Enforce thread-safety of bitmaps in pictures via the type.
No runtime difference here, but it makes it impossible to forget to make
a shallow copy; you can't get at the full bitmap without it.
NOTREECHECKS=true
BUG=skia:
Review URL: https://codereview.chromium.org/799603002
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 7f575d1..b714e759 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -74,11 +74,6 @@
namespace SkRecords {
-// FIXME: SkBitmaps are stateful, so we need to copy them to play back in multiple threads.
-static SkBitmap shallow_copy(const SkBitmap& bitmap) {
- return bitmap;
-}
-
// NoOps draw nothing.
template <> void Draw::draw(const NoOp&) {}
@@ -100,13 +95,13 @@
DRAW(AddComment, addComment(r.key, r.value));
DRAW(EndCommentGroup, endCommentGroup());
-DRAW(DrawBitmap, drawBitmap(shallow_copy(r.bitmap), r.left, r.top, r.paint));
-DRAW(DrawBitmapNine, drawBitmapNine(shallow_copy(r.bitmap), r.center, r.dst, r.paint));
+DRAW(DrawBitmap, drawBitmap(r.bitmap.shallowCopy(), r.left, r.top, r.paint));
+DRAW(DrawBitmapNine, drawBitmapNine(r.bitmap.shallowCopy(), r.center, r.dst, r.paint));
DRAW(DrawBitmapRectToRect,
- drawBitmapRectToRect(shallow_copy(r.bitmap), r.src, r.dst, r.paint,
+ drawBitmapRectToRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint,
SkCanvas::kNone_DrawBitmapRectFlag));
DRAW(DrawBitmapRectToRectBleed,
- drawBitmapRectToRect(shallow_copy(r.bitmap), r.src, r.dst, r.paint,
+ drawBitmapRectToRect(r.bitmap.shallowCopy(), r.src, r.dst, r.paint,
SkCanvas::kBleed_DrawBitmapRectFlag));
DRAW(DrawDRRect, drawDRRect(r.outer, r.inner, r.paint));
DRAW(DrawImage, drawImage(r.image, r.left, r.top, r.paint));
@@ -121,7 +116,7 @@
DRAW(DrawPosTextH, drawPosTextH(r.text, r.byteLength, r.xpos, r.y, r.paint));
DRAW(DrawRRect, drawRRect(r.rrect, r.paint));
DRAW(DrawRect, drawRect(r.rect, r.paint));
-DRAW(DrawSprite, drawSprite(shallow_copy(r.bitmap), r.left, r.top, r.paint));
+DRAW(DrawSprite, drawSprite(r.bitmap.shallowCopy(), r.left, r.top, r.paint));
DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint));
DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint));
DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, &r.matrix, r.paint));
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index d6fc723..d8dfb2b 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -183,15 +183,24 @@
// Like SkBitmap, but deep copies pixels if they're not immutable.
// Using this, we guarantee the immutability of all bitmaps we record.
-struct ImmutableBitmap : public SkBitmap {
+class ImmutableBitmap : SkNoncopyable {
+public:
explicit ImmutableBitmap(const SkBitmap& bitmap) {
if (bitmap.isImmutable()) {
- *(SkBitmap*)this = bitmap;
+ fBitmap = bitmap;
} else {
- bitmap.copyTo(this);
+ bitmap.copyTo(&fBitmap);
}
- this->setImmutable();
+ fBitmap.setImmutable();
}
+
+ int width() const { return fBitmap.width(); }
+ int height() const { return fBitmap.height(); }
+
+ // While the pixels are immutable, SkBitmap itself is not thread-safe, so return a copy.
+ SkBitmap shallowCopy() const { return fBitmap; }
+private:
+ SkBitmap fBitmap;
};
// SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context.