Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba2ce39b authored by Daniel Nicoara's avatar Daniel Nicoara
Browse files

VR: Add dvr API for service apps connecting to VR HWC

Bug: 36050795
Test: Compiled
Change-Id: I447fe56f7585ed3774bdc3577389d1f9b8281e7c
parent aba4d01a
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -75,6 +75,31 @@ cc_binary {
  ],
}

cc_library_static {
  name: "libdvr_hwc",
  srcs: [
    "dvr_hardware_composer_client.cpp",
  ],
  static_libs: [
    "libvr_hwc-impl",
    // NOTE: This needs to be included after the *-impl lib otherwise the
    // symbols in the *-binder library get optimized out.
    "libvr_hwc-binder",
  ],
  shared_libs: [
    "libbase",
    "libbinder",
    "liblog",
    "libnativewindow",
    "libui",
    "libutils",
  ],
  export_include_dirs: ["private"],
  export_shared_lib_headers: [
    "libnativewindow",
  ],
}

cc_test {
  name: "vr_hwc_test",
  gtest: true,
+136 −0
Original line number Diff line number Diff line
#include "private/android/dvr_hardware_composer_client.h"

#include <android/dvr/IVrComposer.h>
#include <android/dvr/BnVrComposerCallback.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);
  ~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_;

  HwcCallback(const HwcCallback&) = delete;
  void operator=(const HwcCallback&) = delete;
};

HwcCallback::HwcCallback(DvrHwcOnFrameCallback callback)
    : callback_(callback) {}

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_(dvr_frame.release())));
  return android::binder::Status::ok();
}

}  // namespace

struct DvrHwcClient {
  android::sp<android::dvr::IVrComposer> composer;
  android::sp<HwcCallback> callback;
};

DvrHwcClient* dvrHwcCreateClient(DvrHwcOnFrameCallback callback) {
  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);
  android::binder::Status status = client->composer->registerObserver(
      client->callback);
  if (!status.isOk())
    return nullptr;

  return client.release();
}

void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
  delete frame;
}

Display dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
  return frame->frame.display_id;
}

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;
}
+62 −0
Original line number Diff line number Diff line
#ifndef VR_HARDWARE_COMPOSER_PRIVATE_ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
#define VR_HARDWARE_COMPOSER_PRIVATE_ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H

#include <android/dvr_hardware_composer_defs.h>
#include <android/hardware_buffer.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct DvrHwcClient DvrHwcClient;
typedef struct DvrHwcFrame DvrHwcFrame;

// Called when a new frame has arrived.
//
// @param frame New frame. Owned by the client.
// @return fence FD for the release of the last frame.
typedef int(*DvrHwcOnFrameCallback)(DvrHwcFrame* frame);

DvrHwcClient* dvrHwcCreateClient(DvrHwcOnFrameCallback callback);

// Called to free the frame information.
void dvrHwcFrameDestroy(DvrHwcFrame* frame);

Display dvrHwcFrameGetDisplayId(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  // VR_HARDWARE_COMPOSER_PRIVATE_ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
+50 −0
Original line number Diff line number Diff line
#ifndef VR_HARDWARE_COMPOSER_PRIVATE_ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
#define VR_HARDWARE_COMPOSER_PRIVATE_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  // VR_HARDWARE_COMPOSER_PRIVATE_ANDROID_DVR_HARDWARE_COMPOSER_DEFS_H