Sketch SkPictureRecorder::optimizeFor(GrContext*).
I'm open to API suggestions. We can pass this in finishAs(), up front, whatever. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2203453002 Review-Url: https://codereview.chromium.org/2203453002
This commit is contained in:
parent
7a34b1cd02
commit
1bb5fecbea
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user