!7100 RSUIDirector在PostTask时确保任务抛回正确的容器实例

Merge pull request !7100 from Caoruihong/fix_uiDirector
This commit is contained in:
openharmony_ci 2024-04-05 14:07:46 +00:00 committed by Gitee
commit 6e4a2fd074
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 78 additions and 20 deletions

View File

@ -37,6 +37,7 @@ using FrameRateLinkerId = uint64_t;
using SurfaceId = uint64_t;
constexpr uint32_t UNI_MAIN_THREAD_INDEX = UINT32_MAX;
constexpr uint64_t INVALID_NODEID = 0;
constexpr int32_t INSTANCE_ID_UNDEFINED = -1;
// types in the same layer should be 0/1/2/4/8
// types for UINode

View File

@ -70,6 +70,13 @@ bool RSNodeMap::RegisterNode(const RSBaseNode::SharedPtr& nodePtr)
return true;
}
bool RSNodeMap::RegisterNodeInstanceId(NodeId id, int32_t instanceId)
{
std::unique_lock<std::mutex> lock(mutex_);
nodeIdMap_.emplace(id, instanceId);
return true;
}
void RSNodeMap::UnregisterNode(NodeId id)
{
if (!g_instance_valid.load()) {
@ -78,6 +85,7 @@ void RSNodeMap::UnregisterNode(NodeId id)
std::unique_lock<std::mutex> lock(mutex_);
auto itr = nodeMap_.find(id);
if (itr != nodeMap_.end()) {
nodeIdMap_.erase(id);
nodeMap_.erase(itr);
} else {
ROSEN_LOGW("RSNodeMap::UnregisterNode: node id %{public}" PRIu64 " not found", id);
@ -98,6 +106,19 @@ const std::shared_ptr<RSBaseNode> RSNodeMap::GetNode<RSBaseNode>(NodeId id) cons
return itr->second.lock();
}
int32_t RSNodeMap::GetNodeInstanceId(NodeId id) const
{
if (!g_instance_valid.load()) {
return INSTANCE_ID_UNDEFINED;
}
std::unique_lock<std::mutex> lock(mutex_);
auto itr = nodeIdMap_.find(id);
if (itr == nodeIdMap_.end()) {
return INSTANCE_ID_UNDEFINED;
}
return itr->second;
}
const std::shared_ptr<RSNode> RSNodeMap::GetAnimationFallbackNode() const
{
return animationFallbackNode_;

View File

@ -32,6 +32,7 @@ public:
static RSNodeMap& MutableInstance();
bool RegisterNode(const std::shared_ptr<RSBaseNode>& nodePtr);
bool RegisterNodeInstanceId(NodeId id, int32_t instanceId);
void UnregisterNode(NodeId id);
// Get RSNode with type T, return nullptr if not found or type mismatch
@ -42,6 +43,7 @@ public:
}
template<>
const std::shared_ptr<RSBaseNode> GetNode(NodeId id) const;
int32_t GetNodeInstanceId(NodeId id) const;
const std::shared_ptr<RSNode> GetAnimationFallbackNode() const;
@ -56,6 +58,7 @@ private:
private:
mutable std::mutex mutex_;
std::unordered_map<NodeId, std::weak_ptr<RSBaseNode>> nodeMap_;
std::unordered_map<NodeId, int32_t> nodeIdMap_;
std::shared_ptr<RSNode> animationFallbackNode_;
};
} // namespace Rosen

View File

@ -2186,5 +2186,11 @@ template bool RSNode::IsInstanceOf<RSCanvasNode>() const;
template bool RSNode::IsInstanceOf<RSRootNode>() const;
template bool RSNode::IsInstanceOf<RSCanvasDrawingNode>() const;
void RSNode::SetInstanceId(int32_t instanceId)
{
instanceId_ = instanceId;
RSNodeMap::MutableInstance().RegisterNodeInstanceId(id_, instanceId_);
}
} // namespace Rosen
} // namespace OHOS

View File

@ -382,6 +382,12 @@ public:
// key: symbolSpanID, value:symbol animation node list
std::unordered_map<uint64_t, std::list<SharedPtr>> canvasNodesListMap;
void SetInstanceId(int32_t instanceId);
int32_t GetInstanceId() const
{
return instanceId_;
}
protected:
explicit RSNode(bool isRenderServiceNode, bool isTextureExportNode = false);
explicit RSNode(bool isRenderServiceNode, NodeId id, bool isTextureExportNode = false);
@ -414,6 +420,7 @@ private:
static void InitUniRenderEnabled();
NodeId id_;
NodeId parent_ = 0;
int32_t instanceId_ = INSTANCE_ID_UNDEFINED;
int32_t frameNodeId_ = -1;
std::string frameNodeTag_;
std::string nodeName_ = "";

View File

@ -321,9 +321,10 @@ bool RSUIDirector::HasUIAnimation()
return false;
}
void RSUIDirector::SetUITaskRunner(const TaskRunner& uiTaskRunner)
void RSUIDirector::SetUITaskRunner(const TaskRunner& uiTaskRunner, int32_t instanceId)
{
std::unique_lock<std::mutex> lock(g_uiTaskRunnersVisitorMutex);
instanceId_ = instanceId;
g_uiTaskRunners[this] = uiTaskRunner;
if (!isHgmConfigChangeCallbackReg_) {
RSFrameRatePolicy::GetInstance()->RegisterHgmConfigChangeCallback();
@ -360,23 +361,34 @@ void RSUIDirector::RecvMessages(std::shared_ptr<RSTransactionData> cmds)
if (cmds == nullptr || cmds->IsEmpty()) {
return;
}
ROSEN_LOGD("RSUIDirector::RecvMessages success");
PostTask([cmds]() {
ROSEN_LOGD("RSUIDirector::ProcessMessages success");
RSUIDirector::ProcessMessages(cmds);
std::unique_lock<std::mutex> lock(g_vsyncCallbackMutex);
if (requestVsyncCallback_ != nullptr) {
requestVsyncCallback_();
} else {
RSTransaction::FlushImplicitTransaction();
}
});
ROSEN_LOGD("ProcessMessages begin");
RSUIDirector::ProcessMessages(cmds);
}
void RSUIDirector::ProcessMessages(std::shared_ptr<RSTransactionData> cmds)
{
static RSContext context; // RSCommand->process() needs it
cmds->Process(context);
std::map<int32_t, std::vector<std::unique_ptr<RSCommand>>> m;
for (auto &[id, _, cmd] : cmds->GetPayload()) {
m[RSNodeMap::Instance().GetNodeInstanceId(id)].push_back(std::move(cmd));
}
auto counter = std::make_shared<std::atomic_size_t>(m.size());
for (auto &[instanceId, commands] : m) {
PostTask([cmds = std::make_shared<std::vector<std::unique_ptr<RSCommand>>>(std::move(commands)), counter] {
for (auto &cmd : *cmds) {
RSContext context; // RSCommand->process() needs it
cmd->Process(context);
}
if (counter->fetch_sub(1) == 1) {
std::unique_lock<std::mutex> lock(g_vsyncCallbackMutex);
if (requestVsyncCallback_ != nullptr) {
requestVsyncCallback_();
} else {
RSTransaction::FlushImplicitTransaction();
}
ROSEN_LOGD("ProcessMessages end");
}
}, instanceId);
}
}
void RSUIDirector::AnimationCallbackProcessor(NodeId nodeId, AnimationId animId, AnimationCallbackEvent event)
@ -406,14 +418,21 @@ void RSUIDirector::PostFrameRateTask(const std::function<void()>& task)
PostTask(task);
}
void RSUIDirector::PostTask(const std::function<void()>& task)
void RSUIDirector::PostTask(const std::function<void()>& task, int32_t instanceId)
{
std::unique_lock<std::mutex> lock(g_uiTaskRunnersVisitorMutex);
for (auto [_, taskRunner] : g_uiTaskRunners) {
if (taskRunner == nullptr) {
ROSEN_LOGE("RSUIDirector::PostTask, uiTaskRunner is null");
for (const auto &[director, taskRunner] : g_uiTaskRunners) {
if (director->instanceId_ != instanceId) {
continue;
}
ROSEN_LOGD("RSUIDirector::PostTask instanceId=%{public}d success", instanceId);
taskRunner(task);
return;
}
if (instanceId != INSTANCE_ID_UNDEFINED) {
ROSEN_LOGW("RSUIDirector::PostTask instanceId=%{public}d not found", instanceId);
}
for (const auto &[_, taskRunner] : g_uiTaskRunners) {
ROSEN_LOGD("RSUIDirector::PostTask success");
taskRunner(task);
return;

View File

@ -52,7 +52,7 @@ public:
void SetFlushEmptyCallback(FlushEmptyCallback flushEmptyCallback);
void SetRoot(NodeId root);
void SetUITaskRunner(const TaskRunner& uiTaskRunner);
void SetUITaskRunner(const TaskRunner& uiTaskRunner, int32_t instanceId = INSTANCE_ID_UNDEFINED);
void SendMessages(); // post messages to render thread
void SetTimeStamp(uint64_t timeStamp, const std::string& abilityName);
@ -78,7 +78,7 @@ private:
static void RecvMessages(std::shared_ptr<RSTransactionData> cmds);
static void ProcessMessages(std::shared_ptr<RSTransactionData> cmds); // receive message
static void AnimationCallbackProcessor(NodeId nodeId, AnimationId animId, AnimationCallbackEvent event);
static void PostTask(const std::function<void()>& task);
static void PostTask(const std::function<void()>& task, int32_t instanceId = INSTANCE_ID_UNDEFINED);
RSUIDirector() = default;
RSUIDirector(const RSUIDirector&) = delete;
@ -88,6 +88,7 @@ private:
std::mutex mutex_;
NodeId root_ = 0;
int32_t instanceId_ = INSTANCE_ID_UNDEFINED;
bool isActive_ = false;
bool isUniRenderEnabled_ = false;