DrawFrameTask.cpp revision d5a4a1aac980c304d6f46f07f15bfc5c94d8f9d0
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define ATRACE_TAG ATRACE_TAG_VIEW 18 19#include "DrawFrameTask.h" 20 21#include <utils/Log.h> 22#include <utils/Trace.h> 23 24#include "../DeferredLayerUpdater.h" 25#include "../DisplayList.h" 26#include "../RenderNode.h" 27#include "CanvasContext.h" 28#include "RenderThread.h" 29 30namespace android { 31namespace uirenderer { 32namespace renderthread { 33 34DrawFrameTask::DrawFrameTask() 35 : mRenderThread(NULL) 36 , mContext(NULL) 37 , mDensity(1.0f) // safe enough default 38 , mSyncResult(kSync_OK) { 39} 40 41DrawFrameTask::~DrawFrameTask() { 42} 43 44void DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context) { 45 mRenderThread = thread; 46 mContext = context; 47} 48 49void DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) { 50 LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to pushLayerUpdate with!"); 51 52 for (size_t i = 0; i < mLayers.size(); i++) { 53 if (mLayers[i].get() == layer) { 54 return; 55 } 56 } 57 mLayers.push_back(layer); 58} 59 60void DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) { 61 for (size_t i = 0; i < mLayers.size(); i++) { 62 if (mLayers[i].get() == layer) { 63 mLayers.erase(mLayers.begin() + i); 64 return; 65 } 66 } 67} 68 69int DrawFrameTask::drawFrame() { 70 LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); 71 72 mSyncResult = kSync_OK; 73 postAndWait(); 74 75 return mSyncResult; 76} 77 78void DrawFrameTask::postAndWait() { 79 AutoMutex _lock(mLock); 80 mRenderThread->queue(this); 81 mSignal.wait(mLock); 82} 83 84void DrawFrameTask::run() { 85 ATRACE_NAME("DrawFrame"); 86 87 mContext->profiler().setDensity(mDensity); 88 mContext->profiler().startFrame(); 89 90 bool canUnblockUiThread; 91 bool canDrawThisFrame; 92 { 93 TreeInfo info(TreeInfo::MODE_FULL, mRenderThread->renderState()); 94 canUnblockUiThread = syncFrameState(info); 95 canDrawThisFrame = info.out.canDrawThisFrame; 96 } 97 98 // Grab a copy of everything we need 99 CanvasContext* context = mContext; 100 101 // From this point on anything in "this" is *UNSAFE TO ACCESS* 102 if (canUnblockUiThread) { 103 unblockUiThread(); 104 } 105 106 if (CC_LIKELY(canDrawThisFrame)) { 107 context->draw(); 108 } 109 110 if (!canUnblockUiThread) { 111 unblockUiThread(); 112 } 113} 114 115bool DrawFrameTask::syncFrameState(TreeInfo& info) { 116 ATRACE_CALL(); 117 mRenderThread->timeLord().vsyncReceived(mFrameInfo[FrameInfoIndex::kVsync]); 118 mContext->makeCurrent(); 119 Caches::getInstance().textureCache.resetMarkInUse(); 120 121 for (size_t i = 0; i < mLayers.size(); i++) { 122 mContext->processLayerUpdate(mLayers[i].get()); 123 } 124 mLayers.clear(); 125 mContext->prepareTree(info, mFrameInfo); 126 127 // This is after the prepareTree so that any pending operations 128 // (RenderNode tree state, prefetched layers, etc...) will be flushed. 129 if (CC_UNLIKELY(!mContext->hasSurface())) { 130 mSyncResult |= kSync_LostSurfaceRewardIfFound; 131 } 132 133 if (info.out.hasAnimations) { 134 if (info.out.requiresUiRedraw) { 135 mSyncResult |= kSync_UIRedrawRequired; 136 } 137 } 138 // If prepareTextures is false, we ran out of texture cache space 139 return info.prepareTextures; 140} 141 142void DrawFrameTask::unblockUiThread() { 143 AutoMutex _lock(mLock); 144 mSignal.signal(); 145} 146 147} /* namespace renderthread */ 148} /* namespace uirenderer */ 149} /* namespace android */ 150