DrawFrameTask.cpp revision 18f16e6fba74eda173e1e7c869e6e2e2acc073ff
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 3318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn ReckDrawFrameTask::DrawFrameTask() 3418f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck : mRenderThread(NULL) 3518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck , mContext(NULL) 3618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck , mFrameTimeNanos(NULL) { 37668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 38668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 39668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::~DrawFrameTask() { 40668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 41668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 4218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context) { 4318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread = thread; 44668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mContext = context; 45668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 46668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 47668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::addLayer(DeferredLayerUpdater* layer) { 48087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!"); 49087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 50668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mLayers.push(layer); 51668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 52668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 53668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) { 54668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck for (size_t i = 0; i < mLayers.size(); i++) { 55668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (mLayers[i] == layer) { 56668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mLayers.removeAt(i); 57668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck break; 58668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 59668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 60668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 61668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 62668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDirty(int left, int top, int right, int bottom) { 63668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.set(left, top, right, bottom); 64668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 65668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 6618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::drawFrame(nsecs_t frameTimeNanos) { 67668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 68668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 6918f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mFrameTimeNanos = frameTimeNanos; 7018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck postAndWait(); 71668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 72668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Reset the single-frame data 7318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mFrameTimeNanos = 0; 74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mDirty.setEmpty(); 75668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 7718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::postAndWait() { 78087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck AutoMutex _lock(mLock); 7918f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread->queue(this); 80087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck mSignal.wait(mLock); 81087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck} 82087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 83668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() { 84668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_NAME("DrawFrame"); 85668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 86f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck bool canUnblockUiThread = syncFrameState(); 87668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 88668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Grab a copy of everything we need 89e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck Rect dirty(mDirty); 90668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck CanvasContext* context = mContext; 91668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 92668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // From this point on anything in "this" is *UNSAFE TO ACCESS* 93668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (canUnblockUiThread) { 94668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 95668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 96668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 97e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck context->draw(&dirty); 98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (!canUnblockUiThread) { 100668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 101668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 102668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 103668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 104e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic void initTreeInfo(TreeInfo& info) { 105860d155f866cc15a725e7ce03763280987f24901John Reck info.prepareTextures = true; 106e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.performStagingPush = true; 107e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.evaluateAnimations = true; 108860d155f866cc15a725e7ce03763280987f24901John Reck} 109860d155f866cc15a725e7ce03763280987f24901John Reck 110f4198b713e43c0c0f9adac74203cf24c2a49b802John Reckbool DrawFrameTask::syncFrameState() { 111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 11218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos); 113860d155f866cc15a725e7ce03763280987f24901John Reck mContext->makeCurrent(); 114860d155f866cc15a725e7ce03763280987f24901John Reck Caches::getInstance().textureCache.resetMarkInUse(); 115860d155f866cc15a725e7ce03763280987f24901John Reck TreeInfo info; 116e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck initTreeInfo(info); 117860d155f866cc15a725e7ce03763280987f24901John Reck mContext->processLayerUpdates(&mLayers, info); 118e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mContext->prepareTree(info); 11952244fff29042926e21fa897ef5ab11148e35299John Reck if (info.hasAnimations) { 12052244fff29042926e21fa897ef5ab11148e35299John Reck // TODO: dirty calculations, for now just do a full-screen inval 12152244fff29042926e21fa897ef5ab11148e35299John Reck mDirty.setEmpty(); 12252244fff29042926e21fa897ef5ab11148e35299John Reck } 123860d155f866cc15a725e7ce03763280987f24901John Reck // If prepareTextures is false, we ran out of texture cache space 124860d155f866cc15a725e7ce03763280987f24901John Reck return !info.hasFunctors && info.prepareTextures; 125668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 126668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 127668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() { 128668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck AutoMutex _lock(mLock); 129668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mSignal.signal(); 130668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 131668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 132668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */ 133668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */ 134668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */ 135