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

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

Issue 162023002: Reduce internal Flush() in GL resource glGen/Delete APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove program_info_manager.cc fix. Create separate CL for this. Created 6 years, 10 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
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 <set>
6 #include <vector>
7
5 #include "gpu/command_buffer/client/share_group.h" 8 #include "gpu/command_buffer/client/share_group.h"
6 9
7 #include "base/logging.h" 10 #include "base/logging.h"
8 #include "base/synchronization/lock.h" 11 #include "base/synchronization/lock.h"
9 #include "gpu/command_buffer/client/gles2_implementation.h" 12 #include "gpu/command_buffer/client/gles2_implementation.h"
10 #include "gpu/command_buffer/client/program_info_manager.h" 13 #include "gpu/command_buffer/client/program_info_manager.h"
11 #include "gpu/command_buffer/common/id_allocator.h" 14 #include "gpu/command_buffer/common/id_allocator.h"
12 15
13 namespace gpu { 16 namespace gpu {
14 namespace gles2 { 17 namespace gles2 {
15 18
19 ShareGroupContextData::IdHandlerData::IdHandlerData() : flush_generation_(0) {}
20 ShareGroupContextData::IdHandlerData::~IdHandlerData() {}
21
16 COMPILE_ASSERT(gpu::kInvalidResource == 0, 22 COMPILE_ASSERT(gpu::kInvalidResource == 0,
17 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS); 23 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
18 24
19 // The standard id handler. 25 // The standard id handler.
20 class IdHandler : public IdHandlerInterface { 26 class IdHandler : public IdHandlerInterface {
21 public: 27 public:
22 IdHandler() { } 28 IdHandler() { }
23 virtual ~IdHandler() { } 29 virtual ~IdHandler() { }
24 30
25 // Overridden from IdHandlerInterface. 31 // Overridden from IdHandlerInterface.
(...skipping 10 matching lines...) Expand all
36 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset); 42 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
37 id_offset = ids[ii] + 1; 43 id_offset = ids[ii] + 1;
38 } 44 }
39 } 45 }
40 } 46 }
41 47
42 // Overridden from IdHandlerInterface. 48 // Overridden from IdHandlerInterface.
43 virtual bool FreeIds( 49 virtual bool FreeIds(
44 GLES2Implementation* gl_impl, 50 GLES2Implementation* gl_impl,
45 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE { 51 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
46 base::AutoLock auto_lock(lock_); 52 {
47 for (GLsizei ii = 0; ii < n; ++ii) { 53 base::AutoLock auto_lock(lock_);
48 id_allocator_.FreeID(ids[ii]); 54
55 for (GLsizei ii = 0; ii < n; ++ii) {
56 id_allocator_.FreeID(ids[ii]);
57 }
49 } 58 }
59
50 (gl_impl->*delete_fn)(n, ids); 60 (gl_impl->*delete_fn)(n, ids);
piman 2014/02/18 22:16:48 Isn't there a race where another thread might Gen/
vmiura 2014/02/18 23:04:20 I don't think another thread can be using the same
piman 2014/02/18 23:28:26 Not the same gl_impl, but the same share group. S
vmiura 2014/02/18 23:36:48 2.b saves the id for later collection. At this po
vmiura 2014/02/18 23:42:25 I'm sorry I am thinking of StrictIdHandler. You're
vmiura 2014/02/19 19:39:22 Done. Set the lock to include the delete + flush.
51 // We need to ensure that the delete call is evaluated on the service side 61 // We need to ensure that the delete call is evaluated on the service side
52 // before any other contexts issue commands using these client ids. 62 // before any other contexts issue commands using these client ids.
63 // TODO(vmiura): Can remove this by virtualizing internal ids, however
64 // this code only affects PPAPI for now.
53 gl_impl->helper()->CommandBufferHelper::Flush(); 65 gl_impl->helper()->CommandBufferHelper::Flush();
54 return true; 66 return true;
55 } 67 }
56 68
57 // Overridden from IdHandlerInterface. 69 // Overridden from IdHandlerInterface.
58 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 70 virtual bool MarkAsUsedForBind(GLES2Implementation* /* gl_impl */,
71 GLuint id) OVERRIDE {
59 if (id == 0) 72 if (id == 0)
60 return true; 73 return true;
61 base::AutoLock auto_lock(lock_); 74 base::AutoLock auto_lock(lock_);
62 return id_allocator_.MarkAsUsed(id); 75 return id_allocator_.MarkAsUsed(id);
63 } 76 }
64 77
65 protected: 78 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
79
80 private:
66 base::Lock lock_; 81 base::Lock lock_;
67 IdAllocator id_allocator_; 82 IdAllocator id_allocator_;
68 }; 83 };
69 84
70 // An id handler that requires Gen before Bind. 85 // An id handler that requires Gen before Bind.
71 class StrictIdHandler : public IdHandler { 86 class StrictIdHandler : public IdHandlerInterface {
72 public: 87 public:
73 StrictIdHandler() {} 88 explicit StrictIdHandler(int id_namespace) : id_namespace_(id_namespace) {}
74 virtual ~StrictIdHandler() {} 89 virtual ~StrictIdHandler() {}
75 90
76 // Overridden from IdHandler. 91 // Overridden from IdHandler.
77 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 92 virtual void MakeIds(GLES2Implementation* gl_impl,
93 GLuint id_offset,
94 GLsizei n,
95 GLuint* ids) OVERRIDE {
96 base::AutoLock auto_lock(lock_);
97
98 // Collect pending FreeIds from other flush_generation.
99 CollectPendingFreeIds(gl_impl);
100
101 // Allocate Ids.
102 if (id_offset == 0) {
103 for (GLsizei ii = 0; ii < n; ++ii) {
104 ids[ii] = id_allocator_.AllocateID();
105 }
106 } else {
107 for (GLsizei ii = 0; ii < n; ++ii) {
108 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
109 id_offset = ids[ii] + 1;
110 }
111 }
112 }
113
114 // Overridden from IdHandler.
115 virtual bool FreeIds(GLES2Implementation* gl_impl,
116 GLsizei n,
117 const GLuint* ids,
118 DeleteFn delete_fn) OVERRIDE {
119
120 // Delete stub must run before CollectPendingFreeIds.
121 (gl_impl->*delete_fn)(n, ids);
122
123 {
124 base::AutoLock auto_lock(lock_);
125
126 // Collect pending FreeIds from other flush_generation.
127 CollectPendingFreeIds(gl_impl);
128
129 // Save Ids to free in a later flush_generation.
130 ShareGroupContextData::IdHandlerData* ctxt_data =
131 gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
132 for (GLsizei ii = 0; ii < n; ++ii) {
133 GLuint id = ids[ii];
134 if (id != 0) {
135 DCHECK(group_freed_ids_.find(id) == group_freed_ids_.end());
136 DCHECK(id_allocator_.InUse(id));
137
138 // Save freed Id for later.
139 if (group_freed_ids_.insert(id).second)
140 ctxt_data->freed_ids_.push_back(id);
141 }
142 }
143 }
144
145 return true;
146 }
147
148 // Overridden from IdHandler.
149 virtual bool MarkAsUsedForBind(GLES2Implementation* gl_impl,
150 GLuint id) OVERRIDE {
78 #ifndef NDEBUG 151 #ifndef NDEBUG
79 { 152 {
80 base::AutoLock auto_lock(lock_); 153 base::AutoLock auto_lock(lock_);
81 DCHECK(id == 0 || id_allocator_.InUse(id)); 154 if (id != 0) {
155 DCHECK(group_freed_ids_.find(id) == group_freed_ids_.end());
156 DCHECK(id_allocator_.InUse(id));
157 }
82 } 158 }
159 #else
160 (void)gl_impl;
83 #endif 161 #endif
84 return true; 162 return true;
85 } 163 }
164
165 // Overridden from IdHandlerInterface.
166 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {
167 base::AutoLock auto_lock(lock_);
168 CollectPendingFreeIds(gl_impl);
169 }
170
171 private:
172 void CollectPendingFreeIds(GLES2Implementation* gl_impl) {
173 uint32 flush_generation = gl_impl->helper()->flush_generation();
174 ShareGroupContextData::IdHandlerData* ctxt_data =
175 gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
176
177 if (ctxt_data->flush_generation_ != flush_generation) {
178 ctxt_data->flush_generation_ = flush_generation;
179 for (uint32 ii = 0; ii < ctxt_data->freed_ids_.size(); ++ii) {
180 const GLuint id = ctxt_data->freed_ids_[ii];
181 DCHECK(group_freed_ids_.find(id) != group_freed_ids_.end());
182 group_freed_ids_.erase(id);
183 id_allocator_.FreeID(id);
184 }
185 ctxt_data->freed_ids_.clear();
186 }
187 }
188
189 int id_namespace_;
190
191 base::Lock lock_;
192 IdAllocator id_allocator_;
193 std::set<GLuint> group_freed_ids_;
piman 2014/02/18 22:16:48 Adding one more set seems overkill, it sounds like
vmiura 2014/02/18 23:04:20 Will do.
vmiura 2014/02/18 23:28:01 Done.
86 }; 194 };
87 195
88 // An id handler for ids that are never reused. 196 // An id handler for ids that are never reused.
89 class NonReusedIdHandler : public IdHandlerInterface { 197 class NonReusedIdHandler : public IdHandlerInterface {
90 public: 198 public:
91 NonReusedIdHandler() : last_id_(0) {} 199 NonReusedIdHandler() : last_id_(0) {}
92 virtual ~NonReusedIdHandler() {} 200 virtual ~NonReusedIdHandler() {}
93 201
94 // Overridden from IdHandlerInterface. 202 // Overridden from IdHandlerInterface.
95 virtual void MakeIds( 203 virtual void MakeIds(
96 GLES2Implementation* /* gl_impl */, 204 GLES2Implementation* /* gl_impl */,
97 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE { 205 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
98 base::AutoLock auto_lock(lock_); 206 base::AutoLock auto_lock(lock_);
99 for (GLsizei ii = 0; ii < n; ++ii) { 207 for (GLsizei ii = 0; ii < n; ++ii) {
100 ids[ii] = ++last_id_ + id_offset; 208 ids[ii] = ++last_id_ + id_offset;
101 } 209 }
102 } 210 }
103 211
104 // Overridden from IdHandlerInterface. 212 // Overridden from IdHandlerInterface.
105 virtual bool FreeIds( 213 virtual bool FreeIds(
106 GLES2Implementation* gl_impl, 214 GLES2Implementation* gl_impl,
107 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE { 215 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
108 // Ids are never freed. 216 // Ids are never freed.
109 (gl_impl->*delete_fn)(n, ids); 217 (gl_impl->*delete_fn)(n, ids);
110 return true; 218 return true;
111 } 219 }
112 220
113 // Overridden from IdHandlerInterface. 221 // Overridden from IdHandlerInterface.
114 virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE { 222 virtual bool MarkAsUsedForBind(GLES2Implementation* /* gl_impl */,
223 GLuint /* id */) OVERRIDE {
115 // This is only used for Shaders and Programs which have no bind. 224 // This is only used for Shaders and Programs which have no bind.
116 return false; 225 return false;
117 } 226 }
118 227
228 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
229
119 private: 230 private:
120 base::Lock lock_; 231 base::Lock lock_;
121 GLuint last_id_; 232 GLuint last_id_;
122 }; 233 };
123 234
124 ShareGroup::ShareGroup(bool bind_generates_resource) 235 ShareGroup::ShareGroup(bool bind_generates_resource)
125 : bind_generates_resource_(bind_generates_resource) { 236 : bind_generates_resource_(bind_generates_resource) {
126 if (bind_generates_resource) { 237 if (bind_generates_resource) {
127 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 238 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
128 if (i == id_namespaces::kProgramsAndShaders) { 239 if (i == id_namespaces::kProgramsAndShaders) {
129 id_handlers_[i].reset(new NonReusedIdHandler()); 240 id_handlers_[i].reset(new NonReusedIdHandler());
130 } else { 241 } else {
131 id_handlers_[i].reset(new IdHandler()); 242 id_handlers_[i].reset(new IdHandler());
132 } 243 }
133 } 244 }
134 } else { 245 } else {
135 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 246 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
136 if (i == id_namespaces::kProgramsAndShaders) { 247 if (i == id_namespaces::kProgramsAndShaders) {
137 id_handlers_[i].reset(new NonReusedIdHandler()); 248 id_handlers_[i].reset(new NonReusedIdHandler());
138 } else { 249 } else {
139 id_handlers_[i].reset(new StrictIdHandler()); 250 id_handlers_[i].reset(new StrictIdHandler(i));
140 } 251 }
141 } 252 }
142 } 253 }
143 program_info_manager_.reset(ProgramInfoManager::Create(false)); 254 program_info_manager_.reset(ProgramInfoManager::Create(false));
144 } 255 }
145 256
146 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) { 257 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
147 program_info_manager_.reset(manager); 258 program_info_manager_.reset(manager);
148 } 259 }
149 260
150 ShareGroup::~ShareGroup() {} 261 ShareGroup::~ShareGroup() {}
151 262
152 } // namespace gles2 263 } // namespace gles2
153 } // namespace gpu 264 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698