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

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: Revert lock_ pattern change in IdHandler::FreeIds. 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
« no previous file with comments | « gpu/command_buffer/client/share_group.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <stack>
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 11 matching lines...) Expand all
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 base::AutoLock auto_lock(lock_);
53
47 for (GLsizei ii = 0; ii < n; ++ii) { 54 for (GLsizei ii = 0; ii < n; ++ii) {
48 id_allocator_.FreeID(ids[ii]); 55 id_allocator_.FreeID(ids[ii]);
49 } 56 }
57
50 (gl_impl->*delete_fn)(n, ids); 58 (gl_impl->*delete_fn)(n, ids);
51 // We need to ensure that the delete call is evaluated on the service side 59 // 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. 60 // before any other contexts issue commands using these client ids.
61 // TODO(vmiura): Can remove this by virtualizing internal ids, however
62 // this code only affects PPAPI for now.
53 gl_impl->helper()->CommandBufferHelper::Flush(); 63 gl_impl->helper()->CommandBufferHelper::Flush();
54 return true; 64 return true;
55 } 65 }
56 66
57 // Overridden from IdHandlerInterface. 67 // Overridden from IdHandlerInterface.
58 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 68 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
59 if (id == 0) 69 if (id == 0)
60 return true; 70 return true;
61 base::AutoLock auto_lock(lock_); 71 base::AutoLock auto_lock(lock_);
62 return id_allocator_.MarkAsUsed(id); 72 return id_allocator_.MarkAsUsed(id);
63 } 73 }
64 74
65 protected: 75 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
76
77 private:
66 base::Lock lock_; 78 base::Lock lock_;
67 IdAllocator id_allocator_; 79 IdAllocator id_allocator_;
68 }; 80 };
69 81
70 // An id handler that requires Gen before Bind. 82 // An id handler that requires Gen before Bind.
71 class StrictIdHandler : public IdHandler { 83 class StrictIdHandler : public IdHandlerInterface {
72 public: 84 public:
73 StrictIdHandler() {} 85 explicit StrictIdHandler(int id_namespace) : id_namespace_(id_namespace) {}
74 virtual ~StrictIdHandler() {} 86 virtual ~StrictIdHandler() {}
75 87
76 // Overridden from IdHandler. 88 // Overridden from IdHandler.
89 virtual void MakeIds(GLES2Implementation* gl_impl,
90 GLuint /* id_offset */,
91 GLsizei n,
92 GLuint* ids) OVERRIDE {
93 base::AutoLock auto_lock(lock_);
94
95 // Collect pending FreeIds from other flush_generation.
96 CollectPendingFreeIds(gl_impl);
97
98 for (GLsizei ii = 0; ii < n; ++ii) {
99 if (!free_ids_.empty()) {
100 // Allocate a previously freed Id.
101 ids[ii] = free_ids_.top();
102 free_ids_.pop();
103
104 // Record kIdInUse state.
105 DCHECK(id_states_[ids[ii] - 1] == kIdFree);
106 id_states_[ids[ii] - 1] = kIdInUse;
107 } else {
108 // Allocate a new Id.
109 id_states_.push_back(kIdInUse);
110 ids[ii] = id_states_.size();
111 }
112 }
113 }
114
115 // Overridden from IdHandler.
116 virtual bool FreeIds(GLES2Implementation* gl_impl,
117 GLsizei n,
118 const GLuint* ids,
119 DeleteFn delete_fn) OVERRIDE {
120
121 // Delete stub must run before CollectPendingFreeIds.
122 (gl_impl->*delete_fn)(n, ids);
123
124 {
125 base::AutoLock auto_lock(lock_);
126
127 // Collect pending FreeIds from other flush_generation.
128 CollectPendingFreeIds(gl_impl);
129
130 // Save Ids to free in a later flush_generation.
131 ShareGroupContextData::IdHandlerData* ctxt_data =
132 gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
133
134 for (GLsizei ii = 0; ii < n; ++ii) {
135 GLuint id = ids[ii];
136 if (id != 0) {
137 // Save freed Id for later.
138 DCHECK(id_states_[id - 1] == kIdInUse);
139 id_states_[id - 1] = kIdPendingFree;
140 ctxt_data->freed_ids_.push_back(id);
141 }
142 }
143 }
144
145 return true;
146 }
147
148 // Overridden from IdHandler.
77 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 149 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
78 #ifndef NDEBUG 150 #ifndef NDEBUG
79 { 151 if (id != 0) {
80 base::AutoLock auto_lock(lock_); 152 base::AutoLock auto_lock(lock_);
81 DCHECK(id == 0 || id_allocator_.InUse(id)); 153 DCHECK(id_states_[id - 1] == kIdInUse);
82 } 154 }
83 #endif 155 #endif
84 return true; 156 return true;
85 } 157 }
158
159 // Overridden from IdHandlerInterface.
160 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {
161 base::AutoLock auto_lock(lock_);
162 CollectPendingFreeIds(gl_impl);
163 }
164
165 private:
166 enum IdState { kIdFree, kIdPendingFree, kIdInUse };
167
168 void CollectPendingFreeIds(GLES2Implementation* gl_impl) {
169 uint32 flush_generation = gl_impl->helper()->flush_generation();
170 ShareGroupContextData::IdHandlerData* ctxt_data =
171 gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
172
173 if (ctxt_data->flush_generation_ != flush_generation) {
174 ctxt_data->flush_generation_ = flush_generation;
175 for (uint32 ii = 0; ii < ctxt_data->freed_ids_.size(); ++ii) {
176 const GLuint id = ctxt_data->freed_ids_[ii];
177 DCHECK(id_states_[id - 1] == kIdPendingFree);
178 id_states_[id - 1] = kIdFree;
179 free_ids_.push(id);
180 }
181 ctxt_data->freed_ids_.clear();
182 }
183 }
184
185 int id_namespace_;
186
187 base::Lock lock_;
188 std::vector<uint8> id_states_;
189 std::stack<uint32> free_ids_;
86 }; 190 };
87 191
88 // An id handler for ids that are never reused. 192 // An id handler for ids that are never reused.
89 class NonReusedIdHandler : public IdHandlerInterface { 193 class NonReusedIdHandler : public IdHandlerInterface {
90 public: 194 public:
91 NonReusedIdHandler() : last_id_(0) {} 195 NonReusedIdHandler() : last_id_(0) {}
92 virtual ~NonReusedIdHandler() {} 196 virtual ~NonReusedIdHandler() {}
93 197
94 // Overridden from IdHandlerInterface. 198 // Overridden from IdHandlerInterface.
95 virtual void MakeIds( 199 virtual void MakeIds(
(...skipping 13 matching lines...) Expand all
109 (gl_impl->*delete_fn)(n, ids); 213 (gl_impl->*delete_fn)(n, ids);
110 return true; 214 return true;
111 } 215 }
112 216
113 // Overridden from IdHandlerInterface. 217 // Overridden from IdHandlerInterface.
114 virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE { 218 virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE {
115 // This is only used for Shaders and Programs which have no bind. 219 // This is only used for Shaders and Programs which have no bind.
116 return false; 220 return false;
117 } 221 }
118 222
223 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
224
119 private: 225 private:
120 base::Lock lock_; 226 base::Lock lock_;
121 GLuint last_id_; 227 GLuint last_id_;
122 }; 228 };
123 229
124 ShareGroup::ShareGroup(bool bind_generates_resource) 230 ShareGroup::ShareGroup(bool bind_generates_resource)
125 : bind_generates_resource_(bind_generates_resource) { 231 : bind_generates_resource_(bind_generates_resource) {
126 if (bind_generates_resource) { 232 if (bind_generates_resource) {
127 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 233 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
128 if (i == id_namespaces::kProgramsAndShaders) { 234 if (i == id_namespaces::kProgramsAndShaders) {
129 id_handlers_[i].reset(new NonReusedIdHandler()); 235 id_handlers_[i].reset(new NonReusedIdHandler());
130 } else { 236 } else {
131 id_handlers_[i].reset(new IdHandler()); 237 id_handlers_[i].reset(new IdHandler());
132 } 238 }
133 } 239 }
134 } else { 240 } else {
135 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 241 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
136 if (i == id_namespaces::kProgramsAndShaders) { 242 if (i == id_namespaces::kProgramsAndShaders) {
137 id_handlers_[i].reset(new NonReusedIdHandler()); 243 id_handlers_[i].reset(new NonReusedIdHandler());
138 } else { 244 } else {
139 id_handlers_[i].reset(new StrictIdHandler()); 245 id_handlers_[i].reset(new StrictIdHandler(i));
140 } 246 }
141 } 247 }
142 } 248 }
143 program_info_manager_.reset(ProgramInfoManager::Create(false)); 249 program_info_manager_.reset(ProgramInfoManager::Create(false));
144 } 250 }
145 251
146 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) { 252 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
147 program_info_manager_.reset(manager); 253 program_info_manager_.reset(manager);
148 } 254 }
149 255
150 ShareGroup::~ShareGroup() {} 256 ShareGroup::~ShareGroup() {}
151 257
152 } // namespace gles2 258 } // namespace gles2
153 } // namespace gpu 259 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/share_group.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698