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