diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/DeferredLayerUpdater.h | 2 | ||||
| -rw-r--r-- | libs/hwui/RenderNode.cpp | 43 | ||||
| -rw-r--r-- | libs/hwui/RenderNode.h | 14 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 2 | ||||
| -rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 21 | ||||
| -rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.h | 6 |
8 files changed, 53 insertions, 51 deletions
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index 358e1af92aeb..c64c16989c58 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -62,7 +62,7 @@ void DeferredLayerUpdater::setDisplayList(RenderNode* displayList, } } -bool DeferredLayerUpdater::apply() { +bool DeferredLayerUpdater::apply(bool* hasFunctors) { bool success = true; // These properties are applied the same to both layer types mLayer->setColorFilter(mColorFilter); @@ -73,7 +73,11 @@ bool DeferredLayerUpdater::apply() { success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight); } mLayer->setBlend(mBlend); - mDisplayList->pushStagingChanges(); + TreeInfo info = {0}; + mDisplayList->prepareTree(info); + if (info.hasFunctors) { + *hasFunctors = true; + } mLayer->updateDeferred(mDisplayList.get(), mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom); mDirtyRect.setEmpty(); diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index ce08c2de8960..2cc92295c5f6 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -77,7 +77,7 @@ public: ANDROID_API void setPaint(const SkPaint* paint); - ANDROID_API bool apply(); + ANDROID_API bool apply(bool* hasFunctors); ANDROID_API Layer* backingLayer() { return mLayer; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 761fb84c25ab..823ae7b8d0d1 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -93,7 +93,18 @@ void RenderNode::output(uint32_t level) { ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string()); } -void RenderNode::pushStagingChanges() { +void RenderNode::prepareTree(TreeInfo& info) { + ATRACE_CALL(); + + prepareTreeImpl(info); +} + +void RenderNode::prepareTreeImpl(TreeInfo& info) { + pushStagingChanges(info); + prepareSubTree(info, mDisplayListData); +} + +void RenderNode::pushStagingChanges(TreeInfo& info) { if (mNeedsPropertiesSync) { mNeedsPropertiesSync = false; mProperties = mStagingProperties; @@ -102,41 +113,27 @@ void RenderNode::pushStagingChanges() { mNeedsDisplayListDataSync = false; // Do a push pass on the old tree to handle freeing DisplayListData // that are no longer used - pushSubTreeStagingChanges(mDisplayListData); + TreeInfo oldTreeInfo = {0}; + prepareSubTree(oldTreeInfo, mDisplayListData); + // TODO: The damage for the old tree should be accounted for delete mDisplayListData; mDisplayListData = mStagingDisplayListData; mStagingDisplayListData = 0; } - - pushSubTreeStagingChanges(mDisplayListData); } -void RenderNode::pushSubTreeStagingChanges(DisplayListData* subtree) { +void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) { if (subtree) { + if (!info.hasFunctors) { + info.hasFunctors = subtree->functorCount; + } for (size_t i = 0; i < subtree->children().size(); i++) { RenderNode* childNode = subtree->children()[i]->mDisplayList; - childNode->pushStagingChanges(); + childNode->prepareTreeImpl(info); } } } -bool RenderNode::hasFunctors() { - if (!mDisplayListData) return false; - - if (mDisplayListData->functorCount) { - return true; - } - - for (size_t i = 0; i < mDisplayListData->children().size(); i++) { - RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList; - if (childNode->hasFunctors()) { - return true; - } - } - - return false; -} - /* * For property operations, we pass a savecount of 0, since the operations aren't part of the * displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index e5b9d7c395b6..78537011667f 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -65,6 +65,11 @@ class SaveOp; class RestoreToCountOp; class DrawDisplayListOp; +struct TreeInfo { + bool hasFunctors; + // TODO: Damage calculations? Flag to skip staging pushes for RT animations? +}; + /** * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties. * @@ -141,10 +146,7 @@ public: return properties().getHeight(); } - ANDROID_API void pushStagingChanges(); - - // Returns true if this RenderNode or any of its children have functors - bool hasFunctors(); + ANDROID_API void prepareTree(TreeInfo& info); private: typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair; @@ -203,7 +205,9 @@ private: const char* mText; }; - static void pushSubTreeStagingChanges(DisplayListData* subtree); + void prepareTreeImpl(TreeInfo& info); + void pushStagingChanges(TreeInfo& info); + void prepareSubTree(TreeInfo& info, DisplayListData* subtree); String8 mName; bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 014c7d0332b6..c5122e27a253 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -385,11 +385,12 @@ void CanvasContext::setup(int width, int height) { mCanvas->setViewport(width, height); } -void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters) { +void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, + bool* hasFunctors) { 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!"); + LOG_ALWAYS_FATAL_IF(!update->apply(hasFunctors), "Failed to update layer!"); if (update->backingLayer()->deferredUpdateScheduled) { mCanvas->pushLayerUpdate(update->backingLayer()); } @@ -483,7 +484,8 @@ void CanvasContext::queueFunctorsTask(int delayMs) { bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { requireGlContext(); - layer->apply(); + bool hasFunctors; + layer->apply(&hasFunctors); return LayerRenderer::copyLayer(layer->backingLayer(), bitmap); } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 4d830babfd6c..a24162e6d89e 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -65,7 +65,7 @@ public: void updateSurface(EGLNativeWindowType window); void pauseSurface(EGLNativeWindowType window); void setup(int width, int height); - void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters); + void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, bool* hasFunctors); void drawDisplayList(RenderNode* displayList, Rect* dirty); void destroyCanvas(); diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 6e7ec9b42ef9..372d0d0084d6 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -94,7 +94,8 @@ void DrawFrameTask::postAndWait(RenderThread* renderThread, TaskMode mode) { void DrawFrameTask::run() { ATRACE_NAME("DrawFrame"); - syncFrameState(); + // canUnblockUiThread is temporary until WebView has a solution for syncing frame state + bool canUnblockUiThread = syncFrameState(); if (mTaskMode == MODE_STATE_ONLY) { unblockUiThread(); @@ -106,9 +107,6 @@ void DrawFrameTask::run() { sp<RenderNode> renderNode = mRenderNode; CanvasContext* context = mContext; - // This is temporary until WebView has a solution for syncing frame state - bool canUnblockUiThread = !requiresSynchronousDraw(renderNode.get()); - // From this point on anything in "this" is *UNSAFE TO ACCESS* if (canUnblockUiThread) { unblockUiThread(); @@ -121,15 +119,20 @@ void DrawFrameTask::run() { } } -void DrawFrameTask::syncFrameState() { +bool DrawFrameTask::syncFrameState() { ATRACE_CALL(); - mContext->processLayerUpdates(&mLayers); + bool hasFunctors = false; + mContext->processLayerUpdates(&mLayers, &hasFunctors); // If we don't have an mRenderNode this is a state flush only if (mRenderNode.get()) { - mRenderNode->pushStagingChanges(); + TreeInfo info = {0}; + mRenderNode->prepareTree(info); + hasFunctors |= info.hasFunctors; } + + return !hasFunctors; } void DrawFrameTask::unblockUiThread() { @@ -147,10 +150,6 @@ void DrawFrameTask::drawRenderNode(CanvasContext* context, RenderNode* renderNod context->drawDisplayList(renderNode, dirty); } -bool DrawFrameTask::requiresSynchronousDraw(RenderNode* renderNode) { - return renderNode->hasFunctors(); -} - } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index ddf756b71877..a5124088d790 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -68,14 +68,10 @@ private: }; void postAndWait(RenderThread* renderThread, TaskMode mode); - void syncFrameState(); + bool syncFrameState(); void unblockUiThread(); static void drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty); - // This checks to see if there are any drawGlFunctors which would require - // a synchronous drawRenderNode() - static bool requiresSynchronousDraw(RenderNode* renderNode); - Mutex mLock; Condition mSignal; |