Tweak the android menu button alignment to spec.
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_manager.cc
blob6b43e5b2e168a24ca0acba5b615d5a6e660f7cda
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>
10 #include <vector>
12 #include "base/at_exit.h"
13 #include "base/bind.h"
14 #include "base/memory/ref_counted_memory.h"
15 #include "gpu/command_buffer/client/gles2_implementation.h"
16 #include "gpu/command_buffer/client/gles2_lib.h"
17 #include "gpu/command_buffer/client/transfer_buffer.h"
18 #include "gpu/command_buffer/common/constants.h"
19 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
20 #include "gpu/command_buffer/service/command_buffer_service.h"
21 #include "gpu/command_buffer/service/context_group.h"
22 #include "gpu/command_buffer/service/gl_context_virtual.h"
23 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
24 #include "gpu/command_buffer/service/gpu_scheduler.h"
25 #include "gpu/command_buffer/service/image_manager.h"
26 #include "gpu/command_buffer/service/mailbox_manager.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/gfx/gpu_memory_buffer.h"
29 #include "ui/gl/gl_context.h"
30 #include "ui/gl/gl_image_ref_counted_memory.h"
31 #include "ui/gl/gl_share_group.h"
32 #include "ui/gl/gl_surface.h"
34 namespace gpu {
35 namespace {
37 int BytesPerPixel(unsigned internalformat) {
38 switch (internalformat) {
39 case GL_RGBA8_OES:
40 return 4;
41 default:
42 NOTREACHED();
43 return 0;
47 class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
48 public:
49 GpuMemoryBufferImpl(base::RefCountedBytes* bytes,
50 const gfx::Size& size,
51 unsigned internalformat)
52 : bytes_(bytes),
53 size_(size),
54 internalformat_(internalformat),
55 mapped_(false) {}
57 // Overridden from gfx::GpuMemoryBuffer:
58 virtual void* Map() OVERRIDE {
59 mapped_ = true;
60 return &bytes_->data().front();
62 virtual void Unmap() OVERRIDE { mapped_ = false; }
63 virtual bool IsMapped() const OVERRIDE { return mapped_; }
64 virtual uint32 GetStride() const OVERRIDE {
65 return size_.width() * BytesPerPixel(internalformat_);
67 virtual gfx::GpuMemoryBufferHandle GetHandle() const OVERRIDE {
68 NOTREACHED();
69 return gfx::GpuMemoryBufferHandle();
72 private:
73 scoped_refptr<base::RefCountedBytes> bytes_;
74 const gfx::Size size_;
75 unsigned internalformat_;
76 bool mapped_;
79 } // namespace
81 int GLManager::use_count_;
82 scoped_refptr<gfx::GLShareGroup>* GLManager::base_share_group_;
83 scoped_refptr<gfx::GLSurface>* GLManager::base_surface_;
84 scoped_refptr<gfx::GLContext>* GLManager::base_context_;
86 GLManager::Options::Options()
87 : size(4, 4),
88 share_group_manager(NULL),
89 share_mailbox_manager(NULL),
90 virtual_manager(NULL),
91 bind_generates_resource(false),
92 lose_context_when_out_of_memory(false),
93 context_lost_allowed(false) {
96 GLManager::GLManager() : context_lost_allowed_(false) {
97 SetupBaseContext();
100 GLManager::~GLManager() {
101 --use_count_;
102 if (!use_count_) {
103 if (base_share_group_) {
104 delete base_context_;
105 base_context_ = NULL;
107 if (base_surface_) {
108 delete base_surface_;
109 base_surface_ = NULL;
111 if (base_context_) {
112 delete base_context_;
113 base_context_ = NULL;
118 void GLManager::Initialize(const GLManager::Options& options) {
119 const int32 kCommandBufferSize = 1024 * 1024;
120 const size_t kStartTransferBufferSize = 4 * 1024 * 1024;
121 const size_t kMinTransferBufferSize = 1 * 256 * 1024;
122 const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
124 context_lost_allowed_ = options.context_lost_allowed;
126 gles2::MailboxManager* mailbox_manager = NULL;
127 if (options.share_mailbox_manager) {
128 mailbox_manager = options.share_mailbox_manager->mailbox_manager();
129 } else if (options.share_group_manager) {
130 mailbox_manager = options.share_group_manager->mailbox_manager();
133 gfx::GLShareGroup* share_group = NULL;
134 if (options.share_group_manager) {
135 share_group = options.share_group_manager->share_group();
136 } else if (options.share_mailbox_manager) {
137 share_group = options.share_mailbox_manager->share_group();
140 gles2::ContextGroup* context_group = NULL;
141 gles2::ShareGroup* client_share_group = NULL;
142 if (options.share_group_manager) {
143 context_group = options.share_group_manager->decoder_->GetContextGroup();
144 client_share_group =
145 options.share_group_manager->gles2_implementation()->share_group();
148 gfx::GLContext* real_gl_context = NULL;
149 if (options.virtual_manager) {
150 real_gl_context = options.virtual_manager->context();
153 mailbox_manager_ =
154 mailbox_manager ? mailbox_manager : new gles2::MailboxManager;
155 share_group_ =
156 share_group ? share_group : new gfx::GLShareGroup;
158 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
159 std::vector<int32> attribs;
160 gles2::ContextCreationAttribHelper attrib_helper;
161 attrib_helper.red_size_ = 8;
162 attrib_helper.green_size_ = 8;
163 attrib_helper.blue_size_ = 8;
164 attrib_helper.alpha_size_ = 8;
165 attrib_helper.depth_size_ = 16;
166 attrib_helper.Serialize(&attribs);
168 if (!context_group) {
169 context_group =
170 new gles2::ContextGroup(mailbox_manager_.get(),
171 NULL,
172 new gpu::gles2::ShaderTranslatorCache,
173 NULL,
174 options.bind_generates_resource);
177 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group));
179 command_buffer_.reset(new CommandBufferService(
180 decoder_->GetContextGroup()->transfer_buffer_manager()));
181 ASSERT_TRUE(command_buffer_->Initialize())
182 << "could not create command buffer service";
184 gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(),
185 decoder_.get(),
186 decoder_.get()));
188 decoder_->set_engine(gpu_scheduler_.get());
190 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(options.size);
191 ASSERT_TRUE(surface_.get() != NULL) << "could not create offscreen surface";
193 if (base_context_) {
194 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
195 share_group_.get(), base_context_->get(), decoder_->AsWeakPtr()));
196 ASSERT_TRUE(context_->Initialize(
197 surface_.get(), gfx::PreferIntegratedGpu));
198 } else {
199 if (real_gl_context) {
200 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
201 share_group_.get(), real_gl_context, decoder_->AsWeakPtr()));
202 ASSERT_TRUE(context_->Initialize(
203 surface_.get(), gfx::PreferIntegratedGpu));
204 } else {
205 context_ = gfx::GLContext::CreateGLContext(share_group_.get(),
206 surface_.get(),
207 gpu_preference);
210 ASSERT_TRUE(context_.get() != NULL) << "could not create GL context";
212 ASSERT_TRUE(context_->MakeCurrent(surface_.get()));
214 ASSERT_TRUE(decoder_->Initialize(
215 surface_.get(),
216 context_.get(),
217 true,
218 options.size,
219 ::gpu::gles2::DisallowedFeatures(),
220 attribs)) << "could not initialize decoder";
222 command_buffer_->SetPutOffsetChangeCallback(
223 base::Bind(&GLManager::PumpCommands, base::Unretained(this)));
224 command_buffer_->SetGetBufferChangeCallback(
225 base::Bind(&GLManager::GetBufferChanged, base::Unretained(this)));
227 // Create the GLES2 helper, which writes the command buffer protocol.
228 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get()));
229 ASSERT_TRUE(gles2_helper_->Initialize(kCommandBufferSize));
231 // Create a transfer buffer.
232 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
234 // Create the object exposing the OpenGL API.
235 gles2_implementation_.reset(
236 new gles2::GLES2Implementation(gles2_helper_.get(),
237 client_share_group,
238 transfer_buffer_.get(),
239 options.bind_generates_resource,
240 options.lose_context_when_out_of_memory,
241 this));
243 ASSERT_TRUE(gles2_implementation_->Initialize(
244 kStartTransferBufferSize,
245 kMinTransferBufferSize,
246 kMaxTransferBufferSize,
247 gpu::gles2::GLES2Implementation::kNoLimit))
248 << "Could not init GLES2Implementation";
250 MakeCurrent();
253 void GLManager::SetupBaseContext() {
254 if (use_count_) {
255 #if defined(OS_ANDROID)
256 base_share_group_ = new scoped_refptr<gfx::GLShareGroup>(
257 new gfx::GLShareGroup);
258 gfx::Size size(4, 4);
259 base_surface_ = new scoped_refptr<gfx::GLSurface>(
260 gfx::GLSurface::CreateOffscreenGLSurface(size));
261 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
262 base_context_ = new scoped_refptr<gfx::GLContext>(
263 gfx::GLContext::CreateGLContext(base_share_group_->get(),
264 base_surface_->get(),
265 gpu_preference));
266 #endif
268 ++use_count_;
271 void GLManager::MakeCurrent() {
272 ::gles2::SetGLContext(gles2_implementation_.get());
275 void GLManager::SetSurface(gfx::GLSurface* surface) {
276 decoder_->SetSurface(surface);
279 void GLManager::Destroy() {
280 if (gles2_implementation_.get()) {
281 MakeCurrent();
282 EXPECT_TRUE(glGetError() == GL_NONE);
283 gles2_implementation_->Flush();
284 gles2_implementation_.reset();
286 transfer_buffer_.reset();
287 gles2_helper_.reset();
288 command_buffer_.reset();
289 if (decoder_.get()) {
290 decoder_->MakeCurrent();
291 decoder_->Destroy(true);
292 decoder_.reset();
296 const gpu::gles2::FeatureInfo::Workarounds& GLManager::workarounds() const {
297 return decoder_->GetContextGroup()->feature_info()->workarounds();
300 void GLManager::PumpCommands() {
301 decoder_->MakeCurrent();
302 gpu_scheduler_->PutChanged();
303 ::gpu::CommandBuffer::State state = command_buffer_->GetLastState();
304 if (!context_lost_allowed_) {
305 ASSERT_EQ(::gpu::error::kNoError, state.error);
309 bool GLManager::GetBufferChanged(int32 transfer_buffer_id) {
310 return gpu_scheduler_->SetGetBuffer(transfer_buffer_id);
313 Capabilities GLManager::GetCapabilities() {
314 return decoder_->GetCapabilities();
317 gfx::GpuMemoryBuffer* GLManager::CreateGpuMemoryBuffer(
318 size_t width,
319 size_t height,
320 unsigned internalformat,
321 unsigned usage,
322 int32* id) {
323 gfx::Size size(width, height);
325 *id = -1;
327 std::vector<unsigned char> data(
328 size.GetArea() * BytesPerPixel(internalformat), 0);
329 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data));
330 scoped_ptr<gfx::GpuMemoryBuffer> buffer(
331 new GpuMemoryBufferImpl(bytes.get(), size, internalformat));
333 static int32 next_id = 1;
334 int32 new_id = next_id++;
336 scoped_refptr<gfx::GLImageRefCountedMemory> image(
337 new gfx::GLImageRefCountedMemory(size, internalformat));
338 if (!image->Initialize(bytes.get()))
339 return NULL;
341 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
342 DCHECK(image_manager);
343 image_manager->AddImage(image.get(), new_id);
345 *id = new_id;
346 DCHECK(gpu_memory_buffers_.find(new_id) == gpu_memory_buffers_.end());
347 return gpu_memory_buffers_.add(new_id, buffer.Pass()).first->second;
350 void GLManager::DestroyGpuMemoryBuffer(int32 id) {
351 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
352 DCHECK(image_manager);
353 image_manager->RemoveImage(id);
355 gpu_memory_buffers_.erase(id);
358 uint32 GLManager::InsertSyncPoint() {
359 NOTIMPLEMENTED();
360 return 0u;
363 uint32 GLManager::InsertFutureSyncPoint() {
364 NOTIMPLEMENTED();
365 return 0u;
368 void GLManager::RetireSyncPoint(uint32 sync_point) {
369 NOTIMPLEMENTED();
372 void GLManager::SignalSyncPoint(uint32 sync_point,
373 const base::Closure& callback) {
374 NOTIMPLEMENTED();
377 void GLManager::SignalQuery(uint32 query, const base::Closure& callback) {
378 NOTIMPLEMENTED();
381 void GLManager::SetSurfaceVisible(bool visible) {
382 NOTIMPLEMENTED();
385 void GLManager::Echo(const base::Closure& callback) {
386 NOTIMPLEMENTED();
389 uint32 GLManager::CreateStreamTexture(uint32 texture_id) {
390 NOTIMPLEMENTED();
391 return 0;
394 } // namespace gpu