• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "benchmarks/rs_recording_thread.h"
17 
18 #include <thread>
19 #include "common/rs_thread_handler.h"
20 #include "platform/common/rs_system_properties.h"
21 #include "platform/common/rs_log.h"
22 #include "rs_trace.h"
23 #include "transaction/rs_marshalling_helper.h"
24 #ifdef RS_ENABLE_VK
25 #include "platform/ohos/backend/rs_vulkan_context.h"
26 #endif
27 
28 namespace OHOS::Rosen {
~RSRecordingThread()29 RSRecordingThread::~RSRecordingThread()
30 {
31     RS_LOGI("RSRecordingThread::~RSRecordingThread()");
32     PostTask([this]() {
33         DestroyShareEglContext();
34     });
35 }
36 
Instance(RenderContext * context)37 RSRecordingThread &RSRecordingThread::Instance(RenderContext* context)
38 {
39     static RSRecordingThread instance(context);
40     return instance;
41 }
42 
Start()43 void RSRecordingThread::Start()
44 {
45     runner_ = AppExecFwk::EventRunner::Create("RSRecordingThread");
46     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
47     PostTask([this]() {
48         grContext_ = CreateShareGrContext();
49     });
50 }
51 
CreateShareGrContext()52 std::shared_ptr<Drawing::GPUContext> RSRecordingThread::CreateShareGrContext()
53 {
54     RS_TRACE_NAME("CreateShareGrContext");
55     auto gpuContext = std::make_shared<Drawing::GPUContext>();
56 #ifdef RS_ENABLE_GL
57     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
58         CreateShareEglContext();
59         Drawing::GPUContextOptions options;
60         auto handler = std::make_shared<MemoryHandler>();
61         auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
62         auto size = glesVersion ? strlen(glesVersion) : 0;
63         handler->ConfigureContext(&options, glesVersion, size);
64         if (!gpuContext->BuildFromGL(options)) {
65             RS_LOGE("gpuContext is null");
66             return nullptr;
67         }
68         return gpuContext;
69     }
70 #endif
71 #ifdef RS_ENABLE_VK
72     if (RSSystemProperties::IsUseVulkan()) {
73         Drawing::GPUContextOptions options;
74         auto handler = std::make_shared<MemoryHandler>();
75         std::string vulkanVersion = RsVulkanContext::GetSingleton().GetVulkanVersion();
76         auto size = vulkanVersion.size();
77         handler->ConfigureContext(&options, vulkanVersion.c_str(), size);
78         if (!gpuContext->BuildFromVK(RsVulkanContext::GetSingleton().GetGrVkBackendContext(), options)) {
79             RS_LOGE("gpuContext is null");
80             return nullptr;
81         }
82         return gpuContext;
83     }
84 #endif
85     return nullptr;
86 }
87 
CreateShareEglContext()88 void RSRecordingThread::CreateShareEglContext()
89 {
90     if (renderContext_ == nullptr) {
91         RS_LOGE("renderContext_ is nullptr");
92         return;
93     }
94 #ifdef RS_ENABLE_GL
95     if (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) {
96         return;
97     }
98     eglShareContext_ = renderContext_->CreateShareContext();
99     if (eglShareContext_ == EGL_NO_CONTEXT) {
100         RS_LOGE("eglShareContext_ is EGL_NO_CONTEXT");
101         return;
102     }
103     if (!eglMakeCurrent(renderContext_->GetEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, eglShareContext_)) {
104         RS_LOGE("eglMakeCurrent failed");
105         return;
106     }
107 #endif
108 }
109 
DestroyShareEglContext()110 void RSRecordingThread::DestroyShareEglContext()
111 {
112 #ifdef RS_ENABLE_GL
113     if (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) {
114         return;
115     }
116     if (renderContext_ != nullptr) {
117         eglDestroyContext(renderContext_->GetEGLDisplay(), eglShareContext_);
118         eglShareContext_ = EGL_NO_CONTEXT;
119         eglMakeCurrent(renderContext_->GetEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
120     }
121 #endif
122 }
IsIdle()123 bool RSRecordingThread::IsIdle()
124 {
125     return handler_ && handler_->IsIdle();
126 }
127 
PostTask(const std::function<void ()> & task)128 void RSRecordingThread::PostTask(const std::function<void()> &task)
129 {
130     if (handler_) {
131         handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
132     }
133 }
134 
CheckAndRecording()135 bool RSRecordingThread::CheckAndRecording()
136 {
137     if (!handler_) {
138         Start();
139     }
140     RSTaskMessage::RSTask task = [this]() {
141         std::string line = "RSRecordingThread::CheckAndRecording curDumpFrame = " + std::to_string(curDumpFrame_) +
142             ", dumpFrameNum = " + std::to_string(dumpFrameNum_);
143         RS_LOGD("%{public}s", line.c_str());
144         mode_ = RecordingMode(RSSystemProperties::GetRecordingEnabled());
145         // init curDumpFrame
146         if (GetRecordingEnabled() && curDumpFrame_ == 0) {
147             RS_TRACE_NAME(line);
148             dumpFrameNum_ = RSSystemProperties::GetDumpFrameNum();
149             fileDir_ = RSSystemProperties::GetRecordingFile();
150             if (access(fileDir_.c_str(), F_OK) != 0) {
151                 mkdir(fileDir_.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH));
152             }
153         }
154     };
155     PostTask(task);
156     return GetRecordingEnabled();
157 }
158 
FinishRecordingOneFrameTask(RecordingMode modeSubThread)159 void RSRecordingThread::FinishRecordingOneFrameTask(RecordingMode modeSubThread)
160 {
161     for (int curFrameIndex = 0; curFrameIndex < dumpFrameNum_; curFrameIndex++) {
162         std::shared_ptr<MessageParcel> messageParcel = std::make_shared<MessageParcel>();
163         std::string opsDescription = "drawing ops no description";
164         if (modeSubThread == RecordingMode::HIGH_SPPED_RECORDING) {
165             RS_LOGI("RSRecordingThread::High speed!");
166             messageParcel->SetMaxCapacity(RECORDING_PARCEL_CAPCITY);
167             RSMarshallingHelper::BeginNoSharedMem(std::this_thread::get_id());
168             RSMarshallingHelper::Marshalling(*messageParcel, drawCmdListVec_[curFrameIndex]);
169             RSMarshallingHelper::EndNoSharedMem();
170         } else if (modeSubThread == RecordingMode::LOW_SPEED_RECORDING) {
171             messageParcel = messageParcelVec_[curFrameIndex];
172         }
173         OHOS::Rosen::Benchmarks::WriteMessageParcelToFile(messageParcel, opsDescription, curFrameIndex, fileDir_);
174     }
175     drawCmdListVec_.clear();
176     messageParcelVec_.clear();
177     opsDescriptionVec_.clear();
178     curDumpFrame_ = 0;
179     dumpFrameNum_ = 0;
180     fileDir_ = "";
181     RSSystemProperties::SetRecordingDisenabled();
182     RS_LOGD("RSRecordingThread::FinishRecordingOneFrame isRecordingEnabled = false");
183 }
184 
FinishRecordingOneFrame()185 void RSRecordingThread::FinishRecordingOneFrame()
186 {
187     std::string line = "RSRecordingThread::FinishRecordingOneFrame curDumpFrame = " + std::to_string(curDumpFrame_) +
188         ", dumpFrameNum = " + std::to_string(dumpFrameNum_);
189     RS_LOGD("%{public}s", line.c_str());
190     RS_TRACE_NAME(line);
191     if (curDumpFrame_ < dumpFrameNum_) {
192         curDumpFrame_++;
193         return;
194     }
195     auto modeSubThread = mode_;
196     mode_ = RecordingMode::STOP_RECORDING;
197 #ifdef RS_ENABLE_GL
198     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
199         RSTaskMessage::RSTask task = [this, modeSubThread]() {
200             FinishRecordingOneFrameTask(modeSubThread);
201         };
202         PostTask(task);
203     } else {
204         FinishRecordingOneFrameTask(modeSubThread);
205     }
206 #else
207     FinishRecordingOneFrameTask(modeSubThread);
208 #endif
209 }
210 
RecordingToFile(const std::shared_ptr<Drawing::DrawCmdList> & drawCmdList)211 void RSRecordingThread::RecordingToFile(const std::shared_ptr<Drawing::DrawCmdList>& drawCmdList)
212 {
213     if (curDumpFrame_ < 0 || drawCmdList == nullptr) {
214         return;
215     }
216     if (mode_ == RecordingMode::HIGH_SPPED_RECORDING) {
217         drawCmdListVec_.push_back(drawCmdList);
218     } else if (mode_ == RecordingMode::LOW_SPEED_RECORDING) {
219         std::shared_ptr<MessageParcel> messageParcel = std::make_shared<MessageParcel>();
220         messageParcel->SetMaxCapacity(RECORDING_PARCEL_CAPCITY);
221         RSMarshallingHelper::BeginNoSharedMem(std::this_thread::get_id());
222         RSMarshallingHelper::Marshalling(*messageParcel, drawCmdList);
223         RSMarshallingHelper::EndNoSharedMem();
224         opsDescriptionVec_.push_back(drawCmdList->GetOpsWithDesc());
225         messageParcelVec_.push_back(messageParcel);
226     }
227 
228     FinishRecordingOneFrame();
229 }
230 }
231