blob: 39472bc2e1d044044fd01a2cd4692ae07365ce07 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#ifndef SkGLTextCache_DEFINED
9#define SkGLTextCache_DEFINED
10
11#include "SkGL.h"
12
13class SkGlyph;
14
15class SkGLTextCache {
16public:
17 SkGLTextCache();
18 ~SkGLTextCache();
19
20 /** Delete all of the strikes in the cache. Pass true if the texture IDs are
21 still valid, in which case glDeleteTextures will be called. Pass false
22 if they are invalid (e.g. the gl-context has changed), in which case
23 they will just be abandoned.
24 */
25 void deleteAllStrikes(bool texturesAreValid);
26
27 class Strike {
28 public:
29 int width() const { return fStrikeWidth; }
30 int height() const { return fStrikeHeight; }
31 GLuint texture() const { return fTexName; }
32 int widthShift() const { return fStrikeWidthShift; }
33 int heightShift() const { return fStrikeHeightShift; }
34
35 // call this to force us to ignore the texture name in our destructor
36 // only call it right before our destructor
37 void abandonTexture() { fTexName = 0; }
38
39 private:
40 // if next is non-null, its height must match our height
41 Strike(Strike* next, int width, int height);
42 ~Strike();
43
44 Strike* findGlyph(const SkGlyph&, int* offset);
45 Strike* addGlyphAndBind(const SkGlyph&, const uint8_t*, int* offset);
46
47 enum {
48 kMinStrikeWidth = 1024,
49 kMaxGlyphCount = 256
50 };
51
52 Strike* fNext;
53 GLuint fTexName;
54 uint32_t fGlyphIDArray[kMaxGlyphCount]; // stores glyphIDs
55 uint16_t fGlyphOffsetX[kMaxGlyphCount]; // stores x-offsets
56 uint16_t fGlyphCount;
57 uint16_t fNextFreeOffsetX;
58 uint16_t fStrikeWidth;
59 uint16_t fStrikeHeight;
60 uint8_t fStrikeWidthShift; // pow2(fStrikeWidth)
61 uint8_t fStrikeHeightShift; // pow2(fStrikeHeight)
62
63 friend class SkGLTextCache;
64 };
65
66 /** If found, returns the exact strike containing it (there may be more than
67 one with a given height), and sets offset to the offset for that glyph
68 (if not null). Does NOT bind the texture.
69 If not found, returns null and ignores offset param.
70 */
71 Strike* findGlyph(const SkGlyph&, int* offset);
72
73 /** Adds the specified glyph to this list of strikes, returning the new
74 head of the list. If offset is not null, it is set to the offset
75 for this glyph within the strike. The associated texture is bound
76 to the gl context.
77 */
78 Strike* addGlyphAndBind(const SkGlyph&, const uint8_t image[], int* offset);
79
80private:
81 enum {
82 // greater than this we won't cache
83 kMaxGlyphHeightShift = 9,
84
85 kMaxGlyphHeight = 1 << kMaxGlyphHeightShift,
86 kMaxStrikeListCount = kMaxGlyphHeightShift + 1
87 };
88
89 // heads of the N families, one for each pow2 height
90 Strike* fStrikeList[kMaxStrikeListCount];
91};
92
93#endif