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 200908764b2b3cf5075df4178a5f0a8547dcb7b317Romain Guy#include <GLES3/gl3.h> 219f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 229f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#include <SkScalerContext.h> 239f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 249f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#include <utils/Log.h> 259f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 269f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#include "FontUtil.h" 271e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease#include "../PixelBuffer.h" 28661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy#include "../Rect.h" 29661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy#include "../Vertex.h" 309f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 319f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guynamespace android { 329f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guynamespace uirenderer { 339f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 348aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyclass Caches; 35cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 369f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy/** 379f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * CacheBlock is a node in a linked list of current free space areas in a CacheTexture. 389f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * Using CacheBlocks enables us to pack the cache from top to bottom as well as left to right. 399f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * When we add a glyph to the cache, we see if it fits within one of the existing columns that 409f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * have already been started (this is the case if the glyph fits vertically as well as 419f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * horizontally, and if its width is sufficiently close to the column width to avoid 429f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * sub-optimal packing of small glyphs into wide columns). If there is no column in which the 439f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * glyph fits, we check the final node, which is the remaining space in the cache, creating 449f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * a new column as appropriate. 459f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * 469f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * As columns fill up, we remove their CacheBlock from the list to avoid having to check 479f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy * small blocks in the future. 489f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy */ 499f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guystruct CacheBlock { 509f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mX; 519f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mY; 529f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mWidth; 539f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mHeight; 549f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock* mNext; 559f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock* mPrev; 569f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 57e63f7c622a2086aefa80983c6f41b74fb166bb42Chris Craik CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height): 589b1204baf4740b4d443e72157dea98571cf84e1fRomain Guy mX(x), mY(y), mWidth(width), mHeight(height), mNext(NULL), mPrev(NULL) { 599f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 609f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 61e43f785b7ff3fdf75f6d1c92282ebca6db191f2fRomain Guy static CacheBlock* insertBlock(CacheBlock* head, CacheBlock* newBlock); 62e43f785b7ff3fdf75f6d1c92282ebca6db191f2fRomain Guy static CacheBlock* removeBlock(CacheBlock* head, CacheBlock* blockToRemove); 639f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 649f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy void output() { 65e43f785b7ff3fdf75f6d1c92282ebca6db191f2fRomain Guy CacheBlock* currBlock = this; 669f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy while (currBlock) { 679f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy ALOGD("Block: this, x, y, w, h = %p, %d, %d, %d, %d", 68661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy currBlock, currBlock->mX, currBlock->mY, 69661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy currBlock->mWidth, currBlock->mHeight); 709f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy currBlock = currBlock->mNext; 719f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 729f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy } 739f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; 749f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 759f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guyclass CacheTexture { 769f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guypublic: 771e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount); 78661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy ~CacheTexture(); 799f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 80661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy void reset(); 81661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy void init(); 829f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 83661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy void releaseMesh(); 84661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy void releaseTexture(); 859f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 86661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy void allocateTexture(); 87661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy void allocateMesh(); 888087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 89cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy // Returns true if glPixelStorei(GL_UNPACK_ROW_LENGTH) must be reset 90cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy // This method will also call setDirty(false) 91cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy bool upload(); 92cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 93e43f785b7ff3fdf75f6d1c92282ebca6db191f2fRomain Guy bool fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY); 949f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 958087246d9964b11de8ce116bc63b156faa4197e0Romain Guy inline uint16_t getWidth() const { 968087246d9964b11de8ce116bc63b156faa4197e0Romain Guy return mWidth; 978087246d9964b11de8ce116bc63b156faa4197e0Romain Guy } 988087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 998087246d9964b11de8ce116bc63b156faa4197e0Romain Guy inline uint16_t getHeight() const { 1008087246d9964b11de8ce116bc63b156faa4197e0Romain Guy return mHeight; 1018087246d9964b11de8ce116bc63b156faa4197e0Romain Guy } 1028087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 1031e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease inline GLenum getFormat() const { 1041e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease return mFormat; 1051e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease } 1061e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease 1071e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease inline uint32_t getOffset(uint16_t x, uint16_t y) const { 1081e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease return (y * mWidth + x) * PixelBuffer::formatSize(mFormat); 1091e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease } 1101e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease 111b92d8f7979c29c7c09932578a11b2f8d6eec1d90Chet Haase inline const Rect* getDirtyRect() const { 112b92d8f7979c29c7c09932578a11b2f8d6eec1d90Chet Haase return &mDirtyRect; 113b92d8f7979c29c7c09932578a11b2f8d6eec1d90Chet Haase } 114b92d8f7979c29c7c09932578a11b2f8d6eec1d90Chet Haase 115cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy inline PixelBuffer* getPixelBuffer() const { 1168087246d9964b11de8ce116bc63b156faa4197e0Romain Guy return mTexture; 1178087246d9964b11de8ce116bc63b156faa4197e0Romain Guy } 1188087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 119574cf6070d34e66dfd6f2006937986eddd1f09e7Romain Guy GLuint getTextureId() { 120574cf6070d34e66dfd6f2006937986eddd1f09e7Romain Guy allocateTexture(); 1218087246d9964b11de8ce116bc63b156faa4197e0Romain Guy return mTextureId; 1228087246d9964b11de8ce116bc63b156faa4197e0Romain Guy } 1238087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 1248087246d9964b11de8ce116bc63b156faa4197e0Romain Guy inline bool isDirty() const { 1258087246d9964b11de8ce116bc63b156faa4197e0Romain Guy return mDirty; 1268087246d9964b11de8ce116bc63b156faa4197e0Romain Guy } 1278087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 1288087246d9964b11de8ce116bc63b156faa4197e0Romain Guy inline bool getLinearFiltering() const { 1298087246d9964b11de8ce116bc63b156faa4197e0Romain Guy return mLinearFiltering; 1308087246d9964b11de8ce116bc63b156faa4197e0Romain Guy } 1318087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 1328087246d9964b11de8ce116bc63b156faa4197e0Romain Guy /** 1338087246d9964b11de8ce116bc63b156faa4197e0Romain Guy * This method assumes that the proper texture unit is active. 1348087246d9964b11de8ce116bc63b156faa4197e0Romain Guy */ 135cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void setLinearFiltering(bool linearFiltering, bool bind = true); 1368087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 1378087246d9964b11de8ce116bc63b156faa4197e0Romain Guy inline uint16_t getGlyphCount() const { 1388087246d9964b11de8ce116bc63b156faa4197e0Romain Guy return mNumGlyphs; 1398087246d9964b11de8ce116bc63b156faa4197e0Romain Guy } 1408087246d9964b11de8ce116bc63b156faa4197e0Romain Guy 141661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy TextureVertex* mesh() const { 142661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy return mMesh; 143661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy } 144661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy 145661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy uint32_t meshElementCount() const { 146661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy return mCurrentQuad * 6; 147661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy } 148661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy 149661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy uint16_t* indices() const { 150661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy return (uint16_t*) 0; 151661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy } 152661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy 153661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy void resetMesh() { 154661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy mCurrentQuad = 0; 155661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy } 156661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy 157661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy inline void addQuad(float x1, float y1, float u1, float v1, 158661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy float x2, float y2, float u2, float v2, 159661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy float x3, float y3, float u3, float v3, 160661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy float x4, float y4, float u4, float v4) { 161661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy TextureVertex* mesh = mMesh + mCurrentQuad * 4; 162661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy TextureVertex::set(mesh++, x2, y2, u2, v2); 163661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy TextureVertex::set(mesh++, x3, y3, u3, v3); 16431e08e953fe7bdb1b1cbc247156cb6a19917a2f1Romain Guy TextureVertex::set(mesh++, x1, y1, u1, v1); 165661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy TextureVertex::set(mesh++, x4, y4, u4, v4); 166661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy mCurrentQuad++; 167661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy } 168661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy 169661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy bool canDraw() const { 170661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy return mCurrentQuad > 0; 171661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy } 172661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy 173661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy bool endOfMesh() const { 174661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy return mCurrentQuad == mMaxQuadCount; 175661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy } 176661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy 1778087246d9964b11de8ce116bc63b156faa4197e0Romain Guyprivate: 178cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy void setDirty(bool dirty); 179cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy 180cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy PixelBuffer* mTexture; 1819f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy GLuint mTextureId; 1829f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mWidth; 1839f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mHeight; 1841e546815bbb736c50679a8aefc25f48561026fc5Victoria Lease GLenum mFormat; 1859f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy bool mLinearFiltering; 1869f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy bool mDirty; 1879f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy uint16_t mNumGlyphs; 188661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy TextureVertex* mMesh; 189661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy uint32_t mCurrentQuad; 190661a87ec28a49458f1faf533783abf2ab9927cabRomain Guy uint32_t mMaxQuadCount; 1918aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy Caches& mCaches; 1929f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy CacheBlock* mCacheBlocks; 193318ae7bb92869d99a05388c598ad105e7aa4cdbdRomain Guy bool mHasUnpackRowLength; 1948aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy Rect mDirtyRect; 1959f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; 1969f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 1979f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; // namespace uirenderer 1989f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy}; // namespace android 1999f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy 2009f5dab3fc228fa11c32b483e6101ec086895a32bRomain Guy#endif // ANDROID_HWUI_CACHE_TEXTURE_H 201