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/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
index a04ed50..b70f726 100644
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ b/libs/vr/libdvr/dvr_surface.cpp
@@ -1,65 +1,162 @@
#include "include/dvr/dvr_surface.h"
+#include <inttypes.h>
+
#include <private/dvr/display_client.h>
-using namespace android;
+#include "dvr_internal.h"
-struct DvrSurface {
- std::unique_ptr<dvr::DisplaySurfaceClient> display_surface_;
-};
+using android::dvr::display::DisplayClient;
+using android::dvr::display::Surface;
+using android::dvr::display::SurfaceAttributes;
+using android::dvr::display::SurfaceAttributeValue;
+using android::dvr::CreateDvrReadBufferFromBufferConsumer;
+using android::dvr::CreateDvrWriteBufferQueueFromProducerQueue;
+
+namespace {
+
+bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
+ size_t attribute_count,
+ SurfaceAttributes* surface_attributes,
+ size_t* error_index) {
+ for (size_t i = 0; i < attribute_count; i++) {
+ SurfaceAttributeValue value;
+ switch (attributes[i].value.type) {
+ case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
+ value = attributes[i].value.int32_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
+ value = attributes[i].value.int64_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
+ value = attributes[i].value.bool_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
+ value = attributes[i].value.float_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
+ value = attributes[i].value.float2_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
+ value = attributes[i].value.float3_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
+ value = attributes[i].value.float4_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
+ value = attributes[i].value.float8_value;
+ break;
+ case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
+ value = attributes[i].value.float16_value;
+ break;
+ default:
+ *error_index = i;
+ return false;
+ }
+
+ surface_attributes->emplace(attributes[i].key, value);
+ }
+
+ return true;
+}
+
+} // anonymous namespace
extern "C" {
-int dvrSurfaceCreate(int width, int height, int format, uint64_t usage0,
- uint64_t usage1, int flags, DvrSurface** out_surface) {
+struct DvrSurface {
+ std::unique_ptr<Surface> surface;
+};
+
+int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
+ size_t attribute_count, DvrSurface** out_surface) {
if (out_surface == nullptr) {
- ALOGE("dvrSurfaceCreate: invalid inputs: out_surface=%p.", out_surface);
+ ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
return -EINVAL;
}
- int error;
- auto client = dvr::DisplayClient::Create(&error);
- if (!client) {
- ALOGE("Failed to create display client!");
- return error;
+ size_t error_index;
+ SurfaceAttributes surface_attributes;
+ if (!ConvertSurfaceAttributes(attributes, attribute_count,
+ &surface_attributes, &error_index)) {
+ ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
+ attributes[error_index].value.type);
+ return -EINVAL;
}
- // TODO(hendrikw): When we move to gralloc1, pass both usage0 and usage1 down.
- std::unique_ptr<dvr::DisplaySurfaceClient> surface =
- client->CreateDisplaySurface(
- width, height, static_cast<int>(usage0 | usage1), format, flags);
+ auto status = Surface::CreateSurface(surface_attributes);
+ if (!status) {
+ ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
+ status.GetErrorMessage().c_str());
+ return -status.error();
+ }
- DvrSurface* dvr_surface = new DvrSurface;
- dvr_surface->display_surface_ = std::move(surface);
- *out_surface = dvr_surface;
+ *out_surface = new DvrSurface{status.take()};
return 0;
}
-int dvrSurfaceGetWriteBufferQueue(DvrSurface* surface,
- DvrWriteBufferQueue** out_writer) {
+void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
+
+int dvrSurfaceGetId(DvrSurface* surface) {
+ return surface->surface->surface_id();
+}
+
+int dvrSurfaceSetAttributes(DvrSurface* surface,
+ const DvrSurfaceAttribute* attributes,
+ size_t attribute_count) {
+ if (surface == nullptr || attributes == nullptr) {
+ ALOGE(
+ "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
+ "attribute_count=%zu",
+ surface, attributes, attribute_count);
+ return -EINVAL;
+ }
+
+ size_t error_index;
+ SurfaceAttributes surface_attributes;
+ if (!ConvertSurfaceAttributes(attributes, attribute_count,
+ &surface_attributes, &error_index)) {
+ ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
+ attributes[error_index].value.type);
+ return -EINVAL;
+ }
+
+ auto status = surface->surface->SetAttributes(surface_attributes);
+ if (!status) {
+ ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
+ status.GetErrorMessage().c_str());
+ return -status.error();
+ }
+
+ return 0;
+}
+
+int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
+ uint32_t height, uint32_t format,
+ uint64_t usage, size_t capacity,
+ DvrWriteBufferQueue** out_writer) {
if (surface == nullptr || out_writer == nullptr) {
ALOGE(
- "dvrSurfaceGetWriteBufferQueue: Invalid inputs: surface=%p, "
+ "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
"out_writer=%p.",
surface, out_writer);
return -EINVAL;
}
- DvrWriteBufferQueue* buffer_writer = new DvrWriteBufferQueue;
- buffer_writer->producer_queue_ =
- surface->display_surface_->GetProducerQueue();
- if (buffer_writer->producer_queue_ == nullptr) {
- ALOGE(
- "dvrSurfaceGetWriteBufferQueue: Failed to get producer queue from "
- "display surface.");
- return -ENOMEM;
+
+ auto status =
+ surface->surface->CreateQueue(width, height, format, usage, capacity);
+ if (!status) {
+ ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
+ status.GetErrorMessage().c_str());
+ return -status.error();
}
- *out_writer = buffer_writer;
+ *out_writer = CreateDvrWriteBufferQueueFromProducerQueue(status.take());
return 0;
}
int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) {
- auto client = android::dvr::DisplayClient::Create();
+ auto client = DisplayClient::Create();
if (!client) {
ALOGE("dvrGetNamedBuffer: Failed to create display client!");
return -ECOMM;
@@ -71,12 +168,13 @@
return -EINVAL;
}
- auto named_buffer = client->GetNamedBuffer(name);
- if (!named_buffer) {
- ALOGE("dvrGetNamedBuffer: Failed to find named buffer: %s.", name);
- return -EINVAL;
+ auto status = client->GetNamedBuffer(name);
+ if (!status) {
+ ALOGE("dvrGetNamedBuffer: Failed to find named buffer name=%s: %s", name,
+ status.GetErrorMessage().c_str());
+ return -status.error();
}
- *out_buffer = CreateDvrBufferFromIonBuffer(std::move(named_buffer));
+ *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
return 0;
}