diff options
Diffstat (limited to 'libs/hwui/renderthread/DrawFrameTask.cpp')
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 1e9089a30a46..372d0d0084d6 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -30,7 +30,7 @@ namespace android { namespace uirenderer { namespace renderthread { -DrawFrameTask::DrawFrameTask() : mContext(0), mRenderNode(0) { +DrawFrameTask::DrawFrameTask() : mContext(0), mTaskMode(MODE_INVALID), mRenderNode(0) { } DrawFrameTask::~DrawFrameTask() { @@ -40,14 +40,9 @@ void DrawFrameTask::setContext(CanvasContext* context) { mContext = context; } -void DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) { - SetDisplayListData setter; - setter.targetNode = renderNode; - setter.newData = newData; - mDisplayListDataUpdates.push(setter); -} - void DrawFrameTask::addLayer(DeferredLayerUpdater* layer) { + LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!"); + mLayers.push(layer); } @@ -61,6 +56,8 @@ void DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) { } void DrawFrameTask::setRenderNode(RenderNode* renderNode) { + LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to setRenderNode with!"); + mRenderNode = renderNode; } @@ -69,54 +66,73 @@ void DrawFrameTask::setDirty(int left, int top, int right, int bottom) { } void DrawFrameTask::drawFrame(RenderThread* renderThread) { - LOG_ALWAYS_FATAL_IF(!mRenderNode, "Cannot drawFrame with no render node!"); + LOG_ALWAYS_FATAL_IF(!mRenderNode.get(), "Cannot drawFrame with no render node!"); LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); - AutoMutex _lock(mLock); - renderThread->queue(this); - mSignal.wait(mLock); + postAndWait(renderThread, MODE_FULL); // Reset the single-frame data mDirty.setEmpty(); mRenderNode = 0; } +void DrawFrameTask::flushStateChanges(RenderThread* renderThread) { + LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); + + postAndWait(renderThread, MODE_STATE_ONLY); +} + +void DrawFrameTask::postAndWait(RenderThread* renderThread, TaskMode mode) { + LOG_ALWAYS_FATAL_IF(mode == MODE_INVALID, "That's not a real mode, silly!"); + + mTaskMode = mode; + AutoMutex _lock(mLock); + renderThread->queue(this); + mSignal.wait(mLock); +} + 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(); + return; + } // Grab a copy of everything we need Rect dirtyCopy(mDirty); - RenderNode* renderNode = mRenderNode; + sp<RenderNode> renderNode = mRenderNode; CanvasContext* context = mContext; - // This is temporary until WebView has a solution for syncing frame state - bool canUnblockUiThread = !requiresSynchronousDraw(renderNode); - // From this point on anything in "this" is *UNSAFE TO ACCESS* if (canUnblockUiThread) { unblockUiThread(); } - drawRenderNode(context, renderNode, &dirtyCopy); + drawRenderNode(context, renderNode.get(), &dirtyCopy); if (!canUnblockUiThread) { unblockUiThread(); } } -void DrawFrameTask::syncFrameState() { +bool DrawFrameTask::syncFrameState() { ATRACE_CALL(); - for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) { - const SetDisplayListData& setter = mDisplayListDataUpdates[i]; - setter.targetNode->setData(setter.newData); + bool hasFunctors = false; + mContext->processLayerUpdates(&mLayers, &hasFunctors); + + // If we don't have an mRenderNode this is a state flush only + if (mRenderNode.get()) { + TreeInfo info = {0}; + mRenderNode->prepareTree(info); + hasFunctors |= info.hasFunctors; } - mDisplayListDataUpdates.clear(); - mContext->processLayerUpdates(&mLayers); - mRenderNode->updateProperties(); + return !hasFunctors; } void DrawFrameTask::unblockUiThread() { @@ -134,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 */ |