diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 6e8e0cec1c..6fed008fc3 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -82,19 +82,22 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions, // GL driver that our performance and correctness tuning was performed on. To avoid losing // that we strip the ANGLE info and for the rest of caps setup pretend we're directly on top of // the GL driver. Note that this means that some driver workarounds are likely implemented at - // two levels of the stack (Skia and ANGLE) but we haven't determined which. + // two levels of the stack (Skia and ANGLE) but we haven't determined which. There may be some + // checks that we do want to know if we're backed by angle (e.g. msaa bgra) so we pass in a flag + // to tell us that. if (ctxInfo.angleBackend() == GrGLANGLEBackend::kOpenGL) { - this->init(contextOptions, ctxInfo.makeNonAngle(), glInterface); + this->init(contextOptions, ctxInfo.makeNonAngle(), glInterface, true); // A major caveat is that ANGLE does not allow client side arrays. fPreferClientSideDynamicBuffers = false; } else { - this->init(contextOptions, ctxInfo, glInterface); + this->init(contextOptions, ctxInfo, glInterface, false); } } void GrGLCaps::init(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo, - const GrGLInterface* gli) { + const GrGLInterface* gli, + bool driverIsActuallyAngle) { GrGLStandard standard = ctxInfo.standard(); // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set sk_ignore_unused_variable(standard); @@ -803,7 +806,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } // Requires msaa support, ES compatibility have already been detected. - this->initFormatTable(ctxInfo, gli, formatWorkarounds); + this->initFormatTable(ctxInfo, gli, formatWorkarounds, driverIsActuallyAngle); this->finishInitialization(contextOptions); @@ -1361,7 +1364,8 @@ void GrGLCaps::setColorTypeFormat(GrColorType colorType, GrGLFormat format) { } void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli, - const FormatWorkarounds& formatWorkarounds) { + const FormatWorkarounds& formatWorkarounds, + bool driverIsActuallyAngle) { GrGLStandard standard = ctxInfo.standard(); // standard can be unused (optimized away) if SK_ASSUME_GL_ES is set sk_ignore_unused_variable(standard); @@ -1934,24 +1938,6 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa FormatInfo& info = this->getFormatInfo(GrGLFormat::kBGRA8); info.fFormatType = FormatType::kNormalizedFixedPoint; - // We currently only use the renderbuffer format when allocating msaa renderbuffers, so we - // are making decisions here based on that use case. The GL_EXT_texture_format_BGRA8888 - // extension adds BGRA color renderbuffer support for ES 2.0, but this does not guarantee - // support for MSAA renderbuffers. Additionally, the renderable support was added in a later - // revision of the extension. So it is possible for older drivers to support the extension - // but only an early revision of it without renderable support. We have no way of - // distinguishing between the two. The GL_APPLE_texture_format_BGRA8888 does not add support - // for BGRA color renderbuffers at all. Ideally, for both cases we would use RGBA8 for our - // format for the MSAA buffer. In the GL_EXT_texture_format_BGRA8888 case we can still - // make the resolve BGRA and which will work for glBlitFramebuffer for resolving which just - // requires the src and dst be bindable to FBOs. However, we can't do this in the current - // world since some devices (e.g. chromium & angle) require the formats in glBlitFramebuffer - // to match. We don't have a way to really check this during resolve since we only actually - // have GrBackendFormat that is shared by the GrGLRenderTarget. We always set the - // renderbuffer format to RGBA8 but disable MSAA unless we have the APPLE extension. - // Once we break those up into different surface we can revisit doing this change. - info.fInternalFormatForRenderbuffer = GR_GL_RGBA8; - info.fDefaultExternalFormat = GR_GL_BGRA; info.fDefaultExternalType = GR_GL_UNSIGNED_BYTE; info.fDefaultColorType = GrColorType::kBGRA_8888; @@ -1981,9 +1967,42 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa if (GR_IS_GR_GL_ES(standard)) { if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) { + // The GL_EXT_texture_format_BGRA8888 extension adds BGRA color renderbuffer support + // for ES 2.0. The extension adds BGRA to the supported renerable formats in table + // 4.5. In ES 2.0. All the extensions that add multisample support, all reference + // table 4.5 as the formats that are supported. Thus we can use msaaRenderFlags. + // Additionally, the renderable support was added in a later revision of the + // extension. So it is possible for older drivers to support the extension but only + // an early revision of it without renderable support. We have no way of + // distinguishing between the two and assume renderable. + + info.fFlags = FormatInfo::kTexturable_Flag - | FormatInfo::kTransfers_Flag - | nonMSAARenderFlags; + | FormatInfo::kTransfers_Flag; + // Only enable BGRA msaa if we know we're going through Angle. The spec for + // GL_EXT_texture_format_BGRA8888 was updated in 2016 to add support for GL_BGRA_EXT + // as a sized, renderable format. But we may end up running on old drivers written + // against earlier version of the spec. Also the interactions between all these + // extensions are very suibtle and it wouldn't be hard for a driver to mess them up. + // We are confident that Angle does it as we expect. Our non-angle test bots do seem + // to pass and draw correctly so we could consider enabling this more broadly in the + // future. + if (driverIsActuallyAngle) { + // Angle incorrectly requires GL_BGRA8_EXT for the interalFormat for both ES2 + // and ES3 even though this extension does not define that value. The extension + // only defines GL_BGRA_EXT as an internal format. + info.fInternalFormatForRenderbuffer = GR_GL_BGRA8; + info.fFlags |= msaaRenderFlags; + } else { + // It is not clear what the correct format to use on ES3 is. This extension only + // defines GL_BGRA_EXT. That is definitely the correct thing to use on ES2, but + // its unclear whether that is valid in ES3 or if it wants something like + // GL_BGRA8_EXT (which is only defined in the apple extenstion). For now we set + // everything to use BGRA since its the only explicitly defined value. Until we + // enable MSAA for non-angle this is a moot point. + info.fInternalFormatForRenderbuffer = GR_GL_BGRA; + info.fFlags |= nonMSAARenderFlags; + } // GL_EXT_texture storage has defined interactions with // GL_EXT_texture_format_BGRA8888. However, ES3 supports glTexStorage but // without GL_EXT_texture_storage it does not allow the BGRA8 sized internal format. @@ -2006,6 +2025,9 @@ void GrGLCaps::initFormatTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa info.fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kTransfers_Flag | msaaRenderFlags; + // The GL_APPLE_texture_format_BGRA8888 does not add support for BGRA color + // renderbuffers at all so we use RGBA here. + info.fInternalFormatForRenderbuffer = GR_GL_RGBA8; supportsBGRATexStorage = true; } } diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index 64f907eff1..dc0249c319 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -500,7 +500,8 @@ private: GrColorType memoryColorType, ExternalFormatUsage usage, GrGLenum* externalFormat, GrGLenum* externalType) const; - void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*); + void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*, + bool wasOriginallyAngle); void initGLSL(const GrGLContextInfo&, const GrGLInterface*); struct FormatWorkarounds { @@ -530,7 +531,8 @@ private: void initBlendEqationSupport(const GrGLContextInfo&); void initStencilSupport(const GrGLContextInfo&); // This must be called after initFSAASupport(). - void initFormatTable(const GrGLContextInfo&, const GrGLInterface*, const FormatWorkarounds&); + void initFormatTable(const GrGLContextInfo&, const GrGLInterface*, const FormatWorkarounds&, + bool driverIsActuallyAngle); void setupSampleCounts(const GrGLContextInfo&, const GrGLInterface*); bool onSurfaceSupportsWritePixels(const GrSurface*) const override; bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,