Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_manager.cc
blobd527203d3a6d7d036344d9515ada4e7f9af35163
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_implementation.h"
17 #include "gpu/command_buffer/client/gles2_lib.h"
18 #include "gpu/command_buffer/client/transfer_buffer.h"
19 #include "gpu/command_buffer/common/constants.h"
20 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
21 #include "gpu/command_buffer/common/value_state.h"
22 #include "gpu/command_buffer/service/command_buffer_service.h"
23 #include "gpu/command_buffer/service/context_group.h"
24 #include "gpu/command_buffer/service/gl_context_virtual.h"
25 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
26 #include "gpu/command_buffer/service/gpu_scheduler.h"
27 #include "gpu/command_buffer/service/image_manager.h"
28 #include "gpu/command_buffer/service/mailbox_manager_impl.h"
29 #include "gpu/command_buffer/service/memory_tracking.h"
30 #include "gpu/command_buffer/service/valuebuffer_manager.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/gfx/gpu_memory_buffer.h"
33 #include "ui/gl/gl_context.h"
34 #include "ui/gl/gl_image_ref_counted_memory.h"
35 #include "ui/gl/gl_share_group.h"
36 #include "ui/gl/gl_surface.h"
38 namespace gpu {
39 namespace {
41 size_t NumberOfPlanesForGpuMemoryBufferFormat(
42 gfx::GpuMemoryBuffer::Format format) {
43 switch (format) {
44 case gfx::GpuMemoryBuffer::ATC:
45 case gfx::GpuMemoryBuffer::ATCIA:
46 case gfx::GpuMemoryBuffer::DXT1:
47 case gfx::GpuMemoryBuffer::DXT5:
48 case gfx::GpuMemoryBuffer::ETC1:
49 case gfx::GpuMemoryBuffer::R_8:
50 case gfx::GpuMemoryBuffer::RGBA_4444:
51 case gfx::GpuMemoryBuffer::RGBA_8888:
52 case gfx::GpuMemoryBuffer::RGBX_8888:
53 case gfx::GpuMemoryBuffer::BGRA_8888:
54 return 1;
55 case gfx::GpuMemoryBuffer::YUV_420:
56 return 3;
58 NOTREACHED();
59 return 0;
62 size_t SubsamplingFactor(gfx::GpuMemoryBuffer::Format format, int plane) {
63 switch (format) {
64 case gfx::GpuMemoryBuffer::ATC:
65 case gfx::GpuMemoryBuffer::ATCIA:
66 case gfx::GpuMemoryBuffer::DXT1:
67 case gfx::GpuMemoryBuffer::DXT5:
68 case gfx::GpuMemoryBuffer::ETC1:
69 case gfx::GpuMemoryBuffer::R_8:
70 case gfx::GpuMemoryBuffer::RGBA_4444:
71 case gfx::GpuMemoryBuffer::RGBA_8888:
72 case gfx::GpuMemoryBuffer::RGBX_8888:
73 case gfx::GpuMemoryBuffer::BGRA_8888:
74 return 1;
75 case gfx::GpuMemoryBuffer::YUV_420: {
76 static size_t factor[] = {1, 2, 2};
77 DCHECK_LT(static_cast<size_t>(plane), arraysize(factor));
78 return factor[plane];
81 NOTREACHED();
82 return 0;
85 size_t StrideInBytes(size_t width,
86 gfx::GpuMemoryBuffer::Format format,
87 int plane) {
88 switch (format) {
89 case gfx::GpuMemoryBuffer::ATCIA:
90 case gfx::GpuMemoryBuffer::DXT5:
91 DCHECK_EQ(plane, 0);
92 return width;
93 case gfx::GpuMemoryBuffer::ATC:
94 case gfx::GpuMemoryBuffer::DXT1:
95 case gfx::GpuMemoryBuffer::ETC1:
96 DCHECK_EQ(plane, 0);
97 DCHECK_EQ(width % 2, 0U);
98 return width / 2;
99 case gfx::GpuMemoryBuffer::R_8:
100 return (width + 3) & ~0x3;
101 case gfx::GpuMemoryBuffer::RGBA_4444:
102 DCHECK_EQ(plane, 0);
103 return width * 2;
104 case gfx::GpuMemoryBuffer::RGBA_8888:
105 case gfx::GpuMemoryBuffer::BGRA_8888:
106 DCHECK_EQ(plane, 0);
107 return width * 4;
108 case gfx::GpuMemoryBuffer::RGBX_8888:
109 NOTREACHED();
110 return 0;
111 case gfx::GpuMemoryBuffer::YUV_420:
112 return width / SubsamplingFactor(format, plane);
115 NOTREACHED();
116 return 0;
119 size_t BufferSizeInBytes(const gfx::Size& size,
120 gfx::GpuMemoryBuffer::Format format) {
121 size_t size_in_bytes = 0;
122 size_t num_planes = NumberOfPlanesForGpuMemoryBufferFormat(format);
123 for (size_t i = 0; i < num_planes; ++i) {
124 size_in_bytes += StrideInBytes(size.width(), format, i) *
125 (size.height() / SubsamplingFactor(format, i));
127 return size_in_bytes;
130 class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
131 public:
132 GpuMemoryBufferImpl(base::RefCountedBytes* bytes,
133 const gfx::Size& size,
134 gfx::GpuMemoryBuffer::Format format)
135 : bytes_(bytes), size_(size), format_(format), mapped_(false) {}
137 static GpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer) {
138 return reinterpret_cast<GpuMemoryBufferImpl*>(buffer);
141 // Overridden from gfx::GpuMemoryBuffer:
142 bool Map(void** data) override {
143 size_t offset = 0;
144 size_t num_planes = NumberOfPlanesForGpuMemoryBufferFormat(format_);
145 for (size_t i = 0; i < num_planes; ++i) {
146 data[i] = reinterpret_cast<uint8*>(&bytes_->data().front()) + offset;
147 offset += StrideInBytes(size_.width(), format_, i) *
148 (size_.height() / SubsamplingFactor(format_, i));
150 mapped_ = true;
151 return true;
153 void Unmap() override { mapped_ = false; }
154 bool IsMapped() const override { return mapped_; }
155 Format GetFormat() const override { return format_; }
156 void GetStride(int* stride) const override {
157 size_t num_planes = NumberOfPlanesForGpuMemoryBufferFormat(format_);
158 for (size_t i = 0; i < num_planes; ++i)
159 stride[i] = StrideInBytes(size_.width(), format_, i);
161 gfx::GpuMemoryBufferHandle GetHandle() const override {
162 NOTREACHED();
163 return gfx::GpuMemoryBufferHandle();
165 ClientBuffer AsClientBuffer() override {
166 return reinterpret_cast<ClientBuffer>(this);
169 base::RefCountedBytes* bytes() { return bytes_.get(); }
171 private:
172 scoped_refptr<base::RefCountedBytes> bytes_;
173 const gfx::Size size_;
174 gfx::GpuMemoryBuffer::Format format_;
175 bool mapped_;
178 } // namespace
180 int GLManager::use_count_;
181 scoped_refptr<gfx::GLShareGroup>* GLManager::base_share_group_;
182 scoped_refptr<gfx::GLSurface>* GLManager::base_surface_;
183 scoped_refptr<gfx::GLContext>* GLManager::base_context_;
185 GLManager::Options::Options()
186 : size(4, 4),
187 share_group_manager(NULL),
188 share_mailbox_manager(NULL),
189 virtual_manager(NULL),
190 bind_generates_resource(false),
191 lose_context_when_out_of_memory(false),
192 context_lost_allowed(false) {
195 GLManager::GLManager() : context_lost_allowed_(false) {
196 SetupBaseContext();
199 GLManager::~GLManager() {
200 --use_count_;
201 if (!use_count_) {
202 if (base_share_group_) {
203 delete base_context_;
204 base_context_ = NULL;
206 if (base_surface_) {
207 delete base_surface_;
208 base_surface_ = NULL;
210 if (base_context_) {
211 delete base_context_;
212 base_context_ = NULL;
217 // static
218 scoped_ptr<gfx::GpuMemoryBuffer> GLManager::CreateGpuMemoryBuffer(
219 const gfx::Size& size,
220 gfx::GpuMemoryBuffer::Format format) {
221 std::vector<unsigned char> data(BufferSizeInBytes(size, format), 0);
222 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data));
223 return make_scoped_ptr<gfx::GpuMemoryBuffer>(
224 new GpuMemoryBufferImpl(bytes.get(), size, format));
227 void GLManager::Initialize(const GLManager::Options& options) {
228 InitializeWithCommandLine(options, nullptr);
230 void GLManager::InitializeWithCommandLine(const GLManager::Options& options,
231 base::CommandLine* command_line) {
232 const int32 kCommandBufferSize = 1024 * 1024;
233 const size_t kStartTransferBufferSize = 4 * 1024 * 1024;
234 const size_t kMinTransferBufferSize = 1 * 256 * 1024;
235 const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
237 context_lost_allowed_ = options.context_lost_allowed;
239 gles2::MailboxManager* mailbox_manager = NULL;
240 if (options.share_mailbox_manager) {
241 mailbox_manager = options.share_mailbox_manager->mailbox_manager();
242 } else if (options.share_group_manager) {
243 mailbox_manager = options.share_group_manager->mailbox_manager();
246 gfx::GLShareGroup* share_group = NULL;
247 if (options.share_group_manager) {
248 share_group = options.share_group_manager->share_group();
249 } else if (options.share_mailbox_manager) {
250 share_group = options.share_mailbox_manager->share_group();
253 gles2::ContextGroup* context_group = NULL;
254 gles2::ShareGroup* client_share_group = NULL;
255 if (options.share_group_manager) {
256 context_group = options.share_group_manager->decoder_->GetContextGroup();
257 client_share_group =
258 options.share_group_manager->gles2_implementation()->share_group();
261 gfx::GLContext* real_gl_context = NULL;
262 if (options.virtual_manager) {
263 real_gl_context = options.virtual_manager->context();
266 mailbox_manager_ =
267 mailbox_manager ? mailbox_manager : new gles2::MailboxManagerImpl;
268 share_group_ =
269 share_group ? share_group : new gfx::GLShareGroup;
271 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
272 std::vector<int32> attribs;
273 gles2::ContextCreationAttribHelper attrib_helper;
274 attrib_helper.red_size = 8;
275 attrib_helper.green_size = 8;
276 attrib_helper.blue_size = 8;
277 attrib_helper.alpha_size = 8;
278 attrib_helper.depth_size = 16;
279 attrib_helper.stencil_size = 8;
280 attrib_helper.Serialize(&attribs);
282 DCHECK(!command_line || !context_group);
283 if (!context_group) {
284 scoped_refptr<gles2::FeatureInfo> feature_info;
285 if (command_line)
286 feature_info = new gles2::FeatureInfo(*command_line);
287 context_group =
288 new gles2::ContextGroup(mailbox_manager_.get(),
289 NULL,
290 new gpu::gles2::ShaderTranslatorCache,
291 feature_info,
292 NULL,
293 NULL,
294 options.bind_generates_resource);
297 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group));
299 command_buffer_.reset(new CommandBufferService(
300 decoder_->GetContextGroup()->transfer_buffer_manager()));
301 ASSERT_TRUE(command_buffer_->Initialize())
302 << "could not create command buffer service";
304 gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(),
305 decoder_.get(),
306 decoder_.get()));
308 decoder_->set_engine(gpu_scheduler_.get());
310 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
311 ASSERT_TRUE(surface_.get() != NULL) << "could not create offscreen surface";
313 if (base_context_) {
314 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
315 share_group_.get(), base_context_->get(), decoder_->AsWeakPtr()));
316 ASSERT_TRUE(context_->Initialize(
317 surface_.get(), gfx::PreferIntegratedGpu));
318 } else {
319 if (real_gl_context) {
320 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
321 share_group_.get(), real_gl_context, decoder_->AsWeakPtr()));
322 ASSERT_TRUE(context_->Initialize(
323 surface_.get(), gfx::PreferIntegratedGpu));
324 } else {
325 context_ = gfx::GLContext::CreateGLContext(share_group_.get(),
326 surface_.get(),
327 gpu_preference);
330 ASSERT_TRUE(context_.get() != NULL) << "could not create GL context";
332 ASSERT_TRUE(context_->MakeCurrent(surface_.get()));
334 ASSERT_TRUE(decoder_->Initialize(
335 surface_.get(),
336 context_.get(),
337 true,
338 options.size,
339 ::gpu::gles2::DisallowedFeatures(),
340 attribs)) << "could not initialize decoder";
342 command_buffer_->SetPutOffsetChangeCallback(
343 base::Bind(&GLManager::PumpCommands, base::Unretained(this)));
344 command_buffer_->SetGetBufferChangeCallback(
345 base::Bind(&GLManager::GetBufferChanged, base::Unretained(this)));
347 // Create the GLES2 helper, which writes the command buffer protocol.
348 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get()));
349 ASSERT_TRUE(gles2_helper_->Initialize(kCommandBufferSize));
351 // Create a transfer buffer.
352 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
354 // Create the object exposing the OpenGL API.
355 const bool support_client_side_arrays = true;
356 gles2_implementation_.reset(
357 new gles2::GLES2Implementation(gles2_helper_.get(),
358 client_share_group,
359 transfer_buffer_.get(),
360 options.bind_generates_resource,
361 options.lose_context_when_out_of_memory,
362 support_client_side_arrays,
363 this));
365 ASSERT_TRUE(gles2_implementation_->Initialize(
366 kStartTransferBufferSize,
367 kMinTransferBufferSize,
368 kMaxTransferBufferSize,
369 gpu::gles2::GLES2Implementation::kNoLimit))
370 << "Could not init GLES2Implementation";
372 MakeCurrent();
375 void GLManager::SetupBaseContext() {
376 if (use_count_) {
377 #if defined(OS_ANDROID)
378 base_share_group_ = new scoped_refptr<gfx::GLShareGroup>(
379 new gfx::GLShareGroup);
380 gfx::Size size(4, 4);
381 base_surface_ = new scoped_refptr<gfx::GLSurface>(
382 gfx::GLSurface::CreateOffscreenGLSurface(size));
383 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
384 base_context_ = new scoped_refptr<gfx::GLContext>(
385 gfx::GLContext::CreateGLContext(base_share_group_->get(),
386 base_surface_->get(),
387 gpu_preference));
388 #endif
390 ++use_count_;
393 void GLManager::MakeCurrent() {
394 ::gles2::SetGLContext(gles2_implementation_.get());
397 void GLManager::SetSurface(gfx::GLSurface* surface) {
398 decoder_->SetSurface(surface);
401 void GLManager::Destroy() {
402 if (gles2_implementation_.get()) {
403 MakeCurrent();
404 EXPECT_TRUE(glGetError() == GL_NONE);
405 gles2_implementation_->Flush();
406 gles2_implementation_.reset();
408 transfer_buffer_.reset();
409 gles2_helper_.reset();
410 command_buffer_.reset();
411 if (decoder_.get()) {
412 bool have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get());
413 decoder_->Destroy(have_context);
414 decoder_.reset();
418 const gpu::gles2::FeatureInfo::Workarounds& GLManager::workarounds() const {
419 return decoder_->GetContextGroup()->feature_info()->workarounds();
422 void GLManager::PumpCommands() {
423 if (!decoder_->MakeCurrent()) {
424 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
425 command_buffer_->SetParseError(::gpu::error::kLostContext);
426 return;
428 gpu_scheduler_->PutChanged();
429 ::gpu::CommandBuffer::State state = command_buffer_->GetLastState();
430 if (!context_lost_allowed_) {
431 ASSERT_EQ(::gpu::error::kNoError, state.error);
435 bool GLManager::GetBufferChanged(int32 transfer_buffer_id) {
436 return gpu_scheduler_->SetGetBuffer(transfer_buffer_id);
439 Capabilities GLManager::GetCapabilities() {
440 return decoder_->GetCapabilities();
443 int32 GLManager::CreateImage(ClientBuffer buffer,
444 size_t width,
445 size_t height,
446 unsigned internalformat) {
447 GpuMemoryBufferImpl* gpu_memory_buffer =
448 GpuMemoryBufferImpl::FromClientBuffer(buffer);
450 scoped_refptr<gfx::GLImageRefCountedMemory> image(
451 new gfx::GLImageRefCountedMemory(gfx::Size(width, height),
452 internalformat));
453 if (!image->Initialize(gpu_memory_buffer->bytes(),
454 gpu_memory_buffer->GetFormat())) {
455 return -1;
458 static int32 next_id = 1;
459 int32 new_id = next_id++;
461 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
462 DCHECK(image_manager);
463 image_manager->AddImage(image.get(), new_id);
464 return new_id;
467 int32 GLManager::CreateGpuMemoryBufferImage(size_t width,
468 size_t height,
469 unsigned internalformat,
470 unsigned usage) {
471 DCHECK_EQ(usage, static_cast<unsigned>(GL_MAP_CHROMIUM));
472 scoped_ptr<gfx::GpuMemoryBuffer> buffer = GLManager::CreateGpuMemoryBuffer(
473 gfx::Size(width, height), gfx::GpuMemoryBuffer::RGBA_8888);
474 return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
477 void GLManager::DestroyImage(int32 id) {
478 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
479 DCHECK(image_manager);
480 image_manager->RemoveImage(id);
483 uint32 GLManager::InsertSyncPoint() {
484 NOTIMPLEMENTED();
485 return 0u;
488 uint32 GLManager::InsertFutureSyncPoint() {
489 NOTIMPLEMENTED();
490 return 0u;
493 void GLManager::RetireSyncPoint(uint32 sync_point) {
494 NOTIMPLEMENTED();
497 void GLManager::SignalSyncPoint(uint32 sync_point,
498 const base::Closure& callback) {
499 NOTIMPLEMENTED();
502 void GLManager::SignalQuery(uint32 query, const base::Closure& callback) {
503 NOTIMPLEMENTED();
506 void GLManager::SetSurfaceVisible(bool visible) {
507 NOTIMPLEMENTED();
510 uint32 GLManager::CreateStreamTexture(uint32 texture_id) {
511 NOTIMPLEMENTED();
512 return 0;
515 void GLManager::SetLock(base::Lock*) {
516 NOTIMPLEMENTED();
519 } // namespace gpu