recording Skp

Signed-off-by: 凯鑫 <liukaixin@huawei.com>
This commit is contained in:
凯鑫 2023-06-12 16:27:36 +08:00
parent e243c03b9d
commit 48af0f1985
6 changed files with 4 additions and 630 deletions

View File

@ -70,8 +70,9 @@ ohos_executable("drawing_engine_sample") {
sources += [
"benchmarks/benchmark_config.cpp",
"benchmarks/benchmark_dcl/dcl_command.cpp",
"benchmarks/benchmark_dcl/drawing_dcl.cpp",
"benchmarks/benchmark_dcl/drawing_command.cpp",
"benchmarks/benchmark_dcl/drawing_playback.cpp",
"benchmarks/benchmark_dcl/skia_recording.cpp",
"benchmarks/benchmark_multithread/drawing_mutilthread.cpp",
"benchmarks/benchmark_singlethread/drawing_singlethread.cpp",
]

View File

@ -1,148 +0,0 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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 "dcl_command.h"
#include <sstream>
#include <vector>
namespace OHOS {
namespace Rosen {
DCLCommand::DCLCommand(int32_t argc, char* argv[])
{
std::vector<std::string> argvNew(argv, argv + argc);
ParseCommand(argvNew);
}
void DCLCommand::ParseCommand(std::vector<std::string> argv)
{
const size_t twoParam = 2;
const size_t threeParam = 3;
switch (argv.size()) {
case twoParam:
std::cout << "iterate frame by default, beginFrame = " << beginFrame_ << ", endFrame = " <<
endFrame_ << std::endl;
break;
case threeParam:
if (strcmp(argv.back().c_str(), "--help") != 0 || strcmp(argv.back().c_str(), "-h") != 0) {
std::cout << dclMsg_ << std::endl;
}
break;
default:
for (size_t i = 2; i < argv.size(); ++i) {
std::string option = argv[i];
std::string augment;
if (i < argv.size() - 1) {
augment = argv[i + 1];
}
if (commandMap_.count(option) > 0) {
HandleCommand(option, augment);
}
}
CheckParameter();
break;
}
}
DCLCommand::DCLCommand(std::string commandLine)
{
std::istringstream ss(commandLine);
std::string param;
std::vector<std::string> params;
if (commandLine.find("drawing_ending_sample") == std::string::npos) {
params.emplace_back("drawing_engine_sample");
params.emplace_back("dcl");
}
while (ss >> param) {
params.emplace_back(param);
}
ParseCommand(params);
}
void DCLCommand::HandleCommandIterateType(const std::string& inputStr)
{
switch (std::stoi(inputStr.c_str())) {
case static_cast<int>(IterateType::ITERATE_FRAME):
iterateType_ = IterateType::ITERATE_FRAME;
break;
case static_cast<int>(IterateType::ITERATE_OPITEM):
iterateType_ = IterateType::ITERATE_OPITEM;
break;
case static_cast<int>(IterateType::ITERATE_OPITEM_MANUALLY):
iterateType_ = IterateType::ITERATE_OPITEM_MANUALLY;
break;
default:
std::cout <<"Wrong Parameter: iterateType" << std::endl;
return;
}
}
void DCLCommand::HandleCommand(std::string option, const std::string& augment)
{
int inputNum = 0;
switch (commandMap_.at(option)) {
case CommandType::CT_T:
HandleCommandIterateType(augment);
break;
case CommandType::CT_B:
inputNum = std::stoi(augment.c_str());
beginFrame_ = inputNum > 0 ? inputNum : 0;
break;
case CommandType::CT_E:
inputNum = std::stoi(augment.c_str());
endFrame_ = inputNum > 0 ? inputNum : 0;
break;
case CommandType::CT_L:
inputNum = std::stoi(augment.c_str());
loop_ = inputNum > 0 ? inputNum : 0;
break;
case CommandType::CT_S:
opItemStep_ = std::stod(augment.c_str());
opItemStep_ = opItemStep_ > 0 ? opItemStep_ : 1;
break;
case CommandType::CT_I:
inputFilePath_ = augment;
if (inputFilePath_.back() != '/') {
inputFilePath_ += '/';
}
break;
case CommandType::CT_O:
outputFilePath_ = augment;
if (outputFilePath_.back() != '/') {
outputFilePath_ += '/';
}
break;
case CommandType::CT_H:
std::cout << dclMsg_ <<std::endl;
break;
default:
std::cout << "other unknown args:" <<std::endl;
break;
}
}
void DCLCommand::CheckParameter()
{
if (beginFrame_ > endFrame_) {
std::cout << "Wrong Parameter: beginFrame or endFrame!" << std::endl;
beginFrame_ = 0;
endFrame_ = 0;
}
if (opItemStep_ < 0) {
std::cout << "Wrong Parameter: opItemStep!" << std::endl;
opItemStep_ = 1;
}
}
}
}

View File

@ -1,93 +0,0 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef DCL_COMMAND_H
#define DCL_COMMAND_H
#include <iostream>
#include <vector>
#include <unordered_map>
namespace OHOS {
namespace Rosen {
enum class IterateType {
ITERATE_FRAME,
ITERATE_OPITEM,
ITERATE_OPITEM_MANUALLY,
OTHER,
};
class DCLCommand {
public:
DCLCommand(int32_t argc, char* argv[]);
explicit DCLCommand(std::string commandLine);
~DCLCommand()= default;
void ParseCommand(std::vector<std::string> argv);
void HandleCommand(std::string option, const std::string& augment);
void HandleCommandIterateType(const std::string& inputStr);
void CheckParameter();
private:
friend class DrawingDCL;
enum class CommandType {
CT_T,
CT_B,
CT_E,
CT_L,
CT_S,
CT_I,
CT_O,
CT_H,
};
const std::unordered_map<std::string, CommandType> commandMap_ = {
{ std::string("-t"), CommandType::CT_T }, { std::string("--type"), CommandType::CT_T },
{ std::string("-b"), CommandType::CT_B }, { std::string("--beginFrame"), CommandType::CT_B },
{ std::string("-e"), CommandType::CT_E }, { std::string("--endFrame"), CommandType::CT_E },
{ std::string("-l"), CommandType::CT_L }, { std::string("--loop"), CommandType::CT_L },
{ std::string("-s"), CommandType::CT_S }, { std::string("--step"), CommandType::CT_S },
{ std::string("-i"), CommandType::CT_I }, { std::string("--inputFilePath"), CommandType::CT_I },
{ std::string("-o"), CommandType::CT_O }, { std::string("--outputFilePath"), CommandType::CT_O },
{ std::string("-h"), CommandType::CT_H }, { std::string("--help"), CommandType::CT_H },
};
const std::string dclMsgErr_ = "error input!\n use command '--help' get more information\n";
const std::string breakLine_ = std::string(80, '-');
const std::string dclMsg_ = "usage: /data/drawing_engine_sample dcl <option> <argument> \n" + breakLine_ +
"\nThere are common commands list:\n"
" -t,--type set the type of playback, \n"
" \t0: iterate by frame,\n"
" \t1: iterate by opItem,\n"
" \t2: iterate by opItem using manual control,\n"
" -b,--beginFrame set the start number of frames for playback, \n"
" -e,--beginFrame set the end number of frames for playback, \n"
" -l,--loop set the loops of iterating by frame, \n"
" -s,--step set the step when iterating by opItem "
"(the step can be a decimal), \n"
" -i,--inputFilePath set the input path for drawCmdList files, \n"
" -o,--outputFilePath set the output path for drawCmdList files, \n"
" -h,--help get help, \n" + breakLine_ +
"\nExample: /data/drawing_ening_sample dcl -t 0 -b 1 -e 100 \n" + breakLine_ + "\n";
IterateType iterateType_ = IterateType::ITERATE_FRAME;
uint32_t beginFrame_ = 0;
uint32_t endFrame_ = 100;
uint32_t loop_ = 1;
double opItemStep_ = 1;
std::string inputFilePath_ = "/data/lkx/";
std::string outputFilePath_ = "/data/lkx/";
};
}
}
#endif

View File

@ -1,318 +0,0 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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 "drawing_dcl.h"
#include <sstream>
#include <fcntl.h>
#include <unique_fd.h>
namespace OHOS {
namespace Rosen {
DrawingDCL::DrawingDCL(int32_t argc, char* argv[])
{
DCLCommand dclCommand = DCLCommand(argc, argv);
UpdateParametersFromDCLCommand(dclCommand);
}
DrawingDCL::~DrawingDCL()
{
std::cout << "~DrawingDCL" << std::endl;
delete dcl_;
}
void DrawingDCL::PrintDurationTime(const std::string & description,
std::chrono::time_point<std::chrono::system_clock> start)
{
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds> (end - start);
const double convertToMs = 1000000.0;
std::cout << description << duration.count() / convertToMs << "ms" << std::endl;
}
bool DrawingDCL::IterateFrame(int &curLoop, int &frame)
{
++frame;
if (frame > endFrame_) {
frame = beginFrame_;
if (++curLoop == loop_) {
return false;
}
}
return true;
}
bool DrawingDCL::PlayBackByFrame(SkCanvas* skiaCanvas, bool isDumpPictures)
{
//read DrawCmdList from file
if (skiaCanvas == nullptr) {
return false;
}
auto start = std::chrono::system_clock::now();
static int frame = beginFrame_;
static int curLoop = 0;
std::string dclFile = inputFilePath_ + "frame" + std::to_string(frame) + ".txt";
std::cout << "PlayBackByFrame dclFile:" << dclFile << std::endl;
if (LoadDrawCmdList(dclFile) < 0) {
std::cout << "failed to loadDrawCmdList" << std::endl;
IterateFrame(curLoop, frame);
return false;
}
PrintDurationTime("Load DrawCmdList file time is ", start);
start = std::chrono::system_clock::now();
dcl_->Playback(*skiaCanvas);
PrintDurationTime("The frame PlayBack time is ", start);
return IterateFrame(curLoop, frame);
}
bool DrawingDCL::PlayBackByOpItem(SkCanvas* skiaCanvas, bool isMoreOps)
{
if (skiaCanvas == nullptr) {
return false;
}
auto start = std::chrono::system_clock::now();
// read drawCmdList from file
std::string dclFile = inputFilePath_ + "frameByOpItem.txt";
std::cout << "PlayBackFrame dclFile:" << dclFile << std::endl;
if (LoadDrawCmdList(dclFile) < 0) {
std::cout << "failed to loadDrawCmdList" << std::endl;
return false;
}
PrintDurationTime("Load DrawCmdList file time is ", start);
// Playback
static double opitemId = 0;
double oldOpId = opitemId;
if (!isMoreOps) {
opitemId -= opItemStep_;
if (opitemId < 0) {
opitemId = 0;
}
std::cout<< "This is already the first OpItem." << std::endl;
} else {
opitemId += opItemStep_;
}
std::cout << "play back to opitemId = " << static_cast<int>(opitemId) << std::endl;
if (opitemId < dcl_->GetSize()) {
std::cout << dcl_->PlayBackForRecord(*skiaCanvas, 0, static_cast<int>(opitemId), static_cast<int>(oldOpId))
<< std::endl;
} else {
std::cout << dcl_->PlayBackForRecord(*skiaCanvas, 0, dcl_->GetSize(), static_cast<int>(oldOpId)) << std::endl;
opitemId = 0;
return false;
}
return true;
}
bool DrawingDCL::GetDirectionAndStep(std::string command, bool &isMoreOps)
{
if (command.empty()) {
return true;
}
std::vector<std::string> words;
std::stringstream ss(command);
std::string word;
while (ss >> word) {
words.emplace_back(word);
}
const size_t twoParam = 2;
if (words.size() != twoParam) {
std::cout << "Wrong Parameter!" << std::endl;
return false;
}
if (std::strcmp(words[0].c_str(), "l") == 0 || std::strcmp(words[0].c_str(), "L") == 0) {
isMoreOps = false;
} else if (std::strcmp(words[0].c_str(), "m") == 0 || std::strcmp(words[0].c_str(), "M") == 0) {
isMoreOps = true;
} else {
std::cout << "Wrong Direction!" << std::endl;
return false;
}
// check if the input for step is valid
int dotPostion = -1;
for (size_t i = 0; i < words[1].size(); ++i) {
if (words[1][i] == '.' && dotPostion == -1) {
dotPostion = i;
} else if (words[1][i] >= '0' && words[1][i] <= '9') {
continue;
} else {
std::cout << "Please enter right step!" << std::endl;
return false;
}
}
opItemStep_ = std::stod(words[1]);
return true;
}
void DrawingDCL::UpdateParametersFromDCLCommand(const DCLCommand &dclCommand)
{
iterateType = dclCommand.iterateType_;
beginFrame_ = dclCommand.beginFrame_;
endFrame_ = dclCommand.endFrame_;
loop_ = dclCommand.loop_;
opItemStep_ = dclCommand.opItemStep_;
inputFilePath_ = dclCommand.inputFilePath_;
outputFilePath_ = dclCommand.outputFilePath_;
}
void DrawingDCL::UpdateParameters(bool notNeeded)
{
if (notNeeded) {
return;
}
std::cout << "Please re-enter the parameters" << std::endl;
std::string line;
getline(std::cin, line);
if (line.empty()) {
return;
}
DCLCommand dclCommand = DCLCommand(line);
UpdateParametersFromDCLCommand(dclCommand);
}
void DrawingDCL::Test(SkCanvas* canvas, int width, int height)
{
std::cout << "DrawingDCL::Test+" << std::endl;
auto start = std::chrono::system_clock::now();
switch (iterateType) {
case IterateType::ITERATE_FRAME:
UpdateParameters(PlayBackByFrame(canvas));
break;
case IterateType::ITERATE_OPITEM:
UpdateParameters(PlayBackByOpItem(canvas));
break;
case IterateType::ITERATE_OPITEM_MANUALLY: {
static bool isMoreOps = true;
std::string opActionsStr = isMoreOps ? "more" : "less";
std::cout << "Do you want to execute " << opItemStep_ << " OpItems " << opActionsStr << " ?\n"
"To Modify, enter the action (More or less) and step size, for example, \"M 2\". \n"
" Press Enter to continue." << std::endl;
std::string line;
do {
getline(std::cin, line);
} while (!GetDirectionAndStep(line, isMoreOps));
UpdateParameters(PlayBackByOpItem(canvas, isMoreOps));
break;
}
case IterateType::OTHER:
std::cout << "Unknown iteratetype, please reenter parameters!" << std::endl;
break;
default:
std::cout << "Wrong iteratetype!" << std::endl;
break;
}
PrintDurationTime("This frame draw time is: ", start);
std::cout << "DrawingDCL::Test-" << std::endl;
}
void DrawingDCL::Output()
{
}
class MyAllocator : public DefaultAllocator {
public:
MyAllocator(int fd, size_t size, uint8_t* mapFile) : fd_(fd), size_(size), mapFile_(mapFile) {}
~MyAllocator()
{
Dealloc(mapFile_);
}
void Dealloc(void *mapFile)
{
if (mapFile != mapFile_) {
std::cout << "MyAllocator::Dealloc data addr not match!" << std::endl;
}
if (mapFile_ != nullptr) {
if (::munmap(mapFile_, size_) == -1) {
std::cout << "munmap failed!" <<std::endl;
}
mapFile_ = nullptr;
}
if (fd_ > 0) {
::close(fd_);
fd_ = -1;
}
}
private:
int fd_;
size_t size_;
uint8_t *mapFile_;
};
std::string DrawingDCL::GetRealPathStr(const std::string& filePath)
{
std::string realPathStr = "";
char actualPath[PATH_MAX + 1] = {0};
if (realpath(filePath.c_str(), actualPath) == nullptr) {
std::cout << "The path of DrawCmdList file is empty!" << std::endl;
return realPathStr;
}
realPathStr = actualPath;
return realPathStr;
}
bool DrawingDCL::IsValidFile(const std::string& realPathStr)
{
return realPathStr.find(dclFileDir_) == 0;
}
int DrawingDCL::LoadDrawCmdList(const std::string& dclFile)
{
std::string realDclFilePathStr = GetRealPathStr(dclFile);
if (realDclFilePathStr.empty()) {
return -1;
}
if (!IsValidFile(realDclFilePathStr)) {
std::cout << "The path of DrawCmdList file is not valid!" << std::endl;
return -1;
}
UniqueFd fd(open(realDclFilePathStr.c_str(), O_RDONLY));
if (fd.Get() < 0) {
std::cout << "Open file failed" << dclFile.c_str() << std::endl;
return -1;
}
struct stat statbuf;
if (fstat(fd.Get(), &statbuf) < 0) {
return -1;
}
std::cout << "statbuf.st_size = " << statbuf.st_size << std::endl;
auto mapFile = static_cast<uint8_t *>(mmap(nullptr, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
if (mapFile == MAP_FAILED) {
return -1;
}
std::cout << "mapFile OK" << std::endl;
MessageParcel messageParcel(new MyAllocator(fd.Get(), statbuf.st_size, mapFile));
messageParcel.SetMaxCapacity(recordingParcelMaxCapcity_);
if (!messageParcel.ParseFrom(reinterpret_cast<uintptr_t>(mapFile), statbuf.st_size)) {
munmap(mapFile, statbuf.st_size);
return -1;
}
std::cout << "messageParcel GetDataSize() = " << messageParcel.GetDataSize() << std::endl;
dcl_ = DrawCmdList::Unmarshalling(messageParcel);
if (dcl_ == nullptr) {
std::cout << "dcl is nullptr" << std::endl;
munmap(mapFile, statbuf.st_size);
return -1;
}
std::cout << "The size of Ops is " << dcl_->GetSize() << std::endl;
munmap(mapFile, statbuf.st_size);
return 0;
}
}
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef DRAWING_DCL_H
#define DRAWING_DCL_H
#include <chrono>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <message_parcel.h>
#include "pipeline/rs_draw_cmd_list.h"
#include "benchmark.h"
#include "dcl_command.h"
namespace OHOS {
namespace Rosen {
class DrawingDCL : public BenchMark {
public:
DrawingDCL() { std::cout << "DrawingDCL" << std::endl; }
DrawingDCL(int32_t argc, char* argv[]);
~DrawingDCL();
bool GetDirectionAndStep(std::string command, bool &isMoreOps);
bool IterateFrame(int &curLoop, int &frame);
bool PlayBackByFrame(SkCanvas *skiaCanvas, bool isDumpPictures = false);
bool PlayBackByOpItem(SkCanvas *skiaCanvas, bool isMoreOps = true);
void UpdateParameters(bool notNeeded);
void UpdateParametersFromDCLCommand(const DCLCommand& dclCommand);
void PrintDurationTime(const std::string &description, std::chrono::time_point<std::chrono::system_clock> start);
void Start() override {};
void Stop() override {};
void Test(SkCanvas *canvas, int width, int height) override;
void Output() override;
int LoadDrawCmdList(const std::string& dclFile);
std::string GetRealPathStr(const std::string& filePath);
bool IsValidFile(const std::string& realPathStr);
private:
friend class DCLCommand;
const static size_t recordingParcelMaxCapcity_ = 234 * 1000 * 1024;
inline const static std::string dclFileDir_ = "/data/";
DrawCmdList* dcl_ = nullptr;
IterateType iterateType = IterateType::ITERATE_FRAME;
int beginFrame_ = 0;
int endFrame_ = 100;
int loop_ = 1;
double opItemStep_ = 1;
std::string inputFilePath_ = "/data/lkx/";
std::string outputFilePath_ = "/data/lkx/";
};
}
}
#endif

View File

@ -22,7 +22,7 @@
#include "drawing_multithread.h"
#include "drawing_singlethread.h"
#include "drawing_api.h"
#include "drawing_dcl.h"
#include "drawing_playback.h"
using namespace OHOS;
using namespace OHOS::Rosen;