DrawFrameTask.cpp revision d72e0a339b54af0c4e731513bbad120dff694723
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 24d72e0a339b54af0c4e731513bbad120dff694723John Reck#include "../DeferredLayerUpdater.h" 25668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../DisplayList.h" 26668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../RenderNode.h" 27668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "CanvasContext.h" 28668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "RenderThread.h" 29668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 30668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace android { 31668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace uirenderer { 32668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace renderthread { 33668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 3418f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn ReckDrawFrameTask::DrawFrameTask() 3518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck : mRenderThread(NULL) 3618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck , mContext(NULL) 37f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck , mFrameTimeNanos(0) 38fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck , mRecordDurationNanos(0) 39fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck , mDensity(1.0f) // safe enough default 40f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck , mSyncResult(kSync_OK) { 41668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 42668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 43668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::~DrawFrameTask() { 44668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 45668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 4618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context) { 4718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread = thread; 48668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mContext = context; 49668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 50668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 51d72e0a339b54af0c4e731513bbad120dff694723John Reckvoid DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) { 52d72e0a339b54af0c4e731513bbad120dff694723John Reck LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to pushLayerUpdate with!"); 53087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 54d72e0a339b54af0c4e731513bbad120dff694723John Reck for (size_t i = 0; i < mLayers.size(); i++) { 55d72e0a339b54af0c4e731513bbad120dff694723John Reck if (mLayers[i].get() == layer) { 56d72e0a339b54af0c4e731513bbad120dff694723John Reck return; 57d72e0a339b54af0c4e731513bbad120dff694723John Reck } 58d72e0a339b54af0c4e731513bbad120dff694723John Reck } 59d72e0a339b54af0c4e731513bbad120dff694723John Reck mLayers.push_back(layer); 60668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 61668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 62d72e0a339b54af0c4e731513bbad120dff694723John Reckvoid DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) { 63668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck for (size_t i = 0; i < mLayers.size(); i++) { 64d72e0a339b54af0c4e731513bbad120dff694723John Reck if (mLayers[i].get() == layer) { 65d72e0a339b54af0c4e731513bbad120dff694723John Reck mLayers.erase(mLayers.begin() + i); 66d72e0a339b54af0c4e731513bbad120dff694723John Reck return; 67668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 68668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 69668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 70668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 71668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDirty(int left, int top, int right, int bottom) { 72668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.set(left, top, right, bottom); 73668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 75fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckint DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos) { 76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 77668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 78f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mSyncResult = kSync_OK; 7918f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mFrameTimeNanos = frameTimeNanos; 80fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mRecordDurationNanos = recordDurationNanos; 8118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck postAndWait(); 82668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 83668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Reset the single-frame data 8418f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mFrameTimeNanos = 0; 85fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mRecordDurationNanos = 0; 86668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.setEmpty(); 87f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck 88f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck return mSyncResult; 89668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 90668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 9118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::postAndWait() { 92087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck AutoMutex _lock(mLock); 9318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread->queue(this); 94087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck mSignal.wait(mLock); 95087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck} 96087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 97668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() { 98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_NAME("DrawFrame"); 99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 100fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mContext->profiler().setDensity(mDensity); 101fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mContext->profiler().startFrame(mRecordDurationNanos); 102fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 103a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck bool canUnblockUiThread; 104a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck bool canDrawThisFrame; 105a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck { 106a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck TreeInfo info; 107a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck canUnblockUiThread = syncFrameState(info); 108a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck canDrawThisFrame = info.out.canDrawThisFrame; 109a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 110668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Grab a copy of everything we need 112e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck Rect dirty(mDirty); 113668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck CanvasContext* context = mContext; 114668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 115668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // From this point on anything in "this" is *UNSAFE TO ACCESS* 116668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (canUnblockUiThread) { 117668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 118668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 119668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 120a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck if (CC_LIKELY(canDrawThisFrame)) { 121a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck context->draw(&dirty); 122a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 123668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 124668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (!canUnblockUiThread) { 125668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 126668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 127668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 128668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 129e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic void initTreeInfo(TreeInfo& info) { 130860d155f866cc15a725e7ce03763280987f24901John Reck info.prepareTextures = true; 131e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.performStagingPush = true; 132e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.evaluateAnimations = true; 133860d155f866cc15a725e7ce03763280987f24901John Reck} 134860d155f866cc15a725e7ce03763280987f24901John Reck 135a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckbool DrawFrameTask::syncFrameState(TreeInfo& info) { 136668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 13718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos); 138860d155f866cc15a725e7ce03763280987f24901John Reck mContext->makeCurrent(); 139860d155f866cc15a725e7ce03763280987f24901John Reck Caches::getInstance().textureCache.resetMarkInUse(); 140e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck initTreeInfo(info); 141d72e0a339b54af0c4e731513bbad120dff694723John Reck 142d72e0a339b54af0c4e731513bbad120dff694723John Reck for (size_t i = 0; i < mLayers.size(); i++) { 143d72e0a339b54af0c4e731513bbad120dff694723John Reck mContext->processLayerUpdate(mLayers[i].get(), info); 144d72e0a339b54af0c4e731513bbad120dff694723John Reck } 145d72e0a339b54af0c4e731513bbad120dff694723John Reck mLayers.clear(); 146d72e0a339b54af0c4e731513bbad120dff694723John Reck if (info.out.hasAnimations) { 147d72e0a339b54af0c4e731513bbad120dff694723John Reck // TODO: Uh... crap? 148d72e0a339b54af0c4e731513bbad120dff694723John Reck } 149d72e0a339b54af0c4e731513bbad120dff694723John Reck mContext->prepareTree(info); 150d72e0a339b54af0c4e731513bbad120dff694723John Reck 151f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.hasAnimations) { 15252244fff29042926e21fa897ef5ab11148e35299John Reck // TODO: dirty calculations, for now just do a full-screen inval 15352244fff29042926e21fa897ef5ab11148e35299John Reck mDirty.setEmpty(); 154f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.requiresUiRedraw) { 155f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mSyncResult |= kSync_UIRedrawRequired; 156f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } 15752244fff29042926e21fa897ef5ab11148e35299John Reck } 158860d155f866cc15a725e7ce03763280987f24901John Reck // If prepareTextures is false, we ran out of texture cache space 159f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck return !info.out.hasFunctors && info.prepareTextures; 160668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 161668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 162668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() { 163668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck AutoMutex _lock(mLock); 164668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mSignal.signal(); 165668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 166668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 167668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */ 168668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */ 169668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */ 170