Caches.cpp revision 27eaec23881f9564f98b484765d000822de5fdc3
1/* 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 19#include <utils/Log.h> 20#include <utils/String8.h> 21 22#include "Caches.h" 23#include "DisplayListRenderer.h" 24#include "GammaFontRenderer.h" 25#include "Properties.h" 26#include "LayerRenderer.h" 27#include "ShadowTessellator.h" 28#include "RenderState.h" 29 30namespace android { 31 32#ifdef USE_OPENGL_RENDERER 33using namespace uirenderer; 34ANDROID_SINGLETON_STATIC_INSTANCE(Caches); 35#endif 36 37namespace uirenderer { 38 39/////////////////////////////////////////////////////////////////////////////// 40// Macros 41/////////////////////////////////////////////////////////////////////////////// 42 43#if DEBUG_CACHE_FLUSH 44 #define FLUSH_LOGD(...) ALOGD(__VA_ARGS__) 45#else 46 #define FLUSH_LOGD(...) 47#endif 48 49/////////////////////////////////////////////////////////////////////////////// 50// Constructors/destructor 51/////////////////////////////////////////////////////////////////////////////// 52 53Caches::Caches(): Singleton<Caches>(), 54 mExtensions(Extensions::getInstance()), mInitialized(false), mRenderState(NULL) { 55 init(); 56 initFont(); 57 initConstraints(); 58 initProperties(); 59 initStaticProperties(); 60 initExtensions(); 61 initTempProperties(); 62 63 mDebugLevel = readDebugLevel(); 64 ALOGD("Enabling debug mode %d", mDebugLevel); 65} 66 67bool Caches::init() { 68 if (mInitialized) return false; 69 70 ATRACE_NAME("Caches::init"); 71 72 glGenBuffers(1, &meshBuffer); 73 glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); 74 glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW); 75 76 mCurrentBuffer = meshBuffer; 77 mCurrentIndicesBuffer = 0; 78 mCurrentPositionPointer = this; 79 mCurrentPositionStride = 0; 80 mCurrentTexCoordsPointer = this; 81 mCurrentPixelBuffer = 0; 82 83 mTexCoordsArrayEnabled = false; 84 85 glDisable(GL_SCISSOR_TEST); 86 scissorEnabled = false; 87 mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0; 88 89 glActiveTexture(gTextureUnits[0]); 90 mTextureUnit = 0; 91 92 mRegionMesh = NULL; 93 mMeshIndices = 0; 94 mShadowStripsIndices = 0; 95 blend = false; 96 lastSrcMode = GL_ZERO; 97 lastDstMode = GL_ZERO; 98 currentProgram = NULL; 99 100 mFunctorsCount = 0; 101 102 debugLayersUpdates = false; 103 debugOverdraw = false; 104 debugStencilClip = kStencilHide; 105 106 patchCache.init(*this); 107 108 mInitialized = true; 109 110 resetBoundTextures(); 111 112 return true; 113} 114 115void Caches::initFont() { 116 fontRenderer = GammaFontRenderer::createRenderer(); 117} 118 119void Caches::initExtensions() { 120 if (mExtensions.hasDebugMarker()) { 121 eventMark = glInsertEventMarkerEXT; 122 123 startMark = glPushGroupMarkerEXT; 124 endMark = glPopGroupMarkerEXT; 125 } else { 126 eventMark = eventMarkNull; 127 startMark = startMarkNull; 128 endMark = endMarkNull; 129 } 130 131 if (mExtensions.hasDebugLabel() && (drawDeferDisabled || drawReorderDisabled)) { 132 setLabel = glLabelObjectEXT; 133 getLabel = glGetObjectLabelEXT; 134 } else { 135 setLabel = setLabelNull; 136 getLabel = getLabelNull; 137 } 138} 139 140void Caches::initConstraints() { 141 GLint maxTextureUnits; 142 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); 143 if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) { 144 ALOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT); 145 } 146 147 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 148} 149 150void Caches::initStaticProperties() { 151 gpuPixelBuffersEnabled = false; 152 153 // OpenGL ES 3.0+ specific features 154 if (mExtensions.hasPixelBufferObjects()) { 155 char property[PROPERTY_VALUE_MAX]; 156 if (property_get(PROPERTY_ENABLE_GPU_PIXEL_BUFFERS, property, "true") > 0) { 157 gpuPixelBuffersEnabled = !strcmp(property, "true"); 158 } 159 } 160} 161 162bool Caches::initProperties() { 163 bool prevDebugLayersUpdates = debugLayersUpdates; 164 bool prevDebugOverdraw = debugOverdraw; 165 StencilClipDebug prevDebugStencilClip = debugStencilClip; 166 167 char property[PROPERTY_VALUE_MAX]; 168 if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, NULL) > 0) { 169 INIT_LOGD(" Layers updates debug enabled: %s", property); 170 debugLayersUpdates = !strcmp(property, "true"); 171 } else { 172 debugLayersUpdates = false; 173 } 174 175 debugOverdraw = false; 176 if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) { 177 INIT_LOGD(" Overdraw debug enabled: %s", property); 178 if (!strcmp(property, "show")) { 179 debugOverdraw = true; 180 mOverdrawDebugColorSet = kColorSet_Default; 181 } else if (!strcmp(property, "show_deuteranomaly")) { 182 debugOverdraw = true; 183 mOverdrawDebugColorSet = kColorSet_Deuteranomaly; 184 } 185 } 186 187 // See Properties.h for valid values 188 if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, NULL) > 0) { 189 INIT_LOGD(" Stencil clip debug enabled: %s", property); 190 if (!strcmp(property, "hide")) { 191 debugStencilClip = kStencilHide; 192 } else if (!strcmp(property, "highlight")) { 193 debugStencilClip = kStencilShowHighlight; 194 } else if (!strcmp(property, "region")) { 195 debugStencilClip = kStencilShowRegion; 196 } 197 } else { 198 debugStencilClip = kStencilHide; 199 } 200 201 if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) { 202 drawDeferDisabled = !strcasecmp(property, "true"); 203 INIT_LOGD(" Draw defer %s", drawDeferDisabled ? "disabled" : "enabled"); 204 } else { 205 drawDeferDisabled = false; 206 INIT_LOGD(" Draw defer enabled"); 207 } 208 209 if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) { 210 drawReorderDisabled = !strcasecmp(property, "true"); 211 INIT_LOGD(" Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled"); 212 } else { 213 drawReorderDisabled = false; 214 INIT_LOGD(" Draw reorder enabled"); 215 } 216 217 return (prevDebugLayersUpdates != debugLayersUpdates) || 218 (prevDebugOverdraw != debugOverdraw) || 219 (prevDebugStencilClip != debugStencilClip); 220} 221 222void Caches::terminate() { 223 if (!mInitialized) return; 224 225 glDeleteBuffers(1, &meshBuffer); 226 mCurrentBuffer = 0; 227 228 glDeleteBuffers(1, &mMeshIndices); 229 delete[] mRegionMesh; 230 mMeshIndices = 0; 231 mRegionMesh = NULL; 232 233 glDeleteBuffers(1, &mShadowStripsIndices); 234 mShadowStripsIndices = 0; 235 236 fboCache.clear(); 237 238 programCache.clear(); 239 currentProgram = NULL; 240 241 assetAtlas.terminate(); 242 243 patchCache.clear(); 244 245 clearGarbage(); 246 247 mInitialized = false; 248} 249 250/////////////////////////////////////////////////////////////////////////////// 251// Debug 252/////////////////////////////////////////////////////////////////////////////// 253 254uint32_t Caches::getOverdrawColor(uint32_t amount) const { 255 static uint32_t sOverdrawColors[2][4] = { 256 { 0x2f0000ff, 0x2f00ff00, 0x3fff0000, 0x7fff0000 }, 257 { 0x2f0000ff, 0x4fffff00, 0x5fff8ad8, 0x7fff0000 } 258 }; 259 if (amount < 1) amount = 1; 260 if (amount > 4) amount = 4; 261 return sOverdrawColors[mOverdrawDebugColorSet][amount - 1]; 262} 263 264void Caches::dumpMemoryUsage() { 265 String8 stringLog; 266 dumpMemoryUsage(stringLog); 267 ALOGD("%s", stringLog.string()); 268} 269 270void Caches::dumpMemoryUsage(String8 &log) { 271 uint32_t total = 0; 272 log.appendFormat("Current memory usage / total memory usage (bytes):\n"); 273 log.appendFormat(" TextureCache %8d / %8d\n", 274 textureCache.getSize(), textureCache.getMaxSize()); 275 log.appendFormat(" LayerCache %8d / %8d (numLayers = %zu)\n", 276 layerCache.getSize(), layerCache.getMaxSize(), layerCache.getCount()); 277 if (mRenderState) { 278 int memused = 0; 279 for (std::set<const Layer*>::iterator it = mRenderState->mActiveLayers.begin(); 280 it != mRenderState->mActiveLayers.end(); it++) { 281 const Layer* layer = *it; 282 log.appendFormat(" Layer size %dx%d; isTextureLayer()=%d; texid=%u fbo=%u; refs=%d\n", 283 layer->getWidth(), layer->getHeight(), 284 layer->isTextureLayer(), layer->getTexture(), 285 layer->getFbo(), layer->getStrongCount()); 286 memused += layer->getWidth() * layer->getHeight() * 4; 287 } 288 log.appendFormat(" Layers total %8d (numLayers = %zu)\n", 289 memused, mRenderState->mActiveLayers.size()); 290 total += memused; 291 } 292 log.appendFormat(" RenderBufferCache %8d / %8d\n", 293 renderBufferCache.getSize(), renderBufferCache.getMaxSize()); 294 log.appendFormat(" GradientCache %8d / %8d\n", 295 gradientCache.getSize(), gradientCache.getMaxSize()); 296 log.appendFormat(" PathCache %8d / %8d\n", 297 pathCache.getSize(), pathCache.getMaxSize()); 298 log.appendFormat(" TessellationCache %8d / %8d\n", 299 tessellationCache.getSize(), tessellationCache.getMaxSize()); 300 log.appendFormat(" TextDropShadowCache %8d / %8d\n", dropShadowCache.getSize(), 301 dropShadowCache.getMaxSize()); 302 log.appendFormat(" PatchCache %8d / %8d\n", 303 patchCache.getSize(), patchCache.getMaxSize()); 304 for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) { 305 const uint32_t sizeA8 = fontRenderer->getFontRendererSize(i, GL_ALPHA); 306 const uint32_t sizeRGBA = fontRenderer->getFontRendererSize(i, GL_RGBA); 307 log.appendFormat(" FontRenderer %d A8 %8d / %8d\n", i, sizeA8, sizeA8); 308 log.appendFormat(" FontRenderer %d RGBA %8d / %8d\n", i, sizeRGBA, sizeRGBA); 309 log.appendFormat(" FontRenderer %d total %8d / %8d\n", i, sizeA8 + sizeRGBA, 310 sizeA8 + sizeRGBA); 311 } 312 log.appendFormat("Other:\n"); 313 log.appendFormat(" FboCache %8d / %8d\n", 314 fboCache.getSize(), fboCache.getMaxSize()); 315 316 total += textureCache.getSize(); 317 total += renderBufferCache.getSize(); 318 total += gradientCache.getSize(); 319 total += pathCache.getSize(); 320 total += tessellationCache.getSize(); 321 total += dropShadowCache.getSize(); 322 total += patchCache.getSize(); 323 for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) { 324 total += fontRenderer->getFontRendererSize(i, GL_ALPHA); 325 total += fontRenderer->getFontRendererSize(i, GL_RGBA); 326 } 327 328 log.appendFormat("Total memory usage:\n"); 329 log.appendFormat(" %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f); 330} 331 332/////////////////////////////////////////////////////////////////////////////// 333// Memory management 334/////////////////////////////////////////////////////////////////////////////// 335 336void Caches::clearGarbage() { 337 textureCache.clearGarbage(); 338 pathCache.clearGarbage(); 339 patchCache.clearGarbage(); 340} 341 342void Caches::flush(FlushMode mode) { 343 FLUSH_LOGD("Flushing caches (mode %d)", mode); 344 345 // We must stop tasks before clearing caches 346 if (mode > kFlushMode_Layers) { 347 tasks.stop(); 348 } 349 350 switch (mode) { 351 case kFlushMode_Full: 352 textureCache.clear(); 353 patchCache.clear(); 354 dropShadowCache.clear(); 355 gradientCache.clear(); 356 fontRenderer->clear(); 357 fboCache.clear(); 358 dither.clear(); 359 // fall through 360 case kFlushMode_Moderate: 361 fontRenderer->flush(); 362 textureCache.flush(); 363 pathCache.clear(); 364 tessellationCache.clear(); 365 // fall through 366 case kFlushMode_Layers: 367 layerCache.clear(); 368 renderBufferCache.clear(); 369 break; 370 } 371 372 clearGarbage(); 373 glFinish(); 374} 375 376/////////////////////////////////////////////////////////////////////////////// 377// VBO 378/////////////////////////////////////////////////////////////////////////////// 379 380bool Caches::bindMeshBuffer() { 381 return bindMeshBuffer(meshBuffer); 382} 383 384bool Caches::bindMeshBuffer(const GLuint buffer) { 385 if (mCurrentBuffer != buffer) { 386 glBindBuffer(GL_ARRAY_BUFFER, buffer); 387 mCurrentBuffer = buffer; 388 return true; 389 } 390 return false; 391} 392 393bool Caches::unbindMeshBuffer() { 394 if (mCurrentBuffer) { 395 glBindBuffer(GL_ARRAY_BUFFER, 0); 396 mCurrentBuffer = 0; 397 return true; 398 } 399 return false; 400} 401 402bool Caches::bindIndicesBufferInternal(const GLuint buffer) { 403 if (mCurrentIndicesBuffer != buffer) { 404 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); 405 mCurrentIndicesBuffer = buffer; 406 return true; 407 } 408 return false; 409} 410 411bool Caches::bindQuadIndicesBuffer() { 412 if (!mMeshIndices) { 413 uint16_t* regionIndices = new uint16_t[gMaxNumberOfQuads * 6]; 414 for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) { 415 uint16_t quad = i * 4; 416 int index = i * 6; 417 regionIndices[index ] = quad; // top-left 418 regionIndices[index + 1] = quad + 1; // top-right 419 regionIndices[index + 2] = quad + 2; // bottom-left 420 regionIndices[index + 3] = quad + 2; // bottom-left 421 regionIndices[index + 4] = quad + 1; // top-right 422 regionIndices[index + 5] = quad + 3; // bottom-right 423 } 424 425 glGenBuffers(1, &mMeshIndices); 426 bool force = bindIndicesBufferInternal(mMeshIndices); 427 glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t), 428 regionIndices, GL_STATIC_DRAW); 429 430 delete[] regionIndices; 431 return force; 432 } 433 434 return bindIndicesBufferInternal(mMeshIndices); 435} 436 437bool Caches::bindShadowIndicesBuffer() { 438 if (!mShadowStripsIndices) { 439 uint16_t* shadowIndices = new uint16_t[MAX_SHADOW_INDEX_COUNT]; 440 ShadowTessellator::generateShadowIndices(shadowIndices); 441 glGenBuffers(1, &mShadowStripsIndices); 442 bool force = bindIndicesBufferInternal(mShadowStripsIndices); 443 glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t), 444 shadowIndices, GL_STATIC_DRAW); 445 446 delete[] shadowIndices; 447 return force; 448 } 449 450 return bindIndicesBufferInternal(mShadowStripsIndices); 451} 452 453bool Caches::unbindIndicesBuffer() { 454 if (mCurrentIndicesBuffer) { 455 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 456 mCurrentIndicesBuffer = 0; 457 return true; 458 } 459 return false; 460} 461 462/////////////////////////////////////////////////////////////////////////////// 463// PBO 464/////////////////////////////////////////////////////////////////////////////// 465 466bool Caches::bindPixelBuffer(const GLuint buffer) { 467 if (mCurrentPixelBuffer != buffer) { 468 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); 469 mCurrentPixelBuffer = buffer; 470 return true; 471 } 472 return false; 473} 474 475bool Caches::unbindPixelBuffer() { 476 if (mCurrentPixelBuffer) { 477 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 478 mCurrentPixelBuffer = 0; 479 return true; 480 } 481 return false; 482} 483 484/////////////////////////////////////////////////////////////////////////////// 485// Meshes and textures 486/////////////////////////////////////////////////////////////////////////////// 487 488void Caches::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { 489 if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) { 490 GLuint slot = currentProgram->position; 491 glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); 492 mCurrentPositionPointer = vertices; 493 mCurrentPositionStride = stride; 494 } 495} 496 497void Caches::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { 498 if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) { 499 GLuint slot = currentProgram->texCoords; 500 glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); 501 mCurrentTexCoordsPointer = vertices; 502 mCurrentTexCoordsStride = stride; 503 } 504} 505 506void Caches::resetVertexPointers() { 507 mCurrentPositionPointer = this; 508 mCurrentTexCoordsPointer = this; 509} 510 511void Caches::resetTexCoordsVertexPointer() { 512 mCurrentTexCoordsPointer = this; 513} 514 515void Caches::enableTexCoordsVertexArray() { 516 if (!mTexCoordsArrayEnabled) { 517 glEnableVertexAttribArray(Program::kBindingTexCoords); 518 mCurrentTexCoordsPointer = this; 519 mTexCoordsArrayEnabled = true; 520 } 521} 522 523void Caches::disableTexCoordsVertexArray() { 524 if (mTexCoordsArrayEnabled) { 525 glDisableVertexAttribArray(Program::kBindingTexCoords); 526 mTexCoordsArrayEnabled = false; 527 } 528} 529 530void Caches::activeTexture(GLuint textureUnit) { 531 if (mTextureUnit != textureUnit) { 532 glActiveTexture(gTextureUnits[textureUnit]); 533 mTextureUnit = textureUnit; 534 } 535} 536 537void Caches::resetActiveTexture() { 538 mTextureUnit = -1; 539} 540 541void Caches::bindTexture(GLuint texture) { 542 if (mBoundTextures[mTextureUnit] != texture) { 543 glBindTexture(GL_TEXTURE_2D, texture); 544 mBoundTextures[mTextureUnit] = texture; 545 } 546} 547 548void Caches::bindTexture(GLenum target, GLuint texture) { 549 if (target == GL_TEXTURE_2D) { 550 bindTexture(texture); 551 } else { 552 // GLConsumer directly calls glBindTexture() with 553 // target=GL_TEXTURE_EXTERNAL_OES, don't cache this target 554 // since the cached state could be stale 555 glBindTexture(target, texture); 556 } 557} 558 559void Caches::deleteTexture(GLuint texture) { 560 // When glDeleteTextures() is called on a currently bound texture, 561 // OpenGL ES specifies that the texture is then considered unbound 562 // Consider the following series of calls: 563 // 564 // glGenTextures -> creates texture name 2 565 // glBindTexture(2) 566 // glDeleteTextures(2) -> 2 is now unbound 567 // glGenTextures -> can return 2 again 568 // 569 // If we don't call glBindTexture(2) after the second glGenTextures 570 // call, any texture operation will be performed on the default 571 // texture (name=0) 572 573 unbindTexture(texture); 574 575 glDeleteTextures(1, &texture); 576} 577 578void Caches::resetBoundTextures() { 579 memset(mBoundTextures, 0, REQUIRED_TEXTURE_UNITS_COUNT * sizeof(GLuint)); 580} 581 582void Caches::unbindTexture(GLuint texture) { 583 for (int i = 0; i < REQUIRED_TEXTURE_UNITS_COUNT; i++) { 584 if (mBoundTextures[i] == texture) { 585 mBoundTextures[i] = 0; 586 } 587 } 588} 589 590/////////////////////////////////////////////////////////////////////////////// 591// Scissor 592/////////////////////////////////////////////////////////////////////////////// 593 594bool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) { 595 if (scissorEnabled && (x != mScissorX || y != mScissorY || 596 width != mScissorWidth || height != mScissorHeight)) { 597 598 if (x < 0) { 599 width += x; 600 x = 0; 601 } 602 if (y < 0) { 603 height += y; 604 y = 0; 605 } 606 if (width < 0) { 607 width = 0; 608 } 609 if (height < 0) { 610 height = 0; 611 } 612 glScissor(x, y, width, height); 613 614 mScissorX = x; 615 mScissorY = y; 616 mScissorWidth = width; 617 mScissorHeight = height; 618 619 return true; 620 } 621 return false; 622} 623 624bool Caches::enableScissor() { 625 if (!scissorEnabled) { 626 glEnable(GL_SCISSOR_TEST); 627 scissorEnabled = true; 628 resetScissor(); 629 return true; 630 } 631 return false; 632} 633 634bool Caches::disableScissor() { 635 if (scissorEnabled) { 636 glDisable(GL_SCISSOR_TEST); 637 scissorEnabled = false; 638 return true; 639 } 640 return false; 641} 642 643void Caches::setScissorEnabled(bool enabled) { 644 if (scissorEnabled != enabled) { 645 if (enabled) glEnable(GL_SCISSOR_TEST); 646 else glDisable(GL_SCISSOR_TEST); 647 scissorEnabled = enabled; 648 } 649} 650 651void Caches::resetScissor() { 652 mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0; 653} 654 655/////////////////////////////////////////////////////////////////////////////// 656// Tiling 657/////////////////////////////////////////////////////////////////////////////// 658 659void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard) { 660 if (mExtensions.hasTiledRendering() && !debugOverdraw) { 661 glStartTilingQCOM(x, y, width, height, (discard ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM)); 662 } 663} 664 665void Caches::endTiling() { 666 if (mExtensions.hasTiledRendering() && !debugOverdraw) { 667 glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM); 668 } 669} 670 671bool Caches::hasRegisteredFunctors() { 672 return mFunctorsCount > 0; 673} 674 675void Caches::registerFunctors(uint32_t functorCount) { 676 mFunctorsCount += functorCount; 677} 678 679void Caches::unregisterFunctors(uint32_t functorCount) { 680 if (functorCount > mFunctorsCount) { 681 mFunctorsCount = 0; 682 } else { 683 mFunctorsCount -= functorCount; 684 } 685} 686 687/////////////////////////////////////////////////////////////////////////////// 688// Regions 689/////////////////////////////////////////////////////////////////////////////// 690 691TextureVertex* Caches::getRegionMesh() { 692 // Create the mesh, 2 triangles and 4 vertices per rectangle in the region 693 if (!mRegionMesh) { 694 mRegionMesh = new TextureVertex[gMaxNumberOfQuads * 4]; 695 } 696 697 return mRegionMesh; 698} 699 700/////////////////////////////////////////////////////////////////////////////// 701// Temporary Properties 702/////////////////////////////////////////////////////////////////////////////// 703 704void Caches::initTempProperties() { 705 propertyLightDiameter = -1.0f; 706 propertyLightPosY = -1.0f; 707 propertyLightPosZ = -1.0f; 708 propertyAmbientRatio = -1.0f; 709 propertyAmbientShadowStrength = -1; 710 propertySpotShadowStrength = -1; 711} 712 713void Caches::setTempProperty(const char* name, const char* value) { 714 ALOGD("setting property %s to %s", name, value); 715 if (!strcmp(name, "ambientRatio")) { 716 propertyAmbientRatio = fmin(fmax(atof(value), 0.0), 10.0); 717 ALOGD("ambientRatio = %.2f", propertyAmbientRatio); 718 return; 719 } else if (!strcmp(name, "lightDiameter")) { 720 propertyLightDiameter = fmin(fmax(atof(value), 0.0), 3000.0); 721 ALOGD("lightDiameter = %.2f", propertyLightDiameter); 722 return; 723 } else if (!strcmp(name, "lightPosY")) { 724 propertyLightPosY = fmin(fmax(atof(value), 0.0), 3000.0); 725 ALOGD("lightPos Y = %.2f", propertyLightPosY); 726 return; 727 } else if (!strcmp(name, "lightPosZ")) { 728 propertyLightPosZ = fmin(fmax(atof(value), 0.0), 3000.0); 729 ALOGD("lightPos Z = %.2f", propertyLightPosZ); 730 return; 731 } else if (!strcmp(name, "ambientShadowStrength")) { 732 propertyAmbientShadowStrength = atoi(value); 733 ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength); 734 return; 735 } else if (!strcmp(name, "spotShadowStrength")) { 736 propertySpotShadowStrength = atoi(value); 737 ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength); 738 return; 739 } 740 ALOGD(" failed"); 741} 742 743}; // namespace uirenderer 744}; // namespace android 745