Caches.cpp revision 82bc7a772747fcf8a6fe7097f70bf2981429ffe9
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"
23e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy#include "Properties.h"
2409b7c91de73b59aa3f679b3ae3ba299f82ec9f8aRomain Guy#include "LayerRenderer.h"
25dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
26dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasenamespace android {
27dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
28dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#ifdef USE_OPENGL_RENDERER
29dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haaseusing namespace uirenderer;
30dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet HaaseANDROID_SINGLETON_STATIC_INSTANCE(Caches);
31dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase#endif
32dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
33dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haasenamespace uirenderer {
34dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
35dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase///////////////////////////////////////////////////////////////////////////////
36bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy// Macros
37bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy///////////////////////////////////////////////////////////////////////////////
38bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
39bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy#if DEBUG_CACHE_FLUSH
40bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    #define FLUSH_LOGD(...) LOGD(__VA_ARGS__)
41bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy#else
42bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    #define FLUSH_LOGD(...)
43bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy#endif
44bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
45bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy///////////////////////////////////////////////////////////////////////////////
46dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase// Constructors/destructor
47dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase///////////////////////////////////////////////////////////////////////////////
48dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
498ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain GuyCaches::Caches(): Singleton<Caches>(), mInitialized(false) {
50dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    GLint maxTextureUnits;
51dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
52dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
53dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        LOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
54dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
55dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
56746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
57746b7401ceb86b5f2805f8c0d3b39ac739152015Romain Guy
588ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    init();
59e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy
60e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy    mDebugLevel = readDebugLevel();
61e190aa69756aecfaffabdd4c6d32cb6b3220d842Romain Guy    LOGD("Enabling debug mode %d", mDebugLevel);
627230a74e9a36dfc6c4346c14e325bf07cd05b380Romain Guy
637230a74e9a36dfc6c4346c14e325bf07cd05b380Romain Guy#if RENDER_LAYERS_AS_REGIONS
6402ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy    INIT_LOGD("Layers will be composited as regions");
657230a74e9a36dfc6c4346c14e325bf07cd05b380Romain Guy#endif
66dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
67dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
688ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guyvoid Caches::init() {
698ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    if (mInitialized) return;
708ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
718ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glGenBuffers(1, &meshBuffer);
728ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
738ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
748ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
758ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mCurrentBuffer = meshBuffer;
7615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    mCurrentIndicesBuffer = 0;
77f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentPositionPointer = this;
78f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentTexCoordsPointer = this;
79f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
8015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    mTexCoordsArrayEnabled = false;
8115bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
828f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
838f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
84a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    glActiveTexture(gTextureUnits[0]);
85a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    mTextureUnit = 0;
86a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy
878ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mRegionMesh = NULL;
888ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
898ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    blend = false;
908ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    lastSrcMode = GL_ZERO;
918ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    lastDstMode = GL_ZERO;
928ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    currentProgram = NULL;
938ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
948ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mInitialized = true;
958ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy}
968ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
978ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guyvoid Caches::terminate() {
988ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    if (!mInitialized) return;
998ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
1008ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glDeleteBuffers(1, &meshBuffer);
1018ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mCurrentBuffer = 0;
1028ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
1038ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    glDeleteBuffers(1, &mRegionMeshIndices);
1045b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    delete[] mRegionMesh;
1058ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mRegionMesh = NULL;
1068ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
1078ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    fboCache.clear();
1088ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
1098ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    programCache.clear();
1108ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    currentProgram = NULL;
1118ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
1128ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mInitialized = false;
1135b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
1145b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
1155b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
116c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy// Debug
117c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
118c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
119c15008e72ec00ca20a271c3006dac649fd07533bRomain Guyvoid Caches::dumpMemoryUsage() {
1209c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    String8 stringLog;
1219c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    dumpMemoryUsage(stringLog);
1229c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    LOGD("%s", stringLog.string());
1239c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase}
1249c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
1259c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haasevoid Caches::dumpMemoryUsage(String8 &log) {
1269c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("Current memory usage / total memory usage (bytes):\n");
1279c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  TextureCache         %8d / %8d\n",
1289c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            textureCache.getSize(), textureCache.getMaxSize());
1299c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  LayerCache           %8d / %8d\n",
1309c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            layerCache.getSize(), layerCache.getMaxSize());
1319c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  GradientCache        %8d / %8d\n",
1329c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            gradientCache.getSize(), gradientCache.getMaxSize());
1339c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  PathCache            %8d / %8d\n",
1349c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            pathCache.getSize(), pathCache.getMaxSize());
1359c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  CircleShapeCache     %8d / %8d\n",
13601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy            circleShapeCache.getSize(), circleShapeCache.getMaxSize());
1379c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  OvalShapeCache       %8d / %8d\n",
1382fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy            ovalShapeCache.getSize(), ovalShapeCache.getMaxSize());
1399c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  RoundRectShapeCache  %8d / %8d\n",
14001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy            roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
1419c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  RectShapeCache       %8d / %8d\n",
1422fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy            rectShapeCache.getSize(), rectShapeCache.getMaxSize());
1439c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  ArcShapeCache        %8d / %8d\n",
1442fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy            arcShapeCache.getSize(), arcShapeCache.getMaxSize());
1459c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  TextDropShadowCache  %8d / %8d\n", dropShadowCache.getSize(),
146c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy            dropShadowCache.getMaxSize());
147c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
148c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        const uint32_t size = fontRenderer.getFontRendererSize(i);
1499c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase        log.appendFormat("  FontRenderer %d       %8d / %8d\n", i, size, size);
150c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
151d2ba50ab861ec0950bda18dd0f463b687e66249fRomain Guy    log.appendFormat("Other:\n");
1529c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  FboCache             %8d / %8d\n",
1539c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            fboCache.getSize(), fboCache.getMaxSize());
1549c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  PatchCache           %8d / %8d\n",
1559c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            patchCache.getSize(), patchCache.getMaxSize());
156c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
157c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    uint32_t total = 0;
158c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += textureCache.getSize();
159c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += layerCache.getSize();
160c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += gradientCache.getSize();
161c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += pathCache.getSize();
162c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    total += dropShadowCache.getSize();
1632fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy    total += roundRectShapeCache.getSize();
1642fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy    total += circleShapeCache.getSize();
1652fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy    total += ovalShapeCache.getSize();
1662fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy    total += rectShapeCache.getSize();
1672fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy    total += arcShapeCache.getSize();
168c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
169c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy        total += fontRenderer.getFontRendererSize(i);
170c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy    }
171c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
1729c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("Total memory usage:\n");
1739c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    log.appendFormat("  %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f);
174c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy}
175c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy
176c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy///////////////////////////////////////////////////////////////////////////////
177fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy// Memory management
178fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
179fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
180fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guyvoid Caches::clearGarbage() {
181fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    textureCache.clearGarbage();
182fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy    pathCache.clearGarbage();
18357066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
18457066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    Mutex::Autolock _l(mGarbageLock);
18557066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
186ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    size_t count = mLayerGarbage.size();
18757066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    for (size_t i = 0; i < count; i++) {
188ada830f639591b99c3e40de22b07296c7932a33fRomain Guy        Layer* layer = mLayerGarbage.itemAt(i);
18909b7c91de73b59aa3f679b3ae3ba299f82ec9f8aRomain Guy        LayerRenderer::destroyLayer(layer);
19057066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    }
191ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    mLayerGarbage.clear();
19257066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy}
19357066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
194ada830f639591b99c3e40de22b07296c7932a33fRomain Guyvoid Caches::deleteLayerDeferred(Layer* layer) {
19557066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    Mutex::Autolock _l(mGarbageLock);
196ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    mLayerGarbage.push(layer);
197fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy}
198fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy
199bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guyvoid Caches::flush(FlushMode mode) {
200bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    FLUSH_LOGD("Flushing caches (mode %d)", mode);
201bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
202bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    clearGarbage();
203bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
204bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    switch (mode) {
205bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy        case kFlushMode_Full:
206bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            textureCache.clear();
207bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            patchCache.clear();
208bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            dropShadowCache.clear();
209bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            gradientCache.clear();
210eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            fontRenderer.clear();
211bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            // fall through
212bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy        case kFlushMode_Moderate:
213eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            fontRenderer.flush();
214eca0ca2424afc1e98912405906edfc32f7733e16Romain Guy            textureCache.flush();
215bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            pathCache.clear();
216bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            roundRectShapeCache.clear();
217bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            circleShapeCache.clear();
218bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            ovalShapeCache.clear();
219bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            rectShapeCache.clear();
220bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            arcShapeCache.clear();
2216d7475d666baefaa3ba9f0dcee25238739454241Romain Guy            // fall through
2226d7475d666baefaa3ba9f0dcee25238739454241Romain Guy        case kFlushMode_Layers:
2236d7475d666baefaa3ba9f0dcee25238739454241Romain Guy            layerCache.clear();
224bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy            break;
225bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    }
226bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy}
227bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy
228fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy///////////////////////////////////////////////////////////////////////////////
2295b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy// VBO
2305b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy///////////////////////////////////////////////////////////////////////////////
2315b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
232f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guybool Caches::bindMeshBuffer() {
233f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    return bindMeshBuffer(meshBuffer);
234dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
235dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
236f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guybool Caches::bindMeshBuffer(const GLuint buffer) {
2379bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer != buffer) {
238dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, buffer);
2399bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = buffer;
240f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        return true;
241dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
242f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    return false;
243dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
244dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
245f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guybool Caches::unbindMeshBuffer() {
2469bca4793a33d2714b306d69ceb870925a588fe71Romain Guy    if (mCurrentBuffer) {
247dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase        glBindBuffer(GL_ARRAY_BUFFER, 0);
2489bca4793a33d2714b306d69ceb870925a588fe71Romain Guy        mCurrentBuffer = 0;
249f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        return true;
250f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    }
251f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    return false;
252f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
253f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
25415bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guybool Caches::bindIndicesBuffer(const GLuint buffer) {
25515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (mCurrentIndicesBuffer != buffer) {
25615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
25715bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mCurrentIndicesBuffer = buffer;
25815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        return true;
25915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
26015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    return false;
26115bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
26215bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
26315bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guybool Caches::unbindIndicesBuffer() {
26415bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (mCurrentIndicesBuffer) {
26515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
26615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mCurrentIndicesBuffer = 0;
26715bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        return true;
26815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
26915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    return false;
27015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
27115bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
272f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guyvoid Caches::bindPositionVertexPointer(bool force, GLuint slot, GLvoid* vertices, GLsizei stride) {
273f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    if (force || vertices != mCurrentPositionPointer) {
274f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
275f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        mCurrentPositionPointer = vertices;
276dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase    }
277dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}
278dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase
279f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guyvoid Caches::bindTexCoordsVertexPointer(bool force, GLuint slot, GLvoid* vertices) {
280f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    if (force || vertices != mCurrentTexCoordsPointer) {
281f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, gMeshStride, vertices);
282f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy        mCurrentTexCoordsPointer = vertices;
283f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    }
284f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
285f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
286f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guyvoid Caches::resetVertexPointers() {
287f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentPositionPointer = this;
288f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentTexCoordsPointer = this;
289f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
290f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
291f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guyvoid Caches::resetTexCoordsVertexPointer() {
292f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy    mCurrentTexCoordsPointer = this;
293f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy}
294f3a910b423db7ad79cf61518bdd9278c048ad0d8Romain Guy
29515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guyvoid Caches::enableTexCoordsVertexArray() {
29615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (!mTexCoordsArrayEnabled) {
29715bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glEnableVertexAttribArray(Program::kBindingTexCoords);
298ec31f83bd3af1f900d1ee9116b15f56904c66dcdRomain Guy        mCurrentTexCoordsPointer = this;
29915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mTexCoordsArrayEnabled = true;
30015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
30115bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
30215bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
30315bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guyvoid Caches::disbaleTexCoordsVertexArray() {
30415bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    if (mTexCoordsArrayEnabled) {
30515bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        glDisableVertexAttribArray(Program::kBindingTexCoords);
30615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        mTexCoordsArrayEnabled = false;
30715bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy    }
30815bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy}
30915bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy
310a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guyvoid Caches::activeTexture(GLuint textureUnit) {
311a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    if (mTextureUnit != textureUnit) {
312a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        glActiveTexture(gTextureUnits[textureUnit]);
313a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy        mTextureUnit = textureUnit;
314a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy    }
315a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy}
316a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy
3178f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guyvoid Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
3188f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    if (x != mScissorX || y != mScissorY || width != mScissorWidth || height != mScissorHeight) {
3198f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        glScissor(x, y, width, height);
3208f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
3218f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorX = x;
3228f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorY = y;
3238f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorWidth = width;
3248f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy        mScissorHeight = height;
3258f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy    }
3268f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy}
3278f85e80b64b89fd38cc23b129f61ec36ddde7f15Romain Guy
32882bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guyvoid Caches::resetScissor() {
32982bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guy    mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
33082bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guy}
33182bc7a772747fcf8a6fe7097f70bf2981429ffe9Romain Guy
3325b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain GuyTextureVertex* Caches::getRegionMesh() {
3335b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
3345b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    if (!mRegionMesh) {
3355b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
3365b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
3375b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
3385b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
3395b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            uint16_t quad = i * 4;
3405b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            int index = i * 6;
3415b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index    ] = quad;       // top-left
3425b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 1] = quad + 1;   // top-right
3435b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 2] = quad + 2;   // bottom-left
3445b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 3] = quad + 2;   // bottom-left
3455b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 4] = quad + 1;   // top-right
3465b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy            regionIndices[index + 5] = quad + 3;   // bottom-right
3475b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        }
3485b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
3495b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glGenBuffers(1, &mRegionMeshIndices);
35015bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        bindIndicesBuffer(mRegionMeshIndices);
3515b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
3525b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy                regionIndices, GL_STATIC_DRAW);
3535b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
3545b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        delete[] regionIndices;
3555b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    } else {
35615bc6437f8b4cf10dba55c7638d349e7b9563f4fRomain Guy        bindIndicesBuffer(mRegionMeshIndices);
3575b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    }
3585b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
3595b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    return mRegionMesh;
3605b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
3615b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
362dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace uirenderer
363dd78ccacff83f0714ad90be98b58ad85f5d08c66Chet Haase}; // namespace android
364