Commit 1a4c5275 authored by kylechar's avatar kylechar Committed by Commit Bot

Cleanup DrmOverlayManager logic and add test.

Move all checks for if a OverlaySurfaceCandidate is potentially valid
into CanHandleCandidate(). Also simplify CheckOverlaySupport() a bit.

Add a test that exercises DrmOverlayManger caching to ensure that
request for overlay validation gets sent at the right time.

Bug: 930173
Change-Id: I1d0705b76c1b2ba806a207b9e2ba55d161ae60d6
Reviewed-on: https://chromium-review.googlesource.com/c/1495740Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Commit-Queue: Michael Spang <spang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636908}
parent c290a7d2
...@@ -173,6 +173,7 @@ source_set("gbm") { ...@@ -173,6 +173,7 @@ source_set("gbm") {
source_set("gbm_unittests") { source_set("gbm_unittests") {
testonly = true testonly = true
sources = [ sources = [
"common/drm_overlay_manager_unittest.cc",
"common/drm_util_unittest.cc", "common/drm_util_unittest.cc",
"gpu/drm_overlay_validator_unittest.cc", "gpu/drm_overlay_validator_unittest.cc",
"gpu/drm_window_unittest.cc", "gpu/drm_window_unittest.cc",
......
...@@ -53,22 +53,14 @@ void DrmOverlayManager::CheckOverlaySupport( ...@@ -53,22 +53,14 @@ void DrmOverlayManager::CheckOverlaySupport(
std::vector<OverlaySurfaceCandidate> result_candidates; std::vector<OverlaySurfaceCandidate> result_candidates;
for (auto& candidate : *candidates) { for (auto& candidate : *candidates) {
// Reject candidates that don't fall on a pixel boundary. bool can_handle = CanHandleCandidate(candidate, widget);
if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f)) {
DCHECK_NE(candidate.plane_z_order, 0);
result_candidates.push_back(OverlaySurfaceCandidate());
result_candidates.back().overlay_handled = false;
continue;
}
result_candidates.push_back(OverlaySurfaceCandidate(candidate)); // CanHandleCandidate() should never return false if the candidate is
// Start out hoping that we can have an overlay. // the primary plane.
result_candidates.back().overlay_handled = true; DCHECK(can_handle || candidate.plane_z_order != 0);
if (!CanHandleCandidate(candidate, widget)) { result_candidates.push_back(candidate);
DCHECK_NE(candidate.plane_z_order, 0); result_candidates.back().overlay_handled = can_handle;
result_candidates.back().overlay_handled = false;
}
} }
auto iter = cache_.Get(result_candidates); auto iter = cache_.Get(result_candidates);
...@@ -98,7 +90,7 @@ void DrmOverlayManager::CheckOverlaySupport( ...@@ -98,7 +90,7 @@ void DrmOverlayManager::CheckOverlaySupport(
size_t size = candidates->size(); size_t size = candidates->size();
const std::vector<OverlayStatus>& status = value.status; const std::vector<OverlayStatus>& status = value.status;
DCHECK(size == status.size()); DCHECK_EQ(size, status.size());
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
DCHECK(status[i] == OVERLAY_STATUS_ABLE || DCHECK(status[i] == OVERLAY_STATUS_ABLE ||
status[i] == OVERLAY_STATUS_NOT); status[i] == OVERLAY_STATUS_NOT);
...@@ -116,6 +108,10 @@ bool DrmOverlayManager::CanHandleCandidate( ...@@ -116,6 +108,10 @@ bool DrmOverlayManager::CanHandleCandidate(
if (candidate.transform == gfx::OVERLAY_TRANSFORM_INVALID) if (candidate.transform == gfx::OVERLAY_TRANSFORM_INVALID)
return false; return false;
// Reject candidates that don't fall on a pixel boundary.
if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f))
return false;
if (candidate.is_clipped && !candidate.clip_rect.Contains( if (candidate.is_clipped && !candidate.clip_rect.Contains(
gfx::ToNearestRect(candidate.display_rect))) { gfx::ToNearestRect(candidate.display_rect))) {
return false; return false;
......
...@@ -11,13 +11,16 @@ ...@@ -11,13 +11,16 @@
#include "base/containers/mru_cache.h" #include "base/containers/mru_cache.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/public/overlay_candidates_ozone.h" #include "ui/ozone/public/overlay_candidates_ozone.h"
#include "ui/ozone/public/overlay_manager_ozone.h" #include "ui/ozone/public/overlay_manager_ozone.h"
namespace ui { namespace ui {
class OverlaySurfaceCandidate; class OverlaySurfaceCandidate;
// Ozone DRM extension of the OverlayManagerOzone interface. // Ozone DRM extension of the OverlayManagerOzone interface. It queries the
// DrmDevice to see if an overlay configuration will work and keeps an MRU cache
// of recent configurations.
class DrmOverlayManager : public OverlayManagerOzone { class DrmOverlayManager : public OverlayManagerOzone {
public: public:
DrmOverlayManager(); DrmOverlayManager();
...@@ -46,7 +49,7 @@ class DrmOverlayManager : public OverlayManagerOzone { ...@@ -46,7 +49,7 @@ class DrmOverlayManager : public OverlayManagerOzone {
// should call UpdateCacheForOverlayCandidates() with the response. // should call UpdateCacheForOverlayCandidates() with the response.
virtual void SendOverlayValidationRequest( virtual void SendOverlayValidationRequest(
const std::vector<OverlaySurfaceCandidate>& candidates, const std::vector<OverlaySurfaceCandidate>& candidates,
gfx::AcceleratedWidget widget) const = 0; gfx::AcceleratedWidget widget) = 0;
// Perform basic validation to see if |candidate| is a valid request. // Perform basic validation to see if |candidate| is a valid request.
virtual bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate, virtual bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
......
// Copyright 2019 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/common/drm_overlay_manager.h"
#include "base/bind.h"
#include "base/callback.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/ozone/public/overlay_surface_candidate.h"
namespace ui {
namespace {
constexpr gfx::AcceleratedWidget kWidget = 1;
class TestDrmOverlayManager : public DrmOverlayManager {
public:
TestDrmOverlayManager() = default;
~TestDrmOverlayManager() override = default;
using DrmOverlayManager::UpdateCacheForOverlayCandidates;
std::vector<std::vector<OverlaySurfaceCandidate>>& requests() {
return requests_;
}
// DrmOverlayManager:
void SendOverlayValidationRequest(
const std::vector<OverlaySurfaceCandidate>& candidates,
gfx::AcceleratedWidget widget) override {
requests_.push_back(candidates);
}
private:
std::vector<std::vector<OverlaySurfaceCandidate>> requests_;
};
OverlaySurfaceCandidate CreateCandidate(const gfx::Rect& rect,
int plane_z_order) {
ui::OverlaySurfaceCandidate candidate;
candidate.transform = gfx::OVERLAY_TRANSFORM_NONE;
candidate.format = gfx::BufferFormat::YUV_420_BIPLANAR;
candidate.plane_z_order = plane_z_order;
candidate.buffer_size = rect.size();
candidate.display_rect = gfx::RectF(rect);
candidate.crop_rect = gfx::RectF(rect);
return candidate;
}
} // namespace
TEST(DrmOverlayManagerTest, CacheLogic) {
TestDrmOverlayManager manager;
// Candidates for output surface and single-on-top quad.
std::vector<OverlaySurfaceCandidate> candidates = {
CreateCandidate(gfx::Rect(0, 0, 100, 100), 0),
CreateCandidate(gfx::Rect(10, 10, 20, 20), 1)};
// The first three times that CheckOverlaySupport() is called for an overlay
// configuration it won't send a validation request.
for (int i = 0; i < 3; ++i) {
manager.CheckOverlaySupport(&candidates, kWidget);
EXPECT_FALSE(candidates[0].overlay_handled);
EXPECT_FALSE(candidates[1].overlay_handled);
EXPECT_EQ(manager.requests().size(), 0u);
}
// The fourth call with the same overlay configuration should trigger a
// request to validate the configuration. Still assume the overlay
// configuration won't work until we get a response.
manager.CheckOverlaySupport(&candidates, kWidget);
EXPECT_FALSE(candidates[0].overlay_handled);
EXPECT_FALSE(candidates[1].overlay_handled);
EXPECT_EQ(manager.requests().size(), 1u);
// While waiting for a response we shouldn't send the same request.
manager.CheckOverlaySupport(&candidates, kWidget);
EXPECT_FALSE(candidates[0].overlay_handled);
EXPECT_FALSE(candidates[1].overlay_handled);
ASSERT_EQ(manager.requests().size(), 1u);
// Receive response that the overlay configuration will work.
manager.UpdateCacheForOverlayCandidates(
manager.requests().front(),
std::vector<OverlayStatus>(candidates.size(), OVERLAY_STATUS_ABLE));
manager.requests().clear();
// CheckOverlaySupport() should now indicate the overlay configuration will
// work.
manager.CheckOverlaySupport(&candidates, kWidget);
EXPECT_TRUE(candidates[0].overlay_handled);
EXPECT_TRUE(candidates[1].overlay_handled);
EXPECT_EQ(manager.requests().size(), 0u);
}
} // namespace ui
...@@ -37,7 +37,7 @@ void DrmOverlayManagerHost::GpuSentOverlayResult( ...@@ -37,7 +37,7 @@ void DrmOverlayManagerHost::GpuSentOverlayResult(
void DrmOverlayManagerHost::SendOverlayValidationRequest( void DrmOverlayManagerHost::SendOverlayValidationRequest(
const OverlaySurfaceCandidateList& candidates, const OverlaySurfaceCandidateList& candidates,
gfx::AcceleratedWidget widget) const { gfx::AcceleratedWidget widget) {
if (!proxy_->IsConnected()) if (!proxy_->IsConnected())
return; return;
TRACE_EVENT_ASYNC_BEGIN0( TRACE_EVENT_ASYNC_BEGIN0(
......
...@@ -45,7 +45,7 @@ class DrmOverlayManagerHost : public DrmOverlayManager { ...@@ -45,7 +45,7 @@ class DrmOverlayManagerHost : public DrmOverlayManager {
// DrmOverlayManager: // DrmOverlayManager:
void SendOverlayValidationRequest( void SendOverlayValidationRequest(
const OverlaySurfaceCandidateList& candidates, const OverlaySurfaceCandidateList& candidates,
gfx::AcceleratedWidget widget) const override; gfx::AcceleratedWidget widget) override;
bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate, bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
gfx::AcceleratedWidget widget) const override; gfx::AcceleratedWidget widget) const override;
......
...@@ -30,8 +30,8 @@ class OZONE_BASE_EXPORT OverlaySurfaceCandidate { ...@@ -30,8 +30,8 @@ class OZONE_BASE_EXPORT OverlaySurfaceCandidate {
~OverlaySurfaceCandidate(); ~OverlaySurfaceCandidate();
OverlaySurfaceCandidate& operator=(const OverlaySurfaceCandidate& other); OverlaySurfaceCandidate& operator=(const OverlaySurfaceCandidate& other);
// Note that |clip_rect|, |is_clipped| and |overlay_handled| are *not* // Note that |crop_rect|, |clip_rect|, |is_clipped| and |overlay_handled| are
// used as part of the comparison. // *not* used as part of the comparison.
bool operator<(const OverlaySurfaceCandidate& other) const; bool operator<(const OverlaySurfaceCandidate& other) const;
// Transformation to apply to layer during composition. // Transformation to apply to layer during composition.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment