1 /*
2 * Copyright (c) 2025 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 "gfx/first_frame_notifier/rs_first_frame_notifier.h"
17 #include "common/rs_background_thread.h"
18 #include "rs_trace.h"
19 #include "platform/common/rs_log.h"
20
21 namespace OHOS::Rosen {
GetInstance()22 RSFirstFrameNotifier& RSFirstFrameNotifier::GetInstance()
23 {
24 static RSFirstFrameNotifier instance;
25 return instance;
26 }
27
RegisterFirstFrameCommitCallback(pid_t pid,const sptr<RSIFirstFrameCommitCallback> & callback)28 void RSFirstFrameNotifier::RegisterFirstFrameCommitCallback(
29 pid_t pid, const sptr<RSIFirstFrameCommitCallback>& callback)
30 {
31 std::unique_lock<std::shared_mutex> lock(callbacksMutex_);
32 if (callback == nullptr) {
33 if (firstFrameCommitCallbacks_.find(pid) != firstFrameCommitCallbacks_.end()) {
34 firstFrameCommitCallbacks_.erase(pid);
35 RS_LOGD("FirstFrameCommitCallback unregister succ.");
36 }
37 return ;
38 }
39 firstFrameCommitCallbacks_[pid] = callback;
40 RS_LOGD("FirstFrameCommitCallback: add a remote callback succeed.");
41 }
42
OnFirstFrameCommitCallback(ScreenId screenId)43 void RSFirstFrameNotifier::OnFirstFrameCommitCallback(ScreenId screenId)
44 {
45 std::shared_lock<std::shared_mutex> lock(callbacksMutex_);
46 int64_t timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(
47 std::chrono::steady_clock::now().time_since_epoch()).count();
48 RS_TRACE_NAME_FMT("OnFirstFrameCommitCallback screenId:%" PRIu64 ", timestamp:%" PRId64 ".",
49 screenId, timestamp);
50 for (const auto& callback : firstFrameCommitCallbacks_) {
51 if (callback.second != nullptr) {
52 callback.second->OnFirstFrameCommit(screenId, timestamp);
53 }
54 }
55 }
56
ExecIfFirstFrameCommit(ScreenId screenId)57 void RSFirstFrameNotifier::ExecIfFirstFrameCommit(ScreenId screenId)
58 {
59 std::unique_lock<std::mutex> lock(screensMutex_);
60 if (firstFrameCommitScreens_.find(screenId) != firstFrameCommitScreens_.end()) {
61 firstFrameCommitScreens_.erase(screenId);
62 RS_TRACE_NAME_FMT("ExecIfFirstFrameCommit screenId:%" PRIu64 ".", screenId);
63 RS_LOGD("ExecIfFirstFrameCommit screenId:%{public}" PRIu64 ".", screenId);
64 RSBackgroundThread::Instance().PostTask([this, screenId]() {
65 OnFirstFrameCommitCallback(screenId);
66 });
67 }
68 }
69
AddFirstFrameCommitScreen(ScreenId screenId)70 void RSFirstFrameNotifier::AddFirstFrameCommitScreen(ScreenId screenId)
71 {
72 std::unique_lock<std::mutex> lock(screensMutex_);
73 firstFrameCommitScreens_.insert(screenId);
74 }
75 }