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() {}