Add backend texture and backend render target versions snapshot GMs

GPU may behave differently depending on whether the SkSurface backing
store is wrapped and whether it is a texture or not.

Bug: skia:11208
Change-Id: I5e9921d56c0840cfe34ed2926a55be7460409b23
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/364639
Reviewed-by: Adlai Holler <adlai@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2021-02-03 10:44:15 -05:00 committed by Skia Commit-Bot
parent c112932089
commit fa87f9c7b9
5 changed files with 102 additions and 19 deletions

View File

@ -26,9 +26,9 @@ class SkCanvas;
class SkMetaData;
struct GrContextOptions;
#define DEF_GM(CODE) \
static skiagm::GMRegistry SK_MACRO_APPEND_LINE(REG_)(\
[](){return std::unique_ptr<skiagm::GM>([](){ CODE ; }());});
#define DEF_GM(CODE) \
static skiagm::GMRegistry SK_MACRO_APPEND_COUNTER(REG_)( \
[]() { return std::unique_ptr<skiagm::GM>([]() { CODE; }()); });
// A Simple GM is a rendering test that does not store state between rendering calls or make use of
// the onOnceBeforeDraw() virtual; it consists of:

View File

@ -27,8 +27,11 @@
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/utils/SkTextUtils.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/BackendSurfaceFactory.h"
#define W 200
#define H 100
@ -167,9 +170,77 @@ DEF_GM( return new NewSurfaceGM )
///////////////////////////////////////////////////////////////////////////////////////////////////
DEF_SIMPLE_GM(copy_on_write_retain, canvas, 256, 256) {
// The GPU backend may behave differently when images are snapped from wrapped textures and
// render targets compared.
namespace {
enum SurfaceType {
kManaged,
kBackendTexture,
kBackendRenderTarget
};
}
static sk_sp<SkSurface> make_surface(const SkImageInfo& ii, SkCanvas* canvas, SurfaceType type) {
GrDirectContext* direct = GrAsDirectContext(canvas->recordingContext());
switch (type) {
case kManaged:
return ToolUtils::makeSurface(canvas, ii);
case kBackendTexture:
if (!direct) {
return nullptr;
}
return sk_gpu_test::MakeBackendTextureSurface(direct, ii, kTopLeft_GrSurfaceOrigin, 1);
case kBackendRenderTarget:
return sk_gpu_test::MakeBackendRenderTargetSurface(direct,
ii,
kTopLeft_GrSurfaceOrigin,
1);
}
return nullptr;
}
using MakeSurfaceFn = std::function<sk_sp<SkSurface>(const SkImageInfo&)>;
#define DEF_BASIC_SURFACE_TEST(name, canvas, main, W, H) \
DEF_SIMPLE_GM(name, canvas, W, H) { \
auto make = [canvas](const SkImageInfo& ii) { \
return make_surface(ii, canvas, SurfaceType::kManaged); \
}; \
main(canvas, MakeSurfaceFn(make)); \
}
#define DEF_BACKEND_SURFACE_TEST(name, canvas, main, type, W, H) \
DEF_SIMPLE_GM_CAN_FAIL(name, canvas, err_msg, W, H) { \
GrDirectContext* direct = GrAsDirectContext(canvas->recordingContext()); \
if (!direct || direct->abandoned()) { \
*err_msg = "Requires non-abandoned GrDirectContext"; \
return skiagm::DrawResult::kSkip; \
} \
auto make = [canvas](const SkImageInfo& ii) { return make_surface(ii, canvas, type); }; \
main(canvas, MakeSurfaceFn(make)); \
return skiagm::DrawResult::kOk; \
}
#define DEF_BET_SURFACE_TEST(name, canvas, main, W, H) \
DEF_BACKEND_SURFACE_TEST(SK_MACRO_CONCAT(name, _bet), canvas, main, \
SurfaceType::kBackendTexture, W, H)
#define DEF_BERT_SURFACE_TEST(name, canvas, main, W, H) \
DEF_BACKEND_SURFACE_TEST(SK_MACRO_CONCAT(name, _bert), canvas, main, \
SurfaceType::kBackendRenderTarget, W, H)
// This makes 3 GMs from the same code, normal, wrapped backend texture, and wrapped backend
// render target.
#define DEF_SURFACE_TESTS(name, canvas, W, H) \
static void SK_MACRO_CONCAT(name, _main)(SkCanvas*, const MakeSurfaceFn&); \
DEF_BASIC_SURFACE_TEST(name, canvas, SK_MACRO_CONCAT(name, _main), W, H) \
DEF_BET_SURFACE_TEST (name, canvas, SK_MACRO_CONCAT(name, _main), W, H) \
DEF_BERT_SURFACE_TEST (name, canvas, SK_MACRO_CONCAT(name, _main), W, H) \
static void SK_MACRO_CONCAT(name, _main)(SkCanvas * canvas, const MakeSurfaceFn& make)
DEF_SURFACE_TESTS(copy_on_write_retain, canvas, 256, 256) {
const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
sk_sp<SkSurface> surf = ToolUtils::makeSurface(canvas, info);
sk_sp<SkSurface> surf = make(info);
surf->getCanvas()->clear(SK_ColorRED);
// its important that image survives longer than the next draw, so the surface will see
@ -185,9 +256,9 @@ DEF_SIMPLE_GM(copy_on_write_retain, canvas, 256, 256) {
canvas->drawImage(surf->makeImageSnapshot(), 0, 0);
}
DEF_SIMPLE_GM(copy_on_write_savelayer, canvas, 256, 256) {
DEF_SURFACE_TESTS(copy_on_write_savelayer, canvas, 256, 256) {
const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
sk_sp<SkSurface> surf = ToolUtils::makeSurface(canvas, info);
sk_sp<SkSurface> surf = make(info);
surf->getCanvas()->clear(SK_ColorRED);
// its important that image survives longer than the next draw, so the surface will see
// an outstanding image, and have to decide if it should retain or discard those pixels
@ -206,9 +277,9 @@ DEF_SIMPLE_GM(copy_on_write_savelayer, canvas, 256, 256) {
canvas->drawImage(surf->makeImageSnapshot(), 0, 0);
}
DEF_SIMPLE_GM(surface_underdraw, canvas, 256, 256) {
DEF_SURFACE_TESTS(surface_underdraw, canvas, 256, 256) {
SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256, nullptr);
auto surf = ToolUtils::makeSurface(canvas, info);
auto surf = make(info);
const SkIRect subset = SkIRect::MakeLTRB(180, 0, 256, 256);

View File

@ -24,6 +24,8 @@
*/
#define SK_MACRO_APPEND_LINE(name) SK_MACRO_CONCAT(name, __LINE__)
#define SK_MACRO_APPEND_COUNTER(name) SK_MACRO_CONCAT(name, __COUNTER__)
////////////////////////////////////////////////////////////////////////////////
// Can be used to bracket data types that must be dense, e.g. hash keys.

View File

@ -29,6 +29,11 @@ sk_sp<GrRenderTask> GrCopyRenderTask::Make(GrDrawingManager* drawingMgr,
return nullptr;
}
if (src->framebufferOnly()) {
return nullptr;
}
sk_sp<GrCopyRenderTask> task(new GrCopyRenderTask(drawingMgr,
std::move(src),
srcRect,

View File

@ -835,23 +835,28 @@ bool GrDrawingManager::newCopyRenderTask(sk_sp<GrSurfaceProxy> src,
SkDEBUGCODE(this->validate());
SkASSERT(fContext);
this->closeActiveOpsTask();
GrRenderTask* task = this->appendTask(GrCopyRenderTask::Make(this,
src,
srcRect,
std::move(dst),
dstPoint,
origin));
sk_sp<GrRenderTask> task = GrCopyRenderTask::Make(this,
src,
srcRect,
std::move(dst),
dstPoint,
origin);
if (!task) {
return false;
}
this->closeActiveOpsTask();
GrRenderTask* appendedTask = this->appendTask(std::move(task));
const GrCaps& caps = *fContext->priv().caps();
// We always say GrMipmapped::kNo here since we are always just copying from the base layer to
// another base layer. We don't need to make sure the whole mip map chain is valid.
task->addDependency(this, src.get(), GrMipmapped::kNo, GrTextureResolveManager(this), caps);
task->makeClosed(caps);
appendedTask->addDependency(this,
src.get(),
GrMipmapped::kNo,
GrTextureResolveManager(this),
caps);
appendedTask->makeClosed(caps);
// We have closed the previous active oplist but since a new oplist isn't being added there
// shouldn't be an active one.