1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9 #ifndef GrGLCaps_DEFINED 10 #define GrGLCaps_DEFINED 11 12 #include "GrDrawTargetCaps.h" 13 #include "GrGLStencilAttachment.h" 14 #include "SkChecksum.h" 15 #include "SkTHash.h" 16 #include "SkTArray.h" 17 18 class GrGLContextInfo; 19 class GrGLSLCaps; 20 21 /** 22 * Stores some capabilities of a GL context. Most are determined by the GL 23 * version and the extensions string. It also tracks formats that have passed 24 * the FBO completeness test. 25 */ 26 class GrGLCaps : public GrDrawTargetCaps { 27 public: 28 SK_DECLARE_INST_COUNT(GrGLCaps) 29 30 typedef GrGLStencilAttachment::Format StencilFormat; 31 32 /** 33 * The type of MSAA for FBOs supported. Different extensions have different 34 * semantics of how / when a resolve is performed. 35 */ 36 enum MSFBOType { 37 /** 38 * no support for MSAA FBOs 39 */ 40 kNone_MSFBOType = 0, 41 /** 42 * GL3.0-style MSAA FBO (GL_ARB_framebuffer_object). 43 */ 44 kDesktop_ARB_MSFBOType, 45 /** 46 * earlier GL_EXT_framebuffer* extensions 47 */ 48 kDesktop_EXT_MSFBOType, 49 /** 50 * Similar to kDesktop_ARB but with additional restrictions on glBlitFramebuffer. 51 */ 52 kES_3_0_MSFBOType, 53 /** 54 * GL_APPLE_framebuffer_multisample ES extension 55 */ 56 kES_Apple_MSFBOType, 57 /** 58 * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers. 59 * Instead the texture is multisampled when bound to the FBO and then resolved automatically 60 * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call 61 * GR_GL_MAX_SAMPLES_IMG). 62 */ 63 kES_IMG_MsToTexture_MSFBOType, 64 /** 65 * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard 66 * GL_MAX_SAMPLES value. 67 */ 68 kES_EXT_MsToTexture_MSFBOType, 69 70 kLast_MSFBOType = kES_EXT_MsToTexture_MSFBOType 71 }; 72 73 enum InvalidateFBType { 74 kNone_InvalidateFBType, 75 kDiscard_InvalidateFBType, //<! glDiscardFramebuffer() 76 kInvalidate_InvalidateFBType, //<! glInvalidateFramebuffer() 77 78 kLast_InvalidateFBType = kInvalidate_InvalidateFBType 79 }; 80 81 enum MapBufferType { 82 kNone_MapBufferType, 83 kMapBuffer_MapBufferType, // glMapBuffer() 84 kMapBufferRange_MapBufferType, // glMapBufferRange() 85 kChromium_MapBufferType, // GL_CHROMIUM_map_sub 86 87 kLast_MapBufferType = kChromium_MapBufferType, 88 }; 89 90 /** 91 * Creates a GrGLCaps that advertises no support for any extensions, 92 * formats, etc. Call init to initialize from a GrGLContextInfo. 93 */ 94 GrGLCaps(); 95 96 GrGLCaps(const GrGLCaps& caps); 97 98 GrGLCaps& operator = (const GrGLCaps& caps); 99 100 /** 101 * Resets the caps such that nothing is supported. 102 */ 103 void reset() override; 104 105 /** 106 * Initializes the GrGLCaps to the set of features supported in the current 107 * OpenGL context accessible via ctxInfo. 108 */ 109 bool init(const GrGLContextInfo& ctxInfo, const GrGLInterface* glInterface); 110 111 /** 112 * Call to note that a color config has been verified as a valid color 113 * attachment. This may save future calls to glCheckFramebufferStatus 114 * using isConfigVerifiedColorAttachment(). 115 */ markConfigAsValidColorAttachment(GrPixelConfig config)116 void markConfigAsValidColorAttachment(GrPixelConfig config) { 117 fVerifiedColorConfigs.markVerified(config); 118 } 119 120 /** 121 * Call to check whether a config has been verified as a valid color 122 * attachment. 123 */ isConfigVerifiedColorAttachment(GrPixelConfig config)124 bool isConfigVerifiedColorAttachment(GrPixelConfig config) const { 125 return fVerifiedColorConfigs.isVerified(config); 126 } 127 128 /** 129 * Call to note that a color config / stencil format pair passed 130 * FBO status check. We may skip calling glCheckFramebufferStatus for 131 * this combination in the future using 132 * isColorConfigAndStencilFormatVerified(). 133 */ 134 void markColorConfigAndStencilFormatAsVerified( 135 GrPixelConfig config, 136 const GrGLStencilAttachment::Format& format); 137 138 /** 139 * Call to check whether color config / stencil format pair has already 140 * passed FBO status check. 141 */ 142 bool isColorConfigAndStencilFormatVerified( 143 GrPixelConfig config, 144 const GrGLStencilAttachment::Format& format) const; 145 146 /** 147 * Reports the type of MSAA FBO support. 148 */ msFBOType()149 MSFBOType msFBOType() const { return fMSFBOType; } 150 151 /** 152 * Does the supported MSAA FBO extension have MSAA renderbuffers? 153 */ usesMSAARenderBuffers()154 bool usesMSAARenderBuffers() const { 155 return kNone_MSFBOType != fMSFBOType && 156 kES_IMG_MsToTexture_MSFBOType != fMSFBOType && 157 kES_EXT_MsToTexture_MSFBOType != fMSFBOType; 158 } 159 160 /** 161 * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and 162 * then implicitly resolved when read. 163 */ usesImplicitMSAAResolve()164 bool usesImplicitMSAAResolve() const { 165 return kES_IMG_MsToTexture_MSFBOType == fMSFBOType || 166 kES_EXT_MsToTexture_MSFBOType == fMSFBOType; 167 } 168 fbMixedSamplesSupport()169 bool fbMixedSamplesSupport() const { return fFBMixedSamplesSupport; } 170 invalidateFBType()171 InvalidateFBType invalidateFBType() const { return fInvalidateFBType; } 172 173 /// What type of buffer mapping is supported? mapBufferType()174 MapBufferType mapBufferType() const { return fMapBufferType; } 175 176 /** 177 * Gets an array of legal stencil formats. These formats are not guaranteed 178 * to be supported by the driver but are legal GLenum names given the GL 179 * version and extensions supported. 180 */ stencilFormats()181 const SkTArray<StencilFormat, true>& stencilFormats() const { 182 return fStencilFormats; 183 } 184 185 /// The maximum number of fragment uniform vectors (GLES has min. 16). maxFragmentUniformVectors()186 int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; } 187 188 /// maximum number of attribute values per vertex maxVertexAttributes()189 int maxVertexAttributes() const { return fMaxVertexAttributes; } 190 191 /// maximum number of texture units accessible in the fragment shader. maxFragmentTextureUnits()192 int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; } 193 194 /// ES requires an extension to support RGBA8 in RenderBufferStorage rgba8RenderbufferSupport()195 bool rgba8RenderbufferSupport() const { return fRGBA8RenderbufferSupport; } 196 197 /** 198 * Depending on the ES extensions present the BGRA external format may 199 * correspond either a BGRA or RGBA internalFormat. On desktop GL it is 200 * RGBA. 201 */ bgraIsInternalFormat()202 bool bgraIsInternalFormat() const { return fBGRAIsInternalFormat; } 203 204 /// GL_ARB_texture_swizzle support textureSwizzleSupport()205 bool textureSwizzleSupport() const { return fTextureSwizzleSupport; } 206 207 /// Is there support for GL_UNPACK_ROW_LENGTH unpackRowLengthSupport()208 bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; } 209 210 /// Is there support for GL_UNPACK_FLIP_Y unpackFlipYSupport()211 bool unpackFlipYSupport() const { return fUnpackFlipYSupport; } 212 213 /// Is there support for GL_PACK_ROW_LENGTH packRowLengthSupport()214 bool packRowLengthSupport() const { return fPackRowLengthSupport; } 215 216 /// Is there support for GL_PACK_REVERSE_ROW_ORDER packFlipYSupport()217 bool packFlipYSupport() const { return fPackFlipYSupport; } 218 219 /// Is there support for texture parameter GL_TEXTURE_USAGE textureUsageSupport()220 bool textureUsageSupport() const { return fTextureUsageSupport; } 221 222 /// Is there support for glTexStorage texStorageSupport()223 bool texStorageSupport() const { return fTexStorageSupport; } 224 225 /// Is there support for GL_RED and GL_R8 textureRedSupport()226 bool textureRedSupport() const { return fTextureRedSupport; } 227 228 /// Is GL_ARB_IMAGING supported imagingSupport()229 bool imagingSupport() const { return fImagingSupport; } 230 231 /// Is GL_ARB_fragment_coord_conventions supported? fragCoordConventionsSupport()232 bool fragCoordConventionsSupport() const { return fFragCoordsConventionSupport; } 233 234 /// Is there support for Vertex Array Objects? vertexArrayObjectSupport()235 bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; } 236 237 /// Is there support for ES2 compatability? ES2CompatibilitySupport()238 bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; } 239 240 /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content. useNonVBOVertexAndIndexDynamicData()241 bool useNonVBOVertexAndIndexDynamicData() const { 242 return fUseNonVBOVertexAndIndexDynamicData; 243 } 244 245 /// Does ReadPixels support the provided format/type combo? 246 bool readPixelsSupported(const GrGLInterface* intf, 247 GrGLenum format, 248 GrGLenum type, 249 GrGLenum currFboFormat) const; 250 isCoreProfile()251 bool isCoreProfile() const { return fIsCoreProfile; } 252 253 fullClearIsFree()254 bool fullClearIsFree() const { return fFullClearIsFree; } 255 256 /** 257 * Returns a string containing the caps info. 258 */ 259 SkString dump() const override; 260 261 /** 262 * LATC can appear under one of three possible names. In order to know 263 * which GL internal format to use, we need to keep track of which name 264 * we found LATC under. The default is LATC. 265 */ 266 enum LATCAlias { 267 kLATC_LATCAlias, 268 kRGTC_LATCAlias, 269 k3DC_LATCAlias 270 }; 271 latcAlias()272 LATCAlias latcAlias() const { return fLATCAlias; } 273 glslCaps()274 GrGLSLCaps* glslCaps() const { return reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get()); } 275 276 private: 277 /** 278 * Maintains a bit per GrPixelConfig. It is used to avoid redundantly 279 * performing glCheckFrameBufferStatus for the same config. 280 */ 281 struct VerifiedColorConfigs { VerifiedColorConfigsVerifiedColorConfigs282 VerifiedColorConfigs() { 283 this->reset(); 284 } 285 resetVerifiedColorConfigs286 void reset() { 287 for (int i = 0; i < kNumUints; ++i) { 288 fVerifiedColorConfigs[i] = 0; 289 } 290 } 291 292 static const int kNumUints = (kGrPixelConfigCnt + 31) / 32; 293 uint32_t fVerifiedColorConfigs[kNumUints]; 294 markVerifiedVerifiedColorConfigs295 void markVerified(GrPixelConfig config) { 296 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 297 return; 298 #endif 299 int u32Idx = config / 32; 300 int bitIdx = config % 32; 301 fVerifiedColorConfigs[u32Idx] |= 1 << bitIdx; 302 } 303 isVerifiedVerifiedColorConfigs304 bool isVerified(GrPixelConfig config) const { 305 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 306 return false; 307 #endif 308 int u32Idx = config / 32; 309 int bitIdx = config % 32; 310 return SkToBool(fVerifiedColorConfigs[u32Idx] & (1 << bitIdx)); 311 } 312 }; 313 314 void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*); 315 void initStencilFormats(const GrGLContextInfo&); 316 // This must be called after initFSAASupport(). 317 void initConfigRenderableTable(const GrGLContextInfo&); 318 void initConfigTexturableTable(const GrGLContextInfo&, const GrGLInterface*); 319 320 bool doReadPixelsSupported(const GrGLInterface* intf, GrGLenum format, GrGLenum type) const; 321 322 // tracks configs that have been verified to pass the FBO completeness when 323 // used as a color attachment 324 VerifiedColorConfigs fVerifiedColorConfigs; 325 326 SkTArray<StencilFormat, true> fStencilFormats; 327 // tracks configs that have been verified to pass the FBO completeness when 328 // used as a color attachment when a particular stencil format is used 329 // as a stencil attachment. 330 SkTArray<VerifiedColorConfigs, true> fStencilVerifiedColorConfigs; 331 332 int fMaxFragmentUniformVectors; 333 int fMaxVertexAttributes; 334 int fMaxFragmentTextureUnits; 335 336 MSFBOType fMSFBOType; 337 InvalidateFBType fInvalidateFBType; 338 MapBufferType fMapBufferType; 339 LATCAlias fLATCAlias; 340 341 bool fRGBA8RenderbufferSupport : 1; 342 bool fBGRAIsInternalFormat : 1; 343 bool fTextureSwizzleSupport : 1; 344 bool fUnpackRowLengthSupport : 1; 345 bool fUnpackFlipYSupport : 1; 346 bool fPackRowLengthSupport : 1; 347 bool fPackFlipYSupport : 1; 348 bool fTextureUsageSupport : 1; 349 bool fTexStorageSupport : 1; 350 bool fTextureRedSupport : 1; 351 bool fImagingSupport : 1; 352 bool fTwoFormatLimit : 1; 353 bool fFragCoordsConventionSupport : 1; 354 bool fVertexArrayObjectSupport : 1; 355 bool fES2CompatibilitySupport : 1; 356 bool fUseNonVBOVertexAndIndexDynamicData : 1; 357 bool fIsCoreProfile : 1; 358 bool fFullClearIsFree : 1; 359 bool fFBMixedSamplesSupport : 1; 360 361 struct ReadPixelsSupportedFormat { 362 GrGLenum fFormat; 363 GrGLenum fType; 364 GrGLenum fFboFormat; 365 366 bool operator==(const ReadPixelsSupportedFormat& rhs) const { 367 return fFormat == rhs.fFormat 368 && fType == rhs.fType 369 && fFboFormat == rhs.fFboFormat; 370 } 371 }; 372 mutable SkTHashMap<ReadPixelsSupportedFormat, bool> fReadPixelsSupportedCache; 373 374 typedef GrDrawTargetCaps INHERITED; 375 }; 376 377 378 class GrGLSLCaps : public GrShaderCaps { 379 public: 380 SK_DECLARE_INST_COUNT(GrGLSLCaps) 381 382 /** 383 * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires 384 * special layout qualifiers in the fragment shader. 385 */ 386 enum AdvBlendEqInteraction { 387 kNotSupported_AdvBlendEqInteraction, //<! No _blend_equation_advanced extension 388 kAutomatic_AdvBlendEqInteraction, //<! No interaction required 389 kGeneralEnable_AdvBlendEqInteraction, //<! layout(blend_support_all_equations) out 390 kSpecificEnables_AdvBlendEqInteraction, //<! Specific layout qualifiers per equation 391 392 kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction 393 }; 394 395 /** 396 * Creates a GrGLSLCaps that advertises no support for any extensions, 397 * formats, etc. Call init to initialize from a GrGLContextInfo. 398 */ 399 GrGLSLCaps(); ~GrGLSLCaps()400 ~GrGLSLCaps() override {} 401 402 GrGLSLCaps(const GrGLSLCaps& caps); 403 404 GrGLSLCaps& operator = (const GrGLSLCaps& caps); 405 406 /** 407 * Resets the caps such that nothing is supported. 408 */ 409 void reset() override; 410 411 /** 412 * Initializes the GrGLSLCaps to the set of features supported in the current 413 * OpenGL context accessible via ctxInfo. 414 */ 415 bool init(const GrGLContextInfo&, const GrGLInterface*, const GrGLCaps&); 416 417 /** 418 * Some helper functions for encapsulating various extensions to read FB Buffer on openglES 419 * 420 * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect 421 */ fbFetchSupport()422 bool fbFetchSupport() const { return fFBFetchSupport; } 423 fbFetchNeedsCustomOutput()424 bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; } 425 fbFetchColorName()426 const char* fbFetchColorName() const { return fFBFetchColorName; } 427 fbFetchExtensionString()428 const char* fbFetchExtensionString() const { return fFBFetchExtensionString; } 429 dropsTileOnZeroDivide()430 bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; } 431 advBlendEqInteraction()432 AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; } 433 mustEnableAdvBlendEqs()434 bool mustEnableAdvBlendEqs() const { 435 return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction; 436 } 437 mustEnableSpecificAdvBlendEqs()438 bool mustEnableSpecificAdvBlendEqs() const { 439 return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction; 440 } 441 442 /** 443 * Returns a string containing the caps info. 444 */ 445 SkString dump() const override; 446 447 private: 448 // Must be called after fGeometryShaderSupport is initialized. 449 void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*); 450 451 bool fDropsTileOnZeroDivide : 1; 452 bool fFBFetchSupport : 1; 453 bool fFBFetchNeedsCustomOutput : 1; 454 455 const char* fFBFetchColorName; 456 const char* fFBFetchExtensionString; 457 458 AdvBlendEqInteraction fAdvBlendEqInteraction; 459 460 typedef GrShaderCaps INHERITED; 461 }; 462 463 464 #endif 465