Chromium Code Reviews| Index: ui/ozone/platform/drm/host/drm_overlay_manager.cc |
| diff --git a/ui/ozone/platform/drm/host/drm_overlay_manager.cc b/ui/ozone/platform/drm/host/drm_overlay_manager.cc |
| index 26410b3f94c606e095b36bd42966cda33f33f4ea..ec30186db96beafab2d7e04350a0be066fdd2245 100644 |
| --- a/ui/ozone/platform/drm/host/drm_overlay_manager.cc |
| +++ b/ui/ozone/platform/drm/host/drm_overlay_manager.cc |
| @@ -1,87 +1,156 @@ |
| -// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Copyright 2016 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/host/drm_overlay_manager.h" |
| +#include <stddef.h> |
| + |
| +#include <algorithm> |
| + |
| +#include "base/command_line.h" |
| #include "ui/gfx/geometry/rect_conversions.h" |
| #include "ui/ozone/common/gpu/ozone_gpu_messages.h" |
|
dnicoara
2016/02/03 14:54:30
nit: Maybe remove this include.
rjkroege
2016/02/04 00:09:40
Done.
|
| -#include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h" |
| #include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h" |
| #include "ui/ozone/platform/drm/host/drm_window_host.h" |
| #include "ui/ozone/platform/drm/host/drm_window_host_manager.h" |
| -#include "ui/ozone/public/overlay_candidates_ozone.h" |
| +#include "ui/ozone/public/ozone_switches.h" |
| namespace ui { |
| -DrmOverlayManager::DrmOverlayManager( |
| - DrmGpuPlatformSupportHost* platform_support_host, |
| - DrmWindowHostManager* window_manager) |
| - : sender_(new OverlayCandidatesIPC(platform_support_host, this)), |
| - core_(new DrmOverlayManagerCore(sender_.get(), window_manager)) {} |
| +typedef OverlayCandidatesOzone::OverlaySurfaceCandidateList |
| + OverlaySurfaceCandidateList; |
| +typedef OverlayCandidatesOzone::OverlaySurfaceCandidate OverlaySurfaceCandidate; |
| + |
| +namespace { |
| +const size_t kMaxCacheSize = 200; |
| +} // namespace |
| + |
| +DrmOverlayManager::DrmOverlayManager(GpuThreadAdapter* proxy, |
| + DrmWindowHostManager* window_manager) |
| + : proxy_(proxy), window_manager_(window_manager), cache_(kMaxCacheSize) { |
| + is_supported_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kOzoneTestSingleOverlaySupport); |
| + proxy_->RegisterHandlerForDrmOverlayManager(this); |
| +} |
| DrmOverlayManager::~DrmOverlayManager() { |
| + proxy_->UnRegisterHandlerForDrmOverlayManager(); |
| } |
| scoped_ptr<OverlayCandidatesOzone> DrmOverlayManager::CreateOverlayCandidates( |
| gfx::AcceleratedWidget w) { |
| - return core_->CreateOverlayCandidates(w); |
| + if (!is_supported_) |
| + return nullptr; |
| + return make_scoped_ptr(new DrmOverlayCandidatesHost(this, w)); |
| } |
| -void DrmOverlayManager::OnChannelEstablished( |
| - int host_id, |
| - scoped_refptr<base::SingleThreadTaskRunner> send_runner, |
| - const base::Callback<void(IPC::Message*)>& sender) { |
| - core_->ResetCache(); |
| -} |
| - |
| -void DrmOverlayManager::OnChannelDestroyed(int host_id) {} |
| - |
| -bool DrmOverlayManager::OnMessageReceived(const IPC::Message& message) { |
| - bool handled = true; |
| - IPC_BEGIN_MESSAGE_MAP(DrmOverlayManager, message) |
| - IPC_MESSAGE_HANDLER(OzoneHostMsg_OverlayCapabilitiesReceived, |
| - OnOverlayResult) |
| - IPC_MESSAGE_UNHANDLED(handled = false) |
| - IPC_END_MESSAGE_MAP() |
| - return handled; |
| +void DrmOverlayManager::CheckOverlaySupport( |
| + OverlayCandidatesOzone::OverlaySurfaceCandidateList* candidates, |
| + gfx::AcceleratedWidget widget) { |
| + std::vector<OverlayCheck_Params> overlay_params; |
| + for (auto& candidate : *candidates) { |
| + // Reject candidates that don't fall on a pixel boundary. |
| + if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f)) { |
| + DCHECK(candidate.plane_z_order != 0); |
| + overlay_params.push_back(OverlayCheck_Params()); |
| + overlay_params.back().is_overlay_candidate = false; |
| + continue; |
| + } |
| + |
| + // Compositor doesn't have information about the total size of primary |
| + // candidate. We get this information from display rect. |
| + if (candidate.plane_z_order == 0) |
| + candidate.buffer_size = gfx::ToNearestRect(candidate.display_rect).size(); |
| + |
| + overlay_params.push_back(OverlayCheck_Params(candidate)); |
| + } |
| + |
| + const auto& iter = cache_.Get(overlay_params); |
| + // We are still waiting on results for this candidate list from GPU. |
| + if (iter != cache_.end() && iter->second) |
| + return; |
| + |
| + size_t size = candidates->size(); |
| + |
| + if (iter == cache_.end()) { |
| + // We can skip GPU side validation in case all candidates are invalid. |
| + bool needs_gpu_validation = false; |
| + for (size_t i = 0; i < size; i++) { |
| + if (!overlay_params.at(i).is_overlay_candidate) |
| + continue; |
| + |
| + const OverlaySurfaceCandidate& candidate = candidates->at(i); |
| + if (!CanHandleCandidate(candidate, widget)) { |
| + DCHECK(candidate.plane_z_order != 0); |
| + overlay_params.at(i).is_overlay_candidate = false; |
| + continue; |
| + } |
| + |
| + needs_gpu_validation = true; |
| + } |
| + |
| + cache_.Put(overlay_params, needs_gpu_validation); |
| + |
| + if (needs_gpu_validation) |
| + SendOverlayValidationRequest(overlay_params, widget); |
| + } else { |
| + const std::vector<OverlayCheck_Params>& validated_params = iter->first; |
| + DCHECK(size == validated_params.size()); |
| + |
| + for (size_t i = 0; i < size; i++) { |
| + candidates->at(i).overlay_handled = |
| + validated_params.at(i).is_overlay_candidate; |
| + } |
| + } |
| } |
| void DrmOverlayManager::ResetCache() { |
| - core_->ResetCache(); |
| -} |
| - |
| -void DrmOverlayManager::OnOverlayResult( |
| - gfx::AcceleratedWidget widget, |
| - const std::vector<OverlayCheck_Params>& params) { |
| - core_->GpuSentOverlayResult(widget, params); |
| + cache_.Clear(); |
| } |
| -// TODO(rjkroege): There is a refactoring opportunity in the sender pattern. |
| -DrmOverlayManager::OverlayCandidatesIPC::OverlayCandidatesIPC( |
| - DrmGpuPlatformSupportHost* platform_support, |
| - DrmOverlayManager* parent) |
| - : platform_support_(platform_support), parent_(parent) {} |
| +void DrmOverlayManager::SendOverlayValidationRequest( |
| + const std::vector<OverlayCheck_Params>& new_params, |
| + gfx::AcceleratedWidget widget) const { |
| + if (!proxy_->IsConnected()) |
| + return; |
| -DrmOverlayManager::OverlayCandidatesIPC::~OverlayCandidatesIPC() {} |
| - |
| -void DrmOverlayManager::OverlayCandidatesIPC::UnregisterHandler() { |
| - platform_support_->UnregisterHandler(parent_); |
| + proxy_->GpuCheckOverlayCapabilities(widget, new_params); |
| } |
| -void DrmOverlayManager::OverlayCandidatesIPC::RegisterHandler() { |
| - platform_support_->RegisterHandler(parent_); |
| -} |
| - |
| -bool DrmOverlayManager::OverlayCandidatesIPC::IsConnected() { |
| - return platform_support_->IsConnected(); |
| +void DrmOverlayManager::GpuSentOverlayResult( |
| + gfx::AcceleratedWidget widget, |
| + const std::vector<OverlayCheck_Params>& params) { |
| + cache_.Put(params, false); |
| } |
| -bool DrmOverlayManager::OverlayCandidatesIPC::CheckOverlayCapabilities( |
| - gfx::AcceleratedWidget widget, |
| - const std::vector<OverlayCheck_Params>& new_params) { |
| - return platform_support_->Send( |
| - new OzoneGpuMsg_CheckOverlayCapabilities(widget, new_params)); |
| +bool DrmOverlayManager::CanHandleCandidate( |
| + const OverlaySurfaceCandidate& candidate, |
| + gfx::AcceleratedWidget widget) const { |
| + if (candidate.buffer_size.IsEmpty()) |
| + return false; |
| + |
| + if (candidate.transform == gfx::OVERLAY_TRANSFORM_INVALID) |
| + return false; |
| + |
| + if (candidate.plane_z_order != 0) { |
| + // It is possible that the cc rect we get actually falls off the edge of |
| + // the screen. Usually this is prevented via things like status bars |
| + // blocking overlaying or cc clipping it, but in case it wasn't properly |
| + // clipped (since GL will render this situation fine) just ignore it |
| + // here. This should be an extremely rare occurrance. |
| + DrmWindowHost* window = window_manager_->GetWindow(widget); |
| + if (!window->GetBounds().Contains( |
| + gfx::ToNearestRect(candidate.display_rect))) { |
| + return false; |
| + } |
| + } |
| + |
| + if (candidate.is_clipped && |
| + !candidate.clip_rect.Contains(candidate.quad_rect_in_target_space)) |
| + return false; |
| + |
| + return true; |
| } |
| } // namespace ui |