DrawFrameTask.cpp revision aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19
178e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar/* 278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Copyright (C) 2014 The Android Open Source Project 378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * 478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License"); 578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * you may not use this file except in compliance with the License. 678e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * You may obtain a copy of the License at 778e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * 878e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * http://www.apache.org/licenses/LICENSE-2.0 978e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * 1078e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Unless required by applicable law or agreed to in writing, software 1178e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS, 1278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * See the License for the specific language governing permissions and 1478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * limitations under the License. 1578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar */ 160c1bc742181ded4930842b46e9507372f0b1b963James Dong 170c1bc742181ded4930842b46e9507372f0b1b963James Dong#define ATRACE_TAG ATRACE_TAG_VIEW 180c1bc742181ded4930842b46e9507372f0b1b963James Dong 190c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "DrawFrameTask.h" 200c1bc742181ded4930842b46e9507372f0b1b963James Dong 210c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <utils/Log.h> 220c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <utils/Trace.h> 230c1bc742181ded4930842b46e9507372f0b1b963James Dong 240c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "../DeferredLayerUpdater.h" 250c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "../DisplayList.h" 260c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "../RenderNode.h" 270c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "CanvasContext.h" 280c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "RenderThread.h" 290c1bc742181ded4930842b46e9507372f0b1b963James Dong 300c1bc742181ded4930842b46e9507372f0b1b963James Dongnamespace android { 310c1bc742181ded4930842b46e9507372f0b1b963James Dongnamespace uirenderer { 320c1bc742181ded4930842b46e9507372f0b1b963James Dongnamespace renderthread { 330c1bc742181ded4930842b46e9507372f0b1b963James Dong 340c1bc742181ded4930842b46e9507372f0b1b963James DongDrawFrameTask::DrawFrameTask() 350c1bc742181ded4930842b46e9507372f0b1b963James Dong : mRenderThread(NULL) 360c1bc742181ded4930842b46e9507372f0b1b963James Dong , mContext(NULL) 370c1bc742181ded4930842b46e9507372f0b1b963James Dong , mFrameTimeNanos(0) 380c1bc742181ded4930842b46e9507372f0b1b963James Dong , mRecordDurationNanos(0) 390c1bc742181ded4930842b46e9507372f0b1b963James Dong , mDensity(1.0f) // safe enough default 400c1bc742181ded4930842b46e9507372f0b1b963James Dong , mSyncResult(kSync_OK) { 410c1bc742181ded4930842b46e9507372f0b1b963James Dong} 420c1bc742181ded4930842b46e9507372f0b1b963James Dong 430c1bc742181ded4930842b46e9507372f0b1b963James DongDrawFrameTask::~DrawFrameTask() { 440c1bc742181ded4930842b46e9507372f0b1b963James Dong} 450c1bc742181ded4930842b46e9507372f0b1b963James Dong 460c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context) { 470c1bc742181ded4930842b46e9507372f0b1b963James Dong mRenderThread = thread; 480c1bc742181ded4930842b46e9507372f0b1b963James Dong mContext = context; 490c1bc742181ded4930842b46e9507372f0b1b963James Dong} 500c1bc742181ded4930842b46e9507372f0b1b963James Dong 510c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) { 520c1bc742181ded4930842b46e9507372f0b1b963James Dong LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to pushLayerUpdate with!"); 530c1bc742181ded4930842b46e9507372f0b1b963James Dong 540c1bc742181ded4930842b46e9507372f0b1b963James Dong for (size_t i = 0; i < mLayers.size(); i++) { 550c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mLayers[i].get() == layer) { 560c1bc742181ded4930842b46e9507372f0b1b963James Dong return; 570c1bc742181ded4930842b46e9507372f0b1b963James Dong } 580c1bc742181ded4930842b46e9507372f0b1b963James Dong } 590c1bc742181ded4930842b46e9507372f0b1b963James Dong mLayers.push_back(layer); 600c1bc742181ded4930842b46e9507372f0b1b963James Dong} 610c1bc742181ded4930842b46e9507372f0b1b963James Dong 620c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) { 630c1bc742181ded4930842b46e9507372f0b1b963James Dong for (size_t i = 0; i < mLayers.size(); i++) { 640c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mLayers[i].get() == layer) { 650c1bc742181ded4930842b46e9507372f0b1b963James Dong mLayers.erase(mLayers.begin() + i); 660c1bc742181ded4930842b46e9507372f0b1b963James Dong return; 670c1bc742181ded4930842b46e9507372f0b1b963James Dong } 680c1bc742181ded4930842b46e9507372f0b1b963James Dong } 690c1bc742181ded4930842b46e9507372f0b1b963James Dong} 700c1bc742181ded4930842b46e9507372f0b1b963James Dong 710c1bc742181ded4930842b46e9507372f0b1b963James Dongint DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos) { 720c1bc742181ded4930842b46e9507372f0b1b963James Dong LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 730c1bc742181ded4930842b46e9507372f0b1b963James Dong 740c1bc742181ded4930842b46e9507372f0b1b963James Dong mSyncResult = kSync_OK; 750c1bc742181ded4930842b46e9507372f0b1b963James Dong mFrameTimeNanos = frameTimeNanos; 760c1bc742181ded4930842b46e9507372f0b1b963James Dong mRecordDurationNanos = recordDurationNanos; 770c1bc742181ded4930842b46e9507372f0b1b963James Dong postAndWait(); 780c1bc742181ded4930842b46e9507372f0b1b963James Dong 790c1bc742181ded4930842b46e9507372f0b1b963James Dong // Reset the single-frame data 800c1bc742181ded4930842b46e9507372f0b1b963James Dong mFrameTimeNanos = 0; 810c1bc742181ded4930842b46e9507372f0b1b963James Dong mRecordDurationNanos = 0; 820c1bc742181ded4930842b46e9507372f0b1b963James Dong 830c1bc742181ded4930842b46e9507372f0b1b963James Dong return mSyncResult; 840c1bc742181ded4930842b46e9507372f0b1b963James Dong} 850c1bc742181ded4930842b46e9507372f0b1b963James Dong 860c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid DrawFrameTask::postAndWait() { 870c1bc742181ded4930842b46e9507372f0b1b963James Dong AutoMutex _lock(mLock); 880c1bc742181ded4930842b46e9507372f0b1b963James Dong mRenderThread->queue(this); 890c1bc742181ded4930842b46e9507372f0b1b963James Dong mSignal.wait(mLock); 900c1bc742181ded4930842b46e9507372f0b1b963James Dong} 910c1bc742181ded4930842b46e9507372f0b1b963James Dong 920c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid DrawFrameTask::run() { 930c1bc742181ded4930842b46e9507372f0b1b963James Dong ATRACE_NAME("DrawFrame"); 940c1bc742181ded4930842b46e9507372f0b1b963James Dong 950c1bc742181ded4930842b46e9507372f0b1b963James Dong mContext->profiler().setDensity(mDensity); 960c1bc742181ded4930842b46e9507372f0b1b963James Dong mContext->profiler().startFrame(mRecordDurationNanos); 970c1bc742181ded4930842b46e9507372f0b1b963James Dong 980c1bc742181ded4930842b46e9507372f0b1b963James Dong bool canUnblockUiThread; 990c1bc742181ded4930842b46e9507372f0b1b963James Dong bool canDrawThisFrame; 1000c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1010c1bc742181ded4930842b46e9507372f0b1b963James Dong TreeInfo info(TreeInfo::MODE_FULL, mRenderThread->renderState()); 1020c1bc742181ded4930842b46e9507372f0b1b963James Dong canUnblockUiThread = syncFrameState(info); 1030c1bc742181ded4930842b46e9507372f0b1b963James Dong canDrawThisFrame = info.out.canDrawThisFrame; 1040c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1050c1bc742181ded4930842b46e9507372f0b1b963James Dong 1060c1bc742181ded4930842b46e9507372f0b1b963James Dong // Grab a copy of everything we need 1070c1bc742181ded4930842b46e9507372f0b1b963James Dong CanvasContext* context = mContext; 1080c1bc742181ded4930842b46e9507372f0b1b963James Dong 1090c1bc742181ded4930842b46e9507372f0b1b963James Dong // From this point on anything in "this" is *UNSAFE TO ACCESS* 1100c1bc742181ded4930842b46e9507372f0b1b963James Dong if (canUnblockUiThread) { 1110c1bc742181ded4930842b46e9507372f0b1b963James Dong unblockUiThread(); 1120c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1130c1bc742181ded4930842b46e9507372f0b1b963James Dong 1140c1bc742181ded4930842b46e9507372f0b1b963James Dong if (CC_LIKELY(canDrawThisFrame)) { 1150c1bc742181ded4930842b46e9507372f0b1b963James Dong context->draw(); 1160c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1170c1bc742181ded4930842b46e9507372f0b1b963James Dong 1180c1bc742181ded4930842b46e9507372f0b1b963James Dong if (!canUnblockUiThread) { 1190c1bc742181ded4930842b46e9507372f0b1b963James Dong unblockUiThread(); 1200c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1210c1bc742181ded4930842b46e9507372f0b1b963James Dong} 1220c1bc742181ded4930842b46e9507372f0b1b963James Dong 1230c1bc742181ded4930842b46e9507372f0b1b963James Dongbool DrawFrameTask::syncFrameState(TreeInfo& info) { 1240c1bc742181ded4930842b46e9507372f0b1b963James Dong ATRACE_CALL(); 1250c1bc742181ded4930842b46e9507372f0b1b963James Dong mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos); 1260c1bc742181ded4930842b46e9507372f0b1b963James Dong mContext->makeCurrent(); 1270c1bc742181ded4930842b46e9507372f0b1b963James Dong Caches::getInstance().textureCache.resetMarkInUse(); 1280c1bc742181ded4930842b46e9507372f0b1b963James Dong 1290c1bc742181ded4930842b46e9507372f0b1b963James Dong for (size_t i = 0; i < mLayers.size(); i++) { 1300c1bc742181ded4930842b46e9507372f0b1b963James Dong mContext->processLayerUpdate(mLayers[i].get()); 1310c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1320c1bc742181ded4930842b46e9507372f0b1b963James Dong mLayers.clear(); 1330c1bc742181ded4930842b46e9507372f0b1b963James Dong mContext->prepareTree(info); 1340c1bc742181ded4930842b46e9507372f0b1b963James Dong 1350c1bc742181ded4930842b46e9507372f0b1b963James Dong // This is after the prepareTree so that any pending operations 1360c1bc742181ded4930842b46e9507372f0b1b963James Dong // (RenderNode tree state, prefetched layers, etc...) will be flushed. 1370c1bc742181ded4930842b46e9507372f0b1b963James Dong if (CC_UNLIKELY(!mContext->hasSurface())) { 1380c1bc742181ded4930842b46e9507372f0b1b963James Dong mSyncResult |= kSync_LostSurfaceRewardIfFound; 1390c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1400c1bc742181ded4930842b46e9507372f0b1b963James Dong 1410c1bc742181ded4930842b46e9507372f0b1b963James Dong if (info.out.hasAnimations) { 1420c1bc742181ded4930842b46e9507372f0b1b963James Dong if (info.out.requiresUiRedraw) { 1430c1bc742181ded4930842b46e9507372f0b1b963James Dong mSyncResult |= kSync_UIRedrawRequired; 1440c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1450c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1460c1bc742181ded4930842b46e9507372f0b1b963James Dong // If prepareTextures is false, we ran out of texture cache space 1470c1bc742181ded4930842b46e9507372f0b1b963James Dong return info.prepareTextures; 1480c1bc742181ded4930842b46e9507372f0b1b963James Dong} 1490c1bc742181ded4930842b46e9507372f0b1b963James Dong 1500c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid DrawFrameTask::unblockUiThread() { 1510c1bc742181ded4930842b46e9507372f0b1b963James Dong AutoMutex _lock(mLock); 1520c1bc742181ded4930842b46e9507372f0b1b963James Dong mSignal.signal(); 1530c1bc742181ded4930842b46e9507372f0b1b963James Dong} 1540c1bc742181ded4930842b46e9507372f0b1b963James Dong 1550c1bc742181ded4930842b46e9507372f0b1b963James Dong} /* namespace renderthread */ 1560c1bc742181ded4930842b46e9507372f0b1b963James Dong} /* namespace uirenderer */ 1570c1bc742181ded4930842b46e9507372f0b1b963James Dong} /* namespace android */ 1580c1bc742181ded4930842b46e9507372f0b1b963James Dong