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/ozone_platform.h"
27 #include "ui/ozone/public/surface_factory_ozone.h"
28 #include "ui/ozone/public/surface_ozone_egl.h"
34 void WaitForFence(EGLDisplay display
, EGLSyncKHR fence
) {
35 eglClientWaitSyncKHR(display
, fence
, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR
,
39 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow
40 class GL_EXPORT GLSurfaceOzoneEGL
: public NativeViewGLSurfaceEGL
{
42 GLSurfaceOzoneEGL(scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
43 AcceleratedWidget widget
);
46 bool Initialize() override
;
47 bool Resize(const gfx::Size
& size
) override
;
48 gfx::SwapResult
SwapBuffers() override
;
49 bool ScheduleOverlayPlane(int z_order
,
50 OverlayTransform transform
,
52 const Rect
& bounds_rect
,
53 const RectF
& crop_rect
) override
;
56 using NativeViewGLSurfaceEGL::Initialize
;
58 ~GLSurfaceOzoneEGL() override
;
60 bool ReinitializeNativeSurface();
62 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
63 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface_
;
64 AcceleratedWidget widget_
;
66 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL
);
69 GLSurfaceOzoneEGL::GLSurfaceOzoneEGL(
70 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
71 AcceleratedWidget widget
)
72 : NativeViewGLSurfaceEGL(ozone_surface
->GetNativeWindow()),
73 ozone_surface_(ozone_surface
.Pass()),
77 bool GLSurfaceOzoneEGL::Initialize() {
78 return Initialize(ozone_surface_
->CreateVSyncProvider());
81 bool GLSurfaceOzoneEGL::Resize(const gfx::Size
& size
) {
82 if (!ozone_surface_
->ResizeNativeWindow(size
)) {
83 if (!ReinitializeNativeSurface() ||
84 !ozone_surface_
->ResizeNativeWindow(size
))
88 return NativeViewGLSurfaceEGL::Resize(size
);
91 gfx::SwapResult
GLSurfaceOzoneEGL::SwapBuffers() {
92 gfx::SwapResult result
= NativeViewGLSurfaceEGL::SwapBuffers();
93 if (result
!= gfx::SwapResult::SWAP_ACK
)
96 return ozone_surface_
->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
97 : gfx::SwapResult::SWAP_FAILED
;
100 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order
,
101 OverlayTransform transform
,
103 const Rect
& bounds_rect
,
104 const RectF
& crop_rect
) {
105 return image
->ScheduleOverlayPlane(widget_
, z_order
, transform
, bounds_rect
,
109 GLSurfaceOzoneEGL::~GLSurfaceOzoneEGL() {
110 Destroy(); // EGL surface must be destroyed before SurfaceOzone
113 bool GLSurfaceOzoneEGL::ReinitializeNativeSurface() {
114 scoped_ptr
<ui::ScopedMakeCurrent
> scoped_make_current
;
115 GLContext
* current_context
= GLContext::GetCurrent();
116 bool was_current
= current_context
&& current_context
->IsCurrent(this);
118 scoped_make_current
.reset(new ui::ScopedMakeCurrent(current_context
, this));
122 ozone_surface_
= ui::OzonePlatform::GetInstance()
123 ->GetSurfaceFactoryOzone()
124 ->CreateEGLSurfaceForWidget(widget_
)
126 if (!ozone_surface_
) {
127 LOG(ERROR
) << "Failed to create native surface.";
131 window_
= ozone_surface_
->GetNativeWindow();
133 LOG(ERROR
) << "Failed to initialize.";
140 class GL_EXPORT GLSurfaceOzoneSurfaceless
: public SurfacelessEGL
{
142 GLSurfaceOzoneSurfaceless(scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
143 AcceleratedWidget widget
);
146 bool Initialize() override
;
147 bool Resize(const gfx::Size
& size
) override
;
148 gfx::SwapResult
SwapBuffers() override
;
149 bool ScheduleOverlayPlane(int z_order
,
150 OverlayTransform transform
,
152 const Rect
& bounds_rect
,
153 const RectF
& crop_rect
) override
;
154 bool IsOffscreen() override
;
155 VSyncProvider
* GetVSyncProvider() override
;
156 bool SupportsPostSubBuffer() override
;
157 gfx::SwapResult
PostSubBuffer(int x
, int y
, int width
, int height
) override
;
158 bool SwapBuffersAsync(const SwapCompletionCallback
& callback
) override
;
159 bool PostSubBufferAsync(int x
,
163 const SwapCompletionCallback
& callback
) override
;
168 OverlayTransform transform
,
170 const Rect
& bounds_rect
,
171 const RectF
& crop_rect
);
173 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget
) const;
176 OverlayTransform transform
;
177 scoped_refptr
<GLImage
> image
;
182 struct PendingFrame
{
185 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget
);
188 std::vector
<Overlay
> overlays
;
189 SwapCompletionCallback callback
;
192 ~GLSurfaceOzoneSurfaceless() override
;
196 EGLSyncKHR
InsertFence();
197 void FenceRetired(EGLSyncKHR fence
, PendingFrame
* frame
);
199 void SwapCompleted(const SwapCompletionCallback
& callback
,
200 gfx::SwapResult result
);
202 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
203 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface_
;
204 AcceleratedWidget widget_
;
205 scoped_ptr
<VSyncProvider
> vsync_provider_
;
206 ScopedVector
<PendingFrame
> unsubmitted_frames_
;
207 bool has_implicit_external_sync_
;
208 bool last_swap_buffers_result_
;
209 bool swap_buffers_pending_
;
211 base::WeakPtrFactory
<GLSurfaceOzoneSurfaceless
> weak_factory_
;
213 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless
);
216 GLSurfaceOzoneSurfaceless::Overlay::Overlay(int z_order
,
217 OverlayTransform transform
,
219 const Rect
& bounds_rect
,
220 const RectF
& crop_rect
)
222 transform(transform
),
224 bounds_rect(bounds_rect
),
225 crop_rect(crop_rect
) {
228 bool GLSurfaceOzoneSurfaceless::Overlay::ScheduleOverlayPlane(
229 gfx::AcceleratedWidget widget
) const {
230 return image
->ScheduleOverlayPlane(widget
, z_order
, transform
, bounds_rect
,
234 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {
237 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes(
238 gfx::AcceleratedWidget widget
) {
239 for (const auto& overlay
: overlays
)
240 if (!overlay
.ScheduleOverlayPlane(widget
))
245 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless(
246 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
247 AcceleratedWidget widget
)
248 : SurfacelessEGL(gfx::Size()),
249 ozone_surface_(ozone_surface
.Pass()),
251 has_implicit_external_sync_(
252 HasEGLExtension("EGL_ARM_implicit_external_sync")),
253 last_swap_buffers_result_(true),
254 swap_buffers_pending_(false),
255 weak_factory_(this) {
256 unsubmitted_frames_
.push_back(new PendingFrame());
259 bool GLSurfaceOzoneSurfaceless::Initialize() {
260 if (!SurfacelessEGL::Initialize())
262 vsync_provider_
= ozone_surface_
->CreateVSyncProvider();
263 if (!vsync_provider_
)
267 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size
& size
) {
268 if (!ozone_surface_
->ResizeNativeWindow(size
))
271 return SurfacelessEGL::Resize(size
);
273 gfx::SwapResult
GLSurfaceOzoneSurfaceless::SwapBuffers() {
275 // TODO: the following should be replaced by a per surface flush as it gets
276 // implemented in GL drivers.
277 if (has_implicit_external_sync_
) {
278 EGLSyncKHR fence
= InsertFence();
280 return SwapResult::SWAP_FAILED
;
282 EGLDisplay display
= GetDisplay();
283 WaitForFence(display
, fence
);
284 eglDestroySyncKHR(display
, fence
);
285 } else if (ozone_surface_
->IsUniversalDisplayLinkDevice()) {
289 unsubmitted_frames_
.back()->ScheduleOverlayPlanes(widget_
);
290 unsubmitted_frames_
.back()->overlays
.clear();
292 return ozone_surface_
->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
293 : gfx::SwapResult::SWAP_FAILED
;
295 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(int z_order
,
296 OverlayTransform transform
,
298 const Rect
& bounds_rect
,
299 const RectF
& crop_rect
) {
300 unsubmitted_frames_
.back()->overlays
.push_back(
301 Overlay(z_order
, transform
, image
, bounds_rect
, crop_rect
));
304 bool GLSurfaceOzoneSurfaceless::IsOffscreen() {
307 VSyncProvider
* GLSurfaceOzoneSurfaceless::GetVSyncProvider() {
308 return vsync_provider_
.get();
310 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() {
313 gfx::SwapResult
GLSurfaceOzoneSurfaceless::PostSubBuffer(int x
,
317 // The actual sub buffer handling is handled at higher layers.
319 return gfx::SwapResult::SWAP_ACK
;
321 bool GLSurfaceOzoneSurfaceless::SwapBuffersAsync(
322 const SwapCompletionCallback
& callback
) {
323 // If last swap failed, don't try to schedule new ones.
324 if (!last_swap_buffers_result_
)
329 SwapCompletionCallback surface_swap_callback
=
330 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted
,
331 weak_factory_
.GetWeakPtr(), callback
);
333 PendingFrame
* frame
= unsubmitted_frames_
.back();
334 frame
->callback
= surface_swap_callback
;
335 unsubmitted_frames_
.push_back(new PendingFrame());
337 // TODO: the following should be replaced by a per surface flush as it gets
338 // implemented in GL drivers.
339 if (has_implicit_external_sync_
) {
340 EGLSyncKHR fence
= InsertFence();
344 base::Closure fence_wait_task
=
345 base::Bind(&WaitForFence
, GetDisplay(), fence
);
347 base::Closure fence_retired_callback
=
348 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired
,
349 weak_factory_
.GetWeakPtr(), fence
, frame
);
351 base::WorkerPool::PostTaskAndReply(FROM_HERE
, fence_wait_task
,
352 fence_retired_callback
, false);
354 } else if (ozone_surface_
->IsUniversalDisplayLinkDevice()) {
360 return last_swap_buffers_result_
;
362 bool GLSurfaceOzoneSurfaceless::PostSubBufferAsync(
367 const SwapCompletionCallback
& callback
) {
368 return SwapBuffersAsync(callback
);
371 GLSurfaceOzoneSurfaceless::~GLSurfaceOzoneSurfaceless() {
372 Destroy(); // EGL surface must be destroyed before SurfaceOzone
375 void GLSurfaceOzoneSurfaceless::SubmitFrame() {
376 DCHECK(!unsubmitted_frames_
.empty());
378 if (unsubmitted_frames_
.front()->ready
&& !swap_buffers_pending_
) {
379 scoped_ptr
<PendingFrame
> frame(unsubmitted_frames_
.front());
380 unsubmitted_frames_
.weak_erase(unsubmitted_frames_
.begin());
381 swap_buffers_pending_
= true;
383 last_swap_buffers_result_
=
384 frame
->ScheduleOverlayPlanes(widget_
) &&
385 ozone_surface_
->OnSwapBuffersAsync(frame
->callback
);
389 EGLSyncKHR
GLSurfaceOzoneSurfaceless::InsertFence() {
390 const EGLint attrib_list
[] = {EGL_SYNC_CONDITION_KHR
,
391 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM
,
393 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR
, attrib_list
);
396 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence
,
397 PendingFrame
* frame
) {
398 eglDestroySyncKHR(GetDisplay(), fence
);
403 void GLSurfaceOzoneSurfaceless::SwapCompleted(
404 const SwapCompletionCallback
& callback
,
405 gfx::SwapResult result
) {
406 callback
.Run(result
);
407 swap_buffers_pending_
= false;
412 // This provides surface-like semantics implemented through surfaceless.
413 // A framebuffer is bound automatically.
414 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
415 : public GLSurfaceOzoneSurfaceless
{
417 GLSurfaceOzoneSurfacelessSurfaceImpl(
418 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
419 AcceleratedWidget widget
);
422 unsigned int GetBackingFrameBufferObject() override
;
423 bool OnMakeCurrent(GLContext
* context
) override
;
424 bool Resize(const gfx::Size
& size
) override
;
425 bool SupportsPostSubBuffer() override
;
426 gfx::SwapResult
SwapBuffers() override
;
427 bool SwapBuffersAsync(const SwapCompletionCallback
& callback
) override
;
428 void Destroy() override
;
431 class SurfaceImage
: public GLImageLinuxDMABuffer
{
433 SurfaceImage(const gfx::Size
& size
, unsigned internalformat
);
435 bool Initialize(scoped_refptr
<ui::NativePixmap
> pixmap
,
436 gfx::GpuMemoryBuffer::Format format
);
437 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
439 gfx::OverlayTransform transform
,
440 const gfx::Rect
& bounds_rect
,
441 const gfx::RectF
& crop_rect
) override
;
444 ~SurfaceImage() override
;
446 scoped_refptr
<ui::NativePixmap
> pixmap_
;
449 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override
;
451 void BindFramebuffer();
452 bool CreatePixmaps();
456 scoped_refptr
<GLImage
> images_
[2];
457 int current_surface_
;
458 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl
);
461 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::SurfaceImage(
462 const gfx::Size
& size
,
463 unsigned internalformat
)
464 : GLImageLinuxDMABuffer(size
, internalformat
) {
467 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::Initialize(
468 scoped_refptr
<ui::NativePixmap
> pixmap
,
469 gfx::GpuMemoryBuffer::Format format
) {
470 base::FileDescriptor
handle(pixmap
->GetDmaBufFd(), false);
471 if (!GLImageLinuxDMABuffer::Initialize(handle
, format
,
472 pixmap
->GetDmaBufPitch()))
477 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::ScheduleOverlayPlane(
478 gfx::AcceleratedWidget widget
,
480 gfx::OverlayTransform transform
,
481 const gfx::Rect
& bounds_rect
,
482 const gfx::RectF
& crop_rect
) {
483 return pixmap_
->ScheduleOverlayPlane(widget
, z_order
, transform
, bounds_rect
,
487 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::~SurfaceImage() {
490 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl(
491 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
492 AcceleratedWidget widget
)
493 : GLSurfaceOzoneSurfaceless(ozone_surface
.Pass(), widget
),
495 current_surface_(0) {
496 for (auto& texture
: textures_
)
501 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() {
505 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext
* context
) {
507 glGenFramebuffersEXT(1, &fbo_
);
510 glGenTextures(arraysize(textures_
), textures_
);
511 if (!CreatePixmaps())
515 glBindFramebufferEXT(GL_FRAMEBUFFER
, fbo_
);
516 return SurfacelessEGL::OnMakeCurrent(context
);
519 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size
& size
) {
520 if (size
== GetSize())
522 return GLSurfaceOzoneSurfaceless::Resize(size
) && CreatePixmaps();
525 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() {
529 gfx::SwapResult
GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() {
530 if (!images_
[current_surface_
]->ScheduleOverlayPlane(
531 widget_
, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE
,
532 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
533 return gfx::SwapResult::SWAP_FAILED
;
534 gfx::SwapResult result
= GLSurfaceOzoneSurfaceless::SwapBuffers();
535 if (result
!= gfx::SwapResult::SWAP_ACK
)
537 current_surface_
^= 1;
539 return gfx::SwapResult::SWAP_ACK
;
542 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync(
543 const SwapCompletionCallback
& callback
) {
544 if (!images_
[current_surface_
]->ScheduleOverlayPlane(
545 widget_
, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE
,
546 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
548 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback
))
550 current_surface_
^= 1;
555 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() {
556 GLContext
* current_context
= GLContext::GetCurrent();
557 DCHECK(current_context
&& current_context
->IsCurrent(this));
558 glBindFramebufferEXT(GL_FRAMEBUFFER
, 0);
560 glDeleteTextures(arraysize(textures_
), textures_
);
561 for (auto& texture
: textures_
)
563 glDeleteFramebuffersEXT(1, &fbo_
);
566 for (auto image
: images_
) {
568 image
->Destroy(true);
572 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() {
574 for (size_t i
= 0; i
< arraysize(textures_
); i
++)
575 DCHECK(!textures_
[i
]) << "texture " << i
<< " not released";
578 void GLSurfaceOzoneSurfacelessSurfaceImpl::BindFramebuffer() {
579 ScopedFrameBufferBinder
fb(fbo_
);
580 glFramebufferTexture2DEXT(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
,
581 textures_
[current_surface_
], 0);
584 bool GLSurfaceOzoneSurfacelessSurfaceImpl::CreatePixmaps() {
587 for (size_t i
= 0; i
< arraysize(textures_
); i
++) {
588 scoped_refptr
<ui::NativePixmap
> pixmap
=
589 ui::OzonePlatform::GetInstance()
590 ->GetSurfaceFactoryOzone()
591 ->CreateNativePixmap(widget_
, GetSize(),
592 ui::SurfaceFactoryOzone::BGRA_8888
,
593 ui::SurfaceFactoryOzone::SCANOUT
);
596 scoped_refptr
<SurfaceImage
> image
=
597 new SurfaceImage(GetSize(), GL_BGRA_EXT
);
598 if (!image
->Initialize(pixmap
, gfx::GpuMemoryBuffer::Format::BGRA_8888
))
601 // Bind image to texture.
602 ScopedTextureBinder
binder(GL_TEXTURE_2D
, textures_
[i
]);
603 if (!images_
[i
]->BindTexImage(GL_TEXTURE_2D
))
612 bool GLSurface::InitializeOneOffInternal() {
613 switch (GetGLImplementation()) {
614 case kGLImplementationEGLGLES2
:
615 if (!GLSurfaceEGL::InitializeOneOff()) {
616 LOG(ERROR
) << "GLSurfaceEGL::InitializeOneOff failed.";
621 case kGLImplementationOSMesaGL
:
622 case kGLImplementationMockGL
:
630 scoped_refptr
<GLSurface
> GLSurface::CreateSurfacelessViewGLSurface(
631 gfx::AcceleratedWidget window
) {
632 if (GetGLImplementation() == kGLImplementationEGLGLES2
&&
633 window
!= kNullAcceleratedWidget
&&
634 GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
635 ui::OzonePlatform::GetInstance()
636 ->GetSurfaceFactoryOzone()
637 ->CanShowPrimaryPlaneAsOverlay()) {
638 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
639 ui::OzonePlatform::GetInstance()
640 ->GetSurfaceFactoryOzone()
641 ->CreateSurfacelessEGLSurfaceForWidget(window
);
644 scoped_refptr
<GLSurface
> surface
;
645 surface
= new GLSurfaceOzoneSurfaceless(surface_ozone
.Pass(), window
);
646 if (surface
->Initialize())
654 scoped_refptr
<GLSurface
> GLSurface::CreateViewGLSurface(
655 gfx::AcceleratedWidget window
) {
656 if (GetGLImplementation() == kGLImplementationOSMesaGL
) {
657 scoped_refptr
<GLSurface
> surface(new GLSurfaceOSMesaHeadless());
658 if (!surface
->Initialize())
662 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2
);
663 if (window
!= kNullAcceleratedWidget
) {
664 scoped_refptr
<GLSurface
> surface
;
665 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
666 ui::OzonePlatform::GetInstance()
667 ->GetSurfaceFactoryOzone()
668 ->CanShowPrimaryPlaneAsOverlay()) {
669 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
670 ui::OzonePlatform::GetInstance()
671 ->GetSurfaceFactoryOzone()
672 ->CreateSurfacelessEGLSurfaceForWidget(window
);
675 surface
= new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone
.Pass(),
678 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
679 ui::OzonePlatform::GetInstance()
680 ->GetSurfaceFactoryOzone()
681 ->CreateEGLSurfaceForWidget(window
);
685 surface
= new GLSurfaceOzoneEGL(surface_ozone
.Pass(), window
);
687 if (!surface
->Initialize())
691 scoped_refptr
<GLSurface
> surface
= new GLSurfaceStub();
692 if (surface
->Initialize())
699 scoped_refptr
<GLSurface
> GLSurface::CreateOffscreenGLSurface(
700 const gfx::Size
& size
) {
701 switch (GetGLImplementation()) {
702 case kGLImplementationOSMesaGL
: {
703 scoped_refptr
<GLSurface
> surface(
704 new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA
, size
));
705 if (!surface
->Initialize())
710 case kGLImplementationEGLGLES2
: {
711 scoped_refptr
<GLSurface
> surface
;
712 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
713 (size
.width() == 0 && size
.height() == 0)) {
714 surface
= new SurfacelessEGL(size
);
716 surface
= new PbufferGLSurfaceEGL(size
);
718 if (!surface
->Initialize())
722 case kGLImplementationMockGL
:
723 return new GLSurfaceStub
;
730 EGLNativeDisplayType
GetPlatformDefaultEGLNativeDisplay() {
731 return ui::OzonePlatform::GetInstance()
732 ->GetSurfaceFactoryOzone()
733 ->GetNativeDisplay();