• 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 "android/base/containers/HybridComponentManager.h"
20 #include "android/base/synchronization/AndroidLock.h"
21 
22 #include <GLES2/gl2.h>
23 
24 template <class IndexType, bool initialIsTrue>
25 class PredicateMap {
26 public:
27     static const uint64_t kBitsPerEntry = 64;
add(IndexType objId)28     void add(IndexType objId) {
29         static const uint64_t kNone = 0ULL;
30         static const uint64_t kAll = ~kNone;
31         IndexType index = objId / kBitsPerEntry;
32         if (!mStorage.get_const(index)) {
33             mStorage.add(index, initialIsTrue ? kAll : kNone);
34         }
35     }
36 
remove(IndexType objId)37     void remove(IndexType objId) {
38         if (initialIsTrue) {
39             set(objId, true);
40         } else {
41             set(objId, false);
42         }
43     }
44 
set(IndexType objId,bool predicate)45     void set(IndexType objId, bool predicate) {
46         IndexType index = objId / kBitsPerEntry;
47 
48         if (!mStorage.get_const(index)) return;
49 
50         uint64_t* current = mStorage.get(index);
51 
52         uint64_t flag = 1ULL << (objId % kBitsPerEntry);
53 
54         if (predicate) {
55             *current = *current | flag;
56         } else {
57             *current = *current & (~flag);
58         }
59     }
60 
get(IndexType objId)61     bool get(IndexType objId) const {
62         IndexType index = objId / kBitsPerEntry;
63 
64         const uint64_t* current = mStorage.get_const(index);
65 
66         if (!current) return initialIsTrue;
67 
68         uint64_t flag = 1ULL << (objId % kBitsPerEntry);
69         return (flag & (*current)) != 0;
70     }
71 
72 private:
73     using Storage = android::base::HybridComponentManager<10000, IndexType, uint64_t>;
74     Storage mStorage;
75 };
76 
77 // Structures for fast validation of uniforms/attribs.
78 
79 struct UniformLocationInfo {
80     bool valid = false;
81     uint32_t columns;
82     uint32_t rows;
83     bool isSampler;
84     bool isInt;
85     bool isArray;
86     bool isUnsigned;
87     bool isBool;
88 };
89 
90 struct AttribIndexInfo {
91     bool validInProgram = false;
92 };
93 
94 using UniformValidationInfo = android::base::HybridComponentManager<1000, uint32_t, UniformLocationInfo>;
95 using AttribValidationInfo = android::base::HybridComponentManager<16, uint32_t, AttribIndexInfo>;
96 
97 using LastQueryTargetInfo = android::base::HybridComponentManager<1000, uint32_t, uint32_t>;
98 
99 using ExistenceMap = PredicateMap<uint32_t, false>;
100 
101 struct RboProps {
102     GLenum format;
103     GLsizei multisamples;
104     GLsizei width;
105     GLsizei height;
106     bool previouslyBound;
107     uint32_t refcount;
108     bool boundEGLImage;
109 };
110 
111 struct SamplerProps {
112     uint32_t refcount;
113 };
114 
115 template <class T>
116 class ScopedLockedView {
117 public:
ScopedLockedView(T * info)118     ScopedLockedView(T* info) : mInfo(info) {
119         mInfo->lock();
120     }
~ScopedLockedView()121     virtual ~ScopedLockedView() {
122         mInfo->unlock();
123     }
124 protected:
125     T* mInfo;
126 
internalInfo()127     T* internalInfo() { return mInfo; }
internalInfo_const()128     const T* internalInfo_const() const { return mInfo; }
129 };
130 
131 struct RenderbufferInfo {
132     android::base::guest::Lock infoLock;
133     android::base::HybridComponentManager<1000, uint32_t, RboProps> component;
134 
lockRenderbufferInfo135     void lock() { infoLock.lock(); }
unlockRenderbufferInfo136     void unlock() { infoLock.unlock(); }
137 
138     class ScopedView : public ScopedLockedView<RenderbufferInfo> {
139         public:
ScopedViewRenderbufferInfo140             ScopedView(RenderbufferInfo* info) : ScopedLockedView<RenderbufferInfo>(info) { }
hasRboRenderbufferInfo141             bool hasRbo(GLuint id) const {
142                 const RboProps* info = internalInfo_const()->component.get_const(id);
143                 if (!info) return false;
144                 return 0 != info->refcount;
145             }
146             virtual ~ScopedView() = default;
getRenderbufferInfo147             RboProps* get(GLuint id) {
148                 return internalInfo()->component.get(id);
149             }
get_constRenderbufferInfo150             const RboProps* get_const(GLuint id) {
151                 return internalInfo_const()->component.get_const(id);
152             }
addFreshRenderbufferInfo153             void addFresh(GLuint id) {
154                 RboProps props;
155                 props.format = GL_NONE;
156                 props.multisamples = 0;
157                 props.width = 0;
158                 props.height = 0;
159                 props.previouslyBound = false;
160                 props.refcount = 1;
161                 props.boundEGLImage = false;
162                 internalInfo()->component.add(id, props);
163             }
bindRenderbufferInfo164             RboProps* bind(GLuint id) {
165                 if (!hasRbo(id)) addFresh(id);
166                 ref(id);
167                 RboProps* res = get(id);
168                 res->previouslyBound = true;
169                 return res;
170             }
refRenderbufferInfo171             void ref(GLuint id) {
172                 RboProps* props = get(id);
173                 if (!props) return;
174                 ++props->refcount;
175             }
unrefRenderbufferInfo176             bool unref(GLuint id) {
177                 RboProps* props = get(id);
178                 if (!props) return false;
179                 if (!props->refcount) return false;
180                 --props->refcount;
181                 bool gone = 0 == props->refcount;
182                 if (gone) {
183                     props->format = 0;
184                     props->multisamples = 0;
185                     props->width = 0;
186                     props->height = 0;
187                     props->previouslyBound = false;
188                     props->boundEGLImage = false;
189                 }
190                 return gone;
191             }
192     };
193 };
194 
195 struct SamplerInfo {
196     android::base::guest::Lock infoLock;
197     android::base::HybridComponentManager<1000, uint32_t, SamplerProps> component;
198 
lockSamplerInfo199     void lock() { infoLock.lock(); }
unlockSamplerInfo200     void unlock() { infoLock.unlock(); }
201 
202     class ScopedView : public ScopedLockedView<SamplerInfo> {
203         public:
ScopedViewSamplerInfo204             ScopedView(SamplerInfo* info) : ScopedLockedView<SamplerInfo>(info) { }
samplerExistsSamplerInfo205             bool samplerExists(GLuint id) const {
206                 const SamplerProps* info = internalInfo_const()->component.get_const(id);
207                 if (!info) return false;
208                 return 0 != info->refcount;
209             }
210             virtual ~ScopedView() = default;
getSamplerInfo211             SamplerProps* get(GLuint id) {
212                 return internalInfo()->component.get(id);
213             }
get_constSamplerInfo214             const SamplerProps* get_const(GLuint id) {
215                 return internalInfo_const()->component.get_const(id);
216             }
addFreshSamplerInfo217             void addFresh(GLuint id) {
218                 SamplerProps props;
219                 props.refcount = 1;
220                 internalInfo()->component.add(id, props);
221             }
bindSamplerInfo222             SamplerProps* bind(GLuint id) {
223                 if (!samplerExists(id)) return 0;
224                 ref(id);
225                 SamplerProps* res = get(id);
226                 return res;
227             }
refSamplerInfo228             void ref(GLuint id) {
229                 SamplerProps* props = get(id);
230                 if (!props) return;
231                 ++props->refcount;
232             }
unrefSamplerInfo233             bool unref(GLuint id) {
234                 SamplerProps* props = get(id);
235                 if (!props) return false;
236                 if (!props->refcount) return false;
237                 --props->refcount;
238                 bool gone = 0 == props->refcount;
239                 return gone;
240             }
241     };
242 };
243 
244 
245 #endif
246