Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
PipelineDataCache.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
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 skgpu_graphite_PipelineDataCache_DEFINED
9#define skgpu_graphite_PipelineDataCache_DEFINED
10
12#include "src/core/SkTHash.h"
14
15
16namespace skgpu::graphite {
17
18// Add a block of data to the cache and return a stable pointer to the contents (assuming that a
19// resettable gatherer had accumulated the input data pointer).
20//
21// If an identical block of data is already in the cache, that existing pointer is returned, making
22// pointer comparison suitable when comparing data blocks retrieved from the cache.
23//
24// T must define a hash() function, an operator==, and a static Make(const T&, SkArenaAlloc*)
25// factory that's used to copy the data into an arena allocation owned by the PipelineDataCache.
26template<typename T>
28public:
29 PipelineDataCache() = default;
30
31 const T* insert(const T& dataBlock) {
32 DataRef data{&dataBlock}; // will not be persisted, since pointer isn't from the arena.
33 const DataRef* existing = fDataPointers.find(data);
34 if (existing) {
35 return existing->fPointer;
36 } else {
37 // Need to make a copy of dataBlock into the arena
38 T* copy = T::Make(dataBlock, &fArena);
39 fDataPointers.add(DataRef{copy});
40 return copy;
41 }
42 }
43
44 // The number of unique T objects in the cache
45 int count() const {
46 return fDataPointers.count();
47 }
48
49 // Call fn on every item in the set. You may not mutate anything.
50 template <typename Fn> // f(T), f(const T&)
51 void foreach(Fn&& fn) const {
52 fDataPointers.foreach([fn](const DataRef& ref){
53 fn(ref.fPointer);
54 });
55 }
56
57private:
58 struct DataRef {
59 const T* fPointer;
60
61 bool operator==(const DataRef& o) const {
62 if (!fPointer || !o.fPointer) {
63 return !fPointer && !o.fPointer;
64 } else {
65 return *fPointer == *o.fPointer;
66 }
67 }
68 };
69 struct Hash {
70 // This hash operator de-references and hashes the data contents
71 size_t operator()(const DataRef& dataBlock) const {
72 return dataBlock.fPointer ? dataBlock.fPointer->hash() : 0;
73 }
74 };
75
77 // Holds the data that is pointed to by fDataPointers
78 SkArenaAlloc fArena{0};
79};
80
81// A UniformDataCache only lives for a single Recording. It's used to deduplicate uniform data
82// blocks uploaded to uniform/storage buffers for a DrawPass pipeline.
83using UniformDataCache = PipelineDataCache<UniformDataBlock>;
84
85// A TextureDataCache only lives for a single Recording. When a Recording is snapped it is pulled
86// off of the Recorder and goes with the Recording as a record of the required Textures and
87// Samplers.
88using TextureDataCache = PipelineDataCache<TextureDataBlock>;
89
90} // namespace skgpu::graphite
91
92#endif // skgpu_graphite_PipelineDataCache_DEFINED
const T * insert(const T &dataBlock)
int count() const
Definition SkTHash.h:564
const T * find(const T &item) const
Definition SkTHash.h:580
void add(T item)
Definition SkTHash.h:573
void foreach(Fn &&fn) const
Definition SkTHash.h:590
Definition copy.py:1
PipelineDataCache< UniformDataBlock > UniformDataCache
Definition Recorder.h:59
PipelineDataCache< TextureDataBlock > TextureDataCache
Definition Recorder.h:60
#define T