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 13struct DvrHwcFrame { 14 android::dvr::ComposerView::Frame frame; 15}; 16 17namespace { 18 19class 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 49HwcCallback::HwcCallback(const CallbackFunction& callback) 50 : callback_(callback) {} 51 52HwcCallback::~HwcCallback() {} 53 54void HwcCallback::Shutdown() { 55 std::lock_guard<std::mutex> guard(mutex_); 56 callback_ = nullptr; 57} 58 59android::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 78struct DvrHwcClient { 79 android::sp<android::dvr::IVrComposer> composer; 80 android::sp<HwcCallback> callback; 81}; 82 83DvrHwcClient* 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 102void 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 113void dvrHwcFrameDestroy(DvrHwcFrame* frame) { 114 delete frame; 115} 116 117DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) { 118 return frame->frame.display_id; 119} 120 121int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) { 122 return frame->frame.display_width; 123} 124 125int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) { 126 return frame->frame.display_height; 127} 128 129bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) { 130 return frame->frame.removed; 131} 132 133size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) { 134 return frame->frame.layers.size(); 135} 136 137uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) { 138 return static_cast<uint32_t>(frame->frame.active_config); 139} 140 141uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) { 142 return static_cast<uint32_t>(frame->frame.color_mode); 143} 144 145void 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 152uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) { 153 return static_cast<uint32_t>(frame->frame.power_mode); 154} 155 156uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) { 157 return static_cast<uint32_t>(frame->frame.vsync_enabled); 158} 159 160DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) { 161 return frame->frame.layers[layer_index].id; 162} 163 164AHardwareBuffer* 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 172int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) { 173 return frame->frame.layers[layer_index].fence->dup(); 174} 175 176DvrHwcRecti 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 186DvrHwcRectf 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 195DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame, 196 size_t layer_index) { 197 return static_cast<DvrHwcBlendMode>( 198 frame->frame.layers[layer_index].blend_mode); 199} 200 201float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) { 202 return frame->frame.layers[layer_index].alpha; 203} 204 205uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) { 206 return frame->frame.layers[layer_index].type; 207} 208 209uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame, 210 size_t layer_index) { 211 return frame->frame.layers[layer_index].app_id; 212} 213 214uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) { 215 return frame->frame.layers[layer_index].z_order; 216} 217 218void 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 224uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) { 225 return frame->frame.layers[layer_index].transform; 226} 227 228uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) { 229 return frame->frame.layers[layer_index].dataspace; 230} 231 232uint32_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 239uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame, 240 size_t layer_index) { 241 return frame->frame.layers[layer_index].visible_regions.size(); 242} 243 244DvrHwcRecti 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 254uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame, 255 size_t layer_index) { 256 return frame->frame.layers[layer_index].damaged_regions.size(); 257} 258 259DvrHwcRecti 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