VR: Move VR HWC DVR API to libdvr
Moved VR HWC API into a common API library.
Bug: 36050795
Test: Compiled
Change-Id: I1af32f4dedb7a6d4bb77a18d3c48cfbc8ea00a66
(cherry picked from commit 3d3fb3960f9c3956074496fd7fa1beb230ac1043)
diff --git a/libs/vr/libdvr/Android.mk b/libs/vr/libdvr/Android.mk
index 5449cb5..3c6934b 100644
--- a/libs/vr/libdvr/Android.mk
+++ b/libs/vr/libdvr/Android.mk
@@ -33,6 +33,7 @@
dvr_api.cpp \
dvr_buffer.cpp \
dvr_buffer_queue.cpp \
+ dvr_hardware_composer_client.cpp \
dvr_surface.cpp \
vsync_client_api.cpp \
@@ -42,12 +43,15 @@
libdisplay \
libvrsensor \
libvirtualtouchpadclient \
+ libvr_hwc-impl \
+ libvr_hwc-binder \
LOCAL_SHARED_LIBRARIES := \
android.hardware.graphics.bufferqueue@1.0 \
android.hidl.token@1.0-utils \
libandroid_runtime \
libbase \
+ libnativewindow \
include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index f464411..f786c29 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -11,6 +11,7 @@
// Headers not yet moved into libdvr.
// TODO(jwcai) Move these once their callers are moved into Google3.
+#include <dvr/dvr_hardware_composer_client.h>
#include <dvr/pose_client.h>
#include <dvr/virtual_touchpad_client.h>
@@ -100,6 +101,26 @@
dvr_api->virtual_touchpad_touch = dvrVirtualTouchpadTouch;
dvr_api->virtual_touchpad_button_state = dvrVirtualTouchpadButtonState;
+ // dvr_hardware_composer_client.h
+ dvr_api->hwc_client_create = dvrHwcClientCreate;
+ dvr_api->hwc_client_destroy = dvrHwcClientDestroy;
+ dvr_api->hwc_frame_destroy = dvrHwcFrameDestroy;
+ dvr_api->hwc_frame_get_display_id = dvrHwcFrameGetDisplayId;
+ dvr_api->hwc_frame_get_display_width = dvrHwcFrameGetDisplayWidth;
+ dvr_api->hwc_frame_get_display_height = dvrHwcFrameGetDisplayHeight;
+ dvr_api->hwc_frame_get_layer_count = dvrHwcFrameGetLayerCount;
+ dvr_api->hwc_frame_get_layer_id = dvrHwcFrameGetLayerId;
+ dvr_api->hwc_frame_get_layer_buffer = dvrHwcFrameGetLayerBuffer;
+ dvr_api->hwc_frame_get_layer_fence = dvrHwcFrameGetLayerFence;
+ dvr_api->hwc_frame_get_layer_display_frame =
+ dvrHwcFrameGetLayerDisplayFrame;
+ dvr_api->hwc_frame_get_layer_crop = dvrHwcFrameGetLayerCrop;
+ dvr_api->hwc_frame_get_layer_blend_mode = dvrHwcFrameGetLayerBlendMode;
+ dvr_api->hwc_frame_get_layer_alpha = dvrHwcFrameGetLayerAlpha;
+ dvr_api->hwc_frame_get_layer_type = dvrHwcFrameGetLayerType;
+ dvr_api->hwc_frame_get_layer_application_id =
+ dvrHwcFrameGetLayerApplicationId;
+
return 0;
}
return -EINVAL;
diff --git a/libs/vr/libdvr/dvr_hardware_composer_client.cpp b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
new file mode 100644
index 0000000..e5665e1
--- /dev/null
+++ b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
@@ -0,0 +1,156 @@
+#include "include/dvr/dvr_hardware_composer_client.h"
+
+#include <android/dvr/IVrComposer.h>
+#include <android/dvr/BnVrComposerCallback.h>
+#include <android/hardware_buffer.h>
+#include <binder/IServiceManager.h>
+#include <private/android/AHardwareBufferHelpers.h>
+
+#include <memory>
+
+struct DvrHwcFrame {
+ android::dvr::ComposerView::Frame frame;
+};
+
+namespace {
+
+class HwcCallback : public android::dvr::BnVrComposerCallback {
+ public:
+ explicit HwcCallback(DvrHwcOnFrameCallback callback,
+ void* client_state);
+ ~HwcCallback() override;
+
+ std::unique_ptr<DvrHwcFrame> DequeueFrame();
+
+ private:
+ // android::dvr::BnVrComposerCallback:
+ android::binder::Status onNewFrame(
+ const android::dvr::ParcelableComposerFrame& frame,
+ android::dvr::ParcelableUniqueFd* fence) override;
+
+ DvrHwcOnFrameCallback callback_;
+ void* client_state_;
+
+ HwcCallback(const HwcCallback&) = delete;
+ void operator=(const HwcCallback&) = delete;
+};
+
+HwcCallback::HwcCallback(DvrHwcOnFrameCallback callback, void* client_state)
+ : callback_(callback), client_state_(client_state) {}
+
+HwcCallback::~HwcCallback() {}
+
+android::binder::Status HwcCallback::onNewFrame(
+ const android::dvr::ParcelableComposerFrame& frame,
+ android::dvr::ParcelableUniqueFd* fence) {
+ std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame());
+ dvr_frame->frame = frame.frame();
+
+ fence->set_fence(android::base::unique_fd(callback_(client_state_,
+ dvr_frame.release())));
+ return android::binder::Status::ok();
+}
+
+} // namespace
+
+struct DvrHwcClient {
+ android::sp<android::dvr::IVrComposer> composer;
+ android::sp<HwcCallback> callback;
+};
+
+DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) {
+ std::unique_ptr<DvrHwcClient> client(new DvrHwcClient());
+
+ android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+ client->composer = android::interface_cast<android::dvr::IVrComposer>(
+ sm->getService(android::dvr::IVrComposer::SERVICE_NAME()));
+ if (!client->composer.get())
+ return nullptr;
+
+ client->callback = new HwcCallback(callback, data);
+ android::binder::Status status = client->composer->registerObserver(
+ client->callback);
+ if (!status.isOk())
+ return nullptr;
+
+ return client.release();
+}
+
+void dvrHwcClientDestroy(DvrHwcClient* client) {
+ delete client;
+}
+
+void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
+ delete frame;
+}
+
+Display dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
+ return frame->frame.display_id;
+}
+
+int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
+ return frame->frame.display_width;
+}
+
+int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
+ return frame->frame.display_height;
+}
+
+bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
+ return frame->frame.removed;
+}
+
+size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
+ return frame->frame.layers.size();
+}
+
+Layer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
+ return frame->frame.layers[layer_index].id;
+}
+
+AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
+ size_t layer_index) {
+ AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer(
+ frame->frame.layers[layer_index].buffer.get());
+ AHardwareBuffer_acquire(buffer);
+ return buffer;
+}
+
+int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
+ return frame->frame.layers[layer_index].fence->dup();
+}
+
+Recti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame, size_t layer_index) {
+ return Recti{
+ frame->frame.layers[layer_index].display_frame.left,
+ frame->frame.layers[layer_index].display_frame.top,
+ frame->frame.layers[layer_index].display_frame.right,
+ frame->frame.layers[layer_index].display_frame.bottom,
+ };
+}
+
+Rectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) {
+ return Rectf{
+ frame->frame.layers[layer_index].crop.left,
+ frame->frame.layers[layer_index].crop.top,
+ frame->frame.layers[layer_index].crop.right,
+ frame->frame.layers[layer_index].crop.bottom,
+ };
+}
+
+BlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame, size_t layer_index) {
+ return static_cast<BlendMode>(frame->frame.layers[layer_index].blend_mode);
+}
+
+float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
+ return frame->frame.layers[layer_index].alpha;
+}
+
+uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
+ return frame->frame.layers[layer_index].type;
+}
+
+uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
+ size_t layer_index) {
+ return frame->frame.layers[layer_index].app_id;
+}
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index d840b6c..053382f 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <dvr/dvr_hardware_composer_defs.h>
#include <jni.h>
#ifdef __cplusplus
@@ -144,6 +145,37 @@
typedef int (*DvrVirtualTouchpadButtonStatePtr)(DvrVirtualTouchpad* client,
int touchpad, int buttons);
+// dvr_hardware_composer_client.h
+typedef struct DvrHwcClient DvrHwcClient;
+typedef struct DvrHwcFrame DvrHwcFrame;
+typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
+typedef DvrHwcClient* (*DvrHwcClientCreatePtr)(DvrHwcOnFrameCallback callback,
+ void* client_state);
+typedef void (*DvrHwcClientDestroyPtr)(DvrHwcClient* client);
+typedef void (*DvrHwcFrameDestroyPtr)(DvrHwcFrame* frame);
+typedef Display (*DvrHwcFrameGetDisplayIdPtr)(DvrHwcFrame* frame);
+typedef int32_t (*DvrHwcFrameGetDisplayWidthPtr)(DvrHwcFrame* frame);
+typedef int32_t (*DvrHwcFrameGetDisplayHeightPtr)(DvrHwcFrame* frame);
+typedef bool (*DvrHwcFrameGetDisplayRemovedPtr)(DvrHwcFrame* frame);
+typedef size_t (*DvrHwcFrameGetLayerCountPtr)(DvrHwcFrame* frame);
+typedef Layer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame, size_t layer_index);
+typedef AHardwareBuffer* (*DvrHwcFrameGetLayerBufferPtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+typedef int (*DvrHwcFrameGetLayerFencePtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+typedef Recti (*DvrHwcFrameGetLayerDisplayFramePtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+typedef Rectf (*DvrHwcFrameGetLayerCropPtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+typedef BlendMode (*DvrHwcFrameGetLayerBlendModePtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+typedef float (*DvrHwcFrameGetLayerAlphaPtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+typedef uint32_t (*DvrHwcFrameGetLayerTypePtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+typedef uint32_t (*DvrHwcFrameGetLayerApplicationIdPtr)(DvrHwcFrame* frame,
+ size_t layer_index);
+
struct DvrApi_v1 {
// Display manager client
DvrDisplayManagerClientCreatePtr display_manager_client_create;
@@ -220,6 +252,25 @@
DvrVirtualTouchpadDetachPtr virtual_touchpad_detach;
DvrVirtualTouchpadTouchPtr virtual_touchpad_touch;
DvrVirtualTouchpadButtonStatePtr virtual_touchpad_button_state;
+
+ // VR HWComposer client
+ DvrHwcClientCreatePtr hwc_client_create;
+ DvrHwcClientDestroyPtr hwc_client_destroy;
+ DvrHwcFrameDestroyPtr hwc_frame_destroy;
+ DvrHwcFrameGetDisplayIdPtr hwc_frame_get_display_id;
+ DvrHwcFrameGetDisplayWidthPtr hwc_frame_get_display_width;
+ DvrHwcFrameGetDisplayHeightPtr hwc_frame_get_display_height;
+ DvrHwcFrameGetDisplayRemovedPtr hwc_frame_get_display_removed;
+ DvrHwcFrameGetLayerCountPtr hwc_frame_get_layer_count;
+ DvrHwcFrameGetLayerIdPtr hwc_frame_get_layer_id;
+ DvrHwcFrameGetLayerBufferPtr hwc_frame_get_layer_buffer;
+ DvrHwcFrameGetLayerFencePtr hwc_frame_get_layer_fence;
+ DvrHwcFrameGetLayerDisplayFramePtr hwc_frame_get_layer_display_frame;
+ DvrHwcFrameGetLayerCropPtr hwc_frame_get_layer_crop;
+ DvrHwcFrameGetLayerBlendModePtr hwc_frame_get_layer_blend_mode;
+ DvrHwcFrameGetLayerAlphaPtr hwc_frame_get_layer_alpha;
+ DvrHwcFrameGetLayerTypePtr hwc_frame_get_layer_type;
+ DvrHwcFrameGetLayerApplicationIdPtr hwc_frame_get_layer_application_id;
};
int dvrGetApi(void* api, size_t struct_size, int version);
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
new file mode 100644
index 0000000..692864d
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
@@ -0,0 +1,78 @@
+#ifndef ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
+#define ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
+
+#include <dvr/dvr_hardware_composer_defs.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct AHardwareBuffer AHardwareBuffer;
+typedef struct DvrHwcClient DvrHwcClient;
+typedef struct DvrHwcFrame DvrHwcFrame;
+
+// Called when a new frame has arrived.
+//
+// @param client_state Pointer to client state passed in |dvrHwcCreateClient()|.
+// @param frame New frame. Owned by the client.
+// @return fence FD for the release of the last frame.
+typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
+
+// @param callback Called when a new frame is available.
+// @param client_state Pointer to client state passed back in the callback.
+DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback,
+ void* client_state);
+
+void dvrHwcClientDestroy(DvrHwcClient* client);
+
+// Called to free the frame information.
+void dvrHwcFrameDestroy(DvrHwcFrame* frame);
+
+Display dvrHwcFrameGetDisplayId(DvrHwcFrame* frame);
+
+int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame);
+
+int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame);
+
+// @return True if the display has been removed. In this case the current frame
+// does not contain any valid layers to display. It is a signal to clean up any
+// display related state.
+bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame);
+
+// @return Number of layers in the frame.
+size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame);
+
+Layer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index);
+
+// Return the graphic buffer associated with the layer at |layer_index| in
+// |frame|.
+//
+// @return Graphic buffer. Caller owns the buffer and is responsible for freeing
+// it. (see AHardwareBuffer_release())
+AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
+ size_t layer_index);
+
+// Returns the fence FD for the layer at index |layer_index| in |frame|.
+//
+// @return Fence FD. Caller owns the FD and is responsible for closing it.
+int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index);
+
+Recti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame, size_t layer_index);
+
+Rectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index);
+
+BlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame, size_t layer_index);
+
+float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index);
+
+uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index);
+
+uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
+ size_t layer_index);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_defs.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_defs.h
new file mode 100644
index 0000000..546ed7b
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_defs.h
@@ -0,0 +1,50 @@
+#ifndef ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
+#define ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// NOTE: These definitions must match the ones in
+// //hardware/libhardware/include/hardware/hwcomposer2.h. They are used by the
+// client side which does not have access to hwc2 headers.
+enum BlendMode {
+ BLEND_MODE_INVALID = 0,
+ BLEND_MODE_NONE = 1,
+ BLEND_MODE_PREMULTIPLIED = 2,
+ BLEND_MODE_COVERAGE = 3,
+};
+
+enum Composition {
+ COMPOSITION_INVALID = 0,
+ COMPOSITION_CLIENT = 1,
+ COMPOSITION_DEVICE = 2,
+ COMPOSITION_SOLID_COLOR = 3,
+ COMPOSITION_CURSOR = 4,
+ COMPOSITION_SIDEBAND = 5,
+};
+
+typedef uint64_t Display;
+typedef uint64_t Layer;
+
+struct Recti {
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+};
+
+struct Rectf {
+ float left;
+ float top;
+ float right;
+ float bottom;
+};
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_DVR_HARDWARE_COMPOSER_DEFS_H