diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-07 17:14:40 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-07 17:14:40 +0000 |
commit | 4595426b553c0c721f41aa14d598caa5d9940207 (patch) | |
tree | 0f5d52324d947a15f08fec5ff58d2775f7c28813 /src/core | |
parent | 8f30fb7dfafe9d1954d73458a88d50060085abb2 (diff) |
cache fontmetrics in picture-record
Review URL: https://codereview.appspot.com/6908049
git-svn-id: http://skia.googlecode.com/svn/trunk@6706 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkPictureFlat.cpp | 1 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 29 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 49 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 7 |
4 files changed, 63 insertions, 23 deletions
diff --git a/src/core/SkPictureFlat.cpp b/src/core/SkPictureFlat.cpp index 8f6e0895d7..e104a402bc 100644 --- a/src/core/SkPictureFlat.cpp +++ b/src/core/SkPictureFlat.cpp @@ -120,6 +120,7 @@ SkFlatData* SkFlatData::Create(SkFlatController* controller, const void* obj, SkFlatData* result = (SkFlatData*) controller->allocThrow(allocSize); result->fIndex = index; + result->fTopBot[0] = result->fTopBot[1] = 0; // initial to sentinel values result->fFlatSize = size; // put the serialized contents into the data section of the new allocation diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index a00596fed0..429236150b 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -329,9 +329,34 @@ public: return !memcmp(a.dataToCompare(), b.dataToCompare(), N); } + // returns true if fTopBot[] has been recorded + bool isTopBotValid() const { + return fTopBot[0] < fTopBot[1]; + } + + // Returns fTopBot array, so it can be passed to a routine to compute them. + // For efficiency, we assert that fTopBot have not been recorded yet. + SkScalar* writableTopBot() { + SkASSERT(!this->isTopBotValid()); + return fTopBot; + } + + // return the topbot[] after it has been recorded + const SkScalar* topBot() const { + SkASSERT(this->isTopBotValid()); + return fTopBot; + } + private: + // This is *not* part of the key for search/sort int fIndex; + // Cache of paint's FontMetrics fTop,fBottom + // initialied to [0,0] as a sentinel that they have not been recorded yet + // + // This is *not* part of the key for search/sort + SkScalar fTopBot[2]; + // From here down is the data we look at in the search/sort. We always begin // with the checksum and then length. uint32_t fChecksum; @@ -621,6 +646,10 @@ class SkPaintDictionary : public SkFlatDictionary<SkPaint> { fFlattenProc = &SkFlattenObjectProc<SkPaint>; fUnflattenProc = &SkUnflattenObjectProc<SkPaint>; } + + SkFlatData* writableFlatData(int index) { + return const_cast<SkFlatData*>((*this)[index]); + } }; class SkRegionDictionary : public SkFlatDictionary<SkRegion> { diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 270eee5bd4..b62b5b94da 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -473,19 +473,30 @@ void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, validate(); } -void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, - SkScalar minY, SkScalar maxY) { +// Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been +// tweaked by paint.computeFastBounds(). +// +static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]) { SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); SkRect bounds; // construct a rect so we can see any adjustments from the paint. // we use 0,1 for left,right, just so the rect isn't empty - bounds.set(0, metrics.fTop + minY, - SK_Scalar1, metrics.fBottom + maxY); + bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom); (void)paint.computeFastBounds(bounds, &bounds); - // now record the top and bottom - addScalar(bounds.fTop); - addScalar(bounds.fBottom); + topbot[0] = bounds.fTop; + topbot[1] = bounds.fBottom; +} + +void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, int index, + SkScalar minY, SkScalar maxY) { + SkFlatData* flat = fPaints.writableFlatData(index); + if (!flat->isTopBotValid()) { + computeFontMetricsTopBottom(paint, flat->writableTopBot()); + SkASSERT(flat->isTopBotValid()); + } + addScalar(flat->topBot()[0] + minY); + addScalar(flat->topBot()[1] + maxY); } void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, @@ -493,12 +504,12 @@ void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); addDraw(fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT); - addPaint(paint); + int paintIndex = addPaint(paint); addText(text, byteLength); addScalar(x); addScalar(y); if (fast) { - addFontMetricsTopBottom(paint, y, y); + addFontMetricsTopBottom(paint, paintIndex - 1, y, y); } validate(); } @@ -539,7 +550,7 @@ void SkPictureRecord::drawPosText(const void* text, size_t byteLength, } else { addDraw(DRAW_POS_TEXT); } - addPaint(paint); + int paintIndex = addPaint(paint); addText(text, byteLength); addInt(points); @@ -548,7 +559,7 @@ void SkPictureRecord::drawPosText(const void* text, size_t byteLength, #endif if (canUseDrawH) { if (fast) { - addFontMetricsTopBottom(paint, pos[0].fY, pos[0].fY); + addFontMetricsTopBottom(paint, paintIndex - 1, pos[0].fY, pos[0].fY); } addScalar(pos[0].fY); SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); @@ -558,7 +569,7 @@ void SkPictureRecord::drawPosText(const void* text, size_t byteLength, else { fWriter.writeMul4(pos, points * sizeof(SkPoint)); if (fastBounds) { - addFontMetricsTopBottom(paint, minY, maxY); + addFontMetricsTopBottom(paint, paintIndex - 1, minY, maxY); } } #ifdef SK_DEBUG_SIZE @@ -578,7 +589,7 @@ void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H); - addPaint(paint); + int paintIndex = this->addPaint(paint); addText(text, byteLength); addInt(points); @@ -586,7 +597,7 @@ void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, size_t start = fWriter.size(); #endif if (fast) { - addFontMetricsTopBottom(paint, constY, constY); + addFontMetricsTopBottom(paint, paintIndex - 1, constY, constY); } addScalar(constY); fWriter.writeMul4(xpos, points * sizeof(SkScalar)); @@ -673,12 +684,10 @@ void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) { this->addInt(matrix ? fMatrices.find(*matrix) : 0); } -void SkPictureRecord::addPaint(const SkPaint& paint) { - addPaintPtr(&paint); -} - -void SkPictureRecord::addPaintPtr(const SkPaint* paint) { - this->addInt(paint ? fPaints.find(*paint) : 0); +int SkPictureRecord::addPaintPtr(const SkPaint* paint) { + int index = paint ? fPaints.find(*paint) : 0; + this->addInt(index); + return index; } void SkPictureRecord::addPath(const SkPath& path) { diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index 77e011416f..77a6b04fc7 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -72,7 +72,8 @@ public: virtual void drawData(const void*, size_t) SK_OVERRIDE; virtual bool isDrawingToLayer() const SK_OVERRIDE; - void addFontMetricsTopBottom(const SkPaint& paint, SkScalar minY, SkScalar maxY); + void addFontMetricsTopBottom(const SkPaint& paint, int paintIndex, + SkScalar minY, SkScalar maxY); const SkTDArray<SkPicture* >& getPictureRefs() const { return fPictureRefs; @@ -118,8 +119,8 @@ private: void addBitmap(const SkBitmap& bitmap); void addMatrix(const SkMatrix& matrix); void addMatrixPtr(const SkMatrix* matrix); - void addPaint(const SkPaint& paint); - void addPaintPtr(const SkPaint* paint); + int addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); } + int addPaintPtr(const SkPaint* paint); void addPath(const SkPath& path); void addPicture(SkPicture& picture); void addPoint(const SkPoint& point); |