Remove the VR compositor from the framework.
Remove the VR compositor framework and enable out-of-process VR composition
in VrCore.
This CL seems large due to the ripple effect of changing the VrFlinger
API and protocol types. There are three major modules that require
concurrent changes:
1. Protocol definitions and low-level VrFlinger API in libdisplay.
* Additional changes needed to keep old interfaces working for
a short time while replacing the dependent code (dvrGraphics*).
2. VrFlinger service implementation changes to support VrCore compositor
and the removal of the internal compositor.
3. Changes to libdvr platform library API due to changes in #1 and #2.
Because of the nature of the interdependence of types and other defs it is
difficult to break this CL into smaller chunks. However, review of the three
major modules (libdisplay, libdvr, and libvrflinger) may be done separately
to ease the mental burden on reviewers.
Change Summary:
- Remove obsolete screenshot service. VR screenshots will be implemented
by VrCore.
- Update display protocol definitions for changes in VrFlinger service
requirements. The majority of the changes in libdisplay are a
consequence of these protocol and service changes.
- Update VrFlinger to support two kinds of surfaces:
1. Application - use by VR apps.
2. Direct - used by VrCore (protected by permission check).
- Remove VrFlinger internal compositor and GL context.
- Remove obsolete debug console.
- Update VrFlinger hardware composer interface to handle direct
surfaces only, removing the concept of GPU (compositor) layers.
- Update display manager to expose access to application surface info
to VrCore (protected by permission check).
- Update libdvr platform library interfaces for changes to VrFlinger
API / protocol.
- Clean up libdvr API struct setup using a common include.
- Add C++ header-only helpers for DVR platform library opaque types.
Bug: 36401174
Test: Build; run VrFlinger display test tool.
Change-Id: I15abfde5f72dbb3725a3f58621486afba6b64902
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index f56bc02..47efa76 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -3,30 +3,30 @@
#include <unistd.h>
#include <vector>
+#include <dvr/dvr_display_types.h>
#include <pdx/default_transport/service_endpoint.h>
#include <pdx/rpc/remote_method.h>
-#include <private/dvr/composite_hmd.h>
-#include <private/dvr/device_metrics.h>
#include <private/dvr/display_protocol.h>
-#include <private/dvr/display_types.h>
#include <private/dvr/numeric.h>
-#include <private/dvr/polynomial_radial_distortion.h>
#include <private/dvr/types.h>
+using android::dvr::display::DisplayProtocol;
using android::pdx::Channel;
+using android::pdx::ErrorStatus;
using android::pdx::Message;
+using android::pdx::Status;
using android::pdx::default_transport::Endpoint;
using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::WrapBuffer;
namespace android {
namespace dvr {
-DisplayService::DisplayService() : DisplayService(nullptr) {}
-
-DisplayService::DisplayService(Hwc2::Composer* hidl)
- : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
- hardware_composer_(hidl) {
+DisplayService::DisplayService(Hwc2::Composer* hidl,
+ RequestDisplayCallback request_display_callback)
+ : BASE("DisplayService",
+ Endpoint::Create(display::DisplayProtocol::kClientPath)),
+ hardware_composer_(hidl, request_display_callback),
+ request_display_callback_(request_display_callback) {
hardware_composer_.Initialize();
}
@@ -34,68 +34,51 @@
return BASE::IsInitialized() && hardware_composer_.IsInitialized();
}
-std::string DisplayService::DumpState(size_t max_length) {
- std::vector<char> buffer(max_length);
- uint32_t max_len_p = static_cast<uint32_t>(max_length);
- hardware_composer_.Dump(buffer.data(), &max_len_p);
- return std::string(buffer.data());
+std::string DisplayService::DumpState(size_t /*max_length*/) {
+ return hardware_composer_.Dump();
}
-void DisplayService::OnChannelClose(pdx::Message& /*message*/,
+void DisplayService::OnChannelClose(pdx::Message& message,
const std::shared_ptr<Channel>& channel) {
- auto surface = std::static_pointer_cast<SurfaceChannel>(channel);
- if (surface && surface->type() == SurfaceTypeEnum::Normal) {
- auto display_surface = std::static_pointer_cast<DisplaySurface>(surface);
- display_surface->ManagerSetVisible(false);
- display_surface->ClientSetVisible(false);
- NotifyDisplayConfigurationUpdate();
+ if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
+ surface->OnSetAttributes(message,
+ {{display::SurfaceAttribute::Visible,
+ display::SurfaceAttributeValue{false}}});
+ SurfaceUpdated(surface->surface_type(),
+ display::SurfaceUpdateFlags::VisibilityChanged);
}
- // TODO(jwcai) Handle ChannelClose of VideoMeshSurface.
}
// First-level dispatch for display service messages. Directly handles messages
// that are independent of the display surface (metrics, creation) and routes
// surface-specific messages to the per-instance handlers.
-pdx::Status<void> DisplayService::HandleMessage(pdx::Message& message) {
- auto channel = message.GetChannel<SurfaceChannel>();
-
+Status<void> DisplayService::HandleMessage(pdx::Message& message) {
+ ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
switch (message.GetOp()) {
- case DisplayRPC::GetMetrics::Opcode:
- DispatchRemoteMethod<DisplayRPC::GetMetrics>(
+ case DisplayProtocol::GetMetrics::Opcode:
+ DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
*this, &DisplayService::OnGetMetrics, message);
return {};
- case DisplayRPC::GetEdsCapture::Opcode:
- DispatchRemoteMethod<DisplayRPC::GetEdsCapture>(
- *this, &DisplayService::OnGetEdsCapture, message);
- return {};
-
- case DisplayRPC::CreateSurface::Opcode:
- DispatchRemoteMethod<DisplayRPC::CreateSurface>(
+ case DisplayProtocol::CreateSurface::Opcode:
+ DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
*this, &DisplayService::OnCreateSurface, message);
return {};
- case DisplayRPC::SetViewerParams::Opcode:
- DispatchRemoteMethod<DisplayRPC::SetViewerParams>(
- *this, &DisplayService::OnSetViewerParams, message);
- return {};
-
- case DisplayRPC::GetNamedBuffer::Opcode:
- DispatchRemoteMethod<DisplayRPC::GetNamedBuffer>(
+ case DisplayProtocol::GetNamedBuffer::Opcode:
+ DispatchRemoteMethod<DisplayProtocol::GetNamedBuffer>(
*this, &DisplayService::OnGetNamedBuffer, message);
return {};
- case DisplayRPC::IsVrAppRunning::Opcode:
- DispatchRemoteMethod<DisplayRPC::IsVrAppRunning>(
+ case DisplayProtocol::IsVrAppRunning::Opcode:
+ DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
*this, &DisplayService::IsVrAppRunning, message);
return {};
// Direct the surface specific messages to the surface instance.
- case DisplayRPC::CreateBufferQueue::Opcode:
- case DisplayRPC::SetAttributes::Opcode:
- case DisplayRPC::GetMetadataBuffer::Opcode:
- case DisplayRPC::CreateVideoMeshSurface::Opcode:
- case DisplayRPC::VideoMeshSurfaceCreateProducerQueue::Opcode:
+ case DisplayProtocol::SetAttributes::Opcode:
+ case DisplayProtocol::CreateQueue::Opcode:
+ case DisplayProtocol::GetSurfaceInfo::Opcode:
return HandleSurfaceMessage(message);
default:
@@ -103,49 +86,29 @@
}
}
-SystemDisplayMetrics DisplayService::OnGetMetrics(pdx::Message& message) {
- const Compositor* compositor = hardware_composer_.GetCompositor();
- if (compositor == nullptr)
- REPLY_ERROR_RETURN(message, EINVAL, {});
-
- HeadMountMetrics head_mount = compositor->head_mount_metrics();
- CompositeHmd hmd(head_mount, hardware_composer_.GetHmdDisplayMetrics());
- vec2i distorted_render_size = hmd.GetRecommendedRenderTargetSize();
- FieldOfView left_fov = hmd.GetEyeFov(kLeftEye);
- FieldOfView right_fov = hmd.GetEyeFov(kRightEye);
-
- SystemDisplayMetrics metrics;
-
- metrics.display_native_width = GetDisplayMetrics().width;
- metrics.display_native_height = GetDisplayMetrics().height;
- metrics.display_x_dpi = GetDisplayMetrics().dpi.x;
- metrics.display_y_dpi = GetDisplayMetrics().dpi.y;
- metrics.distorted_width = distorted_render_size[0];
- metrics.distorted_height = distorted_render_size[1];
- metrics.vsync_period_ns =
- hardware_composer_.native_display_metrics().vsync_period_ns;
- metrics.hmd_ipd_mm = 0;
- metrics.inter_lens_distance_m = head_mount.GetInterLensDistance();
- metrics.left_fov_lrbt[0] = left_fov.GetLeft();
- metrics.left_fov_lrbt[1] = left_fov.GetRight();
- metrics.left_fov_lrbt[2] = left_fov.GetBottom();
- metrics.left_fov_lrbt[3] = left_fov.GetTop();
- metrics.right_fov_lrbt[0] = right_fov.GetLeft();
- metrics.right_fov_lrbt[1] = right_fov.GetRight();
- metrics.right_fov_lrbt[2] = right_fov.GetBottom();
- metrics.right_fov_lrbt[3] = right_fov.GetTop();
-
- return metrics;
+Status<display::Metrics> DisplayService::OnGetMetrics(
+ pdx::Message& /*message*/) {
+ return {{static_cast<uint32_t>(GetDisplayMetrics().width),
+ static_cast<uint32_t>(GetDisplayMetrics().height),
+ static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
+ static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
+ static_cast<uint32_t>(
+ hardware_composer_.native_display_metrics().vsync_period_ns),
+ 0,
+ 0,
+ 0,
+ 0.0,
+ {},
+ {}}};
}
// Creates a new DisplaySurface and associates it with this channel. This may
// only be done once per channel.
-int DisplayService::OnCreateSurface(pdx::Message& message, int width,
- int height, int format, int usage,
- DisplaySurfaceFlags flags) {
+Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
+ pdx::Message& message, const display::SurfaceAttributes& attributes) {
// A surface may only be created once per channel.
if (message.GetChannel())
- return -EINVAL;
+ return ErrorStatus(EINVAL);
ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
message.GetChannelId());
@@ -153,119 +116,66 @@
// Use the channel id as the unique surface id.
const int surface_id = message.GetChannelId();
const int process_id = message.GetProcessId();
+ const int user_id = message.GetEffectiveUserId();
ALOGI_IF(TRACE,
- "DisplayService::OnCreateSurface: surface_id=%d process_id=%d "
- "width=%d height=%d format=%x usage=%x flags=%x",
- surface_id, process_id, width, height, format, usage, flags);
+ "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
+ surface_id, process_id);
- // TODO(eieio,jbates): Validate request parameters.
- auto channel = std::make_shared<DisplaySurface>(
- this, surface_id, process_id, width, height, format, usage, flags);
+ auto surface_status =
+ DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
+ if (!surface_status) {
+ ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
+ surface_status.GetErrorMessage().c_str());
+ return ErrorStatus(surface_status.error());
+ }
- message.SetChannel(channel);
- NotifyDisplayConfigurationUpdate();
- return 0;
+ SurfaceType surface_type = surface_status.get()->surface_type();
+ display::SurfaceUpdateFlags update_flags =
+ surface_status.get()->update_flags();
+ display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
+ surface_status.get()->visible(),
+ surface_status.get()->z_order()};
+
+ message.SetChannel(surface_status.take());
+
+ SurfaceUpdated(surface_type, update_flags);
+ return {surface_info};
}
-DisplayRPC::ByteBuffer DisplayService::OnGetEdsCapture(pdx::Message& message) {
- Compositor* compositor = hardware_composer_.GetCompositor();
- if (compositor == nullptr)
- REPLY_ERROR_RETURN(message, EINVAL, {});
-
- std::vector<std::uint8_t> buffer(sizeof(LateLatchOutput));
-
- if (!compositor->GetLastEdsPose(
- reinterpret_cast<LateLatchOutput*>(buffer.data()))) {
- REPLY_ERROR_RETURN(message, EPERM, {});
+void DisplayService::SurfaceUpdated(SurfaceType surface_type,
+ display::SurfaceUpdateFlags update_flags) {
+ ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
+ update_flags.value());
+ if (update_flags.value() != 0) {
+ if (surface_type == SurfaceType::Application)
+ NotifyDisplayConfigurationUpdate();
+ else
+ UpdateActiveDisplaySurfaces();
}
-
- return WrapBuffer(std::move(buffer));
-}
-
-void DisplayService::OnSetViewerParams(pdx::Message& message,
- const ViewerParams& view_params) {
- Compositor* compositor = hardware_composer_.GetCompositor();
- if (compositor == nullptr)
- REPLY_ERROR_RETURN(message, EINVAL);
-
- FieldOfView left(55.0f, 55.0f, 55.0f, 55.0f);
- FieldOfView right(55.0f, 55.0f, 55.0f, 55.0f);
- if (view_params.left_eye_field_of_view_angles.size() >= 4) {
- left = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[0]),
- ToRad(view_params.left_eye_field_of_view_angles[1]),
- ToRad(view_params.left_eye_field_of_view_angles[2]),
- ToRad(view_params.left_eye_field_of_view_angles[3]));
- right = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[1]),
- ToRad(view_params.left_eye_field_of_view_angles[0]),
- ToRad(view_params.left_eye_field_of_view_angles[2]),
- ToRad(view_params.left_eye_field_of_view_angles[3]));
- }
-
- std::shared_ptr<ColorChannelDistortion> red_distortion;
- std::shared_ptr<ColorChannelDistortion> green_distortion;
- std::shared_ptr<ColorChannelDistortion> blue_distortion;
-
- // We should always have a red distortion.
- LOG_FATAL_IF(view_params.distortion_coefficients_r.empty());
- red_distortion = std::make_shared<PolynomialRadialDistortion>(
- view_params.distortion_coefficients_r);
-
- if (!view_params.distortion_coefficients_g.empty()) {
- green_distortion = std::make_shared<PolynomialRadialDistortion>(
- view_params.distortion_coefficients_g);
- }
-
- if (!view_params.distortion_coefficients_b.empty()) {
- blue_distortion = std::make_shared<PolynomialRadialDistortion>(
- view_params.distortion_coefficients_b);
- }
-
- HeadMountMetrics::EyeOrientation left_orientation =
- HeadMountMetrics::EyeOrientation::kCCW0Degrees;
- HeadMountMetrics::EyeOrientation right_orientation =
- HeadMountMetrics::EyeOrientation::kCCW0Degrees;
-
- if (view_params.eye_orientations.size() > 1) {
- left_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
- view_params.eye_orientations[0]);
- right_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
- view_params.eye_orientations[1]);
- }
-
- HeadMountMetrics head_mount_metrics(
- view_params.inter_lens_distance, view_params.tray_to_lens_distance,
- view_params.screen_to_lens_distance,
- static_cast<HeadMountMetrics::VerticalAlignment>(
- view_params.vertical_alignment),
- left, right, red_distortion, green_distortion, blue_distortion,
- left_orientation, right_orientation,
- view_params.screen_center_to_lens_distance);
-
- compositor->UpdateHeadMountMetrics(head_mount_metrics);
}
pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
pdx::Message& /* message */, const std::string& name) {
+ ALOGD_IF(TRACE, "displayService::OnGetNamedBuffer: name=%s", name.c_str());
auto named_buffer = named_buffers_.find(name);
- if (named_buffer != named_buffers_.end()) {
+ if (named_buffer != named_buffers_.end())
return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
- }
-
- return pdx::ErrorStatus(EINVAL);
+ else
+ return pdx::ErrorStatus(EINVAL);
}
// Calls the message handler for the DisplaySurface associated with this
// channel.
-pdx::Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
- auto surface = std::static_pointer_cast<SurfaceChannel>(message.GetChannel());
+Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
+ auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
ALOGW_IF(!surface,
"DisplayService::HandleSurfaceMessage: surface is nullptr!");
if (surface)
return surface->HandleMessage(message);
else
- REPLY_ERROR_RETURN(message, EINVAL, {});
+ return ErrorStatus(EINVAL);
}
std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
@@ -278,14 +188,18 @@
return GetChannels<DisplaySurface>();
}
-std::vector<std::shared_ptr<DisplaySurface>>
+std::vector<std::shared_ptr<DirectDisplaySurface>>
DisplayService::GetVisibleDisplaySurfaces() const {
- std::vector<std::shared_ptr<DisplaySurface>> visible_surfaces;
+ std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
ForEachDisplaySurface(
+ SurfaceType::Direct,
[&](const std::shared_ptr<DisplaySurface>& surface) mutable {
- if (surface->IsVisible())
- visible_surfaces.push_back(surface);
+ if (surface->visible()) {
+ visible_surfaces.push_back(
+ std::static_pointer_cast<DirectDisplaySurface>(surface));
+ surface->ClearUpdate();
+ }
});
return visible_surfaces;
@@ -294,40 +208,21 @@
void DisplayService::UpdateActiveDisplaySurfaces() {
auto visible_surfaces = GetVisibleDisplaySurfaces();
- // Sort the surfaces based on manager z order first, then client z order.
std::sort(visible_surfaces.begin(), visible_surfaces.end(),
[](const std::shared_ptr<DisplaySurface>& a,
const std::shared_ptr<DisplaySurface>& b) {
- return a->manager_z_order() != b->manager_z_order()
- ? a->manager_z_order() < b->manager_z_order()
- : a->client_z_order() < b->client_z_order();
+ return a->z_order() < b->z_order();
});
ALOGD_IF(TRACE,
"DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
visible_surfaces.size());
- // TODO(jbates) Have the shell manage blurred layers.
- bool blur_requested = false;
- auto end = visible_surfaces.crend();
- for (auto it = visible_surfaces.crbegin(); it != end; ++it) {
- auto surface = *it;
- // Surfaces with exclude_from_blur==true are not blurred
- // and are excluded from blur computation of other layers.
- if (surface->client_exclude_from_blur()) {
- surface->ManagerSetBlur(0.0f);
- continue;
- }
- surface->ManagerSetBlur(blur_requested ? 1.0f : 0.0f);
- if (surface->client_blur_behind())
- blur_requested = true;
- }
-
hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
}
pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
- const std::string& name, size_t size, int usage) {
+ const std::string& name, size_t size, uint64_t usage) {
auto named_buffer = named_buffers_.find(name);
if (named_buffer == named_buffers_.end()) {
auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
@@ -354,15 +249,16 @@
update_notifier_();
}
-int DisplayService::IsVrAppRunning(pdx::Message& message) {
+Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
bool visible = false;
ForEachDisplaySurface(
+ SurfaceType::Application,
[&visible](const std::shared_ptr<DisplaySurface>& surface) {
- if (surface->client_z_order() == 0 && surface->IsVisible())
+ if (surface->visible())
visible = true;
});
- REPLY_SUCCESS_RETURN(message, visible, 0);
+ return {visible};
}
} // namespace dvr