Upstream version 7.36.149.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/transfer_buffer_manager.h"
15 #include "gpu/gles2_conform_support/egl/config.h"
16 #include "gpu/gles2_conform_support/egl/surface.h"
17
18 namespace {
19 const int32 kCommandBufferSize = 1024 * 1024;
20 const int32 kTransferBufferSize = 512 * 1024;
21 }
22
23 namespace egl {
24
25 Display::Display(EGLNativeDisplayType display_id)
26     : display_id_(display_id),
27       is_initialized_(false),
28       create_offscreen_(false),
29       create_offscreen_width_(0),
30       create_offscreen_height_(0) {
31 }
32
33 Display::~Display() {
34   gles2::Terminate();
35 }
36
37 bool Display::Initialize() {
38   gles2::Initialize();
39   is_initialized_ = true;
40   return true;
41 }
42
43 bool Display::IsValidConfig(EGLConfig config) {
44   return (config != NULL) && (config == config_.get());
45 }
46
47 bool Display::ChooseConfigs(EGLConfig* configs,
48                             EGLint config_size,
49                             EGLint* num_config) {
50   // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
51   // does not support finding or choosing configs.
52   *num_config = 1;
53   if (configs != NULL) {
54     if (config_ == NULL) {
55       config_.reset(new Config);
56     }
57     configs[0] = config_.get();
58   }
59   return true;
60 }
61
62 bool Display::GetConfigs(EGLConfig* configs,
63                          EGLint config_size,
64                          EGLint* num_config) {
65   // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
66   // does not support finding or choosing configs.
67   *num_config = 1;
68   if (configs != NULL) {
69     if (config_ == NULL) {
70       config_.reset(new Config);
71     }
72     configs[0] = config_.get();
73   }
74   return true;
75 }
76
77 bool Display::GetConfigAttrib(EGLConfig config,
78                               EGLint attribute,
79                               EGLint* value) {
80   const egl::Config* cfg = static_cast<egl::Config*>(config);
81   return cfg->GetAttrib(attribute, value);
82 }
83
84 bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
85 #if defined OS_WIN
86   return ::IsWindow(win) != FALSE;
87 #else
88   // TODO(alokp): Validate window handle.
89   return true;
90 #endif  // OS_WIN
91 }
92
93 bool Display::IsValidSurface(EGLSurface surface) {
94   return (surface != NULL) && (surface == surface_.get());
95 }
96
97 EGLSurface Display::CreateWindowSurface(EGLConfig config,
98                                         EGLNativeWindowType win,
99                                         const EGLint* attrib_list) {
100   if (surface_ != NULL) {
101     // We do not support more than one window surface.
102     return EGL_NO_SURFACE;
103   }
104
105   {
106     gpu::TransferBufferManager* manager = new gpu::TransferBufferManager();
107     transfer_buffer_manager_.reset(manager);
108     manager->Initialize();
109   }
110   scoped_ptr<gpu::CommandBufferService> command_buffer(
111       new gpu::CommandBufferService(transfer_buffer_manager_.get()));
112   if (!command_buffer->Initialize())
113     return NULL;
114
115   scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
116       NULL, NULL, NULL, new gpu::gles2::ShaderTranslatorCache, NULL, true));
117
118   decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
119   if (!decoder_.get())
120     return EGL_NO_SURFACE;
121
122   gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer.get(),
123                                              decoder_.get(),
124                                              NULL));
125
126   decoder_->set_engine(gpu_scheduler_.get());
127   gfx::Size size(create_offscreen_width_, create_offscreen_height_);
128   if (create_offscreen_) {
129     gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
130     create_offscreen_ = false;
131     create_offscreen_width_ = 0;
132     create_offscreen_height_ = 0;
133   } else {
134     gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win);
135   }
136   if (!gl_surface_.get())
137     return EGL_NO_SURFACE;
138
139   gl_context_ = gfx::GLContext::CreateGLContext(NULL,
140                                                 gl_surface_.get(),
141                                                 gfx::PreferDiscreteGpu);
142   if (!gl_context_.get())
143     return EGL_NO_SURFACE;
144
145   gl_context_->MakeCurrent(gl_surface_.get());
146
147   EGLint depth_size = 0;
148   EGLint alpha_size = 0;
149   EGLint stencil_size = 0;
150   GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size);
151   GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size);
152   GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size);
153   std::vector<int32> attribs;
154   attribs.push_back(EGL_DEPTH_SIZE);
155   attribs.push_back(depth_size);
156   attribs.push_back(EGL_ALPHA_SIZE);
157   attribs.push_back(alpha_size);
158   attribs.push_back(EGL_STENCIL_SIZE);
159   attribs.push_back(stencil_size);
160   // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null
161   attribs.push_back(EGL_NONE);
162
163   if (!decoder_->Initialize(gl_surface_.get(),
164                             gl_context_.get(),
165                             gl_surface_->IsOffscreen(),
166                             size,
167                             gpu::gles2::DisallowedFeatures(),
168                             attribs)) {
169     return EGL_NO_SURFACE;
170   }
171
172   gpu_control_service_.reset(new gpu::GpuControlService(NULL, NULL));
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
232   context_.reset(
233       new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(),
234                                           NULL,
235                                           transfer_buffer_.get(),
236                                           bind_generates_resources,
237                                           lose_context_when_out_of_memory,
238                                           this));
239
240   if (!context_->Initialize(
241       kTransferBufferSize,
242       kTransferBufferSize / 2,
243       kTransferBufferSize * 2,
244       gpu::gles2::GLES2Implementation::kNoLimit)) {
245     return EGL_NO_CONTEXT;
246   }
247
248   context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
249   context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
250
251   return context_.get();
252 }
253
254 void Display::DestroyContext(EGLContext ctx) {
255   DCHECK(IsValidContext(ctx));
256   context_.reset();
257   transfer_buffer_.reset();
258 }
259
260 bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
261   if (ctx == EGL_NO_CONTEXT) {
262     gles2::SetGLContext(NULL);
263   } else {
264     DCHECK(IsValidSurface(draw));
265     DCHECK(IsValidSurface(read));
266     DCHECK(IsValidContext(ctx));
267     gles2::SetGLContext(context_.get());
268   }
269   return true;
270 }
271
272 gpu::Capabilities Display::GetCapabilities() {
273   return decoder_->GetCapabilities();
274 }
275
276 gfx::GpuMemoryBuffer* Display::CreateGpuMemoryBuffer(
277     size_t width,
278     size_t height,
279     unsigned internalformat,
280     unsigned usage,
281     int32* id) {
282   NOTIMPLEMENTED();
283   return NULL;
284 }
285
286 void Display::DestroyGpuMemoryBuffer(int32 id) {
287   NOTIMPLEMENTED();
288 }
289
290 uint32 Display::InsertSyncPoint() {
291   NOTIMPLEMENTED();
292   return 0u;
293 }
294
295 void Display::SignalSyncPoint(uint32 sync_point,
296                              const base::Closure& callback) {
297   NOTIMPLEMENTED();
298 }
299
300 void Display::SignalQuery(uint32 query, const base::Closure& callback) {
301   NOTIMPLEMENTED();
302 }
303
304 void Display::SetSurfaceVisible(bool visible) {
305   NOTIMPLEMENTED();
306 }
307
308 void Display::SendManagedMemoryStats(const gpu::ManagedMemoryStats& stats) {
309   NOTIMPLEMENTED();
310 }
311
312 void Display::Echo(const base::Closure& callback) {
313   NOTIMPLEMENTED();
314 }
315
316 uint32 Display::CreateStreamTexture(uint32 texture_id) {
317   NOTIMPLEMENTED();
318   return 0;
319 }
320
321 }  // namespace egl