diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h index 53bd1cd8df69..6e86e4b4514c 100644 --- a/src/gpu/GrCaps.h +++ b/src/gpu/GrCaps.h @@ -240,8 +240,17 @@ class GrCaps : public SkRefCnt { virtual bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, int sampleCount = 1) const = 0; + virtual bool isRenderTargetAsColorTypeRenderable(GrColorType ct, + const GrBackendRenderTarget& rt) const { + return this->isFormatAsColorTypeRenderable(ct, rt.getBackendFormat(), rt.sampleCnt()); + } + virtual bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const = 0; + virtual bool isRenderTargetRenderable(const GrBackendRenderTarget& rt) const { + return this->isFormatRenderable(rt.getBackendFormat(), rt.sampleCnt()); + } + // Find a sample count greater than or equal to the requested count which is supported for a // render target of the given format or 0 if no such sample count is supported. If the requested // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0. diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 023d510cb6ba..3f2b059d13a7 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -359,7 +359,7 @@ sk_sp GrGpu::wrapBackendRenderTarget(const GrBackendRenderTarget const GrCaps* caps = this->caps(); - if (!caps->isFormatRenderable(backendRT.getBackendFormat(), backendRT.sampleCnt())) { + if (!caps->isRenderTargetRenderable(backendRT)) { return nullptr; } diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index ee78717d52f9..1b3111115c48 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -4481,6 +4481,20 @@ bool GrGLCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendForm return this->isFormatRenderable(f, sampleCount); } +bool GrGLCaps::isRenderTargetAsColorTypeRenderable(GrColorType ct, + const GrBackendRenderTarget& rt) const { + int sampleCntToCheck; + GrGLFramebufferInfo fbi; + if (rt.getGLFramebufferInfo(&fbi) && fbi.fFBOID == 0) { + // FBO0 has different multisampling rules than offscreen render targets. If the user wrapped + // FBO0 and told us it's multisampled, just trust that the msaa is valid. + sampleCntToCheck = 1; + } else { + sampleCntToCheck = rt.sampleCnt(); + } + return this->isFormatAsColorTypeRenderable(ct, rt.getBackendFormat(), sampleCntToCheck); +} + bool GrGLCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const { if (format.textureType() == GrTextureType::kRectangle && !this->rectangleTextureSupport()) { return false; @@ -4491,6 +4505,19 @@ bool GrGLCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount return this->isFormatRenderable(format.asGLFormat(), sampleCount); } +bool GrGLCaps::isRenderTargetRenderable(const GrBackendRenderTarget& rt) const { + int sampleCntToCheck; + GrGLFramebufferInfo fbi; + if (rt.getGLFramebufferInfo(&fbi) && fbi.fFBOID == 0) { + // FBO0 has different multisampling rules than offscreen render targets. If the user wrapped + // FBO0 and told us it's multisampled, just trust that the msaa is valid. + sampleCntToCheck = 1; + } else { + sampleCntToCheck = rt.sampleCnt(); + } + return this->isFormatRenderable(rt.getBackendFormat(), sampleCntToCheck); +} + int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrGLFormat format) const { const FormatInfo& info = this->getFormatInfo(format); diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index 8897cb9ec0f5..864e9827e6ab 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -125,7 +125,10 @@ class GrGLCaps : public GrCaps { bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, int sampleCount = 1) const override; + bool isRenderTargetAsColorTypeRenderable(GrColorType, + const GrBackendRenderTarget&) const override; bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; + bool isRenderTargetRenderable(const GrBackendRenderTarget&) const override; bool isFormatRenderable(GrGLFormat format, int sampleCount) const { return sampleCount <= this->maxRenderTargetSampleCount(format); } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 49b98e78c179..00250aae7078 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -784,12 +784,19 @@ sk_sp GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTa return nullptr; } - const auto format = backendRT.getBackendFormat().asGLFormat(); - if (!this->glCaps().isFormatRenderable(format, backendRT.sampleCnt())) { + if (!this->glCaps().isRenderTargetRenderable(backendRT)) { return nullptr; } - int sampleCount = this->glCaps().getRenderTargetSampleCount(backendRT.sampleCnt(), format); + const auto format = backendRT.getBackendFormat().asGLFormat(); + int sampleCount; + if (info.fFBOID == 0) { + // FBO0 has different multisampling rules than offscreen render targets. If the user wrapped + // FBO0 and told us it's multisampled, just trust the provided sample count. + sampleCount = backendRT.sampleCnt(); + } else { + sampleCount = this->glCaps().getRenderTargetSampleCount(backendRT.sampleCnt(), format); + } GrGLRenderTarget::IDs rtIDs; if (sampleCount <= 1) { diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 70c4f9f10e15..adaa00bc7d2b 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -579,7 +579,7 @@ bool validate_backend_render_target(const GrCaps* caps, const GrBackendRenderTar return false; } - if (!caps->isFormatAsColorTypeRenderable(grCT, rt.getBackendFormat(), rt.sampleCnt())) { + if (!caps->isRenderTargetAsColorTypeRenderable(grCT, rt)) { return false; }