Overte C++ Documentation
PointerStorage.h
1 //
2 // Created by Bradley Austin Davis on 2019/01/25
3 // Copyright 2013-2019 High Fidelity, Inc.
4 //
5 // Distributed under the Apache License, Version 2.0.
6 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
7 //
8 #pragma once
9 #ifndef hifi_gpu_PointerStorage_h
10 #define hifi_gpu_PointerStorage_h
11 
12 namespace gpu {
13 
14 //
15 // GL Backend pointer storage mechanism
16 // One of the following three defines must be defined.
17 // GPU_POINTER_STORAGE_SHARED
18 
19 // The platonic ideal, use references to smart pointers.
20 // However, this produces artifacts because there are too many places in the code right now that
21 // create temporary values (undesirable smart pointer duplications) and then those temp variables
22 // get passed on and have their reference taken, and then invalidated
23 // GPU_POINTER_STORAGE_REF
24 
25 // Raw pointer manipulation. Seems more dangerous than the reference wrappers,
26 // but in practice, the danger of grabbing a reference to a temporary variable
27 // is causing issues
28 // GPU_POINTER_STORAGE_RAW
29 
30 #if defined(GPU_POINTER_STORAGE_SHARED)
31 template <typename T>
32 static inline bool compare(const std::shared_ptr<T>& a, const std::shared_ptr<T>& b) {
33  return a == b;
34 }
35 
36 template <typename T>
37 static inline T* acquire(const std::shared_ptr<T>& pointer) {
38  return pointer.get();
39 }
40 
41 template <typename T>
42 static inline void reset(std::shared_ptr<T>& pointer) {
43  return pointer.reset();
44 }
45 
46 template <typename T>
47 static inline bool valid(const std::shared_ptr<T>& pointer) {
48  return pointer.operator bool();
49 }
50 
51 template <typename T>
52 static inline void assign(std::shared_ptr<T>& pointer, const std::shared_ptr<T>& source) {
53  pointer = source;
54 }
55 
56 using BufferReference = BufferPointer;
57 using TextureReference = TexturePointer;
58 using FramebufferReference = FramebufferPointer;
59 using FormatReference = Stream::FormatPointer;
60 using PipelineReference = PipelinePointer;
61 
62 #define GPU_REFERENCE_INIT_VALUE nullptr
63 
64 #elif defined(GPU_POINTER_STORAGE_REF)
65 
66 template <typename T>
67 class PointerReferenceWrapper : public std::reference_wrapper<const std::shared_ptr<T>> {
68  using Parent = std::reference_wrapper<const std::shared_ptr<T>>;
69 
70 public:
71  using Pointer = std::shared_ptr<T>;
72  PointerReferenceWrapper() : Parent(EMPTY()) {}
73  PointerReferenceWrapper(const Pointer& pointer) : Parent(pointer) {}
74  void clear() { *this = EMPTY(); }
75 
76 private:
77  static const Pointer& EMPTY() {
78  static const Pointer EMPTY_VALUE;
79  return EMPTY_VALUE;
80  };
81 };
82 
83 template <typename T>
84 static bool compare(const PointerReferenceWrapper<T>& reference, const std::shared_ptr<T>& pointer) {
85  return reference.get() == pointer;
86 }
87 
88 template <typename T>
89 static inline T* acquire(const PointerReferenceWrapper<T>& reference) {
90  return reference.get().get();
91 }
92 
93 template <typename T>
94 static void assign(PointerReferenceWrapper<T>& reference, const std::shared_ptr<T>& pointer) {
95  reference = pointer;
96 }
97 
98 template <typename T>
99 static bool valid(const PointerReferenceWrapper<T>& reference) {
100  return reference.get().operator bool();
101 }
102 
103 template <typename T>
104 static inline void reset(PointerReferenceWrapper<T>& reference) {
105  return reference.clear();
106 }
107 
108 using BufferReference = PointerReferenceWrapper<Buffer>;
109 using TextureReference = PointerReferenceWrapper<Texture>;
110 using FramebufferReference = PointerReferenceWrapper<Framebuffer>;
111 using FormatReference = PointerReferenceWrapper<Stream::Format>;
112 using PipelineReference = PointerReferenceWrapper<Pipeline>;
113 
114 #define GPU_REFERENCE_INIT_VALUE
115 
116 #elif defined(GPU_POINTER_STORAGE_RAW)
117 
118 template <typename T>
119 static bool compare(const T* const& rawPointer, const std::shared_ptr<T>& pointer) {
120  return rawPointer == pointer.get();
121 }
122 
123 template <typename T>
124 static inline T* acquire(T* const& rawPointer) {
125  return rawPointer;
126 }
127 
128 template <typename T>
129 static inline bool valid(const T* const& rawPointer) {
130  return rawPointer;
131 }
132 
133 template <typename T>
134 static inline void reset(T*& rawPointer) {
135  rawPointer = nullptr;
136 }
137 
138 template <typename T>
139 static inline void assign(T*& rawPointer, const std::shared_ptr<T>& pointer) {
140  rawPointer = pointer.get();
141 }
142 
143 using BufferReference = Buffer*;
144 using TextureReference = Texture*;
145 using FramebufferReference = Framebuffer*;
146 using FormatReference = Stream::Format*;
147 using PipelineReference = Pipeline*;
148 
149 #define GPU_REFERENCE_INIT_VALUE nullptr
150 
151 #else
152 
153 #error "No GPU pointer storage scheme defined"
154 
155 #endif
156 
157 }
158 
159 #endif // hifi_gpu_PointerStorage_h
A simple object wrapper for an OpenGL texture.
Definition: material-networking/src/material-networking/TextureCache.h:39