Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "OpenGLRenderer"
     18 
     19 #include <utils/Log.h>
     20 #include <utils/String8.h>
     21 
     22 #include "Caches.h"
     23 #include "Properties.h"
     24 #include "LayerRenderer.h"
     25 
     26 namespace android {
     27 
     28 #ifdef USE_OPENGL_RENDERER
     29 using namespace uirenderer;
     30 ANDROID_SINGLETON_STATIC_INSTANCE(Caches);
     31 #endif
     32 
     33 namespace uirenderer {
     34 
     35 ///////////////////////////////////////////////////////////////////////////////
     36 // Macros
     37 ///////////////////////////////////////////////////////////////////////////////
     38 
     39 #if DEBUG_CACHE_FLUSH
     40     #define FLUSH_LOGD(...) LOGD(__VA_ARGS__)
     41 #else
     42     #define FLUSH_LOGD(...)
     43 #endif
     44 
     45 ///////////////////////////////////////////////////////////////////////////////
     46 // Constructors/destructor
     47 ///////////////////////////////////////////////////////////////////////////////
     48 
     49 Caches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO),
     50         lastDstMode(GL_ZERO), currentProgram(NULL) {
     51     GLint maxTextureUnits;
     52     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
     53     if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
     54         LOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
     55     }
     56 
     57     glGenBuffers(1, &meshBuffer);
     58     glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
     59     glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
     60 
     61     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
     62 
     63     mCurrentBuffer = meshBuffer;
     64     mRegionMesh = NULL;
     65 
     66     mDebugLevel = readDebugLevel();
     67     LOGD("Enabling debug mode %d", mDebugLevel);
     68 
     69 #if RENDER_LAYERS_AS_REGIONS
     70     INIT_LOGD("Layers will be composited as regions");
     71 #endif
     72 }
     73 
     74 Caches::~Caches() {
     75     delete[] mRegionMesh;
     76 }
     77 
     78 ///////////////////////////////////////////////////////////////////////////////
     79 // Debug
     80 ///////////////////////////////////////////////////////////////////////////////
     81 
     82 void Caches::dumpMemoryUsage() {
     83     String8 stringLog;
     84     dumpMemoryUsage(stringLog);
     85     LOGD("%s", stringLog.string());
     86 }
     87 
     88 void Caches::dumpMemoryUsage(String8 &log) {
     89     log.appendFormat("Current memory usage / total memory usage (bytes):\n");
     90     log.appendFormat("  TextureCache         %8d / %8d\n",
     91             textureCache.getSize(), textureCache.getMaxSize());
     92     log.appendFormat("  LayerCache           %8d / %8d\n",
     93             layerCache.getSize(), layerCache.getMaxSize());
     94     log.appendFormat("  GradientCache        %8d / %8d\n",
     95             gradientCache.getSize(), gradientCache.getMaxSize());
     96     log.appendFormat("  PathCache            %8d / %8d\n",
     97             pathCache.getSize(), pathCache.getMaxSize());
     98     log.appendFormat("  CircleShapeCache     %8d / %8d\n",
     99             circleShapeCache.getSize(), circleShapeCache.getMaxSize());
    100     log.appendFormat("  OvalShapeCache       %8d / %8d\n",
    101             ovalShapeCache.getSize(), ovalShapeCache.getMaxSize());
    102     log.appendFormat("  RoundRectShapeCache  %8d / %8d\n",
    103             roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
    104     log.appendFormat("  RectShapeCache       %8d / %8d\n",
    105             rectShapeCache.getSize(), rectShapeCache.getMaxSize());
    106     log.appendFormat("  ArcShapeCache        %8d / %8d\n",
    107             arcShapeCache.getSize(), arcShapeCache.getMaxSize());
    108     log.appendFormat("  TextDropShadowCache  %8d / %8d\n", dropShadowCache.getSize(),
    109             dropShadowCache.getMaxSize());
    110     for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
    111         const uint32_t size = fontRenderer.getFontRendererSize(i);
    112         log.appendFormat("  FontRenderer %d       %8d / %8d\n", i, size, size);
    113     }
    114     log.appendFormat("Other:\n");
    115     log.appendFormat("  FboCache             %8d / %8d\n",
    116             fboCache.getSize(), fboCache.getMaxSize());
    117     log.appendFormat("  PatchCache           %8d / %8d\n",
    118             patchCache.getSize(), patchCache.getMaxSize());
    119 
    120     uint32_t total = 0;
    121     total += textureCache.getSize();
    122     total += layerCache.getSize();
    123     total += gradientCache.getSize();
    124     total += pathCache.getSize();
    125     total += dropShadowCache.getSize();
    126     total += roundRectShapeCache.getSize();
    127     total += circleShapeCache.getSize();
    128     total += ovalShapeCache.getSize();
    129     total += rectShapeCache.getSize();
    130     total += arcShapeCache.getSize();
    131     for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
    132         total += fontRenderer.getFontRendererSize(i);
    133     }
    134 
    135     log.appendFormat("Total memory usage:\n");
    136     log.appendFormat("  %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f);
    137 }
    138 
    139 ///////////////////////////////////////////////////////////////////////////////
    140 // Memory management
    141 ///////////////////////////////////////////////////////////////////////////////
    142 
    143 void Caches::clearGarbage() {
    144     textureCache.clearGarbage();
    145     pathCache.clearGarbage();
    146 
    147     Mutex::Autolock _l(mGarbageLock);
    148 
    149     size_t count = mLayerGarbage.size();
    150     for (size_t i = 0; i < count; i++) {
    151         Layer* layer = mLayerGarbage.itemAt(i);
    152         LayerRenderer::destroyLayer(layer);
    153     }
    154     mLayerGarbage.clear();
    155 }
    156 
    157 void Caches::deleteLayerDeferred(Layer* layer) {
    158     Mutex::Autolock _l(mGarbageLock);
    159     mLayerGarbage.push(layer);
    160 }
    161 
    162 void Caches::flush(FlushMode mode) {
    163     FLUSH_LOGD("Flushing caches (mode %d)", mode);
    164 
    165     clearGarbage();
    166 
    167     switch (mode) {
    168         case kFlushMode_Full:
    169             textureCache.clear();
    170             patchCache.clear();
    171             dropShadowCache.clear();
    172             gradientCache.clear();
    173             // fall through
    174         case kFlushMode_Moderate:
    175             pathCache.clear();
    176             roundRectShapeCache.clear();
    177             circleShapeCache.clear();
    178             ovalShapeCache.clear();
    179             rectShapeCache.clear();
    180             arcShapeCache.clear();
    181             // fall through
    182         case kFlushMode_Layers:
    183             layerCache.clear();
    184             break;
    185     }
    186 }
    187 
    188 ///////////////////////////////////////////////////////////////////////////////
    189 // VBO
    190 ///////////////////////////////////////////////////////////////////////////////
    191 
    192 void Caches::bindMeshBuffer() {
    193     bindMeshBuffer(meshBuffer);
    194 }
    195 
    196 void Caches::bindMeshBuffer(const GLuint buffer) {
    197     if (mCurrentBuffer != buffer) {
    198         glBindBuffer(GL_ARRAY_BUFFER, buffer);
    199         mCurrentBuffer = buffer;
    200     }
    201 }
    202 
    203 void Caches::unbindMeshBuffer() {
    204     if (mCurrentBuffer) {
    205         glBindBuffer(GL_ARRAY_BUFFER, 0);
    206         mCurrentBuffer = 0;
    207     }
    208 }
    209 
    210 TextureVertex* Caches::getRegionMesh() {
    211     // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
    212     if (!mRegionMesh) {
    213         mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
    214 
    215         uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
    216         for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
    217             uint16_t quad = i * 4;
    218             int index = i * 6;
    219             regionIndices[index    ] = quad;       // top-left
    220             regionIndices[index + 1] = quad + 1;   // top-right
    221             regionIndices[index + 2] = quad + 2;   // bottom-left
    222             regionIndices[index + 3] = quad + 2;   // bottom-left
    223             regionIndices[index + 4] = quad + 1;   // top-right
    224             regionIndices[index + 5] = quad + 3;   // bottom-right
    225         }
    226 
    227         glGenBuffers(1, &mRegionMeshIndices);
    228         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
    229         glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
    230                 regionIndices, GL_STATIC_DRAW);
    231 
    232         delete[] regionIndices;
    233     } else {
    234         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
    235     }
    236 
    237     return mRegionMesh;
    238 }
    239 
    240 }; // namespace uirenderer
    241 }; // namespace android
    242