1#include "include/dvr/dvr_display_manager.h"
2
3#include <dvr/dvr_buffer.h>
4#include <pdx/rpc/variant.h>
5#include <private/dvr/buffer_hub_client.h>
6#include <private/dvr/buffer_hub_queue_client.h>
7#include <private/dvr/display_client.h>
8#include <private/dvr/display_manager_client.h>
9
10#include "dvr_internal.h"
11#include "dvr_buffer_queue_internal.h"
12
13using android::dvr::BufferConsumer;
14using android::dvr::display::DisplayManagerClient;
15using android::dvr::display::SurfaceAttributes;
16using android::dvr::display::SurfaceAttribute;
17using android::dvr::display::SurfaceState;
18using android::pdx::rpc::EmptyVariant;
19
20namespace {
21
22// Extracts type and value from the attribute Variant and writes them into the
23// respective fields of DvrSurfaceAttribute.
24struct AttributeVisitor {
25  DvrSurfaceAttribute* attribute;
26
27  void operator()(int32_t value) {
28    attribute->value.int32_value = value;
29    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
30  }
31  void operator()(int64_t value) {
32    attribute->value.int64_value = value;
33    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
34  }
35  void operator()(bool value) {
36    attribute->value.bool_value = value;
37    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
38  }
39  void operator()(float value) {
40    attribute->value.float_value = value;
41    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
42  }
43  void operator()(const std::array<float, 2>& value) {
44    std::copy(value.cbegin(), value.cend(), attribute->value.float2_value);
45    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
46  }
47  void operator()(const std::array<float, 3>& value) {
48    std::copy(value.cbegin(), value.cend(), attribute->value.float3_value);
49    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
50  }
51  void operator()(const std::array<float, 4>& value) {
52    std::copy(value.cbegin(), value.cend(), attribute->value.float4_value);
53    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
54  }
55  void operator()(const std::array<float, 8>& value) {
56    std::copy(value.cbegin(), value.cend(), attribute->value.float8_value);
57    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
58  }
59  void operator()(const std::array<float, 16>& value) {
60    std::copy(value.cbegin(), value.cend(), attribute->value.float16_value);
61    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
62  }
63  void operator()(EmptyVariant) {
64    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
65  }
66};
67
68size_t ConvertSurfaceAttributes(const SurfaceAttributes& surface_attributes,
69                                DvrSurfaceAttribute* attributes,
70                                size_t max_count) {
71  size_t count = 0;
72  for (const auto& attribute : surface_attributes) {
73    if (count >= max_count)
74      break;
75
76    // Copy the key and extract the Variant value using a visitor.
77    attributes[count].key = attribute.first;
78    attribute.second.Visit(AttributeVisitor{&attributes[count]});
79    count++;
80  }
81
82  return count;
83}
84
85}  // anonymous namespace
86
87extern "C" {
88
89struct DvrDisplayManager {
90  std::unique_ptr<DisplayManagerClient> client;
91};
92
93struct DvrSurfaceState {
94  std::vector<SurfaceState> state;
95};
96
97int dvrDisplayManagerCreate(DvrDisplayManager** client_out) {
98  if (!client_out)
99    return -EINVAL;
100
101  auto client = DisplayManagerClient::Create();
102  if (!client) {
103    ALOGE("dvrDisplayManagerCreate: Failed to create display manager client!");
104    return -EIO;
105  }
106
107  *client_out = new DvrDisplayManager{std::move(client)};
108  return 0;
109}
110
111void dvrDisplayManagerDestroy(DvrDisplayManager* client) { delete client; }
112
113int dvrDisplayManagerGetEventFd(DvrDisplayManager* client) {
114  if (!client)
115    return -EINVAL;
116
117  return client->client->event_fd();
118}
119
120int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
121                                             int in_events, int* out_events) {
122  if (!client || !out_events)
123    return -EINVAL;
124
125  auto status = client->client->GetEventMask(in_events);
126  if (!status)
127    return -status.error();
128
129  *out_events = status.get();
130  return 0;
131}
132
133int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
134                                     DvrSurfaceState* state) {
135  if (!client || !state)
136    return -EINVAL;
137
138  auto status = client->client->GetSurfaceState();
139  if (!status)
140    return -status.error();
141
142  state->state = status.take();
143  return 0;
144}
145
146int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
147                                        int surface_id, int queue_id,
148                                        DvrReadBufferQueue** queue_out) {
149  if (!client || !queue_out)
150    return -EINVAL;
151
152  auto status = client->client->GetSurfaceQueue(surface_id, queue_id);
153  if (!status) {
154    ALOGE("dvrDisplayManagerGetReadBufferQueue: Failed to get queue: %s",
155          status.GetErrorMessage().c_str());
156    return -status.error();
157  }
158
159  *queue_out = new DvrReadBufferQueue(status.take());
160  return 0;
161}
162
163int dvrSurfaceStateCreate(DvrSurfaceState** surface_state_out) {
164  if (!surface_state_out)
165    return -EINVAL;
166
167  *surface_state_out = new DvrSurfaceState{};
168  return 0;
169}
170
171void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state) {
172  delete surface_state;
173}
174
175int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
176                                   size_t* count_out) {
177  if (!surface_state)
178    return -EINVAL;
179
180  *count_out = surface_state->state.size();
181  return 0;
182}
183
184int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
185                                  size_t surface_index,
186                                  DvrSurfaceUpdateFlags* flags_out) {
187  if (!surface_state || surface_index >= surface_state->state.size())
188    return -EINVAL;
189
190  *flags_out = surface_state->state[surface_index].update_flags;
191  return 0;
192}
193
194int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
195                                size_t surface_index, int* surface_id_out) {
196  if (!surface_state || surface_index >= surface_state->state.size())
197    return -EINVAL;
198
199  *surface_id_out = surface_state->state[surface_index].surface_id;
200  return 0;
201}
202
203int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
204                                size_t surface_index, int* process_id_out) {
205  if (!surface_state || surface_index >= surface_state->state.size())
206    return -EINVAL;
207
208  *process_id_out = surface_state->state[surface_index].process_id;
209  return 0;
210}
211
212int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
213                                 size_t surface_index, size_t* count_out) {
214  if (!surface_state || surface_index >= surface_state->state.size())
215    return -EINVAL;
216
217  *count_out = surface_state->state[surface_index].queue_ids.size();
218  return 0;
219}
220
221ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
222                                   size_t surface_index, int* queue_ids,
223                                   size_t max_count) {
224  if (!surface_state || surface_index >= surface_state->state.size())
225    return -EINVAL;
226
227  size_t i;
228  const auto& state = surface_state->state[surface_index];
229  for (i = 0; i < std::min(max_count, state.queue_ids.size()); i++) {
230    queue_ids[i] = state.queue_ids[i];
231  }
232
233  return i;
234}
235
236int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
237                             size_t surface_index, int* z_order_out) {
238  if (!surface_state || surface_index >= surface_state->state.size() ||
239      !z_order_out) {
240    return -EINVAL;
241  }
242
243  *z_order_out = surface_state->state[surface_index].GetZOrder();
244  return 0;
245}
246
247int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
248                              size_t surface_index, bool* visible_out) {
249  if (!surface_state || surface_index >= surface_state->state.size() ||
250      !visible_out) {
251    return -EINVAL;
252  }
253
254  *visible_out = surface_state->state[surface_index].GetVisible();
255  return 0;
256}
257
258int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
259                                     size_t surface_index, size_t* count_out) {
260  if (!surface_state || surface_index >= surface_state->state.size() ||
261      !count_out) {
262    return -EINVAL;
263  }
264
265  *count_out = surface_state->state[surface_index].surface_attributes.size();
266  return 0;
267}
268
269ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
270                                     size_t surface_index,
271                                     DvrSurfaceAttribute* attributes,
272                                     size_t max_count) {
273  if (!surface_state || surface_index >= surface_state->state.size() ||
274      !attributes) {
275    return -EINVAL;
276  }
277
278  return ConvertSurfaceAttributes(
279      surface_state->state[surface_index].surface_attributes, attributes,
280      max_count);
281}
282
283}  // extern "C"
284