1 /*
2  * Copyright 2018 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 GrMtlResourceProvider_DEFINED
9 #define GrMtlResourceProvider_DEFINED
10 
11 #include "GrMtlCopyPipelineState.h"
12 #include "GrMtlPipelineStateBuilder.h"
13 #include "SkLRUCache.h"
14 #include "SkTArray.h"
15 
16 #import <metal/metal.h>
17 
18 class GrMtlGpu;
19 
20 class GrMtlResourceProvider {
21 public:
22     GrMtlResourceProvider(GrMtlGpu* gpu);
23 
24     GrMtlCopyPipelineState* findOrCreateCopyPipelineState(MTLPixelFormat dstPixelFormat,
25                                                           id<MTLFunction> vertexFunction,
26                                                           id<MTLFunction> fragmentFunction,
27                                                           MTLVertexDescriptor* vertexDescriptor);
28 
29     GrMtlPipelineState* findOrCreateCompatiblePipelineState(
30         GrRenderTarget*, GrSurfaceOrigin,
31         const GrPipeline&,
32         const GrPrimitiveProcessor&,
33         const GrTextureProxy* const primProcProxies[],
34         GrPrimitiveType);
35 
36 private:
37 #ifdef SK_DEBUG
38 #define GR_PIPELINE_STATE_CACHE_STATS
39 #endif
40 
41     class PipelineStateCache : public ::SkNoncopyable {
42     public:
43         PipelineStateCache(GrMtlGpu* gpu);
44         ~PipelineStateCache();
45 
46         GrMtlPipelineState* refPipelineState(GrRenderTarget*, GrSurfaceOrigin,
47                                              const GrPrimitiveProcessor&,
48                                              const GrTextureProxy* const primProcProxies[],
49                                              const GrPipeline&,
50                                              GrPrimitiveType);
51 
52     private:
53         enum {
54             // We may actually have kMaxEntries+1 PipelineStates in context because we create a new
55             // PipelineState before evicting from the cache.
56             kMaxEntries = 128,
57         };
58 
59         struct Entry;
60 
61         struct DescHash {
operatorDescHash62             uint32_t operator()(const GrProgramDesc& desc) const {
63                 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
64             }
65         };
66 
67         SkLRUCache<const GrMtlPipelineStateBuilder::Desc, std::unique_ptr<Entry>, DescHash> fMap;
68 
69         GrMtlGpu*                    fGpu;
70 
71 #ifdef GR_PIPELINE_STATE_CACHE_STATS
72         int                         fTotalRequests;
73         int                         fCacheMisses;
74 #endif
75     };
76 
77     SkTArray<std::unique_ptr<GrMtlCopyPipelineState>> fCopyPipelineStateCache;
78 
79     GrMtlGpu* fGpu;
80 
81     // Cache of GrMtlPipelineStates
82     std::unique_ptr<PipelineStateCache> fPipelineStateCache;
83 };
84 
85 #endif
86