Reconcile with jb-mr1-factory-release jb-mr1-release - do not merge
Change-Id: I219247f1b0f5d87b4144dc1535039e93fc636a94
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index ef5c2e9..f3fcca0 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -85,6 +85,7 @@
dump_file("ZONEINFO", "/proc/zoneinfo");
dump_file("PAGETYPEINFO", "/proc/pagetypeinfo");
dump_file("BUDDYINFO", "/proc/buddyinfo");
+ dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index");
dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 002aafc..6500ad5 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -69,7 +69,8 @@
/* create a display
* requires ACCESS_SURFACE_FLINGER permission.
*/
- virtual sp<IBinder> createDisplay(const String8& displayName) = 0;
+ virtual sp<IBinder> createDisplay(const String8& displayName,
+ bool secure) = 0;
/* get the token for the existing default displays. possible values
* for id are eDisplayIdMain and eDisplayIdHdmi.
@@ -108,9 +109,6 @@
/* returns information about a display
* intended to be used to get information about built-in displays */
virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0;
-
- /* connects to an external display */
- virtual void connectDisplay(const sp<ISurfaceTexture>& display) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 21d16a9..ae5d69a 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -86,7 +86,7 @@
);
//! Create a display
- static sp<IBinder> createDisplay(const String8& displayName);
+ static sp<IBinder> createDisplay(const String8& displayName, bool secure);
//! Get the token for the existing default displays.
//! Possible values for id are eDisplayIdMain and eDisplayIdHdmi.
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
index c7dc354..c3a4d6b 100644
--- a/include/ui/DisplayInfo.h
+++ b/include/ui/DisplayInfo.h
@@ -32,7 +32,8 @@
float fps;
float density;
uint8_t orientation;
- uint8_t reserved[3];
+ bool secure;
+ uint8_t reserved[2];
// TODO: this needs to go away (currently needed only by webkit)
PixelFormatInfo pixelFormatInfo;
};
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
index e5cc7ec..93e2285 100644
--- a/include/utils/Trace.h
+++ b/include/utils/Trace.h
@@ -67,6 +67,11 @@
// function body.
#define ATRACE_CALL() android::ScopedTrace ___tracer(ATRACE_TAG, __FUNCTION__)
+// ATRACE_NAME traces the beginning and end of the current function. To trace
+// the correct start and end times this macro should be the first line of the
+// function body.
+#define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name)
+
// ATRACE_INT traces a named integer value. This can be used to track how the
// value changes over time in a trace.
#define ATRACE_INT(name, value) android::Tracer::traceCounter(ATRACE_TAG, name, value)
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
index b1224c6..c4ec2ff 100644
--- a/include/utils/VectorImpl.h
+++ b/include/utils/VectorImpl.h
@@ -104,6 +104,16 @@
virtual void do_splat(void* dest, const void* item, size_t num) const = 0;
virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0;
virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0;
+
+ // take care of FBC...
+ virtual void reservedVectorImpl1();
+ virtual void reservedVectorImpl2();
+ virtual void reservedVectorImpl3();
+ virtual void reservedVectorImpl4();
+ virtual void reservedVectorImpl5();
+ virtual void reservedVectorImpl6();
+ virtual void reservedVectorImpl7();
+ virtual void reservedVectorImpl8();
private:
void* _grow(size_t where, size_t amount);
@@ -155,6 +165,16 @@
protected:
virtual int do_compare(const void* lhs, const void* rhs) const = 0;
+ // take care of FBC...
+ virtual void reservedSortedVectorImpl1();
+ virtual void reservedSortedVectorImpl2();
+ virtual void reservedSortedVectorImpl3();
+ virtual void reservedSortedVectorImpl4();
+ virtual void reservedSortedVectorImpl5();
+ virtual void reservedSortedVectorImpl6();
+ virtual void reservedSortedVectorImpl7();
+ virtual void reservedSortedVectorImpl8();
+
private:
ssize_t _indexOrderOf(const void* item, size_t* order = 0) const;
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index d408476..590946a 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -385,18 +385,8 @@
(uint32_t(buffer->format) != format) ||
((uint32_t(buffer->usage) & usage) != usage))
{
- status_t error;
- sp<GraphicBuffer> graphicBuffer(
- mGraphicBufferAlloc->createGraphicBuffer(
- w, h, format, usage, &error));
- if (graphicBuffer == 0) {
- ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
- "failed");
- return error;
- }
-
mSlots[buf].mAcquireCalled = false;
- mSlots[buf].mGraphicBuffer = graphicBuffer;
+ mSlots[buf].mGraphicBuffer = NULL;
mSlots[buf].mRequestBufferCalled = false;
mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
mSlots[buf].mFence.clear();
@@ -412,6 +402,30 @@
mSlots[buf].mFence.clear();
} // end lock scope
+ if (returnFlags & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) {
+ status_t error;
+ sp<GraphicBuffer> graphicBuffer(
+ mGraphicBufferAlloc->createGraphicBuffer(
+ w, h, format, usage, &error));
+ if (graphicBuffer == 0) {
+ ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
+ "failed");
+ return error;
+ }
+
+ { // Scope for the lock
+ Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
+ mSlots[*outBuf].mGraphicBuffer = graphicBuffer;
+ }
+ }
+
+
if (eglFence != EGL_NO_SYNC_KHR) {
EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
// If something goes wrong, log the error, but return the buffer without
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index aff1b45..85a9488 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -179,11 +179,12 @@
return result;
}
- virtual sp<IBinder> createDisplay(const String8& displayName)
+ virtual sp<IBinder> createDisplay(const String8& displayName, bool secure)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeString8(displayName);
+ data.writeInt32(secure ? 1 : 0);
remote()->transact(BnSurfaceComposer::CREATE_DISPLAY, data, &reply);
return reply.readStrongBinder();
}
@@ -222,14 +223,6 @@
memcpy(info, reply.readInplace(sizeof(DisplayInfo)), sizeof(DisplayInfo));
return reply.readInt32();
}
-
-
- virtual void connectDisplay(const sp<ISurfaceTexture>& display) {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display->asBinder());
- remote()->transact(BnSurfaceComposer::CONNECT_DISPLAY, data, &reply);
- }
};
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -309,7 +302,8 @@
case CREATE_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
String8 displayName = data.readString8();
- sp<IBinder> display(createDisplay(displayName));
+ bool secure = bool(data.readInt32());
+ sp<IBinder> display(createDisplay(displayName, secure));
reply->writeStrongBinder(display);
return NO_ERROR;
} break;
@@ -338,12 +332,6 @@
memcpy(reply->writeInplace(sizeof(DisplayInfo)), &info, sizeof(DisplayInfo));
reply->writeInt32(result);
} break;
- case CONNECT_DISPLAY: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<ISurfaceTexture> surfaceTexture =
- interface_cast<ISurfaceTexture>(data.readStrongBinder());
- connectDisplay(surfaceTexture);
- } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 8586ed2..80dd6ee 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -131,7 +131,7 @@
DisplayState& getDisplayStateLocked(const sp<IBinder>& token);
public:
- sp<IBinder> createDisplay(const String8& displayName);
+ sp<IBinder> createDisplay(const String8& displayName, bool secure);
sp<IBinder> getBuiltInDisplay(int32_t id);
status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
@@ -175,8 +175,9 @@
// ---------------------------------------------------------------------------
-sp<IBinder> Composer::createDisplay(const String8& displayName) {
- return ComposerService::getComposerService()->createDisplay(displayName);
+sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) {
+ return ComposerService::getComposerService()->createDisplay(displayName,
+ secure);
}
sp<IBinder> Composer::getBuiltInDisplay(int32_t id) {
@@ -459,8 +460,9 @@
return result;
}
-sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName) {
- return Composer::getInstance().createDisplay(displayName);
+sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName,
+ bool secure) {
+ return Composer::getInstance().createDisplay(displayName, secure);
}
sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index 8083bba..c3257bb 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -494,6 +494,15 @@
do_move_backward(dest, from, num);
}
+void VectorImpl::reservedVectorImpl1() { }
+void VectorImpl::reservedVectorImpl2() { }
+void VectorImpl::reservedVectorImpl3() { }
+void VectorImpl::reservedVectorImpl4() { }
+void VectorImpl::reservedVectorImpl5() { }
+void VectorImpl::reservedVectorImpl6() { }
+void VectorImpl::reservedVectorImpl7() { }
+void VectorImpl::reservedVectorImpl8() { }
+
/*****************************************************************************/
SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)
@@ -609,6 +618,16 @@
return i;
}
+void SortedVectorImpl::reservedSortedVectorImpl1() { };
+void SortedVectorImpl::reservedSortedVectorImpl2() { };
+void SortedVectorImpl::reservedSortedVectorImpl3() { };
+void SortedVectorImpl::reservedSortedVectorImpl4() { };
+void SortedVectorImpl::reservedSortedVectorImpl5() { };
+void SortedVectorImpl::reservedSortedVectorImpl6() { };
+void SortedVectorImpl::reservedSortedVectorImpl7() { };
+void SortedVectorImpl::reservedSortedVectorImpl8() { };
+
+
/*****************************************************************************/
}; // namespace android
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 7ca210c..96e1cba 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -62,12 +62,18 @@
// ----------------------------------------------------------------------------
/**
- * There are two different tracing methods:
- * 1. libs/EGL/trace.cpp: Traces all functions to logcat.
+ * There are three different tracing methods:
+ * 1. libs/EGL/trace.cpp: Traces all functions to systrace.
+ * To enable:
+ * - set system property "debug.egl.trace" to "systrace" to trace all apps.
+ * 2. libs/EGL/trace.cpp: Logs a stack trace for GL errors after each function call.
+ * To enable:
+ * - set system property "debug.egl.trace" to "error" to trace all apps.
+ * 3. libs/EGL/trace.cpp: Traces all functions to logcat.
* To enable:
* - set system property "debug.egl.trace" to 1 to trace all apps.
* - or call setGLTraceLevel(1) from an app to enable tracing for that app.
- * 2. libs/GLES_trace: Traces all functions via protobuf to host.
+ * 4. libs/GLES_trace: Traces all functions via protobuf to host.
* To enable:
* - set system property "debug.egl.debug_proc" to the application name.
* - or call setGLDebugLevel(1) from the app.
@@ -75,10 +81,15 @@
static int sEGLTraceLevel;
static int sEGLApplicationTraceLevel;
+static bool sEGLSystraceEnabled;
+static bool sEGLGetErrorEnabled;
+
int gEGLDebugLevel;
static int sEGLApplicationDebugLevel;
extern gl_hooks_t gHooksTrace;
+extern gl_hooks_t gHooksSystrace;
+extern gl_hooks_t gHooksErrorTrace;
static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
pthread_setspecific(gGLTraceKey, value);
@@ -91,6 +102,20 @@
void initEglTraceLevel() {
char value[PROPERTY_VALUE_MAX];
property_get("debug.egl.trace", value, "0");
+
+ sEGLGetErrorEnabled = !strcasecmp(value, "error");
+ if (sEGLGetErrorEnabled) {
+ sEGLSystraceEnabled = false;
+ sEGLTraceLevel = 0;
+ return;
+ }
+
+ sEGLSystraceEnabled = !strcasecmp(value, "systrace");
+ if (sEGLSystraceEnabled) {
+ sEGLTraceLevel = 0;
+ return;
+ }
+
int propertyLevel = atoi(value);
int applicationLevel = sEGLApplicationTraceLevel;
sEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel;
@@ -125,7 +150,13 @@
}
void setGLHooksThreadSpecific(gl_hooks_t const *value) {
- if (sEGLTraceLevel > 0) {
+ if (sEGLGetErrorEnabled) {
+ setGlTraceThreadSpecific(value);
+ setGlThreadSpecific(&gHooksErrorTrace);
+ } else if (sEGLSystraceEnabled) {
+ setGlTraceThreadSpecific(value);
+ setGlThreadSpecific(&gHooksSystrace);
+ } else if (sEGLTraceLevel > 0) {
setGlTraceThreadSpecific(value);
setGlThreadSpecific(&gHooksTrace);
} else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 92023ba..23e89da 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -204,6 +204,59 @@
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso) {
+ if (attrib_list) {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.egl.force_msaa", value, "false");
+
+ if (!strcmp(value, "true")) {
+ size_t attribCount = 0;
+ EGLint attrib = attrib_list[0];
+
+ // Only enable MSAA if the context is OpenGL ES 2.0 and
+ // if no caveat is requested
+ const EGLint *attribRendererable = NULL;
+ const EGLint *attribCaveat = NULL;
+
+ // Count the number of attributes and look for
+ // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
+ while (attrib != EGL_NONE) {
+ attrib = attrib_list[attribCount];
+ switch (attrib) {
+ case EGL_RENDERABLE_TYPE:
+ attribRendererable = &attrib_list[attribCount];
+ break;
+ case EGL_CONFIG_CAVEAT:
+ attribCaveat = &attrib_list[attribCount];
+ break;
+ }
+ attribCount++;
+ }
+
+ if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
+ (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
+
+ // Insert 2 extra attributes to force-enable MSAA 4x
+ EGLint aaAttribs[attribCount + 4];
+ aaAttribs[0] = EGL_SAMPLE_BUFFERS;
+ aaAttribs[1] = 1;
+ aaAttribs[2] = EGL_SAMPLES;
+ aaAttribs[3] = 4;
+
+ memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
+
+ EGLint numConfigAA;
+ EGLBoolean resAA = cnx->egl.eglChooseConfig(
+ dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
+
+ if (resAA == EGL_TRUE && numConfigAA > 0) {
+ ALOGD("Enabling MSAA 4x");
+ *num_config = numConfigAA;
+ return resAA;
+ }
+ }
+ }
+ }
+
res = cnx->egl.eglChooseConfig(
dp->disp.dpy, attrib_list, configs, config_size, num_config);
}
diff --git a/opengl/libs/EGL/trace.cpp b/opengl/libs/EGL/trace.cpp
index 52907c1..a51b086 100644
--- a/opengl/libs/EGL/trace.cpp
+++ b/opengl/libs/EGL/trace.cpp
@@ -26,6 +26,11 @@
#include <cutils/log.h>
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <utils/Trace.h>
+
+#include <utils/CallStack.h>
+
#include "egl_tls.h"
#include "hooks.h"
@@ -314,6 +319,10 @@
va_end(argp);
}
+///////////////////////////////////////////////////////////////////////////
+// Log trace
+///////////////////////////////////////////////////////////////////////////
+
#undef TRACE_GL_VOID
#undef TRACE_GL
@@ -349,7 +358,6 @@
};
#undef GL_ENTRY
-
#undef TRACE_GL_VOID
#undef TRACE_GL
@@ -372,6 +380,99 @@
#include "../debug.in"
}
+///////////////////////////////////////////////////////////////////////////
+// Systrace
+///////////////////////////////////////////////////////////////////////////
+
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+#define TRACE_GL_VOID(_api, _args, _argList, ...) \
+static void Systrace_ ## _api _args { \
+ ATRACE_NAME(#_api); \
+ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
+ _c->_api _argList; \
+}
+
+#define TRACE_GL(_type, _api, _args, _argList, ...) \
+static _type Systrace_ ## _api _args { \
+ ATRACE_NAME(#_api); \
+ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
+ return _c->_api _argList; \
+}
+
+extern "C" {
+#include "../trace.in"
+}
+
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+#define GL_ENTRY(_r, _api, ...) Systrace_ ## _api,
+EGLAPI gl_hooks_t gHooksSystrace = {
+ {
+ #include "entries.in"
+ },
+ {
+ {0}
+ }
+};
+#undef GL_ENTRY
+
+///////////////////////////////////////////////////////////////////////////
+//
+///////////////////////////////////////////////////////////////////////////
+
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+#define CHECK_ERROR(_c, _api) \
+ GLenum status = GL_NO_ERROR; \
+ bool error = false; \
+ while ((status = _c->glGetError()) != GL_NO_ERROR) { \
+ ALOGD("[" #_api "] 0x%x", status); \
+ error = true; \
+ } \
+ if (error) { \
+ CallStack s; \
+ s.update(); \
+ s.dump("glGetError:" #_api); \
+ } \
+
+#define TRACE_GL_VOID(_api, _args, _argList, ...) \
+static void ErrorTrace_ ## _api _args { \
+ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
+ _c->_api _argList; \
+ CHECK_ERROR(_c, _api); \
+}
+
+#define TRACE_GL(_type, _api, _args, _argList, ...) \
+static _type ErrorTrace_ ## _api _args { \
+ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
+ _type _r = _c->_api _argList; \
+ CHECK_ERROR(_c, _api); \
+ return _r; \
+}
+
+extern "C" {
+#include "../trace.in"
+}
+
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+#define GL_ENTRY(_r, _api, ...) ErrorTrace_ ## _api,
+EGLAPI gl_hooks_t gHooksErrorTrace = {
+ {
+ #include "entries.in"
+ },
+ {
+ {0}
+ }
+};
+#undef GL_ENTRY
+#undef CHECK_ERROR
+
#undef TRACE_GL_VOID
#undef TRACE_GL
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 2d0045e..55ef499 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -26,11 +26,6 @@
#include <cutils/log.h>
#include <cutils/properties.h>
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
-
-#include <utils/CallStack.h>
-
#include "hooks.h"
#include "egl_impl.h"
@@ -44,10 +39,6 @@
#undef CALL_GL_API
#undef CALL_GL_API_RETURN
-#define DEBUG_CALL_GL_API 0
-#define DEBUG_PRINT_CALL_STACK_ON_ERROR 0
-#define SYSTRACE_CALL_GL_API 0
-
#if USE_FAST_TLS_KEY
#ifdef HAVE_ARM_TLS_REGISTER
@@ -83,38 +74,10 @@
#define API_ENTRY(_api) _api
-#if DEBUG_CALL_GL_API
-
- #define CALL_GL_API(_api, ...) \
- gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
- _c->_api(__VA_ARGS__); \
- GLenum status = GL_NO_ERROR; \
- bool error = false; \
- while ((status = glGetError()) != GL_NO_ERROR) { \
- ALOGD("[" #_api "] 0x%x", status); \
- error = true; \
- } \
- if (DEBUG_PRINT_CALL_STACK_ON_ERROR && error) { \
- CallStack s; \
- s.update(); \
- s.dump("glGetError:" #_api); \
- }
-
-#elif SYSTRACE_CALL_GL_API
-
- #define CALL_GL_API(_api, ...) \
- ATRACE_CALL(); \
- gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
- _c->_api(__VA_ARGS__);
-
-#else
-
#define CALL_GL_API(_api, ...) \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
_c->_api(__VA_ARGS__);
-#endif
-
#define CALL_GL_API_RETURN(_api, ...) \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
return _c->_api(__VA_ARGS__)
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 40631ee..ce98b67 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -69,7 +69,9 @@
DisplayDevice::DisplayDevice(
const sp<SurfaceFlinger>& flinger,
- DisplayType type, const wp<IBinder>& displayToken,
+ DisplayType type,
+ bool isSecure,
+ const wp<IBinder>& displayToken,
const sp<ANativeWindow>& nativeWindow,
const sp<FramebufferSurface>& framebufferSurface,
EGLConfig config)
@@ -83,6 +85,7 @@
mDisplayWidth(), mDisplayHeight(), mFormat(),
mFlags(),
mPageFlipCount(),
+ mIsSecure(isSecure),
mSecureLayerVisible(false),
mScreenAcquired(false),
mLayerStack(0),
@@ -431,13 +434,13 @@
snprintf(buffer, SIZE,
"+ DisplayDevice: %s\n"
" type=%x, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
- "flips=%u, secure=%d, acquired=%d, numLayers=%u\n"
+ "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], "
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
mDisplayName.string(), mType,
mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
mOrientation, tr.getType(), getPageFlipCount(),
- mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
+ mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
tr[0][0], tr[1][0], tr[2][0],
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 058680b..d6da422 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -67,7 +67,9 @@
DisplayDevice(
const sp<SurfaceFlinger>& flinger,
- DisplayType type, const wp<IBinder>& displayToken,
+ DisplayType type,
+ bool isSecure,
+ const wp<IBinder>& displayToken,
const sp<ANativeWindow>& nativeWindow,
const sp<FramebufferSurface>& framebufferSurface,
EGLConfig config);
@@ -78,6 +80,10 @@
// when an non existing id is requested
bool isValid() const;
+ // isSecure indicates whether this display can be trusted to display
+ // secure surfaces.
+ bool isSecure() const { return mIsSecure; }
+
// Flip the front and back buffers if the back buffer is "dirty". Might
// be instantaneous, might involve copying the frame buffer around.
void flip(const Region& dirty) const;
@@ -167,6 +173,7 @@
uint32_t mFlags;
mutable uint32_t mPageFlipCount;
String8 mDisplayName;
+ bool mIsSecure;
/*
* Can only accessed from the main thread, these members
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index d9bda11..31d731e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -128,6 +128,11 @@
abort();
}
+ // these display IDs are always reserved
+ for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
+ mAllocatedDisplayIDs.markBit(i);
+ }
+
if (mHwc) {
ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
(hwcApiVersion(mHwc) >> 24) & 0xff,
@@ -149,11 +154,6 @@
// always turn vsync off when we start
eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
- // these IDs are always reserved
- for (size_t i=0 ; i<HWC_NUM_DISPLAY_TYPES ; i++) {
- mAllocatedDisplayIDs.markBit(i);
- }
-
// the number of displays we actually have depends on the
// hw composer version
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
@@ -445,6 +445,13 @@
void HWComposer::eventControl(int disp, int event, int enabled) {
if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) {
+ ALOGD("eventControl ignoring event %d on unallocated disp %d (en=%d)",
+ event, disp, enabled);
+ return;
+ }
+ if (event != EVENT_VSYNC) {
+ ALOGW("eventControl got unexpected event %d (disp=%d en=%d)",
+ event, disp, enabled);
return;
}
status_t err = NO_ERROR;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c2da238..064f689 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -253,6 +253,10 @@
layer.setSkip(true);
}
+ if (isSecure() && !hw->isSecure()) {
+ layer.setSkip(true);
+ }
+
/*
* Transformations are applied in this order:
* 1) buffer orientation/flip/mirror
@@ -342,7 +346,9 @@
// is probably going to have something visibly wrong.
}
- if (!isProtected()) {
+ bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
+
+ if (!blackOutLayer) {
// TODO: we could be more subtle with isFixedSize()
const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index 0fd744f..f8009b3 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -37,7 +37,7 @@
LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
const sp<Client>& client)
: LayerBaseClient(flinger, client),
- mTextureName(0), mFlinger(flinger)
+ mTextureName(0), mFlinger(flinger), mIsSecure(false)
{
}
@@ -56,6 +56,10 @@
return result;
}
initTexture(u, v);
+
+ // Currently screenshot always comes from the default display
+ mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
+
return NO_ERROR;
}
@@ -66,6 +70,10 @@
return result;
}
initTexture(u, v);
+
+ // Currently screenshot always comes from the default display
+ mIsSecure = mFlinger->getDefaultDisplayDevice()->getSecureLayerVisible();
+
return NO_ERROR;
}
@@ -84,6 +92,10 @@
if (!(flags & ISurfaceComposerClient::eHidden)) {
capture();
}
+ if (flags & ISurfaceComposerClient::eSecure) {
+ ALOGW("ignoring surface flag eSecure - LayerScreenshot is considered "
+ "secure iff it captures the contents of a secure surface.");
+ }
}
uint32_t LayerScreenshot::doTransaction(uint32_t flags)
@@ -125,6 +137,11 @@
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
+ GLuint texName = mTextureName;
+ if (isSecure() && !hw->isSecure()) {
+ texName = mFlinger->getProtectedTexName();
+ }
+
LayerMesh mesh;
computeGeometry(hw, &mesh);
@@ -133,7 +150,7 @@
glDisable(GL_TEXTURE_EXTERNAL_OES);
glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, mTextureName);
+ glBindTexture(GL_TEXTURE_2D, texName);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
index 7807ffc..38cbd88 100644
--- a/services/surfaceflinger/LayerScreenshot.h
+++ b/services/surfaceflinger/LayerScreenshot.h
@@ -34,6 +34,7 @@
GLuint mTextureName;
GLfloat mTexCoords[8];
sp<SurfaceFlinger> mFlinger;
+ bool mIsSecure;
public:
LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
virtual ~LayerScreenshot();
@@ -44,7 +45,7 @@
virtual uint32_t doTransaction(uint32_t flags);
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
virtual bool isOpaque() const { return false; }
- virtual bool isSecure() const { return false; }
+ virtual bool isSecure() const { return mIsSecure; }
virtual bool isProtectedByApp() const { return false; }
virtual bool isProtectedByDRM() const { return false; }
virtual const char* getTypeId() const { return "LayerScreenshot"; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e21e2bf..ce10c78 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,7 +163,8 @@
return bclient;
}
-sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName)
+sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
+ bool secure)
{
class DisplayToken : public BBinder {
sp<SurfaceFlinger> flinger;
@@ -184,6 +185,7 @@
Mutex::Autolock _l(mStateLock);
DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
info.displayName = displayName;
+ info.isSecure = secure;
mCurrentState.displays.add(token, info);
return token;
@@ -485,12 +487,14 @@
// set-up the displays that are already connected
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
+ // All non-virtual displays are currently considered secure.
+ bool isSecure = true;
mCurrentState.displays.add(token, DisplayDeviceState(type));
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i);
sp<SurfaceTextureClient> stc = new SurfaceTextureClient(
static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
sp<DisplayDevice> hw = new DisplayDevice(this,
- type, token, stc, fbs, mEGLConfig);
+ type, isSecure, token, stc, fbs, mEGLConfig);
if (i > DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't get blank/unblank requests
// for displays other than the main display, so we always
@@ -507,7 +511,7 @@
// or when a texture is (asynchronously) destroyed, and for that
// we need a valid surface, so it's convenient to use the main display
// for that.
- sp<const DisplayDevice> hw = getDefaultDisplayDevice();
+ sp<const DisplayDevice> hw(getDefaultDisplayDevice());
// initialize OpenGL ES
DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
@@ -666,6 +670,10 @@
info->xdpi = xdpi;
info->ydpi = ydpi;
info->fps = float(1e9 / hwc.getRefreshPeriod(type));
+
+ // All non-virtual displays are currently considered secure.
+ info->secure = true;
+
return NO_ERROR;
}
@@ -675,34 +683,6 @@
return mEventThread->createEventConnection();
}
-void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) {
-
- sp<IBinder> token;
- { // scope for the lock
- Mutex::Autolock _l(mStateLock);
- token = mExtDisplayToken;
- }
-
- if (token == 0) {
- token = createDisplay(String8("Display from connectDisplay"));
- }
-
- { // scope for the lock
- Mutex::Autolock _l(mStateLock);
- if (surface == 0) {
- // release our current display. we're guarantee to have
- // a reference to it (token), while we hold the lock
- mExtDisplayToken = 0;
- } else {
- mExtDisplayToken = token;
- }
-
- DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
- info.surface = surface;
- setTransactionFlags(eDisplayTransactionNeeded);
- }
-}
-
// ----------------------------------------------------------------------------
void SurfaceFlinger::waitForEvent() {
@@ -998,10 +978,10 @@
if (hw->canDraw()) {
// transform the dirty region into this screen's coordinate space
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
- if (!dirtyRegion.isEmpty()) {
- // repaint the framebuffer (if needed)
- doDisplayComposition(hw, dirtyRegion);
- }
+
+ // repaint the framebuffer (if needed)
+ doDisplayComposition(hw, dirtyRegion);
+
hw->dirtyRegion.clear();
hw->flip(hw->swapRegion);
hw->swapRegion.clear();
@@ -1126,7 +1106,7 @@
// Call makeCurrent() on the primary display so we can
// be sure that nothing associated with this display
// is current.
- const sp<const DisplayDevice>& hw(getDefaultDisplayDevice());
+ const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
mDisplays.removeItem(draw.keyAt(i));
getHwComposer().disconnectDisplay(draw[i].type);
@@ -1150,7 +1130,7 @@
continue;
}
- const sp<DisplayDevice>& disp(getDisplayDevice(display));
+ const sp<DisplayDevice> disp(getDisplayDevice(display));
if (disp != NULL) {
if (state.layerStack != draw[i].layerStack) {
disp->setLayerStack(state.layerStack);
@@ -1183,6 +1163,7 @@
for (size_t i=0 ; i<cc ; i++) {
if (draw.indexOfKey(curr.keyAt(i)) < 0) {
const DisplayDeviceState& state(curr[i]);
+ bool isSecure = false;
sp<FramebufferSurface> fbs;
sp<SurfaceTextureClient> stc;
@@ -1193,21 +1174,28 @@
"surface is provided (%p), ignoring it",
state.surface.get());
+ // All non-virtual displays are currently considered
+ // secure.
+ isSecure = true;
+
// for supported (by hwc) displays we provide our
// own rendering surface
fbs = new FramebufferSurface(*mHwc, state.type);
stc = new SurfaceTextureClient(
- static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
+ static_cast< sp<ISurfaceTexture> >(
+ fbs->getBufferQueue()));
} else {
if (state.surface != NULL) {
stc = new SurfaceTextureClient(state.surface);
}
+ isSecure = state.isSecure;
}
const wp<IBinder>& display(curr.keyAt(i));
if (stc != NULL) {
sp<DisplayDevice> hw = new DisplayDevice(this,
- state.type, display, stc, fbs, mEGLConfig);
+ state.type, isSecure, display, stc, fbs,
+ mEGLConfig);
hw->setLayerStack(state.layerStack);
hw->setProjection(state.orientation,
state.viewport, state.frame);
@@ -1512,6 +1500,28 @@
drawWormhole(hw, region);
}
}
+
+ if (hw->getDisplayType() >= DisplayDevice::DISPLAY_EXTERNAL) {
+ // TODO: just to be on the safe side, we don't set the
+ // scissor on the main display. It should never be needed
+ // anyways (though in theory it could since the API allows it).
+ const Rect& bounds(hw->getBounds());
+ const Transform& tr(hw->getTransform());
+ const Rect scissor(tr.transform(hw->getViewport()));
+ if (scissor != bounds) {
+ // scissor doesn't match the screen's dimensions, so we
+ // need to clear everything outside of it and enable
+ // the GL scissor so we don't draw anything where we shouldn't
+ const GLint height = hw->getHeight();
+ glScissor(scissor.left, height - scissor.bottom,
+ scissor.getWidth(), scissor.getHeight());
+ // clear everything unscissored
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ // enable scissor for this frame
+ glEnable(GL_SCISSOR_TEST);
+ }
+ }
}
/*
@@ -1564,6 +1574,9 @@
}
}
}
+
+ // disable scissor at the end of the frame
+ glDisable(GL_SCISSOR_TEST);
}
void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
@@ -1664,6 +1677,7 @@
const Vector<DisplayState>& displays,
uint32_t flags)
{
+ ATRACE_CALL();
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags = 0;
@@ -1671,11 +1685,12 @@
// For window updates that are part of an animation we must wait for
// previous animation "frames" to be handled.
while (mAnimTransactionPending) {
- status_t err = mTransactionCV.waitRelative(mStateLock, 500 * 1000);
+ status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the
- // caller after a few hundred microseconds.
- ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
+ // caller after a few seconds.
+ ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
+ "waiting for previous animation frame");
mAnimTransactionPending = false;
break;
}
@@ -1691,8 +1706,23 @@
count = state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
- sp<Client> client( static_cast<Client *>(s.client.get()) );
- transactionFlags |= setClientStateLocked(client, s.state);
+ // Here we need to check that the interface we're given is indeed
+ // one of our own. A malicious client could give us a NULL
+ // IInterface, or one of its own or even one of our own but a
+ // different type. All these situations would cause us to crash.
+ //
+ // NOTE: it would be better to use RTTI as we could directly check
+ // that we have a Client*. however, RTTI is disabled in Android.
+ if (s.client != NULL) {
+ sp<IBinder> binder = s.client->asBinder();
+ if (binder != NULL) {
+ String16 desc(binder->getInterfaceDescriptor());
+ if (desc == ISurfaceComposerClient::descriptor) {
+ sp<Client> client( static_cast<Client *>(s.client.get()) );
+ transactionFlags |= setClientStateLocked(client, s.state);
+ }
+ }
+ }
}
if (transactionFlags) {
@@ -2043,48 +2073,48 @@
void SurfaceFlinger::unblank(const sp<IBinder>& display) {
class MessageScreenAcquired : public MessageBase {
- SurfaceFlinger* mFlinger;
- const sp<DisplayDevice>& mHw;
+ SurfaceFlinger& mFlinger;
+ sp<IBinder> mDisplay;
public:
- MessageScreenAcquired(SurfaceFlinger* flinger,
- const sp<DisplayDevice>& hw) : mFlinger(flinger), mHw(hw) { }
+ MessageScreenAcquired(SurfaceFlinger& flinger,
+ const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
virtual bool handler() {
- mFlinger->onScreenAcquired(mHw);
+ const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
+ if (hw == NULL) {
+ ALOGE("Attempt to unblank null display %p", mDisplay.get());
+ } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
+ ALOGW("Attempt to unblank virtual display");
+ } else {
+ mFlinger.onScreenAcquired(hw);
+ }
return true;
}
};
- const sp<DisplayDevice>& hw = getDisplayDevice(display);
- if (hw == NULL) {
- ALOGE("Attempt to unblank null display %p", display.get());
- } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
- ALOGW("Attempt to unblank virtual display");
- } else {
- sp<MessageBase> msg = new MessageScreenAcquired(this, hw);
- postMessageSync(msg);
- }
+ sp<MessageBase> msg = new MessageScreenAcquired(*this, display);
+ postMessageSync(msg);
}
void SurfaceFlinger::blank(const sp<IBinder>& display) {
class MessageScreenReleased : public MessageBase {
- SurfaceFlinger* mFlinger;
- const sp<DisplayDevice>& mHw;
+ SurfaceFlinger& mFlinger;
+ sp<IBinder> mDisplay;
public:
- MessageScreenReleased(SurfaceFlinger* flinger,
- const sp<DisplayDevice>& hw) : mFlinger(flinger), mHw(hw) { }
+ MessageScreenReleased(SurfaceFlinger& flinger,
+ const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
virtual bool handler() {
- mFlinger->onScreenReleased(mHw);
+ const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
+ if (hw == NULL) {
+ ALOGE("Attempt to blank null display %p", mDisplay.get());
+ } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
+ ALOGW("Attempt to blank virtual display");
+ } else {
+ mFlinger.onScreenReleased(hw);
+ }
return true;
}
};
- const sp<DisplayDevice>& hw = getDisplayDevice(display);
- if (hw == NULL) {
- ALOGE("Attempt to blank null display %p", display.get());
- } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
- ALOGW("Attempt to blank virtual display");
- } else {
- sp<MessageBase> msg = new MessageScreenReleased(this, hw);
- postMessageSync(msg);
- }
+ sp<MessageBase> msg = new MessageScreenReleased(*this, display);
+ postMessageSync(msg);
}
// ---------------------------------------------------------------------------
@@ -2359,6 +2389,7 @@
const Vector< sp<LayerBase> >&
SurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) {
+ // Note: mStateLock is held here
return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ();
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index efe34af..b0d3bac 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -140,6 +140,7 @@
friend class LayerBase;
friend class LayerBaseClient;
friend class Layer;
+ friend class LayerScreenshot;
// We're reference counted, never destroy SurfaceFlinger directly
virtual ~SurfaceFlinger();
@@ -168,6 +169,7 @@
Rect frame;
uint8_t orientation;
String8 displayName;
+ bool isSecure;
};
struct State {
@@ -187,7 +189,7 @@
*/
virtual sp<ISurfaceComposerClient> createConnection();
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
- virtual sp<IBinder> createDisplay(const String8& displayName);
+ virtual sp<IBinder> createDisplay(const String8& displayName, bool secure);
virtual sp<IBinder> getBuiltInDisplay(int32_t id);
virtual void setTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags);
@@ -204,7 +206,6 @@
// called when screen is turning back on
virtual void unblank(const sp<IBinder>& display);
virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
- virtual void connectDisplay(const sp<ISurfaceTexture>& display);
/* ------------------------------------------------------------------------
* DeathRecipient interface
@@ -327,10 +328,13 @@
// called when starting, or restarting after system_server death
void initializeDisplays();
+ // NOTE: can only be called from the main thread or with mStateLock held
sp<const DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) const {
return mDisplays.valueFor(dpy);
}
- const sp<DisplayDevice>& getDisplayDevice(const wp<IBinder>& dpy) {
+
+ // NOTE: can only be called from the main thread or with mStateLock held
+ sp<DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) {
return mDisplays.valueFor(dpy);
}
@@ -425,6 +429,9 @@
State mDrawingState;
bool mVisibleRegionsDirty;
bool mHwWorkListDirty;
+
+ // this may only be written from the main thread with mStateLock held
+ // it may be read from other threads with mStateLock held
DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;
// don't use a lock for these, we don't care