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

Side by Side Diff: ui/ozone/platform/drm/gpu/drm_overlay_validator.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: Review fixes Created 4 years, 11 months 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/gpu/drm_overlay_validator.h" 5 #include "ui/ozone/platform/drm/gpu/drm_overlay_validator.h"
6 6
7 #include <drm_fourcc.h> 7 #include <drm_fourcc.h>
8 8
9 #include "ui/gfx/geometry/size_conversions.h" 9 #include "ui/gfx/geometry/size_conversions.h"
10 #include "ui/ozone/platform/drm/common/drm_util.h" 10 #include "ui/ozone/platform/drm/common/drm_util.h"
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 100
101 } // namespace 101 } // namespace
102 102
103 DrmOverlayValidator::OverlayHints::OverlayHints(uint32_t format, 103 DrmOverlayValidator::OverlayHints::OverlayHints(uint32_t format,
104 bool scale_buffer) 104 bool scale_buffer)
105 : optimal_format(format), handle_scaling(scale_buffer) {} 105 : optimal_format(format), handle_scaling(scale_buffer) {}
106 106
107 DrmOverlayValidator::OverlayHints::~OverlayHints() {} 107 DrmOverlayValidator::OverlayHints::~OverlayHints() {}
108 108
109 DrmOverlayValidator::DrmOverlayValidator(DrmWindow* window) 109 DrmOverlayValidator::DrmOverlayValidator(
110 : window_(window), overlay_hints_cache_(kMaxCacheSize) {} 110 DrmWindow* window,
111 ScanoutBufferGenerator* buffer_generator)
112 : window_(window),
113 buffer_generator_(buffer_generator),
114 overlay_hints_cache_(kMaxCacheSize) {}
111 115
112 DrmOverlayValidator::~DrmOverlayValidator() {} 116 DrmOverlayValidator::~DrmOverlayValidator() {}
113 117
114 std::vector<OverlayCheck_Params> DrmOverlayValidator::TestPageFlip( 118 std::vector<OverlayCheck_Params> DrmOverlayValidator::TestPageFlip(
115 const std::vector<OverlayCheck_Params>& params, 119 const std::vector<OverlayCheck_Params>& params,
116 const OverlayPlaneList& last_used_planes, 120 const OverlayPlaneList& last_used_planes) {
117 ScanoutBufferGenerator* buffer_generator) {
118 std::vector<OverlayCheck_Params> validated_params = params; 121 std::vector<OverlayCheck_Params> validated_params = params;
119 HardwareDisplayController* controller = window_->GetController(); 122 HardwareDisplayController* controller = window_->GetController();
120 if (!controller) { 123 if (!controller) {
121 // Nothing much we can do here. 124 // Nothing much we can do here.
122 for (auto& overlay : validated_params) 125 for (auto& overlay : validated_params)
123 overlay.is_overlay_candidate = false; 126 overlay.is_overlay_candidate = false;
124 127
125 return validated_params; 128 return validated_params;
126 } 129 }
127 130
128 OverlayPlaneList test_list; 131 OverlayPlaneList test_list;
129 std::vector<scoped_refptr<ScanoutBuffer>> reusable_buffers; 132 std::vector<scoped_refptr<ScanoutBuffer>> reusable_buffers;
130 scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice(); 133 scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice();
131 134
132 for (const auto& plane : last_used_planes) 135 for (const auto& plane : last_used_planes)
133 reusable_buffers.push_back(plane.buffer); 136 reusable_buffers.push_back(plane.buffer);
134 137
135 for (auto& overlay : validated_params) { 138 for (auto& overlay : validated_params) {
136 if (!overlay.is_overlay_candidate) 139 if (!overlay.is_overlay_candidate)
137 continue; 140 continue;
138 141
139 gfx::Size scaled_buffer_size = GetScaledSize( 142 gfx::Size scaled_buffer_size = GetScaledSize(
140 overlay.buffer_size, overlay.display_rect, overlay.crop_rect); 143 overlay.buffer_size, overlay.display_rect, overlay.crop_rect);
141 144
142 scoped_refptr<ScanoutBuffer> buffer = GetBufferForPageFlipTest( 145 scoped_refptr<ScanoutBuffer> buffer = GetBufferForPageFlipTest(
143 drm, scaled_buffer_size, GetFourCCFormatForFramebuffer(overlay.format), 146 drm, scaled_buffer_size, GetFourCCFormatForFramebuffer(overlay.format),
144 buffer_generator, &reusable_buffers); 147 buffer_generator_, &reusable_buffers);
145 DCHECK(buffer); 148 DCHECK(buffer);
146 149
147 OverlayPlane plane(buffer, overlay.plane_z_order, overlay.transform, 150 OverlayPlane plane(buffer, overlay.plane_z_order, overlay.transform,
148 overlay.display_rect, overlay.crop_rect); 151 overlay.display_rect, overlay.crop_rect);
149 test_list.push_back(plane); 152 test_list.push_back(plane);
150 153
151 if (controller->TestPageFlip(test_list)) { 154 if (controller->TestPageFlip(test_list)) {
152 overlay.is_overlay_candidate = true; 155 overlay.is_overlay_candidate = true;
153 } else { 156 } else {
154 // If test failed here, platform cannot support this configuration 157 // If test failed here, platform cannot support this configuration
155 // with current combination of layers. This is usually the case when this 158 // with current combination of layers. This is usually the case when this
156 // plane has requested post processing capability which needs additional 159 // plane has requested post processing capability which needs additional
157 // hardware resources and they might be already in use by other planes. 160 // hardware resources and they might be already in use by other planes.
158 // For example this plane has requested scaling capabilities and all 161 // For example this plane has requested scaling capabilities and all
159 // available scalars are already in use by other planes. 162 // available scalars are already in use by other planes.
160 DCHECK(test_list.size() > 1); 163 DCHECK(test_list.size() > 1);
161 overlay.is_overlay_candidate = false; 164 overlay.is_overlay_candidate = false;
162 test_list.pop_back(); 165 test_list.pop_back();
163 } 166 }
164 } 167 }
165 168
166 UpdateOverlayHintsCache(drm, test_list, buffer_generator, &reusable_buffers); 169 UpdateOverlayHintsCache(drm, test_list, &reusable_buffers);
167 170
168 return validated_params; 171 return validated_params;
169 } 172 }
170 173
171 uint32_t DrmOverlayValidator::GetOptimalBufferFormat( 174 OverlayPlaneList DrmOverlayValidator::PrepareBuffersForPageFlip(
172 const OverlayPlane& plane, 175 const OverlayPlaneList& planes) {
173 const OverlayPlaneList& plane_list) const { 176 if (planes.size() <= 1)
174 const auto& iter = overlay_hints_cache_.Peek(plane_list); 177 return planes;
175 // We dont have any information in cache about this combination of layers,
176 // return standard BGRX format.
177 if (iter == overlay_hints_cache_.end())
178 return DRM_FORMAT_XRGB8888;
179 178
180 DCHECK(plane_list.size() == iter->second.size()); 179 HardwareDisplayController* controller = window_->GetController();
180 if (!controller)
181 return planes;
181 182
182 size_t size = plane_list.size(); 183 OverlayPlaneList pending_planes = planes;
183 uint32_t index; 184 const auto& overlay_hints = overlay_hints_cache_.Get(planes);
184 for (index = 0; index < size; index++) { 185
185 const OverlayPlane& test_plane = plane_list.at(index); 186 size_t size = planes.size();
186 if (test_plane.z_order == plane.z_order && 187 bool use_hints = overlay_hints != overlay_hints_cache_.end();
187 test_plane.plane_transform == plane.plane_transform && 188
188 test_plane.display_bounds == plane.display_bounds && 189 for (size_t i = 0; i < size; i++) {
189 test_plane.crop_rect == plane.crop_rect) { 190 auto& plane = pending_planes.at(i);
190 break; 191 if (plane.processing_callback.is_null())
192 continue;
193
194 uint32_t original_format = plane.buffer->GetFramebufferPixelFormat();
195 uint32_t target_format = original_format;
196
197 const gfx::Size& original_size = plane.buffer->GetSize();
198 gfx::Size target_size =
199 GetScaledSize(original_size, plane.display_bounds, plane.crop_rect);
200
201 if (use_hints) {
202 DCHECK(size == overlay_hints->second.size());
203 const OverlayHints& hints = overlay_hints->second.at(i);
204 target_format = hints.optimal_format;
205
206 // We can handle plane scaling, avoid scaling buffer here.
207 if (!hints.handle_scaling)
208 target_size = original_size;
209 }
210
211 if (original_size != target_size || original_format != target_format) {
212 scoped_refptr<ScanoutBuffer> processed_buffer =
213 plane.processing_callback.Run(target_size, target_format);
214
215 if (processed_buffer)
216 plane.buffer = processed_buffer;
191 } 217 }
192 } 218 }
193 219
194 return iter->second.at(index).optimal_format; 220 return pending_planes;
195 } 221 }
196 222
197 void DrmOverlayValidator::ClearCache() { 223 void DrmOverlayValidator::ClearCache() {
198 overlay_hints_cache_.Clear(); 224 overlay_hints_cache_.Clear();
199 } 225 }
200 226
201 void DrmOverlayValidator::UpdateOverlayHintsCache( 227 void DrmOverlayValidator::UpdateOverlayHintsCache(
202 const scoped_refptr<DrmDevice>& drm, 228 const scoped_refptr<DrmDevice>& drm,
203 const OverlayPlaneList& plane_list, 229 const OverlayPlaneList& plane_list,
204 ScanoutBufferGenerator* buffer_generator,
205 std::vector<scoped_refptr<ScanoutBuffer>>* reusable_buffers) { 230 std::vector<scoped_refptr<ScanoutBuffer>>* reusable_buffers) {
206 const auto& iter = overlay_hints_cache_.Get(plane_list); 231 const auto& iter = overlay_hints_cache_.Get(plane_list);
207 if (iter != overlay_hints_cache_.end()) 232 if (iter != overlay_hints_cache_.end())
208 return; 233 return;
209 234
210 OverlayPlaneList preferred_format_test_list = plane_list; 235 OverlayPlaneList preferred_format_test_list = plane_list;
211 HardwareDisplayController* controller = window_->GetController(); 236 HardwareDisplayController* controller = window_->GetController();
212 OverlayHintsList overlay_hints; 237 OverlayHintsList overlay_hints;
213 for (auto& plane : preferred_format_test_list) { 238 for (auto& plane : preferred_format_test_list) {
214 uint32_t original_format = plane.buffer->GetFramebufferPixelFormat(); 239 uint32_t original_format = plane.buffer->GetFramebufferPixelFormat();
215 240
216 if (plane.z_order == 0) { 241 if (plane.z_order == 0) {
217 overlay_hints.push_back( 242 overlay_hints.push_back(
218 OverlayHints(original_format, true /* scaling */)); 243 OverlayHints(original_format, true /* scaling */));
219 continue; 244 continue;
220 } 245 }
221 246
222 uint32_t optimal_format = FindOptimalBufferFormat( 247 uint32_t optimal_format = FindOptimalBufferFormat(
223 original_format, plane.z_order, plane.display_bounds, window_->bounds(), 248 original_format, plane.z_order, plane.display_bounds, window_->bounds(),
224 controller); 249 controller);
225 250
226 if (optimal_format != original_format) { 251 if (optimal_format != original_format) {
227 scoped_refptr<ScanoutBuffer> original_buffer = plane.buffer; 252 scoped_refptr<ScanoutBuffer> original_buffer = plane.buffer;
228 plane.buffer = 253 plane.buffer =
229 GetBufferForPageFlipTest(drm, plane.buffer->GetSize(), optimal_format, 254 GetBufferForPageFlipTest(drm, plane.buffer->GetSize(), optimal_format,
230 buffer_generator, reusable_buffers); 255 buffer_generator_, reusable_buffers);
231 256
232 if (!controller->TestPageFlip(preferred_format_test_list)) { 257 if (!controller->TestPageFlip(preferred_format_test_list)) {
233 // If test failed here, it means even though optimal_format is 258 // If test failed here, it means even though optimal_format is
234 // supported, platform cannot support it with current combination of 259 // supported, platform cannot support it with current combination of
235 // layers. This is usually the case when optimal_format needs certain 260 // layers. This is usually the case when optimal_format needs certain
236 // capabilites (i.e. conversion, scaling etc) and needed hardware 261 // capabilites (i.e. conversion, scaling etc) and needed hardware
237 // resources might be already in use. Fall back to original format. 262 // resources might be already in use. Fall back to original format.
238 optimal_format = original_format; 263 optimal_format = original_format;
239 plane.buffer = original_buffer; 264 plane.buffer = original_buffer;
240 } 265 }
241 } 266 }
242 267
243 // TODO(kalyank): We always request scaling to be done by 3D engine, VPP 268 // TODO(kalyank): We always request scaling to be done by 3D engine, VPP
244 // etc. We should use them only if downscaling is needed and let display 269 // etc. We should use them only if downscaling is needed and let display
245 // controller handle up-scaling on platforms which support it. 270 // controller handle up-scaling on platforms which support it.
246 overlay_hints.push_back(OverlayHints(optimal_format, true /* scaling */)); 271 overlay_hints.push_back(OverlayHints(optimal_format, true /* scaling */));
247 } 272 }
248 273
249 // Make sure we dont hold reference to buffer when caching this plane list. 274 // Make sure we dont hold reference to buffer when caching this plane list.
250 for (auto& plane : preferred_format_test_list) 275 for (auto& plane : preferred_format_test_list)
251 plane.buffer = nullptr; 276 plane.buffer = nullptr;
252 277
253 DCHECK(preferred_format_test_list.size() == overlay_hints.size()); 278 DCHECK(preferred_format_test_list.size() == overlay_hints.size());
254 overlay_hints_cache_.Put(preferred_format_test_list, overlay_hints); 279 overlay_hints_cache_.Put(preferred_format_test_list, overlay_hints);
255 } 280 }
256 281
257 } // namespace ui 282 } // namespace ui
OLDNEW
« no previous file with comments | « ui/ozone/platform/drm/gpu/drm_overlay_validator.h ('k') | ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698