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 // TODO: this should be replaced by a fence when supported by the driver.
127 return ozone_surface_
->OnSwapBuffers();
129 virtual bool ScheduleOverlayPlane(int z_order
,
130 OverlayTransform transform
,
132 const Rect
& bounds_rect
,
133 const RectF
& crop_rect
) override
{
134 return image
->ScheduleOverlayPlane(
135 widget_
, z_order
, transform
, bounds_rect
, crop_rect
);
137 virtual bool IsOffscreen() override
{ return false; }
138 virtual VSyncProvider
* GetVSyncProvider() override
{
139 return vsync_provider_
.get();
141 virtual bool SupportsPostSubBuffer() override
{ return true; }
142 virtual bool PostSubBuffer(int x
, int y
, int width
, int height
) override
{
143 // The actual sub buffer handling is handled at higher layers.
147 virtual bool IsSurfaceless() const override
{ return true; }
150 virtual ~GLSurfaceOzoneSurfaceless() {
151 Destroy(); // EGL surface must be destroyed before SurfaceOzone
154 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
155 scoped_ptr
<ui::SurfaceOzoneEGL
> ozone_surface_
;
156 AcceleratedWidget widget_
;
157 scoped_ptr
<VSyncProvider
> vsync_provider_
;
159 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless
);
165 bool GLSurface::InitializeOneOffInternal() {
166 switch (GetGLImplementation()) {
167 case kGLImplementationEGLGLES2
:
168 if (!GLSurfaceEGL::InitializeOneOff()) {
169 LOG(ERROR
) << "GLSurfaceEGL::InitializeOneOff failed.";
174 case kGLImplementationOSMesaGL
:
175 case kGLImplementationMockGL
:
183 scoped_refptr
<GLSurface
> GLSurface::CreateViewGLSurface(
184 gfx::AcceleratedWidget window
) {
185 if (GetGLImplementation() == kGLImplementationOSMesaGL
) {
186 scoped_refptr
<GLSurface
> surface(new GLSurfaceOSMesaHeadless());
187 if (!surface
->Initialize())
191 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2
);
192 if (window
!= kNullAcceleratedWidget
) {
193 scoped_refptr
<GLSurface
> surface
;
194 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
195 ui::SurfaceFactoryOzone::GetInstance()
196 ->CanShowPrimaryPlaneAsOverlay()) {
197 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
198 ui::SurfaceFactoryOzone::GetInstance()
199 ->CreateSurfacelessEGLSurfaceForWidget(window
);
202 surface
= new GLSurfaceOzoneSurfaceless(surface_ozone
.Pass(), window
);
204 scoped_ptr
<ui::SurfaceOzoneEGL
> surface_ozone
=
205 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
210 surface
= new GLSurfaceOzoneEGL(surface_ozone
.Pass(), window
);
212 if (!surface
->Initialize())
216 scoped_refptr
<GLSurface
> surface
= new GLSurfaceStub();
217 if (surface
->Initialize())
224 scoped_refptr
<GLSurface
> GLSurface::CreateOffscreenGLSurface(
225 const gfx::Size
& size
) {
226 switch (GetGLImplementation()) {
227 case kGLImplementationOSMesaGL
: {
228 scoped_refptr
<GLSurface
> surface(
229 new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA
, size
));
230 if (!surface
->Initialize())
235 case kGLImplementationEGLGLES2
: {
236 scoped_refptr
<GLSurface
> surface
;
237 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
238 (size
.width() == 0 && size
.height() == 0)) {
239 surface
= new SurfacelessEGL(size
);
241 surface
= new PbufferGLSurfaceEGL(size
);
243 if (!surface
->Initialize())
253 EGLNativeDisplayType
GetPlatformDefaultEGLNativeDisplay() {
254 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();