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 122 bool isConfigTexturable(GrPixelConfig config) const override { 123 SkASSERT(kGrPixelConfigCnt > config); 124 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag); 125 } 126 127 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override { 128 SkASSERT(kGrPixelConfigCnt > config); 129 if (withMSAA) { 130 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag); 131 } else { 132 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag); 133 } 134 } 135 136 /** Returns the mapping between GrPixelConfig components and GL internal format components. */ 137 const GrSwizzle& configSwizzle(GrPixelConfig config) const { 138 return fConfigTable[config].fSwizzle; 139 } 140 141 bool getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig, 142 GrGLenum* internalFormat, GrGLenum* externalFormat, 143 GrGLenum* externalType) const; 144 145 bool getCompressedTexImageFormats(GrPixelConfig surfaceConfig, GrGLenum* internalFormat) const; 146 147 bool getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig, 148 GrGLenum* externalFormat, GrGLenum* externalType) const; 149 150 bool getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const; 151 152 /** 153 * Gets an array of legal stencil formats. These formats are not guaranteed 154 * to be supported by the driver but are legal GLenum names given the GL 155 * version and extensions supported. 156 */ 157 const SkTArray<StencilFormat, true>& stencilFormats() const { 158 return fStencilFormats; 159 } 160 161 /** 162 * Has a stencil format index been found for the config (or we've found that no format works). 163 */ 164 bool hasStencilFormatBeenDeterminedForConfig(GrPixelConfig config) const { 165 return fConfigTable[config].fStencilFormatIndex != ConfigInfo::kUnknown_StencilIndex; 166 } 167 168 /** 169 * Gets the stencil format index for the config. This assumes 170 * hasStencilFormatBeenDeterminedForConfig has already been checked. Returns a value < 0 if 171 * no stencil format is supported with the config. Otherwise, returned index refers to the array 172 * returned by stencilFormats(). 173 */ 174 int getStencilFormatIndexForConfig(GrPixelConfig config) const { 175 SkASSERT(this->hasStencilFormatBeenDeterminedForConfig(config)); 176 return fConfigTable[config].fStencilFormatIndex; 177 } 178 179 /** 180 * If index is >= 0 this records an index into stencilFormats() as the best stencil format for 181 * the config. If < 0 it records that the config has no supported stencil format index. 182 */ 183 void setStencilFormatIndexForConfig(GrPixelConfig config, int index) { 184 SkASSERT(!this->hasStencilFormatBeenDeterminedForConfig(config)); 185 if (index < 0) { 186 fConfigTable[config].fStencilFormatIndex = ConfigInfo::kUnsupported_StencilFormatIndex; 187 } else { 188 fConfigTable[config].fStencilFormatIndex = index; 189 } 190 } 191 192 /** 193 * Call to note that a color config has been verified as a valid color 194 * attachment. This may save future calls to glCheckFramebufferStatus 195 * using isConfigVerifiedColorAttachment(). 196 */ 197 void markConfigAsValidColorAttachment(GrPixelConfig config) { 198 fConfigTable[config].fFlags |= ConfigInfo::kVerifiedColorAttachment_Flag; 199 } 200 201 /** 202 * Call to check whether a config has been verified as a valid color 203 * attachment. 204 */ 205 bool isConfigVerifiedColorAttachment(GrPixelConfig config) const { 206 return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kVerifiedColorAttachment_Flag); 207 } 208 209 /** 210 * Reports the type of MSAA FBO support. 211 */ 212 MSFBOType msFBOType() const { return fMSFBOType; } 213 214 /** 215 * Does the preferred MSAA FBO extension have MSAA renderbuffers? 216 */ 217 bool usesMSAARenderBuffers() const { 218 return kNone_MSFBOType != fMSFBOType && 219 kES_IMG_MsToTexture_MSFBOType != fMSFBOType && 220 kES_EXT_MsToTexture_MSFBOType != fMSFBOType && 221 kMixedSamples_MSFBOType != fMSFBOType; 222 } 223 224 /** 225 * What functionality is supported by glBlitFramebuffer. 226 */ 227 BlitFramebufferSupport blitFramebufferSupport() const { return fBlitFramebufferSupport; } 228 229 /** 230 * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and 231 * then implicitly resolved when read. 232 */ 233 bool usesImplicitMSAAResolve() const { 234 return kES_IMG_MsToTexture_MSFBOType == fMSFBOType || 235 kES_EXT_MsToTexture_MSFBOType == fMSFBOType; 236 } 237 238 InvalidateFBType invalidateFBType() const { return fInvalidateFBType; } 239 240 /// What type of buffer mapping is supported? 241 MapBufferType mapBufferType() const { return fMapBufferType; } 242 243 /// What type of transfer buffer is supported? 244 TransferBufferType transferBufferType() const { return fTransferBufferType; } 245 246 /// The maximum number of fragment uniform vectors (GLES has min. 16). 247 int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; } 248 249 /// maximum number of attribute values per vertex 250 int maxVertexAttributes() const { return fMaxVertexAttributes; } 251 252 /// maximum number of texture units accessible in the fragment shader. 253 int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; } 254 255 /** 256 * Depending on the ES extensions present the BGRA external format may 257 * correspond to either a BGRA or RGBA internalFormat. On desktop GL it is 258 * RGBA. 259 */ 260 bool bgraIsInternalFormat() const; 261 262 /// Is there support for GL_UNPACK_ROW_LENGTH 263 bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; } 264 265 /// Is there support for GL_UNPACK_FLIP_Y 266 bool unpackFlipYSupport() const { return fUnpackFlipYSupport; } 267 268 /// Is there support for GL_PACK_ROW_LENGTH 269 bool packRowLengthSupport() const { return fPackRowLengthSupport; } 270 271 /// Is there support for GL_PACK_REVERSE_ROW_ORDER 272 bool packFlipYSupport() const { return fPackFlipYSupport; } 273 274 /// Is there support for texture parameter GL_TEXTURE_USAGE 275 bool textureUsageSupport() const { return fTextureUsageSupport; } 276 277 /// Is there support for glTexStorage 278 bool texStorageSupport() const { return fTexStorageSupport; } 279 280 /// Is there support for GL_RED and GL_R8 281 bool textureRedSupport() const { return fTextureRedSupport; } 282 283 /// Is GL_ARB_IMAGING supported 284 bool imagingSupport() const { return fImagingSupport; } 285 286 /// Is there support for Vertex Array Objects? 287 bool vertexArrayObjectSupport() const { return fVertexArrayObjectSupport; } 288 289 /// Is there support for GL_EXT_direct_state_access? 290 bool directStateAccessSupport() const { return fDirectStateAccessSupport; } 291 292 /// Is there support for GL_KHR_debug? 293 bool debugSupport() const { return fDebugSupport; } 294 295 /// Is there support for ES2 compatability? 296 bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; } 297 298 /// Can we call glDisable(GL_MULTISAMPLE)? 299 bool multisampleDisableSupport() const { return fMultisampleDisableSupport; } 300 301 /// Is there support for glDraw*Indirect? Note that the baseInstance fields of indirect draw 302 /// commands cannot be used unless we have base instance support. 303 bool drawIndirectSupport() const { return fDrawIndirectSupport; } 304 305 /// Is there support for glMultiDraw*Indirect? Note that the baseInstance fields of indirect 306 /// draw commands cannot be used unless we have base instance support. 307 bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; } 308 309 /// Are the baseInstance fields supported in indirect draw commands? 310 bool baseInstanceSupport() const { return fBaseInstanceSupport; } 311 312 /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content. 313 bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; } 314 315 /// Does ReadPixels support reading readConfig pixels from a FBO that is renderTargetConfig? 316 bool readPixelsSupported(GrPixelConfig renderTargetConfig, 317 GrPixelConfig readConfig, 318 std::function<void (GrGLenum, GrGLint*)> getIntegerv, 319 std::function<bool ()> bindRenderTarget) const; 320 321 bool isCoreProfile() const { return fIsCoreProfile; } 322 323 bool bindFragDataLocationSupport() const { return fBindFragDataLocationSupport; } 324 325 bool bindUniformLocationSupport() const { return fBindUniformLocationSupport; } 326 327 /// Are textures with GL_TEXTURE_EXTERNAL_OES type supported. 328 bool externalTextureSupport() const { return fExternalTextureSupport; } 329 330 /// Are textures with GL_TEXTURE_RECTANGLE type supported. 331 bool rectangleTextureSupport() const { return fRectangleTextureSupport; } 332 333 /// GL_ARB_texture_swizzle 334 bool textureSwizzleSupport() const { return fTextureSwizzleSupport; } 335 336 /** 337 * Is there support for enabling/disabling sRGB writes for sRGB-capable color attachments? 338 * If false this does not mean sRGB is not supported but rather that if it is supported 339 * it cannot be turned off for configs that support it. 340 */ 341 bool srgbWriteControl() const { return fSRGBWriteControl; } 342 343 /** 344 * Returns a string containing the caps info. 345 */ 346 SkString dump() const override; 347 348 bool rgba8888PixelsOpsAreSlow() const { return fRGBA8888PixelsOpsAreSlow; } 349 bool partialFBOReadIsSlow() const { return fPartialFBOReadIsSlow; } 350 351 const GrGLSLCaps* glslCaps() const { return reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get()); } 352 353 private: 354 enum ExternalFormatUsage { 355 kTexImage_ExternalFormatUsage, 356 kOther_ExternalFormatUsage, 357 358 kLast_ExternalFormatUsage = kOther_ExternalFormatUsage 359 }; 360 static const int kExternalFormatUsageCnt = kLast_ExternalFormatUsage + 1; 361 bool getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig, 362 ExternalFormatUsage usage, GrGLenum* externalFormat, 363 GrGLenum* externalType) const; 364 365 void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*); 366 void initGLSL(const GrGLContextInfo&); 367 bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*); 368 369 void onApplyOptionsOverrides(const GrContextOptions& options) override; 370 371 void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*); 372 void initBlendEqationSupport(const GrGLContextInfo&); 373 void initStencilFormats(const GrGLContextInfo&); 374 // This must be called after initFSAASupport(). 375 void initConfigTable(const GrGLContextInfo&, const GrGLInterface* gli, GrGLSLCaps* glslCaps); 376 377 void initShaderPrecisionTable(const GrGLContextInfo& ctxInfo, 378 const GrGLInterface* intf, 379 GrGLSLCaps* glslCaps); 380 381 GrGLStandard fStandard; 382 383 SkTArray<StencilFormat, true> fStencilFormats; 384 385 int fMaxFragmentUniformVectors; 386 int fMaxVertexAttributes; 387 int fMaxFragmentTextureUnits; 388 389 MSFBOType fMSFBOType; 390 InvalidateFBType fInvalidateFBType; 391 MapBufferType fMapBufferType; 392 TransferBufferType fTransferBufferType; 393 394 bool fUnpackRowLengthSupport : 1; 395 bool fUnpackFlipYSupport : 1; 396 bool fPackRowLengthSupport : 1; 397 bool fPackFlipYSupport : 1; 398 bool fTextureUsageSupport : 1; 399 bool fTexStorageSupport : 1; 400 bool fTextureRedSupport : 1; 401 bool fImagingSupport : 1; 402 bool fVertexArrayObjectSupport : 1; 403 bool fDirectStateAccessSupport : 1; 404 bool fDebugSupport : 1; 405 bool fES2CompatibilitySupport : 1; 406 bool fMultisampleDisableSupport : 1; 407 bool fDrawIndirectSupport : 1; 408 bool fMultiDrawIndirectSupport : 1; 409 bool fBaseInstanceSupport : 1; 410 bool fUseNonVBOVertexAndIndexDynamicData : 1; 411 bool fIsCoreProfile : 1; 412 bool fBindFragDataLocationSupport : 1; 413 bool fSRGBWriteControl : 1; 414 bool fRGBA8888PixelsOpsAreSlow : 1; 415 bool fPartialFBOReadIsSlow : 1; 416 bool fBindUniformLocationSupport : 1; 417 bool fExternalTextureSupport : 1; 418 bool fRectangleTextureSupport : 1; 419 bool fTextureSwizzleSupport : 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 { 430 ReadPixelsFormat() : fFormat(0), fType(0) {} 431 GrGLenum fFormat; 432 GrGLenum fType; 433 }; 434 435 struct ConfigFormats { 436 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 { 459 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 }; 486 uint32_t fFlags; 487 488 GrSwizzle fSwizzle; 489 }; 490 491 ConfigInfo fConfigTable[kGrPixelConfigCnt]; 492 493 typedef GrCaps INHERITED; 494 }; 495 496 #endif 497