Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Unified Diff: src/core/SkPictureRecord.cpp

Issue 617953002: Strip old backend recording down to essentials (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: debug-only Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkPictureRecord.h ('k') | src/core/SkPictureRecorder.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkPictureRecord.cpp
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 5b28468898e0438c11b1f5b55d64c8999e136bb3..16cb3b5a1bd0ba755ca7e4c52a4e9cc6382d3f27 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -6,10 +6,8 @@
*/
#include "SkPictureRecord.h"
-#include "SkBBoxHierarchy.h"
#include "SkDevice.h"
#include "SkPatchUtils.h"
-#include "SkPictureStateTree.h"
#include "SkPixelRef.h"
#include "SkRRect.h"
#include "SkTextBlob.h"
@@ -17,15 +15,6 @@
#define HEAP_BLOCK_SIZE 4096
-// If SK_RECORD_LITERAL_PICTURES is defined, record our inputs as literally as possible.
-// Otherwise, we can be clever and record faster equivalents. kBeClever is normally true.
-static const bool kBeClever =
-#ifdef SK_RECORD_LITERAL_PICTURES
- false;
-#else
- true;
-#endif
-
enum {
// just need a value that save or getSaveCount would never return
kNoInitialSave = -1,
@@ -40,12 +29,9 @@ static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect
SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags)
: INHERITED(dimensions.width(), dimensions.height())
- , fBoundingHierarchy(NULL)
- , fStateTree(NULL)
, fFlattenableHeap(HEAP_BLOCK_SIZE)
, fPaints(&fFlattenableHeap)
- , fRecordFlags(flags)
- , fOptsEnabled(kBeClever) {
+ , fRecordFlags(flags) {
fBitmapHeap = SkNEW(SkBitmapHeap);
fFlattenableHeap.setBitmapStorage(fBitmapHeap);
@@ -56,8 +42,6 @@ SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags)
SkPictureRecord::~SkPictureRecord() {
SkSafeUnref(fBitmapHeap);
- SkSafeUnref(fBoundingHierarchy);
- SkSafeUnref(fStateTree);
fFlattenableHeap.setBitmapStorage(NULL);
fPictureRefs.unrefAll();
fTextBlobRefs.unrefAll();
@@ -211,15 +195,7 @@ bool SkPictureRecord::isDrawingToLayer() const {
return fFirstSavedLayerIndex != kNoSavedLayerIndex;
}
-/*
- * Read the op code from 'offset' in 'writer'.
- */
#ifdef SK_DEBUG
-static DrawType peek_op(SkWriter32* writer, size_t offset) {
- return (DrawType)(writer->readTAt<uint32_t>(offset) >> 24);
-}
-#endif
-
/*
* Read the op code from 'offset' in 'writer' and extract the size too.
*/
@@ -234,346 +210,7 @@ static DrawType peek_op_and_size(SkWriter32* writer, size_t offset, uint32_t* si
}
return (DrawType) op;
}
-
-// Is the supplied paint simply a color?
-static bool is_simple(const SkPaint& p) {
- intptr_t orAccum = (intptr_t)p.getPathEffect() |
- (intptr_t)p.getShader() |
- (intptr_t)p.getXfermode() |
- (intptr_t)p.getMaskFilter() |
- (intptr_t)p.getColorFilter() |
- (intptr_t)p.getRasterizer() |
- (intptr_t)p.getLooper() |
- (intptr_t)p.getImageFilter();
- return 0 == orAccum;
-}
-
-// CommandInfos are fed to the 'match' method and filled in with command
-// information.
-struct CommandInfo {
- DrawType fActualOp;
- uint32_t fOffset;
- uint32_t fSize;
-};
-
-/*
- * Attempt to match the provided pattern of commands starting at 'offset'
- * in the byte stream and stopping at the end of the stream. Upon success,
- * return true with all the pattern information filled out in the result
- * array (i.e., actual ops, offsets and sizes).
- * Note this method skips any NOOPs seen in the stream
- */
-static bool match(SkWriter32* writer, uint32_t offset,
- int* pattern, CommandInfo* result, int numCommands) {
- SkASSERT(offset < writer->bytesWritten());
-
- uint32_t curOffset = offset;
- uint32_t curSize = 0;
- int numMatched;
- for (numMatched = 0; numMatched < numCommands && curOffset < writer->bytesWritten(); ++numMatched) {
- DrawType op = peek_op_and_size(writer, curOffset, &curSize);
- while (NOOP == op) {
- curOffset += curSize;
- if (curOffset >= writer->bytesWritten()) {
- return false;
- }
- op = peek_op_and_size(writer, curOffset, &curSize);
- }
-
- if (kDRAW_BITMAP_FLAVOR == pattern[numMatched]) {
- if (DRAW_BITMAP != op && DRAW_BITMAP_MATRIX != op &&
- DRAW_BITMAP_NINE != op && DRAW_BITMAP_RECT_TO_RECT != op) {
- return false;
- }
- } else if (op != pattern[numMatched]) {
- return false;
- }
-
- result[numMatched].fActualOp = op;
- result[numMatched].fOffset = curOffset;
- result[numMatched].fSize = curSize;
-
- curOffset += curSize;
- }
-
- if (numMatched != numCommands) {
- return false;
- }
-
- if (curOffset < writer->bytesWritten()) {
- // Something else between the last command and the end of the stream
- return false;
- }
-
- return true;
-}
-
-// temporarily here to make code review easier
-static bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer,
- SkPaintDictionary* paintDict,
- const CommandInfo& saveLayerInfo,
- const CommandInfo& dbmInfo);
-
-/*
- * Restore has just been called (but not recorded), look back at the
- * matching save* and see if we are in the configuration:
- * SAVE_LAYER
- * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_RECT
- * RESTORE
- * where the saveLayer's color can be moved into the drawBitmap*'s paint
- */
-static bool remove_save_layer1(SkWriter32* writer, int32_t offset,
- SkPaintDictionary* paintDict) {
- // back up to the save block
- // TODO: add a stack to track save*/restore offsets rather than searching backwards
- while (offset > 0) {
- offset = writer->readTAt<uint32_t>(offset);
- }
-
- int pattern[] = { SAVE_LAYER, kDRAW_BITMAP_FLAVOR, /* RESTORE */ };
- CommandInfo result[SK_ARRAY_COUNT(pattern)];
-
- if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) {
- return false;
- }
-
- if (kSaveLayerWithBoundsSize == result[0].fSize) {
- // The saveLayer's bound can offset where the dbm is drawn
- return false;
- }
-
- return merge_savelayer_paint_into_drawbitmp(writer, paintDict,
- result[0], result[1]);
-}
-
-/*
- * Convert the command code located at 'offset' to a NOOP. Leave the size
- * field alone so the NOOP can be skipped later.
- */
-static void convert_command_to_noop(SkWriter32* writer, uint32_t offset) {
- uint32_t command = writer->readTAt<uint32_t>(offset);
- writer->overwriteTAt(offset, (command & MASK_24) | (NOOP << 24));
-}
-
-/*
- * Attempt to merge the saveLayer's paint into the drawBitmap*'s paint.
- * Return true on success; false otherwise.
- */
-static bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer,
- SkPaintDictionary* paintDict,
- const CommandInfo& saveLayerInfo,
- const CommandInfo& dbmInfo) {
- SkASSERT(SAVE_LAYER == saveLayerInfo.fActualOp);
- SkASSERT(DRAW_BITMAP == dbmInfo.fActualOp ||
- DRAW_BITMAP_MATRIX == dbmInfo.fActualOp ||
- DRAW_BITMAP_NINE == dbmInfo.fActualOp ||
- DRAW_BITMAP_RECT_TO_RECT == dbmInfo.fActualOp);
-
- size_t dbmPaintOffset = getPaintOffset(dbmInfo.fActualOp, dbmInfo.fSize);
- size_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerInfo.fSize);
-
- // we have a match, now we need to get the paints involved
- uint32_t dbmPaintId = writer->readTAt<uint32_t>(dbmInfo.fOffset + dbmPaintOffset);
- uint32_t saveLayerPaintId = writer->readTAt<uint32_t>(saveLayerInfo.fOffset + slPaintOffset);
-
- if (0 == saveLayerPaintId) {
- // In this case the saveLayer/restore isn't needed at all - just kill the saveLayer
- // and signal the caller (by returning true) to not add the RESTORE op
- convert_command_to_noop(writer, saveLayerInfo.fOffset);
- return true;
- }
-
- if (0 == dbmPaintId) {
- // In this case just make the DBM* use the saveLayer's paint, kill the saveLayer
- // and signal the caller (by returning true) to not add the RESTORE op
- convert_command_to_noop(writer, saveLayerInfo.fOffset);
- writer->overwriteTAt(dbmInfo.fOffset + dbmPaintOffset, saveLayerPaintId);
- return true;
- }
-
- SkAutoTDelete<SkPaint> saveLayerPaint(paintDict->unflatten(saveLayerPaintId));
- if (NULL == saveLayerPaint.get() || !is_simple(*saveLayerPaint)) {
- return false;
- }
-
- // For this optimization we only fold the saveLayer and drawBitmapRect
- // together if the saveLayer's draw is simple (i.e., no fancy effects) and
- // and the only difference in the colors is that the saveLayer's can have
- // an alpha while the drawBitmapRect's is opaque.
- // TODO: it should be possible to fold them together even if they both
- // have different non-255 alphas
- SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque
-
- SkAutoTDelete<SkPaint> dbmPaint(paintDict->unflatten(dbmPaintId));
- if (NULL == dbmPaint.get() || dbmPaint->getColor() != layerColor || !is_simple(*dbmPaint)) {
- return false;
- }
-
- SkColor newColor = SkColorSetA(dbmPaint->getColor(),
- SkColorGetA(saveLayerPaint->getColor()));
- dbmPaint->setColor(newColor);
-
- const SkFlatData* data = paintDict->findAndReturnFlat(*dbmPaint);
- if (NULL == data) {
- return false;
- }
-
- // kill the saveLayer and alter the DBMR2R's paint to be the modified one
- convert_command_to_noop(writer, saveLayerInfo.fOffset);
- writer->overwriteTAt(dbmInfo.fOffset + dbmPaintOffset, data->index());
- return true;
-}
-
-/*
- * Restore has just been called (but not recorded), look back at the
- * matching save* and see if we are in the configuration:
- * SAVE_LAYER (with NULL == bounds)
- * SAVE
- * CLIP_RECT
- * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_RECT
- * RESTORE
- * RESTORE
- * where the saveLayer's color can be moved into the drawBitmap*'s paint
- */
-static bool remove_save_layer2(SkWriter32* writer, int32_t offset,
- SkPaintDictionary* paintDict) {
- // back up to the save block
- // TODO: add a stack to track save*/restore offsets rather than searching backwards
- while (offset > 0) {
- offset = writer->readTAt<uint32_t>(offset);
- }
-
- int pattern[] = { SAVE_LAYER, SAVE, CLIP_RECT, kDRAW_BITMAP_FLAVOR, RESTORE, /* RESTORE */ };
- CommandInfo result[SK_ARRAY_COUNT(pattern)];
-
- if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) {
- return false;
- }
-
- if (kSaveLayerWithBoundsSize == result[0].fSize) {
- // The saveLayer's bound can offset where the dbm is drawn
- return false;
- }
-
- return merge_savelayer_paint_into_drawbitmp(writer, paintDict,
- result[0], result[3]);
-}
-
-static bool is_drawing_op(DrawType op) {
-
- // FIXME: yuck. convert to a lookup table?
- return (op > CONCAT && op < ROTATE)
- || DRAW_DRRECT == op
- || DRAW_PATCH == op
- || DRAW_PICTURE_MATRIX_PAINT == op
- || DRAW_TEXT_BLOB == op;
-}
-
-/*
- * Restore has just been called (but not recorded), so look back at the
- * matching save(), and see if we can eliminate the pair of them, due to no
- * intervening matrix/clip calls.
- *
- * If so, update the writer and return true, in which case we won't even record
- * the restore() call. If we still need the restore(), return false.
- */
-static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset,
- SkPaintDictionary* paintDict) {
- int32_t restoreOffset = (int32_t)writer->bytesWritten();
-
- // back up to the save block
- while (offset > 0) {
- offset = writer->readTAt<uint32_t>(offset);
- }
-
- // now offset points to a save
- offset = -offset;
- uint32_t opSize;
- DrawType op = peek_op_and_size(writer, offset, &opSize);
- if (SAVE_LAYER == op) {
- // not ready to cull these out yet (mrr)
- return false;
- }
- SkASSERT(SAVE == op);
- SkASSERT(kSaveSize == opSize);
-
- // Walk forward until we get back to either a draw-verb (abort) or we hit
- // our restore (success).
- int32_t saveOffset = offset;
-
- offset += opSize;
- while (offset < restoreOffset) {
- op = peek_op_and_size(writer, offset, &opSize);
- if (is_drawing_op(op) || (SAVE_LAYER == op)) {
- // drawing verb, abort
- return false;
- }
- offset += opSize;
- }
-
- writer->rewindToOffset(saveOffset);
- return true;
-}
-
-typedef bool (*PictureRecordOptProc)(SkWriter32* writer, int32_t offset,
- SkPaintDictionary* paintDict);
-enum PictureRecordOptType {
- kRewind_OptType, // Optimization rewinds the command stream
- kCollapseSaveLayer_OptType, // Optimization eliminates a save/restore pair
-};
-
-enum PictureRecordOptFlags {
- kSkipIfBBoxHierarchy_Flag = 0x1, // Optimization should be skipped if the
- // SkPicture has a bounding box hierarchy.
- kRescindLastSave_Flag = 0x2,
- kRescindLastSaveLayer_Flag = 0x4,
-};
-
-struct PictureRecordOpt {
- PictureRecordOptProc fProc;
- PictureRecordOptType fType;
- unsigned fFlags;
-};
-/*
- * A list of the optimizations that are tried upon seeing a restore
- * TODO: add a real API for such optimizations
- * Add the ability to fire optimizations on any op (not just RESTORE)
- */
-static const PictureRecordOpt gPictureRecordOpts[] = {
- // 'collapse_save_clip_restore' is skipped if there is a BBoxHierarchy
- // because it is redundant with the state traversal optimization in
- // SkPictureStateTree, and applying the optimization introduces significant
- // record time overhead because it requires rewinding contents that were
- // recorded into the BBoxHierarchy.
- { collapse_save_clip_restore, kRewind_OptType,
- kSkipIfBBoxHierarchy_Flag|kRescindLastSave_Flag },
- { remove_save_layer1, kCollapseSaveLayer_OptType, kRescindLastSaveLayer_Flag },
- { remove_save_layer2, kCollapseSaveLayer_OptType, kRescindLastSaveLayer_Flag }
-};
-
-// This is called after an optimization has been applied to the command stream
-// in order to adjust the contents and state of the bounding box hierarchy and
-// state tree to reflect the optimization.
-static void apply_optimization_to_bbh(PictureRecordOptType opt, SkPictureStateTree* stateTree,
- SkBBoxHierarchy* boundingHierarchy) {
- switch (opt) {
- case kCollapseSaveLayer_OptType:
- if (stateTree) {
- stateTree->saveCollapsed();
- }
- break;
- case kRewind_OptType:
- if (boundingHierarchy) {
- boundingHierarchy->rewindInserts();
- }
- // Note: No need to touch the state tree for this to work correctly.
- // Unused branches do not burden the playback, and pruning the tree
- // would be O(N^2), so it is best to leave it alone.
- break;
- default:
- SkASSERT(0);
- }
-}
+#endif//SK_DEBUG
void SkPictureRecord::willRestore() {
// FIXME: SkDeferredCanvas needs to be refactored to respect
@@ -592,31 +229,7 @@ void SkPictureRecord::willRestore() {
fFirstSavedLayerIndex = kNoSavedLayerIndex;
}
- size_t opt = 0;
- if (fOptsEnabled) {
- for (opt = 0; opt < SK_ARRAY_COUNT(gPictureRecordOpts); ++opt) {
- if (0 != (gPictureRecordOpts[opt].fFlags & kSkipIfBBoxHierarchy_Flag)
- && fBoundingHierarchy) {
- continue;
- }
- if ((*gPictureRecordOpts[opt].fProc)(&fWriter, fRestoreOffsetStack.top(), &fPaints)) {
- // Some optimization fired so don't add the RESTORE
- apply_optimization_to_bbh(gPictureRecordOpts[opt].fType,
- fStateTree, fBoundingHierarchy);
- if (gPictureRecordOpts[opt].fFlags & kRescindLastSave_Flag) {
- fContentInfo.rescindLastSave();
- } else if (gPictureRecordOpts[opt].fFlags & kRescindLastSaveLayer_Flag) {
- fContentInfo.rescindLastSaveLayer();
- }
- break;
- }
- }
- }
-
- if (!fOptsEnabled || SK_ARRAY_COUNT(gPictureRecordOpts) == opt) {
- // No optimization fired so add the RESTORE
- this->recordRestore();
- }
+ this->recordRestore();
fRestoreOffsetStack.pop();
@@ -905,19 +518,13 @@ void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
}
void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
- if (rrect.isRect() && kBeClever) {
- this->SkPictureRecord::drawRect(rrect.getBounds(), paint);
- } else if (rrect.isOval() && kBeClever) {
- this->SkPictureRecord::drawOval(rrect.getBounds(), paint);
- } else {
- // op + paint index + rrect
- size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory;
- size_t initialOffset = this->addDraw(DRAW_RRECT, &size);
- SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.bytesWritten());
- this->addPaint(paint);
- this->addRRect(rrect);
- this->validate(initialOffset, size);
- }
+ // op + paint index + rrect
+ size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory;
+ size_t initialOffset = this->addDraw(DRAW_RRECT, &size);
+ SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.bytesWritten());
+ this->addPaint(paint);
+ this->addRRect(rrect);
+ this->validate(initialOffset, size);
}
void SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
@@ -946,10 +553,6 @@ void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
const SkPaint* paint = NULL) {
- if (bitmap.drawsNothing() && kBeClever) {
- return;
- }
-
// op + paint index + bitmap index + left + top
size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
size_t initialOffset = this->addDraw(DRAW_BITMAP, &size);
@@ -964,10 +567,6 @@ void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar
void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
const SkRect& dst, const SkPaint* paint,
DrawBitmapRectFlags flags) {
- if (bitmap.drawsNothing() && kBeClever) {
- return;
- }
-
// id + paint index + bitmap index + bool for 'src' + flags
size_t size = 5 * kUInt32Size;
if (src) {
@@ -988,10 +587,6 @@ void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect*
void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix,
const SkPaint* paint) {
- if (bitmap.drawsNothing() && kBeClever) {
- return;
- }
-
// id + paint index + bitmap index + matrix
size_t size = 3 * kUInt32Size + matrix.writeToMemory(NULL);
size_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size);
@@ -1004,10 +599,6 @@ void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m
void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint* paint) {
- if (bitmap.drawsNothing() && kBeClever) {
- return;
- }
-
// op + paint index + bitmap id + center + dst rect
size_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst);
size_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size);
@@ -1021,10 +612,6 @@ void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent
void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
const SkPaint* paint = NULL) {
- if (bitmap.drawsNothing() && kBeClever) {
- return;
- }
-
// op + paint index + bitmap index + left + top
size_t size = 5 * kUInt32Size;
size_t initialOffset = this->addDraw(DRAW_SPRITE, &size);
@@ -1036,160 +623,52 @@ void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
this->validate(initialOffset, size);
}
-void SkPictureRecord::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, SK_Scalar1, metrics.fBottom);
- (void)paint.computeFastBounds(bounds, &bounds);
- topbot[0] = bounds.fTop;
- topbot[1] = bounds.fBottom;
-}
-
-void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlatData& flat,
- SkScalar minY, SkScalar maxY) {
- WriteTopBot(paint, flat);
- this->addScalar(flat.topBot()[0] + minY);
- this->addScalar(flat.topBot()[1] + maxY);
-}
-
void SkPictureRecord::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
const SkPaint& paint) {
- bool fast = !paint.isVerticalText() && paint.canComputeFastBounds() && kBeClever;
-
// op + paint index + length + 'length' worth of chars + x + y
size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar);
- if (fast) {
- size += 2 * sizeof(SkScalar); // + top & bottom
- }
- DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT;
+ DrawType op = DRAW_TEXT;
size_t initialOffset = this->addDraw(op, &size);
SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.bytesWritten());
- const SkFlatData* flatPaintData = addPaint(paint);
- SkASSERT(flatPaintData);
+ this->addPaint(paint);
this->addText(text, byteLength);
this->addScalar(x);
this->addScalar(y);
- if (fast) {
- this->addFontMetricsTopBottom(paint, *flatPaintData, y, y);
- }
this->validate(initialOffset, size);
}
void SkPictureRecord::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
const SkPaint& paint) {
int points = paint.countText(text, byteLength);
- if (0 == points)
- return;
- bool canUseDrawH = true;
- SkScalar minY = pos[0].fY;
- SkScalar maxY = pos[0].fY;
- // check if the caller really should have used drawPosTextH()
- {
- const SkScalar firstY = pos[0].fY;
- for (int index = 1; index < points; index++) {
- if (pos[index].fY != firstY) {
- canUseDrawH = false;
- if (pos[index].fY < minY) {
- minY = pos[index].fY;
- } else if (pos[index].fY > maxY) {
- maxY = pos[index].fY;
- }
- }
- }
- }
-
- bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds() && kBeClever;
- bool fast = canUseDrawH && fastBounds && kBeClever;
+ // op + paint index + length + 'length' worth of data + num points + x&y point data
+ size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + points * sizeof(SkPoint);
- // op + paint index + length + 'length' worth of data + num points
- size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size;
- if (canUseDrawH) {
- if (fast) {
- size += 2 * sizeof(SkScalar); // + top & bottom
- }
- // + y-pos + actual x-point data
- size += sizeof(SkScalar) + points * sizeof(SkScalar);
- } else {
- // + x&y point data
- size += points * sizeof(SkPoint);
- if (fastBounds) {
- size += 2 * sizeof(SkScalar); // + top & bottom
- }
- }
+ DrawType op = DRAW_POS_TEXT;
- DrawType op;
- if (fast) {
- op = DRAW_POS_TEXT_H_TOP_BOTTOM;
- } else if (canUseDrawH) {
- op = DRAW_POS_TEXT_H;
- } else if (fastBounds) {
- op = DRAW_POS_TEXT_TOP_BOTTOM;
- } else {
- op = DRAW_POS_TEXT;
- }
size_t initialOffset = this->addDraw(op, &size);
SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.bytesWritten());
- const SkFlatData* flatPaintData = this->addPaint(paint);
- SkASSERT(flatPaintData);
+ this->addPaint(paint);
this->addText(text, byteLength);
this->addInt(points);
-
- if (canUseDrawH) {
- if (fast) {
- this->addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY);
- }
- this->addScalar(pos[0].fY);
- SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar));
- for (int index = 0; index < points; index++)
- *xptr++ = pos[index].fX;
- } else {
- fWriter.writeMul4(pos, points * sizeof(SkPoint));
- if (fastBounds) {
- this->addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY);
- }
- }
+ fWriter.writeMul4(pos, points * sizeof(SkPoint));
this->validate(initialOffset, size);
}
void SkPictureRecord::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
SkScalar constY, const SkPaint& paint) {
- const SkFlatData* flatPaintData = this->getFlatPaintData(paint);
- this->drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData);
-}
-
-void SkPictureRecord::drawPosTextHImpl(const void* text, size_t byteLength,
- const SkScalar xpos[], SkScalar constY,
- const SkPaint& paint, const SkFlatData* flatPaintData) {
int points = paint.countText(text, byteLength);
- if (0 == points && kBeClever) {
- return;
- }
-
- bool fast = !paint.isVerticalText() && paint.canComputeFastBounds() && kBeClever;
// op + paint index + length + 'length' worth of data + num points
size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size;
- if (fast) {
- size += 2 * sizeof(SkScalar); // + top & bottom
- }
// + y + the actual points
size += 1 * kUInt32Size + points * sizeof(SkScalar);
- size_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H,
- &size);
- SkASSERT(flatPaintData);
- this->addFlatPaint(flatPaintData);
+ size_t initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size);
+ this->addPaint(paint);
this->addText(text, byteLength);
this->addInt(points);
-
- if (fast) {
- this->addFontMetricsTopBottom(paint, *flatPaintData, constY, constY);
- }
this->addScalar(constY);
fWriter.writeMul4(xpos, points * sizeof(SkScalar));
this->validate(initialOffset, size);
@@ -1331,13 +810,13 @@ void SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors
size += kUInt32Size;
}
}
-
+
size_t initialOffset = this->addDraw(DRAW_PATCH, &size);
SkASSERT(initialOffset+getPaintOffset(DRAW_PATCH, size) == fWriter.bytesWritten());
this->addPaint(paint);
this->addPatch(cubics);
this->addInt(flag);
-
+
// write optional parameters
if (colors) {
fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
@@ -1409,14 +888,6 @@ void SkPictureRecord::onPopCull() {
uint32_t cullSkipOffset = fCullOffsetStack.top();
fCullOffsetStack.pop();
- // Collapse empty push/pop pairs.
- if ((size_t)(cullSkipOffset + kUInt32Size) == fWriter.bytesWritten() && kBeClever) {
- SkASSERT(fWriter.bytesWritten() >= kPushCullOpSize);
- SkASSERT(PUSH_CULL == peek_op(&fWriter, fWriter.bytesWritten() - kPushCullOpSize));
- fWriter.rewindToOffset(fWriter.bytesWritten() - kPushCullOpSize);
- return;
- }
-
// op only
size_t size = kUInt32Size;
size_t initialOffset = this->addDraw(POP_CULL, &size);
@@ -1447,21 +918,16 @@ void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
fWriter.writeMatrix(matrix);
}
-const SkFlatData* SkPictureRecord::getFlatPaintData(const SkPaint& paint) {
- return fPaints.findAndReturnFlat(paint);
-}
-
-const SkFlatData* SkPictureRecord::addPaintPtr(const SkPaint* paint) {
+void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
fContentInfo.onAddPaintPtr(paint);
- const SkFlatData* data = paint ? getFlatPaintData(*paint) : NULL;
- this->addFlatPaint(data);
- return data;
-}
-
-void SkPictureRecord::addFlatPaint(const SkFlatData* flatPaint) {
- int index = flatPaint ? flatPaint->index() : 0;
- this->addInt(index);
+ if (paint) {
+ const SkFlatData* flat = fPaints.findAndReturnFlat(*paint);
+ SkASSERT(flat && flat->index() != 0);
+ this->addInt(flat->index());
+ } else {
+ this->addInt(0);
+ }
}
int SkPictureRecord::addPathToHeap(const SkPath& path) {
« no previous file with comments | « src/core/SkPictureRecord.h ('k') | src/core/SkPictureRecorder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698