Added unit test for DevTools' ephemeral port support.
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_manager.cc
blobb0b947e318dbd8d02eb46f705b431dbf31e91257
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"
7 #include <vector>
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"
30 namespace gpu {
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()
38 : size(4, 4),
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) {
49 SetupBaseContext();
52 GLManager::~GLManager() {
53 --use_count_;
54 if (!use_count_) {
55 if (base_share_group_) {
56 delete base_context_;
57 base_context_ = NULL;
59 if (base_surface_) {
60 delete base_surface_;
61 base_surface_ = NULL;
63 if (base_context_) {
64 delete base_context_;
65 base_context_ = NULL;
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();
96 client_share_group =
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();
105 mailbox_manager_ =
106 mailbox_manager ? mailbox_manager : new gles2::MailboxManager;
107 share_group_ =
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) {
121 context_group =
122 new gles2::ContextGroup(mailbox_manager_.get(),
123 options.image_manager,
124 NULL,
125 new gpu::gles2::ShaderTranslatorCache,
126 NULL,
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(),
138 decoder_.get(),
139 decoder_.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";
146 if (base_context_) {
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));
151 } else {
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));
157 } else {
158 context_ = gfx::GLContext::CreateGLContext(share_group_.get(),
159 surface_.get(),
160 gpu_preference);
163 ASSERT_TRUE(context_.get() != NULL) << "could not create GL context";
165 ASSERT_TRUE(context_->MakeCurrent(surface_.get()));
167 ASSERT_TRUE(decoder_->Initialize(
168 surface_.get(),
169 context_.get(),
170 true,
171 options.size,
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(),
195 client_share_group,
196 transfer_buffer_.get(),
197 options.bind_generates_resource,
198 options.lose_context_when_out_of_memory,
199 this));
201 ASSERT_TRUE(gles2_implementation_->Initialize(
202 kStartTransferBufferSize,
203 kMinTransferBufferSize,
204 kMaxTransferBufferSize,
205 gpu::gles2::GLES2Implementation::kNoLimit))
206 << "Could not init GLES2Implementation";
208 MakeCurrent();
211 void GLManager::SetupBaseContext() {
212 if (use_count_) {
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(),
223 gpu_preference));
224 #endif
226 ++use_count_;
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()) {
239 MakeCurrent();
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);
250 decoder_.reset();
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(
276 size_t width,
277 size_t height,
278 unsigned internalformat,
279 unsigned usage,
280 int32* id) {
281 *id = -1;
282 scoped_ptr<gfx::GpuMemoryBuffer> buffer(
283 gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
284 width, height, internalformat, usage));
285 if (!buffer.get())
286 return NULL;
288 static int32 next_id = 1;
289 *id = next_id++;
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());
294 return raw_buffer;
297 void GLManager::DestroyGpuMemoryBuffer(int32 id) {
298 memory_buffers_.erase(id);
299 gpu_control_service_->UnregisterGpuMemoryBuffer(id);
302 uint32 GLManager::InsertSyncPoint() {
303 NOTIMPLEMENTED();
304 return 0u;
307 void GLManager::SignalSyncPoint(uint32 sync_point,
308 const base::Closure& callback) {
309 NOTIMPLEMENTED();
312 void GLManager::SignalQuery(uint32 query, const base::Closure& callback) {
313 NOTIMPLEMENTED();
316 void GLManager::SetSurfaceVisible(bool visible) {
317 NOTIMPLEMENTED();
320 void GLManager::SendManagedMemoryStats(const ManagedMemoryStats& stats) {
321 NOTIMPLEMENTED();
324 void GLManager::Echo(const base::Closure& callback) {
325 NOTIMPLEMENTED();
328 uint32 GLManager::CreateStreamTexture(uint32 texture_id) {
329 NOTIMPLEMENTED();
330 return 0;
333 } // namespace gpu