Windows should animate when they are about to get docked at screen edges.
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_manager.cc
blobc4b84a2c9df0a763ac853afab08ecbf63c2824d2
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/transfer_buffer.h"
14 #include "gpu/command_buffer/common/constants.h"
15 #include "gpu/command_buffer/service/command_buffer_service.h"
16 #include "gpu/command_buffer/service/context_group.h"
17 #include "gpu/command_buffer/service/gl_context_virtual.h"
18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
19 #include "gpu/command_buffer/service/gpu_scheduler.h"
20 #include "gpu/command_buffer/service/image_manager.h"
21 #include "gpu/command_buffer/service/mailbox_manager.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/gl/gl_context.h"
24 #include "ui/gl/gl_share_group.h"
25 #include "ui/gl/gl_surface.h"
27 namespace gpu {
29 int GLManager::use_count_;
30 scoped_refptr<gfx::GLShareGroup>* GLManager::base_share_group_;
31 scoped_refptr<gfx::GLSurface>* GLManager::base_surface_;
32 scoped_refptr<gfx::GLContext>* GLManager::base_context_;
34 GLManager::Options::Options()
35 : size(4, 4),
36 share_group_manager(NULL),
37 share_mailbox_manager(NULL),
38 virtual_manager(NULL),
39 bind_generates_resource(false),
40 context_lost_allowed(false),
41 image_manager(NULL),
42 image_factory(NULL) {
45 GLManager::GLManager()
46 : context_lost_allowed_(false) {
47 SetupBaseContext();
50 GLManager::~GLManager() {
51 --use_count_;
52 if (!use_count_) {
53 if (base_share_group_) {
54 delete base_context_;
55 base_context_ = NULL;
57 if (base_surface_) {
58 delete base_surface_;
59 base_surface_ = NULL;
61 if (base_context_) {
62 delete base_context_;
63 base_context_ = NULL;
68 void GLManager::Initialize(const GLManager::Options& options) {
69 const int32 kCommandBufferSize = 1024 * 1024;
70 const size_t kStartTransferBufferSize = 4 * 1024 * 1024;
71 const size_t kMinTransferBufferSize = 1 * 256 * 1024;
72 const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
74 context_lost_allowed_ = options.context_lost_allowed;
76 gles2::MailboxManager* mailbox_manager = NULL;
77 if (options.share_mailbox_manager) {
78 mailbox_manager = options.share_mailbox_manager->mailbox_manager();
79 } else if (options.share_group_manager) {
80 mailbox_manager = options.share_group_manager->mailbox_manager();
83 gfx::GLShareGroup* share_group = NULL;
84 if (options.share_group_manager) {
85 share_group = options.share_group_manager->share_group();
86 } else if (options.share_mailbox_manager) {
87 share_group = options.share_mailbox_manager->share_group();
90 gles2::ContextGroup* context_group = NULL;
91 gles2::ShareGroup* client_share_group = NULL;
92 if (options.share_group_manager) {
93 context_group = options.share_group_manager->decoder_->GetContextGroup();
94 client_share_group =
95 options.share_group_manager->gles2_implementation()->share_group();
98 gfx::GLContext* real_gl_context = NULL;
99 if (options.virtual_manager) {
100 real_gl_context = options.virtual_manager->context();
103 // From <EGL/egl.h>.
104 const int32 EGL_ALPHA_SIZE = 0x3021;
105 const int32 EGL_BLUE_SIZE = 0x3022;
106 const int32 EGL_GREEN_SIZE = 0x3023;
107 const int32 EGL_RED_SIZE = 0x3024;
108 const int32 EGL_DEPTH_SIZE = 0x3025;
109 const int32 EGL_NONE = 0x3038;
111 mailbox_manager_ =
112 mailbox_manager ? mailbox_manager : new gles2::MailboxManager;
113 share_group_ =
114 share_group ? share_group : new gfx::GLShareGroup;
116 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
117 const char* allowed_extensions = "*";
118 std::vector<int32> attribs;
119 attribs.push_back(EGL_RED_SIZE);
120 attribs.push_back(8);
121 attribs.push_back(EGL_GREEN_SIZE);
122 attribs.push_back(8);
123 attribs.push_back(EGL_BLUE_SIZE);
124 attribs.push_back(8);
125 attribs.push_back(EGL_ALPHA_SIZE);
126 attribs.push_back(8);
127 attribs.push_back(EGL_DEPTH_SIZE);
128 attribs.push_back(16);
129 attribs.push_back(EGL_NONE);
131 if (!context_group) {
132 context_group = new gles2::ContextGroup(mailbox_manager_.get(),
133 options.image_manager,
134 NULL,
135 NULL,
136 options.bind_generates_resource);
139 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group));
141 command_buffer_.reset(new CommandBufferService(
142 decoder_->GetContextGroup()->transfer_buffer_manager()));
143 ASSERT_TRUE(command_buffer_->Initialize())
144 << "could not create command buffer service";
146 gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(),
147 decoder_.get(),
148 decoder_.get()));
150 decoder_->set_engine(gpu_scheduler_.get());
152 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(options.size);
153 ASSERT_TRUE(surface_.get() != NULL) << "could not create offscreen surface";
155 if (real_gl_context) {
156 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
157 share_group_.get(), real_gl_context, decoder_->AsWeakPtr()));
158 ASSERT_TRUE(context_->Initialize(
159 surface_.get(), gfx::PreferIntegratedGpu));
160 } else {
161 if (base_context_) {
162 context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
163 share_group_.get(), base_context_->get(), decoder_->AsWeakPtr()));
164 ASSERT_TRUE(context_->Initialize(
165 surface_.get(), gfx::PreferIntegratedGpu));
166 } else {
167 context_ = gfx::GLContext::CreateGLContext(share_group_.get(),
168 surface_.get(),
169 gpu_preference);
172 ASSERT_TRUE(context_.get() != NULL) << "could not create GL context";
174 ASSERT_TRUE(context_->MakeCurrent(surface_.get()));
176 ASSERT_TRUE(decoder_->Initialize(
177 surface_.get(),
178 context_.get(),
179 true,
180 options.size,
181 ::gpu::gles2::DisallowedFeatures(),
182 allowed_extensions,
183 attribs)) << "could not initialize decoder";
185 command_buffer_->SetPutOffsetChangeCallback(
186 base::Bind(&GLManager::PumpCommands, base::Unretained(this)));
187 command_buffer_->SetGetBufferChangeCallback(
188 base::Bind(&GLManager::GetBufferChanged, base::Unretained(this)));
190 // Create the GLES2 helper, which writes the command buffer protocol.
191 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get()));
192 ASSERT_TRUE(gles2_helper_->Initialize(kCommandBufferSize));
194 // Create a transfer buffer.
195 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
197 // Create the object exposing the OpenGL API.
198 gles2_implementation_.reset(new gles2::GLES2Implementation(
199 gles2_helper_.get(),
200 client_share_group,
201 transfer_buffer_.get(),
202 options.bind_generates_resource,
203 options.image_factory));
205 ASSERT_TRUE(gles2_implementation_->Initialize(
206 kStartTransferBufferSize,
207 kMinTransferBufferSize,
208 kMaxTransferBufferSize)) << "Could not init GLES2Implementation";
210 MakeCurrent();
213 void GLManager::SetupBaseContext() {
214 if (use_count_) {
215 #if defined(OS_ANDROID)
216 base_share_group_ = new scoped_refptr<gfx::GLShareGroup>(
217 new gfx::GLShareGroup);
218 gfx::Size size(4, 4);
219 base_surface_ = new scoped_refptr<gfx::GLSurface>(
220 gfx::GLSurface::CreateOffscreenGLSurface(size));
221 gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
222 base_context_ = new scoped_refptr<gfx::GLContext>(
223 gfx::GLContext::CreateGLContext(base_share_group_->get(),
224 base_surface_->get(),
225 gpu_preference));
226 #endif
228 ++use_count_;
231 void GLManager::MakeCurrent() {
232 ::gles2::SetGLContext(gles2_implementation_.get());
235 void GLManager::SetSurface(gfx::GLSurface* surface) {
236 decoder_->SetSurface(surface);
239 void GLManager::Destroy() {
240 if (gles2_implementation_.get()) {
241 MakeCurrent();
242 EXPECT_TRUE(glGetError() == GL_NONE);
243 gles2_implementation_->Flush();
244 gles2_implementation_.reset();
246 transfer_buffer_.reset();
247 gles2_helper_.reset();
248 command_buffer_.reset();
249 if (decoder_.get()) {
250 decoder_->MakeCurrent();
251 decoder_->Destroy(true);
252 decoder_.reset();
256 const gpu::gles2::FeatureInfo::Workarounds& GLManager::workarounds() const {
257 return decoder_->GetContextGroup()->feature_info()->workarounds();
260 void GLManager::PumpCommands() {
261 decoder_->MakeCurrent();
262 gpu_scheduler_->PutChanged();
263 ::gpu::CommandBuffer::State state = command_buffer_->GetState();
264 if (!context_lost_allowed_) {
265 ASSERT_EQ(::gpu::error::kNoError, state.error);
269 bool GLManager::GetBufferChanged(int32 transfer_buffer_id) {
270 return gpu_scheduler_->SetGetBuffer(transfer_buffer_id);
273 } // namespace gpu