Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: gpu/command_buffer/client/share_group.cc

Issue 9918027: Make ShareGroup thread safe (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add id==0 check Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "../client/atomicops.h"
5 #include "../client/share_group.h" 6 #include "../client/share_group.h"
7 #include "../client/gles2_implementation.h"
8 #include "../client/program_info_manager.h"
9 #include "../common/id_allocator.h"
6 #include "../common/logging.h" 10 #include "../common/logging.h"
7 11
8 namespace gpu { 12 namespace gpu {
9 namespace gles2 { 13 namespace gles2 {
10 14
11 ShareGroup::ShareGroup() { 15 COMPILE_ASSERT(gpu::kInvalidResource == 0,
16 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
17
18 // An id handler for non-shared ids.
19 class NonSharedIdHandler : public IdHandlerInterface {
20 public:
21 NonSharedIdHandler() { }
22 virtual ~NonSharedIdHandler() { }
23
24 // Overridden from IdHandlerInterface.
25 virtual void Destroy(GLES2Implementation* /* gl_impl */) {
26 }
27
28 // Overridden from IdHandlerInterface.
29 virtual void MakeIds(
30 GLES2Implementation* /* gl_impl */,
31 GLuint id_offset, GLsizei n, GLuint* ids) {
32 if (id_offset == 0) {
33 for (GLsizei ii = 0; ii < n; ++ii) {
34 ids[ii] = id_allocator_.AllocateID();
35 }
36 } else {
37 for (GLsizei ii = 0; ii < n; ++ii) {
38 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
39 id_offset = ids[ii] + 1;
40 }
41 }
42 }
43
44 // Overridden from IdHandlerInterface.
45 virtual bool FreeIds(
46 GLES2Implementation* /* gl_impl */,
47 GLsizei n, const GLuint* ids) {
48 for (GLsizei ii = 0; ii < n; ++ii) {
49 id_allocator_.FreeID(ids[ii]);
50 }
51 return true;
52 }
53
54 // Overridden from IdHandlerInterface.
55 virtual bool MarkAsUsedForBind(GLuint id) {
56 return id == 0 ? true : id_allocator_.MarkAsUsed(id);
57 }
58 private:
59 IdAllocator id_allocator_;
60 };
61
62 // An id handler for non-shared ids that are never reused.
63 class NonSharedNonReusedIdHandler : public IdHandlerInterface {
64 public:
65 NonSharedNonReusedIdHandler() : last_id_(0) { }
66 virtual ~NonSharedNonReusedIdHandler() { }
67
68 // Overridden from IdHandlerInterface.
69 virtual void Destroy(GLES2Implementation* /* gl_impl */) {
70 }
71
72 // Overridden from IdHandlerInterface.
73 virtual void MakeIds(
74 GLES2Implementation* /* gl_impl */,
75 GLuint id_offset, GLsizei n, GLuint* ids) {
76 for (GLsizei ii = 0; ii < n; ++ii) {
77 ids[ii] = ++last_id_ + id_offset;
78 }
79 }
80
81 // Overridden from IdHandlerInterface.
82 virtual bool FreeIds(
83 GLES2Implementation* /* gl_impl */,
84 GLsizei /* n */, const GLuint* /* ids */) {
85 // Ids are never freed.
86 return true;
87 }
88
89 // Overridden from IdHandlerInterface.
90 virtual bool MarkAsUsedForBind(GLuint /* id */) {
91 // This is only used for Shaders and Programs which have no bind.
92 return false;
93 }
94
95 private:
96 GLuint last_id_;
97 };
98
99 // An id handler for shared ids.
100 class SharedIdHandler : public IdHandlerInterface {
101 public:
102 SharedIdHandler(
103 id_namespaces::IdNamespaces id_namespace)
104 : id_namespace_(id_namespace) {
105 }
106
107 virtual ~SharedIdHandler() { }
108
109 // Overridden from IdHandlerInterface.
110 virtual void Destroy(GLES2Implementation* /* gl_impl */) {
111 }
112
113 virtual void MakeIds(
114 GLES2Implementation* gl_impl,
115 GLuint id_offset, GLsizei n, GLuint* ids) {
116 gl_impl->GenSharedIdsCHROMIUM(id_namespace_, id_offset, n, ids);
117 }
118
119 virtual bool FreeIds(
120 GLES2Implementation* gl_impl,
121 GLsizei n, const GLuint* ids) {
122 gl_impl->DeleteSharedIdsCHROMIUM(id_namespace_, n, ids);
123 // We need to ensure that the delete call is evaluated on the service side
124 // before any other contexts issue commands using these client ids.
125 gl_impl->helper()->CommandBufferHelper::Flush();
126 return true;
127 }
128
129 virtual bool MarkAsUsedForBind(GLuint /* id */) {
130 // This has no meaning for shared resources.
131 return true;
132 }
133
134 private:
135 id_namespaces::IdNamespaces id_namespace_;
136 };
137
138 // An id handler for shared ids that requires ids are made before using and
139 // that only the context that created the id can delete it.
140 // Assumes the service will enforce that non made ids generate an error.
141 class StrictSharedIdHandler : public IdHandlerInterface {
142 public:
143 StrictSharedIdHandler(
144 id_namespaces::IdNamespaces id_namespace)
145 : id_namespace_(id_namespace) {
146 }
147
148 virtual ~StrictSharedIdHandler() {
149 }
150
151 // Overridden from IdHandlerInterface.
152 virtual void Destroy(GLES2Implementation* gl_impl) {
153 GPU_DCHECK(gl_impl);
154 // Free all the ids not being used.
155 while (!free_ids_.empty()) {
156 GLuint ids[kNumIdsToGet];
157 int count = 0;
158 while (count < kNumIdsToGet && !free_ids_.empty()) {
159 ids[count++] = free_ids_.front();
160 free_ids_.pop();
161 }
162 gl_impl->DeleteSharedIdsCHROMIUM(id_namespace_, count, ids);
163 }
164 }
165
166 virtual void MakeIds(
167 GLES2Implementation* gl_impl,
168 GLuint id_offset, GLsizei n, GLuint* ids) {
169 GPU_DCHECK(gl_impl);
170 for (GLsizei ii = 0; ii < n; ++ii) {
171 ids[ii] = GetId(gl_impl, id_offset);
172 }
173 }
174
175 virtual bool FreeIds(
176 GLES2Implementation* /* gl_impl */,
177 GLsizei n, const GLuint* ids) {
178 // OpenGL sematics. If any id is bad none of them get freed.
179 for (GLsizei ii = 0; ii < n; ++ii) {
180 GLuint id = ids[ii];
181 if (id != 0) {
182 ResourceIdSet::iterator it = used_ids_.find(id);
183 if (it == used_ids_.end()) {
184 return false;
185 }
186 }
187 }
188 for (GLsizei ii = 0; ii < n; ++ii) {
189 GLuint id = ids[ii];
190 if (id != 0) {
191 ResourceIdSet::iterator it = used_ids_.find(id);
192 if (it != used_ids_.end()) {
193 used_ids_.erase(it);
194 free_ids_.push(id);
195 }
196 }
197 }
198 return true;
199 }
200
201 virtual bool MarkAsUsedForBind(GLuint id) {
202 GPU_DCHECK(id == 0 || used_ids_.find(id) != used_ids_.end());
203 // This has no meaning for shared resources.
204 return true;
205 }
206
207 private:
208 static const GLsizei kNumIdsToGet = 2048;
209 typedef std::queue<GLuint> ResourceIdQueue;
210 typedef std::set<GLuint> ResourceIdSet;
211
212 GLuint GetId(GLES2Implementation* gl_impl, GLuint id_offset) {
213 GPU_DCHECK(gl_impl);
214 if (free_ids_.empty()) {
215 GLuint ids[kNumIdsToGet];
216 gl_impl->GenSharedIdsCHROMIUM(
217 id_namespace_, id_offset, kNumIdsToGet, ids);
218 for (GLsizei ii = 0; ii < kNumIdsToGet; ++ii) {
219 free_ids_.push(ids[ii]);
220 }
221 }
222 GLuint id = free_ids_.front();
223 free_ids_.pop();
224 used_ids_.insert(id);
225 return id;
226 }
227
228 id_namespaces::IdNamespaces id_namespace_;
229 ResourceIdSet used_ids_;
230 ResourceIdQueue free_ids_;
231 };
232
233 #ifndef _MSC_VER
234 const GLsizei StrictSharedIdHandler::kNumIdsToGet;
235 #endif
236
237 class ThreadSafeIdHandlerWrapper : public IdHandlerInterface {
238 public:
239 ThreadSafeIdHandlerWrapper(IdHandlerInterface* id_handler)
240 : id_handler_(id_handler) {
241 }
242 virtual ~ThreadSafeIdHandlerWrapper() { }
243
244 // Overridden from IdHandlerInterface.
245 virtual void Destroy(GLES2Implementation* gl_impl) {
246 AutoLock auto_lock(lock_);
247 id_handler_->Destroy(gl_impl);
248 }
249
250 // Overridden from IdHandlerInterface.
251 virtual void MakeIds(
252 GLES2Implementation* gl_impl, GLuint id_offset, GLsizei n, GLuint* ids) {
253 AutoLock auto_lock(lock_);
254 id_handler_->MakeIds(gl_impl, id_offset, n, ids);
255 }
256
257 // Overridden from IdHandlerInterface.
258 virtual bool FreeIds(
259 GLES2Implementation* gl_impl, GLsizei n, const GLuint* ids) {
260 AutoLock auto_lock(lock_);
261 return id_handler_->FreeIds(gl_impl, n, ids);
262 }
263
264 // Overridden from IdHandlerInterface.
265 virtual bool MarkAsUsedForBind(GLuint id) {
266 AutoLock auto_lock(lock_);
267 return id_handler_->MarkAsUsedForBind(id);
268 }
269
270 private:
271 IdHandlerInterface* id_handler_;
272 Lock lock_;
273 };
274
275 ShareGroup::ShareGroup(bool share_resources, bool bind_generates_resource)
276 : sharing_resources_(share_resources),
277 bind_generates_resource_(bind_generates_resource),
278 gles2_(NULL) {
12 GPU_CHECK(ShareGroup::ImplementsThreadSafeReferenceCounting()); 279 GPU_CHECK(ShareGroup::ImplementsThreadSafeReferenceCounting());
280
281 if (sharing_resources_) {
282 if (!bind_generates_resource_) {
283 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
284 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
285 new StrictSharedIdHandler(
286 static_cast<id_namespaces::IdNamespaces>(i))));
287 }
288 } else {
289 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
290 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
291 new SharedIdHandler(
292 static_cast<id_namespaces::IdNamespaces>(i))));
293 }
294 }
295 } else {
296 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
297 if (i == id_namespaces::kProgramsAndShaders)
298 id_handlers_[i].reset(new NonSharedNonReusedIdHandler);
299 else
300 id_handlers_[i].reset(new NonSharedIdHandler);
301 }
302 }
303 program_info_manager_.reset(ProgramInfoManager::Create(sharing_resources_));
13 } 304 }
14 305
15 ShareGroup::~ShareGroup() { 306 ShareGroup::~ShareGroup() {
307 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
308 id_handlers_[i]->Destroy(gles2_);
309 id_handlers_[i].reset();
310 }
16 } 311 }
17 312
313 void ShareGroup::SetGLES2ImplementationForDestruction(
314 GLES2Implementation* gl_impl) {
315 gles2_ = gl_impl;
316 }
317
318
18 } // namespace gles2 319 } // namespace gles2
19 } // namespace gpu 320 } // namespace gpu
20 321
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/share_group.h ('k') | gpu/command_buffer/client/share_group_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698