Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 #include "GrBitmapTextContext.h" | 7 #include "GrBitmapTextContext.h" |
| 8 | 8 |
| 9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
| 10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 } | 94 } |
| 95 | 95 |
| 96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const SkPaint& paint, | 96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const SkPaint& paint, |
| 97 const SkMatrix& viewMatrix, SkScala r x, SkScalar y) { | 97 const SkMatrix& viewMatrix, SkScala r x, SkScalar y) { |
| 98 // We always regenerate blobs with patheffects or mask filters we could cach e these | 98 // We always regenerate blobs with patheffects or mask filters we could cach e these |
| 99 // TODO find some way to cache the maskfilter / patheffects on the textblob | 99 // TODO find some way to cache the maskfilter / patheffects on the textblob |
| 100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY != y || | 100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY != y || |
| 101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() ! = blob.fStyle; | 101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() ! = blob.fStyle; |
| 102 } | 102 } |
| 103 | 103 |
| 104 | |
| 105 inline SkGlyphCache* GrBitmapTextContextB::setupCache(BitmapTextBlob::Run* run, | |
| 106 const SkPaint& skPaint, | |
| 107 const SkMatrix& viewMatrix ) { | |
| 108 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v iewMatrix, false); | |
| 109 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | |
| 110 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc()) ; | |
| 111 } | |
| 112 | |
| 113 inline void GrBitmapTextContextB::BlobGlyphCount(int* glyphCount, int* runCount, | |
|
bsalomon
2015/03/31 21:19:10
if this only uses public interfaces on textblob, d
joshualitt
2015/04/01 13:21:18
see comment in header
| |
| 114 const SkTextBlob* blob) { | |
| 115 SkTextBlob::RunIterator itCounter(blob); | |
| 116 for (; !itCounter.done(); itCounter.next(), (*runCount)++) { | |
| 117 *glyphCount += itCounter.glyphCount(); | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 inline GrBitmapTextContextB::BitmapTextBlob* | |
|
bsalomon
2015/03/31 21:19:10
you really think this should be inlined?
joshualitt
2015/04/01 13:21:17
Acknowledged.
| |
| 122 GrBitmapTextContextB::CreateBlob(int glyphCount, int runCount) { | |
| 123 // We allocate size for the BitmapTextBlob itself, plus size for the vertice s array, | |
| 124 // and size for the glyphIds array. | |
| 125 size_t verticesCount = glyphCount * kVerticesPerGlyph * kGrayTextVASize; | |
|
bsalomon
2015/03/31 21:19:10
static assert that kGrayTextVASize is the largest?
joshualitt
2015/04/01 13:21:18
Acknowledged.
| |
| 126 size_t length = sizeof(BitmapTextBlob) + | |
| 127 verticesCount + | |
| 128 glyphCount * sizeof(GrGlyph::PackedID) + | |
| 129 sizeof(BitmapTextBlob::Run) * runCount; | |
| 130 | |
| 131 BitmapTextBlob* cacheBlob = SkNEW_PLACEMENT(sk_malloc_throw(length), BitmapT extBlob); | |
| 132 | |
| 133 // setup offsets for vertices / glyphs | |
| 134 cacheBlob->fVertices = sizeof(BitmapTextBlob) + reinterpret_cast<unsigned ch ar*>(cacheBlob); | |
| 135 cacheBlob->fGlyphIDs = | |
| 136 reinterpret_cast<GrGlyph::PackedID*>(cacheBlob->fVertices + vertices Count); | |
| 137 cacheBlob->fRuns = reinterpret_cast<BitmapTextBlob::Run*>(cacheBlob->fGlyphI Ds + glyphCount); | |
| 138 | |
| 139 // Initialize runs | |
| 140 for (int i = 0; i < runCount; i++) { | |
| 141 SkNEW_PLACEMENT(&cacheBlob->fRuns[i], BitmapTextBlob::Run); | |
| 142 } | |
| 143 cacheBlob->fRunCount = runCount; | |
| 144 return cacheBlob; | |
| 145 } | |
| 146 | |
| 104 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, | 147 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
| 105 const SkPaint& skPaint, const SkMatrix& viewMatrix, | 148 const SkPaint& skPaint, const SkMatrix& viewMatrix, |
| 106 const SkTextBlob* blob, SkScalar x, SkSc alar y, | 149 const SkTextBlob* blob, SkScalar x, SkSc alar y, |
| 107 SkDrawFilter* drawFilter, const SkIRect& clipBounds) { | 150 SkDrawFilter* drawFilter, const SkIRect& clipBounds) { |
| 108 BitmapTextBlob* cacheBlob; | 151 BitmapTextBlob* cacheBlob; |
| 109 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); | 152 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); |
| 110 | |
| 111 SkIRect clipRect; | 153 SkIRect clipRect; |
| 112 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 154 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 113 | 155 |
| 114 if (foundBlob) { | 156 if (foundBlob) { |
| 115 cacheBlob = *foundBlob; | 157 cacheBlob = *foundBlob; |
| 116 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { | 158 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { |
| 117 // We can get away with reusing the blob if there are no outstanding refs on it. | 159 // We have to remake the blob because changes may invalidate our mas ks. |
| 118 // However, we still have to reset all of the runs. | 160 // TODO we could probably get away reuse most of the time if the poi nter is unique, |
| 119 if (!cacheBlob->unique()) { | 161 // but we'd have to clear the subrun information |
| 120 cacheBlob->unref(); | 162 cacheBlob->unref(); |
| 121 cacheBlob = SkNEW(BitmapTextBlob); | 163 int glyphCount = 0; |
| 122 fCache.set(blob->uniqueID(), cacheBlob); | 164 int runCount = 0; |
| 123 } | 165 BlobGlyphCount(&glyphCount, &runCount, blob); |
| 166 cacheBlob = CreateBlob(glyphCount, runCount); | |
| 167 fCache.set(blob->uniqueID(), cacheBlob); | |
| 124 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, | 168 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, |
| 125 clipRect); | 169 clipRect); |
| 126 } | 170 } |
| 127 } else { | 171 } else { |
| 128 cacheBlob = SkNEW(BitmapTextBlob); | 172 int glyphCount = 0; |
| 173 int runCount = 0; | |
| 174 BlobGlyphCount(&glyphCount, &runCount, blob); | |
| 175 cacheBlob = CreateBlob(glyphCount, runCount); | |
| 129 fCache.set(blob->uniqueID(), cacheBlob); | 176 fCache.set(blob->uniqueID(), cacheBlob); |
| 130 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect); | 177 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect); |
| 131 } | 178 } |
| 132 | 179 |
| 133 // Though for the time being runs in the textblob can override the paint, th ey only touch font | 180 // Though for the time being runs in the textblob can override the paint, th ey only touch font |
| 134 // info. | 181 // info. |
| 135 GrPaint grPaint; | 182 GrPaint grPaint; |
| 136 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); | 183 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); |
| 137 | 184 |
| 138 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat rix, | 185 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat rix, |
| 139 fSkPaint.getAlpha()); | 186 fSkPaint.getAlpha()); |
| 140 } | 187 } |
| 141 | 188 |
| 142 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, | 189 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
| 143 const SkPaint& skPaint, const SkMa trix& viewMatrix, | 190 const SkPaint& skPaint, const SkMa trix& viewMatrix, |
| 144 const SkTextBlob* blob, SkScalar x , SkScalar y, | 191 const SkTextBlob* blob, SkScalar x , SkScalar y, |
| 145 SkDrawFilter* drawFilter, const Sk IRect& clipRect) { | 192 SkDrawFilter* drawFilter, const Sk IRect& clipRect) { |
| 146 cacheBlob->fViewMatrix = viewMatrix; | 193 cacheBlob->fViewMatrix = viewMatrix; |
| 147 cacheBlob->fX = x; | 194 cacheBlob->fX = x; |
| 148 cacheBlob->fY = y; | 195 cacheBlob->fY = y; |
| 149 cacheBlob->fStyle = skPaint.getStyle(); | 196 cacheBlob->fStyle = skPaint.getStyle(); |
| 150 cacheBlob->fRuns.reset(blob->fRunCount); | |
| 151 | 197 |
| 152 // Regenerate textblob | 198 // Regenerate textblob |
| 153 SkPaint runPaint = skPaint; | 199 SkPaint runPaint = skPaint; |
| 154 SkTextBlob::RunIterator it(blob); | 200 SkTextBlob::RunIterator it(blob); |
| 155 for (int run = 0; !it.done(); it.next(), run++) { | 201 for (int run = 0; !it.done(); it.next(), run++) { |
| 156 size_t textLen = it.glyphCount() * sizeof(uint16_t); | 202 int glyphCount = it.glyphCount(); |
| 203 size_t textLen = glyphCount * sizeof(uint16_t); | |
| 157 const SkPoint& offset = it.offset(); | 204 const SkPoint& offset = it.offset(); |
| 158 // applyFontToPaint() always overwrites the exact same attributes, | 205 // applyFontToPaint() always overwrites the exact same attributes, |
| 159 // so it is safe to not re-seed the paint for this reason. | 206 // so it is safe to not re-seed the paint for this reason. |
| 160 it.applyFontToPaint(&runPaint); | 207 it.applyFontToPaint(&runPaint); |
| 161 | 208 |
| 162 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) { | 209 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) { |
| 163 // A false return from filter() means we should abort the current dr aw. | 210 // A false return from filter() means we should abort the current dr aw. |
| 164 runPaint = skPaint; | 211 runPaint = skPaint; |
| 165 continue; | 212 continue; |
| 166 } | 213 } |
| 167 | 214 |
| 168 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); | 215 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); |
| 169 | 216 |
| 217 SkGlyphCache* cache = setupCache(&cacheBlob->fRuns[run], runPaint, viewM atrix); | |
|
bsalomon
2015/03/31 21:19:10
this->
joshualitt
2015/04/01 13:21:17
Acknowledged.
| |
| 218 | |
| 219 // setup vertex / glyphIndex for the new run | |
| 220 if (run > 0) { | |
| 221 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); | |
| 222 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( ); | |
| 223 | |
| 224 newRun.fVertexStartIndex = lastRun.fVertexEndIndex; | |
| 225 newRun.fVertexEndIndex = lastRun.fVertexEndIndex; | |
| 226 | |
| 227 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; | |
| 228 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; | |
| 229 } | |
| 230 | |
| 170 switch (it.positioning()) { | 231 switch (it.positioning()) { |
| 171 case SkTextBlob::kDefault_Positioning: | 232 case SkTextBlob::kDefault_Positioning: |
| 172 this->internalDrawText(cacheBlob, run, runPaint, viewMatrix, | 233 this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatr ix, |
| 173 (const char *)it.glyphs(), textLen, | 234 (const char *)it.glyphs(), textLen, |
| 174 x + offset.x(), y + offset.y(), clipRect) ; | 235 x + offset.x(), y + offset.y(), clipRect) ; |
| 175 break; | 236 break; |
| 176 case SkTextBlob::kHorizontal_Positioning: | 237 case SkTextBlob::kHorizontal_Positioning: |
| 177 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, | 238 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM atrix, |
| 178 (const char*)it.glyphs(), textLen, it. pos(), 1, | 239 (const char*)it.glyphs(), textLen, it. pos(), 1, |
| 179 SkPoint::Make(x, y + offset.y()), clip Rect); | 240 SkPoint::Make(x, y + offset.y()), clip Rect); |
| 180 break; | 241 break; |
| 181 case SkTextBlob::kFull_Positioning: | 242 case SkTextBlob::kFull_Positioning: |
| 182 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, | 243 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM atrix, |
| 183 (const char*)it.glyphs(), textLen, it. pos(), 2, | 244 (const char*)it.glyphs(), textLen, it. pos(), 2, |
| 184 SkPoint::Make(x, y), clipRect); | 245 SkPoint::Make(x, y), clipRect); |
| 185 break; | 246 break; |
| 186 } | 247 } |
| 187 | 248 |
| 188 if (drawFilter) { | 249 if (drawFilter) { |
| 189 // A draw filter may change the paint arbitrarily, so we must re-see d in this case. | 250 // A draw filter may change the paint arbitrarily, so we must re-see d in this case. |
| 190 runPaint = skPaint; | 251 runPaint = skPaint; |
| 191 } | 252 } |
| 253 | |
| 254 SkGlyphCache::AttachCache(cache); | |
| 192 } | 255 } |
| 193 } | 256 } |
| 194 | 257 |
| 195 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, | 258 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, |
| 196 const GrPaint& paint, const SkPaint& skPain t, | 259 const GrPaint& paint, const SkPaint& skPain t, |
| 197 const SkMatrix& viewMatrix, | 260 const SkMatrix& viewMatrix, |
| 198 const char text[], size_t byteLength, | 261 const char text[], size_t byteLength, |
| 199 SkScalar x, SkScalar y, const SkIRect& regi onClipBounds) { | 262 SkScalar x, SkScalar y, const SkIRect& regi onClipBounds) { |
| 200 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); | 263 int glyphCount = skPaint.countText(text, byteLength); |
| 264 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); | |
| 201 blob->fViewMatrix = viewMatrix; | 265 blob->fViewMatrix = viewMatrix; |
| 202 blob->fX = x; | 266 blob->fX = x; |
| 203 blob->fY = y; | 267 blob->fY = y; |
| 204 blob->fStyle = skPaint.getStyle(); | 268 blob->fStyle = skPaint.getStyle(); |
| 205 blob->fRuns.push_back(); | |
| 206 | 269 |
| 207 SkIRect clipRect; | 270 SkIRect clipRect; |
| 208 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 271 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 209 this->internalDrawText(blob, 0, skPaint, viewMatrix, text, byteLength, x, y, clipRect); | 272 |
| 273 // setup cache | |
| 274 SkGlyphCache* cache = setupCache(&blob->fRuns[0], skPaint, viewMatrix); | |
|
bsalomon
2015/03/31 21:19:10
this->
joshualitt
2015/04/01 13:21:17
Acknowledged.
| |
| 275 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength , x, y, clipRect); | |
| 276 SkGlyphCache::AttachCache(cache); | |
| 277 | |
| 210 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk Paint.getAlpha()); | 278 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk Paint.getAlpha()); |
| 211 } | 279 } |
| 212 | 280 |
| 213 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, | 281 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, |
| 214 const SkPaint& skPaint, | 282 SkGlyphCache* cache, const SkPaint& skPaint, |
| 215 const SkMatrix& viewMatrix, | 283 const SkMatrix& viewMatrix, |
| 216 const char text[], size_t byteLength, | 284 const char text[], size_t byteLength, |
| 217 SkScalar x, SkScalar y, const SkIRect & clipRect) { | 285 SkScalar x, SkScalar y, const SkIRect & clipRect) { |
| 218 SkASSERT(byteLength == 0 || text != NULL); | 286 SkASSERT(byteLength == 0 || text != NULL); |
| 219 | 287 |
| 220 // nothing to draw | 288 // nothing to draw |
| 221 if (text == NULL || byteLength == 0) { | 289 if (text == NULL || byteLength == 0) { |
| 222 return; | 290 return; |
| 223 } | 291 } |
| 224 | 292 |
| 225 fCurrStrike = NULL; | 293 fCurrStrike = NULL; |
| 226 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); | 294 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
| 227 | 295 |
| 228 // Get GrFontScaler from cache | 296 // Get GrFontScaler from cache |
| 229 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
| 230 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix, | |
| 231 false)); | |
| 232 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | |
| 233 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri ptor->data()); | |
| 234 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | |
| 235 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 297 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 236 | 298 |
| 237 // transform our starting point | 299 // transform our starting point |
| 238 { | 300 { |
| 239 SkPoint loc; | 301 SkPoint loc; |
| 240 viewMatrix.mapXY(x, y, &loc); | 302 viewMatrix.mapXY(x, y, &loc); |
| 241 x = loc.fX; | 303 x = loc.fX; |
| 242 y = loc.fY; | 304 y = loc.fY; |
| 243 } | 305 } |
| 244 | 306 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 GrGlyph::kCoverage_MaskStyle), | 358 GrGlyph::kCoverage_MaskStyle), |
| 297 Sk48Dot16FloorToInt(fx), | 359 Sk48Dot16FloorToInt(fx), |
| 298 Sk48Dot16FloorToInt(fy), | 360 Sk48Dot16FloorToInt(fy), |
| 299 fontScaler, | 361 fontScaler, |
| 300 clipRect); | 362 clipRect); |
| 301 } | 363 } |
| 302 | 364 |
| 303 fx += glyph.fAdvanceX; | 365 fx += glyph.fAdvanceX; |
| 304 fy += glyph.fAdvanceY; | 366 fy += glyph.fAdvanceY; |
| 305 } | 367 } |
| 306 | |
| 307 SkGlyphCache::AttachCache(cache); | |
| 308 } | 368 } |
| 309 | 369 |
| 310 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, | 370 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
| 311 const GrPaint& paint, const SkPaint& skP aint, | 371 const GrPaint& paint, const SkPaint& skP aint, |
| 312 const SkMatrix& viewMatrix, | 372 const SkMatrix& viewMatrix, |
| 313 const char text[], size_t byteLength, | 373 const char text[], size_t byteLength, |
| 314 const SkScalar pos[], int scalarsPerPosi tion, | 374 const SkScalar pos[], int scalarsPerPosi tion, |
| 315 const SkPoint& offset, const SkIRect& re gionClipBounds) { | 375 const SkPoint& offset, const SkIRect& re gionClipBounds) { |
| 316 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); | 376 int glyphCount = skPaint.countText(text, byteLength); |
| 377 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); | |
| 317 blob->fStyle = skPaint.getStyle(); | 378 blob->fStyle = skPaint.getStyle(); |
| 318 blob->fRuns.push_back(); | |
| 319 blob->fViewMatrix = viewMatrix; | 379 blob->fViewMatrix = viewMatrix; |
| 320 | 380 |
| 321 SkIRect clipRect; | 381 SkIRect clipRect; |
| 322 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 382 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 323 this->internalDrawPosText(blob, 0, skPaint, viewMatrix, text, byteLength, po s, | 383 |
| 384 // setup cache | |
| 385 SkGlyphCache* cache = setupCache(&blob->fRuns[0], skPaint, viewMatrix); | |
|
bsalomon
2015/03/31 21:19:10
this->
joshualitt
2015/04/01 13:21:18
Acknowledged.
| |
| 386 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen gth, pos, | |
| 324 scalarsPerPosition, offset, clipRect); | 387 scalarsPerPosition, offset, clipRect); |
| 388 SkGlyphCache::AttachCache(cache); | |
| 389 | |
| 325 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS kPaint.getAlpha()); | 390 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS kPaint.getAlpha()); |
| 326 } | 391 } |
| 327 | 392 |
| 328 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde x, | 393 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde x, |
| 329 const SkPaint& skPaint, | 394 SkGlyphCache* cache, const SkPain t& skPaint, |
| 330 const SkMatrix& viewMatrix, | 395 const SkMatrix& viewMatrix, |
| 331 const char text[], size_t byteLeng th, | 396 const char text[], size_t byteLeng th, |
| 332 const SkScalar pos[], int scalarsP erPosition, | 397 const SkScalar pos[], int scalarsP erPosition, |
| 333 const SkPoint& offset, const SkIRe ct& clipRect) { | 398 const SkPoint& offset, const SkIRe ct& clipRect) { |
| 334 SkASSERT(byteLength == 0 || text != NULL); | 399 SkASSERT(byteLength == 0 || text != NULL); |
| 335 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 400 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
| 336 | 401 |
| 337 // nothing to draw | 402 // nothing to draw |
| 338 if (text == NULL || byteLength == 0) { | 403 if (text == NULL || byteLength == 0) { |
| 339 return; | 404 return; |
| 340 } | 405 } |
| 341 | 406 |
| 342 fCurrStrike = NULL; | 407 fCurrStrike = NULL; |
| 343 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); | 408 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
| 344 | 409 |
| 345 // Get GrFontScaler from cache | 410 // Get GrFontScaler from cache |
| 346 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
| 347 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix, | |
| 348 false)); | |
| 349 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | |
| 350 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri ptor->data()); | |
| 351 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | |
| 352 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 411 GrFontScaler* fontScaler = GetGrFontScaler(cache); |
| 353 | 412 |
| 354 const char* stop = text + byteLength; | 413 const char* stop = text + byteLength; |
| 355 SkTextAlignProc alignProc(skPaint.getTextAlign()); | 414 SkTextAlignProc alignProc(skPaint.getTextAlign()); |
| 356 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); | 415 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); |
| 357 SkScalar halfSampleX = 0, halfSampleY = 0; | 416 SkScalar halfSampleX = 0, halfSampleY = 0; |
| 358 | 417 |
| 359 if (cache->isSubpixel()) { | 418 if (cache->isSubpixel()) { |
| 360 // maybe we should skip the rounding if linearText is set | 419 // maybe we should skip the rounding if linearText is set |
| 361 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); | 420 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 GrGlyph::kCoverage_MaskStyle ), | 539 GrGlyph::kCoverage_MaskStyle ), |
| 481 Sk48Dot16FloorToInt(fx), | 540 Sk48Dot16FloorToInt(fx), |
| 482 Sk48Dot16FloorToInt(fy), | 541 Sk48Dot16FloorToInt(fy), |
| 483 fontScaler, | 542 fontScaler, |
| 484 clipRect); | 543 clipRect); |
| 485 } | 544 } |
| 486 pos += scalarsPerPosition; | 545 pos += scalarsPerPosition; |
| 487 } | 546 } |
| 488 } | 547 } |
| 489 } | 548 } |
| 490 SkGlyphCache::AttachCache(cache); | |
| 491 } | 549 } |
| 492 | 550 |
| 493 static size_t get_vertex_stride(GrMaskFormat maskFormat) { | 551 static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
| 494 switch (maskFormat) { | 552 switch (maskFormat) { |
| 495 case kA8_GrMaskFormat: | 553 case kA8_GrMaskFormat: |
| 496 return kGrayTextVASize; | 554 return kGrayTextVASize; |
| 497 case kARGB_GrMaskFormat: | 555 case kARGB_GrMaskFormat: |
| 498 return kColorTextVASize; | 556 return kColorTextVASize; |
| 499 default: | 557 default: |
| 500 return kLCDTextVASize; | 558 return kLCDTextVASize; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 // flag the glyph as being dead? | 591 // flag the glyph as being dead? |
| 534 SkDELETE(path); | 592 SkDELETE(path); |
| 535 return; | 593 return; |
| 536 } | 594 } |
| 537 glyph->fPath = path; | 595 glyph->fPath = path; |
| 538 } | 596 } |
| 539 SkASSERT(glyph->fPath); | 597 SkASSERT(glyph->fPath); |
| 540 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v y)); | 598 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v y)); |
| 541 return; | 599 return; |
| 542 } | 600 } |
| 601 | |
| 602 Run& run = blob->fRuns[runIndex]; | |
| 603 | |
| 543 GrMaskFormat format = glyph->fMaskFormat; | 604 GrMaskFormat format = glyph->fMaskFormat; |
| 605 | |
| 606 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); | |
| 607 if (run.fInitialized && subRun->fMaskFormat != format) { | |
| 608 PerSubRunInfo* newSubRun = &run.fSubRunInfo.push_back(); | |
| 609 newSubRun->fGlyphStartIndex = subRun->fGlyphEndIndex; | |
| 610 newSubRun->fGlyphEndIndex = subRun->fGlyphEndIndex; | |
| 611 | |
| 612 newSubRun->fVertexStartIndex = subRun->fVertexEndIndex; | |
| 613 newSubRun->fVertexEndIndex = subRun->fVertexEndIndex; | |
| 614 | |
| 615 subRun = newSubRun; | |
| 616 } | |
| 617 | |
| 618 run.fInitialized = true; | |
| 619 subRun->fMaskFormat = format; | |
| 620 blob->fGlyphIDs[subRun->fGlyphEndIndex] = packed; | |
| 621 | |
| 544 size_t vertexStride = get_vertex_stride(format); | 622 size_t vertexStride = get_vertex_stride(format); |
| 545 | 623 |
| 546 BitmapTextBlob::Run& run = blob->fRuns[runIndex]; | |
| 547 int glyphIdx = run.fInfos[format].fGlyphIDs.count(); | |
| 548 *run.fInfos[format].fGlyphIDs.append() = packed; | |
| 549 run.fInfos[format].fVertices.append(static_cast<int>(vertexStride * kVertice sPerGlyph)); | |
| 550 | |
| 551 SkRect r; | 624 SkRect r; |
| 552 r.fLeft = SkIntToScalar(x); | 625 r.fLeft = SkIntToScalar(x); |
| 553 r.fTop = SkIntToScalar(y); | 626 r.fTop = SkIntToScalar(y); |
| 554 r.fRight = r.fLeft + SkIntToScalar(width); | 627 r.fRight = r.fLeft + SkIntToScalar(width); |
| 555 r.fBottom = r.fTop + SkIntToScalar(height); | 628 r.fBottom = r.fTop + SkIntToScalar(height); |
| 556 | 629 |
| 557 run.fVertexBounds.joinNonEmptyArg(r); | 630 run.fVertexBounds.joinNonEmptyArg(r); |
| 558 GrColor color = fPaint.getColor(); | 631 GrColor color = fPaint.getColor(); |
| 559 run.fColor = color; | 632 run.fColor = color; |
| 560 | 633 |
| 561 intptr_t vertex = reinterpret_cast<intptr_t>(run.fInfos[format].fVertices.be gin()); | 634 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVert exEndIndex); |
| 562 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | |
| 563 | 635 |
| 564 // V0 | 636 // V0 |
| 565 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); | 637 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); |
| 566 position->set(r.fLeft, r.fTop); | 638 position->set(r.fLeft, r.fTop); |
| 567 if (kA8_GrMaskFormat == format) { | 639 if (kA8_GrMaskFormat == format) { |
| 568 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; | 640 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; |
| 569 *colorPtr = color; | 641 *colorPtr = color; |
| 570 } | 642 } |
| 571 vertex += vertexStride; | 643 vertex += vertexStride; |
| 572 | 644 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 588 } | 660 } |
| 589 vertex += vertexStride; | 661 vertex += vertexStride; |
| 590 | 662 |
| 591 // V3 | 663 // V3 |
| 592 position = reinterpret_cast<SkPoint*>(vertex); | 664 position = reinterpret_cast<SkPoint*>(vertex); |
| 593 position->set(r.fRight, r.fTop); | 665 position->set(r.fRight, r.fTop); |
| 594 if (kA8_GrMaskFormat == format) { | 666 if (kA8_GrMaskFormat == format) { |
| 595 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; | 667 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; |
| 596 *colorPtr = color; | 668 *colorPtr = color; |
| 597 } | 669 } |
| 670 | |
| 671 subRun->fGlyphEndIndex++; | |
| 672 subRun->fVertexEndIndex += vertexStride * kVerticesPerGlyph; | |
| 598 } | 673 } |
| 599 | 674 |
| 600 class BitmapTextBatch : public GrBatch { | 675 class BitmapTextBatch : public GrBatch { |
| 601 public: | 676 public: |
| 602 typedef GrBitmapTextContextB::BitmapTextBlob Blob; | 677 typedef GrBitmapTextContextB::BitmapTextBlob Blob; |
| 603 typedef Blob::Run Run; | 678 typedef Blob::Run Run; |
| 604 typedef Run::PerFormatInfo TextInfo; | 679 typedef Run::PerSubRunInfo TextInfo; |
| 605 struct Geometry { | 680 struct Geometry { |
| 606 Geometry() {} | 681 Geometry() {} |
| 607 Geometry(const Geometry& geometry) | 682 Geometry(const Geometry& geometry) |
| 608 : fBlob(SkRef(geometry.fBlob.get())) | 683 : fBlob(SkRef(geometry.fBlob.get())) |
| 609 , fRun(geometry.fRun) | 684 , fRun(geometry.fRun) |
| 685 , fSubRun(geometry.fSubRun) | |
| 610 , fColor(geometry.fColor) {} | 686 , fColor(geometry.fColor) {} |
| 611 SkAutoTUnref<Blob> fBlob; | 687 SkAutoTUnref<Blob> fBlob; |
| 612 int fRun; | 688 int fRun; |
| 689 int fSubRun; | |
| 613 GrColor fColor; | 690 GrColor fColor; |
| 614 }; | 691 }; |
| 615 | 692 |
| 616 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat, | 693 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat, |
| 617 GrBatchFontCache* fontCache) { | 694 int glyphCount, GrBatchFontCache* fontCache) { |
| 618 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, fontCac he)); | 695 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, glyphCo unt, fontCache)); |
| 619 } | 696 } |
| 620 | 697 |
| 621 const char* name() const override { return "BitmapTextBatch"; } | 698 const char* name() const override { return "BitmapTextBatch"; } |
| 622 | 699 |
| 623 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 700 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 624 if (kARGB_GrMaskFormat == fMaskFormat) { | 701 if (kARGB_GrMaskFormat == fMaskFormat) { |
| 625 out->setUnknownFourComponents(); | 702 out->setUnknownFourComponents(); |
| 626 } else { | 703 } else { |
| 627 out->setKnownFourComponents(fBatch.fColor); | 704 out->setKnownFourComponents(fBatch.fColor); |
| 628 } | 705 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); | 788 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); |
| 712 drawInfo.adjustStartVertex(firstVertex); | 789 drawInfo.adjustStartVertex(firstVertex); |
| 713 drawInfo.setVertexBuffer(vertexBuffer); | 790 drawInfo.setVertexBuffer(vertexBuffer); |
| 714 drawInfo.setIndexBuffer(quadIndexBuffer); | 791 drawInfo.setIndexBuffer(quadIndexBuffer); |
| 715 | 792 |
| 716 int instancesToFlush = 0; | 793 int instancesToFlush = 0; |
| 717 for (int i = 0; i < instanceCount; i++) { | 794 for (int i = 0; i < instanceCount; i++) { |
| 718 Geometry& args = fGeoData[i]; | 795 Geometry& args = fGeoData[i]; |
| 719 Blob* blob = args.fBlob; | 796 Blob* blob = args.fBlob; |
| 720 Run& run = blob->fRuns[args.fRun]; | 797 Run& run = blob->fRuns[args.fRun]; |
| 721 TextInfo& info = run.fInfos[fMaskFormat]; | 798 TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
| 722 | 799 |
| 723 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); | 800 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); |
| 724 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen; | 801 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen; |
| 725 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo r != args.fColor; | 802 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo r != args.fColor; |
| 726 int glyphCount = info.fGlyphIDs.count(); | 803 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
| 727 | 804 |
| 728 // We regenerate both texture coords and colors in the blob itself, and update the | 805 // We regenerate both texture coords and colors in the blob itself, and update the |
| 729 // atlas generation. If we don't end up purging any unused plots, w e can avoid | 806 // atlas generation. If we don't end up purging any unused plots, w e can avoid |
| 730 // regenerating the coords. We could take a finer grained approach to updating texture | 807 // regenerating the coords. We could take a finer grained approach to updating texture |
| 731 // coords but its not clear if the extra bookkeeping would offset an y gains. | 808 // coords but its not clear if the extra bookkeeping would offset an y gains. |
| 732 // To avoid looping over the glyphs twice, we do one loop and condit ionally update color | 809 // To avoid looping over the glyphs twice, we do one loop and condit ionally update color |
| 733 // or coords as needed. One final note, if we have to break a run f or an atlas eviction | 810 // or coords as needed. One final note, if we have to break a run f or an atlas eviction |
| 734 // then we can't really trust the atlas has all of the correct data. Atlas evictions | 811 // then we can't really trust the atlas has all of the correct data. Atlas evictions |
| 735 // should be pretty rare, so we just always regenerate in those case s | 812 // should be pretty rare, so we just always regenerate in those case s |
| 736 if (regenerateTextureCoords || regenerateColors) { | 813 if (regenerateTextureCoords || regenerateColors) { |
| 737 // first regenerate texture coordinates / colors if need be | 814 // first regenerate texture coordinates / colors if need be |
| 738 const SkDescriptor* desc = NULL; | 815 const SkDescriptor* desc = NULL; |
| 739 SkGlyphCache* cache = NULL; | 816 SkGlyphCache* cache = NULL; |
| 740 GrFontScaler* scaler = NULL; | 817 GrFontScaler* scaler = NULL; |
| 741 GrBatchTextStrike* strike = NULL; | 818 GrBatchTextStrike* strike = NULL; |
| 742 bool brokenRun = false; | 819 bool brokenRun = false; |
| 743 if (regenerateTextureCoords) { | 820 if (regenerateTextureCoords) { |
| 744 desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor ->data()); | 821 desc = run.fDescriptor.getDesc(); |
| 745 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | 822 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); |
| 746 scaler = GrTextContext::GetGrFontScaler(cache); | 823 scaler = GrTextContext::GetGrFontScaler(cache); |
| 747 strike = fFontCache->getStrike(scaler); | 824 strike = fFontCache->getStrike(scaler); |
| 748 } | 825 } |
| 749 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 826 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { |
| 750 GrGlyph::PackedID glyphID = info.fGlyphIDs[glyphIdx]; | 827 GrGlyph::PackedID glyphID = blob->fGlyphIDs[glyphIdx + info. fGlyphStartIndex]; |
| 751 | 828 |
| 752 if (regenerateTextureCoords) { | 829 if (regenerateTextureCoords) { |
| 753 // Upload the glyph only if needed | 830 // Upload the glyph only if needed |
| 754 GrGlyph* glyph = strike->getGlyph(glyphID, scaler); | 831 GrGlyph* glyph = strike->getGlyph(glyphID, scaler); |
| 755 SkASSERT(glyph); | 832 SkASSERT(glyph); |
| 756 | 833 |
| 757 if (!fFontCache->hasGlyph(glyph) && | 834 if (!fFontCache->hasGlyph(glyph) && |
| 758 !strike->addGlyphToAtlas(batchTarget, glyph, scaler) ) { | 835 !strike->addGlyphToAtlas(batchTarget, glyph, scaler) ) { |
| 759 this->flush(batchTarget, &drawInfo, instancesToFlush , | 836 this->flush(batchTarget, &drawInfo, instancesToFlush , |
| 760 maxInstancesPerDraw); | 837 maxInstancesPerDraw); |
| 761 this->initDraw(batchTarget, gp, pipeline); | 838 this->initDraw(batchTarget, gp, pipeline); |
| 762 instancesToFlush = 0; | 839 instancesToFlush = 0; |
| 763 brokenRun = glyphIdx > 0; | 840 brokenRun = glyphIdx > 0; |
| 764 | 841 |
| 765 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas( batchTarget, glyph, | 842 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas( batchTarget, glyph, |
| 766 scaler); | 843 scaler); |
| 767 SkASSERT(success); | 844 SkASSERT(success); |
| 768 } | 845 } |
| 769 | 846 |
| 770 fFontCache->setGlyphRefToken(glyph, batchTarget->current Token()); | 847 fFontCache->setGlyphRefToken(glyph, batchTarget->current Token()); |
| 771 | 848 |
| 772 // Texture coords are the last vertex attribute so we ge t a pointer to the | 849 // Texture coords are the last vertex attribute so we ge t a pointer to the |
| 773 // first one and then map with stride in regenerateTextu reCoords | 850 // first one and then map with stride in regenerateTextu reCoords |
| 774 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti ces.begin()); | 851 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices); |
| 852 vertex += info.fVertexStartIndex; | |
| 775 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | 853 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; |
| 776 vertex += vertexStride - sizeof(SkIPoint16); | 854 vertex += vertexStride - sizeof(SkIPoint16); |
| 777 | 855 |
| 778 this->regenerateTextureCoords(glyph, vertex, vertexStrid e); | 856 this->regenerateTextureCoords(glyph, vertex, vertexStrid e); |
| 779 } | 857 } |
| 780 | 858 |
| 781 if (regenerateColors) { | 859 if (regenerateColors) { |
| 782 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti ces.begin()); | 860 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices); |
| 861 vertex += info.fVertexStartIndex; | |
| 783 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint); | 862 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint); |
| 784 this->regenerateColors(vertex, vertexStride, args.fColor ); | 863 this->regenerateColors(vertex, vertexStride, args.fColor ); |
| 785 } | 864 } |
| 786 | 865 |
| 787 instancesToFlush++; | 866 instancesToFlush++; |
| 788 } | 867 } |
| 789 | 868 |
| 790 if (regenerateTextureCoords) { | 869 if (regenerateTextureCoords) { |
| 791 SkGlyphCache::AttachCache(cache); | 870 SkGlyphCache::AttachCache(cache); |
| 792 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration : | 871 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration : |
| 793 fFontCache->atlasGenerat ion(fMaskFormat); | 872 fFontCache->atlasGenerat ion(fMaskFormat); |
| 794 } | 873 } |
| 795 } else { | 874 } else { |
| 796 instancesToFlush += glyphCount; | 875 instancesToFlush += glyphCount; |
| 797 } | 876 } |
| 798 | 877 |
| 799 // now copy all vertices | 878 // now copy all vertices |
| 800 int byteCount = info.fVertices.count(); | 879 int byteCount = info.fVertexEndIndex - info.fVertexStartIndex; |
| 801 memcpy(currVertex, info.fVertices.begin(), byteCount); | 880 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCou nt); |
| 802 | 881 |
| 803 currVertex += byteCount; | 882 currVertex += byteCount; |
| 804 } | 883 } |
| 805 | 884 |
| 806 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra w); | 885 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra w); |
| 807 } | 886 } |
| 808 | 887 |
| 809 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 888 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 810 | 889 |
| 811 private: | 890 private: |
| 812 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo rmat, | 891 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo rmat, |
| 813 GrBatchFontCache* fontCache) | 892 int glyphCount, GrBatchFontCache* fontCache) |
| 814 : fMaskFormat(maskFormat) | 893 : fMaskFormat(maskFormat) |
| 815 , fPixelConfig(fontCache->getPixelConfig(maskFormat)) | 894 , fPixelConfig(fontCache->getPixelConfig(maskFormat)) |
| 816 , fFontCache(fontCache) { | 895 , fFontCache(fontCache) { |
| 817 this->initClassID<BitmapTextBatch>(); | 896 this->initClassID<BitmapTextBatch>(); |
| 818 fGeoData.push_back(geometry); | 897 fGeoData.push_back(geometry); |
| 819 fBatch.fColor = color; | 898 fBatch.fColor = color; |
| 820 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; | 899 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; |
| 821 int numGlyphs = geometry.fBlob->fRuns[geometry.fRun].fInfos[maskFormat]. fGlyphIDs.count(); | 900 fBatch.fNumGlyphs = glyphCount; |
| 822 fBatch.fNumGlyphs = numGlyphs; | |
| 823 } | 901 } |
| 824 | 902 |
| 825 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS tride) { | 903 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS tride) { |
| 826 int width = glyph->fBounds.width(); | 904 int width = glyph->fBounds.width(); |
| 827 int height = glyph->fBounds.height(); | 905 int height = glyph->fBounds.height(); |
| 828 int u0 = glyph->fAtlasLocation.fX; | 906 int u0 = glyph->fAtlasLocation.fX; |
| 829 int v0 = glyph->fAtlasLocation.fY; | 907 int v0 = glyph->fAtlasLocation.fY; |
| 830 int u1 = u0 + width; | 908 int u1 = u0 + width; |
| 831 int v1 = v0 + height; | 909 int v1 = v0 + height; |
| 832 | 910 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 int fNumGlyphs; | 1003 int fNumGlyphs; |
| 926 }; | 1004 }; |
| 927 | 1005 |
| 928 BatchTracker fBatch; | 1006 BatchTracker fBatch; |
| 929 SkSTArray<1, Geometry, true> fGeoData; | 1007 SkSTArray<1, Geometry, true> fGeoData; |
| 930 GrMaskFormat fMaskFormat; | 1008 GrMaskFormat fMaskFormat; |
| 931 GrPixelConfig fPixelConfig; | 1009 GrPixelConfig fPixelConfig; |
| 932 GrBatchFontCache* fFontCache; | 1010 GrBatchFontCache* fFontCache; |
| 933 }; | 1011 }; |
| 934 | 1012 |
| 935 void GrBitmapTextContextB::flushSubRun(GrDrawTarget* target, BitmapTextBlob* blo b, int i, | |
| 936 GrPipelineBuilder* pipelineBuilder, GrMas kFormat format, | |
| 937 GrColor color, int paintAlpha) { | |
| 938 if (0 == blob->fRuns[i].fInfos[format].fGlyphIDs.count()) { | |
| 939 return; | |
| 940 } | |
| 941 | |
| 942 if (kARGB_GrMaskFormat == format) { | |
| 943 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha); | |
| 944 } | |
| 945 | |
| 946 BitmapTextBatch::Geometry geometry; | |
| 947 geometry.fBlob.reset(SkRef(blob)); | |
| 948 geometry.fRun = i; | |
| 949 geometry.fColor = color; | |
| 950 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format, | |
| 951 fContext->getBatchFontCa che())); | |
| 952 | |
| 953 target->drawBatch(pipelineBuilder, batch, &blob->fRuns[i].fVertexBounds); | |
| 954 } | |
| 955 | |
| 956 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR enderTarget* rt, | 1013 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR enderTarget* rt, |
| 957 const GrPaint& paint, const GrClip& clip, | 1014 const GrPaint& paint, const GrClip& clip, |
| 958 const SkMatrix& viewMatrix, int paintAlpha) { | 1015 const SkMatrix& viewMatrix, int paintAlpha) { |
| 959 GrPipelineBuilder pipelineBuilder; | 1016 GrPipelineBuilder pipelineBuilder; |
| 960 pipelineBuilder.setFromPaint(paint, rt, clip); | 1017 pipelineBuilder.setFromPaint(paint, rt, clip); |
| 961 | 1018 |
| 962 GrColor color = paint.getColor(); | 1019 GrColor color = paint.getColor(); |
| 963 for (int i = 0; i < blob->fRuns.count(); i++) { | 1020 for (uint32_t run = 0; run < blob->fRunCount; run++) { |
| 964 this->flushSubRun(target, blob, i, &pipelineBuilder, kA8_GrMaskFormat, c olor, paintAlpha); | 1021 for (int subRun = 0; subRun < blob->fRuns[run].fSubRunInfo.count(); subR un++) { |
| 965 this->flushSubRun(target, blob, i, &pipelineBuilder, kA565_GrMaskFormat, color, paintAlpha); | 1022 PerSubRunInfo& info = blob->fRuns[run].fSubRunInfo[subRun]; |
| 966 this->flushSubRun(target, blob, i, &pipelineBuilder, kARGB_GrMaskFormat, color, paintAlpha); | 1023 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
| 1024 if (0 == glyphCount) { | |
| 1025 continue; | |
| 1026 } | |
| 1027 | |
| 1028 GrMaskFormat format = info.fMaskFormat; | |
| 1029 if (kARGB_GrMaskFormat == format) { | |
| 1030 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paint Alpha); | |
| 1031 } | |
| 1032 | |
| 1033 BitmapTextBatch::Geometry geometry; | |
| 1034 geometry.fBlob.reset(SkRef(blob)); | |
| 1035 geometry.fRun = run; | |
| 1036 geometry.fSubRun = subRun; | |
| 1037 geometry.fColor = color; | |
| 1038 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format, glyphCount, | |
| 1039 fContext->getBat chFontCache())); | |
| 1040 | |
| 1041 target->drawBatch(&pipelineBuilder, batch, &blob->fRuns[run].fVertex Bounds); | |
| 1042 } | |
| 967 } | 1043 } |
| 968 | 1044 |
| 969 // Now flush big glyphs | 1045 // Now flush big glyphs |
| 970 for (int i = 0; i < blob->fBigGlyphs.count(); i++) { | 1046 for (int i = 0; i < blob->fBigGlyphs.count(); i++) { |
| 971 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i]; | 1047 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i]; |
| 972 SkMatrix translate; | 1048 SkMatrix translate; |
| 973 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly ph.fVy)); | 1049 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly ph.fVy)); |
| 974 SkPath tmpPath(bigGlyph.fPath); | 1050 SkPath tmpPath(bigGlyph.fPath); |
| 975 tmpPath.transform(translate); | 1051 tmpPath.transform(translate); |
| 976 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); | 1052 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1553 SkSafeSetNull(fCurrTexture); | 1629 SkSafeSetNull(fCurrTexture); |
| 1554 } | 1630 } |
| 1555 } | 1631 } |
| 1556 | 1632 |
| 1557 inline void GrBitmapTextContext::finish() { | 1633 inline void GrBitmapTextContext::finish() { |
| 1558 this->flush(); | 1634 this->flush(); |
| 1559 fTotalVertexCount = 0; | 1635 fTotalVertexCount = 0; |
| 1560 | 1636 |
| 1561 GrTextContext::finish(); | 1637 GrTextContext::finish(); |
| 1562 } | 1638 } |
| OLD | NEW |