xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrProgramDesc.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/SkTFitsIn.h"
15 #include "include/private/base/SkTo.h"
16 
17 #include <cstdint>
18 #include <cstring>
19 
20 class GrCaps;
21 class GrProgramInfo;
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     static constexpr size_t kHeaderSize            = 1;    // "header" in ::Build
92     static constexpr size_t kMaxPreallocProcessors = 8;
93     // This is an overestimate of the average effect key size.
94     static constexpr size_t kIntsPerProcessor      = 4;
95     static constexpr size_t kPreAllocSize          =
96             kHeaderSize + kMaxPreallocProcessors * kIntsPerProcessor;
97 
98     using KeyType = skia_private::STArray<kPreAllocSize, uint32_t, true>;
99 
key()100     KeyType* key() { return &fKey; }
101 
102 private:
103     skia_private::STArray<kPreAllocSize, uint32_t, true> fKey;
104     uint32_t fInitialKeyLength = 0;
105 };
106 
107 #endif
108