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

Side by Side Diff: ui/ozone/platform/drm/gpu/drm_overlay_candidate.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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/ozone/platform/drm/gpu/drm_overlay_candidate.h"
6
7 #include <drm_fourcc.h>
8
9 #include "ui/gfx/geometry/size_conversions.h"
10 #include "ui/ozone/platform/drm/gpu/drm_device.h"
11 #include "ui/ozone/platform/drm/gpu/drm_window.h"
12 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
13 #include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
14
15 namespace ui {
16
17 DrmOverlayCandidate::DrmOverlayCandidate(DrmWindow* window) : window_(window) {}
18
19 DrmOverlayCandidate::~DrmOverlayCandidate() {}
20
21 std::vector<OverlayCheck_Params> DrmOverlayCandidate::TestPageFlip(
22 const std::vector<OverlayCheck_Params>& current_combination,
23 const std::vector<OverlayCheck_Params>& new_combination,
24 const OverlayPlaneList& last_used_planes,
25 ScanoutBufferGenerator* buffer_generator) {
26 std::vector<OverlayCheck_Params> validated_params;
27 HardwareDisplayController* controller = window_->GetController();
28 if (!controller) {
29 // Nothing much we can do here.
30 return validated_params;
31 }
32
33 overlay_params_.clear();
34 OverlayPlaneList test_list;
35 std::vector<scoped_refptr<ScanoutBuffer>> reusable_buffers;
36 scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice();
37 const OverlayPlane& primary_plane =
38 *OverlayPlane::GetPrimaryPlane(last_used_planes);
39
40 for (const auto& plane : last_used_planes)
41 reusable_buffers.push_back(plane.buffer);
42
43 // We save the current in use configurations as we might have frames using
44 // these configurations queued in SurfaceOzone.
45 for (const auto& param : current_combination)
46 overlay_params_.push_back(param);
47
48 for (const auto& overlay : new_combination) {
49 bool needs_flip_test = true;
50 OverlayCheck_Params param(overlay);
51 DCHECK(param.state != OverlayCheck_Params::kInvalid);
52 OverlayPlane plane(nullptr, overlay.plane_z_order, overlay.transform,
53 overlay.display_rect, overlay.crop_rect);
54
55 if (param.state == OverlayCheck_Params::kTest)
56 EvaluateBufferConfiguration(&param, controller);
57
58 // We expect this combination to always work.
59 if (param.plane_z_order == 0 &&
60 param.required_buffer_size == primary_plane.buffer->GetSize() &&
61 param.optimal_format == gfx::BufferFormat::BGRX_8888) {
62 param.state = OverlayCheck_Params::kOverlay;
63 plane.buffer = primary_plane.buffer;
64 overlay_params_.push_back(param);
65 validated_params.push_back(param);
66 test_list.push_back(plane);
67 continue;
68 }
69
70 if (param.state != OverlayCheck_Params::kTest) {
71 plane.buffer = GetBufferForPageFlipTest(
72 buffer_generator, &reusable_buffers, param.required_buffer_size,
73 param.optimal_format, drm);
74 } else {
75 ValidateConfiguration(buffer_generator, &plane, &param, &reusable_buffers,
76 primary_plane, drm);
77 // We can skip page flip test in case test_list size is less than 2 as the
78 // result will be same as in ValidateConfiguration.
79 needs_flip_test = test_list.size() > 1;
80 }
81
82 if (!plane.buffer) {
83 param.state = OverlayCheck_Params::kInvalid;
84 validated_params.push_back(param);
85 continue;
86 }
87
88 test_list.push_back(plane);
89 bool status = true;
90 if (needs_flip_test)
91 status = controller->TestPageFlip(test_list);
92
93 if (status) {
94 param.state = OverlayCheck_Params::kOverlay;
95 overlay_params_.push_back(param);
96 } else {
97 // If test failed here, it means even though this configuration is
98 // compatible, platform cannot support the current combination of layers.
99 // This is usually the case when this plane has requested post processing
100 // capability which needs additional hardware resources and they might
101 // be already in use by other planes. For example this plane has requested
102 // scaling capabilities and all available scalars are already in use by
103 // other planes.
104 DCHECK(test_list.size() > 1);
105 param.state = OverlayCheck_Params::kCompatible;
106 test_list.pop_back();
107 }
108
109 validated_params.push_back(param);
110 }
111
112 return validated_params;
113 }
114
115 std::vector<OverlayCheck_Params> DrmOverlayCandidate::GetOverlayConfigurations()
116 const {
117 return overlay_params_;
118 }
119
120 scoped_refptr<ScanoutBuffer> DrmOverlayCandidate::GetBufferForPageFlipTest(
121 ScanoutBufferGenerator* buffer_generator,
122 std::vector<scoped_refptr<ScanoutBuffer>>* reusable_buffers,
123 const gfx::Size& size,
124 gfx::BufferFormat buffer_format,
125 const scoped_refptr<DrmDevice>& drm_device) {
126 scoped_refptr<ScanoutBuffer> scanout_buffer;
127 uint32_t format = GetFourCCFormatFromBufferFormat(buffer_format);
128 // Check if we can re-use existing buffers.
129 for (const auto& buffer : *reusable_buffers) {
130 if (buffer->GetFramebufferPixelFormat() == format &&
131 buffer->GetSize() == size) {
132 scanout_buffer = buffer;
133 break;
134 }
135 }
136
137 if (!scanout_buffer) {
138 scanout_buffer = buffer_generator->Create(drm_device, buffer_format, size);
139 reusable_buffers->push_back(scanout_buffer);
140 }
141
142 return scanout_buffer;
143 }
144
145 void DrmOverlayCandidate::ValidateConfiguration(
dnicoara 2015/11/23 19:22:54 Could you document what this does? My understandin
146 ScanoutBufferGenerator* buffer_generator,
147 OverlayPlane* plane,
148 OverlayCheck_Params* param,
149 std::vector<scoped_refptr<ScanoutBuffer>>* reusable_buffers,
150 const OverlayPlane& primary_plane,
151 const scoped_refptr<DrmDevice>& drm) {
152 OverlayPlaneList compatible_test_list;
153 HardwareDisplayController* controller = window_->GetController();
154
155 plane->buffer = GetBufferForPageFlipTest(buffer_generator, reusable_buffers,
156 param->required_buffer_size,
157 param->optimal_format, drm);
158
159 if (!plane->buffer)
160 return;
161
162 if (plane->z_order != 0)
163 compatible_test_list.push_back(primary_plane);
164
165 compatible_test_list.push_back(*plane);
166
167 bool compatible = controller->TestPageFlip(compatible_test_list);
168
169 if (!compatible) {
170 plane->buffer = nullptr;
171 if (param->optimal_format == param->format)
172 return;
173
174 // We tried to optimize the format and failed, check if original format
175 // request can be supported.
176 param->optimal_format = param->format;
177 plane->buffer = GetBufferForPageFlipTest(buffer_generator, reusable_buffers,
178 param->required_buffer_size,
179 param->optimal_format, drm);
180
181 if (!plane->buffer)
182 return;
183
184 compatible_test_list.back().buffer = plane->buffer;
185
186 if (!controller->TestPageFlip(compatible_test_list))
187 plane->buffer = nullptr;
188 }
189 }
190
191 void DrmOverlayCandidate::EvaluateBufferConfiguration(
192 OverlayCheck_Params* param,
193 HardwareDisplayController* controller) {
194 uint32_t plane_z_order = param->plane_z_order;
195 // TODO(kalyank): We always request scaling to be done by 3D engine, VPP etc.
196 // We should only use them only if downscaling is needed and let display
197 // controller handle up-scaling on platforms which support it.
198 if (!param->crop_rect.IsEmpty()) {
199 param->required_buffer_size = gfx::ToCeiledSize(
200 gfx::SizeF(param->display_rect.width() / param->crop_rect.width(),
201 param->display_rect.height() / param->crop_rect.height()));
202 }
203
204 gfx::BufferFormat format = param->format;
205 // TODO(kalyank): We assume that it's always a Video buffer in case
206 // plane_z_order > 0. This needs to be revisited when we add Overlay support
207 // for other layers.
208 if (param->plane_z_order > 0) {
209 format = gfx::BufferFormat::BGRX_8888;
dnicoara 2015/11/23 19:22:54 Shouldn't this be in the following if-statement? W
210 // Full screen is a special case, Plane manager will collapse Overlay plane
211 // to primary.
212 if (param->display_rect == window_->bounds())
213 plane_z_order = 0;
214
215 // TODO(kalyank): In fullscreen case, we always fall back to BGRX format.
216 // Currently, PlaneManager collapses planes to one only if format is BGRX.
217 // This is due to the fact that page flip can fail on non-atomic kernels,
218 // when trying to flip a buffer of format other than what was used during
219 // Modeset with primary. However, with Atomic we can use test commit to
220 // check if the actual commit will pass or not and make a decision. Remove
221 // this restriction here and in plane manager once we are able to test it.
222 if (plane_z_order &&
223 controller->IsFormatSupported(DRM_FORMAT_UYVY, plane_z_order)) {
224 format = gfx::BufferFormat::UYVY_422;
225 }
226 }
227
228 param->optimal_format = format;
229 }
230
231 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698