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 |