CanvasContext.cpp revision 3e8249568cc428296ac76c7ddce3f0382d40fe5b
123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck/*
223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * Copyright (C) 2014 The Android Open Source Project
323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck *
423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * Licensed under the Apache License, Version 2.0 (the "License");
523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * you may not use this file except in compliance with the License.
623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * You may obtain a copy of the License at
723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck *
823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck *      http://www.apache.org/licenses/LICENSE-2.0
923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck *
1023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * Unless required by applicable law or agreed to in writing, software
1123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * distributed under the License is distributed on an "AS IS" BASIS,
1223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * See the License for the specific language governing permissions and
1423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck * limitations under the License.
1523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck */
1623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
1723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include "CanvasContext.h"
1823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include <private/hwui/DrawGlInfo.h>
2023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include <strings.h>
2123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
223b20251a355c88193c439f928a84ae69483fb488John Reck#include "EglManager.h"
234f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include "RenderThread.h"
2423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include "../Caches.h"
2519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck#include "../DeferredLayerUpdater.h"
263b20251a355c88193c439f928a84ae69483fb488John Reck#include "../RenderState.h"
2719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck#include "../LayerRenderer.h"
284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include "../OpenGLRenderer.h"
2923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include "../Stencil.h"
3023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
31f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck#define TRIM_MEMORY_COMPLETE 80
32f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck#define TRIM_MEMORY_UI_HIDDEN 20
33f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
3423b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace android {
3523b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace uirenderer {
3623b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace renderthread {
3723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
383b20251a355c88193c439f928a84ae69483fb488John ReckCanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode)
393b20251a355c88193c439f928a84ae69483fb488John Reck        : mRenderThread(thread)
403b20251a355c88193c439f928a84ae69483fb488John Reck        , mEglManager(thread.eglManager())
414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        , mEglSurface(EGL_NO_SURFACE)
424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        , mDirtyRegionsEnabled(false)
434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        , mOpaque(!translucent)
443b20251a355c88193c439f928a84ae69483fb488John Reck        , mCanvas(NULL)
45e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        , mHaveNewSurface(false)
46e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        , mRootRenderNode(rootRenderNode) {
4723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}
4823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
4923b797ab5151eb2474f3bdd679f2f07bfd723042John ReckCanvasContext::~CanvasContext() {
50fae904d63947fe1687d1d44be29234cc3d538f24John Reck    destroyCanvasAndSurface();
51e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    mRenderThread.removeFrameCallback(this);
524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
54fae904d63947fe1687d1d44be29234cc3d538f24John Reckvoid CanvasContext::destroyCanvasAndSurface() {
554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    if (mCanvas) {
564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        delete mCanvas;
574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        mCanvas = 0;
584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
5923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck    setSurface(NULL);
6023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}
6123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
62a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::setSurface(ANativeWindow* window) {
63a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    mNativeWindow = window;
64a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
6523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck    if (mEglSurface != EGL_NO_SURFACE) {
663b20251a355c88193c439f928a84ae69483fb488John Reck        mEglManager.destroySurface(mEglSurface);
6723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck        mEglSurface = EGL_NO_SURFACE;
6823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck    }
6923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
7023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck    if (window) {
713b20251a355c88193c439f928a84ae69483fb488John Reck        mEglSurface = mEglManager.createSurface(window);
7223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck    }
7323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
7423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck    if (mEglSurface != EGL_NO_SURFACE) {
753b20251a355c88193c439f928a84ae69483fb488John Reck        mDirtyRegionsEnabled = mEglManager.enableDirtyRegions(mEglSurface);
764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        mHaveNewSurface = true;
77dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck        makeCurrent();
78368cdd85268999997fb495cf90c4417221797de0John Reck    } else {
79368cdd85268999997fb495cf90c4417221797de0John Reck        mRenderThread.removeFrameCallback(this);
804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::swapBuffers() {
843b20251a355c88193c439f928a84ae69483fb488John Reck    mEglManager.swapBuffers(mEglSurface);
854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    mHaveNewSurface = false;
864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
88f7d9c1dc84671d4e99657ef071d275700d85bb11John Reckvoid CanvasContext::requireSurface() {
89f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
90f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            "requireSurface() called but no surface set!");
91dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck    makeCurrent();
924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
94a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckbool CanvasContext::initialize(ANativeWindow* window) {
954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    if (mCanvas) return false;
964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    setSurface(window);
973b20251a355c88193c439f928a84ae69483fb488John Reck    mCanvas = new OpenGLRenderer(mRenderThread.renderState());
984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    mCanvas->initProperties();
994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    return true;
1004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
1014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
102a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::updateSurface(ANativeWindow* window) {
1034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    setSurface(window);
104f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck}
105f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
106a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::pauseSurface(ANativeWindow* window) {
107f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    // TODO: For now we just need a fence, in the future suspend any animations
108f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    // and such to prevent from trying to render into this surface
1094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
1104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
111058fc640017c90120c599d378a4cbc55668b05b7Chris Craikvoid CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius,
112058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
1134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    if (!mCanvas) return;
1144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    mCanvas->setViewport(width, height);
115058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    mCanvas->initLight(lightCenter, lightRadius, ambientShadowAlpha, spotShadowAlpha);
1164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck}
1174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
11863a06673253914510bbeebd500655008682dade1John Reckvoid CanvasContext::setOpaque(bool opaque) {
11963a06673253914510bbeebd500655008682dade1John Reck    mOpaque = opaque;
12063a06673253914510bbeebd500655008682dade1John Reck}
12163a06673253914510bbeebd500655008682dade1John Reck
122860d155f866cc15a725e7ce03763280987f24901John Reckvoid CanvasContext::makeCurrent() {
123dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck    // TODO: Figure out why this workaround is needed, see b/13913604
124dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck    // In the meantime this matches the behavior of GLRenderer, so it is not a regression
1253b20251a355c88193c439f928a84ae69483fb488John Reck    mHaveNewSurface |= mEglManager.makeCurrent(mEglSurface);
126860d155f866cc15a725e7ce03763280987f24901John Reck}
127860d155f866cc15a725e7ce03763280987f24901John Reck
12868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckvoid CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) {
12968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck    bool success = layerUpdater->apply();
130d72e0a339b54af0c4e731513bbad120dff694723John Reck    LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!");
131d72e0a339b54af0c4e731513bbad120dff694723John Reck    if (layerUpdater->backingLayer()->deferredUpdateScheduled) {
132d72e0a339b54af0c4e731513bbad120dff694723John Reck        mCanvas->pushLayerUpdate(layerUpdater->backingLayer());
13319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
13419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck}
13519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
136e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckvoid CanvasContext::prepareTree(TreeInfo& info) {
137f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    mRenderThread.removeFrameCallback(this);
13818f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
139f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    info.frameTimeMs = mRenderThread.timeLord().frameTimeMs();
140e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck    info.damageAccumulator = &mDamageAccumulator;
14125fbb3fa1138675379102a44405852555cefccbdJohn Reck    info.renderer = mCanvas;
142e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    mRootRenderNode->prepareTree(info);
143e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
144a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    int runningBehind = 0;
145a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // TODO: This query is moderately expensive, investigate adding some sort
146a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // of fast-path based off when we last called eglSwapBuffers() as well as
147a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    // last vsync time. Or something.
148a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    mNativeWindow->query(mNativeWindow.get(),
149a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck            NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind);
150a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    info.out.canDrawThisFrame = !runningBehind;
151a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
152a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    if (info.out.hasAnimations || !info.out.canDrawThisFrame) {
153cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck        if (!info.out.requiresUiRedraw) {
154f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            // If animationsNeedsRedraw is set don't bother posting for an RT anim
155f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            // as we will just end up fighting the UI thread.
156f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            mRenderThread.postFrameCallback(this);
157f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
158e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
159e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}
160e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
161f47a594f5250b1914c36423ee6b371f0b8db09d0John Reckvoid CanvasContext::stopDrawing() {
162f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    mRenderThread.removeFrameCallback(this);
163f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck}
164f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
165a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::notifyFramePending() {
166a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    ATRACE_CALL();
167a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    mRenderThread.pushBackFrameCallback(this);
168a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck}
169a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
170e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reckvoid CanvasContext::draw() {
1714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
172a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik            "drawRenderNode called on a context with no canvas or surface!");
1734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
174fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    profiler().markPlaybackStart();
175fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
176e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck    SkRect dirty;
177e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck    mDamageAccumulator.finish(&dirty);
178e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck
1794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    EGLint width, height;
1803b20251a355c88193c439f928a84ae69483fb488John Reck    mEglManager.beginFrame(mEglSurface, &width, &height);
1814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
1824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        mCanvas->setViewport(width, height);
183e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck        dirty.setEmpty();
1844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    } else if (!mDirtyRegionsEnabled || mHaveNewSurface) {
185e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck        dirty.setEmpty();
186fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    } else {
1875cdb8f998c58a2226112b36e4c391866346e5e17John Reck        if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) {
1880a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            ALOGW("Dirty " RECT_STRING " doesn't intersect with 0 0 %d %d ?",
1890a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                    SK_RECT_ARGS(dirty), width, height);
1900a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            dirty.setEmpty();
1910a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        }
192e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck        profiler().unionDirty(&dirty);
1934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
1944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    status_t status;
196e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck    if (!dirty.isEmpty()) {
197e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck        status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
198e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck                dirty.fRight, dirty.fBottom, mOpaque);
1994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    } else {
2004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        status = mCanvas->prepare(mOpaque);
2014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
2024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
2034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    Rect outBounds;
204a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik    status |= mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds);
2054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
206fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    profiler().draw(mCanvas);
2074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
2084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    mCanvas->finish();
2094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
210fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    profiler().markPlaybackEnd();
211fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
2124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    if (status & DrawGlInfo::kStatusDrew) {
2134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        swapBuffers();
21423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck    }
215fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
216fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    profiler().finishFrame();
21723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}
21823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
219e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// Called by choreographer to do an RT-driven animation
22018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid CanvasContext::doFrame() {
221368cdd85268999997fb495cf90c4417221797de0John Reck    if (CC_UNLIKELY(!mCanvas || mEglSurface == EGL_NO_SURFACE)) {
222368cdd85268999997fb495cf90c4417221797de0John Reck        return;
223368cdd85268999997fb495cf90c4417221797de0John Reck    }
224368cdd85268999997fb495cf90c4417221797de0John Reck
225e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    ATRACE_CALL();
226e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
227fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    profiler().startFrame();
228fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
2293b20251a355c88193c439f928a84ae69483fb488John Reck    TreeInfo info(TreeInfo::MODE_RT_ONLY, mRenderThread.renderState());
230e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    prepareTree(info);
231a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    if (info.out.canDrawThisFrame) {
232e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck        draw();
233a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
234e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}
235e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
2363b20251a355c88193c439f928a84ae69483fb488John Reckvoid CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
237d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck    ATRACE_CALL();
2380d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
2393b20251a355c88193c439f928a84ae69483fb488John Reck    if (thread.eglManager().hasEglContext()) {
2403b20251a355c88193c439f928a84ae69483fb488John Reck        thread.eglManager().requireGlContext();
2410d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck        mode = DrawGlInfo::kModeProcess;
2420d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
2436f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck
2443b20251a355c88193c439f928a84ae69483fb488John Reck    thread.renderState().invokeFunctor(functor, mode, NULL);
24523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}
24623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck
2473e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reckvoid CanvasContext::buildLayer(RenderNode* node) {
2483e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    ATRACE_CALL();
2493e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    if (!mEglManager.hasEglContext() || !mCanvas) {
2503e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        return;
2513e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    }
2523e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    requireGlContext();
2533e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    // buildLayer() will leave the tree in an unknown state, so we must stop drawing
2543e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    stopDrawing();
2553e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
2563e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState());
2573e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    info.frameTimeMs = mRenderThread.timeLord().frameTimeMs();
2583e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    info.damageAccumulator = &mDamageAccumulator;
2593e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    info.renderer = mCanvas;
2603e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    node->prepareTree(info);
2613e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    SkRect ignore;
2623e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    mDamageAccumulator.finish(&ignore);
2633e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    // Tickle the GENERIC property on node to mark it as dirty for damaging
2643e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    // purposes when the frame is actually drawn
2653e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    node->setPropertyFieldsDirty(RenderNode::GENERIC);
2663e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
2673e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    mCanvas->flushLayerUpdates();
2683e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck}
2693e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
27019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckbool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
27119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    requireGlContext();
27268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck    layer->apply();
2733b20251a355c88193c439f928a84ae69483fb488John Reck    return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
27419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck}
27519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
276f47a594f5250b1914c36423ee6b371f0b8db09d0John Reckvoid CanvasContext::destroyHardwareResources() {
277f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    stopDrawing();
2783b20251a355c88193c439f928a84ae69483fb488John Reck    if (mEglManager.hasEglContext()) {
279e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck        requireGlContext();
280dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck        mRootRenderNode->destroyHardwareResources();
281f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        Caches::getInstance().flush(Caches::kFlushMode_Layers);
282f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
283f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck}
284f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
285f47a594f5250b1914c36423ee6b371f0b8db09d0John Reckvoid CanvasContext::trimMemory(RenderThread& thread, int level) {
286f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    // No context means nothing to free
287f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    if (!thread.eglManager().hasEglContext()) return;
288f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
2893c2b7fa8c584c5ed56f1bd6ad53f2e87f0a6eb44John Reck    thread.eglManager().requireGlContext();
290f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    if (level >= TRIM_MEMORY_COMPLETE) {
291f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        Caches::getInstance().flush(Caches::kFlushMode_Full);
292f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        thread.eglManager().destroy();
293f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
294f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        Caches::getInstance().flush(Caches::kFlushMode_Moderate);
295e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck    }
296e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck}
297e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
298fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reckvoid CanvasContext::runWithGlContext(RenderTask* task) {
29919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    requireGlContext();
30019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    task->run();
30119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck}
30219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
3031949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createRenderLayer(int width, int height) {
304f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    requireSurface();
3053b20251a355c88193c439f928a84ae69483fb488John Reck    return LayerRenderer::createRenderLayer(mRenderThread.renderState(), width, height);
3061949e7928eeec22cd3f74b5f763a4eb433238453John Reck}
3071949e7928eeec22cd3f74b5f763a4eb433238453John Reck
3081949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createTextureLayer() {
309f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    requireSurface();
3103b20251a355c88193c439f928a84ae69483fb488John Reck    return LayerRenderer::createTextureLayer(mRenderThread.renderState());
3111949e7928eeec22cd3f74b5f763a4eb433238453John Reck}
3121949e7928eeec22cd3f74b5f763a4eb433238453John Reck
31319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckvoid CanvasContext::requireGlContext() {
314f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    mEglManager.requireGlContext();
315fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck}
316fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck
3173b20251a355c88193c439f928a84ae69483fb488John Reckvoid CanvasContext::setTextureAtlas(RenderThread& thread,
3183b20251a355c88193c439f928a84ae69483fb488John Reck        const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) {
3193b20251a355c88193c439f928a84ae69483fb488John Reck    thread.eglManager().setTextureAtlas(buffer, map, mapSize);
32066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck}
32166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
32223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace renderthread */
32323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace uirenderer */
32423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace android */
325