• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "graphics_task.h"
17 #include <mutex>
18 #include <utility>
19 #include <pthread.h>
20 #include <sys/prctl.h>
21 #include <sys/resource.h>
22 #include <sys/time.h>
23 #include <sys/resource.h>
24 
25 #include "3d_widget_adapter_log.h"
26 
27 #define ENGINE_SERVICE_PRIORITY (-20)
28 
29 namespace OHOS::Render3D {
Message(const std::function<Task> & task)30 GraphicsTask::Message::Message(const std::function<Task>& task)
31     : task_(std::move(task))
32 {}
33 
Message(GraphicsTask::Message && msg)34 GraphicsTask::Message::Message(GraphicsTask::Message&& msg)
35     : task_(std::move(msg.task_)), pms_(std::move(msg.pms_)), ftr_(std::move(msg.ftr_))
36 {}
37 
operator =(GraphicsTask::Message && msg)38 GraphicsTask::Message& GraphicsTask::Message::operator=(GraphicsTask::Message&& msg)
39 {
40     task_ = std::move(msg.task_);
41     pms_ = std::move(msg.pms_);
42     ftr_ = std::move(msg.ftr_);
43     return *this;
44 }
45 
Execute()46 void GraphicsTask::Message::Execute()
47 {
48     task_();
49     Finish();
50 }
51 
Finish()52 void GraphicsTask::Message::Finish()
53 {
54     pms_.set_value();
55 }
56 
GetFuture()57 std::shared_future<void> GraphicsTask::Message::GetFuture()
58 {
59     return std::move(ftr_);
60 }
61 
GetInstance()62 GraphicsTask& GraphicsTask::GetInstance()
63 {
64     static GraphicsTask gfxTask;
65     return gfxTask;
66 }
67 
PushSyncMessage(const std::function<Task> & task)68 void GraphicsTask::PushSyncMessage(const std::function<Task>& task)
69 {
70     std::shared_future<void> ftr;
71     {
72         std::lock_guard<std::mutex> lk(messageQueueMut_);
73         ftr = messageQueue_.emplace(std::move(task)).GetFuture();
74         messageQueueCnd_.notify_one();
75     }
76 
77     if (ftr.valid()) {
78         ftr.get();
79     }
80 }
81 
PushAsyncMessage(const std::function<Task> & task)82 std::shared_future<void> GraphicsTask::PushAsyncMessage(const std::function<Task>& task)
83 {
84     std::lock_guard<std::mutex> lk(messageQueueMut_);
85 
86     Message& msg = messageQueue_.emplace(std::move(task));
87     messageQueueCnd_.notify_one();
88 
89     return msg.GetFuture();
90 }
91 
GraphicsTask()92 GraphicsTask::GraphicsTask()
93 {
94     Start();
95 }
96 
~GraphicsTask()97 GraphicsTask::~GraphicsTask()
98 {
99     Stop();
100     {
101         std::lock_guard<std::mutex> lk(messageQueueMut_);
102         while (!messageQueue_.empty()) {
103             messageQueue_.front().Finish();
104             messageQueue_.pop();
105         }
106     }
107 
108     if (loop_.joinable()) {
109         loop_.join();
110     }
111     WIDGET_LOGI("~GraphicsTask() end");
112 }
113 
Start()114 void GraphicsTask::Start()
115 {
116     WIDGET_LOGI("GraphicsTask::Start start");
117 
118     if (!exit_) {
119         return;
120     }
121     exit_ = false;
122     loop_ = std::thread([this] { this->EngineThread(); });
123     PushAsyncMessage([this] {
124         this->SetName();
125         setpriority(0, 0, ENGINE_SERVICE_PRIORITY);
126     });
127     WIDGET_LOGD("GraphicsTask::Start end");
128 }
129 
Stop()130 void GraphicsTask::Stop()
131 {
132     exit_ = true;
133 }
134 
EngineThread()135 void GraphicsTask::EngineThread()
136 {
137     WIDGET_LOGD("GraphicsTask::EngineThread execute start");
138     do {
139         std::unique_lock<std::mutex> lk(messageQueueMut_);
140         messageQueueCnd_.wait(lk, [this] { return !messageQueue_.empty(); });
141 
142         Message msg(std::move(messageQueue_.front()));
143         messageQueue_.pop();
144         lk.unlock();
145 
146         msg.Execute();
147     } while (!exit_);
148 
149     WIDGET_LOGD("GraphicsTask::EngineThread execute exit");
150 }
151 
SetName()152 void GraphicsTask::SetName()
153 {
154     WIDGET_LOGD("GraphicsTask::SetName start");
155     prctl(PR_SET_NAME, "Engine Service Lume", 0, 0, 0);
156 }
157 } // namespace OHOS::Render3D
158