CanvasContext.cpp revision 832b151465ed81c43e59891d5eebe62128b21fbb
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; } 94dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck // Returns true if the current surface changed, false if it was already current 95dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck bool makeCurrent(EGLSurface surface); 964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); 974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck void swapBuffers(EGLSurface surface); 9823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 9923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck bool enableDirtyRegions(EGLSurface surface); 10023b797ab5151eb2474f3bdd679f2f07bfd723042John 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; 12123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck}; 12223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12323b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::sContext = 0; 12423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 12523b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext* GlobalContext::get() { 12623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!sContext) { 12723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck sContext = new GlobalContext(); 12823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 12923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return sContext; 13023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 13123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 13223b797ab5151eb2474f3bdd679f2f07bfd723042John ReckGlobalContext::GlobalContext() 13323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck : mEglDisplay(EGL_NO_DISPLAY) 13423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglConfig(0) 13523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mEglContext(EGL_NO_CONTEXT) 13623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mPBufferSurface(EGL_NO_SURFACE) 13723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mRequestDirtyRegions(load_dirty_regions_property()) 13823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck , mCurrentSurface(EGL_NO_SURFACE) { 13923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = mRequestDirtyRegions; 14023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); 14123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 14223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initialize() { 1440d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck if (hasContext()) return; 14523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 14623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 1474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 1484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to get EGL_DEFAULT_DISPLAY! err=%s", egl_error_str()); 14923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 15023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint major, minor; 1514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(eglInitialize(mEglDisplay, &major, &minor) == EGL_FALSE, 1524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to initialize display %p! err=%s", mEglDisplay, egl_error_str()); 15323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor); 15523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck loadConfig(); 1574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck createContext(); 1584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck usePBufferSurface(); 1594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Caches::getInstance().init(); 1604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck initAtlas(); 16123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 16223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1630d1f634f4b5e1bb37aa51777efb6a68619488d01John Reckbool GlobalContext::hasContext() { 1640d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck return mEglDisplay != EGL_NO_DISPLAY; 1650d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck} 1660d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck 1674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::loadConfig() { 16823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; 16923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { 17023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 17123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_RED_SIZE, 8, 17223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_GREEN_SIZE, 8, 17323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_BLUE_SIZE, 8, 17423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_ALPHA_SIZE, 8, 17523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_DEPTH_SIZE, 0, 17623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_CONFIG_CAVEAT, EGL_NONE, 17723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_STENCIL_SIZE, Stencil::getStencilSize(), 17823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior, 17923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGL_NONE 18023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck }; 18123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 18223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint num_configs = 1; 18323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs) 18423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck || num_configs != 1) { 18523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Failed to get a valid config 18623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 18723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); 18823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Try again without dirty regions enabled 18923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCanSetDirtyRegions = false; 19023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck loadConfig(); 19123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else { 1924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); 19323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 19423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 19523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 19623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 1974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::createContext() { 19823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, EGL_NONE }; 19923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs); 2004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT, 2014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create context, error = %s", egl_error_str()); 2024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 2034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 2044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::initAtlas() { 2054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO implement 2064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // For now just run without an atlas 20723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 20823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::usePBufferSurface() { 2104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, 2114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "usePBufferSurface() called on uninitialized GlobalContext!"); 21223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 21323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mPBufferSurface == EGL_NO_SURFACE) { 21423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; 21523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); 21623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 2174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(mPBufferSurface); 21823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 21923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 22023b797ab5151eb2474f3bdd679f2f07bfd723042John ReckEGLSurface GlobalContext::createSurface(EGLNativeWindowType window) { 22123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck initialize(); 22223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return eglCreateWindowSurface(mEglDisplay, mEglConfig, window, NULL); 22323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 22423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 22523b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroySurface(EGLSurface surface) { 22623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (isCurrent(surface)) { 22723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck makeCurrent(EGL_NO_SURFACE); 22823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 22923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglDestroySurface(mEglDisplay, surface)) { 23023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to destroy surface %p, error=%s", (void*)surface, egl_error_str()); 23123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 23223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 23323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 23423b797ab5151eb2474f3bdd679f2f07bfd723042John Reckvoid GlobalContext::destroy() { 23523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglDisplay == EGL_NO_DISPLAY) return; 23623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 23723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck usePBufferSurface(); 23823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (Caches::hasInstance()) { 23923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck Caches::getInstance().terminate(); 24023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 24123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 24223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroyContext(mEglDisplay, mEglContext); 24323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglDestroySurface(mEglDisplay, mPBufferSurface); 24423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 24523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglTerminate(mEglDisplay); 24623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglReleaseThread(); 24723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 24823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglDisplay = EGL_NO_DISPLAY; 24923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglContext = EGL_NO_CONTEXT; 25023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mPBufferSurface = EGL_NO_SURFACE; 25123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = EGL_NO_SURFACE; 25223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 25323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 254dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reckbool GlobalContext::makeCurrent(EGLSurface surface) { 255dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck if (isCurrent(surface)) return false; 25623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 25723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (surface == EGL_NO_SURFACE) { 25823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // If we are setting EGL_NO_SURFACE we don't care about any of the potential 25923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // return errors, which would only happen if mEglDisplay had already been 26023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // destroyed in which case the current context is already NO_CONTEXT 26123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 26223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } else if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) { 2634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s", 2644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*)surface, egl_error_str()); 26523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 26623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mCurrentSurface = surface; 267dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck return true; 26823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 26923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 2704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) { 2714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE, 2724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Tried to beginFrame on EGL_NO_SURFACE!"); 2734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck makeCurrent(surface); 2744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width) { 2754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width); 27623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 2774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (height) { 2784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height); 2794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 2804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglBeginFrame(mEglDisplay, surface); 2814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 2824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 2834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid GlobalContext::swapBuffers(EGLSurface surface) { 2844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck eglSwapBuffers(mEglDisplay, surface); 2854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint err = eglGetError(); 2864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(err != EGL_SUCCESS, 2874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Encountered EGL error %d %s during rendering", err, egl_error_str(err)); 28823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 28923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 29023b797ab5151eb2474f3bdd679f2f07bfd723042John Reckbool GlobalContext::enableDirtyRegions(EGLSurface surface) { 29123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!mRequestDirtyRegions) return false; 29223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 29323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mCanSetDirtyRegions) { 29423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { 29523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s", 29623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 29723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 29823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 29923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return true; 30023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 30123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck // Perhaps it is already enabled? 30223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck EGLint value; 30323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) { 30423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", 30523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck (void*) surface, egl_error_str()); 30623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return false; 30723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 30823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck return value == EGL_BUFFER_PRESERVED; 30923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 31023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 311e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn ReckCanvasContext::CanvasContext(bool translucent, RenderNode* rootRenderNode) 3124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck : mRenderThread(RenderThread::getInstance()) 3134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mEglSurface(EGL_NO_SURFACE) 3144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mDirtyRegionsEnabled(false) 3154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mOpaque(!translucent) 3164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck , mCanvas(0) 317e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck , mHaveNewSurface(false) 318e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck , mRootRenderNode(rootRenderNode) { 31923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext = GlobalContext::get(); 32023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 32123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 32223b797ab5151eb2474f3bdd679f2f07bfd723042John ReckCanvasContext::~CanvasContext() { 323fae904d63947fe1687d1d44be29234cc3d538f24John Reck destroyCanvasAndSurface(); 324e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mRenderThread.removeFrameCallback(this); 3254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3264f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 327fae904d63947fe1687d1d44be29234cc3d538f24John Reckvoid CanvasContext::destroyCanvasAndSurface() { 3284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) { 3294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck delete mCanvas; 3304f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = 0; 3314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 33223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck setSurface(NULL); 33323b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 33423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 3354f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::setSurface(EGLNativeWindowType window) { 33623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 33723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mGlobalContext->destroySurface(mEglSurface); 33823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = EGL_NO_SURFACE; 33923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 34023b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 34123b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (window) { 34223b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mEglSurface = mGlobalContext->createSurface(window); 3434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, 3444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "Failed to create EGLSurface for window %p, eglErr = %s", 3454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck (void*) window, egl_error_str()); 34623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 34723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 34823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck if (mEglSurface != EGL_NO_SURFACE) { 34923b797ab5151eb2474f3bdd679f2f07bfd723042John Reck mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface); 3504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = true; 351dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck makeCurrent(); 3524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 3534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::swapBuffers() { 3564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->swapBuffers(mEglSurface); 3574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mHaveNewSurface = false; 3584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 360f7d9c1dc84671d4e99657ef071d275700d85bb11John Reckvoid CanvasContext::requireSurface() { 361f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, 362f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck "requireSurface() called but no surface set!"); 363dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck makeCurrent(); 3644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckbool CanvasContext::initialize(EGLNativeWindowType window) { 3674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (mCanvas) return false; 3684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 3694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas = new OpenGLRenderer(); 3704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->initProperties(); 3714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck return true; 3724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::updateSurface(EGLNativeWindowType window) { 3754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck setSurface(window); 376f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck} 377f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck 378f7d9c1dc84671d4e99657ef071d275700d85bb11John Reckvoid CanvasContext::pauseSurface(EGLNativeWindowType window) { 379f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck // TODO: For now we just need a fence, in the future suspend any animations 380f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck // and such to prevent from trying to render into this surface 3814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 3834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reckvoid CanvasContext::setup(int width, int height) { 3844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (!mCanvas) return; 3854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 3864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck} 3874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 388860d155f866cc15a725e7ce03763280987f24901John Reckvoid CanvasContext::makeCurrent() { 389dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck // TODO: Figure out why this workaround is needed, see b/13913604 390dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck // In the meantime this matches the behavior of GLRenderer, so it is not a regression 391dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck mHaveNewSurface |= mGlobalContext->makeCurrent(mEglSurface); 392860d155f866cc15a725e7ce03763280987f24901John Reck} 393860d155f866cc15a725e7ce03763280987f24901John Reck 394f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reckvoid CanvasContext::prepareDraw(const Vector<DeferredLayerUpdater*>* layerUpdaters, 395860d155f866cc15a725e7ce03763280987f24901John Reck TreeInfo& info) { 396f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck LOG_ALWAYS_FATAL_IF(!mCanvas, "Cannot prepareDraw without a canvas!"); 397860d155f866cc15a725e7ce03763280987f24901John Reck makeCurrent(); 398f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck 399f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck processLayerUpdates(layerUpdaters, info); 400f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.hasAnimations) { 401f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // TODO: Uh... crap? 402f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } 403f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck prepareTree(info); 404f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck} 405f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck 406f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reckvoid CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, 407f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck TreeInfo& info) { 40819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck for (size_t i = 0; i < layerUpdaters->size(); i++) { 40919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck DeferredLayerUpdater* update = layerUpdaters->itemAt(i); 410860d155f866cc15a725e7ce03763280987f24901John Reck bool success = update->apply(info); 411860d155f866cc15a725e7ce03763280987f24901John Reck LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!"); 41219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck if (update->backingLayer()->deferredUpdateScheduled) { 41319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck mCanvas->pushLayerUpdate(update->backingLayer()); 41419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 41519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 41619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 41719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 418e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckvoid CanvasContext::prepareTree(TreeInfo& info) { 419f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mRenderThread.removeFrameCallback(this); 42018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck 421f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); 422e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mRootRenderNode->prepareTree(info); 423e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 424f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.hasAnimations) { 425f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if (info.out.hasFunctors) { 426f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck info.out.requiresUiRedraw = true; 427f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } else if (!info.out.requiresUiRedraw) { 428f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // If animationsNeedsRedraw is set don't bother posting for an RT anim 429f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // as we will just end up fighting the UI thread. 430f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck mRenderThread.postFrameCallback(this); 431f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } 432e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 433e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 434e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 435e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckvoid CanvasContext::draw(Rect* dirty) { 4364f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE, 4374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck "drawDisplayList called on a context with no canvas or surface!"); 4384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck EGLint width, height; 4404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mGlobalContext->beginFrame(mEglSurface, &width, &height); 4414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { 4424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->setViewport(width, height); 4434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty = NULL; 4444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else if (!mDirtyRegionsEnabled || mHaveNewSurface) { 4454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty = NULL; 4464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status_t status; 449e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck if (dirty && !dirty->isEmpty()) { 4504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status = mCanvas->prepareDirty(dirty->left, dirty->top, 4514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck dirty->right, dirty->bottom, mOpaque); 4524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } else { 4534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck status = mCanvas->prepare(mOpaque); 4544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 4554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck Rect outBounds; 457e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck status |= mCanvas->drawDisplayList(mRootRenderNode.get(), outBounds); 4584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Draw debug info 4604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck // TODO: Performance tracking 4614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck mCanvas->finish(); 4634f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 4644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (status & DrawGlInfo::kStatusDrew) { 4654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck swapBuffers(); 46623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck } 46723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 46823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 469e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// Called by choreographer to do an RT-driven animation 47018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reckvoid CanvasContext::doFrame() { 471e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck ATRACE_CALL(); 472e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 473e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck TreeInfo info; 474e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.evaluateAnimations = true; 475e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.performStagingPush = false; 476e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck info.prepareTextures = false; 477e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 478e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck prepareTree(info); 479e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck draw(NULL); 480e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 481e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 4820d1f634f4b5e1bb37aa51777efb6a68619488d01John Reckvoid CanvasContext::invokeFunctor(Functor* functor) { 483d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck ATRACE_CALL(); 4840d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext; 4850d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck if (mGlobalContext->hasContext()) { 4860d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck requireGlContext(); 4870d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck mode = DrawGlInfo::kModeProcess; 4880d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck } 489832b151465ed81c43e59891d5eebe62128b21fbbJohn Reck (*functor)(mode, NULL); 4906f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck 4916f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck if (mCanvas) { 4926f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck mCanvas->resume(); 4936f07a0dc875a9eac67312085a8e0133b9e2f4771John Reck } 49423b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} 49523b797ab5151eb2474f3bdd679f2f07bfd723042John Reck 49619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckbool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { 49719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 498860d155f866cc15a725e7ce03763280987f24901John Reck TreeInfo info; 499860d155f866cc15a725e7ce03763280987f24901John Reck layer->apply(info); 50019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck return LayerRenderer::copyLayer(layer->backingLayer(), bitmap); 50119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 50219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 503fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reckvoid CanvasContext::runWithGlContext(RenderTask* task) { 50419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck requireGlContext(); 50519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck task->run(); 50619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck} 50719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 5081949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createRenderLayer(int width, int height) { 509f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck requireSurface(); 5101949e7928eeec22cd3f74b5f763a4eb433238453John Reck return LayerRenderer::createRenderLayer(width, height); 5111949e7928eeec22cd3f74b5f763a4eb433238453John Reck} 5121949e7928eeec22cd3f74b5f763a4eb433238453John Reck 5131949e7928eeec22cd3f74b5f763a4eb433238453John ReckLayer* CanvasContext::createTextureLayer() { 514f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck requireSurface(); 5151949e7928eeec22cd3f74b5f763a4eb433238453John Reck return LayerRenderer::createTextureLayer(); 5161949e7928eeec22cd3f74b5f763a4eb433238453John Reck} 5171949e7928eeec22cd3f74b5f763a4eb433238453John Reck 51819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reckvoid CanvasContext::requireGlContext() { 519fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck if (mEglSurface != EGL_NO_SURFACE) { 520dbc9a86d05e5e835051de22f6cb30ec1921e9705John Reck makeCurrent(); 521fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } else { 522fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck mGlobalContext->usePBufferSurface(); 523fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck } 524fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck} 525fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck 52623b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace renderthread */ 52723b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace uirenderer */ 52823b797ab5151eb2474f3bdd679f2f07bfd723042John Reck} /* namespace android */ 529