Caches.cpp revision 02ccac69fd1c0a03c24c5f3ace0ad4bed337b1fd
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 26namespace android { 27 28#ifdef USE_OPENGL_RENDERER 29using namespace uirenderer; 30ANDROID_SINGLETON_STATIC_INSTANCE(Caches); 31#endif 32 33namespace uirenderer { 34 35/////////////////////////////////////////////////////////////////////////////// 36// Constructors/destructor 37/////////////////////////////////////////////////////////////////////////////// 38 39Caches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO), 40 lastDstMode(GL_ZERO), currentProgram(NULL) { 41 GLint maxTextureUnits; 42 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); 43 if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) { 44 LOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT); 45 } 46 47 glGenBuffers(1, &meshBuffer); 48 glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); 49 glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW); 50 51 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 52 53 mCurrentBuffer = meshBuffer; 54 mRegionMesh = NULL; 55 56 mDebugLevel = readDebugLevel(); 57 LOGD("Enabling debug mode %d", mDebugLevel); 58 59#if RENDER_LAYERS_AS_REGIONS 60 INIT_LOGD("Layers will be composited as regions"); 61#endif 62} 63 64Caches::~Caches() { 65 delete[] mRegionMesh; 66} 67 68/////////////////////////////////////////////////////////////////////////////// 69// Debug 70/////////////////////////////////////////////////////////////////////////////// 71 72void Caches::dumpMemoryUsage() { 73 String8 stringLog; 74 dumpMemoryUsage(stringLog); 75 LOGD("%s", stringLog.string()); 76 delete stringLog; 77} 78 79void Caches::dumpMemoryUsage(String8 &log) { 80 log.appendFormat("Current memory usage / total memory usage (bytes):\n"); 81 log.appendFormat(" TextureCache %8d / %8d\n", 82 textureCache.getSize(), textureCache.getMaxSize()); 83 log.appendFormat(" LayerCache %8d / %8d\n", 84 layerCache.getSize(), layerCache.getMaxSize()); 85 log.appendFormat(" GradientCache %8d / %8d\n", 86 gradientCache.getSize(), gradientCache.getMaxSize()); 87 log.appendFormat(" PathCache %8d / %8d\n", 88 pathCache.getSize(), pathCache.getMaxSize()); 89 log.appendFormat(" CircleShapeCache %8d / %8d\n", 90 circleShapeCache.getSize(), circleShapeCache.getMaxSize()); 91 log.appendFormat(" OvalShapeCache %8d / %8d\n", 92 ovalShapeCache.getSize(), ovalShapeCache.getMaxSize()); 93 log.appendFormat(" RoundRectShapeCache %8d / %8d\n", 94 roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize()); 95 log.appendFormat(" RectShapeCache %8d / %8d\n", 96 rectShapeCache.getSize(), rectShapeCache.getMaxSize()); 97 log.appendFormat(" ArcShapeCache %8d / %8d\n", 98 arcShapeCache.getSize(), arcShapeCache.getMaxSize()); 99 log.appendFormat(" TextDropShadowCache %8d / %8d\n", dropShadowCache.getSize(), 100 dropShadowCache.getMaxSize()); 101 for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) { 102 const uint32_t size = fontRenderer.getFontRendererSize(i); 103 log.appendFormat(" FontRenderer %d %8d / %8d\n", i, size, size); 104 } 105 log.appendFormat("Other:\n"); 106 log.appendFormat(" FboCache %8d / %8d\n", 107 fboCache.getSize(), fboCache.getMaxSize()); 108 log.appendFormat(" PatchCache %8d / %8d\n", 109 patchCache.getSize(), patchCache.getMaxSize()); 110 111 uint32_t total = 0; 112 total += textureCache.getSize(); 113 total += layerCache.getSize(); 114 total += gradientCache.getSize(); 115 total += pathCache.getSize(); 116 total += dropShadowCache.getSize(); 117 total += roundRectShapeCache.getSize(); 118 total += circleShapeCache.getSize(); 119 total += ovalShapeCache.getSize(); 120 total += rectShapeCache.getSize(); 121 total += arcShapeCache.getSize(); 122 for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) { 123 total += fontRenderer.getFontRendererSize(i); 124 } 125 126 log.appendFormat("Total memory usage:\n"); 127 log.appendFormat(" %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f); 128} 129 130/////////////////////////////////////////////////////////////////////////////// 131// Memory management 132/////////////////////////////////////////////////////////////////////////////// 133 134void Caches::clearGarbage() { 135 textureCache.clearGarbage(); 136 gradientCache.clearGarbage(); 137 pathCache.clearGarbage(); 138 139 Mutex::Autolock _l(mGarbageLock); 140 141 size_t count = mLayerGarbage.size(); 142 for (size_t i = 0; i < count; i++) { 143 Layer* layer = mLayerGarbage.itemAt(i); 144 LayerRenderer::destroyLayer(layer); 145 } 146 mLayerGarbage.clear(); 147} 148 149void Caches::deleteLayerDeferred(Layer* layer) { 150 Mutex::Autolock _l(mGarbageLock); 151 mLayerGarbage.push(layer); 152} 153 154/////////////////////////////////////////////////////////////////////////////// 155// VBO 156/////////////////////////////////////////////////////////////////////////////// 157 158void Caches::bindMeshBuffer() { 159 bindMeshBuffer(meshBuffer); 160} 161 162void Caches::bindMeshBuffer(const GLuint buffer) { 163 if (mCurrentBuffer != buffer) { 164 glBindBuffer(GL_ARRAY_BUFFER, buffer); 165 mCurrentBuffer = buffer; 166 } 167} 168 169void Caches::unbindMeshBuffer() { 170 if (mCurrentBuffer) { 171 glBindBuffer(GL_ARRAY_BUFFER, 0); 172 mCurrentBuffer = 0; 173 } 174} 175 176TextureVertex* Caches::getRegionMesh() { 177 // Create the mesh, 2 triangles and 4 vertices per rectangle in the region 178 if (!mRegionMesh) { 179 mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4]; 180 181 uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6]; 182 for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) { 183 uint16_t quad = i * 4; 184 int index = i * 6; 185 regionIndices[index ] = quad; // top-left 186 regionIndices[index + 1] = quad + 1; // top-right 187 regionIndices[index + 2] = quad + 2; // bottom-left 188 regionIndices[index + 3] = quad + 2; // bottom-left 189 regionIndices[index + 4] = quad + 1; // top-right 190 regionIndices[index + 5] = quad + 3; // bottom-right 191 } 192 193 glGenBuffers(1, &mRegionMeshIndices); 194 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices); 195 glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t), 196 regionIndices, GL_STATIC_DRAW); 197 198 delete[] regionIndices; 199 } else { 200 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices); 201 } 202 203 return mRegionMesh; 204} 205 206}; // namespace uirenderer 207}; // namespace android 208