aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkPictureRecorder.h6
-rw-r--r--include/private/SkRecords.h47
-rw-r--r--src/core/SkPictureCommon.h10
-rw-r--r--src/core/SkPictureRecorder.cpp51
4 files changed, 83 insertions, 31 deletions
diff --git a/include/core/SkPictureRecorder.h b/include/core/SkPictureRecorder.h
index 82efcf0e99..f20a06adf4 100644
--- a/include/core/SkPictureRecorder.h
+++ b/include/core/SkPictureRecorder.h
@@ -19,6 +19,7 @@ namespace android {
};
#endif
+class GrContext;
class SkCanvas;
class SkDrawable;
class SkPictureRecord;
@@ -111,6 +112,9 @@ public:
SkPicture* SK_WARN_UNUSED_RESULT endRecording() { return this->endRecordingAsPicture(); }
#endif
+ // Strawman API.
+ void optimizeFor(GrContext* ctx) { fGrContextToOptimizeFor = ctx; }
+
private:
void reset();
@@ -131,6 +135,8 @@ private:
SkAutoTUnref<SkRecord> fRecord;
SkMiniRecorder fMiniRecorder;
+ GrContext* fGrContextToOptimizeFor = nullptr;
+
typedef SkNoncopyable INHERITED;
};
diff --git a/include/private/SkRecords.h b/include/private/SkRecords.h
index 0b50d1163d..32da3dd377 100644
--- a/include/private/SkRecords.h
+++ b/include/private/SkRecords.h
@@ -153,6 +153,7 @@ enum Tags {
kDraw_Tag = 1, // May draw something (usually named DrawFoo).
kHasImage_Tag = 2, // Contains an SkImage or SkBitmap.
kHasText_Tag = 4, // Contains text.
+ kHasPaint_Tag = 8, // May have an SkPaint field, at least optionally.
};
// A macro to make it a little easier to define a struct that can be stored in SkRecord.
@@ -169,7 +170,7 @@ RECORD(Restore, 0,
TypedMatrix matrix);
RECORD(Save, 0);
-RECORD(SaveLayer, 0,
+RECORD(SaveLayer, kHasPaint_Tag,
Optional<SkRect> bounds;
Optional<SkPaint> paint;
sk_sp<const SkImageFilter> backdrop;
@@ -208,7 +209,7 @@ RECORD(ClipRegion, 0,
SkRegion::Op op);
// While not strictly required, if you have an SkPaint, it's fastest to put it first.
-RECORD(DrawDRRect, kDraw_Tag,
+RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
SkRRect outer;
SkRRect inner);
@@ -216,90 +217,90 @@ RECORD(DrawDrawable, kDraw_Tag,
Optional<SkMatrix> matrix;
SkRect worstCaseBounds;
int32_t index);
-RECORD(DrawImage, kDraw_Tag|kHasImage_Tag,
+RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
Optional<SkPaint> paint;
sk_sp<const SkImage> image;
SkScalar left;
SkScalar top);
-RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag,
+RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
Optional<SkPaint> paint;
sk_sp<const SkImage> image;
Optional<SkRect> src;
SkRect dst;
SkCanvas::SrcRectConstraint constraint);
-RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag,
+RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
Optional<SkPaint> paint;
sk_sp<const SkImage> image;
SkIRect center;
SkRect dst);
-RECORD(DrawOval, kDraw_Tag,
+RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
SkRect oval);
-RECORD(DrawPaint, kDraw_Tag,
+RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag,
SkPaint paint);
-RECORD(DrawPath, kDraw_Tag,
+RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
PreCachedPath path);
-RECORD(DrawPicture, kDraw_Tag,
+RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag,
Optional<SkPaint> paint;
sk_sp<const SkPicture> picture;
TypedMatrix matrix);
-RECORD(DrawShadowedPicture, kDraw_Tag,
+RECORD(DrawShadowedPicture, kDraw_Tag|kHasPaint_Tag,
Optional<SkPaint> paint;
sk_sp<const SkPicture> picture;
TypedMatrix matrix);
-RECORD(DrawPoints, kDraw_Tag,
+RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
SkCanvas::PointMode mode;
unsigned count;
SkPoint* pts);
-RECORD(DrawPosText, kDraw_Tag|kHasText_Tag,
+RECORD(DrawPosText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
SkPaint paint;
PODArray<char> text;
size_t byteLength;
PODArray<SkPoint> pos);
-RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag,
+RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
SkPaint paint;
PODArray<char> text;
unsigned byteLength;
SkScalar y;
PODArray<SkScalar> xpos);
-RECORD(DrawRRect, kDraw_Tag,
+RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
SkRRect rrect);
-RECORD(DrawRect, kDraw_Tag,
+RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
SkRect rect);
-RECORD(DrawText, kDraw_Tag|kHasText_Tag,
+RECORD(DrawText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
SkPaint paint;
PODArray<char> text;
size_t byteLength;
SkScalar x;
SkScalar y);
-RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag,
+RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
SkPaint paint;
sk_sp<const SkTextBlob> blob;
SkScalar x;
SkScalar y);
-RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag,
+RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
SkPaint paint;
PODArray<char> text;
size_t byteLength;
PreCachedPath path;
TypedMatrix matrix);
-RECORD(DrawTextRSXform, kDraw_Tag|kHasText_Tag,
+RECORD(DrawTextRSXform, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
SkPaint paint;
PODArray<char> text;
size_t byteLength;
PODArray<SkRSXform> xforms;
Optional<SkRect> cull);
-RECORD(DrawPatch, kDraw_Tag,
+RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
PODArray<SkPoint> cubics;
PODArray<SkColor> colors;
PODArray<SkPoint> texCoords;
sk_sp<SkXfermode> xmode);
-RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag,
+RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
Optional<SkPaint> paint;
sk_sp<const SkImage> atlas;
PODArray<SkRSXform> xforms;
@@ -308,7 +309,7 @@ RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag,
int count;
SkXfermode::Mode mode;
Optional<SkRect> cull);
-RECORD(DrawVertices, kDraw_Tag,
+RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
SkCanvas::VertexMode vmode;
int vertexCount;
@@ -318,7 +319,7 @@ RECORD(DrawVertices, kDraw_Tag,
sk_sp<SkXfermode> xmode;
PODArray<uint16_t> indices;
int indexCount);
-RECORD(DrawAnnotation, 0,
+RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548
SkRect rect;
SkString key;
sk_sp<SkData> value);
diff --git a/src/core/SkPictureCommon.h b/src/core/SkPictureCommon.h
index 1c38b049fa..0a0c6b5ca9 100644
--- a/src/core/SkPictureCommon.h
+++ b/src/core/SkPictureCommon.h
@@ -45,18 +45,12 @@ struct SkBitmapHunter {
// Most draws-type ops have paints.
template <typename T>
- static SK_WHEN(T::kTags & SkRecords::kDraw_Tag, bool) CheckPaint(const T& op) {
+ static SK_WHEN(T::kTags & SkRecords::kHasPaint_Tag, bool) CheckPaint(const T& op) {
return PaintHasBitmap(AsPtr(op.paint));
}
- // SaveLayers also have a paint to check.
- static bool CheckPaint(const SkRecords::SaveLayer& op) {
- return PaintHasBitmap(AsPtr(op.paint));
- }
-
- // Shouldn't be any non-Draw non-SaveLayer ops with paints.
template <typename T>
- static SK_WHEN(!(T::kTags & SkRecords::kDraw_Tag), bool) CheckPaint(const T&) {
+ static SK_WHEN(!(T::kTags & SkRecords::kHasPaint_Tag), bool) CheckPaint(const T&) {
return false;
}
diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp
index 5631a081d4..8e7c7f3b06 100644
--- a/src/core/SkPictureRecorder.cpp
+++ b/src/core/SkPictureRecorder.cpp
@@ -8,6 +8,7 @@
#include "SkBigPicture.h"
#include "SkData.h"
#include "SkDrawable.h"
+#include "SkImage.h"
#include "SkPictureRecorder.h"
#include "SkPictureUtils.h"
#include "SkRecord.h"
@@ -16,6 +17,54 @@
#include "SkRecordedDrawable.h"
#include "SkRecorder.h"
#include "SkTypes.h"
+#include "SkTLogic.h"
+
+namespace SkRecords {
+
+ struct OptimizeFor {
+ GrContext* fCtx;
+
+ // A few ops have a top-level SkImage:
+ void operator()(DrawAtlas* op) { this->make_texture(&op->atlas); }
+ void operator()(DrawImage* op) { this->make_texture(&op->image); }
+ void operator()(DrawImageNine* op) { this->make_texture(&op->image); }
+ void operator()(DrawImageRect* op) { this->make_texture(&op->image); }
+ void make_texture(sk_sp<const SkImage>* img) const {
+ *img = (*img)->makeTextureImage(fCtx);
+ }
+
+ // Some ops have a paint, some have an optional paint.
+ // Either way, get back a pointer.
+ static SkPaint* AsPtr(SkPaint& p) { return &p; }
+ static SkPaint* AsPtr(SkRecords::Optional<SkPaint>& p) { return p; }
+
+ // For all other types of ops, look for images inside the paint.
+ template <typename T>
+ SK_WHEN(T::kTags & kHasPaint_Tag, void) operator()(T* op) {
+ SkMatrix matrix;
+ SkShader::TileMode xy[2];
+
+ if (auto paint = AsPtr(op->paint))
+ if (auto shader = paint->getShader())
+ if (auto image = shader->isAImage(&matrix, xy)) {
+ paint->setShader(image->makeTextureImage(fCtx)->makeShader(xy[0], xy[1], &matrix));
+ }
+
+ // TODO: re-build compose shaders
+ }
+
+ // Control ops, etc. Nothing to do for these.
+ template <typename T>
+ SK_WHEN(!(T::kTags & kHasPaint_Tag), void) operator()(T*) {}
+ };
+
+} // namespace SkRecords
+
+static void optimize_for(GrContext* ctx, SkRecord* record) {
+ for (int i = 0; ctx && i < record->count(); i++) {
+ record->mutate(i, SkRecords::OptimizeFor{ctx});
+ }
+}
SkPictureRecorder::SkPictureRecorder() {
fActivelyRecording = false;
@@ -63,6 +112,7 @@ sk_sp<SkPicture> SkPictureRecorder::finishRecordingAsPicture(uint32_t finishFlag
// TODO: delay as much of this work until just before first playback?
SkRecordOptimize(fRecord);
+ optimize_for(fGrContextToOptimizeFor, fRecord);
if (fRecord->count() == 0) {
if (finishFlags & kReturnNullForEmpty_FinishFlag) {
@@ -123,6 +173,7 @@ sk_sp<SkDrawable> SkPictureRecorder::finishRecordingAsDrawable(uint32_t finishFl
fRecorder->restoreToCount(1); // If we were missing any restores, add them now.
SkRecordOptimize(fRecord);
+ optimize_for(fGrContextToOptimizeFor, fRecord);
if (fRecord->count() == 0) {
if (finishFlags & kReturnNullForEmpty_FinishFlag) {