Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / gl / gl_surface_ozone.cc
blob50a7326f66fb9acdd769248ceeb1ad1fc6748ec6
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"
7 #include "base/bind.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"
30 namespace gfx {
32 namespace {
34 void WaitForFence(EGLDisplay display, EGLSyncKHR fence) {
35 eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
36 EGL_FOREVER_KHR);
39 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow
40 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL {
41 public:
42 GLSurfaceOzoneEGL(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
43 AcceleratedWidget widget);
45 // GLSurface:
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,
51 GLImage* image,
52 const Rect& bounds_rect,
53 const RectF& crop_rect) override;
55 private:
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()),
74 widget_(widget) {
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))
85 return false;
88 return NativeViewGLSurfaceEGL::Resize(size);
91 gfx::SwapResult GLSurfaceOzoneEGL::SwapBuffers() {
92 gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers();
93 if (result != gfx::SwapResult::SWAP_ACK)
94 return result;
96 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
97 : gfx::SwapResult::SWAP_FAILED;
100 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order,
101 OverlayTransform transform,
102 GLImage* image,
103 const Rect& bounds_rect,
104 const RectF& crop_rect) {
105 return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect,
106 crop_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);
117 if (was_current) {
118 scoped_make_current.reset(new ui::ScopedMakeCurrent(current_context, this));
121 Destroy();
122 ozone_surface_ = ui::OzonePlatform::GetInstance()
123 ->GetSurfaceFactoryOzone()
124 ->CreateEGLSurfaceForWidget(widget_)
125 .Pass();
126 if (!ozone_surface_) {
127 LOG(ERROR) << "Failed to create native surface.";
128 return false;
131 window_ = ozone_surface_->GetNativeWindow();
132 if (!Initialize()) {
133 LOG(ERROR) << "Failed to initialize.";
134 return false;
137 return true;
140 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
141 public:
142 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
143 AcceleratedWidget widget);
145 // GLSurface:
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,
151 GLImage* image,
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,
160 int y,
161 int width,
162 int height,
163 const SwapCompletionCallback& callback) override;
165 protected:
166 struct Overlay {
167 Overlay(int z_order,
168 OverlayTransform transform,
169 GLImage* image,
170 const Rect& bounds_rect,
171 const RectF& crop_rect);
173 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget) const;
175 int z_order;
176 OverlayTransform transform;
177 scoped_refptr<GLImage> image;
178 Rect bounds_rect;
179 RectF crop_rect;
182 struct PendingFrame {
183 PendingFrame();
185 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget);
187 bool ready;
188 std::vector<Overlay> overlays;
189 SwapCompletionCallback callback;
192 ~GLSurfaceOzoneSurfaceless() override;
194 void SubmitFrame();
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,
218 GLImage* image,
219 const Rect& bounds_rect,
220 const RectF& crop_rect)
221 : z_order(z_order),
222 transform(transform),
223 image(image),
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,
231 crop_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))
241 return false;
242 return true;
245 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless(
246 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
247 AcceleratedWidget widget)
248 : SurfacelessEGL(gfx::Size()),
249 ozone_surface_(ozone_surface.Pass()),
250 widget_(widget),
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())
261 return false;
262 vsync_provider_ = ozone_surface_->CreateVSyncProvider();
263 if (!vsync_provider_)
264 return false;
265 return true;
267 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size) {
268 if (!ozone_surface_->ResizeNativeWindow(size))
269 return false;
271 return SurfacelessEGL::Resize(size);
273 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() {
274 glFlush();
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();
279 if (!fence)
280 return SwapResult::SWAP_FAILED;
282 EGLDisplay display = GetDisplay();
283 WaitForFence(display, fence);
284 eglDestroySyncKHR(display, fence);
285 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
286 glFinish();
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,
297 GLImage* image,
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));
302 return true;
304 bool GLSurfaceOzoneSurfaceless::IsOffscreen() {
305 return false;
307 VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() {
308 return vsync_provider_.get();
310 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() {
311 return true;
313 gfx::SwapResult GLSurfaceOzoneSurfaceless::PostSubBuffer(int x,
314 int y,
315 int width,
316 int height) {
317 // The actual sub buffer handling is handled at higher layers.
318 SwapBuffers();
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_)
325 return false;
327 glFlush();
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();
341 if (!fence)
342 return false;
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);
353 return true;
354 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
355 glFinish();
358 frame->ready = true;
359 SubmitFrame();
360 return last_swap_buffers_result_;
362 bool GLSurfaceOzoneSurfaceless::PostSubBufferAsync(
363 int x,
364 int y,
365 int width,
366 int height,
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,
392 EGL_NONE};
393 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
396 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence,
397 PendingFrame* frame) {
398 eglDestroySyncKHR(GetDisplay(), fence);
399 frame->ready = true;
400 SubmitFrame();
403 void GLSurfaceOzoneSurfaceless::SwapCompleted(
404 const SwapCompletionCallback& callback,
405 gfx::SwapResult result) {
406 callback.Run(result);
407 swap_buffers_pending_ = false;
409 SubmitFrame();
412 // This provides surface-like semantics implemented through surfaceless.
413 // A framebuffer is bound automatically.
414 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
415 : public GLSurfaceOzoneSurfaceless {
416 public:
417 GLSurfaceOzoneSurfacelessSurfaceImpl(
418 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
419 AcceleratedWidget widget);
421 // GLSurface:
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;
430 private:
431 class SurfaceImage : public GLImageLinuxDMABuffer {
432 public:
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,
438 int z_order,
439 gfx::OverlayTransform transform,
440 const gfx::Rect& bounds_rect,
441 const gfx::RectF& crop_rect) override;
443 private:
444 ~SurfaceImage() override;
446 scoped_refptr<ui::NativePixmap> pixmap_;
449 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override;
451 void BindFramebuffer();
452 bool CreatePixmaps();
454 GLuint fbo_;
455 GLuint textures_[2];
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()))
473 return false;
474 pixmap_ = pixmap;
475 return true;
477 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::ScheduleOverlayPlane(
478 gfx::AcceleratedWidget widget,
479 int z_order,
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,
484 crop_rect);
487 GLSurfaceOzoneSurfacelessSurfaceImpl::SurfaceImage::~SurfaceImage() {
490 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl(
491 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
492 AcceleratedWidget widget)
493 : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget),
494 fbo_(0),
495 current_surface_(0) {
496 for (auto& texture : textures_)
497 texture = 0;
500 unsigned int
501 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() {
502 return fbo_;
505 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext* context) {
506 if (!fbo_) {
507 glGenFramebuffersEXT(1, &fbo_);
508 if (!fbo_)
509 return false;
510 glGenTextures(arraysize(textures_), textures_);
511 if (!CreatePixmaps())
512 return false;
514 BindFramebuffer();
515 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
516 return SurfacelessEGL::OnMakeCurrent(context);
519 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size) {
520 if (size == GetSize())
521 return true;
522 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps();
525 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() {
526 return false;
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)
536 return result;
537 current_surface_ ^= 1;
538 BindFramebuffer();
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)))
547 return false;
548 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback))
549 return false;
550 current_surface_ ^= 1;
551 BindFramebuffer();
552 return true;
555 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() {
556 GLContext* current_context = GLContext::GetCurrent();
557 DCHECK(current_context && current_context->IsCurrent(this));
558 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
559 if (fbo_) {
560 glDeleteTextures(arraysize(textures_), textures_);
561 for (auto& texture : textures_)
562 texture = 0;
563 glDeleteFramebuffersEXT(1, &fbo_);
564 fbo_ = 0;
566 for (auto image : images_) {
567 if (image)
568 image->Destroy(true);
572 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() {
573 DCHECK(!fbo_);
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() {
585 if (!fbo_)
586 return true;
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);
594 if (!pixmap)
595 return false;
596 scoped_refptr<SurfaceImage> image =
597 new SurfaceImage(GetSize(), GL_BGRA_EXT);
598 if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888))
599 return false;
600 images_[i] = image;
601 // Bind image to texture.
602 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]);
603 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
604 return false;
606 return true;
609 } // namespace
611 // static
612 bool GLSurface::InitializeOneOffInternal() {
613 switch (GetGLImplementation()) {
614 case kGLImplementationEGLGLES2:
615 if (!GLSurfaceEGL::InitializeOneOff()) {
616 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
617 return false;
620 return true;
621 case kGLImplementationOSMesaGL:
622 case kGLImplementationMockGL:
623 return true;
624 default:
625 return false;
629 // static
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);
642 if (!surface_ozone)
643 return nullptr;
644 scoped_refptr<GLSurface> surface;
645 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window);
646 if (surface->Initialize())
647 return surface;
650 return nullptr;
653 // static
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())
659 return NULL;
660 return surface;
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);
673 if (!surface_ozone)
674 return NULL;
675 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(),
676 window);
677 } else {
678 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
679 ui::OzonePlatform::GetInstance()
680 ->GetSurfaceFactoryOzone()
681 ->CreateEGLSurfaceForWidget(window);
682 if (!surface_ozone)
683 return NULL;
685 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window);
687 if (!surface->Initialize())
688 return NULL;
689 return surface;
690 } else {
691 scoped_refptr<GLSurface> surface = new GLSurfaceStub();
692 if (surface->Initialize())
693 return surface;
695 return NULL;
698 // static
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())
706 return NULL;
708 return surface;
710 case kGLImplementationEGLGLES2: {
711 scoped_refptr<GLSurface> surface;
712 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
713 (size.width() == 0 && size.height() == 0)) {
714 surface = new SurfacelessEGL(size);
715 } else
716 surface = new PbufferGLSurfaceEGL(size);
718 if (!surface->Initialize())
719 return NULL;
720 return surface;
722 case kGLImplementationMockGL:
723 return new GLSurfaceStub;
724 default:
725 NOTREACHED();
726 return NULL;
730 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
731 return ui::OzonePlatform::GetInstance()
732 ->GetSurfaceFactoryOzone()
733 ->GetNativeDisplay();
736 } // namespace gfx