blob: f34d61fe4982c86769485d13c5d46e8c9aa15555 [file] [log] [blame]
#ifndef ANDROID_DVR_DISPLAY_PROTOCOL_H_
#define ANDROID_DVR_DISPLAY_PROTOCOL_H_
#include <sys/types.h>
#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>
// RPC protocol definitions for DVR display services (VrFlinger).
namespace android {
namespace dvr {
namespace display {
// 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 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(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);
};
// 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;
};
// 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, 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,
};
SurfaceAttribute() : Base{Invalid} {}
using Base::Base;
};
// Collection of surface attribute key/value pairs.
using SurfaceAttributes = std::map<SurfaceAttributeKey, SurfaceAttributeValue>;
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 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;
}
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:
PDX_SERIALIZABLE_MEMBERS(SurfaceInfo, surface_id, visible, z_order);
};
struct DisplayProtocol {
// Service path.
static constexpr char kClientPath[] = "system/vr/display/client";
// Op codes.
enum {
kOpGetMetrics = 0,
kOpGetNamedBuffer,
kOpIsVrAppRunning,
kOpCreateSurface,
kOpGetSurfaceInfo,
kOpCreateQueue,
kOpSetAttributes,
};
// Aliases.
using LocalChannelHandle = pdx::LocalChannelHandle;
using Void = pdx::rpc::Void;
// Methods.
PDX_REMOTE_METHOD(GetMetrics, kOpGetMetrics, Metrics(Void));
PDX_REMOTE_METHOD(GetNamedBuffer, kOpGetNamedBuffer,
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 DisplayManagerProtocol {
// Service path.
static constexpr char kClientPath[] = "system/vr/display/manager";
// Op codes.
enum {
kOpGetSurfaceState = 0,
kOpGetSurfaceQueue,
kOpSetupNamedBuffer,
};
// Aliases.
using LocalChannelHandle = pdx::LocalChannelHandle;
using Void = pdx::rpc::Void;
// Methods.
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 VSyncSchedInfo {
int64_t vsync_period_ns;
int64_t timestamp_ns;
uint32_t next_vsync_count;
private:
PDX_SERIALIZABLE_MEMBERS(VSyncSchedInfo, vsync_period_ns, timestamp_ns,
next_vsync_count);
};
struct VSyncProtocol {
// Service path.
static constexpr char kClientPath[] = "system/vr/display/vsync";
// Op codes.
enum {
kOpWait = 0,
kOpAck,
kOpGetLastTimestamp,
kOpGetSchedInfo,
kOpAcknowledge,
};
// Aliases.
using Void = pdx::rpc::Void;
using Timestamp = int64_t;
// Methods.
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, void(Void));
};
} // namespace display
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_DISPLAY_PROTOCOL_H_