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