Caches.cpp revision fe48f65922d4a3cc4aefe058cee5acec51504a20
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);
56dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
57dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
585b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain GuyCaches::~Caches() {
595b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    delete[] mRegionMesh;
605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
625b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
63c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy// Debug
64c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
65c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
66c15008e72ec00ca20a271c3006dac649fd07533bRomain Guyvoid Caches::dumpMemoryUsage() {
67c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("Current memory usage / total memory usage (bytes):");
68c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  TextureCache         %8d / %8d", textureCache.getSize(), textureCache.getMaxSize());
69c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  LayerCache           %8d / %8d", layerCache.getSize(), layerCache.getMaxSize());
70c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  GradientCache        %8d / %8d", gradientCache.getSize(), gradientCache.getMaxSize());
71c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  PathCache            %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
72c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  TextDropShadowCache  %8d / %8d", dropShadowCache.getSize(),
73c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy            dropShadowCache.getMaxSize());
74c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
75c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        const uint32_t size = fontRenderer.getFontRendererSize(i);
76c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        LOGD("  FontRenderer %d       %8d / %8d", i, size, size);
77c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
78c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("Other:");
79c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  FboCache             %8d / %8d", fboCache.getSize(), fboCache.getMaxSize());
80c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  PatchCache           %8d / %8d", patchCache.getSize(), patchCache.getMaxSize());
81c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
82c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    uint32_t total = 0;
83c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += textureCache.getSize();
84c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += layerCache.getSize();
85c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += gradientCache.getSize();
86c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += pathCache.getSize();
87c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += dropShadowCache.getSize();
88c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
89c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        total += fontRenderer.getFontRendererSize(i);
90c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
91c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
92c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("Total memory usage:");
93c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("  %d bytes, %.2f MB", total, total / 1024.0f / 1024.0f);
94c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    LOGD("\n");
95c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy}
96c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
97c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
98fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy// Memory management
99fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
100fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
101fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guyvoid Caches::clearGarbage() {
102fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    textureCache.clearGarbage();
103fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    gradientCache.clearGarbage();
104fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    pathCache.clearGarbage();
105fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy}
106fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
107fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
1085b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy// VBO
1095b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
1105b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
111dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasevoid Caches::bindMeshBuffer() {
112dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    bindMeshBuffer(meshBuffer);
113dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
114dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
115dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasevoid Caches::bindMeshBuffer(const GLuint buffer) {
1169bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer != buffer) {
117dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, buffer);
1189bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = buffer;
119dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
120dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
121dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
122dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasevoid Caches::unbindMeshBuffer() {
1239bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer) {
124dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, 0);
1259bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = 0;
126dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
127dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
128dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
1295b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain GuyTextureVertex* Caches::getRegionMesh() {
1305b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
1315b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    if (!mRegionMesh) {
1325b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
1335b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1345b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
1355b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
1365b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            uint16_t quad = i * 4;
1375b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            int index = i * 6;
1385b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index    ] = quad;       // top-left
1395b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 1] = quad + 1;   // top-right
1405b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 2] = quad + 2;   // bottom-left
1415b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 3] = quad + 2;   // bottom-left
1425b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 4] = quad + 1;   // top-right
1435b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 5] = quad + 3;   // bottom-right
1445b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        }
1455b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1465b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glGenBuffers(1, &mRegionMeshIndices);
1475b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
1485b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
1495b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy                regionIndices, GL_STATIC_DRAW);
1505b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1515b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        delete[] regionIndices;
1525b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    } else {
1535b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
1545b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
1555b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1565b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    return mRegionMesh;
1575b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
1585b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
159dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace uirenderer
160dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace android
161