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 <functional>
10 #include <memory>
11 #include <mutex>
12
13 struct DvrHwcFrame {
14 android::dvr::ComposerView::Frame frame;
15 };
16
17 namespace {
18
19 class HwcCallback : public android::dvr::BnVrComposerCallback {
20 public:
21 using CallbackFunction = std::function<int(DvrHwcFrame*)>;
22
23 explicit HwcCallback(const CallbackFunction& callback);
24 ~HwcCallback() override;
25
26 // Reset the callback. This needs to be done early to avoid use after free
27 // accesses from binder thread callbacks.
28 void Shutdown();
29
30 std::unique_ptr<DvrHwcFrame> DequeueFrame();
31
32 private:
33 // android::dvr::BnVrComposerCallback:
34 android::binder::Status onNewFrame(
35 const android::dvr::ParcelableComposerFrame& frame,
36 android::dvr::ParcelableUniqueFd* fence) override;
37
38 // Protects the |callback_| from uses from multiple threads. During shutdown
39 // there may be in-flight frame update events. In those cases the callback
40 // access needs to be protected otherwise binder threads may access an invalid
41 // callback.
42 std::mutex mutex_;
43 CallbackFunction callback_;
44
45 HwcCallback(const HwcCallback&) = delete;
46 void operator=(const HwcCallback&) = delete;
47 };
48
HwcCallback(const CallbackFunction & callback)49 HwcCallback::HwcCallback(const CallbackFunction& callback)
50 : callback_(callback) {}
51
~HwcCallback()52 HwcCallback::~HwcCallback() {}
53
Shutdown()54 void HwcCallback::Shutdown() {
55 std::lock_guard<std::mutex> guard(mutex_);
56 callback_ = nullptr;
57 }
58
onNewFrame(const android::dvr::ParcelableComposerFrame & frame,android::dvr::ParcelableUniqueFd * fence)59 android::binder::Status HwcCallback::onNewFrame(
60 const android::dvr::ParcelableComposerFrame& frame,
61 android::dvr::ParcelableUniqueFd* fence) {
62 std::lock_guard<std::mutex> guard(mutex_);
63
64 if (!callback_) {
65 fence->set_fence(android::base::unique_fd());
66 return android::binder::Status::ok();
67 }
68
69 std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame());
70 dvr_frame->frame = frame.frame();
71
72 fence->set_fence(android::base::unique_fd(callback_(dvr_frame.release())));
73 return android::binder::Status::ok();
74 }
75
76 } // namespace
77
78 struct DvrHwcClient {
79 android::sp<android::dvr::IVrComposer> composer;
80 android::sp<HwcCallback> callback;
81 };
82
dvrHwcClientCreate(DvrHwcOnFrameCallback callback,void * data)83 DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) {
84 std::unique_ptr<DvrHwcClient> client(new DvrHwcClient());
85
86 android::sp<android::IServiceManager> sm(android::defaultServiceManager());
87 client->composer = android::interface_cast<android::dvr::IVrComposer>(
88 sm->getService(android::dvr::IVrComposer::SERVICE_NAME()));
89 if (!client->composer.get())
90 return nullptr;
91
92 client->callback = new HwcCallback(std::bind(callback, data,
93 std::placeholders::_1));
94 android::binder::Status status = client->composer->registerObserver(
95 client->callback);
96 if (!status.isOk())
97 return nullptr;
98
99 return client.release();
100 }
101
dvrHwcClientDestroy(DvrHwcClient * client)102 void dvrHwcClientDestroy(DvrHwcClient* client) {
103 client->composer->clearObserver();
104
105 // NOTE: Deleting DvrHwcClient* isn't enough since DvrHwcClient::callback is a
106 // shared pointer that could be referenced from a binder thread. But the
107 // client callback isn't valid past this calls so that needs to be reset.
108 client->callback->Shutdown();
109
110 delete client;
111 }
112
dvrHwcFrameDestroy(DvrHwcFrame * frame)113 void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
114 delete frame;
115 }
116
dvrHwcFrameGetDisplayId(DvrHwcFrame * frame)117 DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
118 return frame->frame.display_id;
119 }
120
dvrHwcFrameGetDisplayWidth(DvrHwcFrame * frame)121 int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
122 return frame->frame.display_width;
123 }
124
dvrHwcFrameGetDisplayHeight(DvrHwcFrame * frame)125 int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
126 return frame->frame.display_height;
127 }
128
dvrHwcFrameGetDisplayRemoved(DvrHwcFrame * frame)129 bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
130 return frame->frame.removed;
131 }
132
dvrHwcFrameGetLayerCount(DvrHwcFrame * frame)133 size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
134 return frame->frame.layers.size();
135 }
136
dvrHwcFrameGetActiveConfig(DvrHwcFrame * frame)137 uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) {
138 return static_cast<uint32_t>(frame->frame.active_config);
139 }
140
dvrHwcFrameGetColorMode(DvrHwcFrame * frame)141 uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) {
142 return static_cast<uint32_t>(frame->frame.color_mode);
143 }
144
dvrHwcFrameGetColorTransform(DvrHwcFrame * frame,float * out_matrix,int32_t * out_hint)145 void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
146 int32_t* out_hint) {
147 *out_hint = frame->frame.color_transform_hint;
148 memcpy(out_matrix, frame->frame.color_transform,
149 sizeof(frame->frame.color_transform));
150 }
151
dvrHwcFrameGetPowerMode(DvrHwcFrame * frame)152 uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) {
153 return static_cast<uint32_t>(frame->frame.power_mode);
154 }
155
dvrHwcFrameGetVsyncEnabled(DvrHwcFrame * frame)156 uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) {
157 return static_cast<uint32_t>(frame->frame.vsync_enabled);
158 }
159
dvrHwcFrameGetLayerId(DvrHwcFrame * frame,size_t layer_index)160 DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
161 return frame->frame.layers[layer_index].id;
162 }
163
dvrHwcFrameGetLayerBuffer(DvrHwcFrame * frame,size_t layer_index)164 AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
165 size_t layer_index) {
166 AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer(
167 frame->frame.layers[layer_index].buffer.get());
168 AHardwareBuffer_acquire(buffer);
169 return buffer;
170 }
171
dvrHwcFrameGetLayerFence(DvrHwcFrame * frame,size_t layer_index)172 int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
173 return frame->frame.layers[layer_index].fence->dup();
174 }
175
dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame * frame,size_t layer_index)176 DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame,
177 size_t layer_index) {
178 return DvrHwcRecti{
179 frame->frame.layers[layer_index].display_frame.left,
180 frame->frame.layers[layer_index].display_frame.top,
181 frame->frame.layers[layer_index].display_frame.right,
182 frame->frame.layers[layer_index].display_frame.bottom,
183 };
184 }
185
dvrHwcFrameGetLayerCrop(DvrHwcFrame * frame,size_t layer_index)186 DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) {
187 return DvrHwcRectf{
188 frame->frame.layers[layer_index].crop.left,
189 frame->frame.layers[layer_index].crop.top,
190 frame->frame.layers[layer_index].crop.right,
191 frame->frame.layers[layer_index].crop.bottom,
192 };
193 }
194
dvrHwcFrameGetLayerBlendMode(DvrHwcFrame * frame,size_t layer_index)195 DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame,
196 size_t layer_index) {
197 return static_cast<DvrHwcBlendMode>(
198 frame->frame.layers[layer_index].blend_mode);
199 }
200
dvrHwcFrameGetLayerAlpha(DvrHwcFrame * frame,size_t layer_index)201 float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
202 return frame->frame.layers[layer_index].alpha;
203 }
204
dvrHwcFrameGetLayerType(DvrHwcFrame * frame,size_t layer_index)205 uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
206 return frame->frame.layers[layer_index].type;
207 }
208
dvrHwcFrameGetLayerApplicationId(DvrHwcFrame * frame,size_t layer_index)209 uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
210 size_t layer_index) {
211 return frame->frame.layers[layer_index].app_id;
212 }
213
dvrHwcFrameGetLayerZOrder(DvrHwcFrame * frame,size_t layer_index)214 uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) {
215 return frame->frame.layers[layer_index].z_order;
216 }
217
dvrHwcFrameGetLayerCursor(DvrHwcFrame * frame,size_t layer_index,int32_t * out_x,int32_t * out_y)218 void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
219 int32_t* out_x, int32_t* out_y) {
220 *out_x = frame->frame.layers[layer_index].cursor_x;
221 *out_y = frame->frame.layers[layer_index].cursor_y;
222 }
223
dvrHwcFrameGetLayerTransform(DvrHwcFrame * frame,size_t layer_index)224 uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) {
225 return frame->frame.layers[layer_index].transform;
226 }
227
dvrHwcFrameGetLayerDataspace(DvrHwcFrame * frame,size_t layer_index)228 uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) {
229 return frame->frame.layers[layer_index].dataspace;
230 }
231
dvrHwcFrameGetLayerColor(DvrHwcFrame * frame,size_t layer_index)232 uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index) {
233 const auto& color = frame->frame.layers[layer_index].color;
234 return color.r | (static_cast<uint32_t>(color.g) << 8) |
235 (static_cast<uint32_t>(color.b) << 16) |
236 (static_cast<uint32_t>(color.a) << 24);
237 }
238
dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame * frame,size_t layer_index)239 uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
240 size_t layer_index) {
241 return frame->frame.layers[layer_index].visible_regions.size();
242 }
243
dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame * frame,size_t layer_index,size_t index)244 DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
245 size_t layer_index, size_t index) {
246 return DvrHwcRecti{
247 frame->frame.layers[layer_index].visible_regions[index].left,
248 frame->frame.layers[layer_index].visible_regions[index].top,
249 frame->frame.layers[layer_index].visible_regions[index].right,
250 frame->frame.layers[layer_index].visible_regions[index].bottom,
251 };
252 }
253
dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame * frame,size_t layer_index)254 uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
255 size_t layer_index) {
256 return frame->frame.layers[layer_index].damaged_regions.size();
257 }
258
dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame * frame,size_t layer_index,size_t index)259 DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
260 size_t layer_index, size_t index) {
261 return DvrHwcRecti{
262 frame->frame.layers[layer_index].damaged_regions[index].left,
263 frame->frame.layers[layer_index].damaged_regions[index].top,
264 frame->frame.layers[layer_index].damaged_regions[index].right,
265 frame->frame.layers[layer_index].damaged_regions[index].bottom,
266 };
267 }
268