DrawFrameTask.cpp revision 668f0e38ef0277d55d3118af37e17b8c435df85c
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
33668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::DrawFrameTask() : mContext(0), mRenderNode(0) {
34668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
35668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
36668f0e38ef0277d55d3118af37e17b8c435df85cJohn ReckDrawFrameTask::~DrawFrameTask() {
37668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
38668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
39668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setContext(CanvasContext* context) {
40668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mContext = context;
41668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
42668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
43668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
44668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    SetDisplayListData setter;
45668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    setter.targetNode = renderNode;
46668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    setter.newData = newData;
47668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDisplayListDataUpdates.push(setter);
48668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
49668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
50668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::addLayer(DeferredLayerUpdater* layer) {
51668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mLayers.push(layer);
52668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
53668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
54668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) {
55668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    for (size_t i = 0; i < mLayers.size(); i++) {
56668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        if (mLayers[i] == layer) {
57668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck            mLayers.removeAt(i);
58668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck            break;
59668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        }
60668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
61668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
62668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
63668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setRenderNode(RenderNode* renderNode) {
64668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mRenderNode = renderNode;
65668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
66668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
67668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::setDirty(int left, int top, int right, int bottom) {
68668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDirty.set(left, top, right, bottom);
69668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
70668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
71668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::drawFrame(RenderThread* renderThread) {
72668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    LOG_ALWAYS_FATAL_IF(!mRenderNode, "Cannot drawFrame with no render node!");
73668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
74668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
75668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    AutoMutex _lock(mLock);
76668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    renderThread->queue(this);
77668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mSignal.wait(mLock);
78668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
79668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // Reset the single-frame data
80668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDirty.setEmpty();
81668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mRenderNode = 0;
82668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
83668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
84668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::run() {
85668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    ATRACE_NAME("DrawFrame");
86668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
87668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    syncFrameState();
88668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
89668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // Grab a copy of everything we need
90668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    Rect dirtyCopy(mDirty);
91668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    RenderNode* renderNode = mRenderNode;
92668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    CanvasContext* context = mContext;
93668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
94668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // This is temporary until WebView has a solution for syncing frame state
95668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    bool canUnblockUiThread = !requiresSynchronousDraw(renderNode);
96668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
97668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    // From this point on anything in "this" is *UNSAFE TO ACCESS*
98668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    if (canUnblockUiThread) {
99668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        unblockUiThread();
100668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
101668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
102668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    drawRenderNode(context, renderNode, &dirtyCopy);
103668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
104668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    if (!canUnblockUiThread) {
105668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        unblockUiThread();
106668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
107668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
108668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
109668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::syncFrameState() {
110668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    ATRACE_CALL();
111668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
112668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) {
113668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        const SetDisplayListData& setter = mDisplayListDataUpdates[i];
114668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        setter.targetNode->setData(setter.newData);
115668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
116668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mDisplayListDataUpdates.clear();
117668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
118668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mContext->processLayerUpdates(&mLayers);
119668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mRenderNode->updateProperties();
120668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
121668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
122668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::unblockUiThread() {
123668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    AutoMutex _lock(mLock);
124668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    mSignal.signal();
125668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
126668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
127668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckvoid DrawFrameTask::drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty) {
128668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    ATRACE_CALL();
129668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
130668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    if (dirty->bottom == -1 && dirty->left == -1
131668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck            && dirty->top == -1 && dirty->right == -1) {
132668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck        dirty = 0;
133668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    }
134668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    context->drawDisplayList(renderNode, dirty);
135668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
136668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
137668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reckbool DrawFrameTask::requiresSynchronousDraw(RenderNode* renderNode) {
138668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck    return renderNode->hasFunctors();
139668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck}
140668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck
141668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace renderthread */
142668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace uirenderer */
143668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck} /* namespace android */
144