display_service.cpp revision f8b1ef4fd9cd4e0bd750b07f502add63ddf43166
1#include "display_service.h"
2
3#include <unistd.h>
4#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>
9#include <private/dvr/device_metrics.h>
10#include <private/dvr/display_rpc.h>
11#include <private/dvr/display_types.h>
12#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
25DisplayService::DisplayService() : DisplayService(nullptr) {}
26
27DisplayService::DisplayService(Hwc2::Composer* hidl)
28    : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
29      hardware_composer_(hidl) {
30  hardware_composer_.Initialize();
31}
32
33bool DisplayService::IsInitialized() const {
34  return BASE::IsInitialized() && hardware_composer_.IsInitialized();
35}
36
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.
59pdx::Status<void> DisplayService::HandleMessage(pdx::Message& message) {
60  auto channel = message.GetChannel<SurfaceChannel>();
61
62  switch (message.GetOp()) {
63    case DisplayRPC::GetMetrics::Opcode:
64      DispatchRemoteMethod<DisplayRPC::GetMetrics>(
65          *this, &DisplayService::OnGetMetrics, message);
66      return {};
67
68    case DisplayRPC::GetEdsCapture::Opcode:
69      DispatchRemoteMethod<DisplayRPC::GetEdsCapture>(
70          *this, &DisplayService::OnGetEdsCapture, message);
71      return {};
72
73    case DisplayRPC::CreateSurface::Opcode:
74      DispatchRemoteMethod<DisplayRPC::CreateSurface>(
75          *this, &DisplayService::OnCreateSurface, message);
76      return {};
77
78    case DisplayRPC::SetViewerParams::Opcode:
79      DispatchRemoteMethod<DisplayRPC::SetViewerParams>(
80          *this, &DisplayService::OnSetViewerParams, message);
81      return {};
82
83    case DisplayRPC::GetNamedBuffer::Opcode:
84      DispatchRemoteMethod<DisplayRPC::GetNamedBuffer>(
85          *this, &DisplayService::OnGetNamedBuffer, message);
86      return {};
87
88    case DisplayRPC::IsVrAppRunning::Opcode:
89      DispatchRemoteMethod<DisplayRPC::IsVrAppRunning>(
90          *this, &DisplayService::IsVrAppRunning, message);
91      return {};
92
93    // Direct the surface specific messages to the surface instance.
94    case DisplayRPC::CreateBufferQueue::Opcode:
95    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
186void 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());
211  red_distortion = std::make_shared<PolynomialRadialDistortion>(
212      view_params.distortion_coefficients_r);
213
214  if (!view_params.distortion_coefficients_g.empty()) {
215    green_distortion = std::make_shared<PolynomialRadialDistortion>(
216        view_params.distortion_coefficients_g);
217  }
218
219  if (!view_params.distortion_coefficients_b.empty()) {
220    blue_distortion = std::make_shared<PolynomialRadialDistortion>(
221        view_params.distortion_coefficients_b);
222  }
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
248pdx::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)};
253  }
254
255  return pdx::ErrorStatus(EINVAL);
256}
257
258// Calls the message handler for the DisplaySurface associated with this
259// channel.
260pdx::Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
261  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
268    REPLY_ERROR_RETURN(message, EINVAL, {});
269}
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
294void DisplayService::UpdateActiveDisplaySurfaces() {
295  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  }
325
326  hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
327}
328
329pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
330    const std::string& name, size_t size, int producer_usage,
331    int consumer_usage) {
332  auto named_buffer = named_buffers_.find(name);
333  if (named_buffer == named_buffers_.end()) {
334    auto ion_buffer = std::make_unique<IonBuffer>(
335        static_cast<int>(size), 1, HAL_PIXEL_FORMAT_BLOB, producer_usage,
336        consumer_usage);
337    named_buffer =
338        named_buffers_.insert(std::make_pair(name, std::move(ion_buffer)))
339            .first;
340  }
341
342  return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
343}
344
345void DisplayService::OnHardwareComposerRefresh() {
346  hardware_composer_.OnHardwareComposerRefresh();
347}
348
349void DisplayService::SetDisplayConfigurationUpdateNotifier(
350    DisplayConfigurationUpdateNotifier update_notifier) {
351  update_notifier_ = update_notifier;
352}
353
354void DisplayService::NotifyDisplayConfigurationUpdate() {
355  if (update_notifier_)
356    update_notifier_();
357}
358
359int DisplayService::IsVrAppRunning(pdx::Message& message) {
360  bool visible = false;
361  ForEachDisplaySurface(
362      [&visible](const std::shared_ptr<DisplaySurface>& surface) {
363        if (surface->client_z_order() == 0 && surface->IsVisible())
364          visible = true;
365      });
366
367  REPLY_SUCCESS_RETURN(message, visible, 0);
368}
369
370}  // namespace dvr
371}  // namespace android
372