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