display_service.cpp revision 302b74ffc656243d91ee6ddd8743239ef2dfbdba
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>(0.0f, 212 view_params.distortion_coefficients_r); 213 214 if (!view_params.distortion_coefficients_g.empty()) { 215 green_distortion = std::make_shared<PolynomialRadialDistortion>(0.0f, 216 view_params.distortion_coefficients_g); 217 } 218 219 if (!view_params.distortion_coefficients_b.empty()) { 220 blue_distortion = std::make_shared<PolynomialRadialDistortion>(0.0f, 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 // TODO(hendrikw): Update BufferProducer to take producer_usage and 335 // consumer_usage flags. 336 auto ion_buffer = std::make_unique<IonBuffer>( 337 static_cast<int>(size), 1, HAL_PIXEL_FORMAT_BLOB, 338 producer_usage | consumer_usage); 339 named_buffer = 340 named_buffers_.insert(std::make_pair(name, std::move(ion_buffer))) 341 .first; 342 } 343 344 return {BorrowedNativeBufferHandle(*named_buffer->second, 0)}; 345} 346 347void DisplayService::OnHardwareComposerRefresh() { 348 hardware_composer_.OnHardwareComposerRefresh(); 349} 350 351void DisplayService::SetDisplayConfigurationUpdateNotifier( 352 DisplayConfigurationUpdateNotifier update_notifier) { 353 update_notifier_ = update_notifier; 354} 355 356void DisplayService::NotifyDisplayConfigurationUpdate() { 357 if (update_notifier_) 358 update_notifier_(); 359} 360 361int DisplayService::IsVrAppRunning(pdx::Message& message) { 362 bool visible = false; 363 ForEachDisplaySurface( 364 [&visible](const std::shared_ptr<DisplaySurface>& surface) { 365 if (surface->client_z_order() == 0 && surface->IsVisible()) 366 visible = true; 367 }); 368 369 REPLY_SUCCESS_RETURN(message, visible, 0); 370} 371 372} // namespace dvr 373} // namespace android 374