diff --git a/utils/src/surface_draw.cpp b/utils/src/surface_draw.cpp index ef0d794c..90a543f8 100644 --- a/utils/src/surface_draw.cpp +++ b/utils/src/surface_draw.cpp @@ -30,6 +30,7 @@ namespace OHOS { namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SurfaceDraw"}; + constexpr uint32_t IMAGE_BYTES_STRIDE = 4; } // namespace bool SurfaceDraw::DrawImage(std::shared_ptr surfaceNode, int32_t bufferWidth, @@ -202,8 +203,7 @@ bool SurfaceDraw::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, const s canvas.Bind(bitmap); canvas.Clear(Drawing::Color::COLOR_TRANSPARENT); DrawPixelmap(canvas, imagePath); - static constexpr uint32_t stride = 4; - uint32_t addrSize = width * height * stride; + uint32_t addrSize = width * height * IMAGE_BYTES_STRIDE; errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize); if (ret != EOK) { WLOGFE("draw failed"); @@ -224,7 +224,7 @@ bool SurfaceDraw::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, std::sh Drawing::Image image; Drawing::Bitmap imageBitmap; Drawing::SamplingOptions sampling = Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, - Drawing::MipmapMode::NEAREST); + Drawing::MipmapMode::NEAREST); imageBitmap.Build(pixelMap->GetWidth(), pixelMap->GetHeight(), format); imageBitmap.SetPixels(const_cast(pixelMap->GetPixels())); image.BuildFromBitmap(imageBitmap); @@ -233,8 +233,7 @@ bool SurfaceDraw::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, std::sh Drawing::Rect src(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight()); canvas.DrawImageRect(image, src, dst, sampling); - static constexpr uint32_t stride = 4; - uint32_t addrSize = width * height * stride; + uint32_t addrSize = width * height * IMAGE_BYTES_STRIDE; errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize); if (ret != EOK) { WLOGFE("draw failed"); @@ -253,8 +252,7 @@ bool SurfaceDraw::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, uint32_ canvas.Bind(bitmap); canvas.Clear(color); - static constexpr uint32_t stride = 4; - uint32_t addrSize = width * height * stride; + uint32_t addrSize = width * height * IMAGE_BYTES_STRIDE; errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize); if (ret != EOK) { WLOGFE("draw failed"); @@ -299,6 +297,24 @@ bool SurfaceDraw::DrawImageRect(std::shared_ptr surfaceNode, Rect bool SurfaceDraw::DoDrawImageRect(uint8_t *addr, int32_t winWidth, int32_t winHeight, sptr pixelMap, uint32_t color) { + if (pixelMap == nullptr) { + WLOGFE("drawing pixel map failed, because pixel map is nullptr."); + return false; + } + if (pixelMap->GetHeight() <= 0 || pixelMap->GetWidth() <= 0 || winWidth <= 0 || winHeight <= 0) { + WLOGFE("drawing pixel map failed, because width or height is invalid."); + return false; + } + float xAxis = static_cast(winWidth) / pixelMap->GetWidth(); + float yAxis = static_cast(winHeight) / pixelMap->GetHeight(); + float axis = std::min(xAxis, yAxis); + if (axis < 1.0) { + // scale when the size of the pixel map is larger than the window + // use axis to scale equally + pixelMap->scale(axis, axis); + } + int left = (winWidth - pixelMap->GetWidth()) / 2; // 2 is the left and right boundaries of the window + int top = (winHeight - pixelMap->GetHeight()) / 2; // 2 is the top and bottom boundaries of the window Drawing::Bitmap bitmap; Drawing::BitmapFormat format { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_OPAQUE }; @@ -306,29 +322,9 @@ bool SurfaceDraw::DoDrawImageRect(uint8_t *addr, int32_t winWidth, int32_t winHe Drawing::Canvas canvas; canvas.Bind(bitmap); canvas.Clear(color); - if (pixelMap == nullptr) { - WLOGFE("drawing pixel map is nullptr"); - return false; - } - uint32_t iconHeight = pixelMap->GetHeight(); - uint32_t iconWidth = pixelMap->GetWidth(); - Drawing::Image image; - Drawing::Bitmap iconBitmap; - iconBitmap.Build(iconWidth, iconHeight, format); - iconBitmap.SetPixels(const_cast(pixelMap->GetPixels())); - image.BuildFromBitmap(iconBitmap); - Drawing::SamplingOptions sampling = Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, - Drawing::MipmapMode::NEAREST); + canvas.DrawBitmap(*pixelMap, left, top); - int realHeight = std::min(winHeight, pixelMap->GetHeight()); // need to scale - int realWidth = std::min(winWidth, pixelMap->GetWidth()); - int pointX = (winWidth - realWidth) / 2; // 2 is mid point - int pointY = (winHeight - realHeight) / 2; // 2 is mid point - Drawing::Rect dst(pointX, pointY, pointX + realWidth, pointY + realHeight); - canvas.DrawImageRect(image, dst, sampling); - - uint32_t stride = 4; - uint32_t addrSize = winWidth * winHeight * stride; + uint32_t addrSize = winWidth * winHeight * IMAGE_BYTES_STRIDE; errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize); if (ret != EOK) { WLOGFE("draw failed"); diff --git a/wm/src/window_manager.cpp b/wm/src/window_manager.cpp index b956b03d..b196add2 100644 --- a/wm/src/window_manager.cpp +++ b/wm/src/window_manager.cpp @@ -168,6 +168,8 @@ void WindowManager::Impl::PostTask(ListenerTaskCallback &&callback, EventPriorit const std::string name = "WINDOW_MANAGER_TASK") { if (!isHandlerRunning_) { + // Ensure that the callback thread is not used when it is initialized + std::lock_guard lock(mutex_); InitListenerHandler(); } if (listenerHandler_ == nullptr) { @@ -205,8 +207,13 @@ void WindowManager::Impl::NotifyFocused(const sptr& focusChange WLOGFI("NotifyFocused [%{public}u; %{public}" PRIu64"; %{public}d; %{public}d; %{public}u; %{public}p]", focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_, static_cast(focusChangeInfo->windowType_), focusChangeInfo->abilityToken_.GetRefPtr()); - PostTask([this, focusChangeInfo]() mutable { - for (auto& listener : focusChangedListeners_) { + std::vector> focusChangeListeners; + { + std::lock_guard lock(mutex_); + focusChangeListeners = focusChangedListeners_; + } + PostTask([this, focusChangeInfo, focusChangeListeners]() mutable { + for (auto& listener : focusChangeListeners) { listener->OnFocused(focusChangeInfo); } }, EventPriority::LOW, "FocusChangeInfo"); @@ -217,8 +224,13 @@ void WindowManager::Impl::NotifyUnfocused(const sptr& focusChan WLOGFI("NotifyUnfocused [%{public}u; %{public}" PRIu64"; %{public}d; %{public}d; %{public}u; %{public}p]", focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_, static_cast(focusChangeInfo->windowType_), focusChangeInfo->abilityToken_.GetRefPtr()); - PostTask([this, focusChangeInfo]() mutable { - for (auto& listener : focusChangedListeners_) { + std::vector> focusChangeListeners; + { + std::lock_guard lock(mutex_); + focusChangeListeners = focusChangedListeners_; + } + PostTask([this, focusChangeInfo, focusChangeListeners]() mutable { + for (auto& listener : focusChangeListeners) { listener->OnUnfocused(focusChangeInfo); } }, EventPriority::LOW, "UnFocusChangeInfo"); @@ -233,8 +245,13 @@ void WindowManager::Impl::NotifySystemBarChanged(DisplayId displayId, const Syst tint.type_, tint.prop_.enable_, tint.prop_.backgroundColor_, tint.prop_.contentColor_, tint.region_.posX_, tint.region_.posY_, tint.region_.width_, tint.region_.height_); } - PostTask([this, displayId, tints]() mutable { - for (auto& listener : systemBarChangedListeners_) { + std::vector> systemBarChangeListeners; + { + std::lock_guard lock(mutex_); + systemBarChangeListeners = systemBarChangedListeners_; + } + PostTask([this, displayId, tints, systemBarChangeListeners]() mutable { + for (auto& listener : systemBarChangeListeners) { listener->OnSystemBarPropertyChange(displayId, tints); } }, EventPriority::LOW, "SystemBarChangeInfo"); @@ -256,8 +273,13 @@ void WindowManager::Impl::NotifyAccessibilityWindowInfo(const sptrcurrentWindowInfo_->windowRect_.posY_, windowInfo->currentWindowInfo_->focused_, windowInfo->currentWindowInfo_->isDecorEnable_, windowInfo->currentWindowInfo_->displayId_, windowInfo->currentWindowInfo_->mode_, windowInfo->currentWindowInfo_->type_); - PostTask([this, windowInfo, type]() mutable { - for (auto& listener : windowUpdateListeners_) { + std::vector> windowUpdateListeners; + { + std::lock_guard lock(mutex_); + windowUpdateListeners = windowUpdateListeners_; + } + PostTask([this, windowInfo, type, windowUpdateListeners]() mutable { + for (auto& listener : windowUpdateListeners) { listener->OnWindowUpdate(windowInfo, type); } }, EventPriority::LOW, "AccessibilityWindowInfo"); @@ -266,8 +288,13 @@ void WindowManager::Impl::NotifyAccessibilityWindowInfo(const sptr>& windowVisibilityInfos) { - PostTask([this, windowVisibilityInfos]() mutable { - for (auto& listener : windowVisibilityListeners_) { + std::vector> visibilityChangeListeners; + { + std::lock_guard lock(mutex_); + visibilityChangeListeners = windowVisibilityListeners_; + } + PostTask([this, windowVisibilityInfos, visibilityChangeListeners]() mutable { + for (auto& listener : visibilityChangeListeners) { listener->OnWindowVisibilityChanged(windowVisibilityInfos); } }, EventPriority::LOW, "AccessibilityWindowInfo"); @@ -276,8 +303,13 @@ void WindowManager::Impl::NotifyWindowVisibilityInfoChanged( void WindowManager::Impl::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing) { WLOGFI("Camera float window, accessTokenId = %{public}u, isShowing = %{public}u", accessTokenId, isShowing); - PostTask([this, accessTokenId, isShowing]() mutable { - for (auto& listener : cameraFloatWindowChangedListeners_) { + std::vector> cameraFloatWindowChangeListeners; + { + std::lock_guard lock(mutex_); + cameraFloatWindowChangeListeners = cameraFloatWindowChangedListeners_; + } + PostTask([this, accessTokenId, isShowing, cameraFloatWindowChangeListeners]() mutable { + for (auto& listener : cameraFloatWindowChangeListeners) { listener->OnCameraFloatWindowChange(accessTokenId, isShowing); } }, EventPriority::LOW, "CameraFloatWindowStatus"); @@ -528,7 +560,6 @@ void WindowManager::UpdateFocusChangeInfo(const sptr& focusChan return; } WLOGFI("window focus change: %{public}d, id: %{public}u", focused, focusChangeInfo->windowId_); - std::lock_guard lock(pImpl_->mutex_); if (focused) { pImpl_->NotifyFocused(focusChangeInfo); } else { @@ -539,21 +570,18 @@ void WindowManager::UpdateFocusChangeInfo(const sptr& focusChan void WindowManager::UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints) const { - std::lock_guard lock(pImpl_->mutex_); pImpl_->NotifySystemBarChanged(displayId, tints); } void WindowManager::NotifyAccessibilityWindowInfo(const sptr& windowInfo, WindowUpdateType type) const { - std::lock_guard lock(pImpl_->mutex_); pImpl_->NotifyAccessibilityWindowInfo(windowInfo, type); } void WindowManager::UpdateWindowVisibilityInfo( const std::vector>& windowVisibilityInfos) const { - std::lock_guard lock(pImpl_->mutex_); pImpl_->NotifyWindowVisibilityInfoChanged(windowVisibilityInfos); } @@ -568,7 +596,6 @@ WMError WindowManager::GetAccessibilityWindowInfo(sptr& void WindowManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing) const { - std::lock_guard lock(pImpl_->mutex_); pImpl_->UpdateCameraFloatWindowStatus(accessTokenId, isShowing); } } // namespace Rosen