summaryrefslogtreecommitdiffstats
path: root/libs/hwui/renderthread
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2014-10-31 23:30:57 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-10-31 23:30:57 +0000
commit9481684560b2815d2706512086bb36467ef6acc0 (patch)
treee6258e3075f56533df3ec11cf1443a0d1882b17d /libs/hwui/renderthread
parentbc622ed7c3f9ead17c8aede3ccc10babf0b8e0fa (diff)
parente05575e9c36850d8cfe49396ac9a1372511b12bf (diff)
downloadframeworks_base-9481684560b2815d2706512086bb36467ef6acc0.zip
frameworks_base-9481684560b2815d2706512086bb36467ef6acc0.tar.gz
frameworks_base-9481684560b2815d2706512086bb36467ef6acc0.tar.bz2
am e05575e9: am a8d83d63: Merge "Layer changes" into lmp-mr1-dev automerge: a51fba0
* commit 'e05575e9c36850d8cfe49396ac9a1372511b12bf': Layer changes
Diffstat (limited to 'libs/hwui/renderthread')
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp2
-rw-r--r--libs/hwui/renderthread/EglManager.cpp19
-rw-r--r--libs/hwui/renderthread/EglManager.h7
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp42
-rw-r--r--libs/hwui/renderthread/RenderProxy.h4
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp2
6 files changed, 52 insertions, 24 deletions
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9d2ae8b..b499dd0 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -236,6 +236,8 @@ void CanvasContext::draw() {
if (status & DrawGlInfo::kStatusDrew) {
swapBuffers();
+ } else {
+ mEglManager.cancelFrame();
}
profiler().finishFrame();
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 4f79ba7..e49863d 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -74,7 +74,8 @@ EglManager::EglManager(RenderThread& thread)
, mAllowPreserveBuffer(load_dirty_regions_property())
, mCurrentSurface(EGL_NO_SURFACE)
, mAtlasMap(NULL)
- , mAtlasMapSize(0) {
+ , mAtlasMapSize(0)
+ , mInFrame(false) {
mCanSetPreserveBuffer = mAllowPreserveBuffer;
ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
}
@@ -106,10 +107,12 @@ bool EglManager::hasEglContext() {
void EglManager::requireGlContext() {
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, "No EGL context");
- // We can't be certain about the state of the current surface (whether
- // or not it is destroyed, for example), so err on the side of using
- // the pbuffer surface which we fully control
- usePBufferSurface();
+ if (!mInFrame) {
+ // We can't be certain about the state of the current surface (whether
+ // or not it is destroyed, for example), so err on the side of using
+ // the pbuffer surface which we fully control
+ usePBufferSurface();
+ }
}
void EglManager::loadConfig() {
@@ -252,9 +255,11 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
eglBeginFrame(mEglDisplay, surface);
+ mInFrame = true;
}
bool EglManager::swapBuffers(EGLSurface surface) {
+ mInFrame = false;
eglSwapBuffers(mEglDisplay, surface);
EGLint err = eglGetError();
if (CC_LIKELY(err == EGL_SUCCESS)) {
@@ -273,6 +278,10 @@ bool EglManager::swapBuffers(EGLSurface surface) {
return false;
}
+void EglManager::cancelFrame() {
+ mInFrame = false;
+}
+
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index ae03ea1..e12db3a 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -48,6 +48,7 @@ public:
bool makeCurrent(EGLSurface surface);
void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
bool swapBuffers(EGLSurface surface);
+ void cancelFrame();
// Returns true iff the surface is now preserving buffers.
bool setPreserveBuffer(EGLSurface surface, bool preserve);
@@ -80,6 +81,12 @@ private:
sp<GraphicBuffer> mAtlasBuffer;
int64_t* mAtlasMap;
size_t mAtlasMapSize;
+
+ // Whether or not we are in the middle of drawing a frame. This is used
+ // to avoid switching surfaces mid-frame if requireGlContext() is called
+ // TODO: Need to be better about surface/context management so that this isn't
+ // necessary
+ bool mInFrame;
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 8f99b4e..5d55ea6 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -235,12 +235,7 @@ void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
// waitForCompletion = true is expected to be fairly rare and only
// happen in destruction. Thus it should be fine to temporarily
// create a Mutex
- Mutex mutex;
- Condition condition;
- SignalingRenderTask syncTask(task, &mutex, &condition);
- AutoMutex _lock(mutex);
- thread.queue(&syncTask);
- condition.wait(mutex);
+ staticPostAndWait(task);
} else {
thread.queue(task);
}
@@ -258,17 +253,6 @@ void RenderProxy::runWithGlContext(RenderTask* gltask) {
postAndWait(task);
}
-CREATE_BRIDGE1(destroyLayer, Layer* layer) {
- LayerRenderer::destroyLayer(args->layer);
- return NULL;
-}
-
-void RenderProxy::enqueueDestroyLayer(Layer* layer) {
- SETUP_TASK(destroyLayer);
- args->layer = layer;
- RenderThread::getInstance().queue(task);
-}
-
CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) {
Layer* layer = args->context->createTextureLayer();
if (!layer) return 0;
@@ -400,6 +384,17 @@ void RenderProxy::dumpProfileInfo(int fd) {
postAndWait(task);
}
+CREATE_BRIDGE1(outputLogBuffer, int fd) {
+ RenderNode::outputLogBuffer(args->fd);
+ return NULL;
+}
+
+void RenderProxy::outputLogBuffer(int fd) {
+ SETUP_TASK(outputLogBuffer);
+ args->fd = fd;
+ staticPostAndWait(task);
+}
+
CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map, size_t size) {
CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
args->buffer->decStrong(0);
@@ -430,6 +425,19 @@ void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
return retval;
}
+void* RenderProxy::staticPostAndWait(MethodInvokeRenderTask* task) {
+ RenderThread& thread = RenderThread::getInstance();
+ void* retval;
+ task->setReturnPtr(&retval);
+ Mutex mutex;
+ Condition condition;
+ SignalingRenderTask syncTask(task, &mutex, &condition);
+ AutoMutex _lock(mutex);
+ thread.queue(&syncTask);
+ condition.wait(mutex);
+ return retval;
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index dddf0c7..4989b14 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -81,7 +81,6 @@ public:
ANDROID_API void runWithGlContext(RenderTask* task);
- static void enqueueDestroyLayer(Layer* layer);
ANDROID_API DeferredLayerUpdater* createTextureLayer();
ANDROID_API void buildLayer(RenderNode* node);
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
@@ -97,6 +96,7 @@ public:
ANDROID_API void notifyFramePending();
ANDROID_API void dumpProfileInfo(int fd);
+ ANDROID_API static void outputLogBuffer(int fd);
ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size);
@@ -114,6 +114,8 @@ private:
void post(RenderTask* task);
void* postAndWait(MethodInvokeRenderTask* task);
+ static void* staticPostAndWait(MethodInvokeRenderTask* task);
+
// Friend class to help with bridging
friend class RenderProxyBridge;
};
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 403e164..f887103 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -168,7 +168,7 @@ void RenderThread::initializeDisplayEventReceiver() {
void RenderThread::initThreadLocals() {
initializeDisplayEventReceiver();
mEglManager = new EglManager(*this);
- mRenderState = new RenderState();
+ mRenderState = new RenderState(*this);
}
int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {