blob: 2dc840e78a5572a605240eac98af21c90b684f62 [file] [log] [blame]
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001#include "display_service.h"
2
Hendrik Wagenaareaa55222017-04-06 10:56:23 -07003#include <unistd.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08004#include <vector>
5
6#include <pdx/default_transport/service_endpoint.h>
7#include <pdx/rpc/remote_method.h>
8#include <private/dvr/composite_hmd.h>
Hendrik Wagenaar302b74f2017-04-04 14:38:36 -07009#include <private/dvr/device_metrics.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080010#include <private/dvr/display_rpc.h>
11#include <private/dvr/display_types.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080012#include <private/dvr/numeric.h>
13#include <private/dvr/polynomial_radial_distortion.h>
14#include <private/dvr/types.h>
15
16using android::pdx::Channel;
17using android::pdx::Message;
18using android::pdx::default_transport::Endpoint;
19using android::pdx::rpc::DispatchRemoteMethod;
20using android::pdx::rpc::WrapBuffer;
21
22namespace android {
23namespace dvr {
24
Hendrik Wagenaareaa55222017-04-06 10:56:23 -070025DisplayService::DisplayService() : DisplayService(nullptr) {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080026
27DisplayService::DisplayService(Hwc2::Composer* hidl)
28 : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
Stephen Kiazyk016e5e32017-02-21 17:09:22 -080029 hardware_composer_(hidl) {
30 hardware_composer_.Initialize();
31}
32
33bool DisplayService::IsInitialized() const {
34 return BASE::IsInitialized() && hardware_composer_.IsInitialized();
35}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080036
37std::string DisplayService::DumpState(size_t max_length) {
38 std::vector<char> buffer(max_length);
39 uint32_t max_len_p = static_cast<uint32_t>(max_length);
40 hardware_composer_.Dump(buffer.data(), &max_len_p);
41 return std::string(buffer.data());
42}
43
44void DisplayService::OnChannelClose(pdx::Message& /*message*/,
45 const std::shared_ptr<Channel>& channel) {
46 auto surface = std::static_pointer_cast<SurfaceChannel>(channel);
47 if (surface && surface->type() == SurfaceTypeEnum::Normal) {
48 auto display_surface = std::static_pointer_cast<DisplaySurface>(surface);
49 display_surface->ManagerSetVisible(false);
50 display_surface->ClientSetVisible(false);
51 NotifyDisplayConfigurationUpdate();
52 }
53 // TODO(jwcai) Handle ChannelClose of VideoMeshSurface.
54}
55
56// First-level dispatch for display service messages. Directly handles messages
57// that are independent of the display surface (metrics, creation) and routes
58// surface-specific messages to the per-instance handlers.
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070059pdx::Status<void> DisplayService::HandleMessage(pdx::Message& message) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080060 auto channel = message.GetChannel<SurfaceChannel>();
61
62 switch (message.GetOp()) {
63 case DisplayRPC::GetMetrics::Opcode:
64 DispatchRemoteMethod<DisplayRPC::GetMetrics>(
65 *this, &DisplayService::OnGetMetrics, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070066 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080067
68 case DisplayRPC::GetEdsCapture::Opcode:
69 DispatchRemoteMethod<DisplayRPC::GetEdsCapture>(
70 *this, &DisplayService::OnGetEdsCapture, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070071 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080072
73 case DisplayRPC::CreateSurface::Opcode:
74 DispatchRemoteMethod<DisplayRPC::CreateSurface>(
75 *this, &DisplayService::OnCreateSurface, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070076 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080077
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080078 case DisplayRPC::SetViewerParams::Opcode:
79 DispatchRemoteMethod<DisplayRPC::SetViewerParams>(
80 *this, &DisplayService::OnSetViewerParams, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070081 return {};
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080082
Hendrik Wagenaareaa55222017-04-06 10:56:23 -070083 case DisplayRPC::GetNamedBuffer::Opcode:
84 DispatchRemoteMethod<DisplayRPC::GetNamedBuffer>(
85 *this, &DisplayService::OnGetNamedBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070086 return {};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -070087
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -040088 case DisplayRPC::IsVrAppRunning::Opcode:
89 DispatchRemoteMethod<DisplayRPC::IsVrAppRunning>(
90 *this, &DisplayService::IsVrAppRunning, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070091 return {};
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -040092
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080093 // Direct the surface specific messages to the surface instance.
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -080094 case DisplayRPC::CreateBufferQueue::Opcode:
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080095 case DisplayRPC::SetAttributes::Opcode:
96 case DisplayRPC::GetMetadataBuffer::Opcode:
97 case DisplayRPC::CreateVideoMeshSurface::Opcode:
98 case DisplayRPC::VideoMeshSurfaceCreateProducerQueue::Opcode:
99 return HandleSurfaceMessage(message);
100
101 default:
102 return Service::HandleMessage(message);
103 }
104}
105
106SystemDisplayMetrics DisplayService::OnGetMetrics(pdx::Message& message) {
107 const Compositor* compositor = hardware_composer_.GetCompositor();
108 if (compositor == nullptr)
109 REPLY_ERROR_RETURN(message, EINVAL, {});
110
111 HeadMountMetrics head_mount = compositor->head_mount_metrics();
112 CompositeHmd hmd(head_mount, hardware_composer_.GetHmdDisplayMetrics());
113 vec2i distorted_render_size = hmd.GetRecommendedRenderTargetSize();
114 FieldOfView left_fov = hmd.GetEyeFov(kLeftEye);
115 FieldOfView right_fov = hmd.GetEyeFov(kRightEye);
116
117 SystemDisplayMetrics metrics;
118
119 metrics.display_native_width = GetDisplayMetrics().width;
120 metrics.display_native_height = GetDisplayMetrics().height;
121 metrics.display_x_dpi = GetDisplayMetrics().dpi.x;
122 metrics.display_y_dpi = GetDisplayMetrics().dpi.y;
123 metrics.distorted_width = distorted_render_size[0];
124 metrics.distorted_height = distorted_render_size[1];
125 metrics.vsync_period_ns =
126 hardware_composer_.native_display_metrics().vsync_period_ns;
127 metrics.hmd_ipd_mm = 0;
128 metrics.inter_lens_distance_m = head_mount.GetInterLensDistance();
129 metrics.left_fov_lrbt[0] = left_fov.GetLeft();
130 metrics.left_fov_lrbt[1] = left_fov.GetRight();
131 metrics.left_fov_lrbt[2] = left_fov.GetBottom();
132 metrics.left_fov_lrbt[3] = left_fov.GetTop();
133 metrics.right_fov_lrbt[0] = right_fov.GetLeft();
134 metrics.right_fov_lrbt[1] = right_fov.GetRight();
135 metrics.right_fov_lrbt[2] = right_fov.GetBottom();
136 metrics.right_fov_lrbt[3] = right_fov.GetTop();
137
138 return metrics;
139}
140
141// Creates a new DisplaySurface and associates it with this channel. This may
142// only be done once per channel.
143int DisplayService::OnCreateSurface(pdx::Message& message, int width,
144 int height, int format, int usage,
145 DisplaySurfaceFlags flags) {
146 // A surface may only be created once per channel.
147 if (message.GetChannel())
148 return -EINVAL;
149
150 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
151 message.GetChannelId());
152
153 // Use the channel id as the unique surface id.
154 const int surface_id = message.GetChannelId();
155 const int process_id = message.GetProcessId();
156
157 ALOGI_IF(TRACE,
158 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d "
159 "width=%d height=%d format=%x usage=%x flags=%x",
160 surface_id, process_id, width, height, format, usage, flags);
161
162 // TODO(eieio,jbates): Validate request parameters.
163 auto channel = std::make_shared<DisplaySurface>(
164 this, surface_id, process_id, width, height, format, usage, flags);
165
166 message.SetChannel(channel);
167 NotifyDisplayConfigurationUpdate();
168 return 0;
169}
170
171DisplayRPC::ByteBuffer DisplayService::OnGetEdsCapture(pdx::Message& message) {
172 Compositor* compositor = hardware_composer_.GetCompositor();
173 if (compositor == nullptr)
174 REPLY_ERROR_RETURN(message, EINVAL, {});
175
176 std::vector<std::uint8_t> buffer(sizeof(LateLatchOutput));
177
178 if (!compositor->GetLastEdsPose(
179 reinterpret_cast<LateLatchOutput*>(buffer.data()))) {
180 REPLY_ERROR_RETURN(message, EPERM, {});
181 }
182
183 return WrapBuffer(std::move(buffer));
184}
185
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800186void DisplayService::OnSetViewerParams(pdx::Message& message,
187 const ViewerParams& view_params) {
188 Compositor* compositor = hardware_composer_.GetCompositor();
189 if (compositor == nullptr)
190 REPLY_ERROR_RETURN(message, EINVAL);
191
192 FieldOfView left(55.0f, 55.0f, 55.0f, 55.0f);
193 FieldOfView right(55.0f, 55.0f, 55.0f, 55.0f);
194 if (view_params.left_eye_field_of_view_angles.size() >= 4) {
195 left = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[0]),
196 ToRad(view_params.left_eye_field_of_view_angles[1]),
197 ToRad(view_params.left_eye_field_of_view_angles[2]),
198 ToRad(view_params.left_eye_field_of_view_angles[3]));
199 right = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[1]),
200 ToRad(view_params.left_eye_field_of_view_angles[0]),
201 ToRad(view_params.left_eye_field_of_view_angles[2]),
202 ToRad(view_params.left_eye_field_of_view_angles[3]));
203 }
204
205 std::shared_ptr<ColorChannelDistortion> red_distortion;
206 std::shared_ptr<ColorChannelDistortion> green_distortion;
207 std::shared_ptr<ColorChannelDistortion> blue_distortion;
208
209 // We should always have a red distortion.
210 LOG_FATAL_IF(view_params.distortion_coefficients_r.empty());
Hendrik Wagenaardb576382017-04-17 15:24:19 -0700211 red_distortion = std::make_shared<PolynomialRadialDistortion>(
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700212 view_params.distortion_coefficients_r);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800213
214 if (!view_params.distortion_coefficients_g.empty()) {
Hendrik Wagenaardb576382017-04-17 15:24:19 -0700215 green_distortion = std::make_shared<PolynomialRadialDistortion>(
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700216 view_params.distortion_coefficients_g);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800217 }
218
219 if (!view_params.distortion_coefficients_b.empty()) {
Hendrik Wagenaardb576382017-04-17 15:24:19 -0700220 blue_distortion = std::make_shared<PolynomialRadialDistortion>(
Hendrik Wagenaarf8b1ef42017-04-18 15:12:30 -0700221 view_params.distortion_coefficients_b);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800222 }
223
224 HeadMountMetrics::EyeOrientation left_orientation =
225 HeadMountMetrics::EyeOrientation::kCCW0Degrees;
226 HeadMountMetrics::EyeOrientation right_orientation =
227 HeadMountMetrics::EyeOrientation::kCCW0Degrees;
228
229 if (view_params.eye_orientations.size() > 1) {
230 left_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
231 view_params.eye_orientations[0]);
232 right_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
233 view_params.eye_orientations[1]);
234 }
235
236 HeadMountMetrics head_mount_metrics(
237 view_params.inter_lens_distance, view_params.tray_to_lens_distance,
238 view_params.screen_to_lens_distance,
239 static_cast<HeadMountMetrics::VerticalAlignment>(
240 view_params.vertical_alignment),
241 left, right, red_distortion, green_distortion, blue_distortion,
242 left_orientation, right_orientation,
243 view_params.screen_center_to_lens_distance);
244
245 compositor->UpdateHeadMountMetrics(head_mount_metrics);
246}
247
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700248pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
249 pdx::Message& /* message */, const std::string& name) {
250 auto named_buffer = named_buffers_.find(name);
251 if (named_buffer != named_buffers_.end()) {
252 return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700253 }
254
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700255 return pdx::ErrorStatus(EINVAL);
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700256}
257
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800258// Calls the message handler for the DisplaySurface associated with this
259// channel.
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700260pdx::Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800261 auto surface = std::static_pointer_cast<SurfaceChannel>(message.GetChannel());
262 ALOGW_IF(!surface,
263 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
264
265 if (surface)
266 return surface->HandleMessage(message);
267 else
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700268 REPLY_ERROR_RETURN(message, EINVAL, {});
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800269}
270
271std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
272 int surface_id) const {
273 return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
274}
275
276std::vector<std::shared_ptr<DisplaySurface>>
277DisplayService::GetDisplaySurfaces() const {
278 return GetChannels<DisplaySurface>();
279}
280
281std::vector<std::shared_ptr<DisplaySurface>>
282DisplayService::GetVisibleDisplaySurfaces() const {
283 std::vector<std::shared_ptr<DisplaySurface>> visible_surfaces;
284
285 ForEachDisplaySurface(
286 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
287 if (surface->IsVisible())
288 visible_surfaces.push_back(surface);
289 });
290
291 return visible_surfaces;
292}
293
Steven Thomas050b2c82017-03-06 11:45:16 -0800294void DisplayService::UpdateActiveDisplaySurfaces() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800295 auto visible_surfaces = GetVisibleDisplaySurfaces();
296
297 // Sort the surfaces based on manager z order first, then client z order.
298 std::sort(visible_surfaces.begin(), visible_surfaces.end(),
299 [](const std::shared_ptr<DisplaySurface>& a,
300 const std::shared_ptr<DisplaySurface>& b) {
301 return a->manager_z_order() != b->manager_z_order()
302 ? a->manager_z_order() < b->manager_z_order()
303 : a->client_z_order() < b->client_z_order();
304 });
305
306 ALOGD_IF(TRACE,
307 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
308 visible_surfaces.size());
309
310 // TODO(jbates) Have the shell manage blurred layers.
311 bool blur_requested = false;
312 auto end = visible_surfaces.crend();
313 for (auto it = visible_surfaces.crbegin(); it != end; ++it) {
314 auto surface = *it;
315 // Surfaces with exclude_from_blur==true are not blurred
316 // and are excluded from blur computation of other layers.
317 if (surface->client_exclude_from_blur()) {
318 surface->ManagerSetBlur(0.0f);
319 continue;
320 }
321 surface->ManagerSetBlur(blur_requested ? 1.0f : 0.0f);
322 if (surface->client_blur_behind())
323 blur_requested = true;
324 }
Steven Thomas050b2c82017-03-06 11:45:16 -0800325
326 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800327}
328
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700329pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700330 const std::string& name, size_t size, int usage) {
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700331 auto named_buffer = named_buffers_.find(name);
332 if (named_buffer == named_buffers_.end()) {
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700333 auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
334 HAL_PIXEL_FORMAT_BLOB, usage);
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700335 named_buffer =
336 named_buffers_.insert(std::make_pair(name, std::move(ion_buffer)))
337 .first;
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700338 }
339
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700340 return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700341}
342
Steven Thomas3cfac282017-02-06 12:29:30 -0800343void DisplayService::OnHardwareComposerRefresh() {
344 hardware_composer_.OnHardwareComposerRefresh();
345}
346
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800347void DisplayService::SetDisplayConfigurationUpdateNotifier(
348 DisplayConfigurationUpdateNotifier update_notifier) {
349 update_notifier_ = update_notifier;
350}
351
352void DisplayService::NotifyDisplayConfigurationUpdate() {
353 if (update_notifier_)
354 update_notifier_();
355}
356
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400357int DisplayService::IsVrAppRunning(pdx::Message& message) {
Albert Chaulk356bc372017-04-05 18:01:58 -0400358 bool visible = false;
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700359 ForEachDisplaySurface(
360 [&visible](const std::shared_ptr<DisplaySurface>& surface) {
361 if (surface->client_z_order() == 0 && surface->IsVisible())
362 visible = true;
363 });
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400364
365 REPLY_SUCCESS_RETURN(message, visible, 0);
366}
367
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800368} // namespace dvr
369} // namespace android