• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "gpu/command_buffer/client/share_group.h"
6 
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"
12 
13 namespace gpu {
14 namespace gles2 {
15 
16 COMPILE_ASSERT(gpu::kInvalidResource == 0,
17                INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
18 
19 // The standard id handler.
20 class IdHandler : public IdHandlerInterface {
21  public:
IdHandler()22   IdHandler() { }
~IdHandler()23   virtual ~IdHandler() { }
24 
25   // Overridden from IdHandlerInterface.
MakeIds(GLES2Implementation *,GLuint id_offset,GLsizei n,GLuint * ids)26   virtual void MakeIds(
27       GLES2Implementation* /* gl_impl */,
28       GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
29     if (id_offset == 0) {
30       for (GLsizei ii = 0; ii < n; ++ii) {
31         ids[ii] = id_allocator_.AllocateID();
32       }
33     } else {
34       for (GLsizei ii = 0; ii < n; ++ii) {
35         ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
36         id_offset = ids[ii] + 1;
37       }
38     }
39   }
40 
41   // Overridden from IdHandlerInterface.
FreeIds(GLES2Implementation * gl_impl,GLsizei n,const GLuint * ids,DeleteFn delete_fn)42   virtual bool FreeIds(
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]);
47     }
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();
52     return true;
53   }
54 
55   // Overridden from IdHandlerInterface.
MarkAsUsedForBind(GLuint id)56   virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
57     return id == 0 ? true : id_allocator_.MarkAsUsed(id);
58   }
59  protected:
60   IdAllocator id_allocator_;
61 };
62 
63 // An id handler that require Gen before Bind.
64 class StrictIdHandler : public IdHandler {
65  public:
StrictIdHandler()66   StrictIdHandler() {}
~StrictIdHandler()67   virtual ~StrictIdHandler() {}
68 
69   // Overridden from IdHandler.
MarkAsUsedForBind(GLuint id)70   virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
71     DCHECK(id == 0 || id_allocator_.InUse(id));
72     return IdHandler::MarkAsUsedForBind(id);
73   }
74 };
75 
76 // An id handler for ids that are never reused.
77 class NonReusedIdHandler : public IdHandlerInterface {
78  public:
NonReusedIdHandler()79   NonReusedIdHandler() : last_id_(0) {}
~NonReusedIdHandler()80   virtual ~NonReusedIdHandler() {}
81 
82   // Overridden from IdHandlerInterface.
MakeIds(GLES2Implementation *,GLuint id_offset,GLsizei n,GLuint * ids)83   virtual void MakeIds(
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;
88     }
89   }
90 
91   // Overridden from IdHandlerInterface.
FreeIds(GLES2Implementation * gl_impl,GLsizei n,const GLuint * ids,DeleteFn delete_fn)92   virtual bool FreeIds(
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);
97     return true;
98   }
99 
100   // Overridden from IdHandlerInterface.
MarkAsUsedForBind(GLuint)101   virtual bool MarkAsUsedForBind(GLuint /* id */) OVERRIDE {
102     // This is only used for Shaders and Programs which have no bind.
103     return false;
104   }
105 
106  private:
107   GLuint last_id_;
108 };
109 
110 // An id handler for shared ids.
111 class SharedIdHandler : public IdHandlerInterface {
112  public:
SharedIdHandler(id_namespaces::IdNamespaces id_namespace)113   SharedIdHandler(
114       id_namespaces::IdNamespaces id_namespace)
115       : id_namespace_(id_namespace) {
116   }
117 
~SharedIdHandler()118   virtual ~SharedIdHandler() {}
119 
MakeIds(GLES2Implementation * gl_impl,GLuint id_offset,GLsizei n,GLuint * ids)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 
FreeIds(GLES2Implementation * gl_impl,GLsizei n,const GLuint * ids,DeleteFn delete_fn)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 
MarkAsUsedForBind(GLuint id)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:
ThreadSafeIdHandlerWrapper(IdHandlerInterface * id_handler)150   ThreadSafeIdHandlerWrapper(IdHandlerInterface* id_handler)
151       : id_handler_(id_handler) {
152   }
~ThreadSafeIdHandlerWrapper()153   virtual ~ThreadSafeIdHandlerWrapper() { }
154 
155   // Overridden from IdHandlerInterface.
MakeIds(GLES2Implementation * gl_impl,GLuint id_offset,GLsizei n,GLuint * ids)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.
FreeIds(GLES2Implementation * gl_impl,GLsizei n,const GLuint * ids,DeleteFn delete_fn)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.
MarkAsUsedForBind(GLuint id)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 };
183 
ShareGroup(bool bind_generates_resource)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()));
191       } else {
192         id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
193             new IdHandler()));
194       }
195     }
196   } else {
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()));
201       } else {
202         id_handlers_[i].reset(new ThreadSafeIdHandlerWrapper(
203             new StrictIdHandler()));
204       }
205     }
206   }
207   program_info_manager_.reset(ProgramInfoManager::Create(false));
208 }
209 
set_program_info_manager(ProgramInfoManager * manager)210 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
211   program_info_manager_.reset(manager);
212 }
213 
~ShareGroup()214 ShareGroup::~ShareGroup() {}
215 
216 }  // namespace gles2
217 }  // namespace gpu
218