Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / gpu / gles2_conform_support / egl / display.cc
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.
4
5 #include "gpu/gles2_conform_support/egl/display.h"
6
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/service/context_group.h"
14 #include "gpu/command_buffer/service/mailbox_manager.h"
15 #include "gpu/command_buffer/service/memory_tracking.h"
16 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
17 #include "gpu/gles2_conform_support/egl/config.h"
18 #include "gpu/gles2_conform_support/egl/surface.h"
19
20 namespace {
21 const int32 kCommandBufferSize = 1024 * 1024;
22 const int32 kTransferBufferSize = 512 * 1024;
23 }
24
25 namespace egl {
26
27 Display::Display(EGLNativeDisplayType display_id)
28     : display_id_(display_id),
29       is_initialized_(false),
30       create_offscreen_(false),
31       create_offscreen_width_(0),
32       create_offscreen_height_(0) {
33 }
34
35 Display::~Display() {
36   gles2::Terminate();
37 }
38
39 bool Display::Initialize() {
40   gles2::Initialize();
41   is_initialized_ = true;
42   return true;
43 }
44
45 bool Display::IsValidConfig(EGLConfig config) {
46   return (config != NULL) && (config == config_.get());
47 }
48
49 bool Display::ChooseConfigs(EGLConfig* configs,
50                             EGLint config_size,
51                             EGLint* num_config) {
52   // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
53   // does not support finding or choosing configs.
54   *num_config = 1;
55   if (configs != NULL) {
56     if (config_ == NULL) {
57       config_.reset(new Config);
58     }
59     configs[0] = config_.get();
60   }
61   return true;
62 }
63
64 bool Display::GetConfigs(EGLConfig* configs,
65                          EGLint config_size,
66                          EGLint* num_config) {
67   // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
68   // does not support finding or choosing configs.
69   *num_config = 1;
70   if (configs != NULL) {
71     if (config_ == NULL) {
72       config_.reset(new Config);
73     }
74     configs[0] = config_.get();
75   }
76   return true;
77 }
78
79 bool Display::GetConfigAttrib(EGLConfig config,
80                               EGLint attribute,
81                               EGLint* value) {
82   const egl::Config* cfg = static_cast<egl::Config*>(config);
83   return cfg->GetAttrib(attribute, value);
84 }
85
86 bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
87 #if defined OS_WIN
88   return ::IsWindow(win) != FALSE;
89 #else
90   // TODO(alokp): Validate window handle.
91   return true;
92 #endif  // OS_WIN
93 }
94
95 bool Display::IsValidSurface(EGLSurface surface) {
96   return (surface != NULL) && (surface == surface_.get());
97 }
98
99 EGLSurface Display::CreateWindowSurface(EGLConfig config,
100                                         EGLNativeWindowType win,
101                                         const EGLint* attrib_list) {
102   if (surface_ != NULL) {
103     // We do not support more than one window surface.
104     return EGL_NO_SURFACE;
105   }
106
107   {
108     gpu::TransferBufferManager* manager = new gpu::TransferBufferManager();
109     transfer_buffer_manager_.reset(manager);
110     manager->Initialize();
111   }
112   scoped_ptr<gpu::CommandBufferService> command_buffer(
113       new gpu::CommandBufferService(transfer_buffer_manager_.get()));
114   if (!command_buffer->Initialize())
115     return NULL;
116
117   scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
118       NULL, NULL, new gpu::gles2::ShaderTranslatorCache, NULL, true));
119
120   decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
121   if (!decoder_.get())
122     return EGL_NO_SURFACE;
123
124   gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer.get(),
125                                              decoder_.get(),
126                                              NULL));
127
128   decoder_->set_engine(gpu_scheduler_.get());
129   gfx::Size size(create_offscreen_width_, create_offscreen_height_);
130   if (create_offscreen_) {
131     gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
132     create_offscreen_ = false;
133     create_offscreen_width_ = 0;
134     create_offscreen_height_ = 0;
135   } else {
136     gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win);
137   }
138   if (!gl_surface_.get())
139     return EGL_NO_SURFACE;
140
141   gl_context_ = gfx::GLContext::CreateGLContext(NULL,
142                                                 gl_surface_.get(),
143                                                 gfx::PreferDiscreteGpu);
144   if (!gl_context_.get())
145     return EGL_NO_SURFACE;
146
147   gl_context_->MakeCurrent(gl_surface_.get());
148
149   EGLint depth_size = 0;
150   EGLint alpha_size = 0;
151   EGLint stencil_size = 0;
152   GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size);
153   GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size);
154   GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size);
155   std::vector<int32> attribs;
156   attribs.push_back(EGL_DEPTH_SIZE);
157   attribs.push_back(depth_size);
158   attribs.push_back(EGL_ALPHA_SIZE);
159   attribs.push_back(alpha_size);
160   attribs.push_back(EGL_STENCIL_SIZE);
161   attribs.push_back(stencil_size);
162   // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null
163   attribs.push_back(EGL_NONE);
164
165   if (!decoder_->Initialize(gl_surface_.get(),
166                             gl_context_.get(),
167                             gl_surface_->IsOffscreen(),
168                             size,
169                             gpu::gles2::DisallowedFeatures(),
170                             attribs)) {
171     return EGL_NO_SURFACE;
172   }
173
174   command_buffer->SetPutOffsetChangeCallback(
175       base::Bind(&gpu::GpuScheduler::PutChanged,
176                  base::Unretained(gpu_scheduler_.get())));
177   command_buffer->SetGetBufferChangeCallback(
178       base::Bind(&gpu::GpuScheduler::SetGetBuffer,
179                  base::Unretained(gpu_scheduler_.get())));
180
181   scoped_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper(
182       new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
183   if (!cmd_helper->Initialize(kCommandBufferSize))
184     return NULL;
185
186   scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer(
187       cmd_helper.get()));
188
189   command_buffer_.reset(command_buffer.release());
190   transfer_buffer_.reset(transfer_buffer.release());
191   gles2_cmd_helper_.reset(cmd_helper.release());
192   surface_.reset(new Surface(win));
193
194   return surface_.get();
195 }
196
197 void Display::DestroySurface(EGLSurface surface) {
198   DCHECK(IsValidSurface(surface));
199   gpu_scheduler_.reset();
200   if (decoder_.get()) {
201     decoder_->Destroy(true);
202   }
203   decoder_.reset();
204   gl_surface_ = NULL;
205   gl_context_ = NULL;
206   surface_.reset();
207 }
208
209 void Display::SwapBuffers(EGLSurface surface) {
210   DCHECK(IsValidSurface(surface));
211   context_->SwapBuffers();
212 }
213
214 bool Display::IsValidContext(EGLContext ctx) {
215   return (ctx != NULL) && (ctx == context_.get());
216 }
217
218 EGLContext Display::CreateContext(EGLConfig config,
219                                   EGLContext share_ctx,
220                                   const EGLint* attrib_list) {
221   DCHECK(IsValidConfig(config));
222   // TODO(alokp): Add support for shared contexts.
223   if (share_ctx != NULL)
224     return EGL_NO_CONTEXT;
225
226   DCHECK(command_buffer_ != NULL);
227   DCHECK(transfer_buffer_.get());
228
229   bool bind_generates_resources = true;
230   bool lose_context_when_out_of_memory = false;
231   bool support_client_side_arrays = true;
232
233   context_.reset(
234       new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(),
235                                           NULL,
236                                           transfer_buffer_.get(),
237                                           bind_generates_resources,
238                                           lose_context_when_out_of_memory,
239                                           support_client_side_arrays,
240                                           this));
241
242   if (!context_->Initialize(
243       kTransferBufferSize,
244       kTransferBufferSize / 2,
245       kTransferBufferSize * 2,
246       gpu::gles2::GLES2Implementation::kNoLimit)) {
247     return EGL_NO_CONTEXT;
248   }
249
250   context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
251   context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
252
253   return context_.get();
254 }
255
256 void Display::DestroyContext(EGLContext ctx) {
257   DCHECK(IsValidContext(ctx));
258   context_.reset();
259   transfer_buffer_.reset();
260 }
261
262 bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
263   if (ctx == EGL_NO_CONTEXT) {
264     gles2::SetGLContext(NULL);
265   } else {
266     DCHECK(IsValidSurface(draw));
267     DCHECK(IsValidSurface(read));
268     DCHECK(IsValidContext(ctx));
269     gles2::SetGLContext(context_.get());
270   }
271   return true;
272 }
273
274 gpu::Capabilities Display::GetCapabilities() {
275   return decoder_->GetCapabilities();
276 }
277
278 int32_t Display::CreateImage(ClientBuffer buffer,
279                              size_t width,
280                              size_t height,
281                              unsigned internalformat) {
282   NOTIMPLEMENTED();
283   return -1;
284 }
285
286 void Display::DestroyImage(int32 id) {
287   NOTIMPLEMENTED();
288 }
289
290 int32_t Display::CreateGpuMemoryBufferImage(size_t width,
291                                             size_t height,
292                                             unsigned internalformat,
293                                             unsigned usage) {
294   NOTIMPLEMENTED();
295   return -1;
296 }
297
298 uint32 Display::InsertSyncPoint() {
299   NOTIMPLEMENTED();
300   return 0u;
301 }
302
303 uint32 Display::InsertFutureSyncPoint() {
304   NOTIMPLEMENTED();
305   return 0u;
306 }
307
308 void Display::RetireSyncPoint(uint32 sync_point) {
309   NOTIMPLEMENTED();
310 }
311
312 void Display::SignalSyncPoint(uint32 sync_point,
313                               const base::Closure& callback) {
314   NOTIMPLEMENTED();
315 }
316
317 void Display::SignalQuery(uint32 query, const base::Closure& callback) {
318   NOTIMPLEMENTED();
319 }
320
321 void Display::SetSurfaceVisible(bool visible) {
322   NOTIMPLEMENTED();
323 }
324
325 uint32 Display::CreateStreamTexture(uint32 texture_id) {
326   NOTIMPLEMENTED();
327   return 0;
328 }
329
330 }  // namespace egl