1 // Copyright 2014 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 "ui/gl/gl_surface.h"
8 #include "base/callback.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/threading/worker_pool.h"
15 #include "ui/gfx/native_widget_types.h"
16 #include "ui/gl/gl_context.h"
17 #include "ui/gl/gl_image.h"
18 #include "ui/gl/gl_image_linux_dma_buffer.h"
19 #include "ui/gl/gl_implementation.h"
20 #include "ui/gl/gl_surface_egl.h"
21 #include "ui/gl/gl_surface_osmesa.h"
22 #include "ui/gl/gl_surface_stub.h"
23 #include "ui/gl/scoped_binders.h"
24 #include "ui/gl/scoped_make_current.h"
25 #include "ui/ozone/public/native_pixmap.h"
26 #include "ui/ozone/public/surface_factory_ozone.h"
27 #include "ui/ozone/public/surface_ozone_egl.h"
33 void WaitForFence(EGLDisplay display
, EGLSyncKHR fence
) {
34 eglClientWaitSyncKHR(display
, fence
, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR
,
38 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow
39 class GL_EXPORT GLSurfaceOzoneEGL
: public NativeViewGLSurfaceEGL
{
41 GLSurfaceOzoneEGL(scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
42 AcceleratedWidget widget
);
45 bool Initialize() override
;
46 bool Resize(const gfx::Size
& size
) override
;
47 bool SwapBuffers() override
;
48 bool ScheduleOverlayPlane(int z_order
,
49 OverlayTransform transform
,
51 const Rect
& bounds_rect
,
52 const RectF
& crop_rect
) override
;
55 using NativeViewGLSurfaceEGL::Initialize
;
57 ~GLSurfaceOzoneEGL() override
;
59 bool ReinitializeNativeSurface();
61 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
62 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface_
;
63 AcceleratedWidget widget_
;
65 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL
);
68 GLSurfaceOzoneEGL::GLSurfaceOzoneEGL(
69 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
70 AcceleratedWidget widget
)
71 : NativeViewGLSurfaceEGL(ozone_surface
->GetNativeWindow()),
72 ozone_surface_(ozone_surface
.Pass()),
76 bool GLSurfaceOzoneEGL::Initialize() {
77 return Initialize(ozone_surface_
->CreateVSyncProvider());
80 bool GLSurfaceOzoneEGL::Resize(const gfx::Size
& size
) {
81 if (!ozone_surface_
->ResizeNativeWindow(size
)) {
82 if (!ReinitializeNativeSurface() ||
83 !ozone_surface_
->ResizeNativeWindow(size
))
87 return NativeViewGLSurfaceEGL::Resize(size
);
90 bool GLSurfaceOzoneEGL::SwapBuffers() {
91 if (!NativeViewGLSurfaceEGL::SwapBuffers())
94 return ozone_surface_
->OnSwapBuffers();
97 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order
,
98 OverlayTransform transform
,
100 const Rect
& bounds_rect
,
101 const RectF
& crop_rect
) {
102 return image
->ScheduleOverlayPlane(widget_
, z_order
, transform
, bounds_rect
,
106 GLSurfaceOzoneEGL::~GLSurfaceOzoneEGL() {
107 Destroy(); // EGL surface must be destroyed before SurfaceOzone
110 bool GLSurfaceOzoneEGL::ReinitializeNativeSurface() {
111 scoped_ptr
<ui::ScopedMakeCurrent
> scoped_make_current
;
112 GLContext
* current_context
= GLContext::GetCurrent();
113 bool was_current
= current_context
&& current_context
->IsCurrent(this);
115 scoped_make_current
.reset(new ui::ScopedMakeCurrent(current_context
, this));
119 ozone_surface_
= ui::SurfaceFactoryOzone::GetInstance()
120 ->CreateEGLSurfaceForWidget(widget_
)
122 if (!ozone_surface_
) {
123 LOG(ERROR
) << "Failed to create native surface.";
127 window_
= ozone_surface_
->GetNativeWindow();
129 LOG(ERROR
) << "Failed to initialize.";
136 class GL_EXPORT GLSurfaceOzoneSurfaceless
: public SurfacelessEGL
{
138 GLSurfaceOzoneSurfaceless(scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
139 AcceleratedWidget widget
);
142 bool Initialize() override
;
143 bool Resize(const gfx::Size
& size
) override
;
144 bool SwapBuffers() override
;
145 bool ScheduleOverlayPlane(int z_order
,
146 OverlayTransform transform
,
148 const Rect
& bounds_rect
,
149 const RectF
& crop_rect
) override
;
150 bool IsOffscreen() override
;
151 VSyncProvider
* GetVSyncProvider() override
;
152 bool SupportsPostSubBuffer() override
;
153 bool PostSubBuffer(int x
, int y
, int width
, int height
) override
;
154 bool SwapBuffersAsync(const SwapCompletionCallback
& callback
) override
;
155 bool PostSubBufferAsync(int x
,
159 const SwapCompletionCallback
& callback
) override
;
164 OverlayTransform transform
,
166 const Rect
& bounds_rect
,
167 const RectF
& crop_rect
);
169 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget
) const;
172 OverlayTransform transform
;
173 scoped_refptr
<GLImage
> image
;
178 struct PendingFrame
{
181 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget
);
184 std::vector
<Overlay
> overlays
;
185 SwapCompletionCallback callback
;
188 ~GLSurfaceOzoneSurfaceless() override
;
192 EGLSyncKHR
InsertFence();
193 void FenceRetired(EGLSyncKHR fence
, PendingFrame
* frame
);
195 void SwapCompleted(const SwapCompletionCallback
& callback
);
197 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
198 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface_
;
199 AcceleratedWidget widget_
;
200 scoped_ptr
<VSyncProvider
> vsync_provider_
;
201 ScopedVector
<PendingFrame
> unsubmitted_frames_
;
202 bool has_implicit_external_sync_
;
203 bool last_swap_buffers_result_
;
204 bool swap_buffers_pending_
;
206 base::WeakPtrFactory
<GLSurfaceOzoneSurfaceless
> weak_factory_
;
208 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless
);
211 GLSurfaceOzoneSurfaceless::Overlay::Overlay(int z_order
,
212 OverlayTransform transform
,
214 const Rect
& bounds_rect
,
215 const RectF
& crop_rect
)
217 transform(transform
),
219 bounds_rect(bounds_rect
),
220 crop_rect(crop_rect
) {
223 bool GLSurfaceOzoneSurfaceless::Overlay::ScheduleOverlayPlane(
224 gfx::AcceleratedWidget widget
) const {
225 return image
->ScheduleOverlayPlane(widget
, z_order
, transform
, bounds_rect
,
229 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {
232 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes(
233 gfx::AcceleratedWidget widget
) {
234 for (const auto& overlay
: overlays
)
235 if (!overlay
.ScheduleOverlayPlane(widget
))
240 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless(
241 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
242 AcceleratedWidget widget
)
243 : SurfacelessEGL(gfx::Size()),
244 ozone_surface_(ozone_surface
.Pass()),
246 has_implicit_external_sync_(
247 HasEGLExtension("EGL_ARM_implicit_external_sync")),
248 last_swap_buffers_result_(true),
249 swap_buffers_pending_(false),
250 weak_factory_(this) {
251 unsubmitted_frames_
.push_back(new PendingFrame());
254 bool GLSurfaceOzoneSurfaceless::Initialize() {
255 if (!SurfacelessEGL::Initialize())
257 vsync_provider_
= ozone_surface_
->CreateVSyncProvider();
258 if (!vsync_provider_
)
262 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size
& size
) {
263 if (!ozone_surface_
->ResizeNativeWindow(size
))
266 return SurfacelessEGL::Resize(size
);
268 bool GLSurfaceOzoneSurfaceless::SwapBuffers() {
270 // TODO: the following should be replaced by a per surface flush as it gets
271 // implemented in GL drivers.
272 if (has_implicit_external_sync_
) {
273 EGLSyncKHR fence
= InsertFence();
277 EGLDisplay display
= GetDisplay();
278 WaitForFence(display
, fence
);
279 eglDestroySyncKHR(display
, fence
);
280 } else if (ozone_surface_
->IsUniversalDisplayLinkDevice()) {
284 unsubmitted_frames_
.back()->ScheduleOverlayPlanes(widget_
);
285 unsubmitted_frames_
.back()->overlays
.clear();
287 return ozone_surface_
->OnSwapBuffers();
289 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(int z_order
,
290 OverlayTransform transform
,
292 const Rect
& bounds_rect
,
293 const RectF
& crop_rect
) {
294 unsubmitted_frames_
.back()->overlays
.push_back(
295 Overlay(z_order
, transform
, image
, bounds_rect
, crop_rect
));
298 bool GLSurfaceOzoneSurfaceless::IsOffscreen() {
301 VSyncProvider
* GLSurfaceOzoneSurfaceless::GetVSyncProvider() {
302 return vsync_provider_
.get();
304 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() {
307 bool GLSurfaceOzoneSurfaceless::PostSubBuffer(int x
,
311 // The actual sub buffer handling is handled at higher layers.
315 bool GLSurfaceOzoneSurfaceless::SwapBuffersAsync(
316 const SwapCompletionCallback
& callback
) {
317 // If last swap failed, don't try to schedule new ones.
318 if (!last_swap_buffers_result_
)
323 base::Closure surface_swap_callback
=
324 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted
,
325 weak_factory_
.GetWeakPtr(), callback
);
327 PendingFrame
* frame
= unsubmitted_frames_
.back();
328 frame
->callback
= surface_swap_callback
;
329 unsubmitted_frames_
.push_back(new PendingFrame());
331 // TODO: the following should be replaced by a per surface flush as it gets
332 // implemented in GL drivers.
333 if (has_implicit_external_sync_
) {
334 EGLSyncKHR fence
= InsertFence();
338 base::Closure fence_wait_task
=
339 base::Bind(&WaitForFence
, GetDisplay(), fence
);
341 base::Closure fence_retired_callback
=
342 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired
,
343 weak_factory_
.GetWeakPtr(), fence
, frame
);
345 base::WorkerPool::PostTaskAndReply(FROM_HERE
, fence_wait_task
,
346 fence_retired_callback
, false);
348 } else if (ozone_surface_
->IsUniversalDisplayLinkDevice()) {
354 return last_swap_buffers_result_
;
356 bool GLSurfaceOzoneSurfaceless::PostSubBufferAsync(
361 const SwapCompletionCallback
& callback
) {
362 return SwapBuffersAsync(callback
);
365 GLSurfaceOzoneSurfaceless::~GLSurfaceOzoneSurfaceless() {
366 Destroy(); // EGL surface must be destroyed before SurfaceOzone
369 void GLSurfaceOzoneSurfaceless::SubmitFrame() {
370 DCHECK(!unsubmitted_frames_
.empty());
372 if (unsubmitted_frames_
.front()->ready
&& !swap_buffers_pending_
) {
373 scoped_ptr
<PendingFrame
> frame(unsubmitted_frames_
.front());
374 unsubmitted_frames_
.weak_erase(unsubmitted_frames_
.begin());
375 swap_buffers_pending_
= true;
377 last_swap_buffers_result_
=
378 frame
->ScheduleOverlayPlanes(widget_
) &&
379 ozone_surface_
->OnSwapBuffersAsync(frame
->callback
);
383 EGLSyncKHR
GLSurfaceOzoneSurfaceless::InsertFence() {
384 const EGLint attrib_list
[] = {EGL_SYNC_CONDITION_KHR
,
385 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM
,
387 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR
, attrib_list
);
390 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence
,
391 PendingFrame
* frame
) {
392 eglDestroySyncKHR(GetDisplay(), fence
);
397 void GLSurfaceOzoneSurfaceless::SwapCompleted(
398 const SwapCompletionCallback
& callback
) {
400 swap_buffers_pending_
= false;
405 // This provides surface-like semantics implemented through surfaceless.
406 // A framebuffer is bound automatically.
407 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
408 : public GLSurfaceOzoneSurfaceless
{
410 GLSurfaceOzoneSurfacelessSurfaceImpl(
411 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
412 AcceleratedWidget widget
);
415 unsigned int GetBackingFrameBufferObject() override
;
416 bool OnMakeCurrent(GLContext
* context
) override
;
417 bool Resize(const gfx::Size
& size
) override
;
418 bool SupportsPostSubBuffer() override
;
419 bool SwapBuffers() override
;
420 bool SwapBuffersAsync(const SwapCompletionCallback
& callback
) override
;
421 void Destroy() override
;
424 class SurfaceImage
: public GLImageLinuxDMABuffer
{
426 SurfaceImage(const gfx::Size
& size
, unsigned internalformat
);
428 bool Initialize(scoped_refptr
<ui::NativePixmap
> pixmap
,
429 gfx::GpuMemoryBuffer::Format format
);
430 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
432 gfx::OverlayTransform transform
,
433 const gfx::Rect
& bounds_rect
,
434 const gfx::RectF
& crop_rect
) override
;
437 ~SurfaceImage() override
;
439 scoped_refptr
<ui::NativePixmap
> pixmap_
;
442 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override
;
444 void BindFramebuffer();
445 bool CreatePixmaps();
449 scoped_refptr
<GLImage
> images_
[2];
450 int current_surface_
;
451 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl
);
454 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::SurfaceImage(
455 const gfx::Size
& size
,
456 unsigned internalformat
)
457 : GLImageLinuxDMABuffer(size
, internalformat
) {
460 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::Initialize(
461 scoped_refptr
<ui::NativePixmap
> pixmap
,
462 gfx::GpuMemoryBuffer::Format format
) {
463 base::FileDescriptor
handle(pixmap
->GetDmaBufFd(), false);
464 if (!GLImageLinuxDMABuffer::Initialize(handle
, format
,
465 pixmap
->GetDmaBufPitch()))
470 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::ScheduleOverlayPlane(
471 gfx::AcceleratedWidget widget
,
473 gfx::OverlayTransform transform
,
474 const gfx::Rect
& bounds_rect
,
475 const gfx::RectF
& crop_rect
) {
476 return ui::SurfaceFactoryOzone::GetInstance()->ScheduleOverlayPlane(
477 widget
, z_order
, transform
, pixmap_
, bounds_rect
, crop_rect
);
480 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::~SurfaceImage() {
483 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl(
484 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
485 AcceleratedWidget widget
)
486 : GLSurfaceOzoneSurfaceless(ozone_surface
.Pass(), widget
),
488 current_surface_(0) {
489 for (auto& texture
: textures_
)
494 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() {
498 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext
* context
) {
500 glGenFramebuffersEXT(1, &fbo_
);
503 glGenTextures(arraysize(textures_
), textures_
);
504 if (!CreatePixmaps())
508 glBindFramebufferEXT(GL_FRAMEBUFFER
, fbo_
);
509 return SurfacelessEGL::OnMakeCurrent(context
);
512 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size
& size
) {
513 if (size
== GetSize())
515 return GLSurfaceOzoneSurfaceless::Resize(size
) && CreatePixmaps();
518 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() {
522 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() {
523 if (!images_
[current_surface_
]->ScheduleOverlayPlane(
524 widget_
, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE
,
525 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
527 if (!GLSurfaceOzoneSurfaceless::SwapBuffers())
529 current_surface_
^= 1;
534 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync(
535 const SwapCompletionCallback
& callback
) {
536 if (!images_
[current_surface_
]->ScheduleOverlayPlane(
537 widget_
, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE
,
538 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
540 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback
))
542 current_surface_
^= 1;
547 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() {
548 GLContext
* current_context
= GLContext::GetCurrent();
549 DCHECK(current_context
&& current_context
->IsCurrent(this));
550 glBindFramebufferEXT(GL_FRAMEBUFFER
, 0);
552 glDeleteTextures(arraysize(textures_
), textures_
);
553 for (auto& texture
: textures_
)
555 glDeleteFramebuffersEXT(1, &fbo_
);
558 for (auto image
: images_
) {
560 image
->Destroy(true);
564 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() {
566 for (size_t i
= 0; i
< arraysize(textures_
); i
++)
567 DCHECK(!textures_
[i
]) << "texture " << i
<< " not released";
570 void GLSurfaceOzoneSurfacelessSurfaceImpl::BindFramebuffer() {
571 ScopedFrameBufferBinder
fb(fbo_
);
572 glFramebufferTexture2DEXT(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
,
573 textures_
[current_surface_
], 0);
576 bool GLSurfaceOzoneSurfacelessSurfaceImpl::CreatePixmaps() {
579 for (size_t i
= 0; i
< arraysize(textures_
); i
++) {
580 scoped_refptr
<ui::NativePixmap
> pixmap
=
581 ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap(
582 widget_
, GetSize(), ui::SurfaceFactoryOzone::BGRA_8888
,
583 ui::SurfaceFactoryOzone::SCANOUT
);
586 scoped_refptr
<SurfaceImage
> image
=
587 new SurfaceImage(GetSize(), GL_BGRA_EXT
);
588 if (!image
->Initialize(pixmap
, gfx::GpuMemoryBuffer::Format::BGRA_8888
))
591 // Bind image to texture.
592 ScopedTextureBinder
binder(GL_TEXTURE_2D
, textures_
[i
]);
593 if (!images_
[i
]->BindTexImage(GL_TEXTURE_2D
))
602 bool GLSurface::InitializeOneOffInternal() {
603 switch (GetGLImplementation()) {
604 case kGLImplementationEGLGLES2
:
605 if (!GLSurfaceEGL::InitializeOneOff()) {
606 LOG(ERROR
) << "GLSurfaceEGL::InitializeOneOff failed.";
611 case kGLImplementationOSMesaGL
:
612 case kGLImplementationMockGL
:
620 scoped_refptr
<GLSurface
> GLSurface::CreateSurfacelessViewGLSurface(
621 gfx::AcceleratedWidget window
) {
622 if (GetGLImplementation() == kGLImplementationEGLGLES2
&&
623 window
!= kNullAcceleratedWidget
&&
624 GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
625 ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) {
626 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
627 ui::SurfaceFactoryOzone::GetInstance()
628 ->CreateSurfacelessEGLSurfaceForWidget(window
);
631 scoped_refptr
<GLSurface
> surface
;
632 surface
= new GLSurfaceOzoneSurfaceless(surface_ozone
.Pass(), window
);
633 if (surface
->Initialize())
641 scoped_refptr
<GLSurface
> GLSurface::CreateViewGLSurface(
642 gfx::AcceleratedWidget window
) {
643 if (GetGLImplementation() == kGLImplementationOSMesaGL
) {
644 scoped_refptr
<GLSurface
> surface(new GLSurfaceOSMesaHeadless());
645 if (!surface
->Initialize())
649 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2
);
650 if (window
!= kNullAcceleratedWidget
) {
651 scoped_refptr
<GLSurface
> surface
;
652 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
653 ui::SurfaceFactoryOzone::GetInstance()
654 ->CanShowPrimaryPlaneAsOverlay()) {
655 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
656 ui::SurfaceFactoryOzone::GetInstance()
657 ->CreateSurfacelessEGLSurfaceForWidget(window
);
660 surface
= new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone
.Pass(),
663 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
664 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
669 surface
= new GLSurfaceOzoneEGL(surface_ozone
.Pass(), window
);
671 if (!surface
->Initialize())
675 scoped_refptr
<GLSurface
> surface
= new GLSurfaceStub();
676 if (surface
->Initialize())
683 scoped_refptr
<GLSurface
> GLSurface::CreateOffscreenGLSurface(
684 const gfx::Size
& size
) {
685 switch (GetGLImplementation()) {
686 case kGLImplementationOSMesaGL
: {
687 scoped_refptr
<GLSurface
> surface(
688 new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA
, size
));
689 if (!surface
->Initialize())
694 case kGLImplementationEGLGLES2
: {
695 scoped_refptr
<GLSurface
> surface
;
696 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
697 (size
.width() == 0 && size
.height() == 0)) {
698 surface
= new SurfacelessEGL(size
);
700 surface
= new PbufferGLSurfaceEGL(size
);
702 if (!surface
->Initialize())
706 case kGLImplementationMockGL
:
707 return new GLSurfaceStub
;
714 EGLNativeDisplayType
GetPlatformDefaultEGLNativeDisplay() {
715 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();