Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 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 | 8 |
| 9 | 9 |
| 10 #include "GrTextContext.h" | 10 #include "GrTextContext.h" |
| 11 #include "GrAtlas.h" | 11 #include "GrAtlas.h" |
| 12 #include "GrContext.h" | 12 #include "GrContext.h" |
| 13 #include "GrDrawTarget.h" | 13 #include "GrDrawTarget.h" |
| 14 #include "GrFontScaler.h" | 14 #include "GrFontScaler.h" |
| 15 #include "GrIndexBuffer.h" | 15 #include "GrIndexBuffer.h" |
| 16 #include "GrTextStrike.h" | 16 #include "GrTextStrike.h" |
| 17 #include "GrTextStrike_impl.h" | 17 #include "GrTextStrike_impl.h" |
| 18 #include "SkPath.h" | 18 #include "SkPath.h" |
| 19 #include "SkStrokeRec.h" | 19 #include "SkStrokeRec.h" |
| 20 | 20 |
| 21 // glyph rendering shares this stage with edge rendering (kEdgeEffectStage in Gr Context) && SW path | 21 // glyph rendering shares this stage with edge rendering (kEdgeEffectStage in Gr Context) && SW path |
| 22 // rendering (kPathMaskStage in GrSWMaskHelper) | 22 // rendering (kPathMaskStage in GrSWMaskHelper) |
| 23 static const int kGlyphMaskStage = GrPaint::kTotalStages; | 23 static const int kGlyphMaskStage = GrPaint::kTotalStages; |
| 24 static const int kGlyphCoordsAttributeIndex = 1; | 24 static const int kGlyphCoordsAttributeIndex = 1; |
| 25 | 25 |
| 26 void GrTextContext::flushGlyphs() { | 26 void GrTextContext::flushGlyphs() { |
| 27 if (NULL == fDrawTarget) { | 27 if (NULL == fDrawTarget) { |
| 28 return; | 28 return; |
| 29 } | 29 } |
| 30 GrDrawTarget::AutoStateRestore asr(fDrawTarget, GrDrawTarget::kPreserve_ASRI nit); | |
|
bsalomon
2013/06/13 14:20:53
This will be replaced by a lighter weight auto-res
| |
| 30 GrDrawState* drawState = fDrawTarget->drawState(); | 31 GrDrawState* drawState = fDrawTarget->drawState(); |
| 32 drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget()); | |
| 33 | |
| 31 if (fCurrVertex > 0) { | 34 if (fCurrVertex > 0) { |
| 32 // setup our sampler state for our text texture/atlas | 35 // setup our sampler state for our text texture/atlas |
| 33 GrAssert(GrIsALIGN4(fCurrVertex)); | 36 GrAssert(GrIsALIGN4(fCurrVertex)); |
| 34 GrAssert(fCurrTexture); | 37 GrAssert(fCurrTexture); |
| 35 GrTextureParams params(SkShader::kRepeat_TileMode, false); | 38 GrTextureParams params(SkShader::kRepeat_TileMode, false); |
| 36 | 39 |
| 37 // This effect could be stored with one of the cache objects (atlas?) | 40 // This effect could be stored with one of the cache objects (atlas?) |
| 38 drawState->setEffect(kGlyphMaskStage, | 41 drawState->setEffect(kGlyphMaskStage, |
| 39 GrSimpleTextureEffect::CreateWithCustomCoords(fCurr Texture, params), | 42 GrSimpleTextureEffect::CreateWithCustomCoords(fCurr Texture, params), |
| 40 kGlyphCoordsAttributeIndex)->unref(); | 43 kGlyphCoordsAttributeIndex)->unref(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 61 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 64 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
| 62 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, | 65 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
| 63 nGlyphs, | 66 nGlyphs, |
| 64 4, 6); | 67 4, 6); |
| 65 fDrawTarget->resetVertexSource(); | 68 fDrawTarget->resetVertexSource(); |
| 66 fVertices = NULL; | 69 fVertices = NULL; |
| 67 fMaxVertices = 0; | 70 fMaxVertices = 0; |
| 68 fCurrVertex = 0; | 71 fCurrVertex = 0; |
| 69 GrSafeSetNull(fCurrTexture); | 72 GrSafeSetNull(fCurrTexture); |
| 70 } | 73 } |
| 71 drawState->disableStages(); | |
| 72 fDrawTarget = NULL; | |
| 73 } | 74 } |
| 74 | 75 |
| 75 GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint( paint) { | 76 GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint( paint) { |
| 76 fContext = context; | 77 fContext = context; |
| 77 fStrike = NULL; | 78 fStrike = NULL; |
| 78 | 79 |
| 79 fCurrTexture = NULL; | 80 fCurrTexture = NULL; |
| 80 fCurrVertex = 0; | 81 fCurrVertex = 0; |
| 81 | 82 |
| 82 const GrClipData* clipData = context->getClip(); | 83 const GrClipData* clipData = context->getClip(); |
| 83 | 84 |
| 84 GrRect devConservativeBound; | 85 GrRect devConservativeBound; |
| 85 clipData->fClipStack->getConservativeBounds( | 86 clipData->fClipStack->getConservativeBounds( |
| 86 -clipData->fOrigin.fX, | 87 -clipData->fOrigin.fX, |
| 87 -clipData->fOrigin.fY, | 88 -clipData->fOrigin.fY, |
| 88 context->getRenderTarget()->width(), | 89 context->getRenderTarget()->width(), |
| 89 context->getRenderTarget()->height(), | 90 context->getRenderTarget()->height(), |
| 90 &devConservativeBound); | 91 &devConservativeBound); |
| 91 | 92 |
| 92 devConservativeBound.roundOut(&fClipRect); | 93 devConservativeBound.roundOut(&fClipRect); |
| 93 | 94 |
| 94 fAutoMatrix.setIdentity(fContext, &fPaint); | 95 fAutoMatrix.setIdentity(fContext, &fPaint); |
| 95 | 96 |
| 96 fDrawTarget = NULL; | 97 fDrawTarget = fContext->getTextTarget(); |
| 97 | 98 |
| 98 fVertices = NULL; | 99 fVertices = NULL; |
| 99 fMaxVertices = 0; | 100 fMaxVertices = 0; |
| 100 } | 101 } |
| 101 | 102 |
| 102 GrTextContext::~GrTextContext() { | 103 GrTextContext::~GrTextContext() { |
| 103 this->flushGlyphs(); | 104 this->flushGlyphs(); |
| 104 if (fDrawTarget) { | |
| 105 fDrawTarget->drawState()->disableStages(); | |
| 106 } | |
| 107 } | 105 } |
| 108 | 106 |
| 109 void GrTextContext::flush() { | 107 void GrTextContext::flush() { |
| 110 this->flushGlyphs(); | 108 this->flushGlyphs(); |
| 111 } | 109 } |
| 112 | 110 |
| 113 namespace { | 111 namespace { |
| 114 | 112 |
| 115 // position + texture coord | 113 // position + texture coord |
| 116 extern const GrVertexAttrib gTextVertexAttribs[] = { | 114 extern const GrVertexAttrib gTextVertexAttribs[] = { |
| 117 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, | 115 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
| 118 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} | 116 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} |
| 119 }; | 117 }; |
| 120 | 118 |
| 121 }; | 119 }; |
| 122 | 120 |
| 123 void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed, | 121 void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
| 124 GrFixed vx, GrFixed vy, | 122 GrFixed vx, GrFixed vy, |
| 125 GrFontScaler* scaler) { | 123 GrFontScaler* scaler) { |
| 124 if (NULL == fDrawTarget) { | |
| 125 return; | |
| 126 } | |
| 126 if (NULL == fStrike) { | 127 if (NULL == fStrike) { |
| 127 fStrike = fContext->getFontCache()->getStrike(scaler); | 128 fStrike = fContext->getFontCache()->getStrike(scaler); |
| 128 } | 129 } |
| 129 | 130 |
| 130 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 131 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
| 131 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 132 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
| 132 return; | 133 return; |
| 133 } | 134 } |
| 134 | 135 |
| 135 vx += SkIntToFixed(glyph->fBounds.fLeft); | 136 vx += SkIntToFixed(glyph->fBounds.fLeft); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 | 198 |
| 198 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { | 199 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { |
| 199 this->flushGlyphs(); | 200 this->flushGlyphs(); |
| 200 fCurrTexture = texture; | 201 fCurrTexture = texture; |
| 201 fCurrTexture->ref(); | 202 fCurrTexture->ref(); |
| 202 } | 203 } |
| 203 | 204 |
| 204 if (NULL == fVertices) { | 205 if (NULL == fVertices) { |
| 205 // If we need to reserve vertices allow the draw target to suggest | 206 // If we need to reserve vertices allow the draw target to suggest |
| 206 // a number of verts to reserve and whether to perform a flush. | 207 // a number of verts to reserve and whether to perform a flush. |
| 207 fMaxVertices = kMinRequestedVerts; | 208 fMaxVertices = kMinRequestedVerts; |
|
robertphillips
2013/06/13 16:26:08
overlength
| |
| 208 bool flush = false; | 209 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_ARRAY_ COUNT(gTextVertexAttribs)); |
| 209 fDrawTarget = fContext->getTextTarget(fPaint); | 210 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); |
| 210 if (NULL != fDrawTarget) { | |
| 211 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_AR RAY_COUNT(gTextVertexAttribs)); | |
| 212 flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
| 213 } | |
| 214 if (flush) { | 211 if (flush) { |
| 215 this->flushGlyphs(); | 212 this->flushGlyphs(); |
| 216 fContext->flush(); | 213 fContext->flush(); |
| 217 // flushGlyphs() will reset fDrawTarget to NULL. | |
| 218 fDrawTarget = fContext->getTextTarget(fPaint); | |
| 219 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_AR RAY_COUNT(gTextVertexAttribs)); | 214 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_AR RAY_COUNT(gTextVertexAttribs)); |
| 220 } | 215 } |
| 221 fMaxVertices = kDefaultRequestedVerts; | 216 fMaxVertices = kDefaultRequestedVerts; |
| 222 // ignore return, no point in flushing again. | 217 // ignore return, no point in flushing again. |
| 223 fDrawTarget->geometryHints(&fMaxVertices, NULL); | 218 fDrawTarget->geometryHints(&fMaxVertices, NULL); |
| 224 | 219 |
| 225 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); | 220 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); |
| 226 if (fMaxVertices < kMinRequestedVerts) { | 221 if (fMaxVertices < kMinRequestedVerts) { |
| 227 fMaxVertices = kDefaultRequestedVerts; | 222 fMaxVertices = kDefaultRequestedVerts; |
| 228 } else if (fMaxVertices > maxQuadVertices) { | 223 } else if (fMaxVertices > maxQuadVertices) { |
| 229 // don't exceed the limit of the index buffer | 224 // don't exceed the limit of the index buffer |
| 230 fMaxVertices = maxQuadVertices; | 225 fMaxVertices = maxQuadVertices; |
| 231 } | 226 } |
| 232 bool success = fDrawTarget->reserveVertexAndIndexSpace( | 227 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, |
| 233 fMaxVertices, | 228 0, |
| 234 0, | 229 GrTCast<void**>(& fVertices), |
| 235 GrTCast<void**>(&fVertices), | 230 NULL); |
| 236 NULL); | |
| 237 GrAlwaysAssert(success); | 231 GrAlwaysAssert(success); |
| 238 GrAssert(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( )); | 232 GrAssert(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( )); |
| 239 } | 233 } |
| 240 | 234 |
| 241 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX); | 235 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX); |
| 242 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY); | 236 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY); |
| 243 | 237 |
| 244 fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx), | 238 fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx), |
| 245 SkFixedToFloat(vy), | 239 SkFixedToFloat(vy), |
| 246 SkFixedToFloat(vx + width), | 240 SkFixedToFloat(vx + width), |
| 247 SkFixedToFloat(vy + height), | 241 SkFixedToFloat(vy + height), |
| 248 2 * sizeof(SkPoint)); | 242 2 * sizeof(SkPoint)); |
| 249 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)), | 243 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)), |
| 250 SkFixedToFloat(texture->normalizeFixed Y(ty)), | 244 SkFixedToFloat(texture->normalizeFixed Y(ty)), |
| 251 SkFixedToFloat(texture->normalizeFixed X(tx + width)), | 245 SkFixedToFloat(texture->normalizeFixed X(tx + width)), |
| 252 SkFixedToFloat(texture->normalizeFixed Y(ty + height)), | 246 SkFixedToFloat(texture->normalizeFixed Y(ty + height)), |
| 253 2 * sizeof(SkPoint)); | 247 2 * sizeof(SkPoint)); |
| 254 fCurrVertex += 4; | 248 fCurrVertex += 4; |
| 255 } | 249 } |
| OLD | NEW |