| Index: src/gpu/gl/GrGLCaps.cpp
|
| diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
|
| index ad0f2caf78619944c53ad4f10cce6988eb1a660f..40405fd55c1549660127ce6b6ffc4951177b0a03 100644
|
| --- a/src/gpu/gl/GrGLCaps.cpp
|
| +++ b/src/gpu/gl/GrGLCaps.cpp
|
| @@ -47,19 +47,52 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
|
|
|
| fReadPixelsSupportedCache.reset();
|
|
|
| - this->init(ctxInfo, glInterface);
|
| -
|
| fShaderCaps.reset(SkNEW_ARGS(GrGLSLCaps, (contextOptions,
|
| ctxInfo, glInterface, *this)));
|
|
|
| - this->applyOptionsOverrides(contextOptions);
|
| + this->init(contextOptions, ctxInfo, glInterface);
|
| }
|
|
|
| -void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
| +void GrGLCaps::init(const GrContextOptions& contextOptions,
|
| + const GrGLContextInfo& ctxInfo,
|
| + const GrGLInterface* gli) {
|
| GrGLStandard standard = ctxInfo.standard();
|
| GrGLVersion version = ctxInfo.version();
|
|
|
| /**************************************************************************
|
| + * Caps specific to GrGLSLCaps
|
| + **************************************************************************/
|
| +
|
| + GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
|
| + glslCaps->fGLSLGeneration = ctxInfo.glslGeneration();
|
| +
|
| + if (kGLES_GrGLStandard == standard) {
|
| + if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
|
| + glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
|
| + glslCaps->fFBFetchSupport = true;
|
| + glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
|
| + glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
|
| + }
|
| + else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
|
| + // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
|
| + glslCaps->fFBFetchNeedsCustomOutput = false;
|
| + glslCaps->fFBFetchSupport = true;
|
| + glslCaps->fFBFetchColorName = "gl_LastFragData[0]";
|
| + glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
|
| + }
|
| + else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
|
| + // The arm extension also requires an additional flag which we will set onResetContext
|
| + glslCaps->fFBFetchNeedsCustomOutput = false;
|
| + glslCaps->fFBFetchSupport = true;
|
| + glslCaps->fFBFetchColorName = "gl_LastFragColorARM";
|
| + glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
|
| + }
|
| + }
|
| +
|
| + // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
|
| + glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
|
| +
|
| + /**************************************************************************
|
| * Caps specific to GrGLCaps
|
| **************************************************************************/
|
|
|
| @@ -210,12 +243,63 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
| fMultisampleDisableSupport = false;
|
| }
|
|
|
| - this->initFSAASupport(ctxInfo, gli);
|
| - this->initStencilFormats(ctxInfo);
|
| + /**************************************************************************
|
| + * GrShaderCaps fields
|
| + **************************************************************************/
|
| +
|
| + glslCaps->fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering");
|
| +
|
| + if (glslCaps->fPathRenderingSupport) {
|
| + if (kGL_GrGLStandard == standard) {
|
| + // We only support v1.3+ of GL_NV_path_rendering which allows us to
|
| + // set individual fragment inputs with ProgramPathFragmentInputGen. The API
|
| + // additions are detected by checking the existence of the function.
|
| + glslCaps->fPathRenderingSupport =
|
| + ctxInfo.hasExtension("GL_EXT_direct_state_access") &&
|
| + ((ctxInfo.version() >= GR_GL_VER(4, 3) ||
|
| + ctxInfo.hasExtension("GL_ARB_program_interface_query")) &&
|
| + gli->fFunctions.fProgramPathFragmentInputGen);
|
| + }
|
| + else {
|
| + glslCaps->fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
|
| + }
|
| + }
|
| +
|
| + // For now these two are equivalent but we could have dst read in shader via some other method
|
| + glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
|
| +
|
| + // Enable supported shader-related caps
|
| + if (kGL_GrGLStandard == standard) {
|
| + glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
|
| + ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
|
| + GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
|
| + glslCaps->fShaderDerivativeSupport = true;
|
| + // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
|
| + glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
|
| + ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
|
| + }
|
| + else {
|
| + glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
|
| + ctxInfo.hasExtension("GL_OES_standard_derivatives");
|
| + }
|
| +
|
| + // We need dual source blending and the ability to disable multisample in order to support mixed
|
| + // samples in every corner case.
|
| + if (fMultisampleDisableSupport && glslCaps->fDualSourceBlendingSupport) {
|
| + // We understand "mixed samples" to mean the collective capability of 3 different extensions
|
| + glslCaps->fMixedSamplesSupport =
|
| + ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") &&
|
| + ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage") &&
|
| + ctxInfo.hasExtension("GL_EXT_raster_multisample");
|
| + }
|
|
|
| /**************************************************************************
|
| * GrCaps fields
|
| **************************************************************************/
|
| +
|
| + this->initFSAASupport(ctxInfo, gli);
|
| + this->initStencilFormats(ctxInfo);
|
| +
|
| if (kGL_GrGLStandard == standard) {
|
| // we could also look for GL_ATI_separate_stencil extension or
|
| // GL_EXT_stencil_two_side but they use different function signatures
|
| @@ -233,18 +317,19 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
| // Disabling advanced blend until we can resolve various bugs
|
| #if 0
|
| if (kIntel_GrGLVendor != ctxInfo.vendor()) {
|
| - if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent") ||
|
| - ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
|
| + if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) {
|
| fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
|
| - } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced") ||
|
| - ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
|
| + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
|
| + } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) {
|
| + fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
|
| + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
|
| + } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) {
|
| fBlendEquationSupport = kAdvanced_BlendEquationSupport;
|
| - } else {
|
| - fBlendEquationSupport = kBasic_BlendEquationSupport;
|
| + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction;
|
| + } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) {
|
| + fBlendEquationSupport = kAdvanced_BlendEquationSupport;
|
| + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction;
|
| }
|
| - } else {
|
| - // On Intel platforms, KHR_blend_equation_advanced is not conformant.
|
| - fBlendEquationSupport = kBasic_BlendEquationSupport;
|
| }
|
| #endif
|
| if (kGL_GrGLStandard == standard) {
|
| @@ -338,6 +423,10 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
|
|
| this->initConfigTexturableTable(ctxInfo, gli);
|
| this->initConfigRenderableTable(ctxInfo);
|
| + glslCaps->initShaderPrecisionTable(ctxInfo, gli);
|
| +
|
| + this->applyOptionsOverrides(contextOptions);
|
| + glslCaps->applyOptionsOverrides(contextOptions);
|
| }
|
|
|
| void GrGLCaps::initConfigRenderableTable(const GrGLContextInfo& ctxInfo) {
|
| @@ -917,108 +1006,6 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options,
|
| fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
|
| fFBFetchColorName = NULL;
|
| fFBFetchExtensionString = NULL;
|
| - this->init(ctxInfo, gli, glCaps);
|
| - this->applyOptionsOverrides(options);
|
| -}
|
| -
|
| -void GrGLSLCaps::init(const GrGLContextInfo& ctxInfo,
|
| - const GrGLInterface* gli,
|
| - const GrGLCaps& glCaps) {
|
| - fGLSLGeneration = ctxInfo.glslGeneration();
|
| - GrGLStandard standard = ctxInfo.standard();
|
| - GrGLVersion version = ctxInfo.version();
|
| -
|
| - /**************************************************************************
|
| - * Caps specific to GrGLSLCaps
|
| - **************************************************************************/
|
| -
|
| - if (kGLES_GrGLStandard == standard) {
|
| - if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
|
| - fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0));
|
| - fFBFetchSupport = true;
|
| - fFBFetchColorName = "gl_LastFragData[0]";
|
| - fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
|
| - }
|
| - else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
|
| - // Actually, we haven't seen an ES3.0 device with this extension yet, so we don't know
|
| - fFBFetchNeedsCustomOutput = false;
|
| - fFBFetchSupport = true;
|
| - fFBFetchColorName = "gl_LastFragData[0]";
|
| - fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
|
| - }
|
| - else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
|
| - // The arm extension also requires an additional flag which we will set onResetContext
|
| - fFBFetchNeedsCustomOutput = false;
|
| - fFBFetchSupport = true;
|
| - fFBFetchColorName = "gl_LastFragColorARM";
|
| - fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
|
| - }
|
| - }
|
| -
|
| - // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
|
| - fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
|
| -
|
| - /**************************************************************************
|
| - * GrShaderCaps fields
|
| - **************************************************************************/
|
| -
|
| - fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering");
|
| -
|
| - if (fPathRenderingSupport) {
|
| - if (kGL_GrGLStandard == standard) {
|
| - // We only support v1.3+ of GL_NV_path_rendering which allows us to
|
| - // set individual fragment inputs with ProgramPathFragmentInputGen. The API
|
| - // additions are detected by checking the existence of the function.
|
| - fPathRenderingSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access") &&
|
| - ((ctxInfo.version() >= GR_GL_VER(4, 3) ||
|
| - ctxInfo.hasExtension("GL_ARB_program_interface_query")) &&
|
| - gli->fFunctions.fProgramPathFragmentInputGen);
|
| - }
|
| - else {
|
| - fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
|
| - }
|
| - }
|
| -
|
| - // For now these two are equivalent but we could have dst read in shader via some other method
|
| - fDstReadInShaderSupport = fFBFetchSupport;
|
| -
|
| - // Enable supported shader-related caps
|
| - if (kGL_GrGLStandard == standard) {
|
| - fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3, 3) ||
|
| - ctxInfo.hasExtension("GL_ARB_blend_func_extended")) &&
|
| - GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration());
|
| - fShaderDerivativeSupport = true;
|
| - // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
|
| - fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
|
| - ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
|
| - }
|
| - else {
|
| - fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
|
| - ctxInfo.hasExtension("GL_OES_standard_derivatives");
|
| - }
|
| -
|
| - // We need dual source blending and the ability to disable multisample in order to support mixed
|
| - // samples in every corner case.
|
| - if (fDualSourceBlendingSupport && glCaps.multisampleDisableSupport()) {
|
| - // We understand "mixed samples" to mean the collective capability of 3 different extensions
|
| - fMixedSamplesSupport = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") &&
|
| - ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage") &&
|
| - ctxInfo.hasExtension("GL_EXT_raster_multisample");
|
| - }
|
| -
|
| - if (glCaps.advancedBlendEquationSupport()) {
|
| - bool coherent = glCaps.advancedCoherentBlendEquationSupport();
|
| - if (ctxInfo.hasExtension(coherent ? "GL_NV_blend_equation_advanced_coherent"
|
| - : "GL_NV_blend_equation_advanced")) {
|
| - fAdvBlendEqInteraction = kAutomatic_AdvBlendEqInteraction;
|
| - } else {
|
| - fAdvBlendEqInteraction = kGeneralEnable_AdvBlendEqInteraction;
|
| - // TODO: Use the following on any platform where "blend_support_all_equations" is slow.
|
| - //fAdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction;
|
| - }
|
| - }
|
| -
|
| - this->initShaderPrecisionTable(ctxInfo, gli);
|
| }
|
|
|
| SkString GrGLSLCaps::dump() const {
|
|
|