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

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: Lock required in FreeContext(). 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 <vector>
6
5 #include "gpu/command_buffer/client/share_group.h" 7 #include "gpu/command_buffer/client/share_group.h"
6 8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
9 #include "gpu/command_buffer/client/gles2_implementation.h" 11 #include "gpu/command_buffer/client/gles2_implementation.h"
10 #include "gpu/command_buffer/client/program_info_manager.h" 12 #include "gpu/command_buffer/client/program_info_manager.h"
11 #include "gpu/command_buffer/common/id_allocator.h" 13 #include "gpu/command_buffer/common/id_allocator.h"
12 14
13 namespace gpu { 15 namespace gpu {
14 namespace gles2 { 16 namespace gles2 {
15 17
18 ShareGroupContextData::IdHandlerData::IdHandlerData() : flush_generation_(0) {}
19 ShareGroupContextData::IdHandlerData::~IdHandlerData() {}
20
16 COMPILE_ASSERT(gpu::kInvalidResource == 0, 21 COMPILE_ASSERT(gpu::kInvalidResource == 0,
17 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS); 22 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
18 23
19 // The standard id handler. 24 // The standard id handler.
20 class IdHandler : public IdHandlerInterface { 25 class IdHandler : public IdHandlerInterface {
21 public: 26 public:
22 IdHandler() { } 27 IdHandler() { }
23 virtual ~IdHandler() { } 28 virtual ~IdHandler() { }
24 29
25 // Overridden from IdHandlerInterface. 30 // Overridden from IdHandlerInterface.
(...skipping 17 matching lines...) Expand all
43 virtual bool FreeIds( 48 virtual bool FreeIds(
44 GLES2Implementation* gl_impl, 49 GLES2Implementation* gl_impl,
45 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE { 50 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
46 base::AutoLock auto_lock(lock_); 51 base::AutoLock auto_lock(lock_);
47 for (GLsizei ii = 0; ii < n; ++ii) { 52 for (GLsizei ii = 0; ii < n; ++ii) {
48 id_allocator_.FreeID(ids[ii]); 53 id_allocator_.FreeID(ids[ii]);
49 } 54 }
50 (gl_impl->*delete_fn)(n, ids); 55 (gl_impl->*delete_fn)(n, ids);
51 // We need to ensure that the delete call is evaluated on the service side 56 // 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. 57 // before any other contexts issue commands using these client ids.
58 // TODO(vmiura): Can remove this by virtualizing internal ids, however
59 // this code only affects PPAPI for now.
53 gl_impl->helper()->CommandBufferHelper::Flush(); 60 gl_impl->helper()->CommandBufferHelper::Flush();
54 return true; 61 return true;
55 } 62 }
56 63
57 // Overridden from IdHandlerInterface. 64 // Overridden from IdHandlerInterface.
58 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 65 virtual bool MarkAsUsedForBind(GLES2Implementation* /* gl_impl */,
66 GLuint id) OVERRIDE {
59 if (id == 0) 67 if (id == 0)
60 return true; 68 return true;
61 base::AutoLock auto_lock(lock_); 69 base::AutoLock auto_lock(lock_);
62 return id_allocator_.MarkAsUsed(id); 70 return id_allocator_.MarkAsUsed(id);
63 } 71 }
64 72
65 protected: 73 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
74
75 private:
66 base::Lock lock_; 76 base::Lock lock_;
67 IdAllocator id_allocator_; 77 IdAllocator id_allocator_;
68 }; 78 };
69 79
70 // An id handler that requires Gen before Bind. 80 // An id handler that requires Gen before Bind.
71 class StrictIdHandler : public IdHandler { 81 class StrictIdHandler : public IdHandlerInterface {
72 public: 82 public:
73 StrictIdHandler() {} 83 explicit StrictIdHandler(int id_namespace) : id_namespace_(id_namespace) {}
74 virtual ~StrictIdHandler() {} 84 virtual ~StrictIdHandler() {}
75 85
76 // Overridden from IdHandler. 86 // Overridden from IdHandler.
77 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 87 virtual void MakeIds(GLES2Implementation* gl_impl,
88 GLuint id_offset,
89 GLsizei n,
90 GLuint* ids) OVERRIDE {
91 base::AutoLock auto_lock(lock_);
92
93 // Collect pending FreeIds from other flush_generation.
94 CollectPendingFreeIds(gl_impl);
95
96 // Allocate Ids.
97 if (id_offset == 0) {
98 for (GLsizei ii = 0; ii < n; ++ii) {
99 ids[ii] = id_allocator_.AllocateID();
100 }
101 } else {
102 for (GLsizei ii = 0; ii < n; ++ii) {
103 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
104 id_offset = ids[ii] + 1;
105 }
106 }
107 }
108
109 // Overridden from IdHandler.
110 virtual bool FreeIds(GLES2Implementation* gl_impl,
111 GLsizei n,
112 const GLuint* ids,
113 DeleteFn delete_fn) OVERRIDE {
114 base::AutoLock auto_lock(lock_);
115
116 // Collect pending FreeIds from other flush_generation.
117 CollectPendingFreeIds(gl_impl);
vmiura 2014/02/16 17:41:31 Bug: CollectPendingFreeIds() is recording the curr
vmiura 2014/02/16 20:28:01 Correction, the gl_impl->*delete_fn() call is caus
vmiura 2014/02/18 21:15:01 Fixed by moving order of gl_impl->*delete_fn().
118
119 // Save Ids to free in a later flush_generation.
120 ShareGroupContextData::IdHandlerData* ctxt_data =
121 gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
122 for (GLsizei ii = 0; ii < n; ++ii) {
123 ctxt_data->freed_ids_.push_back(ids[ii]);
124 }
125
vmiura 2014/02/16 17:41:31 Bug: Keeping freed_ids_ per context is not suffici
vmiura 2014/02/18 20:08:08 I see that deleting the same Ids twice is a GL err
vmiura 2014/02/18 21:15:01 Fixed by adding DCHECKs.
126 (gl_impl->*delete_fn)(n, ids);
127 return true;
128 }
129
130 // Overridden from IdHandler.
131 virtual bool MarkAsUsedForBind(GLES2Implementation* gl_impl,
132 GLuint id) OVERRIDE {
78 #ifndef NDEBUG 133 #ifndef NDEBUG
79 { 134 {
80 base::AutoLock auto_lock(lock_); 135 base::AutoLock auto_lock(lock_);
136 ShareGroupContextData::IdHandlerData* ctxt_data =
137 gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
138 for (uint32 ii = 0; ii < ctxt_data->freed_ids_.size(); ++ii) {
139 DCHECK(id == 0 || id != ctxt_data->freed_ids_[ii]);
140 }
81 DCHECK(id == 0 || id_allocator_.InUse(id)); 141 DCHECK(id == 0 || id_allocator_.InUse(id));
82 } 142 }
143 #else
144 (void)gl_impl;
83 #endif 145 #endif
84 return true; 146 return true;
85 } 147 }
148
149 // Overridden from IdHandlerInterface.
150 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {
151 base::AutoLock auto_lock(lock_);
vmiura 2014/02/16 17:41:31 Bug: This lock was missing.
vmiura 2014/02/18 21:15:01 Done.
152 CollectPendingFreeIds(gl_impl);
153 }
154
155 private:
156 void CollectPendingFreeIds(GLES2Implementation* gl_impl) {
157 uint32 flush_generation = gl_impl->helper()->flush_generation();
158 ShareGroupContextData::IdHandlerData* ctxt_data =
159 gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
160
161 if (ctxt_data->flush_generation_ != flush_generation) {
162 ctxt_data->flush_generation_ = flush_generation;
163 for (uint32 ii = 0; ii < ctxt_data->freed_ids_.size(); ++ii) {
164 id_allocator_.FreeID(ctxt_data->freed_ids_[ii]);
165 }
166 ctxt_data->freed_ids_.clear();
167 }
168 }
169
170 int id_namespace_;
171
172 base::Lock lock_;
173 IdAllocator id_allocator_;
86 }; 174 };
87 175
88 // An id handler for ids that are never reused. 176 // An id handler for ids that are never reused.
89 class NonReusedIdHandler : public IdHandlerInterface { 177 class NonReusedIdHandler : public IdHandlerInterface {
90 public: 178 public:
91 NonReusedIdHandler() : last_id_(0) {} 179 NonReusedIdHandler() : last_id_(0) {}
92 virtual ~NonReusedIdHandler() {} 180 virtual ~NonReusedIdHandler() {}
93 181
94 // Overridden from IdHandlerInterface. 182 // Overridden from IdHandlerInterface.
95 virtual void MakeIds( 183 virtual void MakeIds(
96 GLES2Implementation* /* gl_impl */, 184 GLES2Implementation* /* gl_impl */,
97 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE { 185 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
98 base::AutoLock auto_lock(lock_); 186 base::AutoLock auto_lock(lock_);
99 for (GLsizei ii = 0; ii < n; ++ii) { 187 for (GLsizei ii = 0; ii < n; ++ii) {
100 ids[ii] = ++last_id_ + id_offset; 188 ids[ii] = ++last_id_ + id_offset;
101 } 189 }
102 } 190 }
103 191
104 // Overridden from IdHandlerInterface. 192 // Overridden from IdHandlerInterface.
105 virtual bool FreeIds( 193 virtual bool FreeIds(
106 GLES2Implementation* gl_impl, 194 GLES2Implementation* gl_impl,
107 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE { 195 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
108 // Ids are never freed. 196 // Ids are never freed.
109 (gl_impl->*delete_fn)(n, ids); 197 (gl_impl->*delete_fn)(n, ids);
110 return true; 198 return true;
111 } 199 }
112 200
113 // Overridden from IdHandlerInterface. 201 // Overridden from IdHandlerInterface.
114 virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE { 202 virtual bool MarkAsUsedForBind(GLES2Implementation* /* gl_impl */,
203 GLuint /* id */) OVERRIDE {
115 // This is only used for Shaders and Programs which have no bind. 204 // This is only used for Shaders and Programs which have no bind.
116 return false; 205 return false;
117 } 206 }
118 207
208 virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
209
119 private: 210 private:
120 base::Lock lock_; 211 base::Lock lock_;
121 GLuint last_id_; 212 GLuint last_id_;
122 }; 213 };
123 214
124 ShareGroup::ShareGroup(bool bind_generates_resource) 215 ShareGroup::ShareGroup(bool bind_generates_resource)
125 : bind_generates_resource_(bind_generates_resource) { 216 : bind_generates_resource_(bind_generates_resource) {
126 if (bind_generates_resource) { 217 if (bind_generates_resource) {
127 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 218 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
128 if (i == id_namespaces::kProgramsAndShaders) { 219 if (i == id_namespaces::kProgramsAndShaders) {
129 id_handlers_[i].reset(new NonReusedIdHandler()); 220 id_handlers_[i].reset(new NonReusedIdHandler());
130 } else { 221 } else {
131 id_handlers_[i].reset(new IdHandler()); 222 id_handlers_[i].reset(new IdHandler());
132 } 223 }
133 } 224 }
134 } else { 225 } else {
135 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 226 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
136 if (i == id_namespaces::kProgramsAndShaders) { 227 if (i == id_namespaces::kProgramsAndShaders) {
137 id_handlers_[i].reset(new NonReusedIdHandler()); 228 id_handlers_[i].reset(new NonReusedIdHandler());
138 } else { 229 } else {
139 id_handlers_[i].reset(new StrictIdHandler()); 230 id_handlers_[i].reset(new StrictIdHandler(i));
140 } 231 }
141 } 232 }
142 } 233 }
143 program_info_manager_.reset(ProgramInfoManager::Create(false)); 234 program_info_manager_.reset(ProgramInfoManager::Create(false));
144 } 235 }
145 236
146 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) { 237 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
147 program_info_manager_.reset(manager); 238 program_info_manager_.reset(manager);
148 } 239 }
149 240
150 ShareGroup::~ShareGroup() {} 241 ShareGroup::~ShareGroup() {}
151 242
152 } // namespace gles2 243 } // namespace gles2
153 } // namespace gpu 244 } // 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