Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / gpu / gles2_conform_support / egl / display.cc
blobdce6599acf0d7d552076cc3cc8c281d9ebb4efcb
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/gles2_conform_support/egl/display.h"
7 #include <vector>
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "gpu/command_buffer/client/gles2_implementation.h"
11 #include "gpu/command_buffer/client/gles2_lib.h"
12 #include "gpu/command_buffer/client/transfer_buffer.h"
13 #include "gpu/command_buffer/common/value_state.h"
14 #include "gpu/command_buffer/service/context_group.h"
15 #include "gpu/command_buffer/service/mailbox_manager.h"
16 #include "gpu/command_buffer/service/memory_tracking.h"
17 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
18 #include "gpu/command_buffer/service/valuebuffer_manager.h"
19 #include "gpu/gles2_conform_support/egl/config.h"
20 #include "gpu/gles2_conform_support/egl/surface.h"
22 namespace {
23 const int32 kCommandBufferSize = 1024 * 1024;
24 const int32 kTransferBufferSize = 512 * 1024;
27 namespace egl {
29 Display::Display(EGLNativeDisplayType display_id)
30 : display_id_(display_id),
31 is_initialized_(false),
32 create_offscreen_(false),
33 create_offscreen_width_(0),
34 create_offscreen_height_(0) {
37 Display::~Display() {
38 gles2::Terminate();
41 bool Display::Initialize() {
42 gles2::Initialize();
43 is_initialized_ = true;
44 return true;
47 bool Display::IsValidConfig(EGLConfig config) {
48 return (config != NULL) && (config == config_.get());
51 bool Display::ChooseConfigs(EGLConfig* configs,
52 EGLint config_size,
53 EGLint* num_config) {
54 // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
55 // does not support finding or choosing configs.
56 *num_config = 1;
57 if (configs != NULL) {
58 if (config_ == NULL) {
59 config_.reset(new Config);
61 configs[0] = config_.get();
63 return true;
66 bool Display::GetConfigs(EGLConfig* configs,
67 EGLint config_size,
68 EGLint* num_config) {
69 // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
70 // does not support finding or choosing configs.
71 *num_config = 1;
72 if (configs != NULL) {
73 if (config_ == NULL) {
74 config_.reset(new Config);
76 configs[0] = config_.get();
78 return true;
81 bool Display::GetConfigAttrib(EGLConfig config,
82 EGLint attribute,
83 EGLint* value) {
84 const egl::Config* cfg = static_cast<egl::Config*>(config);
85 return cfg->GetAttrib(attribute, value);
88 bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
89 #if defined OS_WIN
90 return ::IsWindow(win) != FALSE;
91 #else
92 // TODO(alokp): Validate window handle.
93 return true;
94 #endif // OS_WIN
97 bool Display::IsValidSurface(EGLSurface surface) {
98 return (surface != NULL) && (surface == surface_.get());
101 EGLSurface Display::CreateWindowSurface(EGLConfig config,
102 EGLNativeWindowType win,
103 const EGLint* attrib_list) {
104 if (surface_ != NULL) {
105 // We do not support more than one window surface.
106 return EGL_NO_SURFACE;
110 gpu::TransferBufferManager* manager = new gpu::TransferBufferManager();
111 transfer_buffer_manager_ = manager;
112 manager->Initialize();
114 scoped_ptr<gpu::CommandBufferService> command_buffer(
115 new gpu::CommandBufferService(transfer_buffer_manager_.get()));
116 if (!command_buffer->Initialize())
117 return NULL;
119 scoped_refptr<gpu::gles2::ContextGroup> group(
120 new gpu::gles2::ContextGroup(NULL,
121 NULL,
122 new gpu::gles2::ShaderTranslatorCache,
123 NULL,
124 NULL,
125 NULL,
126 true));
128 decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
129 if (!decoder_.get())
130 return EGL_NO_SURFACE;
132 gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer.get(),
133 decoder_.get(),
134 NULL));
136 decoder_->set_engine(gpu_scheduler_.get());
137 gfx::Size size(create_offscreen_width_, create_offscreen_height_);
138 if (create_offscreen_) {
139 gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
140 create_offscreen_ = false;
141 create_offscreen_width_ = 0;
142 create_offscreen_height_ = 0;
143 } else {
144 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win);
146 if (!gl_surface_.get())
147 return EGL_NO_SURFACE;
149 gl_context_ = gfx::GLContext::CreateGLContext(NULL,
150 gl_surface_.get(),
151 gfx::PreferDiscreteGpu);
152 if (!gl_context_.get())
153 return EGL_NO_SURFACE;
155 gl_context_->MakeCurrent(gl_surface_.get());
157 EGLint depth_size = 0;
158 EGLint alpha_size = 0;
159 EGLint stencil_size = 0;
160 GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size);
161 GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size);
162 GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size);
163 std::vector<int32> attribs;
164 attribs.push_back(EGL_DEPTH_SIZE);
165 attribs.push_back(depth_size);
166 attribs.push_back(EGL_ALPHA_SIZE);
167 attribs.push_back(alpha_size);
168 attribs.push_back(EGL_STENCIL_SIZE);
169 attribs.push_back(stencil_size);
170 // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null
171 attribs.push_back(EGL_NONE);
173 if (!decoder_->Initialize(gl_surface_.get(),
174 gl_context_.get(),
175 gl_surface_->IsOffscreen(),
176 size,
177 gpu::gles2::DisallowedFeatures(),
178 attribs)) {
179 return EGL_NO_SURFACE;
182 command_buffer->SetPutOffsetChangeCallback(
183 base::Bind(&gpu::GpuScheduler::PutChanged,
184 base::Unretained(gpu_scheduler_.get())));
185 command_buffer->SetGetBufferChangeCallback(
186 base::Bind(&gpu::GpuScheduler::SetGetBuffer,
187 base::Unretained(gpu_scheduler_.get())));
189 scoped_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper(
190 new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
191 if (!cmd_helper->Initialize(kCommandBufferSize))
192 return NULL;
194 scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer(
195 cmd_helper.get()));
197 command_buffer_.reset(command_buffer.release());
198 transfer_buffer_.reset(transfer_buffer.release());
199 gles2_cmd_helper_.reset(cmd_helper.release());
200 surface_.reset(new Surface(win));
202 return surface_.get();
205 void Display::DestroySurface(EGLSurface surface) {
206 DCHECK(IsValidSurface(surface));
207 gpu_scheduler_.reset();
208 if (decoder_.get()) {
209 decoder_->Destroy(true);
211 decoder_.reset();
212 gl_surface_ = NULL;
213 gl_context_ = NULL;
214 surface_.reset();
217 void Display::SwapBuffers(EGLSurface surface) {
218 DCHECK(IsValidSurface(surface));
219 context_->SwapBuffers();
222 bool Display::IsValidContext(EGLContext ctx) {
223 return (ctx != NULL) && (ctx == context_.get());
226 EGLContext Display::CreateContext(EGLConfig config,
227 EGLContext share_ctx,
228 const EGLint* attrib_list) {
229 DCHECK(IsValidConfig(config));
230 // TODO(alokp): Add support for shared contexts.
231 if (share_ctx != NULL)
232 return EGL_NO_CONTEXT;
234 DCHECK(command_buffer_ != NULL);
235 DCHECK(transfer_buffer_.get());
237 bool bind_generates_resources = true;
238 bool lose_context_when_out_of_memory = false;
239 bool support_client_side_arrays = true;
241 context_.reset(
242 new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(),
243 NULL,
244 transfer_buffer_.get(),
245 bind_generates_resources,
246 lose_context_when_out_of_memory,
247 support_client_side_arrays,
248 this));
250 if (!context_->Initialize(
251 kTransferBufferSize,
252 kTransferBufferSize / 2,
253 kTransferBufferSize * 2,
254 gpu::gles2::GLES2Implementation::kNoLimit)) {
255 return EGL_NO_CONTEXT;
258 context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
259 context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
261 return context_.get();
264 void Display::DestroyContext(EGLContext ctx) {
265 DCHECK(IsValidContext(ctx));
266 context_.reset();
267 transfer_buffer_.reset();
270 bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
271 if (ctx == EGL_NO_CONTEXT) {
272 gles2::SetGLContext(NULL);
273 } else {
274 DCHECK(IsValidSurface(draw));
275 DCHECK(IsValidSurface(read));
276 DCHECK(IsValidContext(ctx));
277 gles2::SetGLContext(context_.get());
279 return true;
282 gpu::Capabilities Display::GetCapabilities() {
283 return decoder_->GetCapabilities();
286 int32_t Display::CreateImage(ClientBuffer buffer,
287 size_t width,
288 size_t height,
289 unsigned internalformat) {
290 NOTIMPLEMENTED();
291 return -1;
294 void Display::DestroyImage(int32 id) {
295 NOTIMPLEMENTED();
298 int32_t Display::CreateGpuMemoryBufferImage(size_t width,
299 size_t height,
300 unsigned internalformat,
301 unsigned usage) {
302 NOTIMPLEMENTED();
303 return -1;
306 uint32 Display::InsertSyncPoint() {
307 NOTIMPLEMENTED();
308 return 0u;
311 uint32 Display::InsertFutureSyncPoint() {
312 NOTIMPLEMENTED();
313 return 0u;
316 void Display::RetireSyncPoint(uint32 sync_point) {
317 NOTIMPLEMENTED();
320 void Display::SignalSyncPoint(uint32 sync_point,
321 const base::Closure& callback) {
322 NOTIMPLEMENTED();
325 void Display::SignalQuery(uint32 query, const base::Closure& callback) {
326 NOTIMPLEMENTED();
329 void Display::SetSurfaceVisible(bool visible) {
330 NOTIMPLEMENTED();
333 uint32 Display::CreateStreamTexture(uint32 texture_id) {
334 NOTIMPLEMENTED();
335 return 0;
338 void Display::SetLock(base::Lock*) {
339 NOTIMPLEMENTED();
342 bool Display::IsGpuChannelLost() {
343 NOTIMPLEMENTED();
344 return false;
347 } // namespace egl