CacheTexture.h revision 9f5dab3fc228fa11c32b483e6101ec086895a32b
19f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy/* 29f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * Copyright (C) 2012 The Android Open Source Project 39f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * 49f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 59f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * you may not use this file except in compliance with the License. 69f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * You may obtain a copy of the License at 79f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * 89f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 99f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * 109f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * Unless required by applicable law or agreed to in writing, software 119f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 129f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * See the License for the specific language governing permissions and 149f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * limitations under the License. 159f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy */ 169f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 179f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#ifndef ANDROID_HWUI_CACHE_TEXTURE_H 189f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#define ANDROID_HWUI_CACHE_TEXTURE_H 199f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 209f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#include <GLES2/gl2.h> 219f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 229f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#include <SkScalerContext.h> 239f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 249f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#include <utils/Log.h> 259f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 269f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#include "FontUtil.h" 279f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 289f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guynamespace android { 299f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guynamespace uirenderer { 309f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 319f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy/** 329f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * CacheBlock is a node in a linked list of current free space areas in a CacheTexture. 339f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * Using CacheBlocks enables us to pack the cache from top to bottom as well as left to right. 349f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * When we add a glyph to the cache, we see if it fits within one of the existing columns that 359f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * have already been started (this is the case if the glyph fits vertically as well as 369f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * horizontally, and if its width is sufficiently close to the column width to avoid 379f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * sub-optimal packing of small glyphs into wide columns). If there is no column in which the 389f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * glyph fits, we check the final node, which is the remaining space in the cache, creating 399f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * a new column as appropriate. 409f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * 419f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * As columns fill up, we remove their CacheBlock from the list to avoid having to check 429f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * small blocks in the future. 439f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy */ 449f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guystruct CacheBlock { 459f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mX; 469f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mY; 479f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mWidth; 489f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mHeight; 499f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock* mNext; 509f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock* mPrev; 519f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 529f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height, bool empty = false): 539f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mX(x), mY(y), mWidth(width), mHeight(height), mNext(NULL), mPrev(NULL) 549f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy { 559f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 569f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 579f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy static CacheBlock* insertBlock(CacheBlock* head, CacheBlock *newBlock); 589f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 599f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy static CacheBlock* removeBlock(CacheBlock* head, CacheBlock *blockToRemove); 609f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 619f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy void output() { 629f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock *currBlock = this; 639f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy while (currBlock) { 649f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy ALOGD("Block: this, x, y, w, h = %p, %d, %d, %d, %d", 659f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy currBlock, currBlock->mX, currBlock->mY, currBlock->mWidth, currBlock->mHeight); 669f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy currBlock = currBlock->mNext; 679f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 689f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 699f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; 709f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 719f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guyclass CacheTexture { 729f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guypublic: 739f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheTexture(uint16_t width, uint16_t height) : 749f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mTexture(NULL), mTextureId(0), mWidth(width), mHeight(height), 759f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mLinearFiltering(false), mDirty(false), mNumGlyphs(0) { 769f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE, 779f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true); 789f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 799f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 809f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy ~CacheTexture() { 819f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy if (mTexture) { 829f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy delete[] mTexture; 839f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 849f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy if (mTextureId) { 859f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy glDeleteTextures(1, &mTextureId); 869f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 879f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy reset(); 889f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 899f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 909f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy void reset() { 919f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy // Delete existing cache blocks 929f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy while (mCacheBlocks != NULL) { 939f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock* tmpBlock = mCacheBlocks; 949f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mCacheBlocks = mCacheBlocks->mNext; 959f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy delete tmpBlock; 969f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 979f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mNumGlyphs = 0; 989f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 999f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 1009f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy void init() { 1019f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy // reset, then create a new remainder space to start again 1029f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy reset(); 1039f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE, 1049f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true); 1059f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 1069f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 1079f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY); 1089f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 1099f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint8_t* mTexture; 1109f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy GLuint mTextureId; 1119f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mWidth; 1129f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mHeight; 1139f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy bool mLinearFiltering; 1149f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy bool mDirty; 1159f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mNumGlyphs; 1169f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock* mCacheBlocks; 1179f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; 1189f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 1199f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; // namespace uirenderer 1209f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; // namespace android 1219f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 1229f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#endif // ANDROID_HWUI_CACHE_TEXTURE_H 123