OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h" | 5 #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h" |
6 | 6 |
| 7 #include <drm_fourcc.h> |
| 8 |
7 #include <set> | 9 #include <set> |
8 | 10 |
9 #include "base/logging.h" | 11 #include "base/logging.h" |
10 #include "ui/gfx/geometry/rect.h" | 12 #include "ui/gfx/geometry/rect.h" |
11 #include "ui/ozone/platform/drm/gpu/drm_device.h" | 13 #include "ui/ozone/platform/drm/gpu/drm_device.h" |
12 #include "ui/ozone/platform/drm/gpu/scanout_buffer.h" | 14 #include "ui/ozone/platform/drm/gpu/scanout_buffer.h" |
13 | 15 |
14 namespace ui { | 16 namespace ui { |
15 namespace { | 17 namespace { |
16 | 18 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 if (!plane->IsSupportedFormat(overlay.buffer->GetFramebufferPixelFormat())) | 173 if (!plane->IsSupportedFormat(overlay.buffer->GetFramebufferPixelFormat())) |
172 return false; | 174 return false; |
173 | 175 |
174 // TODO(kalyank): We should check for z-order and any needed transformation | 176 // TODO(kalyank): We should check for z-order and any needed transformation |
175 // support. Driver doesn't expose any property to check for z-order, can we | 177 // support. Driver doesn't expose any property to check for z-order, can we |
176 // rely on the sorting we do based on plane ids ? | 178 // rely on the sorting we do based on plane ids ? |
177 | 179 |
178 return true; | 180 return true; |
179 } | 181 } |
180 | 182 |
| 183 void HardwareDisplayPlaneManager::ResetCurrentPlaneList( |
| 184 HardwareDisplayPlaneList* plane_list) const { |
| 185 for (auto* hardware_plane : plane_list->plane_list) { |
| 186 hardware_plane->set_in_use(false); |
| 187 hardware_plane->set_owning_crtc(0); |
| 188 } |
| 189 |
| 190 plane_list->plane_list.clear(); |
| 191 plane_list->legacy_page_flips.clear(); |
| 192 #if defined(USE_DRM_ATOMIC) |
| 193 plane_list->atomic_property_set.reset(drmModeAtomicAlloc()); |
| 194 #endif |
| 195 } |
| 196 |
181 void HardwareDisplayPlaneManager::BeginFrame( | 197 void HardwareDisplayPlaneManager::BeginFrame( |
182 HardwareDisplayPlaneList* plane_list) { | 198 HardwareDisplayPlaneList* plane_list) { |
183 for (auto* plane : plane_list->old_plane_list) { | 199 for (auto* plane : plane_list->old_plane_list) { |
184 plane->set_in_use(false); | 200 plane->set_in_use(false); |
185 } | 201 } |
186 } | 202 } |
187 | 203 |
188 bool HardwareDisplayPlaneManager::AssignOverlayPlanes( | 204 bool HardwareDisplayPlaneManager::AssignOverlayPlanes( |
189 HardwareDisplayPlaneList* plane_list, | 205 HardwareDisplayPlaneList* plane_list, |
190 const OverlayPlaneList& overlay_list, | 206 const OverlayPlaneList& overlay_list, |
191 uint32_t crtc_id, | 207 uint32_t crtc_id, |
192 CrtcController* crtc) { | 208 CrtcController* crtc) { |
193 int crtc_index = LookupCrtcIndex(crtc_id); | 209 int crtc_index = LookupCrtcIndex(crtc_id); |
194 if (crtc_index < 0) { | 210 if (crtc_index < 0) { |
195 LOG(ERROR) << "Cannot find crtc " << crtc_id; | 211 LOG(ERROR) << "Cannot find crtc " << crtc_id; |
196 return false; | 212 return false; |
197 } | 213 } |
198 | 214 |
199 size_t plane_idx = 0; | 215 size_t plane_idx = 0; |
| 216 HardwareDisplayPlane* primary_plane = nullptr; |
| 217 gfx::Rect primary_display_bounds; |
| 218 gfx::Rect primary_src_rect; |
| 219 uint32_t primary_format; |
200 for (const auto& plane : overlay_list) { | 220 for (const auto& plane : overlay_list) { |
201 HardwareDisplayPlane* hw_plane = | 221 HardwareDisplayPlane* hw_plane = |
202 FindNextUnusedPlane(&plane_idx, crtc_index, plane); | 222 FindNextUnusedPlane(&plane_idx, crtc_index, plane); |
203 if (!hw_plane) { | 223 if (!hw_plane) { |
204 LOG(ERROR) << "Failed to find a free plane for crtc " << crtc_id; | 224 LOG(ERROR) << "Failed to find a free plane for crtc " << crtc_id; |
| 225 ResetCurrentPlaneList(plane_list); |
205 return false; | 226 return false; |
206 } | 227 } |
207 | 228 |
208 gfx::Rect fixed_point_rect; | 229 gfx::Rect fixed_point_rect; |
| 230 uint32_t fourcc_format = plane.buffer->GetFramebufferPixelFormat(); |
209 if (hw_plane->type() != HardwareDisplayPlane::kDummy) { | 231 if (hw_plane->type() != HardwareDisplayPlane::kDummy) { |
210 const gfx::Size& size = plane.buffer->GetSize(); | 232 const gfx::Size& size = plane.buffer->GetSize(); |
211 gfx::RectF crop_rect = gfx::RectF(plane.crop_rect); | 233 gfx::RectF crop_rect = plane.crop_rect; |
212 crop_rect.Scale(size.width(), size.height()); | 234 crop_rect.Scale(size.width(), size.height()); |
213 | 235 |
214 // This returns a number in 16.16 fixed point, required by the DRM overlay | 236 // This returns a number in 16.16 fixed point, required by the DRM overlay |
215 // APIs. | 237 // APIs. |
216 auto to_fixed_point = | 238 auto to_fixed_point = |
217 [](double v) -> uint32_t { return v * kFixedPointScaleValue; }; | 239 [](double v) -> uint32_t { return v * kFixedPointScaleValue; }; |
218 fixed_point_rect = gfx::Rect(to_fixed_point(crop_rect.x()), | 240 fixed_point_rect = gfx::Rect(to_fixed_point(crop_rect.x()), |
219 to_fixed_point(crop_rect.y()), | 241 to_fixed_point(crop_rect.y()), |
220 to_fixed_point(crop_rect.width()), | 242 to_fixed_point(crop_rect.width()), |
221 to_fixed_point(crop_rect.height())); | 243 to_fixed_point(crop_rect.height())); |
222 } | 244 } |
223 | 245 |
| 246 // If Overlay completely covers primary and isn't transparent, than use |
| 247 // it as primary. This reduces the no of planes which need to be read in |
| 248 // display controller side. |
| 249 if (primary_plane) { |
| 250 bool needs_blending = true; |
| 251 if (fourcc_format == DRM_FORMAT_XRGB8888) |
| 252 needs_blending = false; |
| 253 // TODO(kalyank): Check if we can move this optimization to |
| 254 // DrmOverlayCandidatesHost. |
| 255 if (!needs_blending && primary_format == fourcc_format && |
| 256 primary_display_bounds == plane.display_bounds && |
| 257 fixed_point_rect == primary_src_rect) { |
| 258 ResetCurrentPlaneList(plane_list); |
| 259 hw_plane = primary_plane; |
| 260 } |
| 261 } else { |
| 262 primary_plane = hw_plane; |
| 263 primary_display_bounds = plane.display_bounds; |
| 264 primary_src_rect = fixed_point_rect; |
| 265 primary_format = fourcc_format; |
| 266 } |
| 267 |
| 268 if (!SetPlaneData(plane_list, hw_plane, plane, crtc_id, fixed_point_rect, |
| 269 crtc)) { |
| 270 ResetCurrentPlaneList(plane_list); |
| 271 return false; |
| 272 } |
| 273 |
224 plane_list->plane_list.push_back(hw_plane); | 274 plane_list->plane_list.push_back(hw_plane); |
225 hw_plane->set_owning_crtc(crtc_id); | 275 hw_plane->set_owning_crtc(crtc_id); |
226 if (SetPlaneData(plane_list, hw_plane, plane, crtc_id, fixed_point_rect, | 276 hw_plane->set_in_use(true); |
227 crtc)) { | |
228 hw_plane->set_in_use(true); | |
229 } else { | |
230 return false; | |
231 } | |
232 } | 277 } |
233 return true; | 278 return true; |
234 } | 279 } |
235 | 280 |
236 std::vector<uint32_t> | 281 std::vector<uint32_t> |
237 HardwareDisplayPlaneManager::GetCompatibleHardwarePlaneIds( | 282 HardwareDisplayPlaneManager::GetCompatibleHardwarePlaneIds( |
238 const OverlayPlane& plane, | 283 const OverlayPlane& plane, |
239 uint32_t crtc_id) const { | 284 uint32_t crtc_id) const { |
240 int crtc_index = LookupCrtcIndex(crtc_id); | 285 int crtc_index = LookupCrtcIndex(crtc_id); |
241 if (crtc_index < 0) { | 286 if (crtc_index < 0) { |
242 LOG(ERROR) << "Cannot find crtc " << crtc_id; | 287 LOG(ERROR) << "Cannot find crtc " << crtc_id; |
243 return std::vector<uint32_t>(); | 288 return std::vector<uint32_t>(); |
244 } | 289 } |
245 | 290 |
246 std::vector<uint32_t> plane_ids; | 291 std::vector<uint32_t> plane_ids; |
247 for (auto* hardware_plane : planes_) { | 292 for (auto* hardware_plane : planes_) { |
248 if (IsCompatible(hardware_plane, plane, crtc_index)) | 293 if (IsCompatible(hardware_plane, plane, crtc_index)) |
249 plane_ids.push_back(hardware_plane->plane_id()); | 294 plane_ids.push_back(hardware_plane->plane_id()); |
250 } | 295 } |
251 | 296 |
252 return plane_ids; | 297 return plane_ids; |
253 } | 298 } |
254 | 299 |
255 } // namespace ui | 300 } // namespace ui |
OLD | NEW |