#include "include/dvr/dvr_surface.h" #include #include #include "dvr_internal.h" using android::dvr::display::DisplayClient; using android::dvr::display::Surface; using android::dvr::display::SurfaceAttributes; using android::dvr::display::SurfaceAttributeValue; using android::dvr::CreateDvrReadBufferFromBufferConsumer; using android::dvr::CreateDvrWriteBufferQueueFromProducerQueue; namespace { bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes, size_t attribute_count, SurfaceAttributes* surface_attributes, size_t* error_index) { for (size_t i = 0; i < attribute_count; i++) { SurfaceAttributeValue value; switch (attributes[i].value.type) { case DVR_SURFACE_ATTRIBUTE_TYPE_INT32: value = attributes[i].value.int32_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_INT64: value = attributes[i].value.int64_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL: value = attributes[i].value.bool_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT: value = attributes[i].value.float_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2: value = attributes[i].value.float2_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3: value = attributes[i].value.float3_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4: value = attributes[i].value.float4_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8: value = attributes[i].value.float8_value; break; case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16: value = attributes[i].value.float16_value; break; default: *error_index = i; return false; } surface_attributes->emplace(attributes[i].key, value); } return true; } } // anonymous namespace extern "C" { struct DvrSurface { std::unique_ptr surface; }; int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes, size_t attribute_count, DvrSurface** out_surface) { if (out_surface == nullptr) { ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface); return -EINVAL; } size_t error_index; SurfaceAttributes surface_attributes; if (!ConvertSurfaceAttributes(attributes, attribute_count, &surface_attributes, &error_index)) { ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64, attributes[error_index].value.type); return -EINVAL; } auto status = Surface::CreateSurface(surface_attributes); if (!status) { ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s", status.GetErrorMessage().c_str()); return -status.error(); } *out_surface = new DvrSurface{status.take()}; return 0; } void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; } int dvrSurfaceGetId(DvrSurface* surface) { return surface->surface->surface_id(); } int dvrSurfaceSetAttributes(DvrSurface* surface, const DvrSurfaceAttribute* attributes, size_t attribute_count) { if (surface == nullptr || attributes == nullptr) { ALOGE( "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p " "attribute_count=%zu", surface, attributes, attribute_count); return -EINVAL; } size_t error_index; SurfaceAttributes surface_attributes; if (!ConvertSurfaceAttributes(attributes, attribute_count, &surface_attributes, &error_index)) { ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64, attributes[error_index].value.type); return -EINVAL; } auto status = surface->surface->SetAttributes(surface_attributes); if (!status) { ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s", status.GetErrorMessage().c_str()); return -status.error(); } return 0; } int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width, uint32_t height, uint32_t format, uint32_t layer_count, uint64_t usage, size_t capacity, DvrWriteBufferQueue** out_writer) { if (surface == nullptr || out_writer == nullptr) { ALOGE( "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, " "out_writer=%p.", surface, out_writer); return -EINVAL; } auto status = surface->surface->CreateQueue(width, height, layer_count, format, usage, capacity); if (!status) { ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s", status.GetErrorMessage().c_str()); return -status.error(); } *out_writer = CreateDvrWriteBufferQueueFromProducerQueue(status.take()); return 0; } int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) { auto client = DisplayClient::Create(); if (!client) { ALOGE("dvrGetNamedBuffer: Failed to create display client!"); return -ECOMM; } if (out_buffer == nullptr || name == nullptr) { ALOGE("dvrGetNamedBuffer: Invalid inputs: name=%p, out_buffer=%p.", name, out_buffer); return -EINVAL; } auto status = client->GetNamedBuffer(name); if (!status) { ALOGE("dvrGetNamedBuffer: Failed to find named buffer name=%s: %s", name, status.GetErrorMessage().c_str()); return -status.error(); } *out_buffer = CreateDvrBufferFromIonBuffer(status.take()); return 0; } } // extern "C"