aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrCaps.h5
-rw-r--r--src/gpu/gl/GrGLCaps.cpp221
-rw-r--r--src/gpu/gl/GrGLCaps.h6
3 files changed, 109 insertions, 123 deletions
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index f219cb23e0..727e9fcc46 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -84,9 +84,8 @@ public:
bool floatPrecisionVaries() const { return fShaderPrecisionVaries; }
protected:
- /** Subclasses must call this at the end of their constructors in order to apply caps
- overrides requested by the client. Note that overrides will only reduce the caps never
- expand them. */
+ /** Subclasses must call this after initialization in order to apply caps overrides requested by
+ the client. Note that overrides will only reduce the caps never expand them. */
void applyOptionsOverrides(const GrContextOptions& options);
bool fShaderDerivativeSupport : 1;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index ad0f2caf78..40405fd55c 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 {
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 742a74d360..e924c60efb 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -264,7 +264,7 @@ public:
GrGLSLCaps* glslCaps() const { return reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get()); }
private:
- void init(const GrGLContextInfo& ctxInfo, const GrGLInterface* glInterface);
+ void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*);
/**
* Maintains a bit per GrPixelConfig. It is used to avoid redundantly
@@ -428,8 +428,6 @@ public:
SkString dump() const override;
private:
- void init(const GrGLContextInfo&, const GrGLInterface*, const GrGLCaps&);
-
// Must be called after fGeometryShaderSupport is initialized.
void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*);
@@ -444,6 +442,8 @@ private:
AdvBlendEqInteraction fAdvBlendEqInteraction;
+ friend class GrGLCaps; // For initialization.
+
typedef GrShaderCaps INHERITED;
};