Add unit test for SkDeferredDisplayLists (take 2)
Change-Id: I76a4c77d5b9418cb7fe677bd55ba32a2e336924d Reviewed-on: https://skia-review.googlesource.com/79820 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
bee6cacc54
commit
7ffbcf909d
@ -47,8 +47,9 @@ tests_sources = [
|
||||
"$_tests/CTest.cpp",
|
||||
"$_tests/DashPathEffectTest.cpp",
|
||||
"$_tests/DataRefTest.cpp",
|
||||
"$_tests/DequeTest.cpp",
|
||||
"$_tests/DefaultPathRendererTest.cpp",
|
||||
"$_tests/DeferredDisplayListTest.cpp",
|
||||
"$_tests/DequeTest.cpp",
|
||||
"$_tests/DetermineDomainModeTest.cpp",
|
||||
"$_tests/DeviceLooperTest.cpp",
|
||||
"$_tests/DeviceTest.cpp",
|
||||
|
@ -362,7 +362,7 @@ public:
|
||||
* The draw will be skipped if the characterization stored in the display list
|
||||
* isn't compatible with this surface.
|
||||
*/
|
||||
void draw(SkDeferredDisplayList* deferredDisplayList);
|
||||
bool draw(SkDeferredDisplayList* deferredDisplayList);
|
||||
|
||||
protected:
|
||||
SkSurface(int width, int height, const SkSurfaceProps* surfaceProps);
|
||||
|
@ -51,6 +51,7 @@ struct GrMockOptions {
|
||||
bool fIntegerSupport = false;
|
||||
bool fFlatInterpolationSupport = false;
|
||||
int fMaxVertexSamplers = 0;
|
||||
int fMaxFragmentSamplers = 8;
|
||||
bool fShaderDerivativeSupport = true;
|
||||
};
|
||||
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
}
|
||||
|
||||
// TODO: remove this. It is just scaffolding to get something up & running
|
||||
void draw(SkSurface*);
|
||||
bool draw(SkSurface*);
|
||||
|
||||
private:
|
||||
const SkSurfaceCharacterization fCharacterization;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "GrTypes.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrTypesPriv.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class GrContextThreadSafeProxy;
|
||||
@ -21,7 +22,7 @@ class SkColorSpace;
|
||||
rendering decisions. When passed into a SkDeferredDisplayListRecorder it will copy the
|
||||
data and pass it on to the SkDeferredDisplayList if/when it is created. Note that both of
|
||||
those objects (the Recorder and the DisplayList) will take a ref on the
|
||||
GrContextThreadSafeProxy object.
|
||||
GrContextThreadSafeProxy and SkColorSpace objects.
|
||||
*/
|
||||
class SkSurfaceCharacterization {
|
||||
public:
|
||||
@ -30,7 +31,8 @@ public:
|
||||
, fWidth(0)
|
||||
, fHeight(0)
|
||||
, fConfig(kUnknown_GrPixelConfig)
|
||||
, fSampleCnt(0)
|
||||
, fFSAAType(GrFSAAType::kNone)
|
||||
, fStencilCnt(0)
|
||||
, fSurfaceProps(0, kUnknown_SkPixelGeometry) {
|
||||
}
|
||||
|
||||
@ -45,7 +47,8 @@ public:
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
GrPixelConfig config() const { return fConfig; }
|
||||
int sampleCount() const { return fSampleCnt; }
|
||||
GrFSAAType fsaaType() const { return fFSAAType; }
|
||||
int stencilCount() const { return fStencilCnt; }
|
||||
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
|
||||
sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
|
||||
const SkSurfaceProps& surfaceProps()const { return fSurfaceProps; }
|
||||
@ -57,7 +60,8 @@ private:
|
||||
GrSurfaceOrigin origin,
|
||||
int width, int height,
|
||||
GrPixelConfig config,
|
||||
int sampleCnt,
|
||||
GrFSAAType fsaaType,
|
||||
int stencilCnt,
|
||||
sk_sp<SkColorSpace> colorSpace,
|
||||
const SkSurfaceProps& surfaceProps) {
|
||||
fContextInfo = contextInfo;
|
||||
@ -65,7 +69,8 @@ private:
|
||||
fWidth = width;
|
||||
fHeight = height;
|
||||
fConfig = config;
|
||||
fSampleCnt = sampleCnt;
|
||||
fFSAAType = fsaaType;
|
||||
fStencilCnt = stencilCnt;
|
||||
fColorSpace = std::move(colorSpace);
|
||||
fSurfaceProps = surfaceProps;
|
||||
}
|
||||
@ -75,7 +80,8 @@ private:
|
||||
int fWidth;
|
||||
int fHeight;
|
||||
GrPixelConfig fConfig;
|
||||
int fSampleCnt;
|
||||
GrFSAAType fFSAAType;
|
||||
int fStencilCnt;
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
SkSurfaceProps fSurfaceProps;
|
||||
};
|
||||
|
@ -43,6 +43,7 @@ std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() {
|
||||
|
||||
// Placeholder. Ultimately, the SkSurface_Gpu will pass the wrapped opLists to its
|
||||
// renderTargetContext.
|
||||
void SkDeferredDisplayList::draw(SkSurface* surface) {
|
||||
bool SkDeferredDisplayList::draw(SkSurface* surface) {
|
||||
surface->getCanvas()->drawImage(fImage.get(), 0, 0);
|
||||
return true;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
fShaderCaps->fIntegerSupport = options.fIntegerSupport;
|
||||
fShaderCaps->fFlatInterpolationSupport = options.fFlatInterpolationSupport;
|
||||
fShaderCaps->fMaxVertexSamplers = options.fMaxVertexSamplers;
|
||||
fShaderCaps->fMaxFragmentSamplers = options.fMaxFragmentSamplers;
|
||||
fShaderCaps->fShaderDerivativeSupport = options.fShaderDerivativeSupport;
|
||||
|
||||
this->applyOptionsOverrides(contextOptions);
|
||||
|
@ -213,7 +213,7 @@ bool SkSurface::characterize(SkSurfaceCharacterization* characterization) const
|
||||
return asSB(const_cast<SkSurface*>(this))->onCharacterize(characterization);
|
||||
}
|
||||
|
||||
void SkSurface::draw(SkDeferredDisplayList* ddl) {
|
||||
bool SkSurface::draw(SkDeferredDisplayList* ddl) {
|
||||
return asSB(this)->onDraw(ddl);
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
}
|
||||
|
||||
virtual bool onCharacterize(SkSurfaceCharacterization*) const { return false; }
|
||||
virtual void onDraw(SkDeferredDisplayList*) { }
|
||||
virtual bool onDraw(SkDeferredDisplayList*) { return false; }
|
||||
|
||||
inline SkCanvas* getCachedCanvas();
|
||||
inline sk_sp<SkImage> refCachedImage();
|
||||
|
@ -165,7 +165,7 @@ bool SkSurface_Gpu::onCharacterize(SkSurfaceCharacterization* data) const {
|
||||
GrContext* ctx = fDevice->context();
|
||||
|
||||
data->set(ctx->threadSafeProxy(), rtc->origin(), rtc->width(), rtc->height(),
|
||||
rtc->colorSpaceInfo().config(), rtc->numColorSamples(),
|
||||
rtc->colorSpaceInfo().config(), rtc->fsaaType(), rtc->numStencilSamples(),
|
||||
rtc->colorSpaceInfo().refColorSpace(), this->props());
|
||||
|
||||
return true;
|
||||
@ -178,19 +178,19 @@ bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& data) const {
|
||||
return data.contextInfo() && data.contextInfo()->matches(ctx) &&
|
||||
data.origin() == rtc->origin() && data.width() == rtc->width() &&
|
||||
data.height() == rtc->height() && data.config() == rtc->colorSpaceInfo().config() &&
|
||||
data.sampleCount() == rtc->numColorSamples() &&
|
||||
data.fsaaType() == rtc->fsaaType() && data.stencilCount() == rtc->numStencilSamples() &&
|
||||
SkColorSpace::Equals(data.colorSpace(), rtc->colorSpaceInfo().colorSpace()) &&
|
||||
data.surfaceProps() == rtc->surfaceProps();
|
||||
}
|
||||
|
||||
void SkSurface_Gpu::onDraw(SkDeferredDisplayList* dl) {
|
||||
bool SkSurface_Gpu::onDraw(SkDeferredDisplayList* dl) {
|
||||
if (!this->isCompatible(dl->characterization())) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ultimately need to pass opLists from the DeferredDisplayList on to the
|
||||
// SkGpuDevice's renderTargetContext.
|
||||
dl->draw(this);
|
||||
return dl->draw(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) override;
|
||||
bool onCharacterize(SkSurfaceCharacterization*) const override;
|
||||
bool isCompatible(const SkSurfaceCharacterization&) const;
|
||||
void onDraw(SkDeferredDisplayList*) override;
|
||||
bool onDraw(SkDeferredDisplayList*) override;
|
||||
|
||||
SkGpuDevice* getDevice() { return fDevice.get(); }
|
||||
|
||||
|
142
tests/DeferredDisplayListTest.cpp
Normal file
142
tests/DeferredDisplayListTest.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDeferredDisplayListRecorder.h"
|
||||
#include "SkGpuDevice.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkSurface_Gpu.h"
|
||||
#include "SkSurfaceCharacterization.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
#include "Test.h"
|
||||
|
||||
class SurfaceParameters {
|
||||
public:
|
||||
static const int kNumParams = 8;
|
||||
static const int kSampleCount = 5;
|
||||
|
||||
SurfaceParameters()
|
||||
: fWidth(64)
|
||||
, fHeight(64)
|
||||
, fOrigin(kTopLeft_GrSurfaceOrigin)
|
||||
, fColorType(kRGBA_8888_SkColorType)
|
||||
, fColorSpace(SkColorSpace::MakeSRGB())
|
||||
, fSampleCount(0)
|
||||
, fSurfaceProps(0x0, kUnknown_SkPixelGeometry) {
|
||||
}
|
||||
|
||||
int sampleCount() const { return fSampleCount; }
|
||||
|
||||
// Modify the SurfaceParameters in just one way
|
||||
void modify(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
fWidth = 63;
|
||||
break;
|
||||
case 1:
|
||||
fHeight = 63;
|
||||
break;
|
||||
case 2:
|
||||
fOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||
break;
|
||||
case 3:
|
||||
fColorType = kRGBA_F16_SkColorType;
|
||||
break;
|
||||
case 4:
|
||||
fColorSpace = SkColorSpace::MakeSRGBLinear();
|
||||
break;
|
||||
case kSampleCount:
|
||||
fSampleCount = 4;
|
||||
break;
|
||||
case 6:
|
||||
fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
|
||||
break;
|
||||
case 7:
|
||||
fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
|
||||
kUnknown_SkPixelGeometry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the surface with the current set of parameters
|
||||
sk_sp<SkSurface> make(GrContext* context) const {
|
||||
// Note that Ganesh doesn't make use of the SkImageInfo's alphaType
|
||||
SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
|
||||
kPremul_SkAlphaType, fColorSpace);
|
||||
|
||||
return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, fSampleCount,
|
||||
fOrigin, &fSurfaceProps);
|
||||
}
|
||||
|
||||
private:
|
||||
int fWidth;
|
||||
int fHeight;
|
||||
GrSurfaceOrigin fOrigin;
|
||||
SkColorType fColorType;
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
int fSampleCount;
|
||||
SkSurfaceProps fSurfaceProps;
|
||||
};
|
||||
|
||||
// This tests SkSurfaceCharacterization/SkSurface compatibility
|
||||
DEF_GPUTEST_FOR_ALL_CONTEXTS(SkSurfaceCharacterization, reporter, ctxInfo) {
|
||||
GrContext* context = ctxInfo.grContext();
|
||||
|
||||
std::unique_ptr<SkDeferredDisplayList> ddl;
|
||||
|
||||
// First, create a DDL using the stock SkSurface parameters
|
||||
{
|
||||
SurfaceParameters params;
|
||||
|
||||
sk_sp<SkSurface> s = params.make(context);
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkSurfaceCharacterization c;
|
||||
SkAssertResult(s->characterize(&c));
|
||||
|
||||
SkDeferredDisplayListRecorder r(c);
|
||||
SkCanvas* canvas = r.getCanvas();
|
||||
canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
|
||||
ddl = r.detach();
|
||||
|
||||
REPORTER_ASSERT(reporter, s->draw(ddl.get()));
|
||||
}
|
||||
|
||||
// Then, alter each parameter in turn and check that the DDL & surface are incompatible
|
||||
for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
|
||||
SurfaceParameters params;
|
||||
params.modify(i);
|
||||
|
||||
sk_sp<SkSurface> s = params.make(context);
|
||||
if (!s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SurfaceParameters::kSampleCount == i) {
|
||||
SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
|
||||
|
||||
int supportedSampleCount = context->caps()->getSampleCount(
|
||||
params.sampleCount(),
|
||||
gpuSurf->getDevice()->accessRenderTargetContext()->asRenderTargetProxy()->config());
|
||||
if (0 == supportedSampleCount) {
|
||||
// If changing the sample count won't result in a different
|
||||
// surface characterization, skip this step
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user