Add DaydreamVR native libraries and services
Upstreaming the main VR system components from master-dreamos-dev
into goog/master.
Bug: None
Test: `m -j32` succeeds. Sailfish boots and basic_vr sample app works
Change-Id: I853015872afc443aecee10411ef2d6b79184d051
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
new file mode 100644
index 0000000..cfb346d
--- /dev/null
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -0,0 +1,276 @@
+#include "include/private/dvr/display_client.h"
+
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+#include <pdx/default_transport/client_channel.h>
+#include <pdx/default_transport/client_channel_factory.h>
+#include <pdx/status.h>
+
+#include <mutex>
+
+#include <private/dvr/display_rpc.h>
+#include <private/dvr/late_latch.h>
+#include <private/dvr/native_buffer.h>
+
+using android::pdx::LocalHandle;
+using android::pdx::LocalChannelHandle;
+using android::pdx::Status;
+using android::pdx::Transaction;
+using android::pdx::rpc::IfAnyOf;
+
+namespace android {
+namespace dvr {
+
+SurfaceClient::SurfaceClient(LocalChannelHandle channel_handle,
+ SurfaceType type)
+ : Client{pdx::default_transport::ClientChannel::Create(
+ std::move(channel_handle))},
+ type_(type) {}
+
+SurfaceClient::SurfaceClient(const std::string& endpoint_path, SurfaceType type)
+ : Client{pdx::default_transport::ClientChannelFactory::Create(
+ endpoint_path),
+ kInfiniteTimeout},
+ type_(type) {}
+
+int SurfaceClient::GetMetadataBufferFd(LocalHandle* out_fd) {
+ auto buffer_producer = GetMetadataBuffer();
+ if (!buffer_producer)
+ return -ENOMEM;
+
+ *out_fd = buffer_producer->GetBlobFd();
+ return 0;
+}
+
+std::shared_ptr<BufferProducer> SurfaceClient::GetMetadataBuffer() {
+ if (!metadata_buffer_) {
+ auto status = InvokeRemoteMethod<DisplayRPC::GetMetadataBuffer>();
+ if (!status) {
+ ALOGE(
+ "SurfaceClient::AllocateMetadataBuffer: Failed to allocate buffer: "
+ "%s",
+ status.GetErrorMessage().c_str());
+ return nullptr;
+ }
+
+ metadata_buffer_ = BufferProducer::Import(status.take());
+ }
+
+ return metadata_buffer_;
+}
+
+DisplaySurfaceClient::DisplaySurfaceClient(int width, int height, int format,
+ int usage, int flags)
+ : BASE(DisplayRPC::kClientPath, SurfaceTypeEnum::Normal),
+ width_(width),
+ height_(height),
+ format_(format),
+ usage_(usage),
+ flags_(flags),
+ z_order_(0),
+ visible_(true),
+ exclude_from_blur_(false),
+ blur_behind_(true),
+ mapped_metadata_buffer_(nullptr) {
+ auto status = InvokeRemoteMethod<DisplayRPC::CreateSurface>(
+ width, height, format, usage, flags);
+ if (!status) {
+ ALOGE(
+ "DisplaySurfaceClient::DisplaySurfaceClient: Failed to create display "
+ "surface: %s",
+ status.GetErrorMessage().c_str());
+ Close(status.error());
+ }
+}
+
+void DisplaySurfaceClient::SetVisible(bool visible) {
+ SetAttributes({{DisplaySurfaceAttributeEnum::Visible,
+ DisplaySurfaceAttributeValue{visible}}});
+}
+
+void DisplaySurfaceClient::SetZOrder(int z_order) {
+ SetAttributes({{DisplaySurfaceAttributeEnum::ZOrder,
+ DisplaySurfaceAttributeValue{z_order}}});
+}
+
+void DisplaySurfaceClient::SetExcludeFromBlur(bool exclude_from_blur) {
+ SetAttributes({{DisplaySurfaceAttributeEnum::ExcludeFromBlur,
+ DisplaySurfaceAttributeValue{exclude_from_blur}}});
+}
+
+void DisplaySurfaceClient::SetBlurBehind(bool blur_behind) {
+ SetAttributes({{DisplaySurfaceAttributeEnum::BlurBehind,
+ DisplaySurfaceAttributeValue{blur_behind}}});
+}
+
+void DisplaySurfaceClient::SetAttributes(
+ const DisplaySurfaceAttributes& attributes) {
+ Status<int> status =
+ InvokeRemoteMethod<DisplayRPC::SetAttributes>(attributes);
+ if (!status) {
+ ALOGE(
+ "DisplaySurfaceClient::SetAttributes: Failed to set display surface "
+ "attributes: %s",
+ status.GetErrorMessage().c_str());
+ return;
+ }
+
+ // Set the local cached copies of the attributes we care about from the full
+ // set of attributes sent to the display service.
+ for (const auto& attribute : attributes) {
+ const auto& key = attribute.first;
+ const auto* variant = &attribute.second;
+ bool invalid_value = false;
+ switch (key) {
+ case DisplaySurfaceAttributeEnum::Visible:
+ invalid_value =
+ !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
+ break;
+ case DisplaySurfaceAttributeEnum::ZOrder:
+ invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
+ break;
+ case DisplaySurfaceAttributeEnum::ExcludeFromBlur:
+ invalid_value =
+ !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &exclude_from_blur_);
+ break;
+ case DisplaySurfaceAttributeEnum::BlurBehind:
+ invalid_value =
+ !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &blur_behind_);
+ break;
+ }
+
+ if (invalid_value) {
+ ALOGW(
+ "DisplaySurfaceClient::SetAttributes: Failed to set display "
+ "surface attribute '%s' because of incompatible type: %d",
+ DisplaySurfaceAttributeEnum::ToString(key).c_str(), variant->index());
+ }
+ }
+}
+
+std::shared_ptr<BufferProducer> DisplaySurfaceClient::AllocateBuffer(
+ uint32_t* buffer_index) {
+ auto status = InvokeRemoteMethod<DisplayRPC::AllocateBuffer>();
+ if (!status) {
+ ALOGE("DisplaySurfaceClient::AllocateBuffer: Failed to allocate buffer: %s",
+ status.GetErrorMessage().c_str());
+ return nullptr;
+ }
+
+ if (buffer_index)
+ *buffer_index = status.get().first;
+ return BufferProducer::Import(status.take().second);
+}
+
+volatile DisplaySurfaceMetadata* DisplaySurfaceClient::GetMetadataBufferPtr() {
+ if (!mapped_metadata_buffer_) {
+ if (auto buffer_producer = GetMetadataBuffer()) {
+ void* addr = nullptr;
+ const int ret = buffer_producer->GetBlobReadWritePointer(
+ sizeof(DisplaySurfaceMetadata), &addr);
+ if (ret < 0) {
+ ALOGE(
+ "DisplaySurfaceClient::GetMetadataBufferPtr: Failed to map surface "
+ "metadata: %s",
+ strerror(-ret));
+ return nullptr;
+ }
+ mapped_metadata_buffer_ = static_cast<DisplaySurfaceMetadata*>(addr);
+ }
+ }
+
+ return mapped_metadata_buffer_;
+}
+
+LocalChannelHandle DisplaySurfaceClient::CreateVideoMeshSurface() {
+ auto status = InvokeRemoteMethod<DisplayRPC::CreateVideoMeshSurface>();
+ if (!status) {
+ ALOGE(
+ "DisplaySurfaceClient::CreateVideoMeshSurface: Failed to create "
+ "video mesh surface: %s",
+ status.GetErrorMessage().c_str());
+ }
+ return status.take();
+}
+
+DisplayClient::DisplayClient(int* error)
+ : BASE(pdx::default_transport::ClientChannelFactory::Create(
+ DisplayRPC::kClientPath),
+ kInfiniteTimeout) {
+ if (error)
+ *error = Client::error();
+}
+
+int DisplayClient::GetDisplayMetrics(SystemDisplayMetrics* metrics) {
+ auto status = InvokeRemoteMethod<DisplayRPC::GetMetrics>();
+ if (!status) {
+ ALOGE("DisplayClient::GetDisplayMetrics: Failed to get metrics: %s",
+ status.GetErrorMessage().c_str());
+ return -status.error();
+ }
+
+ *metrics = status.get();
+ return 0;
+}
+
+pdx::Status<void> DisplayClient::SetViewerParams(const ViewerParams& viewer_params) {
+ auto status = InvokeRemoteMethod<DisplayRPC::SetViewerParams>(viewer_params);
+ if (!status) {
+ ALOGE("DisplayClient::SetViewerParams: Failed to set viewer params: %s",
+ status.GetErrorMessage().c_str());
+ }
+ return status;
+}
+
+int DisplayClient::GetLastFrameEdsTransform(LateLatchOutput* ll_out) {
+ auto status = InvokeRemoteMethod<DisplayRPC::GetEdsCapture>();
+ if (!status) {
+ ALOGE(
+ "DisplayClient::GetLastFrameLateLatch: Failed to get most recent late"
+ " latch: %s",
+ status.GetErrorMessage().c_str());
+ return -status.error();
+ }
+
+ if (status.get().size() != sizeof(LateLatchOutput)) {
+ ALOGE(
+ "DisplayClient::GetLastFrameLateLatch: Error expected to receive %zu "
+ "bytes but received %zu",
+ sizeof(LateLatchOutput), status.get().size());
+ return -EIO;
+ }
+
+ *ll_out = *reinterpret_cast<const LateLatchOutput*>(status.get().data());
+ return 0;
+}
+
+int DisplayClient::EnterVrMode() {
+ auto status = InvokeRemoteMethod<DisplayRPC::EnterVrMode>();
+ if (!status) {
+ ALOGE(
+ "DisplayClient::EnterVrMode: Failed to set display service to Vr mode");
+ return -status.error();
+ }
+
+ return 0;
+}
+
+int DisplayClient::ExitVrMode() {
+ auto status = InvokeRemoteMethod<DisplayRPC::ExitVrMode>();
+ if (!status) {
+ ALOGE(
+ "DisplayClient::ExitVrMode: Failed to revert display service from Vr "
+ "mode");
+ return -status.error();
+ }
+
+ return 0;
+}
+
+std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface(
+ int width, int height, int format, int usage, int flags) {
+ return DisplaySurfaceClient::Create(width, height, format, usage, flags);
+}
+
+} // namespace dvr
+} // namespace android