diff --git a/frameworks/core/pipeline_ng/pipeline_context.cpp b/frameworks/core/pipeline_ng/pipeline_context.cpp index c99a83d50598c2c4e1d4fdda6c7c6637ab1febbc..18f1d25c0e674579d38c6a5005232be3d1289792 100755 --- a/frameworks/core/pipeline_ng/pipeline_context.cpp +++ b/frameworks/core/pipeline_ng/pipeline_context.cpp @@ -3708,54 +3708,86 @@ void PipelineContext::FlushTouchEvents() } } - void PipelineContext::SetBackgroundColorModeUpdated(bool backgroundColorModeUpdated) { backgroundColorModeUpdated_ = backgroundColorModeUpdated; } +void PipelineContext::ConsumeTouchEventsInterpolation( + const std::unordered_set& ids, const std::map& timestampToIds, + std::unordered_map& newIdTouchPoints, + const std::unordered_map& idToTouchPoints) +{ + auto fakeIds = ids; + auto targetTimeStamp = resampleTimeStamp_; + for (auto it = timestampToIds.rbegin(); it != timestampToIds.rend(); ++it) { + auto touchId = it->second; + if (fakeIds.find(touchId) == fakeIds.end()) { + continue; + } + const auto touchIter = idToTouchPoints.find(touchId); + if (touchIter == idToTouchPoints.end()) { + continue; + } + auto stamp = std::chrono::duration_cast( + touchIter->second.time.time_since_epoch()).count(); + if (targetTimeStamp > static_cast(stamp)) { + continue; + } + TouchEvent newTouchEvent; + if (eventManager_->GetResampleTouchEvent( + historyPointsById_[touchId], touchIter->second.history, + targetTimeStamp, newTouchEvent)) { + newIdTouchPoints[touchId] = newTouchEvent; + } + historyPointsById_[touchId] = touchIter->second.history; + fakeIds.erase(touchId); + } +} + void PipelineContext::ConsumeTouchEvents( std::list& touchEvents, std::unordered_map& idToTouchPoints) { + std::map timestampToIds; + std::unordered_set ids; bool needInterpolation = true; std::unordered_map newIdTouchPoints; - for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter) { + + int32_t inputIndex = touchEvents.size() - 1; + for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter, --inputIndex) { auto scalePoint = (*iter).CreateScalePoint(GetViewScale()); idToTouchPoints.emplace(scalePoint.id, scalePoint); idToTouchPoints[scalePoint.id].history.insert(idToTouchPoints[scalePoint.id].history.begin(), scalePoint); needInterpolation = iter->type != TouchType::MOVE ? false : true; + timestampToIds.emplace(inputIndex, scalePoint.id); + ids.insert(scalePoint.id); } + if (!NeedTouchInterpolation()) { needInterpolation = false; } + if (needInterpolation) { - auto targetTimeStamp = resampleTimeStamp_; - for (const auto& idIter : idToTouchPoints) { - auto stamp = - std::chrono::duration_cast(idIter.second.time.time_since_epoch()).count(); - if (targetTimeStamp > static_cast(stamp)) { - continue; - } - TouchEvent newTouchEvent; - if (eventManager_->GetResampleTouchEvent( - historyPointsById_[idIter.first], idIter.second.history, targetTimeStamp, newTouchEvent)) { - newIdTouchPoints[idIter.first] = newTouchEvent; - } - historyPointsById_[idIter.first] = idIter.second.history; - } + ConsumeTouchEventsInterpolation(ids, timestampToIds, newIdTouchPoints, idToTouchPoints); } + touchEvents.clear(); - for (const auto& iter : idToTouchPoints) { - auto lastDispatchTime = eventManager_->GetLastDispatchTime(); - lastDispatchTime[iter.first] = GetVsyncTime() - compensationValue_; - eventManager_->SetLastDispatchTime(std::move(lastDispatchTime)); - auto it = newIdTouchPoints.find(iter.first); + auto lastDispatchTime = eventManager_->GetLastDispatchTime(); + for (auto iter = timestampToIds.rbegin(); iter != timestampToIds.rend(); ++iter) { + auto touchId = iter->second; + if (ids.find(touchId) == ids.end()) { + continue; + } + lastDispatchTime[touchId] = GetVsyncTime() - compensationValue_; + auto it = newIdTouchPoints.find(touchId); if (it != newIdTouchPoints.end()) { touchEvents.emplace_back(it->second); } else { - touchEvents.emplace_back(iter.second); + touchEvents.emplace_back(idToTouchPoints[touchId]); } + ids.erase(touchId); } + eventManager_->SetLastDispatchTime(std::move(lastDispatchTime)); } uint64_t PipelineContext::GetResampleStamp() const @@ -3768,13 +3800,20 @@ uint64_t PipelineContext::GetResampleStamp() const void PipelineContext::AccelerateConsumeTouchEvents( std::list& touchEvents, std::unordered_map& idToTouchPoints) { + std::map timestampToIds; + std::unordered_set ids; + + int32_t inputIndex = touchEvents.size() - 1; // consume touchEvents and generate idToTouchPoints. - for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter) { + for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter, --inputIndex) { auto scalePoint = iter->CreateScalePoint(GetViewScale()); idToTouchPoints.emplace(scalePoint.id, scalePoint); auto& history = idToTouchPoints[scalePoint.id].history; history.emplace(history.begin(), std::move(scalePoint)); + timestampToIds.emplace(inputIndex, scalePoint.id); + ids.insert(scalePoint.id); } + bool needInterpolation = (touchEvents.front().type == TouchType::MOVE) && NeedTouchInterpolation(); auto& lastDispatchTime = eventManager_->GetLastDispatchTime(); auto curVsyncArrivalTime = GetVsyncTime() - compensationValue_; @@ -3783,17 +3822,27 @@ void PipelineContext::AccelerateConsumeTouchEvents( // resample and generate event to dispatch in touchEvents if (needInterpolation) { auto targetTimeStamp = GetResampleStamp(); - for (const auto& idIter : idToTouchPoints) { - TouchEvent newTouchEvent = idIter.second; + for (auto it = timestampToIds.rbegin(); it != timestampToIds.rend(); ++it) { + auto touchId = it->second; + if (ids.find(touchId) == ids.end()) { + continue; + } + TouchEvent newTouchEvent = idToTouchPoints[touchId]; eventManager_->TryResampleTouchEvent( - historyPointsById_[idIter.first], idIter.second.history, targetTimeStamp, newTouchEvent); - lastDispatchTime[idIter.first] = curVsyncArrivalTime; - touchEvents.emplace_back(newTouchEvent); + historyPointsById_[touchId], idToTouchPoints[touchId].history, targetTimeStamp, newTouchEvent); + lastDispatchTime[touchId] = curVsyncArrivalTime; + touchEvents.emplace_back(std::move(newTouchEvent)); + ids.erase(touchId); } } else { - for (const auto& idIter : idToTouchPoints) { - lastDispatchTime[idIter.first] = curVsyncArrivalTime; - touchEvents.emplace_back(idIter.second); + for (auto it = timestampToIds.rbegin(); it != timestampToIds.rend(); ++it) { + auto touchId = it->second; + if (ids.find(touchId) == ids.end()) { + continue; + } + lastDispatchTime[touchId] = curVsyncArrivalTime; + touchEvents.emplace_back(idToTouchPoints[touchId]); + ids.erase(touchId); } } } diff --git a/frameworks/core/pipeline_ng/pipeline_context.h b/frameworks/core/pipeline_ng/pipeline_context.h index 20325bfbbd3f192afe3199032b51e420b63d5ffc..a15927c223e1540b75e3b17418a268ff8b34baad 100755 --- a/frameworks/core/pipeline_ng/pipeline_context.h +++ b/frameworks/core/pipeline_ng/pipeline_context.h @@ -1328,6 +1328,10 @@ private: uint64_t GetResampleStamp() const; void ConsumeTouchEvents(std::list& touchEvents, std::unordered_map& idToTouchPoints); + void ConsumeTouchEventsInterpolation( + const std::unordered_set& ids, const std::map& timestampToIds, + std::unordered_map& newIdTouchPoints, + const std::unordered_map& idToTouchPoints); void AccelerateConsumeTouchEvents( std::list& touchEvents, std::unordered_map& idToTouchPoints); void SetTouchAccelarate(bool isEnable) override diff --git a/test/unittest/core/pipeline/pipeline_context_test_ng_two.cpp b/test/unittest/core/pipeline/pipeline_context_test_ng_two.cpp index da35777049a31fe5f9f75f18eb631eaa20b4a2ac..f4b0692a9d6a23c8eb0f91f13eaf95d5b47986c5 100644 --- a/test/unittest/core/pipeline/pipeline_context_test_ng_two.cpp +++ b/test/unittest/core/pipeline/pipeline_context_test_ng_two.cpp @@ -2585,5 +2585,30 @@ HWTEST_F(PipelineContextTestNg, FlushMouseEventForHover001, TestSize.Level1) context_->FlushMouseEventForHover(); EXPECT_EQ(context_->lastMouseEvent_->button, MouseButton::LEFT_BUTTON); } + +/** + * @tc.name: ConsumeTouchEventsInterpolationTest001 + * @tc.desc: Test ConsumeTouchEventsInterpolation. + * @tc.type: FUNC + */ +HWTEST_F(PipelineContextTestNg, ConsumeTouchEventsInterpolationTest001, TestSize.Level1) +{ + /** + * @tc.steps1: Create consumeTouchEventsInterpolation testcase. + */ + std::unordered_set ids = { 1, 2, 3 }; + std::map timestampToIds = { { 1, 0 }, { 2, 1 }, { 3, 2 }, { 4, 3 } }; + std::unordered_map newIdTouchPoints; + TouchEvent touchEventBefore = TouchEvent(); + touchEventBefore.time = TimeStamp(std::chrono::nanoseconds(BEFORE_VSYNC_TIME)); + TouchEvent touchEventAfter = TouchEvent(); + touchEventAfter.time = TimeStamp(std::chrono::nanoseconds(AFTER_VSYNC_TIME)); + std::unordered_map idToTouchPoints = { { 2, touchEventBefore }, { 3, touchEventAfter } }; + ASSERT_NE(context_, nullptr); + context_->resampleTimeStamp_ = DEFAULT_VSYNC_TIME; + context_->historyPointsById_.clear(); + context_->ConsumeTouchEventsInterpolation(ids, timestampToIds, newIdTouchPoints, idToTouchPoints); + EXPECT_EQ(context_->historyPointsById_.size(), 1); +} } // namespace NG } // namespace OHOS::Ace