diff options
-rw-r--r-- | core/java/android/view/GLRenderer.java | 4 | ||||
-rw-r--r-- | core/jni/android_view_GLRenderer.cpp | 7 | ||||
-rw-r--r-- | core/jni/android_view_HardwareLayer.cpp | 3 | ||||
-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 |
11 files changed, 61 insertions, 57 deletions
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java index b589cc2b471d..eba4f7feac48 100644 --- a/core/java/android/view/GLRenderer.java +++ b/core/java/android/view/GLRenderer.java @@ -1317,7 +1317,7 @@ public class GLRenderer extends HardwareRenderer { } Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList"); - nPushStagingChanges(displayList.getNativeDisplayList()); + nPrepareTree(displayList.getNativeDisplayList()); try { status |= canvas.drawDisplayList(displayList, mRedrawClip, RenderNode.FLAG_CLIP_CHILDREN); @@ -1476,7 +1476,7 @@ public class GLRenderer extends HardwareRenderer { static native void nDestroyLayer(long layerPtr); - private static native void nPushStagingChanges(long displayListPtr); + private static native void nPrepareTree(long displayListPtr); class DrawPerformanceDataProvider extends GraphDataProvider { private final int mGraphType; diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp index 8f59e8704ba7..6ae6c8f84356 100644 --- a/core/jni/android_view_GLRenderer.cpp +++ b/core/jni/android_view_GLRenderer.cpp @@ -142,11 +142,12 @@ static void android_view_GLRenderer_destroyLayer(JNIEnv* env, jobject clazz, LayerRenderer::destroyLayer(layer); } -static void android_view_GLRenderer_pushStagingChanges(JNIEnv* env, jobject clazz, +static void android_view_GLRenderer_prepareTree(JNIEnv* env, jobject clazz, jlong renderNodePtr) { using namespace android::uirenderer; RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); - renderNode->pushStagingChanges(); + TreeInfo info = {0}; + renderNode->prepareTree(info); } static void android_view_GLRenderer_invokeFunctor(JNIEnv* env, jobject clazz, @@ -187,7 +188,7 @@ static JNINativeMethod gMethods[] = { { "getSystemTime", "()J", (void*) android_view_GLRenderer_getSystemTime }, { "nDestroyLayer", "(J)V", (void*) android_view_GLRenderer_destroyLayer }, - { "nPushStagingChanges", "(J)V", (void*) android_view_GLRenderer_pushStagingChanges }, + { "nPrepareTree", "(J)V", (void*) android_view_GLRenderer_prepareTree }, { "nInvokeFunctor", "(JZ)V", (void*) android_view_GLRenderer_invokeFunctor }, #endif diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp index 4bf5f78374e8..2eb0d78db263 100644 --- a/core/jni/android_view_HardwareLayer.cpp +++ b/core/jni/android_view_HardwareLayer.cpp @@ -127,7 +127,8 @@ static void android_view_HardwareLayer_updateRenderLayer(JNIEnv* env, jobject cl static jboolean android_view_HardwareLayer_flushChanges(JNIEnv* env, jobject clazz, jlong layerUpdaterPtr) { DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr); - return layer->apply(); + bool ignoredHasFunctors; + return layer->apply(&ignoredHasFunctors); } static jlong android_view_HardwareLayer_getLayer(JNIEnv* env, jobject clazz, 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; |