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
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/client/share_group.h"
7 #include "base/logging.h"
8 #include "base/synchronization/lock.h"
9 #include "gpu/command_buffer/client/gles2_implementation.h"
10 #include "gpu/command_buffer/client/program_info_manager.h"
11 #include "gpu/command_buffer/common/id_allocator.h"
16 COMPILE_ASSERT(gpu::kInvalidResource == 0,
17 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
19 // The standard id handler.
20 class IdHandler : public IdHandlerInterface {
23 virtual ~IdHandler() { }
25 // Overridden from IdHandlerInterface.
27 GLES2Implementation* /* gl_impl */,
28 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
30 for (GLsizei ii = 0; ii < n; ++ii) {
31 ids[ii] = id_allocator_.AllocateID();
34 for (GLsizei ii = 0; ii < n; ++ii) {
35 ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
36 id_offset = ids[ii] + 1;
41 // Overridden from IdHandlerInterface.
43 GLES2Implementation* gl_impl,
44 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
45 for (GLsizei ii = 0; ii < n; ++ii) {
46 id_allocator_.FreeID(ids[ii]);
48 (gl_impl->*delete_fn)(n, ids);
49 // 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.
51 gl_impl->helper()->CommandBufferHelper::Flush();
55 // Overridden from IdHandlerInterface.
56 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
57 return id == 0 ? true : id_allocator_.MarkAsUsed(id);
60 IdAllocator id_allocator_;
63 // An id handler that require Gen before Bind.
64 class StrictIdHandler : public IdHandler {
67 virtual ~StrictIdHandler() {}
69 // Overridden from IdHandler.
70 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
71 DCHECK(id == 0 || id_allocator_.InUse(id));
72 return IdHandler::MarkAsUsedForBind(id);
76 // An id handler for ids that are never reused.
77 class NonReusedIdHandler : public IdHandlerInterface {
79 NonReusedIdHandler() : last_id_(0) {}
80 virtual ~NonReusedIdHandler() {}
82 // Overridden from IdHandlerInterface.
84 GLES2Implementation* /* gl_impl */,
85 GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
86 for (GLsizei ii = 0; ii < n; ++ii) {
87 ids[ii] = ++last_id_ + id_offset;
91 // Overridden from IdHandlerInterface.
93 GLES2Implementation* gl_impl,
94 GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
95 // Ids are never freed.
96 (gl_impl->*delete_fn)(n, ids);
100 // Overridden from IdHandlerInterface.
101 virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE {
102 // This is only used for Shaders and Programs which have no bind.
110 // An id handler for shared ids.
111 class SharedIdHandler : public IdHandlerInterface {
114 id_namespaces::IdNamespaces id_namespace)
115 : id_namespace_(id_namespace) {
118 virtual ~SharedIdHandler() {}
120 virtual void MakeIds(GLES2Implementation* gl_impl,
123 GLuint* ids) OVERRIDE {
124 gl_impl->GenSharedIdsCHROMIUM(id_namespace_, id_offset, n, ids);
127 virtual bool FreeIds(GLES2Implementation* gl_impl,
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();
139 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
140 // This has no meaning for shared resources.
145 id_namespaces::IdNamespaces id_namespace_;
148 class ThreadSafeIdHandlerWrapper : public IdHandlerInterface {
150 ThreadSafeIdHandlerWrapper(IdHandlerInterface* id_handler)
151 : id_handler_(id_handler) {
153 virtual ~ThreadSafeIdHandlerWrapper() { }
155 // Overridden from IdHandlerInterface.
156 virtual void MakeIds(GLES2Implementation* gl_impl,
159 GLuint* ids) OVERRIDE {
160 base::AutoLock auto_lock(lock_);
161 id_handler_->MakeIds(gl_impl, id_offset, n, ids);
164 // Overridden from IdHandlerInterface.
165 virtual bool FreeIds(GLES2Implementation* gl_impl,
168 DeleteFn delete_fn) OVERRIDE {
169 base::AutoLock auto_lock(lock_);
170 return id_handler_->FreeIds(gl_impl, n, ids, delete_fn);
173 // Overridden from IdHandlerInterface.
174 virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
175 base::AutoLock auto_lock(lock_);
176 return id_handler_->MarkAsUsedForBind(id);
180 scoped_ptr<IdHandlerInterface> id_handler_;
184 ShareGroup::ShareGroup(bool bind_generates_resource)
185 : bind_generates_resource_(bind_generates_resource) {
186 if (bind_generates_resource) {
187 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
188 if (i == id_namespaces::kProgramsAndShaders) {
189 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
190 new NonReusedIdHandler()));
192 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
197 for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
198 if (i == id_namespaces::kProgramsAndShaders) {
199 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
200 new NonReusedIdHandler()));
202 id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
203 new StrictIdHandler()));
207 program_info_manager_.reset(ProgramInfoManager::Create(false));
210 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
211 program_info_manager_.reset(manager);
214 ShareGroup::~ShareGroup() {}