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