| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef GrAtlasTextContext_DEFINED | 8 #ifndef GrAtlasTextContext_DEFINED |
| 9 #define GrAtlasTextContext_DEFINED | 9 #define GrAtlasTextContext_DEFINED |
| 10 | 10 |
| 11 #include "GrTextContext.h" | 11 #include "GrTextContext.h" |
| 12 | 12 |
| 13 #include "GrGeometryProcessor.h" | 13 #include "GrGeometryProcessor.h" |
| 14 #include "SkDescriptor.h" | 14 #include "SkDescriptor.h" |
| 15 #include "SkTextBlob.h" |
| 15 #include "SkTHash.h" | 16 #include "SkTHash.h" |
| 16 | 17 |
| 17 class GrBatchTextStrike; | 18 class GrBatchTextStrike; |
| 18 class GrPipelineBuilder; | 19 class GrPipelineBuilder; |
| 19 | 20 |
| 20 /* | 21 /* |
| 21 * This class implements GrTextContext using standard bitmap fonts, and can also
process textblobs. | 22 * This class implements GrTextContext using standard bitmap fonts, and can also
process textblobs. |
| 22 * TODO replace GrBitmapTextContext | 23 * TODO replace GrBitmapTextContext |
| 23 */ | 24 */ |
| 24 class GrAtlasTextContext : public GrTextContext { | 25 class GrAtlasTextContext : public GrTextContext { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 38 SkScalar x, SkScalar y, const SkIRect& regionClipBounds) ove
rride; | 39 SkScalar x, SkScalar y, const SkIRect& regionClipBounds) ove
rride; |
| 39 void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkP
aint&, | 40 void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkP
aint&, |
| 40 const SkMatrix& viewMatrix, | 41 const SkMatrix& viewMatrix, |
| 41 const char text[], size_t byteLength, | 42 const char text[], size_t byteLength, |
| 42 const SkScalar pos[], int scalarsPerPosition, | 43 const SkScalar pos[], int scalarsPerPosition, |
| 43 const SkPoint& offset, const SkIRect& regionClipBounds) o
verride; | 44 const SkPoint& offset, const SkIRect& regionClipBounds) o
verride; |
| 44 void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&, | 45 void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&, |
| 45 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x,
SkScalar y, | 46 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x,
SkScalar y, |
| 46 SkDrawFilter*, const SkIRect& clipBounds) override; | 47 SkDrawFilter*, const SkIRect& clipBounds) override; |
| 47 | 48 |
| 48 void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, | |
| 49 const SkIRect& regionClipBounds); | |
| 50 | |
| 51 /* | 49 /* |
| 52 * A BitmapTextBlob contains a fully processed SkTextBlob, suitable for near
ly immediate drawing | 50 * A BitmapTextBlob contains a fully processed SkTextBlob, suitable for near
ly immediate drawing |
| 53 * on the GPU. These are initially created with valid positions and colors,
but invalid | 51 * on the GPU. These are initially created with valid positions and colors,
but invalid |
| 54 * texture coordinates. The BitmapTextBlob itself has a few Blob-wide prope
rties, and also | 52 * texture coordinates. The BitmapTextBlob itself has a few Blob-wide prope
rties, and also |
| 55 * consists of a number of runs. Runs inside a blob are flushed individuall
y so they can be | 53 * consists of a number of runs. Runs inside a blob are flushed individuall
y so they can be |
| 56 * reordered. | 54 * reordered. |
| 57 * | 55 * |
| 58 * The only thing(aside from a memcopy) required to flush a BitmapTextBlob i
s to ensure that | 56 * The only thing(aside from a memcopy) required to flush a BitmapTextBlob i
s to ensure that |
| 59 * the GrAtlas will not evict anything the Blob needs. | 57 * the GrAtlas will not evict anything the Blob needs. |
| 60 * TODO this is currently a bug | 58 * TODO this is currently a bug |
| 61 */ | 59 */ |
| 62 struct BitmapTextBlob : public SkRefCnt { | 60 struct BitmapTextBlob : public SkRefCnt { |
| 63 // Each Run inside of the blob can have its texture coordinates regenera
ted if required. | 61 /* |
| 64 // To determine if regeneration is necessary, fAtlasGeneration is used.
If there have been | 62 * Each Run inside of the blob can have its texture coordinates regenera
ted if required. |
| 65 // any evictions inside of the atlas, then we will simply regenerate Run
s. We could track | 63 * To determine if regeneration is necessary, fAtlasGeneration is used.
If there have been |
| 66 // this at a more fine grained level, but its not clear if this is worth
it, as evictions | 64 * any evictions inside of the atlas, then we will simply regenerate Run
s. We could track |
| 67 // should be fairly rare. | 65 * this at a more fine grained level, but its not clear if this is worth
it, as evictions |
| 68 // One additional point, each run can contain glyphs with any of the thr
ee mask formats. | 66 * should be fairly rare. |
| 69 // We call these SubRuns. Because a subrun must be a contiguous range,
we have to create | 67 * |
| 70 // a new subrun each time the mask format changes in a run. In theory,
a run can have as | 68 * One additional point, each run can contain glyphs with any of the thr
ee mask formats. |
| 71 // many SubRuns as it has glyphs, ie if a run alternates between color e
moji and A8. In | 69 * We call these SubRuns. Because a subrun must be a contiguous range,
we have to create |
| 72 // practice, the vast majority of runs have only a single subrun. | 70 * a new subrun each time the mask format changes in a run. In theory,
a run can have as |
| 71 * many SubRuns as it has glyphs, ie if a run alternates between color e
moji and A8. In |
| 72 * practice, the vast majority of runs have only a single subrun. |
| 73 * |
| 74 * Finally, for runs where the entire thing is too large for the GrAtlas
TextContext to |
| 75 * handle, we have a bit to mark the run as flusahable via rendering as
paths. It is worth |
| 76 * pointing. It would be a bit expensive to figure out ahead of time whe
ther or not a run |
| 77 * can flush in this manner, so we always allocate vertices for the run,
regardless of |
| 78 * whether or not it is too large. The benefit of this strategy is that
we can always reuse |
| 79 * a blob allocation regardless of viewmatrix changes. We could store p
ositions for these |
| 80 * glyphs. However, its not clear if this is a win because we'd still h
ave to either go the |
| 81 * glyph cache to get the path at flush time, or hold onto the path in t
he cache, which |
| 82 * would greatly increase the memory of these cached items. |
| 83 */ |
| 73 | 84 |
| 74 struct Run { | 85 struct Run { |
| 75 Run() : fColor(GrColor_ILLEGAL), fInitialized(false) { | 86 Run() : fColor(GrColor_ILLEGAL), fInitialized(false), fDrawAsPaths(f
alse) { |
| 76 fVertexBounds.setLargestInverted(); | 87 fVertexBounds.setLargestInverted(); |
| 77 // We insert the first subrun to gurantee a run always has atlea
st one subrun. | 88 // We insert the first subrun to gurantee a run always has atlea
st one subrun. |
| 78 // We do this to simplify things when we 'hand off' data from on
e subrun to the | 89 // We do this to simplify things when we 'hand off' data from on
e subrun to the |
| 79 // next | 90 // next |
| 80 fSubRunInfo.push_back(); | 91 fSubRunInfo.push_back(); |
| 81 } | 92 } |
| 82 struct SubRunInfo { | 93 struct SubRunInfo { |
| 83 SubRunInfo() | 94 SubRunInfo() |
| 84 : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) | 95 : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) |
| 85 , fGlyphStartIndex(0) | 96 , fGlyphStartIndex(0) |
| 86 , fGlyphEndIndex(0) | 97 , fGlyphEndIndex(0) |
| 87 , fVertexStartIndex(0) | 98 , fVertexStartIndex(0) |
| 88 , fVertexEndIndex(0) {} | 99 , fVertexEndIndex(0) {} |
| 89 GrMaskFormat fMaskFormat; | 100 GrMaskFormat fMaskFormat; |
| 90 uint64_t fAtlasGeneration; | 101 uint64_t fAtlasGeneration; |
| 91 uint32_t fGlyphStartIndex; | 102 uint32_t fGlyphStartIndex; |
| 92 uint32_t fGlyphEndIndex; | 103 uint32_t fGlyphEndIndex; |
| 93 size_t fVertexStartIndex; | 104 size_t fVertexStartIndex; |
| 94 size_t fVertexEndIndex; | 105 size_t fVertexEndIndex; |
| 95 }; | 106 }; |
| 96 SkSTArray<1, SubRunInfo, true> fSubRunInfo; | 107 SkSTArray<1, SubRunInfo, true> fSubRunInfo; |
| 97 SkAutoDescriptor fDescriptor; | 108 SkAutoDescriptor fDescriptor; |
| 98 SkAutoTUnref<SkTypeface> fTypeface; | 109 SkAutoTUnref<SkTypeface> fTypeface; |
| 99 SkRect fVertexBounds; | 110 SkRect fVertexBounds; |
| 100 GrColor fColor; | 111 GrColor fColor; |
| 101 bool fInitialized; | 112 bool fInitialized; |
| 113 bool fDrawAsPaths; |
| 102 }; | 114 }; |
| 103 | 115 |
| 104 struct BigGlyph { | 116 struct BigGlyph { |
| 105 BigGlyph(const SkPath& path, int vx, int vy) : fPath(path), fVx(vx),
fVy(vy) {} | 117 BigGlyph(const SkPath& path, int vx, int vy) : fPath(path), fVx(vx),
fVy(vy) {} |
| 106 SkPath fPath; | 118 SkPath fPath; |
| 107 int fVx; | 119 int fVx; |
| 108 int fVy; | 120 int fVy; |
| 109 }; | 121 }; |
| 110 | 122 |
| 111 SkTArray<BigGlyph> fBigGlyphs; | 123 SkTArray<BigGlyph> fBigGlyphs; |
| 112 SkMatrix fViewMatrix; | 124 SkMatrix fViewMatrix; |
| 113 SkScalar fX; | 125 SkScalar fX; |
| 114 SkScalar fY; | 126 SkScalar fY; |
| 115 SkPaint::Style fStyle; | 127 SkPaint::Style fStyle; |
| 116 uint32_t fRunCount; | 128 int fRunCount; |
| 117 | 129 |
| 118 // all glyph / vertex offsets are into these pools. | 130 // all glyph / vertex offsets are into these pools. |
| 119 unsigned char* fVertices; | 131 unsigned char* fVertices; |
| 120 GrGlyph::PackedID* fGlyphIDs; | 132 GrGlyph::PackedID* fGlyphIDs; |
| 121 Run* fRuns; | 133 Run* fRuns; |
| 122 | 134 |
| 123 static uint32_t Hash(const uint32_t& key) { | 135 static uint32_t Hash(const uint32_t& key) { |
| 124 return SkChecksum::Mix(key); | 136 return SkChecksum::Mix(key); |
| 125 } | 137 } |
| 126 | 138 |
| 127 void operator delete(void* p) { sk_free(p); } | 139 void operator delete(void* p) { sk_free(p); } |
| 128 void* operator new(size_t) { | 140 void* operator new(size_t) { |
| 129 SkFAIL("All blobs are created by placement new."); | 141 SkFAIL("All blobs are created by placement new."); |
| 130 return sk_malloc_throw(0); | 142 return sk_malloc_throw(0); |
| 131 } | 143 } |
| 132 | 144 |
| 133 void* operator new(size_t, void* p) { return p; } | 145 void* operator new(size_t, void* p) { return p; } |
| 134 void operator delete(void* target, void* placement) { | 146 void operator delete(void* target, void* placement) { |
| 135 ::operator delete(target, placement); | 147 ::operator delete(target, placement); |
| 136 } | 148 } |
| 137 }; | 149 }; |
| 138 | 150 |
| 139 typedef BitmapTextBlob::Run Run; | 151 typedef BitmapTextBlob::Run Run; |
| 140 typedef Run::SubRunInfo PerSubRunInfo; | 152 typedef Run::SubRunInfo PerSubRunInfo; |
| 141 | 153 |
| 142 BitmapTextBlob* CreateBlob(int glyphCount, int runCount); | 154 BitmapTextBlob* CreateBlob(int glyphCount, int runCount); |
| 143 | 155 |
| 144 void appendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, int left,
int top, | 156 void appendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, int left,
int top, |
| 145 GrColor color, GrFontScaler*, const SkIRect& clipRect); | 157 GrColor color, GrFontScaler*, const SkIRect& clipRect); |
| 146 void flush(GrDrawTarget*, BitmapTextBlob*, GrRenderTarget*, const GrPaint&,
const GrClip&, | 158 |
| 147 const SkMatrix& viewMatrix, int paintAlpha); | 159 inline void flushRunAsPaths(const SkTextBlob::RunIterator&, const SkPaint&,
SkDrawFilter*, |
| 160 const SkMatrix& viewMatrix, const SkIRect& clipB
ounds, SkScalar x, |
| 161 SkScalar y); |
| 162 inline void flushRun(GrDrawTarget*, GrPipelineBuilder*, BitmapTextBlob*, int
run, GrColor, |
| 163 uint8_t paintAlpha); |
| 164 inline void flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRenderTarget* rt, |
| 165 const GrPaint& grPaint, const GrClip& clip); |
| 166 |
| 167 // We have to flush SkTextBlobs differently from drawText / drawPosText |
| 168 void flush(GrDrawTarget*, const SkTextBlob*, BitmapTextBlob*, GrRenderTarget
*, const SkPaint&, |
| 169 const GrPaint&, SkDrawFilter*, const GrClip&, const SkMatrix& vie
wMatrix, |
| 170 const SkIRect& clipBounds, SkScalar x, SkScalar y); |
| 171 void flush(GrDrawTarget*, BitmapTextBlob*, GrRenderTarget*, const SkPaint&, |
| 172 const GrPaint&, const GrClip&, const SkMatrix& viewMatrix); |
| 148 | 173 |
| 149 void internalDrawText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const Sk
Paint&, | 174 void internalDrawText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const Sk
Paint&, |
| 150 const SkMatrix& viewMatrix, const char text[], size_t
byteLength, | 175 const SkMatrix& viewMatrix, const char text[], size_t
byteLength, |
| 151 SkScalar x, SkScalar y, const SkIRect& clipRect); | 176 SkScalar x, SkScalar y, const SkIRect& clipRect); |
| 152 void internalDrawPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const
SkPaint&, | 177 void internalDrawPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const
SkPaint&, |
| 153 const SkMatrix& viewMatrix, | 178 const SkMatrix& viewMatrix, |
| 154 const char text[], size_t byteLength, | 179 const char text[], size_t byteLength, |
| 155 const SkScalar pos[], int scalarsPerPosition, | 180 const SkScalar pos[], int scalarsPerPosition, |
| 156 const SkPoint& offset, const SkIRect& clipRect); | 181 const SkPoint& offset, const SkIRect& clipRect); |
| 157 | 182 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 173 // TODO use real cache | 198 // TODO use real cache |
| 174 static void ClearCacheEntry(uint32_t key, BitmapTextBlob**); | 199 static void ClearCacheEntry(uint32_t key, BitmapTextBlob**); |
| 175 SkTHashMap<uint32_t, BitmapTextBlob*, BitmapTextBlob::Hash> fCache; | 200 SkTHashMap<uint32_t, BitmapTextBlob*, BitmapTextBlob::Hash> fCache; |
| 176 | 201 |
| 177 friend class BitmapTextBatch; | 202 friend class BitmapTextBatch; |
| 178 | 203 |
| 179 typedef GrTextContext INHERITED; | 204 typedef GrTextContext INHERITED; |
| 180 }; | 205 }; |
| 181 | 206 |
| 182 #endif | 207 #endif |
| OLD | NEW |