display_service.cpp revision 050b2c83304bd16ec3a838da08b6ba6acf6a3af4
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() 34 : DisplayService(nullptr) {} 35 36DisplayService::DisplayService(Hwc2::Composer* hidl) 37 : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)), 38 hardware_composer_(hidl) { 39 hardware_composer_.Initialize(); 40} 41 42bool DisplayService::IsInitialized() const { 43 return BASE::IsInitialized() && hardware_composer_.IsInitialized(); 44} 45 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 87 case DisplayRPC::SetViewerParams::Opcode: 88 DispatchRemoteMethod<DisplayRPC::SetViewerParams>( 89 *this, &DisplayService::OnSetViewerParams, message); 90 return 0; 91 92 case DisplayRPC::GetPoseBuffer::Opcode: 93 DispatchRemoteMethod<DisplayRPC::GetPoseBuffer>( 94 *this, &DisplayService::OnGetPoseBuffer, message); 95 return 0; 96 97 // Direct the surface specific messages to the surface instance. 98 case DisplayRPC::CreateBufferQueue::Opcode: 99 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 190void 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 252pdx::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 261// 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 297void DisplayService::UpdateActiveDisplaySurfaces() { 298 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 } 328 329 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces)); 330} 331 332pdx::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 344void DisplayService::OnHardwareComposerRefresh() { 345 hardware_composer_.OnHardwareComposerRefresh(); 346} 347 348void 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 360