CacheTexture.h revision 661a87ec28a49458f1faf533783abf2ab9927cab
18182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood/* 28182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * Copyright (C) 2012 The Android Open Source Project 38182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * 48182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 58182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * you may not use this file except in compliance with the License. 68182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * You may obtain a copy of the License at 78182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * 88182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 98182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * 108182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * Unless required by applicable law or agreed to in writing, software 118182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 128182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * See the License for the specific language governing permissions and 148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * limitations under the License. 158182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood */ 168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#ifndef ANDROID_HWUI_CACHE_TEXTURE_H 188182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#define ANDROID_HWUI_CACHE_TEXTURE_H 19c4308f01c965571dc2354107c3574df113e397eeMike Lockwood 20acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood#include <GLES2/gl2.h> 218182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 228182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include <SkScalerContext.h> 230cdd9f7def708a71a0d0722361f52c0416370dc6Scott Main 240cdd9f7def708a71a0d0722361f52c0416370dc6Scott Main#include <utils/Log.h> 250cdd9f7def708a71a0d0722361f52c0416370dc6Scott Main 260cdd9f7def708a71a0d0722361f52c0416370dc6Scott Main#include "FontUtil.h" 278182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "../Rect.h" 288182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood#include "../Vertex.h" 298182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 308182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodnamespace android { 318182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodnamespace uirenderer { 328182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 338182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood/** 348182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * CacheBlock is a node in a linked list of current free space areas in a CacheTexture. 358182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * Using CacheBlocks enables us to pack the cache from top to bottom as well as left to right. 368182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * When we add a glyph to the cache, we see if it fits within one of the existing columns that 378182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * have already been started (this is the case if the glyph fits vertically as well as 38540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood * horizontally, and if its width is sufficiently close to the column width to avoid 39540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood * sub-optimal packing of small glyphs into wide columns). If there is no column in which the 40540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood * glyph fits, we check the final node, which is the remaining space in the cache, creating 41c4308f01c965571dc2354107c3574df113e397eeMike Lockwood * a new column as appropriate. 42540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood * 438182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * As columns fill up, we remove their CacheBlock from the list to avoid having to check 448182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * small blocks in the future. 458182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood */ 468182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodstruct CacheBlock { 47540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood uint16_t mX; 48acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood uint16_t mY; 49acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood uint16_t mWidth; 50acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood uint16_t mHeight; 51acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood CacheBlock* mNext; 52540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood CacheBlock* mPrev; 53acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood 54540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height, bool empty = false): 55540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood mX(x), mY(y), mWidth(width), mHeight(height), mNext(NULL), mPrev(NULL) { 56acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood } 57acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood 58acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood static CacheBlock* insertBlock(CacheBlock* head, CacheBlock* newBlock); 59acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood static CacheBlock* removeBlock(CacheBlock* head, CacheBlock* blockToRemove); 608182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 61acc29cc91be634070c92a807df412ced97b9b375Mike Lockwood void output() { 628182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood CacheBlock* currBlock = this; 638182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood while (currBlock) { 64540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood ALOGD("Block: this, x, y, w, h = %p, %d, %d, %d, %d", 6511dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood currBlock, currBlock->mX, currBlock->mY, 6611dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood currBlock->mWidth, currBlock->mHeight); 6711dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood currBlock = currBlock->mNext; 68540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 698182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 708182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood}; 718182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 728182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodclass CacheTexture { 738182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodpublic: 748182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood CacheTexture(uint16_t width, uint16_t height, uint32_t maxQuadCount); 758182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood ~CacheTexture(); 768182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 778182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood void reset(); 788182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood void init(); 798182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 808182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood void releaseMesh(); 818182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood void releaseTexture(); 82540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 83540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood void allocateTexture(); 8411dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood void allocateMesh(); 8511dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood 86540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood bool fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY); 87540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 88540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood inline uint16_t getWidth() const { 898182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood return mWidth; 908182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 918182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 928182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood inline uint16_t getHeight() const { 93540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood return mHeight; 9411dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood } 9511dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood 9611dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood inline const Rect* getDirtyRect() const { 97540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood return &mDirtyRect; 98540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 99540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 1008182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood inline uint8_t* getTexture() const { 1018182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood return mTexture; 1028182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 1038182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 1048182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood GLuint getTextureId() { 1058182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood allocateTexture(); 1068182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood return mTextureId; 1078182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 1088182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 109540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood inline bool isDirty() const { 11011dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood return mDirty; 111540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 112540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 113540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood inline void setDirty(bool dirty) { 1148182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood mDirty = dirty; 1158182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood if (!dirty) { 1168182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood mDirtyRect.setEmpty(); 1178182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 118540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 119540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 12011dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood inline bool getLinearFiltering() const { 121540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood return mLinearFiltering; 12211dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood } 123540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 1248182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood /** 1258182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood * This method assumes that the proper texture unit is active. 1268182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood */ 1278182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood void setLinearFiltering(bool linearFiltering, bool bind = true) { 128540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood if (linearFiltering != mLinearFiltering) { 129540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood mLinearFiltering = linearFiltering; 130540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 13111dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST; 132540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood if (bind) glBindTexture(GL_TEXTURE_2D, getTextureId()); 133540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); 134540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); 135540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 136540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 137540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 1388182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood inline uint16_t getGlyphCount() const { 1398182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood return mNumGlyphs; 1408182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 1418182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 142540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood TextureVertex* mesh() const { 143540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood return mMesh; 14411dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood } 14511dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood 146540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood uint32_t meshElementCount() const { 147540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood return mCurrentQuad * 6; 148540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 14911dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood 150540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood uint16_t* indices() const { 151540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood return (uint16_t*) 0; 1528182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 1538182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 1548182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood void resetMesh() { 1558182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood mCurrentQuad = 0; 156540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 157540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 15811dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood inline void addQuad(float x1, float y1, float u1, float v1, 15911dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood float x2, float y2, float u2, float v2, 16011dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood float x3, float y3, float u3, float v3, 16111dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood float x4, float y4, float u4, float v4) { 162540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood TextureVertex* mesh = mMesh + mCurrentQuad * 4; 163540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood TextureVertex::set(mesh++, x1, y1, u1, v1); 164540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood TextureVertex::set(mesh++, x2, y2, u2, v2); 165540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood TextureVertex::set(mesh++, x3, y3, u3, v3); 1668182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood TextureVertex::set(mesh++, x4, y4, u4, v4); 1678182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood mCurrentQuad++; 1688182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 1698182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 170540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood bool canDraw() const { 17111dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood return mCurrentQuad > 0; 172540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood } 173540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 174540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood bool endOfMesh() const { 175540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood return mCurrentQuad == mMaxQuadCount; 1768182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood } 1778182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood 1788182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwoodprivate: 1798182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood uint8_t* mTexture; 180540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood GLuint mTextureId; 18111dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood uint16_t mWidth; 182540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood uint16_t mHeight; 183540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood bool mLinearFiltering; 184540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood bool mDirty; 185540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood uint16_t mNumGlyphs; 1868182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood TextureVertex* mMesh; 1878182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood uint32_t mCurrentQuad; 1888182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood uint32_t mMaxQuadCount; 1898182e72479a8b0d832df9c392890b25bfa6f97b5Mike Lockwood CacheBlock* mCacheBlocks; 190540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood Rect mDirtyRect; 19111dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood}; 19211dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood 19311dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood}; // namespace uirenderer 194540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood}; // namespace android 195540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood 196540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood#endif // ANDROID_HWUI_CACHE_TEXTURE_H 197540380fb0a45b12af3970f9ea1ed041607451f46Mike Lockwood