/* * Copyright 2013 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrCaps_DEFINED #define GrCaps_DEFINED #include "GrTypes.h" #include "GrTypesPriv.h" #include "GrBlend.h" #include "GrShaderVar.h" #include "SkRefCnt.h" #include "SkString.h" struct GrContextOptions; class GrShaderCaps : public SkRefCnt { public: SK_DECLARE_INST_COUNT(GrShaderCaps) /** Info about shader variable precision within a given shader stage. That is, this info is relevant to a float (or vecNf) variable declared with a GrSLPrecision in a given GrShaderType. The info here is hoisted from the OpenGL spec. */ struct PrecisionInfo { PrecisionInfo() { fLogRangeLow = 0; fLogRangeHigh = 0; fBits = 0; } /** Is this precision level allowed in the shader stage? */ bool supported() const { return 0 != fBits; } bool operator==(const PrecisionInfo& that) const { return fLogRangeLow == that.fLogRangeLow && fLogRangeHigh == that.fLogRangeHigh && fBits == that.fBits; } bool operator!=(const PrecisionInfo& that) const { return !(*this == that); } /** floor(log2(|min_value|)) */ int fLogRangeLow; /** floor(log2(|max_value|)) */ int fLogRangeHigh; /** Number of bits of precision. As defined in OpenGL (with names modified to reflect this struct) : """ If the smallest representable value greater than 1 is 1 + e, then fBits will contain floor(log2(e)), and every value in the range [2^fLogRangeLow, 2^fLogRangeHigh] can be represented to at least one part in 2^fBits. """ */ int fBits; }; GrShaderCaps(); virtual SkString dump() const; bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; } bool geometryShaderSupport() const { return fGeometryShaderSupport; } bool pathRenderingSupport() const { return fPathRenderingSupport; } bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; } bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; } bool mixedSamplesSupport() const { return fMixedSamplesSupport; } /** * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a * given shader type. If the shader type is not supported or the precision level is not * supported in that shader type then the returned struct will report false when supported() is * called. */ const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType, GrSLPrecision precision) const { return fFloatPrecisions[shaderType][precision]; }; /** * Is there any difference between the float shader variable precision types? If this is true * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would * report the same info for all precisions in all shader types. */ bool floatPrecisionVaries() const { return fShaderPrecisionVaries; } protected: /** 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; bool fGeometryShaderSupport : 1; bool fPathRenderingSupport : 1; bool fDstReadInShaderSupport : 1; bool fDualSourceBlendingSupport : 1; bool fMixedSamplesSupport : 1; bool fShaderPrecisionVaries; PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount]; private: typedef SkRefCnt INHERITED; }; /** * Represents the capabilities of a GrContext. */ class GrCaps : public SkRefCnt { public: SK_DECLARE_INST_COUNT(GrCaps) GrCaps(const GrContextOptions&); virtual SkString dump() const; GrShaderCaps* shaderCaps() const { return fShaderCaps; } bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g. only for POT textures) */ bool mipMapSupport() const { return fMipMapSupport; } bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; } bool stencilWrapOpsSupport() const { return fStencilWrapOpsSupport; } bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } #if GR_FORCE_GPU_TRACE_DEBUGGING bool gpuTracingSupport() const { return true; } #else bool gpuTracingSupport() const { return fGpuTracingSupport; } #endif bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; } bool oversizedStencilSupport() const { return fOversizedStencilSupport; } bool textureBarrierSupport() const { return fTextureBarrierSupport; } bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; } bool useDrawInsteadOfPartialTextureWrite() const { return fUseDrawInsteadOfPartialTextureWrite; } /** * Indicates the capabilities of the fixed function blend unit. */ enum BlendEquationSupport { kBasic_BlendEquationSupport, //= kAdvanced_BlendEquationSupport; } bool advancedCoherentBlendEquationSupport() const { return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; } bool canUseAdvancedBlendEquation(GrBlendEquation equation) const { SkASSERT(GrBlendEquationIsAdvanced(equation)); return SkToBool(fAdvBlendEqBlacklist & (1 << equation)); } /** * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and * textures allows partial mappings or full mappings. */ enum MapFlags { kNone_MapFlags = 0x0, // config); return fConfigRenderSupport[config][withMSAA]; } bool isConfigTexturable(GrPixelConfig config) const { SkASSERT(kGrPixelConfigCnt > config); return fConfigTextureSupport[config]; } bool suppressPrints() const { return fSupressPrints; } bool drawPathMasksToCompressedTexturesSupport() const { return fDrawPathMasksToCompressedTextureSupport; } size_t geometryBufferMapThreshold() const { SkASSERT(fGeometryBufferMapThreshold >= 0); return fGeometryBufferMapThreshold; } 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. */ void applyOptionsOverrides(const GrContextOptions& options); SkAutoTUnref fShaderCaps; bool fNPOTTextureTileSupport : 1; bool fMipMapSupport : 1; bool fTwoSidedStencilSupport : 1; bool fStencilWrapOpsSupport : 1; bool fDiscardRenderTargetSupport : 1; bool fReuseScratchTextures : 1; bool fGpuTracingSupport : 1; bool fCompressedTexSubImageSupport : 1; bool fOversizedStencilSupport : 1; bool fTextureBarrierSupport : 1; // Driver workaround bool fUseDrawInsteadOfClear : 1; bool fUseDrawInsteadOfPartialTextureWrite : 1; BlendEquationSupport fBlendEquationSupport; uint32_t fAdvBlendEqBlacklist; GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); uint32_t fMapBufferFlags; int fGeometryBufferMapThreshold; int fMaxRenderTargetSize; int fMaxTextureSize; int fMinTextureSize; int fMaxSampleCount; // The first entry for each config is without msaa and the second is with. bool fConfigRenderSupport[kGrPixelConfigCnt][2]; bool fConfigTextureSupport[kGrPixelConfigCnt]; private: bool fSupressPrints : 1; bool fDrawPathMasksToCompressedTextureSupport : 1; typedef SkRefCnt INHERITED; }; #endif