#include "include/dvr/dvr_display_manager.h" #include #include #include #include #include #include #include "dvr_internal.h" #include "dvr_buffer_queue_internal.h" using android::dvr::ConsumerBuffer; using android::dvr::display::DisplayManagerClient; using android::dvr::display::SurfaceAttribute; using android::dvr::display::SurfaceAttributes; using android::dvr::display::SurfaceState; using android::pdx::rpc::EmptyVariant; namespace { // Extracts type and value from the attribute Variant and writes them into the // respective fields of DvrSurfaceAttribute. struct AttributeVisitor { DvrSurfaceAttribute* attribute; void operator()(int32_t value) { attribute->value.int32_value = value; attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32; } void operator()(int64_t value) { attribute->value.int64_value = value; attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64; } void operator()(bool value) { attribute->value.bool_value = value; attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL; } void operator()(float value) { attribute->value.float_value = value; attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT; } void operator()(const std::array& value) { std::copy(value.cbegin(), value.cend(), attribute->value.float2_value); attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2; } void operator()(const std::array& value) { std::copy(value.cbegin(), value.cend(), attribute->value.float3_value); attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3; } void operator()(const std::array& value) { std::copy(value.cbegin(), value.cend(), attribute->value.float4_value); attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4; } void operator()(const std::array& value) { std::copy(value.cbegin(), value.cend(), attribute->value.float8_value); attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8; } void operator()(const std::array& value) { std::copy(value.cbegin(), value.cend(), attribute->value.float16_value); attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16; } void operator()(EmptyVariant) { attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE; } }; size_t ConvertSurfaceAttributes(const SurfaceAttributes& surface_attributes, DvrSurfaceAttribute* attributes, size_t max_count) { size_t count = 0; for (const auto& attribute : surface_attributes) { if (count >= max_count) break; // Copy the key and extract the Variant value using a visitor. attributes[count].key = attribute.first; attribute.second.Visit(AttributeVisitor{&attributes[count]}); count++; } return count; } } // anonymous namespace extern "C" { struct DvrDisplayManager { std::unique_ptr client; }; struct DvrSurfaceState { std::vector state; }; int dvrDisplayManagerCreate(DvrDisplayManager** client_out) { if (!client_out) return -EINVAL; auto client = DisplayManagerClient::Create(); if (!client) { ALOGE("dvrDisplayManagerCreate: Failed to create display manager client!"); return -EIO; } *client_out = new DvrDisplayManager{std::move(client)}; return 0; } void dvrDisplayManagerDestroy(DvrDisplayManager* client) { delete client; } int dvrDisplayManagerGetEventFd(DvrDisplayManager* client) { if (!client) return -EINVAL; return client->client->event_fd(); } int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client, int in_events, int* out_events) { if (!client || !out_events) return -EINVAL; auto status = client->client->GetEventMask(in_events); if (!status) return -status.error(); *out_events = status.get(); return 0; } int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client, DvrSurfaceState* state) { if (!client || !state) return -EINVAL; auto status = client->client->GetSurfaceState(); if (!status) return -status.error(); state->state = status.take(); return 0; } int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client, int surface_id, int queue_id, DvrReadBufferQueue** queue_out) { if (!client || !queue_out) return -EINVAL; auto status = client->client->GetSurfaceQueue(surface_id, queue_id); if (!status) { ALOGE("dvrDisplayManagerGetReadBufferQueue: Failed to get queue: %s", status.GetErrorMessage().c_str()); return -status.error(); } *queue_out = new DvrReadBufferQueue(status.take()); return 0; } int dvrSurfaceStateCreate(DvrSurfaceState** surface_state_out) { if (!surface_state_out) return -EINVAL; *surface_state_out = new DvrSurfaceState{}; return 0; } void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state) { delete surface_state; } int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state, size_t* count_out) { if (!surface_state) return -EINVAL; *count_out = surface_state->state.size(); return 0; } int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state, size_t surface_index, DvrSurfaceUpdateFlags* flags_out) { if (!surface_state || surface_index >= surface_state->state.size()) return -EINVAL; *flags_out = surface_state->state[surface_index].update_flags; return 0; } int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state, size_t surface_index, int* surface_id_out) { if (!surface_state || surface_index >= surface_state->state.size()) return -EINVAL; *surface_id_out = surface_state->state[surface_index].surface_id; return 0; } int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state, size_t surface_index, int* process_id_out) { if (!surface_state || surface_index >= surface_state->state.size()) return -EINVAL; *process_id_out = surface_state->state[surface_index].process_id; return 0; } int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state, size_t surface_index, size_t* count_out) { if (!surface_state || surface_index >= surface_state->state.size()) return -EINVAL; *count_out = surface_state->state[surface_index].queue_ids.size(); return 0; } ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state, size_t surface_index, int* queue_ids, size_t max_count) { if (!surface_state || surface_index >= surface_state->state.size()) return -EINVAL; size_t i; const auto& state = surface_state->state[surface_index]; for (i = 0; i < std::min(max_count, state.queue_ids.size()); i++) { queue_ids[i] = state.queue_ids[i]; } return i; } int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state, size_t surface_index, int* z_order_out) { if (!surface_state || surface_index >= surface_state->state.size() || !z_order_out) { return -EINVAL; } *z_order_out = surface_state->state[surface_index].GetZOrder(); return 0; } int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state, size_t surface_index, bool* visible_out) { if (!surface_state || surface_index >= surface_state->state.size() || !visible_out) { return -EINVAL; } *visible_out = surface_state->state[surface_index].GetVisible(); return 0; } int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state, size_t surface_index, size_t* count_out) { if (!surface_state || surface_index >= surface_state->state.size() || !count_out) { return -EINVAL; } *count_out = surface_state->state[surface_index].surface_attributes.size(); return 0; } ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state, size_t surface_index, DvrSurfaceAttribute* attributes, size_t max_count) { if (!surface_state || surface_index >= surface_state->state.size() || !attributes) { return -EINVAL; } return ConvertSurfaceAttributes( surface_state->state[surface_index].surface_attributes, attributes, max_count); } } // extern "C"