Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / gl / gl_surface_egl.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 // This include must be here so that the includes provided transitively
6 // by gl_surface_egl.h don't make it impossible to compile this code.
7 #include "third_party/mesa/src/include/GL/osmesa.h"
8
9 #include "ui/gl/gl_surface_egl.h"
10
11 #if defined(OS_ANDROID)
12 #include <android/native_window_jni.h>
13 #include "base/android/sys_utils.h"
14 #endif
15
16 #include "base/debug/trace_event.h"
17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/message_loop/message_loop.h"
20 #include "build/build_config.h"
21 #include "ui/gfx/geometry/rect.h"
22 #include "ui/gl/egl_util.h"
23 #include "ui/gl/gl_context.h"
24 #include "ui/gl/gl_implementation.h"
25 #include "ui/gl/gl_surface_osmesa.h"
26 #include "ui/gl/gl_surface_stub.h"
27 #include "ui/gl/gl_switches.h"
28 #include "ui/gl/scoped_make_current.h"
29 #include "ui/gl/sync_control_vsync_provider.h"
30
31 #if defined(USE_X11)
32 extern "C" {
33 #include <X11/Xlib.h>
34 }
35 #endif
36
37 #if defined (USE_OZONE)
38 #include "ui/gfx/ozone/surface_factory_ozone.h"
39 #endif
40
41 #if !defined(EGL_FIXED_SIZE_ANGLE)
42 #define EGL_FIXED_SIZE_ANGLE 0x3201
43 #endif
44
45 using ui::GetLastEGLErrorString;
46
47 namespace gfx {
48
49 namespace {
50
51 EGLConfig g_config;
52 EGLDisplay g_display;
53 EGLNativeDisplayType g_native_display;
54
55 const char* g_egl_extensions = NULL;
56 bool g_egl_create_context_robustness_supported = false;
57 bool g_egl_sync_control_supported = false;
58 bool g_egl_window_fixed_size_supported = false;
59 bool g_egl_surfaceless_context_supported = false;
60
61 class EGLSyncControlVSyncProvider
62     : public gfx::SyncControlVSyncProvider {
63  public:
64   explicit EGLSyncControlVSyncProvider(EGLSurface surface)
65       : SyncControlVSyncProvider(),
66         surface_(surface) {
67   }
68
69   virtual ~EGLSyncControlVSyncProvider() { }
70
71  protected:
72   virtual bool GetSyncValues(int64* system_time,
73                              int64* media_stream_counter,
74                              int64* swap_buffer_counter) OVERRIDE {
75     uint64 u_system_time, u_media_stream_counter, u_swap_buffer_counter;
76     bool result = eglGetSyncValuesCHROMIUM(
77         g_display, surface_, &u_system_time,
78         &u_media_stream_counter, &u_swap_buffer_counter) == EGL_TRUE;
79     if (result) {
80       *system_time = static_cast<int64>(u_system_time);
81       *media_stream_counter = static_cast<int64>(u_media_stream_counter);
82       *swap_buffer_counter = static_cast<int64>(u_swap_buffer_counter);
83     }
84     return result;
85   }
86
87   virtual bool GetMscRate(int32* numerator, int32* denominator) OVERRIDE {
88     return false;
89   }
90
91  private:
92   EGLSurface surface_;
93
94   DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider);
95 };
96
97 bool ValidateEglConfig(EGLDisplay display,
98                        const EGLint* config_attribs,
99                        EGLint* num_configs) {
100   if (!eglChooseConfig(display,
101                        config_attribs,
102                        NULL,
103                        0,
104                        num_configs)) {
105     LOG(ERROR) << "eglChooseConfig failed with error "
106                << GetLastEGLErrorString();
107     return false;
108   }
109   if (*num_configs == 0) {
110     LOG(ERROR) << "No suitable EGL configs found.";
111     return false;
112   }
113   return true;
114 }
115
116 }  // namespace
117
118 GLSurfaceEGL::GLSurfaceEGL() {}
119
120 bool GLSurfaceEGL::InitializeOneOff() {
121   static bool initialized = false;
122   if (initialized)
123     return true;
124
125   g_native_display = GetPlatformDefaultEGLNativeDisplay();
126   g_display = eglGetDisplay(g_native_display);
127   if (!g_display) {
128     LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString();
129     return false;
130   }
131
132   if (!eglInitialize(g_display, NULL, NULL)) {
133     LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
134     return false;
135   }
136
137   // Choose an EGL configuration.
138   // On X this is only used for PBuffer surfaces.
139   static EGLint config_attribs_8888[] = {
140     EGL_BUFFER_SIZE, 32,
141     EGL_ALPHA_SIZE, 8,
142     EGL_BLUE_SIZE, 8,
143     EGL_GREEN_SIZE, 8,
144     EGL_RED_SIZE, 8,
145     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
146     EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
147     EGL_NONE
148   };
149
150 #if defined(OS_ANDROID)
151   static EGLint config_attribs_565[] = {
152     EGL_BUFFER_SIZE, 16,
153     EGL_BLUE_SIZE, 5,
154     EGL_GREEN_SIZE, 6,
155     EGL_RED_SIZE, 5,
156     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
157     EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
158     EGL_NONE
159   };
160 #endif
161   EGLint* choose_attributes = config_attribs_8888;
162
163 #if defined(OS_ANDROID)
164   if (base::android::SysUtils::IsLowEndDevice()) {
165     choose_attributes = config_attribs_565;
166   }
167 #endif
168
169 #if defined(USE_OZONE)
170   const EGLint* config_attribs =
171       SurfaceFactoryOzone::GetInstance()->GetEGLSurfaceProperties(
172           choose_attributes);
173 #else
174   const EGLint* config_attribs = choose_attributes;
175 #endif
176
177   EGLint num_configs;
178   EGLint config_size = 1;
179   EGLConfig* config_data = &g_config;
180   // Validate if there are any configs for given atrribs.
181   if (!ValidateEglConfig(g_display,
182                          config_attribs,
183                          &num_configs)) {
184     return false;
185   }
186
187 #if defined(OS_ANDROID)
188   scoped_ptr<EGLConfig[]> matching_configs(new EGLConfig[num_configs]);
189   if (base::android::SysUtils::IsLowEndDevice()) {
190     config_size = num_configs;
191     config_data = matching_configs.get();
192   }
193 #endif
194
195   if (!eglChooseConfig(g_display,
196                        config_attribs,
197                        config_data,
198                        config_size,
199                        &num_configs)) {
200     LOG(ERROR) << "eglChooseConfig failed with error "
201                << GetLastEGLErrorString();
202     return false;
203   }
204
205 #if defined(OS_ANDROID)
206   if (base::android::SysUtils::IsLowEndDevice()) {
207     // Because of the EGL config sort order, we have to iterate
208     // through all of them (it'll put higher sum(R,G,B) bits
209     // first with the above attribs).
210     bool match_found = false;
211     for (int i = 0; i < num_configs; i++) {
212       EGLBoolean success;
213       EGLint red, green, blue;
214       // Read the relevent attributes of the EGLConfig.
215       success = eglGetConfigAttrib(g_display, matching_configs[i],
216                                    EGL_RED_SIZE, &red);
217       success &= eglGetConfigAttrib(g_display, matching_configs[i],
218                                     EGL_BLUE_SIZE, &blue);
219       success &= eglGetConfigAttrib(g_display, matching_configs[i],
220                                     EGL_GREEN_SIZE, &green);
221       if ((success == EGL_TRUE) && (red == 5) &&
222           (green == 6) && (blue == 5)) {
223         g_config = matching_configs[i];
224         match_found = true;
225         break;
226       }
227     }
228     if (!match_found) {
229       // To fall back to default 32 bit format, choose with
230       // the right attributes again.
231       if (!ValidateEglConfig(g_display,
232                              config_attribs_8888,
233                              &num_configs)) {
234         return false;
235       }
236       if (!eglChooseConfig(g_display,
237                            config_attribs_8888,
238                            &g_config,
239                            1,
240                            &num_configs)) {
241         LOG(ERROR) << "eglChooseConfig failed with error "
242                    << GetLastEGLErrorString();
243         return false;
244       }
245     }
246   }
247
248 #endif
249
250   g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS);
251   g_egl_create_context_robustness_supported =
252       HasEGLExtension("EGL_EXT_create_context_robustness");
253   g_egl_sync_control_supported =
254       HasEGLExtension("EGL_CHROMIUM_sync_control");
255   g_egl_window_fixed_size_supported =
256       HasEGLExtension("EGL_ANGLE_window_fixed_size");
257
258   // Check if SurfacelessEGL is supported.
259   g_egl_surfaceless_context_supported =
260       HasEGLExtension("EGL_KHR_surfaceless_context");
261   if (g_egl_surfaceless_context_supported) {
262     // EGL_KHR_surfaceless_context is supported but ensure
263     // GL_OES_surfaceless_context is also supported. We need a current context
264     // to query for supported GL extensions.
265     scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1));
266     scoped_refptr<GLContext> context = GLContext::CreateGLContext(
267       NULL, surface.get(), PreferIntegratedGpu);
268     if (!context->MakeCurrent(surface.get()))
269       g_egl_surfaceless_context_supported = false;
270
271     // Ensure context supports GL_OES_surfaceless_context.
272     if (g_egl_surfaceless_context_supported) {
273       g_egl_surfaceless_context_supported = context->HasExtension(
274           "GL_OES_surfaceless_context");
275       context->ReleaseCurrent(surface.get());
276     }
277   }
278
279   initialized = true;
280
281   return true;
282 }
283
284 EGLDisplay GLSurfaceEGL::GetDisplay() {
285   return g_display;
286 }
287
288 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() {
289   return g_display;
290 }
291
292 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() {
293   return g_native_display;
294 }
295
296 const char* GLSurfaceEGL::GetEGLExtensions() {
297   return g_egl_extensions;
298 }
299
300 bool GLSurfaceEGL::HasEGLExtension(const char* name) {
301   return ExtensionsContain(GetEGLExtensions(), name);
302 }
303
304 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() {
305   return g_egl_create_context_robustness_supported;
306 }
307
308 bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() {
309   return g_egl_surfaceless_context_supported;
310 }
311
312 GLSurfaceEGL::~GLSurfaceEGL() {}
313
314 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window)
315     : window_(window),
316       surface_(NULL),
317       supports_post_sub_buffer_(false),
318       config_(NULL),
319       size_(1, 1) {
320 #if defined(OS_ANDROID)
321   if (window)
322     ANativeWindow_acquire(window);
323 #endif
324
325 #if defined(OS_WIN)
326   RECT windowRect;
327   if (GetClientRect(window_, &windowRect))
328     size_ = gfx::Rect(windowRect).size();
329 #endif
330 }
331
332 bool NativeViewGLSurfaceEGL::Initialize() {
333   return Initialize(scoped_ptr<VSyncProvider>());
334 }
335
336 bool NativeViewGLSurfaceEGL::Initialize(
337     scoped_ptr<VSyncProvider> sync_provider) {
338   DCHECK(!surface_);
339
340   if (!GetDisplay()) {
341     LOG(ERROR) << "Trying to create surface with invalid display.";
342     return false;
343   }
344
345   std::vector<EGLint> egl_window_attributes;
346
347   if (g_egl_window_fixed_size_supported) {
348     egl_window_attributes.push_back(EGL_FIXED_SIZE_ANGLE);
349     egl_window_attributes.push_back(EGL_TRUE);
350     egl_window_attributes.push_back(EGL_WIDTH);
351     egl_window_attributes.push_back(size_.width());
352     egl_window_attributes.push_back(EGL_HEIGHT);
353     egl_window_attributes.push_back(size_.height());
354   }
355
356   if (gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer) {
357     egl_window_attributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV);
358     egl_window_attributes.push_back(EGL_TRUE);
359   }
360
361   egl_window_attributes.push_back(EGL_NONE);
362   // Create a surface for the native window.
363   surface_ = eglCreateWindowSurface(
364       GetDisplay(), GetConfig(), window_, &egl_window_attributes[0]);
365
366   if (!surface_) {
367     LOG(ERROR) << "eglCreateWindowSurface failed with error "
368                << GetLastEGLErrorString();
369     Destroy();
370     return false;
371   }
372
373   EGLint surfaceVal;
374   EGLBoolean retVal = eglQuerySurface(GetDisplay(),
375                                       surface_,
376                                       EGL_POST_SUB_BUFFER_SUPPORTED_NV,
377                                       &surfaceVal);
378   supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE;
379
380   if (sync_provider)
381     vsync_provider_.reset(sync_provider.release());
382   else if (g_egl_sync_control_supported)
383     vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_));
384   return true;
385 }
386
387 void NativeViewGLSurfaceEGL::Destroy() {
388   if (surface_) {
389     if (!eglDestroySurface(GetDisplay(), surface_)) {
390       LOG(ERROR) << "eglDestroySurface failed with error "
391                  << GetLastEGLErrorString();
392     }
393     surface_ = NULL;
394   }
395 }
396
397 EGLConfig NativeViewGLSurfaceEGL::GetConfig() {
398 #if !defined(USE_X11)
399   return g_config;
400 #else
401   if (!config_) {
402     // Get a config compatible with the window
403     DCHECK(window_);
404     XWindowAttributes win_attribs;
405     if (!XGetWindowAttributes(GetNativeDisplay(), window_, &win_attribs)) {
406       return NULL;
407     }
408
409     // Try matching the window depth with an alpha channel,
410     // because we're worried the destination alpha width could
411     // constrain blending precision.
412     const int kBufferSizeOffset = 1;
413     const int kAlphaSizeOffset = 3;
414     EGLint config_attribs[] = {
415       EGL_BUFFER_SIZE, ~0,
416       EGL_ALPHA_SIZE, 8,
417       EGL_BLUE_SIZE, 8,
418       EGL_GREEN_SIZE, 8,
419       EGL_RED_SIZE, 8,
420       EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
421       EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
422       EGL_NONE
423     };
424     config_attribs[kBufferSizeOffset] = win_attribs.depth;
425
426     EGLint num_configs;
427     if (!eglChooseConfig(g_display,
428                          config_attribs,
429                          &config_,
430                          1,
431                          &num_configs)) {
432       LOG(ERROR) << "eglChooseConfig failed with error "
433                  << GetLastEGLErrorString();
434       return NULL;
435     }
436
437     if (num_configs) {
438       EGLint config_depth;
439       if (!eglGetConfigAttrib(g_display,
440                               config_,
441                               EGL_BUFFER_SIZE,
442                               &config_depth)) {
443         LOG(ERROR) << "eglGetConfigAttrib failed with error "
444                    << GetLastEGLErrorString();
445         return NULL;
446       }
447
448       if (config_depth == win_attribs.depth) {
449         return config_;
450       }
451     }
452
453     // Try without an alpha channel.
454     config_attribs[kAlphaSizeOffset] = 0;
455     if (!eglChooseConfig(g_display,
456                          config_attribs,
457                          &config_,
458                          1,
459                          &num_configs)) {
460       LOG(ERROR) << "eglChooseConfig failed with error "
461                  << GetLastEGLErrorString();
462       return NULL;
463     }
464
465     if (num_configs == 0) {
466       LOG(ERROR) << "No suitable EGL configs found.";
467       return NULL;
468     }
469   }
470   return config_;
471 #endif
472 }
473
474 bool NativeViewGLSurfaceEGL::IsOffscreen() {
475   return false;
476 }
477
478 bool NativeViewGLSurfaceEGL::SwapBuffers() {
479   TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers",
480       "width", GetSize().width(),
481       "height", GetSize().height());
482
483   if (!eglSwapBuffers(GetDisplay(), surface_)) {
484     DVLOG(1) << "eglSwapBuffers failed with error "
485              << GetLastEGLErrorString();
486     return false;
487   }
488
489   return true;
490 }
491
492 gfx::Size NativeViewGLSurfaceEGL::GetSize() {
493   EGLint width;
494   EGLint height;
495   if (!eglQuerySurface(GetDisplay(), surface_, EGL_WIDTH, &width) ||
496       !eglQuerySurface(GetDisplay(), surface_, EGL_HEIGHT, &height)) {
497     NOTREACHED() << "eglQuerySurface failed with error "
498                  << GetLastEGLErrorString();
499     return gfx::Size();
500   }
501
502   return gfx::Size(width, height);
503 }
504
505 bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size) {
506   if (size == GetSize())
507     return true;
508
509   size_ = size;
510
511   scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
512   GLContext* current_context = GLContext::GetCurrent();
513   bool was_current =
514       current_context && current_context->IsCurrent(this);
515   if (was_current) {
516     scoped_make_current.reset(
517         new ui::ScopedMakeCurrent(current_context, this));
518     current_context->ReleaseCurrent(this);
519   }
520
521   Destroy();
522
523   if (!Initialize()) {
524     LOG(ERROR) << "Failed to resize window.";
525     return false;
526   }
527
528   return true;
529 }
530
531 bool NativeViewGLSurfaceEGL::Recreate() {
532   Destroy();
533   if (!Initialize()) {
534     LOG(ERROR) << "Failed to create surface.";
535     return false;
536   }
537   return true;
538 }
539
540 EGLSurface NativeViewGLSurfaceEGL::GetHandle() {
541   return surface_;
542 }
543
544 bool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() {
545   return supports_post_sub_buffer_;
546 }
547
548 bool NativeViewGLSurfaceEGL::PostSubBuffer(
549     int x, int y, int width, int height) {
550   DCHECK(supports_post_sub_buffer_);
551   if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) {
552     DVLOG(1) << "eglPostSubBufferNV failed with error "
553              << GetLastEGLErrorString();
554     return false;
555   }
556   return true;
557 }
558
559 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() {
560   return vsync_provider_.get();
561 }
562
563 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() {
564   Destroy();
565 #if defined(OS_ANDROID)
566   if (window_)
567     ANativeWindow_release(window_);
568 #endif
569 }
570
571 void NativeViewGLSurfaceEGL::SetHandle(EGLSurface surface) {
572   surface_ = surface;
573 }
574
575 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size)
576     : size_(size),
577       surface_(NULL) {
578 }
579
580 bool PbufferGLSurfaceEGL::Initialize() {
581   EGLSurface old_surface = surface_;
582
583   EGLDisplay display = GetDisplay();
584   if (!display) {
585     LOG(ERROR) << "Trying to create surface with invalid display.";
586     return false;
587   }
588
589   if (size_.GetArea() == 0) {
590     LOG(ERROR) << "Error: surface has zero area "
591                << size_.width() << " x " << size_.height();
592     return false;
593   }
594
595   // Allocate the new pbuffer surface before freeing the old one to ensure
596   // they have different addresses. If they have the same address then a
597   // future call to MakeCurrent might early out because it appears the current
598   // context and surface have not changed.
599   const EGLint pbuffer_attribs[] = {
600     EGL_WIDTH, size_.width(),
601     EGL_HEIGHT, size_.height(),
602     EGL_NONE
603   };
604
605   EGLSurface new_surface = eglCreatePbufferSurface(display,
606                                                    GetConfig(),
607                                                    pbuffer_attribs);
608   if (!new_surface) {
609     LOG(ERROR) << "eglCreatePbufferSurface failed with error "
610                << GetLastEGLErrorString();
611     return false;
612   }
613
614   if (old_surface)
615     eglDestroySurface(display, old_surface);
616
617   surface_ = new_surface;
618   return true;
619 }
620
621 void PbufferGLSurfaceEGL::Destroy() {
622   if (surface_) {
623     if (!eglDestroySurface(GetDisplay(), surface_)) {
624       LOG(ERROR) << "eglDestroySurface failed with error "
625                  << GetLastEGLErrorString();
626     }
627     surface_ = NULL;
628   }
629 }
630
631 EGLConfig PbufferGLSurfaceEGL::GetConfig() {
632   return g_config;
633 }
634
635 bool PbufferGLSurfaceEGL::IsOffscreen() {
636   return true;
637 }
638
639 bool PbufferGLSurfaceEGL::SwapBuffers() {
640   NOTREACHED() << "Attempted to call SwapBuffers on a PbufferGLSurfaceEGL.";
641   return false;
642 }
643
644 gfx::Size PbufferGLSurfaceEGL::GetSize() {
645   return size_;
646 }
647
648 bool PbufferGLSurfaceEGL::Resize(const gfx::Size& size) {
649   if (size == size_)
650     return true;
651
652   scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
653   GLContext* current_context = GLContext::GetCurrent();
654   bool was_current =
655       current_context && current_context->IsCurrent(this);
656   if (was_current) {
657     scoped_make_current.reset(
658         new ui::ScopedMakeCurrent(current_context, this));
659   }
660
661   size_ = size;
662
663   if (!Initialize()) {
664     LOG(ERROR) << "Failed to resize pbuffer.";
665     return false;
666   }
667
668   return true;
669 }
670
671 EGLSurface PbufferGLSurfaceEGL::GetHandle() {
672   return surface_;
673 }
674
675 void* PbufferGLSurfaceEGL::GetShareHandle() {
676 #if defined(OS_ANDROID)
677   NOTREACHED();
678   return NULL;
679 #else
680   if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_query_surface_pointer)
681     return NULL;
682
683   if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle)
684     return NULL;
685
686   void* handle;
687   if (!eglQuerySurfacePointerANGLE(g_display,
688                                    GetHandle(),
689                                    EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
690                                    &handle)) {
691     return NULL;
692   }
693
694   return handle;
695 #endif
696 }
697
698 PbufferGLSurfaceEGL::~PbufferGLSurfaceEGL() {
699   Destroy();
700 }
701
702 SurfacelessEGL::SurfacelessEGL(const gfx::Size& size)
703     : size_(size) {
704 }
705
706 bool SurfacelessEGL::Initialize() {
707   return true;
708 }
709
710 void SurfacelessEGL::Destroy() {
711 }
712
713 EGLConfig SurfacelessEGL::GetConfig() {
714   return g_config;
715 }
716
717 bool SurfacelessEGL::IsOffscreen() {
718   return true;
719 }
720
721 bool SurfacelessEGL::SwapBuffers() {
722   LOG(ERROR) << "Attempted to call SwapBuffers with SurfacelessEGL.";
723   return false;
724 }
725
726 gfx::Size SurfacelessEGL::GetSize() {
727   return size_;
728 }
729
730 bool SurfacelessEGL::Resize(const gfx::Size& size) {
731   size_ = size;
732   return true;
733 }
734
735 EGLSurface SurfacelessEGL::GetHandle() {
736   return EGL_NO_SURFACE;
737 }
738
739 void* SurfacelessEGL::GetShareHandle() {
740   return NULL;
741 }
742
743 SurfacelessEGL::~SurfacelessEGL() {
744 }
745
746 }  // namespace gfx