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:
parent
e45d32abe1
commit
85ae7159c9
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user