blob: fdb84c506958e6178e3f2f63c17b32da7aa37c4d [file] [log] [blame]
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001#include "display_service.h"
2
3#include <vector>
4
5#include <pdx/default_transport/service_endpoint.h>
6#include <pdx/rpc/remote_method.h>
7#include <private/dvr/composite_hmd.h>
8#include <private/dvr/display_rpc.h>
9#include <private/dvr/display_types.h>
10#include <private/dvr/lucid_metrics.h>
11#include <private/dvr/numeric.h>
12#include <private/dvr/polynomial_radial_distortion.h>
13#include <private/dvr/types.h>
14
15using android::pdx::Channel;
16using android::pdx::Message;
17using android::pdx::default_transport::Endpoint;
18using android::pdx::rpc::DispatchRemoteMethod;
19using android::pdx::rpc::WrapBuffer;
20
21namespace android {
22namespace dvr {
23
Jin Qian7480c062017-03-21 00:04:15 +000024DisplayService::DisplayService() : DisplayService(nullptr) {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080025
26DisplayService::DisplayService(Hwc2::Composer* hidl)
27 : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
Stephen Kiazyk016e5e32017-02-21 17:09:22 -080028 hardware_composer_(hidl) {
29 hardware_composer_.Initialize();
30}
31
32bool DisplayService::IsInitialized() const {
33 return BASE::IsInitialized() && hardware_composer_.IsInitialized();
34}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080035
36std::string DisplayService::DumpState(size_t max_length) {
37 std::vector<char> buffer(max_length);
38 uint32_t max_len_p = static_cast<uint32_t>(max_length);
39 hardware_composer_.Dump(buffer.data(), &max_len_p);
40 return std::string(buffer.data());
41}
42
43void DisplayService::OnChannelClose(pdx::Message& /*message*/,
44 const std::shared_ptr<Channel>& channel) {
45 auto surface = std::static_pointer_cast<SurfaceChannel>(channel);
46 if (surface && surface->type() == SurfaceTypeEnum::Normal) {
47 auto display_surface = std::static_pointer_cast<DisplaySurface>(surface);
48 display_surface->ManagerSetVisible(false);
49 display_surface->ClientSetVisible(false);
50 NotifyDisplayConfigurationUpdate();
51 }
52 // TODO(jwcai) Handle ChannelClose of VideoMeshSurface.
53}
54
55// First-level dispatch for display service messages. Directly handles messages
56// that are independent of the display surface (metrics, creation) and routes
57// surface-specific messages to the per-instance handlers.
58int DisplayService::HandleMessage(pdx::Message& message) {
59 auto channel = message.GetChannel<SurfaceChannel>();
60
61 switch (message.GetOp()) {
62 case DisplayRPC::GetMetrics::Opcode:
63 DispatchRemoteMethod<DisplayRPC::GetMetrics>(
64 *this, &DisplayService::OnGetMetrics, message);
65 return 0;
66
67 case DisplayRPC::GetEdsCapture::Opcode:
68 DispatchRemoteMethod<DisplayRPC::GetEdsCapture>(
69 *this, &DisplayService::OnGetEdsCapture, message);
70 return 0;
71
72 case DisplayRPC::CreateSurface::Opcode:
73 DispatchRemoteMethod<DisplayRPC::CreateSurface>(
74 *this, &DisplayService::OnCreateSurface, message);
75 return 0;
76
Jin Qian7480c062017-03-21 00:04:15 +000077 case DisplayRPC::EnterVrMode::Opcode:
78 DispatchRemoteMethod<DisplayRPC::EnterVrMode>(
79 *this, &DisplayService::OnEnterVrMode, message);
80 return 0;
81
82 case DisplayRPC::ExitVrMode::Opcode:
83 DispatchRemoteMethod<DisplayRPC::ExitVrMode>(
84 *this, &DisplayService::OnExitVrMode, message);
85 return 0;
86
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080087 case DisplayRPC::SetViewerParams::Opcode:
88 DispatchRemoteMethod<DisplayRPC::SetViewerParams>(
89 *this, &DisplayService::OnSetViewerParams, message);
90 return 0;
91
92 // Direct the surface specific messages to the surface instance.
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -080093 case DisplayRPC::CreateBufferQueue::Opcode:
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080094 case DisplayRPC::SetAttributes::Opcode:
95 case DisplayRPC::GetMetadataBuffer::Opcode:
96 case DisplayRPC::CreateVideoMeshSurface::Opcode:
97 case DisplayRPC::VideoMeshSurfaceCreateProducerQueue::Opcode:
98 return HandleSurfaceMessage(message);
99
100 default:
101 return Service::HandleMessage(message);
102 }
103}
104
105SystemDisplayMetrics DisplayService::OnGetMetrics(pdx::Message& message) {
106 const Compositor* compositor = hardware_composer_.GetCompositor();
107 if (compositor == nullptr)
108 REPLY_ERROR_RETURN(message, EINVAL, {});
109
110 HeadMountMetrics head_mount = compositor->head_mount_metrics();
111 CompositeHmd hmd(head_mount, hardware_composer_.GetHmdDisplayMetrics());
112 vec2i distorted_render_size = hmd.GetRecommendedRenderTargetSize();
113 FieldOfView left_fov = hmd.GetEyeFov(kLeftEye);
114 FieldOfView right_fov = hmd.GetEyeFov(kRightEye);
115
116 SystemDisplayMetrics metrics;
117
118 metrics.display_native_width = GetDisplayMetrics().width;
119 metrics.display_native_height = GetDisplayMetrics().height;
120 metrics.display_x_dpi = GetDisplayMetrics().dpi.x;
121 metrics.display_y_dpi = GetDisplayMetrics().dpi.y;
122 metrics.distorted_width = distorted_render_size[0];
123 metrics.distorted_height = distorted_render_size[1];
124 metrics.vsync_period_ns =
125 hardware_composer_.native_display_metrics().vsync_period_ns;
126 metrics.hmd_ipd_mm = 0;
127 metrics.inter_lens_distance_m = head_mount.GetInterLensDistance();
128 metrics.left_fov_lrbt[0] = left_fov.GetLeft();
129 metrics.left_fov_lrbt[1] = left_fov.GetRight();
130 metrics.left_fov_lrbt[2] = left_fov.GetBottom();
131 metrics.left_fov_lrbt[3] = left_fov.GetTop();
132 metrics.right_fov_lrbt[0] = right_fov.GetLeft();
133 metrics.right_fov_lrbt[1] = right_fov.GetRight();
134 metrics.right_fov_lrbt[2] = right_fov.GetBottom();
135 metrics.right_fov_lrbt[3] = right_fov.GetTop();
136
137 return metrics;
138}
139
140// Creates a new DisplaySurface and associates it with this channel. This may
141// only be done once per channel.
142int DisplayService::OnCreateSurface(pdx::Message& message, int width,
143 int height, int format, int usage,
144 DisplaySurfaceFlags flags) {
145 // A surface may only be created once per channel.
146 if (message.GetChannel())
147 return -EINVAL;
148
149 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
150 message.GetChannelId());
151
152 // Use the channel id as the unique surface id.
153 const int surface_id = message.GetChannelId();
154 const int process_id = message.GetProcessId();
155
156 ALOGI_IF(TRACE,
157 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d "
158 "width=%d height=%d format=%x usage=%x flags=%x",
159 surface_id, process_id, width, height, format, usage, flags);
160
161 // TODO(eieio,jbates): Validate request parameters.
162 auto channel = std::make_shared<DisplaySurface>(
163 this, surface_id, process_id, width, height, format, usage, flags);
164
165 message.SetChannel(channel);
166 NotifyDisplayConfigurationUpdate();
167 return 0;
168}
169
170DisplayRPC::ByteBuffer DisplayService::OnGetEdsCapture(pdx::Message& message) {
171 Compositor* compositor = hardware_composer_.GetCompositor();
172 if (compositor == nullptr)
173 REPLY_ERROR_RETURN(message, EINVAL, {});
174
175 std::vector<std::uint8_t> buffer(sizeof(LateLatchOutput));
176
177 if (!compositor->GetLastEdsPose(
178 reinterpret_cast<LateLatchOutput*>(buffer.data()))) {
179 REPLY_ERROR_RETURN(message, EPERM, {});
180 }
181
182 return WrapBuffer(std::move(buffer));
183}
184
Jin Qian7480c062017-03-21 00:04:15 +0000185int DisplayService::OnEnterVrMode(pdx::Message& /*message*/) {
186 hardware_composer_.Resume();
187 return 0;
188}
189
190int DisplayService::OnExitVrMode(pdx::Message& /*message*/) {
191 hardware_composer_.Suspend();
192 return 0;
193}
194
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800195void DisplayService::OnSetViewerParams(pdx::Message& message,
196 const ViewerParams& view_params) {
197 Compositor* compositor = hardware_composer_.GetCompositor();
198 if (compositor == nullptr)
199 REPLY_ERROR_RETURN(message, EINVAL);
200
201 FieldOfView left(55.0f, 55.0f, 55.0f, 55.0f);
202 FieldOfView right(55.0f, 55.0f, 55.0f, 55.0f);
203 if (view_params.left_eye_field_of_view_angles.size() >= 4) {
204 left = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[0]),
205 ToRad(view_params.left_eye_field_of_view_angles[1]),
206 ToRad(view_params.left_eye_field_of_view_angles[2]),
207 ToRad(view_params.left_eye_field_of_view_angles[3]));
208 right = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[1]),
209 ToRad(view_params.left_eye_field_of_view_angles[0]),
210 ToRad(view_params.left_eye_field_of_view_angles[2]),
211 ToRad(view_params.left_eye_field_of_view_angles[3]));
212 }
213
214 std::shared_ptr<ColorChannelDistortion> red_distortion;
215 std::shared_ptr<ColorChannelDistortion> green_distortion;
216 std::shared_ptr<ColorChannelDistortion> blue_distortion;
217
218 // We should always have a red distortion.
219 LOG_FATAL_IF(view_params.distortion_coefficients_r.empty());
220 red_distortion = std::make_shared<PolynomialRadialDistortion>(
221 view_params.distortion_coefficients_r);
222
223 if (!view_params.distortion_coefficients_g.empty()) {
224 green_distortion = std::make_shared<PolynomialRadialDistortion>(
225 view_params.distortion_coefficients_g);
226 }
227
228 if (!view_params.distortion_coefficients_b.empty()) {
229 blue_distortion = std::make_shared<PolynomialRadialDistortion>(
230 view_params.distortion_coefficients_b);
231 }
232
233 HeadMountMetrics::EyeOrientation left_orientation =
234 HeadMountMetrics::EyeOrientation::kCCW0Degrees;
235 HeadMountMetrics::EyeOrientation right_orientation =
236 HeadMountMetrics::EyeOrientation::kCCW0Degrees;
237
238 if (view_params.eye_orientations.size() > 1) {
239 left_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
240 view_params.eye_orientations[0]);
241 right_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
242 view_params.eye_orientations[1]);
243 }
244
245 HeadMountMetrics head_mount_metrics(
246 view_params.inter_lens_distance, view_params.tray_to_lens_distance,
247 view_params.screen_to_lens_distance,
248 static_cast<HeadMountMetrics::VerticalAlignment>(
249 view_params.vertical_alignment),
250 left, right, red_distortion, green_distortion, blue_distortion,
251 left_orientation, right_orientation,
252 view_params.screen_center_to_lens_distance);
253
254 compositor->UpdateHeadMountMetrics(head_mount_metrics);
255}
256
257// Calls the message handler for the DisplaySurface associated with this
258// channel.
259int DisplayService::HandleSurfaceMessage(pdx::Message& message) {
260 auto surface = std::static_pointer_cast<SurfaceChannel>(message.GetChannel());
261 ALOGW_IF(!surface,
262 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
263
264 if (surface)
265 return surface->HandleMessage(message);
266 else
267 REPLY_ERROR_RETURN(message, EINVAL, 0);
268}
269
270std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
271 int surface_id) const {
272 return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
273}
274
275std::vector<std::shared_ptr<DisplaySurface>>
276DisplayService::GetDisplaySurfaces() const {
277 return GetChannels<DisplaySurface>();
278}
279
280std::vector<std::shared_ptr<DisplaySurface>>
281DisplayService::GetVisibleDisplaySurfaces() const {
282 std::vector<std::shared_ptr<DisplaySurface>> visible_surfaces;
283
284 ForEachDisplaySurface(
285 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
286 if (surface->IsVisible())
287 visible_surfaces.push_back(surface);
288 });
289
290 return visible_surfaces;
291}
292
Jin Qian7480c062017-03-21 00:04:15 +0000293int DisplayService::UpdateActiveDisplaySurfaces() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800294 auto visible_surfaces = GetVisibleDisplaySurfaces();
295
296 // Sort the surfaces based on manager z order first, then client z order.
297 std::sort(visible_surfaces.begin(), visible_surfaces.end(),
298 [](const std::shared_ptr<DisplaySurface>& a,
299 const std::shared_ptr<DisplaySurface>& b) {
300 return a->manager_z_order() != b->manager_z_order()
301 ? a->manager_z_order() < b->manager_z_order()
302 : a->client_z_order() < b->client_z_order();
303 });
304
305 ALOGD_IF(TRACE,
306 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
307 visible_surfaces.size());
308
309 // TODO(jbates) Have the shell manage blurred layers.
310 bool blur_requested = false;
311 auto end = visible_surfaces.crend();
312 for (auto it = visible_surfaces.crbegin(); it != end; ++it) {
313 auto surface = *it;
314 // Surfaces with exclude_from_blur==true are not blurred
315 // and are excluded from blur computation of other layers.
316 if (surface->client_exclude_from_blur()) {
317 surface->ManagerSetBlur(0.0f);
318 continue;
319 }
320 surface->ManagerSetBlur(blur_requested ? 1.0f : 0.0f);
321 if (surface->client_blur_behind())
322 blur_requested = true;
323 }
Jin Qian7480c062017-03-21 00:04:15 +0000324 return hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800325}
326
Steven Thomas3cfac282017-02-06 12:29:30 -0800327void DisplayService::OnHardwareComposerRefresh() {
328 hardware_composer_.OnHardwareComposerRefresh();
329}
330
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800331void DisplayService::SetDisplayConfigurationUpdateNotifier(
332 DisplayConfigurationUpdateNotifier update_notifier) {
333 update_notifier_ = update_notifier;
334}
335
336void DisplayService::NotifyDisplayConfigurationUpdate() {
337 if (update_notifier_)
338 update_notifier_();
339}
340
341} // namespace dvr
342} // namespace android