CanvasContext.cpp revision 750ca6dbdb259aea0ca5b77380a9303e586ef3ea
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#ifdef USE_OPENGL_RENDERER 364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck// Android-specific addition that is used to show when frames began in systrace 374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John ReckEGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); 384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck#endif 394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4023b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace android { 4123b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace uirenderer { 4223b797ab5151eb2474f3bdd679f2f07bfd723042John Recknamespace renderthread { 4323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 4423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck#define ERROR_CASE(x) case x: return #x; 4523b797ab5151eb2474f3bdd679f2f07bfd723042John Reckstatic const char* egl_error_str(EGLint error) { 4623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck switch (error) { 4723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_SUCCESS) 4823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_NOT_INITIALIZED) 4923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_ACCESS) 5023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_ALLOC) 5123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_ATTRIBUTE) 5223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_CONFIG) 5323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_CONTEXT) 5423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_CURRENT_SURFACE) 5523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_DISPLAY) 5623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_MATCH) 5723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_NATIVE_PIXMAP) 5823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_NATIVE_WINDOW) 5923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_PARAMETER) 6023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_BAD_SURFACE) 6123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ERROR_CASE(EGL_CONTEXT_LOST) 6223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck default: 6323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return "Unknown error"; 6423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 6523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 6623b797ab5151eb2474f3bdd679f2f07bfd723042John Reckstatic const char* egl_error_str() { 6723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return egl_error_str(eglGetError()); 6823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 6923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 7023b797ab5151eb2474f3bdd679f2f07bfd723042John Reckstatic bool load_dirty_regions_property() { 7123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck char buf[PROPERTY_VALUE_MAX]; 7223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck int len = property_get(PROPERTY_RENDER_DIRTY_REGIONS, buf, "true"); 7323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return !strncasecmp("true", buf, len); 7423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 7523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 7623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck// This class contains the shared global EGL objects, such as EGLDisplay 7723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck// and EGLConfig, which are re-used by CanvasContext 7823b797ab5151eb2474f3bdd679f2f07bfd723042John Reckclass GlobalContext { 7923b797ab5151eb2474f3bdd679f2f07bfd723042John Reckpublic: 8023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck static GlobalContext* get(); 8123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // Returns true on success, false on failure 834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void initialize(); 8423b797ab5151eb2474f3bdd679f2f07bfd723042John 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; } 924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void makeCurrent(EGLSurface surface); 934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); 944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void swapBuffers(EGLSurface surface); 9523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool enableDirtyRegions(EGLSurface surface); 9723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9823b797ab5151eb2474f3bdd679f2f07bfd723042John Reckprivate: 9923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck GlobalContext(); 10023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // GlobalContext is never destroyed, method is purposely not implemented 10123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ~GlobalContext(); 10223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void loadConfig(); 1044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void createContext(); 1054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void initAtlas(); 10623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 10723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck static GlobalContext* sContext; 10823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 10923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLDisplay mEglDisplay; 11023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLConfig mEglConfig; 11123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLContext mEglContext; 11223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface mPBufferSurface; 11323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck const bool mRequestDirtyRegions; 11523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool mCanSetDirtyRegions; 11623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface mCurrentSurface; 11823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}; 11923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12023b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::sContext = 0; 12123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12223b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::get() { 12323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!sContext) { 12423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck sContext = new GlobalContext(); 12523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 12623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return sContext; 12723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 12823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12923b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext::GlobalContext() 13023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck : mEglDisplay(EGL_NO_DISPLAY) 13123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglConfig(0) 13223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglContext(EGL_NO_CONTEXT) 13323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mPBufferSurface(EGL_NO_SURFACE) 13423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mRequestDirtyRegions(load_dirty_regions_property()) 13523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mCurrentSurface(EGL_NO_SURFACE) { 13623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = mRequestDirtyRegions; 13723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); 13823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 13923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initialize() { 1414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mEglDisplay != EGL_NO_DISPLAY) return; 14223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 14323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 1444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 1454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to get EGL_DEFAULT_DISPLAY! err=%s", egl_error_str()); 14623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 14723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint major, minor; 1484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(eglInitialize(mEglDisplay, &major, &minor) == EGL_FALSE, 1494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to initialize display %p! err=%s", mEglDisplay, egl_error_str()); 15023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor); 15223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck loadConfig(); 1544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck createContext(); 1554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck usePBufferSurface(); 1564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Caches::getInstance().init(); 1574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck initAtlas(); 15823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 15923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::loadConfig() { 16123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; 16223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { 16323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 16423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RED_SIZE, 8, 16523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_GREEN_SIZE, 8, 16623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_BLUE_SIZE, 8, 16723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_ALPHA_SIZE, 8, 16823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_DEPTH_SIZE, 0, 16923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_CONFIG_CAVEAT, EGL_NONE, 17023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_STENCIL_SIZE, Stencil::getStencilSize(), 17123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior, 17223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_NONE 17323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck }; 17423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 17523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint num_configs = 1; 17623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs) 17723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck || num_configs != 1) { 17823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Failed to get a valid config 17923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 18023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); 18123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Try again without dirty regions enabled 18223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = false; 18323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck loadConfig(); 18423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else { 1854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); 18623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 18723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 18823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 18923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::createContext() { 19123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, EGL_NONE }; 19223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs); 1934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT, 1944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create context, error = %s", egl_error_str()); 1954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 1964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 1974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initAtlas() { 1984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO implement 1994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // For now just run without an atlas 20023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 20123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::usePBufferSurface() { 2034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 2044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "usePBufferSurface() called on uninitialized GlobalContext!"); 20523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 20623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mPBufferSurface == EGL_NO_SURFACE) { 20723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; 20823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); 20923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 2104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(mPBufferSurface); 21123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 21223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 21323b797ab5151eb2474f3bdd679f2f07bfd723042John ReckEGLSurface GlobalContext::createSurface(EGLNativeWindowType window) { 21423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck initialize(); 21523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return eglCreateWindowSurface(mEglDisplay, mEglConfig, window, NULL); 21623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 21723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 21823b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroySurface(EGLSurface surface) { 21923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (isCurrent(surface)) { 22023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck makeCurrent(EGL_NO_SURFACE); 22123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 22223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglDestroySurface(mEglDisplay, surface)) { 22323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to destroy surface %p, error=%s", (void*)surface, egl_error_str()); 22423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 22523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 22623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 22723b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroy() { 22823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglDisplay == EGL_NO_DISPLAY) return; 22923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 23023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck usePBufferSurface(); 23123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (Caches::hasInstance()) { 23223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck Caches::getInstance().terminate(); 23323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 23423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 23523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroyContext(mEglDisplay, mEglContext); 23623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroySurface(mEglDisplay, mPBufferSurface); 23723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 23823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglTerminate(mEglDisplay); 23923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglReleaseThread(); 24023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 24123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = EGL_NO_DISPLAY; 24223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = EGL_NO_CONTEXT; 24323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = EGL_NO_SURFACE; 24423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = EGL_NO_SURFACE; 24523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 24623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::makeCurrent(EGLSurface surface) { 2484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (isCurrent(surface)) return; 24923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 25023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (surface == EGL_NO_SURFACE) { 25123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // If we are setting EGL_NO_SURFACE we don't care about any of the potential 25223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // return errors, which would only happen if mEglDisplay had already been 25323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // destroyed in which case the current context is already NO_CONTEXT 25423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 25523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) { 2564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s", 2574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*)surface, egl_error_str()); 25823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 25923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = surface; 26023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 26123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { 2634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE, 2644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Tried to beginFrame on EGL_NO_SURFACE!"); 2654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(surface); 2664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width) { 2674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width); 26823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 2694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (height) { 2704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height); 2714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 2724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglBeginFrame(mEglDisplay, surface); 2734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 2744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 2754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::swapBuffers(EGLSurface surface) { 2764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglSwapBuffers(mEglDisplay, surface); 2774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint err = eglGetError(); 2784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Check whether we need to special case EGL_CONTEXT_LOST 2794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(err != EGL_SUCCESS, 2804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Encountered EGL error %d %s during rendering", err, egl_error_str(err)); 28123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 28223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 28323b797ab5151eb2474f3bdd679f2f07bfd723042John Reckbool GlobalContext::enableDirtyRegions(EGLSurface surface) { 28423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!mRequestDirtyRegions) return false; 28523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 28623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 28723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { 28823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s", 28923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 29023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 29123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 29223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return true; 29323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 29423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Perhaps it is already enabled? 29523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint value; 29623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) { 29723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", 29823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 29923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 30023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 30123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return value == EGL_BUFFER_PRESERVED; 30223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 30323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 3044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John ReckCanvasContext::CanvasContext(bool translucent) 3054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck : mRenderThread(RenderThread::getInstance()) 3064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mEglSurface(EGL_NO_SURFACE) 3074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mDirtyRegionsEnabled(false) 3084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mOpaque(!translucent) 3094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mCanvas(0) 3104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mHaveNewSurface(false) 3114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mInvokeFunctorsPending(false) 3124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mInvokeFunctorsTask(this) { 31323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext = GlobalContext::get(); 31423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 31523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 31623b797ab5151eb2474f3bdd679f2f07bfd723042John ReckCanvasContext::~CanvasContext() { 3174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck removeFunctorsTask(); 3184f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck destroyCanvas(); 3194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3204f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::destroyCanvas() { 3224f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) { 3234f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck delete mCanvas; 3244f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = 0; 3254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 32623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck setSurface(NULL); 32723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 32823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 3294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::setSurface(EGLNativeWindowType window) { 33023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 33123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext->destroySurface(mEglSurface); 33223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = EGL_NO_SURFACE; 33323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 33423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 33523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (window) { 33623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = mGlobalContext->createSurface(window); 3374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, 3384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create EGLSurface for window %p, eglErr = %s", 3394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*) window, egl_error_str()); 34023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 34123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 34223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 34323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface); 3444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = true; 3454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 3464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::swapBuffers() { 3494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->swapBuffers(mEglSurface); 3504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = false; 3514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::makeCurrent() { 3544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->makeCurrent(mEglSurface); 3554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckbool CanvasContext::initialize(EGLNativeWindowType window) { 3584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) return false; 3594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 3604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(); 3614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = new OpenGLRenderer(); 3624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->initProperties(); 3634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck return true; 3644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::updateSurface(EGLNativeWindowType window) { 3674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 3684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(); 3694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::setup(int width, int height) { 3724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mCanvas) return; 3734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 3744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 376e18264b079481a244b30e3f71012c53bbd861f92John Reckvoid CanvasContext::setDisplayListData(RenderNode* displayList, DisplayListData* newData) { 37744fd8d24f761f82d21e9b00932648a1b6bf91449John Reck displayList->setData(newData); 37844fd8d24f761f82d21e9b00932648a1b6bf91449John Reck} 37944fd8d24f761f82d21e9b00932648a1b6bf91449John Reck 38019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckvoid CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters) { 38119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck mGlobalContext->makeCurrent(mEglSurface); 38219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck for (size_t i = 0; i < layerUpdaters->size(); i++) { 38319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck DeferredLayerUpdater* update = layerUpdaters->itemAt(i); 38419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck LOG_ALWAYS_FATAL_IF(!update->apply(), "Failed to update layer!"); 38519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck if (update->backingLayer()->deferredUpdateScheduled) { 38619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck mCanvas->pushLayerUpdate(update->backingLayer()); 38719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 38819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 38919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 39019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 391e18264b079481a244b30e3f71012c53bbd861f92John Reckvoid CanvasContext::drawDisplayList(RenderNode* displayList, Rect* dirty) { 3924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, 3934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "drawDisplayList called on a context with no canvas or surface!"); 3944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint width, height; 3964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->beginFrame(mEglSurface, &width, &height); 3974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { 3984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 3994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty = NULL; 4004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else if (!mDirtyRegionsEnabled || mHaveNewSurface) { 4014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty = NULL; 4024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status_t status; 4054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (dirty) { 4064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status = mCanvas->prepareDirty(dirty->left, dirty->top, 4074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty->right, dirty->bottom, mOpaque); 4084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else { 4094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status = mCanvas->prepare(mOpaque); 4104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Rect outBounds; 4134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status |= mCanvas->drawDisplayList(displayList, outBounds); 4144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Draw debug info 4164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Performance tracking 4174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4184f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->finish(); 4194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4204f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (status & DrawGlInfo::kStatusDrew) { 4214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck swapBuffers(); 42223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 42323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 42423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 4254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid InvokeFunctorsTask::run() { 4264f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mContext->invokeFunctors(); 42723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 42823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 4294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::attachFunctor(Functor* functor) { 4304f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mCanvas) return; 4314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4324f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->attachFunctor(functor); 4334f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck removeFunctorsTask(); 4344f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck queueFunctorsTask(0); 43523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 43623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 4374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::detachFunctor(Functor* functor) { 4384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mCanvas) return; 4394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->detachFunctor(functor); 4414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 4424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::invokeFunctors() { 4444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mInvokeFunctorsPending = false; 4454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mCanvas) return; 4474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(); 4494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Rect dirty; 450750ca6dbdb259aea0ca5b77380a9303e586ef3eaJohn Reck mCanvas->invokeFunctors(dirty); 4514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 4524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::removeFunctorsTask() { 4544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mInvokeFunctorsPending) return; 4554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 45616efa9a330fcf10a09cc9564e9d319c6f4be2ae1John Reck mInvokeFunctorsPending = false; 4574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mRenderThread.remove(&mInvokeFunctorsTask); 4584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 4594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::queueFunctorsTask(int delayMs) { 4614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mInvokeFunctorsPending) return; 4624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mInvokeFunctorsPending = true; 4644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mRenderThread.queueDelayed(&mInvokeFunctorsTask, delayMs); 46523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 46623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 46719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckbool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { 46819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 46919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck layer->apply(); 47019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck return LayerRenderer::copyLayer(layer->backingLayer(), bitmap); 47119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 47219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 473fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reckvoid CanvasContext::runWithGlContext(RenderTask* task) { 47419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 47519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck task->run(); 47619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 47719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 47819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckvoid CanvasContext::requireGlContext() { 479fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck if (mEglSurface != EGL_NO_SURFACE) { 480fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck mGlobalContext->makeCurrent(mEglSurface); 481fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } else { 482fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck mGlobalContext->usePBufferSurface(); 483fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } 484fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck} 485fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck 48623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace renderthread */ 48723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace uirenderer */ 48823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace android */ 489