diff --git a/sdm/libs/hwc2/hwc_color_manager.cpp b/sdm/libs/hwc2/hwc_color_manager.cpp index 61618cb9..9f336a07 100644 --- a/sdm/libs/hwc2/hwc_color_manager.cpp +++ b/sdm/libs/hwc2/hwc_color_manager.cpp @@ -88,8 +88,8 @@ void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data, out_parcel->write(data.payload, data.size); } -HWCColorManager *HWCColorManager::CreateColorManager() { - HWCColorManager *color_mgr = new HWCColorManager(); +HWCColorManager *HWCColorManager::CreateColorManager(HWCBufferAllocator * buffer_allocator) { + HWCColorManager *color_mgr = new HWCColorManager(buffer_allocator); if (color_mgr) { // Load display API interface library. And retrieve color API function tables. @@ -135,6 +135,10 @@ HWCColorManager *HWCColorManager::CreateColorManager() { return color_mgr; } +HWCColorManager::HWCColorManager(HWCBufferAllocator *buffer_allocator) : + buffer_allocator_(buffer_allocator) { +} + HWCColorManager::~HWCColorManager() { } @@ -216,17 +220,9 @@ int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_ buffer_info.alloc_buffer_info.stride = 0; buffer_info.alloc_buffer_info.size = 0; - buffer_allocator_ = new HWCBufferAllocator(); - if (buffer_allocator_ == NULL) { - DLOGE("Memory allocation for buffer_allocator_ FAILED"); - return -ENOMEM; - } - ret = buffer_allocator_->AllocateBuffer(&buffer_info); if (ret != 0) { DLOGE("Buffer allocation failed. ret: %d", ret); - delete buffer_allocator_; - buffer_allocator_ = NULL; return -ENOMEM; } else { void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, PROT_READ | PROT_WRITE, @@ -236,8 +232,6 @@ int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_ DLOGE("mmap failed. err = %d", errno); frame_capture_data->buffer = NULL; ret = buffer_allocator_->FreeBuffer(&buffer_info); - delete buffer_allocator_; - buffer_allocator_ = NULL; return -EFAULT; } else { frame_capture_data->buffer = reinterpret_cast(buffer); @@ -263,8 +257,6 @@ int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_ if (ret != 0) { DLOGE("FreeBuffer failed. ret = %d", ret); } - delete buffer_allocator_; - buffer_allocator_ = NULL; } } else { DLOGE("GetFrameCaptureStatus failed. ret = %d", ret); diff --git a/sdm/libs/hwc2/hwc_color_manager.h b/sdm/libs/hwc2/hwc_color_manager.h index a407f85e..32f7f5ff 100644 --- a/sdm/libs/hwc2/hwc_color_manager.h +++ b/sdm/libs/hwc2/hwc_color_manager.h @@ -105,12 +105,13 @@ class HWCQDCMModeManager { class HWCColorManager { public: static const int kNumSolidFillLayers = 2; - static HWCColorManager *CreateColorManager(); + static HWCColorManager *CreateColorManager(HWCBufferAllocator *buffer_allocator); static int CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id, PPDisplayAPIPayload *sink); static void MarshallStructIntoParcel(const PPDisplayAPIPayload &data, android::Parcel *out_parcel); + explicit HWCColorManager(HWCBufferAllocator *buffer_allocator); ~HWCColorManager(); void DestroyColorManager(); int EnableQDCMMode(bool enable, HWCDisplay *hwc_display); diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp index e3b05230..2157d231 100644 --- a/sdm/libs/hwc2/hwc_display.cpp +++ b/sdm/libs/hwc2/hwc_display.cpp @@ -213,7 +213,7 @@ void HWCColorMode::PopulateTransform(const android_color_mode_t &mode, HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type, hwc2_display_t id, bool needs_blit, qService::QService *qservice, - DisplayClass display_class) + DisplayClass display_class, BufferAllocator *buffer_allocator) : core_intf_(core_intf), callbacks_(callbacks), type_(type), @@ -221,6 +221,7 @@ HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, Displa needs_blit_(needs_blit), qservice_(qservice), display_class_(display_class) { + buffer_allocator_ = static_cast(buffer_allocator); } int HWCDisplay::Init() { @@ -237,8 +238,6 @@ int HWCDisplay::Init() { swap_interval_zero_ = true; } - buffer_allocator_ = new HWCBufferAllocator(); - client_target_ = new HWCLayer(id_, buffer_allocator_); int blit_enabled = 0; @@ -262,11 +261,6 @@ int HWCDisplay::Deinit() { delete client_target_; - if (buffer_allocator_) { - delete buffer_allocator_; - buffer_allocator_ = NULL; - } - if (color_mode_) { color_mode_->DeInit(); delete color_mode_; diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h index d8f85bd7..22cef4cd 100644 --- a/sdm/libs/hwc2/hwc_display.h +++ b/sdm/libs/hwc2/hwc_display.h @@ -199,7 +199,8 @@ class HWCDisplay : public DisplayEventHandler { static const uint32_t kMaxLayerCount = 32; HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type, hwc2_display_t id, - bool needs_blit, qService::QService *qservice, DisplayClass display_class); + bool needs_blit, qService::QService *qservice, DisplayClass display_class, + BufferAllocator *buffer_allocator); // DisplayEventHandler methods virtual DisplayError VSync(const DisplayEventVSync &vsync); diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp index 248e0104..39d46712 100644 --- a/sdm/libs/hwc2/hwc_display_external.cpp +++ b/sdm/libs/hwc2/hwc_display_external.cpp @@ -39,12 +39,14 @@ namespace sdm { -int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCCallbacks *callbacks, - qService::QService *qservice, HWCDisplay **hwc_display) { - return Create(core_intf, callbacks, 0, 0, qservice, false, hwc_display); +int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, qService::QService *qservice, + HWCDisplay **hwc_display) { + return Create(core_intf, buffer_allocator, callbacks, 0, 0, qservice, false, hwc_display); } -int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCCallbacks *callbacks, +int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, uint32_t primary_width, uint32_t primary_height, qService::QService *qservice, bool use_primary_res, HWCDisplay **hwc_display) { @@ -52,7 +54,8 @@ int HWCDisplayExternal::Create(CoreInterface *core_intf, HWCCallbacks *callbacks uint32_t external_height = 0; DisplayError error = kErrorNone; - HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, callbacks, qservice); + HWCDisplay *hwc_display_external = new HWCDisplayExternal(core_intf, buffer_allocator, callbacks, + qservice); int status = hwc_display_external->Init(); if (status) { delete hwc_display_external; @@ -95,10 +98,12 @@ void HWCDisplayExternal::Destroy(HWCDisplay *hwc_display) { delete hwc_display; } -HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, HWCCallbacks *callbacks, +HWCDisplayExternal::HWCDisplayExternal(CoreInterface *core_intf, + HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, qService::QService *qservice) : HWCDisplay(core_intf, callbacks, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice, - DISPLAY_CLASS_EXTERNAL) { + DISPLAY_CLASS_EXTERNAL, buffer_allocator) { } HWC2::Error HWCDisplayExternal::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) { diff --git a/sdm/libs/hwc2/hwc_display_external.h b/sdm/libs/hwc2/hwc_display_external.h index ce7547c0..802a77c8 100644 --- a/sdm/libs/hwc2/hwc_display_external.h +++ b/sdm/libs/hwc2/hwc_display_external.h @@ -36,10 +36,12 @@ namespace sdm { class HWCDisplayExternal : public HWCDisplay { public: - static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t primary_width, + static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, uint32_t primary_width, uint32_t primary_height, qService::QService *qservice, bool use_primary_res, HWCDisplay **hwc_display); - static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, qService::QService *qservice, + static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, qService::QService *qservice, HWCDisplay **hwc_display); static void Destroy(HWCDisplay *hwc_display); virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests); @@ -47,8 +49,8 @@ class HWCDisplayExternal : public HWCDisplay { virtual void SetSecureDisplay(bool secure_display_active); private: - HWCDisplayExternal(CoreInterface *core_intf, HWCCallbacks *callbacks, - qService::QService *qservice); + HWCDisplayExternal(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, qService::QService *qservice); void ApplyScanAdjustment(hwc_rect_t *display_frame); static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height, uint32_t *virtual_width, uint32_t *virtual_height); diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp index a99a8b1f..a27dca19 100644 --- a/sdm/libs/hwc2/hwc_display_primary.cpp +++ b/sdm/libs/hwc2/hwc_display_primary.cpp @@ -88,7 +88,7 @@ void HWCDisplayPrimary::Destroy(HWCDisplay *hwc_display) { HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, BufferAllocator *buffer_allocator, HWCCallbacks *callbacks, qService::QService *qservice) : HWCDisplay(core_intf, callbacks, kPrimary, HWC_DISPLAY_PRIMARY, true, qservice, - DISPLAY_CLASS_PRIMARY), + DISPLAY_CLASS_PRIMARY, buffer_allocator), buffer_allocator_(buffer_allocator), cpu_hint_(NULL) { } diff --git a/sdm/libs/hwc2/hwc_display_virtual.cpp b/sdm/libs/hwc2/hwc_display_virtual.cpp index 46fec4e9..11346eda 100644 --- a/sdm/libs/hwc2/hwc_display_virtual.cpp +++ b/sdm/libs/hwc2/hwc_display_virtual.cpp @@ -42,10 +42,12 @@ namespace sdm { -int HWCDisplayVirtual::Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t width, +int HWCDisplayVirtual::Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, uint32_t width, uint32_t height, int32_t *format, HWCDisplay **hwc_display) { int status = 0; - HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, callbacks); + HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, buffer_allocator, + callbacks); // TODO(user): Populate format correctly DLOGI("Creating virtual display: w: %d h:%d format:0x%x", width, height, *format); @@ -89,9 +91,10 @@ void HWCDisplayVirtual::Destroy(HWCDisplay *hwc_display) { delete hwc_display; } -HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, HWCCallbacks *callbacks) +HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks) : HWCDisplay(core_intf, callbacks, kVirtual, HWC_DISPLAY_VIRTUAL, false, NULL, - DISPLAY_CLASS_VIRTUAL) { + DISPLAY_CLASS_VIRTUAL, buffer_allocator) { } int HWCDisplayVirtual::Init() { diff --git a/sdm/libs/hwc2/hwc_display_virtual.h b/sdm/libs/hwc2/hwc_display_virtual.h index fe744b12..36e85091 100644 --- a/sdm/libs/hwc2/hwc_display_virtual.h +++ b/sdm/libs/hwc2/hwc_display_virtual.h @@ -38,7 +38,8 @@ namespace sdm { class HWCDisplayVirtual : public HWCDisplay { public: - static int Create(CoreInterface *core_intf, HWCCallbacks *callbacks, uint32_t width, + static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks, uint32_t width, uint32_t height, int32_t *format, HWCDisplay **hwc_display); static void Destroy(HWCDisplay *hwc_display); virtual int Init(); @@ -49,7 +50,8 @@ class HWCDisplayVirtual : public HWCDisplay { HWC2::Error SetOutputBuffer(buffer_handle_t buf, int32_t release_fence); private: - HWCDisplayVirtual(CoreInterface *core_intf, HWCCallbacks *callbacks); + HWCDisplayVirtual(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator, + HWCCallbacks *callbacks); int SetConfig(uint32_t width, uint32_t height); bool dump_output_layer_ = false; diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp index d514e744..31c2fa6c 100644 --- a/sdm/libs/hwc2/hwc_session.cpp +++ b/sdm/libs/hwc2/hwc_session.cpp @@ -93,7 +93,9 @@ int HWCSession::Init() { return -EINVAL; } - DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_, + buffer_allocator_ = new HWCBufferAllocator(); + + DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), buffer_allocator_, &buffer_sync_handler_, &socket_handler_, &core_intf_); if (error != kErrorNone) { @@ -109,11 +111,11 @@ int HWCSession::Init() { if (error == kErrorNone && hw_disp_info.type == kHDMI && hw_disp_info.is_connected) { // HDMI is primary display. If already connected, then create it and store in // primary display slot. If not connected, create a NULL display for now. - status = HWCDisplayExternal::Create(core_intf_, &callbacks_, qservice_, + status = HWCDisplayExternal::Create(core_intf_, buffer_allocator_, &callbacks_, qservice_, &hwc_display_[HWC_DISPLAY_PRIMARY]); } else { // Create and power on primary display - status = HWCDisplayPrimary::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_, + status = HWCDisplayPrimary::Create(core_intf_, buffer_allocator_, &callbacks_, qservice_, &hwc_display_[HWC_DISPLAY_PRIMARY]); } @@ -122,7 +124,7 @@ int HWCSession::Init() { return status; } - color_mgr_ = HWCColorManager::CreateColorManager(); + color_mgr_ = HWCColorManager::CreateColorManager(buffer_allocator_); if (!color_mgr_) { DLOGW("Failed to load HWCColorManager."); } @@ -152,13 +154,21 @@ int HWCSession::Deinit() { color_mgr_->DestroyColorManager(); } uevent_thread_exit_ = true; - pthread_join(uevent_thread_, NULL); + DLOGD("Terminating uevent thread"); + // TODO(user): on restarting HWC in the same process, the uevent thread does not restart + // cleanly. + Sys::pthread_cancel_(uevent_thread_); DisplayError error = CoreInterface::DestroyCore(); if (error != kErrorNone) { DLOGE("Display core de-initialization failed. Error = %d", error); } + if (buffer_allocator_ != nullptr) { + delete buffer_allocator_; + } + buffer_allocator_ = nullptr; + return 0; } @@ -704,8 +714,8 @@ HWC2::Error HWCSession::CreateVirtualDisplayObject(uint32_t width, uint32_t heig if (hwc_display_[HWC_DISPLAY_VIRTUAL]) { return HWC2::Error::NoResources; } - auto status = HWCDisplayVirtual::Create(core_intf_, &callbacks_, width, height, format, - &hwc_display_[HWC_DISPLAY_VIRTUAL]); + auto status = HWCDisplayVirtual::Create(core_intf_, buffer_allocator_, &callbacks_, width, + height, format, &hwc_display_[HWC_DISPLAY_VIRTUAL]); // TODO(user): validate width and height support if (status) return HWC2::Error::Unsupported; @@ -723,8 +733,8 @@ int32_t HWCSession::ConnectDisplay(int disp) { hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height); if (disp == HWC_DISPLAY_EXTERNAL) { - status = HWCDisplayExternal::Create(core_intf_, &callbacks_, primary_width, primary_height, - qservice_, false, &hwc_display_[disp]); + status = HWCDisplayExternal::Create(core_intf_, buffer_allocator_, &callbacks_, primary_width, + primary_height, qservice_, false, &hwc_display_[disp]); } else { DLOGE("Invalid display type"); return -1; diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h index befc96ce..500a763f 100644 --- a/sdm/libs/hwc2/hwc_session.h +++ b/sdm/libs/hwc2/hwc_session.h @@ -177,7 +177,7 @@ class HWCSession : hwc2_device_t, public qClient::BnQClient { pthread_t uevent_thread_; bool uevent_thread_exit_ = false; const char *uevent_thread_name_ = "HWC_UeventThread"; - HWCBufferAllocator buffer_allocator_; + HWCBufferAllocator *buffer_allocator_; HWCBufferSyncHandler buffer_sync_handler_; HWCColorManager *color_mgr_ = NULL; bool reset_panel_ = false;