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