Merge "Optimize EventHub to process events in big chunks."
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index 168310c..6ed3c6f 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -62,8 +62,11 @@
// contents of the buffer associated with slot and transfers ownership of
// that slot back to the server. It is not valid to call queueBuffer on a
// slot that is not owned by the client or one for which a buffer associated
- // via requestBuffer.
- virtual status_t queueBuffer(int slot) = 0;
+ // via requestBuffer. In addition, a timestamp must be provided by the
+ // client for this buffer. The timestamp is measured in nanoseconds, and
+ // must be monotonically increasing. Its other properties (zero point, etc)
+ // are client-dependent, and should be documented by the client.
+ virtual status_t queueBuffer(int slot, int64_t timestamp) = 0;
// cancelBuffer indicates that the client does not wish to fill in the
// buffer associated with slot and transfers ownership of the slot back to
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 9bf38f7..afa64d3 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -66,7 +66,12 @@
// unmodified.
virtual status_t dequeueBuffer(int *buf);
- virtual status_t queueBuffer(int buf);
+ // queueBuffer returns a filled buffer to the SurfaceTexture. In addition, a
+ // timestamp must be provided for the buffer. The timestamp is in
+ // nanoseconds, and must be monotonically increasing. Its other semantics
+ // (zero point, etc) are client-dependent and should be documented by the
+ // client.
+ virtual status_t queueBuffer(int buf, int64_t timestamp);
virtual void cancelBuffer(int buf);
virtual status_t setCrop(const Rect& reg);
virtual status_t setTransform(uint32_t transform);
@@ -98,6 +103,14 @@
// functions.
void getTransformMatrix(float mtx[16]);
+ // getTimestamp retrieves the timestamp associated with the texture image
+ // set by the most recent call to updateTexImage.
+ //
+ // The timestamp is in nanoseconds, and is monotonically increasing. Its
+ // other semantics (zero point, etc) are source-dependent and should be
+ // documented by the source.
+ int64_t getTimestamp();
+
// setFrameAvailableListener sets the listener object that will be notified
// when a new frame becomes available.
void setFrameAvailableListener(const sp<FrameAvailableListener>& l);
@@ -172,6 +185,10 @@
// gets set to mLastQueuedTransform each time updateTexImage is called.
uint32_t mCurrentTransform;
+ // mCurrentTimestamp is the timestamp for the current texture. It
+ // gets set to mLastQueuedTimestamp each time updateTexImage is called.
+ int64_t mCurrentTimestamp;
+
// mLastQueued is the buffer slot index of the most recently enqueued buffer.
// At construction time it is initialized to INVALID_BUFFER_SLOT, and is
// updated each time queueBuffer is called.
@@ -187,6 +204,10 @@
// queueBuffer gets called.
uint32_t mLastQueuedTransform;
+ // mLastQueuedTimestamp is the timestamp for the buffer that was most
+ // recently queued. This gets set by queueBuffer.
+ int64_t mLastQueuedTimestamp;
+
// mNextCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mNextCrop;
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 7992105..df82bf2 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -63,6 +63,7 @@
int dispatchSetBufferCount(va_list args);
int dispatchSetBuffersGeometry(va_list args);
int dispatchSetBuffersTransform(va_list args);
+ int dispatchSetBuffersTimestamp(va_list args);
int dispatchSetCrop(va_list args);
int dispatchSetUsage(va_list args);
@@ -71,6 +72,7 @@
int setBufferCount(int bufferCount);
int setBuffersGeometry(int w, int h, int format);
int setBuffersTransform(int transform);
+ int setBuffersTimestamp(int64_t timestamp);
int setCrop(Rect const* rect);
int setUsage(uint32_t reqUsage);
@@ -114,6 +116,11 @@
// at the next deuque operation. It is initialized to 0.
uint32_t mReqUsage;
+ // mTimestamp is the timestamp that will be used for the next buffer queue
+ // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that
+ // a timestamp is auto-generated when queueBuffer is called.
+ int64_t mTimestamp;
+
// 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.
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 9e0b5bb..a59d9e5 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -226,7 +226,8 @@
int dispatch_set_buffer_count(va_list args);
int dispatch_set_buffers_geometry(va_list args);
int dispatch_set_buffers_transform(va_list args);
-
+ int dispatch_set_buffers_timestamp(va_list args);
+
void setUsage(uint32_t reqUsage);
int connect(int api);
int disconnect(int api);
@@ -234,6 +235,7 @@
int setBufferCount(int bufferCount);
int setBuffersGeometry(int w, int h, int format);
int setBuffersTransform(int transform);
+ int setBuffersTimestamp(int64_t timestamp);
/*
* private stuff...
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index b912e9b..8383957 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -228,6 +228,9 @@
{ "BUTTON_14", 201 },
{ "BUTTON_15", 202 },
{ "BUTTON_16", 203 },
+ { "LANGUAGE_SWITCH", 204 },
+ { "MANNER_MODE", 205 },
+ { "3D_MODE", 206 },
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 0fc1ddf..0a6e4fb 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -57,7 +57,7 @@
{
/* a magic value defined by the actual EGL native type */
int magic;
-
+
/* the sizeof() of the actual EGL native type */
int version;
@@ -129,6 +129,7 @@
NATIVE_WINDOW_SET_BUFFER_COUNT,
NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
+ NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,
};
/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -157,7 +158,15 @@
NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, // SurfaceTextureClient
};
-struct ANativeWindow
+/* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
+ *
+ * Special timestamp value to indicate that timestamps should be auto-generated
+ * by the native window when queueBuffer is called. This is equal to INT64_MIN,
+ * defined directly to avoid problems with C99/C++ inclusion of stdint.h.
+ */
+const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1);
+
+struct ANativeWindow
{
#ifdef __cplusplus
ANativeWindow()
@@ -262,7 +271,8 @@
* NATIVE_WINDOW_SET_BUFFER_COUNT
* NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
* NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
- *
+ * NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
+ *
*/
int (*perform)(struct ANativeWindow* window,
@@ -389,6 +399,22 @@
transform);
}
+/*
+ * native_window_set_buffers_timestamp(..., int64_t timestamp)
+ * All buffers queued after this call will be associated with the timestamp
+ * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO
+ * (the default), timestamps will be generated automatically when queueBuffer is
+ * called. The timestamp is measured in nanoseconds, and must be monotonically
+ * increasing.
+ */
+static inline int native_window_set_buffers_timestamp(
+ ANativeWindow* window,
+ int64_t timestamp)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,
+ timestamp);
+}
+
// ---------------------------------------------------------------------------
/* FIXME: this is legacy for pixmaps */
diff --git a/include/utils/Functor.h b/include/utils/Functor.h
index 565f4a3..e24ded4 100644
--- a/include/utils/Functor.h
+++ b/include/utils/Functor.h
@@ -25,8 +25,7 @@
public:
Functor() {}
virtual ~Functor() {}
- virtual status_t operator ()() { return true; }
- virtual status_t operator ()(float* data, uint32_t len) { return true; }
+ virtual status_t operator ()(int what, void* data) { return NO_ERROR; }
};
}; // namespace android
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index ec851bd..6fd307f 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -162,6 +162,9 @@
inline status_t sort(compar_t cmp);
inline status_t sort(compar_r_t cmp, void* state);
+ // for debugging only
+ inline size_t getItemSize() const { return itemSize(); }
+
protected:
virtual void do_construct(void* storage, size_t num) const;
virtual void do_destroy(void* storage, size_t num) const;
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index d661fd5..bc14ad5 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -88,10 +88,11 @@
return result;
}
- virtual status_t queueBuffer(int buf) {
+ virtual status_t queueBuffer(int buf, int64_t timestamp) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(buf);
+ data.writeInt64(timestamp);
remote()->transact(QUEUE_BUFFER, data, &reply);
status_t result = reply.readInt32();
return result;
@@ -174,7 +175,8 @@
case QUEUE_BUFFER: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int buf = data.readInt32();
- status_t result = queueBuffer(buf);
+ int64_t timestamp = data.readInt64();
+ status_t result = queueBuffer(buf, timestamp);
reply->writeInt32(result);
return NO_ERROR;
} break;
@@ -196,7 +198,6 @@
return NO_ERROR;
} break;
case SET_TRANSFORM: {
- Rect reg;
CHECK_INTERFACE(ISurfaceTexture, data, reply);
uint32_t transform = data.readInt32();
status_t result = setTransform(transform);
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 5c6d71b..cdaca47 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -76,9 +76,15 @@
static void mtxMul(float out[16], const float a[16], const float b[16]);
SurfaceTexture::SurfaceTexture(GLuint tex) :
- mBufferCount(MIN_BUFFER_SLOTS), mCurrentTexture(INVALID_BUFFER_SLOT),
- mCurrentTransform(0), mLastQueued(INVALID_BUFFER_SLOT),
- mLastQueuedTransform(0), mNextTransform(0), mTexName(tex) {
+ mBufferCount(MIN_BUFFER_SLOTS),
+ mCurrentTexture(INVALID_BUFFER_SLOT),
+ mCurrentTransform(0),
+ mCurrentTimestamp(0),
+ mLastQueued(INVALID_BUFFER_SLOT),
+ mLastQueuedTransform(0),
+ mLastQueuedTimestamp(0),
+ mNextTransform(0),
+ mTexName(tex) {
LOGV("SurfaceTexture::SurfaceTexture");
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
@@ -153,7 +159,7 @@
return OK;
}
-status_t SurfaceTexture::queueBuffer(int buf) {
+status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
LOGV("SurfaceTexture::queueBuffer");
Mutex::Autolock lock(mMutex);
if (buf < 0 || mBufferCount <= buf) {
@@ -172,6 +178,7 @@
mLastQueued = buf;
mLastQueuedCrop = mNextCrop;
mLastQueuedTransform = mNextTransform;
+ mLastQueuedTimestamp = timestamp;
if (mFrameAvailableListener != 0) {
mFrameAvailableListener->onFrameAvailable();
}
@@ -246,12 +253,13 @@
mCurrentTextureBuf = mSlots[mCurrentTexture].mGraphicBuffer;
mCurrentCrop = mLastQueuedCrop;
mCurrentTransform = mLastQueuedTransform;
+ mCurrentTimestamp = mLastQueuedTimestamp;
}
return OK;
}
void SurfaceTexture::getTransformMatrix(float mtx[16]) {
- LOGV("SurfaceTexture::updateTexImage");
+ LOGV("SurfaceTexture::getTransformMatrix");
Mutex::Autolock lock(mMutex);
float xform[16];
@@ -342,6 +350,12 @@
mtxMul(mtx, mtxFlipV, mtxBeforeFlipV);
}
+nsecs_t SurfaceTexture::getTimestamp() {
+ LOGV("SurfaceTexture::getTimestamp");
+ Mutex::Autolock lock(mMutex);
+ return mCurrentTimestamp;
+}
+
void SurfaceTexture::setFrameAvailableListener(
const sp<FrameAvailableListener>& l) {
LOGV("SurfaceTexture::setFrameAvailableListener");
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 7f1d9cb..a4812d0 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -26,7 +26,8 @@
SurfaceTextureClient::SurfaceTextureClient(
const sp<ISurfaceTexture>& surfaceTexture):
mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(1),
- mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0), mMutex() {
+ mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0),
+ mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO), mMutex() {
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = setSwapInterval;
ANativeWindow::dequeueBuffer = dequeueBuffer;
@@ -135,9 +136,17 @@
int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
LOGV("SurfaceTextureClient::queueBuffer");
Mutex::Autolock lock(mMutex);
+ int64_t timestamp;
+ if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
+ timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ LOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
+ timestamp / 1000000.f);
+ } else {
+ timestamp = mTimestamp;
+ }
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (mSlots[i]->handle == buffer->handle) {
- return mSurfaceTexture->queueBuffer(i);
+ return mSurfaceTexture->queueBuffer(i, timestamp);
}
}
LOGE("queueBuffer: unknown buffer queued");
@@ -196,6 +205,9 @@
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
res = dispatchSetBuffersTransform(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+ res = dispatchSetBuffersTimestamp(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -240,6 +252,11 @@
return setBuffersTransform(transform);
}
+int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) {
+ int64_t timestamp = va_arg(args, int64_t);
+ return setBuffersTimestamp(timestamp);
+}
+
int SurfaceTextureClient::connect(int api) {
LOGV("SurfaceTextureClient::connect");
// XXX: Implement this!
@@ -323,6 +340,14 @@
return err;
}
+int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
+{
+ LOGV("SurfaceTextureClient::setBuffersTimestamp");
+ Mutex::Autolock lock(mMutex);
+ mTimestamp = timestamp;
+ return NO_ERROR;
+}
+
void SurfaceTextureClient::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i] = 0;
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 21d509a..0dfbf01 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -753,6 +753,9 @@
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
res = dispatch_set_buffers_transform( args );
break;
+ case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+ res = dispatch_set_buffers_timestamp( args );
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -792,6 +795,11 @@
return setBuffersTransform(transform);
}
+int Surface::dispatch_set_buffers_timestamp(va_list args) {
+ int64_t timestamp = va_arg(args, int64_t);
+ return setBuffersTimestamp(timestamp);
+}
+
void Surface::setUsage(uint32_t reqUsage)
{
Mutex::Autolock _l(mSurfaceLock);
@@ -910,6 +918,13 @@
return NO_ERROR;
}
+int Surface::setBuffersTimestamp(int64_t timestamp)
+{
+ // Surface doesn't really have anything meaningful to do with timestamps
+ // so they'll just be dropped here.
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
int Surface::getConnectedApi() const
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 1994f6a..a060a5f 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -56,6 +56,9 @@
Region::Region(const Region& rhs)
: mBounds(rhs.mBounds), mStorage(rhs.mStorage)
{
+#if VALIDATE_REGIONS
+ validate(rhs, "rhs copy-ctor");
+#endif
}
Region::Region(const Rect& rhs)
@@ -76,7 +79,8 @@
Region& Region::operator = (const Region& rhs)
{
#if VALIDATE_REGIONS
- validate(rhs, "operator=");
+ validate(*this, "this->operator=");
+ validate(rhs, "rhs.operator=");
#endif
mBounds = rhs.mBounds;
mStorage = rhs.mStorage;
@@ -366,6 +370,12 @@
const Region& lhs,
const Region& rhs, int dx, int dy)
{
+#if VALIDATE_REGIONS
+ validate(lhs, "boolean_operation (before): lhs");
+ validate(rhs, "boolean_operation (before): rhs");
+ validate(dst, "boolean_operation (before): dst");
+#endif
+
size_t lhs_count;
Rect const * const lhs_rects = lhs.getArray(&lhs_count);
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 7ce86b3..75f7078 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -340,7 +340,10 @@
}
if (gEGLDebugLevel > 0)
- StartDebugServer();
+ {
+ property_get("debug.egl.debug_port", value, "5039");
+ StartDebugServer(atoi(value));
+ }
}
static void setGLHooksThreadSpecific(gl_hooks_t const *value) {
@@ -350,7 +353,6 @@
} else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {
setGlTraceThreadSpecific(value);
setGlThreadSpecific(&gHooksDebug);
- LOGD("\n* setGLHooksThreadSpecific gHooksDebug");
} else {
setGlThreadSpecific(value);
}
@@ -2119,14 +2121,15 @@
if (!validate_display_context(dpy, ctx))
return EGL_FALSE;
+ EGLBoolean result = EGL_FALSE;
egl_context_t * const c = get_context(ctx);
-
if (c->cnx->egl.eglDestroySyncKHR) {
- return c->cnx->egl.eglDestroySyncKHR(
+ result = c->cnx->egl.eglDestroySyncKHR(
dp->disp[c->impl].dpy, syncObject->sync);
+ if (result)
+ _s.terminate();
}
-
- return EGL_FALSE;
+ return result;
}
EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
diff --git a/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py b/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
index b14885b..48a29da 100755
--- a/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
+++ b/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
@@ -98,9 +98,6 @@
output.write(" SETPROP = %d;\n" % (i))
i += 1
- output.write(" CAPTURE = %d;\n" % (i))
- i += 1
-
output.write(""" }
required Function function = 2 [default = NEG]; // type/function of message
enum Type
diff --git a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
index 68514df..5c41825 100644
--- a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
+++ b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
@@ -65,8 +65,9 @@
void DbgContext::glUseProgram(GLuint program)
{
- assert(GL_NO_ERROR == hooks->gl.glGetError());
-
+ while (GLenum error = hooks->gl.glGetError())
+ LOGD("DbgContext::glUseProgram: before glGetError() = 0x%.4X", error);
+
this->program = program;
GLint activeAttributes = 0;
@@ -106,6 +107,9 @@
maxAttrib = slot;
}
delete name;
+
+ while (GLenum error = hooks->gl.glGetError())
+ LOGD("DbgContext::glUseProgram: after glGetError() = 0x%.4X", error);
}
static bool HasNonVBOAttribs(const DbgContext * const ctx)
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp b/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
index 4083c44..1f404c2 100644
--- a/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
+++ b/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
@@ -229,7 +229,6 @@
case 188:
case 189:
case 190:
- case 191:
return true;
default:
return false;
@@ -428,7 +427,6 @@
const Message_Function Message::CONTINUE;
const Message_Function Message::SKIP;
const Message_Function Message::SETPROP;
-const Message_Function Message::CAPTURE;
const Message_Function Message::Function_MIN;
const Message_Function Message::Function_MAX;
const int Message::Function_ARRAYSIZE;
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.h b/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
index 3f2b842..59e7bab 100644
--- a/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
+++ b/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
@@ -226,12 +226,11 @@
Message_Function_NEG = 187,
Message_Function_CONTINUE = 188,
Message_Function_SKIP = 189,
- Message_Function_SETPROP = 190,
- Message_Function_CAPTURE = 191
+ Message_Function_SETPROP = 190
};
bool Message_Function_IsValid(int value);
const Message_Function Message_Function_Function_MIN = Message_Function_glActiveTexture;
-const Message_Function Message_Function_Function_MAX = Message_Function_CAPTURE;
+const Message_Function Message_Function_Function_MAX = Message_Function_SETPROP;
const int Message_Function_Function_ARRAYSIZE = Message_Function_Function_MAX + 1;
enum Message_Type {
@@ -488,7 +487,6 @@
static const Function CONTINUE = Message_Function_CONTINUE;
static const Function SKIP = Message_Function_SKIP;
static const Function SETPROP = Message_Function_SETPROP;
- static const Function CAPTURE = Message_Function_CAPTURE;
static inline bool Function_IsValid(int value) {
return Message_Function_IsValid(value);
}
diff --git a/opengl/libs/GLES2_dbg/src/egl.cpp b/opengl/libs/GLES2_dbg/src/egl.cpp
index b3979a3..27c7f7e 100644
--- a/opengl/libs/GLES2_dbg/src/egl.cpp
+++ b/opengl/libs/GLES2_dbg/src/egl.cpp
@@ -19,7 +19,7 @@
EGLBoolean Debug_eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
glesv2debugger::Message msg;
- const bool expectResponse = true;
+ const bool expectResponse = false;
struct : public FunctionCall {
EGLDisplay dpy;
EGLSurface draw;
diff --git a/opengl/libs/GLES2_dbg/src/header.h b/opengl/libs/GLES2_dbg/src/header.h
index cbd448a..b79cc0f 100644
--- a/opengl/libs/GLES2_dbg/src/header.h
+++ b/opengl/libs/GLES2_dbg/src/header.h
@@ -113,7 +113,7 @@
virtual ~FunctionCall() {}
};
-// move these into DbgContext
+// move these into DbgContext as static
extern bool capture;
extern int timeMode; // SYSTEM_TIME_
@@ -121,8 +121,10 @@
unsigned GetBytesPerPixel(const GLenum format, const GLenum type);
+// every Debug_gl* function calls this to send message to client and possibly receive commands
int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
const bool expectResponse, const glesv2debugger::Message_Function function);
+
void Receive(glesv2debugger::Message & cmd);
float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd);
void SetProp(const glesv2debugger::Message & cmd);
diff --git a/opengl/libs/GLES2_dbg/src/server.cpp b/opengl/libs/GLES2_dbg/src/server.cpp
index 820e9de..03c3dae 100644
--- a/opengl/libs/GLES2_dbg/src/server.cpp
+++ b/opengl/libs/GLES2_dbg/src/server.cpp
@@ -38,7 +38,7 @@
exit(1);
}
-void StartDebugServer()
+void StartDebugServer(unsigned short port)
{
LOGD("GLESv2_dbg: StartDebugServer");
if (serverSock >= 0)
@@ -53,8 +53,8 @@
}
/* Construct the server sockaddr_in structure */
server.sin_family = AF_INET; /* Internet/IP */
- server.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */
- server.sin_port = htons(5039); /* server port */
+ server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Incoming addr */
+ server.sin_port = htons(port); /* server port */
/* Bind the server socket */
socklen_t sizeofSockaddr_in = sizeof(sockaddr_in);
@@ -79,13 +79,6 @@
LOGD("Client connected: %s\n", inet_ntoa(client.sin_addr));
// fcntl(clientSock, F_SETFL, O_NONBLOCK);
-
- glesv2debugger::Message msg, cmd;
- msg.set_context_id(0);
- msg.set_function(glesv2debugger::Message_Function_ACK);
- msg.set_type(glesv2debugger::Message_Type_Response);
- msg.set_expect_response(false);
- Send(msg, cmd);
}
void StopDebugServer()
@@ -130,6 +123,27 @@
cmd.ParseFromArray(buffer, len);
}
+bool TryReceive(glesv2debugger::Message & cmd)
+{
+ fd_set readSet;
+ FD_ZERO(&readSet);
+ FD_SET(clientSock, &readSet);
+ timeval timeout;
+ timeout.tv_sec = timeout.tv_usec = 0;
+
+ int rc = select(clientSock + 1, &readSet, NULL, NULL, &timeout);
+ if (rc < 0)
+ Die("failed to select clientSock");
+
+ bool received = false;
+ if (FD_ISSET(clientSock, &readSet)) {
+ LOGD("TryReceive: avaiable for read");
+ Receive(cmd);
+ return true;
+ }
+ return false;
+}
+
float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
{
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -155,12 +169,18 @@
Die("Failed to send message");
}
+ // try to receive commands even though not expecting response,
+ // since client can send SETPROP commands anytime
if (!msg.expect_response()) {
- pthread_mutex_unlock(&mutex);
- return t;
- }
-
- Receive(cmd);
+ if (TryReceive(cmd)) {
+ LOGD("Send: TryReceived");
+ if (glesv2debugger::Message_Function_SETPROP == cmd.function())
+ LOGD("Send: received SETPROP");
+ else
+ LOGD("Send: received something else");
+ }
+ } else
+ Receive(cmd);
//LOGD("Message sent tid=%lu len=%d", pthread_self(), str.length());
pthread_mutex_unlock(&mutex);
@@ -193,24 +213,26 @@
msg.set_type(glesv2debugger::Message_Type_BeforeCall);
msg.set_expect_response(expectResponse);
msg.set_function(function);
- Send(msg, cmd);
if (!expectResponse)
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ Send(msg, cmd);
while (true) {
msg.Clear();
nsecs_t c0 = systemTime(timeMode);
switch (cmd.function()) {
case glesv2debugger::Message_Function_CONTINUE:
ret = functionCall(&dbg->hooks->gl, msg);
+ while (GLenum error = dbg->hooks->gl.glGetError())
+ LOGD("Function=%u glGetError() = 0x%.4X", function, error);
if (!msg.has_time()) // some has output data copy, so time inside call
msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
msg.set_context_id(reinterpret_cast<int>(dbg));
msg.set_function(function);
msg.set_type(glesv2debugger::Message_Type_AfterCall);
msg.set_expect_response(expectResponse);
- Send(msg, cmd);
if (!expectResponse)
cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ Send(msg, cmd);
break;
case glesv2debugger::Message_Function_SKIP:
return const_cast<int *>(ret);
diff --git a/opengl/libs/GLES2_dbg/src/vertex.cpp b/opengl/libs/GLES2_dbg/src/vertex.cpp
index 52ce907..a73967f 100644
--- a/opengl/libs/GLES2_dbg/src/vertex.cpp
+++ b/opengl/libs/GLES2_dbg/src/vertex.cpp
@@ -41,10 +41,10 @@
msg.set_arg6(reinterpret_cast<int>(pixels));
//void * data = NULL;
//unsigned encodedSize = 0;
- Send(msg, cmd);
- float t = 0;
if (!expectResponse)
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ Send(msg, cmd);
+ float t = 0;
while (true) {
msg.Clear();
nsecs_t c0 = systemTime(timeMode);
@@ -61,6 +61,8 @@
//msg.set_data(data, encodedSize);
//free(data);
c0 = systemTime(timeMode);
+ if (!expectResponse)
+ cmd.set_function(glesv2debugger::Message_Function_SKIP);
t = Send(msg, cmd);
msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
msg.set_clock(t);
@@ -69,11 +71,13 @@
msg.set_expect_response(false);
msg.set_type(glesv2debugger::Message_Type_AfterCall);
//Send(msg, cmd);
- if (!expectResponse)
- cmd.set_function(glesv2debugger::Message_Function_SKIP);
break;
case glesv2debugger::Message_Function_SKIP:
return;
+ case glesv2debugger::Message_Function_SETPROP:
+ SetProp(cmd);
+ Receive(cmd);
+ break;
default:
assert(0); //GenerateCall(msg, cmd);
break;
@@ -104,9 +108,9 @@
void * pixels = NULL;
GLint readFormat = 0, readType = 0;
int viewport[4] = {};
- Send(msg, cmd);
if (!expectResponse)
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ Send(msg, cmd);
while (true) {
msg.Clear();
nsecs_t c0 = systemTime(timeMode);
@@ -118,25 +122,26 @@
msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
msg.set_type(glesv2debugger::Message_Type_AfterCall);
msg.set_expect_response(expectResponse);
- Send(msg, cmd);
- if (capture)
- cmd.set_function(glesv2debugger::Message_Function_CAPTURE);
- else if (!expectResponse)
+ if (!expectResponse)
cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ Send(msg, cmd);
+ if (capture) {
+ dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
+ LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
+ viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
+ pixels = malloc(viewport[2] * viewport[3] * 4);
+ Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
+ readFormat, readType, pixels);
+ free(pixels);
+ }
break;
case glesv2debugger::Message_Function_SKIP:
return;
- case glesv2debugger::Message_Function_CAPTURE:
- dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
- dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
- dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
- LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
- viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
- pixels = malloc(viewport[2] * viewport[3] * 4);
- Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
- readFormat, readType, pixels);
- free(pixels);
- cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ case glesv2debugger::Message_Function_SETPROP:
+ SetProp(cmd);
+ Receive(cmd);
break;
default:
assert(0); //GenerateCall(msg, cmd);
@@ -189,9 +194,9 @@
void * pixels = NULL;
GLint readFormat = 0, readType = 0;
int viewport[4] = {};
- Send(msg, cmd);
if (!expectResponse)
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
+ Send(msg, cmd);
while (true) {
msg.Clear();
nsecs_t c0 = systemTime(timeMode);
@@ -203,25 +208,26 @@
msg.set_function(glesv2debugger::Message_Function_glDrawElements);
msg.set_type(glesv2debugger::Message_Type_AfterCall);
msg.set_expect_response(expectResponse);
- Send(msg, cmd);
- if (capture)
- cmd.set_function(glesv2debugger::Message_Function_CAPTURE);
- else if (!expectResponse)
+ if (!expectResponse)
cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ Send(msg, cmd);
+ if (capture) {
+ dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
+ dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
+ LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
+ viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
+ pixels = malloc(viewport[2] * viewport[3] * 4);
+ Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
+ readFormat, readType, pixels);
+ free(pixels);
+ }
break;
case glesv2debugger::Message_Function_SKIP:
return;
- case glesv2debugger::Message_Function_CAPTURE:
- dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
- dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
- dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
- LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
- viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
- pixels = malloc(viewport[2] * viewport[3] * 4);
- Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
- readFormat, readType, pixels);
- free(pixels);
- cmd.set_function(glesv2debugger::Message_Function_SKIP);
+ case glesv2debugger::Message_Function_SETPROP:
+ SetProp(cmd);
+ Receive(cmd);
break;
default:
assert(0); //GenerateCall(msg, cmd);
diff --git a/opengl/libs/glesv2dbg.h b/opengl/libs/glesv2dbg.h
index b988eb7..8029dce 100644
--- a/opengl/libs/glesv2dbg.h
+++ b/opengl/libs/glesv2dbg.h
@@ -24,7 +24,7 @@
DbgContext * CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks);
void DestroyDbgContext(DbgContext * const dbg);
- void StartDebugServer(); // create and bind socket if haven't already
+ void StartDebugServer(unsigned short port); // create and bind socket if haven't already
void StopDebugServer(); // close socket if open
}; // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 7a69097..c4027e0 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -811,7 +811,7 @@
{ // scope for strong mUserClient reference
sp<UserClient> userClient(mUserClient.promote());
- if (mUserClient != 0 && mControlBlock != 0) {
+ if (userClient != 0 && mControlBlock != 0) {
mControlBlock->setStatus(NO_INIT);
}
}
@@ -860,11 +860,13 @@
Mutex::Autolock _l(mLock);
if (size < mNumBuffers) {
- // Move the active texture into slot 0
- BufferData activeBufferData = mBufferData[mActiveBufferIndex];
- mBufferData[mActiveBufferIndex] = mBufferData[0];
- mBufferData[0] = activeBufferData;
- mActiveBufferIndex = 0;
+ // If there is an active texture, move it into slot 0 if needed
+ if (mActiveBufferIndex > 0) {
+ BufferData activeBufferData = mBufferData[mActiveBufferIndex];
+ mBufferData[mActiveBufferIndex] = mBufferData[0];
+ mBufferData[0] = activeBufferData;
+ mActiveBufferIndex = 0;
+ }
// Free the buffers that are no longer needed.
for (size_t i = size; i < mNumBuffers; i++) {
diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
index 99f4b4f..0ccca77 100644
--- a/services/surfaceflinger/tests/resize/resize.cpp
+++ b/services/surfaceflinger/tests/resize/resize.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#include <cutils/memory.h>
#include <utils/Log.h>
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
index 194fbb6..67ecf7e 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#include <cutils/memory.h>
#include <utils/Log.h>