diff --git a/src/gpu/batches/GrAtlasTextBatch.cpp b/src/gpu/batches/GrAtlasTextBatch.cpp index b2251a42a8..ce6b2eae2b 100644 --- a/src/gpu/batches/GrAtlasTextBatch.cpp +++ b/src/gpu/batches/GrAtlasTextBatch.cpp @@ -413,19 +413,6 @@ void GrAtlasTextBatch::onPrepareDraws(Target* target) const { size_t byteCount = info.byteCount(); memcpy(currVertex, blob->fVertices + info.vertexStartIndex(), byteCount); -#ifdef SK_DEBUG - // bounds sanity check - SkRect rect; - rect.setLargestInverted(); - SkPoint* vertex = (SkPoint*) ((char*)blob->fVertices + info.vertexStartIndex()); - rect.growToInclude(vertex, vertexStride, kVerticesPerGlyph * info.glyphCount()); - - if (this->usesDistanceFields()) { - fBatch.fViewMatrix.mapRect(&rect); - } - SkASSERT(fBounds.contains(rect)); -#endif - currVertex += byteCount; } diff --git a/src/gpu/batches/GrAtlasTextBatch.h b/src/gpu/batches/GrAtlasTextBatch.h index 01c5615d50..8f20313378 100644 --- a/src/gpu/batches/GrAtlasTextBatch.h +++ b/src/gpu/batches/GrAtlasTextBatch.h @@ -84,31 +84,14 @@ public: fBatch.fViewMatrix = geo.fBlob->fViewMatrix; // We don't yet position distance field text on the cpu, so we have to map the vertex bounds - // into device space. - // We handle vertex bounds differently for distance field text and bitmap text because - // the vertex bounds of bitmap text are in device space. If we are flushing multiple runs - // from one blob then we are going to pay the price here of mapping the rect for each run. + // into device space const Run& run = geo.fBlob->fRuns[geo.fRun]; - SkRect bounds = run.fSubRunInfo[geo.fSubRun].vertexBounds(); if (run.fSubRunInfo[geo.fSubRun].drawAsDistanceFields()) { - // Distance field text is positioned with the (X,Y) as part of the glyph position, - // and currently the view matrix is applied on the GPU - bounds.offset(geo.fBlob->fX - geo.fBlob->fInitialX, - geo.fBlob->fY - geo.fBlob->fInitialY); + SkRect bounds = run.fVertexBounds; fBatch.fViewMatrix.mapRect(&bounds); this->setBounds(bounds); } else { - // Bitmap text is fully positioned on the CPU - SkMatrix boundsMatrix; - bounds.offset(-geo.fBlob->fInitialX, -geo.fBlob->fInitialY); - boundsMatrix.setConcat(fBatch.fViewMatrix, geo.fBlob->fInitialViewMatrixInverse); - boundsMatrix.mapRect(&bounds); - - // Due to floating point numerical inaccuracies, we have to round out here - SkRect roundedOutBounds; - bounds.roundOut(&roundedOutBounds); - roundedOutBounds.offset(geo.fBlob->fX, geo.fBlob->fY); - this->setBounds(roundedOutBounds); + this->setBounds(run.fVertexBounds); } } diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp index 10fc308ea5..05fb5ad415 100644 --- a/src/gpu/text/GrAtlasTextBlob.cpp +++ b/src/gpu/text/GrAtlasTextBlob.cpp @@ -63,7 +63,7 @@ void GrAtlasTextBlob::appendGlyph(int runIndex, subRun->setMaskFormat(format); - subRun->joinGlyphBounds(positions); + run.fVertexBounds.joinNonEmptyArg(positions); subRun->setColor(color); intptr_t vertex = reinterpret_cast(this->fVertices + subRun->vertexEndIndex()); @@ -219,6 +219,7 @@ bool GrAtlasTextBlob::mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, (*outTransY) = y - fY; } + // If we can reuse the blob, then make sure we update the blob's viewmatrix, and x/y // offsets. Note, we offset the vertex bounds right before flushing fViewMatrix = viewMatrix; @@ -382,6 +383,7 @@ void GrAtlasTextBlob::flushCached(GrContext* context, drawFilter, viewMatrix, clipBounds, x, y); continue; } + fRuns[run].fVertexBounds.offset(transX, transY); this->flushRun(dc, &pipelineBuilder, run, color, transX, transY, skPaint, props, distanceAdjustTable, context->getBatchFontCache()); diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h index af6441e003..1c5ea5e60e 100644 --- a/src/gpu/text/GrAtlasTextBlob.h +++ b/src/gpu/text/GrAtlasTextBlob.h @@ -210,11 +210,13 @@ public: // We use this color vs the SkPaint color because it has the colorfilter applied. void initReusableBlob(GrColor color, const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { fPaintColor = color; - this->setupViewMatrix(viewMatrix, x, y); + fViewMatrix = viewMatrix; + fX = x; + fY = y; } - void initThrowawayBlob(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { - this->setupViewMatrix(viewMatrix, x, y); + void initThrowawayBlob(const SkMatrix& viewMatrix) { + fViewMatrix = viewMatrix; } GrDrawBatch* test_createBatch(int glyphCount, int run, int subRun, @@ -247,20 +249,6 @@ private: SkDrawFilter* drawFilter, const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y); - // This function will only be called when we are regenerating a blob from scratch. We record the - // initial view matrix and initial offsets(x,y), because we record vertex bounds relative to - // these numbers. When blobs are reused with new matrices, we need to return to model space so - // we can update the vertex bounds appropriately. - void setupViewMatrix(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { - fViewMatrix = viewMatrix; - if (!viewMatrix.invert(&fInitialViewMatrixInverse)) { - fInitialViewMatrixInverse = SkMatrix::I(); - SkDebugf("Could not invert viewmatrix\n"); - } - fX = fInitialX = x; - fY = fInitialY = y; - } - /* * Each Run inside of the blob can have its texture coordinates regenerated if required. * To determine if regeneration is necessary, fAtlasGeneration is used. If there have been @@ -288,6 +276,7 @@ private: Run() : fInitialized(false) , fDrawAsPaths(false) { + fVertexBounds.setLargestInverted(); // To ensure we always have one subrun, we push back a fresh run here fSubRunInfo.push_back(); } @@ -301,13 +290,10 @@ private: , fColor(GrColor_ILLEGAL) , fMaskFormat(kA8_GrMaskFormat) , fDrawAsDistanceFields(false) - , fUseLCDText(false) { - fVertexBounds.setLargestInverted(); - } + , fUseLCDText(false) {} SubRunInfo(const SubRunInfo& that) : fBulkUseToken(that.fBulkUseToken) , fStrike(SkSafeRef(that.fStrike.get())) - , fVertexBounds(that.fVertexBounds) , fAtlasGeneration(that.fAtlasGeneration) , fVertexStartIndex(that.fVertexStartIndex) , fVertexEndIndex(that.fVertexEndIndex) @@ -352,11 +338,6 @@ private: fVertexEndIndex = prev.vertexEndIndex(); } - const SkRect& vertexBounds() const { return fVertexBounds; } - void joinGlyphBounds(const SkRect& glyphBounds) { - fVertexBounds.joinNonEmptyArg(glyphBounds); - } - // df properties void setUseLCDText(bool useLCDText) { fUseLCDText = useLCDText; } bool hasUseLCDText() const { return fUseLCDText; } @@ -366,7 +347,6 @@ private: private: GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken; SkAutoTUnref fStrike; - SkRect fVertexBounds; uint64_t fAtlasGeneration; size_t fVertexStartIndex; size_t fVertexEndIndex; @@ -388,6 +368,7 @@ private: } static const int kMinSubRuns = 1; SkAutoTUnref fTypeface; + SkRect fVertexBounds; SkSTArray fSubRunInfo; SkAutoDescriptor fDescriptor; @@ -442,10 +423,7 @@ private: SkTArray fBigGlyphs; Key fKey; SkMatrix fViewMatrix; - SkMatrix fInitialViewMatrixInverse; GrColor fPaintColor; - SkScalar fInitialX; - SkScalar fInitialY; SkScalar fX; SkScalar fY; diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp index d491da901e..e286aa6d0f 100644 --- a/src/gpu/text/GrAtlasTextContext.cpp +++ b/src/gpu/text/GrAtlasTextContext.cpp @@ -281,7 +281,7 @@ GrAtlasTextContext::createDrawTextBlob(const GrPaint& paint, const SkPaint& skPa int glyphCount = skPaint.countText(text, byteLength); GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASize); - blob->initThrowawayBlob(viewMatrix, x, y); + blob->initThrowawayBlob(viewMatrix); if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, fSurfaceProps, *fContext->caps()->shaderCaps())) { @@ -304,7 +304,7 @@ GrAtlasTextContext::createDrawPosTextBlob(const GrPaint& paint, const SkPaint& s int glyphCount = skPaint.countText(text, byteLength); GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASize); - blob->initThrowawayBlob(viewMatrix, offset.x(), offset.y()); + blob->initThrowawayBlob(viewMatrix); if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, fSurfaceProps, *fContext->caps()->shaderCaps())) {