Add GM::gpuSetup step

In order to emulate OOP-R's behavior, GM needs to pass GPU-backed resources to a DDL recorder.

This change allows GMs to create GPU resources first (in onGpuSetup w/ a direct context) and then use them in onDraw (with only a GrRecordingContext).


Change-Id: Ifa3002af73eb9926f653fb4c4bf4542c0749d658
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294336
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2020-06-16 11:11:33 -04:00 committed by Skia Commit-Bot
parent b71b6ae106
commit 889d613875
8 changed files with 76 additions and 65 deletions

View File

@ -906,7 +906,7 @@ static void push_sink(const SkCommandLineConfig& config, Sink* s) {
// Try a simple Src as a canary. If it fails, skip this sink.
struct : public Src {
Result draw(SkCanvas* c) const override {
Result draw(GrContext*, SkCanvas* c) const override {
c->drawRect(SkRect::MakeWH(1,1), SkPaint());
return Result::Ok();
}

View File

@ -90,10 +90,18 @@ namespace DM {
GMSrc::GMSrc(skiagm::GMFactory factory) : fFactory(factory) {}
Result GMSrc::draw(SkCanvas* canvas) const {
Result GMSrc::draw(GrContext* context, SkCanvas* canvas) const {
std::unique_ptr<skiagm::GM> gm(fFactory());
SkString msg;
skiagm::DrawResult gpuSetupResult = gm->gpuSetup(context, &msg);
switch (gpuSetupResult) {
case skiagm::DrawResult::kOk : break;
case skiagm::DrawResult::kFail: return Result(Result::Status::Fatal, msg);
case skiagm::DrawResult::kSkip: return Result(Result::Status::Skip, msg);
default: SK_ABORT("");
}
skiagm::DrawResult drawResult = gm->draw(canvas, &msg);
switch (drawResult) {
case skiagm::DrawResult::kOk : return Result(Result::Status::Ok, msg);
@ -158,7 +166,7 @@ static inline void alpha8_to_gray8(SkBitmap* bitmap) {
}
}
Result BRDSrc::draw(SkCanvas* canvas) const {
Result BRDSrc::draw(GrContext*, SkCanvas* canvas) const {
SkColorType colorType = canvas->imageInfo().colorType();
if (kRGB_565_SkColorType == colorType &&
CodecSrc::kGetFromCanvas_DstColorType != fDstColorType)
@ -399,7 +407,7 @@ static void set_bitmap_color_space(SkImageInfo* info) {
*info = info->makeColorSpace(SkColorSpace::MakeSRGB());
}
Result CodecSrc::draw(SkCanvas* canvas) const {
Result CodecSrc::draw(GrContext*, SkCanvas* canvas) const {
sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str()));
if (!encoded) {
return Result::Fatal("Couldn't read %s.", fPath.c_str());
@ -784,7 +792,7 @@ bool AndroidCodecSrc::veto(SinkFlags flags) const {
|| flags.approach != SinkFlags::kDirect;
}
Result AndroidCodecSrc::draw(SkCanvas* canvas) const {
Result AndroidCodecSrc::draw(GrContext*, SkCanvas* canvas) const {
sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str()));
if (!encoded) {
return Result::Fatal("Couldn't read %s.", fPath.c_str());
@ -876,7 +884,7 @@ bool ImageGenSrc::veto(SinkFlags flags) const {
return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect;
}
Result ImageGenSrc::draw(SkCanvas* canvas) const {
Result ImageGenSrc::draw(GrContext*, SkCanvas* canvas) const {
if (kRGB_565_SkColorType == canvas->imageInfo().colorType()) {
return Result::Skip("Uninteresting to test image generator to 565.");
}
@ -974,7 +982,7 @@ bool ColorCodecSrc::veto(SinkFlags flags) const {
return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect;
}
Result ColorCodecSrc::draw(SkCanvas* canvas) const {
Result ColorCodecSrc::draw(GrContext*, SkCanvas* canvas) const {
sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str()));
if (!encoded) {
return Result::Fatal("Couldn't read %s.", fPath.c_str());
@ -1039,7 +1047,7 @@ static DEFINE_int(skpViewportSize, 1000,
SKPSrc::SKPSrc(Path path) : fPath(path) { }
Result SKPSrc::draw(SkCanvas* canvas) const {
Result SKPSrc::draw(GrContext*, SkCanvas* canvas) const {
std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(fPath.c_str());
if (!stream) {
return Result::Fatal("Couldn't read %s.", fPath.c_str());
@ -1081,7 +1089,7 @@ Name SKPSrc::name() const { return SkOSPath::Basename(fPath.c_str()); }
BisectSrc::BisectSrc(Path path, const char* trail) : INHERITED(path), fTrail(trail) {}
Result BisectSrc::draw(SkCanvas* canvas) const {
Result BisectSrc::draw(GrContext* context, SkCanvas* canvas) const {
struct FoundPath {
SkPath fPath;
SkPaint fPaint;
@ -1104,7 +1112,7 @@ Result BisectSrc::draw(SkCanvas* canvas) const {
PathFindingCanvas pathFinder(canvas->getBaseLayerSize().width(),
canvas->getBaseLayerSize().height());
Result result = this->INHERITED::draw(&pathFinder);
Result result = this->INHERITED::draw(context, &pathFinder);
if (!result.isOk()) {
return result;
}
@ -1137,7 +1145,7 @@ static DEFINE_bool(useLottieGlyphPaths, false,
SkottieSrc::SkottieSrc(Path path) : fPath(std::move(path)) {}
Result SkottieSrc::draw(SkCanvas* canvas) const {
Result SkottieSrc::draw(GrContext*, SkCanvas* canvas) const {
auto resource_provider =
skresources::DataURIResourceProviderProxy::Make(
skresources::FileResourceProvider::Make(SkOSPath::Dirname(fPath.c_str()),
@ -1243,7 +1251,7 @@ SVGSrc::SVGSrc(Path path)
}
}
Result SVGSrc::draw(SkCanvas* canvas) const {
Result SVGSrc::draw(GrContext*, SkCanvas* canvas) const {
if (!fDom) {
return Result::Fatal("Unable to parse file: %s", fName.c_str());
}
@ -1294,10 +1302,10 @@ SkISize MSKPSrc::size(int i) const {
return i >= 0 && i < fPages.count() ? fPages[i].fSize.toCeil() : SkISize{0, 0};
}
Result MSKPSrc::draw(SkCanvas* c) const {
return this->draw(0, c);
Result MSKPSrc::draw(GrContext* context, SkCanvas* c) const {
return this->draw(0, context, c);
}
Result MSKPSrc::draw(int i, SkCanvas* canvas) const {
Result MSKPSrc::draw(int i, GrContext*, SkCanvas* canvas) const {
if (this->pageCount() == 0) {
return Result::Fatal("Unable to parse MultiPictureDocument file: %s", fPath.c_str());
}
@ -1325,7 +1333,7 @@ Name MSKPSrc::name() const { return SkOSPath::Basename(fPath.c_str()); }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Result NullSink::draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const {
return src.draw(SkMakeNullCanvas().get());
return src.draw(nullptr, SkMakeNullCanvas().get());
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
@ -1472,7 +1480,7 @@ Result GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log,
factory.abandonContexts();
}
SkCanvas* canvas = surface->getCanvas();
Result result = src.draw(canvas);
Result result = src.draw(context, canvas);
if (!result.isOk()) {
return result;
}
@ -1638,7 +1646,7 @@ Result GPUOOPRSink::ooprDraw(const Src& src,
SkDeferredDisplayListRecorder recorder(dstCharacterization);
Result result = src.draw(recorder.getCanvas());
Result result = src.draw(context, recorder.getCanvas());
if (!result.isOk()) {
return result;
}
@ -1739,8 +1747,8 @@ Result GPUDDLSink::ddlDraw(const Src& src,
auto size = src.size();
SkPictureRecorder recorder;
Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
Result result = src.draw(gpuThreadCtx, recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
if (!result.isOk()) {
gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); });
gpuTaskGroup->wait();
@ -1919,7 +1927,7 @@ static Result draw_skdocument(const Src& src, SkDocument* doc, SkWStream* dst) {
if (!canvas) {
return Result::Fatal("SkDocument::beginPage(w,h) returned nullptr");
}
Result result = src.draw(i, canvas);
Result result = src.draw(i, nullptr, canvas);
if (!result.isOk()) {
return result;
}
@ -1990,7 +1998,7 @@ SKPSink::SKPSink() {}
Result SKPSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const {
auto size = SkSize::Make(src.size());
SkPictureRecorder recorder;
Result result = src.draw(recorder.beginRecording(size.width(), size.height()));
Result result = src.draw(nullptr, recorder.beginRecording(size.width(), size.height()));
if (!result.isOk()) {
return result;
}
@ -2002,7 +2010,7 @@ Result SKPSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const
Result DebugSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const {
DebugCanvas debugCanvas(src.size().width(), src.size().height());
Result result = src.draw(&debugCanvas);
Result result = src.draw(nullptr, &debugCanvas);
if (!result.isOk()) {
return result;
}
@ -2029,7 +2037,7 @@ Result SVGSink::draw(const Src& src, SkBitmap*, SkWStream* dst, SkString*) const
fPageIndex, pageCount);
}
}
return src.draw(fPageIndex,
return src.draw(fPageIndex, nullptr,
SkSVGCanvas::Make(SkRect::MakeWH(SkIntToScalar(src.size().width()),
SkIntToScalar(src.size().height())),
dst)
@ -2056,7 +2064,7 @@ Result RasterSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString*) co
SkBitmap::kZeroPixels_AllocFlag);
SkCanvas canvas(*dst);
return src.draw(&canvas);
return src.draw(nullptr, &canvas);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
@ -2071,7 +2079,7 @@ static Result draw_to_canvas(Sink* sink, SkBitmap* bitmap, SkWStream* stream, Sk
class ProxySrc : public Src {
public:
ProxySrc(SkISize size, const Fn& draw) : fSize(size), fDraw(draw) {}
Result draw(SkCanvas* canvas) const override { return fDraw(canvas); }
Result draw(GrContext*, SkCanvas* canvas) const override { return fDraw(canvas); }
Name name() const override { return "ProxySrc"; }
SkISize size() const override { return fSize; }
private:
@ -2120,7 +2128,7 @@ Result ViaMatrix::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkSt
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(canvas);
return src.draw(nullptr, canvas);
});
}
@ -2165,8 +2173,8 @@ Result ViaSerialization::draw(
// Record our Src into a picture.
auto size = src.size();
SkPictureRecorder recorder;
Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
Result result = src.draw(nullptr, recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
if (!result.isOk()) {
return result;
}
@ -2194,8 +2202,8 @@ ViaDDL::ViaDDL(int numReplays, int numDivisions, Sink* sink)
Result ViaDDL::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const {
auto size = src.size();
SkPictureRecorder recorder;
Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
Result result = src.draw(nullptr, recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
if (!result.isOk()) {
return result;
}
@ -2289,8 +2297,8 @@ Result ViaPicture::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkS
Result result = draw_to_canvas(fSink.get(), bitmap, stream, log, size, [&](SkCanvas* canvas) {
SkPictureRecorder recorder;
sk_sp<SkPicture> pic;
Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
Result result = src.draw(nullptr, recorder.beginRecording(SkIntToScalar(size.width()),
SkIntToScalar(size.height())));
if (!result.isOk()) {
return result;
}

View File

@ -86,15 +86,15 @@ struct SinkFlags {
struct Src {
virtual ~Src() {}
virtual Result SK_WARN_UNUSED_RESULT draw(SkCanvas*) const = 0;
virtual Result SK_WARN_UNUSED_RESULT draw(GrContext*, SkCanvas*) 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, SkCanvas* canvas) const {
return this->draw(canvas);
virtual Result SK_WARN_UNUSED_RESULT draw(int, GrContext* context, SkCanvas* canvas) const {
return this->draw(context, canvas);
}
virtual SkISize size(int) const { return this->size(); }
// Force Tasks using this Src to run on the main thread?
@ -130,7 +130,7 @@ class GMSrc : public Src {
public:
explicit GMSrc(skiagm::GMFactory);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
void modifyGrContextOptions(GrContextOptions* options) const override;
@ -162,7 +162,7 @@ public:
};
CodecSrc(Path, Mode, DstColorType, SkAlphaType, float);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkFlags) const override;
@ -180,7 +180,7 @@ class AndroidCodecSrc : public Src {
public:
AndroidCodecSrc(Path, CodecSrc::DstColorType, SkAlphaType, int sampleSize);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkFlags) const override;
@ -209,7 +209,7 @@ public:
BRDSrc(Path, Mode, CodecSrc::DstColorType, uint32_t);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkFlags) const override;
@ -229,7 +229,7 @@ public:
};
ImageGenSrc(Path, Mode, SkAlphaType, bool);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkFlags) const override;
@ -246,7 +246,7 @@ class ColorCodecSrc : public Src {
public:
ColorCodecSrc(Path, bool decode_to_dst);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkFlags) const override;
@ -259,7 +259,7 @@ class SKPSrc : public Src {
public:
explicit SKPSrc(Path path);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
private:
@ -273,7 +273,7 @@ class BisectSrc : public SKPSrc {
public:
explicit BisectSrc(Path path, const char* trail);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
private:
SkString fTrail;
@ -287,7 +287,7 @@ class SkottieSrc final : public Src {
public:
explicit SkottieSrc(Path path);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkFlags) const override;
@ -315,7 +315,7 @@ class SVGSrc : public Src {
public:
explicit SVGSrc(Path path);
Result draw(SkCanvas*) const override;
Result draw(GrContext*, SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
bool veto(SinkFlags) const override;
@ -335,8 +335,8 @@ public:
explicit MSKPSrc(Path path);
int pageCount() const override;
Result draw(SkCanvas* c) const override;
Result draw(int, SkCanvas*) const override;
Result draw(GrContext*, SkCanvas* c) const override;
Result draw(int, GrContext*, SkCanvas*) const override;
SkISize size() const override;
SkISize size(int) const override;
Name name() const override;

View File

@ -72,6 +72,11 @@ GM::GM(SkColor bgColor) {
GM::~GM() {}
DrawResult GM::gpuSetup(GrContext* context, SkString* errorMsg) {
TRACE_EVENT1("GM", TRACE_FUNC, "name", TRACE_STR_COPY(this->getName()));
return this->onGpuSetup(context, errorMsg);
}
DrawResult GM::draw(SkCanvas* canvas, SkString* errorMsg) {
TRACE_EVENT1("GM", TRACE_FUNC, "name", TRACE_STR_COPY(this->getName()));
this->drawBackground(canvas);
@ -169,7 +174,7 @@ void GM::drawSizeBounds(SkCanvas* canvas, SkColor color) {
template GMRegistry* GMRegistry::gHead;
DrawResult GpuGM::onDraw(GrContext* ctx, GrRenderTargetContext* rtc, SkCanvas* canvas,
SkString* errorMsg) {
SkString* errorMsg) {
this->onDraw(ctx, rtc, canvas);
return DrawResult::kOk;
}

View File

@ -110,6 +110,8 @@ namespace skiagm {
static constexpr char kErrorMsg_DrawSkippedGpuOnly[] = "This test is for GPU configs only.";
DrawResult gpuSetup(GrContext*, SkString* errorMsg);
DrawResult draw(SkCanvas* canvas) {
SkString errorMsg;
return this->draw(canvas, &errorMsg);
@ -152,8 +154,10 @@ namespace skiagm {
virtual std::unique_ptr<verifiers::VerifierList> getVerifiers() const;
protected:
// onGpuSetup is called once before any other processing with a direct context.
virtual DrawResult onGpuSetup(GrContext*, SkString*) { return DrawResult::kOk; }
virtual void onOnceBeforeDraw();
virtual DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg);
virtual DrawResult onDraw(SkCanvas*, SkString* errorMsg);
virtual void onDraw(SkCanvas*);
virtual SkISize onISize() = 0;

View File

@ -70,7 +70,11 @@ protected:
return DrawResult::kOk;
}
DrawResult onGpuSetup(GrContext* context, SkString* errorMsg) {
DrawResult onGpuSetup(GrContext* context, SkString* errorMsg) override {
if (!context) {
return DrawResult::kSkip;
}
SkASSERT(context->priv().asDirectContext());
if (context->backend() != GrBackendApi::kVulkan) {
@ -86,18 +90,7 @@ protected:
return DrawResult::kOk;
}
DrawResult onDraw(GrContext* context, GrRenderTargetContext*, SkCanvas* canvas,
SkString* errorMsg) override {
if (context->backend() != GrBackendApi::kVulkan) {
*errorMsg = "This GM requires a Vulkan context.";
return DrawResult::kSkip;
}
DrawResult result = this->onGpuSetup(context, errorMsg);
if (result != DrawResult::kOk) {
return result;
}
DrawResult onDraw(GrContext*, GrRenderTargetContext*, SkCanvas* canvas, SkString*) override {
SkASSERT(fYCbCrImage);
SkPaint paint;

View File

@ -109,6 +109,7 @@ void DDLTileHelper::createComposeDDL() {
}
fComposeDDL = recorder.detach();
SkASSERT(fComposeDDL);
}
void DDLTileHelper::TileData::precompile(GrContext* context) {

View File

@ -100,11 +100,11 @@ public:
const SkIRect& viewport,
int numDivisions);
void createSKPPerTile(SkData* compressedPictureData, const DDLPromiseImageHelper& helper);
void createSKPPerTile(SkData* compressedPictureData, const DDLPromiseImageHelper&);
void kickOffThreadedWork(SkTaskGroup* recordingTaskGroup,
SkTaskGroup* gpuTaskGroup,
GrContext* gpuThreadContext);
GrContext*);
void createDDLsInParallel();