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/ozone/platform/drm/gbm_surface_factory.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "third_party/khronos/EGL/egl.h"
12 #include "ui/ozone/common/egl_util.h"
13 #include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
14 #include "ui/ozone/platform/drm/gpu/drm_window.h"
15 #include "ui/ozone/platform/drm/gpu/gbm_buffer.h"
16 #include "ui/ozone/platform/drm/gpu/gbm_device.h"
17 #include "ui/ozone/platform/drm/gpu/gbm_surface.h"
18 #include "ui/ozone/platform/drm/gpu/gbm_surfaceless.h"
19 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
20 #include "ui/ozone/platform/drm/gpu/screen_manager.h"
21 #include "ui/ozone/public/native_pixmap.h"
22 #include "ui/ozone/public/overlay_candidates_ozone.h"
23 #include "ui/ozone/public/ozone_switches.h"
24 #include "ui/ozone/public/surface_ozone_canvas.h"
25 #include "ui/ozone/public/surface_ozone_egl.h"
30 class SingleOverlay
: public OverlayCandidatesOzone
{
33 ~SingleOverlay() override
{}
35 void CheckOverlaySupport(OverlaySurfaceCandidateList
* candidates
) override
{
36 if (candidates
->size() == 2) {
37 OverlayCandidatesOzone::OverlaySurfaceCandidate
* first
=
39 OverlayCandidatesOzone::OverlaySurfaceCandidate
* second
=
41 OverlayCandidatesOzone::OverlaySurfaceCandidate
* overlay
;
42 if (first
->plane_z_order
== 0) {
44 } else if (second
->plane_z_order
== 0) {
50 if (overlay
->plane_z_order
> 0 &&
51 IsTransformSupported(overlay
->transform
)) {
52 overlay
->overlay_handled
= true;
58 bool IsTransformSupported(gfx::OverlayTransform transform
) {
60 case gfx::OVERLAY_TRANSFORM_NONE
:
67 DISALLOW_COPY_AND_ASSIGN(SingleOverlay
);
72 GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless
)
73 : DrmSurfaceFactory(NULL
), allow_surfaceless_(allow_surfaceless
) {
76 GbmSurfaceFactory::~GbmSurfaceFactory() {
79 void GbmSurfaceFactory::InitializeGpu(DrmDeviceManager
* drm_device_manager
,
80 ScreenManager
* screen_manager
) {
81 drm_device_manager_
= drm_device_manager
;
82 screen_manager_
= screen_manager
;
85 intptr_t GbmSurfaceFactory::GetNativeDisplay() {
86 #if defined(USE_MESA_PLATFORM_NULL)
87 return EGL_DEFAULT_DISPLAY
;
89 scoped_refptr
<GbmDevice
> gbm
= GetGbmDevice(gfx::kNullAcceleratedWidget
);
91 return reinterpret_cast<intptr_t>(gbm
->device());
95 int GbmSurfaceFactory::GetDrmFd() {
96 scoped_refptr
<GbmDevice
> gbm
= GetGbmDevice(gfx::kNullAcceleratedWidget
);
101 const int32
* GbmSurfaceFactory::GetEGLSurfaceProperties(
102 const int32
* desired_list
) {
103 static const int32 kConfigAttribs
[] = {EGL_BUFFER_SIZE
,
119 return kConfigAttribs
;
122 bool GbmSurfaceFactory::LoadEGLGLES2Bindings(
123 AddGLLibraryCallback add_gl_library
,
124 SetGLGetProcAddressProcCallback set_gl_get_proc_address
) {
125 return LoadDefaultEGLGLES2Bindings(add_gl_library
, set_gl_get_proc_address
);
128 scoped_ptr
<SurfaceOzoneCanvas
> GbmSurfaceFactory::CreateCanvasForWidget(
129 gfx::AcceleratedWidget widget
) {
130 LOG(FATAL
) << "Software rendering mode is not supported with GBM platform";
134 scoped_ptr
<SurfaceOzoneEGL
> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
135 gfx::AcceleratedWidget widget
) {
136 scoped_refptr
<GbmDevice
> gbm
= GetGbmDevice(widget
);
139 scoped_ptr
<GbmSurface
> surface(
140 new GbmSurface(screen_manager_
->GetWindow(widget
), gbm
));
141 if (!surface
->Initialize())
144 return surface
.Pass();
147 scoped_ptr
<SurfaceOzoneEGL
>
148 GbmSurfaceFactory::CreateSurfacelessEGLSurfaceForWidget(
149 gfx::AcceleratedWidget widget
) {
150 if (!allow_surfaceless_
)
153 return make_scoped_ptr(new GbmSurfaceless(screen_manager_
->GetWindow(widget
),
154 drm_device_manager_
));
157 scoped_refptr
<ui::NativePixmap
> GbmSurfaceFactory::CreateNativePixmap(
158 gfx::AcceleratedWidget widget
,
165 scoped_refptr
<GbmDevice
> gbm
= GetGbmDevice(widget
);
168 scoped_refptr
<GbmBuffer
> buffer
=
169 GbmBuffer::CreateBuffer(gbm
, format
, size
, true);
173 scoped_refptr
<GbmPixmap
> pixmap(new GbmPixmap(buffer
));
174 if (!pixmap
->Initialize())
180 OverlayCandidatesOzone
* GbmSurfaceFactory::GetOverlayCandidates(
181 gfx::AcceleratedWidget w
) {
182 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
183 switches::kOzoneTestSingleOverlaySupport
))
184 return new SingleOverlay();
188 bool GbmSurfaceFactory::ScheduleOverlayPlane(
189 gfx::AcceleratedWidget widget
,
191 gfx::OverlayTransform plane_transform
,
192 scoped_refptr
<NativePixmap
> buffer
,
193 const gfx::Rect
& display_bounds
,
194 const gfx::RectF
& crop_rect
) {
195 scoped_refptr
<GbmPixmap
> pixmap
= static_cast<GbmPixmap
*>(buffer
.get());
197 LOG(ERROR
) << "ScheduleOverlayPlane passed NULL buffer.";
200 HardwareDisplayController
* hdc
=
201 screen_manager_
->GetWindow(widget
)->GetController();
205 hdc
->QueueOverlayPlane(OverlayPlane(pixmap
->buffer(), plane_z_order
,
206 plane_transform
, display_bounds
,
211 bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() {
212 return allow_surfaceless_
;
215 bool GbmSurfaceFactory::CanCreateNativePixmap(BufferUsage usage
) {
226 scoped_refptr
<GbmDevice
> GbmSurfaceFactory::GetGbmDevice(
227 gfx::AcceleratedWidget widget
) {
228 return static_cast<GbmDevice
*>(
229 drm_device_manager_
->GetDrmDevice(widget
).get());