TextDropShadowCache.cpp revision 1e45aae5de003657e5d18f74d34998f5de5db5b7
11e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/* 21e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Copyright (C) 2010 The Android Open Source Project 31e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * 41e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 51e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * you may not use this file except in compliance with the License. 61e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * You may obtain a copy of the License at 71e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * 81e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 91e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * 101e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Unless required by applicable law or agreed to in writing, software 111e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 121e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * See the License for the specific language governing permissions and 141e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * limitations under the License. 151e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 161e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 171e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#define LOG_TAG "OpenGLRenderer" 181e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 191e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include "TextDropShadowCache.h" 201e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 211e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace android { 221e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace uirenderer { 231e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 241e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 251e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Constructors/destructor 261e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 281e45aae5de003657e5d18f74d34998f5de5db5b7Romain GuyTextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize): 291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mCache(GenerationCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity), 301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mSize(0), mMaxSize(maxByteSize) { 311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mCache.setOnEntryRemovedListener(this); 321e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 331e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 341e45aae5de003657e5d18f74d34998f5de5db5b7Romain GuyTextDropShadowCache::~TextDropShadowCache() { 351e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mCache.clear(); 361e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 371e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 381e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 391e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Size management 401e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 411e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 421e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyuint32_t TextDropShadowCache::getSize() { 431e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy return mSize; 441e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 451e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 461e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyuint32_t TextDropShadowCache::getMaxSize() { 471e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy return mMaxSize; 481e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 491e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 501e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyvoid TextDropShadowCache::setMaxSize(uint32_t maxSize) { 511e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mMaxSize = maxSize; 521e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy while (mSize > mMaxSize) { 531e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mCache.removeOldest(); 541e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 551e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 561e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 571e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 581e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Callbacks 591e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 601e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 611e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyvoid TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) { 621e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy const uint32_t size = texture->width * texture->height; 631e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mSize -= size; 641e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 651e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy if (texture) { 661e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glDeleteTextures(1, &texture->id); 671e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy delete texture; 681e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 691e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 701e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 711e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 721e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Caching 731e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/////////////////////////////////////////////////////////////////////////////// 741e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 751e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyvoid TextDropShadowCache::clear() { 761e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mCache.clear(); 771e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 781e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 791e45aae5de003657e5d18f74d34998f5de5db5b7Romain GuyShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32_t len, 801e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy int numGlyphs, uint32_t radius) { 811e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ShadowText entry(paint, radius, len, text); 821e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ShadowTexture* texture = mCache.get(entry); 831e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 841e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy if (!texture) { 851e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy FontRenderer::DropShadow shadow = mRenderer->renderDropShadow(paint, text, 0, 861e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy len, numGlyphs, radius); 871e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 881e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture = new ShadowTexture; 891e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture->left = shadow.penX; 901e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture->top = shadow.penY; 911e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture->width = shadow.width; 921e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture->height = shadow.height; 931e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture->generation = 0; 941e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture->blend = true; 951e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 961e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy const uint32_t size = shadow.width * shadow.height; 971e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy // Don't even try to cache a bitmap that's bigger than the cache 981e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy if (size < mMaxSize) { 991e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy while (mSize + size > mMaxSize) { 1001e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mCache.removeOldest(); 1011e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1021e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1031e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1041e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glGenTextures(1, &texture->id); 1051e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1061e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glBindTexture(GL_TEXTURE_2D, texture->id); 1071e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy // Textures are Alpha8 1081e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 1091e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1101e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0, 1111e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy GL_ALPHA, GL_UNSIGNED_BYTE, shadow.image); 1121e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1131e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1141e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1151e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1161e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1171e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1181e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1191e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy if (size < mMaxSize) { 1201e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mSize += size; 1211e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mCache.put(entry, texture); 1221e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } else { 1231e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy texture->cleanup = true; 1241e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1251e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1261e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy // Cleanup shadow 1271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy delete[] shadow.image; 1281e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy return texture; 1311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy} 1321e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1331e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace uirenderer 1341e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace android 135