Home | History | Annotate | Download | only in libdvr
      1 #include "include/dvr/dvr_surface.h"
      2 
      3 #include <inttypes.h>
      4 
      5 #include <private/dvr/display_client.h>
      6 
      7 #include "dvr_internal.h"
      8 
      9 using android::dvr::display::DisplayClient;
     10 using android::dvr::display::Surface;
     11 using android::dvr::display::SurfaceAttributes;
     12 using android::dvr::display::SurfaceAttributeValue;
     13 using android::dvr::CreateDvrReadBufferFromBufferConsumer;
     14 using android::dvr::CreateDvrWriteBufferQueueFromProducerQueue;
     15 
     16 namespace {
     17 
     18 bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
     19                               size_t attribute_count,
     20                               SurfaceAttributes* surface_attributes,
     21                               size_t* error_index) {
     22   for (size_t i = 0; i < attribute_count; i++) {
     23     SurfaceAttributeValue value;
     24     switch (attributes[i].value.type) {
     25       case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
     26         value = attributes[i].value.int32_value;
     27         break;
     28       case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
     29         value = attributes[i].value.int64_value;
     30         break;
     31       case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
     32         value = attributes[i].value.bool_value;
     33         break;
     34       case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
     35         value = attributes[i].value.float_value;
     36         break;
     37       case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
     38         value = attributes[i].value.float2_value;
     39         break;
     40       case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
     41         value = attributes[i].value.float3_value;
     42         break;
     43       case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
     44         value = attributes[i].value.float4_value;
     45         break;
     46       case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
     47         value = attributes[i].value.float8_value;
     48         break;
     49       case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
     50         value = attributes[i].value.float16_value;
     51         break;
     52       default:
     53         *error_index = i;
     54         return false;
     55     }
     56 
     57     surface_attributes->emplace(attributes[i].key, value);
     58   }
     59 
     60   return true;
     61 }
     62 
     63 }  // anonymous namespace
     64 
     65 extern "C" {
     66 
     67 struct DvrSurface {
     68   std::unique_ptr<Surface> surface;
     69 };
     70 
     71 int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
     72                      size_t attribute_count, DvrSurface** out_surface) {
     73   if (out_surface == nullptr) {
     74     ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
     75     return -EINVAL;
     76   }
     77 
     78   size_t error_index;
     79   SurfaceAttributes surface_attributes;
     80   if (!ConvertSurfaceAttributes(attributes, attribute_count,
     81                                 &surface_attributes, &error_index)) {
     82     ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
     83           attributes[error_index].value.type);
     84     return -EINVAL;
     85   }
     86 
     87   auto status = Surface::CreateSurface(surface_attributes);
     88   if (!status) {
     89     ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
     90           status.GetErrorMessage().c_str());
     91     return -status.error();
     92   }
     93 
     94   *out_surface = new DvrSurface{status.take()};
     95   return 0;
     96 }
     97 
     98 void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
     99 
    100 int dvrSurfaceGetId(DvrSurface* surface) {
    101   return surface->surface->surface_id();
    102 }
    103 
    104 int dvrSurfaceSetAttributes(DvrSurface* surface,
    105                             const DvrSurfaceAttribute* attributes,
    106                             size_t attribute_count) {
    107   if (surface == nullptr || attributes == nullptr) {
    108     ALOGE(
    109         "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
    110         "attribute_count=%zu",
    111         surface, attributes, attribute_count);
    112     return -EINVAL;
    113   }
    114 
    115   size_t error_index;
    116   SurfaceAttributes surface_attributes;
    117   if (!ConvertSurfaceAttributes(attributes, attribute_count,
    118                                 &surface_attributes, &error_index)) {
    119     ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
    120           attributes[error_index].value.type);
    121     return -EINVAL;
    122   }
    123 
    124   auto status = surface->surface->SetAttributes(surface_attributes);
    125   if (!status) {
    126     ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
    127           status.GetErrorMessage().c_str());
    128     return -status.error();
    129   }
    130 
    131   return 0;
    132 }
    133 
    134 int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
    135                                      uint32_t height, uint32_t format,
    136                                      uint32_t layer_count, uint64_t usage,
    137                                      size_t capacity,
    138                                      DvrWriteBufferQueue** out_writer) {
    139   if (surface == nullptr || out_writer == nullptr) {
    140     ALOGE(
    141         "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
    142         "out_writer=%p.",
    143         surface, out_writer);
    144     return -EINVAL;
    145   }
    146 
    147   auto status = surface->surface->CreateQueue(width, height, layer_count,
    148                                               format, usage, capacity);
    149   if (!status) {
    150     ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
    151           status.GetErrorMessage().c_str());
    152     return -status.error();
    153   }
    154 
    155   *out_writer = CreateDvrWriteBufferQueueFromProducerQueue(status.take());
    156   return 0;
    157 }
    158 
    159 int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) {
    160   auto client = DisplayClient::Create();
    161   if (!client) {
    162     ALOGE("dvrGetNamedBuffer: Failed to create display client!");
    163     return -ECOMM;
    164   }
    165 
    166   if (out_buffer == nullptr || name == nullptr) {
    167     ALOGE("dvrGetNamedBuffer: Invalid inputs: name=%p, out_buffer=%p.", name,
    168           out_buffer);
    169     return -EINVAL;
    170   }
    171 
    172   auto status = client->GetNamedBuffer(name);
    173   if (!status) {
    174     ALOGE("dvrGetNamedBuffer: Failed to find named buffer name=%s: %s", name,
    175           status.GetErrorMessage().c_str());
    176     return -status.error();
    177   }
    178   *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
    179   return 0;
    180 }
    181 
    182 }  // extern "C"
    183