FontRenderer.h revision 115096f50a560e64a7f95d37686d4861042c7aeb
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HWUI_FONT_RENDERER_H
18#define ANDROID_HWUI_FONT_RENDERER_H
19
20#include <utils/LruCache.h>
21#include <utils/Vector.h>
22
23#include <SkPaint.h>
24
25#include <GLES2/gl2.h>
26
27#include "font/FontUtil.h"
28#include "font/CacheTexture.h"
29#include "font/CachedGlyphInfo.h"
30#include "font/Font.h"
31#include "utils/SortedList.h"
32#include "Matrix.h"
33#include "Properties.h"
34
35namespace RSC {
36    class Element;
37    class RS;
38    class ScriptIntrinsicBlur;
39}
40
41namespace android {
42namespace uirenderer {
43
44///////////////////////////////////////////////////////////////////////////////
45// Renderer
46///////////////////////////////////////////////////////////////////////////////
47
48class FontRenderer {
49public:
50    FontRenderer();
51    ~FontRenderer();
52
53    void flushLargeCaches();
54
55    void setGammaTable(const uint8_t* gammaTable) {
56        mGammaTable = gammaTable;
57    }
58
59    void setFont(SkPaint* paint, const mat4& matrix);
60
61    void precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix);
62
63    // bounds is an out parameter
64    bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
65            uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds);
66    // bounds is an out parameter
67    bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
68            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds);
69
70    struct DropShadow {
71        DropShadow() { };
72
73        DropShadow(const DropShadow& dropShadow):
74            width(dropShadow.width), height(dropShadow.height),
75            image(dropShadow.image), penX(dropShadow.penX),
76            penY(dropShadow.penY) {
77        }
78
79        uint32_t width;
80        uint32_t height;
81        uint8_t* image;
82        int32_t penX;
83        int32_t penY;
84    };
85
86    // After renderDropShadow returns, the called owns the memory in DropShadow.image
87    // and is responsible for releasing it when it's done with it
88    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
89            uint32_t len, int numGlyphs, uint32_t radius, const float* positions);
90
91    GLuint getTexture(bool linearFiltering = false) {
92        checkInit();
93
94        mCurrentCacheTexture->setLinearFiltering(linearFiltering);
95        mLinearFiltering = linearFiltering;
96
97        return mCurrentCacheTexture->getTextureId();
98    }
99
100    uint32_t getCacheSize() const {
101        uint32_t size = 0;
102        for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
103            CacheTexture* cacheTexture = mCacheTextures[i];
104            if (cacheTexture && cacheTexture->getTexture()) {
105                size += cacheTexture->getWidth() * cacheTexture->getHeight();
106            }
107        }
108        return size;
109    }
110
111private:
112    friend class Font;
113
114    const uint8_t* mGammaTable;
115
116    void allocateTextureMemory(CacheTexture* cacheTexture);
117    void deallocateTextureMemory(CacheTexture* cacheTexture);
118    void initTextTexture();
119    CacheTexture* createCacheTexture(int width, int height, bool allocate);
120    void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
121            uint32_t *retOriginX, uint32_t *retOriginY, bool precaching);
122    CacheTexture* cacheBitmapInTexture(const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
123
124    void flushAllAndInvalidate();
125    void initVertexArrayBuffers();
126
127    void checkInit();
128    void initRender(const Rect* clip, Rect* bounds);
129    void finishRender();
130
131    void issueDrawCommand();
132    void appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
133            float x2, float y2, float u2, float v2,
134            float x3, float y3, float u3, float v3,
135            float x4, float y4, float u4, float v4, CacheTexture* texture);
136    void appendMeshQuad(float x1, float y1, float u1, float v1,
137            float x2, float y2, float u2, float v2,
138            float x3, float y3, float u3, float v3,
139            float x4, float y4, float u4, float v4, CacheTexture* texture);
140    void appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
141            float x2, float y2, float u2, float v2,
142            float x3, float y3, float u3, float v3,
143            float x4, float y4, float u4, float v4, CacheTexture* texture);
144
145    void removeFont(const Font* font);
146
147    void updateDrawParams();
148    void checkTextureUpdate();
149
150    void setTextureDirty() {
151        mUploadTexture = true;
152    }
153
154    uint32_t mSmallCacheWidth;
155    uint32_t mSmallCacheHeight;
156    uint32_t mLargeCacheWidth;
157    uint32_t mLargeCacheHeight;
158
159    Vector<CacheTexture*> mCacheTextures;
160
161    Font* mCurrentFont;
162    LruCache<Font::FontDescription, Font*> mActiveFonts;
163
164    CacheTexture* mCurrentCacheTexture;
165
166    bool mUploadTexture;
167
168    // Pointer to vertex data to speed up frame to frame work
169    float* mTextMesh;
170    uint32_t mCurrentQuadIndex;
171    uint32_t mLastQuadIndex;
172    uint32_t mMaxNumberOfQuads;
173
174    uint32_t mIndexBufferID;
175
176    const Rect* mClip;
177    Rect* mBounds;
178    bool mDrawn;
179
180    bool mInitialized;
181
182    bool mLinearFiltering;
183
184    struct TextBatch {
185        TextBatch(): offset(NULL), count(0), texture(NULL) {
186        }
187
188        TextBatch(uint16_t* offset, uint32_t count, CacheTexture* texture):
189                offset(offset), count(count), texture(texture) {
190        }
191
192        static int compare(const TextBatch& lhs, const TextBatch& rhs) {
193            return lhs.texture->getTextureId() - rhs.texture->getTextureId();
194        }
195
196        friend inline int strictly_order_type(const TextBatch& lhs, const TextBatch& rhs) {
197            return compare(lhs, rhs) < 0;
198        }
199
200        friend inline int compare_type(const TextBatch& lhs, const TextBatch& rhs) {
201            return compare(lhs, rhs);
202        }
203
204        uint16_t* offset;
205        uint32_t count;
206        CacheTexture* texture;
207    };
208
209    SortedList<TextBatch> mDrawBatch;
210
211    // RS constructs
212    sp<RSC::RS> mRs;
213    sp<const RSC::Element> mRsElement;
214    sp<RSC::ScriptIntrinsicBlur> mRsScript;
215
216    static void computeGaussianWeights(float* weights, int32_t radius);
217    static void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
218            int32_t width, int32_t height);
219    static void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
220            int32_t width, int32_t height);
221
222    // the input image handle may have its pointer replaced (to avoid copies)
223    void blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius);
224};
225
226}; // namespace uirenderer
227}; // namespace android
228
229#endif // ANDROID_HWUI_FONT_RENDERER_H
230