diff options
author | John Reck <jreck@google.com> | 2014-02-14 20:03:38 -0800 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-02-19 10:47:19 -0800 |
commit | 19b6bcfd83eb7fb92ebd06d2fec89e308311f1d0 (patch) | |
tree | 617b09881e87d86d03a7486f5c3f05242199210d /libs | |
parent | 587f43d8725b11632b5d64a0a56a647207f01668 (diff) | |
download | frameworks_base-19b6bcfd83eb7fb92ebd06d2fec89e308311f1d0.zip frameworks_base-19b6bcfd83eb7fb92ebd06d2fec89e308311f1d0.tar.gz frameworks_base-19b6bcfd83eb7fb92ebd06d2fec89e308311f1d0.tar.bz2 |
Support HardwareLayers in RenderThread
Also has a few HardwareLayer lifecycle fixes
Change-Id: I6308cb05f8f199eed72189ace768013a46815941
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 22 | ||||
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.h | 1 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 8 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 73 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 11 |
6 files changed, 114 insertions, 27 deletions
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index 5d3d393..efb1298 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -123,27 +123,5 @@ void DeferredLayerUpdater::doUpdateTexImage() { } } -void DeferredLayerUpdater::applyDeferred(DeferredLayerUpdater* deferredApply) { - // Default assignment operator doesn't quite work, and fails due to mCaches anyway - deferredApply->mWidth = mWidth; - deferredApply->mHeight = mHeight; - deferredApply->mBlend = mBlend; - deferredApply->mAlpha = mAlpha; - deferredApply->mMode = mMode; - deferredApply->mDirtyRect.set(mDirtyRect); - deferredApply->mDisplayList = mDisplayList; - deferredApply->mSurfaceTexture = mSurfaceTexture; - deferredApply->mNeedsGLContextAttach = mNeedsGLContextAttach; - deferredApply->mUpdateTexImage = mUpdateTexImage; - deferredApply->setColorFilter(mColorFilter); - deferredApply->setTransform(mTransform); - - mDisplayList = 0; - mDirtyRect.setEmpty(); - mTransform = 0; - mNeedsGLContextAttach = false; - mUpdateTexImage = false; -} - } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 9800c2f..624db2c 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -82,7 +82,6 @@ public: ANDROID_API void setColorFilter(SkColorFilter* colorFilter); ANDROID_API bool apply(); - ANDROID_API void applyDeferred(DeferredLayerUpdater* deferredApply); ANDROID_API Layer* backingLayer() { return mLayer; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 4e665d9..fe781bd 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -24,6 +24,8 @@ #include "RenderThread.h" #include "../Caches.h" +#include "../DeferredLayerUpdater.h" +#include "../LayerRenderer.h" #include "../OpenGLRenderer.h" #include "../Stencil.h" @@ -371,6 +373,17 @@ void CanvasContext::setup(int width, int height) { mCanvas->setViewport(width, height); } +void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters) { + mGlobalContext->makeCurrent(mEglSurface); + for (size_t i = 0; i < layerUpdaters->size(); i++) { + DeferredLayerUpdater* update = layerUpdaters->itemAt(i); + LOG_ALWAYS_FATAL_IF(!update->apply(), "Failed to update layer!"); + if (update->backingLayer()->deferredUpdateScheduled) { + mCanvas->pushLayerUpdate(update->backingLayer()); + } + } +} + void CanvasContext::drawDisplayList(DisplayList* displayList, Rect* dirty) { LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, "drawDisplayList called on a context with no canvas or surface!"); @@ -462,14 +475,23 @@ void CanvasContext::queueFunctorsTask(int delayMs) { mRenderThread.queueDelayed(&mInvokeFunctorsTask, delayMs); } +bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { + requireGlContext(); + layer->apply(); + return LayerRenderer::copyLayer(layer->backingLayer(), bitmap); +} + void CanvasContext::runWithGlContext(RenderTask* task) { + requireGlContext(); + task->run(); +} + +void CanvasContext::requireGlContext() { if (mEglSurface != EGL_NO_SURFACE) { mGlobalContext->makeCurrent(mEglSurface); } else { mGlobalContext->usePBufferSurface(); } - - task->run(); } } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 3197df3..5fac582 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -19,7 +19,9 @@ #include <cutils/compiler.h> #include <EGL/egl.h> +#include <SkBitmap.h> #include <utils/Functor.h> +#include <utils/Vector.h> #include "RenderTask.h" @@ -28,6 +30,7 @@ namespace android { namespace uirenderer { +class DeferredLayerUpdater; class DisplayList; class OpenGLRenderer; class Rect; @@ -59,9 +62,12 @@ public: bool initialize(EGLNativeWindowType window); void updateSurface(EGLNativeWindowType window); void setup(int width, int height); + void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters); void drawDisplayList(DisplayList* displayList, Rect* dirty); void destroyCanvas(); + bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap); + void attachFunctor(Functor* functor); void detachFunctor(Functor* functor); @@ -78,6 +84,8 @@ private: void removeFunctorsTask(); void queueFunctorsTask(int delayMs = FUNCTOR_PROCESS_DELAY); + void requireGlContext(); + GlobalContext* mGlobalContext; RenderThread& mRenderThread; EGLSurface mEglSurface; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 34f1961..0c667fd 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -22,7 +22,9 @@ #include "RenderTask.h" #include "RenderThread.h" +#include "../DeferredLayerUpdater.h" #include "../DisplayList.h" +#include "../LayerRenderer.h" #include "../Rect.h" namespace android { @@ -31,6 +33,7 @@ namespace renderthread { #define ARGS(method) method ## Args +#define CREATE_BRIDGE0(name) CREATE_BRIDGE(name,,,,,,,,) #define CREATE_BRIDGE1(name, a1) CREATE_BRIDGE(name, a1,,,,,,,) #define CREATE_BRIDGE2(name, a1, a2) CREATE_BRIDGE(name, a1,a2,,,,,,) #define CREATE_BRIDGE3(name, a1, a2, a3) CREATE_BRIDGE(name, a1,a2,a3,,,,,) @@ -114,13 +117,14 @@ void RenderProxy::setup(int width, int height) { post(task); } -CREATE_BRIDGE3(drawDisplayList, CanvasContext* context, DisplayList* displayList, - Rect dirty) { +CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, DisplayList* displayList, + Rect dirty, const Vector<DeferredLayerUpdater*>* layerUpdates) { Rect* dirty = &args->dirty; if (dirty->bottom == -1 && dirty->left == -1 && dirty->top == -1 && dirty->right == -1) { dirty = 0; } + args->context->processLayerUpdates(args->layerUpdates); args->context->drawDisplayList(args->displayList, dirty); return NULL; } @@ -131,6 +135,7 @@ void RenderProxy::drawDisplayList(DisplayList* displayList, args->context = mContext; args->displayList = displayList; args->dirty.set(dirtyLeft, dirtyTop, dirtyRight, dirtyBottom); + args->layerUpdates = &mLayers; // TODO: Switch to post() once some form of thread safety strategy is in place postAndWait(task); } @@ -182,6 +187,70 @@ void RenderProxy::runWithGlContext(RenderTask* gltask) { postAndWait(task); } +CREATE_BRIDGE2(createDisplayListLayer, int width, int height) { + Layer* layer = LayerRenderer::createRenderLayer(args->width, args->height); + if (!layer) return 0; + + OpenGLRenderer* renderer = new LayerRenderer(layer); + renderer->initProperties(); + return new DeferredLayerUpdater(layer, renderer); +} + +DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) { + SETUP_TASK(createDisplayListLayer); + args->width = width; + args->height = height; + void* retval = postAndWait(task); + DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval); + mLayers.push(layer); + return layer; +} + +CREATE_BRIDGE0(createTextureLayer) { + Layer* layer = LayerRenderer::createTextureLayer(); + if (!layer) return 0; + return new DeferredLayerUpdater(layer); +} + +DeferredLayerUpdater* RenderProxy::createTextureLayer() { + SETUP_TASK(createTextureLayer); + void* retval = postAndWait(task); + DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval); + mLayers.push(layer); + return layer; +} + +CREATE_BRIDGE1(destroyLayer, Layer* layer) { + LayerRenderer::destroyLayer(args->layer); + return NULL; +} + +CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer, + SkBitmap* bitmap) { + bool success = args->context->copyLayerInto(args->layer, args->bitmap); + return (void*) success; +} + +bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { + SETUP_TASK(copyLayerInto); + args->context = mContext; + args->layer = layer; + args->bitmap = bitmap; + return (bool) postAndWait(task); +} + +void RenderProxy::destroyLayer(DeferredLayerUpdater* layer) { + for (size_t i = 0; i < mLayers.size(); i++) { + if (mLayers[i] == layer) { + mLayers.removeAt(i); + break; + } + } + SETUP_TASK(destroyLayer); + args->layer = layer->detachBackingLayer(); + post(task); +} + MethodInvokeRenderTask* RenderProxy::createTask(RunnableMethod method) { // TODO: Consider having a small pool of these to avoid alloc churn return new MethodInvokeRenderTask(method); diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 1ad0c2d..8ff3d63 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -21,15 +21,19 @@ #include <cutils/compiler.h> #include <EGL/egl.h> +#include <SkBitmap.h> #include <utils/Condition.h> #include <utils/Functor.h> #include <utils/Mutex.h> #include <utils/StrongPointer.h> +#include <utils/Vector.h> namespace android { namespace uirenderer { +class DeferredLayerUpdater; class DisplayList; +class Layer; class Rect; namespace renderthread { @@ -64,6 +68,11 @@ public: ANDROID_API void runWithGlContext(RenderTask* task); + ANDROID_API DeferredLayerUpdater* createDisplayListLayer(int width, int height); + ANDROID_API DeferredLayerUpdater* createTextureLayer(); + ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap); + ANDROID_API void destroyLayer(DeferredLayerUpdater* layer); + private: RenderThread& mRenderThread; CanvasContext* mContext; @@ -71,6 +80,8 @@ private: Mutex mSyncMutex; Condition mSyncCondition; + Vector<DeferredLayerUpdater*> mLayers; + void destroyContext(); MethodInvokeRenderTask* createTask(RunnableMethod method); |