| #include "include/dvr/dvr_display_manager.h" | |
| #include <dvr/dvr_buffer.h> | |
| #include <pdx/rpc/variant.h> | |
| #include <private/dvr/buffer_hub_client.h> | |
| #include <private/dvr/buffer_hub_queue_client.h> | |
| #include <private/dvr/display_client.h> | |
| #include <private/dvr/display_manager_client.h> | |
| #include "dvr_internal.h" | |
| #include "dvr_buffer_queue_internal.h" | |
| using android::dvr::BufferConsumer; | |
| using android::dvr::display::DisplayManagerClient; | |
| using android::dvr::display::SurfaceAttributes; | |
| using android::dvr::display::SurfaceAttribute; | |
| 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<float, 2>& value) { | |
| std::copy(value.cbegin(), value.cend(), attribute->value.float2_value); | |
| attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2; | |
| } | |
| void operator()(const std::array<float, 3>& value) { | |
| std::copy(value.cbegin(), value.cend(), attribute->value.float3_value); | |
| attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3; | |
| } | |
| void operator()(const std::array<float, 4>& value) { | |
| std::copy(value.cbegin(), value.cend(), attribute->value.float4_value); | |
| attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4; | |
| } | |
| void operator()(const std::array<float, 8>& value) { | |
| std::copy(value.cbegin(), value.cend(), attribute->value.float8_value); | |
| attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8; | |
| } | |
| void operator()(const std::array<float, 16>& 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<DisplayManagerClient> client; | |
| }; | |
| struct DvrSurfaceState { | |
| std::vector<SurfaceState> 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" |