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/tests/gl_manager.h"
9 #include "base/at_exit.h"
10 #include "base/bind.h"
11 #include "gpu/command_buffer/client/gles2_implementation.h"
12 #include "gpu/command_buffer/client/gles2_lib.h"
13 #include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
14 #include "gpu/command_buffer/client/transfer_buffer.h"
15 #include "gpu/command_buffer/common/constants.h"
16 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
17 #include "gpu/command_buffer/service/command_buffer_service.h"
18 #include "gpu/command_buffer/service/context_group.h"
19 #include "gpu/command_buffer/service/gl_context_virtual.h"
20 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
21 #include "gpu/command_buffer/service/gpu_control_service.h"
22 #include "gpu/command_buffer/service/gpu_scheduler.h"
23 #include "gpu/command_buffer/service/image_manager.h"
24 #include "gpu/command_buffer/service/mailbox_manager.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gl/gl_context.h"
27 #include "ui/gl/gl_share_group.h"
28 #include "ui/gl/gl_surface.h"
32 int GLManager::use_count_
;
33 scoped_refptr
<gfx::GLShareGroup
>* GLManager::base_share_group_
;
34 scoped_refptr
<gfx::GLSurface
>* GLManager::base_surface_
;
35 scoped_refptr
<gfx::GLContext
>* GLManager::base_context_
;
37 GLManager::Options::Options()
39 share_group_manager(NULL
),
40 share_mailbox_manager(NULL
),
41 virtual_manager(NULL
),
42 bind_generates_resource(false),
43 lose_context_when_out_of_memory(false),
44 context_lost_allowed(false),
45 image_manager(NULL
) {}
47 GLManager::GLManager()
48 : context_lost_allowed_(false), gpu_memory_buffer_factory_(NULL
) {
52 GLManager::~GLManager() {
55 if (base_share_group_
) {
70 void GLManager::Initialize(const GLManager::Options
& options
) {
71 const int32 kCommandBufferSize
= 1024 * 1024;
72 const size_t kStartTransferBufferSize
= 4 * 1024 * 1024;
73 const size_t kMinTransferBufferSize
= 1 * 256 * 1024;
74 const size_t kMaxTransferBufferSize
= 16 * 1024 * 1024;
76 context_lost_allowed_
= options
.context_lost_allowed
;
78 gles2::MailboxManager
* mailbox_manager
= NULL
;
79 if (options
.share_mailbox_manager
) {
80 mailbox_manager
= options
.share_mailbox_manager
->mailbox_manager();
81 } else if (options
.share_group_manager
) {
82 mailbox_manager
= options
.share_group_manager
->mailbox_manager();
85 gfx::GLShareGroup
* share_group
= NULL
;
86 if (options
.share_group_manager
) {
87 share_group
= options
.share_group_manager
->share_group();
88 } else if (options
.share_mailbox_manager
) {
89 share_group
= options
.share_mailbox_manager
->share_group();
92 gles2::ContextGroup
* context_group
= NULL
;
93 gles2::ShareGroup
* client_share_group
= NULL
;
94 if (options
.share_group_manager
) {
95 context_group
= options
.share_group_manager
->decoder_
->GetContextGroup();
97 options
.share_group_manager
->gles2_implementation()->share_group();
100 gfx::GLContext
* real_gl_context
= NULL
;
101 if (options
.virtual_manager
) {
102 real_gl_context
= options
.virtual_manager
->context();
106 mailbox_manager
? mailbox_manager
: new gles2::MailboxManager
;
108 share_group
? share_group
: new gfx::GLShareGroup
;
110 gfx::GpuPreference
gpu_preference(gfx::PreferDiscreteGpu
);
111 std::vector
<int32
> attribs
;
112 gles2::ContextCreationAttribHelper attrib_helper
;
113 attrib_helper
.red_size_
= 8;
114 attrib_helper
.green_size_
= 8;
115 attrib_helper
.blue_size_
= 8;
116 attrib_helper
.alpha_size_
= 8;
117 attrib_helper
.depth_size_
= 16;
118 attrib_helper
.Serialize(&attribs
);
120 if (!context_group
) {
122 new gles2::ContextGroup(mailbox_manager_
.get(),
123 options
.image_manager
,
125 new gpu::gles2::ShaderTranslatorCache
,
127 options
.bind_generates_resource
);
130 decoder_
.reset(::gpu::gles2::GLES2Decoder::Create(context_group
));
132 command_buffer_
.reset(new CommandBufferService(
133 decoder_
->GetContextGroup()->transfer_buffer_manager()));
134 ASSERT_TRUE(command_buffer_
->Initialize())
135 << "could not create command buffer service";
137 gpu_scheduler_
.reset(new GpuScheduler(command_buffer_
.get(),
141 decoder_
->set_engine(gpu_scheduler_
.get());
143 surface_
= gfx::GLSurface::CreateOffscreenGLSurface(options
.size
);
144 ASSERT_TRUE(surface_
.get() != NULL
) << "could not create offscreen surface";
147 context_
= scoped_refptr
<gfx::GLContext
>(new gpu::GLContextVirtual(
148 share_group_
.get(), base_context_
->get(), decoder_
->AsWeakPtr()));
149 ASSERT_TRUE(context_
->Initialize(
150 surface_
.get(), gfx::PreferIntegratedGpu
));
152 if (real_gl_context
) {
153 context_
= scoped_refptr
<gfx::GLContext
>(new gpu::GLContextVirtual(
154 share_group_
.get(), real_gl_context
, decoder_
->AsWeakPtr()));
155 ASSERT_TRUE(context_
->Initialize(
156 surface_
.get(), gfx::PreferIntegratedGpu
));
158 context_
= gfx::GLContext::CreateGLContext(share_group_
.get(),
163 ASSERT_TRUE(context_
.get() != NULL
) << "could not create GL context";
165 ASSERT_TRUE(context_
->MakeCurrent(surface_
.get()));
167 ASSERT_TRUE(decoder_
->Initialize(
172 ::gpu::gles2::DisallowedFeatures(),
173 attribs
)) << "could not initialize decoder";
175 gpu_control_service_
.reset(
176 new GpuControlService(decoder_
->GetContextGroup()->image_manager(),
177 decoder_
->GetQueryManager()));
178 gpu_memory_buffer_factory_
= options
.gpu_memory_buffer_factory
;
180 command_buffer_
->SetPutOffsetChangeCallback(
181 base::Bind(&GLManager::PumpCommands
, base::Unretained(this)));
182 command_buffer_
->SetGetBufferChangeCallback(
183 base::Bind(&GLManager::GetBufferChanged
, base::Unretained(this)));
185 // Create the GLES2 helper, which writes the command buffer protocol.
186 gles2_helper_
.reset(new gles2::GLES2CmdHelper(command_buffer_
.get()));
187 ASSERT_TRUE(gles2_helper_
->Initialize(kCommandBufferSize
));
189 // Create a transfer buffer.
190 transfer_buffer_
.reset(new TransferBuffer(gles2_helper_
.get()));
192 // Create the object exposing the OpenGL API.
193 gles2_implementation_
.reset(
194 new gles2::GLES2Implementation(gles2_helper_
.get(),
196 transfer_buffer_
.get(),
197 options
.bind_generates_resource
,
198 options
.lose_context_when_out_of_memory
,
201 ASSERT_TRUE(gles2_implementation_
->Initialize(
202 kStartTransferBufferSize
,
203 kMinTransferBufferSize
,
204 kMaxTransferBufferSize
,
205 gpu::gles2::GLES2Implementation::kNoLimit
))
206 << "Could not init GLES2Implementation";
211 void GLManager::SetupBaseContext() {
213 #if defined(OS_ANDROID)
214 base_share_group_
= new scoped_refptr
<gfx::GLShareGroup
>(
215 new gfx::GLShareGroup
);
216 gfx::Size
size(4, 4);
217 base_surface_
= new scoped_refptr
<gfx::GLSurface
>(
218 gfx::GLSurface::CreateOffscreenGLSurface(size
));
219 gfx::GpuPreference
gpu_preference(gfx::PreferDiscreteGpu
);
220 base_context_
= new scoped_refptr
<gfx::GLContext
>(
221 gfx::GLContext::CreateGLContext(base_share_group_
->get(),
222 base_surface_
->get(),
229 void GLManager::MakeCurrent() {
230 ::gles2::SetGLContext(gles2_implementation_
.get());
233 void GLManager::SetSurface(gfx::GLSurface
* surface
) {
234 decoder_
->SetSurface(surface
);
237 void GLManager::Destroy() {
238 if (gles2_implementation_
.get()) {
240 EXPECT_TRUE(glGetError() == GL_NONE
);
241 gles2_implementation_
->Flush();
242 gles2_implementation_
.reset();
244 transfer_buffer_
.reset();
245 gles2_helper_
.reset();
246 command_buffer_
.reset();
247 if (decoder_
.get()) {
248 decoder_
->MakeCurrent();
249 decoder_
->Destroy(true);
254 const gpu::gles2::FeatureInfo::Workarounds
& GLManager::workarounds() const {
255 return decoder_
->GetContextGroup()->feature_info()->workarounds();
258 void GLManager::PumpCommands() {
259 decoder_
->MakeCurrent();
260 gpu_scheduler_
->PutChanged();
261 ::gpu::CommandBuffer::State state
= command_buffer_
->GetLastState();
262 if (!context_lost_allowed_
) {
263 ASSERT_EQ(::gpu::error::kNoError
, state
.error
);
267 bool GLManager::GetBufferChanged(int32 transfer_buffer_id
) {
268 return gpu_scheduler_
->SetGetBuffer(transfer_buffer_id
);
271 Capabilities
GLManager::GetCapabilities() {
272 return decoder_
->GetCapabilities();
275 gfx::GpuMemoryBuffer
* GLManager::CreateGpuMemoryBuffer(
278 unsigned internalformat
,
282 scoped_ptr
<gfx::GpuMemoryBuffer
> buffer(
283 gpu_memory_buffer_factory_
->CreateGpuMemoryBuffer(
284 width
, height
, internalformat
, usage
));
288 static int32 next_id
= 1;
290 gpu_control_service_
->RegisterGpuMemoryBuffer(
291 *id
, buffer
->GetHandle(), width
, height
, internalformat
);
292 gfx::GpuMemoryBuffer
* raw_buffer
= buffer
.get();
293 memory_buffers_
.add(*id
, buffer
.Pass());
297 void GLManager::DestroyGpuMemoryBuffer(int32 id
) {
298 memory_buffers_
.erase(id
);
299 gpu_control_service_
->UnregisterGpuMemoryBuffer(id
);
302 uint32
GLManager::InsertSyncPoint() {
307 void GLManager::SignalSyncPoint(uint32 sync_point
,
308 const base::Closure
& callback
) {
312 void GLManager::SignalQuery(uint32 query
, const base::Closure
& callback
) {
316 void GLManager::SetSurfaceVisible(bool visible
) {
320 void GLManager::SendManagedMemoryStats(const ManagedMemoryStats
& stats
) {
324 void GLManager::Echo(const base::Closure
& callback
) {
328 uint32
GLManager::CreateStreamTexture(uint32 texture_id
) {