xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrDDLContext.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2018 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextThreadSafeProxy.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkNoncopyable.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkChecksum.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkLRUCache.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProgramDesc.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
22*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
23*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker class GrProgramInfo;
26*c8dee2aaSAndroid Build Coastguard Worker 
27*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
28*c8dee2aaSAndroid Build Coastguard Worker 
29*c8dee2aaSAndroid Build Coastguard Worker /**
30*c8dee2aaSAndroid Build Coastguard Worker  * The DDL Context is the one in effect during DDL Recording. It isn't backed by a GrGPU and
31*c8dee2aaSAndroid Build Coastguard Worker  * cannot allocate any GPU resources.
32*c8dee2aaSAndroid Build Coastguard Worker  */
33*c8dee2aaSAndroid Build Coastguard Worker class GrDDLContext final : public GrRecordingContext {
34*c8dee2aaSAndroid Build Coastguard Worker public:
GrDDLContext(sk_sp<GrContextThreadSafeProxy> proxy)35*c8dee2aaSAndroid Build Coastguard Worker     GrDDLContext(sk_sp<GrContextThreadSafeProxy> proxy)
36*c8dee2aaSAndroid Build Coastguard Worker         : INHERITED(std::move(proxy), true) {
37*c8dee2aaSAndroid Build Coastguard Worker     }
38*c8dee2aaSAndroid Build Coastguard Worker 
~GrDDLContext()39*c8dee2aaSAndroid Build Coastguard Worker     ~GrDDLContext() override {}
40*c8dee2aaSAndroid Build Coastguard Worker 
abandonContext()41*c8dee2aaSAndroid Build Coastguard Worker     void abandonContext() override {
42*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(0); // abandoning in a DDL Recorder doesn't make a whole lot of sense
43*c8dee2aaSAndroid Build Coastguard Worker         INHERITED::abandonContext();
44*c8dee2aaSAndroid Build Coastguard Worker     }
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker private:
47*c8dee2aaSAndroid Build Coastguard Worker     // Add to the set of unique program infos required by this DDL
recordProgramInfo(const GrProgramInfo * programInfo)48*c8dee2aaSAndroid Build Coastguard Worker     void recordProgramInfo(const GrProgramInfo* programInfo) final {
49*c8dee2aaSAndroid Build Coastguard Worker         if (!programInfo) {
50*c8dee2aaSAndroid Build Coastguard Worker             return;
51*c8dee2aaSAndroid Build Coastguard Worker         }
52*c8dee2aaSAndroid Build Coastguard Worker 
53*c8dee2aaSAndroid Build Coastguard Worker         const GrCaps* caps = this->caps();
54*c8dee2aaSAndroid Build Coastguard Worker 
55*c8dee2aaSAndroid Build Coastguard Worker         if (this->backend() == GrBackendApi::kMetal || this->backend() == GrBackendApi::kDirect3D) {
56*c8dee2aaSAndroid Build Coastguard Worker             // Currently Metal and Direct3D require a live renderTarget to compute the key
57*c8dee2aaSAndroid Build Coastguard Worker             return;
58*c8dee2aaSAndroid Build Coastguard Worker         }
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker         GrProgramDesc desc = caps->makeDesc(nullptr, *programInfo);
61*c8dee2aaSAndroid Build Coastguard Worker         if (!desc.isValid()) {
62*c8dee2aaSAndroid Build Coastguard Worker             return;
63*c8dee2aaSAndroid Build Coastguard Worker         }
64*c8dee2aaSAndroid Build Coastguard Worker 
65*c8dee2aaSAndroid Build Coastguard Worker         fProgramInfoMap.add(desc, programInfo);
66*c8dee2aaSAndroid Build Coastguard Worker     }
67*c8dee2aaSAndroid Build Coastguard Worker 
detachProgramData(TArray<ProgramData> * dst)68*c8dee2aaSAndroid Build Coastguard Worker     void detachProgramData(TArray<ProgramData>* dst) final {
69*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(dst->empty());
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker         fProgramInfoMap.toArray(dst);
72*c8dee2aaSAndroid Build Coastguard Worker     }
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker private:
76*c8dee2aaSAndroid Build Coastguard Worker     class ProgramInfoMap : public ::SkNoncopyable {
77*c8dee2aaSAndroid Build Coastguard Worker         typedef const GrProgramDesc  CacheKey;
78*c8dee2aaSAndroid Build Coastguard Worker         typedef const GrProgramInfo* CacheValue;
79*c8dee2aaSAndroid Build Coastguard Worker 
80*c8dee2aaSAndroid Build Coastguard Worker     public:
81*c8dee2aaSAndroid Build Coastguard Worker         // All the programInfo data should be stored in the record-time arena so there is no
82*c8dee2aaSAndroid Build Coastguard Worker         // need to ref them here or to delete them in the destructor.
ProgramInfoMap()83*c8dee2aaSAndroid Build Coastguard Worker         ProgramInfoMap() : fMap(10) {}
~ProgramInfoMap()84*c8dee2aaSAndroid Build Coastguard Worker         ~ProgramInfoMap() {}
85*c8dee2aaSAndroid Build Coastguard Worker 
86*c8dee2aaSAndroid Build Coastguard Worker         // TODO: this is doing a lot of reallocating of the ProgramDesc! Once the program descs
87*c8dee2aaSAndroid Build Coastguard Worker         // are allocated in the record-time area there won't be a problem.
add(CacheKey & desc,const GrProgramInfo * programInfo)88*c8dee2aaSAndroid Build Coastguard Worker         void add(CacheKey& desc, const GrProgramInfo* programInfo) {
89*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(desc.isValid());
90*c8dee2aaSAndroid Build Coastguard Worker 
91*c8dee2aaSAndroid Build Coastguard Worker             const CacheValue* preExisting = fMap.find(desc);
92*c8dee2aaSAndroid Build Coastguard Worker             if (preExisting) {
93*c8dee2aaSAndroid Build Coastguard Worker                 return;
94*c8dee2aaSAndroid Build Coastguard Worker             }
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker             fMap.insert(desc, programInfo);
97*c8dee2aaSAndroid Build Coastguard Worker         }
98*c8dee2aaSAndroid Build Coastguard Worker 
toArray(TArray<ProgramData> * dst)99*c8dee2aaSAndroid Build Coastguard Worker         void toArray(TArray<ProgramData>* dst) {
100*c8dee2aaSAndroid Build Coastguard Worker             fMap.foreach([dst](CacheKey* programDesc, CacheValue* programInfo) {
101*c8dee2aaSAndroid Build Coastguard Worker                              // TODO: remove this allocation once the program descs are stored
102*c8dee2aaSAndroid Build Coastguard Worker                              // in the record-time arena.
103*c8dee2aaSAndroid Build Coastguard Worker                              dst->emplace_back(std::make_unique<const GrProgramDesc>(*programDesc),
104*c8dee2aaSAndroid Build Coastguard Worker                                                *programInfo);
105*c8dee2aaSAndroid Build Coastguard Worker                          });
106*c8dee2aaSAndroid Build Coastguard Worker         }
107*c8dee2aaSAndroid Build Coastguard Worker 
108*c8dee2aaSAndroid Build Coastguard Worker     private:
109*c8dee2aaSAndroid Build Coastguard Worker         struct DescHash {
operator ()GrDDLContext::ProgramInfoMap::DescHash110*c8dee2aaSAndroid Build Coastguard Worker             uint32_t operator()(CacheKey& desc) const {
111*c8dee2aaSAndroid Build Coastguard Worker                 return SkChecksum::Hash32(desc.asKey(), desc.keyLength());
112*c8dee2aaSAndroid Build Coastguard Worker             }
113*c8dee2aaSAndroid Build Coastguard Worker         };
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker         SkLRUCache<CacheKey, CacheValue, DescHash> fMap;
116*c8dee2aaSAndroid Build Coastguard Worker     };
117*c8dee2aaSAndroid Build Coastguard Worker 
118*c8dee2aaSAndroid Build Coastguard Worker     ProgramInfoMap fProgramInfoMap;
119*c8dee2aaSAndroid Build Coastguard Worker 
120*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = GrRecordingContext;
121*c8dee2aaSAndroid Build Coastguard Worker };
122*c8dee2aaSAndroid Build Coastguard Worker 
MakeDDL(sk_sp<GrContextThreadSafeProxy> proxy)123*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrRecordingContext> GrRecordingContextPriv::MakeDDL(sk_sp<GrContextThreadSafeProxy> proxy) {
124*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrRecordingContext> context(new GrDDLContext(std::move(proxy)));
125*c8dee2aaSAndroid Build Coastguard Worker 
126*c8dee2aaSAndroid Build Coastguard Worker     if (!context->init()) {
127*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
128*c8dee2aaSAndroid Build Coastguard Worker     }
129*c8dee2aaSAndroid Build Coastguard Worker     return context;
130*c8dee2aaSAndroid Build Coastguard Worker }
131