DrawFrameTask.cpp revision d72e0a339b54af0c4e731513bbad120dff694723
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
71668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDirty(int left, int top, int right, int bottom) {
72668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDirty.set(left, top, right, bottom);
73668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
75fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckint DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos) {
76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
77668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
78f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    mSyncResult = kSync_OK;
7918f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mFrameTimeNanos = frameTimeNanos;
80fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    mRecordDurationNanos = recordDurationNanos;
8118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    postAndWait();
82668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
83668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // Reset the single-frame data
8418f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mFrameTimeNanos = 0;
85fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    mRecordDurationNanos = 0;
86668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDirty.setEmpty();
87f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
88f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    return mSyncResult;
89668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
90668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
9118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::postAndWait() {
92087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck    AutoMutex _lock(mLock);
9318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mRenderThread->queue(this);
94087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck    mSignal.wait(mLock);
95087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck}
96087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck
97668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() {
98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    ATRACE_NAME("DrawFrame");
99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
100fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    mContext->profiler().setDensity(mDensity);
101fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    mContext->profiler().startFrame(mRecordDurationNanos);
102fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
103a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    bool canUnblockUiThread;
104a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    bool canDrawThisFrame;
105a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    {
106a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        TreeInfo info;
107a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        canUnblockUiThread = syncFrameState(info);
108a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        canDrawThisFrame = info.out.canDrawThisFrame;
109a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
110668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // Grab a copy of everything we need
112e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    Rect dirty(mDirty);
113668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    CanvasContext* context = mContext;
114668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
115668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // From this point on anything in "this" is *UNSAFE TO ACCESS*
116668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    if (canUnblockUiThread) {
117668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        unblockUiThread();
118668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
119668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
120a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    if (CC_LIKELY(canDrawThisFrame)) {
121a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        context->draw(&dirty);
122a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
123668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
124668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    if (!canUnblockUiThread) {
125668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        unblockUiThread();
126668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
127668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
128668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
129e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic void initTreeInfo(TreeInfo& info) {
130860d155f866cc15a725e7ce03763280987f24901John Reck    info.prepareTextures = true;
131e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    info.performStagingPush = true;
132e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    info.evaluateAnimations = true;
133860d155f866cc15a725e7ce03763280987f24901John Reck}
134860d155f866cc15a725e7ce03763280987f24901John Reck
135a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckbool DrawFrameTask::syncFrameState(TreeInfo& info) {
136668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    ATRACE_CALL();
13718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos);
138860d155f866cc15a725e7ce03763280987f24901John Reck    mContext->makeCurrent();
139860d155f866cc15a725e7ce03763280987f24901John Reck    Caches::getInstance().textureCache.resetMarkInUse();
140e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    initTreeInfo(info);
141d72e0a339b54af0c4e731513bbad120dff694723John Reck
142d72e0a339b54af0c4e731513bbad120dff694723John Reck    for (size_t i = 0; i < mLayers.size(); i++) {
143d72e0a339b54af0c4e731513bbad120dff694723John Reck        mContext->processLayerUpdate(mLayers[i].get(), info);
144d72e0a339b54af0c4e731513bbad120dff694723John Reck    }
145d72e0a339b54af0c4e731513bbad120dff694723John Reck    mLayers.clear();
146d72e0a339b54af0c4e731513bbad120dff694723John Reck    if (info.out.hasAnimations) {
147d72e0a339b54af0c4e731513bbad120dff694723John Reck        // TODO: Uh... crap?
148d72e0a339b54af0c4e731513bbad120dff694723John Reck    }
149d72e0a339b54af0c4e731513bbad120dff694723John Reck    mContext->prepareTree(info);
150d72e0a339b54af0c4e731513bbad120dff694723John Reck
151f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    if (info.out.hasAnimations) {
15252244fff29042926e21fa897ef5ab11148e35299John Reck        // TODO: dirty calculations, for now just do a full-screen inval
15352244fff29042926e21fa897ef5ab11148e35299John Reck        mDirty.setEmpty();
154f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if (info.out.requiresUiRedraw) {
155f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            mSyncResult |= kSync_UIRedrawRequired;
156f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
15752244fff29042926e21fa897ef5ab11148e35299John Reck    }
158860d155f866cc15a725e7ce03763280987f24901John Reck    // If prepareTextures is false, we ran out of texture cache space
159f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    return !info.out.hasFunctors && info.prepareTextures;
160668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
161668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
162668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() {
163668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    AutoMutex _lock(mLock);
164668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mSignal.signal();
165668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
166668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
167668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */
168668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */
169668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */
170