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