1e0dac50fSopenharmony_ci/* 2e0dac50fSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License. 5e0dac50fSopenharmony_ci * You may obtain a copy of the License at 6e0dac50fSopenharmony_ci * 7e0dac50fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0dac50fSopenharmony_ci * 9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and 13e0dac50fSopenharmony_ci * limitations under the License. 14e0dac50fSopenharmony_ci */ 15e0dac50fSopenharmony_ci 16e0dac50fSopenharmony_ci#include "vsync_station.h" 17e0dac50fSopenharmony_ci 18e0dac50fSopenharmony_ci#include <unistd.h> 19e0dac50fSopenharmony_ci#include "transaction/rs_interfaces.h" 20e0dac50fSopenharmony_ci#include "window_manager_hilog.h" 21e0dac50fSopenharmony_ci 22e0dac50fSopenharmony_ci 23e0dac50fSopenharmony_cinamespace OHOS { 24e0dac50fSopenharmony_cinamespace Rosen { 25e0dac50fSopenharmony_cinamespace { 26e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "VsyncStation"}; 27e0dac50fSopenharmony_ci} 28e0dac50fSopenharmony_ci 29e0dac50fSopenharmony_ciVsyncStation::VsyncStation(NodeId nodeId) : nodeId_(nodeId) 30e0dac50fSopenharmony_ci{ 31e0dac50fSopenharmony_ci TLOGI(WmsLogTag::WMS_MAIN, "Vsync Constructor"); 32e0dac50fSopenharmony_ci} 33e0dac50fSopenharmony_ci 34e0dac50fSopenharmony_civoid VsyncStation::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback) 35e0dac50fSopenharmony_ci{ 36e0dac50fSopenharmony_ci { 37e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 38e0dac50fSopenharmony_ci if (destroyed_) { 39e0dac50fSopenharmony_ci return; 40e0dac50fSopenharmony_ci } 41e0dac50fSopenharmony_ci vsyncCallbacks_.insert(vsyncCallback); 42e0dac50fSopenharmony_ci 43e0dac50fSopenharmony_ci if (!hasInitVsyncReceiver_) { 44e0dac50fSopenharmony_ci auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance(); 45e0dac50fSopenharmony_ci while (receiver_ == nullptr) { 46e0dac50fSopenharmony_ci receiver_ = rsClient.CreateVSyncReceiver("WM_" + std::to_string(getpid()), nodeId_); 47e0dac50fSopenharmony_ci TLOGI(WmsLogTag::WMS_MAIN, "Create vsync receiver for nodeId:%{public}" PRIu64"", nodeId_); 48e0dac50fSopenharmony_ci } 49e0dac50fSopenharmony_ci receiver_->Init(); 50e0dac50fSopenharmony_ci hasInitVsyncReceiver_ = true; 51e0dac50fSopenharmony_ci } 52e0dac50fSopenharmony_ci if (hasRequestedVsync_) { 53e0dac50fSopenharmony_ci return; 54e0dac50fSopenharmony_ci } 55e0dac50fSopenharmony_ci hasRequestedVsync_ = true; 56e0dac50fSopenharmony_ci } 57e0dac50fSopenharmony_ci receiver_->RequestNextVSync(frameCallback_); 58e0dac50fSopenharmony_ci} 59e0dac50fSopenharmony_ci 60e0dac50fSopenharmony_ciint64_t VsyncStation::GetVSyncPeriod() 61e0dac50fSopenharmony_ci{ 62e0dac50fSopenharmony_ci return 0; 63e0dac50fSopenharmony_ci} 64e0dac50fSopenharmony_ci 65e0dac50fSopenharmony_civoid VsyncStation::Init() 66e0dac50fSopenharmony_ci{ 67e0dac50fSopenharmony_ci} 68e0dac50fSopenharmony_ci 69e0dac50fSopenharmony_civoid VsyncStation::RemoveCallback() 70e0dac50fSopenharmony_ci{ 71e0dac50fSopenharmony_ci WLOGI("Remove Vsync callback"); 72e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 73e0dac50fSopenharmony_ci vsyncCallbacks_.clear(); 74e0dac50fSopenharmony_ci} 75e0dac50fSopenharmony_ci 76e0dac50fSopenharmony_civoid VsyncStation::VsyncCallbackInner(int64_t timestamp, int64_t frameCount) 77e0dac50fSopenharmony_ci{ 78e0dac50fSopenharmony_ci std::unordered_set<std::shared_ptr<VsyncCallback>> vsyncCallbacks; 79e0dac50fSopenharmony_ci { 80e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 81e0dac50fSopenharmony_ci hasRequestedVsync_ = false; 82e0dac50fSopenharmony_ci vsyncCallbacks = vsyncCallbacks_; 83e0dac50fSopenharmony_ci vsyncCallbacks_.clear(); 84e0dac50fSopenharmony_ci } 85e0dac50fSopenharmony_ci for (const auto& callback: vsyncCallbacks) { 86e0dac50fSopenharmony_ci callback->onCallback(timestamp, frameCount); 87e0dac50fSopenharmony_ci } 88e0dac50fSopenharmony_ci} 89e0dac50fSopenharmony_ci 90e0dac50fSopenharmony_civoid VsyncStation::OnVsync(int64_t timestamp, int64_t frameCount, void* client) 91e0dac50fSopenharmony_ci{ 92e0dac50fSopenharmony_ci auto vsyncClient = static_cast<VsyncStation*>(client); 93e0dac50fSopenharmony_ci if (vsyncClient) { 94e0dac50fSopenharmony_ci vsyncClient->VsyncCallbackInner(timestamp, frameCount); 95e0dac50fSopenharmony_ci } else { 96e0dac50fSopenharmony_ci WLOGFE("VsyncClient is null"); 97e0dac50fSopenharmony_ci } 98e0dac50fSopenharmony_ci} 99e0dac50fSopenharmony_ci 100e0dac50fSopenharmony_civoid VsyncStation::OnVsyncTimeOut() 101e0dac50fSopenharmony_ci{ 102e0dac50fSopenharmony_ci WLOGW("Vsync time out"); 103e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 104e0dac50fSopenharmony_ci hasRequestedVsync_ = false; 105e0dac50fSopenharmony_ci} 106e0dac50fSopenharmony_ci} 107e0dac50fSopenharmony_ci} 108