• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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