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