Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/ozone/platform/drm/host/drm_overlay_manager.h" | 5 #include "ui/ozone/platform/drm/host/drm_overlay_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #include "base/command_line.h" | |
| 7 #include "ui/gfx/geometry/rect_conversions.h" | 12 #include "ui/gfx/geometry/rect_conversions.h" |
| 8 #include "ui/ozone/common/gpu/ozone_gpu_messages.h" | 13 #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.
| |
| 9 #include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h" | |
| 10 #include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h" | 14 #include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h" |
| 11 #include "ui/ozone/platform/drm/host/drm_window_host.h" | 15 #include "ui/ozone/platform/drm/host/drm_window_host.h" |
| 12 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h" | 16 #include "ui/ozone/platform/drm/host/drm_window_host_manager.h" |
| 13 #include "ui/ozone/public/overlay_candidates_ozone.h" | 17 #include "ui/ozone/public/ozone_switches.h" |
| 14 | 18 |
| 15 namespace ui { | 19 namespace ui { |
| 16 | 20 |
| 17 DrmOverlayManager::DrmOverlayManager( | 21 typedef OverlayCandidatesOzone::OverlaySurfaceCandidateList |
| 18 DrmGpuPlatformSupportHost* platform_support_host, | 22 OverlaySurfaceCandidateList; |
| 19 DrmWindowHostManager* window_manager) | 23 typedef OverlayCandidatesOzone::OverlaySurfaceCandidate OverlaySurfaceCandidate; |
| 20 : sender_(new OverlayCandidatesIPC(platform_support_host, this)), | 24 |
| 21 core_(new DrmOverlayManagerCore(sender_.get(), window_manager)) {} | 25 namespace { |
| 26 const size_t kMaxCacheSize = 200; | |
| 27 } // namespace | |
| 28 | |
| 29 DrmOverlayManager::DrmOverlayManager(GpuThreadAdapter* proxy, | |
| 30 DrmWindowHostManager* window_manager) | |
| 31 : proxy_(proxy), window_manager_(window_manager), cache_(kMaxCacheSize) { | |
| 32 is_supported_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 33 switches::kOzoneTestSingleOverlaySupport); | |
| 34 proxy_->RegisterHandlerForDrmOverlayManager(this); | |
| 35 } | |
| 22 | 36 |
| 23 DrmOverlayManager::~DrmOverlayManager() { | 37 DrmOverlayManager::~DrmOverlayManager() { |
| 38 proxy_->UnRegisterHandlerForDrmOverlayManager(); | |
| 24 } | 39 } |
| 25 | 40 |
| 26 scoped_ptr<OverlayCandidatesOzone> DrmOverlayManager::CreateOverlayCandidates( | 41 scoped_ptr<OverlayCandidatesOzone> DrmOverlayManager::CreateOverlayCandidates( |
| 27 gfx::AcceleratedWidget w) { | 42 gfx::AcceleratedWidget w) { |
| 28 return core_->CreateOverlayCandidates(w); | 43 if (!is_supported_) |
| 44 return nullptr; | |
| 45 return make_scoped_ptr(new DrmOverlayCandidatesHost(this, w)); | |
| 29 } | 46 } |
| 30 | 47 |
| 31 void DrmOverlayManager::OnChannelEstablished( | 48 void DrmOverlayManager::CheckOverlaySupport( |
| 32 int host_id, | 49 OverlayCandidatesOzone::OverlaySurfaceCandidateList* candidates, |
| 33 scoped_refptr<base::SingleThreadTaskRunner> send_runner, | 50 gfx::AcceleratedWidget widget) { |
| 34 const base::Callback<void(IPC::Message*)>& sender) { | 51 std::vector<OverlayCheck_Params> overlay_params; |
| 35 core_->ResetCache(); | 52 for (auto& candidate : *candidates) { |
| 36 } | 53 // Reject candidates that don't fall on a pixel boundary. |
| 54 if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f)) { | |
| 55 DCHECK(candidate.plane_z_order != 0); | |
| 56 overlay_params.push_back(OverlayCheck_Params()); | |
| 57 overlay_params.back().is_overlay_candidate = false; | |
| 58 continue; | |
| 59 } | |
| 37 | 60 |
| 38 void DrmOverlayManager::OnChannelDestroyed(int host_id) {} | 61 // Compositor doesn't have information about the total size of primary |
| 62 // candidate. We get this information from display rect. | |
| 63 if (candidate.plane_z_order == 0) | |
| 64 candidate.buffer_size = gfx::ToNearestRect(candidate.display_rect).size(); | |
| 39 | 65 |
| 40 bool DrmOverlayManager::OnMessageReceived(const IPC::Message& message) { | 66 overlay_params.push_back(OverlayCheck_Params(candidate)); |
| 41 bool handled = true; | 67 } |
| 42 IPC_BEGIN_MESSAGE_MAP(DrmOverlayManager, message) | 68 |
| 43 IPC_MESSAGE_HANDLER(OzoneHostMsg_OverlayCapabilitiesReceived, | 69 const auto& iter = cache_.Get(overlay_params); |
| 44 OnOverlayResult) | 70 // We are still waiting on results for this candidate list from GPU. |
| 45 IPC_MESSAGE_UNHANDLED(handled = false) | 71 if (iter != cache_.end() && iter->second) |
| 46 IPC_END_MESSAGE_MAP() | 72 return; |
| 47 return handled; | 73 |
| 74 size_t size = candidates->size(); | |
| 75 | |
| 76 if (iter == cache_.end()) { | |
| 77 // We can skip GPU side validation in case all candidates are invalid. | |
| 78 bool needs_gpu_validation = false; | |
| 79 for (size_t i = 0; i < size; i++) { | |
| 80 if (!overlay_params.at(i).is_overlay_candidate) | |
| 81 continue; | |
| 82 | |
| 83 const OverlaySurfaceCandidate& candidate = candidates->at(i); | |
| 84 if (!CanHandleCandidate(candidate, widget)) { | |
| 85 DCHECK(candidate.plane_z_order != 0); | |
| 86 overlay_params.at(i).is_overlay_candidate = false; | |
| 87 continue; | |
| 88 } | |
| 89 | |
| 90 needs_gpu_validation = true; | |
| 91 } | |
| 92 | |
| 93 cache_.Put(overlay_params, needs_gpu_validation); | |
| 94 | |
| 95 if (needs_gpu_validation) | |
| 96 SendOverlayValidationRequest(overlay_params, widget); | |
| 97 } else { | |
| 98 const std::vector<OverlayCheck_Params>& validated_params = iter->first; | |
| 99 DCHECK(size == validated_params.size()); | |
| 100 | |
| 101 for (size_t i = 0; i < size; i++) { | |
| 102 candidates->at(i).overlay_handled = | |
| 103 validated_params.at(i).is_overlay_candidate; | |
| 104 } | |
| 105 } | |
| 48 } | 106 } |
| 49 | 107 |
| 50 void DrmOverlayManager::ResetCache() { | 108 void DrmOverlayManager::ResetCache() { |
| 51 core_->ResetCache(); | 109 cache_.Clear(); |
| 52 } | 110 } |
| 53 | 111 |
| 54 void DrmOverlayManager::OnOverlayResult( | 112 void DrmOverlayManager::SendOverlayValidationRequest( |
| 113 const std::vector<OverlayCheck_Params>& new_params, | |
| 114 gfx::AcceleratedWidget widget) const { | |
| 115 if (!proxy_->IsConnected()) | |
| 116 return; | |
| 117 | |
| 118 proxy_->GpuCheckOverlayCapabilities(widget, new_params); | |
| 119 } | |
| 120 | |
| 121 void DrmOverlayManager::GpuSentOverlayResult( | |
| 55 gfx::AcceleratedWidget widget, | 122 gfx::AcceleratedWidget widget, |
| 56 const std::vector<OverlayCheck_Params>& params) { | 123 const std::vector<OverlayCheck_Params>& params) { |
| 57 core_->GpuSentOverlayResult(widget, params); | 124 cache_.Put(params, false); |
| 58 } | 125 } |
| 59 | 126 |
| 60 // TODO(rjkroege): There is a refactoring opportunity in the sender pattern. | 127 bool DrmOverlayManager::CanHandleCandidate( |
| 61 DrmOverlayManager::OverlayCandidatesIPC::OverlayCandidatesIPC( | 128 const OverlaySurfaceCandidate& candidate, |
| 62 DrmGpuPlatformSupportHost* platform_support, | 129 gfx::AcceleratedWidget widget) const { |
| 63 DrmOverlayManager* parent) | 130 if (candidate.buffer_size.IsEmpty()) |
| 64 : platform_support_(platform_support), parent_(parent) {} | 131 return false; |
| 65 | 132 |
| 66 DrmOverlayManager::OverlayCandidatesIPC::~OverlayCandidatesIPC() {} | 133 if (candidate.transform == gfx::OVERLAY_TRANSFORM_INVALID) |
| 134 return false; | |
| 67 | 135 |
| 68 void DrmOverlayManager::OverlayCandidatesIPC::UnregisterHandler() { | 136 if (candidate.plane_z_order != 0) { |
| 69 platform_support_->UnregisterHandler(parent_); | 137 // It is possible that the cc rect we get actually falls off the edge of |
| 70 } | 138 // the screen. Usually this is prevented via things like status bars |
| 139 // blocking overlaying or cc clipping it, but in case it wasn't properly | |
| 140 // clipped (since GL will render this situation fine) just ignore it | |
| 141 // here. This should be an extremely rare occurrance. | |
| 142 DrmWindowHost* window = window_manager_->GetWindow(widget); | |
| 143 if (!window->GetBounds().Contains( | |
| 144 gfx::ToNearestRect(candidate.display_rect))) { | |
| 145 return false; | |
| 146 } | |
| 147 } | |
| 71 | 148 |
| 72 void DrmOverlayManager::OverlayCandidatesIPC::RegisterHandler() { | 149 if (candidate.is_clipped && |
| 73 platform_support_->RegisterHandler(parent_); | 150 !candidate.clip_rect.Contains(candidate.quad_rect_in_target_space)) |
| 74 } | 151 return false; |
| 75 | 152 |
| 76 bool DrmOverlayManager::OverlayCandidatesIPC::IsConnected() { | 153 return true; |
| 77 return platform_support_->IsConnected(); | |
| 78 } | |
| 79 | |
| 80 bool DrmOverlayManager::OverlayCandidatesIPC::CheckOverlayCapabilities( | |
| 81 gfx::AcceleratedWidget widget, | |
| 82 const std::vector<OverlayCheck_Params>& new_params) { | |
| 83 return platform_support_->Send( | |
| 84 new OzoneGpuMsg_CheckOverlayCapabilities(widget, new_params)); | |
| 85 } | 154 } |
| 86 | 155 |
| 87 } // namespace ui | 156 } // namespace ui |
| OLD | NEW |