diff options
author | Robert Phillips <robertphillips@google.com> | 2018-02-13 10:20:13 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-13 16:03:50 +0000 |
commit | d76e56d93c27856b10d6636882a5ffcd79a9d967 (patch) | |
tree | e20c54f11793cfbc57fa4b878d95931ae80a020d | |
parent | 366093f2124c38fa5c590c9ed2d1811817fed8ee (diff) |
Add SkCharacterization creation helper to GrContextThreadSafeProxy
Change-Id: I8ad7cf335f2b586cf501eaa70573690fbbd53efa
Reviewed-on: https://skia-review.googlesource.com/106105
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | include/gpu/GrBackendSurface.h | 63 | ||||
-rw-r--r-- | include/gpu/GrCaps.h | 9 | ||||
-rw-r--r-- | include/gpu/GrContext.h | 41 | ||||
-rw-r--r-- | include/gpu/mock/GrMockTypes.h | 3 | ||||
-rw-r--r-- | include/private/SkSurfaceCharacterization.h | 33 | ||||
-rw-r--r-- | src/core/SkDeferredDisplayListRecorder.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrBackendSurface.cpp | 49 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 37 | ||||
-rw-r--r-- | src/gpu/GrOnFlushResourceProvider.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 3 | ||||
-rw-r--r-- | src/gpu/mock/GrMockCaps.h | 20 | ||||
-rw-r--r-- | src/gpu/mock/GrMockGpu.cpp | 2 | ||||
-rw-r--r-- | src/gpu/mtl/GrMtlCaps.h | 5 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 29 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.h | 3 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 10 | ||||
-rw-r--r-- | tests/DeferredDisplayListTest.cpp | 65 |
18 files changed, 359 insertions, 30 deletions
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h index ffe422d0a7..d28ef8af98 100644 --- a/include/gpu/GrBackendSurface.h +++ b/include/gpu/GrBackendSurface.h @@ -16,6 +16,69 @@ #include "vk/GrVkTypes.h" #endif +class SK_API GrBackendFormat { +public: + // Creates an invalid backend format. + GrBackendFormat() : fValid(false) {} + + static GrBackendFormat MakeGL(GrGLenum format, GrGLenum target) { + return GrBackendFormat(format, target); + } + +#ifdef SK_VULKAN + static GrBackendFormat MakeVK(VkFormat format) { + return GrBackendFormat(format); + } +#endif + + static GrBackendFormat MakeMock(GrPixelConfig config) { + return GrBackendFormat(config); + } + + GrBackend backend() const {return fBackend; } + + // If the backend API is GL, these return a pointer to the format and target. Otherwise + // it returns nullptr. + const GrGLenum* getGLFormat() const; + const GrGLenum* getGLTarget() const; + +#ifdef SK_VULKAN + // If the backend API is Vulkan, this returns a pointer to a VkFormat. Otherwise + // it returns nullptr + const VkFormat* getVkFormat() const; +#endif + + // If the backend API is Mock, this returns a pointer to a GrPixelConfig. Otherwise + // it returns nullptr. + const GrPixelConfig* getMockFormat() const; + + // Returns true if the backend format has been initialized. + bool isValid() const { return fValid; } + +private: + GrBackendFormat(GrGLenum format, GrGLenum target); + +#ifdef SK_VULKAN + GrBackendFormat(const VkFormat vkFormat); +#endif + + GrBackendFormat(const GrPixelConfig config); + + GrBackend fBackend; + bool fValid; + + union { + struct { + GrGLenum fGLTarget; // GL_TEXTURE_2D, GL_TEXTURE_EXTERNAL or GL_TEXTURE_RECTANGLE + GrGLenum fGLFormat; // the sized, internal format of the GL resource + }; +#ifdef SK_VULKAN + VkFormat fVkFormat; +#endif + GrPixelConfig fMockFormat; + }; +}; + class SK_API GrBackendTexture { public: // Creates an invalid backend texture. diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h index 0f03f162f0..1b81b18fcb 100644 --- a/include/gpu/GrCaps.h +++ b/include/gpu/GrCaps.h @@ -15,6 +15,7 @@ #include "SkRefCnt.h" #include "SkString.h" +class GrBackendFormat; class GrBackendRenderTarget; class GrBackendTexture; struct GrContextOptions; @@ -200,7 +201,7 @@ public: bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const; /** - * Returns true if the GrBackendTexutre can we used with the supplied SkColorType. If it is + * Returns true if the GrBackendTexture can be used with the supplied SkColorType. If it is * compatible, the passed in GrPixelConfig will be set to a config that matches the backend * format and requested SkColorType. */ @@ -209,6 +210,12 @@ public: virtual bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType, GrPixelConfig*) const = 0; + // TODO: replace validateBackendTexture and validateBackendRenderTarget with calls to + // getConfigFromBackendFormat? + // TODO: it seems like we could pass the full SkImageInfo and validate its colorSpace too + virtual bool getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct, + GrPixelConfig*) const = 0; + protected: /** Subclasses must call this at the end of their constructors in order to apply caps overrides requested by the client. Note that overrides will only reduce the caps never diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index df9b85bacd..aac0d8dc5a 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -17,6 +17,7 @@ #include "GrContextOptions.h" class GrAtlasGlyphCache; +class GrBackendFormat; class GrBackendSemaphore; class GrContextPriv; class GrContextThreadSafeProxy; @@ -36,17 +37,18 @@ class GrResourceCache; class GrResourceProvider; class GrSamplerState; class GrSurfaceProxy; +class GrSwizzle; class GrTextBlobCache; class GrTextContext; class GrTextureProxy; class GrVertexBuffer; struct GrVkBackendContext; -class GrSwizzle; -class SkTraceMemoryDump; class SkImage; +class SkSurfaceCharacterization; class SkSurfaceProps; class SkTaskGroup; +class SkTraceMemoryDump; class SK_API GrContext : public SkRefCnt { public: @@ -434,6 +436,41 @@ class GrContextThreadSafeProxy : public SkRefCnt { public: bool matches(GrContext* context) const { return context->uniqueID() == fContextUniqueID; } + /** + * Create a surface characterization for a DDL that will be replayed into the GrContext + * that created this proxy. On failure the resulting characterization will be invalid (i.e., + * "!c.isValid()"). + * + * @param cacheMaxResourceBytes The max resource bytes limit that will be in effect when the + * DDL created with this characterization is replayed. + * Note: the contract here is that the DDL will be created as + * if it had a full 'cacheMaxResourceBytes' to use. If replayed + * into a GrContext that already has locked GPU memory, the + * replay can exceed the budget. To rephrase, all resource + * allocation decisions are made at record time and at playback + * time the budget limits will be ignored. + * @param ii The image info specifying properties of the SkSurface that + * the DDL created with this characterization will be replayed + * into. + * Note: Ganesh doesn't make use of the SkImageInfo's alphaType + * @param backendFormat Information about the format of the GPU surface that will + * back the SkSurface upon replay + * @param sampleCount The sample count of the SkSurface that the DDL created with + * this characterization will be replayed into + * @param origin The origin of the SkSurface that the DDL created with this + * characterization will be replayed into + * @param surfaceProps The surface properties of the SkSurface that the DDL created + * with this characterization will be replayed into + * @param isMipMapped Will the surface the DDL will be replayed into have space + * allocated for mipmaps? + */ + SkSurfaceCharacterization createCharacterization( + size_t cacheMaxResourceBytes, + const SkImageInfo& ii, const GrBackendFormat& backendFormat, + int sampleCount, GrSurfaceOrigin origin, + const SkSurfaceProps& surfaceProps, + bool isMipMapped); + private: // DDL TODO: need to add unit tests for backend & maybe options GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, diff --git a/include/gpu/mock/GrMockTypes.h b/include/gpu/mock/GrMockTypes.h index 0954c5eadc..49601cb55e 100644 --- a/include/gpu/mock/GrMockTypes.h +++ b/include/gpu/mock/GrMockTypes.h @@ -12,7 +12,8 @@ #include "../private/GrTypesPriv.h" struct GrMockTextureInfo { - int fID; + GrPixelConfig fConfig; + int fID; }; /** diff --git a/include/private/SkSurfaceCharacterization.h b/include/private/SkSurfaceCharacterization.h index 9e5f40df64..48c22351b3 100644 --- a/include/private/SkSurfaceCharacterization.h +++ b/include/private/SkSurfaceCharacterization.h @@ -36,8 +36,7 @@ public: enum class MipMapped : bool { kNo = false, kYes = true }; SkSurfaceCharacterization() - : fCacheMaxResourceCount(0) - , fCacheMaxResourceBytes(0) + : fCacheMaxResourceBytes(0) , fOrigin(kBottomLeft_GrSurfaceOrigin) , fWidth(0) , fHeight(0) @@ -56,9 +55,10 @@ public: SkSurfaceCharacterization& operator=(const SkSurfaceCharacterization& other) = default; GrContextThreadSafeProxy* contextInfo() const { return fContextInfo.get(); } - int cacheMaxResourceCount() const { return fCacheMaxResourceCount; } size_t cacheMaxResourceBytes() const { return fCacheMaxResourceBytes; } + bool isValid() const { return kUnknown_GrPixelConfig != fConfig; } + GrSurfaceOrigin origin() const { return fOrigin; } int width() const { return fWidth; } int height() const { return fHeight; } @@ -73,9 +73,30 @@ public: private: friend class SkSurface_Gpu; // for 'set' + friend class GrContextThreadSafeProxy; // for private ctor + + SkSurfaceCharacterization(sk_sp<GrContextThreadSafeProxy> contextInfo, + size_t cacheMaxResourceBytes, + GrSurfaceOrigin origin, int width, int height, + GrPixelConfig config, GrFSAAType FSAAType, int stencilCnt, + Textureable isTextureable, MipMapped isMipMapped, + sk_sp<SkColorSpace> colorSpace, + const SkSurfaceProps& surfaceProps) + : fContextInfo(std::move(contextInfo)) + , fCacheMaxResourceBytes(cacheMaxResourceBytes) + , fOrigin(origin) + , fWidth(width) + , fHeight(height) + , fConfig(config) + , fFSAAType(FSAAType) + , fStencilCnt(stencilCnt) + , fIsTextureable(isTextureable) + , fIsMipMapped(isMipMapped) + , fColorSpace(std::move(colorSpace)) + , fSurfaceProps(surfaceProps) { + } void set(sk_sp<GrContextThreadSafeProxy> contextInfo, - int cacheMaxResourceCount, size_t cacheMaxResourceBytes, GrSurfaceOrigin origin, int width, int height, @@ -89,7 +110,6 @@ private: SkASSERT(MipMapped::kNo == isMipMapped || Textureable::kYes == isTextureable); fContextInfo = contextInfo; - fCacheMaxResourceCount = cacheMaxResourceCount; fCacheMaxResourceBytes = cacheMaxResourceBytes; fOrigin = origin; @@ -105,7 +125,6 @@ private: } sk_sp<GrContextThreadSafeProxy> fContextInfo; - int fCacheMaxResourceCount; size_t fCacheMaxResourceBytes; GrSurfaceOrigin fOrigin; @@ -130,6 +149,8 @@ public: , fSurfaceProps(0, kUnknown_SkPixelGeometry) { } + bool isValid() const { return false; } + int width() const { return fWidth; } int height() const { return fHeight; } SkColorSpace* colorSpace() const { return fColorSpace.get(); } diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp index 14e5926637..b3c0679724 100644 --- a/src/core/SkDeferredDisplayListRecorder.cpp +++ b/src/core/SkDeferredDisplayListRecorder.cpp @@ -41,6 +41,10 @@ SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() { bool SkDeferredDisplayListRecorder::init() { SkASSERT(!fSurface); + if (!fCharacterization.isValid()) { + return false; + } + #ifdef SK_RASTER_RECORDER_IMPLEMENTATION // Use raster right now to allow threading const SkImageInfo ii = SkImageInfo::Make(fCharacterization.width(), fCharacterization.height(), diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp index 16fa793d25..dcfbe3b5a5 100644 --- a/src/gpu/GrBackendSurface.cpp +++ b/src/gpu/GrBackendSurface.cpp @@ -14,6 +14,55 @@ #include "vk/GrVkUtil.h" #endif +GrBackendFormat::GrBackendFormat(GrGLenum format, GrGLenum target) + : fBackend(kOpenGL_GrBackend) + , fValid(true) + , fGLTarget(target) + , fGLFormat(format) { +} + +const GrGLenum* GrBackendFormat::getGLFormat() const { + if (this->isValid() && kOpenGL_GrBackend == fBackend) { + return &fGLFormat; + } + return nullptr; +} + +const GrGLenum* GrBackendFormat::getGLTarget() const { + if (this->isValid() && kOpenGL_GrBackend == fBackend) { + return &fGLTarget; + } + return nullptr; +} + +#ifdef SK_VULKAN +GrBackendFormat::GrBackendFormat(VkFormat vkFormat) + : fBackend(kVulkan_GrBackend) + , fValid(true) + , fVkFormat(vkFormat) { +} + +const VkFormat* GrBackendFormat::getVkFormat() const { + if (this->isValid() && kVulkan_GrBackend == fBackend) { + return &fVkFormat; + } + return nullptr; +} +#endif + +GrBackendFormat::GrBackendFormat(GrPixelConfig config) + : fBackend(kMock_GrBackend) + , fValid(true) + , fMockFormat(config) { +} + +const GrPixelConfig* GrBackendFormat::getMockFormat() const { + if (this->isValid() && kMock_GrBackend == fBackend) { + return &fMockFormat; + } + return nullptr; +} + #ifdef SK_VULKAN GrBackendTexture::GrBackendTexture(int width, int height, diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 1700c1be1d..8a5417ed17 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -334,6 +334,42 @@ sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() { return fThreadSafeProxy; } +SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization( + size_t cacheMaxResourceBytes, + const SkImageInfo& ii, const GrBackendFormat& backendFormat, + int sampleCnt, GrSurfaceOrigin origin, + const SkSurfaceProps& surfaceProps, + bool isMipMapped) { + if (!backendFormat.isValid()) { + 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 (!fCaps->mipMapSupport()) { + isMipMapped = false; + } + + GrPixelConfig config = kUnknown_GrPixelConfig; + if (!fCaps->getConfigFromBackendFormat(backendFormat, ii.colorType(), &config)) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + // This surface characterization factory assumes that the resulting characterization is + // textureable. + if (!fCaps->isConfigTexturable(config)) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + return SkSurfaceCharacterization(sk_ref_sp<GrContextThreadSafeProxy>(this), + cacheMaxResourceBytes, + origin, ii.width(), ii.height(), config, FSAAType, sampleCnt, + SkSurfaceCharacterization::Textureable(true), + SkSurfaceCharacterization::MipMapped(isMipMapped), + ii.refColorSpace(), surfaceProps); +} + void GrContext::abandonContext() { ASSERT_SINGLE_OWNER @@ -1081,6 +1117,7 @@ bool GrContext::validPMUPMConversionExists() { ////////////////////////////////////////////////////////////////////////////// +// DDL TODO: remove 'maxResources' void GrContext::getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const { ASSERT_SINGLE_OWNER if (maxResources) { diff --git a/src/gpu/GrOnFlushResourceProvider.h b/src/gpu/GrOnFlushResourceProvider.h index 633abe1411..224160de5f 100644 --- a/src/gpu/GrOnFlushResourceProvider.h +++ b/src/gpu/GrOnFlushResourceProvider.h @@ -57,9 +57,6 @@ public: * Any OnFlushCallbackObject associated with a path renderer will need to be deleted. */ virtual bool retainOnFreeGpuResources() { return false; } - -private: - typedef SkRefCnt INHERITED; }; /* diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 0b2e57067f..56f25ea4cc 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -2539,3 +2539,13 @@ bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkCo return validate_sized_format(fbInfo->fFormat, ct, config, fStandard); } +bool GrGLCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct, + GrPixelConfig* config) const { + const GrGLenum* glFormat = format.getGLFormat(); + if (!glFormat) { + return false; + } + return validate_sized_format(*glFormat, ct, config, fStandard); +} + + diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index c7812be20e..6c8fe5ccd9 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -407,6 +407,9 @@ public: bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType, GrPixelConfig*) const override; + bool getConfigFromBackendFormat(const GrBackendFormat&, SkColorType, + GrPixelConfig*) const override; + private: enum ExternalFormatUsage { kTexImage_ExternalFormatUsage, diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h index 1e448516d7..d96a690b31 100644 --- a/src/gpu/mock/GrMockCaps.h +++ b/src/gpu/mock/GrMockCaps.h @@ -72,8 +72,14 @@ public: } bool validateBackendTexture(const GrBackendTexture& tex, SkColorType, - GrPixelConfig*) const override { - return SkToBool(tex.getMockTextureInfo()); + GrPixelConfig* config) const override { + const GrMockTextureInfo* texInfo = tex.getMockTextureInfo(); + if (!texInfo) { + return false; + } + + *config = texInfo->fConfig; + return true; } bool validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType, @@ -81,6 +87,16 @@ public: return false; } + bool getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct, + GrPixelConfig* config) const override { + const GrPixelConfig* mockFormat = format.getMockFormat(); + if (!mockFormat) { + return false; + } + *config = *mockFormat; + return true; + } + private: static const int kMaxSampleCnt = 16; diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp index da6b21aea0..9d1661be44 100644 --- a/src/gpu/mock/GrMockGpu.cpp +++ b/src/gpu/mock/GrMockGpu.cpp @@ -69,6 +69,7 @@ sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgete GrMipMapsStatus mipMapsStatus = mipLevelCount > 1 ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated; GrMockTextureInfo info; + info.fConfig = desc.fConfig; info.fID = NextInternalTextureID(); if (desc.fFlags & kRenderTarget_GrSurfaceFlag) { return sk_sp<GrTexture>( @@ -94,6 +95,7 @@ GrBackendTexture GrMockGpu::createTestingOnlyBackendTexture(void* pixels, int w, GrPixelConfig config, bool isRT, GrMipMapped) { GrMockTextureInfo info; + info.fConfig = config; info.fID = NextExternalTextureID(); fOutstandingTestingOnlyTextureIDs.add(info.fID); return GrBackendTexture(w, h, config, info); diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h index 935cb07822..c23a9028ca 100644 --- a/src/gpu/mtl/GrMtlCaps.h +++ b/src/gpu/mtl/GrMtlCaps.h @@ -57,6 +57,11 @@ public: return false; } + bool getConfigFromBackendFormat(const GrBackendFormat&, SkColorType, + GrPixelConfig*) const override { + return false; + } + private: void initFeatureSet(MTLFeatureSet featureSet); diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 8af81190af..3fc5a08acb 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -416,11 +416,7 @@ int GrVkCaps::maxRenderTargetSampleCount(GrPixelConfig config) const { return table[table.count() - 1]; } -bool validate_image_info(const GrVkImageInfo* imageInfo, SkColorType ct, GrPixelConfig* config) { - if (!imageInfo) { - return false; - } - VkFormat format = imageInfo->fFormat; +bool validate_image_info(VkFormat format, SkColorType ct, GrPixelConfig* config) { *config = kUnknown_GrPixelConfig; switch (ct) { @@ -478,11 +474,30 @@ bool validate_image_info(const GrVkImageInfo* imageInfo, SkColorType ct, GrPixel bool GrVkCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct, GrPixelConfig* config) const { - return validate_image_info(tex.getVkImageInfo(), ct, config); + const GrVkImageInfo* imageInfo = tex.getVkImageInfo(); + if (!imageInfo) { + return false; + } + + return validate_image_info(imageInfo->fFormat, ct, config); } bool GrVkCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct, GrPixelConfig* config) const { - return validate_image_info(rt.getVkImageInfo(), ct, config); + const GrVkImageInfo* imageInfo = rt.getVkImageInfo(); + if (!imageInfo) { + return false; + } + + return validate_image_info(imageInfo->fFormat, ct, config); +} + +bool GrVkCaps::getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct, + GrPixelConfig* config) const { + const VkFormat* vkFormat = format.getVkFormat(); + if (!vkFormat) { + return false; + } + return validate_image_info(*vkFormat, ct, config); } diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h index 3449dd2ccc..b6c8bebdc9 100644 --- a/src/gpu/vk/GrVkCaps.h +++ b/src/gpu/vk/GrVkCaps.h @@ -113,6 +113,9 @@ public: bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType, GrPixelConfig*) const override; + bool getConfigFromBackendFormat(const GrBackendFormat&, SkColorType, + GrPixelConfig*) const override; + private: enum VkVendor { kAMD_VkVendor = 4098, diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 04333ae508..bb748b8d7e 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -174,7 +174,7 @@ bool SkSurface_Gpu::onCharacterize(SkSurfaceCharacterization* data) const { bool mipmapped = rtc->asTextureProxy() ? GrMipMapped::kYes == rtc->asTextureProxy()->mipMapped() : false; - data->set(ctx->threadSafeProxy(), maxResourceCount, maxResourceBytes, + data->set(ctx->threadSafeProxy(), maxResourceBytes, rtc->origin(), rtc->width(), rtc->height(), rtc->colorSpaceInfo().config(), rtc->fsaaType(), rtc->numStencilSamples(), SkSurfaceCharacterization::Textureable(SkToBool(rtc->asTextureProxy())), @@ -188,8 +188,13 @@ bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& data) const { GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext(); GrContext* ctx = fDevice->context(); + if (!data.isValid()) { + return false; + } + // As long as the current state if the context allows for greater or equal resources, // we allow the DDL to be replayed. + // DDL TODO: should we just remove the resource check and ignore the cache limits on playback? int maxResourceCount; size_t maxResourceBytes; ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes); @@ -210,7 +215,6 @@ bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& data) const { } return data.contextInfo() && data.contextInfo()->matches(ctx) && - data.cacheMaxResourceCount() <= maxResourceCount && data.cacheMaxResourceBytes() <= maxResourceBytes && data.origin() == rtc->origin() && data.width() == rtc->width() && data.height() == rtc->height() && data.config() == rtc->colorSpaceInfo().config() && @@ -220,7 +224,7 @@ bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& data) const { } bool SkSurface_Gpu::onDraw(const SkDeferredDisplayList* ddl) { - if (!this->isCompatible(ddl->characterization())) { + if (!ddl || !this->isCompatible(ddl->characterization())) { return false; } diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp index 468a3695e9..13989a18d7 100644 --- a/tests/DeferredDisplayListTest.cpp +++ b/tests/DeferredDisplayListTest.cpp @@ -20,6 +20,51 @@ #include "SkSurfaceProps.h" #include "Test.h" +#include "gl/GrGLDefines.h" +#ifdef SK_VULKAN +#include "vk/GrVkDefines.h" +#endif + +static GrBackendFormat create_backend_format(GrContext* context, SkColorType colorType) { + const GrCaps* caps = context->caps(); + + switch (context->contextPriv().getBackend()) { + case kOpenGL_GrBackend: + if (kRGBA_8888_SkColorType == colorType) { + GrGLenum format = caps->srgbSupport() ? GR_GL_SRGB8_ALPHA8 : GR_GL_RGBA8; + return GrBackendFormat::MakeGL(format, GR_GL_TEXTURE_2D); + } else if (kRGBA_F16_SkColorType == colorType) { + return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D); + } + break; +#ifdef SK_VULKAN + case kVulkan_GrBackend: + if (kRGBA_8888_SkColorType == colorType) { + VkFormat format = caps->srgbSupport() ? VK_FORMAT_R8G8B8A8_SRGB + : VK_FORMAT_B8G8R8A8_UNORM; + return GrBackendFormat::MakeVK(format); + } else if (kRGBA_F16_SkColorType == colorType) { + return GrBackendFormat::MakeVK(VK_FORMAT_R16G16B16A16_SFLOAT); + } + break; +#endif + case kMock_GrBackend: + if (kRGBA_8888_SkColorType == colorType) { + GrPixelConfig config = caps->srgbSupport() ? kSRGBA_8888_GrPixelConfig + : kRGBA_8888_GrPixelConfig; + return GrBackendFormat::MakeMock(config); + } else if (kRGBA_F16_SkColorType == colorType) { + return GrBackendFormat::MakeMock(kRGBA_half_GrPixelConfig); + } + break; + default: + return GrBackendFormat(); // return an invalid format + } + + return GrBackendFormat(); // return an invalid format +} + + class SurfaceParameters { public: static const int kNumParams = 9; @@ -80,8 +125,20 @@ public: return nullptr; } - SkSurfaceCharacterization c; - SkAssertResult(s->characterize(&c)); + int maxResourceCount; + size_t maxResourceBytes; + context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes); + + // Note that Ganesh doesn't make use of the SkImageInfo's alphaType + SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType, + kPremul_SkAlphaType, fColorSpace); + + GrBackendFormat backendFormat = create_backend_format(context, fColorType); + + SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization( + maxResourceBytes, ii, backendFormat, fSampleCount, + fOrigin, fSurfaceProps, fShouldCreateMipMaps); + SkAssertResult(c.isValid()); SkDeferredDisplayListRecorder r(c); SkCanvas* canvas = r.getCanvas(); @@ -161,6 +218,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) SurfaceParameters params; ddl = params.createDDL(context); + SkAssertResult(ddl); // The DDL should draw into an SkSurface created with the same parameters sk_sp<SkSurface> s = params.make(context); @@ -212,9 +270,6 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) size_t maxResourceBytes; context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes); - context->setResourceCacheLimits(maxResourceCount/2, maxResourceBytes); - REPORTER_ASSERT(reporter, !s->draw(ddl.get())); - context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2); REPORTER_ASSERT(reporter, !s->draw(ddl.get())); |