PatchCache.cpp revision 36fad8f6fcfbc2087b910600ed5a6f9741177d00
1f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/* 2f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * Copyright (C) 2010 The Android Open Source Project 3f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * 4f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * you may not use this file except in compliance with the License. 6f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * You may obtain a copy of the License at 7f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * 8f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 9f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * 10f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * Unless required by applicable law or agreed to in writing, software 11f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * See the License for the specific language governing permissions and 14f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * limitations under the License. 15f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy */ 16f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 17f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#define LOG_TAG "OpenGLRenderer" 18f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <utils/JenkinsHash.h> 20f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#include <utils/Log.h> 21f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "Caches.h" 23f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#include "PatchCache.h" 24fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy#include "Properties.h" 25f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 26f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guynamespace android { 27f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guynamespace uirenderer { 28f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 29f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 30f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy// Constructors/destructor 31f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 32f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 334c2547fa9244e78115cde0a259291053108c3dc7Romain GuyPatchCache::PatchCache(): 344c2547fa9244e78115cde0a259291053108c3dc7Romain Guy mSize(0), mCache(LruCache<PatchDescription, Patch*>::kUnlimitedCapacity), 35e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mMeshBuffer(0), mFreeBlocks(NULL), mGenerationId(0) { 363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy char property[PROPERTY_VALUE_MAX]; 373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (property_get(PROPERTY_PATCH_CACHE_SIZE, property, NULL) > 0) { 383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy INIT_LOGD(" Setting patch cache size to %skB", property); 393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mMaxSize = KB(atoi(property)); 403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } else { 413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy INIT_LOGD(" Using default patch cache size of %.2fkB", DEFAULT_PATCH_CACHE_SIZE); 423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mMaxSize = KB(DEFAULT_PATCH_CACHE_SIZE); 433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 44f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 45f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 46f7f93556c8fcc640ab5adef79d021a80a72a645aRomain GuyPatchCache::~PatchCache() { 47f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy clear(); 48f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 49f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid PatchCache::init(Caches& caches) { 517d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy bool created = false; 527d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy if (!mMeshBuffer) { 537d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy glGenBuffers(1, &mMeshBuffer); 547d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy created = true; 557d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy } 567d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy 573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy caches.bindMeshBuffer(mMeshBuffer); 583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy caches.resetVertexPointers(); 593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 607d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy if (created) { 614c2547fa9244e78115cde0a259291053108c3dc7Romain Guy createVertexBuffer(); 627d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy } 633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 65f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 66f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy// Caching 67f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 68f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyhash_t PatchCache::PatchDescription::hash() const { 703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy uint32_t hash = JenkinsHashMix(0, android::hash_type(mPatch)); 713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy hash = JenkinsHashMix(hash, mBitmapWidth); 723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy hash = JenkinsHashMix(hash, mBitmapHeight); 733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy hash = JenkinsHashMix(hash, mPixelWidth); 743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy hash = JenkinsHashMix(hash, mPixelHeight); 753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return JenkinsHashWhiten(hash); 763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 7713ba0054846ce630ca31e8f26169fd9388faee02Romain Guy 783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyint PatchCache::PatchDescription::compare(const PatchCache::PatchDescription& lhs, 793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const PatchCache::PatchDescription& rhs) { 803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return memcmp(&lhs, &rhs, sizeof(PatchDescription)); 8113ba0054846ce630ca31e8f26169fd9388faee02Romain Guy} 8213ba0054846ce630ca31e8f26169fd9388faee02Romain Guy 83f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guyvoid PatchCache::clear() { 843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy clearCache(); 857d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy 867d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy if (mMeshBuffer) { 877d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy Caches::getInstance().unbindMeshBuffer(); 887d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy glDeleteBuffers(1, &mMeshBuffer); 897d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy mMeshBuffer = 0; 907d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy mSize = 0; 917d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy } 923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid PatchCache::clearCache() { 953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy LruCache<PatchDescription, Patch*>::Iterator i(mCache); 963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy while (i.next()) { 973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy delete i.value(); 982728f961614a385df1f056fc24803a9f65c90fabRomain Guy } 99f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy mCache.clear(); 100e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 101e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* block = mFreeBlocks; 102e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy while (block) { 103e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* next = block->next; 104e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy delete block; 105e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy block = next; 106e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 107e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mFreeBlocks = NULL; 108e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy} 109e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 110e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid PatchCache::remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch) { 111e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy LruCache<PatchDescription, Patch*>::Iterator i(mCache); 112e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy while (i.next()) { 113e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy const PatchDescription& key = i.key(); 114e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy if (key.getPatch() == patch) { 115e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy patchesToRemove.push(patch_pair_t(&key, i.value())); 116e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 117e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 118e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy} 119e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 120e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid PatchCache::removeDeferred(Res_png_9patch* patch) { 121e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy Mutex::Autolock _l(mLock); 122e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mGarbage.push(patch); 123e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy} 124e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 125e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid PatchCache::clearGarbage() { 126e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy Vector<patch_pair_t> patchesToRemove; 127e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 128e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy { // scope for the mutex 129e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy Mutex::Autolock _l(mLock); 130e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy size_t count = mGarbage.size(); 131e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy for (size_t i = 0; i < count; i++) { 13236fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee Res_png_9patch* patch = mGarbage[i]; 13336fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee remove(patchesToRemove, patch); 13436fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee // A Res_png_9patch is actually an array of byte that's larger 13536fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee // than sizeof(Res_png_9patch). It must be freed as an array. 13636fad8f6fcfbc2087b910600ed5a6f9741177d00Sangkyu Lee delete[] (int8_t*) patch; 137e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 138e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mGarbage.clear(); 139e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 140e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 141e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // TODO: We could sort patchesToRemove by offset to merge 142e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // adjacent free blocks 143e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy for (size_t i = 0; i < patchesToRemove.size(); i++) { 144e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy const patch_pair_t& pair = patchesToRemove[i]; 145e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 146e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // Add a new free block to the list 147e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy const Patch* patch = pair.getSecond(); 148e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* block = new BufferBlock(patch->offset, patch->getSize()); 149e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy block->next = mFreeBlocks; 150e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mFreeBlocks = block; 151e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 152e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mSize -= patch->getSize(); 153e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 154e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mCache.remove(*pair.getFirst()); 155e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 156e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 157e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#if DEBUG_PATCHES 158e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy if (patchesToRemove.size() > 0) { 159e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy dumpFreeBlocks("Removed garbage"); 160e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 161e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#endif 162f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 163f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 1644c2547fa9244e78115cde0a259291053108c3dc7Romain Guyvoid PatchCache::createVertexBuffer() { 1654c2547fa9244e78115cde0a259291053108c3dc7Romain Guy glBufferData(GL_ARRAY_BUFFER, mMaxSize, NULL, GL_DYNAMIC_DRAW); 1664c2547fa9244e78115cde0a259291053108c3dc7Romain Guy mSize = 0; 167e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mFreeBlocks = new BufferBlock(0, mMaxSize); 1684c2547fa9244e78115cde0a259291053108c3dc7Romain Guy mGenerationId++; 1694c2547fa9244e78115cde0a259291053108c3dc7Romain Guy} 1704c2547fa9244e78115cde0a259291053108c3dc7Romain Guy 171e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy/** 172e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * Sets the mesh's offsets and copies its associated vertices into 173e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * the mesh buffer (VBO). 174e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy */ 175e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid PatchCache::setupMesh(Patch* newMesh, TextureVertex* vertices) { 176e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // This call ensures the VBO exists and that it is bound 177e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy init(Caches::getInstance()); 178e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 179e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // If we're running out of space, let's clear the entire cache 180e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy uint32_t size = newMesh->getSize(); 181e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy if (mSize + size > mMaxSize) { 182e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy clearCache(); 183e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy createVertexBuffer(); 184e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 185e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 186e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // Find a block where we can fit the mesh 187e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* previous = NULL; 188e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* block = mFreeBlocks; 189e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy while (block) { 190e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // The mesh fits 191e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy if (block->size >= size) { 192e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy break; 193e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 194e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy previous = block; 195e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy block = block->next; 196e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 197e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 198e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // We have enough space left in the buffer, but it's 199e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // too fragmented, let's clear the cache 200e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy if (!block) { 201e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy clearCache(); 202e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy createVertexBuffer(); 203e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy previous = NULL; 204e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy block = mFreeBlocks; 205e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 206e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 207e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // Copy the 9patch mesh in the VBO 208e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy newMesh->offset = (GLintptr) (block->offset); 209e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy newMesh->textureOffset = newMesh->offset + gMeshTextureOffset; 210e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy glBufferSubData(GL_ARRAY_BUFFER, newMesh->offset, size, vertices); 211e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 212e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // Remove the block since we've used it entirely 213e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy if (block->size == size) { 214e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy if (previous) { 215e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy previous->next = block->next; 216e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } else { 217e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mFreeBlocks = block->next; 218e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 219e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } else { 220e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // Resize the block now that it's occupied 221e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy block->offset += size; 222e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy block->size -= size; 223e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 224e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 225e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mSize += size; 226e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy} 227e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 2283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyconst Patch* PatchCache::get(const AssetAtlas::Entry* entry, 2293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const uint32_t bitmapWidth, const uint32_t bitmapHeight, 2303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch) { 2314bb942083a0d4db746adf95349108dd8ef842e32Romain Guy 2323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const PatchDescription description(bitmapWidth, bitmapHeight, pixelWidth, pixelHeight, patch); 2333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const Patch* mesh = mCache.get(description); 2344bb942083a0d4db746adf95349108dd8ef842e32Romain Guy 2353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!mesh) { 2363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Patch* newMesh = new Patch(); 2373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy TextureVertex* vertices; 2383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 2393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (entry) { 240e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // An atlas entry has a UV mapper 2413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy vertices = newMesh->createMesh(bitmapWidth, bitmapHeight, 24203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy pixelWidth, pixelHeight, entry->uvMapper, patch); 2433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } else { 2443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy vertices = newMesh->createMesh(bitmapWidth, bitmapHeight, 24503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy pixelWidth, pixelHeight, patch); 2464bb942083a0d4db746adf95349108dd8ef842e32Romain Guy } 2472728f961614a385df1f056fc24803a9f65c90fabRomain Guy 2483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (vertices) { 249e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy setupMesh(newMesh, vertices); 2502728f961614a385df1f056fc24803a9f65c90fabRomain Guy } 2512728f961614a385df1f056fc24803a9f65c90fabRomain Guy 252e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#if DEBUG_PATCHES 253e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy dumpFreeBlocks("Adding patch"); 254e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#endif 255e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 2563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mCache.put(description, newMesh); 2573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return newMesh; 258f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy } 259f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 260f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy return mesh; 261f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 262f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 263e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#if DEBUG_PATCHES 264e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyvoid PatchCache::dumpFreeBlocks(const char* prefix) { 265e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy String8 dump; 266e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* block = mFreeBlocks; 267e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy while (block) { 268e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy dump.appendFormat("->(%d, %d)", block->offset, block->size); 269e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy block = block->next; 270e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy } 271e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy ALOGD("%s: Free blocks%s", prefix, dump.string()); 272e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy} 273e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#endif 274e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 275f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy}; // namespace uirenderer 276f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy}; // namespace android 277