CanvasContext.cpp revision 25fbb3fa1138675379102a44405852555cefccbd
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#define LOG_TAG "CanvasContext" 1823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include "CanvasContext.h" 2023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include <cutils/properties.h> 224f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include <private/hwui/DrawGlInfo.h> 2323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include <strings.h> 2423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include "RenderThread.h" 2623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include "../Caches.h" 2719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck#include "../DeferredLayerUpdater.h" 2819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck#include "../LayerRenderer.h" 294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#include "../OpenGLRenderer.h" 3023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#include "../Stencil.h" 3123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 3223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#define PROPERTY_RENDER_DIRTY_REGIONS "debug.hwui.render_dirty_regions" 3323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#define GLES_VERSION 2 3423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 354f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck// Android-specific addition that is used to show when frames began in systrace 364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John ReckEGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); 374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3823b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace android { 3923b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace uirenderer { 4023b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace renderthread { 4123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 4223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#define ERROR_CASE(x) case x: return #x; 4323b797ab5151eb2474f3bdd679f2f07bfd723042John Reckstatic const char* egl_error_str(EGLint error) { 4423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck switch (error) { 4523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_SUCCESS) 4623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_NOT_INITIALIZED) 4723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_ACCESS) 4823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_ALLOC) 4923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_ATTRIBUTE) 5023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_CONFIG) 5123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_CONTEXT) 5223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_CURRENT_SURFACE) 5323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_DISPLAY) 5423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_MATCH) 5523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_NATIVE_PIXMAP) 5623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_NATIVE_WINDOW) 5723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_PARAMETER) 5823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_SURFACE) 5923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_CONTEXT_LOST) 6023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck default: 6123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return "Unknown error"; 6223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 6323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 6423b797ab5151eb2474f3bdd679f2f07bfd723042John Reckstatic const char* egl_error_str() { 6523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return egl_error_str(eglGetError()); 6623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 6723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 6823b797ab5151eb2474f3bdd679f2f07bfd723042John Reckstatic bool load_dirty_regions_property() { 6923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck char buf[PROPERTY_VALUE_MAX]; 7023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck int len = property_get(PROPERTY_RENDER_DIRTY_REGIONS, buf, "true"); 7123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return !strncasecmp("true", buf, len); 7223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 7323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 7423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck// This class contains the shared global EGL objects, such as EGLDisplay 7523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck// and EGLConfig, which are re-used by CanvasContext 7623b797ab5151eb2474f3bdd679f2f07bfd723042John Reckclass GlobalContext { 7723b797ab5151eb2474f3bdd679f2f07bfd723042John Reckpublic: 7823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck static GlobalContext* get(); 7923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // Returns true on success, false on failure 814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void initialize(); 8223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 830d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck bool hasContext(); 840d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck 854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void usePBufferSurface(); 8623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface createSurface(EGLNativeWindowType window); 8723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck void destroySurface(EGLSurface surface); 8823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 8923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck void destroy(); 9023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; } 92dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck // Returns true if the current surface changed, false if it was already current 93dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck bool makeCurrent(EGLSurface surface); 944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); 954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void swapBuffers(EGLSurface surface); 9623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool enableDirtyRegions(EGLSurface surface); 9823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); 10066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 10123b797ab5151eb2474f3bdd679f2f07bfd723042John Reckprivate: 10223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck GlobalContext(); 10323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // GlobalContext is never destroyed, method is purposely not implemented 10423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ~GlobalContext(); 10523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void loadConfig(); 1074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void createContext(); 1084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void initAtlas(); 10923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck static GlobalContext* sContext; 11123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLDisplay mEglDisplay; 11323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLConfig mEglConfig; 11423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLContext mEglContext; 11523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface mPBufferSurface; 11623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck const bool mRequestDirtyRegions; 11823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool mCanSetDirtyRegions; 11923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface mCurrentSurface; 12166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 12266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck sp<GraphicBuffer> mAtlasBuffer; 12366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck int64_t* mAtlasMap; 12466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck size_t mAtlasMapSize; 12523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}; 12623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12723b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::sContext = 0; 12823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12923b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::get() { 13023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!sContext) { 13123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck sContext = new GlobalContext(); 13223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 13323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return sContext; 13423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 13523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 13623b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext::GlobalContext() 13723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck : mEglDisplay(EGL_NO_DISPLAY) 13823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglConfig(0) 13923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglContext(EGL_NO_CONTEXT) 14023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mPBufferSurface(EGL_NO_SURFACE) 14123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mRequestDirtyRegions(load_dirty_regions_property()) 14266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck , mCurrentSurface(EGL_NO_SURFACE) 14366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck , mAtlasMap(NULL) 14466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck , mAtlasMapSize(0) { 14523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = mRequestDirtyRegions; 14623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); 14723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 14823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initialize() { 1500d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck if (hasContext()) return; 15123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 15223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 1534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 1544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to get EGL_DEFAULT_DISPLAY! err=%s", egl_error_str()); 15523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 15623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint major, minor; 1574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(eglInitialize(mEglDisplay, &major, &minor) == EGL_FALSE, 1584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to initialize display %p! err=%s", mEglDisplay, egl_error_str()); 15923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor); 16123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck loadConfig(); 1634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck createContext(); 1644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck usePBufferSurface(); 1654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Caches::getInstance().init(); 1664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck initAtlas(); 16723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 16823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1690d1f634f4b5e1bb37aa51777efb6a68619488d01John Reckbool GlobalContext::hasContext() { 1700d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck return mEglDisplay != EGL_NO_DISPLAY; 1710d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck} 1720d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck 1734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::loadConfig() { 17423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; 17523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { 17623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 17723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RED_SIZE, 8, 17823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_GREEN_SIZE, 8, 17923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_BLUE_SIZE, 8, 18023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_ALPHA_SIZE, 8, 18123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_DEPTH_SIZE, 0, 18223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_CONFIG_CAVEAT, EGL_NONE, 18323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_STENCIL_SIZE, Stencil::getStencilSize(), 18423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior, 18523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_NONE 18623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck }; 18723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 18823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint num_configs = 1; 18923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs) 19023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck || num_configs != 1) { 19123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Failed to get a valid config 19223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 19323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); 19423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Try again without dirty regions enabled 19523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = false; 19623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck loadConfig(); 19723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else { 1984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); 19923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 20023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 20123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 20223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::createContext() { 20423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, EGL_NONE }; 20523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs); 2064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT, 2074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create context, error = %s", egl_error_str()); 2084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 2094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 21066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckvoid GlobalContext::setTextureAtlas(const sp<GraphicBuffer>& buffer, 21166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck int64_t* map, size_t mapSize) { 21266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 21366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck // Already initialized 21466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (mAtlasBuffer.get()) { 21566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck ALOGW("Multiple calls to setTextureAtlas!"); 21666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck delete map; 21766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck return; 21866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 21966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 22066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck mAtlasBuffer = buffer; 22166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck mAtlasMap = map; 22266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck mAtlasMapSize = mapSize; 22366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 22466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (hasContext()) { 22566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck usePBufferSurface(); 22666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck initAtlas(); 22766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 22866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck} 22966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 2304f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initAtlas() { 231c8affe0e1b1f3f63b12477f832a1a66019ac0df8John Reck if (mAtlasBuffer.get()) { 232cdfeef6624613ca06fe8a7edfb92608afb0499eeJohn Reck Caches::getInstance().assetAtlas.init(mAtlasBuffer, mAtlasMap, mAtlasMapSize); 233cdfeef6624613ca06fe8a7edfb92608afb0499eeJohn Reck } 23423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 23523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::usePBufferSurface() { 2374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 2384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "usePBufferSurface() called on uninitialized GlobalContext!"); 23923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 24023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mPBufferSurface == EGL_NO_SURFACE) { 24123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; 24223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); 24323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 2444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(mPBufferSurface); 24523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 24623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 24723b797ab5151eb2474f3bdd679f2f07bfd723042John ReckEGLSurface GlobalContext::createSurface(EGLNativeWindowType window) { 24823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck initialize(); 24923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return eglCreateWindowSurface(mEglDisplay, mEglConfig, window, NULL); 25023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 25123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 25223b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroySurface(EGLSurface surface) { 25323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (isCurrent(surface)) { 25423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck makeCurrent(EGL_NO_SURFACE); 25523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 25623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglDestroySurface(mEglDisplay, surface)) { 25723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to destroy surface %p, error=%s", (void*)surface, egl_error_str()); 25823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 25923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 26023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 26123b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroy() { 26223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglDisplay == EGL_NO_DISPLAY) return; 26323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 26423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck usePBufferSurface(); 26523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (Caches::hasInstance()) { 26623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck Caches::getInstance().terminate(); 26723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 26823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 26923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroyContext(mEglDisplay, mEglContext); 27023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroySurface(mEglDisplay, mPBufferSurface); 27123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 27223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglTerminate(mEglDisplay); 27323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglReleaseThread(); 27423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 27523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = EGL_NO_DISPLAY; 27623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = EGL_NO_CONTEXT; 27723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = EGL_NO_SURFACE; 27823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = EGL_NO_SURFACE; 27923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 28023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 281dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reckbool GlobalContext::makeCurrent(EGLSurface surface) { 282dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck if (isCurrent(surface)) return false; 28323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 28423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (surface == EGL_NO_SURFACE) { 28523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // If we are setting EGL_NO_SURFACE we don't care about any of the potential 28623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // return errors, which would only happen if mEglDisplay had already been 28723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // destroyed in which case the current context is already NO_CONTEXT 28823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 28923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) { 2904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s", 2914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*)surface, egl_error_str()); 29223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 29323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = surface; 294dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck return true; 29523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 29623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { 2984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE, 2994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Tried to beginFrame on EGL_NO_SURFACE!"); 3004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(surface); 3014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width) { 3024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width); 30323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 3044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (height) { 3054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height); 3064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 3074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglBeginFrame(mEglDisplay, surface); 3084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::swapBuffers(EGLSurface surface) { 3114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglSwapBuffers(mEglDisplay, surface); 3124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint err = eglGetError(); 3134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(err != EGL_SUCCESS, 3144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Encountered EGL error %d %s during rendering", err, egl_error_str(err)); 31523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 31623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 31723b797ab5151eb2474f3bdd679f2f07bfd723042John Reckbool GlobalContext::enableDirtyRegions(EGLSurface surface) { 31823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!mRequestDirtyRegions) return false; 31923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 32023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 32123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { 32223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s", 32323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 32423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 32523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 32623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return true; 32723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 32823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Perhaps it is already enabled? 32923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint value; 33023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) { 33123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", 33223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 33323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 33423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 33523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return value == EGL_BUFFER_PRESERVED; 33623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 33723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 338e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn ReckCanvasContext::CanvasContext(bool translucent, RenderNode* rootRenderNode) 3394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck : mRenderThread(RenderThread::getInstance()) 3404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mEglSurface(EGL_NO_SURFACE) 3414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mDirtyRegionsEnabled(false) 3424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mOpaque(!translucent) 3434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mCanvas(0) 344e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck , mHaveNewSurface(false) 345e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck , mRootRenderNode(rootRenderNode) { 34623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext = GlobalContext::get(); 34723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 34823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 34923b797ab5151eb2474f3bdd679f2f07bfd723042John ReckCanvasContext::~CanvasContext() { 350fae904d63947fe1687d1d44be29234cc3d538f24John Reck destroyCanvasAndSurface(); 351e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mRenderThread.removeFrameCallback(this); 3524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 354fae904d63947fe1687d1d44be29234cc3d538f24John Reckvoid CanvasContext::destroyCanvasAndSurface() { 3554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) { 3564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck delete mCanvas; 3574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = 0; 3584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 35923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck setSurface(NULL); 36023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 36123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 362a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::setSurface(ANativeWindow* window) { 363a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck mNativeWindow = window; 364a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck 36523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 36623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext->destroySurface(mEglSurface); 36723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = EGL_NO_SURFACE; 36823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 36923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 37023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (window) { 37123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = mGlobalContext->createSurface(window); 3724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, 3734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create EGLSurface for window %p, eglErr = %s", 3744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*) window, egl_error_str()); 37523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 37623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 37723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 37823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface); 3794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = true; 380dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck makeCurrent(); 381368cdd85268999997fb495cf90c4417221797de0John Reck } else { 382368cdd85268999997fb495cf90c4417221797de0John Reck mRenderThread.removeFrameCallback(this); 3834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 3844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::swapBuffers() { 3874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->swapBuffers(mEglSurface); 3884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = false; 3894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 391f7d9c1dc84671d4e99657ef071d275700d85bb11John Reckvoid CanvasContext::requireSurface() { 392f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, 393f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck "requireSurface() called but no surface set!"); 394dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck makeCurrent(); 3954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 397a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckbool CanvasContext::initialize(ANativeWindow* window) { 3984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) return false; 3994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 4004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = new OpenGLRenderer(); 4014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->initProperties(); 4024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck return true; 4034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 4044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 405a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::updateSurface(ANativeWindow* window) { 4064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 407f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck} 408f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck 409a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::pauseSurface(ANativeWindow* window) { 410f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck // TODO: For now we just need a fence, in the future suspend any animations 411f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck // and such to prevent from trying to render into this surface 4124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 4134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 414797b95b26bbb7557678af78b9a2a61830158920fChris Craikvoid CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius) { 4154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mCanvas) return; 4164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 417797b95b26bbb7557678af78b9a2a61830158920fChris Craik mCanvas->initializeLight(lightCenter, lightRadius); 4184f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 4194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 42063a06673253914510bbeebd500655008682dade1John Reckvoid CanvasContext::setOpaque(bool opaque) { 42163a06673253914510bbeebd500655008682dade1John Reck mOpaque = opaque; 42263a06673253914510bbeebd500655008682dade1John Reck} 42363a06673253914510bbeebd500655008682dade1John Reck 424860d155f866cc15a725e7ce03763280987f24901John Reckvoid CanvasContext::makeCurrent() { 425dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck // TODO: Figure out why this workaround is needed, see b/13913604 426dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck // In the meantime this matches the behavior of GLRenderer, so it is not a regression 427dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck mHaveNewSurface |= mGlobalContext->makeCurrent(mEglSurface); 428860d155f866cc15a725e7ce03763280987f24901John Reck} 429860d155f866cc15a725e7ce03763280987f24901John Reck 430d72e0a339b54af0c4e731513bbad120dff694723John Reckvoid CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info) { 431d72e0a339b54af0c4e731513bbad120dff694723John Reck bool success = layerUpdater->apply(info); 432d72e0a339b54af0c4e731513bbad120dff694723John Reck LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!"); 433d72e0a339b54af0c4e731513bbad120dff694723John Reck if (layerUpdater->backingLayer()->deferredUpdateScheduled) { 434d72e0a339b54af0c4e731513bbad120dff694723John Reck mCanvas->pushLayerUpdate(layerUpdater->backingLayer()); 43519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 43619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 43719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 438e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckvoid CanvasContext::prepareTree(TreeInfo& info) { 439f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mRenderThread.removeFrameCallback(this); 44018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck 441f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); 442e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck info.damageAccumulator = &mDamageAccumulator; 44325fbb3fa1138675379102a44405852555cefccbdJohn Reck info.renderer = mCanvas; 444e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mRootRenderNode->prepareTree(info); 445e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 446a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck int runningBehind = 0; 447a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck // TODO: This query is moderately expensive, investigate adding some sort 448a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck // of fast-path based off when we last called eglSwapBuffers() as well as 449a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck // last vsync time. Or something. 450a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck mNativeWindow->query(mNativeWindow.get(), 451a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind); 452a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck info.out.canDrawThisFrame = !runningBehind; 453a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck 454a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck if (info.out.hasAnimations || !info.out.canDrawThisFrame) { 455f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.hasFunctors) { 456f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck info.out.requiresUiRedraw = true; 457f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } else if (!info.out.requiresUiRedraw) { 458f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // If animationsNeedsRedraw is set don't bother posting for an RT anim 459f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // as we will just end up fighting the UI thread. 460f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mRenderThread.postFrameCallback(this); 461f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } 462e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 463e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 464e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 465a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reckvoid CanvasContext::notifyFramePending() { 466a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck ATRACE_CALL(); 467a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck mRenderThread.pushBackFrameCallback(this); 468a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck} 469a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck 470e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reckvoid CanvasContext::draw() { 4714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, 4724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "drawDisplayList called on a context with no canvas or surface!"); 4734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 474fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck profiler().markPlaybackStart(); 475fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 476e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck SkRect dirty; 477e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck mDamageAccumulator.finish(&dirty); 478e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck 4794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint width, height; 4804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->beginFrame(mEglSurface, &width, &height); 4814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { 4824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 483e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck dirty.setEmpty(); 4844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else if (!mDirtyRegionsEnabled || mHaveNewSurface) { 485e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck dirty.setEmpty(); 486fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck } else { 487e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck profiler().unionDirty(&dirty); 4884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status_t status; 491e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck if (!dirty.isEmpty()) { 492e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop, 493e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck dirty.fRight, dirty.fBottom, mOpaque); 4944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else { 4954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status = mCanvas->prepare(mOpaque); 4964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Rect outBounds; 499e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck status |= mCanvas->drawDisplayList(mRootRenderNode.get(), outBounds); 5004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 501fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck profiler().draw(mCanvas); 5024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 5034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->finish(); 5044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 505fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck profiler().markPlaybackEnd(); 506fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 5074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (status & DrawGlInfo::kStatusDrew) { 5084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck swapBuffers(); 50923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 510fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 511fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck profiler().finishFrame(); 51223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 51323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 514e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// Called by choreographer to do an RT-driven animation 51518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid CanvasContext::doFrame() { 516368cdd85268999997fb495cf90c4417221797de0John Reck if (CC_UNLIKELY(!mCanvas || mEglSurface == EGL_NO_SURFACE)) { 517368cdd85268999997fb495cf90c4417221797de0John Reck return; 518368cdd85268999997fb495cf90c4417221797de0John Reck } 519368cdd85268999997fb495cf90c4417221797de0John Reck 520e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck ATRACE_CALL(); 521e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 522fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck profiler().startFrame(); 523fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 524e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck TreeInfo info(TreeInfo::MODE_RT_ONLY); 525e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.prepareTextures = false; 526e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 527e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck prepareTree(info); 528a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck if (info.out.canDrawThisFrame) { 529e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck draw(); 530a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 531e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 532e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 5330d1f634f4b5e1bb37aa51777efb6a68619488d01John Reckvoid CanvasContext::invokeFunctor(Functor* functor) { 534d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck ATRACE_CALL(); 5350d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext; 5360d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck if (mGlobalContext->hasContext()) { 5370d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck requireGlContext(); 5380d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck mode = DrawGlInfo::kModeProcess; 5390d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck } 540832b151465ed81c43e59891d5eebe62128b21fbbJohn Reck (*functor)(mode, NULL); 5416f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck 5426f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck if (mCanvas) { 5436f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck mCanvas->resume(); 5446f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck } 54523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 54623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 54719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckbool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { 54819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 549e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck TreeInfo info(TreeInfo::MODE_FULL); 550860d155f866cc15a725e7ce03763280987f24901John Reck layer->apply(info); 55119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck return LayerRenderer::copyLayer(layer->backingLayer(), bitmap); 55219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 55319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 554e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reckvoid CanvasContext::flushCaches(Caches::FlushMode flushMode) { 555e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck if (mGlobalContext->hasContext()) { 556e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck requireGlContext(); 557e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck Caches::getInstance().flush(flushMode); 558e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck } 559e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck} 560e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck 561fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reckvoid CanvasContext::runWithGlContext(RenderTask* task) { 56219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 56319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck task->run(); 56419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 56519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 5661949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createRenderLayer(int width, int height) { 567f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck requireSurface(); 5681949e7928eeec22cd3f74b5f763a4eb433238453John Reck return LayerRenderer::createRenderLayer(width, height); 5691949e7928eeec22cd3f74b5f763a4eb433238453John Reck} 5701949e7928eeec22cd3f74b5f763a4eb433238453John Reck 5711949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createTextureLayer() { 572f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck requireSurface(); 5731949e7928eeec22cd3f74b5f763a4eb433238453John Reck return LayerRenderer::createTextureLayer(); 5741949e7928eeec22cd3f74b5f763a4eb433238453John Reck} 5751949e7928eeec22cd3f74b5f763a4eb433238453John Reck 57619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckvoid CanvasContext::requireGlContext() { 577fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck if (mEglSurface != EGL_NO_SURFACE) { 578dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck makeCurrent(); 579fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } else { 580fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck mGlobalContext->usePBufferSurface(); 581fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } 582fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck} 583fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck 58466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckvoid CanvasContext::setTextureAtlas(const sp<GraphicBuffer>& buffer, 58566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck int64_t* map, size_t mapSize) { 58666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck GlobalContext::get()->setTextureAtlas(buffer, map, mapSize); 58766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck} 58866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 58923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace renderthread */ 59023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace uirenderer */ 59123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace android */ 592