CanvasContext.cpp revision fae904d63947fe1687d1d44be29234cc3d538f24
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 850d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck bool hasContext(); 860d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck 874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void usePBufferSurface(); 8823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface createSurface(EGLNativeWindowType window); 8923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck void destroySurface(EGLSurface surface); 9023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck void destroy(); 9223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; } 944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void makeCurrent(EGLSurface surface); 954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); 964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void swapBuffers(EGLSurface surface); 9723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool enableDirtyRegions(EGLSurface surface); 9923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 10023b797ab5151eb2474f3bdd679f2f07bfd723042John Reckprivate: 10123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck GlobalContext(); 10223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // GlobalContext is never destroyed, method is purposely not implemented 10323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ~GlobalContext(); 10423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void loadConfig(); 1064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void createContext(); 1074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void initAtlas(); 10823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 10923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck static GlobalContext* sContext; 11023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLDisplay mEglDisplay; 11223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLConfig mEglConfig; 11323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLContext mEglContext; 11423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface mPBufferSurface; 11523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck const bool mRequestDirtyRegions; 11723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool mCanSetDirtyRegions; 11823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 11923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLSurface mCurrentSurface; 12023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}; 12123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12223b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::sContext = 0; 12323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12423b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::get() { 12523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!sContext) { 12623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck sContext = new GlobalContext(); 12723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 12823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return sContext; 12923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 13023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 13123b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext::GlobalContext() 13223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck : mEglDisplay(EGL_NO_DISPLAY) 13323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglConfig(0) 13423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglContext(EGL_NO_CONTEXT) 13523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mPBufferSurface(EGL_NO_SURFACE) 13623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mRequestDirtyRegions(load_dirty_regions_property()) 13723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mCurrentSurface(EGL_NO_SURFACE) { 13823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = mRequestDirtyRegions; 13923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); 14023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 14123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initialize() { 1430d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck if (hasContext()) return; 14423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 14523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 1464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 1474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to get EGL_DEFAULT_DISPLAY! err=%s", egl_error_str()); 14823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 14923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint major, minor; 1504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(eglInitialize(mEglDisplay, &major, &minor) == EGL_FALSE, 1514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to initialize display %p! err=%s", mEglDisplay, egl_error_str()); 15223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor); 15423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck loadConfig(); 1564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck createContext(); 1574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck usePBufferSurface(); 1584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Caches::getInstance().init(); 1594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck initAtlas(); 16023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 16123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1620d1f634f4b5e1bb37aa51777efb6a68619488d01John Reckbool GlobalContext::hasContext() { 1630d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck return mEglDisplay != EGL_NO_DISPLAY; 1640d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck} 1650d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck 1664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::loadConfig() { 16723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; 16823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { 16923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 17023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RED_SIZE, 8, 17123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_GREEN_SIZE, 8, 17223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_BLUE_SIZE, 8, 17323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_ALPHA_SIZE, 8, 17423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_DEPTH_SIZE, 0, 17523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_CONFIG_CAVEAT, EGL_NONE, 17623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_STENCIL_SIZE, Stencil::getStencilSize(), 17723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior, 17823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_NONE 17923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck }; 18023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 18123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint num_configs = 1; 18223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs) 18323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck || num_configs != 1) { 18423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Failed to get a valid config 18523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 18623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); 18723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Try again without dirty regions enabled 18823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = false; 18923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck loadConfig(); 19023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else { 1914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); 19223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 19323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 19423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 19523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::createContext() { 19723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, EGL_NONE }; 19823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs); 1994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT, 2004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create context, error = %s", egl_error_str()); 2014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 2024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 2034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initAtlas() { 2044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO implement 2054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // For now just run without an atlas 20623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 20723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::usePBufferSurface() { 2094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 2104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "usePBufferSurface() called on uninitialized GlobalContext!"); 21123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 21223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mPBufferSurface == EGL_NO_SURFACE) { 21323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; 21423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); 21523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 2164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(mPBufferSurface); 21723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 21823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 21923b797ab5151eb2474f3bdd679f2f07bfd723042John ReckEGLSurface GlobalContext::createSurface(EGLNativeWindowType window) { 22023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck initialize(); 22123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return eglCreateWindowSurface(mEglDisplay, mEglConfig, window, NULL); 22223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 22323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 22423b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroySurface(EGLSurface surface) { 22523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (isCurrent(surface)) { 22623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck makeCurrent(EGL_NO_SURFACE); 22723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 22823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglDestroySurface(mEglDisplay, surface)) { 22923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to destroy surface %p, error=%s", (void*)surface, egl_error_str()); 23023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 23123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 23223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 23323b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroy() { 23423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglDisplay == EGL_NO_DISPLAY) return; 23523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 23623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck usePBufferSurface(); 23723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (Caches::hasInstance()) { 23823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck Caches::getInstance().terminate(); 23923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 24023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 24123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroyContext(mEglDisplay, mEglContext); 24223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroySurface(mEglDisplay, mPBufferSurface); 24323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 24423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglTerminate(mEglDisplay); 24523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglReleaseThread(); 24623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 24723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = EGL_NO_DISPLAY; 24823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = EGL_NO_CONTEXT; 24923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = EGL_NO_SURFACE; 25023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = EGL_NO_SURFACE; 25123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 25223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::makeCurrent(EGLSurface surface) { 2544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (isCurrent(surface)) return; 25523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 25623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (surface == EGL_NO_SURFACE) { 25723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // If we are setting EGL_NO_SURFACE we don't care about any of the potential 25823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // return errors, which would only happen if mEglDisplay had already been 25923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // destroyed in which case the current context is already NO_CONTEXT 26023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 26123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) { 2624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s", 2634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*)surface, egl_error_str()); 26423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 26523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = surface; 26623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 26723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { 2694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE, 2704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Tried to beginFrame on EGL_NO_SURFACE!"); 2714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(surface); 2724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width) { 2734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width); 27423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 2754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (height) { 2764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height); 2774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 2784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglBeginFrame(mEglDisplay, surface); 2794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 2804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 2814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::swapBuffers(EGLSurface surface) { 2824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglSwapBuffers(mEglDisplay, surface); 2834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint err = eglGetError(); 2844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Check whether we need to special case EGL_CONTEXT_LOST 2854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(err != EGL_SUCCESS, 2864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Encountered EGL error %d %s during rendering", err, egl_error_str(err)); 28723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 28823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 28923b797ab5151eb2474f3bdd679f2f07bfd723042John Reckbool GlobalContext::enableDirtyRegions(EGLSurface surface) { 29023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!mRequestDirtyRegions) return false; 29123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 29223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 29323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { 29423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s", 29523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 29623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 29723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 29823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return true; 29923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 30023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Perhaps it is already enabled? 30123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint value; 30223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) { 30323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", 30423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 30523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 30623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 30723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return value == EGL_BUFFER_PRESERVED; 30823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 30923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 3104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John ReckCanvasContext::CanvasContext(bool translucent) 3114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck : mRenderThread(RenderThread::getInstance()) 3124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mEglSurface(EGL_NO_SURFACE) 3134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mDirtyRegionsEnabled(false) 3144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mOpaque(!translucent) 3154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mCanvas(0) 316d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck , mHaveNewSurface(false) { 31723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext = GlobalContext::get(); 31823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 31923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 32023b797ab5151eb2474f3bdd679f2f07bfd723042John ReckCanvasContext::~CanvasContext() { 321fae904d63947fe1687d1d44be29234cc3d538f24John Reck destroyCanvasAndSurface(); 3224f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3234f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 324fae904d63947fe1687d1d44be29234cc3d538f24John Reckvoid CanvasContext::destroyCanvasAndSurface() { 3254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) { 3264f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck delete mCanvas; 3274f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = 0; 3284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 32923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck setSurface(NULL); 33023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 33123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 3324f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::setSurface(EGLNativeWindowType window) { 33323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 33423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext->destroySurface(mEglSurface); 33523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = EGL_NO_SURFACE; 33623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 33723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 33823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (window) { 33923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = mGlobalContext->createSurface(window); 3404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, 3414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create EGLSurface for window %p, eglErr = %s", 3424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*) window, egl_error_str()); 34323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 34423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 34523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 34623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface); 347f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck mGlobalContext->makeCurrent(mEglSurface); 3484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = true; 3494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 3504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::swapBuffers() { 3534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->swapBuffers(mEglSurface); 3544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = false; 3554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 357f7d9c1dc84671d4e99657ef071d275700d85bb11John Reckvoid CanvasContext::requireSurface() { 358f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, 359f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck "requireSurface() called but no surface set!"); 3604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->makeCurrent(mEglSurface); 3614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckbool CanvasContext::initialize(EGLNativeWindowType window) { 3644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) return false; 3654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 3664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = new OpenGLRenderer(); 3674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->initProperties(); 3684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck return true; 3694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::updateSurface(EGLNativeWindowType window) { 3724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 373f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck} 374f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck 375f7d9c1dc84671d4e99657ef071d275700d85bb11John Reckvoid CanvasContext::pauseSurface(EGLNativeWindowType window) { 376f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck // TODO: For now we just need a fence, in the future suspend any animations 377f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck // and such to prevent from trying to render into this surface 3784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::setup(int width, int height) { 3814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mCanvas) return; 3824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 3834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 385f4198b713e43c0c0f9adac74203cf24c2a49b802John Reckvoid CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, 386f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck bool* hasFunctors) { 3878ca3eecc2b7fe507d3482745efc4cd2567ad15a1John Reck LOG_ALWAYS_FATAL_IF(!mCanvas, "Cannot process layer updates without a canvas!"); 38819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck mGlobalContext->makeCurrent(mEglSurface); 38919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck for (size_t i = 0; i < layerUpdaters->size(); i++) { 39019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck DeferredLayerUpdater* update = layerUpdaters->itemAt(i); 391f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck LOG_ALWAYS_FATAL_IF(!update->apply(hasFunctors), "Failed to update layer!"); 39219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck if (update->backingLayer()->deferredUpdateScheduled) { 39319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck mCanvas->pushLayerUpdate(update->backingLayer()); 39419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 39519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 39619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 39719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 398e18264b079481a244b30e3f71012c53bbd861f92John Reckvoid CanvasContext::drawDisplayList(RenderNode* displayList, Rect* dirty) { 3994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, 4004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "drawDisplayList called on a context with no canvas or surface!"); 4014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint width, height; 4034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->beginFrame(mEglSurface, &width, &height); 4044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { 4054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 4064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty = NULL; 4074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else if (!mDirtyRegionsEnabled || mHaveNewSurface) { 4084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty = NULL; 4094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status_t status; 4124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (dirty) { 4134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status = mCanvas->prepareDirty(dirty->left, dirty->top, 4144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty->right, dirty->bottom, mOpaque); 4154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else { 4164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status = mCanvas->prepare(mOpaque); 4174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4184f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Rect outBounds; 4204f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status |= mCanvas->drawDisplayList(displayList, outBounds); 4214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4224f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Draw debug info 4234f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Performance tracking 4244f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->finish(); 4264f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4274f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (status & DrawGlInfo::kStatusDrew) { 4284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck swapBuffers(); 42923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 43023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 43123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 4320d1f634f4b5e1bb37aa51777efb6a68619488d01John Reckvoid CanvasContext::invokeFunctor(Functor* functor) { 433d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck ATRACE_CALL(); 4340d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext; 4350d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck if (mGlobalContext->hasContext()) { 4360d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck requireGlContext(); 4370d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck mode = DrawGlInfo::kModeProcess; 4380d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck } 439d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck // TODO: Remove the dummy info in the future 440d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck DrawGlInfo dummyInfo; 441d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck memset(&dummyInfo, 0, sizeof(DrawGlInfo)); 442d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck (*functor)(mode, &dummyInfo); 44323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 44423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 44519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckbool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { 44619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 447f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck bool hasFunctors; 448f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck layer->apply(&hasFunctors); 44919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck return LayerRenderer::copyLayer(layer->backingLayer(), bitmap); 45019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 45119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 452fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reckvoid CanvasContext::runWithGlContext(RenderTask* task) { 45319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 45419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck task->run(); 45519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 45619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 4571949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createRenderLayer(int width, int height) { 458f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck requireSurface(); 4591949e7928eeec22cd3f74b5f763a4eb433238453John Reck return LayerRenderer::createRenderLayer(width, height); 4601949e7928eeec22cd3f74b5f763a4eb433238453John Reck} 4611949e7928eeec22cd3f74b5f763a4eb433238453John Reck 4621949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createTextureLayer() { 463f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck requireSurface(); 4641949e7928eeec22cd3f74b5f763a4eb433238453John Reck return LayerRenderer::createTextureLayer(); 4651949e7928eeec22cd3f74b5f763a4eb433238453John Reck} 4661949e7928eeec22cd3f74b5f763a4eb433238453John Reck 46719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckvoid CanvasContext::requireGlContext() { 468fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck if (mEglSurface != EGL_NO_SURFACE) { 469fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck mGlobalContext->makeCurrent(mEglSurface); 470fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } else { 471fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck mGlobalContext->usePBufferSurface(); 472fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } 473fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck} 474fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck 47523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace renderthread */ 47623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace uirenderer */ 47723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace android */ 478