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#include "DrawFrameTask.h" 18668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 19668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include <utils/Log.h> 20668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include <utils/Trace.h> 21668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 22d72e0a339b54af0c4e731513bbad120dff694723John Reck#include "../DeferredLayerUpdater.h" 23668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../DisplayList.h" 24668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../RenderNode.h" 25668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "CanvasContext.h" 26668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "RenderThread.h" 27668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 28668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace android { 29668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace uirenderer { 30668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace renderthread { 31668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 3218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn ReckDrawFrameTask::DrawFrameTask() 33d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : mRenderThread(nullptr) 34d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mContext(nullptr) 359a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck , mSyncResult(SyncResult::OK) { 36668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 37668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 38668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::~DrawFrameTask() { 39668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 40668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 41ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhnevoid DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context, 42ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne RenderNode* targetNode) { 4318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mRenderThread = thread; 44668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mContext = context; 45ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne mTargetNode = targetNode; 46668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 47668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 48d72e0a339b54af0c4e731513bbad120dff694723John Reckvoid DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) { 49d72e0a339b54af0c4e731513bbad120dff694723John Reck LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to pushLayerUpdate with!"); 50087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 51d72e0a339b54af0c4e731513bbad120dff694723John Reck for (size_t i = 0; i < mLayers.size(); i++) { 52d72e0a339b54af0c4e731513bbad120dff694723John Reck if (mLayers[i].get() == layer) { 53d72e0a339b54af0c4e731513bbad120dff694723John Reck return; 54d72e0a339b54af0c4e731513bbad120dff694723John Reck } 55d72e0a339b54af0c4e731513bbad120dff694723John Reck } 56d72e0a339b54af0c4e731513bbad120dff694723John Reck mLayers.push_back(layer); 57668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 58668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 59d72e0a339b54af0c4e731513bbad120dff694723John Reckvoid DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) { 60668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck for (size_t i = 0; i < mLayers.size(); i++) { 61d72e0a339b54af0c4e731513bbad120dff694723John Reck if (mLayers[i].get() == layer) { 62d72e0a339b54af0c4e731513bbad120dff694723John Reck mLayers.erase(mLayers.begin() + i); 63d72e0a339b54af0c4e731513bbad120dff694723John Reck return; 64668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 65668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 66668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 67668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 682de950d5a8b47c7b4648ada1b1260ce4b7342798John Reckint DrawFrameTask::drawFrame() { 69668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 70668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 719a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck mSyncResult = SyncResult::OK; 72be3fba05e823f740f65b2679929347dc3dd282adJohn Reck mSyncQueued = systemTime(CLOCK_MONOTONIC); 7318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck postAndWait(); 74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 75f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck return mSyncResult; 76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 77668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 7818f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::postAndWait() { 79087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck AutoMutex _lock(mLock); 80738ec3aace180018560998d1c2cdeb9ddde5fbfaChris Craik mRenderThread->queue(this); 81738ec3aace180018560998d1c2cdeb9ddde5fbfaChris Craik mSignal.wait(mLock); 82087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck} 83087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 84668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() { 85668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_NAME("DrawFrame"); 86668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 87a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck bool canUnblockUiThread; 88a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck bool canDrawThisFrame; 89a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck { 90e2e53a7079733694bd52dbce665e9ceff21e9727Chris Craik TreeInfo info(TreeInfo::MODE_FULL, *mContext); 91a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck canUnblockUiThread = syncFrameState(info); 92a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck canDrawThisFrame = info.out.canDrawThisFrame; 93a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 94668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 95668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // Grab a copy of everything we need 96668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck CanvasContext* context = mContext; 97668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck // From this point on anything in "this" is *UNSAFE TO ACCESS* 99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (canUnblockUiThread) { 100668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 101668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 102668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 103a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck if (CC_LIKELY(canDrawThisFrame)) { 104e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck context->draw(); 10506e2e9cf4c3fe1eaac3271c9a346d5cc7fe5c3a8Chris Craik } else { 10606e2e9cf4c3fe1eaac3271c9a346d5cc7fe5c3a8Chris Craik // wait on fences so tasks don't overlap next frame 10706e2e9cf4c3fe1eaac3271c9a346d5cc7fe5c3a8Chris Craik context->waitOnFences(); 108a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 109668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 110668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck if (!canUnblockUiThread) { 111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck unblockUiThread(); 112668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck } 113668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 114668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 115a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckbool DrawFrameTask::syncFrameState(TreeInfo& info) { 116668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck ATRACE_CALL(); 1171b54fb27ac48495ed0b33868fda5776fb49fe0f3Chris Craik int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)]; 118c87be99c6ead0720a8918ea38ce3b25e5c49e1c6John Reck mRenderThread->timeLord().vsyncReceived(vsync); 1198afcc76920499d0a384dba1470c5a377f80ed768John Reck bool canDraw = mContext->makeCurrent(); 120b7d34b64dd32e3d84bd43344c9c3d9ad098129afDerek Sollenberger mContext->unpinImages(); 121d72e0a339b54af0c4e731513bbad120dff694723John Reck 122d72e0a339b54af0c4e731513bbad120dff694723John Reck for (size_t i = 0; i < mLayers.size(); i++) { 123d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik mLayers[i]->apply(); 124d72e0a339b54af0c4e731513bbad120dff694723John Reck } 125d72e0a339b54af0c4e731513bbad120dff694723John Reck mLayers.clear(); 126ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne mContext->prepareTree(info, mFrameInfo, mSyncQueued, mTargetNode); 127d72e0a339b54af0c4e731513bbad120dff694723John Reck 128aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck // This is after the prepareTree so that any pending operations 129aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck // (RenderNode tree state, prefetched layers, etc...) will be flushed. 1308afcc76920499d0a384dba1470c5a377f80ed768John Reck if (CC_UNLIKELY(!mContext->hasSurface() || !canDraw)) { 1319a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck if (!mContext->hasSurface()) { 1329a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck mSyncResult |= SyncResult::LostSurfaceRewardIfFound; 1339a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck } else { 1349a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck // If we have a surface but can't draw we must be stopped 1359a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck mSyncResult |= SyncResult::ContextIsStopped; 1369a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck } 1378afcc76920499d0a384dba1470c5a377f80ed768John Reck info.out.canDrawThisFrame = false; 138aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck } 139aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck 140f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.hasAnimations) { 141f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.requiresUiRedraw) { 1429a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck mSyncResult |= SyncResult::UIRedrawRequired; 143f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } 14452244fff29042926e21fa897ef5ab11148e35299John Reck } 145860d155f866cc15a725e7ce03763280987f24901John Reck // If prepareTextures is false, we ran out of texture cache space 146826b56448691221e4cfe2f19a09c3d8790f78d2cBo Liu return info.prepareTextures; 147668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 148668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 149668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() { 150668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck AutoMutex _lock(mLock); 151668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck mSignal.signal(); 152668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} 153668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck 154668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */ 155668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */ 156668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */ 157