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