blob: 442c4fbb60f40056787a70e5684842db6ec6ad56 [file] [log] [blame]
Chet Haasedd78cca2010-10-22 18:59:26 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "OpenGLRenderer"
18
Romain Guyc15008e2010-11-10 11:59:15 -080019#include <utils/Log.h>
Chet Haase9c1e23b2011-03-24 10:51:31 -070020#include <utils/String8.h>
Romain Guyc15008e2010-11-10 11:59:15 -080021
Chet Haasedd78cca2010-10-22 18:59:26 -070022#include "Caches.h"
Romain Guybb0acdf2012-03-05 13:44:35 -080023#include "DisplayListRenderer.h"
Romain Guye190aa62010-11-10 19:01:29 -080024#include "Properties.h"
Romain Guy09b7c912011-02-02 20:28:09 -080025#include "LayerRenderer.h"
Chet Haasedd78cca2010-10-22 18:59:26 -070026
27namespace android {
28
29#ifdef USE_OPENGL_RENDERER
30using namespace uirenderer;
31ANDROID_SINGLETON_STATIC_INSTANCE(Caches);
32#endif
33
34namespace uirenderer {
35
36///////////////////////////////////////////////////////////////////////////////
Romain Guybdf76092011-07-18 15:00:43 -070037// Macros
38///////////////////////////////////////////////////////////////////////////////
39
40#if DEBUG_CACHE_FLUSH
Steve Block5baa3a62011-12-20 16:23:08 +000041 #define FLUSH_LOGD(...) ALOGD(__VA_ARGS__)
Romain Guybdf76092011-07-18 15:00:43 -070042#else
43 #define FLUSH_LOGD(...)
44#endif
45
46///////////////////////////////////////////////////////////////////////////////
Chet Haasedd78cca2010-10-22 18:59:26 -070047// Constructors/destructor
48///////////////////////////////////////////////////////////////////////////////
49
Romain Guy8ff6b9e2011-11-09 20:10:18 -080050Caches::Caches(): Singleton<Caches>(), mInitialized(false) {
Romain Guy8ff6b9e2011-11-09 20:10:18 -080051 init();
Romain Guyb1d0a4e2012-07-13 18:25:35 -070052 initFont();
Romain Guydfa10462012-05-12 16:18:58 -070053 initExtensions();
54 initConstraints();
Romain Guy4ff0cf42012-08-06 14:51:10 -070055 initProperties();
Romain Guye190aa62010-11-10 19:01:29 -080056
57 mDebugLevel = readDebugLevel();
Steve Block5baa3a62011-12-20 16:23:08 +000058 ALOGD("Enabling debug mode %d", mDebugLevel);
Chet Haasedd78cca2010-10-22 18:59:26 -070059}
60
Romain Guy8ff6b9e2011-11-09 20:10:18 -080061void Caches::init() {
62 if (mInitialized) return;
63
64 glGenBuffers(1, &meshBuffer);
65 glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
66 glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
67
68 mCurrentBuffer = meshBuffer;
Romain Guy15bc6432011-12-13 13:11:32 -080069 mCurrentIndicesBuffer = 0;
Romain Guyf3a910b42011-12-12 20:35:21 -080070 mCurrentPositionPointer = this;
71 mCurrentTexCoordsPointer = this;
72
Romain Guy15bc6432011-12-13 13:11:32 -080073 mTexCoordsArrayEnabled = false;
74
Romain Guyb1d0a4e2012-07-13 18:25:35 -070075 glDisable(GL_SCISSOR_TEST);
Romain Guy586cae32012-07-13 15:28:31 -070076 scissorEnabled = false;
Romain Guy8f85e802011-12-14 19:23:32 -080077 mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
78
Romain Guya1d3c912011-12-13 14:55:06 -080079 glActiveTexture(gTextureUnits[0]);
80 mTextureUnit = 0;
81
Romain Guy8ff6b9e2011-11-09 20:10:18 -080082 mRegionMesh = NULL;
83
84 blend = false;
85 lastSrcMode = GL_ZERO;
86 lastDstMode = GL_ZERO;
87 currentProgram = NULL;
88
Romain Guy54c1a642012-09-27 17:55:46 -070089 mFunctorsCount = 0;
90
Romain Guy8ff6b9e2011-11-09 20:10:18 -080091 mInitialized = true;
92}
93
Romain Guyb1d0a4e2012-07-13 18:25:35 -070094void Caches::initFont() {
95 fontRenderer = GammaFontRenderer::createRenderer();
96}
97
Romain Guydfa10462012-05-12 16:18:58 -070098void Caches::initExtensions() {
99 if (extensions.hasDebugMarker()) {
100 eventMark = glInsertEventMarkerEXT;
101 startMark = glPushGroupMarkerEXT;
102 endMark = glPopGroupMarkerEXT;
103 } else {
104 eventMark = eventMarkNull;
105 startMark = startMarkNull;
106 endMark = endMarkNull;
107 }
108
109 if (extensions.hasDebugLabel()) {
110 setLabel = glLabelObjectEXT;
111 getLabel = glGetObjectLabelEXT;
112 } else {
113 setLabel = setLabelNull;
114 getLabel = getLabelNull;
115 }
116}
117
118void Caches::initConstraints() {
119 GLint maxTextureUnits;
120 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
121 if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) {
122 ALOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT);
123 }
124
125 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
126}
127
Romain Guy4ff0cf42012-08-06 14:51:10 -0700128void Caches::initProperties() {
129 char property[PROPERTY_VALUE_MAX];
130 if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, NULL) > 0) {
131 INIT_LOGD(" Layers updates debug enabled: %s", property);
132 debugLayersUpdates = !strcmp(property, "true");
133 } else {
134 debugLayersUpdates = false;
135 }
Romain Guy7c450aa2012-09-21 19:15:00 -0700136
137 if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) {
138 INIT_LOGD(" Overdraw debug enabled: %s", property);
139 debugOverdraw = !strcmp(property, "true");
140 } else {
141 debugOverdraw = false;
142 }
Romain Guy4ff0cf42012-08-06 14:51:10 -0700143}
144
Romain Guy8ff6b9e2011-11-09 20:10:18 -0800145void Caches::terminate() {
146 if (!mInitialized) return;
147
148 glDeleteBuffers(1, &meshBuffer);
149 mCurrentBuffer = 0;
150
151 glDeleteBuffers(1, &mRegionMeshIndices);
Romain Guy5b3b3522010-10-27 18:57:51 -0700152 delete[] mRegionMesh;
Romain Guy8ff6b9e2011-11-09 20:10:18 -0800153 mRegionMesh = NULL;
154
155 fboCache.clear();
156
157 programCache.clear();
158 currentProgram = NULL;
159
160 mInitialized = false;
Romain Guy5b3b3522010-10-27 18:57:51 -0700161}
162
163///////////////////////////////////////////////////////////////////////////////
Romain Guyc15008e2010-11-10 11:59:15 -0800164// Debug
165///////////////////////////////////////////////////////////////////////////////
166
167void Caches::dumpMemoryUsage() {
Chet Haase9c1e23b2011-03-24 10:51:31 -0700168 String8 stringLog;
169 dumpMemoryUsage(stringLog);
Steve Block5baa3a62011-12-20 16:23:08 +0000170 ALOGD("%s", stringLog.string());
Chet Haase9c1e23b2011-03-24 10:51:31 -0700171}
172
173void Caches::dumpMemoryUsage(String8 &log) {
174 log.appendFormat("Current memory usage / total memory usage (bytes):\n");
175 log.appendFormat(" TextureCache %8d / %8d\n",
176 textureCache.getSize(), textureCache.getMaxSize());
177 log.appendFormat(" LayerCache %8d / %8d\n",
178 layerCache.getSize(), layerCache.getMaxSize());
179 log.appendFormat(" GradientCache %8d / %8d\n",
180 gradientCache.getSize(), gradientCache.getMaxSize());
181 log.appendFormat(" PathCache %8d / %8d\n",
182 pathCache.getSize(), pathCache.getMaxSize());
183 log.appendFormat(" CircleShapeCache %8d / %8d\n",
Romain Guy01d58e42011-01-19 21:54:02 -0800184 circleShapeCache.getSize(), circleShapeCache.getMaxSize());
Chet Haase9c1e23b2011-03-24 10:51:31 -0700185 log.appendFormat(" OvalShapeCache %8d / %8d\n",
Romain Guy2fc941e2011-02-03 15:06:05 -0800186 ovalShapeCache.getSize(), ovalShapeCache.getMaxSize());
Chet Haase9c1e23b2011-03-24 10:51:31 -0700187 log.appendFormat(" RoundRectShapeCache %8d / %8d\n",
Romain Guy01d58e42011-01-19 21:54:02 -0800188 roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
Chet Haase9c1e23b2011-03-24 10:51:31 -0700189 log.appendFormat(" RectShapeCache %8d / %8d\n",
Romain Guy2fc941e2011-02-03 15:06:05 -0800190 rectShapeCache.getSize(), rectShapeCache.getMaxSize());
Chet Haase9c1e23b2011-03-24 10:51:31 -0700191 log.appendFormat(" ArcShapeCache %8d / %8d\n",
Romain Guy2fc941e2011-02-03 15:06:05 -0800192 arcShapeCache.getSize(), arcShapeCache.getMaxSize());
Chet Haase9c1e23b2011-03-24 10:51:31 -0700193 log.appendFormat(" TextDropShadowCache %8d / %8d\n", dropShadowCache.getSize(),
Romain Guyc15008e2010-11-10 11:59:15 -0800194 dropShadowCache.getMaxSize());
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700195 for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
196 const uint32_t size = fontRenderer->getFontRendererSize(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -0700197 log.appendFormat(" FontRenderer %d %8d / %8d\n", i, size, size);
Romain Guyc15008e2010-11-10 11:59:15 -0800198 }
Romain Guyd2ba50a2011-05-27 10:21:07 -0700199 log.appendFormat("Other:\n");
Chet Haase9c1e23b2011-03-24 10:51:31 -0700200 log.appendFormat(" FboCache %8d / %8d\n",
201 fboCache.getSize(), fboCache.getMaxSize());
202 log.appendFormat(" PatchCache %8d / %8d\n",
203 patchCache.getSize(), patchCache.getMaxSize());
Romain Guyc15008e2010-11-10 11:59:15 -0800204
205 uint32_t total = 0;
206 total += textureCache.getSize();
207 total += layerCache.getSize();
208 total += gradientCache.getSize();
209 total += pathCache.getSize();
210 total += dropShadowCache.getSize();
Romain Guy2fc941e2011-02-03 15:06:05 -0800211 total += roundRectShapeCache.getSize();
212 total += circleShapeCache.getSize();
213 total += ovalShapeCache.getSize();
214 total += rectShapeCache.getSize();
215 total += arcShapeCache.getSize();
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700216 for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
217 total += fontRenderer->getFontRendererSize(i);
Romain Guyc15008e2010-11-10 11:59:15 -0800218 }
219
Chet Haase9c1e23b2011-03-24 10:51:31 -0700220 log.appendFormat("Total memory usage:\n");
221 log.appendFormat(" %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f);
Romain Guyc15008e2010-11-10 11:59:15 -0800222}
223
224///////////////////////////////////////////////////////////////////////////////
Romain Guyfe48f652010-11-11 15:36:56 -0800225// Memory management
226///////////////////////////////////////////////////////////////////////////////
227
228void Caches::clearGarbage() {
229 textureCache.clearGarbage();
Romain Guyfe48f652010-11-11 15:36:56 -0800230 pathCache.clearGarbage();
Romain Guy57066eb2011-01-12 12:53:32 -0800231
Mathias Agopian17ef62c2012-09-25 22:52:40 -0700232 Vector<DisplayList*> displayLists;
233 Vector<Layer*> layers;
Romain Guy57066eb2011-01-12 12:53:32 -0800234
Mathias Agopian17ef62c2012-09-25 22:52:40 -0700235 { // scope for the lock
236 Mutex::Autolock _l(mGarbageLock);
237 displayLists = mDisplayListGarbage;
238 layers = mLayerGarbage;
239 mDisplayListGarbage.clear();
240 mLayerGarbage.clear();
Romain Guy57066eb2011-01-12 12:53:32 -0800241 }
Romain Guybb0acdf2012-03-05 13:44:35 -0800242
Mathias Agopian17ef62c2012-09-25 22:52:40 -0700243 size_t count = displayLists.size();
Romain Guybb0acdf2012-03-05 13:44:35 -0800244 for (size_t i = 0; i < count; i++) {
Mathias Agopian17ef62c2012-09-25 22:52:40 -0700245 DisplayList* displayList = displayLists.itemAt(i);
Romain Guybb0acdf2012-03-05 13:44:35 -0800246 delete displayList;
247 }
Mathias Agopian17ef62c2012-09-25 22:52:40 -0700248
249 count = layers.size();
250 for (size_t i = 0; i < count; i++) {
251 Layer* layer = layers.itemAt(i);
252 delete layer;
253 }
254 layers.clear();
Romain Guy57066eb2011-01-12 12:53:32 -0800255}
256
Romain Guyada830f2011-01-13 12:13:20 -0800257void Caches::deleteLayerDeferred(Layer* layer) {
Romain Guy57066eb2011-01-12 12:53:32 -0800258 Mutex::Autolock _l(mGarbageLock);
Romain Guyada830f2011-01-13 12:13:20 -0800259 mLayerGarbage.push(layer);
Romain Guyfe48f652010-11-11 15:36:56 -0800260}
261
Romain Guybb0acdf2012-03-05 13:44:35 -0800262void Caches::deleteDisplayListDeferred(DisplayList* displayList) {
263 Mutex::Autolock _l(mGarbageLock);
264 mDisplayListGarbage.push(displayList);
265}
266
Romain Guybdf76092011-07-18 15:00:43 -0700267void Caches::flush(FlushMode mode) {
268 FLUSH_LOGD("Flushing caches (mode %d)", mode);
269
270 clearGarbage();
271
272 switch (mode) {
273 case kFlushMode_Full:
274 textureCache.clear();
275 patchCache.clear();
276 dropShadowCache.clear();
277 gradientCache.clear();
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700278 fontRenderer->clear();
Romain Guy211efea2012-07-31 21:16:07 -0700279 dither.clear();
Romain Guybdf76092011-07-18 15:00:43 -0700280 // fall through
281 case kFlushMode_Moderate:
Romain Guyb1d0a4e2012-07-13 18:25:35 -0700282 fontRenderer->flush();
Romain Guyeca0ca22011-11-04 15:12:29 -0700283 textureCache.flush();
Romain Guybdf76092011-07-18 15:00:43 -0700284 pathCache.clear();
285 roundRectShapeCache.clear();
286 circleShapeCache.clear();
287 ovalShapeCache.clear();
288 rectShapeCache.clear();
289 arcShapeCache.clear();
Romain Guy6d7475d2011-07-27 16:28:21 -0700290 // fall through
291 case kFlushMode_Layers:
292 layerCache.clear();
Romain Guybdf76092011-07-18 15:00:43 -0700293 break;
294 }
295}
296
Romain Guyfe48f652010-11-11 15:36:56 -0800297///////////////////////////////////////////////////////////////////////////////
Romain Guy5b3b3522010-10-27 18:57:51 -0700298// VBO
299///////////////////////////////////////////////////////////////////////////////
300
Romain Guyf3a910b42011-12-12 20:35:21 -0800301bool Caches::bindMeshBuffer() {
302 return bindMeshBuffer(meshBuffer);
Chet Haasedd78cca2010-10-22 18:59:26 -0700303}
304
Romain Guyf3a910b42011-12-12 20:35:21 -0800305bool Caches::bindMeshBuffer(const GLuint buffer) {
Romain Guy9bca4792010-10-25 18:42:25 -0700306 if (mCurrentBuffer != buffer) {
Chet Haasedd78cca2010-10-22 18:59:26 -0700307 glBindBuffer(GL_ARRAY_BUFFER, buffer);
Romain Guy9bca4792010-10-25 18:42:25 -0700308 mCurrentBuffer = buffer;
Romain Guyf3a910b42011-12-12 20:35:21 -0800309 return true;
Chet Haasedd78cca2010-10-22 18:59:26 -0700310 }
Romain Guyf3a910b42011-12-12 20:35:21 -0800311 return false;
Chet Haasedd78cca2010-10-22 18:59:26 -0700312}
313
Romain Guyf3a910b42011-12-12 20:35:21 -0800314bool Caches::unbindMeshBuffer() {
Romain Guy9bca4792010-10-25 18:42:25 -0700315 if (mCurrentBuffer) {
Chet Haasedd78cca2010-10-22 18:59:26 -0700316 glBindBuffer(GL_ARRAY_BUFFER, 0);
Romain Guy9bca4792010-10-25 18:42:25 -0700317 mCurrentBuffer = 0;
Romain Guyf3a910b42011-12-12 20:35:21 -0800318 return true;
Chet Haasedd78cca2010-10-22 18:59:26 -0700319 }
Romain Guyf3a910b42011-12-12 20:35:21 -0800320 return false;
321}
322
Romain Guy15bc6432011-12-13 13:11:32 -0800323bool Caches::bindIndicesBuffer(const GLuint buffer) {
324 if (mCurrentIndicesBuffer != buffer) {
325 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
326 mCurrentIndicesBuffer = buffer;
327 return true;
328 }
329 return false;
330}
331
332bool Caches::unbindIndicesBuffer() {
333 if (mCurrentIndicesBuffer) {
334 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
335 mCurrentIndicesBuffer = 0;
336 return true;
337 }
338 return false;
339}
340
Romain Guy85ef80d2012-09-13 20:26:50 -0700341///////////////////////////////////////////////////////////////////////////////
342// Meshes and textures
343///////////////////////////////////////////////////////////////////////////////
344
Romain Guyf3a910b42011-12-12 20:35:21 -0800345void Caches::bindPositionVertexPointer(bool force, GLuint slot, GLvoid* vertices, GLsizei stride) {
346 if (force || vertices != mCurrentPositionPointer) {
347 glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
348 mCurrentPositionPointer = vertices;
349 }
350}
351
352void Caches::bindTexCoordsVertexPointer(bool force, GLuint slot, GLvoid* vertices) {
353 if (force || vertices != mCurrentTexCoordsPointer) {
354 glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, gMeshStride, vertices);
355 mCurrentTexCoordsPointer = vertices;
356 }
357}
358
359void Caches::resetVertexPointers() {
360 mCurrentPositionPointer = this;
361 mCurrentTexCoordsPointer = this;
362}
363
364void Caches::resetTexCoordsVertexPointer() {
365 mCurrentTexCoordsPointer = this;
Chet Haasedd78cca2010-10-22 18:59:26 -0700366}
367
Romain Guy15bc6432011-12-13 13:11:32 -0800368void Caches::enableTexCoordsVertexArray() {
369 if (!mTexCoordsArrayEnabled) {
370 glEnableVertexAttribArray(Program::kBindingTexCoords);
Romain Guyec31f832011-12-13 18:39:19 -0800371 mCurrentTexCoordsPointer = this;
Romain Guy15bc6432011-12-13 13:11:32 -0800372 mTexCoordsArrayEnabled = true;
373 }
374}
375
376void Caches::disbaleTexCoordsVertexArray() {
377 if (mTexCoordsArrayEnabled) {
378 glDisableVertexAttribArray(Program::kBindingTexCoords);
379 mTexCoordsArrayEnabled = false;
380 }
381}
382
Romain Guya1d3c912011-12-13 14:55:06 -0800383void Caches::activeTexture(GLuint textureUnit) {
384 if (mTextureUnit != textureUnit) {
385 glActiveTexture(gTextureUnits[textureUnit]);
386 mTextureUnit = textureUnit;
387 }
388}
389
Romain Guy85ef80d2012-09-13 20:26:50 -0700390///////////////////////////////////////////////////////////////////////////////
391// Scissor
392///////////////////////////////////////////////////////////////////////////////
393
Romain Guy8a4ac612012-07-17 17:32:48 -0700394bool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
Romain Guy586cae32012-07-13 15:28:31 -0700395 if (scissorEnabled && (x != mScissorX || y != mScissorY ||
396 width != mScissorWidth || height != mScissorHeight)) {
397
Romain Guy35643dd2012-09-18 15:40:58 -0700398 if (x < 0) x = 0;
399 if (y < 0) y = 0;
400
Romain Guy8f85e802011-12-14 19:23:32 -0800401 glScissor(x, y, width, height);
402
403 mScissorX = x;
404 mScissorY = y;
405 mScissorWidth = width;
406 mScissorHeight = height;
Romain Guy8a4ac612012-07-17 17:32:48 -0700407
408 return true;
Romain Guy8f85e802011-12-14 19:23:32 -0800409 }
Romain Guy8a4ac612012-07-17 17:32:48 -0700410 return false;
Romain Guy8f85e802011-12-14 19:23:32 -0800411}
412
Romain Guy8a4ac612012-07-17 17:32:48 -0700413bool Caches::enableScissor() {
Romain Guy586cae32012-07-13 15:28:31 -0700414 if (!scissorEnabled) {
415 glEnable(GL_SCISSOR_TEST);
416 scissorEnabled = true;
Romain Guy8a4ac612012-07-17 17:32:48 -0700417 return true;
Romain Guy586cae32012-07-13 15:28:31 -0700418 }
Romain Guy8a4ac612012-07-17 17:32:48 -0700419 return false;
Romain Guy586cae32012-07-13 15:28:31 -0700420}
421
Romain Guy8a4ac612012-07-17 17:32:48 -0700422bool Caches::disableScissor() {
Romain Guy586cae32012-07-13 15:28:31 -0700423 if (scissorEnabled) {
424 glDisable(GL_SCISSOR_TEST);
425 scissorEnabled = false;
Romain Guy8a4ac612012-07-17 17:32:48 -0700426 return true;
Romain Guy586cae32012-07-13 15:28:31 -0700427 }
Romain Guy8a4ac612012-07-17 17:32:48 -0700428 return false;
Romain Guy586cae32012-07-13 15:28:31 -0700429}
430
431void Caches::setScissorEnabled(bool enabled) {
432 if (scissorEnabled != enabled) {
433 if (enabled) glEnable(GL_SCISSOR_TEST);
434 else glDisable(GL_SCISSOR_TEST);
435 scissorEnabled = enabled;
436 }
437}
438
Romain Guy82bc7a72012-01-03 14:13:39 -0800439void Caches::resetScissor() {
440 mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
441}
442
Romain Guy85ef80d2012-09-13 20:26:50 -0700443///////////////////////////////////////////////////////////////////////////////
444// Tiling
445///////////////////////////////////////////////////////////////////////////////
446
447void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) {
Romain Guy4285de32012-09-23 14:46:35 -0700448 if (extensions.hasTiledRendering() && !debugOverdraw) {
449 glStartTilingQCOM(x, y, width, height, (opaque ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM));
Romain Guy85ef80d2012-09-13 20:26:50 -0700450 }
451}
452
453void Caches::endTiling() {
Romain Guy4285de32012-09-23 14:46:35 -0700454 if (extensions.hasTiledRendering() && !debugOverdraw) {
Romain Guy2b7028e2012-09-19 17:25:38 -0700455 glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
Romain Guy85ef80d2012-09-13 20:26:50 -0700456 }
457}
458
Romain Guy54c1a642012-09-27 17:55:46 -0700459bool Caches::hasRegisteredFunctors() {
460 return mFunctorsCount > 0;
461}
462
463void Caches::registerFunctors(uint32_t functorCount) {
464 mFunctorsCount += functorCount;
465}
466
467void Caches::unregisterFunctors(uint32_t functorCount) {
468 if (functorCount > mFunctorsCount) {
469 mFunctorsCount = 0;
470 } else {
471 mFunctorsCount -= functorCount;
472 }
473}
474
Romain Guy85ef80d2012-09-13 20:26:50 -0700475///////////////////////////////////////////////////////////////////////////////
476// Regions
477///////////////////////////////////////////////////////////////////////////////
478
Romain Guy5b3b3522010-10-27 18:57:51 -0700479TextureVertex* Caches::getRegionMesh() {
480 // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
481 if (!mRegionMesh) {
482 mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
483
484 uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
485 for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
486 uint16_t quad = i * 4;
487 int index = i * 6;
488 regionIndices[index ] = quad; // top-left
489 regionIndices[index + 1] = quad + 1; // top-right
490 regionIndices[index + 2] = quad + 2; // bottom-left
491 regionIndices[index + 3] = quad + 2; // bottom-left
492 regionIndices[index + 4] = quad + 1; // top-right
493 regionIndices[index + 5] = quad + 3; // bottom-right
494 }
495
496 glGenBuffers(1, &mRegionMeshIndices);
Romain Guy15bc6432011-12-13 13:11:32 -0800497 bindIndicesBuffer(mRegionMeshIndices);
Romain Guy5b3b3522010-10-27 18:57:51 -0700498 glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
499 regionIndices, GL_STATIC_DRAW);
500
501 delete[] regionIndices;
502 } else {
Romain Guy15bc6432011-12-13 13:11:32 -0800503 bindIndicesBuffer(mRegionMeshIndices);
Romain Guy5b3b3522010-10-27 18:57:51 -0700504 }
505
506 return mRegionMesh;
507}
508
Chet Haasedd78cca2010-10-22 18:59:26 -0700509}; // namespace uirenderer
510}; // namespace android