cb9f9bca5c6819e8769fdf11e738046eddafa364
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / client / share_group.cc
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:
22   IdHandler() { }
23   virtual ~IdHandler() { }
24
25   // Overridden from IdHandlerInterface.
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.
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.
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:
66   StrictIdHandler() {}
67   virtual ~StrictIdHandler() {}
68
69   // Overridden from IdHandler.
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:
79   NonReusedIdHandler() : last_id_(0) {}
80   virtual ~NonReusedIdHandler() {}
81
82   // Overridden from IdHandlerInterface.
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.
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.
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:
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 };
183
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
210 void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
211   program_info_manager_.reset(manager);
212 }
213
214 ShareGroup::~ShareGroup() {}
215
216 }  // namespace gles2
217 }  // namespace gpu