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

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

Issue 154263011: Reduce cost of glBind* on contexts without bind_generates_resource. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 "gpu/command_buffer/client/share_group.h" 5 #include "gpu/command_buffer/client/share_group.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/synchronization/lock.h" 8 #include "base/synchronization/lock.h"
9 #include "gpu/command_buffer/client/gles2_implementation.h" 9 #include "gpu/command_buffer/client/gles2_implementation.h"
10 #include "gpu/command_buffer/client/program_info_manager.h" 10 #include "gpu/command_buffer/client/program_info_manager.h"
11 #include "gpu/command_buffer/common/id_allocator.h" 11 #include "gpu/command_buffer/common/id_allocator.h"
12 12
13 namespace gpu { 13 namespace gpu {
14 namespace gles2 { 14 namespace gles2 {
15 15
16 COMPILE_ASSERT(gpu::kInvalidResource == 0, 16 COMPILE_ASSERT(gpu::kInvalidResource == 0,
17 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS); 17 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
18 18
19 // The standard id handler. 19 // The standard id handler.
20 class IdHandler : public IdHandlerInterface { 20 class IdHandler : public IdHandlerInterface {
21 public: 21 public:
22 IdHandler() { } 22 IdHandler() { }
23 virtual ~IdHandler() { } 23 virtual ~IdHandler() { }
24 24
25 // Overridden from IdHandlerInterface. 25 // Overridden from IdHandlerInterface.
26 virtual void MakeIds( 26 virtual void MakeIds(
27 GLES2Implementation* /* gl_impl */, 27 GLES2Implementation* /* gl_impl */,
28 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE { 28 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
29 base::AutoLock auto_lock(lock_);
29 if (id_offset == 0) { 30 if (id_offset == 0) {
30 for (GLsizei ii = 0; ii < n; ++ii) { 31 for (GLsizei ii = 0; ii < n; ++ii) {
31 ids[ii] = id_allocator_.AllocateID(); 32 ids[ii] = id_allocator_.AllocateID();
32 } 33 }
33 } else { 34 } else {
34 for (GLsizei ii = 0; ii < n; ++ii) { 35 for (GLsizei ii = 0; ii < n; ++ii) {
35 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset); 36 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
36 id_offset = ids[ii] + 1; 37 id_offset = ids[ii] + 1;
37 } 38 }
38 } 39 }
39 } 40 }
40 41
41 // Overridden from IdHandlerInterface. 42 // Overridden from IdHandlerInterface.
42 virtual bool FreeIds( 43 virtual bool FreeIds(
43 GLES2Implementation* gl_impl, 44 GLES2Implementation* gl_impl,
44 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE { 45 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
46 base::AutoLock auto_lock(lock_);
45 for (GLsizei ii = 0; ii < n; ++ii) { 47 for (GLsizei ii = 0; ii < n; ++ii) {
46 id_allocator_.FreeID(ids[ii]); 48 id_allocator_.FreeID(ids[ii]);
47 } 49 }
48 (gl_impl->*delete_fn)(n, ids); 50 (gl_impl->*delete_fn)(n, ids);
49 // We need to ensure that the delete call is evaluated on the service side 51 // We need to ensure that the delete call is evaluated on the service side
50 // before any other contexts issue commands using these client ids. 52 // before any other contexts issue commands using these client ids.
51 gl_impl->helper()->CommandBufferHelper::Flush(); 53 gl_impl->helper()->CommandBufferHelper::Flush();
52 return true; 54 return true;
53 } 55 }
54 56
55 // Overridden from IdHandlerInterface. 57 // Overridden from IdHandlerInterface.
56 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 58 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
57 return id == 0 ? true : id_allocator_.MarkAsUsed(id); 59 if (id == 0)
60 return true;
61 base::AutoLock auto_lock(lock_);
62 return id_allocator_.MarkAsUsed(id);
58 } 63 }
64
59 protected: 65 protected:
60 IdAllocator id_allocator_; 66 IdAllocator id_allocator_;
67 base::Lock lock_;
piman 2014/02/12 00:52:53 nit: a common pattern is to put the lock before th
vmiura 2014/02/12 02:03:52 Done.
61 }; 68 };
62 69
63 // An id handler that require Gen before Bind. 70 // An id handler that requires Gen before Bind.
64 class StrictIdHandler : public IdHandler { 71 class StrictIdHandler : public IdHandler {
65 public: 72 public:
66 StrictIdHandler() {} 73 StrictIdHandler() {}
67 virtual ~StrictIdHandler() {} 74 virtual ~StrictIdHandler() {}
68 75
69 // Overridden from IdHandler. 76 // Overridden from IdHandler.
70 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { 77 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE { return true; }
piman 2014/02/12 00:52:53 nit: it'd be nice to keep the DCHECK. We can do: #
no sievers 2014/02/12 01:09:04 Although at other times we argue that you shouldn'
vmiura 2014/02/12 02:03:52 Done.
71 DCHECK(id == 0 || id_allocator_.InUse(id));
72 return IdHandler::MarkAsUsedForBind(id);
73 }
74 }; 78 };
75 79
76 // An id handler for ids that are never reused. 80 // An id handler for ids that are never reused.
77 class NonReusedIdHandler : public IdHandlerInterface { 81 class NonReusedIdHandler : public IdHandlerInterface {
78 public: 82 public:
79 NonReusedIdHandler() : last_id_(0) {} 83 NonReusedIdHandler() : last_id_(0) {}
80 virtual ~NonReusedIdHandler() {} 84 virtual ~NonReusedIdHandler() {}
81 85
82 // Overridden from IdHandlerInterface. 86 // Overridden from IdHandlerInterface.
83 virtual void MakeIds( 87 virtual void MakeIds(
84 GLES2Implementation* /* gl_impl */, 88 GLES2Implementation* /* gl_impl */,
85 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE { 89 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
90 base::AutoLock auto_lock(lock_);
86 for (GLsizei ii = 0; ii < n; ++ii) { 91 for (GLsizei ii = 0; ii < n; ++ii) {
87 ids[ii] = ++last_id_ + id_offset; 92 ids[ii] = ++last_id_ + id_offset;
no sievers 2014/02/12 01:09:04 I guess we could make that use an atomic as a foll
88 } 93 }
89 } 94 }
90 95
91 // Overridden from IdHandlerInterface. 96 // Overridden from IdHandlerInterface.
92 virtual bool FreeIds( 97 virtual bool FreeIds(
93 GLES2Implementation* gl_impl, 98 GLES2Implementation* gl_impl,
94 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE { 99 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
95 // Ids are never freed. 100 // Ids are never freed.
96 (gl_impl->*delete_fn)(n, ids); 101 (gl_impl->*delete_fn)(n, ids);
97 return true; 102 return true;
98 } 103 }
99 104
100 // Overridden from IdHandlerInterface. 105 // Overridden from IdHandlerInterface.
101 virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE { 106 virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE {
102 // This is only used for Shaders and Programs which have no bind. 107 // This is only used for Shaders and Programs which have no bind.
103 return false; 108 return false;
104 } 109 }
105 110
106 private: 111 private:
107 GLuint last_id_; 112 GLuint last_id_;
108 }; 113 base::Lock lock_;
109
110 // An id handler for shared ids.
111 class SharedIdHandler : public IdHandlerInterface {
112 public:
113 SharedIdHandler(
114 id_namespaces::IdNamespaces id_namespace)
115 : id_namespace_(id_namespace) {
116 }
117
118 virtual ~SharedIdHandler() {}
119
120 virtual void MakeIds(GLES2Implementation* gl_impl,
121 GLuint id_offset,
122 GLsizei n,
123 GLuint* ids) OVERRIDE {
124 gl_impl->GenSharedIdsCHROMIUM(id_namespace_, id_offset, n, ids);
125 }
126
127 virtual bool FreeIds(GLES2Implementation* gl_impl,
128 GLsizei n,
129 const GLuint* ids,
130 DeleteFn delete_fn) OVERRIDE {
131 gl_impl->DeleteSharedIdsCHROMIUM(id_namespace_, n, ids);
132 (gl_impl->*delete_fn)(n, ids);
133 // We need to ensure that the delete call is evaluated on the service side
134 // before any other contexts issue commands using these client ids.
135 gl_impl->helper()->CommandBufferHelper::Flush();
136 return true;
137 }
138
139 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
140 // This has no meaning for shared resources.
141 return true;
142 }
143
144 private:
145 id_namespaces::IdNamespaces id_namespace_;
146 };
147
148 class ThreadSafeIdHandlerWrapper : public IdHandlerInterface {
149 public:
150 ThreadSafeIdHandlerWrapper(IdHandlerInterface* id_handler)
151 : id_handler_(id_handler) {
152 }
153 virtual ~ThreadSafeIdHandlerWrapper() { }
154
155 // Overridden from IdHandlerInterface.
156 virtual void MakeIds(GLES2Implementation* gl_impl,
157 GLuint id_offset,
158 GLsizei n,
159 GLuint* ids) OVERRIDE {
160 base::AutoLock auto_lock(lock_);
161 id_handler_->MakeIds(gl_impl, id_offset, n, ids);
162 }
163
164 // Overridden from IdHandlerInterface.
165 virtual bool FreeIds(GLES2Implementation* gl_impl,
166 GLsizei n,
167 const GLuint* ids,
168 DeleteFn delete_fn) OVERRIDE {
169 base::AutoLock auto_lock(lock_);
170 return id_handler_->FreeIds(gl_impl, n, ids, delete_fn);
171 }
172
173 // Overridden from IdHandlerInterface.
174 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
175 base::AutoLock auto_lock(lock_);
176 return id_handler_->MarkAsUsedForBind(id);
177 }
178
179 private:
180 scoped_ptr<IdHandlerInterface> id_handler_;
181 base::Lock lock_;
182 }; 114 };
183 115
184 ShareGroup::ShareGroup(bool bind_generates_resource) 116 ShareGroup::ShareGroup(bool bind_generates_resource)
185 : bind_generates_resource_(bind_generates_resource) { 117 : bind_generates_resource_(bind_generates_resource) {
186 if (bind_generates_resource) { 118 if (bind_generates_resource) {
187 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 119 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
188 if (i == id_namespaces::kProgramsAndShaders) { 120 if (i == id_namespaces::kProgramsAndShaders) {
189 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper( 121 id_handlers_[i].reset(new NonReusedIdHandler());
190 new NonReusedIdHandler()));
191 } else { 122 } else {
192 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper( 123 id_handlers_[i].reset(new IdHandler());
193 new IdHandler()));
194 } 124 }
195 } 125 }
196 } else { 126 } else {
197 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { 127 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
198 if (i == id_namespaces::kProgramsAndShaders) { 128 if (i == id_namespaces::kProgramsAndShaders) {
199 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper( 129 id_handlers_[i].reset(new NonReusedIdHandler());
200 new NonReusedIdHandler()));
201 } else { 130 } else {
202 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper( 131 id_handlers_[i].reset(new StrictIdHandler());
203 new StrictIdHandler()));
204 } 132 }
205 } 133 }
206 } 134 }
207 program_info_manager_.reset(ProgramInfoManager::Create(false)); 135 program_info_manager_.reset(ProgramInfoManager::Create(false));
208 } 136 }
209 137
210 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) { 138 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
211 program_info_manager_.reset(manager); 139 program_info_manager_.reset(manager);
212 } 140 }
213 141
214 ShareGroup::~ShareGroup() {} 142 ShareGroup::~ShareGroup() {}
215 143
216 } // namespace gles2 144 } // namespace gles2
217 } // namespace gpu 145 } // namespace gpu
OLDNEW
« no previous file with comments | « no previous file | gpu/command_buffer/service/gles2_cmd_decoder.cc » ('j') | gpu/command_buffer/service/gles2_cmd_decoder.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698