DrawFrameTask.cpp revision 18f16e6fba74eda173e1e7c869e6e2e2acc073ff
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
24668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../DisplayList.h"
25668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "../RenderNode.h"
26668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "CanvasContext.h"
27668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck#include "RenderThread.h"
28668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
29668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace android {
30668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace uirenderer {
31668f0e38ef0277d55d3118af37e17b8c435df85cJohn Recknamespace renderthread {
32668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
3318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn ReckDrawFrameTask::DrawFrameTask()
3418f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        : mRenderThread(NULL)
3518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        , mContext(NULL)
3618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        , mFrameTimeNanos(NULL) {
37668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
38668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
39668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::~DrawFrameTask() {
40668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
41668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
4218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context) {
4318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mRenderThread = thread;
44668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mContext = context;
45668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
46668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
47668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::addLayer(DeferredLayerUpdater* layer) {
48087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck    LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!");
49087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck
50668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mLayers.push(layer);
51668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
52668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
53668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) {
54668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    for (size_t i = 0; i < mLayers.size(); i++) {
55668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        if (mLayers[i] == layer) {
56668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck            mLayers.removeAt(i);
57668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck            break;
58668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        }
59668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
60668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
61668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
62668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDirty(int left, int top, int right, int bottom) {
63668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDirty.set(left, top, right, bottom);
64668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
65668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
6618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::drawFrame(nsecs_t frameTimeNanos) {
67668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
68668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
6918f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mFrameTimeNanos = frameTimeNanos;
7018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    postAndWait();
71668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
72668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // Reset the single-frame data
7318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mFrameTimeNanos = 0;
74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDirty.setEmpty();
75668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
7718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid DrawFrameTask::postAndWait() {
78087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck    AutoMutex _lock(mLock);
7918f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mRenderThread->queue(this);
80087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck    mSignal.wait(mLock);
81087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck}
82087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck
83668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() {
84668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    ATRACE_NAME("DrawFrame");
85668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
86f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck    bool canUnblockUiThread = syncFrameState();
87668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
88668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // Grab a copy of everything we need
89e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    Rect dirty(mDirty);
90668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    CanvasContext* context = mContext;
91668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
92668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // From this point on anything in "this" is *UNSAFE TO ACCESS*
93668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    if (canUnblockUiThread) {
94668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        unblockUiThread();
95668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
96668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
97e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    context->draw(&dirty);
98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    if (!canUnblockUiThread) {
100668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        unblockUiThread();
101668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
102668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
103668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
104e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic void initTreeInfo(TreeInfo& info) {
105860d155f866cc15a725e7ce03763280987f24901John Reck    info.prepareTextures = true;
106e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    info.performStagingPush = true;
107e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    info.evaluateAnimations = true;
108860d155f866cc15a725e7ce03763280987f24901John Reck}
109860d155f866cc15a725e7ce03763280987f24901John Reck
110f4198b713e43c0c0f9adac74203cf24c2a49b802John Reckbool DrawFrameTask::syncFrameState() {
111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    ATRACE_CALL();
11218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos);
113860d155f866cc15a725e7ce03763280987f24901John Reck    mContext->makeCurrent();
114860d155f866cc15a725e7ce03763280987f24901John Reck    Caches::getInstance().textureCache.resetMarkInUse();
115860d155f866cc15a725e7ce03763280987f24901John Reck    TreeInfo info;
116e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    initTreeInfo(info);
117860d155f866cc15a725e7ce03763280987f24901John Reck    mContext->processLayerUpdates(&mLayers, info);
118e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    mContext->prepareTree(info);
11952244fff29042926e21fa897ef5ab11148e35299John Reck    if (info.hasAnimations) {
12052244fff29042926e21fa897ef5ab11148e35299John Reck        // TODO: dirty calculations, for now just do a full-screen inval
12152244fff29042926e21fa897ef5ab11148e35299John Reck        mDirty.setEmpty();
12252244fff29042926e21fa897ef5ab11148e35299John Reck    }
123860d155f866cc15a725e7ce03763280987f24901John Reck    // If prepareTextures is false, we ran out of texture cache space
124860d155f866cc15a725e7ce03763280987f24901John Reck    return !info.hasFunctors && info.prepareTextures;
125668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
126668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
127668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() {
128668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    AutoMutex _lock(mLock);
129668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mSignal.signal();
130668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
131668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
132668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */
133668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */
134668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */
135