diff options
author | Brian Salomon <bsalomon@google.com> | 2018-02-01 18:02:35 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-02 00:16:28 +0000 |
commit | 85ae7159c9c8a9186a4c7e74304eabb35bca9a79 (patch) | |
tree | 8f1cf3aa71803889d1f2b1b84b43013395f188ac | |
parent | e45d32abe13239e3482fc4a13f006ab72073252a (diff) |
Add new GrContext queries for imagability, surfacability, and max sample count of color types
Bug: skia:7538
Change-Id: I235fc1aa947ba57faa7aef5e7e7ce9241b315fff
Reviewed-on: https://skia-review.googlesource.com/99704
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | include/gpu/GrContext.h | 20 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 12 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 4 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 4 | ||||
-rw-r--r-- | tests/ImageTest.cpp | 24 | ||||
-rw-r--r-- | tests/SurfaceTest.cpp | 127 | ||||
-rw-r--r-- | tools/gpu/GrTest.cpp | 7 |
7 files changed, 191 insertions, 7 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 3c79ac74ce..d0ca90e0f0 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -216,6 +216,26 @@ public: /** Access the context capabilities */ const GrCaps* caps() const { return fCaps.get(); } + /** + * Can a SkImage be created with the given color type. + */ + bool colorTypeSupportedAsImage(SkColorType) const; + + /** + * Can a SkSurface be created with the given color type. To check whether MSAA is supported + * use maxSurfaceSampleCountForColorType(). + */ + bool colorTypeSupportedAsSurface(SkColorType colorType) const { + return this->maxSurfaceSampleCountForColorType(colorType) > 0; + } + + /** + * Gets the maximum supported sample count for a color type. 1 is returned if only non-MSAA + * rendering is supported for the color type. 0 is returned if rendering to this color type + * is not supported at all. + */ + int maxSurfaceSampleCountForColorType(SkColorType) const; + /* * Create a new render target context backed by a deferred-style * GrRenderTargetProxy. We guarantee that "asTextureProxy" will succeed for diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 0d481ac6ef..05908f4889 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -420,6 +420,18 @@ size_t GrContext::getResourceCachePurgeableBytes() const { //////////////////////////////////////////////////////////////////////////////// +bool GrContext::colorTypeSupportedAsImage(SkColorType colorType) const { + GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *this->caps()); + return this->caps()->isConfigTexturable(config); +} + +int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const { + GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *this->caps()); + return this->caps()->maxRenderTargetSampleCount(config); +} + +//////////////////////////////////////////////////////////////////////////////// + void GrContext::TextBlobCacheOverBudgetCB(void* data) { SkASSERT(data); // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 2f12073f8a..6527064b93 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -455,6 +455,10 @@ public: /** Creates a texture directly in the backend API without wrapping it in a GrTexture. This is only to be used for testing (particularly for testing the methods that import an externally created texture into Skia. Must be matched with a call to deleteTestingOnlyTexture(). */ + GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, SkColorType, + bool isRenderTarget, GrMipMapped); + + /** Older version based on GrPixelConfig. Currently the preferred one above devolves to this. */ virtual GrBackendTexture createTestingOnlyBackendTexture( void* pixels, int w, int h, GrPixelConfig config, diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 8d81665511..8759f3eeed 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -334,7 +334,9 @@ bool validate_backend_texture(GrContext* ctx, const GrBackendTexture& tex, GrPix return false; } - if (ctx->caps()->getRenderTargetSampleCount(sampleCnt, *config) != sampleCnt) { + // We don't require that the client gave us an exact valid sample cnt. However, it must be + // less than the max supported sample count and 1 if MSAA is unsupported for the color type. + if (!ctx->caps()->getRenderTargetSampleCount(sampleCnt, *config)) { return false; } diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index a1472d42dd..9a89000748 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -38,6 +38,7 @@ #include "GrResourceCache.h" #include "GrTest.h" #include "GrTexture.h" +#include "SkGr.h" #endif using namespace sk_gpu_test; @@ -486,6 +487,29 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkImage_drawAbandonedGpuImage, reporter, c surface->getCanvas()->drawImage(image, 0, 0); } +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrContext_colorTypeSupportedAsImage, reporter, ctxInfo) { + for (int ct = 0; ct < kLastEnum_SkColorType; ++ct) { + static constexpr int kSize = 10; + SkColorType colorType = static_cast<SkColorType>(ct); + bool can = ctxInfo.grContext()->colorTypeSupportedAsImage(colorType); + auto* gpu = ctxInfo.grContext()->contextPriv().getGpu(); + GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture( + nullptr, kSize, kSize, colorType, false, GrMipMapped::kNo); + auto img = + SkImage::MakeFromTexture(ctxInfo.grContext(), backendTex, kTopLeft_GrSurfaceOrigin, + colorType, kOpaque_SkAlphaType, nullptr); + REPORTER_ASSERT(reporter, can == SkToBool(img), + "%d, colorTypeSupportedAsImage:%d, actual:%d, ct:%d", can, SkToBool(img), + colorType); + + img.reset(); + ctxInfo.grContext()->flush(); + if (backendTex.isValid()) { + gpu->deleteTestingOnlyBackendTexture(&backendTex); + } + } +} + #endif class EmptyGenerator : public SkImageGenerator { diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp index 7acd3ebbe2..de1cd9a984 100644 --- a/tests/SurfaceTest.cpp +++ b/tests/SurfaceTest.cpp @@ -19,13 +19,17 @@ #include "Test.h" #if SK_SUPPORT_GPU +#include <vector> #include "GrContext.h" #include "GrContextPriv.h" -#include "GrRenderTargetContext.h" #include "GrGpu.h" +#include "GrGpuResourcePriv.h" +#include "GrRenderTargetContext.h" #include "GrResourceProvider.h" #include "GrTest.h" -#include <vector> +#include "SkGpuDevice.h" +#include "SkImage_Gpu.h" +#include "SkSurface_Gpu.h" #endif #include <initializer_list> @@ -88,6 +92,121 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) { } #endif +#if SK_SUPPORT_GPU +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrContext_colorTypeSupportedAsSurface, reporter, ctxInfo) { + for (int ct = 0; ct < kLastEnum_SkColorType; ++ct) { + static constexpr int kSize = 10; + + SkColorType colorType = static_cast<SkColorType>(ct); + auto info = SkImageInfo::Make(kSize, kSize, colorType, kOpaque_SkAlphaType, nullptr); + bool can = ctxInfo.grContext()->colorTypeSupportedAsSurface(colorType); + auto surf = SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kYes, info, 1, + nullptr); + REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d", + colorType, can, SkToBool(surf)); + + auto* gpu = ctxInfo.grContext()->contextPriv().getGpu(); + GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture( + nullptr, kSize, kSize, colorType, true, GrMipMapped::kNo); + surf = SkSurface::MakeFromBackendTexture(ctxInfo.grContext(), backendTex, + kTopLeft_GrSurfaceOrigin, 0, colorType, nullptr, + nullptr); + REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d", + colorType, can, SkToBool(surf)); + + surf = SkSurface::MakeFromBackendTextureAsRenderTarget(ctxInfo.grContext(), backendTex, + kTopLeft_GrSurfaceOrigin, 1, + colorType, nullptr, nullptr); + REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d", + colorType, can, SkToBool(surf)); + + surf.reset(); + ctxInfo.grContext()->flush(); + if (backendTex.isValid()) { + gpu->deleteTestingOnlyBackendTexture(&backendTex); + } + + static constexpr int kSampleCnt = 2; + + can = ctxInfo.grContext()->maxSurfaceSampleCountForColorType(colorType) >= kSampleCnt; + surf = SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kYes, info, kSampleCnt, + nullptr); + REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d", + colorType, can, SkToBool(surf)); + + backendTex = gpu->createTestingOnlyBackendTexture(nullptr, kSize, kSize, colorType, true, + GrMipMapped::kNo); + surf = SkSurface::MakeFromBackendTexture(ctxInfo.grContext(), backendTex, + kTopLeft_GrSurfaceOrigin, kSampleCnt, colorType, + nullptr, nullptr); + REPORTER_ASSERT(reporter, can == SkToBool(surf), + "colorTypeSupportedAsSurface:%d, surf:%d, ct:%d", can, SkToBool(surf), + colorType); + // Ensure that the sample count stored on the resulting SkSurface is a valid value. + if (surf) { + auto* rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext(); + int storedCnt = rtc->numStencilSamples(); + int allowedCnt = ctxInfo.grContext()->caps()->getSampleCount( + storedCnt, rtc->asSurfaceProxy()->config()); + REPORTER_ASSERT(reporter, storedCnt == allowedCnt, + "Should store an allowed sample count (%d vs %d)", allowedCnt, + storedCnt); + } + + surf = SkSurface::MakeFromBackendTextureAsRenderTarget(ctxInfo.grContext(), backendTex, + kTopLeft_GrSurfaceOrigin, kSampleCnt, + colorType, nullptr, nullptr); + REPORTER_ASSERT(reporter, can == SkToBool(surf), + "colorTypeSupportedAsSurface:%d, surf:%d, ct:%d", can, SkToBool(surf), + colorType); + if (surf) { + auto* rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext(); + int storedCnt = rtc->numStencilSamples(); + int allowedCnt = ctxInfo.grContext()->caps()->getSampleCount( + storedCnt, rtc->asSurfaceProxy()->config()); + REPORTER_ASSERT(reporter, storedCnt == allowedCnt, + "Should store an allowed sample count (%d vs %d)", allowedCnt, + storedCnt); + } + + surf.reset(); + ctxInfo.grContext()->flush(); + if (backendTex.isValid()) { + gpu->deleteTestingOnlyBackendTexture(&backendTex); + } + } +} + +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrContext_maxSurfaceSamplesForColorType, reporter, ctxInfo) { + for (int ct = 0; ct < kLastEnum_SkColorType; ++ct) { + static constexpr int kSize = 10; + + SkColorType colorType = static_cast<SkColorType>(ct); + int max = ctxInfo.grContext()->maxSurfaceSampleCountForColorType(colorType); + if (!max) { + continue; + } + auto* gpu = ctxInfo.grContext()->contextPriv().getGpu(); + GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture( + nullptr, kSize, kSize, colorType, true, GrMipMapped::kNo); + + auto info = SkImageInfo::Make(kSize, kSize, colorType, kOpaque_SkAlphaType, nullptr); + auto surf = SkSurface::MakeFromBackendTexture(ctxInfo.grContext(), backendTex, + kTopLeft_GrSurfaceOrigin, max, + colorType, nullptr, nullptr); + REPORTER_ASSERT(reporter, surf); + if (!surf) { + continue; + } + int sampleCnt = ((SkSurface_Gpu*)(surf.get())) + ->getDevice() + ->accessRenderTargetContext() + ->numStencilSamples(); + REPORTER_ASSERT(reporter, sampleCnt == max, "Exected: %d, actual: %d", max, sampleCnt); + } +} +#endif + static void test_canvas_peek(skiatest::Reporter* reporter, sk_sp<SkSurface>& surface, const SkImageInfo& requestInfo, @@ -437,10 +556,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacepeekTexture_Gpu, reporter, ctxInfo) { #endif #if SK_SUPPORT_GPU -#include "GrGpuResourcePriv.h" -#include "SkGpuDevice.h" -#include "SkImage_Gpu.h" -#include "SkSurface_Gpu.h" static SkBudgeted is_budgeted(const sk_sp<SkSurface>& surf) { SkSurface_Gpu* gsurf = (SkSurface_Gpu*)surf.get(); diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index 829ddcbe89..06d9b831a5 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -182,6 +182,13 @@ void GrGpu::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* #endif +GrBackendTexture GrGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, + SkColorType colorType, bool isRenderTarget, + GrMipMapped mipMapped) { + GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *this->caps()); + return this->createTestingOnlyBackendTexture(pixels, w, h, config, isRenderTarget, mipMapped); +} + #if GR_CACHE_STATS void GrResourceCache::getStats(Stats* stats) const { stats->reset(); |