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/logging.h"
8 #include "base/memory/ref_counted.h"
9 #include "ui/gfx/native_widget_types.h"
10 #include "ui/gl/gl_context.h"
11 #include "ui/gl/gl_image.h"
12 #include "ui/gl/gl_implementation.h"
13 #include "ui/gl/gl_surface_egl.h"
14 #include "ui/gl/gl_surface_osmesa.h"
15 #include "ui/gl/gl_surface_stub.h"
16 #include "ui/gl/scoped_make_current.h"
17 #include "ui/ozone/public/surface_factory_ozone.h"
18 #include "ui/ozone/public/surface_ozone_egl.h"
24 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow
25 class GL_EXPORT GLSurfaceOzoneEGL
: public NativeViewGLSurfaceEGL
{
27 GLSurfaceOzoneEGL(scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
28 AcceleratedWidget widget
)
29 : NativeViewGLSurfaceEGL(ozone_surface
->GetNativeWindow()),
30 ozone_surface_(ozone_surface
.Pass()),
33 virtual bool Initialize() OVERRIDE
{
34 return Initialize(ozone_surface_
->CreateVSyncProvider());
36 virtual bool Resize(const gfx::Size
& size
) OVERRIDE
{
37 if (!ozone_surface_
->ResizeNativeWindow(size
)) {
38 if (!ReinitializeNativeSurface() ||
39 !ozone_surface_
->ResizeNativeWindow(size
))
43 return NativeViewGLSurfaceEGL::Resize(size
);
45 virtual bool SwapBuffers() OVERRIDE
{
46 if (!NativeViewGLSurfaceEGL::SwapBuffers())
49 return ozone_surface_
->OnSwapBuffers();
51 virtual bool ScheduleOverlayPlane(int z_order
,
52 OverlayTransform transform
,
54 const Rect
& bounds_rect
,
55 const RectF
& crop_rect
) OVERRIDE
{
56 return image
->ScheduleOverlayPlane(
57 widget_
, z_order
, transform
, bounds_rect
, crop_rect
);
61 using NativeViewGLSurfaceEGL::Initialize
;
63 virtual ~GLSurfaceOzoneEGL() {
64 Destroy(); // EGL surface must be destroyed before SurfaceOzone
67 bool ReinitializeNativeSurface() {
68 scoped_ptr
<ui::ScopedMakeCurrent
> scoped_make_current
;
69 GLContext
* current_context
= GLContext::GetCurrent();
71 current_context
&& current_context
->IsCurrent(this);
73 scoped_make_current
.reset(
74 new ui::ScopedMakeCurrent(current_context
, this));
79 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
81 if (!ozone_surface_
) {
82 LOG(ERROR
) << "Failed to create native surface.";
86 window_
= ozone_surface_
->GetNativeWindow();
88 LOG(ERROR
) << "Failed to initialize.";
95 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
96 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface_
;
97 AcceleratedWidget widget_
;
99 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL
);
102 class GL_EXPORT GLSurfaceOzoneSurfaceless
: public SurfacelessEGL
{
104 GLSurfaceOzoneSurfaceless(scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface
,
105 AcceleratedWidget widget
)
106 : SurfacelessEGL(gfx::Size()),
107 ozone_surface_(ozone_surface
.Pass()),
110 virtual bool Initialize() OVERRIDE
{
111 if (!SurfacelessEGL::Initialize())
113 vsync_provider_
= ozone_surface_
->CreateVSyncProvider();
114 if (!vsync_provider_
)
118 virtual bool Resize(const gfx::Size
& size
) OVERRIDE
{
119 if (!ozone_surface_
->ResizeNativeWindow(size
))
122 return SurfacelessEGL::Resize(size
);
124 virtual bool SwapBuffers() OVERRIDE
{
125 return ozone_surface_
->OnSwapBuffers();
127 virtual bool ScheduleOverlayPlane(int z_order
,
128 OverlayTransform transform
,
130 const Rect
& bounds_rect
,
131 const RectF
& crop_rect
) OVERRIDE
{
132 return image
->ScheduleOverlayPlane(
133 widget_
, z_order
, transform
, bounds_rect
, crop_rect
);
135 virtual bool IsOffscreen() OVERRIDE
{ return false; }
136 virtual VSyncProvider
* GetVSyncProvider() OVERRIDE
{
137 return vsync_provider_
.get();
141 virtual ~GLSurfaceOzoneSurfaceless() {
142 Destroy(); // EGL surface must be destroyed before SurfaceOzone
145 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
146 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface_
;
147 AcceleratedWidget widget_
;
148 scoped_ptr
<VSyncProvider
> vsync_provider_
;
150 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless
);
156 bool GLSurface::InitializeOneOffInternal() {
157 switch (GetGLImplementation()) {
158 case kGLImplementationEGLGLES2
:
159 if (!GLSurfaceEGL::InitializeOneOff()) {
160 LOG(ERROR
) << "GLSurfaceEGL::InitializeOneOff failed.";
165 case kGLImplementationOSMesaGL
:
166 case kGLImplementationMockGL
:
174 scoped_refptr
<GLSurface
> GLSurface::CreateViewGLSurface(
175 gfx::AcceleratedWidget window
) {
176 if (GetGLImplementation() == kGLImplementationOSMesaGL
) {
177 scoped_refptr
<GLSurface
> surface(new GLSurfaceOSMesaHeadless());
178 if (!surface
->Initialize())
182 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2
);
183 if (window
!= kNullAcceleratedWidget
) {
184 scoped_refptr
<GLSurface
> surface
;
185 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
186 ui::SurfaceFactoryOzone::GetInstance()
187 ->CanShowPrimaryPlaneAsOverlay()) {
188 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
189 ui::SurfaceFactoryOzone::GetInstance()
190 ->CreateSurfacelessEGLSurfaceForWidget(window
);
193 surface
= new GLSurfaceOzoneSurfaceless(surface_ozone
.Pass(), window
);
195 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
196 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
201 surface
= new GLSurfaceOzoneEGL(surface_ozone
.Pass(), window
);
203 if (!surface
->Initialize())
207 scoped_refptr
<GLSurface
> surface
= new GLSurfaceStub();
208 if (surface
->Initialize())
215 scoped_refptr
<GLSurface
> GLSurface::CreateOffscreenGLSurface(
216 const gfx::Size
& size
) {
217 switch (GetGLImplementation()) {
218 case kGLImplementationOSMesaGL
: {
219 scoped_refptr
<GLSurface
> surface(
220 new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA
, size
));
221 if (!surface
->Initialize())
226 case kGLImplementationEGLGLES2
: {
227 scoped_refptr
<GLSurface
> surface
;
228 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
229 (size
.width() == 0 && size
.height() == 0)) {
230 surface
= new SurfacelessEGL(size
);
232 surface
= new PbufferGLSurfaceEGL(size
);
234 if (!surface
->Initialize())
244 EGLNativeDisplayType
GetPlatformDefaultEGLNativeDisplay() {
245 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();