Merge "View pressed state dispatching tweaks"
diff --git a/api/current.txt b/api/current.txt
index fffa1fe..137b672 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16080,6 +16080,7 @@
protected static abstract interface CalendarContract.RemindersColumns {
field public static final java.lang.String EVENT_ID = "event_id";
field public static final java.lang.String METHOD = "method";
+ field public static final int METHOD_ALARM = 4; // 0x4
field public static final int METHOD_ALERT = 1; // 0x1
field public static final int METHOD_DEFAULT = 0; // 0x0
field public static final int METHOD_EMAIL = 2; // 0x2
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 16dc517..ebe28db 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -88,11 +88,11 @@
if (screenshot_path[0]) {
ALOGI("taking screenshot\n");
- run_command(NULL, 5, "su", "root", "screenshot", screenshot_path, NULL);
+ run_command(NULL, 5, SU_PATH, "root", "screenshot", screenshot_path, NULL);
ALOGI("wrote screenshot: %s\n", screenshot_path);
}
- run_command("SYSTEM SETTINGS", 20, "su", "root", "sqlite3",
+ run_command("SYSTEM SETTINGS", 20, SU_PATH, "root", "sqlite3",
"/data/data/com.android.providers.settings/databases/settings.db",
"pragma user_version; select * from system; select * from secure;", NULL);
run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
@@ -118,7 +118,7 @@
run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
- run_command("NETWORK INTERFACES", 10, "su", "root", "netcfg", NULL);
+ run_command("NETWORK INTERFACES", 10, SU_PATH, "root", "netcfg", NULL);
dump_file("NETWORK DEV INFO", "/proc/net/dev");
dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
@@ -133,28 +133,28 @@
run_command("ROUTE TABLE 61", 10, "ip", "route", "show", "table", "61", NULL);
run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "61", NULL);
dump_file("ARP CACHE", "/proc/net/arp");
- run_command("IPTABLES", 10, "su", "root", "iptables", "-L", "-nvx", NULL);
- run_command("IP6TABLES", 10, "su", "root", "ip6tables", "-L", "-nvx", NULL);
- run_command("IPTABLE NAT", 10, "su", "root", "iptables", "-t", "nat", "-L", "-n", NULL);
- run_command("IPT6ABLE NAT", 10, "su", "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
+ run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
+ run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
+ run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-n", NULL);
+ run_command("IPT6ABLE NAT", 10, SU_PATH, "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
run_command("WIFI NETWORKS", 20,
- "su", "root", "wpa_cli", "list_networks", NULL);
+ SU_PATH, "root", "wpa_cli", "list_networks", NULL);
property_get("dhcp.wlan0.gateway", network, "");
if (network[0])
- run_command("PING GATEWAY", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+ run_command("PING GATEWAY", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
property_get("dhcp.wlan0.dns1", network, "");
if (network[0])
- run_command("PING DNS1", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+ run_command("PING DNS1", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
property_get("dhcp.wlan0.dns2", network, "");
if (network[0])
- run_command("PING DNS2", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+ run_command("PING DNS2", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
#ifdef FWDUMP_bcm4329
run_command("DUMP WIFI STATUS", 20,
- "su", "root", "dhdutil", "-i", "wlan0", "dump", NULL);
+ SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
run_command("DUMP WIFI INTERNAL COUNTERS", 20,
- "su", "root", "wlutil", "counters", NULL);
+ SU_PATH, "root", "wlutil", "counters", NULL);
#endif
char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
@@ -168,7 +168,7 @@
"vril-dump", NULL);
} else {
run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
- "su", "root", "vril-dump", NULL);
+ SU_PATH, "root", "vril-dump", NULL);
}
}
@@ -192,7 +192,7 @@
dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
- run_command("FILESYSTEMS & FREE SPACE", 10, "su", "root", "df", NULL);
+ run_command("FILESYSTEMS & FREE SPACE", 10, SU_PATH, "root", "df", NULL);
dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
@@ -218,7 +218,7 @@
dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
printf("\n");
- run_command("LIST OF OPEN FILES", 10, "su", "root", "lsof", NULL);
+ run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index b02db0b..c1c2ad8 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -21,6 +21,8 @@
#include <unistd.h>
#include <stdio.h>
+#define SU_PATH "/system/xbin/su"
+
/* prints the contents of a file */
int dump_file(const char *title, const char* path);
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 21526f9..0d5ab90 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -127,7 +127,7 @@
sprintf(title, "SHOW MAP %d (%s)", pid, name);
sprintf(arg, "%d", pid);
- run_command(title, 10, "su", "root", "showmap", arg, NULL);
+ run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
}
/* prints the contents of a file */
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index f427e78..492fcc7 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -149,7 +149,7 @@
* {@link Fragment#getFragmentManager() Fragment.getFragmentManager()}.
*
* <p>The Fragment class can be used many ways to achieve a wide variety of
- * results. It is core, it represents a particular operation or interface
+ * results. In its core, it represents a particular operation or interface
* that is running within a larger {@link Activity}. A Fragment is closely
* tied to the Activity it is in, and can not be used apart from one. Though
* Fragment defines its own lifecycle, that lifecycle is dependent on its
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 413150b..fa59b32f 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -402,8 +402,8 @@
* A comma separated list of reminder methods supported for this
* calendar in the format "#,#,#". Valid types are
* {@link Reminders#METHOD_DEFAULT}, {@link Reminders#METHOD_ALERT},
- * {@link Reminders#METHOD_EMAIL}, {@link Reminders#METHOD_SMS}. Column
- * name.
+ * {@link Reminders#METHOD_EMAIL}, {@link Reminders#METHOD_SMS},
+ * {@link Reminders#METHOD_ALARM}. Column name.
* <P>Type: TEXT</P>
*/
public static final String ALLOWED_REMINDERS = "allowedReminders";
@@ -1930,11 +1930,11 @@
/**
* The alarm method, as set on the server. {@link #METHOD_DEFAULT},
- * {@link #METHOD_ALERT}, {@link #METHOD_EMAIL}, and {@link #METHOD_SMS}
- * are possible values; the device will only process
- * {@link #METHOD_DEFAULT} and {@link #METHOD_ALERT} reminders (the
- * other types are simply stored so we can send the same reminder info
- * back to the server when we make changes).
+ * {@link #METHOD_ALERT}, {@link #METHOD_EMAIL}, {@link #METHOD_SMS} and
+ * {@link #METHOD_ALARM} are possible values; the device will only
+ * process {@link #METHOD_DEFAULT} and {@link #METHOD_ALERT} reminders
+ * (the other types are simply stored so we can send the same reminder
+ * info back to the server when we make changes).
*/
public static final String METHOD = "method";
@@ -1942,6 +1942,7 @@
public static final int METHOD_ALERT = 1;
public static final int METHOD_EMAIL = 2;
public static final int METHOD_SMS = 3;
+ public static final int METHOD_ALARM = 4;
}
/**
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index dd1558c..8c21a28 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -40,6 +40,7 @@
};
enum { NUM_BUFFER_SLOTS = 32 };
enum { NO_CONNECTED_API = 0 };
+ enum { INVALID_BUFFER_SLOT = -1 };
struct FrameAvailableListener : public virtual RefBase {
// onFrameAvailable() is called from queueBuffer() each time an
@@ -119,8 +120,91 @@
// connected to the specified client API.
virtual status_t disconnect(int api);
-protected:
+ // dump our state in a String
+ virtual void dump(String8& result) const;
+ virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
+ // public facing structure for BufferSlot
+ struct BufferItem {
+
+ BufferItem()
+ :
+ mTransform(0),
+ mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+ mTimestamp(0),
+ mFrameNumber(0),
+ mBuf(INVALID_BUFFER_SLOT) {
+ mCrop.makeInvalid();
+ }
+ // mGraphicBuffer points to the buffer allocated for this slot or is NULL
+ // if no buffer has been allocated.
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // mCrop is the current crop rectangle for this buffer slot. This gets
+ // set to mNextCrop each time queueBuffer gets called for this buffer.
+ Rect mCrop;
+
+ // mTransform is the current transform flags for this buffer slot. This
+ // gets set to mNextTransform each time queueBuffer gets called for this
+ // slot.
+ uint32_t mTransform;
+
+ // mScalingMode is the current scaling mode for this buffer slot. This
+ // gets set to mNextScalingMode each time queueBuffer gets called for
+ // this slot.
+ uint32_t mScalingMode;
+
+ // mTimestamp is the current timestamp for this buffer slot. This gets
+ // to set by queueBuffer each time this slot is queued.
+ int64_t mTimestamp;
+
+ // mFrameNumber is the number of the queued frame for this slot.
+ uint64_t mFrameNumber;
+
+ // buf is the slot index of this buffer
+ int mBuf;
+
+ };
+
+ // The following public functions is the consumer facing interface
+
+ // acquire consumes a buffer by transferring its ownership to a consumer.
+ // buffer contains the GraphicBuffer and its corresponding information.
+ // buffer.mGraphicsBuffer will be NULL when the buffer has been already
+ // acquired by the consumer.
+
+ status_t acquire(BufferItem *buffer);
+
+ // releaseBuffer releases a buffer slot from the consumer back to the
+ // BufferQueue pending a fence sync.
+ status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence);
+
+ // consumerDisconnect disconnects a consumer from the BufferQueue. All
+ // buffers will be freed.
+ status_t consumerDisconnect();
+
+ // setDefaultBufferSize is used to set the size of buffers returned by
+ // requestBuffers when a with and height of zero is requested.
+ status_t setDefaultBufferSize(uint32_t w, uint32_t h);
+
+ // setBufferCountServer set the buffer count. If the client has requested
+ // a buffer count using setBufferCount, the server-buffer count will
+ // take effect once the client sets the count back to zero.
+ status_t setBufferCountServer(int bufferCount);
+
+ // isSynchronousMode returns whether the SurfaceTexture is currently in
+ // synchronous mode.
+ bool isSynchronousMode() const;
+
+ // setConsumerName sets the name used in logging
+ void setConsumerName(const String8& name);
+
+ // setFrameAvailableListener sets the listener object that will be notified
+ // when a new frame becomes available.
+ void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+
+private:
// freeBufferLocked frees the resources (both GraphicBuffer and EGLImage)
// for the given slot.
void freeBufferLocked(int index);
@@ -145,20 +229,18 @@
status_t setBufferCountServerLocked(int bufferCount);
- enum { INVALID_BUFFER_SLOT = -1 };
-
struct BufferSlot {
BufferSlot()
- : mEglImage(EGL_NO_IMAGE_KHR),
- mEglDisplay(EGL_NO_DISPLAY),
+ : mEglDisplay(EGL_NO_DISPLAY),
mBufferState(BufferSlot::FREE),
mRequestBufferCalled(false),
mTransform(0),
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mTimestamp(0),
mFrameNumber(0),
- mFence(EGL_NO_SYNC_KHR) {
+ mFence(EGL_NO_SYNC_KHR),
+ mAcquireCalled(false) {
mCrop.makeInvalid();
}
@@ -166,9 +248,6 @@
// if no buffer has been allocated.
sp<GraphicBuffer> mGraphicBuffer;
- // mEglImage is the EGLImage created from mGraphicBuffer.
- EGLImageKHR mEglImage;
-
// mEglDisplay is the EGLDisplay used to create mEglImage.
EGLDisplay mEglDisplay;
@@ -178,6 +257,7 @@
// FREE indicates that the buffer is not currently being used and
// will not be used in the future until it gets dequeued and
// subsequently queued by the client.
+ // aka "owned by BufferQueue, ready to be dequeued"
FREE = 0,
// DEQUEUED indicates that the buffer has been dequeued by the
@@ -190,6 +270,7 @@
// dequeued by the client. That means that the current buffer can
// be in either the DEQUEUED or QUEUED state. In asynchronous mode,
// however, the current buffer is always in the QUEUED state.
+ // aka "owned by producer, ready to be queued"
DEQUEUED = 1,
// QUEUED indicates that the buffer has been queued by the client,
@@ -199,7 +280,11 @@
// the current buffer may be dequeued by the client under some
// circumstances. See the note about the current buffer in the
// documentation for DEQUEUED.
+ // aka "owned by BufferQueue, ready to be acquired"
QUEUED = 2,
+
+ // aka "owned by consumer, ready to be released"
+ ACQUIRED = 3
};
// mBufferState is the current state of this buffer slot.
@@ -236,6 +321,9 @@
// to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
// on a compile-time option) set to a new sync object in updateTexImage.
EGLSyncKHR mFence;
+
+ // Indicates whether this buffer has been seen by a consumer yet
+ bool mAcquireCalled;
};
// mSlots is the array of buffer slots that must be mirrored on the client
@@ -245,7 +333,6 @@
// for a slot when requestBuffer is called with that slot's index.
BufferSlot mSlots[NUM_BUFFER_SLOTS];
-
// mDefaultWidth holds the default width of allocated buffers. It is used
// in requestBuffers() if a width and height of zero is specified.
uint32_t mDefaultWidth;
@@ -271,14 +358,6 @@
// mServerBufferCount buffer count requested by the server-side
int mServerBufferCount;
- // mCurrentTexture is the buffer slot index of the buffer that is currently
- // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
- // indicating that no buffer slot is currently bound to the texture. Note,
- // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
- // that no buffer is bound to the texture. A call to setBufferCount will
- // reset mCurrentTexture to INVALID_BUFFER_SLOT.
- int mCurrentTexture;
-
// mNextCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mNextCrop;
@@ -327,7 +406,7 @@
// mName is a string used to identify the BufferQueue in log messages.
// It is set by the setName method.
- String8 mName;
+ String8 mConsumerName;
// mMutex is the mutex used to prevent concurrent access to the member
// variables of BufferQueue objects. It must be locked whenever the
@@ -337,6 +416,8 @@
// mFrameCounter is the free running counter, incremented for every buffer queued
// with the surface Texture.
uint64_t mFrameCounter;
+
+ bool mBufferHasBeenQueued;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index dcab049..5531e53 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -153,8 +153,8 @@
void setName(const String8& name);
// dump our state in a String
- void dump(String8& result) const;
- void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
+ virtual void dump(String8& result) const;
+ virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
protected:
@@ -217,6 +217,56 @@
// browser's tile cache exceeds.
const GLenum mTexTarget;
+ // SurfaceTexture maintains EGL information about GraphicBuffers that corresponds
+ // directly with BufferQueue's buffers
+ struct EGLSlot {
+ EGLSlot()
+ : mEglImage(EGL_NO_IMAGE_KHR),
+ mEglDisplay(EGL_NO_DISPLAY),
+ mFence(EGL_NO_SYNC_KHR) {
+ }
+
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // mEglImage is the EGLImage created from mGraphicBuffer.
+ EGLImageKHR mEglImage;
+
+ // mEglDisplay is the EGLDisplay used to create mEglImage.
+ EGLDisplay mEglDisplay;
+
+ // mFence is the EGL sync object that must signal before the buffer
+ // associated with this buffer slot may be dequeued. It is initialized
+ // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
+ // on a compile-time option) set to a new sync object in updateTexImage.
+ EGLSyncKHR mFence;
+ };
+
+ EGLSlot mEGLSlots[NUM_BUFFER_SLOTS];
+
+ // mAbandoned indicates that the BufferQueue will no longer be used to
+ // consume images buffers pushed to it using the ISurfaceTexture interface.
+ // It is initialized to false, and set to true in the abandon method. A
+ // BufferQueue that has been abandoned will return the NO_INIT error from
+ // all ISurfaceTexture methods capable of returning an error.
+ bool mAbandoned;
+
+ // mName is a string used to identify the SurfaceTexture in log messages.
+ // It can be set by the setName method.
+ String8 mName;
+
+ // mMutex is the mutex used to prevent concurrent access to the member
+ // variables of SurfaceTexture objects. It must be locked whenever the
+ // member variables are accessed.
+ mutable Mutex mMutex;
+
+ // mCurrentTexture is the buffer slot index of the buffer that is currently
+ // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
+ // indicating that no buffer slot is currently bound to the texture. Note,
+ // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+ // that no buffer is bound to the texture. A call to setBufferCount will
+ // reset mCurrentTexture to INVALID_BUFFER_SLOT.
+ int mCurrentTexture;
+
};
// ----------------------------------------------------------------------------
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 261336a..66fc16d 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "BufferQueue"
+//#define LOG_NDEBUG 0
#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
@@ -27,6 +28,7 @@
#include <private/gui/ComposerService.h>
#include <utils/Log.h>
+#include <gui/SurfaceTexture.h>
// This compile option causes SurfaceTexture to return the buffer that is currently
// attached to the GL texture from dequeueBuffer when no other buffers are
@@ -34,6 +36,10 @@
// implicit cross-process synchronization to prevent the buffer from being
// written to before the buffer has (a) been detached from the GL texture and
// (b) all GL reads from the buffer have completed.
+
+// During refactoring, do not support dequeuing the current buffer
+#undef ALLOW_DEQUEUE_CURRENT_BUFFER
+
#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true
#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
@@ -42,11 +48,11 @@
#endif
// Macros for including the BufferQueue name in log messages
-#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
namespace android {
@@ -63,17 +69,17 @@
mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
mClientBufferCount(0),
mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
- mCurrentTexture(INVALID_BUFFER_SLOT),
mNextTransform(0),
mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mSynchronousMode(false),
mAllowSynchronousMode(allowSynchronousMode),
mConnectedApi(NO_CONNECTED_API),
mAbandoned(false),
- mFrameCounter(0)
+ mFrameCounter(0),
+ mBufferHasBeenQueued(false)
{
// Choose a name using the PID and a process-unique ID.
- mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+ mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
ST_LOGV("BufferQueue");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
@@ -119,6 +125,23 @@
return OK;
}
+bool BufferQueue::isSynchronousMode() const {
+ Mutex::Autolock lock(mMutex);
+ return mSynchronousMode;
+}
+
+void BufferQueue::setConsumerName(const String8& name) {
+ Mutex::Autolock lock(mMutex);
+ mConsumerName = name;
+}
+
+void BufferQueue::setFrameAvailableListener(
+ const sp<FrameAvailableListener>& listener) {
+ ST_LOGV("setFrameAvailableListener");
+ Mutex::Autolock lock(mMutex);
+ mFrameAvailableListener = listener;
+}
+
status_t BufferQueue::setBufferCount(int bufferCount) {
ST_LOGV("setBufferCount: count=%d", bufferCount);
Mutex::Autolock lock(mMutex);
@@ -160,7 +183,7 @@
freeAllBuffersLocked();
mBufferCount = bufferCount;
mClientBufferCount = bufferCount;
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mBufferHasBeenQueued = false;
mQueue.clear();
mDequeueCondition.signal();
return OK;
@@ -276,7 +299,7 @@
mBufferCount = mServerBufferCount;
if (mBufferCount < minBufferCountNeeded)
mBufferCount = minBufferCountNeeded;
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mBufferHasBeenQueued = false;
returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
}
@@ -290,19 +313,12 @@
dequeuedCount++;
}
- // if buffer is FREE it CANNOT be current
- ALOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
- "dequeueBuffer: buffer %d is both FREE and current!",
- i);
-
- if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
- if (state == BufferSlot::FREE || i == mCurrentTexture) {
- foundSync = i;
- if (i != mCurrentTexture) {
- found = i;
- break;
- }
- }
+ // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER)
+ // but dequeuing the current buffer is disabled.
+ if (false) {
+ // This functionality has been temporarily removed so
+ // BufferQueue and SurfaceTexture can be refactored into
+ // separate objects
} else {
if (state == BufferSlot::FREE) {
/* We return the oldest of the free buffers to avoid
@@ -331,8 +347,7 @@
// See whether a buffer has been queued since the last
// setBufferCount so we know whether to perform the
// MIN_UNDEQUEUED_BUFFERS check below.
- bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
- if (bufferHasBeenQueued) {
+ if (mBufferHasBeenQueued) {
// make sure the client is not trying to dequeue more buffers
// than allowed.
const int avail = mBufferCount - (dequeuedCount+1);
@@ -404,27 +419,23 @@
if (updateFormat) {
mPixelFormat = format;
}
+
+ mSlots[buf].mAcquireCalled = false;
mSlots[buf].mGraphicBuffer = graphicBuffer;
mSlots[buf].mRequestBufferCalled = false;
mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mSlots[buf].mEglDisplay,
- mSlots[buf].mEglImage);
- mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
- mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
- }
- if (mCurrentTexture == buf) {
- // The current texture no longer references the buffer in this slot
- // since we just allocated a new buffer.
- mCurrentTexture = INVALID_BUFFER_SLOT;
- }
+ mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+
+
+
+
returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
}
dpy = mSlots[buf].mEglDisplay;
fence = mSlots[buf].mFence;
mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- }
+ } // end lock scope
if (fence != EGL_NO_SYNC_KHR) {
EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
@@ -437,6 +448,7 @@
ALOGE("dequeueBuffer: timeout waiting for fence");
}
eglDestroySyncKHR(dpy, fence);
+
}
ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
@@ -496,9 +508,6 @@
ST_LOGE("queueBuffer: slot %d is not owned by the client "
"(state=%d)", buf, mSlots[buf].mBufferState);
return -EINVAL;
- } else if (buf == mCurrentTexture) {
- ST_LOGE("queueBuffer: slot %d is current!", buf);
- return -EINVAL;
} else if (!mSlots[buf].mRequestBufferCalled) {
ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
"buffer", buf);
@@ -538,6 +547,7 @@
mFrameCounter++;
mSlots[buf].mFrameNumber = mFrameCounter;
+ mBufferHasBeenQueued = true;
mDequeueCondition.signal();
*outWidth = mDefaultWidth;
@@ -647,6 +657,9 @@
err = -EINVAL;
break;
}
+
+ mBufferHasBeenQueued = false;
+
return err;
}
@@ -687,26 +700,185 @@
return err;
}
+void BufferQueue::dump(String8& result) const
+{
+ char buffer[1024];
+ BufferQueue::dump(result, "", buffer, 1024);
+}
+
+void BufferQueue::dump(String8& result, const char* prefix,
+ char* buffer, size_t SIZE) const
+{
+ Mutex::Autolock _l(mMutex);
+ snprintf(buffer, SIZE,
+ "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x}\n"
+ ,prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
+ mNextCrop.bottom, mNextTransform
+ );
+ result.append(buffer);
+
+ String8 fifo;
+ int fifoSize = 0;
+ Fifo::const_iterator i(mQueue.begin());
+ while (i != mQueue.end()) {
+ snprintf(buffer, SIZE, "%02d ", *i++);
+ fifoSize++;
+ fifo.append(buffer);
+ }
+
+ snprintf(buffer, SIZE,
+ "%s-BufferQueue mBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
+ "mPixelFormat=%d, FIFO(%d)={%s}\n",
+ prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
+ mDefaultHeight, mPixelFormat, fifoSize, fifo.string());
+ result.append(buffer);
+
+
+ struct {
+ const char * operator()(int state) const {
+ switch (state) {
+ case BufferSlot::DEQUEUED: return "DEQUEUED";
+ case BufferSlot::QUEUED: return "QUEUED";
+ case BufferSlot::FREE: return "FREE";
+ case BufferSlot::ACQUIRED: return "ACQUIRED";
+ default: return "Unknown";
+ }
+ }
+ } stateName;
+
+ for (int i=0 ; i<mBufferCount ; i++) {
+ const BufferSlot& slot(mSlots[i]);
+ snprintf(buffer, SIZE,
+ "%s%s[%02d] "
+ "state=%-8s, crop=[%d,%d,%d,%d], "
+ "transform=0x%02x, timestamp=%lld",
+ prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
+ stateName(slot.mBufferState),
+ slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
+ slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
+ );
+ result.append(buffer);
+
+ const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
+ if (buf != NULL) {
+ snprintf(buffer, SIZE,
+ ", %p [%4ux%4u:%4u,%3X]",
+ buf->handle, buf->width, buf->height, buf->stride,
+ buf->format);
+ result.append(buffer);
+ }
+ result.append("\n");
+ }
+}
+
void BufferQueue::freeBufferLocked(int i) {
mSlots[i].mGraphicBuffer = 0;
mSlots[i].mBufferState = BufferSlot::FREE;
mSlots[i].mFrameNumber = 0;
- if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
- mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
- mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+ mSlots[i].mAcquireCalled = false;
+
+ // destroy fence as BufferQueue now takes ownership
+ if (mSlots[i].mFence != EGL_NO_SYNC_KHR) {
+ eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence);
+ mSlots[i].mFence = EGL_NO_SYNC_KHR;
}
}
void BufferQueue::freeAllBuffersLocked() {
ALOGW_IF(!mQueue.isEmpty(),
"freeAllBuffersLocked called but mQueue is not empty");
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mQueue.clear();
+ mBufferHasBeenQueued = false;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
freeBufferLocked(i);
}
}
+status_t BufferQueue::acquire(BufferItem *buffer) {
+ Mutex::Autolock _l(mMutex);
+ // check if queue is empty
+ // In asynchronous mode the list is guaranteed to be one buffer
+ // deep, while in synchronous mode we use the oldest buffer.
+ if (!mQueue.empty()) {
+ Fifo::iterator front(mQueue.begin());
+ int buf = *front;
+
+ if (mSlots[buf].mAcquireCalled) {
+ buffer->mGraphicBuffer = NULL;
+ }
+ else {
+ buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
+ }
+ buffer->mCrop = mSlots[buf].mCrop;
+ buffer->mTransform = mSlots[buf].mTransform;
+ buffer->mScalingMode = mSlots[buf].mScalingMode;
+ buffer->mFrameNumber = mSlots[buf].mFrameNumber;
+ buffer->mBuf = buf;
+ mSlots[buf].mAcquireCalled = true;
+
+ mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
+ mQueue.erase(front);
+ }
+ else {
+ return -EINVAL; //should be a better return code
+ }
+
+ return OK;
+}
+
+status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
+ EGLSyncKHR fence) {
+ Mutex::Autolock _l(mMutex);
+
+ if (buf == INVALID_BUFFER_SLOT) {
+ return -EINVAL;
+ }
+
+ mSlots[buf].mEglDisplay = display;
+ mSlots[buf].mFence = fence;
+
+ // The current buffer becomes FREE if it was still in the queued
+ // state. If it has already been given to the client
+ // (synchronous mode), then it stays in DEQUEUED state.
+ if (mSlots[buf].mBufferState == BufferSlot::QUEUED
+ || mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
+ mSlots[buf].mBufferState = BufferSlot::FREE;
+ }
+ mDequeueCondition.signal();
+
+ return OK;
+}
+
+status_t BufferQueue::consumerDisconnect() {
+ Mutex::Autolock lock(mMutex);
+ // Once the SurfaceTexture disconnects, the BufferQueue
+ // is considered abandoned
+ mAbandoned = true;
+ freeAllBuffersLocked();
+ mDequeueCondition.signal();
+ return OK;
+}
+
+status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
+{
+ ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
+ if (!w || !h) {
+ ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
+ w, h);
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+ mDefaultWidth = w;
+ mDefaultHeight = h;
+ return OK;
+}
+
+status_t BufferQueue::setBufferCountServer(int bufferCount) {
+ Mutex::Autolock lock(mMutex);
+ return setBufferCountServerLocked(bufferCount);
+}
+
void BufferQueue::freeAllBuffersExceptHeadLocked() {
ALOGW_IF(!mQueue.isEmpty(),
"freeAllBuffersExceptCurrentLocked called but mQueue is not empty");
@@ -715,7 +887,7 @@
Fifo::iterator front(mQueue.begin());
head = *front;
}
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mBufferHasBeenQueued = false;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (i != head) {
freeBufferLocked(i);
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 5f0013c..a23a328 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -96,6 +96,11 @@
static void mtxMul(float out[16], const float a[16], const float b[16]);
+// Get an ID that's unique within this process.
+static int32_t createProcessUniqueId() {
+ static volatile int32_t globalCounter = 0;
+ return android_atomic_inc(&globalCounter);
+}
SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
GLenum texTarget, bool useFenceSync) :
@@ -108,8 +113,13 @@
#else
mUseFenceSync(false),
#endif
- mTexTarget(texTarget)
+ mTexTarget(texTarget),
+ mAbandoned(false),
+ mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT)
{
+ // Choose a name using the PID and a process-unique ID.
+ mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+ BufferQueue::setConsumerName(mName);
ST_LOGV("SurfaceTexture");
memcpy(mCurrentTransformMatrix, mtxIdentity,
@@ -118,28 +128,18 @@
SurfaceTexture::~SurfaceTexture() {
ST_LOGV("~SurfaceTexture");
- freeAllBuffersLocked();
+ abandon();
}
status_t SurfaceTexture::setBufferCountServer(int bufferCount) {
Mutex::Autolock lock(mMutex);
- return setBufferCountServerLocked(bufferCount);
+ return BufferQueue::setBufferCountServer(bufferCount);
}
status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
{
- ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
- if (!w || !h) {
- ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
- w, h);
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mMutex);
- mDefaultWidth = w;
- mDefaultHeight = h;
- return OK;
+ return BufferQueue::setDefaultBufferSize(w, h);
}
status_t SurfaceTexture::updateTexImage() {
@@ -151,23 +151,35 @@
return NO_INIT;
}
+ BufferItem item;
+
// In asynchronous mode the list is guaranteed to be one buffer
// deep, while in synchronous mode we use the oldest buffer.
- if (!mQueue.empty()) {
- Fifo::iterator front(mQueue.begin());
- int buf = *front;
+ if (acquire(&item) == NO_ERROR) {
+ int buf = item.mBuf;
+ // This buffer was newly allocated, so we need to clean up on our side
+ if (item.mGraphicBuffer != NULL) {
+ mEGLSlots[buf].mGraphicBuffer = 0;
+ if (mEGLSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mEGLSlots[buf].mEglDisplay,
+ mEGLSlots[buf].mEglImage);
+ mEGLSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
+ mEGLSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+ }
+ mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
+ }
// Update the GL texture object.
- EGLImageKHR image = mSlots[buf].mEglImage;
+ EGLImageKHR image = mEGLSlots[buf].mEglImage;
EGLDisplay dpy = eglGetCurrentDisplay();
if (image == EGL_NO_IMAGE_KHR) {
- if (mSlots[buf].mGraphicBuffer == 0) {
+ if (item.mGraphicBuffer == 0) {
ST_LOGE("buffer at slot %d is null", buf);
return BAD_VALUE;
}
- image = createImage(dpy, mSlots[buf].mGraphicBuffer);
- mSlots[buf].mEglImage = image;
- mSlots[buf].mEglDisplay = dpy;
+ image = createImage(dpy, item.mGraphicBuffer);
+ mEGLSlots[buf].mEglImage = image;
+ mEGLSlots[buf].mEglDisplay = dpy;
if (image == EGL_NO_IMAGE_KHR) {
// NOTE: if dpy was invalid, createImage() is guaranteed to
// fail. so we'd end up here.
@@ -190,6 +202,8 @@
failed = true;
}
if (failed) {
+ releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
+ mEGLSlots[buf].mFence);
return -EINVAL;
}
@@ -200,40 +214,37 @@
if (fence == EGL_NO_SYNC_KHR) {
ALOGE("updateTexImage: error creating fence: %#x",
eglGetError());
+ releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
+ mEGLSlots[buf].mFence);
return -EINVAL;
}
glFlush();
- mSlots[mCurrentTexture].mFence = fence;
+ mEGLSlots[mCurrentTexture].mFence = fence;
}
}
ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)",
mCurrentTexture,
mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0,
- buf, mSlots[buf].mGraphicBuffer->handle);
+ buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0);
- if (mCurrentTexture != INVALID_BUFFER_SLOT) {
- // The current buffer becomes FREE if it was still in the queued
- // state. If it has already been given to the client
- // (synchronous mode), then it stays in DEQUEUED state.
- if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED) {
- mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE;
- }
- }
+ // release old buffer
+ releaseBuffer(mCurrentTexture,
+ mEGLSlots[mCurrentTexture].mEglDisplay,
+ mEGLSlots[mCurrentTexture].mFence);
// Update the SurfaceTexture state.
mCurrentTexture = buf;
- mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
- mCurrentCrop = mSlots[buf].mCrop;
- mCurrentTransform = mSlots[buf].mTransform;
- mCurrentScalingMode = mSlots[buf].mScalingMode;
- mCurrentTimestamp = mSlots[buf].mTimestamp;
+ mCurrentTextureBuf = mEGLSlots[buf].mGraphicBuffer;
+ mCurrentCrop = item.mCrop;
+ mCurrentTransform = item.mTransform;
+ mCurrentScalingMode = item.mScalingMode;
+ mCurrentTimestamp = item.mTimestamp;
computeCurrentTransformMatrix();
// Now that we've passed the point at which failures can happen,
// it's safe to remove the buffer from the front of the queue.
- mQueue.erase(front);
- mDequeueCondition.signal();
+
} else {
// We always bind the texture even if we don't update its contents.
glBindTexture(mTexTarget, mTexName);
@@ -299,7 +310,7 @@
}
}
- sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
+ sp<GraphicBuffer>& buf(mCurrentTextureBuf);
float tx, ty, sx, sy;
if (!mCurrentCrop.isEmpty()) {
// In order to prevent bilinear sampling at the of the crop rectangle we
@@ -371,7 +382,7 @@
const sp<FrameAvailableListener>& listener) {
ST_LOGV("setFrameAvailableListener");
Mutex::Autolock lock(mMutex);
- mFrameAvailableListener = listener;
+ BufferQueue::setFrameAvailableListener(listener);
}
EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
@@ -412,22 +423,33 @@
bool SurfaceTexture::isSynchronousMode() const {
Mutex::Autolock lock(mMutex);
- return mSynchronousMode;
+ return BufferQueue::isSynchronousMode();
}
-
-
void SurfaceTexture::abandon() {
Mutex::Autolock lock(mMutex);
- mQueue.clear();
mAbandoned = true;
mCurrentTextureBuf.clear();
- freeAllBuffersLocked();
- mDequeueCondition.signal();
+
+ // destroy all egl buffers
+ for (int i =0; i < NUM_BUFFER_SLOTS; i++) {
+ mEGLSlots[i].mGraphicBuffer = 0;
+ if (mEGLSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mEGLSlots[i].mEglDisplay,
+ mEGLSlots[i].mEglImage);
+ mEGLSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
+ mEGLSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+ }
+ }
+
+ // disconnect from the BufferQueue
+ BufferQueue::consumerDisconnect();
}
void SurfaceTexture::setName(const String8& name) {
+ Mutex::Autolock _l(mMutex);
mName = name;
+ BufferQueue::setConsumerName(name);
}
void SurfaceTexture::dump(String8& result) const
@@ -440,68 +462,19 @@
char* buffer, size_t SIZE) const
{
Mutex::Autolock _l(mMutex);
- snprintf(buffer, SIZE,
- "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
- "mPixelFormat=%d, mTexName=%d\n",
- prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
- mDefaultHeight, mPixelFormat, mTexName);
+ snprintf(buffer, SIZE, "%smTexName=%d\n", prefix, mTexName);
result.append(buffer);
- String8 fifo;
- int fifoSize = 0;
- Fifo::const_iterator i(mQueue.begin());
- while (i != mQueue.end()) {
- snprintf(buffer, SIZE, "%02d ", *i++);
- fifoSize++;
- fifo.append(buffer);
- }
-
snprintf(buffer, SIZE,
- "%scurrent: {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
- "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, FIFO(%d)={%s}}\n"
- ,
- prefix, mCurrentCrop.left,
+ "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
+ ,prefix, mCurrentCrop.left,
mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
- mCurrentTransform, mCurrentTexture,
- prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
- mNextCrop.bottom, mNextTransform, fifoSize, fifo.string()
+ mCurrentTransform, mCurrentTexture
);
result.append(buffer);
- struct {
- const char * operator()(int state) const {
- switch (state) {
- case BufferSlot::DEQUEUED: return "DEQUEUED";
- case BufferSlot::QUEUED: return "QUEUED";
- case BufferSlot::FREE: return "FREE";
- default: return "Unknown";
- }
- }
- } stateName;
- for (int i=0 ; i<mBufferCount ; i++) {
- const BufferSlot& slot(mSlots[i]);
- snprintf(buffer, SIZE,
- "%s%s[%02d] "
- "state=%-8s, crop=[%d,%d,%d,%d], "
- "transform=0x%02x, timestamp=%lld",
- prefix, (i==mCurrentTexture)?">":" ", i,
- stateName(slot.mBufferState),
- slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
- slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
- );
- result.append(buffer);
-
- const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
- if (buf != NULL) {
- snprintf(buffer, SIZE,
- ", %p [%4ux%4u:%4u,%3X]",
- buf->handle, buf->width, buf->height, buf->stride,
- buf->format);
- result.append(buffer);
- }
- result.append("\n");
- }
+ BufferQueue::dump(result, prefix, buffer, SIZE);
}
static void mtxMul(float out[16], const float a[16], const float b[16]) {
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 098a1a2..dc27d38 100755
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -845,6 +845,17 @@
config->inputCfg.samplingRate, config->inputCfg.channels);
int status;
+ // if at least one process is enabled, do not accept configuration changes
+ if (session->enabledMsk) {
+ if (session->samplingRate != config->inputCfg.samplingRate ||
+ session->inChannelCount != inCnl ||
+ session->outChannelCount != outCnl) {
+ return -ENOSYS;
+ } else {
+ return 0;
+ }
+ }
+
// AEC implementation is limited to 16kHz
if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
session->apmSamplingRate = 32000;
@@ -1287,7 +1298,9 @@
if (*(int *)pReplyData != 0) {
break;
}
- *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+ if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
+ *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+ }
break;
case EFFECT_CMD_GET_CONFIG:
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index b8516afd..059d6b9 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -19,8 +19,6 @@
#include "../include/SoftwareRenderer.h"
-#include <binder/MemoryHeapBase.h>
-#include <binder/MemoryHeapPmem.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MetaData.h>
#include <system/window.h>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 3a2ea65..a08b99a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -22,7 +22,6 @@
<drawable name="notification_item_background_color_pressed">#ff257390</drawable>
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
<drawable name="status_bar_background">#ff000000</drawable>
- <drawable name="status_bar_recents_background_solid">#b3000000</drawable>
<drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
<color name="status_bar_recents_app_label_color">#ffffffff</color>
<drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
index 78050a2..deb5670 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
@@ -27,9 +27,5 @@
void handleOnClick(View selectedView);
void handleSwipe(View selectedView);
void handleLongPress(View selectedView, View anchorView, View thumbnailView);
- void handleShowBackground(boolean show);
void dismiss();
-
- // TODO: find another way to get this info from RecentsPanelView
- boolean isRecentsVisible();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 4dc3e33..76e6ee8 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -217,14 +217,6 @@
}
@Override
- protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (mPerformanceHelper != null) {
- mPerformanceHelper.onLayoutCallback();
- }
- }
-
- @Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -327,12 +319,6 @@
});
}
- public void onRecentsVisibilityChanged() {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.updateShowBackground();
- }
- }
-
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -379,9 +365,6 @@
@Override
public void setLayoutTransition(LayoutTransition transition) {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.setLayoutTransitionCallback(transition);
- }
// The layout transition applies to our embedded LinearLayout
mLinearLayout.setLayoutTransition(transition);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 7896720..18132ff 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -32,13 +32,14 @@
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewRootImpl;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
@@ -325,18 +326,6 @@
}
}
- public void handleShowBackground(boolean show) {
- if (show) {
- mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background_solid);
- } else {
- mRecentsScrim.setBackgroundDrawable(null);
- }
- }
-
- public boolean isRecentsVisible() {
- return getVisibility() == VISIBLE;
- }
-
public void onAnimationCancel(Animator animation) {
}
@@ -457,9 +446,15 @@
mRecentsNoApps = findViewById(R.id.recents_no_apps);
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsContainer, mRecentsNoApps, this);
- // In order to save space, we make the background texture repeat in the Y direction
- if (mRecentsScrim != null && mRecentsScrim.getBackground() instanceof BitmapDrawable) {
- ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
+ if (mRecentsScrim != null) {
+ Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay();
+ if (!ActivityManager.isHighEndGfx(d)) {
+ mRecentsScrim.setBackgroundDrawable(null);
+ } else if (mRecentsScrim.getBackground() instanceof BitmapDrawable) {
+ // In order to save space, we make the background texture repeat in the Y direction
+ ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
+ }
}
mPreloadTasksRunnable = new Runnable() {
@@ -478,21 +473,6 @@
transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
}
- @Override
- protected void onVisibilityChanged(View changedView, int visibility) {
- super.onVisibilityChanged(changedView, visibility);
- if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")");
-
- if (mRecentsContainer instanceof RecentsHorizontalScrollView) {
- ((RecentsHorizontalScrollView) mRecentsContainer).onRecentsVisibilityChanged();
- } else if (mRecentsContainer instanceof RecentsVerticalScrollView) {
- ((RecentsVerticalScrollView) mRecentsContainer).onRecentsVisibilityChanged();
- } else {
- throw new IllegalArgumentException("missing Recents[Horizontal]ScrollView");
- }
- }
-
-
private void updateIcon(ViewHolder h, Drawable icon, boolean show, boolean anim) {
if (icon != null) {
h.iconView.setImageDrawable(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
index 813099a..5529d0c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
@@ -78,39 +78,13 @@
mScrollView.setVerticalFadingEdgeEnabled(false);
mScrollView.setHorizontalFadingEdgeEnabled(false);
}
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- mCallback = callback;
- mLinearLayout = layout;
- mAttachedToWindow = true;
- mBackgroundDrawable = mContext.getResources()
- .getDrawable(R.drawable.status_bar_recents_background_solid).getConstantState();
- updateShowBackground();
- }
-
}
public void addViewCallback(View newLinearLayoutChild) {
if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
final View view = newLinearLayoutChild;
- if (mShowBackground) {
- view.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
- view.setDrawingCacheEnabled(true);
- view.buildDrawingCache();
- } else {
- view.setBackgroundDrawable(null);
- view.setDrawingCacheEnabled(false);
- view.destroyDrawingCache();
- }
- }
- }
-
- public void onLayoutCallback() {
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- mScrollView.post(new Runnable() {
- public void run() {
- updateShowBackground();
- }
- });
+ view.setDrawingCacheEnabled(true);
+ view.buildDrawingCache();
}
}
@@ -118,37 +92,6 @@
int left, int right, int top, int bottom, int scrollX, int scrollY,
float topFadingEdgeStrength, float bottomFadingEdgeStrength,
float leftFadingEdgeStrength, float rightFadingEdgeStrength) {
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- if (mIsVertical) {
- if (scrollY < 0) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(0, scrollY, mScrollView.getWidth(), 0);
- d.draw(canvas);
- } else {
- final int childHeight = mLinearLayout.getHeight();
- if (scrollY + mScrollView.getHeight() > childHeight) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(0, childHeight, mScrollView.getWidth(),
- scrollY + mScrollView.getHeight());
- d.draw(canvas);
- }
- }
- } else {
- if (scrollX < 0) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(scrollX, 0, 0, mScrollView.getHeight());
- d.draw(canvas);
- } else {
- final int childWidth = mLinearLayout.getWidth();
- if (scrollX + mScrollView.getWidth() > childWidth) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(childWidth, 0,
- scrollX + mScrollView.getWidth(), mScrollView.getHeight());
- d.draw(canvas);
- }
- }
- }
- }
if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
|| USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
@@ -241,64 +184,4 @@
return mFadingEdgeLength;
}
- public void setLayoutTransitionCallback(LayoutTransition transition) {
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- if (transition != null) {
- transition.addTransitionListener(new LayoutTransition.TransitionListener() {
- @Override
- public void startTransition(LayoutTransition transition,
- ViewGroup container, View view, int transitionType) {
- updateShowBackground();
- }
-
- @Override
- public void endTransition(LayoutTransition transition,
- ViewGroup container, View view, int transitionType) {
- updateShowBackground();
- }
- });
- }
- }
- }
-
- // Turn on/off drawing the background in our ancestor, and turn on/off drawing
- // in the items in LinearLayout contained by this scrollview.
- // Moving the background drawing to our children, and turning on a drawing cache
- // for each of them, gives us a ~20fps gain when Recents is rendered in software
- public void updateShowBackground() {
- if (!mAttachedToWindow) {
- // We haven't been initialized yet-- we'll get called again when we are
- return;
- }
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- LayoutTransition transition = mLinearLayout.getLayoutTransition();
- int linearLayoutSize =
- mIsVertical ? mLinearLayout.getHeight() : mLinearLayout.getWidth();
- int scrollViewSize =
- mIsVertical ? mScrollView.getHeight() : mScrollView.getWidth();
- boolean show = !mScrollView.isHardwareAccelerated() &&
- (linearLayoutSize > scrollViewSize) &&
- !(transition != null && transition.isRunning()) &&
- mCallback.isRecentsVisible();
-
- if (!mFirstTime && show == mShowBackground) return;
- mShowBackground = show;
- mFirstTime = false;
-
- mCallback.handleShowBackground(!show);
- for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
- View v = mLinearLayout.getChildAt(i);
- if (show) {
- v.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
- v.setDrawingCacheEnabled(true);
- v.buildDrawingCache();
- } else {
- v.setDrawingCacheEnabled(false);
- v.destroyDrawingCache();
- v.setBackgroundDrawable(null);
- }
- }
- }
- }
-
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 19fce37..1bfd000 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -224,14 +224,6 @@
}
@Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (mPerformanceHelper != null) {
- mPerformanceHelper.onLayoutCallback();
- }
- }
-
- @Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -334,12 +326,6 @@
});
}
- public void onRecentsVisibilityChanged() {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.updateShowBackground();
- }
- }
-
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -387,9 +373,6 @@
@Override
public void setLayoutTransition(LayoutTransition transition) {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.setLayoutTransitionCallback(transition);
- }
// The layout transition applies to our embedded LinearLayout
mLinearLayout.setLayoutTransition(transition);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 2458495..b2d9e64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -397,6 +397,9 @@
(opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
if (ActivityManager.isHighEndGfx(mDisplay)) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ } else {
+ lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+ lp.dimAmount = 0.7f;
}
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
lp.setTitle("RecentsPanel");
diff --git a/packages/VpnDialogs/res/layout/manage.xml b/packages/VpnDialogs/res/layout/manage.xml
index ec710ff..56332c3 100644
--- a/packages/VpnDialogs/res/layout/manage.xml
+++ b/packages/VpnDialogs/res/layout/manage.xml
@@ -32,12 +32,12 @@
<TextView android:id="@+id/duration" style="@style/value"/>
</TableRow>
- <TableRow>
+ <TableRow android:id="@+id/data_transmitted_row" android:visibility="gone">
<TextView android:text="@string/data_transmitted" style="@style/label"/>
<TextView android:id="@+id/data_transmitted" style="@style/value"/>
</TableRow>
- <TableRow>
+ <TableRow android:id="@+id/data_received_row" android:visibility="gone">
<TextView android:text="@string/data_received" style="@style/label"/>
<TextView android:id="@+id/data_received" style="@style/value"/>
</TableRow>
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml
index 1352e9b..3ff767a 100644
--- a/packages/VpnDialogs/res/values/strings.xml
+++ b/packages/VpnDialogs/res/values/strings.xml
@@ -48,8 +48,6 @@
<!-- Label for the network usage of data received over VPN. [CHAR LIMIT=20] -->
<string name="data_received">Received:</string>
- <!-- Dummy string for a blank value. [CHAR LIMIT=40] -->
- <string name="blank_value">--</string>
<!-- Formatted string for the network usage over VPN. [CHAR LIMIT=40] -->
<string name="data_value_format">
<xliff:g id="number">%1$s</xliff:g> bytes /
diff --git a/packages/VpnDialogs/res/values/styles.xml b/packages/VpnDialogs/res/values/styles.xml
index e3469ec..0dda673 100644
--- a/packages/VpnDialogs/res/values/styles.xml
+++ b/packages/VpnDialogs/res/values/styles.xml
@@ -25,6 +25,5 @@
<item name="android:gravity">center_vertical|left</item>
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
- <item name="android:text">@string/blank_value</item>
</style>
</resources>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 2de0251..9999adb1 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -50,6 +50,7 @@
private TextView mDuration;
private TextView mDataTransmitted;
private TextView mDataReceived;
+ private boolean mDataRowsHidden;
private Handler mHandler;
@@ -76,6 +77,7 @@
mDuration = (TextView) view.findViewById(R.id.duration);
mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
mDataReceived = (TextView) view.findViewById(R.id.data_received);
+ mDataRowsHidden = true;
if (mConfig.user.equals(VpnConfig.LEGACY_VPN)) {
mAlertParams.mIconId = android.R.drawable.ic_dialog_info;
@@ -140,8 +142,15 @@
seconds / 3600, seconds / 60 % 60, seconds % 60));
}
- String[] numbers = getStatistics();
+ String[] numbers = getNumbers();
if (numbers != null) {
+ // First unhide the related data rows.
+ if (mDataRowsHidden) {
+ findViewById(R.id.data_transmitted_row).setVisibility(View.VISIBLE);
+ findViewById(R.id.data_received_row).setVisibility(View.VISIBLE);
+ mDataRowsHidden = false;
+ }
+
// [1] and [2] are received data in bytes and packets.
mDataReceived.setText(getString(R.string.data_value_format,
numbers[1], numbers[2]));
@@ -155,7 +164,7 @@
return true;
}
- private String[] getStatistics() {
+ private String[] getNumbers() {
DataInputStream in = null;
try {
// See dev_seq_printf_stats() in net/core/dev.c.
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java
index 6665614..da65438 100644
--- a/services/java/com/android/server/BootReceiver.java
+++ b/services/java/com/android/server/BootReceiver.java
@@ -39,8 +39,10 @@
public class BootReceiver extends BroadcastReceiver {
private static final String TAG = "BootReceiver";
- // Maximum size of a logged event (files get truncated if they're longer)
- private static final int LOG_SIZE = 65536;
+ // Maximum size of a logged event (files get truncated if they're longer).
+ // Give userdebug builds a larger max to capture extra debug, esp. for last_kmsg.
+ private static final int LOG_SIZE =
+ SystemProperties.getInt("ro.debuggable", 0) == 1 ? 98304 : 65536;
private static final File TOMBSTONE_DIR = new File("/data/tombstones");