blob: 6ed8460bdf534cdb571dbb7d4e1b8db2a48f3fe7 [file] [log] [blame]
Lingfeng Yang7d677c52020-08-19 09:06:15 -07001/*
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"
Lingfeng Yanged069c52020-09-03 19:11:02 -070020#include "android/base/synchronization/AndroidLock.h"
Lingfeng Yang7d677c52020-08-19 09:06:15 -070021
Lingfeng Yanged069c52020-09-03 19:11:02 -070022#include <GLES2/gl2.h>
Yahan Zhoue9be3542022-05-11 18:47:32 -070023#include <memory>
Lingfeng Yanged069c52020-09-03 19:11:02 -070024
25template <class IndexType, bool initialIsTrue>
Lingfeng Yang7d677c52020-08-19 09:06:15 -070026class PredicateMap {
27public:
28 static const uint64_t kBitsPerEntry = 64;
Lingfeng Yanged069c52020-09-03 19:11:02 -070029 void add(IndexType objId) {
Lingfeng Yang7d677c52020-08-19 09:06:15 -070030 static const uint64_t kNone = 0ULL;
31 static const uint64_t kAll = ~kNone;
Lingfeng Yanged069c52020-09-03 19:11:02 -070032 IndexType index = objId / kBitsPerEntry;
Lingfeng Yang7d677c52020-08-19 09:06:15 -070033 if (!mStorage.get_const(index)) {
34 mStorage.add(index, initialIsTrue ? kAll : kNone);
35 }
36 }
37
Lingfeng Yanged069c52020-09-03 19:11:02 -070038 void remove(IndexType objId) {
Lingfeng Yang7d677c52020-08-19 09:06:15 -070039 if (initialIsTrue) {
40 set(objId, true);
41 } else {
42 set(objId, false);
43 }
44 }
45
Lingfeng Yanged069c52020-09-03 19:11:02 -070046 void set(IndexType objId, bool predicate) {
47 IndexType index = objId / kBitsPerEntry;
Lingfeng Yang7d677c52020-08-19 09:06:15 -070048
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
Lingfeng Yanged069c52020-09-03 19:11:02 -070062 bool get(IndexType objId) const {
63 IndexType index = objId / kBitsPerEntry;
Lingfeng Yang7d677c52020-08-19 09:06:15 -070064
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
73private:
Lingfeng Yanged069c52020-09-03 19:11:02 -070074 using Storage = android::base::HybridComponentManager<10000, IndexType, uint64_t>;
Lingfeng Yang7d677c52020-08-19 09:06:15 -070075 Storage mStorage;
76};
77
Lingfeng Yang62054e92020-09-16 18:55:01 -070078// Structures for fast validation of uniforms/attribs.
79
Lingfeng Yanged069c52020-09-03 19:11:02 -070080struct 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
Lingfeng Yang62054e92020-09-16 18:55:01 -070091struct AttribIndexInfo {
92 bool validInProgram = false;
93};
94
Lingfeng Yanged069c52020-09-03 19:11:02 -070095using UniformValidationInfo = android::base::HybridComponentManager<1000, uint32_t, UniformLocationInfo>;
Lingfeng Yang62054e92020-09-16 18:55:01 -070096using AttribValidationInfo = android::base::HybridComponentManager<16, uint32_t, AttribIndexInfo>;
Lingfeng Yanged069c52020-09-03 19:11:02 -070097
98using LastQueryTargetInfo = android::base::HybridComponentManager<1000, uint32_t, uint32_t>;
99
100using ExistenceMap = PredicateMap<uint32_t, false>;
101
102struct RboProps {
103 GLenum format;
104 GLsizei multisamples;
105 GLsizei width;
106 GLsizei height;
107 bool previouslyBound;
Lingfeng Yanged069c52020-09-03 19:11:02 -0700108 bool boundEGLImage;
Yahan Zhoue9be3542022-05-11 18:47:32 -0700109 GLuint id;
Lingfeng Yanged069c52020-09-03 19:11:02 -0700110};
111
112struct SamplerProps {
113 uint32_t refcount;
114};
115
116template <class T>
117class ScopedLockedView {
118public:
119 ScopedLockedView(T* info) : mInfo(info) {
120 mInfo->lock();
121 }
122 virtual ~ScopedLockedView() {
123 mInfo->unlock();
124 }
125protected:
126 T* mInfo;
127
128 T* internalInfo() { return mInfo; }
129 const T* internalInfo_const() const { return mInfo; }
130};
131
132struct RenderbufferInfo {
133 android::base::guest::Lock infoLock;
Yahan Zhoue9be3542022-05-11 18:47:32 -0700134 android::base::HybridComponentManager<1000, uint32_t, std::shared_ptr<RboProps>> component;
Lingfeng Yanged069c52020-09-03 19:11:02 -0700135
136 void lock() { infoLock.lock(); }
137 void unlock() { infoLock.unlock(); }
138
139 class ScopedView : public ScopedLockedView<RenderbufferInfo> {
140 public:
141 ScopedView(RenderbufferInfo* info) : ScopedLockedView<RenderbufferInfo>(info) { }
142 bool hasRbo(GLuint id) const {
Yahan Zhoue9be3542022-05-11 18:47:32 -0700143 return nullptr != internalInfo_const()->component.get_const(id);
Lingfeng Yanged069c52020-09-03 19:11:02 -0700144 }
145 virtual ~ScopedView() = default;
146 RboProps* get(GLuint id) {
Yahan Zhoue9be3542022-05-11 18:47:32 -0700147 auto rboPropPtr = internalInfo()->component.get(id);
148 if (!rboPropPtr) {
149 return nullptr;
150 }
151 return rboPropPtr->get();
152 }
153 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 }
161 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;
Lingfeng Yanged069c52020-09-03 19:11:02 -0700167 }
168 const RboProps* get_const(GLuint id) {
Yahan Zhoue9be3542022-05-11 18:47:32 -0700169 auto rboPropPtr = internalInfo()->component.get_const(id);
170 if (!rboPropPtr) {
171 return nullptr;
172 }
173 return rboPropPtr->get();
Lingfeng Yanged069c52020-09-03 19:11:02 -0700174 }
175 void addFresh(GLuint id) {
Yahan Zhoue9be3542022-05-11 18:47:32 -0700176 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));
Lingfeng Yanged069c52020-09-03 19:11:02 -0700185 }
Yahan Zhoue9be3542022-05-11 18:47:32 -0700186 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 }
Lingfeng Yanged069c52020-09-03 19:11:02 -0700192 res->previouslyBound = true;
193 return res;
194 }
Yahan Zhoue9be3542022-05-11 18:47:32 -0700195 void remove(GLuint id) {
Yahan Zhou8764f2c2022-04-25 13:02:04 -0700196 if (id == 0) {
197 return;
198 }
Yahan Zhoue9be3542022-05-11 18:47:32 -0700199 internalInfo()->component.remove(id);
Lingfeng Yanged069c52020-09-03 19:11:02 -0700200 }
201 };
202};
203
204struct SamplerInfo {
205 android::base::guest::Lock infoLock;
206 android::base::HybridComponentManager<1000, uint32_t, SamplerProps> component;
207
208 void lock() { infoLock.lock(); }
209 void unlock() { infoLock.unlock(); }
210
211 class ScopedView : public ScopedLockedView<SamplerInfo> {
212 public:
213 ScopedView(SamplerInfo* info) : ScopedLockedView<SamplerInfo>(info) { }
214 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;
220 SamplerProps* get(GLuint id) {
221 return internalInfo()->component.get(id);
222 }
223 const SamplerProps* get_const(GLuint id) {
224 return internalInfo_const()->component.get_const(id);
225 }
226 void addFresh(GLuint id) {
227 SamplerProps props;
228 props.refcount = 1;
229 internalInfo()->component.add(id, props);
230 }
231 SamplerProps* bind(GLuint id) {
232 if (!samplerExists(id)) return 0;
233 ref(id);
234 SamplerProps* res = get(id);
235 return res;
236 }
237 void ref(GLuint id) {
238 SamplerProps* props = get(id);
239 if (!props) return;
240 ++props->refcount;
241 }
242 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
Lingfeng Yang7d677c52020-08-19 09:06:15 -0700254#endif