Let Custom Tabs Use Light Progressbar for Dark Toolbar
[chromium-blink-merge.git] / ui / gl / gl_surface_ozone.cc
blob04fc760d366fbe8d248bc5363ce6e5d5a60ef0a5
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_ozone_native_pixmap.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) {}
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))
84 return false;
87 return NativeViewGLSurfaceEGL::Resize(size);
90 gfx::SwapResult GLSurfaceOzoneEGL::SwapBuffers() {
91 gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers();
92 if (result != gfx::SwapResult::SWAP_ACK)
93 return result;
95 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
96 : gfx::SwapResult::SWAP_FAILED;
99 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order,
100 OverlayTransform transform,
101 GLImage* image,
102 const Rect& bounds_rect,
103 const RectF& crop_rect) {
104 return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect,
105 crop_rect);
108 GLSurfaceOzoneEGL::~GLSurfaceOzoneEGL() {
109 Destroy(); // The EGL surface must be destroyed before SurfaceOzone.
112 bool GLSurfaceOzoneEGL::ReinitializeNativeSurface() {
113 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
114 GLContext* current_context = GLContext::GetCurrent();
115 bool was_current = current_context && current_context->IsCurrent(this);
116 if (was_current) {
117 scoped_make_current.reset(new ui::ScopedMakeCurrent(current_context, this));
120 Destroy();
121 ozone_surface_ = ui::OzonePlatform::GetInstance()
122 ->GetSurfaceFactoryOzone()
123 ->CreateEGLSurfaceForWidget(widget_);
124 if (!ozone_surface_) {
125 LOG(ERROR) << "Failed to create native surface.";
126 return false;
129 window_ = ozone_surface_->GetNativeWindow();
130 if (!Initialize()) {
131 LOG(ERROR) << "Failed to initialize.";
132 return false;
135 return true;
138 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
139 public:
140 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
141 AcceleratedWidget widget);
143 // GLSurface:
144 bool Initialize() override;
145 bool Resize(const gfx::Size& size) override;
146 gfx::SwapResult SwapBuffers() override;
147 bool ScheduleOverlayPlane(int z_order,
148 OverlayTransform transform,
149 GLImage* image,
150 const Rect& bounds_rect,
151 const RectF& crop_rect) override;
152 bool IsOffscreen() override;
153 VSyncProvider* GetVSyncProvider() override;
154 bool SupportsPostSubBuffer() override;
155 gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override;
156 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override;
157 bool PostSubBufferAsync(int x,
158 int y,
159 int width,
160 int height,
161 const SwapCompletionCallback& callback) override;
163 protected:
164 struct Overlay {
165 Overlay(int z_order,
166 OverlayTransform transform,
167 GLImage* image,
168 const Rect& bounds_rect,
169 const RectF& crop_rect);
171 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget) const;
173 int z_order;
174 OverlayTransform transform;
175 scoped_refptr<GLImage> image;
176 Rect bounds_rect;
177 RectF crop_rect;
180 struct PendingFrame {
181 PendingFrame();
183 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget);
185 bool ready;
186 std::vector<Overlay> overlays;
187 SwapCompletionCallback callback;
190 ~GLSurfaceOzoneSurfaceless() override;
192 void SubmitFrame();
194 EGLSyncKHR InsertFence();
195 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame);
197 void SwapCompleted(const SwapCompletionCallback& callback,
198 gfx::SwapResult result);
200 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
201 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
202 AcceleratedWidget widget_;
203 scoped_ptr<VSyncProvider> vsync_provider_;
204 ScopedVector<PendingFrame> unsubmitted_frames_;
205 bool has_implicit_external_sync_;
206 bool last_swap_buffers_result_;
207 bool swap_buffers_pending_;
209 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_;
211 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
214 GLSurfaceOzoneSurfaceless::Overlay::Overlay(int z_order,
215 OverlayTransform transform,
216 GLImage* image,
217 const Rect& bounds_rect,
218 const RectF& crop_rect)
219 : z_order(z_order),
220 transform(transform),
221 image(image),
222 bounds_rect(bounds_rect),
223 crop_rect(crop_rect) {}
225 bool GLSurfaceOzoneSurfaceless::Overlay::ScheduleOverlayPlane(
226 gfx::AcceleratedWidget widget) const {
227 return image->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect,
228 crop_rect);
231 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {}
233 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes(
234 gfx::AcceleratedWidget widget) {
235 for (const auto& overlay : overlays)
236 if (!overlay.ScheduleOverlayPlane(widget))
237 return false;
238 return true;
241 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless(
242 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
243 AcceleratedWidget widget)
244 : SurfacelessEGL(gfx::Size()),
245 ozone_surface_(ozone_surface.Pass()),
246 widget_(widget),
247 has_implicit_external_sync_(
248 HasEGLExtension("EGL_ARM_implicit_external_sync")),
249 last_swap_buffers_result_(true),
250 swap_buffers_pending_(false),
251 weak_factory_(this) {
252 unsubmitted_frames_.push_back(new PendingFrame());
255 bool GLSurfaceOzoneSurfaceless::Initialize() {
256 if (!SurfacelessEGL::Initialize())
257 return false;
258 vsync_provider_ = ozone_surface_->CreateVSyncProvider();
259 if (!vsync_provider_)
260 return false;
261 return true;
264 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size) {
265 if (!ozone_surface_->ResizeNativeWindow(size))
266 return false;
268 return SurfacelessEGL::Resize(size);
271 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() {
272 glFlush();
273 // TODO: the following should be replaced by a per surface flush as it gets
274 // implemented in GL drivers.
275 if (has_implicit_external_sync_) {
276 EGLSyncKHR fence = InsertFence();
277 if (!fence)
278 return SwapResult::SWAP_FAILED;
280 EGLDisplay display = GetDisplay();
281 WaitForFence(display, fence);
282 eglDestroySyncKHR(display, fence);
283 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
284 glFinish();
287 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_);
288 unsubmitted_frames_.back()->overlays.clear();
290 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
291 : gfx::SwapResult::SWAP_FAILED;
294 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(int z_order,
295 OverlayTransform transform,
296 GLImage* image,
297 const Rect& bounds_rect,
298 const RectF& crop_rect) {
299 unsubmitted_frames_.back()->overlays.push_back(
300 Overlay(z_order, transform, image, bounds_rect, crop_rect));
301 return true;
304 bool GLSurfaceOzoneSurfaceless::IsOffscreen() {
305 return false;
308 VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() {
309 return vsync_provider_.get();
312 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() {
313 return true;
316 gfx::SwapResult GLSurfaceOzoneSurfaceless::PostSubBuffer(int x,
317 int y,
318 int width,
319 int height) {
320 // The actual sub buffer handling is handled at higher layers.
321 SwapBuffers();
322 return gfx::SwapResult::SWAP_ACK;
325 bool GLSurfaceOzoneSurfaceless::SwapBuffersAsync(
326 const SwapCompletionCallback& callback) {
327 // If last swap failed, don't try to schedule new ones.
328 if (!last_swap_buffers_result_)
329 return false;
331 glFlush();
333 SwapCompletionCallback surface_swap_callback =
334 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted,
335 weak_factory_.GetWeakPtr(), callback);
337 PendingFrame* frame = unsubmitted_frames_.back();
338 frame->callback = surface_swap_callback;
339 unsubmitted_frames_.push_back(new PendingFrame());
341 // TODO: the following should be replaced by a per surface flush as it gets
342 // implemented in GL drivers.
343 if (has_implicit_external_sync_) {
344 EGLSyncKHR fence = InsertFence();
345 if (!fence)
346 return false;
348 base::Closure fence_wait_task =
349 base::Bind(&WaitForFence, GetDisplay(), fence);
351 base::Closure fence_retired_callback =
352 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
353 weak_factory_.GetWeakPtr(), fence, frame);
355 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
356 fence_retired_callback, false);
357 return true;
358 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
359 glFinish();
362 frame->ready = true;
363 SubmitFrame();
364 return last_swap_buffers_result_;
367 bool GLSurfaceOzoneSurfaceless::PostSubBufferAsync(
368 int x,
369 int y,
370 int width,
371 int height,
372 const SwapCompletionCallback& callback) {
373 return SwapBuffersAsync(callback);
376 GLSurfaceOzoneSurfaceless::~GLSurfaceOzoneSurfaceless() {
377 Destroy(); // The EGL surface must be destroyed before SurfaceOzone.
380 void GLSurfaceOzoneSurfaceless::SubmitFrame() {
381 DCHECK(!unsubmitted_frames_.empty());
383 if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) {
384 scoped_ptr<PendingFrame> frame(unsubmitted_frames_.front());
385 unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin());
386 swap_buffers_pending_ = true;
388 last_swap_buffers_result_ =
389 frame->ScheduleOverlayPlanes(widget_) &&
390 ozone_surface_->OnSwapBuffersAsync(frame->callback);
394 EGLSyncKHR GLSurfaceOzoneSurfaceless::InsertFence() {
395 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR,
396 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM,
397 EGL_NONE};
398 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
401 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence,
402 PendingFrame* frame) {
403 eglDestroySyncKHR(GetDisplay(), fence);
404 frame->ready = true;
405 SubmitFrame();
408 void GLSurfaceOzoneSurfaceless::SwapCompleted(
409 const SwapCompletionCallback& callback,
410 gfx::SwapResult result) {
411 callback.Run(result);
412 swap_buffers_pending_ = false;
414 SubmitFrame();
417 // This provides surface-like semantics implemented through surfaceless.
418 // A framebuffer is bound automatically.
419 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
420 : public GLSurfaceOzoneSurfaceless {
421 public:
422 GLSurfaceOzoneSurfacelessSurfaceImpl(
423 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
424 AcceleratedWidget widget);
426 // GLSurface:
427 unsigned int GetBackingFrameBufferObject() override;
428 bool OnMakeCurrent(GLContext* context) override;
429 bool Resize(const gfx::Size& size) override;
430 bool SupportsPostSubBuffer() override;
431 gfx::SwapResult SwapBuffers() override;
432 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override;
433 void Destroy() override;
434 bool IsSurfaceless() const override;
436 private:
437 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override;
439 void BindFramebuffer();
440 bool CreatePixmaps();
442 scoped_refptr<GLContext> context_;
443 GLuint fbo_;
444 GLuint textures_[2];
445 scoped_refptr<GLImage> images_[2];
446 int current_surface_;
447 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl);
450 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl(
451 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
452 AcceleratedWidget widget)
453 : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget),
454 context_(nullptr),
455 fbo_(0),
456 current_surface_(0) {
457 for (auto& texture : textures_)
458 texture = 0;
461 unsigned int
462 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() {
463 return fbo_;
466 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext* context) {
467 DCHECK(!context_ || context == context_);
468 context_ = context;
469 if (!fbo_) {
470 glGenFramebuffersEXT(1, &fbo_);
471 if (!fbo_)
472 return false;
473 glGenTextures(arraysize(textures_), textures_);
474 if (!CreatePixmaps())
475 return false;
477 BindFramebuffer();
478 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
479 return SurfacelessEGL::OnMakeCurrent(context);
482 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size) {
483 if (size == GetSize())
484 return true;
485 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps();
488 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() {
489 return false;
492 gfx::SwapResult GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() {
493 if (!images_[current_surface_]->ScheduleOverlayPlane(
494 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
495 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
496 return gfx::SwapResult::SWAP_FAILED;
497 gfx::SwapResult result = GLSurfaceOzoneSurfaceless::SwapBuffers();
498 if (result != gfx::SwapResult::SWAP_ACK)
499 return result;
500 current_surface_ ^= 1;
501 BindFramebuffer();
502 return gfx::SwapResult::SWAP_ACK;
505 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync(
506 const SwapCompletionCallback& callback) {
507 if (!images_[current_surface_]->ScheduleOverlayPlane(
508 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
509 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
510 return false;
511 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback))
512 return false;
513 current_surface_ ^= 1;
514 BindFramebuffer();
515 return true;
518 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() {
519 if (!context_)
520 return;
521 ui::ScopedMakeCurrent context(context_.get(), this);
522 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
523 if (fbo_) {
524 glDeleteTextures(arraysize(textures_), textures_);
525 for (auto& texture : textures_)
526 texture = 0;
527 glDeleteFramebuffersEXT(1, &fbo_);
528 fbo_ = 0;
530 for (auto image : images_) {
531 if (image)
532 image->Destroy(true);
536 bool GLSurfaceOzoneSurfacelessSurfaceImpl::IsSurfaceless() const {
537 return false;
540 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() {
541 DCHECK(!fbo_);
542 for (size_t i = 0; i < arraysize(textures_); i++)
543 DCHECK(!textures_[i]) << "texture " << i << " not released";
546 void GLSurfaceOzoneSurfacelessSurfaceImpl::BindFramebuffer() {
547 ScopedFrameBufferBinder fb(fbo_);
548 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
549 textures_[current_surface_], 0);
552 bool GLSurfaceOzoneSurfacelessSurfaceImpl::CreatePixmaps() {
553 if (!fbo_)
554 return true;
555 for (size_t i = 0; i < arraysize(textures_); i++) {
556 scoped_refptr<ui::NativePixmap> pixmap =
557 ui::OzonePlatform::GetInstance()
558 ->GetSurfaceFactoryOzone()
559 ->CreateNativePixmap(widget_, GetSize(),
560 gfx::BufferFormat::BGRA_8888,
561 gfx::BufferUsage::SCANOUT);
562 if (!pixmap)
563 return false;
564 scoped_refptr<GLImageOzoneNativePixmap> image =
565 new GLImageOzoneNativePixmap(GetSize(), GL_BGRA_EXT);
566 if (!image->Initialize(pixmap.get(), gfx::BufferFormat::BGRA_8888))
567 return false;
568 images_[i] = image;
569 // Bind image to texture.
570 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]);
571 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
572 return false;
574 return true;
577 scoped_refptr<GLSurface> CreateViewGLSurfaceOzone(
578 gfx::AcceleratedWidget window) {
579 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
580 ui::OzonePlatform::GetInstance()
581 ->GetSurfaceFactoryOzone()
582 ->CreateEGLSurfaceForWidget(window);
583 if (!surface_ozone)
584 return nullptr;
585 scoped_refptr<GLSurface> surface =
586 new GLSurfaceOzoneEGL(surface_ozone.Pass(), window);
587 if (!surface->Initialize())
588 return nullptr;
589 return surface;
592 scoped_refptr<GLSurface> CreateViewGLSurfaceOzoneSurfacelessSurfaceImpl(
593 gfx::AcceleratedWidget window) {
594 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
595 ui::OzonePlatform::GetInstance()
596 ->GetSurfaceFactoryOzone()
597 ->CreateSurfacelessEGLSurfaceForWidget(window);
598 if (!surface_ozone)
599 return nullptr;
600 scoped_refptr<GLSurface> surface =
601 new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(), window);
602 if (!surface->Initialize())
603 return nullptr;
604 return surface;
607 } // namespace
609 // static
610 bool GLSurface::InitializeOneOffInternal() {
611 switch (GetGLImplementation()) {
612 case kGLImplementationEGLGLES2:
613 if (!GLSurfaceEGL::InitializeOneOff()) {
614 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
615 return false;
618 return true;
619 case kGLImplementationOSMesaGL:
620 case kGLImplementationMockGL:
621 return true;
622 default:
623 return false;
627 // static
628 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface(
629 gfx::AcceleratedWidget window) {
630 if (GetGLImplementation() == kGLImplementationEGLGLES2 &&
631 window != kNullAcceleratedWidget &&
632 GLSurfaceEGL::IsEGLSurfacelessContextSupported()) {
633 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
634 ui::OzonePlatform::GetInstance()
635 ->GetSurfaceFactoryOzone()
636 ->CreateSurfacelessEGLSurfaceForWidget(window);
637 if (!surface_ozone)
638 return nullptr;
639 scoped_refptr<GLSurface> surface;
640 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window);
641 if (surface->Initialize())
642 return surface;
645 return nullptr;
648 // static
649 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
650 gfx::AcceleratedWidget window) {
651 if (GetGLImplementation() == kGLImplementationOSMesaGL) {
652 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless());
653 if (!surface->Initialize())
654 return nullptr;
655 return surface;
657 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2);
658 if (window != kNullAcceleratedWidget) {
659 scoped_refptr<GLSurface> surface;
660 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported())
661 surface = CreateViewGLSurfaceOzoneSurfacelessSurfaceImpl(window);
662 if (!surface)
663 surface = CreateViewGLSurfaceOzone(window);
664 return surface;
665 } else {
666 scoped_refptr<GLSurface> surface = new GLSurfaceStub();
667 if (surface->Initialize())
668 return surface;
670 return nullptr;
673 // static
674 scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(
675 const gfx::Size& size) {
676 switch (GetGLImplementation()) {
677 case kGLImplementationOSMesaGL: {
678 scoped_refptr<GLSurface> surface(
679 new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, size));
680 if (!surface->Initialize())
681 return nullptr;
683 return surface;
685 case kGLImplementationEGLGLES2: {
686 scoped_refptr<GLSurface> surface;
687 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
688 (size.width() == 0 && size.height() == 0)) {
689 surface = new SurfacelessEGL(size);
690 } else
691 surface = new PbufferGLSurfaceEGL(size);
693 if (!surface->Initialize())
694 return nullptr;
695 return surface;
697 case kGLImplementationMockGL:
698 return new GLSurfaceStub;
699 default:
700 NOTREACHED();
701 return nullptr;
705 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
706 return ui::OzonePlatform::GetInstance()
707 ->GetSurfaceFactoryOzone()
708 ->GetNativeDisplay();
711 } // namespace gfx