From 5bb82cbecd740d21b92e8d2944280ab6eb6af7a6 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Fri, 2 Feb 2018 13:51:50 -0500 Subject: Revert "Revert "Revert "Revert "Redefine the meaning of sample counts in GPU backend."""" This reverts commit 18c52a7b52211de5d0dcd86dc048adef758c6c75. Also relands "More sample count cleanup:" and "Add new GrContext queries for imagability, surfacability, and max sample count of color types" Bug: skia: Change-Id: I4028105a3a1f16ce3944e134619eb6245af6b947 Reviewed-on: https://skia-review.googlesource.com/102940 Reviewed-by: Brian Salomon Commit-Queue: Brian Salomon --- src/gpu/gl/GrGLCaps.cpp | 47 +++++++++++++++++++++------- src/gpu/gl/GrGLCaps.h | 11 ++----- src/gpu/gl/GrGLGpu.cpp | 59 ++++++++++++++++++++---------------- src/gpu/gl/GrGLRenderTarget.cpp | 2 +- src/gpu/gl/GrGLStencilAttachment.cpp | 2 +- 5 files changed, 73 insertions(+), 48 deletions(-) (limited to 'src/gpu/gl') diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 3b90676be1..99f56564d8 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -1958,6 +1958,8 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions, for (int i = 0; i < kGrPixelConfigCnt; ++i) { if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) { + // We assume that MSAA rendering is supported only if we support non-MSAA rendering. + SkASSERT(ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags); if ((kGL_GrGLStandard == ctxInfo.standard() && (ctxInfo.version() >= GR_GL_VER(4,2) || ctxInfo.hasExtension("GL_ARB_internalformat_query"))) || @@ -1970,10 +1972,15 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions, int* temp = new int[count]; GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count, temp); + // GL has a concept of MSAA rasterization with a single sample but we do not. + if (count && temp[count - 1] == 1) { + --count; + SkASSERT(!count || temp[count -1] > 1); + } fConfigTable[i].fColorSampleCounts.setCount(count+1); - // We initialize our supported values with 0 (no msaa) and reverse the order + // We initialize our supported values with 1 (no msaa) and reverse the order // returned by GL so that the array is ascending. - fConfigTable[i].fColorSampleCounts[0] = 0; + fConfigTable[i].fColorSampleCounts[0] = 1; for (int j = 0; j < count; ++j) { fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1]; } @@ -1982,14 +1989,16 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions, } else { // Fake out the table using some semi-standard counts up to the max allowed sample // count. - int maxSampleCnt = 0; + int maxSampleCnt = 1; if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) { GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &maxSampleCnt); } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) { GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &maxSampleCnt); } + // Chrome has a mock GL implementation that returns 0. + maxSampleCnt = SkTMax(1, maxSampleCnt); - static constexpr int kDefaultSamples[] = {0, 1, 2, 4, 8}; + static constexpr int kDefaultSamples[] = {1, 2, 4, 8}; int count = SK_ARRAY_COUNT(kDefaultSamples); for (; count > 0; --count) { if (kDefaultSamples[count - 1] <= maxSampleCnt) { @@ -2000,6 +2009,9 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions, fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples); } } + } else if (ConfigInfo::kRenderable_Flag & fConfigTable[i].fFlags) { + fConfigTable[i].fColorSampleCounts.setCount(1); + fConfigTable[i].fColorSampleCounts[0] = 1; } } @@ -2034,7 +2046,7 @@ bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* // If the src is a texture, we can implement the blit as a draw assuming the config is // renderable. - if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) { + if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) { desc->fOrigin = kBottomLeft_GrSurfaceOrigin; desc->fFlags = kRenderTarget_GrSurfaceFlag; desc->fConfig = src->config(); @@ -2059,14 +2071,14 @@ bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin; bool rectsMustMatchForBlitFramebuffer = false; bool disallowSubrectForBlitFramebuffer = false; - if (src->numColorSamples() && + if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() & kResolveMustBeFull_BlitFrambufferFlag)) { rectsMustMatchForBlitFramebuffer = true; disallowSubrectForBlitFramebuffer = true; // Mirroring causes rects to mismatch later, don't allow it. originForBlitFramebuffer = src->origin(); - } else if (src->numColorSamples() && (this->blitFramebufferSupportFlags() & - kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) { + } else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() & + kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) { rectsMustMatchForBlitFramebuffer = true; // Mirroring causes rects to mismatch later, don't allow it. originForBlitFramebuffer = src->origin(); @@ -2456,18 +2468,31 @@ void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) { } } -int GrGLCaps::getSampleCount(int requestedCount, GrPixelConfig config) const { +int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const { + requestedCount = SkTMax(1, requestedCount); int count = fConfigTable[config].fColorSampleCounts.count(); - if (!count || !this->isConfigRenderable(config, true)) { + if (!count) { return 0; } + if (1 == requestedCount) { + return fConfigTable[config].fColorSampleCounts[0] == 1 ? 1 : 0; + } + for (int i = 0; i < count; ++i) { if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) { return fConfigTable[config].fColorSampleCounts[i]; } } - return fConfigTable[config].fColorSampleCounts[count-1]; + return 0; +} + +int GrGLCaps::maxRenderTargetSampleCount(GrPixelConfig config) const { + const auto& table = fConfigTable[config].fColorSampleCounts; + if (!table.count()) { + return 0; + } + return table[table.count() - 1]; } bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* config, diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index fd49a65598..7a443e49b0 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -112,19 +112,12 @@ public: GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo, const GrGLInterface* glInterface); - int getSampleCount(int requestedCount, GrPixelConfig config) const override; - bool isConfigTexturable(GrPixelConfig config) const override { return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag); } - bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override { - if (withMSAA) { - return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag); - } else { - return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag); - } - } + int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override; + int maxRenderTargetSampleCount(GrPixelConfig config) const override; bool isConfigCopyable(GrPixelConfig config) const override { // In GL we have three ways to be able to copy. CopyTexImage, blit, and draw. CopyTexImage diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index ae31495b06..b4a0341174 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -545,7 +545,7 @@ sk_sp GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTe surfDesc.fWidth = backendTex.width(); surfDesc.fHeight = backendTex.height(); surfDesc.fConfig = backendTex.config(); - surfDesc.fSampleCnt = 0; + surfDesc.fSampleCnt = 1; GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated; @@ -581,7 +581,10 @@ sk_sp GrGLGpu::onWrapRenderableBackendTexture(const GrBackendTexture& surfDesc.fWidth = backendTex.width(); surfDesc.fHeight = backendTex.height(); surfDesc.fConfig = backendTex.config(); - surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, backendTex.config()); + surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config()); + if (surfDesc.fSampleCnt < 1) { + return nullptr; + } GrGLRenderTarget::IDDesc rtIDDesc; if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) { @@ -616,7 +619,8 @@ sk_sp GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTa desc.fWidth = backendRT.width(); desc.fHeight = backendRT.height(); desc.fConfig = backendRT.config(); - desc.fSampleCnt = this->caps()->getSampleCount(backendRT.sampleCnt(), backendRT.config()); + desc.fSampleCnt = + this->caps()->getRenderTargetSampleCount(backendRT.sampleCnt(), backendRT.config()); return GrGLRenderTarget::MakeWrapped(this, desc, idDesc, backendRT.stencilBits()); } @@ -645,7 +649,7 @@ sk_sp GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBacken surfDesc.fWidth = tex.width(); surfDesc.fHeight = tex.height(); surfDesc.fConfig = tex.config(); - surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, tex.config()); + surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config()); GrGLRenderTarget::IDDesc rtIDDesc; if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) { @@ -686,7 +690,7 @@ bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOri } // If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target. - if (dstSurface->asRenderTarget() && dstSurface->asRenderTarget()->numColorSamples() > 0) { + if (dstSurface->asRenderTarget() && dstSurface->asRenderTarget()->numColorSamples() > 1) { ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); } @@ -704,7 +708,7 @@ bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOri tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; tempDrawInfo->fTempSurfaceDesc.fWidth = width; tempDrawInfo->fTempSurfaceDesc.fHeight = height; - tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; + tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1; tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config(); @@ -1277,13 +1281,13 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, idDesc->fTexFBOID = 0; SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) == this->caps()->usesMixedSamples()); - idDesc->fIsMixedSampled = desc.fSampleCnt > 0 && this->caps()->usesMixedSamples(); + idDesc->fIsMixedSampled = desc.fSampleCnt > 1 && this->caps()->usesMixedSamples(); GrGLenum status; GrGLenum colorRenderbufferFormat = 0; // suppress warning - if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) { + if (desc.fSampleCnt > 1 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) { goto FAILED; } @@ -1296,7 +1300,7 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, // the texture bound to the other. The exception is the IMG multisample extension. With this // extension the texture is multisampled when rendered to and then auto-resolves it when it is // rendered from. - if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { + if (desc.fSampleCnt > 1 && this->glCaps().usesMSAARenderBuffers()) { GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID)); GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); if (!idDesc->fRTFBOID || @@ -1313,7 +1317,7 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, // below here we may bind the FBO fHWBoundRenderTargetUniqueID.makeInvalid(); if (idDesc->fRTFBOID != idDesc->fTexFBOID) { - SkASSERT(desc.fSampleCnt > 0); + SkASSERT(desc.fSampleCnt > 1); GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbufferID)); if (!renderbuffer_storage_msaa(*fGLContext, desc.fSampleCnt, @@ -1338,7 +1342,7 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, fStats.incRenderTargetBinds(); GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID)); - if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { + if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 1) { GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, texInfo.fTarget, @@ -1415,7 +1419,7 @@ sk_sp GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, const GrMipLevel texels[], int mipLevelCount) { // We fail if the MSAA was requested and is not available. - if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) { + if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt > 1) { //SkDebugf("MSAA RT requested but not supported on this platform."); return return_null_texture(); } @@ -1524,7 +1528,7 @@ void inline get_stencil_rb_sizes(const GrGLInterface* gl, int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) { static const int kSize = 16; - SkASSERT(this->caps()->isConfigRenderable(config, false)); + SkASSERT(this->caps()->isConfigRenderable(config)); if (!this->glCaps().hasStencilFormatBeenDeterminedForConfig(config)) { // Default to unsupported, set this if we find a stencil format that works. int firstWorkingStencilFormatIndex = -1; @@ -1694,7 +1698,7 @@ GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); // we do this "if" so that we don't call the multisample // version on a GL that doesn't have an MSAA extension. - if (samples > 0) { + if (samples > 1) { SkAssertResult(renderbuffer_storage_msaa(*fGLContext, samples, sFmt.fInternalFormat, @@ -2133,7 +2137,7 @@ bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConf GrSurfaceDesc desc; desc.fConfig = rtConfig; desc.fWidth = desc.fHeight = 16; - if (this->glCaps().isConfigRenderable(rtConfig, false)) { + if (this->glCaps().isConfigRenderable(rtConfig)) { desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fOrigin = kBottomLeft_GrSurfaceOrigin; temp = this->createTexture(desc, SkBudgeted::kNo); @@ -2194,7 +2198,7 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrig tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag; tempDrawInfo->fTempSurfaceDesc.fWidth = width; tempDrawInfo->fTempSurfaceDesc.fHeight = height; - tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; + tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1; tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. tempDrawInfo->fTempSurfaceFit = this->glCaps().partialFBOReadIsSlow() ? SkBackingFit::kExact : SkBackingFit::kApprox; @@ -2872,10 +2876,13 @@ void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabl GL_CALL(Enable(GR_GL_RASTER_MULTISAMPLE)); fHWRasterMultisampleEnabled = kYes_TriState; } - if (rt->numStencilSamples() != fHWNumRasterSamples) { - SkASSERT(rt->numStencilSamples() <= this->caps()->maxRasterSamples()); - GL_CALL(RasterSamples(rt->numStencilSamples(), GR_GL_TRUE)); - fHWNumRasterSamples = rt->numStencilSamples(); + int numStencilSamples = rt->numStencilSamples(); + // convert to GL's understanding of sample counts where 0 means nonMSAA. + numStencilSamples = 1 == numStencilSamples ? 0 : numStencilSamples; + if (numStencilSamples != fHWNumRasterSamples) { + SkASSERT(numStencilSamples <= this->caps()->maxRasterSamples()); + GL_CALL(RasterSamples(numStencilSamples, GR_GL_TRUE)); + fHWNumRasterSamples = numStencilSamples; } } else { if (kNo_TriState != fHWRasterMultisampleEnabled) { @@ -3334,8 +3341,8 @@ static inline bool can_blit_framebuffer_for_copy_surface( } } if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) { - if (srcRT && srcRT->numColorSamples()) { - if (dstRT && !dstRT->numColorSamples()) { + if (srcRT && srcRT->numColorSamples() > 1) { + if (dstRT && 1 == dstRT->numColorSamples()) { return false; } if (SkRect::Make(srcRect) != srcRT->getBoundsRect()) { @@ -3344,7 +3351,7 @@ static inline bool can_blit_framebuffer_for_copy_surface( } } if (GrGLCaps::kNoMSAADst_BlitFramebufferFlag & blitFramebufferFlags) { - if (dstRT && dstRT->numColorSamples() > 0) { + if (dstRT && dstRT->numColorSamples() > 1) { return false; } } @@ -3354,12 +3361,12 @@ static inline bool can_blit_framebuffer_for_copy_surface( } } else if (GrGLCaps::kNoFormatConversionForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) { const GrRenderTarget* srcRT = src->asRenderTarget(); - if (srcRT && srcRT->numColorSamples() && dst->config() != src->config()) { + if (srcRT && srcRT->numColorSamples() > 1 && dst->config() != src->config()) { return false; } } if (GrGLCaps::kRectsMustMatchForMSAASrc_BlitFramebufferFlag & blitFramebufferFlags) { - if (srcRT && srcRT->numColorSamples()) { + if (srcRT && srcRT->numColorSamples() > 1) { if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) { return false; } @@ -3376,7 +3383,7 @@ static bool rt_has_msaa_render_buffer(const GrGLRenderTarget* rt, const GrGLCaps // 1) It's multisampled // 2) We're using an extension with separate MSAA renderbuffers // 3) It's not FBO 0, which is special and always auto-resolves - return rt->numColorSamples() > 0 && glCaps.usesMSAARenderBuffers() && rt->renderFBOID() != 0; + return rt->numColorSamples() > 1 && glCaps.usesMSAARenderBuffers() && rt->renderFBOID() != 0; } static inline bool can_copy_texsubimage(const GrSurface* dst, GrSurfaceOrigin dstOrigin, diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 443128d4d4..6f3714c504 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -224,7 +224,7 @@ int GrGLRenderTarget::msaaSamples() const { if (fTexFBOID == kUnresolvableFBOID || fTexFBOID != fRTFBOID) { // If the render target's FBO is external (fTexFBOID == kUnresolvableFBOID), or if we own // the render target's FBO (fTexFBOID == fRTFBOID) then we use the provided sample count. - return SkTMax(1, this->numStencilSamples()); + return this->numStencilSamples(); } // When fTexFBOID == fRTFBOID, we either are not using MSAA, or MSAA is auto resolving, so use diff --git a/src/gpu/gl/GrGLStencilAttachment.cpp b/src/gpu/gl/GrGLStencilAttachment.cpp index aa813ed50e..5c07a7d383 100644 --- a/src/gpu/gl/GrGLStencilAttachment.cpp +++ b/src/gpu/gl/GrGLStencilAttachment.cpp @@ -14,7 +14,7 @@ size_t GrGLStencilAttachment::onGpuMemorySize() const { uint64_t size = this->width(); size *= this->height(); size *= fFormat.fTotalBits; - size *= SkTMax(1,this->numSamples()); + size *= this->numSamples(); return static_cast(size / 8); } -- cgit v1.2.3