blob: 30f25e32aa81b650ab752e9a331d187adf45f0e5 [file] [log] [blame]
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -07001#include "include/dvr/dvr_surface.h"
2
Corey Tabaka2251d822017-04-20 16:04:07 -07003#include <inttypes.h>
4
Corey Tabaka49a706d2017-06-08 14:29:58 -07005#include <pdx/rpc/variant.h>
Corey Tabaka99c2d732017-06-07 17:54:33 -07006#include <private/android/AHardwareBufferHelpers.h>
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -07007#include <private/dvr/display_client.h>
8
Jiwen 'Steve' Cai656f4062017-05-22 13:02:33 -07009#include "dvr_buffer_queue_internal.h"
Corey Tabaka99c2d732017-06-07 17:54:33 -070010#include "dvr_internal.h"
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -070011
Corey Tabaka99c2d732017-06-07 17:54:33 -070012using android::AHardwareBuffer_convertToGrallocUsageBits;
Corey Tabaka2251d822017-04-20 16:04:07 -070013using android::dvr::display::DisplayClient;
14using android::dvr::display::Surface;
15using android::dvr::display::SurfaceAttributes;
16using android::dvr::display::SurfaceAttributeValue;
17using android::dvr::CreateDvrReadBufferFromBufferConsumer;
Corey Tabaka49a706d2017-06-08 14:29:58 -070018using android::pdx::rpc::EmptyVariant;
Corey Tabaka2251d822017-04-20 16:04:07 -070019
20namespace {
21
22bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
23 size_t attribute_count,
24 SurfaceAttributes* surface_attributes,
25 size_t* error_index) {
26 for (size_t i = 0; i < attribute_count; i++) {
27 SurfaceAttributeValue value;
28 switch (attributes[i].value.type) {
29 case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
30 value = attributes[i].value.int32_value;
31 break;
32 case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
33 value = attributes[i].value.int64_value;
34 break;
35 case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
36 value = attributes[i].value.bool_value;
37 break;
38 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
39 value = attributes[i].value.float_value;
40 break;
41 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
42 value = attributes[i].value.float2_value;
43 break;
44 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
45 value = attributes[i].value.float3_value;
46 break;
47 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
48 value = attributes[i].value.float4_value;
49 break;
50 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
51 value = attributes[i].value.float8_value;
52 break;
53 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
54 value = attributes[i].value.float16_value;
55 break;
Corey Tabaka49a706d2017-06-08 14:29:58 -070056 case DVR_SURFACE_ATTRIBUTE_TYPE_NONE:
57 value = EmptyVariant{};
58 break;
Corey Tabaka2251d822017-04-20 16:04:07 -070059 default:
60 *error_index = i;
61 return false;
62 }
63
64 surface_attributes->emplace(attributes[i].key, value);
65 }
66
67 return true;
68}
69
70} // anonymous namespace
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070071
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -070072extern "C" {
73
Corey Tabaka2251d822017-04-20 16:04:07 -070074struct DvrSurface {
75 std::unique_ptr<Surface> surface;
76};
77
78int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
79 size_t attribute_count, DvrSurface** out_surface) {
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070080 if (out_surface == nullptr) {
Corey Tabaka2251d822017-04-20 16:04:07 -070081 ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070082 return -EINVAL;
83 }
84
Corey Tabaka2251d822017-04-20 16:04:07 -070085 size_t error_index;
86 SurfaceAttributes surface_attributes;
87 if (!ConvertSurfaceAttributes(attributes, attribute_count,
88 &surface_attributes, &error_index)) {
89 ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
90 attributes[error_index].value.type);
91 return -EINVAL;
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070092 }
93
Corey Tabaka2251d822017-04-20 16:04:07 -070094 auto status = Surface::CreateSurface(surface_attributes);
95 if (!status) {
96 ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
97 status.GetErrorMessage().c_str());
98 return -status.error();
99 }
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700100
Corey Tabaka2251d822017-04-20 16:04:07 -0700101 *out_surface = new DvrSurface{status.take()};
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700102 return 0;
103}
104
Corey Tabaka2251d822017-04-20 16:04:07 -0700105void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
106
107int dvrSurfaceGetId(DvrSurface* surface) {
108 return surface->surface->surface_id();
109}
110
111int dvrSurfaceSetAttributes(DvrSurface* surface,
112 const DvrSurfaceAttribute* attributes,
113 size_t attribute_count) {
114 if (surface == nullptr || attributes == nullptr) {
115 ALOGE(
116 "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
117 "attribute_count=%zu",
118 surface, attributes, attribute_count);
119 return -EINVAL;
120 }
121
122 size_t error_index;
123 SurfaceAttributes surface_attributes;
124 if (!ConvertSurfaceAttributes(attributes, attribute_count,
125 &surface_attributes, &error_index)) {
126 ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
127 attributes[error_index].value.type);
128 return -EINVAL;
129 }
130
131 auto status = surface->surface->SetAttributes(surface_attributes);
132 if (!status) {
133 ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
134 status.GetErrorMessage().c_str());
135 return -status.error();
136 }
137
138 return 0;
139}
140
141int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
142 uint32_t height, uint32_t format,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700143 uint32_t layer_count, uint64_t usage,
Jiwen 'Steve' Cai532e5292017-06-02 15:36:44 -0700144 size_t capacity, size_t metadata_size,
Corey Tabaka2251d822017-04-20 16:04:07 -0700145 DvrWriteBufferQueue** out_writer) {
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700146 if (surface == nullptr || out_writer == nullptr) {
147 ALOGE(
Corey Tabaka2251d822017-04-20 16:04:07 -0700148 "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700149 "out_writer=%p.",
150 surface, out_writer);
151 return -EINVAL;
152 }
Corey Tabaka2251d822017-04-20 16:04:07 -0700153
Corey Tabaka99c2d732017-06-07 17:54:33 -0700154 auto status = surface->surface->CreateQueue(
155 width, height, layer_count, format, usage, capacity, metadata_size);
Corey Tabaka2251d822017-04-20 16:04:07 -0700156 if (!status) {
157 ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
158 status.GetErrorMessage().c_str());
159 return -status.error();
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700160 }
161
Jiwen 'Steve' Cai656f4062017-05-22 13:02:33 -0700162 *out_writer = new DvrWriteBufferQueue(status.take());
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700163 return 0;
164}
165
Corey Tabaka99c2d732017-06-07 17:54:33 -0700166int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
167 DvrBuffer** buffer_out) {
168 if (!buffer_out)
169 return -EINVAL;
170
171 int error;
172 auto client = DisplayClient::Create(&error);
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700173 if (!client) {
Corey Tabaka99c2d732017-06-07 17:54:33 -0700174 ALOGE("dvrSetupGlobalBuffer: Failed to create display client: %s",
175 strerror(-error));
176 return error;
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700177 }
178
Corey Tabaka99c2d732017-06-07 17:54:33 -0700179 uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
180
181 auto buffer_status = client->SetupGlobalBuffer(key, size, gralloc_usage);
182 if (!buffer_status) {
183 ALOGE("dvrSetupGlobalBuffer: Failed to setup global buffer: %s",
184 buffer_status.GetErrorMessage().c_str());
185 return -buffer_status.error();
186 }
187
188 *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take());
189 return 0;
190}
191
192int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key) {
193 int error;
194 auto client = DisplayClient::Create(&error);
195 if (!client) {
196 ALOGE("dvrDeleteGlobalBuffer: Failed to create display client: %s",
197 strerror(-error));
198 return error;
199 }
200
201 auto buffer_status = client->DeleteGlobalBuffer(key);
202 if (!buffer_status) {
203 ALOGE("dvrDeleteGlobalBuffer: Failed to delete named buffer: %s",
204 buffer_status.GetErrorMessage().c_str());
205 return -buffer_status.error();
206 }
207
208 return 0;
209}
210
211int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) {
212 if (!out_buffer)
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700213 return -EINVAL;
Corey Tabaka99c2d732017-06-07 17:54:33 -0700214
215 int error;
216 auto client = DisplayClient::Create(&error);
217 if (!client) {
218 ALOGE("dvrGetGlobalBuffer: Failed to create display client: %s",
219 strerror(-error));
220 return error;
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700221 }
222
Okan Arikan36d23802017-05-15 15:20:39 -0700223 auto status = client->GetGlobalBuffer(key);
Corey Tabaka2251d822017-04-20 16:04:07 -0700224 if (!status) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700225 return -status.error();
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700226 }
Corey Tabaka2251d822017-04-20 16:04:07 -0700227 *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700228 return 0;
229}
230
Stephen Kiazykc6033312017-06-09 14:26:31 -0700231int dvrGetNativeDisplayMetrics(size_t sizeof_metrics,
232 DvrNativeDisplayMetrics* metrics) {
233 ALOGE_IF(sizeof_metrics != sizeof(DvrNativeDisplayMetrics),
234 "dvrGetNativeDisplayMetrics: metrics struct mismatch, your dvr api "
235 "header is out of date.");
236
237 auto client = DisplayClient::Create();
238 if (!client) {
239 ALOGE("dvrGetNativeDisplayMetrics: Failed to create display client!");
240 return -ECOMM;
241 }
242
243 if (metrics == nullptr) {
244 ALOGE("dvrGetNativeDisplayMetrics: output metrics buffer must be non-null");
245 return -EINVAL;
246 }
247
248 auto status = client->GetDisplayMetrics();
249
250 if (!status) {
251 return -status.error();
252 }
253
254 if (sizeof_metrics >= 20) {
255 metrics->display_width = status.get().display_width;
256 metrics->display_height = status.get().display_height;
257 metrics->display_x_dpi = status.get().display_x_dpi;
258 metrics->display_y_dpi = status.get().display_y_dpi;
259 metrics->vsync_period_ns = status.get().vsync_period_ns;
260 }
261
262 return 0;
263}
264
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700265} // extern "C"