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