Chromium Code Reviews| Index: ui/ozone/platform/drm/host/drm_host_overlay_candidates.cc |
| diff --git a/ui/ozone/platform/drm/host/drm_host_overlay_candidates.cc b/ui/ozone/platform/drm/host/drm_host_overlay_candidates.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2550705b87a4379e969cea0df268fd5cb3d1c877 |
| --- /dev/null |
| +++ b/ui/ozone/platform/drm/host/drm_host_overlay_candidates.cc |
| @@ -0,0 +1,146 @@ |
| +#include "ui/ozone/platform/drm/host/drm_host_overlay_candidates.h" |
| + |
| +#include <algorithm> |
| + |
| +#include "ui/gfx/geometry/rect_conversions.h" |
| +#include "ui/ozone/common/gpu/ozone_gpu_messages.h" |
| +#include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h" |
| + |
| +namespace ui { |
| + |
| +namespace { |
| +const size_t kMaxCacheSize = 10000; |
| +} // namespace |
| + |
| +DrmHostOverlayCandidates::PendingCheck::PendingCheck( |
| + uint32_t id, |
| + const OverlayCheck_Params& overlay) |
| + : request_id(id), overlay(overlay) { |
| +} |
| +DrmHostOverlayCandidates::PendingCheck::~PendingCheck() { |
| +} |
| + |
| +bool DrmHostOverlayCandidates::OverlayCompare::operator()( |
| + const OverlayCheck_Params& l, |
| + const OverlayCheck_Params& r) { |
| + return l.plane_z_order < r.plane_z_order || |
| + (l.plane_z_order == r.plane_z_order && |
| + (l.display_rect < r.display_rect || |
| + (l.display_rect == r.display_rect && |
| + (l.format < r.format || |
| + (l.format == r.format && |
| + (l.transform < r.transform || |
| + (l.transform == r.transform && |
| + (l.buffer_size.width() < r.buffer_size.width() || |
| + (l.buffer_size.width() == r.buffer_size.width() && |
| + l.buffer_size.height() < r.buffer_size.height()))))))))); |
| +} |
| + |
| +DrmHostOverlayCandidates::DrmHostOverlayCandidates( |
| + gfx::AcceleratedWidget widget, |
| + DrmGpuPlatformSupportHost* platform_support) |
| + : channel_established_(false), |
| + next_request_id_(1), |
| + widget_(widget), |
| + platform_support_(platform_support) { |
| + platform_support_->RegisterHandler(this); |
| +} |
| + |
| +DrmHostOverlayCandidates::~DrmHostOverlayCandidates() { |
| + platform_support_->UnregisterHandler(this); |
| +} |
| + |
| +void DrmHostOverlayCandidates::CheckOverlaySupport( |
| + OverlaySurfaceCandidateList* candidates) { |
| + if (candidates->size() == 2) |
| + CheckSingleOverlay(candidates); |
| +} |
| + |
| +void DrmHostOverlayCandidates::CheckSingleOverlay( |
| + OverlaySurfaceCandidateList* candidates) { |
| + OverlayCandidatesOzone::OverlaySurfaceCandidate* first = &(*candidates)[0]; |
| + OverlayCandidatesOzone::OverlaySurfaceCandidate* second = &(*candidates)[1]; |
| + OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay; |
| + if (first->plane_z_order == 0) { |
| + overlay = second; |
| + } else if (second->plane_z_order == 0) { |
| + overlay = first; |
| + } else { |
| + return; |
| + } |
| + // 0.01 constant chosen to match DCHECKs in gfx::ToNearestRect and avoid |
| + // that code asserting on quads that we accept. |
| + if (!gfx::IsNearestRectWithinDistance(overlay->display_rect, 0.01f)) |
| + return; |
| + if (overlay->transform == gfx::OVERLAY_TRANSFORM_INVALID) |
| + return; |
| + |
| + OverlayCheck_Params lookup(*overlay); |
| + auto iter = cache_.find(lookup); |
| + if (iter == cache_.end()) { |
| + if (cache_.size() > kMaxCacheSize) |
| + cache_.clear(); |
| + cache_[lookup] = false; |
| + SendRequest(*candidates, PendingCheck(next_request_id_++, lookup)); |
|
dnicoara
2015/05/28 21:09:54
The more I read, the clearer it is to me that the
achaulk
2015/05/29 18:49:20
Done.
|
| + } else { |
| + overlay->overlay_handled = iter->second; |
| + } |
| +} |
| + |
| +void DrmHostOverlayCandidates::OnChannelEstablished( |
|
dnicoara
2015/05/28 21:09:54
Also, you'll want to clear all pending requests if
achaulk
2015/05/29 18:49:20
If the GPU process goes away nothing matters becau
dnicoara
2015/05/29 19:28:23
I thought the compositor for the primary widget ju
achaulk
2015/05/29 19:36:36
No, the OutputSurface at least gets re-created in
|
| + int host_id, |
| + scoped_refptr<base::SingleThreadTaskRunner> send_runner, |
| + const base::Callback<void(IPC::Message*)>& sender) { |
| + channel_established_ = true; |
|
dnicoara
2015/05/28 21:09:54
You can use DrmGpuPlatformSupportHost::IsConnected
achaulk
2015/05/29 18:49:20
Done.
|
| + send_callback_ = sender; |
| +} |
| + |
| +void DrmHostOverlayCandidates::OnChannelDestroyed(int host_id) { |
| + channel_established_ = false; |
| +} |
| + |
| +bool DrmHostOverlayCandidates::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = false; |
| + IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(DrmHostOverlayCandidates, message, &handled) |
| + IPC_MESSAGE_FORWARD(OzoneHostMsg_OverlayCapabilitiesReceived, this, |
| + DrmHostOverlayCandidates::OnOverlayResult) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +void DrmHostOverlayCandidates::SendRequest( |
| + const OverlaySurfaceCandidateList& candidates, |
| + const PendingCheck& check) { |
| + if (!channel_established_) |
| + return; |
| + pending_checks_.push_back(check); |
| + std::vector<OverlayCheck_Params> list; |
| + for (const auto& candidate : candidates) |
| + list.push_back(OverlayCheck_Params(candidate)); |
| + send_callback_.Run(new OzoneGpuMsg_CheckOverlayCapabilities( |
|
dnicoara
2015/05/28 21:09:54
Should this post taks using the |send_runner|?
FY
achaulk
2015/05/29 18:49:20
Done.
|
| + widget_, check.request_id, list)); |
| +} |
| + |
| +void DrmHostOverlayCandidates::OnOverlayResult(bool* handled, |
| + gfx::AcceleratedWidget widget, |
| + uint32_t id, |
| + bool result) { |
| + if (widget != widget_) |
| + return; |
| + *handled = true; |
| + auto iter = |
| + std::find_if(pending_checks_.begin(), pending_checks_.end(), |
| + [id](const PendingCheck& l) { return l.request_id == id; }); |
| + if (iter == pending_checks_.end()) |
| + return; |
| + ProcessResult(*iter, result); |
| + pending_checks_.erase(iter); |
| +} |
| + |
| +void DrmHostOverlayCandidates::ProcessResult(const PendingCheck& check, |
| + bool result) { |
| + if (result) |
| + cache_[check.overlay] = true; |
| +} |
| + |
| +} // namespace ui |