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#pragma once
18
19#include "font/CacheTexture.h"
20#include "font/CachedGlyphInfo.h"
21#include "font/Font.h"
22#include "font/FontUtil.h"
23#ifdef BUGREPORT_FONT_CACHE_USAGE
24#include "font/FontCacheHistoryTracker.h"
25#endif
26
27#include <utils/LruCache.h>
28#include <utils/String8.h>
29#include <utils/StrongPointer.h>
30
31#include <SkPaint.h>
32
33#include <GLES2/gl2.h>
34
35#include <vector>
36
37#include "RenderScript.h"
38namespace RSC {
39class Element;
40class RS;
41class ScriptIntrinsicBlur;
42class sp;
43}
44
45namespace android {
46namespace uirenderer {
47
48class BakedOpState;
49class BakedOpRenderer;
50struct ClipBase;
51
52class TextDrawFunctor {
53public:
54    TextDrawFunctor(BakedOpRenderer* renderer, const BakedOpState* bakedState, const ClipBase* clip,
55                    float x, float y, bool pureTranslate, int alpha, SkBlendMode mode,
56                    const SkPaint* paint)
57            : renderer(renderer)
58            , bakedState(bakedState)
59            , clip(clip)
60            , x(x)
61            , y(y)
62            , pureTranslate(pureTranslate)
63            , alpha(alpha)
64            , mode(mode)
65            , paint(paint) {}
66
67    void draw(CacheTexture& texture, bool linearFiltering);
68
69    BakedOpRenderer* renderer;
70    const BakedOpState* bakedState;
71    const ClipBase* clip;
72    float x;
73    float y;
74    bool pureTranslate;
75    int alpha;
76    SkBlendMode mode;
77    const SkPaint* paint;
78};
79
80class FontRenderer {
81public:
82    explicit FontRenderer(const uint8_t* gammaTable);
83    ~FontRenderer();
84
85    void flushLargeCaches(std::vector<CacheTexture*>& cacheTextures);
86    void flushLargeCaches();
87
88    void setFont(const SkPaint* paint, const SkMatrix& matrix);
89
90    void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
91                  const SkMatrix& matrix);
92    void endPrecaching();
93
94    bool renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs, int numGlyphs,
95                       int x, int y, const float* positions, Rect* outBounds,
96                       TextDrawFunctor* functor, bool forceFinish = true);
97
98    bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
99                          int numGlyphs, const SkPath* path, float hOffset, float vOffset,
100                          Rect* outBounds, TextDrawFunctor* functor);
101
102    struct DropShadow {
103        uint32_t width;
104        uint32_t height;
105        uint8_t* image;
106        int32_t penX;
107        int32_t penY;
108    };
109
110    // After renderDropShadow returns, the called owns the memory in DropShadow.image
111    // and is responsible for releasing it when it's done with it
112    DropShadow renderDropShadow(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
113                                float radius, const float* positions);
114
115    void setTextureFiltering(bool linearFiltering) { mLinearFiltering = linearFiltering; }
116
117    uint32_t getSize() const;
118    void dumpMemoryUsage(String8& log) const;
119
120#ifdef BUGREPORT_FONT_CACHE_USAGE
121    FontCacheHistoryTracker& historyTracker() { return mHistoryTracker; }
122#endif
123
124private:
125    friend class Font;
126
127    const uint8_t* mGammaTable;
128
129    void allocateTextureMemory(CacheTexture* cacheTexture);
130    void deallocateTextureMemory(CacheTexture* cacheTexture);
131    void initTextTexture();
132    CacheTexture* createCacheTexture(int width, int height, GLenum format, bool allocate);
133    void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph, uint32_t* retOriginX,
134                     uint32_t* retOriginY, bool precaching);
135    CacheTexture* cacheBitmapInTexture(std::vector<CacheTexture*>& cacheTextures,
136                                       const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
137
138    void flushAllAndInvalidate();
139
140    void checkInit();
141    void initRender(const Rect* clip, Rect* bounds, TextDrawFunctor* functor);
142    void finishRender();
143
144    void issueDrawCommand(std::vector<CacheTexture*>& cacheTextures);
145    void issueDrawCommand();
146    void appendMeshQuadNoClip(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
147                              float v2, float x3, float y3, float u3, float v3, float x4, float y4,
148                              float u4, float v4, CacheTexture* texture);
149    void appendMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
150                        float v2, float x3, float y3, float u3, float v3, float x4, float y4,
151                        float u4, float v4, CacheTexture* texture);
152    void appendRotatedMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
153                               float v2, float x3, float y3, float u3, float v3, float x4, float y4,
154                               float u4, float v4, CacheTexture* texture);
155
156    void checkTextureUpdate();
157
158    void setTextureDirty() { mUploadTexture = true; }
159
160    const std::vector<CacheTexture*>& cacheTexturesForFormat(GLenum format) const;
161    uint32_t getCacheSize(GLenum format) const;
162    uint32_t getFreeCacheSize(GLenum format) const;
163
164    uint32_t mSmallCacheWidth;
165    uint32_t mSmallCacheHeight;
166    uint32_t mLargeCacheWidth;
167    uint32_t mLargeCacheHeight;
168
169    std::vector<CacheTexture*> mACacheTextures;
170    std::vector<CacheTexture*> mRGBACacheTextures;
171
172    Font* mCurrentFont;
173    LruCache<Font::FontDescription, Font*> mActiveFonts;
174
175    CacheTexture* mCurrentCacheTexture;
176
177    bool mUploadTexture;
178
179    TextDrawFunctor* mFunctor;
180    const Rect* mClip;
181    Rect* mBounds;
182    bool mDrawn;
183
184    bool mInitialized;
185
186    bool mLinearFiltering;
187
188#ifdef BUGREPORT_FONT_CACHE_USAGE
189    FontCacheHistoryTracker mHistoryTracker;
190#endif
191
192    // RS constructs
193    RSC::sp<RSC::RS> mRs;
194    RSC::sp<const RSC::Element> mRsElement;
195    RSC::sp<RSC::ScriptIntrinsicBlur> mRsScript;
196
197    static void computeGaussianWeights(float* weights, int32_t radius);
198    static void horizontalBlur(float* weights, int32_t radius, const uint8_t* source, uint8_t* dest,
199                               int32_t width, int32_t height);
200    static void verticalBlur(float* weights, int32_t radius, const uint8_t* source, uint8_t* dest,
201                             int32_t width, int32_t height);
202
203    // the input image handle may have its pointer replaced (to avoid copies)
204    void blurImage(uint8_t** image, int32_t width, int32_t height, float radius);
205};
206
207};  // namespace uirenderer
208};  // namespace android
209