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>
This commit is contained in:
Brian Salomon 2018-02-01 18:02:35 -05:00 committed by Skia Commit-Bot
parent e45d32abe1
commit 85ae7159c9
7 changed files with 191 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

@ -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 {

View File

@ -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();

View File

@ -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();