1bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai#include "include/dvr/dvr_surface.h"
2bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai
32251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <inttypes.h>
42251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
5bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai#include <private/dvr/display_client.h>
6bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai
72251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include "dvr_internal.h"
8bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai
92251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::display::DisplayClient;
102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::display::Surface;
112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::display::SurfaceAttributes;
122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::display::SurfaceAttributeValue;
132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::CreateDvrReadBufferFromBufferConsumer;
142251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::dvr::CreateDvrWriteBufferQueueFromProducerQueue;
152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakanamespace {
172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
182251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakabool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                              size_t attribute_count,
202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                              SurfaceAttributes* surface_attributes,
212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                              size_t* error_index) {
222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  for (size_t i = 0; i < attribute_count; i++) {
232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    SurfaceAttributeValue value;
242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    switch (attributes[i].value.type) {
252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.int32_value;
272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.int64_value;
302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.bool_value;
332251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.float_value;
362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.float2_value;
392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.float3_value;
422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.float4_value;
452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.float8_value;
482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        value = attributes[i].value.float16_value;
512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        break;
522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      default:
532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        *error_index = i;
542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        return false;
552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    }
562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    surface_attributes->emplace(attributes[i].key, value);
582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  }
592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return true;
612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka}
622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka}  // anonymous namespace
6474cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai
65bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Caiextern "C" {
66bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai
672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakastruct DvrSurface {
682251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  std::unique_ptr<Surface> surface;
692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka};
702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaint dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                     size_t attribute_count, DvrSurface** out_surface) {
7374cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  if (out_surface == nullptr) {
742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
7574cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai    return -EINVAL;
7674cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  }
7774cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai
782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  size_t error_index;
792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  SurfaceAttributes surface_attributes;
802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!ConvertSurfaceAttributes(attributes, attribute_count,
812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                                &surface_attributes, &error_index)) {
822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          attributes[error_index].value.type);
842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return -EINVAL;
852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  }
862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto status = Surface::CreateSurface(surface_attributes);
882251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!status) {
892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          status.GetErrorMessage().c_str());
912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return -status.error();
9274cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  }
9374cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai
942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  *out_surface = new DvrSurface{status.take()};
952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return 0;
962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka}
972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaint dvrSurfaceGetId(DvrSurface* surface) {
1012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return surface->surface->surface_id();
1022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka}
1032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaint dvrSurfaceSetAttributes(DvrSurface* surface,
1052251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                            const DvrSurfaceAttribute* attributes,
1062251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                            size_t attribute_count) {
1072251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (surface == nullptr || attributes == nullptr) {
1082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE(
1092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
1102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        "attribute_count=%zu",
1112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        surface, attributes, attribute_count);
1122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return -EINVAL;
1132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  }
1142251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  size_t error_index;
1162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  SurfaceAttributes surface_attributes;
1172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!ConvertSurfaceAttributes(attributes, attribute_count,
1182251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                                &surface_attributes, &error_index)) {
1192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
1202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          attributes[error_index].value.type);
1212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return -EINVAL;
1222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  }
1232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto status = surface->surface->SetAttributes(surface_attributes);
1252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!status) {
1262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
1272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          status.GetErrorMessage().c_str());
1282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return -status.error();
1292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  }
13074cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai
13174cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  return 0;
13274cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai}
13374cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai
1342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaint dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
1352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                                     uint32_t height, uint32_t format,
136108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar                                     uint32_t layer_count, uint64_t usage,
137108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar                                     size_t capacity,
1382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka                                     DvrWriteBufferQueue** out_writer) {
13974cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  if (surface == nullptr || out_writer == nullptr) {
14074cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai    ALOGE(
1412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
14274cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai        "out_writer=%p.",
14374cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai        surface, out_writer);
14474cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai    return -EINVAL;
14574cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  }
1462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
147108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar  auto status = surface->surface->CreateQueue(width, height, layer_count,
148108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar                                              format, usage, capacity);
1492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!status) {
1502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
1512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          status.GetErrorMessage().c_str());
1522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return -status.error();
15374cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  }
15474cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai
1552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  *out_writer = CreateDvrWriteBufferQueueFromProducerQueue(status.take());
15674cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai  return 0;
15774cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai}
15874cf084cab653537e89f46b90344b3133a94b3a3Jiwen 'Steve' Cai
159eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaarint dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) {
1602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto client = DisplayClient::Create();
161bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai  if (!client) {
162eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar    ALOGE("dvrGetNamedBuffer: Failed to create display client!");
163bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai    return -ECOMM;
164bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai  }
165bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai
166eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar  if (out_buffer == nullptr || name == nullptr) {
167eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar    ALOGE("dvrGetNamedBuffer: Invalid inputs: name=%p, out_buffer=%p.", name,
168eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar          out_buffer);
169eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar    return -EINVAL;
170eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar  }
171eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar
1722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto status = client->GetNamedBuffer(name);
1732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!status) {
1742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("dvrGetNamedBuffer: Failed to find named buffer name=%s: %s", name,
1752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          status.GetErrorMessage().c_str());
1762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return -status.error();
177eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar  }
1782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
179bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai  return 0;
180bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai}
181bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai
182bdcee79b0d7e87cb48049907a7ba8201d0288f75Jiwen 'Steve' Cai}  // extern "C"
183