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