Caches.cpp revision 01d58e43ede5ca98cbebdd166f9b0c545032c01b
1dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase/*
2dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * Copyright (C) 2010 The Android Open Source Project
3dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase *
4dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * Licensed under the Apache License, Version 2.0 (the "License");
5dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * you may not use this file except in compliance with the License.
6dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * You may obtain a copy of the License at
7dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase *
8dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase *      http://www.apache.org/licenses/LICENSE-2.0
9dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase *
10dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * Unless required by applicable law or agreed to in writing, software
11dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * distributed under the License is distributed on an "AS IS" BASIS,
12dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * See the License for the specific language governing permissions and
14dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase * limitations under the License.
15dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase */
16dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
17dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#define LOG_TAG "OpenGLRenderer"
18dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
19c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy#include <utils/Log.h>
20c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
21dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#include "Caches.h"
22e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy#include "Properties.h"
23dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
24dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasenamespace android {
25dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
26dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#ifdef USE_OPENGL_RENDERER
27dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haaseusing namespace uirenderer;
28dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet HaaseANDROID_SINGLETON_STATIC_INSTANCE(Caches);
29dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#endif
30dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
31dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasenamespace uirenderer {
32dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
33dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase///////////////////////////////////////////////////////////////////////////////
34dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase// Constructors/destructor
35dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase///////////////////////////////////////////////////////////////////////////////
36dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
37dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet HaaseCaches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO),
38dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        lastDstMode(GL_ZERO), currentProgram(NULL) {
39dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    GLint maxTextureUnits;
40dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
41dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
42dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        LOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
43dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
44dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
45dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    glGenBuffers(1, &meshBuffer);
46dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
47dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
48dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
49746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
50746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy
519bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    mCurrentBuffer = meshBuffer;
525b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    mRegionMesh = NULL;
53e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy
54e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy    mDebugLevel = readDebugLevel();
55e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy    LOGD("Enabling debug mode %d", mDebugLevel);
567230a74e9a36dfc6c4346c14e325bf07cd05b380Romain Guy
577230a74e9a36dfc6c4346c14e325bf07cd05b380Romain Guy#if RENDER_LAYERS_AS_REGIONS
587230a74e9a36dfc6c4346c14e325bf07cd05b380Romain Guy    LOGD("Layers will be composited as regions");
597230a74e9a36dfc6c4346c14e325bf07cd05b380Romain Guy#endif
60dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
61dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain GuyCaches::~Caches() {
635b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    delete[] mRegionMesh;
645b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
655b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
665b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
67c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy// Debug
68c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
69c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
70c15008e72ec00ca20a271c3006dac649fd07533bRomain Guyvoid Caches::dumpMemoryUsage() {
71c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("Current memory usage / total memory usage (bytes):");
72c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  TextureCache         %8d / %8d", textureCache.getSize(), textureCache.getMaxSize());
73c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  LayerCache           %8d / %8d", layerCache.getSize(), layerCache.getMaxSize());
74c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  GradientCache        %8d / %8d", gradientCache.getSize(), gradientCache.getMaxSize());
75c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  PathCache            %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
7601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    LOGD("  CircleShapeCache     %8d / %8d",
7701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy            circleShapeCache.getSize(), circleShapeCache.getMaxSize());
7801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    LOGD("  RoundRectShapeCache  %8d / %8d",
7901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy            roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
80c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  TextDropShadowCache  %8d / %8d", dropShadowCache.getSize(),
81c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy            dropShadowCache.getMaxSize());
82c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
83c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        const uint32_t size = fontRenderer.getFontRendererSize(i);
84c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        LOGD("  FontRenderer %d       %8d / %8d", i, size, size);
85c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
86c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("Other:");
87c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  FboCache             %8d / %8d", fboCache.getSize(), fboCache.getMaxSize());
88c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  PatchCache           %8d / %8d", patchCache.getSize(), patchCache.getMaxSize());
89c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
90c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    uint32_t total = 0;
91c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += textureCache.getSize();
92c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += layerCache.getSize();
93c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += gradientCache.getSize();
94c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += pathCache.getSize();
95c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += dropShadowCache.getSize();
96c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
97c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        total += fontRenderer.getFontRendererSize(i);
98c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
99c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
100c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("Total memory usage:");
101c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  %d bytes, %.2f MB", total, total / 1024.0f / 1024.0f);
102c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("\n");
103c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy}
104c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
105c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
106fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy// Memory management
107fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
108fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
109fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guyvoid Caches::clearGarbage() {
110fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    textureCache.clearGarbage();
111fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    gradientCache.clearGarbage();
112fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    pathCache.clearGarbage();
11357066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
11457066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    Mutex::Autolock _l(mGarbageLock);
11557066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
116ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    size_t count = mLayerGarbage.size();
11757066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    for (size_t i = 0; i < count; i++) {
118ada830f639591b99c3e40de22b07296c7932a33fRomain Guy        Layer* layer = mLayerGarbage.itemAt(i);
119ada830f639591b99c3e40de22b07296c7932a33fRomain Guy        if (layer) {
120ada830f639591b99c3e40de22b07296c7932a33fRomain Guy            if (layer->fbo) glDeleteFramebuffers(1, &layer->fbo);
121ada830f639591b99c3e40de22b07296c7932a33fRomain Guy            if (layer->texture) glDeleteTextures(1, &layer->texture);
12257066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
123ada830f639591b99c3e40de22b07296c7932a33fRomain Guy            delete layer;
124ada830f639591b99c3e40de22b07296c7932a33fRomain Guy        }
12557066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    }
126ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    mLayerGarbage.clear();
12757066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy}
12857066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
129ada830f639591b99c3e40de22b07296c7932a33fRomain Guyvoid Caches::deleteLayerDeferred(Layer* layer) {
13057066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    Mutex::Autolock _l(mGarbageLock);
131ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    mLayerGarbage.push(layer);
132fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy}
133fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
134fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
1355b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy// VBO
1365b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
1375b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
138dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasevoid Caches::bindMeshBuffer() {
139dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    bindMeshBuffer(meshBuffer);
140dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
141dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
142dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasevoid Caches::bindMeshBuffer(const GLuint buffer) {
1439bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer != buffer) {
144dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, buffer);
1459bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = buffer;
146dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
147dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
148dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
149dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasevoid Caches::unbindMeshBuffer() {
1509bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer) {
151dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, 0);
1529bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = 0;
153dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
154dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
155dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
1565b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain GuyTextureVertex* Caches::getRegionMesh() {
1575b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
1585b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    if (!mRegionMesh) {
1595b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
1605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
1625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
1635b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            uint16_t quad = i * 4;
1645b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            int index = i * 6;
1655b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index    ] = quad;       // top-left
1665b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 1] = quad + 1;   // top-right
1675b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 2] = quad + 2;   // bottom-left
1685b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 3] = quad + 2;   // bottom-left
1695b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 4] = quad + 1;   // top-right
1705b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 5] = quad + 3;   // bottom-right
1715b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        }
1725b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1735b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glGenBuffers(1, &mRegionMeshIndices);
1745b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
1755b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
1765b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy                regionIndices, GL_STATIC_DRAW);
1775b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1785b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        delete[] regionIndices;
1795b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    } else {
1805b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
1815b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
1825b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1835b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    return mRegionMesh;
1845b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
1855b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
186dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace uirenderer
187dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace android
188