DrawFrameTask.cpp revision 860d155f866cc15a725e7ce03763280987f24901
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 338ca3eecc2b7fe507d3482745efc4cd2567ad15a1John 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::addLayer(DeferredLayerUpdater* layer) { 44087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!"); 45087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 46668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mLayers.push(layer); 47668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 48668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 49668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) { 50668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck for (size_t i = 0; i < mLayers.size(); i++) { 51668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (mLayers[i] == layer) { 52668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mLayers.removeAt(i); 53668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck break; 54668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 55668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 56668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 57668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 58668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setRenderNode(RenderNode* renderNode) { 59087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to setRenderNode with!"); 60087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 61668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mRenderNode = renderNode; 62668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 63668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 64668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDirty(int left, int top, int right, int bottom) { 65668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.set(left, top, right, bottom); 66668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 67668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 68668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::drawFrame(RenderThread* renderThread) { 69087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck LOG_ALWAYS_FATAL_IF(!mRenderNode.get(), "Cannot drawFrame with no render node!"); 70668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 71668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 728ca3eecc2b7fe507d3482745efc4cd2567ad15a1John Reck postAndWait(renderThread); 73668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Reset the single-frame data 75668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.setEmpty(); 76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mRenderNode = 0; 77668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 78668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 798ca3eecc2b7fe507d3482745efc4cd2567ad15a1John Reckvoid DrawFrameTask::postAndWait(RenderThread* renderThread) { 80087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck AutoMutex _lock(mLock); 81087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck renderThread->queue(this); 82087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck mSignal.wait(mLock); 83087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck} 84087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 85668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() { 86668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_NAME("DrawFrame"); 87668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 88f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck bool canUnblockUiThread = syncFrameState(); 89668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 90668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Grab a copy of everything we need 91668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck Rect dirtyCopy(mDirty); 92087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck sp<RenderNode> renderNode = mRenderNode; 93668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck CanvasContext* context = mContext; 94668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 95668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // From this point on anything in "this" is *UNSAFE TO ACCESS* 96668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (canUnblockUiThread) { 97668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 100087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck drawRenderNode(context, renderNode.get(), &dirtyCopy); 101668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 102668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (!canUnblockUiThread) { 103668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 104668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 105668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 106668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 107860d155f866cc15a725e7ce03763280987f24901John Reckstatic void prepareTreeInfo(TreeInfo& info) { 108860d155f866cc15a725e7ce03763280987f24901John Reck info.prepareTextures = true; 109860d155f866cc15a725e7ce03763280987f24901John Reck} 110860d155f866cc15a725e7ce03763280987f24901John Reck 111f4198b713e43c0c0f9adac74203cf24c2a49b802John Reckbool DrawFrameTask::syncFrameState() { 112668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 113860d155f866cc15a725e7ce03763280987f24901John Reck mContext->makeCurrent(); 114860d155f866cc15a725e7ce03763280987f24901John Reck Caches::getInstance().textureCache.resetMarkInUse(); 115860d155f866cc15a725e7ce03763280987f24901John Reck TreeInfo info; 116860d155f866cc15a725e7ce03763280987f24901John Reck prepareTreeInfo(info); 117860d155f866cc15a725e7ce03763280987f24901John Reck mContext->processLayerUpdates(&mLayers, info); 1188ca3eecc2b7fe507d3482745efc4cd2567ad15a1John Reck mRenderNode->prepareTree(info); 119860d155f866cc15a725e7ce03763280987f24901John Reck // If prepareTextures is false, we ran out of texture cache space 120860d155f866cc15a725e7ce03763280987f24901John Reck return !info.hasFunctors && info.prepareTextures; 121668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 122668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 123668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() { 124668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck AutoMutex _lock(mLock); 125668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mSignal.signal(); 126668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 127668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 128668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty) { 129668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 130668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 131668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (dirty->bottom == -1 && dirty->left == -1 132668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck && dirty->top == -1 && dirty->right == -1) { 133668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck dirty = 0; 134668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 135668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck context->drawDisplayList(renderNode, dirty); 136668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 137668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 138668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */ 139668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */ 140668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */ 141