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/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
index b79c8ba..41baef8 100644
--- a/libs/vr/libdisplay/Android.bp
+++ b/libs/vr/libdisplay/Android.bp
@@ -18,11 +18,11 @@
"display_manager_client.cpp",
"display_protocol.cpp",
"dummy_native_window.cpp",
+ "frame_history.cpp",
"gl_fenced_flush.cpp",
"graphics.cpp",
"late_latch.cpp",
"vsync_client.cpp",
- "frame_history.cpp",
]
localIncludeFiles = [
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index 494514d..dbee9f2 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -12,6 +12,7 @@
#include <private/dvr/late_latch.h>
#include <private/dvr/native_buffer.h>
+using android::pdx::ErrorStatus;
using android::pdx::LocalHandle;
using android::pdx::LocalChannelHandle;
using android::pdx::Status;
@@ -20,99 +21,61 @@
namespace android {
namespace dvr {
+namespace display {
-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",
+Surface::Surface(LocalChannelHandle channel_handle, int* error)
+ : BASE{pdx::default_transport::ClientChannel::Create(
+ std::move(channel_handle))} {
+ auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
+ if (!status) {
+ ALOGE("Surface::Surface: Failed to get surface info: %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());
+ if (error)
+ *error = status.error();
}
+
+ surface_id_ = status.get().surface_id;
+ z_order_ = status.get().z_order;
+ visible_ = status.get().visible;
}
-void DisplaySurfaceClient::SetVisible(bool visible) {
- SetAttributes({{DisplaySurfaceAttributeEnum::Visible,
- DisplaySurfaceAttributeValue{visible}}});
+Surface::Surface(const SurfaceAttributes& attributes, int* error)
+ : BASE{pdx::default_transport::ClientChannelFactory::Create(
+ DisplayProtocol::kClientPath),
+ kInfiniteTimeout} {
+ auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
+ if (!status) {
+ ALOGE("Surface::Surface: Failed to create display surface: %s",
+ status.GetErrorMessage().c_str());
+ Close(status.error());
+ if (error)
+ *error = status.error();
+ }
+
+ surface_id_ = status.get().surface_id;
+ z_order_ = status.get().z_order;
+ visible_ = status.get().visible;
}
-void DisplaySurfaceClient::SetZOrder(int z_order) {
- SetAttributes({{DisplaySurfaceAttributeEnum::ZOrder,
- DisplaySurfaceAttributeValue{z_order}}});
+Status<void> Surface::SetVisible(bool visible) {
+ return SetAttributes(
+ {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
}
-void DisplaySurfaceClient::SetExcludeFromBlur(bool exclude_from_blur) {
- SetAttributes({{DisplaySurfaceAttributeEnum::ExcludeFromBlur,
- DisplaySurfaceAttributeValue{exclude_from_blur}}});
+Status<void> Surface::SetZOrder(int z_order) {
+ return SetAttributes(
+ {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
}
-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);
+Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
+ auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
if (!status) {
ALOGE(
- "DisplaySurfaceClient::SetAttributes: Failed to set display surface "
+ "Surface::SetAttributes: Failed to set display surface "
"attributes: %s",
status.GetErrorMessage().c_str());
- return;
+ return status.error_status();
}
// Set the local cached copies of the attributes we care about from the full
@@ -122,159 +85,130 @@
const auto* variant = &attribute.second;
bool invalid_value = false;
switch (key) {
- case DisplaySurfaceAttributeEnum::Visible:
+ case SurfaceAttribute::Visible:
invalid_value =
!IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
break;
- case DisplaySurfaceAttributeEnum::ZOrder:
+ case SurfaceAttribute::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<ProducerQueue> DisplaySurfaceClient::GetProducerQueue() {
- if (producer_queue_ == nullptr) {
- // Create producer queue through DisplayRPC
- auto status = InvokeRemoteMethod<DisplayRPC::CreateBufferQueue>();
- if (!status) {
- ALOGE(
- "DisplaySurfaceClient::GetProducerQueue: failed to create producer "
- "queue: %s",
- status.GetErrorMessage().c_str());
- return nullptr;
- }
-
- producer_queue_ = ProducerQueue::Import(status.take());
- }
- return producer_queue_;
-}
-
-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);
+ "Surface::SetAttributes: Failed to set display surface "
+ "attribute %d because of incompatible type: %d",
+ key, variant->index());
}
}
- return mapped_metadata_buffer_;
+ return {};
}
-LocalChannelHandle DisplaySurfaceClient::CreateVideoMeshSurface() {
- auto status = InvokeRemoteMethod<DisplayRPC::CreateVideoMeshSurface>();
+Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue() {
+ ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
+ auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(0);
if (!status) {
- ALOGE(
- "DisplaySurfaceClient::CreateVideoMeshSurface: Failed to create "
- "video mesh surface: %s",
- status.GetErrorMessage().c_str());
+ ALOGE("Surface::CreateQueue: Failed to create queue: %s",
+ status.GetErrorMessage().c_str());
+ return status.error_status();
}
- return status.take();
+
+ auto producer_queue = ProducerQueue::Import(status.take());
+ if (!producer_queue) {
+ ALOGE("Surface::CreateQueue: Failed to import producer queue!");
+ return ErrorStatus(ENOMEM);
+ }
+
+ return {std::move(producer_queue)};
+}
+
+Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(uint32_t width,
+ uint32_t height,
+ uint32_t format,
+ uint64_t usage,
+ size_t capacity) {
+ ALOGD_IF(TRACE,
+ "Surface::CreateQueue: width=%u height=%u format=%u usage=%" PRIx64
+ " capacity=%zu",
+ width, height, format, usage, capacity);
+ auto status = CreateQueue();
+ if (!status)
+ return status.error_status();
+
+ auto producer_queue = status.take();
+
+ ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
+ for (size_t i = 0; i < capacity; i++) {
+ size_t slot;
+ const size_t kSliceCount = 1;
+ const int ret = producer_queue->AllocateBuffer(width, height, format, usage,
+ kSliceCount, &slot);
+ if (ret < 0) {
+ ALOGE(
+ "Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
+ producer_queue->id(), strerror(-ret));
+ return ErrorStatus(ENOMEM);
+ }
+ ALOGD_IF(
+ TRACE,
+ "Surface::CreateQueue: Allocated buffer at slot=%zu of capacity=%zu",
+ slot, capacity);
+ }
+
+ return {std::move(producer_queue)};
}
DisplayClient::DisplayClient(int* error)
: BASE(pdx::default_transport::ClientChannelFactory::Create(
- DisplayRPC::kClientPath),
+ DisplayProtocol::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;
+Status<Metrics> DisplayClient::GetDisplayMetrics() {
+ return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
}
-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;
+Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
+ const SurfaceAttributes& attributes) {
+ int error;
+ if (auto client = Surface::Create(attributes, &error))
+ return {std::move(client)};
+ else
+ return ErrorStatus(error);
}
-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;
-}
-
-std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface(
- int width, int height, int format, int usage, int flags) {
- return DisplaySurfaceClient::Create(width, height, format, usage, flags);
-}
-
-std::unique_ptr<IonBuffer> DisplayClient::GetNamedBuffer(
+Status<std::unique_ptr<IonBuffer>> DisplayClient::GetNamedBuffer(
const std::string& name) {
- auto status = InvokeRemoteMethod<DisplayRPC::GetNamedBuffer>(name);
+ auto status = InvokeRemoteMethod<DisplayProtocol::GetNamedBuffer>(name);
if (!status) {
ALOGE(
- "DisplayClient::GetNamedBuffer: Failed to get pose buffer. name=%s, "
+ "DisplayClient::GetNamedBuffer: Failed to get named buffer: name=%s; "
"error=%s",
name.c_str(), status.GetErrorMessage().c_str());
- return nullptr;
+ return status.error_status();
}
auto ion_buffer = std::make_unique<IonBuffer>();
- status.take().Import(ion_buffer.get());
- return ion_buffer;
+ auto native_buffer_handle = status.take();
+ const int ret = native_buffer_handle.Import(ion_buffer.get());
+ if (ret < 0) {
+ ALOGE(
+ "DisplayClient::GetNamedBuffer: Failed to import named buffer: "
+ "name=%s; error=%s",
+ name.c_str(), strerror(-ret));
+ return ErrorStatus(-ret);
+ }
+
+ return {std::move(ion_buffer)};
}
-bool DisplayClient::IsVrAppRunning() {
- auto status = InvokeRemoteMethod<DisplayRPC::IsVrAppRunning>();
- if (!status)
- return 0;
- return static_cast<bool>(status.get());
+Status<bool> DisplayClient::IsVrAppRunning() {
+ return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
}
+} // namespace display
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/display_manager_client.cpp b/libs/vr/libdisplay/display_manager_client.cpp
index ca51ab6..82dacf7 100644
--- a/libs/vr/libdisplay/display_manager_client.cpp
+++ b/libs/vr/libdisplay/display_manager_client.cpp
@@ -2,51 +2,77 @@
#include <pdx/default_transport/client_channel_factory.h>
#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/buffer_hub_queue_client.h>
#include <private/dvr/display_protocol.h>
#include <utils/Log.h>
+using android::pdx::ErrorStatus;
using android::pdx::LocalChannelHandle;
using android::pdx::Transaction;
namespace android {
namespace dvr {
+namespace display {
DisplayManagerClient::DisplayManagerClient()
: BASE(pdx::default_transport::ClientChannelFactory::Create(
- DisplayManagerRPC::kClientPath)) {}
+ DisplayManagerProtocol::kClientPath)) {}
DisplayManagerClient::~DisplayManagerClient() {}
-int DisplayManagerClient::GetSurfaceList(
- std::vector<DisplaySurfaceInfo>* surface_list) {
- auto status = InvokeRemoteMethod<DisplayManagerRPC::GetSurfaceList>();
+pdx::Status<std::vector<display::SurfaceState>>
+DisplayManagerClient::GetSurfaceState() {
+ auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceState>();
if (!status) {
ALOGE(
- "DisplayManagerClient::GetSurfaceList: Failed to get surface info: %s",
+ "DisplayManagerClient::GetSurfaceState: Failed to get surface info: %s",
status.GetErrorMessage().c_str());
- return -status.error();
}
- *surface_list = status.take();
- return 0;
+ return status;
}
-std::unique_ptr<IonBuffer> DisplayManagerClient::SetupNamedBuffer(
+pdx::Status<std::unique_ptr<IonBuffer>> DisplayManagerClient::SetupNamedBuffer(
const std::string& name, size_t size, uint64_t usage) {
- auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupNamedBuffer>(
+ auto status = InvokeRemoteMethod<DisplayManagerProtocol::SetupNamedBuffer>(
name, size, usage);
if (!status) {
ALOGE(
- "DisplayManagerClient::SetupNamedBuffer: Failed to create the named "
- "buffer: name=%s, error=%s",
- name.c_str(), status.GetErrorMessage().c_str());
- return {};
+ "DisplayManagerClient::SetupPoseBuffer: Failed to create the named "
+ "buffer %s",
+ status.GetErrorMessage().c_str());
+ return status.error_status();
}
auto ion_buffer = std::make_unique<IonBuffer>();
- status.take().Import(ion_buffer.get());
- return ion_buffer;
+ auto native_buffer_handle = status.take();
+ const int ret = native_buffer_handle.Import(ion_buffer.get());
+ if (ret < 0) {
+ ALOGE(
+ "DisplayClient::GetNamedBuffer: Failed to import named buffer: "
+ "name=%s; error=%s",
+ name.c_str(), strerror(-ret));
+ return ErrorStatus(-ret);
+ }
+
+ return {std::move(ion_buffer)};
}
+pdx::Status<std::unique_ptr<ConsumerQueue>>
+DisplayManagerClient::GetSurfaceQueue(int surface_id, int queue_id) {
+ auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>(
+ surface_id, queue_id);
+ if (!status) {
+ ALOGE(
+ "DisplayManagerClient::GetSurfaceQueue: Failed to get queue for "
+ "surface_id=%d queue_id=%d: %s",
+ surface_id, queue_id, status.GetErrorMessage().c_str());
+ return status.error_status();
+ }
+
+ return {ConsumerQueue::Import(status.take())};
+}
+
+} // namespace display
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/display_protocol.cpp b/libs/vr/libdisplay/display_protocol.cpp
index e96394c..773f9a5 100644
--- a/libs/vr/libdisplay/display_protocol.cpp
+++ b/libs/vr/libdisplay/display_protocol.cpp
@@ -2,11 +2,12 @@
namespace android {
namespace dvr {
+namespace display {
-constexpr char DisplayRPC::kClientPath[];
-constexpr char DisplayManagerRPC::kClientPath[];
-constexpr char DisplayScreenshotRPC::kClientPath[];
-constexpr char DisplayVSyncRPC::kClientPath[];
+constexpr char DisplayProtocol::kClientPath[];
+constexpr char DisplayManagerProtocol::kClientPath[];
+constexpr char VSyncProtocol::kClientPath[];
-} // namespace dvr
-} // namespace android
+} // namespace display
+} // namespace dvr
+} // namespace android
diff --git a/libs/vr/libdisplay/graphics.cpp b/libs/vr/libdisplay/graphics.cpp
index bd3ed7e..f0e37f8 100644
--- a/libs/vr/libdisplay/graphics.cpp
+++ b/libs/vr/libdisplay/graphics.cpp
@@ -13,19 +13,19 @@
#endif
#include <vulkan/vulkan.h>
+#include <dvr/dvr_display_types.h>
#include <pdx/file_handle.h>
#include <private/dvr/clock_ns.h>
#include <private/dvr/debug.h>
-#include <private/dvr/display_types.h>
#include <private/dvr/frame_history.h>
#include <private/dvr/gl_fenced_flush.h>
#include <private/dvr/graphics/vr_gl_extensions.h>
#include <private/dvr/graphics_private.h>
#include <private/dvr/late_latch.h>
#include <private/dvr/native_buffer_queue.h>
+#include <private/dvr/platform_defines.h>
#include <private/dvr/sensor_constants.h>
#include <private/dvr/vsync_client.h>
-#include <private/dvr/platform_defines.h>
#include <android/native_window.h>
@@ -34,21 +34,30 @@
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
#endif
+using android::pdx::ErrorStatus;
using android::pdx::LocalHandle;
using android::pdx::LocalChannelHandle;
+using android::pdx::Status;
-using android::dvr::DisplaySurfaceAttributeEnum;
-using android::dvr::DisplaySurfaceAttributeValue;
+using android::dvr::display::DisplayClient;
+using android::dvr::display::Metrics;
+using android::dvr::display::NativeBufferQueue;
+using android::dvr::display::Surface;
+using android::dvr::display::SurfaceAttribute;
+using android::dvr::display::SurfaceAttributes;
+using android::dvr::display::SurfaceAttributeValue;
+using android::dvr::VSyncClient;
namespace {
// TODO(urbanus): revisit once we have per-platform usage config in place.
-constexpr int kDefaultDisplaySurfaceUsage =
- GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE |
- GRALLOC_USAGE_QCOM_FRAMEBUFFER_COMPRESSION;
-constexpr int kDefaultDisplaySurfaceFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+constexpr uint64_t kDefaultDisplaySurfaceUsage =
+ GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET |
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_1 | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET |
+ GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
+constexpr uint32_t kDefaultDisplaySurfaceFormat = HAL_PIXEL_FORMAT_RGBA_8888;
// TODO(alexst): revisit this count when HW encode is available for casting.
-constexpr int kDefaultBufferCount = 4;
+constexpr size_t kDefaultBufferCount = 4;
// Use with dvrBeginRenderFrame to disable EDS for the current frame.
constexpr float32x4_t DVR_POSE_NO_EDS = {10.0f, 0.0f, 0.0f, 0.0f};
@@ -278,51 +287,119 @@
return 0;
}
-} // anonymous namespace
+// Utility structure to hold info related to creating a surface.
+struct SurfaceResult {
+ std::shared_ptr<Surface> surface;
+ Metrics metrics;
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+ uint64_t usage;
+ size_t capacity;
+ int geometry;
+ bool direct_surface;
+};
-// TODO(hendrikw): When we remove the calls to this in native_window.cpp, move
-// this back into the anonymous namespace
-std::shared_ptr<android::dvr::DisplaySurfaceClient> CreateDisplaySurfaceClient(
- struct DvrSurfaceParameter* parameters,
- /*out*/ android::dvr::SystemDisplayMetrics* metrics) {
- auto client = android::dvr::DisplayClient::Create();
- if (!client) {
- ALOGE("Failed to create display client!");
- return nullptr;
+Status<std::tuple<std::shared_ptr<android::dvr::ProducerQueue>,
+ std::shared_ptr<android::dvr::BufferProducer>,
+ volatile DisplaySurfaceMetadata*>>
+CreateMetadataBuffer(const std::shared_ptr<Surface>& surface,
+ bool direct_surface) {
+ std::shared_ptr<android::dvr::ProducerQueue> queue;
+ std::shared_ptr<android::dvr::BufferProducer> buffer;
+
+ if (!direct_surface) {
+ auto queue_status = surface->CreateQueue(
+ sizeof(DisplaySurfaceMetadata), 1, HAL_PIXEL_FORMAT_BLOB,
+ GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET |
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN |
+ GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER,
+ 1);
+ if (!queue_status) {
+ ALOGE("CreateMetadataBuffer: Failed to create queue: %s",
+ queue_status.GetErrorMessage().c_str());
+ return queue_status.error_status();
+ }
+
+ queue = queue_status.take();
+ LocalHandle fence;
+ size_t slot;
+ auto buffer_status = queue->Dequeue(-1, &slot, &fence);
+ if (!buffer_status) {
+ ALOGE("CreateMetadataBuffer: Failed to dequeue buffer: %s",
+ buffer_status.GetErrorMessage().c_str());
+ return buffer_status.error_status();
+ }
+ buffer = buffer_status.take();
+ } else {
+ buffer = android::dvr::BufferProducer::CreateUncachedBlob(
+ sizeof(DisplaySurfaceMetadata));
+ if (!buffer) {
+ ALOGE("CreateMetadataBuffer: Failed to create stand-in buffer!");
+ return ErrorStatus(ENOMEM);
+ }
}
- const int ret = client->GetDisplayMetrics(metrics);
+ void* address = nullptr;
+ int ret =
+ buffer->GetBlobReadWritePointer(sizeof(DisplaySurfaceMetadata), &address);
+
if (ret < 0) {
- ALOGE("Failed to get display metrics: %s", strerror(-ret));
- return nullptr;
+ ALOGE("CreateMetadataBuffer: Failed to map buffer: %s", strerror(-ret));
+ return ErrorStatus(-ret);
+ }
+
+ // Post the buffer so that the compositor can retrieve it from the consumer
+ // queue.
+ ret = buffer->Post<void>(LocalHandle{});
+ if (ret < 0) {
+ ALOGE("CreateMetadataBuffer: Failed to post buffer: %s", strerror(-ret));
+ return ErrorStatus(-ret);
+ }
+
+ ALOGD_IF(TRACE, "CreateMetadataBuffer: queue_id=%d buffer_id=%d address=%p",
+ queue ? queue->id() : -1, buffer->id(), address);
+ return {{std::move(queue), std::move(buffer),
+ static_cast<DisplaySurfaceMetadata*>(address)}};
+}
+
+} // anonymous namespace
+
+Status<SurfaceResult> CreateSurface(struct DvrSurfaceParameter* parameters) {
+ int error;
+ auto client = DisplayClient::Create(&error);
+ if (!client) {
+ ALOGE("CreateApplicationSurface: Failed to create display client!");
+ return ErrorStatus(error);
+ }
+
+ auto metrics_status = client->GetDisplayMetrics();
+ if (!metrics_status) {
+ ALOGE("CreateApplicationSurface: Failed to get display metrics: %s",
+ metrics_status.GetErrorMessage().c_str());
+ return metrics_status.error_status();
}
// Parameters that may be modified by the parameters array. Some of these are
// here for future expansion.
- int request_width = -1;
- int request_height = -1;
- int request_flags = 0;
+
+ uint32_t request_width = metrics_status.get().display_width;
+ uint32_t request_height = metrics_status.get().display_width;
+ uint32_t request_format = kDefaultDisplaySurfaceFormat;
+ uint64_t request_usage = kDefaultDisplaySurfaceUsage;
+ size_t request_capacity = kDefaultBufferCount;
+ int request_geometry = DVR_SURFACE_GEOMETRY_SINGLE;
bool disable_distortion = false;
bool disable_stabilization = false;
bool disable_cac = false;
- bool request_visible = true;
+ bool request_visible = false;
bool vertical_flip = false;
+ bool direct_surface = false;
int request_z_order = 0;
- bool request_exclude_from_blur = false;
- bool request_blur_behind = true;
- int request_format = kDefaultDisplaySurfaceFormat;
- int request_usage = kDefaultDisplaySurfaceUsage;
- int geometry_type = DVR_SURFACE_GEOMETRY_SINGLE;
// Handle parameter inputs.
for (auto p = parameters; p && p->key != DVR_SURFACE_PARAMETER_NONE; ++p) {
switch (p->key) {
- case DVR_SURFACE_PARAMETER_WIDTH_IN:
- request_width = p->value;
- break;
- case DVR_SURFACE_PARAMETER_HEIGHT_IN:
- request_height = p->value;
- break;
case DVR_SURFACE_PARAMETER_DISABLE_DISTORTION_IN:
disable_distortion = !!p->value;
break;
@@ -338,20 +415,23 @@
case DVR_SURFACE_PARAMETER_Z_ORDER_IN:
request_z_order = p->value;
break;
- case DVR_SURFACE_PARAMETER_EXCLUDE_FROM_BLUR_IN:
- request_exclude_from_blur = !!p->value;
- break;
- case DVR_SURFACE_PARAMETER_BLUR_BEHIND_IN:
- request_blur_behind = !!p->value;
- break;
case DVR_SURFACE_PARAMETER_VERTICAL_FLIP_IN:
vertical_flip = !!p->value;
break;
- case DVR_SURFACE_PARAMETER_GEOMETRY_IN:
- geometry_type = p->value;
+ case DVR_SURFACE_PARAMETER_DIRECT_IN:
+ direct_surface = !!p->value;
+ break;
+ case DVR_SURFACE_PARAMETER_WIDTH_IN:
+ request_width = p->value;
+ break;
+ case DVR_SURFACE_PARAMETER_HEIGHT_IN:
+ request_height = p->value;
break;
case DVR_SURFACE_PARAMETER_FORMAT_IN:
- request_format = DvrToHalSurfaceFormat(p->value);
+ request_format = p->value;
+ break;
+ case DVR_SURFACE_PARAMETER_GEOMETRY_IN:
+ request_geometry = p->value;
break;
case DVR_SURFACE_PARAMETER_ENABLE_LATE_LATCH_IN:
case DVR_SURFACE_PARAMETER_CREATE_GL_CONTEXT_IN:
@@ -375,113 +455,90 @@
case DVR_SURFACE_PARAMETER_VK_SWAPCHAIN_IMAGE_FORMAT_OUT:
break;
default:
- ALOGE("Invalid display surface parameter: key=%d value=%" PRId64,
- p->key, p->value);
- return nullptr;
+ ALOGE(
+ "CreateSurface: Invalid display surface parameter: key=%d "
+ "value=%" PRId64,
+ p->key, p->value);
+ return ErrorStatus(EINVAL);
}
}
- request_flags |= disable_distortion
- ? DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION
- : 0;
- request_flags |=
- disable_stabilization ? DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_EDS : 0;
- request_flags |=
- disable_cac ? DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_CAC : 0;
- request_flags |= vertical_flip ? DVR_DISPLAY_SURFACE_FLAGS_VERTICAL_FLIP : 0;
- request_flags |= (geometry_type == DVR_SURFACE_GEOMETRY_SEPARATE_2)
- ? DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2
- : 0;
+ // TODO(eieio): Setup a "surface flags" attribute based on the surface
+ // parameters gathered above.
+ SurfaceAttributes surface_attributes;
- if (request_width == -1) {
- request_width = disable_distortion ? metrics->display_native_width
- : metrics->distorted_width;
- if (!disable_distortion &&
- geometry_type == DVR_SURFACE_GEOMETRY_SEPARATE_2) {
- // The metrics always return the single wide buffer resolution.
- // When split between eyes, we need to halve the width of the surface.
- request_width /= 2;
- }
- }
- if (request_height == -1) {
- request_height = disable_distortion ? metrics->display_native_height
- : metrics->distorted_height;
+ surface_attributes[SurfaceAttribute::Direct] = direct_surface;
+ surface_attributes[SurfaceAttribute::Visible] = request_visible;
+ surface_attributes[SurfaceAttribute::ZOrder] = request_z_order;
+
+ auto surface_status = Surface::CreateSurface(surface_attributes);
+ if (!surface_status) {
+ ALOGE("CreateSurface: Failed to create surface: %s",
+ surface_status.GetErrorMessage().c_str());
+ return surface_status.error_status();
}
- std::shared_ptr<android::dvr::DisplaySurfaceClient> surface =
- client->CreateDisplaySurface(request_width, request_height,
- request_format, request_usage,
- request_flags);
- surface->SetAttributes(
- {{DisplaySurfaceAttributeEnum::Visible,
- DisplaySurfaceAttributeValue{request_visible}},
- {DisplaySurfaceAttributeEnum::ZOrder,
- DisplaySurfaceAttributeValue{request_z_order}},
- {DisplaySurfaceAttributeEnum::ExcludeFromBlur,
- DisplaySurfaceAttributeValue{request_exclude_from_blur}},
- {DisplaySurfaceAttributeEnum::BlurBehind,
- DisplaySurfaceAttributeValue{request_blur_behind}}});
+ return {{surface_status.take(), metrics_status.get(), request_width,
+ request_height, request_format, request_usage, request_capacity,
+ request_geometry, direct_surface}};
+}
+
+// TODO(hendrikw): When we remove the calls to this in native_window.cpp, move
+// this back into the anonymous namespace
+Status<SurfaceResult> CreateApplicationSurface(
+ struct DvrSurfaceParameter* parameters) {
+ auto surface_status = CreateSurface(parameters);
+ if (!surface_status)
+ return surface_status;
// Handle parameter output requests down here so we can return surface info.
for (auto p = parameters; p && p->key != DVR_SURFACE_PARAMETER_NONE; ++p) {
switch (p->key) {
case DVR_SURFACE_PARAMETER_DISPLAY_WIDTH_OUT:
- *static_cast<int32_t*>(p->value_out) = metrics->display_native_width;
+ *static_cast<int32_t*>(p->value_out) =
+ surface_status.get().metrics.display_width;
break;
case DVR_SURFACE_PARAMETER_DISPLAY_HEIGHT_OUT:
- *static_cast<int32_t*>(p->value_out) = metrics->display_native_height;
- break;
- case DVR_SURFACE_PARAMETER_SURFACE_WIDTH_OUT:
- *static_cast<int32_t*>(p->value_out) = surface->width();
- break;
- case DVR_SURFACE_PARAMETER_SURFACE_HEIGHT_OUT:
- *static_cast<int32_t*>(p->value_out) = surface->height();
- break;
- case DVR_SURFACE_PARAMETER_INTER_LENS_METERS_OUT:
- *static_cast<float*>(p->value_out) = metrics->inter_lens_distance_m;
- break;
- case DVR_SURFACE_PARAMETER_LEFT_FOV_LRBT_OUT:
- for (int i = 0; i < 4; ++i) {
- float* float_values_out = static_cast<float*>(p->value_out);
- float_values_out[i] = metrics->left_fov_lrbt[i];
- }
- break;
- case DVR_SURFACE_PARAMETER_RIGHT_FOV_LRBT_OUT:
- for (int i = 0; i < 4; ++i) {
- float* float_values_out = static_cast<float*>(p->value_out);
- float_values_out[i] = metrics->right_fov_lrbt[i];
- }
+ *static_cast<int32_t*>(p->value_out) =
+ surface_status.get().metrics.display_height;
break;
case DVR_SURFACE_PARAMETER_VSYNC_PERIOD_OUT:
- *static_cast<uint64_t*>(p->value_out) = metrics->vsync_period_ns;
+ *static_cast<uint64_t*>(p->value_out) =
+ surface_status.get().metrics.vsync_period_ns;
break;
+ case DVR_SURFACE_PARAMETER_SURFACE_WIDTH_OUT:
+ *static_cast<uint32_t*>(p->value_out) = surface_status.get().width;
+ break;
+ case DVR_SURFACE_PARAMETER_SURFACE_HEIGHT_OUT:
+ *static_cast<uint32_t*>(p->value_out) = surface_status.get().height;
+ break;
+
default:
break;
}
}
- return surface;
+ return surface_status;
}
-extern "C" int dvrGetNativeDisplayDimensions(int* native_width,
- int* native_height) {
+extern "C" int dvrGetNativeDisplayDimensions(int* display_width,
+ int* display_height) {
int error = 0;
- auto client = android::dvr::DisplayClient::Create(&error);
+ auto client = DisplayClient::Create(&error);
if (!client) {
- ALOGE("Failed to create display client!");
- return error;
+ ALOGE("dvrGetNativeDisplayDimensions: Failed to create display client!");
+ return -error;
}
- android::dvr::SystemDisplayMetrics metrics;
- const int ret = client->GetDisplayMetrics(&metrics);
-
- if (ret != 0) {
- ALOGE("Failed to get display metrics!");
- return ret;
+ auto metrics_status = client->GetDisplayMetrics();
+ if (!metrics_status) {
+ ALOGE("dvrGetNativeDisplayDimensions: Failed to get display metrics: %s",
+ metrics_status.GetErrorMessage().c_str());
+ return -metrics_status.error();
}
- *native_width = static_cast<int>(metrics.display_native_width);
- *native_height = static_cast<int>(metrics.display_native_height);
+ *display_width = static_cast<int>(metrics_status.get().display_width);
+ *display_height = static_cast<int>(metrics_status.get().display_height);
return 0;
}
@@ -523,9 +580,12 @@
} vk;
// Display surface, metrics, and buffer management members.
- std::shared_ptr<android::dvr::DisplaySurfaceClient> display_surface;
- android::dvr::SystemDisplayMetrics display_metrics;
- std::unique_ptr<android::dvr::NativeBufferQueue> buffer_queue;
+ std::shared_ptr<Surface> display_surface;
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+ Metrics display_metrics;
+ std::unique_ptr<NativeBufferQueue> buffer_queue;
android::dvr::NativeBufferProducer* current_buffer;
bool buffer_already_posted;
@@ -535,8 +595,13 @@
android::dvr::FrameHistory frame_history;
+ // Metadata queue and buffer.
+ // TODO(eieio): Remove the queue once one-off buffers are supported as a
+ // surface primitive element.
+ std::shared_ptr<android::dvr::ProducerQueue> metadata_queue;
+ std::shared_ptr<android::dvr::BufferProducer> metadata_buffer;
// Mapped surface metadata (ie: for pose delivery with presented frames).
- volatile android::dvr::DisplaySurfaceMetadata* surface_metadata;
+ volatile DisplaySurfaceMetadata* surface_metadata;
// LateLatch support.
std::unique_ptr<android::dvr::LateLatch> late_latch;
@@ -611,7 +676,7 @@
int dvrGraphicsContextCreate(struct DvrSurfaceParameter* parameters,
DvrGraphicsContext** return_graphics_context) {
- std::unique_ptr<DvrGraphicsContext> context(new DvrGraphicsContext);
+ auto context = std::make_unique<DvrGraphicsContext>();
// See whether we're using GL or Vulkan
for (auto p = parameters; p && p->key != DVR_SURFACE_PARAMETER_NONE; ++p) {
@@ -676,46 +741,66 @@
return -EINVAL;
}
- context->display_surface =
- CreateDisplaySurfaceClient(parameters, &context->display_metrics);
- if (!context->display_surface) {
- ALOGE("Error: failed to create display surface client");
- return -ECOMM;
+ auto surface_status = CreateApplicationSurface(parameters);
+ if (!surface_status) {
+ ALOGE("dvrGraphicsContextCreate: Failed to create surface: %s",
+ surface_status.GetErrorMessage().c_str());
+ return -surface_status.error();
}
- context->buffer_queue.reset(new android::dvr::NativeBufferQueue(
- context->gl.egl_display, context->display_surface, kDefaultBufferCount));
+ auto surface_result = surface_status.take();
+
+ context->display_surface = surface_result.surface;
+ context->display_metrics = surface_result.metrics;
+ context->width = surface_result.width;
+ context->height = surface_result.height;
+ context->format = surface_result.format;
+
+ // Create an empty queue. NativeBufferQueue allocates the buffers for this
+ // queue.
+ auto queue_status = context->display_surface->CreateQueue();
+ if (!queue_status) {
+ ALOGE("dvrGraphicsContextCreate: Failed to create queue: %s",
+ queue_status.GetErrorMessage().c_str());
+ return -queue_status.error();
+ }
+
+ context->buffer_queue.reset(new NativeBufferQueue(
+ context->gl.egl_display, queue_status.take(), surface_result.width,
+ surface_result.height, surface_result.format, surface_result.usage,
+ surface_result.capacity));
+
+ // Create the metadata buffer.
+ auto metadata_status = CreateMetadataBuffer(context->display_surface,
+ surface_result.direct_surface);
+ if (!metadata_status) {
+ ALOGE("dvrGraphicsContextCreate: Failed to create metadata buffer: %s",
+ metadata_status.GetErrorMessage().c_str());
+ return -metadata_status.error();
+ }
+ std::tie(context->metadata_queue, context->metadata_buffer,
+ context->surface_metadata) = metadata_status.take();
// The way the call sequence works we need 1 more than the buffer queue
// capacity to store data for all pending frames
- context->frame_history.Reset(context->buffer_queue->GetQueueCapacity() + 1);
+ context->frame_history.Reset(context->buffer_queue->capacity() + 1);
- context->vsync_client = android::dvr::VSyncClient::Create();
+ context->vsync_client = VSyncClient::Create();
if (!context->vsync_client) {
- ALOGE("Error: failed to create vsync client");
+ ALOGE("dvrGraphicsContextCreate: failed to create vsync client");
return -ECOMM;
}
context->timerfd.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
if (!context->timerfd) {
- ALOGE("Error: timerfd_create failed because: %s", strerror(errno));
+ ALOGE("dvrGraphicsContextCreate: timerfd_create failed because: %s",
+ strerror(errno));
return -EPERM;
}
- context->surface_metadata = context->display_surface->GetMetadataBufferPtr();
- if (!context->surface_metadata) {
- ALOGE("Error: surface metadata allocation failed");
- return -ENOMEM;
- }
-
- ALOGI("buffer: %d x %d\n", context->display_surface->width(),
- context->display_surface->height());
-
if (context->graphics_api == DVR_GRAPHICS_API_GLES) {
- context->gl.texture_count = (context->display_surface->flags() &
- DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2)
- ? 2
- : 1;
+ context->gl.texture_count =
+ (surface_result.geometry == DVR_SURFACE_GEOMETRY_SEPARATE_2) ? 2 : 1;
// Create the GL textures.
glGenTextures(context->gl.texture_count, context->gl.texture_id);
@@ -756,14 +841,9 @@
// Initialize late latch.
if (is_late_latch) {
- LocalHandle fd;
- int ret = context->display_surface->GetMetadataBufferFd(&fd);
- if (ret == 0) {
- context->late_latch.reset(
- new android::dvr::LateLatch(true, std::move(fd)));
- } else {
- ALOGE("Error: failed to get surface metadata buffer fd for late latch");
- }
+ LocalHandle fd = context->metadata_buffer->GetBlobFd();
+ context->late_latch.reset(
+ new android::dvr::LateLatch(true, std::move(fd)));
}
} else if (context->graphics_api == DVR_GRAPHICS_API_VULKAN) {
VkResult result = VK_SUCCESS;
@@ -963,7 +1043,7 @@
std::lock_guard<std::mutex> autolock(self->lock_);
if (!self->current_buffer) {
- self->current_buffer = self->buffer_queue.get()->Dequeue();
+ self->current_buffer = self->buffer_queue->Dequeue();
}
ATRACE_ASYNC_BEGIN("BufferDraw", self->current_buffer->buffer()->id());
*fence_fd = self->current_buffer->ClaimReleaseFence().Release();
@@ -1030,7 +1110,7 @@
}
}
if (do_enqueue) {
- self->buffer_queue.get()->Enqueue(native_buffer);
+ self->buffer_queue->Enqueue(native_buffer);
}
if (fence_fd >= 0)
close(fence_fd);
@@ -1048,13 +1128,13 @@
switch (what) {
case NATIVE_WINDOW_WIDTH:
- *value = self->display_surface->width();
+ *value = self->width;
return android::NO_ERROR;
case NATIVE_WINDOW_HEIGHT:
- *value = self->display_surface->height();
+ *value = self->height;
return android::NO_ERROR;
case NATIVE_WINDOW_FORMAT:
- *value = self->display_surface->format();
+ *value = self->format;
return android::NO_ERROR;
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
*value = 1;
@@ -1066,10 +1146,10 @@
*value = 1;
return android::NO_ERROR;
case NATIVE_WINDOW_DEFAULT_WIDTH:
- *value = self->display_surface->width();
+ *value = self->width;
return android::NO_ERROR;
case NATIVE_WINDOW_DEFAULT_HEIGHT:
- *value = self->display_surface->height();
+ *value = self->height;
return android::NO_ERROR;
case NATIVE_WINDOW_TRANSFORM_HINT:
*value = 0;
@@ -1196,8 +1276,7 @@
// we don't touch it here.
float32x4_t is_late_latch = DVR_POSE_LATE_LATCH;
if (render_pose_orientation[0] != is_late_latch[0]) {
- volatile android::dvr::DisplaySurfaceMetadata* data =
- graphics_context->surface_metadata;
+ volatile DisplaySurfaceMetadata* data = graphics_context->surface_metadata;
uint32_t buffer_index =
graphics_context->current_buffer->surface_buffer_index();
ALOGE_IF(TRACE, "write pose index %d %f %f", buffer_index,
@@ -1244,6 +1323,7 @@
CHECK_GL();
return 0;
}
+
int dvrBeginRenderFrameEdsVk(DvrGraphicsContext* graphics_context,
float32x4_t render_pose_orientation,
float32x4_t render_pose_translation,
@@ -1421,7 +1501,7 @@
auto buffer = graphics_context->current_buffer->buffer().get();
ATRACE_ASYNC_BEGIN("BufferPost", buffer->id());
- int result = buffer->Post<uint64_t>(LocalHandle(), 0);
+ int result = buffer->Post<void>(LocalHandle());
if (result < 0)
ALOGE("Buffer post failed: %d (%s)", result, strerror(-result));
}
@@ -1452,7 +1532,7 @@
ATRACE_ASYNC_END("BufferDraw", buffer->id());
if (!graphics_context->buffer_already_posted) {
ATRACE_ASYNC_BEGIN("BufferPost", buffer->id());
- int result = buffer->Post<uint64_t>(fence_fd, 0);
+ int result = buffer->Post<void>(fence_fd);
if (result < 0)
ALOGE("Buffer post failed: %d (%s)", result, strerror(-result));
}
@@ -1515,7 +1595,7 @@
extern "C" int dvrGraphicsSurfaceGetVisible(
DvrGraphicsContext* graphics_context) {
- return graphics_context->display_surface->visible() ? 1 : 0;
+ return !!graphics_context->display_surface->visible();
}
extern "C" void dvrGraphicsSurfaceSetZOrder(
@@ -1527,4 +1607,3 @@
DvrGraphicsContext* graphics_context) {
return graphics_context->display_surface->z_order();
}
-
diff --git a/libs/vr/libdisplay/include/dvr/dvr_display_types.h b/libs/vr/libdisplay/include/dvr/dvr_display_types.h
new file mode 100644
index 0000000..25364d8
--- /dev/null
+++ b/libs/vr/libdisplay/include/dvr/dvr_display_types.h
@@ -0,0 +1,65 @@
+#ifndef ANDROID_DVR_DISPLAY_TYPES_H_
+#define ANDROID_DVR_DISPLAY_TYPES_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+// Define types used in pose buffer fields. These types have atomicity
+// guarantees that are useful in lock-free shared memory ring buffers.
+#ifdef __ARM_NEON
+#include <arm_neon.h>
+#else
+#ifndef __FLOAT32X4T_86
+#define __FLOAT32X4T_86
+typedef float float32x4_t __attribute__((__vector_size__(16)));
+typedef struct float32x4x4_t { float32x4_t val[4]; };
+#endif
+#endif
+
+// VrFlinger display manager surface state snapshots per surface flags
+// indicating what changed since the last snapshot.
+enum {
+ // No changes.
+ DVR_SURFACE_UPDATE_FLAGS_NONE = 0,
+ // This surface is new.
+ DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE = (1 << 0),
+ // Buffer queues added/removed.
+ DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED = (1 << 1),
+ // Visibility/z-order changed.
+ DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED = (1 << 2),
+ // Generic attributes changed.
+ DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED = (1 << 3),
+};
+
+// Surface attribute keys. VrFlinger defines keys in the negative integer space.
+// The compositor is free to use keys in the positive integer space for
+// implementation-defined purposes.
+enum {
+ // DIRECT: bool
+ // Determines whether a direct surface is created (compositor output) or an
+ // application surface. Defaults to false (application surface). May only be
+ // set to true by a process with either UID=root or UID validated with
+ // IsTrustedUid() (VrCore).
+ DVR_SURFACE_ATTRIBUTE_DIRECT = -3,
+ // Z_ORDER: int32_t
+ // Interpreted by VrFlinger only on direct surfaces to order the corresponding
+ // hardware layers. More positive values render on top of more negative
+ // values.
+ DVR_SURFACE_ATTRIBUTE_Z_ORDER = -2,
+ // VISIBLE: bool
+ // Interpreted by VrFlinger only on direct surfaces to determine whether a
+ // surface is assigned to a hardware layer or ignored.
+ DVR_SURFACE_ATTRIBUTE_VISIBLE = -1,
+ // INVALID
+ // Invalid key. No attributes should have this key.
+ DVR_SURFACE_ATTRIBUTE_INVALID = 0,
+ // FIRST_USER_KEY
+ // VrFlinger ingores any keys with this value or greater, passing them to the
+ // compositor through surface state query results.
+ DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY = 1,
+};
+
+__END_DECLS
+
+#endif // ANDROID_DVR_DISPLAY_TYPES_H_
diff --git a/libs/vr/libdisplay/include/dvr/graphics.h b/libs/vr/libdisplay/include/dvr/graphics.h
index ac8b27f..c83a698 100644
--- a/libs/vr/libdisplay/include/dvr/graphics.h
+++ b/libs/vr/libdisplay/include/dvr/graphics.h
@@ -9,7 +9,7 @@
#else
#ifndef __FLOAT32X4T_86
#define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__ ((__vector_size__ (16)));
+typedef float float32x4_t __attribute__((__vector_size__(16)));
typedef struct float32x4x4_t { float32x4_t val[4]; };
#endif
#endif
@@ -112,6 +112,10 @@
// VK_SWAPCHAIN_IMAGE_FORMAT: In Vulkan mode, the VkFormat of the swapchain
// images will be returned here.
DVR_SURFACE_PARAMETER_VK_SWAPCHAIN_IMAGE_FORMAT_OUT,
+ // DIRECT: Whether the surface goes directly to the display or to the
+ // compositor. Default is 0 (compositor). Only processes with either uid=root
+ // (test tools) or uid validated by IsTrustedUid() may set this to 1.
+ DVR_SURFACE_PARAMETER_DIRECT_IN,
};
enum {
@@ -439,8 +443,7 @@
// Present a VideoMeshSurface with the current video mesh transfromation matrix.
void dvrGraphicsVideoMeshSurfacePresent(DvrGraphicsContext* graphics_context,
DvrVideoMeshSurface* surface,
- const int eye,
- const float* transform);
+ const int eye, const float* transform);
__END_DECLS
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
index cec62af..668532d 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_client.h
@@ -10,108 +10,69 @@
namespace android {
namespace dvr {
+namespace display {
-struct LateLatchOutput;
-
-// Abstract base class for all surface types maintained in DVR's display
-// service.
-// TODO(jwcai) Explain more, surface is a channel...
-class SurfaceClient : public pdx::Client {
+class Surface : public pdx::ClientBase<Surface> {
public:
- using LocalChannelHandle = pdx::LocalChannelHandle;
- SurfaceType type() const { return type_; }
+ // Utility named constructor. This can be removed once ClientBase::Create is
+ // refactored to return Status<T> types.
+ static pdx::Status<std::unique_ptr<Surface>> CreateSurface(
+ const SurfaceAttributes& attributes) {
+ int error;
+ pdx::Status<std::unique_ptr<Surface>> status;
+ if (auto surface = Create(attributes, &error))
+ status.SetValue(std::move(surface));
+ else
+ status.SetError(error);
+ return status;
+ }
- // Get the shared memory metadata buffer fd for this display surface. If it is
- // not yet allocated, this will allocate it.
- int GetMetadataBufferFd(pdx::LocalHandle* out_fd);
-
- // Allocate the single metadata buffer for providing metadata associated with
- // posted buffers for this surface. This can be used to provide rendered poses
- // for EDS, for example. The buffer format is defined by the struct
- // DisplaySurfaceMetadata.
- // The first call to this method will allocate the buffer in via IPC to the
- // display surface.
- std::shared_ptr<BufferProducer> GetMetadataBuffer();
-
- protected:
- SurfaceClient(LocalChannelHandle channel_handle, SurfaceType type);
- SurfaceClient(const std::string& endpoint_path, SurfaceType type);
-
- private:
- SurfaceType type_;
- std::shared_ptr<BufferProducer> metadata_buffer_;
-};
-
-// DisplaySurfaceClient represents the client interface to a displayd display
-// surface.
-class DisplaySurfaceClient
- : public pdx::ClientBase<DisplaySurfaceClient, SurfaceClient> {
- public:
- using LocalHandle = pdx::LocalHandle;
-
- int width() const { return width_; }
- int height() const { return height_; }
- int format() const { return format_; }
- int usage() const { return usage_; }
- int flags() const { return flags_; }
+ int surface_id() const { return surface_id_; }
int z_order() const { return z_order_; }
bool visible() const { return visible_; }
- void SetVisible(bool visible);
- void SetZOrder(int z_order);
- void SetExcludeFromBlur(bool exclude_from_blur);
- void SetBlurBehind(bool blur_behind);
- void SetAttributes(const DisplaySurfaceAttributes& attributes);
+ pdx::Status<void> SetVisible(bool visible);
+ pdx::Status<void> SetZOrder(int z_order);
+ pdx::Status<void> SetAttributes(const SurfaceAttributes& attributes);
- // Get the producer end of the buffer queue that transports graphics buffer
- // from the application side to the compositor side.
- std::shared_ptr<ProducerQueue> GetProducerQueue();
+ // Creates an empty queue.
+ pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue();
- // Get the shared memory metadata buffer for this display surface. If it is
- // not yet allocated, this will allocate it.
- volatile DisplaySurfaceMetadata* GetMetadataBufferPtr();
-
- // Create a VideoMeshSurface that is attached to the display sruface.
- LocalChannelHandle CreateVideoMeshSurface();
+ // Creates a queue and populates it with |capacity| buffers of the specified
+ // parameters.
+ pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue(uint32_t width,
+ uint32_t height,
+ uint32_t format,
+ uint64_t usage,
+ size_t capacity);
private:
friend BASE;
- DisplaySurfaceClient(int width, int height, int format, int usage, int flags);
+ int surface_id_ = -1;
+ int z_order_ = 0;
+ bool visible_ = false;
- int width_;
- int height_;
- int format_;
- int usage_;
- int flags_;
- int z_order_;
- bool visible_;
- bool exclude_from_blur_;
- bool blur_behind_;
- DisplaySurfaceMetadata* mapped_metadata_buffer_;
+ // TODO(eieio,avakulenko): Remove error param once pdx::ClientBase::Create()
+ // returns Status<T>.
+ explicit Surface(const SurfaceAttributes& attributes, int* error = nullptr);
+ explicit Surface(pdx::LocalChannelHandle channel_handle,
+ int* error = nullptr);
- // TODO(jwcai) Add support for multiple queues.
- std::shared_ptr<ProducerQueue> producer_queue_;
-
- DisplaySurfaceClient(const DisplaySurfaceClient&) = delete;
- void operator=(const DisplaySurfaceClient&) = delete;
+ Surface(const Surface&) = delete;
+ void operator=(const Surface&) = delete;
};
class DisplayClient : public pdx::ClientBase<DisplayClient> {
public:
- int GetDisplayMetrics(SystemDisplayMetrics* metrics);
- pdx::Status<void> SetViewerParams(const ViewerParams& viewer_params);
-
- // Pull the latest eds pose data from the display service renderer
- int GetLastFrameEdsTransform(LateLatchOutput* ll_out);
-
- std::unique_ptr<DisplaySurfaceClient> CreateDisplaySurface(
- int width, int height, int format, int usage, int flags);
-
- std::unique_ptr<IonBuffer> GetNamedBuffer(const std::string& name);
+ pdx::Status<Metrics> GetDisplayMetrics();
+ pdx::Status<std::unique_ptr<IonBuffer>> GetNamedBuffer(
+ const std::string& name);
+ pdx::Status<std::unique_ptr<Surface>> CreateSurface(
+ const SurfaceAttributes& attributes);
// Temporary query for current VR status. Will be removed later.
- bool IsVrAppRunning();
+ pdx::Status<bool> IsVrAppRunning();
private:
friend BASE;
@@ -122,6 +83,7 @@
void operator=(const DisplayClient&) = delete;
};
+} // namespace display
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
index fb2abeb..fea8415 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
@@ -1,28 +1,39 @@
#ifndef ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_
#define ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_
+#include <string>
#include <vector>
#include <pdx/client.h>
+#include <pdx/status.h>
#include <private/dvr/display_protocol.h>
namespace android {
namespace dvr {
-class BufferProducer;
+class IonBuffer;
+class ConsumerQueue;
+
+namespace display {
class DisplayManagerClient : public pdx::ClientBase<DisplayManagerClient> {
public:
~DisplayManagerClient() override;
- int GetSurfaceList(std::vector<DisplaySurfaceInfo>* surface_list);
-
- std::unique_ptr<IonBuffer> SetupNamedBuffer(const std::string& name,
- size_t size,
- uint64_t usage);
+ pdx::Status<std::vector<SurfaceState>> GetSurfaceState();
+ pdx::Status<std::unique_ptr<IonBuffer>> SetupNamedBuffer(
+ const std::string& name, size_t size, uint64_t usage);
+ pdx::Status<std::unique_ptr<ConsumerQueue>> GetSurfaceQueue(int surface_id,
+ int queue_id);
using Client::event_fd;
- using Client::GetChannel;
+
+ pdx::Status<int> GetEventMask(int events) {
+ if (auto* client_channel = GetChannel())
+ return client_channel->GetEventMask(events);
+ else
+ return pdx::ErrorStatus(EINVAL);
+ }
private:
friend BASE;
@@ -33,6 +44,7 @@
void operator=(const DisplayManagerClient&) = delete;
};
+} // namespace display
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/include/private/dvr/display_protocol.h b/libs/vr/libdisplay/include/private/dvr/display_protocol.h
index d0b57e4..f34d61f 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_protocol.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_protocol.h
@@ -6,257 +6,225 @@
#include <array>
#include <map>
+#include <dvr/dvr_display_types.h>
+
#include <pdx/rpc/remote_method.h>
#include <pdx/rpc/serializable.h>
#include <pdx/rpc/variant.h>
#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/display_types.h>
+
+// RPC protocol definitions for DVR display services (VrFlinger).
namespace android {
namespace dvr {
+namespace display {
-struct SystemDisplayMetrics {
- uint32_t display_native_width;
- uint32_t display_native_height;
+// Native display metrics.
+struct Metrics {
+ // Basic display properties.
+ uint32_t display_width;
+ uint32_t display_height;
uint32_t display_x_dpi;
uint32_t display_y_dpi;
+ uint32_t vsync_period_ns;
+
+ // HMD metrics.
+ // TODO(eieio): Determine how these fields should be populated. On phones
+ // these values are determined at runtime by VrCore based on which headset the
+ // phone is in. On dedicated hardware this needs to come from somewhere else.
+ // Perhaps these should be moved to a separate structure that is returned by a
+ // separate runtime call.
uint32_t distorted_width;
uint32_t distorted_height;
- uint32_t vsync_period_ns;
uint32_t hmd_ipd_mm;
float inter_lens_distance_m;
std::array<float, 4> left_fov_lrbt;
std::array<float, 4> right_fov_lrbt;
private:
- PDX_SERIALIZABLE_MEMBERS(SystemDisplayMetrics, display_native_width,
- display_native_height, display_x_dpi, display_y_dpi,
- distorted_width, distorted_height, vsync_period_ns,
- hmd_ipd_mm, inter_lens_distance_m, left_fov_lrbt,
+ PDX_SERIALIZABLE_MEMBERS(Metrics, display_width, display_height,
+ display_x_dpi, display_y_dpi, vsync_period_ns,
+ distorted_width, distorted_height, hmd_ipd_mm,
+ inter_lens_distance_m, left_fov_lrbt,
right_fov_lrbt);
};
-using SurfaceType = uint32_t;
-struct SurfaceTypeEnum {
- enum : SurfaceType {
- Normal = DVR_SURFACE_TYPE_NORMAL,
- VideoMesh = DVR_SURFACE_TYPE_VIDEO_MESH,
- Overlay = DVR_SURFACE_TYPE_OVERLAY,
+// Serializable base type for enum structs. Enum structs are easier to use than
+// enum classes, especially for bitmasks. This base type provides common
+// utilities for flags types.
+template <typename Integer>
+class Flags {
+ public:
+ using Base = Flags<Integer>;
+ using Type = Integer;
+
+ Flags(const Integer& value) : value_{value} {}
+ Flags(const Flags&) = default;
+ Flags& operator=(const Flags&) = default;
+
+ Integer value() const { return value_; }
+ operator Integer() const { return value_; }
+
+ bool IsSet(Integer bits) const { return (value_ & bits) == bits; }
+ bool IsClear(Integer bits) const { return (value_ & bits) == 0; }
+
+ void Set(Integer bits) { value_ |= bits; }
+ void Clear(Integer bits) { value_ &= ~bits; }
+
+ Integer operator|(Integer bits) const { return value_ | bits; }
+ Integer operator&(Integer bits) const { return value_ & bits; }
+
+ Flags& operator|=(Integer bits) {
+ value_ |= bits;
+ return *this;
+ }
+ Flags& operator&=(Integer bits) {
+ value_ &= bits;
+ return *this;
+ }
+
+ private:
+ Integer value_;
+
+ PDX_SERIALIZABLE_MEMBERS(Flags<Integer>, value_);
+};
+
+// Flags indicating what changed since last update.
+struct SurfaceUpdateFlags : public Flags<uint32_t> {
+ enum : Type {
+ None = DVR_SURFACE_UPDATE_FLAGS_NONE,
+ NewSurface = DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE,
+ BuffersChanged = DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED,
+ VisibilityChanged = DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED,
+ AttributesChanged = DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED,
};
+
+ SurfaceUpdateFlags() : Base{None} {}
+ using Base::Base;
};
-using DisplaySurfaceFlags = uint32_t;
-enum class DisplaySurfaceFlagsEnum : DisplaySurfaceFlags {
- DisableSystemEds = DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_EDS,
- DisableSystemDistortion = DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION,
- VerticalFlip = DVR_DISPLAY_SURFACE_FLAGS_VERTICAL_FLIP,
- SeparateGeometry = DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2,
- DisableSystemCac = DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_CAC,
-};
-
-using DisplaySurfaceInfoFlags = uint32_t;
-enum class DisplaySurfaceInfoFlagsEnum : DisplaySurfaceInfoFlags {
- BuffersChanged = DVR_DISPLAY_SURFACE_ITEM_FLAGS_BUFFERS_CHANGED,
-};
-
-using DisplaySurfaceAttributeValue =
+// Surface attribute key/value types.
+using SurfaceAttributeKey = int32_t;
+using SurfaceAttributeValue =
pdx::rpc::Variant<int32_t, int64_t, bool, float, std::array<float, 2>,
std::array<float, 3>, std::array<float, 4>,
- std::array<float, 16>>;
-using DisplaySurfaceAttribute = uint32_t;
-struct DisplaySurfaceAttributeEnum {
- enum : DisplaySurfaceAttribute {
- ZOrder = DVR_DISPLAY_SURFACE_ATTRIBUTE_Z_ORDER,
- Visible = DVR_DISPLAY_SURFACE_ATTRIBUTE_VISIBLE,
- // Manager only.
- Blur = DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR,
- // Client only.
- ExcludeFromBlur = DVR_DISPLAY_SURFACE_ATTRIBUTE_EXCLUDE_FROM_BLUR,
- BlurBehind = DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR_BEHIND,
+ std::array<float, 8>, std::array<float, 16>>;
+
+// Defined surface attribute keys.
+struct SurfaceAttribute : public Flags<SurfaceAttributeKey> {
+ enum : Type {
+ // Keys in the negative integer space are interpreted by VrFlinger for
+ // direct surfaces.
+ Direct = DVR_SURFACE_ATTRIBUTE_DIRECT,
+ ZOrder = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
+ Visible = DVR_SURFACE_ATTRIBUTE_VISIBLE,
+
+ // Invalid key. May be used to terminate C style lists in public API code.
+ Invalid = DVR_SURFACE_ATTRIBUTE_INVALID,
+
+ // Positive keys are interpreted by the compositor only.
+ FirstUserKey = DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY,
};
- static std::string ToString(DisplaySurfaceAttribute attribute) {
- switch (attribute) {
- case ZOrder:
- return "z-order";
- case Visible:
- return "visible";
- case Blur:
- return "blur";
- case ExcludeFromBlur:
- return "exclude-from-blur";
- case BlurBehind:
- return "blur-behind";
- default:
- return "unknown";
- }
- }
+ SurfaceAttribute() : Base{Invalid} {}
+ using Base::Base;
};
-using DisplaySurfaceAttributes =
- std::map<DisplaySurfaceAttribute, DisplaySurfaceAttributeValue>;
+// Collection of surface attribute key/value pairs.
+using SurfaceAttributes = std::map<SurfaceAttributeKey, SurfaceAttributeValue>;
-struct DisplaySurfaceInfo {
- int surface_id;
- int process_id;
- SurfaceType type;
- DisplaySurfaceFlags flags;
- DisplaySurfaceInfoFlags info_flags;
- DisplaySurfaceAttributes client_attributes;
- DisplaySurfaceAttributes manager_attributes;
+struct SurfaceState {
+ int32_t surface_id;
+ int32_t process_id;
+ int32_t user_id;
+
+ SurfaceAttributes surface_attributes;
+ SurfaceUpdateFlags update_flags;
+ std::vector<int32_t> queue_ids;
// Convenience accessors.
- bool IsClientVisible() const {
- const auto* variant =
- FindClientAttribute(DisplaySurfaceAttributeEnum::Visible);
- bool bool_value;
- if (variant && pdx::rpc::IfAnyOf<int32_t, int64_t, bool, float>::Get(
- variant, &bool_value))
- return bool_value;
+ bool GetVisible() const {
+ bool bool_value = false;
+ GetAttribute(SurfaceAttribute::Visible, &bool_value,
+ ValidTypes<int32_t, int64_t, bool, float>{});
+ return bool_value;
+ }
+
+ int GetZOrder() const {
+ int int_value = 0;
+ GetAttribute(SurfaceAttribute::ZOrder, &int_value,
+ ValidTypes<int32_t, int64_t, float>{});
+ return int_value;
+ }
+
+ private:
+ template <typename... Types>
+ struct ValidTypes {};
+
+ template <typename ReturnType, typename... Types>
+ bool GetAttribute(SurfaceAttributeKey key, ReturnType* out_value,
+ ValidTypes<Types...>) const {
+ auto search = surface_attributes.find(key);
+ if (search != surface_attributes.end())
+ return pdx::rpc::IfAnyOf<Types...>::Get(&search->second, out_value);
else
return false;
}
- int ClientZOrder() const {
- const auto* variant =
- FindClientAttribute(DisplaySurfaceAttributeEnum::ZOrder);
- int int_value;
- if (variant &&
- pdx::rpc::IfAnyOf<int32_t, int64_t, float>::Get(variant, &int_value))
- return int_value;
- else
- return 0;
- }
+ PDX_SERIALIZABLE_MEMBERS(SurfaceState, surface_id, process_id,
+ surface_attributes, update_flags, queue_ids);
+};
+
+struct SurfaceInfo {
+ int surface_id;
+ bool visible;
+ int z_order;
private:
- const DisplaySurfaceAttributeValue* FindClientAttribute(
- DisplaySurfaceAttribute key) const {
- auto search = client_attributes.find(key);
- return (search != client_attributes.end()) ? &search->second : nullptr;
- }
-
- PDX_SERIALIZABLE_MEMBERS(DisplaySurfaceInfo, surface_id, process_id, type,
- flags, info_flags, client_attributes,
- manager_attributes);
+ PDX_SERIALIZABLE_MEMBERS(SurfaceInfo, surface_id, visible, z_order);
};
-struct AlignmentMarker {
- public:
- float horizontal;
- float vertical;
-
- PDX_SERIALIZABLE_MEMBERS(AlignmentMarker, horizontal, vertical);
-};
-
-struct DaydreamInternalParams {
- public:
- int32_t version;
- std::vector<AlignmentMarker> alignment_markers;
-
- PDX_SERIALIZABLE_MEMBERS(DaydreamInternalParams, version, alignment_markers);
-};
-
-struct ViewerParams {
- public:
- // TODO(hendrikw): Do we need viewer_vendor_name and viewer_model_name?
- float screen_to_lens_distance;
- float inter_lens_distance;
- float screen_center_to_lens_distance;
- std::vector<float> left_eye_field_of_view_angles;
-
- enum VerticalAlignmentType : int32_t {
- BOTTOM = 0, // phone rests against a fixed bottom tray
- CENTER = 1, // phone screen assumed to be centered w.r.t. lenses
- TOP = 2 // phone rests against a fixed top tray
- };
-
- enum EyeOrientation : int32_t {
- kCCW0Degrees = 0,
- kCCW90Degrees = 1,
- kCCW180Degrees = 2,
- kCCW270Degrees = 3,
- kCCW0DegreesMirrored = 4,
- kCCW90DegreesMirrored = 5,
- kCCW180DegreesMirrored = 6,
- kCCW270DegreesMirrored = 7
- };
-
- VerticalAlignmentType vertical_alignment;
- std::vector<EyeOrientation> eye_orientations;
-
- float tray_to_lens_distance;
-
- std::vector<float> distortion_coefficients_r;
- std::vector<float> distortion_coefficients_g;
- std::vector<float> distortion_coefficients_b;
-
- DaydreamInternalParams daydream_internal;
-
- PDX_SERIALIZABLE_MEMBERS(ViewerParams, screen_to_lens_distance,
- inter_lens_distance, screen_center_to_lens_distance,
- left_eye_field_of_view_angles, vertical_alignment,
- eye_orientations, tray_to_lens_distance,
- distortion_coefficients_r, distortion_coefficients_g,
- distortion_coefficients_b, daydream_internal);
-};
-
-struct DisplayRPC {
+struct DisplayProtocol {
// Service path.
static constexpr char kClientPath[] = "system/vr/display/client";
// Op codes.
enum {
kOpGetMetrics = 0,
- kOpGetEdsCapture,
- kOpCreateSurface,
- kOpCreateBufferQueue,
- kOpSetAttributes,
- kOpGetMetadataBuffer,
- kOpCreateVideoMeshSurface,
- kOpVideoMeshSurfaceCreateProducerQueue,
- kOpSetViewerParams,
kOpGetNamedBuffer,
kOpIsVrAppRunning,
+ kOpCreateSurface,
+ kOpGetSurfaceInfo,
+ kOpCreateQueue,
+ kOpSetAttributes,
};
// Aliases.
- using ByteBuffer = pdx::rpc::BufferWrapper<std::vector<uint8_t>>;
using LocalChannelHandle = pdx::LocalChannelHandle;
using Void = pdx::rpc::Void;
// Methods.
- PDX_REMOTE_METHOD(GetMetrics, kOpGetMetrics, SystemDisplayMetrics(Void));
- PDX_REMOTE_METHOD(GetEdsCapture, kOpGetEdsCapture, ByteBuffer(Void));
- PDX_REMOTE_METHOD(CreateSurface, kOpCreateSurface,
- int(int width, int height, int format, int usage,
- DisplaySurfaceFlags flags));
- PDX_REMOTE_METHOD(CreateBufferQueue, kOpCreateBufferQueue,
- LocalChannelHandle(Void));
- PDX_REMOTE_METHOD(SetAttributes, kOpSetAttributes,
- int(const DisplaySurfaceAttributes& attributes));
- PDX_REMOTE_METHOD(GetMetadataBuffer, kOpGetMetadataBuffer,
- LocalChannelHandle(Void));
- // VideoMeshSurface methods
- PDX_REMOTE_METHOD(CreateVideoMeshSurface, kOpCreateVideoMeshSurface,
- LocalChannelHandle(Void));
- PDX_REMOTE_METHOD(VideoMeshSurfaceCreateProducerQueue,
- kOpVideoMeshSurfaceCreateProducerQueue,
- LocalChannelHandle(Void));
- PDX_REMOTE_METHOD(SetViewerParams, kOpSetViewerParams,
- void(const ViewerParams& viewer_params));
+ PDX_REMOTE_METHOD(GetMetrics, kOpGetMetrics, Metrics(Void));
PDX_REMOTE_METHOD(GetNamedBuffer, kOpGetNamedBuffer,
- LocalNativeBufferHandle(const std::string& name));
- PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, int(Void));
+ LocalNativeBufferHandle(std::string name));
+ PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, bool(Void));
+ PDX_REMOTE_METHOD(CreateSurface, kOpCreateSurface,
+ SurfaceInfo(const SurfaceAttributes& attributes));
+ PDX_REMOTE_METHOD(GetSurfaceInfo, kOpGetSurfaceInfo, SurfaceInfo(Void));
+ PDX_REMOTE_METHOD(CreateQueue, kOpCreateQueue,
+ LocalChannelHandle(size_t meta_size_bytes));
+ PDX_REMOTE_METHOD(SetAttributes, kOpSetAttributes,
+ void(const SurfaceAttributes& attributes));
};
-struct DisplayManagerRPC {
+struct DisplayManagerProtocol {
// Service path.
static constexpr char kClientPath[] = "system/vr/display/manager";
// Op codes.
enum {
- kOpGetSurfaceList = 0,
- kOpUpdateSurfaces,
+ kOpGetSurfaceState = 0,
+ kOpGetSurfaceQueue,
kOpSetupNamedBuffer,
};
@@ -265,42 +233,15 @@
using Void = pdx::rpc::Void;
// Methods.
- PDX_REMOTE_METHOD(GetSurfaceList, kOpGetSurfaceList,
- std::vector<DisplaySurfaceInfo>(Void));
- PDX_REMOTE_METHOD(
- UpdateSurfaces, kOpUpdateSurfaces,
- int(const std::map<int, DisplaySurfaceAttributes>& updates));
+ PDX_REMOTE_METHOD(GetSurfaceState, kOpGetSurfaceState,
+ std::vector<SurfaceState>(Void));
+ PDX_REMOTE_METHOD(GetSurfaceQueue, kOpGetSurfaceQueue,
+ LocalChannelHandle(int surface_id, int queue_id));
PDX_REMOTE_METHOD(SetupNamedBuffer, kOpSetupNamedBuffer,
LocalNativeBufferHandle(const std::string& name,
size_t size, uint64_t usage));
};
-struct ScreenshotData {
- int width;
- int height;
- std::vector<uint8_t> buffer;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(ScreenshotData, width, height, buffer);
-};
-
-struct DisplayScreenshotRPC {
- // Service path.
- static constexpr char kClientPath[] = "system/vr/display/screenshot";
-
- // Op codes.
- enum {
- kOpGetFormat = 0,
- kOpTakeScreenshot,
- };
-
- using Void = pdx::rpc::Void;
-
- PDX_REMOTE_METHOD(GetFormat, kOpGetFormat, int(Void));
- PDX_REMOTE_METHOD(TakeScreenshot, kOpTakeScreenshot,
- ScreenshotData(int layer_index));
-};
-
struct VSyncSchedInfo {
int64_t vsync_period_ns;
int64_t timestamp_ns;
@@ -311,7 +252,7 @@
next_vsync_count);
};
-struct DisplayVSyncRPC {
+struct VSyncProtocol {
// Service path.
static constexpr char kClientPath[] = "system/vr/display/vsync";
@@ -332,9 +273,10 @@
PDX_REMOTE_METHOD(Wait, kOpWait, Timestamp(Void));
PDX_REMOTE_METHOD(GetLastTimestamp, kOpGetLastTimestamp, Timestamp(Void));
PDX_REMOTE_METHOD(GetSchedInfo, kOpGetSchedInfo, VSyncSchedInfo(Void));
- PDX_REMOTE_METHOD(Acknowledge, kOpAcknowledge, int(Void));
+ PDX_REMOTE_METHOD(Acknowledge, kOpAcknowledge, void(Void));
};
+} // namespace display
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/include/private/dvr/display_types.h b/libs/vr/libdisplay/include/private/dvr/display_types.h
deleted file mode 100644
index 2bd02bd..0000000
--- a/libs/vr/libdisplay/include/private/dvr/display_types.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_TYPES_H_
-#define ANDROID_DVR_DISPLAY_TYPES_H_
-
-#ifdef __ARM_NEON
-#include <arm_neon.h>
-#else
-#ifndef __FLOAT32X4T_86
-#define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__ ((__vector_size__ (16)));
-typedef struct float32x4x4_t { float32x4_t val[4]; };
-#endif
-#endif
-
-#include <cutils/native_handle.h>
-
-// DVR display-related data types.
-
-enum dvr_display_surface_type {
- // Normal display surface meant to be used by applications' GL context to
- // render into.
- DVR_SURFACE_TYPE_NORMAL = 0,
-
- // VideoMeshSurface is used to composite video frames into the 3D world.
- DVR_SURFACE_TYPE_VIDEO_MESH,
-
- // System overlay surface type. This is not currently in use.
- DVR_SURFACE_TYPE_OVERLAY,
-};
-
-enum dvr_display_surface_flags {
- DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_EDS = (1 << 0),
- DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION = (1 << 1),
- DVR_DISPLAY_SURFACE_FLAGS_VERTICAL_FLIP = (1 << 2),
- DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2 = (1 << 3),
- DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_CAC = (1 << 4),
-};
-
-enum dvr_display_surface_item_flags {
- DVR_DISPLAY_SURFACE_ITEM_FLAGS_BUFFERS_CHANGED = (1 << 0),
-};
-
-enum dvr_display_surface_attribute {
- DVR_DISPLAY_SURFACE_ATTRIBUTE_Z_ORDER = (1<<0),
- DVR_DISPLAY_SURFACE_ATTRIBUTE_VISIBLE = (1<<1),
- DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR = (1<<2),
- DVR_DISPLAY_SURFACE_ATTRIBUTE_EXCLUDE_FROM_BLUR = (1<<3),
- DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR_BEHIND = (1<<4),
-};
-
-// Maximum number of buffers for a surface. Each buffer represents a single
-// frame and may actually be a buffer array if multiview rendering is in use.
-// Define so that it can be used in shader code.
-#define kSurfaceBufferMaxCount 4
-
-// Maximum number of views per surface. Each eye is a view, for example.
-#define kSurfaceViewMaxCount 4
-
-namespace android {
-namespace dvr {
-
-struct __attribute__((packed, aligned(16))) DisplaySurfaceMetadata {
- // Array of orientations and translations corresponding with surface buffers.
- // The index is associated with each allocated buffer by DisplaySurface and
- // communicated to clients.
- // The maximum number of buffers is hard coded here as 4 so that we can bind
- // this data structure in GPU shaders.
- float32x4_t orientation[kSurfaceBufferMaxCount];
- float32x4_t translation[kSurfaceBufferMaxCount];
-};
-
-struct __attribute__((packed, aligned(16))) VideoMeshSurfaceMetadata {
- // Array of transform matrices corresponding with surface buffers.
- // Note that The index is associated with each allocated buffer by
- // DisplaySurface instead of VideoMeshSurface due to the fact that the
- // metadata here is interpreted as video mesh's transformation in each
- // application's rendering frame.
- float32x4x4_t transform[4][2];
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_DISPLAY_TYPES_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/graphics_private.h b/libs/vr/libdisplay/include/private/dvr/graphics_private.h
index 57c99da..a08b0df 100644
--- a/libs/vr/libdisplay/include/private/dvr/graphics_private.h
+++ b/libs/vr/libdisplay/include/private/dvr/graphics_private.h
@@ -17,6 +17,19 @@
__BEGIN_DECLS
+#define kSurfaceBufferMaxCount 4
+#define kSurfaceViewMaxCount 4
+
+struct __attribute__((packed, aligned(16))) DisplaySurfaceMetadata {
+ // Array of orientations and translations corresponding with surface buffers.
+ // The index is associated with each allocated buffer by DisplaySurface and
+ // communicated to clients.
+ // The maximum number of buffers is hard coded here as 4 so that we can bind
+ // this data structure in GPU shaders.
+ float32x4_t orientation[kSurfaceBufferMaxCount];
+ float32x4_t translation[kSurfaceBufferMaxCount];
+};
+
// Sets the pose used by the system for EDS. If dvrBeginRenderFrameEds() or
// dvrBeginRenderFrameLateLatch() are called instead of dvrBeginRenderFrame()
// it's not necessary to call this function. If this function is used, the call
diff --git a/libs/vr/libdisplay/include/private/dvr/late_latch.h b/libs/vr/libdisplay/include/private/dvr/late_latch.h
index b7c5e4f..c91d15c 100644
--- a/libs/vr/libdisplay/include/private/dvr/late_latch.h
+++ b/libs/vr/libdisplay/include/private/dvr/late_latch.h
@@ -5,11 +5,12 @@
#include <thread>
#include <vector>
+#include <dvr/dvr_display_types.h>
#include <dvr/pose_client.h>
#include <pdx/file_handle.h>
-#include <private/dvr/display_types.h>
#include <private/dvr/graphics/shader_program.h>
#include <private/dvr/graphics/vr_gl_extensions.h>
+#include <private/dvr/graphics_private.h>
#include <private/dvr/types.h>
struct DvrPose;
diff --git a/libs/vr/libdisplay/include/private/dvr/native_buffer_queue.h b/libs/vr/libdisplay/include/private/dvr/native_buffer_queue.h
index 4b1fa98..a260f17 100644
--- a/libs/vr/libdisplay/include/private/dvr/native_buffer_queue.h
+++ b/libs/vr/libdisplay/include/private/dvr/native_buffer_queue.h
@@ -13,30 +13,43 @@
namespace android {
namespace dvr {
+namespace display {
// A wrapper over dvr::ProducerQueue that caches EGLImage.
class NativeBufferQueue {
public:
- // Create a queue with the given number of free buffers.
NativeBufferQueue(EGLDisplay display,
- const std::shared_ptr<DisplaySurfaceClient>& surface,
- size_t capacity);
+ const std::shared_ptr<ProducerQueue>& producer_queue,
+ uint32_t width, uint32_t height, uint32_t format,
+ uint64_t usage, size_t capacity);
- size_t GetQueueCapacity() const { return producer_queue_->capacity(); }
+ uint32_t width() const { return width_; }
+ uint32_t height() const { return height_; }
+ uint32_t format() const { return format_; }
+ uint64_t usage() const { return usage_; }
+ size_t capacity() const { return producer_queue_->capacity(); }
// Dequeue a buffer from the free queue, blocking until one is available.
NativeBufferProducer* Dequeue();
// An noop here to keep Vulkan path in GraphicsContext happy.
// TODO(jwcai, cort) Move Vulkan path into GVR/Google3.
- void Enqueue(NativeBufferProducer* buffer) {}
+ void Enqueue(NativeBufferProducer* /*buffer*/) {}
private:
EGLDisplay display_;
+ uint32_t width_;
+ uint32_t height_;
+ uint32_t format_;
+ uint64_t usage_;
std::shared_ptr<ProducerQueue> producer_queue_;
std::vector<sp<NativeBufferProducer>> buffers_;
+
+ NativeBufferQueue(const NativeBufferQueue&) = delete;
+ void operator=(const NativeBufferQueue&) = delete;
};
+} // namespace display
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/native_buffer_queue.cpp b/libs/vr/libdisplay/native_buffer_queue.cpp
index d516d63..762db32 100644
--- a/libs/vr/libdisplay/native_buffer_queue.cpp
+++ b/libs/vr/libdisplay/native_buffer_queue.cpp
@@ -7,58 +7,59 @@
#include <array>
-#include <private/dvr/display_types.h>
+#include <dvr/dvr_display_types.h>
namespace android {
namespace dvr {
+namespace display {
NativeBufferQueue::NativeBufferQueue(
- EGLDisplay display, const std::shared_ptr<DisplaySurfaceClient>& surface,
+ EGLDisplay display, const std::shared_ptr<ProducerQueue>& producer_queue,
+ uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
size_t capacity)
- : display_(display), buffers_(capacity) {
- std::shared_ptr<ProducerQueue> queue = surface->GetProducerQueue();
-
+ : display_(display),
+ width_(width),
+ height_(height),
+ format_(format),
+ usage_(usage),
+ producer_queue_(producer_queue),
+ buffers_(capacity) {
for (size_t i = 0; i < capacity; i++) {
size_t slot;
// TODO(jwcai) Should change to use BufferViewPort's spec to config.
- int ret =
- queue->AllocateBuffer(surface->width(), surface->height(),
- surface->format(), surface->usage(), 1, &slot);
+ const int ret = producer_queue_->AllocateBuffer(width_, height_, format_,
+ usage_, 1, &slot);
if (ret < 0) {
ALOGE(
- "NativeBufferQueue::NativeBufferQueue: Failed to allocate buffer, "
- "error=%d",
- ret);
+ "NativeBufferQueue::NativeBufferQueue: Failed to allocate buffer: %s",
+ strerror(-ret));
return;
}
- ALOGD_IF(TRACE,
- "NativeBufferQueue::NativeBufferQueue: New buffer allocated at "
- "slot=%zu",
- slot);
+ ALOGD_IF(TRACE, "NativeBufferQueue::NativeBufferQueue: slot=%zu", slot);
}
-
- producer_queue_ = std::move(queue);
}
NativeBufferProducer* NativeBufferQueue::Dequeue() {
ATRACE_NAME("NativeBufferQueue::Dequeue");
-
- // This never times out.
size_t slot;
pdx::LocalHandle fence;
- std::shared_ptr<BufferProducer> buffer =
- producer_queue_->Dequeue(-1, &slot, &fence);
-
- if (buffers_[slot] == nullptr) {
- buffers_[slot] = new NativeBufferProducer(buffer, display_, slot);
+ auto buffer_status = producer_queue_->Dequeue(-1, &slot, &fence);
+ if (!buffer_status) {
+ ALOGE("NativeBufferQueue::Dequeue: Failed to dequeue buffer: %s",
+ buffer_status.GetErrorMessage().c_str());
+ return nullptr;
}
- ALOGD_IF(TRACE,
- "NativeBufferQueue::Dequeue: dequeue buffer at slot=%zu, buffer=%p",
- slot, buffers_[slot].get());
+ if (buffers_[slot] == nullptr)
+ buffers_[slot] =
+ new NativeBufferProducer(buffer_status.take(), display_, slot);
+
+ ALOGD_IF(TRACE, "NativeBufferQueue::Dequeue: slot=%zu buffer=%p", slot,
+ buffers_[slot].get());
return buffers_[slot].get();
}
+} // namespace display
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/tests/graphics_app_tests.cpp b/libs/vr/libdisplay/tests/graphics_app_tests.cpp
index f51dd8a..c592ba9 100644
--- a/libs/vr/libdisplay/tests/graphics_app_tests.cpp
+++ b/libs/vr/libdisplay/tests/graphics_app_tests.cpp
@@ -57,6 +57,8 @@
dvrGraphicsContextCreate(surface_params, &context);
EXPECT_NE(nullptr, context);
+ dvrGraphicsSurfaceSetVisible(context, 1);
+
DvrFrameSchedule schedule;
int wait_result = dvrGraphicsWaitNextFrame(context, 0, &schedule);
EXPECT_EQ(wait_result, 0);
@@ -64,10 +66,10 @@
dvrBeginRenderFrame(context);
- // Check range of vsync period from 70fps to 100fps.
+ // Check range of vsync period from 60fps to 100fps.
// TODO(jbates) Once we have stable hardware, clamp this range down further.
- EXPECT_LT(vsync_period, 1000000000ul / 70ul);
- EXPECT_GT(vsync_period, 1000000000ul / 100ul);
+ EXPECT_LE(vsync_period, 1000000000ul / 60ul);
+ EXPECT_GE(vsync_period, 1000000000ul / 100ul);
dvrPresent(context);
dvrGraphicsContextDestroy(context);
@@ -103,15 +105,3 @@
dvrGraphicsContextDestroy(context);
}
-TEST(GraphicsAppTests, CreateVideoMeshSurface) {
- DvrSurfaceParameter surface_params[] = {DVR_SURFACE_PARAMETER_LIST_END};
- DvrGraphicsContext* context = nullptr;
- int result = dvrGraphicsContextCreate(surface_params, &context);
- EXPECT_NE(nullptr, context);
- EXPECT_EQ(result, 0);
-
- DvrVideoMeshSurface* surface = dvrGraphicsVideoMeshSurfaceCreate(context);
- EXPECT_NE(nullptr, surface);
-
- dvrGraphicsVideoMeshSurfaceDestroy(surface);
-}
diff --git a/libs/vr/libdisplay/vsync_client.cpp b/libs/vr/libdisplay/vsync_client.cpp
index 2f6320c..bc6cf6c 100644
--- a/libs/vr/libdisplay/vsync_client.cpp
+++ b/libs/vr/libdisplay/vsync_client.cpp
@@ -5,6 +5,7 @@
#include <pdx/default_transport/client_channel_factory.h>
#include <private/dvr/display_protocol.h>
+using android::dvr::display::VSyncProtocol;
using android::pdx::Transaction;
namespace android {
@@ -12,15 +13,15 @@
VSyncClient::VSyncClient(long timeout_ms)
: BASE(pdx::default_transport::ClientChannelFactory::Create(
- DisplayVSyncRPC::kClientPath),
+ VSyncProtocol::kClientPath),
timeout_ms) {}
VSyncClient::VSyncClient()
: BASE(pdx::default_transport::ClientChannelFactory::Create(
- DisplayVSyncRPC::kClientPath)) {}
+ VSyncProtocol::kClientPath)) {}
int VSyncClient::Wait(int64_t* timestamp_ns) {
- auto status = InvokeRemoteMethod<DisplayVSyncRPC::Wait>();
+ auto status = InvokeRemoteMethod<VSyncProtocol::Wait>();
if (!status) {
ALOGE("VSyncClient::Wait: Failed to wait for vsync: %s",
status.GetErrorMessage().c_str());
@@ -36,7 +37,7 @@
int VSyncClient::GetFd() { return event_fd(); }
int VSyncClient::GetLastTimestamp(int64_t* timestamp_ns) {
- auto status = InvokeRemoteMethod<DisplayVSyncRPC::GetLastTimestamp>();
+ auto status = InvokeRemoteMethod<VSyncProtocol::GetLastTimestamp>();
if (!status) {
ALOGE("VSyncClient::GetLastTimestamp: Failed to get vsync timestamp: %s",
status.GetErrorMessage().c_str());
@@ -51,7 +52,7 @@
if (!vsync_period_ns || !timestamp_ns || !next_vsync_count)
return -EINVAL;
- auto status = InvokeRemoteMethod<DisplayVSyncRPC::GetSchedInfo>();
+ auto status = InvokeRemoteMethod<VSyncProtocol::GetSchedInfo>();
if (!status) {
ALOGE("VSyncClient::GetSchedInfo:: Failed to get warp timestamp: %s",
status.GetErrorMessage().c_str());
@@ -65,7 +66,7 @@
}
int VSyncClient::Acknowledge() {
- auto status = InvokeRemoteMethod<DisplayVSyncRPC::Acknowledge>();
+ auto status = InvokeRemoteMethod<VSyncProtocol::Acknowledge>();
ALOGE_IF(!status, "VSuncClient::Acknowledge: Failed to ack vsync because: %s",
status.GetErrorMessage().c_str());
return ReturnStatusOrError(status);