Files
libpag/test/MultiThreadCase.cpp
2022-01-13 22:27:11 +08:00

165 lines
5.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making libpag available.
//
// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// unless required by applicable law or agreed to in writing, software distributed under the
// license is distributed on an "as is" basis, without warranties or conditions of any kind,
// either express or implied. see the license for the specific language governing permissions
// and limitations under the license.
//
/////////////////////////////////////////////////////////////////////////////////////////////////
#include <thread>
#include "HitTestCase.h"
#include "base/utils/TimeUtil.h"
#include "framework/pag_test.h"
#include "framework/utils/PAGTestUtils.h"
#include "nlohmann/json.hpp"
namespace pag {
PAG_TEST_CASE(MultiThreadCase)
/**
* swiftshader在多线程同时创建 EGLContextExt 时候会失败,需加锁
*/
void mockPAGView() {
auto file = PAGFile::Load(DEFAULT_PAG_PATH);
ASSERT_NE(file, nullptr) << "pag path is:" << DEFAULT_PAG_PATH << std::endl;
auto surface = PAGSurface::MakeOffscreen(file->width(), file->height());
auto player = std::make_shared<PAGPlayer>();
player->setSurface(surface);
surface->drawable->getDevice();
ASSERT_NE(surface, nullptr);
player->setComposition(file);
int num = 20;
for (int i = 0; i < num; i++) {
long time = file->duration() * i / num;
file->setCurrentTime(time);
player->flush();
DumpMD5(surface);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}
/**
* 用例描述: 使用多个PAGPlayer模拟多个PAGView同时渲染
*/
PAG_TEST(SimpleMultiThreadCase, MultiPAGView) {
std::vector<std::thread> threads;
int num = 10;
for (int i = 0; i < num; i++) {
threads.emplace_back(std::thread(mockPAGView));
}
for (auto& mock : threads) {
if (mock.joinable()) mock.join();
}
}
void mockAsyncFlush(int num = 30) {
ASSERT_NE(PAGCpuTest::TestPAGSurface, nullptr);
for (int i = 0; i < num; i++) {
PAGCpuTest::TestPAGFile->setCurrentTime(PAGCpuTest::TestPAGFile->duration() * i / num);
PAGCpuTest::TestPAGPlayer->flush();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
std::cout << "\nmockAsyncFlush finish" << std::endl;
}
/**
* 用例描述: 测试在A线程调用flushB线程同时进行编辑操作
*/
PAG_TEST_F(MultiThreadCase, AsyncFlush) {
auto mockThread = std::thread(mockAsyncFlush, 10);
std::shared_ptr<PAGComposition> pagCom =
std::static_pointer_cast<PAGComposition>(TestPAGFile->getLayerAt(0));
ASSERT_NE(pagCom, nullptr);
for (int i = 0; i < 10; i++) {
pagCom->swapLayerAt(2, 3);
PAGCpuTest::TestPAGPlayer->flush();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
auto layer = pagCom->getLayerAt(2);
PAGCpuTest::TestPAGPlayer->flush();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
pagCom->removeLayerAt(2);
PAGCpuTest::TestPAGPlayer->flush();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
pagCom->addLayerAt(layer, 2);
PAGCpuTest::TestPAGPlayer->flush();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
std::cout << "\nAsyncFlush edit" << std::endl;
mockThread.join();
}
/**
* 用例描述: 测试在A线程调用flushB线程进行freeCache
*/
PAG_TEST_F(MultiThreadCase, AsyncFlushAndFreeCache) {
ASSERT_NE(TestPAGFile, nullptr);
auto mockThread = std::thread(mockAsyncFlush, 200);
for (int i = 0; i < 200; i++) {
PAGCpuTest::TestPAGSurface->freeCache();
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
std::cout << "\nAsyncFlush edit" << std::endl;
mockThread.join();
}
/**
* 用例描述: 多线程HitTest相关因为flush线程会不停刷新位置所以另外一个线程来测试hit的准确性没有意义此处更多是看
* 多线程会不会引起死锁之类的问题正确性是HitTest接口本身来保证
*/
PAG_TEST_F(MultiThreadCase, HitTestPoint) {
auto mockThread = std::thread(mockAsyncFlush, 30);
for (int i = 0; i < 15; i++) {
TestPAGPlayer->hitTestPoint(TestPAGFile, 720.0 * i / 15, 1080.0 * i / 15, true);
}
mockThread.join();
}
/**
* 用例描述: GetLayersUnderPoint功能测试
*/
PAG_TEST_F(MultiThreadCase, GetLayersUnderPoint) {
auto mockThread = std::thread(mockAsyncFlush, 30);
for (int i = 0; i < 30; i++) {
TestPAGFile->getLayersUnderPoint(720.0 * i / 15, 1080.0 * i / 15);
}
mockThread.join();
}
PAG_TEST_CASE(MultiThreadCase_BitmapSequenceHitTest)
/**
* 用例描述: 图片序列帧的hitTest"
*/
PAG_TEST_F(MultiThreadCase_BitmapSequenceHitTest, BitmapSequenceHitTestPoint) {
auto mockThread = std::thread(mockAsyncFlush, 30);
for (int i = 0; i < 30; i++) {
TestPAGPlayer->hitTestPoint(TestPAGFile, 720.0 * i / 15, 1080.0 * i / 15, true);
}
mockThread.join();
}
PAG_TEST_CASE(MultiThreadCase_VideoSequenceHitTest)
/**
* 用例描述: 视频序列帧的hitTest
*/
PAG_TEST_F(MultiThreadCase_VideoSequenceHitTest, VideoSequenceHitTestPoint) {
auto mockThread = std::thread(mockAsyncFlush, 30);
for (int i = 0; i < 30; i++) {
TestPAGPlayer->hitTestPoint(TestPAGFile, 720.0 * i / 15, 1080.0 * i / 15, true);
}
mockThread.join();
}
} // namespace pag