display_service.cpp revision f43d13e4e35ae7d3cdafc4b97c819669d42cef78
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 android { 22namespace dvr { 23 24DisplayService::DisplayService() 25 : 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. 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 78 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. 84 case DisplayRPC::CreateBufferQueue::Opcode: 85 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 176void 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 274void DisplayService::UpdateActiveDisplaySurfaces() { 275 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 } 305 306 hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces)); 307} 308 309void DisplayService::OnHardwareComposerRefresh() { 310 hardware_composer_.OnHardwareComposerRefresh(); 311} 312 313void 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 325