Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(651)

Side by Side Diff: ui/ozone/platform/drm/host/drm_overlay_candidates_host.cc

Issue 1426993003: Ozone: Dont hardcode format to YUV when using Overlay Composition. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cosmetic fixes Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_candidates_host.h" 5 #include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ui/gfx/geometry/rect_conversions.h" 9 #include "ui/gfx/geometry/rect_conversions.h"
10 #include "ui/ozone/common/gpu/ozone_gpu_messages.h" 10 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
(...skipping 25 matching lines...) Expand all
36 return true; 36 return true;
37 if (l.transform > r.transform) 37 if (l.transform > r.transform)
38 return false; 38 return false;
39 if (l.buffer_size.width() < r.buffer_size.width()) 39 if (l.buffer_size.width() < r.buffer_size.width())
40 return true; 40 return true;
41 if (l.buffer_size.width() > r.buffer_size.width()) 41 if (l.buffer_size.width() > r.buffer_size.width())
42 return false; 42 return false;
43 return l.buffer_size.height() < r.buffer_size.height(); 43 return l.buffer_size.height() < r.buffer_size.height();
44 } 44 }
45 45
46 DrmOverlayCandidatesHost::HardwareDisplayPlaneProxy::HardwareDisplayPlaneProxy(
47 uint32_t id)
48 : plane_id(id) {}
49
50 DrmOverlayCandidatesHost::HardwareDisplayPlaneProxy::
51 ~HardwareDisplayPlaneProxy() {}
52
53 DrmOverlayCandidatesHost::DrmOverlayCandidatesHost( 46 DrmOverlayCandidatesHost::DrmOverlayCandidatesHost(
54 DrmGpuPlatformSupportHost* platform_support, 47 DrmGpuPlatformSupportHost* platform_support,
55 DrmWindowHost* window) 48 DrmWindowHost* window)
56 : platform_support_(platform_support), 49 : platform_support_(platform_support),
57 window_(window), 50 window_(window),
58 cache_(kMaxCacheSize) { 51 cache_(kMaxCacheSize) {
59 platform_support_->RegisterHandler(this); 52 platform_support_->RegisterHandler(this);
60 window_->SetOverlayCandidatesHost(this); 53 window_->SetOverlayCandidatesHost(this);
61 } 54 }
62 55
63 DrmOverlayCandidatesHost::~DrmOverlayCandidatesHost() { 56 DrmOverlayCandidatesHost::~DrmOverlayCandidatesHost() {
64 platform_support_->UnregisterHandler(this); 57 platform_support_->UnregisterHandler(this);
65 window_->SetOverlayCandidatesHost(nullptr); 58 window_->SetOverlayCandidatesHost(nullptr);
66 } 59 }
67 60
68 void DrmOverlayCandidatesHost::CheckOverlaySupport( 61 void DrmOverlayCandidatesHost::CheckOverlaySupport(
69 OverlaySurfaceCandidateList* candidates) { 62 OverlaySurfaceCandidateList* candidates) {
70 uint32_t compatible_candidates = 0; 63 bool validate_params = false;
71 uint32_t planes_in_use = 0;
72 bool force_validation = false;
73 std::vector<OverlayCheck_Params> new_candidates;
74 for (auto& candidate : *candidates) { 64 for (auto& candidate : *candidates) {
75 if (!CanHandleCandidate(candidate)) 65 if (!CanHandleCandidate(candidate))
76 continue; 66 continue;
77 67
68 if (candidate.plane_z_order == 0)
69 candidate.buffer_size = window_->GetBounds().size();
70
71 // TODO(kalyank): We should get correct storage format used for Video from
72 // GPU process.
73 if (candidate.format == gfx::BufferFormat::BGRA_8888)
74 candidate.format = gfx::BufferFormat::BGRX_8888;
75
78 OverlayCheck_Params lookup(candidate); 76 OverlayCheck_Params lookup(candidate);
79 if (!force_validation) {
80 CompatibleParams::const_iterator last_iter =
81 in_use_compatible_params_.find(lookup);
82 if (last_iter != in_use_compatible_params_.end()) {
83 candidate.overlay_handled = last_iter->second;
84 compatible_candidates++;
85 if (candidate.overlay_handled)
86 planes_in_use++;
87 77
88 continue; 78 std::vector<OverlayCheck_Params>::iterator it;
89 } 79 it = std::find(in_use_params_.begin(), in_use_params_.end(), lookup);
80 if (it != in_use_params_.end()) {
81 candidate.overlay_handled = it->state == OverlayCheck_Params::kOverlay;
82 continue;
90 } 83 }
91 84
92 auto iter = cache_.Get(lookup); 85 auto iter = cache_.Peek(lookup);
93 if (iter == cache_.end()) { 86 if (iter == cache_.end()) {
94 lookup.weight = CalculateCandidateWeight(candidate); 87 lookup.weight = CalculateCandidateWeight(candidate);
95 cache_.Put(lookup, false);
96 // It is possible that the cc rect we get actually falls off the edge of 88 // It is possible that the cc rect we get actually falls off the edge of
97 // the screen. Usually this is prevented via things like status bars 89 // the screen. Usually this is prevented via things like status bars
98 // blocking overlaying or cc clipping it, but in case it wasn't properly 90 // blocking overlaying or cc clipping it, but in case it wasn't properly
99 // clipped (since GL will render this situation fine) just ignore it here. 91 // clipped (since GL will render this situation fine) just ignore it here.
100 // This should be an extremely rare occurrance. 92 // This should be an extremely rare occurrance.
101 if (lookup.plane_z_order != 0 && 93 if (lookup.plane_z_order != 0 &&
102 !window_->GetBounds().Contains(lookup.display_rect)) { 94 !window_->GetBounds().Contains(lookup.display_rect)) {
103 continue; 95 lookup.state = OverlayCheck_Params::kInvalid;
96 } else {
97 lookup.state = OverlayCheck_Params::kTest;
98 validate_params = true;
104 } 99 }
105 100
106 new_candidates.push_back(lookup); 101 cache_.Put(lookup, lookup.state);
107 } else if (iter->second) { 102 } else if (iter->second == OverlayCheck_Params::kCompatible) {
108 force_validation = true; 103 validate_params = true;
109 } 104 }
110 } 105 }
111 106
112 // We have new candidates whose configuration needs to be validated in GPU 107 if (validate_params)
113 // side. 108 ValidateCandidates(*candidates);
114 if (!new_candidates.empty())
115 SendRequest(new_candidates);
116
117 if (compatible_candidates > planes_in_use &&
118 planes_in_use < hardware_plane_proxy_.size()) {
119 force_validation = true;
120 }
121
122 if (!force_validation) {
123 DCHECK(planes_in_use <= hardware_plane_proxy_.size())
124 << "Total layers promoted to use Overlay:" << planes_in_use
125 << "While the maximum layers which can be actually supported are:"
126 << hardware_plane_proxy_.size();
127 return;
128 }
129
130 // A new layer has been added or removed from the last validation. We expect
131 // this to be very rare situation, hence not fully optimized. We always
132 // validate the new combination of layers.
133 ValidateCandidates(candidates);
134 } 109 }
135 110
136 void DrmOverlayCandidatesHost::OnChannelEstablished( 111 void DrmOverlayCandidatesHost::OnChannelEstablished(
137 int host_id, 112 int host_id,
138 scoped_refptr<base::SingleThreadTaskRunner> send_runner, 113 scoped_refptr<base::SingleThreadTaskRunner> send_runner,
139 const base::Callback<void(IPC::Message*)>& sender) { 114 const base::Callback<void(IPC::Message*)>& sender) {
140 // Reset any old cache. 115 // Reset any old cache.
141 ResetCache(); 116 ResetCache();
142 } 117 }
143 118
144 void DrmOverlayCandidatesHost::OnChannelDestroyed(int host_id) { 119 void DrmOverlayCandidatesHost::OnChannelDestroyed(int host_id) {
145 } 120 }
146 121
147 bool DrmOverlayCandidatesHost::OnMessageReceived(const IPC::Message& message) { 122 bool DrmOverlayCandidatesHost::OnMessageReceived(const IPC::Message& message) {
148 bool handled = false; 123 bool handled = false;
149 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(DrmOverlayCandidatesHost, message, &handled) 124 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(DrmOverlayCandidatesHost, message, &handled)
150 IPC_MESSAGE_FORWARD(OzoneHostMsg_OverlayCapabilitiesReceived, this, 125 IPC_MESSAGE_FORWARD(OzoneHostMsg_OverlayCapabilitiesReceived, this,
151 DrmOverlayCandidatesHost::OnOverlayResult) 126 DrmOverlayCandidatesHost::OnOverlayResult)
152 IPC_END_MESSAGE_MAP() 127 IPC_END_MESSAGE_MAP()
153 return handled; 128 return handled;
154 } 129 }
155 130
156 void DrmOverlayCandidatesHost::ResetCache() { 131 void DrmOverlayCandidatesHost::ResetCache() {
157 cache_.Clear(); 132 cache_.Clear();
158 in_use_compatible_params_.clear(); 133 in_use_params_.clear();
159 hardware_plane_proxy_.clear();
160 } 134 }
161 135
162 void DrmOverlayCandidatesHost::SendRequest( 136 void DrmOverlayCandidatesHost::SendRequest(
163 const std::vector<OverlayCheck_Params>& list) { 137 const std::vector<OverlayCheck_Params>& current_list,
138 const std::vector<OverlayCheck_Params>& new_list) {
164 if (!platform_support_->IsConnected()) 139 if (!platform_support_->IsConnected())
165 return; 140 return;
166 141
167 platform_support_->Send(new OzoneGpuMsg_CheckOverlayCapabilities( 142 platform_support_->Send(new OzoneGpuMsg_CheckOverlayCapabilities(
168 window_->GetAcceleratedWidget(), list)); 143 window_->GetAcceleratedWidget(), current_list, new_list));
169 } 144 }
170 145
171 void DrmOverlayCandidatesHost::OnOverlayResult( 146 void DrmOverlayCandidatesHost::OnOverlayResult(
172 bool* handled, 147 bool* handled,
173 gfx::AcceleratedWidget widget, 148 gfx::AcceleratedWidget widget,
174 const std::vector<OverlayCheck_Params>& params) { 149 const std::vector<OverlayCheck_Params>& params) {
175 if (widget != window_->GetAcceleratedWidget()) 150 if (widget != window_->GetAcceleratedWidget())
176 return; 151 return;
177 152
178 *handled = true; 153 *handled = true;
154 for (const auto& compatible_param : in_use_params_) {
155 OverlayCheck_Params param = compatible_param;
156 if (param.state == OverlayCheck_Params::kOverlay)
157 param.state = OverlayCheck_Params::kCompatible;
158
159 cache_.Put(param, OverlayCheck_Params::kCompatible);
160 }
161
162 in_use_params_.clear();
179 for (const auto& check : params) { 163 for (const auto& check : params) {
180 // We expect params to contain only supported configurations. 164 in_use_params_.push_back(check);
181 cache_.Put(check, true); 165 cache_.Put(check, OverlayCheck_Params::kCompatible);
182 for (const auto& plane_id : check.plane_ids) {
183 bool plane_found = false;
184 for (const auto* plane : hardware_plane_proxy_) {
185 if (plane->plane_id == plane_id) {
186 plane_found = true;
187 break;
188 }
189 }
190
191 if (!plane_found) {
192 hardware_plane_proxy_.push_back(
193 make_scoped_ptr(new HardwareDisplayPlaneProxy(plane_id)));
194 }
195 }
196 } 166 }
197 } 167 }
198 168
199 bool DrmOverlayCandidatesHost::CanHandleCandidate( 169 bool DrmOverlayCandidatesHost::CanHandleCandidate(
200 const OverlaySurfaceCandidate& candidate) const { 170 const OverlaySurfaceCandidate& candidate) const {
201 // 0.01 constant chosen to match DCHECKs in gfx::ToNearestRect and avoid 171 // 0.01 constant chosen to match DCHECKs in gfx::ToNearestRect and avoid
202 // that code asserting on quads that we accept. 172 // that code asserting on quads that we accept.
203 if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f)) 173 if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f))
204 return false; 174 return false;
205 175
(...skipping 27 matching lines...) Expand all
233 weight++; 203 weight++;
234 } 204 }
235 205
236 // TODO(kalyank): We want to consider size based on power benefits. 206 // TODO(kalyank): We want to consider size based on power benefits.
237 } 207 }
238 208
239 return weight; 209 return weight;
240 } 210 }
241 211
242 void DrmOverlayCandidatesHost::ValidateCandidates( 212 void DrmOverlayCandidatesHost::ValidateCandidates(
243 OverlaySurfaceCandidateList* candidates) { 213 const OverlaySurfaceCandidateList& candidates) {
244 // Make sure params being currently used are in cache. They might have been 214 std::vector<OverlayCheck_Params> current_overlay_params;
245 // removed in case we haven't tried to get them from cache for a while. 215 std::vector<OverlayCheck_Params> new_params;
246 for (const auto& param : in_use_compatible_params_) 216 for (const auto& param : in_use_params_) {
247 cache_.Put(param.first, true); 217 if (param.state == OverlayCheck_Params::kOverlay)
218 current_overlay_params.push_back(param);
248 219
249 in_use_compatible_params_.clear(); 220 // Make sure params being currently used are in cache. They might have
250 typedef std::pair<OverlaySurfaceCandidate*, OverlayCheck_Params> 221 // been removed in case we haven't tried to get them from cache for a
251 CandidatePair; 222 // while.
252 std::vector<CandidatePair> compatible_candidates; 223 cache_.Put(param, OverlayCheck_Params::kCompatible);
253 for (auto& candidate : *candidates) { 224 }
254 candidate.overlay_handled = false;
255 225
226 for (const auto& candidate : candidates) {
256 if (!CanHandleCandidate(candidate)) 227 if (!CanHandleCandidate(candidate))
257 continue; 228 continue;
258 229
259 OverlayCheck_Params lookup(candidate); 230 OverlayCheck_Params lookup(candidate);
260 auto iter = cache_.Peek(lookup); 231 auto iter = cache_.Get(lookup);
261 DCHECK(iter != cache_.end()); 232 DCHECK(iter != cache_.end());
262 if (!iter->second) 233 if (iter->second != OverlayCheck_Params::kInvalid)
263 continue; 234 new_params.push_back(lookup);
264
265 in_use_compatible_params_[iter->first] = false;
266 compatible_candidates.push_back(std::make_pair(&candidate, iter->first));
267 } 235 }
268 236
269 uint32_t available_overlays = hardware_plane_proxy_.size();
270 for (auto* plane : hardware_plane_proxy_)
271 plane->in_use = false;
272
273 // Sort in decending order w.r.t weight. 237 // Sort in decending order w.r.t weight.
274 std::sort(compatible_candidates.begin(), compatible_candidates.end(), 238 std::sort(new_params.begin(), new_params.end(),
275 [](const CandidatePair& l, const CandidatePair& r) { 239 [](const OverlayCheck_Params& l, const OverlayCheck_Params& r) {
276 return l.second.weight > r.second.weight; 240 return l.weight > r.weight;
277 }); 241 });
278 242
279 // Make sure we don't handle more candidates than what we can support in 243 SendRequest(current_overlay_params, new_params);
280 // GPU side.
281 for (const auto& candidate : compatible_candidates) {
282 for (auto* plane : hardware_plane_proxy_) {
283 // Plane is already in use.
284 if (plane->in_use)
285 continue;
286
287 for (const auto& plane_id : candidate.second.plane_ids) {
288 if (plane->plane_id == plane_id) {
289 available_overlays--;
290 auto iter = in_use_compatible_params_.find(candidate.second);
291 DCHECK(iter != in_use_compatible_params_.end());
292 iter->second = true;
293 candidate.first->overlay_handled = true;
294 plane->in_use = true;
295 break;
296 }
297 }
298
299 // We have succefully found a plane.
300 if (plane->in_use)
301 break;
302 }
303
304 // We dont have any free hardware resources.
305 if (!available_overlays)
306 break;
307 }
308 } 244 }
309 245
310 } // namespace ui 246 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698