Home | History | Annotate | Download | only in libdvr
      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 
     49 HwcCallback::HwcCallback(const CallbackFunction& callback)
     50     : callback_(callback) {}
     51 
     52 HwcCallback::~HwcCallback() {}
     53 
     54 void HwcCallback::Shutdown() {
     55   std::lock_guard<std::mutex> guard(mutex_);
     56   callback_ = nullptr;
     57 }
     58 
     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 
     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 
    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 
    113 void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
    114   delete frame;
    115 }
    116 
    117 DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
    118   return frame->frame.display_id;
    119 }
    120 
    121 int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
    122   return frame->frame.display_width;
    123 }
    124 
    125 int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
    126   return frame->frame.display_height;
    127 }
    128 
    129 bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
    130   return frame->frame.removed;
    131 }
    132 
    133 size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
    134   return frame->frame.layers.size();
    135 }
    136 
    137 uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) {
    138   return static_cast<uint32_t>(frame->frame.active_config);
    139 }
    140 
    141 uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) {
    142   return static_cast<uint32_t>(frame->frame.color_mode);
    143 }
    144 
    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 
    152 uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) {
    153   return static_cast<uint32_t>(frame->frame.power_mode);
    154 }
    155 
    156 uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) {
    157   return static_cast<uint32_t>(frame->frame.vsync_enabled);
    158 }
    159 
    160 DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
    161   return frame->frame.layers[layer_index].id;
    162 }
    163 
    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 
    172 int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
    173   return frame->frame.layers[layer_index].fence->dup();
    174 }
    175 
    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 
    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 
    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 
    201 float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
    202   return frame->frame.layers[layer_index].alpha;
    203 }
    204 
    205 uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
    206   return frame->frame.layers[layer_index].type;
    207 }
    208 
    209 uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
    210                                           size_t layer_index) {
    211   return frame->frame.layers[layer_index].app_id;
    212 }
    213 
    214 uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) {
    215   return frame->frame.layers[layer_index].z_order;
    216 }
    217 
    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 
    224 uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) {
    225   return frame->frame.layers[layer_index].transform;
    226 }
    227 
    228 uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) {
    229   return frame->frame.layers[layer_index].dataspace;
    230 }
    231 
    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 
    239 uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
    240                                               size_t layer_index) {
    241   return frame->frame.layers[layer_index].visible_regions.size();
    242 }
    243 
    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 
    254 uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
    255                                               size_t layer_index) {
    256   return frame->frame.layers[layer_index].damaged_regions.size();
    257 }
    258 
    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