DrawFrameTask.cpp revision e4267ea4f20740c37c01bfb6aefcf61fddc4566a
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 71fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckint DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos) { 72668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 73668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 74f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mSyncResult = kSync_OK; 7518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mFrameTimeNanos = frameTimeNanos; 76fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mRecordDurationNanos = recordDurationNanos; 7718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck postAndWait(); 78668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 79668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Reset the single-frame data 8018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mFrameTimeNanos = 0; 81fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mRecordDurationNanos = 0; 82f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck 83f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck return mSyncResult; 84668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 85668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 8618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::postAndWait() { 87087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck AutoMutex _lock(mLock); 8818f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread->queue(this); 89087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck mSignal.wait(mLock); 90087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck} 91087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 92668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() { 93668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_NAME("DrawFrame"); 94668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 95fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mContext->profiler().setDensity(mDensity); 96fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck mContext->profiler().startFrame(mRecordDurationNanos); 97fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 98a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck bool canUnblockUiThread; 99a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck bool canDrawThisFrame; 100a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck { 101e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck TreeInfo info(TreeInfo::MODE_FULL); 102a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck canUnblockUiThread = syncFrameState(info); 103a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck canDrawThisFrame = info.out.canDrawThisFrame; 104a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 105668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 106668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Grab a copy of everything we need 107668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck CanvasContext* context = mContext; 108668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 109668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // From this point on anything in "this" is *UNSAFE TO ACCESS* 110668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (canUnblockUiThread) { 111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 112668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 113668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 114a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck if (CC_LIKELY(canDrawThisFrame)) { 115e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck context->draw(); 116a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 117668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 118668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (!canUnblockUiThread) { 119668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 120668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 121668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 122668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 123a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckbool DrawFrameTask::syncFrameState(TreeInfo& info) { 124668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 12518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos); 126860d155f866cc15a725e7ce03763280987f24901John Reck mContext->makeCurrent(); 127860d155f866cc15a725e7ce03763280987f24901John Reck Caches::getInstance().textureCache.resetMarkInUse(); 128d72e0a339b54af0c4e731513bbad120dff694723John Reck 129d72e0a339b54af0c4e731513bbad120dff694723John Reck for (size_t i = 0; i < mLayers.size(); i++) { 130d72e0a339b54af0c4e731513bbad120dff694723John Reck mContext->processLayerUpdate(mLayers[i].get(), info); 131d72e0a339b54af0c4e731513bbad120dff694723John Reck } 132d72e0a339b54af0c4e731513bbad120dff694723John Reck mLayers.clear(); 133d72e0a339b54af0c4e731513bbad120dff694723John Reck if (info.out.hasAnimations) { 134d72e0a339b54af0c4e731513bbad120dff694723John Reck // TODO: Uh... crap? 135d72e0a339b54af0c4e731513bbad120dff694723John Reck } 136d72e0a339b54af0c4e731513bbad120dff694723John Reck mContext->prepareTree(info); 137d72e0a339b54af0c4e731513bbad120dff694723John Reck 138f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.hasAnimations) { 139f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.requiresUiRedraw) { 140f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mSyncResult |= kSync_UIRedrawRequired; 141f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } 14252244fff29042926e21fa897ef5ab11148e35299John Reck } 143860d155f866cc15a725e7ce03763280987f24901John Reck // If prepareTextures is false, we ran out of texture cache space 144f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck return !info.out.hasFunctors && info.prepareTextures; 145668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 146668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 147668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() { 148668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck AutoMutex _lock(mLock); 149668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mSignal.signal(); 150668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 151668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 152668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */ 153668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */ 154668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */ 155