1#include "include/dvr/dvr_hardware_composer_client.h"
2
3#include <android/dvr/IVrComposer.h>
4#include <android/dvr/BnVrComposerCallback.h>
5#include <android/hardware_buffer.h>
6#include <binder/IServiceManager.h>
7#include <private/android/AHardwareBufferHelpers.h>
8
9#include <memory>
10
11struct DvrHwcFrame {
12  android::dvr::ComposerView::Frame frame;
13};
14
15namespace {
16
17class HwcCallback : public android::dvr::BnVrComposerCallback {
18 public:
19  explicit HwcCallback(DvrHwcOnFrameCallback callback,
20                       void* client_state);
21  ~HwcCallback() override;
22
23  std::unique_ptr<DvrHwcFrame> DequeueFrame();
24
25 private:
26  // android::dvr::BnVrComposerCallback:
27  android::binder::Status onNewFrame(
28      const android::dvr::ParcelableComposerFrame& frame,
29      android::dvr::ParcelableUniqueFd* fence) override;
30
31  DvrHwcOnFrameCallback callback_;
32  void* client_state_;
33
34  HwcCallback(const HwcCallback&) = delete;
35  void operator=(const HwcCallback&) = delete;
36};
37
38HwcCallback::HwcCallback(DvrHwcOnFrameCallback callback, void* client_state)
39    : callback_(callback), client_state_(client_state) {}
40
41HwcCallback::~HwcCallback() {}
42
43android::binder::Status HwcCallback::onNewFrame(
44    const android::dvr::ParcelableComposerFrame& frame,
45    android::dvr::ParcelableUniqueFd* fence) {
46  std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame());
47  dvr_frame->frame = frame.frame();
48
49  fence->set_fence(android::base::unique_fd(callback_(client_state_,
50                                                      dvr_frame.release())));
51  return android::binder::Status::ok();
52}
53
54}  // namespace
55
56struct DvrHwcClient {
57  android::sp<android::dvr::IVrComposer> composer;
58  android::sp<HwcCallback> callback;
59};
60
61DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) {
62  std::unique_ptr<DvrHwcClient> client(new DvrHwcClient());
63
64  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
65  client->composer = android::interface_cast<android::dvr::IVrComposer>(
66      sm->getService(android::dvr::IVrComposer::SERVICE_NAME()));
67  if (!client->composer.get())
68    return nullptr;
69
70  client->callback = new HwcCallback(callback, data);
71  android::binder::Status status = client->composer->registerObserver(
72      client->callback);
73  if (!status.isOk())
74    return nullptr;
75
76  return client.release();
77}
78
79void dvrHwcClientDestroy(DvrHwcClient* client) {
80  delete client;
81}
82
83void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
84  delete frame;
85}
86
87DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
88  return frame->frame.display_id;
89}
90
91int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
92  return frame->frame.display_width;
93}
94
95int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
96  return frame->frame.display_height;
97}
98
99bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
100  return frame->frame.removed;
101}
102
103size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
104  return frame->frame.layers.size();
105}
106
107uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) {
108  return static_cast<uint32_t>(frame->frame.active_config);
109}
110
111uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) {
112  return static_cast<uint32_t>(frame->frame.color_mode);
113}
114
115void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
116                                  int32_t* out_hint) {
117  *out_hint = frame->frame.color_transform_hint;
118  memcpy(out_matrix, frame->frame.color_transform,
119         sizeof(frame->frame.color_transform));
120}
121
122uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) {
123  return static_cast<uint32_t>(frame->frame.power_mode);
124}
125
126uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) {
127  return static_cast<uint32_t>(frame->frame.vsync_enabled);
128}
129
130DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
131  return frame->frame.layers[layer_index].id;
132}
133
134AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
135                                           size_t layer_index) {
136  AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer(
137      frame->frame.layers[layer_index].buffer.get());
138  AHardwareBuffer_acquire(buffer);
139  return buffer;
140}
141
142int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
143  return frame->frame.layers[layer_index].fence->dup();
144}
145
146DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame,
147                                            size_t layer_index) {
148  return DvrHwcRecti{
149    frame->frame.layers[layer_index].display_frame.left,
150    frame->frame.layers[layer_index].display_frame.top,
151    frame->frame.layers[layer_index].display_frame.right,
152    frame->frame.layers[layer_index].display_frame.bottom,
153  };
154}
155
156DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) {
157  return DvrHwcRectf{
158    frame->frame.layers[layer_index].crop.left,
159    frame->frame.layers[layer_index].crop.top,
160    frame->frame.layers[layer_index].crop.right,
161    frame->frame.layers[layer_index].crop.bottom,
162  };
163}
164
165DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame,
166                                             size_t layer_index) {
167  return static_cast<DvrHwcBlendMode>(
168      frame->frame.layers[layer_index].blend_mode);
169}
170
171float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
172  return frame->frame.layers[layer_index].alpha;
173}
174
175uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
176  return frame->frame.layers[layer_index].type;
177}
178
179uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
180                                          size_t layer_index) {
181  return frame->frame.layers[layer_index].app_id;
182}
183
184uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) {
185  return frame->frame.layers[layer_index].z_order;
186}
187
188void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
189                               int32_t* out_x, int32_t* out_y) {
190  *out_x = frame->frame.layers[layer_index].cursor_x;
191  *out_y = frame->frame.layers[layer_index].cursor_y;
192}
193
194uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) {
195  return frame->frame.layers[layer_index].transform;
196}
197
198uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) {
199  return frame->frame.layers[layer_index].dataspace;
200}
201
202uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index) {
203  const auto& color = frame->frame.layers[layer_index].color;
204  return color.r | (static_cast<uint32_t>(color.g) << 8) |
205         (static_cast<uint32_t>(color.b) << 16) |
206         (static_cast<uint32_t>(color.a) << 24);
207}
208
209uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
210                                              size_t layer_index) {
211  return frame->frame.layers[layer_index].visible_regions.size();
212}
213
214DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
215                                             size_t layer_index, size_t index) {
216  return DvrHwcRecti{
217      frame->frame.layers[layer_index].visible_regions[index].left,
218      frame->frame.layers[layer_index].visible_regions[index].top,
219      frame->frame.layers[layer_index].visible_regions[index].right,
220      frame->frame.layers[layer_index].visible_regions[index].bottom,
221  };
222}
223
224uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
225                                              size_t layer_index) {
226  return frame->frame.layers[layer_index].damaged_regions.size();
227}
228
229DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
230                                             size_t layer_index, size_t index) {
231  return DvrHwcRecti{
232      frame->frame.layers[layer_index].damaged_regions[index].left,
233      frame->frame.layers[layer_index].damaged_regions[index].top,
234      frame->frame.layers[layer_index].damaged_regions[index].right,
235      frame->frame.layers[layer_index].damaged_regions[index].bottom,
236  };
237}
238