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/dri/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/platform/dri/dri_window_delegate_impl.h"
13 #include "ui/ozone/platform/dri/dri_window_delegate_manager.h"
14 #include "ui/ozone/platform/dri/gbm_buffer.h"
15 #include "ui/ozone/platform/dri/gbm_surface.h"
16 #include "ui/ozone/platform/dri/gbm_surfaceless.h"
17 #include "ui/ozone/platform/dri/screen_manager.h"
18 #include "ui/ozone/public/native_pixmap.h"
19 #include "ui/ozone/public/overlay_candidates_ozone.h"
20 #include "ui/ozone/public/ozone_switches.h"
21 #include "ui/ozone/public/surface_ozone_egl.h"
26 class SingleOverlay : public OverlayCandidatesOzone {
29 ~SingleOverlay() override {}
31 void CheckOverlaySupport(OverlaySurfaceCandidateList* candidates) override {
32 if (candidates->size() == 2) {
33 OverlayCandidatesOzone::OverlaySurfaceCandidate* first =
35 OverlayCandidatesOzone::OverlaySurfaceCandidate* second =
37 OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay;
38 if (first->plane_z_order == 0) {
40 } else if (second->plane_z_order == 0) {
46 if (overlay->plane_z_order > 0 &&
47 IsTransformSupported(overlay->transform)) {
48 overlay->overlay_handled = true;
54 bool IsTransformSupported(gfx::OverlayTransform transform) {
56 case gfx::OVERLAY_TRANSFORM_NONE:
63 DISALLOW_COPY_AND_ASSIGN(SingleOverlay);
68 GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless)
69 : DriSurfaceFactory(NULL, NULL, NULL),
71 allow_surfaceless_(allow_surfaceless) {
74 GbmSurfaceFactory::~GbmSurfaceFactory() {}
76 void GbmSurfaceFactory::InitializeGpu(
79 ScreenManager* screen_manager,
80 DriWindowDelegateManager* window_manager) {
83 screen_manager_ = screen_manager;
84 window_manager_ = window_manager;
87 intptr_t GbmSurfaceFactory::GetNativeDisplay() {
88 DCHECK(state_ == INITIALIZED);
89 return reinterpret_cast<intptr_t>(device_);
92 const int32* GbmSurfaceFactory::GetEGLSurfaceProperties(
93 const int32* desired_list) {
94 static const int32 kConfigAttribs[] = {
100 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
101 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
105 return kConfigAttribs;
108 bool GbmSurfaceFactory::LoadEGLGLES2Bindings(
109 AddGLLibraryCallback add_gl_library,
110 SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
111 base::NativeLibraryLoadError error;
112 base::NativeLibrary gles_library = base::LoadNativeLibrary(
113 base::FilePath("libGLESv2.so.2"),
116 LOG(WARNING) << "Failed to load GLES library: " << error.ToString();
120 base::NativeLibrary egl_library = base::LoadNativeLibrary(
121 base::FilePath("libEGL.so.1"),
124 LOG(WARNING) << "Failed to load EGL library: " << error.ToString();
125 base::UnloadNativeLibrary(gles_library);
129 GLGetProcAddressProc get_proc_address =
130 reinterpret_cast<GLGetProcAddressProc>(
131 base::GetFunctionPointerFromNativeLibrary(
132 egl_library, "eglGetProcAddress"));
133 if (!get_proc_address) {
134 LOG(ERROR) << "eglGetProcAddress not found.";
135 base::UnloadNativeLibrary(egl_library);
136 base::UnloadNativeLibrary(gles_library);
140 set_gl_get_proc_address.Run(get_proc_address);
141 add_gl_library.Run(egl_library);
142 add_gl_library.Run(gles_library);
147 scoped_ptr<SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
148 gfx::AcceleratedWidget widget) {
149 DCHECK(state_ == INITIALIZED);
151 DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);
153 scoped_ptr<GbmSurface> surface(new GbmSurface(delegate, device_, drm_));
154 if (!surface->Initialize())
157 return surface.Pass();
160 scoped_ptr<SurfaceOzoneEGL>
161 GbmSurfaceFactory::CreateSurfacelessEGLSurfaceForWidget(
162 gfx::AcceleratedWidget widget) {
163 if (!allow_surfaceless_)
164 return scoped_ptr<SurfaceOzoneEGL>();
166 DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);
167 return scoped_ptr<SurfaceOzoneEGL>(new GbmSurfaceless(delegate));
170 scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
172 BufferFormat format) {
173 scoped_refptr<GbmBuffer> buffer = GbmBuffer::CreateBuffer(
174 drm_, device_, format, size, true);
178 scoped_refptr<GbmPixmap> pixmap(new GbmPixmap(buffer));
179 if (!pixmap->Initialize(drm_))
185 OverlayCandidatesOzone* GbmSurfaceFactory::GetOverlayCandidates(
186 gfx::AcceleratedWidget w) {
187 if (CommandLine::ForCurrentProcess()->HasSwitch(
188 switches::kOzoneTestSingleOverlaySupport))
189 return new SingleOverlay();
193 bool GbmSurfaceFactory::ScheduleOverlayPlane(
194 gfx::AcceleratedWidget widget,
196 gfx::OverlayTransform plane_transform,
197 scoped_refptr<NativePixmap> buffer,
198 const gfx::Rect& display_bounds,
199 const gfx::RectF& crop_rect) {
200 scoped_refptr<GbmPixmap> pixmap = static_cast<GbmPixmap*>(buffer.get());
202 LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer.";
205 HardwareDisplayController* hdc =
206 window_manager_->GetWindowDelegate(widget)->GetController();
210 hdc->QueueOverlayPlane(OverlayPlane(pixmap->buffer(),
218 bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() {
219 return allow_surfaceless_;
222 DriWindowDelegate* GbmSurfaceFactory::GetOrCreateWindowDelegate(
223 gfx::AcceleratedWidget widget) {
224 if (!window_manager_->HasWindowDelegate(widget)) {
225 scoped_ptr<DriWindowDelegate> delegate(
226 new DriWindowDelegateImpl(widget, screen_manager_));
227 delegate->Initialize();
228 window_manager_->AddWindowDelegate(widget, delegate.Pass());
231 return window_manager_->GetWindowDelegate(widget);