1 /* 2 * Copyright 2014 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 #ifndef GrProgramDesc_DEFINED 9 #define GrProgramDesc_DEFINED 10 11 #include "include/core/SkString.h" 12 #include "include/private/base/SkAlign.h" 13 #include "include/private/base/SkTArray.h" 14 #include "include/private/base/SkTo.h" 15 #include "include/private/gpu/ganesh/GrTypesPriv.h" 16 17 #include <limits.h> 18 19 class GrCaps; 20 class GrProgramInfo; 21 class GrRenderTarget; 22 23 /** This class is used to generate a generic program cache key. The Dawn, Metal and Vulkan 24 * backends derive backend-specific versions which add additional information. 25 */ 26 class GrProgramDesc { 27 public: 28 GrProgramDesc(const GrProgramDesc& other) = default; 29 GrProgramDesc& operator=(const GrProgramDesc &other) = default; 30 isValid()31 bool isValid() const { return !fKey.empty(); } reset()32 void reset() { *this = GrProgramDesc{}; } 33 34 // Returns this as a uint32_t array to be used as a key in the program cache. asKey()35 const uint32_t* asKey() const { 36 return fKey.data(); 37 } 38 39 // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. keyLength()40 uint32_t keyLength() const { 41 return SkToU32(fKey.size() * sizeof(uint32_t)); 42 } 43 44 bool operator== (const GrProgramDesc& that) const { 45 return this->fKey == that.fKey; 46 } 47 48 bool operator!= (const GrProgramDesc& other) const { 49 return !(*this == other); 50 } 51 initialKeyLength()52 uint32_t initialKeyLength() const { return fInitialKeyLength; } 53 54 // TODO(skia:11372): Incorporate this into caps interface (part of makeDesc, or a parallel 55 // function), so other backends can include their information in the description. 56 static SkString Describe(const GrProgramInfo&, const GrCaps&); 57 58 protected: 59 friend class GrDawnCaps; 60 friend class GrD3DCaps; 61 friend class GrGLCaps; 62 friend class GrMockCaps; 63 friend class GrMtlCaps; 64 friend class GrVkCaps; 65 66 friend class GrGLGpu; // for ProgramCache to access BuildFromData 67 friend class GrMtlResourceProvider; // for PipelineStateCache to access BuildFromData 68 69 // Creates an uninitialized key that must be populated by Build GrProgramDesc()70 GrProgramDesc() {} 71 72 /** 73 * Builds a program descriptor. 74 * 75 * @param desc The built descriptor 76 * @param programInfo Program information need to build the key 77 * @param caps the caps 78 **/ 79 static void Build(GrProgramDesc*, const GrProgramInfo&, const GrCaps&); 80 81 // This is strictly an OpenGL call since the other backends have additional data in their keys. BuildFromData(GrProgramDesc * desc,const void * keyData,size_t keyLength)82 static bool BuildFromData(GrProgramDesc* desc, const void* keyData, size_t keyLength) { 83 if (!SkTFitsIn<int>(keyLength) || !SkIsAlign4(keyLength)) { 84 return false; 85 } 86 desc->fKey.reset(SkToInt(keyLength / 4)); 87 memcpy(desc->fKey.begin(), keyData, keyLength); 88 return true; 89 } 90 91 enum { 92 kHeaderSize = 1, // "header" in ::Build 93 kMaxPreallocProcessors = 8, 94 kIntsPerProcessor = 4, // This is an overestimate of the average effect key size. 95 kPreAllocSize = kHeaderSize + 96 kMaxPreallocProcessors * kIntsPerProcessor, 97 }; 98 99 using KeyType = SkSTArray<kPreAllocSize, uint32_t, true>; 100 key()101 KeyType* key() { return &fKey; } 102 103 private: 104 SkSTArray<kPreAllocSize, uint32_t, true> fKey; 105 uint32_t fInitialKeyLength = 0; 106 }; 107 108 #endif 109