Allow draw_to_canvas to pass through the GrDirectContext.

Some GM slides behave differently when a GrDirectContext is passed (e.g.
the CTMPathEffectGM disables itself when the GrDirectContext is non-null
because it asserts when run on GPU).

Change-Id: Ida18f191474f94426c6077d3a5de659e739056a4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/430476
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
John Stiles 2021-07-20 12:50:40 -04:00 committed by Skia Commit-Bot
parent fb4d380747
commit dfd1a70f39
2 changed files with 28 additions and 21 deletions

View File

@ -2113,18 +2113,21 @@ Result RasterSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString*) co
// passing the Sink draw() arguments, a size, and a function draws into an SkCanvas.
// Several examples below.
template <typename Fn>
static Result draw_to_canvas(Sink* sink, SkBitmap* bitmap, SkWStream* stream, SkString* log,
SkISize size, const Fn& draw) {
using DrawToCanvasFn = std::function<DM::Result(GrDirectContext*, SkCanvas*)>;
static Result draw_to_canvas(Sink* sink, SkBitmap* bitmap, SkWStream* stream,
SkString* log, SkISize size, const DrawToCanvasFn& draw) {
class ProxySrc : public Src {
public:
ProxySrc(SkISize size, const Fn& draw) : fSize(size), fDraw(draw) {}
Result draw(GrDirectContext*, SkCanvas* canvas) const override { return fDraw(canvas); }
ProxySrc(SkISize size, const DrawToCanvasFn& draw) : fSize(size), fDraw(draw) {}
Result draw(GrDirectContext* context, SkCanvas* canvas) const override {
return fDraw(context, canvas);
}
Name name() const override { return "ProxySrc"; }
SkISize size() const override { return fSize; }
private:
SkISize fSize;
const Fn& fDraw;
SkISize fSize;
const DrawToCanvasFn& fDraw;
};
return sink->draw(ProxySrc(size, draw), bitmap, stream, log);
}
@ -2166,10 +2169,11 @@ ViaMatrix::ViaMatrix(SkMatrix matrix, Sink* sink) : Via(sink), fMatrix(matrix) {
Result ViaMatrix::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const {
SkMatrix matrix = fMatrix;
SkISize size = auto_compute_translate(&matrix, src.size().width(), src.size().height());
return draw_to_canvas(fSink.get(), bitmap, stream, log, size, [&](SkCanvas* canvas) {
canvas->concat(matrix);
return src.draw(nullptr, canvas);
});
return draw_to_canvas(fSink.get(), bitmap, stream, log, size,
[&](GrDirectContext* context, SkCanvas* canvas) {
canvas->concat(matrix);
return src.draw(context, canvas);
});
}
// Undoes any flip or 90 degree rotate without changing the scale of the bitmap.
@ -2223,10 +2227,11 @@ Result ViaSerialization::draw(
// Serialize it and then deserialize it.
sk_sp<SkPicture> deserialized(SkPicture::MakeFromData(pic->serialize().get()));
result = draw_to_canvas(fSink.get(), bitmap, stream, log, size, [&](SkCanvas* canvas) {
canvas->drawPicture(deserialized);
return Result::Ok();
});
result = draw_to_canvas(fSink.get(), bitmap, stream, log, size,
[&](GrDirectContext*, SkCanvas* canvas) {
canvas->drawPicture(deserialized);
return Result::Ok();
});
if (!result.isOk()) {
return result;
}
@ -2238,10 +2243,11 @@ Result ViaSerialization::draw(
Result ViaPicture::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const {
auto size = src.size();
Result result = draw_to_canvas(fSink.get(), bitmap, stream, log, size, [&](SkCanvas* canvas) {
Result result = draw_to_canvas(fSink.get(), bitmap, stream, log, size,
[&](GrDirectContext* context, SkCanvas* canvas) {
SkPictureRecorder recorder;
sk_sp<SkPicture> pic;
Result result = src.draw(nullptr, recorder.beginRecording(SkIntToScalar(size.width()),
Result result = src.draw(context, recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
if (!result.isOk()) {
return result;
@ -2266,7 +2272,8 @@ Result ViaPicture::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkS
Result ViaSVG::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const {
auto size = src.size();
return draw_to_canvas(fSink.get(), bitmap, stream, log, size, [&](SkCanvas* canvas) -> Result {
return draw_to_canvas(fSink.get(), bitmap, stream, log, size,
[&](GrDirectContext*, SkCanvas* canvas) -> Result {
SkDynamicMemoryWStream wstream;
SkXMLStreamWriter writer(&wstream);
Result result = src.draw(SkSVGCanvas::Make(SkRect::Make(size), &writer).get());

View File

@ -86,18 +86,18 @@ struct SinkFlags {
struct Src {
virtual ~Src() {}
virtual Result SK_WARN_UNUSED_RESULT draw(GrDirectContext*, SkCanvas*) const = 0;
virtual Result SK_WARN_UNUSED_RESULT draw(GrDirectContext* context, SkCanvas* canvas) const = 0;
virtual SkISize size() const = 0;
virtual Name name() const = 0;
virtual void modifyGrContextOptions(GrContextOptions* options) const {}
virtual bool veto(SinkFlags) const { return false; }
virtual int pageCount() const { return 1; }
virtual Result SK_WARN_UNUSED_RESULT draw(int, GrDirectContext* context,
virtual Result SK_WARN_UNUSED_RESULT draw([[maybe_unused]] int page, GrDirectContext* context,
SkCanvas* canvas) const {
return this->draw(context, canvas);
}
virtual SkISize size(int) const { return this->size(); }
virtual SkISize size([[maybe_unused]] int page) const { return this->size(); }
// Force Tasks using this Src to run on the main thread?
virtual bool serial() const { return false; }