Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / ozone / platform / dri / gbm_surface_factory.cc
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.
4
5 #include "ui/ozone/platform/dri/gbm_surface_factory.h"
6
7 #include <gbm.h>
8
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"
22
23 namespace ui {
24 namespace {
25
26 class SingleOverlay : public OverlayCandidatesOzone {
27  public:
28   SingleOverlay() {}
29   ~SingleOverlay() override {}
30
31   void CheckOverlaySupport(OverlaySurfaceCandidateList* candidates) override {
32     if (candidates->size() == 2) {
33       OverlayCandidatesOzone::OverlaySurfaceCandidate* first =
34           &(*candidates)[0];
35       OverlayCandidatesOzone::OverlaySurfaceCandidate* second =
36           &(*candidates)[1];
37       OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay;
38       if (first->plane_z_order == 0) {
39         overlay = second;
40       } else if (second->plane_z_order == 0) {
41         overlay = first;
42       } else {
43         NOTREACHED();
44         return;
45       }
46       if (overlay->plane_z_order > 0 &&
47           IsTransformSupported(overlay->transform)) {
48         overlay->overlay_handled = true;
49       }
50     }
51   }
52
53  private:
54   bool IsTransformSupported(gfx::OverlayTransform transform) {
55     switch (transform) {
56       case gfx::OVERLAY_TRANSFORM_NONE:
57         return true;
58       default:
59         return false;
60     }
61   }
62
63   DISALLOW_COPY_AND_ASSIGN(SingleOverlay);
64 };
65
66 }  // namespace
67
68 GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless)
69     : DriSurfaceFactory(NULL, NULL, NULL),
70       device_(NULL),
71       allow_surfaceless_(allow_surfaceless) {
72 }
73
74 GbmSurfaceFactory::~GbmSurfaceFactory() {}
75
76 void GbmSurfaceFactory::InitializeGpu(
77     DriWrapper* dri,
78     gbm_device* device,
79     ScreenManager* screen_manager,
80     DriWindowDelegateManager* window_manager) {
81   drm_ = dri;
82   device_ = device;
83   screen_manager_ = screen_manager;
84   window_manager_ = window_manager;
85 }
86
87 intptr_t GbmSurfaceFactory::GetNativeDisplay() {
88   DCHECK(state_ == INITIALIZED);
89   return reinterpret_cast<intptr_t>(device_);
90 }
91
92 const int32* GbmSurfaceFactory::GetEGLSurfaceProperties(
93     const int32* desired_list) {
94   static const int32 kConfigAttribs[] = {
95     EGL_BUFFER_SIZE, 32,
96     EGL_ALPHA_SIZE, 8,
97     EGL_BLUE_SIZE, 8,
98     EGL_GREEN_SIZE, 8,
99     EGL_RED_SIZE, 8,
100     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
101     EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
102     EGL_NONE
103   };
104
105   return kConfigAttribs;
106 }
107
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"),
114       &error);
115   if (!gles_library) {
116     LOG(WARNING) << "Failed to load GLES library: " << error.ToString();
117     return false;
118   }
119
120   base::NativeLibrary egl_library = base::LoadNativeLibrary(
121       base::FilePath("libEGL.so.1"),
122       &error);
123   if (!egl_library) {
124     LOG(WARNING) << "Failed to load EGL library: " << error.ToString();
125     base::UnloadNativeLibrary(gles_library);
126     return false;
127   }
128
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);
137     return false;
138   }
139
140   set_gl_get_proc_address.Run(get_proc_address);
141   add_gl_library.Run(egl_library);
142   add_gl_library.Run(gles_library);
143
144   return true;
145 }
146
147 scoped_ptr<SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
148     gfx::AcceleratedWidget widget) {
149   DCHECK(state_ == INITIALIZED);
150
151   DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);
152
153   scoped_ptr<GbmSurface> surface(new GbmSurface(delegate, device_, drm_));
154   if (!surface->Initialize())
155     return nullptr;
156
157   return surface.Pass();
158 }
159
160 scoped_ptr<SurfaceOzoneEGL>
161 GbmSurfaceFactory::CreateSurfacelessEGLSurfaceForWidget(
162     gfx::AcceleratedWidget widget) {
163   if (!allow_surfaceless_)
164     return scoped_ptr<SurfaceOzoneEGL>();
165
166   DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);
167   return scoped_ptr<SurfaceOzoneEGL>(new GbmSurfaceless(delegate));
168 }
169
170 scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
171     gfx::Size size,
172     BufferFormat format) {
173   scoped_refptr<GbmBuffer> buffer = GbmBuffer::CreateBuffer(
174       drm_, device_, format, size, true);
175   if (!buffer.get())
176     return NULL;
177
178   scoped_refptr<GbmPixmap> pixmap(new GbmPixmap(buffer));
179   if (!pixmap->Initialize(drm_))
180     return NULL;
181
182   return pixmap;
183 }
184
185 OverlayCandidatesOzone* GbmSurfaceFactory::GetOverlayCandidates(
186     gfx::AcceleratedWidget w) {
187   if (CommandLine::ForCurrentProcess()->HasSwitch(
188           switches::kOzoneTestSingleOverlaySupport))
189     return new SingleOverlay();
190   return NULL;
191 }
192
193 bool GbmSurfaceFactory::ScheduleOverlayPlane(
194     gfx::AcceleratedWidget widget,
195     int plane_z_order,
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());
201   if (!pixmap.get()) {
202     LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer.";
203     return false;
204   }
205   HardwareDisplayController* hdc =
206       window_manager_->GetWindowDelegate(widget)->GetController();
207   if (!hdc)
208     return true;
209
210   hdc->QueueOverlayPlane(OverlayPlane(pixmap->buffer(),
211                                       plane_z_order,
212                                       plane_transform,
213                                       display_bounds,
214                                       crop_rect));
215   return true;
216 }
217
218 bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() {
219   return allow_surfaceless_;
220 }
221
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());
229   }
230
231   return window_manager_->GetWindowDelegate(widget);
232 }
233
234 }  // namespace ui