blob: c44f8a699fbe011210b0bfe54f4ef82d0a29234d [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 Tabaka99c2d732017-06-07 17:54:33 -07005#include <private/android/AHardwareBufferHelpers.h>
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -07006#include <private/dvr/display_client.h>
7
Jiwen 'Steve' Cai656f4062017-05-22 13:02:33 -07008#include "dvr_buffer_queue_internal.h"
Corey Tabaka99c2d732017-06-07 17:54:33 -07009#include "dvr_internal.h"
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -070010
Corey Tabaka99c2d732017-06-07 17:54:33 -070011using android::AHardwareBuffer_convertToGrallocUsageBits;
Corey Tabaka2251d822017-04-20 16:04:07 -070012using android::dvr::display::DisplayClient;
13using android::dvr::display::Surface;
14using android::dvr::display::SurfaceAttributes;
15using android::dvr::display::SurfaceAttributeValue;
16using android::dvr::CreateDvrReadBufferFromBufferConsumer;
Corey Tabaka2251d822017-04-20 16:04:07 -070017
18namespace {
19
20bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
21 size_t attribute_count,
22 SurfaceAttributes* surface_attributes,
23 size_t* error_index) {
24 for (size_t i = 0; i < attribute_count; i++) {
25 SurfaceAttributeValue value;
26 switch (attributes[i].value.type) {
27 case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
28 value = attributes[i].value.int32_value;
29 break;
30 case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
31 value = attributes[i].value.int64_value;
32 break;
33 case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
34 value = attributes[i].value.bool_value;
35 break;
36 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
37 value = attributes[i].value.float_value;
38 break;
39 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
40 value = attributes[i].value.float2_value;
41 break;
42 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
43 value = attributes[i].value.float3_value;
44 break;
45 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
46 value = attributes[i].value.float4_value;
47 break;
48 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
49 value = attributes[i].value.float8_value;
50 break;
51 case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
52 value = attributes[i].value.float16_value;
53 break;
54 default:
55 *error_index = i;
56 return false;
57 }
58
59 surface_attributes->emplace(attributes[i].key, value);
60 }
61
62 return true;
63}
64
65} // anonymous namespace
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070066
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -070067extern "C" {
68
Corey Tabaka2251d822017-04-20 16:04:07 -070069struct DvrSurface {
70 std::unique_ptr<Surface> surface;
71};
72
73int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
74 size_t attribute_count, DvrSurface** out_surface) {
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070075 if (out_surface == nullptr) {
Corey Tabaka2251d822017-04-20 16:04:07 -070076 ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070077 return -EINVAL;
78 }
79
Corey Tabaka2251d822017-04-20 16:04:07 -070080 size_t error_index;
81 SurfaceAttributes surface_attributes;
82 if (!ConvertSurfaceAttributes(attributes, attribute_count,
83 &surface_attributes, &error_index)) {
84 ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
85 attributes[error_index].value.type);
86 return -EINVAL;
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070087 }
88
Corey Tabaka2251d822017-04-20 16:04:07 -070089 auto status = Surface::CreateSurface(surface_attributes);
90 if (!status) {
91 ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
92 status.GetErrorMessage().c_str());
93 return -status.error();
94 }
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070095
Corey Tabaka2251d822017-04-20 16:04:07 -070096 *out_surface = new DvrSurface{status.take()};
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -070097 return 0;
98}
99
Corey Tabaka2251d822017-04-20 16:04:07 -0700100void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
101
102int dvrSurfaceGetId(DvrSurface* surface) {
103 return surface->surface->surface_id();
104}
105
106int dvrSurfaceSetAttributes(DvrSurface* surface,
107 const DvrSurfaceAttribute* attributes,
108 size_t attribute_count) {
109 if (surface == nullptr || attributes == nullptr) {
110 ALOGE(
111 "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
112 "attribute_count=%zu",
113 surface, attributes, attribute_count);
114 return -EINVAL;
115 }
116
117 size_t error_index;
118 SurfaceAttributes surface_attributes;
119 if (!ConvertSurfaceAttributes(attributes, attribute_count,
120 &surface_attributes, &error_index)) {
121 ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
122 attributes[error_index].value.type);
123 return -EINVAL;
124 }
125
126 auto status = surface->surface->SetAttributes(surface_attributes);
127 if (!status) {
128 ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
129 status.GetErrorMessage().c_str());
130 return -status.error();
131 }
132
133 return 0;
134}
135
136int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
137 uint32_t height, uint32_t format,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700138 uint32_t layer_count, uint64_t usage,
Jiwen 'Steve' Cai532e5292017-06-02 15:36:44 -0700139 size_t capacity, size_t metadata_size,
Corey Tabaka2251d822017-04-20 16:04:07 -0700140 DvrWriteBufferQueue** out_writer) {
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700141 if (surface == nullptr || out_writer == nullptr) {
142 ALOGE(
Corey Tabaka2251d822017-04-20 16:04:07 -0700143 "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700144 "out_writer=%p.",
145 surface, out_writer);
146 return -EINVAL;
147 }
Corey Tabaka2251d822017-04-20 16:04:07 -0700148
Corey Tabaka99c2d732017-06-07 17:54:33 -0700149 auto status = surface->surface->CreateQueue(
150 width, height, layer_count, format, usage, capacity, metadata_size);
Corey Tabaka2251d822017-04-20 16:04:07 -0700151 if (!status) {
152 ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
153 status.GetErrorMessage().c_str());
154 return -status.error();
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700155 }
156
Jiwen 'Steve' Cai656f4062017-05-22 13:02:33 -0700157 *out_writer = new DvrWriteBufferQueue(status.take());
Jiwen 'Steve' Cai74cf0842017-03-23 18:53:16 -0700158 return 0;
159}
160
Corey Tabaka99c2d732017-06-07 17:54:33 -0700161int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
162 DvrBuffer** buffer_out) {
163 if (!buffer_out)
164 return -EINVAL;
165
166 int error;
167 auto client = DisplayClient::Create(&error);
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700168 if (!client) {
Corey Tabaka99c2d732017-06-07 17:54:33 -0700169 ALOGE("dvrSetupGlobalBuffer: Failed to create display client: %s",
170 strerror(-error));
171 return error;
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700172 }
173
Corey Tabaka99c2d732017-06-07 17:54:33 -0700174 uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
175
176 auto buffer_status = client->SetupGlobalBuffer(key, size, gralloc_usage);
177 if (!buffer_status) {
178 ALOGE("dvrSetupGlobalBuffer: Failed to setup global buffer: %s",
179 buffer_status.GetErrorMessage().c_str());
180 return -buffer_status.error();
181 }
182
183 *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take());
184 return 0;
185}
186
187int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key) {
188 int error;
189 auto client = DisplayClient::Create(&error);
190 if (!client) {
191 ALOGE("dvrDeleteGlobalBuffer: Failed to create display client: %s",
192 strerror(-error));
193 return error;
194 }
195
196 auto buffer_status = client->DeleteGlobalBuffer(key);
197 if (!buffer_status) {
198 ALOGE("dvrDeleteGlobalBuffer: Failed to delete named buffer: %s",
199 buffer_status.GetErrorMessage().c_str());
200 return -buffer_status.error();
201 }
202
203 return 0;
204}
205
206int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) {
207 if (!out_buffer)
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700208 return -EINVAL;
Corey Tabaka99c2d732017-06-07 17:54:33 -0700209
210 int error;
211 auto client = DisplayClient::Create(&error);
212 if (!client) {
213 ALOGE("dvrGetGlobalBuffer: Failed to create display client: %s",
214 strerror(-error));
215 return error;
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700216 }
217
Okan Arikan36d23802017-05-15 15:20:39 -0700218 auto status = client->GetGlobalBuffer(key);
Corey Tabaka2251d822017-04-20 16:04:07 -0700219 if (!status) {
Corey Tabaka2251d822017-04-20 16:04:07 -0700220 return -status.error();
Hendrik Wagenaareaa55222017-04-06 10:56:23 -0700221 }
Corey Tabaka2251d822017-04-20 16:04:07 -0700222 *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700223 return 0;
224}
225
Stephen Kiazykc6033312017-06-09 14:26:31 -0700226int dvrGetNativeDisplayMetrics(size_t sizeof_metrics,
227 DvrNativeDisplayMetrics* metrics) {
228 ALOGE_IF(sizeof_metrics != sizeof(DvrNativeDisplayMetrics),
229 "dvrGetNativeDisplayMetrics: metrics struct mismatch, your dvr api "
230 "header is out of date.");
231
232 auto client = DisplayClient::Create();
233 if (!client) {
234 ALOGE("dvrGetNativeDisplayMetrics: Failed to create display client!");
235 return -ECOMM;
236 }
237
238 if (metrics == nullptr) {
239 ALOGE("dvrGetNativeDisplayMetrics: output metrics buffer must be non-null");
240 return -EINVAL;
241 }
242
243 auto status = client->GetDisplayMetrics();
244
245 if (!status) {
246 return -status.error();
247 }
248
249 if (sizeof_metrics >= 20) {
250 metrics->display_width = status.get().display_width;
251 metrics->display_height = status.get().display_height;
252 metrics->display_x_dpi = status.get().display_x_dpi;
253 metrics->display_y_dpi = status.get().display_y_dpi;
254 metrics->vsync_period_ns = status.get().vsync_period_ns;
255 }
256
257 return 0;
258}
259
Jiwen 'Steve' Caibdcee792017-03-22 16:59:53 -0700260} // extern "C"