• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ConvertSurfaceAttributes(const DvrSurfaceAttribute * attributes,size_t attribute_count,SurfaceAttributes * surface_attributes,size_t * error_index)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 
dvrSurfaceCreate(const DvrSurfaceAttribute * attributes,size_t attribute_count,DvrSurface ** out_surface)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 
dvrSurfaceDestroy(DvrSurface * surface)98 void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
99 
dvrSurfaceGetId(DvrSurface * surface)100 int dvrSurfaceGetId(DvrSurface* surface) {
101   return surface->surface->surface_id();
102 }
103 
dvrSurfaceSetAttributes(DvrSurface * surface,const DvrSurfaceAttribute * attributes,size_t attribute_count)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 
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)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 
dvrGetNamedBuffer(const char * name,DvrBuffer ** out_buffer)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