DrawFrameTask.cpp revision 668f0e38ef0277d55d3118af37e17b8c435df85c
1668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck/* 2668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * Copyright (C) 2014 The Android Open Source Project 3668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * 4668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * you may not use this file except in compliance with the License. 6668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * You may obtain a copy of the License at 7668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * 8668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * http://www.apache.org/licenses/LICENSE-2.0 9668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * 10668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * Unless required by applicable law or agreed to in writing, software 11668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * distributed under the License is distributed on an "AS IS" BASIS, 12668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * See the License for the specific language governing permissions and 14668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck * limitations under the License. 15668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck */ 16668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 17668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#define ATRACE_TAG ATRACE_TAG_VIEW 18668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 19668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "DrawFrameTask.h" 20668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 21668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include <utils/Log.h> 22668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include <utils/Trace.h> 23668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 24668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../DisplayList.h" 25668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../RenderNode.h" 26668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "CanvasContext.h" 27668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "RenderThread.h" 28668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 29668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace android { 30668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace uirenderer { 31668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace renderthread { 32668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 33668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::DrawFrameTask() : mContext(0), mRenderNode(0) { 34668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 35668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 36668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::~DrawFrameTask() { 37668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 38668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 39668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setContext(CanvasContext* context) { 40668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mContext = context; 41668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 42668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 43668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) { 44668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck SetDisplayListData setter; 45668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck setter.targetNode = renderNode; 46668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck setter.newData = newData; 47668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDisplayListDataUpdates.push(setter); 48668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 49668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 50668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::addLayer(DeferredLayerUpdater* layer) { 51668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mLayers.push(layer); 52668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 53668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 54668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) { 55668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck for (size_t i = 0; i < mLayers.size(); i++) { 56668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (mLayers[i] == layer) { 57668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mLayers.removeAt(i); 58668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck break; 59668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 60668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 61668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 62668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 63668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setRenderNode(RenderNode* renderNode) { 64668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mRenderNode = renderNode; 65668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 66668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 67668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDirty(int left, int top, int right, int bottom) { 68668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.set(left, top, right, bottom); 69668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 70668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 71668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::drawFrame(RenderThread* renderThread) { 72668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck LOG_ALWAYS_FATAL_IF(!mRenderNode, "Cannot drawFrame with no render node!"); 73668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 75668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck AutoMutex _lock(mLock); 76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck renderThread->queue(this); 77668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mSignal.wait(mLock); 78668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 79668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Reset the single-frame data 80668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.setEmpty(); 81668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mRenderNode = 0; 82668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 83668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 84668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() { 85668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_NAME("DrawFrame"); 86668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 87668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck syncFrameState(); 88668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 89668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Grab a copy of everything we need 90668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck Rect dirtyCopy(mDirty); 91668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck RenderNode* renderNode = mRenderNode; 92668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck CanvasContext* context = mContext; 93668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 94668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // This is temporary until WebView has a solution for syncing frame state 95668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck bool canUnblockUiThread = !requiresSynchronousDraw(renderNode); 96668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 97668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // From this point on anything in "this" is *UNSAFE TO ACCESS* 98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (canUnblockUiThread) { 99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 100668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 101668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 102668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck drawRenderNode(context, renderNode, &dirtyCopy); 103668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 104668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (!canUnblockUiThread) { 105668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 106668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 107668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 108668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 109668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::syncFrameState() { 110668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 112668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) { 113668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck const SetDisplayListData& setter = mDisplayListDataUpdates[i]; 114668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck setter.targetNode->setData(setter.newData); 115668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 116668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDisplayListDataUpdates.clear(); 117668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 118668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mContext->processLayerUpdates(&mLayers); 119668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mRenderNode->updateProperties(); 120668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 121668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 122668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() { 123668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck AutoMutex _lock(mLock); 124668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mSignal.signal(); 125668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 126668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 127668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty) { 128668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 129668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 130668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (dirty->bottom == -1 && dirty->left == -1 131668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck && dirty->top == -1 && dirty->right == -1) { 132668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck dirty = 0; 133668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 134668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck context->drawDisplayList(renderNode, dirty); 135668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 136668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 137668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckbool DrawFrameTask::requiresSynchronousDraw(RenderNode* renderNode) { 138668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck return renderNode->hasFunctors(); 139668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 140668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 141668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */ 142668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */ 143668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */ 144