Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_manager.cc
blob82930cd9615e5aba04e3b99557cbe4e5fe5acf5c
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 <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h>
9 #include <GLES2/gl2extchromium.h>
11 #include <vector>
13 #include "base/at_exit.h"
14 #include "base/bind.h"
15 #include "base/memory/ref_counted_memory.h"
16 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
17 #include "gpu/command_buffer/client/gles2_implementation.h"
18 #include "gpu/command_buffer/client/gles2_lib.h"
19 #include "gpu/command_buffer/client/transfer_buffer.h"
20 #include "gpu/command_buffer/common/constants.h"
21 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
22 #include "gpu/command_buffer/common/value_state.h"
23 #include "gpu/command_buffer/service/command_buffer_service.h"
24 #include "gpu/command_buffer/service/context_group.h"
25 #include "gpu/command_buffer/service/gl_context_virtual.h"
26 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
27 #include "gpu/command_buffer/service/gpu_scheduler.h"
28 #include "gpu/command_buffer/service/image_manager.h"
29 #include "gpu/command_buffer/service/mailbox_manager_impl.h"
30 #include "gpu/command_buffer/service/memory_tracking.h"
31 #include "gpu/command_buffer/service/valuebuffer_manager.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "ui/gfx/buffer_format_util.h"
34 #include "ui/gfx/gpu_memory_buffer.h"
35 #include "ui/gl/gl_context.h"
36 #include "ui/gl/gl_image_ref_counted_memory.h"
37 #include "ui/gl/gl_share_group.h"
38 #include "ui/gl/gl_surface.h"
40 namespace gpu {
41 namespace {
43 size_t SubsamplingFactor(gfx::BufferFormat format, int plane) {
44 switch (format) {
45 case gfx::BufferFormat::ATC:
46 case gfx::BufferFormat::ATCIA:
47 case gfx::BufferFormat::DXT1:
48 case gfx::BufferFormat::DXT5:
49 case gfx::BufferFormat::ETC1:
50 case gfx::BufferFormat::R_8:
51 case gfx::BufferFormat::RGBA_4444:
52 case gfx::BufferFormat::RGBA_8888:
53 case gfx::BufferFormat::BGRX_8888:
54 case gfx::BufferFormat::BGRA_8888:
55 case gfx::BufferFormat::UYVY_422:
56 return 1;
57 case gfx::BufferFormat::YUV_420: {
58 static size_t factor[] = {1, 2, 2};
59 DCHECK_LT(static_cast<size_t>(plane), arraysize(factor));
60 return factor[plane];
63 NOTREACHED();
64 return 0;
67 size_t StrideInBytes(size_t width, gfx::BufferFormat format, int plane) {
68 switch (format) {
69 case gfx::BufferFormat::ATCIA:
70 case gfx::BufferFormat::DXT5:
71 DCHECK_EQ(plane, 0);
72 return width;
73 case gfx::BufferFormat::ATC:
74 case gfx::BufferFormat::DXT1:
75 case gfx::BufferFormat::ETC1:
76 DCHECK_EQ(plane, 0);
77 DCHECK_EQ(width % 2, 0U);
78 return width / 2;
79 case gfx::BufferFormat::R_8:
80 return (width + 3) & ~0x3;
81 case gfx::BufferFormat::RGBA_4444:
82 case gfx::BufferFormat::UYVY_422:
83 DCHECK_EQ(plane, 0);
84 return width * 2;
85 case gfx::BufferFormat::RGBA_8888:
86 case gfx::BufferFormat::BGRA_8888:
87 DCHECK_EQ(plane, 0);
88 return width * 4;
89 case gfx::BufferFormat::BGRX_8888:
90 NOTREACHED();
91 return 0;
92 case gfx::BufferFormat::YUV_420:
93 return width / SubsamplingFactor(format, plane);
96 NOTREACHED();
97 return 0;
100 size_t BufferSizeInBytes(const gfx::Size& size, gfx::BufferFormat format) {
101 size_t size_in_bytes = 0;
102 size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format);
103 for (size_t i = 0; i < num_planes; ++i) {
104 size_in_bytes += StrideInBytes(size.width(), format, i) *
105 (size.height() / SubsamplingFactor(format, i));
107 return size_in_bytes;
110 class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
111 public:
112 GpuMemoryBufferImpl(base::RefCountedBytes* bytes,
113 const gfx::Size& size,
114 gfx::BufferFormat format)
115 : bytes_(bytes), size_(size), format_(format), mapped_(false) {}
117 static GpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer) {
118 return reinterpret_cast<GpuMemoryBufferImpl*>(buffer);
121 // Overridden from gfx::GpuMemoryBuffer:
122 bool Map(void** data) override {
123 size_t offset = 0;
124 size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format_);
125 for (size_t i = 0; i < num_planes; ++i) {
126 data[i] = reinterpret_cast<uint8*>(&bytes_->data().front()) + offset;
127 offset += StrideInBytes(size_.width(), format_, i) *
128 (size_.height() / SubsamplingFactor(format_, i));
130 mapped_ = true;
131 return true;
133 void Unmap() override { mapped_ = false; }
134 bool IsMapped() const override { return mapped_; }
135 gfx::BufferFormat GetFormat() const override { return format_; }
136 void GetStride(int* stride) const override {
137 size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format_);
138 for (size_t i = 0; i < num_planes; ++i)
139 stride[i] = StrideInBytes(size_.width(), format_, i);
141 gfx::GpuMemoryBufferId GetId() const override {
142 NOTREACHED();
143 return gfx::GpuMemoryBufferId(0);
145 gfx::GpuMemoryBufferHandle GetHandle() const override {
146 NOTREACHED();
147 return gfx::GpuMemoryBufferHandle();
149 ClientBuffer AsClientBuffer() override {
150 return reinterpret_cast<ClientBuffer>(this);
153 base::RefCountedBytes* bytes() { return bytes_.get(); }
155 private:
156 scoped_refptr<base::RefCountedBytes> bytes_;
157 const gfx::Size size_;
158 gfx::BufferFormat format_;
159 bool mapped_;
162 } // namespace
164 int GLManager::use_count_;
165 scoped_refptr<gfx::GLShareGroup>* GLManager::base_share_group_;
166 scoped_refptr<gfx::GLSurface>* GLManager::base_surface_;
167 scoped_refptr<gfx::GLContext>* GLManager::base_context_;
169 GLManager::Options::Options()
170 : size(4, 4),
171 share_group_manager(NULL),
172 share_mailbox_manager(NULL),
173 virtual_manager(NULL),
174 bind_generates_resource(false),
175 lose_context_when_out_of_memory(false),
176 context_lost_allowed(false),
177 webgl_version(0) {
180 GLManager::GLManager() : context_lost_allowed_(false) {
181 SetupBaseContext();
184 GLManager::~GLManager() {
185 --use_count_;
186 if (!use_count_) {
187 if (base_share_group_) {
188 delete base_context_;
189 base_context_ = NULL;
191 if (base_surface_) {
192 delete base_surface_;
193 base_surface_ = NULL;
195 if (base_context_) {
196 delete base_context_;
197 base_context_ = NULL;
202 // static
203 scoped_ptr<gfx::GpuMemoryBuffer> GLManager::CreateGpuMemoryBuffer(
204 const gfx::Size& size,
205 gfx::BufferFormat format) {
206 std::vector<unsigned char> data(BufferSizeInBytes(size, format), 0);
207 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data));
208 return make_scoped_ptr<gfx::GpuMemoryBuffer>(
209 new GpuMemoryBufferImpl(bytes.get(), size, format));
212 void GLManager::Initialize(const GLManager::Options& options) {
213 InitializeWithCommandLine(options, nullptr);
215 void GLManager::InitializeWithCommandLine(const GLManager::Options& options,
216 base::CommandLine* command_line) {
217 const int32 kCommandBufferSize = 1024 * 1024;
218 const size_t kStartTransferBufferSize = 4 * 1024 * 1024;
219 const size_t kMinTransferBufferSize = 1 * 256 * 1024;
220 const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
222 context_lost_allowed_ = options.context_lost_allowed;
224 gles2::MailboxManager* mailbox_manager = NULL;
225 if (options.share_mailbox_manager) {
226 mailbox_manager = options.share_mailbox_manager->mailbox_manager();
227 } else if (options.share_group_manager) {
228 mailbox_manager = options.share_group_manager->mailbox_manager();
231 gfx::GLShareGroup* share_group = NULL;
232 if (options.share_group_manager) {
233 share_group = options.share_group_manager->share_group();
234 } else if (options.share_mailbox_manager) {
235 share_group = options.share_mailbox_manager->share_group();
238 gles2::ContextGroup* context_group = NULL;
239 gles2::ShareGroup* client_share_group = NULL;
240 if (options.share_group_manager) {
241 context_group = options.share_group_manager->decoder_->GetContextGroup();
242 client_share_group =
243 options.share_group_manager->gles2_implementation()->share_group();
246 gfx::GLContext* real_gl_context = NULL;
247 if (options.virtual_manager) {
248 real_gl_context = options.virtual_manager->context();
251 mailbox_manager_ =
252 mailbox_manager ? mailbox_manager : new gles2::MailboxManagerImpl;
253 share_group_ =
254 share_group ? share_group : new gfx::GLShareGroup;
256 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
257 std::vector<int32> attribs;
258 gles2::ContextCreationAttribHelper attrib_helper;
259 attrib_helper.red_size = 8;
260 attrib_helper.green_size = 8;
261 attrib_helper.blue_size = 8;
262 attrib_helper.alpha_size = 8;
263 attrib_helper.depth_size = 16;
264 attrib_helper.stencil_size = 8;
265 attrib_helper.webgl_version = options.webgl_version;
266 attrib_helper.Serialize(&attribs);
268 DCHECK(!command_line || !context_group);
269 if (!context_group) {
270 scoped_refptr<gles2::FeatureInfo> feature_info;
271 if (command_line)
272 feature_info = new gles2::FeatureInfo(*command_line);
273 context_group =
274 new gles2::ContextGroup(mailbox_manager_.get(),
275 NULL,
276 new gpu::gles2::ShaderTranslatorCache,
277 feature_info,
278 NULL,
279 NULL,
280 options.bind_generates_resource);
283 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group));
285 command_buffer_.reset(new CommandBufferService(
286 decoder_->GetContextGroup()->transfer_buffer_manager()));
287 ASSERT_TRUE(command_buffer_->Initialize())
288 << "could not create command buffer service";
290 gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(),
291 decoder_.get(),
292 decoder_.get()));
294 decoder_->set_engine(gpu_scheduler_.get());
296 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
297 ASSERT_TRUE(surface_.get() != NULL) << "could not create offscreen surface";
299 if (base_context_) {
300 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
301 share_group_.get(), base_context_->get(), decoder_->AsWeakPtr()));
302 ASSERT_TRUE(context_->Initialize(
303 surface_.get(), gfx::PreferIntegratedGpu));
304 } else {
305 if (real_gl_context) {
306 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
307 share_group_.get(), real_gl_context, decoder_->AsWeakPtr()));
308 ASSERT_TRUE(context_->Initialize(
309 surface_.get(), gfx::PreferIntegratedGpu));
310 } else {
311 context_ = gfx::GLContext::CreateGLContext(share_group_.get(),
312 surface_.get(),
313 gpu_preference);
316 ASSERT_TRUE(context_.get() != NULL) << "could not create GL context";
318 ASSERT_TRUE(context_->MakeCurrent(surface_.get()));
320 ASSERT_TRUE(decoder_->Initialize(
321 surface_.get(),
322 context_.get(),
323 true,
324 options.size,
325 ::gpu::gles2::DisallowedFeatures(),
326 attribs)) << "could not initialize decoder";
328 command_buffer_->SetPutOffsetChangeCallback(
329 base::Bind(&GLManager::PumpCommands, base::Unretained(this)));
330 command_buffer_->SetGetBufferChangeCallback(
331 base::Bind(&GLManager::GetBufferChanged, base::Unretained(this)));
333 // Create the GLES2 helper, which writes the command buffer protocol.
334 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get()));
335 ASSERT_TRUE(gles2_helper_->Initialize(kCommandBufferSize));
337 // Create a transfer buffer.
338 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
340 // Create the object exposing the OpenGL API.
341 const bool support_client_side_arrays = true;
342 gles2_implementation_.reset(
343 new gles2::GLES2Implementation(gles2_helper_.get(),
344 client_share_group,
345 transfer_buffer_.get(),
346 options.bind_generates_resource,
347 options.lose_context_when_out_of_memory,
348 support_client_side_arrays,
349 this));
351 ASSERT_TRUE(gles2_implementation_->Initialize(
352 kStartTransferBufferSize,
353 kMinTransferBufferSize,
354 kMaxTransferBufferSize,
355 gpu::gles2::GLES2Implementation::kNoLimit))
356 << "Could not init GLES2Implementation";
358 MakeCurrent();
361 void GLManager::SetupBaseContext() {
362 if (use_count_) {
363 #if defined(OS_ANDROID)
364 base_share_group_ = new scoped_refptr<gfx::GLShareGroup>(
365 new gfx::GLShareGroup);
366 gfx::Size size(4, 4);
367 base_surface_ = new scoped_refptr<gfx::GLSurface>(
368 gfx::GLSurface::CreateOffscreenGLSurface(size));
369 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
370 base_context_ = new scoped_refptr<gfx::GLContext>(
371 gfx::GLContext::CreateGLContext(base_share_group_->get(),
372 base_surface_->get(),
373 gpu_preference));
374 #endif
376 ++use_count_;
379 void GLManager::MakeCurrent() {
380 ::gles2::SetGLContext(gles2_implementation_.get());
383 void GLManager::SetSurface(gfx::GLSurface* surface) {
384 decoder_->SetSurface(surface);
387 void GLManager::Destroy() {
388 if (gles2_implementation_.get()) {
389 MakeCurrent();
390 EXPECT_TRUE(glGetError() == GL_NONE);
391 gles2_implementation_->Flush();
392 gles2_implementation_.reset();
394 transfer_buffer_.reset();
395 gles2_helper_.reset();
396 command_buffer_.reset();
397 if (decoder_.get()) {
398 bool have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get());
399 decoder_->Destroy(have_context);
400 decoder_.reset();
404 const gpu::gles2::FeatureInfo::Workarounds& GLManager::workarounds() const {
405 return decoder_->GetContextGroup()->feature_info()->workarounds();
408 void GLManager::PumpCommands() {
409 if (!decoder_->MakeCurrent()) {
410 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
411 command_buffer_->SetParseError(::gpu::error::kLostContext);
412 return;
414 gpu_scheduler_->PutChanged();
415 ::gpu::CommandBuffer::State state = command_buffer_->GetLastState();
416 if (!context_lost_allowed_) {
417 ASSERT_EQ(::gpu::error::kNoError, state.error);
421 bool GLManager::GetBufferChanged(int32 transfer_buffer_id) {
422 return gpu_scheduler_->SetGetBuffer(transfer_buffer_id);
425 Capabilities GLManager::GetCapabilities() {
426 return decoder_->GetCapabilities();
429 int32 GLManager::CreateImage(ClientBuffer buffer,
430 size_t width,
431 size_t height,
432 unsigned internalformat) {
433 GpuMemoryBufferImpl* gpu_memory_buffer =
434 GpuMemoryBufferImpl::FromClientBuffer(buffer);
436 scoped_refptr<gfx::GLImageRefCountedMemory> image(
437 new gfx::GLImageRefCountedMemory(gfx::Size(width, height),
438 internalformat));
439 if (!image->Initialize(gpu_memory_buffer->bytes(),
440 gpu_memory_buffer->GetFormat())) {
441 return -1;
444 static int32 next_id = 1;
445 int32 new_id = next_id++;
447 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
448 DCHECK(image_manager);
449 image_manager->AddImage(image.get(), new_id);
450 return new_id;
453 int32 GLManager::CreateGpuMemoryBufferImage(size_t width,
454 size_t height,
455 unsigned internalformat,
456 unsigned usage) {
457 DCHECK_EQ(usage, static_cast<unsigned>(GL_MAP_CHROMIUM));
458 scoped_ptr<gfx::GpuMemoryBuffer> buffer = GLManager::CreateGpuMemoryBuffer(
459 gfx::Size(width, height), gfx::BufferFormat::RGBA_8888);
460 return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
463 void GLManager::DestroyImage(int32 id) {
464 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
465 DCHECK(image_manager);
466 image_manager->RemoveImage(id);
469 uint32 GLManager::InsertSyncPoint() {
470 NOTIMPLEMENTED();
471 return 0u;
474 uint32 GLManager::InsertFutureSyncPoint() {
475 NOTIMPLEMENTED();
476 return 0u;
479 void GLManager::RetireSyncPoint(uint32 sync_point) {
480 NOTIMPLEMENTED();
483 void GLManager::SignalSyncPoint(uint32 sync_point,
484 const base::Closure& callback) {
485 NOTIMPLEMENTED();
488 void GLManager::SignalQuery(uint32 query, const base::Closure& callback) {
489 NOTIMPLEMENTED();
492 void GLManager::SetSurfaceVisible(bool visible) {
493 NOTIMPLEMENTED();
496 uint32 GLManager::CreateStreamTexture(uint32 texture_id) {
497 NOTIMPLEMENTED();
498 return 0;
501 void GLManager::SetLock(base::Lock*) {
502 NOTIMPLEMENTED();
505 bool GLManager::IsGpuChannelLost() {
506 NOTIMPLEMENTED();
507 return false;
510 } // namespace gpu