CanvasContext.cpp revision f088c349dfea985e561d7e838ecd41be5168cd4a
148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki/*
248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * Copyright (C) 2014 The Android Open Source Project
348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki *
448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * Licensed under the Apache License, Version 2.0 (the "License");
548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * you may not use this file except in compliance with the License.
648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * You may obtain a copy of the License at
748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki *
848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki *      http://www.apache.org/licenses/LICENSE-2.0
948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki *
1048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * Unless required by applicable law or agreed to in writing, software
1148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * distributed under the License is distributed on an "AS IS" BASIS,
1248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * See the License for the specific language governing permissions and
1448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki * limitations under the License.
1548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki */
1648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
1748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki#include "CanvasContext.h"
1848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
198f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki#include <algorithm>
208f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki#include <private/hwui/DrawGlInfo.h>
218f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki#include <strings.h>
22e9864e3df037a1a5610752c6addc4d71e6b292c7Yuichi Araki
23e9864e3df037a1a5610752c6addc4d71e6b292c7Yuichi Araki#include "EglManager.h"
24acf7e812c17c73a27c5e5973dde80e1c59712469Aurimas Liutikas#include "RenderThread.h"
258f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki#include "../AnimationContext.h"
2647a4a1aac79f0ad2279c7a3eeaad1673646f4d81Kassim Maguire#include "../Caches.h"
276bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki#include "../DeferredLayerUpdater.h"
286bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki#include "../RenderState.h"
29dffd8d4be91b2e5e0ce66ad96867182db0c02fd0Yuichi Araki#include "../LayerRenderer.h"
3048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki#include "../OpenGLRenderer.h"
3148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki#include "../Stencil.h"
3248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
336bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki#define TRIM_MEMORY_COMPLETE 80
346bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki#define TRIM_MEMORY_UI_HIDDEN 20
356bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
366bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Arakinamespace android {
37e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Arakinamespace uirenderer {
3848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakinamespace renderthread {
3948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
406bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi ArakiCanvasContext::CanvasContext(RenderThread& thread, bool translucent,
416bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        RenderNode* rootRenderNode, IContextFactory* contextFactory)
4248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        : mRenderThread(thread)
4348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        , mEglManager(thread.eglManager())
4448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        , mEglSurface(EGL_NO_SURFACE)
4548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        , mBufferPreserved(false)
466bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        , mSwapBehavior(kSwap_default)
4748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        , mOpaque(!translucent)
48754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas        , mCanvas(NULL)
49754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas        , mHaveNewSurface(false)
506bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        , mRootRenderNode(rootRenderNode) {
51b1eb1357ec33343b7271a6d3876ac4af84e15510Yuichi Araki    mAnimationContext = contextFactory->createAnimationContext(mRenderThread.timeLord());
526bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    mRenderThread.renderState().registerCanvasContext(this);
536bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki}
5448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
556bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi ArakiCanvasContext::~CanvasContext() {
5648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    destroy();
57b1eb1357ec33343b7271a6d3876ac4af84e15510Yuichi Araki    delete mAnimationContext;
58ee3e8053ef6b55e31fa0be004061318ec394eb64Kirill Grouchnikov    mRenderThread.renderState().unregisterCanvasContext(this);
596cb44089e8c7a5abf8aa7a0cdff3cb6888790708Yuichi Araki}
60ee3e8053ef6b55e31fa0be004061318ec394eb64Kirill Grouchnikov
6148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::destroy() {
6248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    stopDrawing();
6348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    setSurface(NULL);
6448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    freePrefetechedLayers();
6548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    destroyHardwareResources();
6648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    mAnimationContext->destroy();
6748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (mCanvas) {
6848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        delete mCanvas;
6948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        mCanvas = 0;
7048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
7148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
7248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
7348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::setSurface(ANativeWindow* window) {
7448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    ATRACE_CALL();
7548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
7648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    mNativeWindow = window;
7748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
7848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (mEglSurface != EGL_NO_SURFACE) {
79dffd8d4be91b2e5e0ce66ad96867182db0c02fd0Yuichi Araki        mEglManager.destroySurface(mEglSurface);
80dffd8d4be91b2e5e0ce66ad96867182db0c02fd0Yuichi Araki        mEglSurface = EGL_NO_SURFACE;
8148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
8248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
8348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (window) {
8448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        mEglSurface = mEglManager.createSurface(window);
8548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
8648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
8748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (mEglSurface != EGL_NO_SURFACE) {
8848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        const bool preserveBuffer = (mSwapBehavior != kSwap_discardBuffer);
89dffd8d4be91b2e5e0ce66ad96867182db0c02fd0Yuichi Araki        mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
90e9864e3df037a1a5610752c6addc4d71e6b292c7Yuichi Araki        mHaveNewSurface = true;
91e9864e3df037a1a5610752c6addc4d71e6b292c7Yuichi Araki        makeCurrent();
9248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    } else {
9348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        mRenderThread.removeFrameCallback(this);
9448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
9548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
9648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
9748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::swapBuffers() {
9848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (CC_UNLIKELY(!mEglManager.swapBuffers(mEglSurface))) {
9948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        setSurface(NULL);
10048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
10148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    mHaveNewSurface = false;
10248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
10348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
10448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::requireSurface() {
10548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
10648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki            "requireSurface() called but no surface set!");
10748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    makeCurrent();
10848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
10948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
11048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::setSwapBehavior(SwapBehavior swapBehavior) {
11148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    mSwapBehavior = swapBehavior;
11248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
11348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
11448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakibool CanvasContext::initialize(ANativeWindow* window) {
11548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    setSurface(window);
1166bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (mCanvas) return false;
1178f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mCanvas = new OpenGLRenderer(mRenderThread.renderState());
1188f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mCanvas->initProperties();
1198f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    return true;
1208f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki}
1218f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1228f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Arakivoid CanvasContext::updateSurface(ANativeWindow* window) {
1238f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    setSurface(window);
1248f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki}
1258f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1268f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Arakibool CanvasContext::pauseSurface(ANativeWindow* window) {
1278f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    return mRenderThread.removeFrameCallback(this);
1288f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki}
1298f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1308f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki// TODO: don't pass viewport size, it's automatic via EGL
1318f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Arakivoid CanvasContext::setup(int width, int height, const Vector3& lightCenter,
1328f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki        float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
1338f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    if (!mCanvas) return;
1348f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mCanvas->initLight(lightCenter, lightRadius, ambientShadowAlpha, spotShadowAlpha);
1358f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki}
1368f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1378f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Arakivoid CanvasContext::setOpaque(bool opaque) {
1388f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mOpaque = opaque;
1398f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki}
1408f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1418f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Arakivoid CanvasContext::makeCurrent() {
1428f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    // TODO: Figure out why this workaround is needed, see b/13913604
1438f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    // In the meantime this matches the behavior of GLRenderer, so it is not a regression
1448f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mHaveNewSurface |= mEglManager.makeCurrent(mEglSurface);
1458f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki}
1468f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1478f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Arakivoid CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) {
1488f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    bool success = layerUpdater->apply();
1498f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!");
1508f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    if (layerUpdater->backingLayer()->deferredUpdateScheduled) {
1518f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki        mCanvas->pushLayerUpdate(layerUpdater->backingLayer());
1528f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    }
1538f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki}
1548f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1558f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Arakivoid CanvasContext::prepareTree(TreeInfo& info) {
1568f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mRenderThread.removeFrameCallback(this);
1578f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1588f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    info.damageAccumulator = &mDamageAccumulator;
1598f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    info.renderer = mCanvas;
1608f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) {
1618f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki        info.canvasContext = this;
1628f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    }
1638f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mAnimationContext->startFrame(info.mode);
1648f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mRootRenderNode->prepareTree(info);
1658f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    mAnimationContext->runRemainingAnimations(info);
1668f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki
1678f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    if (info.canvasContext) {
1688f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki        freePrefetechedLayers();
1698f8034a4204fc10c4805758051f0cec2159c0e40Yuichi Araki    }
1706bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
1716bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (CC_UNLIKELY(!mNativeWindow.get())) {
1726bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        info.out.canDrawThisFrame = false;
1736bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        return;
1746bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    }
1756bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
1766bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    int runningBehind = 0;
1776bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    // TODO: This query is moderately expensive, investigate adding some sort
1786bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    // of fast-path based off when we last called eglSwapBuffers() as well as
1796bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    // last vsync time. Or something.
1806bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    mNativeWindow->query(mNativeWindow.get(),
1816bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki            NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind);
1826bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    info.out.canDrawThisFrame = !runningBehind;
1836bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
1846bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (info.out.hasAnimations || !info.out.canDrawThisFrame) {
1856bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        if (!info.out.requiresUiRedraw) {
1866bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki            // If animationsNeedsRedraw is set don't bother posting for an RT anim
1876bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki            // as we will just end up fighting the UI thread.
1886bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki            mRenderThread.postFrameCallback(this);
1896bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        }
1906cb44089e8c7a5abf8aa7a0cdff3cb6888790708Yuichi Araki    }
1916bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki}
1926bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
1936bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Arakivoid CanvasContext::stopDrawing() {
1946bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    mRenderThread.removeFrameCallback(this);
1956bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki}
1966bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
1976bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Arakivoid CanvasContext::notifyFramePending() {
1986bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    ATRACE_CALL();
1996bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    mRenderThread.pushBackFrameCallback(this);
2006bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki}
2016bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2026bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Arakivoid CanvasContext::draw() {
2036bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
2046bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki            "drawRenderNode called on a context with no canvas or surface!");
2056bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2066bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    profiler().markPlaybackStart();
2076bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2086bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    SkRect dirty;
2096bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    mDamageAccumulator.finish(&dirty);
2106bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2116bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    EGLint width, height;
2126bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    mEglManager.beginFrame(mEglSurface, &width, &height);
2136bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
2146bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        mCanvas->setViewport(width, height);
2156bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        dirty.setEmpty();
2166bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    } else if (!mBufferPreserved || mHaveNewSurface) {
2176bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        dirty.setEmpty();
2186bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    } else {
2196bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) {
2206bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki            ALOGW("Dirty " RECT_STRING " doesn't intersect with 0 0 %d %d ?",
2216bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki                    SK_RECT_ARGS(dirty), width, height);
2226bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki            dirty.setEmpty();
2236bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        }
2246bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        profiler().unionDirty(&dirty);
2256bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    }
2266bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2276bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    status_t status;
2286bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (!dirty.isEmpty()) {
2296bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
2306bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki                dirty.fRight, dirty.fBottom, mOpaque);
2316bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    } else {
2326bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        status = mCanvas->prepare(mOpaque);
2336bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    }
2346bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2356bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    Rect outBounds;
2366bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    status |= mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds);
2376bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2386bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    profiler().draw(mCanvas);
2396bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2406bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    mCanvas->finish();
2416bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2426bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    profiler().markPlaybackEnd();
2436bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2446bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (status & DrawGlInfo::kStatusDrew) {
2456bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        swapBuffers();
2466bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    } else {
2476bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        mEglManager.cancelFrame();
2486bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    }
2496bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2506bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    profiler().finishFrame();
2516bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki}
2526bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2536bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki// Called by choreographer to do an RT-driven animation
2546bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Arakivoid CanvasContext::doFrame() {
2556bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (CC_UNLIKELY(!mCanvas || mEglSurface == EGL_NO_SURFACE)) {
2566bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        return;
2576bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    }
2586bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2596bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    ATRACE_CALL();
2606bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2616bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    profiler().startFrame();
2626bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki
2636bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    TreeInfo info(TreeInfo::MODE_RT_ONLY, mRenderThread.renderState());
2646bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    prepareTree(info);
2656bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    if (info.out.canDrawThisFrame) {
2666bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki        draw();
2676bef5a31fd4bbfc70b21c0f694bcb272e88400a3Yuichi Araki    }
26848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
26948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
27048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
27148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    ATRACE_CALL();
27248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
27348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (thread.eglManager().hasEglContext()) {
27448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        thread.eglManager().requireGlContext();
27548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        mode = DrawGlInfo::kModeProcess;
27648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
27748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
27848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    thread.renderState().invokeFunctor(functor, mode, NULL);
27948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
28048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
28148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::markLayerInUse(RenderNode* node) {
28248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (mPrefetechedLayers.erase(node)) {
28348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        node->decStrong(0);
28448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
28548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
28648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
287acf7e812c17c73a27c5e5973dde80e1c59712469Aurimas Liutikasstatic void destroyPrefetechedNode(RenderNode* node) {
28848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName());
28948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    node->destroyHardwareResources();
29048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    node->decStrong(0);
29148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
29248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
29348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::freePrefetechedLayers() {
294acf7e812c17c73a27c5e5973dde80e1c59712469Aurimas Liutikas    if (mPrefetechedLayers.size()) {
29548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        requireGlContext();
29648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
29748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        mPrefetechedLayers.clear();
29848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
29948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
30048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
301acf7e812c17c73a27c5e5973dde80e1c59712469Aurimas Liutikasvoid CanvasContext::buildLayer(RenderNode* node) {
302e0573dfb5896eb66e266ea366d8c58437c739c95Yuichi Araki    ATRACE_CALL();
303e0573dfb5896eb66e266ea366d8c58437c739c95Yuichi Araki    if (!mEglManager.hasEglContext() || !mCanvas) {
304e0573dfb5896eb66e266ea366d8c58437c739c95Yuichi Araki        return;
305e0573dfb5896eb66e266ea366d8c58437c739c95Yuichi Araki    }
306e0573dfb5896eb66e266ea366d8c58437c739c95Yuichi Araki    requireGlContext();
307acf7e812c17c73a27c5e5973dde80e1c59712469Aurimas Liutikas    // buildLayer() will leave the tree in an unknown state, so we must stop drawing
30848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    stopDrawing();
30948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
310e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki    TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState());
3118609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    info.damageAccumulator = &mDamageAccumulator;
3128609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    info.renderer = mCanvas;
3138609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    info.runAnimations = false;
3148609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    node->prepareTree(info);
3158609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    SkRect ignore;
3168609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    mDamageAccumulator.finish(&ignore);
3178609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    // Tickle the GENERIC property on node to mark it as dirty for damaging
3188609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    // purposes when the frame is actually drawn
3198609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    node->setPropertyFieldsDirty(RenderNode::GENERIC);
3208609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki
3218609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    mCanvas->markLayersAsBuildLayers();
3228609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    mCanvas->flushLayerUpdates();
3238609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki
3248609a20bfe8d61704facb9c18836db5b3a754105Yuichi Araki    node->incStrong(0);
325e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki    mPrefetechedLayers.insert(node);
326e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki}
327e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki
328e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Arakibool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
329e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki    requireGlContext();
330e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki    layer->apply();
331e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki    return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
332e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki}
333e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki
334e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Arakivoid CanvasContext::destroyHardwareResources() {
335e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki    stopDrawing();
336e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki    if (mEglManager.hasEglContext()) {
337e1b07825c14a3dee006a0489fd8e2c3060d9884fYuichi Araki        requireGlContext();
33848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        freePrefetechedLayers();
33948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        mRootRenderNode->destroyHardwareResources();
34048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        Caches::getInstance().flush(Caches::kFlushMode_Layers);
34148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
34248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
34348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
34448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::trimMemory(RenderThread& thread, int level) {
34548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    // No context means nothing to free
34648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (!thread.eglManager().hasEglContext()) return;
34748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
34848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    ATRACE_CALL();
34948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    thread.eglManager().requireGlContext();
35048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    if (level >= TRIM_MEMORY_COMPLETE) {
35148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        Caches::getInstance().flush(Caches::kFlushMode_Full);
35248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki        thread.eglManager().destroy();
35348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
354d7e25b5cfb70b867b7467acb613a984310a0c40dYuichi Araki        Caches::getInstance().flush(Caches::kFlushMode_Moderate);
35548cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    }
35648cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
35748cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
35848cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Arakivoid CanvasContext::runWithGlContext(RenderTask* task) {
35948cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    requireGlContext();
36048cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    task->run();
36148cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki}
36248cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki
36348cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi ArakiLayer* CanvasContext::createTextureLayer() {
36448cd60a8daad661611618f52a0dce00d5b2c64b9Yuichi Araki    requireSurface();
365cea79d768278d2c55f89263f99b8860cc5447aaaAurimas Liutikas    return LayerRenderer::createTextureLayer(mRenderThread.renderState());
366acf7e812c17c73a27c5e5973dde80e1c59712469Aurimas Liutikas}
367362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki
368362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Arakivoid CanvasContext::requireGlContext() {
369362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki    mEglManager.requireGlContext();
370362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki}
371362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki
372362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Arakivoid CanvasContext::setTextureAtlas(RenderThread& thread,
373362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki        const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) {
374362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki    thread.eglManager().setTextureAtlas(buffer, map, mapSize);
375362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki}
376362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki
377362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki} /* namespace renderthread */
378362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki} /* namespace uirenderer */
379362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki} /* namespace android */
380362585b01e5ca19d1c58e4b152ad0a863b5f6d91Yuichi Araki