blob: b5210c965d7b2b09feb7150b130ce1fbbe66a318 [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
Steven Thomasf43d13e2017-03-06 11:45:16 -080024DisplayService::DisplayService()
25 : 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.
59int 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 0;
67
68 case DisplayRPC::GetEdsCapture::Opcode:
69 DispatchRemoteMethod<DisplayRPC::GetEdsCapture>(
70 *this, &DisplayService::OnGetEdsCapture, message);
71 return 0;
72
73 case DisplayRPC::CreateSurface::Opcode:
74 DispatchRemoteMethod<DisplayRPC::CreateSurface>(
75 *this, &DisplayService::OnCreateSurface, message);
76 return 0;
77
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080078 case DisplayRPC::SetViewerParams::Opcode:
79 DispatchRemoteMethod<DisplayRPC::SetViewerParams>(
80 *this, &DisplayService::OnSetViewerParams, message);
81 return 0;
82
83 // Direct the surface specific messages to the surface instance.
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -080084 case DisplayRPC::CreateBufferQueue::Opcode:
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080085 case DisplayRPC::SetAttributes::Opcode:
86 case DisplayRPC::GetMetadataBuffer::Opcode:
87 case DisplayRPC::CreateVideoMeshSurface::Opcode:
88 case DisplayRPC::VideoMeshSurfaceCreateProducerQueue::Opcode:
89 return HandleSurfaceMessage(message);
90
91 default:
92 return Service::HandleMessage(message);
93 }
94}
95
96SystemDisplayMetrics DisplayService::OnGetMetrics(pdx::Message& message) {
97 const Compositor* compositor = hardware_composer_.GetCompositor();
98 if (compositor == nullptr)
99 REPLY_ERROR_RETURN(message, EINVAL, {});
100
101 HeadMountMetrics head_mount = compositor->head_mount_metrics();
102 CompositeHmd hmd(head_mount, hardware_composer_.GetHmdDisplayMetrics());
103 vec2i distorted_render_size = hmd.GetRecommendedRenderTargetSize();
104 FieldOfView left_fov = hmd.GetEyeFov(kLeftEye);
105 FieldOfView right_fov = hmd.GetEyeFov(kRightEye);
106
107 SystemDisplayMetrics metrics;
108
109 metrics.display_native_width = GetDisplayMetrics().width;
110 metrics.display_native_height = GetDisplayMetrics().height;
111 metrics.display_x_dpi = GetDisplayMetrics().dpi.x;
112 metrics.display_y_dpi = GetDisplayMetrics().dpi.y;
113 metrics.distorted_width = distorted_render_size[0];
114 metrics.distorted_height = distorted_render_size[1];
115 metrics.vsync_period_ns =
116 hardware_composer_.native_display_metrics().vsync_period_ns;
117 metrics.hmd_ipd_mm = 0;
118 metrics.inter_lens_distance_m = head_mount.GetInterLensDistance();
119 metrics.left_fov_lrbt[0] = left_fov.GetLeft();
120 metrics.left_fov_lrbt[1] = left_fov.GetRight();
121 metrics.left_fov_lrbt[2] = left_fov.GetBottom();
122 metrics.left_fov_lrbt[3] = left_fov.GetTop();
123 metrics.right_fov_lrbt[0] = right_fov.GetLeft();
124 metrics.right_fov_lrbt[1] = right_fov.GetRight();
125 metrics.right_fov_lrbt[2] = right_fov.GetBottom();
126 metrics.right_fov_lrbt[3] = right_fov.GetTop();
127
128 return metrics;
129}
130
131// Creates a new DisplaySurface and associates it with this channel. This may
132// only be done once per channel.
133int DisplayService::OnCreateSurface(pdx::Message& message, int width,
134 int height, int format, int usage,
135 DisplaySurfaceFlags flags) {
136 // A surface may only be created once per channel.
137 if (message.GetChannel())
138 return -EINVAL;
139
140 ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
141 message.GetChannelId());
142
143 // Use the channel id as the unique surface id.
144 const int surface_id = message.GetChannelId();
145 const int process_id = message.GetProcessId();
146
147 ALOGI_IF(TRACE,
148 "DisplayService::OnCreateSurface: surface_id=%d process_id=%d "
149 "width=%d height=%d format=%x usage=%x flags=%x",
150 surface_id, process_id, width, height, format, usage, flags);
151
152 // TODO(eieio,jbates): Validate request parameters.
153 auto channel = std::make_shared<DisplaySurface>(
154 this, surface_id, process_id, width, height, format, usage, flags);
155
156 message.SetChannel(channel);
157 NotifyDisplayConfigurationUpdate();
158 return 0;
159}
160
161DisplayRPC::ByteBuffer DisplayService::OnGetEdsCapture(pdx::Message& message) {
162 Compositor* compositor = hardware_composer_.GetCompositor();
163 if (compositor == nullptr)
164 REPLY_ERROR_RETURN(message, EINVAL, {});
165
166 std::vector<std::uint8_t> buffer(sizeof(LateLatchOutput));
167
168 if (!compositor->GetLastEdsPose(
169 reinterpret_cast<LateLatchOutput*>(buffer.data()))) {
170 REPLY_ERROR_RETURN(message, EPERM, {});
171 }
172
173 return WrapBuffer(std::move(buffer));
174}
175
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800176void DisplayService::OnSetViewerParams(pdx::Message& message,
177 const ViewerParams& view_params) {
178 Compositor* compositor = hardware_composer_.GetCompositor();
179 if (compositor == nullptr)
180 REPLY_ERROR_RETURN(message, EINVAL);
181
182 FieldOfView left(55.0f, 55.0f, 55.0f, 55.0f);
183 FieldOfView right(55.0f, 55.0f, 55.0f, 55.0f);
184 if (view_params.left_eye_field_of_view_angles.size() >= 4) {
185 left = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[0]),
186 ToRad(view_params.left_eye_field_of_view_angles[1]),
187 ToRad(view_params.left_eye_field_of_view_angles[2]),
188 ToRad(view_params.left_eye_field_of_view_angles[3]));
189 right = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[1]),
190 ToRad(view_params.left_eye_field_of_view_angles[0]),
191 ToRad(view_params.left_eye_field_of_view_angles[2]),
192 ToRad(view_params.left_eye_field_of_view_angles[3]));
193 }
194
195 std::shared_ptr<ColorChannelDistortion> red_distortion;
196 std::shared_ptr<ColorChannelDistortion> green_distortion;
197 std::shared_ptr<ColorChannelDistortion> blue_distortion;
198
199 // We should always have a red distortion.
200 LOG_FATAL_IF(view_params.distortion_coefficients_r.empty());
201 red_distortion = std::make_shared<PolynomialRadialDistortion>(
202 view_params.distortion_coefficients_r);
203
204 if (!view_params.distortion_coefficients_g.empty()) {
205 green_distortion = std::make_shared<PolynomialRadialDistortion>(
206 view_params.distortion_coefficients_g);
207 }
208
209 if (!view_params.distortion_coefficients_b.empty()) {
210 blue_distortion = std::make_shared<PolynomialRadialDistortion>(
211 view_params.distortion_coefficients_b);
212 }
213
214 HeadMountMetrics::EyeOrientation left_orientation =
215 HeadMountMetrics::EyeOrientation::kCCW0Degrees;
216 HeadMountMetrics::EyeOrientation right_orientation =
217 HeadMountMetrics::EyeOrientation::kCCW0Degrees;
218
219 if (view_params.eye_orientations.size() > 1) {
220 left_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
221 view_params.eye_orientations[0]);
222 right_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
223 view_params.eye_orientations[1]);
224 }
225
226 HeadMountMetrics head_mount_metrics(
227 view_params.inter_lens_distance, view_params.tray_to_lens_distance,
228 view_params.screen_to_lens_distance,
229 static_cast<HeadMountMetrics::VerticalAlignment>(
230 view_params.vertical_alignment),
231 left, right, red_distortion, green_distortion, blue_distortion,
232 left_orientation, right_orientation,
233 view_params.screen_center_to_lens_distance);
234
235 compositor->UpdateHeadMountMetrics(head_mount_metrics);
236}
237
238// Calls the message handler for the DisplaySurface associated with this
239// channel.
240int DisplayService::HandleSurfaceMessage(pdx::Message& message) {
241 auto surface = std::static_pointer_cast<SurfaceChannel>(message.GetChannel());
242 ALOGW_IF(!surface,
243 "DisplayService::HandleSurfaceMessage: surface is nullptr!");
244
245 if (surface)
246 return surface->HandleMessage(message);
247 else
248 REPLY_ERROR_RETURN(message, EINVAL, 0);
249}
250
251std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
252 int surface_id) const {
253 return std::static_pointer_cast<DisplaySurface>(GetChannel(surface_id));
254}
255
256std::vector<std::shared_ptr<DisplaySurface>>
257DisplayService::GetDisplaySurfaces() const {
258 return GetChannels<DisplaySurface>();
259}
260
261std::vector<std::shared_ptr<DisplaySurface>>
262DisplayService::GetVisibleDisplaySurfaces() const {
263 std::vector<std::shared_ptr<DisplaySurface>> visible_surfaces;
264
265 ForEachDisplaySurface(
266 [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
267 if (surface->IsVisible())
268 visible_surfaces.push_back(surface);
269 });
270
271 return visible_surfaces;
272}
273
Steven Thomasf43d13e2017-03-06 11:45:16 -0800274void DisplayService::UpdateActiveDisplaySurfaces() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800275 auto visible_surfaces = GetVisibleDisplaySurfaces();
276
277 // Sort the surfaces based on manager z order first, then client z order.
278 std::sort(visible_surfaces.begin(), visible_surfaces.end(),
279 [](const std::shared_ptr<DisplaySurface>& a,
280 const std::shared_ptr<DisplaySurface>& b) {
281 return a->manager_z_order() != b->manager_z_order()
282 ? a->manager_z_order() < b->manager_z_order()
283 : a->client_z_order() < b->client_z_order();
284 });
285
286 ALOGD_IF(TRACE,
287 "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
288 visible_surfaces.size());
289
290 // TODO(jbates) Have the shell manage blurred layers.
291 bool blur_requested = false;
292 auto end = visible_surfaces.crend();
293 for (auto it = visible_surfaces.crbegin(); it != end; ++it) {
294 auto surface = *it;
295 // Surfaces with exclude_from_blur==true are not blurred
296 // and are excluded from blur computation of other layers.
297 if (surface->client_exclude_from_blur()) {
298 surface->ManagerSetBlur(0.0f);
299 continue;
300 }
301 surface->ManagerSetBlur(blur_requested ? 1.0f : 0.0f);
302 if (surface->client_blur_behind())
303 blur_requested = true;
304 }
Steven Thomasf43d13e2017-03-06 11:45:16 -0800305
306 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800307}
308
Steven Thomas3cfac282017-02-06 12:29:30 -0800309void DisplayService::OnHardwareComposerRefresh() {
310 hardware_composer_.OnHardwareComposerRefresh();
311}
312
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800313void DisplayService::SetDisplayConfigurationUpdateNotifier(
314 DisplayConfigurationUpdateNotifier update_notifier) {
315 update_notifier_ = update_notifier;
316}
317
318void DisplayService::NotifyDisplayConfigurationUpdate() {
319 if (update_notifier_)
320 update_notifier_();
321}
322
323} // namespace dvr
324} // namespace android