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/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"
15 COMPILE_ASSERT(gpu::kInvalidResource
== 0,
16 INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS
);
18 // The standard id handler.
19 class IdHandler
: public IdHandlerInterface
{
22 virtual ~IdHandler() { }
24 // Overridden from IdHandlerInterface.
26 GLES2Implementation
* /* gl_impl */,
27 GLuint id_offset
, GLsizei n
, GLuint
* ids
) OVERRIDE
{
29 for (GLsizei ii
= 0; ii
< n
; ++ii
) {
30 ids
[ii
] = id_allocator_
.AllocateID();
33 for (GLsizei ii
= 0; ii
< n
; ++ii
) {
34 ids
[ii
] = id_allocator_
.AllocateIDAtOrAbove(id_offset
);
35 id_offset
= ids
[ii
] + 1;
40 // Overridden from IdHandlerInterface.
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
]);
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();
54 // Overridden from IdHandlerInterface.
55 virtual bool MarkAsUsedForBind(GLuint id
) OVERRIDE
{
56 return id
== 0 ? true : id_allocator_
.MarkAsUsed(id
);
59 IdAllocator id_allocator_
;
62 // An id handler that require Gen before Bind.
63 class StrictIdHandler
: public IdHandler
{
66 virtual ~StrictIdHandler() {}
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
);
75 // An id handler for ids that are never reused.
76 class NonReusedIdHandler
: public IdHandlerInterface
{
78 NonReusedIdHandler() : last_id_(0) {}
79 virtual ~NonReusedIdHandler() {}
81 // Overridden from IdHandlerInterface.
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
;
90 // Overridden from IdHandlerInterface.
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
);
99 // Overridden from IdHandlerInterface.
100 virtual bool MarkAsUsedForBind(GLuint
/* id */) OVERRIDE
{
101 // This is only used for Shaders and Programs which have no bind.
109 // An id handler for shared ids.
110 class SharedIdHandler
: public IdHandlerInterface
{
113 id_namespaces::IdNamespaces id_namespace
)
114 : id_namespace_(id_namespace
) {
117 virtual ~SharedIdHandler() {}
119 virtual void MakeIds(GLES2Implementation
* gl_impl
,
122 GLuint
* ids
) OVERRIDE
{
123 gl_impl
->GenSharedIdsCHROMIUM(id_namespace_
, id_offset
, n
, ids
);
126 virtual bool FreeIds(GLES2Implementation
* gl_impl
,
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();
138 virtual bool MarkAsUsedForBind(GLuint id
) OVERRIDE
{
139 // This has no meaning for shared resources.
144 id_namespaces::IdNamespaces id_namespace_
;
147 class ThreadSafeIdHandlerWrapper
: public IdHandlerInterface
{
149 ThreadSafeIdHandlerWrapper(IdHandlerInterface
* id_handler
)
150 : id_handler_(id_handler
) {
152 virtual ~ThreadSafeIdHandlerWrapper() { }
154 // Overridden from IdHandlerInterface.
155 virtual void MakeIds(GLES2Implementation
* gl_impl
,
158 GLuint
* ids
) OVERRIDE
{
159 AutoLock
auto_lock(lock_
);
160 id_handler_
->MakeIds(gl_impl
, id_offset
, n
, ids
);
163 // Overridden from IdHandlerInterface.
164 virtual bool FreeIds(GLES2Implementation
* gl_impl
,
167 DeleteFn delete_fn
) OVERRIDE
{
168 AutoLock
auto_lock(lock_
);
169 return id_handler_
->FreeIds(gl_impl
, n
, ids
, delete_fn
);
172 // Overridden from IdHandlerInterface.
173 virtual bool MarkAsUsedForBind(GLuint id
) OVERRIDE
{
174 AutoLock
auto_lock(lock_
);
175 return id_handler_
->MarkAsUsedForBind(id
);
179 scoped_ptr
<IdHandlerInterface
> id_handler_
;
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()));
191 id_handlers_
[i
].reset(new ThreadSafeIdHandlerWrapper(
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()));
201 id_handlers_
[i
].reset(new ThreadSafeIdHandlerWrapper(
202 new StrictIdHandler()));
206 program_info_manager_
.reset(ProgramInfoManager::Create(false));
209 void ShareGroup::set_program_info_manager(ProgramInfoManager
* manager
) {
210 program_info_manager_
.reset(manager
);
213 ShareGroup::~ShareGroup() {}