• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef _STATE_TRACKING_SUPPORT_H_
17 #define _STATE_TRACKING_SUPPORT_H_
18 
19 #include "aemu/base/containers/HybridComponentManager.h"
20 #include "aemu/base/synchronization/AndroidLock.h"
21 
22 #include <GLES2/gl2.h>
23 #include <memory>
24 
25 template <class IndexType, bool initialIsTrue>
26 class PredicateMap {
27 public:
28     static const uint64_t kBitsPerEntry = 64;
add(IndexType objId)29     void add(IndexType objId) {
30         static const uint64_t kNone = 0ULL;
31         static const uint64_t kAll = ~kNone;
32         IndexType index = objId / kBitsPerEntry;
33         if (!mStorage.get_const(index)) {
34             mStorage.add(index, initialIsTrue ? kAll : kNone);
35         }
36     }
37 
remove(IndexType objId)38     void remove(IndexType objId) {
39         if (initialIsTrue) {
40             set(objId, true);
41         } else {
42             set(objId, false);
43         }
44     }
45 
set(IndexType objId,bool predicate)46     void set(IndexType objId, bool predicate) {
47         IndexType index = objId / kBitsPerEntry;
48 
49         if (!mStorage.get_const(index)) return;
50 
51         uint64_t* current = mStorage.get(index);
52 
53         uint64_t flag = 1ULL << (objId % kBitsPerEntry);
54 
55         if (predicate) {
56             *current = *current | flag;
57         } else {
58             *current = *current & (~flag);
59         }
60     }
61 
get(IndexType objId)62     bool get(IndexType objId) const {
63         IndexType index = objId / kBitsPerEntry;
64 
65         const uint64_t* current = mStorage.get_const(index);
66 
67         if (!current) return initialIsTrue;
68 
69         uint64_t flag = 1ULL << (objId % kBitsPerEntry);
70         return (flag & (*current)) != 0;
71     }
72 
73 private:
74     using Storage = gfxstream::guest::HybridComponentManager<10000, IndexType, uint64_t>;
75     Storage mStorage;
76 };
77 
78 // Structures for fast validation of uniforms/attribs.
79 
80 struct UniformLocationInfo {
81     bool valid = false;
82     uint32_t columns;
83     uint32_t rows;
84     bool isSampler;
85     bool isInt;
86     bool isArray;
87     bool isUnsigned;
88     bool isBool;
89 };
90 
91 struct AttribIndexInfo {
92     bool validInProgram = false;
93 };
94 
95 using UniformValidationInfo = gfxstream::guest::HybridComponentManager<1000, uint32_t, UniformLocationInfo>;
96 using AttribValidationInfo = gfxstream::guest::HybridComponentManager<16, uint32_t, AttribIndexInfo>;
97 
98 using LastQueryTargetInfo = gfxstream::guest::HybridComponentManager<1000, uint32_t, uint32_t>;
99 
100 using ExistenceMap = PredicateMap<uint32_t, false>;
101 
102 struct RboProps {
103     GLenum format;
104     GLsizei multisamples;
105     GLsizei width;
106     GLsizei height;
107     bool previouslyBound;
108     bool boundEGLImage;
109     GLuint id;
110 };
111 
112 struct SamplerProps {
113     uint32_t refcount;
114 };
115 
116 template <class T>
117 class ScopedLockedView {
118 public:
ScopedLockedView(T * info)119     ScopedLockedView(T* info) : mInfo(info) {
120         mInfo->lock();
121     }
~ScopedLockedView()122     virtual ~ScopedLockedView() {
123         mInfo->unlock();
124     }
125 protected:
126     T* mInfo;
127 
internalInfo()128     T* internalInfo() { return mInfo; }
internalInfo_const()129     const T* internalInfo_const() const { return mInfo; }
130 };
131 
132 struct RenderbufferInfo {
133     gfxstream::guest::Lock infoLock;
134     gfxstream::guest::HybridComponentManager<1000, uint32_t, std::shared_ptr<RboProps>> component;
135 
lockRenderbufferInfo136     void lock() { infoLock.lock(); }
unlockRenderbufferInfo137     void unlock() { infoLock.unlock(); }
138 
139     class ScopedView : public ScopedLockedView<RenderbufferInfo> {
140         public:
ScopedViewRenderbufferInfo141             ScopedView(RenderbufferInfo* info) : ScopedLockedView<RenderbufferInfo>(info) { }
hasRboRenderbufferInfo142             bool hasRbo(GLuint id) const {
143                 return nullptr != internalInfo_const()->component.get_const(id);
144             }
145             virtual ~ScopedView() = default;
getRenderbufferInfo146             RboProps* get(GLuint id) {
147                 auto rboPropPtr = internalInfo()->component.get(id);
148                 if (!rboPropPtr) {
149                     return nullptr;
150                 }
151                 return rboPropPtr->get();
152             }
get_or_add_shared_ptrRenderbufferInfo153             std::shared_ptr<RboProps> get_or_add_shared_ptr(GLuint id) {
154                 auto rboPropPtr = internalInfo()->component.get(id);
155                 if (!rboPropPtr) {
156                     addFresh(id);
157                     rboPropPtr = internalInfo()->component.get(id);
158                 }
159                 return *rboPropPtr;
160             }
get_shared_ptrRenderbufferInfo161             std::shared_ptr<RboProps> get_shared_ptr(GLuint id) {
162                 auto rboPropPtr = internalInfo()->component.get(id);
163                 if (!internalInfo()->component.get(id)) {
164                     return nullptr;
165                 }
166                 return *rboPropPtr;
167             }
get_constRenderbufferInfo168             const RboProps* get_const(GLuint id) {
169                 auto rboPropPtr = internalInfo()->component.get_const(id);
170                 if (!rboPropPtr) {
171                     return nullptr;
172                 }
173                 return rboPropPtr->get();
174             }
addFreshRenderbufferInfo175             void addFresh(GLuint id) {
176                 std::shared_ptr<RboProps> props(new RboProps());
177                 props->format = GL_NONE;
178                 props->multisamples = 0;
179                 props->width = 0;
180                 props->height = 0;
181                 props->previouslyBound = false;
182                 props->boundEGLImage = false;
183                 props->id = id;
184                 internalInfo()->component.add(id, std::move(props));
185             }
bindRenderbufferInfo186             std::shared_ptr<RboProps> bind(GLuint id) {
187                 auto res = get_shared_ptr(id);
188                 if (!res) {
189                     addFresh(id);
190                     res = get_shared_ptr(id);
191                 }
192                 res->previouslyBound = true;
193                 return res;
194             }
removeRenderbufferInfo195             void remove(GLuint id) {
196                 if (id == 0) {
197                     return;
198                 }
199                 internalInfo()->component.remove(id);
200             }
201     };
202 };
203 
204 struct SamplerInfo {
205     gfxstream::guest::Lock infoLock;
206     gfxstream::guest::HybridComponentManager<1000, uint32_t, SamplerProps> component;
207 
lockSamplerInfo208     void lock() { infoLock.lock(); }
unlockSamplerInfo209     void unlock() { infoLock.unlock(); }
210 
211     class ScopedView : public ScopedLockedView<SamplerInfo> {
212         public:
ScopedViewSamplerInfo213             ScopedView(SamplerInfo* info) : ScopedLockedView<SamplerInfo>(info) { }
samplerExistsSamplerInfo214             bool samplerExists(GLuint id) const {
215                 const SamplerProps* info = internalInfo_const()->component.get_const(id);
216                 if (!info) return false;
217                 return 0 != info->refcount;
218             }
219             virtual ~ScopedView() = default;
getSamplerInfo220             SamplerProps* get(GLuint id) {
221                 return internalInfo()->component.get(id);
222             }
get_constSamplerInfo223             const SamplerProps* get_const(GLuint id) {
224                 return internalInfo_const()->component.get_const(id);
225             }
addFreshSamplerInfo226             void addFresh(GLuint id) {
227                 SamplerProps props;
228                 props.refcount = 1;
229                 internalInfo()->component.add(id, props);
230             }
bindSamplerInfo231             SamplerProps* bind(GLuint id) {
232                 if (!samplerExists(id)) return 0;
233                 ref(id);
234                 SamplerProps* res = get(id);
235                 return res;
236             }
refSamplerInfo237             void ref(GLuint id) {
238                 SamplerProps* props = get(id);
239                 if (!props) return;
240                 ++props->refcount;
241             }
unrefSamplerInfo242             bool unref(GLuint id) {
243                 SamplerProps* props = get(id);
244                 if (!props) return false;
245                 if (!props->refcount) return false;
246                 --props->refcount;
247                 bool gone = 0 == props->refcount;
248                 return gone;
249             }
250     };
251 };
252 
253 
254 #endif
255