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 <functional> 13 14 #include "GrCaps.h" 15 #include "GrGLStencilAttachment.h" 16 #include "GrSwizzle.h" 17 #include "SkChecksum.h" 18 #include "SkTHash.h" 19 #include "SkTArray.h" 20 #include "../private/GrGLSL.h" 21 22 class GrGLContextInfo; 23 class GrGLRenderTarget; 24 25 /** 26 * Stores some capabilities of a GL context. Most are determined by the GL 27 * version and the extensions string. It also tracks formats that have passed 28 * the FBO completeness test. 29 */ 30 class GrGLCaps : public GrCaps { 31 public: 32 typedef GrGLStencilAttachment::Format StencilFormat; 33 34 /** 35 * The type of MSAA for FBOs supported. Different extensions have different 36 * semantics of how / when a resolve is performed. 37 */ 38 enum MSFBOType { 39 /** 40 * no support for MSAA FBOs 41 */ 42 kNone_MSFBOType = 0, 43 /** 44 * OpenGL < 3.0 with GL_EXT_framebuffer_object. Doesn't allow rendering to ALPHA. 45 */ 46 kEXT_MSFBOType, 47 /** 48 * OpenGL 3.0+, OpenGL ES 3.0+, and GL_ARB_framebuffer_object. 49 */ 50 kStandard_MSFBOType, 51 /** 52 * GL_APPLE_framebuffer_multisample ES extension 53 */ 54 kES_Apple_MSFBOType, 55 /** 56 * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers. 57 * Instead the texture is multisampled when bound to the FBO and then resolved automatically 58 * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call 59 * GR_GL_MAX_SAMPLES_IMG). 60 */ 61 kES_IMG_MsToTexture_MSFBOType, 62 /** 63 * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard 64 * GL_MAX_SAMPLES value. 65 */ 66 kES_EXT_MsToTexture_MSFBOType, 67 /** 68 * GL_NV_framebuffer_mixed_samples. 69 */ 70 kMixedSamples_MSFBOType, 71 72 kLast_MSFBOType = kMixedSamples_MSFBOType 73 }; 74 75 enum BlitFramebufferFlags { 76 kNoSupport_BlitFramebufferFlag = 1 << 0, 77 kNoScalingOrMirroring_BlitFramebufferFlag = 1 << 1, 78 kResolveMustBeFull_BlitFrambufferFlag = 1 << 2, 79 kNoMSAADst_BlitFramebufferFlag = 1 << 3, 80 kNoFormatConversion_BlitFramebufferFlag = 1 << 4, 81 kNoFormatConversionForMSAASrc_BlitFramebufferFlag = 1 << 5, 82 kRectsMustMatchForMSAASrc_BlitFramebufferFlag = 1 << 6, 83 }; 84 85 enum InvalidateFBType { 86 kNone_InvalidateFBType, 87 kDiscard_InvalidateFBType, //<! glDiscardFramebuffer() 88 kInvalidate_InvalidateFBType, //<! glInvalidateFramebuffer() 89 90 kLast_InvalidateFBType = kInvalidate_InvalidateFBType 91 }; 92 93 enum MapBufferType { 94 kNone_MapBufferType, 95 kMapBuffer_MapBufferType, // glMapBuffer() 96 kMapBufferRange_MapBufferType, // glMapBufferRange() 97 kChromium_MapBufferType, // GL_CHROMIUM_map_sub 98 99 kLast_MapBufferType = kChromium_MapBufferType, 100 }; 101 102 enum TransferBufferType { 103 kNone_TransferBufferType, 104 kPBO_TransferBufferType, // ARB_pixel_buffer_object 105 kChromium_TransferBufferType, // CHROMIUM_pixel_transfer_buffer_object 106 107 kLast_TransferBufferType = kChromium_TransferBufferType, 108 }; 109 110 /** 111 * Initializes the GrGLCaps to the set of features supported in the current 112 * OpenGL context accessible via ctxInfo. 113 */ 114 GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo, 115 const GrGLInterface* glInterface); 116 isConfigTexturable(GrPixelConfig config)117 bool isConfigTexturable(GrPixelConfig config) const override { 118 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag); 119 } 120 isConfigRenderable(GrPixelConfig config,bool withMSAA)121 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override { 122 if (withMSAA) { 123 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag); 124 } else { 125 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag); 126 } 127 } canConfigBeImageStorage(GrPixelConfig config)128 bool canConfigBeImageStorage(GrPixelConfig config) const override { 129 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseAsImageStorage_Flag); 130 } canConfigBeFBOColorAttachment(GrPixelConfig config)131 bool canConfigBeFBOColorAttachment(GrPixelConfig config) const { 132 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kFBOColorAttachment_Flag); 133 } 134 isConfigTexSupportEnabled(GrPixelConfig config)135 bool isConfigTexSupportEnabled(GrPixelConfig config) const { 136 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseTexStorage_Flag); 137 } 138 canUseConfigWithTexelBuffer(GrPixelConfig config)139 bool canUseConfigWithTexelBuffer(GrPixelConfig config) const { 140 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseWithTexelBuffer_Flag); 141 } 142 143 /** Returns the mapping between GrPixelConfig components and GL internal format components. */ configSwizzle(GrPixelConfig config)144 const GrSwizzle& configSwizzle(GrPixelConfig config) const { 145 return fConfigTable[config].fSwizzle; 146 } 147 configSizedInternalFormat(GrPixelConfig config)148 GrGLenum configSizedInternalFormat(GrPixelConfig config) const { 149 return fConfigTable[config].fFormats.fSizedInternalFormat; 150 } 151 152 bool getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig, 153 GrGLenum* internalFormat, GrGLenum* externalFormat, 154 GrGLenum* externalType) const; 155 156 bool getCompressedTexImageFormats(GrPixelConfig surfaceConfig, GrGLenum* internalFormat) const; 157 158 bool getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig, 159 GrGLenum* externalFormat, GrGLenum* externalType) const; 160 161 bool getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const; 162 163 /** The format to use read/write a texture as an image in a shader */ getImageFormat(GrPixelConfig config)164 GrGLenum getImageFormat(GrPixelConfig config) const { 165 return fConfigTable[config].fFormats.fSizedInternalFormat; 166 } 167 168 /** 169 * Gets an array of legal stencil formats. These formats are not guaranteed 170 * to be supported by the driver but are legal GLenum names given the GL 171 * version and extensions supported. 172 */ stencilFormats()173 const SkTArray<StencilFormat, true>& stencilFormats() const { 174 return fStencilFormats; 175 } 176 177 /** 178 * Has a stencil format index been found for the config (or we've found that no format works). 179 */ hasStencilFormatBeenDeterminedForConfig(GrPixelConfig config)180 bool hasStencilFormatBeenDeterminedForConfig(GrPixelConfig config) const { 181 return fConfigTable[config].fStencilFormatIndex != ConfigInfo::kUnknown_StencilIndex; 182 } 183 184 /** 185 * Gets the stencil format index for the config. This assumes 186 * hasStencilFormatBeenDeterminedForConfig has already been checked. Returns a value < 0 if 187 * no stencil format is supported with the config. Otherwise, returned index refers to the array 188 * returned by stencilFormats(). 189 */ getStencilFormatIndexForConfig(GrPixelConfig config)190 int getStencilFormatIndexForConfig(GrPixelConfig config) const { 191 SkASSERT(this->hasStencilFormatBeenDeterminedForConfig(config)); 192 return fConfigTable[config].fStencilFormatIndex; 193 } 194 195 /** 196 * If index is >= 0 this records an index into stencilFormats() as the best stencil format for 197 * the config. If < 0 it records that the config has no supported stencil format index. 198 */ setStencilFormatIndexForConfig(GrPixelConfig config,int index)199 void setStencilFormatIndexForConfig(GrPixelConfig config, int index) { 200 SkASSERT(!this->hasStencilFormatBeenDeterminedForConfig(config)); 201 if (index < 0) { 202 fConfigTable[config].fStencilFormatIndex = ConfigInfo::kUnsupported_StencilFormatIndex; 203 } else { 204 fConfigTable[config].fStencilFormatIndex = index; 205 } 206 } 207 208 /** 209 * Call to note that a color config has been verified as a valid color 210 * attachment. This may save future calls to glCheckFramebufferStatus 211 * using isConfigVerifiedColorAttachment(). 212 */ markConfigAsValidColorAttachment(GrPixelConfig config)213 void markConfigAsValidColorAttachment(GrPixelConfig config) { 214 fConfigTable[config].fFlags |= ConfigInfo::kVerifiedColorAttachment_Flag; 215 } 216 217 /** 218 * Call to check whether a config has been verified as a valid color 219 * attachment. 220 */ isConfigVerifiedColorAttachment(GrPixelConfig config)221 bool isConfigVerifiedColorAttachment(GrPixelConfig config) const { 222 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kVerifiedColorAttachment_Flag); 223 } 224 225 /** 226 * Reports the type of MSAA FBO support. 227 */ msFBOType()228 MSFBOType msFBOType() const { return fMSFBOType; } 229 230 /** 231 * Does the preferred MSAA FBO extension have MSAA renderbuffers? 232 */ usesMSAARenderBuffers()233 bool usesMSAARenderBuffers() const { 234 return kNone_MSFBOType != fMSFBOType && 235 kES_IMG_MsToTexture_MSFBOType != fMSFBOType && 236 kES_EXT_MsToTexture_MSFBOType != fMSFBOType && 237 kMixedSamples_MSFBOType != fMSFBOType; 238 } 239 240 /** 241 * What functionality is supported by glBlitFramebuffer. 242 */ blitFramebufferSupportFlags()243 uint32_t blitFramebufferSupportFlags() const { return fBlitFramebufferFlags; } 244 245 /** 246 * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and 247 * then implicitly resolved when read. 248 */ usesImplicitMSAAResolve()249 bool usesImplicitMSAAResolve() const { 250 return kES_IMG_MsToTexture_MSFBOType == fMSFBOType || 251 kES_EXT_MsToTexture_MSFBOType == fMSFBOType; 252 } 253 invalidateFBType()254 InvalidateFBType invalidateFBType() const { return fInvalidateFBType; } 255 256 /// What type of buffer mapping is supported? mapBufferType()257 MapBufferType mapBufferType() const { return fMapBufferType; } 258 259 /// What type of transfer buffer is supported? transferBufferType()260 TransferBufferType transferBufferType() const { return fTransferBufferType; } 261 262 /// The maximum number of fragment uniform vectors (GLES has min. 16). maxFragmentUniformVectors()263 int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; } 264 265 /** 266 * Depending on the ES extensions present the BGRA external format may 267 * correspond to either a BGRA or RGBA internalFormat. On desktop GL it is 268 * RGBA. 269 */ 270 bool bgraIsInternalFormat() const; 271 272 /// Is there support for GL_UNPACK_ROW_LENGTH unpackRowLengthSupport()273 bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; } 274 275 /// Is there support for GL_UNPACK_FLIP_Y unpackFlipYSupport()276 bool unpackFlipYSupport() const { return fUnpackFlipYSupport; } 277 278 /// Is there support for GL_PACK_ROW_LENGTH packRowLengthSupport()279 bool packRowLengthSupport() const { return fPackRowLengthSupport; } 280 281 /// Is there support for GL_PACK_REVERSE_ROW_ORDER packFlipYSupport()282 bool packFlipYSupport() const { return fPackFlipYSupport; } 283 284 /// Is there support for texture parameter GL_TEXTURE_USAGE textureUsageSupport()285 bool textureUsageSupport() const { return fTextureUsageSupport; } 286 287 /// Is there support for GL_RED and GL_R8 textureRedSupport()288 bool textureRedSupport() const { return fTextureRedSupport; } 289 290 /// Is GL_ARB_IMAGING supported imagingSupport()291 bool imagingSupport() const { return fImagingSupport; } 292 293 /// Is there support for Vertex Array Objects? vertexArrayObjectSupport()294 bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; } 295 296 /// Is there support for GL_EXT_direct_state_access? directStateAccessSupport()297 bool directStateAccessSupport() const { return fDirectStateAccessSupport; } 298 299 /// Is there support for GL_KHR_debug? debugSupport()300 bool debugSupport() const { return fDebugSupport; } 301 302 /// Is there support for ES2 compatability? ES2CompatibilitySupport()303 bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; } 304 305 /// Is there support for glDraw*Instanced? drawInstancedSupport()306 bool drawInstancedSupport() const { return fDrawInstancedSupport; } 307 308 /// Is there support for glDraw*Indirect? Note that the baseInstance fields of indirect draw 309 /// commands cannot be used unless we have base instance support. drawIndirectSupport()310 bool drawIndirectSupport() const { return fDrawIndirectSupport; } 311 312 /// Is there support for glMultiDraw*Indirect? Note that the baseInstance fields of indirect 313 /// draw commands cannot be used unless we have base instance support. multiDrawIndirectSupport()314 bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; } 315 316 /// Is there support for glDrawRangeElements? drawRangeElementsSupport()317 bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; } 318 319 /// Are the baseInstance fields supported in indirect draw commands? baseInstanceSupport()320 bool baseInstanceSupport() const { return fBaseInstanceSupport; } 321 322 /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content. useNonVBOVertexAndIndexDynamicData()323 bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; } 324 325 /// Does ReadPixels support reading readConfig pixels from a FBO that is surfaceConfig? 326 bool readPixelsSupported(GrPixelConfig surfaceConfig, 327 GrPixelConfig readConfig, 328 std::function<void (GrGLenum, GrGLint*)> getIntegerv, 329 std::function<bool ()> bindRenderTarget, 330 std::function<void ()> unbindRenderTarget) const; 331 isCoreProfile()332 bool isCoreProfile() const { return fIsCoreProfile; } 333 bindFragDataLocationSupport()334 bool bindFragDataLocationSupport() const { return fBindFragDataLocationSupport; } 335 bindUniformLocationSupport()336 bool bindUniformLocationSupport() const { return fBindUniformLocationSupport; } 337 338 /// Are textures with GL_TEXTURE_RECTANGLE type supported. rectangleTextureSupport()339 bool rectangleTextureSupport() const { return fRectangleTextureSupport; } 340 341 /// GL_ARB_texture_swizzle textureSwizzleSupport()342 bool textureSwizzleSupport() const { return fTextureSwizzleSupport; } 343 mipMapLevelAndLodControlSupport()344 bool mipMapLevelAndLodControlSupport() const { return fMipMapLevelAndLodControlSupport; } 345 doManualMipmapping()346 bool doManualMipmapping() const { return fDoManualMipmapping; } 347 srgbDecodeDisableSupport()348 bool srgbDecodeDisableSupport() const { return fSRGBDecodeDisableSupport; } srgbDecodeDisableAffectsMipmaps()349 bool srgbDecodeDisableAffectsMipmaps() const { return fSRGBDecodeDisableAffectsMipmaps; } 350 351 /** 352 * Returns a string containing the caps info. 353 */ 354 SkString dump() const override; 355 rgba8888PixelsOpsAreSlow()356 bool rgba8888PixelsOpsAreSlow() const { return fRGBA8888PixelsOpsAreSlow; } partialFBOReadIsSlow()357 bool partialFBOReadIsSlow() const { return fPartialFBOReadIsSlow; } rgbaToBgraReadbackConversionsAreSlow()358 bool rgbaToBgraReadbackConversionsAreSlow() const { 359 return fRGBAToBGRAReadbackConversionsAreSlow; 360 } 361 362 bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override; 363 364 private: 365 enum ExternalFormatUsage { 366 kTexImage_ExternalFormatUsage, 367 kOther_ExternalFormatUsage, 368 369 kLast_ExternalFormatUsage = kOther_ExternalFormatUsage 370 }; 371 static const int kExternalFormatUsageCnt = kLast_ExternalFormatUsage + 1; 372 bool getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig, 373 ExternalFormatUsage usage, GrGLenum* externalFormat, 374 GrGLenum* externalType) const; 375 376 void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*); 377 void initGLSL(const GrGLContextInfo&); 378 bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*); 379 380 void onApplyOptionsOverrides(const GrContextOptions& options) override; 381 382 void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*); 383 void initBlendEqationSupport(const GrGLContextInfo&); 384 void initStencilFormats(const GrGLContextInfo&); 385 // This must be called after initFSAASupport(). 386 void initConfigTable(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*, 387 GrShaderCaps*); 388 389 void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*, GrShaderCaps*); 390 391 GrGLStandard fStandard; 392 393 SkTArray<StencilFormat, true> fStencilFormats; 394 395 int fMaxFragmentUniformVectors; 396 397 MSFBOType fMSFBOType; 398 InvalidateFBType fInvalidateFBType; 399 MapBufferType fMapBufferType; 400 TransferBufferType fTransferBufferType; 401 402 bool fUnpackRowLengthSupport : 1; 403 bool fUnpackFlipYSupport : 1; 404 bool fPackRowLengthSupport : 1; 405 bool fPackFlipYSupport : 1; 406 bool fTextureUsageSupport : 1; 407 bool fTextureRedSupport : 1; 408 bool fImagingSupport : 1; 409 bool fVertexArrayObjectSupport : 1; 410 bool fDirectStateAccessSupport : 1; 411 bool fDebugSupport : 1; 412 bool fES2CompatibilitySupport : 1; 413 bool fDrawInstancedSupport : 1; 414 bool fDrawIndirectSupport : 1; 415 bool fDrawRangeElementsSupport : 1; 416 bool fMultiDrawIndirectSupport : 1; 417 bool fBaseInstanceSupport : 1; 418 bool fUseNonVBOVertexAndIndexDynamicData : 1; 419 bool fIsCoreProfile : 1; 420 bool fBindFragDataLocationSupport : 1; 421 bool fRGBA8888PixelsOpsAreSlow : 1; 422 bool fPartialFBOReadIsSlow : 1; 423 bool fBindUniformLocationSupport : 1; 424 bool fRectangleTextureSupport : 1; 425 bool fTextureSwizzleSupport : 1; 426 bool fMipMapLevelAndLodControlSupport : 1; 427 bool fRGBAToBGRAReadbackConversionsAreSlow : 1; 428 bool fDoManualMipmapping : 1; 429 bool fSRGBDecodeDisableSupport : 1; 430 bool fSRGBDecodeDisableAffectsMipmaps : 1; 431 432 uint32_t fBlitFramebufferFlags; 433 434 /** Number type of the components (with out considering number of bits.) */ 435 enum FormatType { 436 kNormalizedFixedPoint_FormatType, 437 kFloat_FormatType, 438 kInteger_FormatType, 439 }; 440 441 struct ReadPixelsFormat { ReadPixelsFormatReadPixelsFormat442 ReadPixelsFormat() : fFormat(0), fType(0) {} 443 GrGLenum fFormat; 444 GrGLenum fType; 445 }; 446 447 struct ConfigFormats { ConfigFormatsConfigFormats448 ConfigFormats() { 449 // Inits to known bad GL enum values. 450 memset(this, 0xAB, sizeof(ConfigFormats)); 451 } 452 GrGLenum fBaseInternalFormat; 453 GrGLenum fSizedInternalFormat; 454 455 /** The external format and type are to be used when uploading/downloading data using this 456 config where both the CPU data and GrSurface are the same config. To get the external 457 format and type when converting between configs while copying to/from memory use 458 getExternalFormat(). 459 The kTexImage external format is usually the same as kOther except for kSRGBA on some 460 GL contexts. */ 461 GrGLenum fExternalFormat[kExternalFormatUsageCnt]; 462 GrGLenum fExternalType; 463 464 // Either the base or sized internal format depending on the GL and config. 465 GrGLenum fInternalFormatTexImage; 466 GrGLenum fInternalFormatRenderbuffer; 467 }; 468 469 struct ConfigInfo { ConfigInfoConfigInfo470 ConfigInfo() : fStencilFormatIndex(kUnknown_StencilIndex), fFlags(0) {} 471 472 ConfigFormats fFormats; 473 474 FormatType fFormatType; 475 476 // On ES contexts there are restrictions on type type/format that may be used for 477 // ReadPixels. One is implicitly specified by the current FBO's format. The other is 478 // queryable. This stores the queried option (lazily). 479 ReadPixelsFormat fSecondReadPixelsFormat; 480 481 enum { 482 // This indicates that a stencil format has not yet been determined for the config. 483 kUnknown_StencilIndex = -1, 484 // This indicates that there is no supported stencil format for the config. 485 kUnsupported_StencilFormatIndex = -2 486 }; 487 488 // Index fStencilFormats. 489 int fStencilFormatIndex; 490 491 enum { 492 kVerifiedColorAttachment_Flag = 0x1, 493 kTextureable_Flag = 0x2, 494 kRenderable_Flag = 0x4, 495 kRenderableWithMSAA_Flag = 0x8, 496 /** kFBOColorAttachment means that even if the config cannot be a GrRenderTarget, we can 497 still attach it to a FBO for blitting or reading pixels. */ 498 kFBOColorAttachment_Flag = 0x10, 499 kCanUseTexStorage_Flag = 0x20, 500 kCanUseWithTexelBuffer_Flag = 0x40, 501 kCanUseAsImageStorage_Flag = 0x80, 502 }; 503 uint32_t fFlags; 504 505 GrSwizzle fSwizzle; 506 }; 507 508 ConfigInfo fConfigTable[kGrPixelConfigCnt]; 509 510 typedef GrCaps INHERITED; 511 }; 512 513 #endif 514