diff options
Diffstat (limited to 'src/gpu/GrGpu.cpp')
-rw-r--r-- | src/gpu/GrGpu.cpp | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 955d57ddb0..eb005d110a 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -72,22 +72,68 @@ bool GrGpu::isACopyNeededForTextureParams(int width, int height, return false; } +/** + * Prior to creating a texture, make sure the type of texture being created is + * supported by calling check_texture_creation_params. + * + * @param caps The capabilities of the GL device. + * @param desc The descriptor of the texture to create. + * @param isRT Indicates if the texture can be a render target. + * @param texels The texel data for the mipmap levels + * @param mipLevelCount The number of GrMipLevels in 'texels' + */ +static bool check_texture_creation_params(const GrCaps& caps, const GrSurfaceDesc& desc, + bool* isRT, + const GrMipLevel texels[], int mipLevelCount) { + if (!caps.isConfigTexturable(desc.fConfig)) { + return false; + } + + if (GrPixelConfigIsSint(desc.fConfig) && mipLevelCount > 1) { + return false; + } + + *isRT = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); + if (*isRT && !caps.isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { + return false; + } + + // We currently do not support multisampled textures + if (!*isRT && desc.fSampleCnt > 0) { + return false; + } + + if (*isRT) { + int maxRTSize = caps.maxRenderTargetSize(); + if (desc.fWidth > maxRTSize || desc.fHeight > maxRTSize) { + return false; + } + } else { + int maxSize = caps.maxTextureSize(); + if (desc.fWidth > maxSize || desc.fHeight > maxSize) { + return false; + } + } + + return true; +} + sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budgeted, const GrMipLevel texels[], int mipLevelCount) { GR_CREATE_TRACE_MARKER_CONTEXT("GrGpu", "createTexture", fContext); GrSurfaceDesc desc = origDesc; - GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo; - if (!this->caps()->validateSurfaceDesc(desc, mipMapped)) { + const GrCaps* caps = this->caps(); + bool isRT = false; + bool textureCreationParamsValid = check_texture_creation_params(*caps, desc, &isRT, + texels, mipLevelCount); + if (!textureCreationParamsValid) { return nullptr; } - bool isRT = desc.fFlags & kRenderTarget_GrSurfaceFlag; - if (isRT) { - desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig); - } + desc.fSampleCnt = caps->getSampleCount(desc.fSampleCnt, desc.fConfig); // Attempt to catch un- or wrongly initialized sample counts. - SkASSERT(desc.fSampleCnt > 0 && desc.fSampleCnt <= 64); + SkASSERT(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64); if (mipLevelCount && (desc.fFlags & kPerformInitialClear_GrSurfaceFlag)) { return nullptr; @@ -96,7 +142,7 @@ sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted this->handleDirtyContext(); sk_sp<GrTexture> tex = this->onCreateTexture(desc, budgeted, texels, mipLevelCount); if (tex) { - if (!this->caps()->reuseScratchTextures() && !isRT) { + if (!caps->reuseScratchTextures() && !isRT) { tex->resourcePriv().removeScratchKey(); } fStats.incTextureCreates(); @@ -133,11 +179,8 @@ sk_sp<GrTexture> GrGpu::wrapBackendTexture(const GrBackendTexture& backendTex, sk_sp<GrTexture> GrGpu::wrapRenderableBackendTexture(const GrBackendTexture& backendTex, int sampleCnt, GrWrapOwnership ownership) { this->handleDirtyContext(); - if (sampleCnt < 1) { - return nullptr; - } if (!this->caps()->isConfigTexturable(backendTex.config()) || - !this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config())) { + !this->caps()->isConfigRenderable(backendTex.config(), sampleCnt > 0)) { return nullptr; } @@ -154,7 +197,7 @@ sk_sp<GrTexture> GrGpu::wrapRenderableBackendTexture(const GrBackendTexture& bac } sk_sp<GrRenderTarget> GrGpu::wrapBackendRenderTarget(const GrBackendRenderTarget& backendRT) { - if (0 == this->caps()->getRenderTargetSampleCount(backendRT.sampleCnt(), backendRT.config())) { + if (!this->caps()->isConfigRenderable(backendRT.config(), backendRT.sampleCnt() > 0)) { return nullptr; } this->handleDirtyContext(); @@ -163,14 +206,14 @@ sk_sp<GrRenderTarget> GrGpu::wrapBackendRenderTarget(const GrBackendRenderTarget sk_sp<GrRenderTarget> GrGpu::wrapBackendTextureAsRenderTarget(const GrBackendTexture& tex, int sampleCnt) { - if (0 == this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config())) { + this->handleDirtyContext(); + if (!this->caps()->isConfigRenderable(tex.config(), sampleCnt > 0)) { return nullptr; } int maxSize = this->caps()->maxTextureSize(); if (tex.width() > maxSize || tex.height() > maxSize) { return nullptr; } - this->handleDirtyContext(); return this->onWrapBackendTextureAsRenderTarget(tex, sampleCnt); } @@ -219,7 +262,7 @@ bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, // Check to see if we're going to request that the caller draw when drawing is not possible. if (!srcSurface->asTexture() || - !this->caps()->isConfigRenderable(tempDrawInfo->fTempSurfaceDesc.fConfig)) { + !this->caps()->isConfigRenderable(tempDrawInfo->fTempSurfaceDesc.fConfig, false)) { // If we don't have a fallback to a straight read then fail. if (kRequireDraw_DrawPreference == *drawPreference) { return false; |