mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2024-11-24 07:30:38 +00:00
新增性能雷达打点
Signed-off-by: jason <zhoujianghao@huawei.com> Change-Id: I004793205b8626633e5174f41644046480afe7fd
This commit is contained in:
parent
4fce48ae86
commit
0f505e5d05
@ -74,3 +74,52 @@ JANK_STATS_RS:
|
||||
DURATION: {type: INT64, desc: duration since last report}
|
||||
JANK_STATS: {type: UINT16, desc: jank frame stats}
|
||||
JANK_STATS_VER: {type: UINT32, desc: jank range version}
|
||||
|
||||
INTERACTION_RESPONSE_LATENCY:
|
||||
__BASE: {type: STATISTIC, level: MINOR, tag: performance, desc: interaction response statistics}
|
||||
BUNDLE_NAME: {type: STRING, desc: package name}
|
||||
ABILITY_NAME: {type: STRING, desc: ability name}
|
||||
PROCESS_NAME: {type: STRING, desc: process name}
|
||||
PAGE_URL: {type: STRING, desc: page url}
|
||||
SCENE_ID: {type: STRING, desc: interation scene id}
|
||||
INPUT_TIME: {type: INT64, desc: input time when multimodel receive from kernel}
|
||||
ANIMATION_START_TIME: {type: INT64, desc: animation start time of the scene}
|
||||
RENDER_TIME: {type: INT64, desc: render time of the scene}
|
||||
RESPONSE_LATENCY: {type: INT64, desc: render time minus input time}
|
||||
|
||||
INTERACTION_COMPLETED_LATENCY:
|
||||
__BASE: {type: STATISTIC, level: MINOR, tag: performance, desc: interaction response statistics}
|
||||
APP_PID: {type: INT32, desc: app process id}
|
||||
BUNDLE_NAME: {type: STRING, desc: package name}
|
||||
ABILITY_NAME: {type: STRING, desc: ability name}
|
||||
PROCESS_NAME: {type: STRING, desc: process name}
|
||||
PAGE_URL: {type: STRING, desc: page url}
|
||||
SCENE_ID: {type: STRING, desc: interation scene id}
|
||||
INPUT_TIME: {type: INT64, desc: input time when multimodel receive from kernel}
|
||||
ANIMATION_START_LATENCY: {type: INT64, desc: animation start time minus input time}
|
||||
ANIMATION_END_LATENCY: {type: INT64, desc: end time of the scene}
|
||||
E2E_LATENCY: {type: INT64, desc: end to end time}
|
||||
|
||||
INTERACTION_RENDER_JANK:
|
||||
__BASE: {type: STATISTIC, level: MINOR, tag: performance, desc: interaction jank statistics}
|
||||
UNIQUE_ID: {type: INT32, desc: unique id}
|
||||
SCENE_ID: {type: STRING, desc: interation scene id}
|
||||
PROCESS_NAME: {type: STRING, desc: process name}
|
||||
MODULE_NAME: {type: STRING, desc: package name}
|
||||
ABILITY_NAME: {type: STRING, desc: ability name}
|
||||
PAGE_URL: {type: STRING, desc: page url}
|
||||
TOTAL_FRAMES: {type: INT32, desc: total frames}
|
||||
TOTAL_MISSED_FRAMES: {type: INT32, desc: total missed frames during the scene}
|
||||
MAX_FRAMETIME: {type: INT64, desc: max single frame time during the scene}
|
||||
MAX_SEQ_MISSED_FRAMES: {type: INT32, desc: max successive missed frames during the scene}
|
||||
IS_FOLD_DISP: {type: BOOL, desc: default false, set true if fold screen in expand state}
|
||||
|
||||
FIRST_FRAME_DRAWN:
|
||||
__BASE: {type: STATISTIC, level: MINOR, tag: performance, desc: interaction jank statistics}
|
||||
APP_PID: {type: INT32, desc: app process id}
|
||||
VERSION_CODE: {type: STRING, desc: version code}
|
||||
VERSION_NAME: {type: STRING, desc: version name}
|
||||
PROCESS_NAME: {type: STRING, desc: process name}
|
||||
BUNDLE_NAME: {type: STRING, desc: package name}
|
||||
ABILITY_NAME: {type: STRING, desc: ability name}
|
||||
PAGE_URL: {type: STRING, desc: page url}
|
@ -37,7 +37,6 @@ ohos_shared_library("librender_service") {
|
||||
"core/pipeline/rs_composer_adapter.cpp",
|
||||
"core/pipeline/rs_divided_render_util.cpp",
|
||||
"core/pipeline/rs_hardware_thread.cpp",
|
||||
"core/pipeline/rs_jank_stats.cpp",
|
||||
"core/pipeline/rs_main_thread.cpp",
|
||||
"core/pipeline/rs_physical_screen_processor.cpp",
|
||||
"core/pipeline/rs_processor.cpp",
|
||||
|
@ -1,105 +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 "rs_jank_stats.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hisysevent.h"
|
||||
|
||||
#include "platform/common/rs_log.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
namespace {
|
||||
constexpr float VSYNC_PERIOD = 16.6; // ms
|
||||
}
|
||||
|
||||
RSJankStats& RSJankStats::GetInstance()
|
||||
{
|
||||
static RSJankStats instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void RSJankStats::SetStartTime()
|
||||
{
|
||||
auto start = std::chrono::system_clock::now().time_since_epoch();
|
||||
startTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(start).count();
|
||||
if (isfirstSetStart_) {
|
||||
lastReportTime_ = startTime_;
|
||||
isfirstSetStart_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RSJankStats::SetEndTime()
|
||||
{
|
||||
auto end = std::chrono::system_clock::now().time_since_epoch();
|
||||
endTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(end).count();
|
||||
auto duration = endTime_ - startTime_;
|
||||
if (duration >= VSYNC_PERIOD) {
|
||||
SetRSJankStats(static_cast<int>(duration / VSYNC_PERIOD));
|
||||
}
|
||||
}
|
||||
|
||||
void RSJankStats::SetRSJankStats(int times)
|
||||
{
|
||||
auto type = JankRangeType::JANK_FRAME_INVALID;
|
||||
if (times < 6) { // JANK_FRAME_6_FREQ : (0,6)
|
||||
type = JANK_FRAME_6_FREQ;
|
||||
} else if (times < 15) { // JANK_FRAME_15_FREQ : [6,15)
|
||||
type = JANK_FRAME_15_FREQ;
|
||||
} else if (times < 20) { // JANK_FRAME_20_FREQ : [15,20)
|
||||
type = JANK_FRAME_20_FREQ;
|
||||
} else if (times < 36) { // JANK_FRAME_36_FREQ : [20,36)
|
||||
type = JANK_FRAME_36_FREQ;
|
||||
} else if (times < 48) { // JANK_FRAME_48_FREQ : [36,48)
|
||||
type = JANK_FRAME_48_FREQ;
|
||||
} else if (times < 60) { // JANK_FRAME_60_FREQ : [48,60)
|
||||
type = JANK_FRAME_60_FREQ;
|
||||
} else if (times < 120) { // JANK_FRAME_120_FREQ : [60,120)
|
||||
type = JANK_FRAME_120_FREQ;
|
||||
} else if (times < 180) { // JANK_FRAME_180_FREQ : [120,180)
|
||||
type = JANK_FRAME_180_FREQ;
|
||||
} else {
|
||||
ROSEN_LOGW("RSInterfaces::SetJankStatas Jank Frame Skip more than 180");
|
||||
return;
|
||||
}
|
||||
if (rsJankStats_[type] != USHRT_MAX) {
|
||||
rsJankStats_[type]++;
|
||||
}
|
||||
isNeedReport_ = true;
|
||||
}
|
||||
|
||||
void RSJankStats::ReportJankStats()
|
||||
{
|
||||
if (!isNeedReport_) {
|
||||
ROSEN_LOGW("RSInterfaces::ReportJankStats Nothing need to report");
|
||||
return;
|
||||
}
|
||||
auto report = std::chrono::system_clock::now().time_since_epoch();
|
||||
auto reportTime = std::chrono::duration_cast<std::chrono::milliseconds>(report).count();
|
||||
auto reportDuration = reportTime - lastReportTime_;
|
||||
auto reportName = "JANK_STATS_RS";
|
||||
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, reportName,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "STARTTIME", lastReportTime_, "DURATION", reportDuration,
|
||||
"JANK_STATS", rsJankStats_, "JANK_STATS_VER", 1);
|
||||
std::fill(rsJankStats_.begin(), rsJankStats_.end(), 0);
|
||||
lastReportTime_ = reportTime;
|
||||
isNeedReport_ = false;
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -34,6 +34,7 @@
|
||||
#include "memory/rs_memory_manager.h"
|
||||
#include "memory/rs_memory_track.h"
|
||||
#include "common/rs_common_def.h"
|
||||
#include "platform/ohos/rs_jank_stats.h"
|
||||
#include "platform/ohos/overdraw/rs_overdraw_controller.h"
|
||||
#include "pipeline/rs_base_render_node.h"
|
||||
#include "pipeline/rs_base_render_util.h"
|
||||
@ -44,7 +45,6 @@
|
||||
#include "pipeline/rs_render_service_visitor.h"
|
||||
#include "pipeline/rs_root_render_node.h"
|
||||
#include "pipeline/rs_hardware_thread.h"
|
||||
#include "pipeline/rs_jank_stats.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
#include "pipeline/rs_unmarshal_thread.h"
|
||||
#include "pipeline/rs_uni_render_engine.h"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "pipeline/rs_uni_render_judgement.h"
|
||||
#include "pipeline/rs_uni_ui_capture.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "rs_jank_stats.h"
|
||||
#include "platform/ohos/rs_jank_stats.h"
|
||||
#include "rs_main_thread.h"
|
||||
#include "rs_trace.h"
|
||||
|
||||
@ -804,5 +804,37 @@ void RSRenderServiceConnection::ReportJankStats()
|
||||
auto task = [this]() -> void { RSJankStats::GetInstance().ReportJankStats(); };
|
||||
mainThread_->PostTask(task);
|
||||
}
|
||||
|
||||
void RSRenderServiceConnection::ReportEventResponse(DataBaseRs info)
|
||||
{
|
||||
auto task = [this, info]() -> void {
|
||||
RSJankStats::GetInstance().SetReportEventResponse(info);
|
||||
};
|
||||
mainThread_->PostTask(task);
|
||||
}
|
||||
|
||||
void RSRenderServiceConnection::ReportEventComplete(DataBaseRs info)
|
||||
{
|
||||
auto task = [this, info]() -> void {
|
||||
RSJankStats::GetInstance().SetReportEventComplete(info);
|
||||
};
|
||||
mainThread_->PostTask(task);
|
||||
}
|
||||
|
||||
void RSRenderServiceConnection::ReportEventJankFrame(DataBaseRs info)
|
||||
{
|
||||
auto task = [this, info]() -> void {
|
||||
RSJankStats::GetInstance().SetReportEventJankFrame(info);
|
||||
};
|
||||
mainThread_->PostTask(task);
|
||||
}
|
||||
|
||||
void RSRenderServiceConnection::ReportEventFirstFrame(DataBaseRs info)
|
||||
{
|
||||
auto task = [this, info]() -> void {
|
||||
RSJankStats::GetInstance().SetReportEventFirstFrame(info);
|
||||
};
|
||||
mainThread_->PostTask(task);
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -155,6 +155,14 @@ private:
|
||||
|
||||
void ReportJankStats() override;
|
||||
|
||||
void ReportEventResponse(DataBaseRs info) override;
|
||||
|
||||
void ReportEventComplete(DataBaseRs info) override;
|
||||
|
||||
void ReportEventJankFrame(DataBaseRs info) override;
|
||||
|
||||
void ReportEventFirstFrame(DataBaseRs info) override;
|
||||
|
||||
pid_t remotePid_;
|
||||
wptr<RSRenderService> renderService_;
|
||||
RSMainThread* mainThread_ = nullptr;
|
||||
|
@ -749,6 +749,50 @@ int RSRenderServiceConnectionStub::OnRemoteRequest(
|
||||
ReportJankStats();
|
||||
break;
|
||||
}
|
||||
case REPORT_EVENT_RESPONSE: {
|
||||
auto token = data.ReadInterfaceToken();
|
||||
if (token != RSIRenderServiceConnection::GetDescriptor()) {
|
||||
ret = ERR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
DataBaseRs info;
|
||||
ReadDataBaseRs(info, data);
|
||||
ReportEventResponse(info);
|
||||
break;
|
||||
}
|
||||
case REPORT_EVENT_COMPLETE: {
|
||||
auto token = data.ReadInterfaceToken();
|
||||
if (token != RSIRenderServiceConnection::GetDescriptor()) {
|
||||
ret = ERR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
DataBaseRs info;
|
||||
ReadDataBaseRs(info, data);
|
||||
ReportEventComplete(info);
|
||||
break;
|
||||
}
|
||||
case REPORT_EVENT_JANK_FRAME: {
|
||||
auto token = data.ReadInterfaceToken();
|
||||
if (token != RSIRenderServiceConnection::GetDescriptor()) {
|
||||
ret = ERR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
DataBaseRs info;
|
||||
ReadDataBaseRs(info, data);
|
||||
ReportEventJankFrame(info);
|
||||
break;
|
||||
}
|
||||
case REPORT_EVENT_FIRST_FRAME: {
|
||||
auto token = data.ReadInterfaceToken();
|
||||
if (token != RSIRenderServiceConnection::GetDescriptor()) {
|
||||
ret = ERR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
DataBaseRs info;
|
||||
ReadDataBaseRs(info, data);
|
||||
ReportEventFirstFrame(info);
|
||||
break;
|
||||
}
|
||||
case EXECUTE_SYNCHRONOUS_TASK: {
|
||||
auto token = data.ReadInterfaceToken();
|
||||
if (token != RSIRenderServiceConnection::GetDescriptor()) {
|
||||
@ -785,5 +829,21 @@ int RSRenderServiceConnectionStub::OnRemoteRequest(
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RSRenderServiceConnectionStub::ReadDataBaseRs(DataBaseRs& info, MessageParcel& data)
|
||||
{
|
||||
info.appPid = data.ReadInt32();
|
||||
info.eventType = data.ReadInt32();
|
||||
info.uniqueId = data.ReadInt64();
|
||||
info.inputTime = data.ReadInt64();
|
||||
info.beginVsyncTime = data.ReadInt64();
|
||||
info.endVsyncTime = data.ReadInt64();
|
||||
info.versionCode = data.ReadString();
|
||||
info.versionName = data.ReadString();
|
||||
info.bundleName = data.ReadString();
|
||||
info.processName = data.ReadString();
|
||||
info.abilityName = data.ReadString();
|
||||
info.pageUrl = data.ReadString();
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -30,6 +30,9 @@ public:
|
||||
~RSRenderServiceConnectionStub() noexcept = default;
|
||||
|
||||
int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override;
|
||||
|
||||
private:
|
||||
void ReadDataBaseRs(DataBaseRs& info, MessageParcel& data);
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
return id_;
|
||||
}
|
||||
|
||||
void SetIsOnTheTree(bool flag);
|
||||
virtual void SetIsOnTheTree(bool flag);
|
||||
bool IsOnTheTree() const
|
||||
{
|
||||
return isOnTheTree_;
|
||||
|
@ -66,6 +66,9 @@ public:
|
||||
void PrepareRenderAfterChildren(RSPaintFilterCanvas& canvas);
|
||||
void ResetParent() override;
|
||||
|
||||
#ifdef OHOS_PLATFORM
|
||||
void SetIsOnTheTree(bool flag) override;
|
||||
#endif
|
||||
bool IsAppWindow() const
|
||||
{
|
||||
return nodeType_ == RSSurfaceNodeType::APP_WINDOW_NODE;
|
||||
@ -689,6 +692,7 @@ private:
|
||||
|
||||
bool isSecurityLayer_ = false;
|
||||
bool hasFingerprint_ = false;
|
||||
bool isReportFirstFrame_ = false;
|
||||
RectI srcRect_;
|
||||
#ifndef USE_ROSEN_DRAWING
|
||||
SkMatrix totalMatrix_;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "screen_manager/screen_types.h"
|
||||
#include "screen_manager/rs_virtual_screen_resolution.h"
|
||||
#include "transaction/rs_transaction_data.h"
|
||||
#include "transaction/rs_render_service_client.h"
|
||||
#include "ivsync_connection.h"
|
||||
#include "ipc_callbacks/rs_iocclusion_change_callback.h"
|
||||
|
||||
@ -95,6 +96,10 @@ public:
|
||||
REPORT_JANK_STATS,
|
||||
GET_BITMAP,
|
||||
EXECUTE_SYNCHRONOUS_TASK,
|
||||
REPORT_EVENT_RESPONSE,
|
||||
REPORT_EVENT_COMPLETE,
|
||||
REPORT_EVENT_JANK_FRAME,
|
||||
REPORT_EVENT_FIRST_FRAME,
|
||||
};
|
||||
|
||||
virtual void CommitTransaction(std::unique_ptr<RSTransactionData>& transactionData) = 0;
|
||||
@ -199,6 +204,14 @@ public:
|
||||
virtual void ShowWatermark(const std::shared_ptr<Media::PixelMap> &watermarkImg, bool isShow) = 0;
|
||||
|
||||
virtual void ReportJankStats() = 0;
|
||||
|
||||
virtual void ReportEventResponse(DataBaseRs info) = 0;
|
||||
|
||||
virtual void ReportEventComplete(DataBaseRs info) = 0;
|
||||
|
||||
virtual void ReportEventJankFrame(DataBaseRs info) = 0;
|
||||
|
||||
virtual void ReportEventFirstFrame(DataBaseRs info) = 0;
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -17,8 +17,11 @@
|
||||
#define ROSEN_JANK_STATS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "transaction/rs_render_service_client.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class RSJankStats {
|
||||
@ -27,7 +30,18 @@ public:
|
||||
void SetStartTime();
|
||||
void SetEndTime();
|
||||
void SetRSJankStats(int times);
|
||||
void UpdateJankFrame(int64_t duration);
|
||||
void ReportJankStats();
|
||||
void SetReportEventResponse(DataBaseRs info);
|
||||
void SetReportEventComplete(DataBaseRs info);
|
||||
void SetReportEventJankFrame(DataBaseRs info);
|
||||
void SetReportEventFirstFrame(DataBaseRs info);
|
||||
void ReportEventResponse();
|
||||
void ReportEventComplete();
|
||||
void ReportEventJankFrame();
|
||||
void ReportEventFirstFrame();
|
||||
void SetFirstFrame();
|
||||
void SetPid(uint32_t pid);
|
||||
|
||||
private:
|
||||
RSJankStats() {};
|
||||
@ -42,6 +56,21 @@ private:
|
||||
int64_t startTime_ = 0;
|
||||
int64_t endTime_ = 0;
|
||||
int64_t lastReportTime_ = 0;
|
||||
bool isSetReportEventResponse_ = false;
|
||||
bool isSetReportEventComplete_ = false;
|
||||
bool isReportEventResponse_ = false;
|
||||
bool isReportEventComplete_ = false;
|
||||
bool isSetReportEventJankFrame_ = false;
|
||||
bool isSetReportEventFirstFrame_ = false;
|
||||
bool isFirstFrame_ = false;
|
||||
bool isUpdateJankFrame_ = false;
|
||||
int32_t totalFrames_ = 0;
|
||||
int32_t totalMissedFrames_ = 0;
|
||||
int64_t maxFrameTime_ = 0;
|
||||
int32_t maxSeqMissedFrames_ = 0;
|
||||
int32_t appPid_ = 0;
|
||||
|
||||
DataBaseRs info_;
|
||||
std::vector<uint16_t> rsJankStats_ = std::vector<uint16_t>(JANK_STATS_SIZE, 0);
|
||||
|
||||
enum JankRangeType : int16_t {
|
@ -52,6 +52,23 @@ namespace Rosen {
|
||||
using ScreenChangeCallback = std::function<void(ScreenId, ScreenEvent)>;
|
||||
using BufferAvailableCallback = std::function<void()>;
|
||||
using OcclusionChangeCallback = std::function<void(std::shared_ptr<RSOcclusionData>)>;
|
||||
|
||||
struct DataBaseRs {
|
||||
int32_t appPid = -1;
|
||||
int32_t eventType = -1;
|
||||
int64_t uniqueId = 0;
|
||||
int64_t inputTime = 0;
|
||||
int64_t beginVsyncTime = 0;
|
||||
int64_t endVsyncTime = 0;
|
||||
std::string sceneId;
|
||||
std::string versionCode;
|
||||
std::string versionName;
|
||||
std::string bundleName;
|
||||
std::string processName;
|
||||
std::string abilityName;
|
||||
std::string pageUrl;
|
||||
};
|
||||
|
||||
class SurfaceCaptureCallback {
|
||||
public:
|
||||
SurfaceCaptureCallback() {}
|
||||
@ -171,6 +188,15 @@ public:
|
||||
void ShowWatermark(const std::shared_ptr<Media::PixelMap> &watermarkImg, bool isShow);
|
||||
|
||||
void ReportJankStats();
|
||||
|
||||
void ReportEventResponse(DataBaseRs info);
|
||||
|
||||
void ReportEventComplete(DataBaseRs info);
|
||||
|
||||
void ReportEventJankFrame(DataBaseRs info);
|
||||
|
||||
void ReportEventFirstFrame(DataBaseRs info);
|
||||
|
||||
private:
|
||||
void TriggerSurfaceCaptureCallback(NodeId id, Media::PixelMap* pixelmap);
|
||||
std::mutex mutex_;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include "command/rs_surface_node_command.h"
|
||||
#include "common/rs_common_def.h"
|
||||
#include "common/rs_obj_abs_geometry.h"
|
||||
#include "common/rs_rect.h"
|
||||
#include "common/rs_vector2.h"
|
||||
@ -34,6 +35,7 @@
|
||||
#include "pipeline/rs_render_node.h"
|
||||
#include "pipeline/rs_root_render_node.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "platform/ohos/rs_jank_stats.h"
|
||||
#include "property/rs_properties_painter.h"
|
||||
#include "render/rs_skia_filter.h"
|
||||
#include "transaction/rs_render_service_client.h"
|
||||
@ -1183,5 +1185,19 @@ void RSSurfaceRenderNode::UpdateCacheSurfaceDirtyManager(int bufferAge)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OHOS_PLATFORM
|
||||
void RSSurfaceRenderNode::SetIsOnTheTree(bool flag)
|
||||
{
|
||||
RSBaseRenderNode::SetIsOnTheTree(flag);
|
||||
if (flag == isReportFirstFrame_ || !IsAppWindow()) {
|
||||
return;
|
||||
}
|
||||
if (flag) {
|
||||
RSJankStats::GetInstance().SetFirstFrame();
|
||||
RSJankStats::GetInstance().SetPid(ExtractPid(GetId()));
|
||||
}
|
||||
isReportFirstFrame_ = flag;
|
||||
}
|
||||
#endif
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -281,5 +281,21 @@ void RSRenderServiceClient::ShowWatermark(const std::shared_ptr<Media::PixelMap>
|
||||
void RSRenderServiceClient::ReportJankStats()
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventResponse(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventComplete(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventJankFrame(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventFirstFrame(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -52,6 +52,7 @@ ohos_source_set("rosen_ohos_sources") {
|
||||
"rs_event_manager.cpp",
|
||||
"rs_frame_report.cpp",
|
||||
"rs_innovation.cpp",
|
||||
"rs_jank_stats.cpp",
|
||||
"rs_log.cpp",
|
||||
"rs_marshalling_helper.cpp",
|
||||
"rs_render_service_client.cpp",
|
||||
|
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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 "platform/ohos/rs_jank_stats.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hisysevent.h"
|
||||
|
||||
#include "platform/common/rs_log.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
namespace {
|
||||
constexpr float VSYNC_PERIOD = 16.6; // ms
|
||||
}
|
||||
|
||||
RSJankStats& RSJankStats::GetInstance()
|
||||
{
|
||||
static RSJankStats instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void RSJankStats::SetStartTime()
|
||||
{
|
||||
isReportEventResponse_ = isSetReportEventResponse_;
|
||||
isReportEventComplete_ = isSetReportEventComplete_;
|
||||
auto start = std::chrono::system_clock::now().time_since_epoch();
|
||||
startTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(start).count();
|
||||
if (isfirstSetStart_) {
|
||||
lastReportTime_ = startTime_;
|
||||
isfirstSetStart_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RSJankStats::SetEndTime()
|
||||
{
|
||||
auto end = std::chrono::system_clock::now().time_since_epoch();
|
||||
endTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(end).count();
|
||||
auto duration = endTime_ - startTime_;
|
||||
if (duration >= VSYNC_PERIOD) {
|
||||
SetRSJankStats(static_cast<int>(duration / VSYNC_PERIOD));
|
||||
}
|
||||
if (isReportEventResponse_) {
|
||||
ReportEventResponse();
|
||||
isUpdateJankFrame_ = true;
|
||||
}
|
||||
if (isUpdateJankFrame_) {
|
||||
UpdateJankFrame(duration);
|
||||
}
|
||||
if (isReportEventComplete_) {
|
||||
ReportEventComplete();
|
||||
}
|
||||
if (isSetReportEventJankFrame_) {
|
||||
ReportEventJankFrame();
|
||||
}
|
||||
if (isSetReportEventFirstFrame_ && isFirstFrame_) {
|
||||
ReportEventFirstFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void RSJankStats::SetRSJankStats(int times)
|
||||
{
|
||||
auto type = JankRangeType::JANK_FRAME_INVALID;
|
||||
if (times < 6) { // JANK_FRAME_6_FREQ : (0,6)
|
||||
type = JANK_FRAME_6_FREQ;
|
||||
} else if (times < 15) { // JANK_FRAME_15_FREQ : [6,15)
|
||||
type = JANK_FRAME_15_FREQ;
|
||||
} else if (times < 20) { // JANK_FRAME_20_FREQ : [15,20)
|
||||
type = JANK_FRAME_20_FREQ;
|
||||
} else if (times < 36) { // JANK_FRAME_36_FREQ : [20,36)
|
||||
type = JANK_FRAME_36_FREQ;
|
||||
} else if (times < 48) { // JANK_FRAME_48_FREQ : [36,48)
|
||||
type = JANK_FRAME_48_FREQ;
|
||||
} else if (times < 60) { // JANK_FRAME_60_FREQ : [48,60)
|
||||
type = JANK_FRAME_60_FREQ;
|
||||
} else if (times < 120) { // JANK_FRAME_120_FREQ : [60,120)
|
||||
type = JANK_FRAME_120_FREQ;
|
||||
} else if (times < 180) { // JANK_FRAME_180_FREQ : [120,180)
|
||||
type = JANK_FRAME_180_FREQ;
|
||||
} else {
|
||||
ROSEN_LOGW("RSInterfaces::SetJankStatas Jank Frame Skip more than 180");
|
||||
return;
|
||||
}
|
||||
if (rsJankStats_[type] != USHRT_MAX) {
|
||||
rsJankStats_[type]++;
|
||||
}
|
||||
isNeedReport_ = true;
|
||||
}
|
||||
|
||||
void RSJankStats::UpdateJankFrame(int64_t duration)
|
||||
{
|
||||
totalFrames_++;
|
||||
maxFrameTime_ = std::max(maxFrameTime_, duration);
|
||||
if (duration >= VSYNC_PERIOD) {
|
||||
totalMissedFrames_++;
|
||||
maxSeqMissedFrames_ = std::max(maxSeqMissedFrames_, static_cast<int>(duration / VSYNC_PERIOD));
|
||||
}
|
||||
}
|
||||
|
||||
void RSJankStats::ReportJankStats()
|
||||
{
|
||||
if (!isNeedReport_) {
|
||||
ROSEN_LOGW("RSInterfaces::ReportJankStats Nothing need to report");
|
||||
return;
|
||||
}
|
||||
auto report = std::chrono::system_clock::now().time_since_epoch();
|
||||
auto reportTime = std::chrono::duration_cast<std::chrono::milliseconds>(report).count();
|
||||
auto reportDuration = reportTime - lastReportTime_;
|
||||
auto reportName = "JANK_STATS_RS";
|
||||
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, reportName,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "STARTTIME", lastReportTime_, "DURATION", reportDuration,
|
||||
"JANK_STATS", rsJankStats_, "JANK_STATS_VER", 1);
|
||||
std::fill(rsJankStats_.begin(), rsJankStats_.end(), 0);
|
||||
lastReportTime_ = reportTime;
|
||||
isNeedReport_ = false;
|
||||
}
|
||||
|
||||
void RSJankStats::SetReportEventResponse(DataBaseRs info)
|
||||
{
|
||||
info_ = info;
|
||||
isSetReportEventResponse_ = true;
|
||||
}
|
||||
|
||||
void RSJankStats::SetReportEventComplete(DataBaseRs info)
|
||||
{
|
||||
info_ = info;
|
||||
isSetReportEventComplete_ = true;
|
||||
}
|
||||
|
||||
void RSJankStats::SetReportEventJankFrame(DataBaseRs info)
|
||||
{
|
||||
info_ = info;
|
||||
isSetReportEventJankFrame_ = true;
|
||||
}
|
||||
|
||||
void RSJankStats::SetReportEventFirstFrame(DataBaseRs info)
|
||||
{
|
||||
info_ = info;
|
||||
isSetReportEventFirstFrame_ = true;
|
||||
}
|
||||
|
||||
void RSJankStats::SetFirstFrame()
|
||||
{
|
||||
isFirstFrame_ = true;
|
||||
}
|
||||
|
||||
void RSJankStats::SetPid(uint32_t pid)
|
||||
{
|
||||
appPid_ = pid;
|
||||
}
|
||||
|
||||
void RSJankStats::ReportEventResponse()
|
||||
{
|
||||
auto reportName = "INTERACTION_RESPONSE_LATENCY";
|
||||
auto responseLatency = endTime_ - info_.inputTime;
|
||||
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, reportName,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "BUNDLE_NAME", info_.bundleName, "ABILITY_NAME",
|
||||
info_.abilityName, "PROCESS_NAME", info_.processName, "PAGE_URL", info_.pageUrl, "SCENE_ID", info_.sceneId,
|
||||
"INPUT_TIME", info_.inputTime, "ANIMATION_START_TIME", info_.beginVsyncTime, "RENDER_TIME", endTime_,
|
||||
"RESPONSE_LATENCY", responseLatency);
|
||||
isSetReportEventResponse_ = false;
|
||||
}
|
||||
|
||||
void RSJankStats::ReportEventComplete()
|
||||
{
|
||||
auto reportName = "INTERACTION_COMPLETED_LATENCY";
|
||||
auto animationStartLatency = info_.beginVsyncTime - info_.inputTime;
|
||||
auto animationEndLatency = info_.endVsyncTime - info_.beginVsyncTime;
|
||||
auto completedLatency = endTime_ - info_.inputTime;
|
||||
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, reportName,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_PID", info_.appPid, "BUNDLE_NAME", info_.bundleName,
|
||||
"ABILITY_NAME", info_.abilityName, "PROCESS_NAME", info_.processName, "PAGE_URL", info_.pageUrl, "SCENE_ID",
|
||||
info_.sceneId, "INPUT_TIME", info_.inputTime, "ANIMATION_START_LATENCY", animationStartLatency,
|
||||
"ANIMATION_END_LATENCY", animationEndLatency, "E2E_LATENCY", completedLatency);
|
||||
isSetReportEventComplete_ = false;
|
||||
}
|
||||
|
||||
void RSJankStats::ReportEventJankFrame()
|
||||
{
|
||||
auto reportName = "INTERACTION_RENDER_JANK";
|
||||
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, reportName,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "UNIQUE_ID", info_.uniqueId, "SCENE_ID", info_.sceneId,
|
||||
"PROCESS_NAME", info_.processName, "MODULE_NAME", info_.bundleName, "ABILITY_NAME",
|
||||
info_.abilityName, "PAGE_URL", info_.pageUrl, "TOTAL_FRAMES", totalFrames_, "TOTAL_MISSED_FRAMES",
|
||||
totalMissedFrames_, "MAX_FRAMETIME", maxFrameTime_, "MAX_SEQ_MISSED_FRAMES", maxSeqMissedFrames_,
|
||||
"IS_FOLD_DISP", 0);
|
||||
isSetReportEventJankFrame_ = false;
|
||||
isUpdateJankFrame_ = false;
|
||||
totalFrames_ = 0;
|
||||
totalMissedFrames_ = 0;
|
||||
maxFrameTime_ = 0;
|
||||
maxSeqMissedFrames_ = 0;
|
||||
}
|
||||
|
||||
void RSJankStats::ReportEventFirstFrame()
|
||||
{
|
||||
auto reportName = "FIRST_FRAME_DRAWN";
|
||||
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, reportName,
|
||||
OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "APP_PID", appPid_, "VERSION_CODE", info_.versionCode,
|
||||
"VERSION_NAME", info_.versionName, "PROCESS_NAME", info_.processName, "BUNDLE_NAME", info_.bundleName,
|
||||
"ABILITY_NAME", info_.abilityName, "PAGE_URL", info_.pageUrl);
|
||||
isSetReportEventFirstFrame_ = false;
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -690,5 +690,37 @@ void RSRenderServiceClient::ReportJankStats()
|
||||
renderService->ReportJankStats();
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventResponse(DataBaseRs info)
|
||||
{
|
||||
auto renderService = RSRenderServiceConnectHub::GetRenderService();
|
||||
if (renderService != nullptr) {
|
||||
renderService->ReportEventResponse(info);
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventComplete(DataBaseRs info)
|
||||
{
|
||||
auto renderService = RSRenderServiceConnectHub::GetRenderService();
|
||||
if (renderService != nullptr) {
|
||||
renderService->ReportEventComplete(info);
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventJankFrame(DataBaseRs info)
|
||||
{
|
||||
auto renderService = RSRenderServiceConnectHub::GetRenderService();
|
||||
if (renderService != nullptr) {
|
||||
renderService->ReportEventJankFrame(info);
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventFirstFrame(DataBaseRs info)
|
||||
{
|
||||
auto renderService = RSRenderServiceConnectHub::GetRenderService();
|
||||
if (renderService != nullptr) {
|
||||
renderService->ReportEventFirstFrame(info);
|
||||
}
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -1165,5 +1165,84 @@ void RSRenderServiceConnectionProxy::ReportJankStats()
|
||||
ROSEN_LOGE("RSRenderServiceConnectionProxy::ReportJankStats: Send Request err.");
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceConnectionProxy::ReportEventResponse(DataBaseRs info)
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
if (!data.WriteInterfaceToken(RSIRenderServiceConnection::GetDescriptor())) {
|
||||
return;
|
||||
}
|
||||
ReportDataBaseRs(data, reply, option, info);
|
||||
int32_t err = Remote()->SendRequest(RSIRenderServiceConnection::REPORT_EVENT_RESPONSE, data, reply, option);
|
||||
if (err != NO_ERROR) {
|
||||
ROSEN_LOGE("RSRenderServiceConnectionProxy::ReportEventResponse: Send Request err.");
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceConnectionProxy::ReportEventComplete(DataBaseRs info)
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
if (!data.WriteInterfaceToken(RSIRenderServiceConnection::GetDescriptor())) {
|
||||
return;
|
||||
}
|
||||
ReportDataBaseRs(data, reply, option, info);
|
||||
int32_t err = Remote()->SendRequest(RSIRenderServiceConnection::REPORT_EVENT_COMPLETE, data, reply, option);
|
||||
if (err != NO_ERROR) {
|
||||
ROSEN_LOGE("RSRenderServiceConnectionProxy::ReportEventComplete: Send Request err.");
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceConnectionProxy::ReportEventJankFrame(DataBaseRs info)
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
if (!data.WriteInterfaceToken(RSIRenderServiceConnection::GetDescriptor())) {
|
||||
return;
|
||||
}
|
||||
ReportDataBaseRs(data, reply, option, info);
|
||||
int32_t err = Remote()->SendRequest(RSIRenderServiceConnection::REPORT_EVENT_JANK_FRAME, data, reply, option);
|
||||
if (err != NO_ERROR) {
|
||||
ROSEN_LOGE("RSRenderServiceConnectionProxy::ReportEventJankFrame: Send Request err.");
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceConnectionProxy::ReportEventFirstFrame(DataBaseRs info)
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
if (!data.WriteInterfaceToken(RSIRenderServiceConnection::GetDescriptor())) {
|
||||
return;
|
||||
}
|
||||
ReportDataBaseRs(data, reply, option, info);
|
||||
int32_t err = Remote()->SendRequest(RSIRenderServiceConnection::REPORT_EVENT_FIRST_FRAME, data, reply, option);
|
||||
if (err != NO_ERROR) {
|
||||
ROSEN_LOGE("RSRenderServiceConnectionProxy::ReportEventFirstFrame: Send Request err.");
|
||||
}
|
||||
}
|
||||
|
||||
void RSRenderServiceConnectionProxy::ReportDataBaseRs(
|
||||
MessageParcel& data, MessageParcel& reply, MessageOption& option, DataBaseRs info)
|
||||
{
|
||||
data.WriteInt32(info.appPid);
|
||||
data.WriteInt32(info.eventType);
|
||||
data.WriteInt64(info.uniqueId);
|
||||
data.WriteInt64(info.inputTime);
|
||||
data.WriteInt64(info.beginVsyncTime);
|
||||
data.WriteInt64(info.endVsyncTime);
|
||||
data.WriteString(info.sceneId);
|
||||
data.WriteString(info.versionCode);
|
||||
data.WriteString(info.versionName);
|
||||
data.WriteString(info.bundleName);
|
||||
data.WriteString(info.processName);
|
||||
data.WriteString(info.abilityName);
|
||||
data.WriteString(info.pageUrl);
|
||||
option.SetFlags(MessageOption::TF_ASYNC);
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -128,10 +128,20 @@ public:
|
||||
|
||||
void ReportJankStats() override;
|
||||
|
||||
void ReportEventResponse(DataBaseRs info) override;
|
||||
|
||||
void ReportEventComplete(DataBaseRs info) override;
|
||||
|
||||
void ReportEventJankFrame(DataBaseRs info) override;
|
||||
|
||||
void ReportEventFirstFrame(DataBaseRs info) override;
|
||||
|
||||
private:
|
||||
bool FillParcelWithTransactionData(
|
||||
std::unique_ptr<RSTransactionData>& transactionData, std::shared_ptr<MessageParcel>& data);
|
||||
|
||||
void ReportDataBaseRs(MessageParcel& data, MessageParcel& reply, MessageOption& option, DataBaseRs info);
|
||||
|
||||
static inline BrokerDelegator<RSRenderServiceConnectionProxy> delegator_;
|
||||
|
||||
pid_t pid_ = GetRealPid();
|
||||
|
@ -281,5 +281,21 @@ void RSRenderServiceClient::ShowWatermark(const std::shared_ptr<Media::PixelMap>
|
||||
void RSRenderServiceClient::ReportJankStats()
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventResponse(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventComplete(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventJankFrame(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
|
||||
void RSRenderServiceClient::ReportEventFirstFrame(DataBaseRs info)
|
||||
{
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -319,5 +319,24 @@ void RSInterfaces::ReportJankStats()
|
||||
renderServiceClient_->ReportJankStats();
|
||||
}
|
||||
|
||||
void RSInterfaces::ReportEventResponse(DataBaseRs info)
|
||||
{
|
||||
renderServiceClient_->ReportEventResponse(info);
|
||||
}
|
||||
|
||||
void RSInterfaces::ReportEventComplete(DataBaseRs info)
|
||||
{
|
||||
renderServiceClient_->ReportEventComplete(info);
|
||||
}
|
||||
|
||||
void RSInterfaces::ReportEventJankFrame(DataBaseRs info)
|
||||
{
|
||||
renderServiceClient_->ReportEventJankFrame(info);
|
||||
}
|
||||
|
||||
void RSInterfaces::ReportEventFirstFrame(DataBaseRs info)
|
||||
{
|
||||
renderServiceClient_->ReportEventFirstFrame(info);
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -143,6 +143,14 @@ public:
|
||||
void ShowWatermark(const std::shared_ptr<Media::PixelMap> &watermarkImg, bool isShow);
|
||||
|
||||
void ReportJankStats();
|
||||
|
||||
void ReportEventResponse(DataBaseRs info);
|
||||
|
||||
void ReportEventComplete(DataBaseRs info);
|
||||
|
||||
void ReportEventJankFrame(DataBaseRs info);
|
||||
|
||||
void ReportEventFirstFrame(DataBaseRs info);
|
||||
private:
|
||||
RSInterfaces();
|
||||
~RSInterfaces() noexcept;
|
||||
|
@ -78,7 +78,6 @@ bool RSCanvasNode::IsRecording() const
|
||||
void RSCanvasNode::FinishRecording()
|
||||
{
|
||||
if (!IsRecording()) {
|
||||
ROSEN_LOGW("RSCanvasNode::FinishRecording, IsRecording = false");
|
||||
return;
|
||||
}
|
||||
#ifndef USE_ROSEN_DRAWING
|
||||
|
@ -222,6 +222,14 @@ public:
|
||||
|
||||
void ReportJankStats() override {}
|
||||
|
||||
void ReportEventResponse(DataBaseRs info) override {}
|
||||
|
||||
void ReportEventComplete(DataBaseRs info) override {}
|
||||
|
||||
void ReportEventJankFrame(DataBaseRs info) override {}
|
||||
|
||||
void ReportEventFirstFrame(DataBaseRs info) override {}
|
||||
|
||||
bool GetBitmap(NodeId id, SkBitmap& bitmap) override
|
||||
{
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user