Caches.cpp revision 63d41abb40b3ce40d8b9bccb1cf186e8158a3687
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>
209c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase#include <utils/String8.h>
21c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
22dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#include "Caches.h"
23bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy#include "DisplayListRenderer.h"
24e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy#include "Properties.h"
2509b7c91de73b59aa3f679b3ae3ba299f82ec9f8aRomain Guy#include "LayerRenderer.h"
2663d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui#include "ShadowTessellator.h"
27dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
28dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasenamespace android {
29dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
30dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#ifdef USE_OPENGL_RENDERER
31dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haaseusing namespace uirenderer;
32dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet HaaseANDROID_SINGLETON_STATIC_INSTANCE(Caches);
33dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#endif
34dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
35dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasenamespace uirenderer {
36dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
37dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase///////////////////////////////////////////////////////////////////////////////
38bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy// Macros
39bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy///////////////////////////////////////////////////////////////////////////////
40bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
41bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy#if DEBUG_CACHE_FLUSH
425baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    #define FLUSH_LOGD(...) ALOGD(__VA_ARGS__)
43bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy#else
44bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    #define FLUSH_LOGD(...)
45bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy#endif
46bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
47bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy///////////////////////////////////////////////////////////////////////////////
48dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase// Constructors/destructor
49dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase///////////////////////////////////////////////////////////////////////////////
50dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
518aa195d7081b889f3a7b1f426cbd8556377aae5eRomain GuyCaches::Caches(): Singleton<Caches>(),
528aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        mExtensions(Extensions::getInstance()), mInitialized(false) {
538ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    init();
54b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    initFont();
55dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    initConstraints();
564ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy    initProperties();
57f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy    initStaticProperties();
580f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    initExtensions();
59ba9b613437c34873fa95800a25fc51720638267cChris Craik    initTempProperties();
60e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy
61e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy    mDebugLevel = readDebugLevel();
625baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Enabling debug mode %d", mDebugLevel);
63dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
64dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guybool Caches::init() {
663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    if (mInitialized) return false;
678ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
688ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glGenBuffers(1, &meshBuffer);
698ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
708ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
718ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
728ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mCurrentBuffer = meshBuffer;
7315bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    mCurrentIndicesBuffer = 0;
74f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentPositionPointer = this;
75cb4d6009576cf08195dc23f341a3f4939c0878bbChris Craik    mCurrentPositionStride = 0;
76f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentTexCoordsPointer = this;
77cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    mCurrentPixelBuffer = 0;
78f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
7915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    mTexCoordsArrayEnabled = false;
8015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
81b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    glDisable(GL_SCISSOR_TEST);
82586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    scissorEnabled = false;
838f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
848f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
85a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    glActiveTexture(gTextureUnits[0]);
86a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    mTextureUnit = 0;
87a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy
888ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mRegionMesh = NULL;
893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    mMeshIndices = 0;
9063d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui    mShadowStripsIndices = 0;
918ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    blend = false;
928ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    lastSrcMode = GL_ZERO;
938ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    lastDstMode = GL_ZERO;
948ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    currentProgram = NULL;
958ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
9654c1a64d5441a964890b44280e4457e11f4f924aRomain Guy    mFunctorsCount = 0;
9754c1a64d5441a964890b44280e4457e11f4f924aRomain Guy
98c2a972131f1870042eb63847d4b24fbe718d8e3fRomain Guy    debugLayersUpdates = false;
99c2a972131f1870042eb63847d4b24fbe718d8e3fRomain Guy    debugOverdraw = false;
1003ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy    debugStencilClip = kStencilHide;
101c2a972131f1870042eb63847d4b24fbe718d8e3fRomain Guy
1023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    patchCache.init(*this);
1033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1048ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mInitialized = true;
1053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1068aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    resetBoundTextures();
1078aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy
1083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    return true;
1098ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy}
1108ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
111b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guyvoid Caches::initFont() {
112b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    fontRenderer = GammaFontRenderer::createRenderer();
113b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy}
114b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy
115dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guyvoid Caches::initExtensions() {
1163bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    if (mExtensions.hasDebugMarker()) {
117dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        eventMark = glInsertEventMarkerEXT;
1180f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy
119ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik        startMark = glPushGroupMarkerEXT;
120ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik        endMark = glPopGroupMarkerEXT;
121dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    } else {
122dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        eventMark = eventMarkNull;
123dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        startMark = startMarkNull;
124dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        endMark = endMarkNull;
125dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    }
126dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy
1270f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    if (mExtensions.hasDebugLabel() && (drawDeferDisabled || drawReorderDisabled)) {
128dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        setLabel = glLabelObjectEXT;
129dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        getLabel = glGetObjectLabelEXT;
130dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    } else {
131dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        setLabel = setLabelNull;
132dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        getLabel = getLabelNull;
133dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    }
134dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy}
135dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy
136dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guyvoid Caches::initConstraints() {
137dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    GLint maxTextureUnits;
138dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
139dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
140dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy        ALOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
141dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    }
142dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy
143dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
144dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy}
145dfa1046ecab165eb0daf5caa8475e993350f4a2bRomain Guy
146f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guyvoid Caches::initStaticProperties() {
147f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy    gpuPixelBuffersEnabled = false;
148f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy
149f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy    // OpenGL ES 3.0+ specific features
1507f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy    if (mExtensions.hasPixelBufferObjects()) {
151f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy        char property[PROPERTY_VALUE_MAX];
152f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy        if (property_get(PROPERTY_ENABLE_GPU_PIXEL_BUFFERS, property, "true") > 0) {
153f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy            gpuPixelBuffersEnabled = !strcmp(property, "true");
154f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy        }
155f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy    }
156f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy}
157f9f0016b1ff816eb2c7561eed482c056189005f8Romain Guy
1585bb3c730f5ebd2a0db1b02a8981c6fdbea6c1a2eRomain Guybool Caches::initProperties() {
1595bb3c730f5ebd2a0db1b02a8981c6fdbea6c1a2eRomain Guy    bool prevDebugLayersUpdates = debugLayersUpdates;
1605bb3c730f5ebd2a0db1b02a8981c6fdbea6c1a2eRomain Guy    bool prevDebugOverdraw = debugOverdraw;
1613ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy    StencilClipDebug prevDebugStencilClip = debugStencilClip;
1625bb3c730f5ebd2a0db1b02a8981c6fdbea6c1a2eRomain Guy
1634ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy    char property[PROPERTY_VALUE_MAX];
1644ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy    if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, NULL) > 0) {
1654ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy        INIT_LOGD("  Layers updates debug enabled: %s", property);
1664ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy        debugLayersUpdates = !strcmp(property, "true");
1674ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy    } else {
1684ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy        debugLayersUpdates = false;
1694ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy    }
1707c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy
171627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy    debugOverdraw = false;
1727c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) {
1737c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        INIT_LOGD("  Overdraw debug enabled: %s", property);
174627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy        if (!strcmp(property, "show")) {
175627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy            debugOverdraw = true;
176627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy            mOverdrawDebugColorSet = kColorSet_Default;
177627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy        } else if (!strcmp(property, "show_deuteranomaly")) {
178627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy            debugOverdraw = true;
179627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy            mOverdrawDebugColorSet = kColorSet_Deuteranomaly;
180627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy        }
1817c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    }
1825bb3c730f5ebd2a0db1b02a8981c6fdbea6c1a2eRomain Guy
1833ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy    // See Properties.h for valid values
1843ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy    if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, NULL) > 0) {
1853ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy        INIT_LOGD("  Stencil clip debug enabled: %s", property);
1863ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy        if (!strcmp(property, "hide")) {
1873ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy            debugStencilClip = kStencilHide;
1883ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy        } else if (!strcmp(property, "highlight")) {
1893ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy            debugStencilClip = kStencilShowHighlight;
1903ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy        } else if (!strcmp(property, "region")) {
1913ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy            debugStencilClip = kStencilShowRegion;
1923ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy        }
1933ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy    } else {
1943ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy        debugStencilClip = kStencilHide;
1953ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy    }
1963ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy
1970f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) {
1980f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy        drawDeferDisabled = !strcasecmp(property, "true");
1990f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy        INIT_LOGD("  Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
2000f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    } else {
2010f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy        INIT_LOGD("  Draw defer enabled");
2020f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    }
2030f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy
2040f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) {
2050f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy        drawReorderDisabled = !strcasecmp(property, "true");
2060f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy        INIT_LOGD("  Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
2070f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    } else {
2080f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy        INIT_LOGD("  Draw reorder enabled");
2090f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    }
2100f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy
2115bb3c730f5ebd2a0db1b02a8981c6fdbea6c1a2eRomain Guy    return (prevDebugLayersUpdates != debugLayersUpdates) ||
2123ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy            (prevDebugOverdraw != debugOverdraw) ||
2133ff0bfdd144bba3b023eda8c49b25fb0d0de8653Romain Guy            (prevDebugStencilClip != debugStencilClip);
2144ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy}
2154ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy
2168ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guyvoid Caches::terminate() {
2178ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    if (!mInitialized) return;
2188ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
2198ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glDeleteBuffers(1, &meshBuffer);
2208ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mCurrentBuffer = 0;
2218ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
2223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    glDeleteBuffers(1, &mMeshIndices);
2235b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    delete[] mRegionMesh;
2243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    mMeshIndices = 0;
2258ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mRegionMesh = NULL;
2268ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
22763d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui    glDeleteBuffers(1, &mShadowStripsIndices);
22863d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui    mShadowStripsIndices = 0;
22963d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui
2308ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    fboCache.clear();
2318ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
2328ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    programCache.clear();
2338ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    currentProgram = NULL;
2348ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
2353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    assetAtlas.terminate();
2363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
2373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    patchCache.clear();
2383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
23946bfc4811094e5b1e3196246e457d4c6b58332ecRomain Guy    clearGarbage();
24046bfc4811094e5b1e3196246e457d4c6b58332ecRomain Guy
2418ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mInitialized = false;
2425b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
2435b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
2445b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
245c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy// Debug
246c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
247c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
248627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guyuint32_t Caches::getOverdrawColor(uint32_t amount) const {
249627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy    static uint32_t sOverdrawColors[2][4] = {
250627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy            { 0x2f0000ff, 0x2f00ff00, 0x3fff0000, 0x7fff0000 },
251627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy            { 0x2f0000ff, 0x4fffff00, 0x5fff8ad8, 0x7fff0000 }
252627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy    };
253627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy    if (amount < 1) amount = 1;
254627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy    if (amount > 4) amount = 4;
255627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy    return sOverdrawColors[mOverdrawDebugColorSet][amount - 1];
256627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy}
257627c6fd91377ead85f74a365438e25610ef1e2eeRomain Guy
258c15008e72ec00ca20a271c3006dac649fd07533bRomain Guyvoid Caches::dumpMemoryUsage() {
2599c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    String8 stringLog;
2609c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    dumpMemoryUsage(stringLog);
2615baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("%s", stringLog.string());
2629c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase}
2639c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
2649c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haasevoid Caches::dumpMemoryUsage(String8 &log) {
2659c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("Current memory usage / total memory usage (bytes):\n");
2669c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  TextureCache         %8d / %8d\n",
2679c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            textureCache.getSize(), textureCache.getMaxSize());
2689c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  LayerCache           %8d / %8d\n",
2699c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            layerCache.getSize(), layerCache.getMaxSize());
2708d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    log.appendFormat("  RenderBufferCache    %8d / %8d\n",
2718d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            renderBufferCache.getSize(), renderBufferCache.getMaxSize());
2729c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  GradientCache        %8d / %8d\n",
2739c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            gradientCache.getSize(), gradientCache.getMaxSize());
2749c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  PathCache            %8d / %8d\n",
2759c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            pathCache.getSize(), pathCache.getMaxSize());
2769c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  TextDropShadowCache  %8d / %8d\n", dropShadowCache.getSize(),
277c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy            dropShadowCache.getMaxSize());
2783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    log.appendFormat("  PatchCache           %8d / %8d\n",
2793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            patchCache.getSize(), patchCache.getMaxSize());
280b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
2811e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease        const uint32_t sizeA8 = fontRenderer->getFontRendererSize(i, GL_ALPHA);
2821e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease        const uint32_t sizeRGBA = fontRenderer->getFontRendererSize(i, GL_RGBA);
2831e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease        log.appendFormat("  FontRenderer %d A8    %8d / %8d\n", i, sizeA8, sizeA8);
2841e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease        log.appendFormat("  FontRenderer %d RGBA  %8d / %8d\n", i, sizeRGBA, sizeRGBA);
2851e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease        log.appendFormat("  FontRenderer %d total %8d / %8d\n", i, sizeA8 + sizeRGBA,
2861e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease                sizeA8 + sizeRGBA);
287c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
288d2ba50ab861ec0950bda18dd0f463b687e66249fRomain Guy    log.appendFormat("Other:\n");
2899c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  FboCache             %8d / %8d\n",
2909c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            fboCache.getSize(), fboCache.getMaxSize());
291c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
292c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    uint32_t total = 0;
293c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += textureCache.getSize();
294c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += layerCache.getSize();
2958d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy    total += renderBufferCache.getSize();
296c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += gradientCache.getSize();
297c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += pathCache.getSize();
298c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += dropShadowCache.getSize();
2993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    total += patchCache.getSize();
300b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy    for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
3011e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease        total += fontRenderer->getFontRendererSize(i, GL_ALPHA);
3021e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease        total += fontRenderer->getFontRendererSize(i, GL_RGBA);
303c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
304c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
3059c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("Total memory usage:\n");
3069c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f);
307c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy}
308c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
309c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
310fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy// Memory management
311fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
312fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
313fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guyvoid Caches::clearGarbage() {
314fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    textureCache.clearGarbage();
315fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    pathCache.clearGarbage();
316e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    patchCache.clearGarbage();
31757066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
31817ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian    Vector<DisplayList*> displayLists;
31917ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian    Vector<Layer*> layers;
32017ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian
32117ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian    { // scope for the lock
32217ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        Mutex::Autolock _l(mGarbageLock);
32317ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        displayLists = mDisplayListGarbage;
32417ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        layers = mLayerGarbage;
32517ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        mDisplayListGarbage.clear();
32617ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        mLayerGarbage.clear();
32717ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian    }
32857066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
32917ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian    size_t count = displayLists.size();
33057066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    for (size_t i = 0; i < count; i++) {
33117ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        DisplayList* displayList = displayLists.itemAt(i);
33217ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        delete displayList;
33357066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    }
334bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy
33517ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian    count = layers.size();
336bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy    for (size_t i = 0; i < count; i++) {
33717ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        Layer* layer = layers.itemAt(i);
33817ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian        delete layer;
339bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy    }
34017ef62cc1f9d092669af0fed465a9a77e0dc1a4fMathias Agopian    layers.clear();
34157066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy}
34257066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
343ada830f639591b99c3e40de22b07296c7932a33fRomain Guyvoid Caches::deleteLayerDeferred(Layer* layer) {
34457066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    Mutex::Autolock _l(mGarbageLock);
345ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    mLayerGarbage.push(layer);
346fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy}
347fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
348bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guyvoid Caches::deleteDisplayListDeferred(DisplayList* displayList) {
349bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy    Mutex::Autolock _l(mGarbageLock);
350bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy    mDisplayListGarbage.push(displayList);
351bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy}
352bb0acdf9e1d862a7cf0e2533321fc1105c29b5e3Romain Guy
353bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guyvoid Caches::flush(FlushMode mode) {
354bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    FLUSH_LOGD("Flushing caches (mode %d)", mode);
355bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
356b0a41ed3dcc34a2b4026f6cc8336796f3523aa21Romain Guy    // We must stop tasks before clearing caches
357b0a41ed3dcc34a2b4026f6cc8336796f3523aa21Romain Guy    if (mode > kFlushMode_Layers) {
358b0a41ed3dcc34a2b4026f6cc8336796f3523aa21Romain Guy        tasks.stop();
359b0a41ed3dcc34a2b4026f6cc8336796f3523aa21Romain Guy    }
360b0a41ed3dcc34a2b4026f6cc8336796f3523aa21Romain Guy
361bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    switch (mode) {
362bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy        case kFlushMode_Full:
363bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            textureCache.clear();
364bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            patchCache.clear();
365bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            dropShadowCache.clear();
366bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            gradientCache.clear();
367b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy            fontRenderer->clear();
368b746371de7f21ae36a14953d9b253df06838efb1Romain Guy            fboCache.clear();
369211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy            dither.clear();
370bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            // fall through
371bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy        case kFlushMode_Moderate:
372b1d0a4ed21168fefcb82232c8f22cb95d60acb85Romain Guy            fontRenderer->flush();
373eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            textureCache.flush();
374bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            pathCache.clear();
3756d7475d666baefaa3ba9f0dcee25238739454241Romain Guy            // fall through
3766d7475d666baefaa3ba9f0dcee25238739454241Romain Guy        case kFlushMode_Layers:
3776d7475d666baefaa3ba9f0dcee25238739454241Romain Guy            layerCache.clear();
3788d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffdRomain Guy            renderBufferCache.clear();
379bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            break;
380bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    }
3816a2d17f71342f981c9df1dc5beff33e30eb3ae2bChet Haase
3826a2d17f71342f981c9df1dc5beff33e30eb3ae2bChet Haase    clearGarbage();
383bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy}
384bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
385fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
3865b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy// VBO
3875b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
3885b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
389f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guybool Caches::bindMeshBuffer() {
390f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    return bindMeshBuffer(meshBuffer);
391dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
392dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
393f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guybool Caches::bindMeshBuffer(const GLuint buffer) {
3949bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer != buffer) {
395dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, buffer);
3969bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = buffer;
397f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        return true;
398dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
399f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    return false;
400dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
401dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
402f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guybool Caches::unbindMeshBuffer() {
4039bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer) {
404dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, 0);
4059bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = 0;
406f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        return true;
407f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    }
408f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    return false;
409f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
410f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
41163d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghuibool Caches::bindIndicesBufferInternal(const GLuint buffer) {
41215bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (mCurrentIndicesBuffer != buffer) {
41315bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
41415bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mCurrentIndicesBuffer = buffer;
41515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        return true;
41615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
41715bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    return false;
41815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
41915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
42063d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghuibool Caches::bindQuadIndicesBuffer() {
4213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    if (!mMeshIndices) {
42231e08e953fe7bdb1b1cbc247156cb6a19917a2f1Romain Guy        uint16_t* regionIndices = new uint16_t[gMaxNumberOfQuads * 6];
42331e08e953fe7bdb1b1cbc247156cb6a19917a2f1Romain Guy        for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) {
4243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            uint16_t quad = i * 4;
4253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            int index = i * 6;
4263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            regionIndices[index    ] = quad;       // top-left
4273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            regionIndices[index + 1] = quad + 1;   // top-right
4283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            regionIndices[index + 2] = quad + 2;   // bottom-left
4293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            regionIndices[index + 3] = quad + 2;   // bottom-left
4303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            regionIndices[index + 4] = quad + 1;   // top-right
4313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            regionIndices[index + 5] = quad + 3;   // bottom-right
4323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
4333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
4343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        glGenBuffers(1, &mMeshIndices);
43563d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        bool force = bindIndicesBufferInternal(mMeshIndices);
43631e08e953fe7bdb1b1cbc247156cb6a19917a2f1Romain Guy        glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t),
4373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy                regionIndices, GL_STATIC_DRAW);
4383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
4393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        delete[] regionIndices;
4403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return force;
4413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
4423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
44363d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui    return bindIndicesBufferInternal(mMeshIndices);
44463d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui}
44563d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui
44663d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghuibool Caches::bindShadowIndicesBuffer() {
44763d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui    if (!mShadowStripsIndices) {
44863d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        uint16_t* shadowIndices = new uint16_t[SHADOW_INDEX_COUNT];
44963d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        ShadowTessellator::generateShadowIndices(shadowIndices);
45063d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        glGenBuffers(1, &mShadowStripsIndices);
45163d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        bool force = bindIndicesBufferInternal(mShadowStripsIndices);
45263d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        glBufferData(GL_ELEMENT_ARRAY_BUFFER, SHADOW_INDEX_COUNT * sizeof(uint16_t),
45363d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui            shadowIndices, GL_STATIC_DRAW);
45463d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui
45563d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        delete[] shadowIndices;
45663d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui        return force;
45763d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui    }
45863d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui
45963d41abb40b3ce40d8b9bccb1cf186e8158a3687ztenghui    return bindIndicesBufferInternal(mShadowStripsIndices);
4603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}
4613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
46215bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guybool Caches::unbindIndicesBuffer() {
46315bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (mCurrentIndicesBuffer) {
46415bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
46515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mCurrentIndicesBuffer = 0;
46615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        return true;
46715bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
46815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    return false;
46915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
47015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
47185ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
472cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy// PBO
473cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
474cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
475cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guybool Caches::bindPixelBuffer(const GLuint buffer) {
476cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    if (mCurrentPixelBuffer != buffer) {
477cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
478cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mCurrentPixelBuffer = buffer;
479cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        return true;
480cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
481cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    return false;
482cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
483cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
484cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guybool Caches::unbindPixelBuffer() {
485cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    if (mCurrentPixelBuffer) {
486cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
487cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        mCurrentPixelBuffer = 0;
488cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        return true;
489cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    }
490cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy    return false;
491cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy}
492cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
493cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy///////////////////////////////////////////////////////////////////////////////
49485ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy// Meshes and textures
49585ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
49685ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy
49755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghuivoid Caches::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
498cb4d6009576cf08195dc23f341a3f4939c0878bbChris Craik    if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) {
499cb4d6009576cf08195dc23f341a3f4939c0878bbChris Craik        GLuint slot = currentProgram->position;
500f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
501f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        mCurrentPositionPointer = vertices;
502cb4d6009576cf08195dc23f341a3f4939c0878bbChris Craik        mCurrentPositionStride = stride;
503dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
504dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
505dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
50655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghuivoid Caches::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
507ff316ec7a76e52572a2e89b691e6b3bba0cafba3Romain Guy    if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) {
508cb4d6009576cf08195dc23f341a3f4939c0878bbChris Craik        GLuint slot = currentProgram->texCoords;
509ff316ec7a76e52572a2e89b691e6b3bba0cafba3Romain Guy        glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
510f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        mCurrentTexCoordsPointer = vertices;
511ff316ec7a76e52572a2e89b691e6b3bba0cafba3Romain Guy        mCurrentTexCoordsStride = stride;
512f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    }
513f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
514f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
515f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guyvoid Caches::resetVertexPointers() {
516f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentPositionPointer = this;
517f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentTexCoordsPointer = this;
518f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
519f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
520f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guyvoid Caches::resetTexCoordsVertexPointer() {
521f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentTexCoordsPointer = this;
522f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
523f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
52415bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guyvoid Caches::enableTexCoordsVertexArray() {
52515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (!mTexCoordsArrayEnabled) {
52615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glEnableVertexAttribArray(Program::kBindingTexCoords);
527ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy        mCurrentTexCoordsPointer = this;
52815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mTexCoordsArrayEnabled = true;
52915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
53015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
53115bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
532ff316ec7a76e52572a2e89b691e6b3bba0cafba3Romain Guyvoid Caches::disableTexCoordsVertexArray() {
53315bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (mTexCoordsArrayEnabled) {
53415bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glDisableVertexAttribArray(Program::kBindingTexCoords);
53515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mTexCoordsArrayEnabled = false;
53615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
53715bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
53815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
539a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guyvoid Caches::activeTexture(GLuint textureUnit) {
540a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    if (mTextureUnit != textureUnit) {
541a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        glActiveTexture(gTextureUnits[textureUnit]);
542a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        mTextureUnit = textureUnit;
543a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    }
544a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy}
545a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy
5469ab2d1847552aa4169b4325aae1b1368d6947a9fChris Craikvoid Caches::resetActiveTexture() {
5479ab2d1847552aa4169b4325aae1b1368d6947a9fChris Craik    mTextureUnit = -1;
5489ab2d1847552aa4169b4325aae1b1368d6947a9fChris Craik}
5499ab2d1847552aa4169b4325aae1b1368d6947a9fChris Craik
5508aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyvoid Caches::bindTexture(GLuint texture) {
5518aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    if (mBoundTextures[mTextureUnit] != texture) {
5528aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        glBindTexture(GL_TEXTURE_2D, texture);
5538aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        mBoundTextures[mTextureUnit] = texture;
5548aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    }
5558aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy}
5568aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy
5578aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyvoid Caches::bindTexture(GLenum target, GLuint texture) {
5588aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    if (mBoundTextures[mTextureUnit] != texture) {
5598aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        glBindTexture(target, texture);
5608aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        mBoundTextures[mTextureUnit] = texture;
5618aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    }
5628aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy}
5638aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy
564be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guyvoid Caches::deleteTexture(GLuint texture) {
565be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // When glDeleteTextures() is called on a currently bound texture,
566be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // OpenGL ES specifies that the texture is then considered unbound
567be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // Consider the following series of calls:
568be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    //
569be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // glGenTextures -> creates texture name 2
570be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // glBindTexture(2)
571be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // glDeleteTextures(2) -> 2 is now unbound
572be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // glGenTextures -> can return 2 again
573be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    //
574be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // If we don't call glBindTexture(2) after the second glGenTextures
575be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // call, any texture operation will be performed on the default
576be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    // texture (name=0)
577be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy
578be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    for (int i = 0; i < REQUIRED_TEXTURE_UNITS_COUNT; i++) {
579be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy        if (mBoundTextures[i] == texture) {
580be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy            mBoundTextures[i] = 0;
581be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy        }
582be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    }
583be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    glDeleteTextures(1, &texture);
584be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy}
585be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy
5868aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyvoid Caches::resetBoundTextures() {
5878aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    memset(mBoundTextures, 0, REQUIRED_TEXTURE_UNITS_COUNT * sizeof(GLuint));
5888aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy}
5898aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy
59085ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
59185ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy// Scissor
59285ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
59385ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy
5948a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guybool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
595586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    if (scissorEnabled && (x != mScissorX || y != mScissorY ||
596586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy            width != mScissorWidth || height != mScissorHeight)) {
597586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy
598aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        if (x < 0) {
599aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase            width += x;
600aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase            x = 0;
601aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        }
602aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        if (y < 0) {
603aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase            height += y;
604aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase            y = 0;
605aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        }
606aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        if (width < 0) {
607aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase            width = 0;
608aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        }
609aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        if (height < 0) {
610aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase            height = 0;
611aa42c9af6ea2158a685ebf9b338e6d2355712268Chet Haase        }
6128f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        glScissor(x, y, width, height);
6138f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
6148f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorX = x;
6158f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorY = y;
6168f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorWidth = width;
6178f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorHeight = height;
6188a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guy
6198a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guy        return true;
6208f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    }
6218a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guy    return false;
6228f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy}
6238f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
6248a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guybool Caches::enableScissor() {
625586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    if (!scissorEnabled) {
626586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy        glEnable(GL_SCISSOR_TEST);
627586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy        scissorEnabled = true;
62850ae66a554126fadee2054e0d01a9e57150cedb5Romain Guy        resetScissor();
6298a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guy        return true;
630586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    }
6318a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guy    return false;
632586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy}
633586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy
6348a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guybool Caches::disableScissor() {
635586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    if (scissorEnabled) {
636586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy        glDisable(GL_SCISSOR_TEST);
637586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy        scissorEnabled = false;
6388a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guy        return true;
639586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    }
6408a4ac610e1aaf04931ac1af54b146a7fc8e66114Romain Guy    return false;
641586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy}
642586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy
643586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guyvoid Caches::setScissorEnabled(bool enabled) {
644586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    if (scissorEnabled != enabled) {
645586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy        if (enabled) glEnable(GL_SCISSOR_TEST);
646586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy        else glDisable(GL_SCISSOR_TEST);
647586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy        scissorEnabled = enabled;
648586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy    }
649586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy}
650586cae3ac69c0c667fbf8a954edbd399f620a717Romain Guy
65182bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guyvoid Caches::resetScissor() {
65282bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guy    mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
65382bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guy}
65482bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guy
65585ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
65685ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy// Tiling
65785ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
65885ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy
659f735c8e5cb59d6e1d1aa152fed7a6480a08d1c2aRomain Guyvoid Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard) {
6603bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    if (mExtensions.hasTiledRendering() && !debugOverdraw) {
661f735c8e5cb59d6e1d1aa152fed7a6480a08d1c2aRomain Guy        glStartTilingQCOM(x, y, width, height, (discard ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM));
66285ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy    }
66385ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy}
66485ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy
66585ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guyvoid Caches::endTiling() {
6663bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    if (mExtensions.hasTiledRendering() && !debugOverdraw) {
6672b7028eabac80cec170572bc0e945a1d4224e595Romain Guy        glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
66885ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy    }
66985ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy}
67085ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy
67154c1a64d5441a964890b44280e4457e11f4f924aRomain Guybool Caches::hasRegisteredFunctors() {
67254c1a64d5441a964890b44280e4457e11f4f924aRomain Guy    return mFunctorsCount > 0;
67354c1a64d5441a964890b44280e4457e11f4f924aRomain Guy}
67454c1a64d5441a964890b44280e4457e11f4f924aRomain Guy
67554c1a64d5441a964890b44280e4457e11f4f924aRomain Guyvoid Caches::registerFunctors(uint32_t functorCount) {
67654c1a64d5441a964890b44280e4457e11f4f924aRomain Guy    mFunctorsCount += functorCount;
67754c1a64d5441a964890b44280e4457e11f4f924aRomain Guy}
67854c1a64d5441a964890b44280e4457e11f4f924aRomain Guy
67954c1a64d5441a964890b44280e4457e11f4f924aRomain Guyvoid Caches::unregisterFunctors(uint32_t functorCount) {
68054c1a64d5441a964890b44280e4457e11f4f924aRomain Guy    if (functorCount > mFunctorsCount) {
68154c1a64d5441a964890b44280e4457e11f4f924aRomain Guy        mFunctorsCount = 0;
68254c1a64d5441a964890b44280e4457e11f4f924aRomain Guy    } else {
68354c1a64d5441a964890b44280e4457e11f4f924aRomain Guy        mFunctorsCount -= functorCount;
68454c1a64d5441a964890b44280e4457e11f4f924aRomain Guy    }
68554c1a64d5441a964890b44280e4457e11f4f924aRomain Guy}
68654c1a64d5441a964890b44280e4457e11f4f924aRomain Guy
68785ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
68885ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy// Regions
68985ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy///////////////////////////////////////////////////////////////////////////////
69085ef80d8902afe8d26cb75fa7837fd9e6d019620Romain Guy
6915b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain GuyTextureVertex* Caches::getRegionMesh() {
6925b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
6935b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    if (!mRegionMesh) {
69431e08e953fe7bdb1b1cbc247156cb6a19917a2f1Romain Guy        mRegionMesh = new TextureVertex[gMaxNumberOfQuads * 4];
6955b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
6965b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
6975b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    return mRegionMesh;
6985b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
6995b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
700ba9b613437c34873fa95800a25fc51720638267cChris Craik///////////////////////////////////////////////////////////////////////////////
701ba9b613437c34873fa95800a25fc51720638267cChris Craik// Temporary Properties
702ba9b613437c34873fa95800a25fc51720638267cChris Craik///////////////////////////////////////////////////////////////////////////////
703ba9b613437c34873fa95800a25fc51720638267cChris Craik
704ba9b613437c34873fa95800a25fc51720638267cChris Craikvoid Caches::initTempProperties() {
705ba9b613437c34873fa95800a25fc51720638267cChris Craik    propertyDirtyViewport = false;
706ba9b613437c34873fa95800a25fc51720638267cChris Craik    propertyEnable3d = false;
707ba9b613437c34873fa95800a25fc51720638267cChris Craik    propertyCameraDistance = 1.0f;
708ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui    propertyAmbientShadowStrength = 0x3f;
709ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui    propertySpotShadowStrength = 0x3f;
710cc3c25622c731d14a6f01bce684330eccba7db5aztenghui
711cc3c25622c731d14a6f01bce684330eccba7db5aztenghui    propertyLightPosXScale = 0.5f;
712cc3c25622c731d14a6f01bce684330eccba7db5aztenghui    propertyLightPosYScale = 0.0f;
713cc3c25622c731d14a6f01bce684330eccba7db5aztenghui    propertyLightPosZScale = 1.0f;
714ba9b613437c34873fa95800a25fc51720638267cChris Craik}
715ba9b613437c34873fa95800a25fc51720638267cChris Craik
716ba9b613437c34873fa95800a25fc51720638267cChris Craikvoid Caches::setTempProperty(const char* name, const char* value) {
717ba9b613437c34873fa95800a25fc51720638267cChris Craik    ALOGD("setting property %s to %s", name, value);
718ba9b613437c34873fa95800a25fc51720638267cChris Craik    if (!strcmp(name, "enable3d")) {
719ba9b613437c34873fa95800a25fc51720638267cChris Craik        propertyEnable3d = !strcmp(value, "true");
720ba9b613437c34873fa95800a25fc51720638267cChris Craik        propertyDirtyViewport = true;
721ba9b613437c34873fa95800a25fc51720638267cChris Craik        ALOGD("enable3d = %d", propertyEnable3d);
722ba9b613437c34873fa95800a25fc51720638267cChris Craik        return;
723ba9b613437c34873fa95800a25fc51720638267cChris Craik    } else if (!strcmp(name, "cameraDistance")) {
724ba9b613437c34873fa95800a25fc51720638267cChris Craik        propertyCameraDistance = fmin(fmax(atof(value), 0.001), 10);
725ba9b613437c34873fa95800a25fc51720638267cChris Craik        propertyDirtyViewport = true;
726ba9b613437c34873fa95800a25fc51720638267cChris Craik        ALOGD("camera dist multiplier = %.2f", propertyCameraDistance);
727ba9b613437c34873fa95800a25fc51720638267cChris Craik        return;
728ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui    } else if (!strcmp(name, "ambientShadowStrength")) {
729ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui        propertyAmbientShadowStrength = atoi(value);
730ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui        ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength);
731ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui        return;
732ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui    } else if (!strcmp(name, "spotShadowStrength")) {
733ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui        propertySpotShadowStrength = atoi(value);
734ef94c6f88fbb1deb095b1494378befcdb9722839ztenghui        ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength);
735ba9b613437c34873fa95800a25fc51720638267cChris Craik        return;
736cc3c25622c731d14a6f01bce684330eccba7db5aztenghui    } else if (!strcmp(name, "lightPosXScale")) {
737cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        propertyLightPosXScale = fmin(fmax(atof(value), 0.0), 1.0);
738cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        propertyDirtyViewport = true;
739cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        ALOGD("lightPos X Scale = %.2f", propertyLightPosXScale);
740cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        return;
741cc3c25622c731d14a6f01bce684330eccba7db5aztenghui    }  else if (!strcmp(name, "lightPosYScale")) {
742cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        propertyLightPosYScale = fmin(fmax(atof(value), 0.0), 1.0);
743cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        propertyDirtyViewport = true;
744cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        ALOGD("lightPos Y Scale = %.2f", propertyLightPosXScale);
745cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        return;
746cc3c25622c731d14a6f01bce684330eccba7db5aztenghui    }  else if (!strcmp(name, "lightPosZScale")) {
747cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        propertyLightPosZScale = fmin(fmax(atof(value), 0.0), 1.0);
748cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        propertyDirtyViewport = true;
749cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        ALOGD("lightPos Z Scale = %.2f", propertyLightPosXScale);
750cc3c25622c731d14a6f01bce684330eccba7db5aztenghui        return;
751ba9b613437c34873fa95800a25fc51720638267cChris Craik    }
752ba9b613437c34873fa95800a25fc51720638267cChris Craik    ALOGD("    failed");
753ba9b613437c34873fa95800a25fc51720638267cChris Craik}
754ba9b613437c34873fa95800a25fc51720638267cChris Craik
755dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace uirenderer
756dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace android
757