diff options
author | Robert Phillips <robertphillips@google.com> | 2017-12-04 12:52:46 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-04 18:37:29 +0000 |
commit | 7ffbcf909d365eb22c5e22b776aeac7b7472fbf3 (patch) | |
tree | a71ca068a01ca87ea417f341adf4dee40c811d58 | |
parent | bee6cacc54357e0af1de67d527fe51eb3602c2d6 (diff) |
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>
-rw-r--r-- | gn/tests.gni | 3 | ||||
-rw-r--r-- | include/core/SkSurface.h | 2 | ||||
-rw-r--r-- | include/gpu/mock/GrMockTypes.h | 1 | ||||
-rw-r--r-- | include/private/SkDeferredDisplayList.h | 2 | ||||
-rw-r--r-- | include/private/SkSurfaceCharacterization.h | 18 | ||||
-rw-r--r-- | src/core/SkDeferredDisplayListRecorder.cpp | 3 | ||||
-rw-r--r-- | src/gpu/mock/GrMockCaps.h | 1 | ||||
-rw-r--r-- | src/image/SkSurface.cpp | 2 | ||||
-rw-r--r-- | src/image/SkSurface_Base.h | 2 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 10 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.h | 2 | ||||
-rw-r--r-- | tests/DeferredDisplayListTest.cpp | 142 |
12 files changed, 170 insertions, 18 deletions
diff --git a/gn/tests.gni b/gn/tests.gni index 23e4f831b9..eb20aaba0d 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -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", diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h index a1024039dc..f70db73fe5 100644 --- a/include/core/SkSurface.h +++ b/include/core/SkSurface.h @@ -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); diff --git a/include/gpu/mock/GrMockTypes.h b/include/gpu/mock/GrMockTypes.h index 35bb5efe23..cf30a333f3 100644 --- a/include/gpu/mock/GrMockTypes.h +++ b/include/gpu/mock/GrMockTypes.h @@ -51,6 +51,7 @@ struct GrMockOptions { bool fIntegerSupport = false; bool fFlatInterpolationSupport = false; int fMaxVertexSamplers = 0; + int fMaxFragmentSamplers = 8; bool fShaderDerivativeSupport = true; }; diff --git a/include/private/SkDeferredDisplayList.h b/include/private/SkDeferredDisplayList.h index c6e67f4dcc..b53390d174 100644 --- a/include/private/SkDeferredDisplayList.h +++ b/include/private/SkDeferredDisplayList.h @@ -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; diff --git a/include/private/SkSurfaceCharacterization.h b/include/private/SkSurfaceCharacterization.h index 8b20cacb36..f450b704d9 100644 --- a/include/private/SkSurfaceCharacterization.h +++ b/include/private/SkSurfaceCharacterization.h @@ -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; }; diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp index 18e516ab31..f6981e7535 100644 --- a/src/core/SkDeferredDisplayListRecorder.cpp +++ b/src/core/SkDeferredDisplayListRecorder.cpp @@ -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; } diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h index c4b9449a05..47a5002f96 100644 --- a/src/gpu/mock/GrMockCaps.h +++ b/src/gpu/mock/GrMockCaps.h @@ -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); diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp index 04e16f6281..9cef76f236 100644 --- a/src/image/SkSurface.cpp +++ b/src/image/SkSurface.cpp @@ -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); } diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h index e05d371cd8..b71d4c7043 100644 --- a/src/image/SkSurface_Base.h +++ b/src/image/SkSurface_Base.h @@ -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(); diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 605f229023..dc1f308512 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -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); } diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h index c95966370c..cb21771aa9 100644 --- a/src/image/SkSurface_Gpu.h +++ b/src/image/SkSurface_Gpu.h @@ -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(); } diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp new file mode 100644 index 0000000000..b6839afa1a --- /dev/null +++ b/tests/DeferredDisplayListTest.cpp @@ -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 |