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 19f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#include <utils/Log.h> 20f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 21f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#include "PatchCache.h" 22fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy#include "Properties.h" 23f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 24f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guynamespace android { 25f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guynamespace uirenderer { 26f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 27f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 28f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy// Constructors/destructor 29f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 30f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 312728f961614a385df1f056fc24803a9f65c90fabRomain GuyPatchCache::PatchCache(): mMaxEntries(DEFAULT_PATCH_CACHE_SIZE) { 32fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy} 33fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 342728f961614a385df1f056fc24803a9f65c90fabRomain GuyPatchCache::PatchCache(uint32_t maxEntries): mMaxEntries(maxEntries) { 35f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 36f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 37f7f93556c8fcc640ab5adef79d021a80a72a645aRomain GuyPatchCache::~PatchCache() { 38f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy clear(); 39f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 40f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 41f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 42f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy// Caching 43f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 44f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 45f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guyvoid PatchCache::clear() { 462728f961614a385df1f056fc24803a9f65c90fabRomain Guy size_t count = mCache.size(); 474bb942083a0d4db746adf95349108dd8ef842e32Romain Guy for (size_t i = 0; i < count; i++) { 482728f961614a385df1f056fc24803a9f65c90fabRomain Guy delete mCache.valueAt(i); 492728f961614a385df1f056fc24803a9f65c90fabRomain Guy } 50f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy mCache.clear(); 51f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 52f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 532728f961614a385df1f056fc24803a9f65c90fabRomain GuyPatch* PatchCache::get(const float bitmapWidth, const float bitmapHeight, 542728f961614a385df1f056fc24803a9f65c90fabRomain Guy const float pixelWidth, const float pixelHeight, 554bb942083a0d4db746adf95349108dd8ef842e32Romain Guy const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors, 564bb942083a0d4db746adf95349108dd8ef842e32Romain Guy const uint32_t width, const uint32_t height, const int8_t numColors) { 574bb942083a0d4db746adf95349108dd8ef842e32Romain Guy 584bb942083a0d4db746adf95349108dd8ef842e32Romain Guy int8_t transparentQuads = 0; 594bb942083a0d4db746adf95349108dd8ef842e32Romain Guy uint32_t colorKey = 0; 604bb942083a0d4db746adf95349108dd8ef842e32Romain Guy 614bb942083a0d4db746adf95349108dd8ef842e32Romain Guy if (uint8_t(numColors) < sizeof(uint32_t) * 4) { 624bb942083a0d4db746adf95349108dd8ef842e32Romain Guy for (int8_t i = 0; i < numColors; i++) { 634bb942083a0d4db746adf95349108dd8ef842e32Romain Guy if (colors[i] == 0x0) { 644bb942083a0d4db746adf95349108dd8ef842e32Romain Guy transparentQuads++; 654bb942083a0d4db746adf95349108dd8ef842e32Romain Guy colorKey |= 0x1 << i; 664bb942083a0d4db746adf95349108dd8ef842e32Romain Guy } 674bb942083a0d4db746adf95349108dd8ef842e32Romain Guy } 684bb942083a0d4db746adf95349108dd8ef842e32Romain Guy } 692728f961614a385df1f056fc24803a9f65c90fabRomain Guy 70054dc1840941665e32036f9523df51720ad069c8Romain Guy // If the 9patch is made of only transparent quads 7103750a067e818ca7fbd0f590e2ff6a8fded21e6cRomain Guy if (transparentQuads == int8_t((width + 1) * (height + 1))) { 72054dc1840941665e32036f9523df51720ad069c8Romain Guy return NULL; 73054dc1840941665e32036f9523df51720ad069c8Romain Guy } 74054dc1840941665e32036f9523df51720ad069c8Romain Guy 752728f961614a385df1f056fc24803a9f65c90fabRomain Guy const PatchDescription description(bitmapWidth, bitmapHeight, 764bb942083a0d4db746adf95349108dd8ef842e32Romain Guy pixelWidth, pixelHeight, width, height, transparentQuads, colorKey); 772728f961614a385df1f056fc24803a9f65c90fabRomain Guy 782728f961614a385df1f056fc24803a9f65c90fabRomain Guy ssize_t index = mCache.indexOfKey(description); 792728f961614a385df1f056fc24803a9f65c90fabRomain Guy Patch* mesh = NULL; 802728f961614a385df1f056fc24803a9f65c90fabRomain Guy if (index >= 0) { 812728f961614a385df1f056fc24803a9f65c90fabRomain Guy mesh = mCache.valueAt(index); 822728f961614a385df1f056fc24803a9f65c90fabRomain Guy } 83f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 84f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy if (!mesh) { 854bb942083a0d4db746adf95349108dd8ef842e32Romain Guy PATCH_LOGD("New patch mesh " 864bb942083a0d4db746adf95349108dd8ef842e32Romain Guy "xCount=%d yCount=%d, w=%.2f h=%.2f, bw=%.2f bh=%.2f", 874bb942083a0d4db746adf95349108dd8ef842e32Romain Guy width, height, pixelWidth, pixelHeight, bitmapWidth, bitmapHeight); 882728f961614a385df1f056fc24803a9f65c90fabRomain Guy 894bb942083a0d4db746adf95349108dd8ef842e32Romain Guy mesh = new Patch(width, height, transparentQuads); 906f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mesh->updateColorKey(colorKey); 916f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mesh->copy(xDivs, yDivs); 926f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mesh->updateVertices(bitmapWidth, bitmapHeight, 0.0f, 0.0f, pixelWidth, pixelHeight); 932728f961614a385df1f056fc24803a9f65c90fabRomain Guy 942728f961614a385df1f056fc24803a9f65c90fabRomain Guy if (mCache.size() >= mMaxEntries) { 9521b028a44f3e0bd9b0f0432b8b92c45f661d22a4Romain Guy delete mCache.valueAt(mCache.size() - 1); 9621b028a44f3e0bd9b0f0432b8b92c45f661d22a4Romain Guy mCache.removeItemsAt(mCache.size() - 1, 1); 972728f961614a385df1f056fc24803a9f65c90fabRomain Guy } 982728f961614a385df1f056fc24803a9f65c90fabRomain Guy 992728f961614a385df1f056fc24803a9f65c90fabRomain Guy mCache.add(description, mesh); 1006f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } else if (!mesh->matches(xDivs, yDivs, colorKey)) { 1016f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy PATCH_LOGD("Patch mesh does not match, refreshing vertices"); 1026f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy mesh->updateVertices(bitmapWidth, bitmapHeight, 0.0f, 0.0f, pixelWidth, pixelHeight); 103f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy } 104f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 105f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy return mesh; 106f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy} 107f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 108f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy}; // namespace uirenderer 109f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy}; // namespace android 110