diff options
author | Robert Phillips <robertphillips@google.com> | 2018-03-30 13:57:00 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-30 19:12:26 +0000 |
commit | 6b6fcc78620270ec2dcd57bd520ec500f60f4505 (patch) | |
tree | 4a08bccfd3485a582aa4e10c1e73047ef705fdac | |
parent | 26339bf9a86b5f06747afe8e8bd92e3e6d8b703f (diff) |
Add SkSurface factory that takes an SkSurfaceCharacterization
TBR=bsalomon@google.com
Change-Id: Ie38123dc7c35005bfe8500bf4a16e0d16bbf36bd
Reviewed-on: https://skia-review.googlesource.com/117236
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | docs/SkSurface_Reference.bmh | 25 | ||||
-rw-r--r-- | include/core/SkSurface.h | 12 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 16 | ||||
-rw-r--r-- | src/image/SkSurface.cpp | 5 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 20 | ||||
-rw-r--r-- | tests/DeferredDisplayListTest.cpp | 49 |
6 files changed, 118 insertions, 9 deletions
diff --git a/docs/SkSurface_Reference.bmh b/docs/SkSurface_Reference.bmh index a7053f69d3..e37ac57250 100644 --- a/docs/SkSurface_Reference.bmh +++ b/docs/SkSurface_Reference.bmh @@ -711,6 +711,31 @@ Surface bottom-left corner is pinned to the origin. # ------------------------------------------------------------------------------ +#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, + const SkSurfaceCharacterization& characterization, + SkBudgeted budgeted) + +Returns SkSurface on GPU indicated by context that is compatible with the provided +characterization. budgeted selects whether allocation for pixels is tracked by context. + + @param context GPU context + @param characterization description of the desired SkSurface + @param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes + @return SkSurface if all parameters are valid; otherwise, nullptr + +#Param context GPU_Context ## +#Param characterization description of the desired SkSurface ## +#Param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes +## + +#Return Surface if all parameters are valid; otherwise, nullptr ## + +#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget + +#Method ## + +# ------------------------------------------------------------------------------ + #Method static sk_sp<SkSurface> MakeNull(int width, int height) #In Constructor diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h index 419e548f48..28b830dc27 100644 --- a/include/core/SkSurface.h +++ b/include/core/SkSurface.h @@ -335,6 +335,18 @@ public: nullptr); } + /** Returns SkSurface on GPU indicated by context that is compatible with the provided + characterization. budgeted selects whether allocation for pixels is tracked by context. + + @param context GPU context + @param characterization description of the desired SkSurface + @param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes + @return SkSurface if all parameters are valid; otherwise, nullptr + */ + static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, + const SkSurfaceCharacterization& characterization, + SkBudgeted budgeted); + /** Returns SkSurface without backing pixels. Drawing to SkCanvas returned from SkSurface has no effect. Calling makeImageSnapshot() on returned SkSurface returns nullptr. diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index db13931b2b..1112b5705f 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -33,6 +33,7 @@ #include "SkImageInfoPriv.h" #include "SkJSONWriter.h" #include "SkMakeUnique.h" +#include "SkSurface_Gpu.h" #include "SkTaskGroup.h" #include "SkUnPreMultiplyPriv.h" #include "effects/GrConfigConversionEffect.h" @@ -172,8 +173,9 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization( return SkSurfaceCharacterization(); // return an invalid characterization } - // We're assuming GrFSAAType::kMixedSamples will never be specified via this code path - GrFSAAType FSAAType = sampleCnt > 1 ? GrFSAAType::kUnifiedMSAA : GrFSAAType::kNone; + if (!SkSurface_Gpu::Valid(ii)) { + return SkSurfaceCharacterization(); // return an invalid characterization + } if (!fCaps->mipMapSupport()) { isMipMapped = false; @@ -184,6 +186,16 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization( return SkSurfaceCharacterization(); // return an invalid characterization } + sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, config); + if (!sampleCnt) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + GrFSAAType FSAAType = GrFSAAType::kNone; + if (sampleCnt > 1) { + FSAAType = fCaps->usesMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA; + } + // This surface characterization factory assumes that the resulting characterization is // textureable. if (!fCaps->isConfigTexturable(config)) { diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp index 30a1fa464c..9444de7724 100644 --- a/src/image/SkSurface.cpp +++ b/src/image/SkSurface.cpp @@ -277,6 +277,11 @@ sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext*, SkBudgeted, const SkIma return nullptr; } +sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext*, const SkSurfaceCharacterization&, + SkBudgeted) { + return nullptr; +} + sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext*, const GrBackendTexture&, GrSurfaceOrigin origin, int sampleCnt, SkColorType, sk_sp<SkColorSpace>, diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index ace1981bf7..bc5fe68940 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -269,6 +269,26 @@ bool SkSurface_Gpu::Valid(GrContext* context, GrPixelConfig config, SkColorSpace } } +sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* context, + const SkSurfaceCharacterization& c, + SkBudgeted budgeted) { + if (!c.isValid()) { + return nullptr; + } + + SkColorType ct; + if (!GrPixelConfigToColorType(c.config(), &ct)) { + return nullptr; + } + + SkImageInfo ii = SkImageInfo::Make(c.width(), c.height(), ct, kPremul_SkAlphaType, + c.refColorSpace()); + + return MakeRenderTarget(context, budgeted, ii, c.stencilCount(), c.origin(), + &c.surfaceProps(), c.isMipMapped()); +} + + sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* ctx, SkBudgeted budgeted, const SkImageInfo& info, int sampleCount, GrSurfaceOrigin origin, const SkSurfaceProps* props, diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp index d9aa522125..ddbb4a84c0 100644 --- a/tests/DeferredDisplayListTest.cpp +++ b/tests/DeferredDisplayListTest.cpp @@ -121,13 +121,7 @@ public: } } - // Create a DDL whose characterization captures the current settings - std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const { - sk_sp<SkSurface> s = this->make(context); - if (!s) { - return nullptr; - } - + SkSurfaceCharacterization createCharacterization(GrContext* context) const { int maxResourceCount; size_t maxResourceBytes; context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes); @@ -141,6 +135,12 @@ public: SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization( maxResourceBytes, ii, backendFormat, fSampleCount, fOrigin, fSurfaceProps, fShouldCreateMipMaps); + return c; + } + + // Create a DDL whose characterization captures the current settings + std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const { + SkSurfaceCharacterization c = this->createCharacterization(context); SkAssertResult(c.isValid()); SkDeferredDisplayListRecorder r(c); @@ -205,6 +205,7 @@ private: bool fShouldCreateMipMaps; }; +//////////////////////////////////////////////////////////////////////////////// // This tests SkSurfaceCharacterization/SkSurface compatibility DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); @@ -258,6 +259,8 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) } if (SurfaceParameters::kMipMipCount == i && !context->caps()->mipMapSupport()) { + // If changing the mipmap setting won't result in a different surface characterization, + // skip this step continue; } @@ -345,6 +348,35 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) } } +//////////////////////////////////////////////////////////////////////////////// +// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization. +// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible. +DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) { + GrContext* context = ctxInfo.grContext(); + + for (int i = 0; i < SurfaceParameters::kNumParams; ++i) { + SurfaceParameters params; + params.modify(i); + + SkSurfaceCharacterization c = params.createCharacterization(context); + + sk_sp<SkSurface> s = params.make(context); + if (!s) { + REPORTER_ASSERT(reporter, !c.isValid()); + continue; + } + + REPORTER_ASSERT(reporter, c.isValid()); + + s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes); + REPORTER_ASSERT(reporter, s); + + SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get()); + REPORTER_ASSERT(reporter, g->isCompatible(c)); + } +} + +//////////////////////////////////////////////////////////////////////////////// static constexpr int kSize = 8; struct TextureReleaseChecker { @@ -411,6 +443,7 @@ static void dummy_fulfill_proc(void*, GrBackendTexture*) { SkASSERT(0); } static void dummy_release_proc(void*) { SkASSERT(0); } static void dummy_done_proc(void*) { } +//////////////////////////////////////////////////////////////////////////////// // Test out the behavior of an invalid DDLRecorder DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); @@ -450,6 +483,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) { } +//////////////////////////////////////////////////////////////////////////////// // Ensure that flushing while DDL recording doesn't cause a crash DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); @@ -467,6 +501,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) { canvas->getGrContext()->flush(); } +//////////////////////////////////////////////////////////////////////////////// // Check that the texture-specific flags (i.e., for external & rectangle textures) work // for promise images. As such, this is a GL-only test. DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) { |