Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Unified Diff: ui/ozone/platform/drm/gpu/drm_overlay_candidate.cc

Issue 1426993003: Ozone: Dont hardcode format to YUV when using Overlay Composition. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cosmetic fixes Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/ozone/platform/drm/gpu/drm_overlay_candidate.cc
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_candidate.cc b/ui/ozone/platform/drm/gpu/drm_overlay_candidate.cc
new file mode 100644
index 0000000000000000000000000000000000000000..47c662f158c270223b126a9ad413cf6920f8866d
--- /dev/null
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_candidate.cc
@@ -0,0 +1,231 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/drm/gpu/drm_overlay_candidate.h"
+
+#include <drm_fourcc.h>
+
+#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/ozone/platform/drm/gpu/drm_device.h"
+#include "ui/ozone/platform/drm/gpu/drm_window.h"
+#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
+#include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
+
+namespace ui {
+
+DrmOverlayCandidate::DrmOverlayCandidate(DrmWindow* window) : window_(window) {}
+
+DrmOverlayCandidate::~DrmOverlayCandidate() {}
+
+std::vector<OverlayCheck_Params> DrmOverlayCandidate::TestPageFlip(
+ const std::vector<OverlayCheck_Params>& current_combination,
+ const std::vector<OverlayCheck_Params>& new_combination,
+ const OverlayPlaneList& last_used_planes,
+ ScanoutBufferGenerator* buffer_generator) {
+ std::vector<OverlayCheck_Params> validated_params;
+ HardwareDisplayController* controller = window_->GetController();
+ if (!controller) {
+ // Nothing much we can do here.
+ return validated_params;
+ }
+
+ overlay_params_.clear();
+ OverlayPlaneList test_list;
+ std::vector<scoped_refptr<ScanoutBuffer>> reusable_buffers;
+ scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice();
+ const OverlayPlane& primary_plane =
+ *OverlayPlane::GetPrimaryPlane(last_used_planes);
+
+ for (const auto& plane : last_used_planes)
+ reusable_buffers.push_back(plane.buffer);
+
+ // We save the current in use configurations as we might have frames using
+ // these configurations queued in SurfaceOzone.
+ for (const auto& param : current_combination)
+ overlay_params_.push_back(param);
+
+ for (const auto& overlay : new_combination) {
+ bool needs_flip_test = true;
+ OverlayCheck_Params param(overlay);
+ DCHECK(param.state != OverlayCheck_Params::kInvalid);
+ OverlayPlane plane(nullptr, overlay.plane_z_order, overlay.transform,
+ overlay.display_rect, overlay.crop_rect);
+
+ if (param.state == OverlayCheck_Params::kTest)
+ EvaluateBufferConfiguration(&param, controller);
+
+ // We expect this combination to always work.
+ if (param.plane_z_order == 0 &&
+ param.required_buffer_size == primary_plane.buffer->GetSize() &&
+ param.optimal_format == gfx::BufferFormat::BGRX_8888) {
+ param.state = OverlayCheck_Params::kOverlay;
+ plane.buffer = primary_plane.buffer;
+ overlay_params_.push_back(param);
+ validated_params.push_back(param);
+ test_list.push_back(plane);
+ continue;
+ }
+
+ if (param.state != OverlayCheck_Params::kTest) {
+ plane.buffer = GetBufferForPageFlipTest(
+ buffer_generator, &reusable_buffers, param.required_buffer_size,
+ param.optimal_format, drm);
+ } else {
+ ValidateConfiguration(buffer_generator, &plane, &param, &reusable_buffers,
+ primary_plane, drm);
+ // We can skip page flip test in case test_list size is less than 2 as the
+ // result will be same as in ValidateConfiguration.
+ needs_flip_test = test_list.size() > 1;
+ }
+
+ if (!plane.buffer) {
+ param.state = OverlayCheck_Params::kInvalid;
+ validated_params.push_back(param);
+ continue;
+ }
+
+ test_list.push_back(plane);
+ bool status = true;
+ if (needs_flip_test)
+ status = controller->TestPageFlip(test_list);
+
+ if (status) {
+ param.state = OverlayCheck_Params::kOverlay;
+ overlay_params_.push_back(param);
+ } else {
+ // If test failed here, it means even though this configuration is
+ // compatible, platform cannot support the current combination of layers.
+ // This is usually the case when this plane has requested post processing
+ // capability which needs additional hardware resources and they might
+ // be already in use by other planes. For example this plane has requested
+ // scaling capabilities and all available scalars are already in use by
+ // other planes.
+ DCHECK(test_list.size() > 1);
+ param.state = OverlayCheck_Params::kCompatible;
+ test_list.pop_back();
+ }
+
+ validated_params.push_back(param);
+ }
+
+ return validated_params;
+}
+
+std::vector<OverlayCheck_Params> DrmOverlayCandidate::GetOverlayConfigurations()
+ const {
+ return overlay_params_;
+}
+
+scoped_refptr<ScanoutBuffer> DrmOverlayCandidate::GetBufferForPageFlipTest(
+ ScanoutBufferGenerator* buffer_generator,
+ std::vector<scoped_refptr<ScanoutBuffer>>* reusable_buffers,
+ const gfx::Size& size,
+ gfx::BufferFormat buffer_format,
+ const scoped_refptr<DrmDevice>& drm_device) {
+ scoped_refptr<ScanoutBuffer> scanout_buffer;
+ uint32_t format = GetFourCCFormatFromBufferFormat(buffer_format);
+ // Check if we can re-use existing buffers.
+ for (const auto& buffer : *reusable_buffers) {
+ if (buffer->GetFramebufferPixelFormat() == format &&
+ buffer->GetSize() == size) {
+ scanout_buffer = buffer;
+ break;
+ }
+ }
+
+ if (!scanout_buffer) {
+ scanout_buffer = buffer_generator->Create(drm_device, buffer_format, size);
+ reusable_buffers->push_back(scanout_buffer);
+ }
+
+ return scanout_buffer;
+}
+
+void DrmOverlayCandidate::ValidateConfiguration(
dnicoara 2015/11/23 19:22:54 Could you document what this does? My understandin
+ ScanoutBufferGenerator* buffer_generator,
+ OverlayPlane* plane,
+ OverlayCheck_Params* param,
+ std::vector<scoped_refptr<ScanoutBuffer>>* reusable_buffers,
+ const OverlayPlane& primary_plane,
+ const scoped_refptr<DrmDevice>& drm) {
+ OverlayPlaneList compatible_test_list;
+ HardwareDisplayController* controller = window_->GetController();
+
+ plane->buffer = GetBufferForPageFlipTest(buffer_generator, reusable_buffers,
+ param->required_buffer_size,
+ param->optimal_format, drm);
+
+ if (!plane->buffer)
+ return;
+
+ if (plane->z_order != 0)
+ compatible_test_list.push_back(primary_plane);
+
+ compatible_test_list.push_back(*plane);
+
+ bool compatible = controller->TestPageFlip(compatible_test_list);
+
+ if (!compatible) {
+ plane->buffer = nullptr;
+ if (param->optimal_format == param->format)
+ return;
+
+ // We tried to optimize the format and failed, check if original format
+ // request can be supported.
+ param->optimal_format = param->format;
+ plane->buffer = GetBufferForPageFlipTest(buffer_generator, reusable_buffers,
+ param->required_buffer_size,
+ param->optimal_format, drm);
+
+ if (!plane->buffer)
+ return;
+
+ compatible_test_list.back().buffer = plane->buffer;
+
+ if (!controller->TestPageFlip(compatible_test_list))
+ plane->buffer = nullptr;
+ }
+}
+
+void DrmOverlayCandidate::EvaluateBufferConfiguration(
+ OverlayCheck_Params* param,
+ HardwareDisplayController* controller) {
+ uint32_t plane_z_order = param->plane_z_order;
+ // TODO(kalyank): We always request scaling to be done by 3D engine, VPP etc.
+ // We should only use them only if downscaling is needed and let display
+ // controller handle up-scaling on platforms which support it.
+ if (!param->crop_rect.IsEmpty()) {
+ param->required_buffer_size = gfx::ToCeiledSize(
+ gfx::SizeF(param->display_rect.width() / param->crop_rect.width(),
+ param->display_rect.height() / param->crop_rect.height()));
+ }
+
+ gfx::BufferFormat format = param->format;
+ // TODO(kalyank): We assume that it's always a Video buffer in case
+ // plane_z_order > 0. This needs to be revisited when we add Overlay support
+ // for other layers.
+ if (param->plane_z_order > 0) {
+ format = gfx::BufferFormat::BGRX_8888;
dnicoara 2015/11/23 19:22:54 Shouldn't this be in the following if-statement? W
+ // Full screen is a special case, Plane manager will collapse Overlay plane
+ // to primary.
+ if (param->display_rect == window_->bounds())
+ plane_z_order = 0;
+
+ // TODO(kalyank): In fullscreen case, we always fall back to BGRX format.
+ // Currently, PlaneManager collapses planes to one only if format is BGRX.
+ // This is due to the fact that page flip can fail on non-atomic kernels,
+ // when trying to flip a buffer of format other than what was used during
+ // Modeset with primary. However, with Atomic we can use test commit to
+ // check if the actual commit will pass or not and make a decision. Remove
+ // this restriction here and in plane manager once we are able to test it.
+ if (plane_z_order &&
+ controller->IsFormatSupported(DRM_FORMAT_UYVY, plane_z_order)) {
+ format = gfx::BufferFormat::UYVY_422;
+ }
+ }
+
+ param->optimal_format = format;
+}
+
+} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698