aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2018-02-01 18:02:35 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-02 00:16:28 +0000
commit85ae7159c9c8a9186a4c7e74304eabb35bca9a79 (patch)
tree8f1cf3aa71803889d1f2b1b84b43013395f188ac
parente45d32abe13239e3482fc4a13f006ab72073252a (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.h20
-rw-r--r--src/gpu/GrContext.cpp12
-rw-r--r--src/gpu/GrGpu.h4
-rw-r--r--src/image/SkSurface_Gpu.cpp4
-rw-r--r--tests/ImageTest.cpp24
-rw-r--r--tests/SurfaceTest.cpp127
-rw-r--r--tools/gpu/GrTest.cpp7
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();