display_service.cpp revision 10e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848
1#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 { 22 23constexpr char kPersistentPoseBufferName[] = "DvrPersistentPoseBuffer"; 24const int kPersistentPoseBufferUserId = 0; 25const int kPersistentPoseBufferGroupId = 0; 26const size_t kTimingDataSizeOffset = 128; 27 28} // anonymous namespace 29 30namespace android { 31namespace dvr { 32 33DisplayService::DisplayService() : DisplayService(nullptr) {} 34 35DisplayService::DisplayService(Hwc2::Composer* hidl) 36 : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)), 37 hardware_composer_(hidl) { 38 hardware_composer_.Initialize(); 39} 40 41bool DisplayService::IsInitialized() const { 42 return BASE::IsInitialized() && hardware_composer_.IsInitialized(); 43} 44 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 86 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 96 case DisplayRPC::SetViewerParams::Opcode: 97 DispatchRemoteMethod<DisplayRPC::SetViewerParams>( 98 *this, &DisplayService::OnSetViewerParams, message); 99 return 0; 100 101 case DisplayRPC::GetPoseBuffer::Opcode: 102 DispatchRemoteMethod<DisplayRPC::GetPoseBuffer>( 103 *this, &DisplayService::OnGetPoseBuffer, message); 104 return 0; 105 106 // Direct the surface specific messages to the surface instance. 107 case DisplayRPC::CreateBufferQueue::Opcode: 108 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 199int 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 209void 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 271pdx::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 280// 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 316int DisplayService::UpdateActiveDisplaySurfaces() { 317 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 } 347 return hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces)); 348} 349 350pdx::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 362void DisplayService::OnHardwareComposerRefresh() { 363 hardware_composer_.OnHardwareComposerRefresh(); 364} 365 366void 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 378