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