diff --git a/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.cpp b/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.cpp index 1fc806d693010638f78de2d6c44c6df7b543f764..0b48aae0722a21867edeb0b5604d2e69cb4c354a 100644 --- a/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.cpp +++ b/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.cpp @@ -17,76 +17,166 @@ namespace OHOS { namespace Rosen { -void RSScreenCallbackManager::RegisterCoreCallback(const sptr& listener) +void RSScreenCallbackManager::SetCoreListener(const sptr& listener) { - std::lock_guard lock(mtx_); - coreListeners_.push_back(listener); + coreListener_ = listener; } -void RSScreenCallbackManager::UnRegisterCoreCallback(const sptr& listener) +sptr RSScreenCallbackManager::GetCoreListener() const { - std::lock_guard lock(mtx_); - auto iter = std::find(coreListeners_.cbegin(), coreListeners_.cend(), listener); - if (iter != coreListeners_.cend()) { - coreListeners_.erase(iter); - } + return coreListener_; } -void RSScreenCallbackManager::RegisterAgentCallback(const sptr& listener) +void RSScreenCallbackManager::AddAgentListener(const sptr& listener) { - std::lock_guard lock(mtx_); + std::lock_guard lock(agentMtx_); agentListeners_.push_back(listener); } -void RSScreenCallbackManager::UnRegisterAgentCallback(const sptr& listener) +void RSScreenCallbackManager::RemoveAgentListener(const sptr& listener) { - std::lock_guard lock(mtx_); + std::lock_guard lock(agentListeners_); auto iter = std::find(agentListeners_.cbegin(), agentListeners_.cend(), listener); if (iter != agentListeners_.cend()) { agentListeners_.erase(iter); } } -void RSScreenCallbackManager::NotifyScreenConnected(ScreenId id, const ScreenEventData& data, const ScreenInfo& info) +void RSScreenCallbackManager::NotifyScreenPresenceChanged(const ScreenPresenceEvent& event) { - std::lock_guard lock(mtx_); - for (const auto& coreListener : coreListeners_) { - auto obj = coreListener->OnScreenConnected(id, data, info); - auto iter = remoteObjMap_.find(id); - if (iter != remoteObjMap_.end()) { - iter->second = obj; + if (event.connected) { + sptr remoteConn = nullptr; + if (coreListener_) { + // client to renderConn + remoteConn = coreListener_->OnScreenConnected(event.id, {event.output, event.reason}, event.property); } else { - remoteObjMap_[id] = obj; + RS_LOGE("%{public}s: coreListener is nullptr", __func__); + } + NotifyScreenConnectedToAgentListeners(event.id, event.reason, remoteConn); + { + std::lock_guard lock(remoteConnsMtx_); + auto iter = remoteConns_.find(event.id); + if (iter != remoteConns_.end()) { + iter->second = remoteConn; + } else { + remoteConns_[event.id] = remoteConn; + } } - for (const auto& agentListener : agentListeners_) { - agentListener->OnScreenConnected(id, data.reason, obj); + } else { + if (coreListener_) { + coreListener_->OnScreenDisconnected(event.id, {event.output, event.reason}); + } else { + RS_LOGE("%{public}s: coreListener is nullptr", __func__); } + NotifyScreenDisconnectedToAgentListeners(event.id, {event.output, event.reason}); + { + std::lock_guard lock(remoteConnsMtx_); + auto iter = remoteConns_.find(event.id); + if (iter != remoteConns_.end()) { + remoteConns_.erase(iter); + } + } + } +} + +void RSScreenCallbackManager::NotifyScreenPropertesUpdated(ScreenId id, const RSScreenProperty& property) +{ + if (coreListener_) { + coreListener_->OnScreenPropertyChanged(id, property); + } else { + RS_LOGE("%{public}s: coreListener is nullptr", __func__); + } +} + +void RSScreenCallbackManager::NotifyFrameRefresh() +{ + if (coreListener_) { + coreListener_->OnFrameRefresh(id, property); + } else { + RS_LOGE("%{public}s: coreListener is nullptr", __func__); + } +} + +void RSScreenCallbackManager::NotifyHwcDead(const ScreenPresenceEvent& event) +{ + if (coreListener_) { + // output后续要重构掉 + coreListener_->OnScreenDisconnected(event.id, {event.output, event.reason}); + } else { + RS_LOGE("%{public}s: coreListener is nullptr", __func__); + } +} + +void RSScreenCallbackManager::NotifyVBlankIdle(ScreenId id, uint64_t ns) +{ + if (coreListener_) { + coreListener_->OnVBlankIdle(id, ns); + } else { + RS_LOGE("%{public}s: coreListener is nullptr", __func__); } } -void RSScreenCallbackManager::NotifyScreenDisconnected(ScreenId id, const ScreenEventData& data) +void RSScreenCallbackManager::NotifyVirtualScreenPresenceChanged(ScreenId id, bool connected) { - std::lock_guard lock(mtx_); - for (const auto& coreListener : coreListeners_) { - coreListener->OnScreenDisconnected(id, data); - auto iter = remoteObjMap_.find(id); - if (iter != remoteObjMap_.end()) { - remoteObjMap_.erase(iter); + if (connected) { + if (coreListener_) { + coreListener_->OnVirtualScreenConnected(id); + } else { + RS_LOGE("%{public}s: coreListener is nullptr", __func__); } - for (const auto& agentListener : agentListeners_) { - agentListener->OnScreenDisconnected(id, data.reason); + } else { + if (coreListener_) { + coreListener_->OnVirtualScreenDisconnected(id); + } else { + RS_LOGE("%{public}s: coreListener is nullptr", __func__); } } } -sptr RSScreenCallbackManager::GetScreenRemoteObj(ScreenId id) const +sptr RSScreenCallbackManager::GetScreenRemoteConn(ScreenId id) const { - std::lock_guard lock(mtx_); + std::lock_guard lock(remoteConnsMtx_); auto iter = remoteObjMap_.find(id); - if (iter == remoteObjMap_.end()) { + if (iter != remoteObjMap_.end()) { + return iter->second; + } else { return nullptr; } - return iter->second; +} + +void RSScreenCallbackManager::NotifyScreenConnectedToAgentListeners(ScreenId id, + ScreenChangeReason reason, sptr remoteConn) +{ + std::vector> agentListeners; + { + std::lock_guard lock(agentMtx_); + agentListeners = agentListeners_; + } + RS_LOGI("%{public}s: screen %{public}" PRTu64 "is connected, reason:%{public}u,conn:%{public}s,size:%{public}zu", + __func__, id, static_cast(reason), remoteConn? "not nullptr" : "nullptr", agentListeners.size()); + for (const auto& agentListener : agentListeners) { + if (!agentListener) { + continue; + } + agentListener->OnScreenConnected(id, reason, remoteConn); + } +} + +void RSScreenCallbackManager::NotifyScreenDisconnectedToAgentListeners(ScreenId id, ScreenChangeReason reason) +{ + std::vector> agentListeners; + { + std::lock_guard lock(agentMtx_); + agentListeners = agentListeners_; + } + RS_LOGI("%{public}s: screen %{public}" PRTu64 "is disconnected, reason:%{public}u,conn:%{public}s,size:%{public}zu", + __func__, id, static_cast(reason), remoteConn? "not nullptr" : "nullptr", agentListeners.size()); + for (const auto& agentListener : agentListeners) { + if (!agentListener) { + continue; + } + agentListener->OnScreenDisconnected(id, reason); + } } } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.h b/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.h index cf35e95182e8388b7d9e6af23e8aac32cf797230..a60e0fa8ea4c3b40e1de120064a321082bff1b97 100644 --- a/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.h +++ b/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_manager.h @@ -19,31 +19,47 @@ #include #include +#include #include #include -#include +#include namespace OHOS { namespace Rosen { +struct ScreenPresenceEvent { + ScreenId id; + bool connected = false; + ScreenChangeReason reason; + std::shared_ptr output; + RSScreenProperty property; +}; + class RSScreenCallbackManager { public: - void RegisterCoreCallback(const sptr& listener); - void UnRegisterCoreCallback(const sptr& listener); + void SetCoreListener(const sptr& listener); + sptr GetCoreListener() const; - void RegisterAgentCallback(const sptr& listener); - void UnRegisterAgentCallback(const sptr& listener); + void AddAgentListener(const sptr& listener); + void RemoveAgentListener(const sptr& listener); - void NotifyScreenConnected(ScreenId id, const ScreenEventData& data, const ScreenInfo& info); - void NotifyScreenDisconnected(ScreenId id, const ScreenEventData& data); - void NotifyScreenPropertyChanged(ScreenId id, const ScreenInfo& info); + void NotifyScreenPresenceChanged(const ScreenPresenceEvent& event); + void NotifyScreenPropertesUpdated(ScreenId id, const RSScreenProperty& property); + void NotifyFrameRefresh(); + void NotifyHwcDead(const ScreenPresenceEvent& event); + void NotifyVBlankIdle(ScreenId id, uint64_t ns); + void NotifyVirtualScreenPresenceChanged(ScreenId id, bool connected); - sptr GetScreenRemoteObj(ScreenId id) const; + sptr GetScreenRemoteConn(ScreenId id) const; private: - std::vector> coreListeners_; + void NotifyScreenConnectedToAgentListeners(ScreenId id, ScreenChangeReason reason, sptr remoteConn); + void NotifyScreenDisconnectedToAgentListeners(ScreenId id, ScreenChangeReason reason); + + std::unordered_map> remoteConns_; + sptr coreListener_; std::vector> agentListeners_; - std::unordered_map> remoteObjMap_; - mutable std::mutex mtx_; + mutable std::mutex agentMtx_; + mutable std::mutex remoteConnsMtx_; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_agent_listener.h b/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_agent_listener.h index 6aa671492c166ca9d005902fcb8e3a7e89bd0ee1..cc133f0017284fd11de384243f6c9d3fa62c4e9a 100644 --- a/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_agent_listener.h +++ b/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_agent_listener.h @@ -20,6 +20,7 @@ #include #include +#include namespace OHOS { namespace Rosen { @@ -28,7 +29,7 @@ public: virtual ~RSIScreenManagerAgentListener() = default; virtual void OnScreenConnected(ScreenId id, ScreenChangeReason reason, sptr obj) = 0; virtual void OnScreenDisconnected(ScreenId id, ScreenChangeReason reason) = 0; - virtual void OnScreenPropertyChanged(ScreenId id, const ScreenInfo& info) = 0; + virtual void OnScreenPropertyChanged(ScreenId id, const RSScreenProperty& info) = 0; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_listener.h b/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_listener.h index 7b33d7e56f44ca438cf8b691c2a213ceae3bb588..c963a2d820746ec4b02db2c1d18fec1feced70aa 100644 --- a/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_listener.h +++ b/rosen/modules/render_service/screen_manager/public/rs_iscreen_manager_listener.h @@ -20,15 +20,25 @@ #include #include +#include namespace OHOS { namespace Rosen { +struct ScreenEventData { + std::shared_ptr output; + ScreenChangeReason reason; +}; + class RSIScreenManagerListener : public RefBase { public: virtual ~RSIScreenManagerListener() = default; - virtual sptr OnScreenConnected(ScreenId id, const ScreenEventData& data, const ScreenInfo& info) = 0; + virtual sptr OnScreenConnected(ScreenId id, const ScreenEventData& data, const RSScreenProperty& property) = 0; virtual void OnScreenDisconnected(ScreenId id, const ScreenEventData& data) = 0; - virtual void OnScreenPropertyChanged(ScreenId id, const ScreenInfo& info) = 0; + virtual void OnScreenPropertyChanged(ScreenId id, const RSScreenProperty& property) = 0; + virtual void OnFrameRefresh() = 0; + virtual void OnVBlankIdle(ScreenId id) = 0; + virtual void OnVirtualScreenConnected(ScreenId id) = 0; + virtual void OnVirtualScreenDisconnected(ScreenId id) = 0; }; } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service/screen_manager/rs_screen_preprocessor.cpp b/rosen/modules/render_service/screen_manager/rs_screen_preprocessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..840dd95f1599dab89bc2afb094a1c1f90c7a65d8 --- /dev/null +++ b/rosen/modules/render_service/screen_manager/rs_screen_preprocessor.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rs_screen_preprocessor.h" + +#include "common/rs_optional_trace.h" +#include "graphic_feature_param_manager.h" +#include + +namespace OHOS { +namespace Rosen { +void RSScreenPreprocessor::OnHotPlug(std::shared_ptr& output, bool connected, void *data) +{ + if (output == nullptr) { + RS_LOGE("%{public}s: output is nullptr.", __func__); + return; + } + + RSScreenPreprocessor* processor = nullptr; + if (data != nullptr) { + RS_LOGI("%{public}s: data is not nullptr.", __func__); + processor = static_cast(data); + } else { + RS_LOGI("%{public}s: data is nullptr.", __func__); + } + + if (processor == nullptr) { + RS_LOGE("%{public}s: Failed to find RSScreenPreprocessor instance.", __func__); + return; + } + + processor->OnHotPlugEvent(output, connected); +} + +void RSScreenPreprocessor::OnRefresh(ScreenId id, void *data) +{ + RSScreenPreprocessor* processor = nullptr; + if (data != nullptr) { + RS_LOGI("%{public}s: data is not nullptr.", __func__); + processor = static_cast(data); + } else { + RS_LOGI("%{public}s: data is nullptr.", __func__); + } + + if (processor == nullptr) { + RS_LOGE("%{public}s: Failed to find RSScreenPreprocessor instance.", __func__); + return; + } + processor->OnRefreshEvent(id); +} + +void RSScreenPreprocessor::OnHwcDead(void *data) +{ + RS_LOGW("%{public}s: The composer_host is already dead.", __func__); + RSScreenPreprocessor* processor = nullptr; + if (data != nullptr) { + RS_LOGI("%{public}s: data is not nullptr.", __func__); + processor = static_cast(data); + } else { + RS_LOGI("%{public}s: data is nullptr.", __func__); + } + + if (processor == nullptr) { + RS_LOGE("%{public}s: Failed to find RSScreenPreprocessor instance.", __func__); + return; + } + processor->OnHwcDeadEvent(); +} + +void RSScreenPreprocessor::OnScreenVBlankIdle(uint32_t devId, uint64_t ns, void *data) +{ + RS_LOGI("%{public}s: devId:%{public}u, ns:" RSPUBU64, __func__, devId, ns); + RS_TRACE_NAME_FMT("OnScreenVBlankIdle devId:%u, ns:%lu", devId, ns); + CreateVSyncSampler()->StartSample(true); + RSScreenPreprocessor* processor = nullptr; + if (data != nullptr) { + RS_LOGI("%{public}s: data is not nullptr.", __func__); + processor = static_cast(data); + } else { + RS_LOGI("%{public}s: data is nullptr.", __func__); + } + + if (processor == nullptr) { + RS_LOGE("%{public}s: Failed to find RSScreenPreprocessor instance.", __func__); + return; + } + processor->OnScreenVBlankIdleEvent(devId, ns); +} + +bool RSScreenPreprocessor::Init() noexcept +{ + composer_ = HdiBackend::GetInstance(); + if (composer_ == nullptr) { + RS_LOGE("%{public}s: Failed to get composer.", __func__); + return false; + } + + if (composer_->RegScreenHotplug(&RSScreenPreprocessor::OnHotPlug, this) != 0) { + RS_LOGE("%{public}s: Failed to register OnHotPlug Func to composer.", __func__); + return false; + } + + if (composer_->RegScreenRefresh(&RSScreenPreprocessor::OnRefresh, this) != 0) { + RS_LOGE("%{public}s: Failed to register OnRefresh Func to composer.", __func__); + } + + if (composer_->RegHwcDeadListener(&RSScreenPreprocessor::OnHwcDead, this) != 0) { + RS_LOGE("%{public}s: Failed to register OnHwcDead Func to composer.", __func__); + return false; + } + + // This feature attribute is non-core for startup; do not return false. + if (composer_->RegScreenVBlankIdleCallback(&RSScreenPreprocessor::OnScreenVBlankIdle, this) != 0) { + RS_LOGW("%{public}s: Not support register OnScreenVBlankIdle Func to composer.", __func__); + } + RS_LOGI("Init RSScreenPreprocessor succeed"); + return true; +} + +void RSScreenPreprocessor::OnHotPlugEvent(std::shared_ptr& output, bool connected) +{ + { + std::lock_guard lock(hotPlugMutex_); + ScreenId id = ToScreenId(output->GetScreenId()); + if (pendingHotPlugEvents_.find(id) != pendingHotPlugEvents_.end()) { + RS_LOGE("%{public}s: screen %{public}" PRIu64 "is covered.", __func__, id); + } + pendingHotPlugEvents_[id] = ScreenHotPlugEvent{output, connected}; + RS_LOGI("%{public}s: screen %{public}" PRIu64 "is %{public}s, event has been saved", __func__, id, + connected ? "connected" : "disconnected"); + } + + auto task = [this]() { + std::map pendingHotPlugEvents; + { + std::lock_guard lock(hotPlugMutex_); + pendingHotPlugEvents.swap(pendingHotPlugEvents_); + } + for (auto& [_, event] : pendingHotPlugEvents) { + if (event.output == nullptr) { + RS_LOGE("%{public}s: output is nullptr.", __func__); + continue; + } + if (event.connected) { + ConfigureScreenConnected(event.output); + } else { + ConfigureScreenDisconnected(event.output); + } + } + if (auto owner = owner_.promote()) { + owner->ProcessPendingConnections(); + } + isHwcDead_ = false; + }; + ScheduleTask(task); +} + +void RSScreenPreprocessor::ConfigureScreenConnected(std::share_ptr& output) +{ + ScreenId id = ToScreenId(output->GetScreenId()); + RS_LOGI("%{public}s The screen for id %{public}" PRIu64 " connected.", __func__, id); + + ScreenChangeReason reason = ScreenChangeReason::DEFAULT; + if (isHwcDead_ && id !=0 && MultiScreenParam::IsRsReportHwcDead()) { + reason = ScreenChangeReason::HWCDEAD; + } + if (auto owner = owner.promote()) { + if (owner->GetScreen(id)) { + RS_LOGW("dmulti_process %{public}s The screen for id %{public}" PRIu64 " already existed.", __func__, id); + if (auto callbackMgr = callbackMgrWeak_.lock()) { + ScreenPresenceEvent event = {.id = id, .connected = false, .reason = reason, .output = output}; + callbackMgr->NotifyScreenPresenceChanged(event); + } + } + owner->ProcessScreenConnected(id, output); + if (auto callbackMgr = callbackMgrWeak_.lock()) { + ScreenPresenceEvent event = {.id = id, .connected = true, .reason = reason, + .output = output, .property = owner->QueryScreenProperty(id)}; + callbackMgr->NotifyScreenPresenceChanged(event); + } + owner->AddScreenToHgm(output); + } +} + +void RSScreenPreprocessor::ConfigureScreenDisconnected(std::share_ptr& output) +{ + ScreenId id = ToScreenId(output->GetScreenId()); + RS_LOGI("%{public}s The screen for id %{public}" PRIu64 " disconnected.", __func__, id); + + ScreenChangeReason reason = ScreenChangeReason::DEFAULT; + if (isHwcDead_ && id !=0 && MultiScreenParam::IsRsReportHwcDead()) { + reason = ScreenChangeReason::HWCDEAD; + } + if (auto owner = owner.promote()) { + if (owner->GetScreen(id)) { + RS_LOGW("dmulti_process %{public}s The screen for id %{public}" PRIu64 " already existed.", __func__, id); + if (auto callbackMgr = callbackMgrWeak_.lock()) { + ScreenPresenceEvent event = {.id = id, .connected = false, .reason = reason, .output = output}; + callbackMgr->NotifyScreenPresenceChanged(event); + } + } + owner->ProcessScreenDisConnected(id, output); + owner->RemoveScreenToHgm(output); + } +} + +void RSScreenPreprocessor::OnRefreshEvent(ScreenId id) +{ + if (auto owner = owner_.promote()) { + owner->OnRefreshEvent(); + } +} + +void RSScreenPreprocessor::OnHwcDeadEvent() +{ + auto task = [this]() { + isHwcDead_ = true; + if (auto owner = owner_.promote()) { + owner->OnHwcDeadEvent(); + } + if (!composer_) { + RS_LOGE("CleanAndReinit: Failed to get composer."); + return; + } + composer_->ResetDevice(); + if (!Init()) { + RS_LOGE("CleanAndReinit: Reinit failed, RSScreenPreprocessor init failed."); + return; + } + } +} + +void RSScreenPreprocessor::OnScreenVBlankIdleEvent(uint32_t devId, uint64_t ns) +{ + if (auto owner = owner_.promote()) { + owner->OnScreenVBlankIdleEvent(devId, ns); + } +} + + +void RSScreenPreprocessor::ScheduleTask(std::function task) +{ + if (mainHandler_) { + mainHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE); + } +} +} // namespace Rosen +} // namespace OHOS diff --git a/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_types.h b/rosen/modules/render_service/screen_manager/rs_screen_preprocessor.h similarity index 32% rename from rosen/modules/render_service/screen_manager/callback/rs_screen_callback_types.h rename to rosen/modules/render_service/screen_manager/rs_screen_preprocessor.h index 1bb048ad192ffc856f5bbb2e723d25c85f9f3754..2f13f5d1b69509f9eeb9e263c94c258c1dc6d907 100644 --- a/rosen/modules/render_service/screen_manager/callback/rs_screen_callback_types.h +++ b/rosen/modules/render_service/screen_manager/rs_screen_preprocessor.h @@ -13,20 +13,56 @@ * limitations under the License. */ -#ifndef RS_SCREEN_CALLBACK_TYPES_H -#define RS_SCREEN_CALLBACK_TYPES_H +#ifndef RS_SCREEN_PREPROCESSOR_H +#define RS_SCREEN_PREPROCESSOR_H -#include -#include +#include +#include +#include #include +#include + namespace OHOS { namespace Rosen { -struct ScreenEventData { +class RSScreenManager; +struct ScreenHotPlugEvent { std::shared_ptr output; - ScreenChangeReason reason; + bool connected = false; }; +class RSScreenPreprocessor { +public: + explicit RSScreenPreprocessor(wptr owner, + std::shared_ptr callbackMgr, std::shared_ptr handler) + : owner_(owner), callbackMgrWeak_(callbackMgr), mainHandler_(handler) {} + ~RSScreenPreprocessor() = default; + + static void OnHotPlug(std::shared_ptr& output, bool connected, void *data); + static void OnRefresh(ScreenId id, void *data); + static void OnHwcDead(void *data); + static void OnScreenVBlankIdle(uint32_t devId, uint64_t ns, void *data); + + bool Init() noexcept; +private: + void OnHotPlugEvent(std::shared_ptr& output, bool connected); + void OnRefreshEvent(ScreenId id); + void OnHwcDeadEvent(); + void OnScreenVBlankIdleEvent(uint32_t devId, uint64_t ns); + + void ConfigureScreenConnected(); + void ConfigureScreenDisconnected(); + void ScheduleTask(std::function task); + + std::atomic isHwcDead_ = false; + HdiBackend *composer_ = nullptr; + wptr owner_; + std::weak_ptr callbackMgrWeak_; + std::shared_ptr mainHandler_; + std::map pendingHotPlugEvents_; + multable std::mutex hotPlugMutex_; +}; } // namespace Rosen } // namespace OHOS -#endif // RS_SCREEN_CALLBACK_TYPES_H \ No newline at end of file + +#endif // RS_SCREEN_PREPROCESSOR_H diff --git a/rosen/modules/render_service_base/BUILD.gn b/rosen/modules/render_service_base/BUILD.gn index 1fd41aea0de624d0d46650074b7a48741f2608e1..487a918704f48629e5b2f78463f6eb4dfcd83040 100644 --- a/rosen/modules/render_service_base/BUILD.gn +++ b/rosen/modules/render_service_base/BUILD.gn @@ -379,6 +379,7 @@ ohos_source_set("render_service_base_src") { "src/screen_manager/rs_screen_data.cpp", "src/screen_manager/rs_screen_hdr_capability.cpp", "src/screen_manager/rs_screen_mode_info.cpp", + "src/screen_manager/rs_screen_property.cpp", "src/screen_manager/rs_screen_props.cpp", "src/screen_manager/rs_virtual_screen_resolution.cpp", diff --git a/rosen/modules/render_service_base/include/screen_manager/rs_screen_property.h b/rosen/modules/render_service_base/include/screen_manager/rs_screen_property.h new file mode 100644 index 0000000000000000000000000000000000000000..4e0d884766981edac4c7434e490adc43af2cf917 --- /dev/null +++ b/rosen/modules/render_service_base/include/screen_manager/rs_screen_property.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RENDER_SERVICE_BASE_SCREEN_MANAGER_RS_SCREEN_PROPERTY_H +#define RENDER_SERVICE_BASE_SCREEN_MANAGER_RS_SCREEN_PROPERTY_H + +#include + +#include +#include "rs_screen_info.h" + +namespace OHOS { +namespace Rosen { +class RSB_EXPORT RSScreenProperty : public Parceable { +public: + RSScreenProperty(); + ~RSScreenProperty(); + + bool Marshalling(Parcel &data) const override; + static RSScreenProperty* Unmarshalling(Parcel &data); + + bool UnmarshallingData(Parcel &data); + + void SetId(ScreenId id); + void SetWidth(uint32_t width); + void SetHeight(uint32_t height); + void SetPhyWidth(uint32_t phyWidth); + void SetPhyHeight(uint32_t phyHeight); + void SetOffsetX(int32_t offsetX); + void SetOffsetY(int32_t offsetY); + void SetIsSamplingOn(bool isSamplingOn); + void SetSamplingTranslateX(float samplingTranslateX); + void SetSamplingTranslateY(float samplingTranslateY); + void SetSamplingScale(float samplingScale); + void SetScreenColorGamut(ScreenColorGamut colorGamut); + void SetState(ScreenState state); + void SetScreenSkipFrameInterval(uint32_t skipFrameInterval); + void SetScreenExpectedRefreshRate(uint32_t expectedRefreshRate); + void SetScreenSkipFrameStrategy(SkipFrameStrategy skipFrameStrategy); + void SetIsEqualVsyncPeriod(bool isEqualVsyncPeriod); + void SetPixelFormat(GraphicPixelFormat pixelFormat); + void SetScreenHDRFormat(ScreenHDRFormat hdrFormat); + void SetWhiteList(std::unordered_set whiteList); + void SetEnableVisibleRect(bool enableVisibleRect); + void SetActiveRect(RectI activeRect); + void SetMaskRect(RectI maskRect); + void SetReviseRect(RectI reviseRect); + + ScreenId GetScreenId() const; + uint32_t GetWidth() const; + uint32_t GetHeight() const; + uint32_t GetPhyWidth() const; + uint32_t GetPhyHeight() const; + int32_t GetOffsetX() const; + int32_t GetOffsetY() const; + bool GetIsSamplingOn() const; + float GetSamplingTranslateX() const; + float GetSamplingTranslateY() const; + float GetSamplingScale() const; + ScreenColorGamut GetScreenColorGamut() const; + ScreenState GetState() const; + uint32_t GetScreenSkipFrameInterval() const; + uint32_t GetScreenExpectedRefreshRate() const; + SkipFrameStrategy GetScreenSkipFrameStrategy() const; + bool GetEqualVsyncPeriod() const; + GraphicPixelFormat GetPixelFormat() const; + ScreenHDRFormat GetScreenHDRFormat() const; + std::unordered_set GetWhiteList() const; + bool GetEnableVisibleRect() const; + RectI GetActiveRect() const; + RectI GetMaskRect() const; + RectI GetReviseRect() const; + // TODO:: Temporarily put in public. Should be private + ScreenId id_ = INVALID_SCREEN_ID; + +private: + uint32_t width_ = 0; + uint32_t height_ = 0; + uint32_t phyWidth_ = 0; + uint32_t phyHeight_ = 0; + int32_t offsetX_ = 0; + int32_t offsetY_ = 0; + bool isSamplingOn_ = false; + int samplingDistance_ = 1; + float samplingTranslateX_ = 0.f; + float samplingTranslateY_ = 0.f; + float samplingScale_ = 1.f; + ScreenColorGamut colorGamut_ = ScreenColorGamut::COLOR_GAMUT_SRGB; + ScreenState state_ = ScreenState::UNKNOWN; + ScreenRotation rotation_ = ScreenRotation::ROTATION_0; + std::unordered_set whiteList_ = {}; + RectI activeRect_; + RectI maskRect_; + RectI reviseRect_; + + uint32_t skipFrameInterval_ = DEFAULT_SKIP_FRAME_INTERVAL; + uint32_t expectedRefreshRate_ = INVALID_EXPECTED_REFRESH_RATE; + SkipFrameStrategy skipFrameStrategy_ = SKIP_FRAME_BY_INTERVAL; + bool isEqualVsyncPeriod_ = true; + + GraphicPixelFormat pixelFormat_ = GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888; + ScreenHDRFormat hdrFormat_ = ScreenHDRFormat::NOT_SUPPORT_HDR; + + bool enableVisibleRect_; +}; +} // namespace Rosen +} // namespace OHOS + +#endif // RENDER_SERVICE_BASE_SCREEN_MANAGER_RS_SCREEN_PROPERTY_H \ No newline at end of file diff --git a/rosen/modules/render_service_base/src/screen_manager/rs_screen_property.cpp b/rosen/modules/render_service_base/src/screen_manager/rs_screen_property.cpp new file mode 100644 index 0000000000000000000000000000000000000000..749e5481eb1e1bb4c81ab58493f24d23adb1bfa8 --- /dev/null +++ b/rosen/modules/render_service_base/src/screen_manager/rs_screen_property.cpp @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "screen_manager/rs_screen_property.h" +#include "platform/common/rs_log.h" + +namespace OHOS { +namespace Rosen { +RSScreenProperty::RSScreenProperty() {} +RSScreenProperty::~RSScreenProperty() {} + +void RSScreenProperty::SetId(ScreenId id) +{ + id_ = id; +} + +void RSScreenProperty::SetWidth(uint32_t width) +{ + width_ = width; +} + +void RSScreenProperty::SetHeight(uint32_t height) +{ + height_ = height; +} + +void RSScreenProperty::SetPhyWidth(uint32_t phyWidth) +{ + phyWidth_ = phyWidth_; +} + +void RSScreenProperty::SetPhyHeight(uint32_t phyHeight) +{ + phyHeight_ = phyHeight; +} + +void RSScreenProperty::SetOffsetX(int32_t offsetX) +{ + offsetX_ = offsetX; +} + +void RSScreenProperty::SetOffsetY(int32_t offsetY) +{ + offsetY_ = offsetY; +} + +void RSScreenProperty::SetIsSamplingOn(bool isSamplingOn) +{ + isSamplingOn_ = isSamplingOn; +} + +void RSScreenProperty::SetSamplingTranslateX(float samplingTranslateX) +{ + samplingTranslateX_ = samplingTranslateX; +} + +void RSScreenProperty::SetSamplingTranslateY(float samplingTranslateY) +{ + samplingTranslateY_ = samplingTranslateY; +} + +void RSScreenProperty::SetSamplingScale(float samplingScale) +{ + samplingScale_ = samplingScale; +} + +void RSScreenProperty::SetScreenColorGamut(ScreenColorGamut colorGamut) +{ + colorGamut_ = colorGamut; +} + +void RSScreenProperty::SetState(ScreenState state) +{ + state_ = state; +} + +void RSScreenProperty::SetScreenSkipFrameInterval(uint32_t skipFrameInterval) +{ + skipFrameInterval_ = skipFrameInterval; +} + +void RSScreenProperty::SetScreenExpectedRefreshRate(uint32_t expectedRefreshRate) +{ + expectedRefreshRate_ = expectedRefreshRate; +} + +void RSScreenProperty::SetScreenSkipFrameStrategy(SkipFrameStrategy skipFrameStrategy) +{ + skipFrameStrategy_ = skipFrameStrategy; +} + +void RSScreenProperty::SetIsEqualVsyncPeriod(bool isEqualVsyncPeriod) +{ + isEqualVsyncPeriod_ = isEqualVsyncPeriod; +} + +void RSScreenProperty::SetPixelFormat(GraphicPixelFormat pixelFormat) +{ + pixelFormat_ = pixelFormat; +} + +void RSScreenProperty::SetScreenHDRFormat(ScreenHDRFormat hdrFormat) +{ + hdrFormat_ = hdrFormat; +} + +void RSScreenProperty::SetWhiteList(std::unordered_set whiteList) +{ + whiteList_.swap(whiteList); +} + +void RSScreenProperty::SetEnableVisibleRect(bool enableVisibleRect) +{ + enableVisibleRect_ = enableVisibleRect; +} + +void RSScreenProperty::SetActiveRect(RectI activeRect) +{ + activeRect_ = activeRect; +} + +void RSScreenProperty::SetMaskRect(RectI maskRect) +{ + maskRect_ = maskRect; +} + +void RSScreenProperty::SetReviseRect(RectI reviseRect) +{ + reviseRect_ = reviseRect; +} + +ScreenId RSScreenProperty::GetScreenId() const +{ + return id_; +} + +uint32_t RSScreenProperty::GetWidth() const +{ + return width_; +} + +uint32_t RSScreenProperty::GetHeight() const +{ + return height_; +} + +uint32_t RSScreenProperty::GetPhyWidth() const +{ + return phyWidth_; +} + +uint32_t RSScreenProperty::GetPhyHeight() const +{ + return phyHeight_; +} + +int32_t RSScreenProperty::GetOffsetX() const +{ + return offsetX_; +} + +int32_t RSScreenProperty::GetOffsetY() const +{ + return offsetY_; +} + +bool RSScreenProperty::GetIsSamplingOn() const +{ + return isSamplingOn_; +} + +float RSScreenProperty::GetSamplingTranslateX() const +{ + return samplingTranslateX_; +} + +float RSScreenProperty::GetSamplingTranslateY() const +{ + return samplingTranslateY_; +} + +float RSScreenProperty::GetSamplingScale() const +{ + return samplingScale_; +} + +ScreenColorGamut RSScreenProperty::GetScreenColorGamut() const +{ + return ScreenColorGamut; +} + +ScreenState RSScreenProperty::GetState() const +{ + return state_; +} + +uint32_t RSScreenProperty::GetScreenSkipFrameInterval() const +{ + return skipFrameInterval_; +} + +uint32_t RSScreenProperty::GetScreenExpectedRefreshRate() const +{ + return expectedRefreshRate_; +} + +SkipFrameStrategy RSScreenProperty::GetScreenSkipFrameStrategy() const +{ + return skipFrameStrategy_; +} + +bool RSScreenProperty::GetEqualVsyncPeriod() const +{ + return isEqualVsyncPeriod_; +} + +GraphicPixelFormat RSScreenProperty::GetPixelFormat() const +{ + return pixelFormat_; +} + +ScreenHDRFormat RSScreenProperty::GetScreenHDRFormat() const +{ + return hdrFormat_; +} + +std::unordered_set RSScreenProperty::GetWhiteList() const +{ + return whiteList_; +} + +bool RSScreenProperty::GetEnableVisibleRect() const +{ + return reviseRect_; +} + +RectI RSScreenProperty::GetActiveRect() const +{ + return activeRect_; +} + +RectI RSScreenProperty::GetMaskRect() const +{ + return maskRect_; +} + +RectI RSScreenProperty::GetReviseRect() const +{ + return reviseRect_; +} + +bool RSScreenProperty::Marshalling(Parcel &data) const +{ + if (!data.WriteUint64(id_)) { + ROSEN_LOGE("WriteScreenProperty: WriteUint64 id err."); + return false; + } + if (!data.WriteUint32(width_)) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 width err."); + return false; + } + if (!data.WriteUint32(height_) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 height err."); + return false; + } + if (!data.WriteUint32(phyWidth_) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 phyWidth err."); + return false; + } + if (!data.WriteUint32(phyHeight_) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 phyHeight err."); + return false; + } + if (!data.WriteUint32(offsetX_) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 offsetX err."); + return false; + } + if (!data.WriteUint32(offsetY_) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 offsetY err."); + return false; + } + if (!data.WriteBool(isSamplingOn_) { + ROSEN_LOGE("WriteScreenProperty: WriteBool isSamplingOn err."); + return false; + } + if (!data.WriteInt32(static_cast(samplingDistance_)) { + ROSEN_LOGE("WriteScreenProperty: WriteInt32 samplingDistance err."); + return false; + } + if (!data.WriteFloat(samplingTranslateX_) { + ROSEN_LOGE("WriteScreenProperty: WriteFloat samplingTranslateX err."); + return false; + } + if (!data.WriteFloat(samplingTranslateY_) { + ROSEN_LOGE("WriteScreenProperty: WriteFloat samplingTranslateY err."); + return false; + } + if (!data.WriteFloat(samplingScale_) { + ROSEN_LOGE("WriteScreenProperty: WriteFloat samplingScale err."); + return false; + } + if (!data.WriteUint32(static_cast(colorGamut_)) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 colorGamut err."); + return false; + } + if (!data.WriteUint8(static_cast(state_)) { + ROSEN_LOGE("WriteScreenProperty: WriteUint8 state err."); + return false; + } + if (!data.WriteUint32(static_cast(rotation_)) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 rotation err."); + return false; + } + uint32_t whiteListSize = whiteList_.size(); + if (!data.WriteUint32(whiteListSize) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 whiteListSize err."); + return false; + } + for (auto screenId : whiteList_) { + if (!data.WriteUint64(screenId)) { + ROSEN_LOGE("WriteScreenProperty: WriteUint64 whiteList err."); + return false; + } + } +#ifdef ROSEN_OHOS + if (!activeRect_.Marshalling(data)) { + ROSEN_LOGE("WriteScreenProperty: Marshalling activeRect err."); + return false; + } + if (!maskRect_.Marshalling(data)) { + ROSEN_LOGE("WriteScreenProperty: Marshalling maskRect_ err."); + return false; + } + if (!reviseRect_.Marshalling(data)) { + ROSEN_LOGE("WriteScreenProperty: Marshalling reviseRect_ err."); + return false; + } +#endif + if (!data.WriteUint32(skipFrameInterval_) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 skipFrameInterval err."); + return false; + } + if (!data.WriteUint32(expectedRefreshRate_) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 expectedRefreshRate err."); + return false; + } + if (!data.WriteInt32(static_cast(skipFrameStrategy_)) { + ROSEN_LOGE("WriteScreenProperty: WriteInt32 skipFrameStrategy err."); + return false; + } + if (!data.WriteBool(isEqualVsyncPeriod_) { + ROSEN_LOGE("WriteScreenProperty: WriteBool isEqualVsyncPeriod err."); + return false; + } + if (!data.WriteInt32(static_cast(pixelFromat_)) { + ROSEN_LOGE("WriteScreenProperty: WriteInt32 pixelFromat err."); + return false; + } + if (!data.WriteUint32(static_cast(hdrFormat_)) { + ROSEN_LOGE("WriteScreenProperty: WriteUint32 hdrFormat err."); + return false; + } + if (!data.WriteBool(enableVisibleRect_) { + ROSEN_LOGE("WriteScreenProperty: WriteBool enableVisibleRect err."); + return false; + } + return true; +} + +static RSScreenProperty* RSScreenProperty::Unmarshalling(Parcel &data) +{ + auto screenProperty = new RSScreenProperty(); + if (screenProperty->UnmarshallingData(data)) { + return screenProperty; + } + return nullptr; +} + +bool RSScreenProperty::UnmarshallingData(Parcel &data) +{ + if (!data.ReadUint64(id_)){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint64 id err."); + return false; + } + if (!data.ReadUint32(width_)){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 width err."); + return false; + } + if (!data.ReadUint32(height_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 height err."); + return false; + } + if (!data.ReadUint32(phyWidth_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 phyWidth err."); + return false; + } + if (!data.ReadUint32(phyHeight_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 phyHeight err."); + return false; + } + if (!data.ReadInt32(offsetX_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadInt32 offsetX err."); + return false; + } + if (!data.ReadInt32(offsetY_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadInt32 offsetY err."); + return false; + } + if (!data.ReadBool(isSamplingOn_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadBool isSamplingOn err."); + return false; + } + int32_t samplingDistance = 0; + if (!data.ReadInt32(samplingDistance){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadInt32 samplingDistance err."); + return false; + } + samplingDistance_ = static_cast(samplingDistance); + if (!data.ReadFloat(samplingTranslateX_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadFloat samplingTranslateX err."); + return false; + } + if (!data.ReadFloat(samplingTranslateY_) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadFloat samplingTranslateY err."); + return false; + } + if (!data.ReadFloat(samplingScale_) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadFloat samplingScale err."); + return false; + } + uint32_t colorGamut = 0; + if (!data.ReadUint32(colorGamut) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 colorGamut err."); + return false; + } + colorGamut_ = static_cast(colorGamut); + uint8_t state = 0; + if (!data.ReadUint8(state) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint8 state err."); + return false; + } + state_ = static_cast(state); + uint32_t rotation = 0; + if (!data.ReadUint32(rotation) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 rotation err."); + return false; + } + rotation_ = static_cast(rotation); + // whiteList + uint32_t whiteListSize = 0; + ScreenId screenId = 0; + if (!data.ReadUint32(whiteListSize) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 whiteListSize err."); + return false; + } + for (auto i = 0; i < whiteListSize; i++) { + if (!data.ReadUint64(screenId)) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint64 whiteList err."); + return false; + } + whiteList_.emplace(screenId); + } + +// Rects +#ifdef ROSEN_OHOS + if (!RSMarshallingHelper::Unmarshalling(data, activeRect_)) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: Unmarshalling activeRect err."); + return false; + } + if (!RSMarshallingHelper::Unmarshalling(data, maskRect_)) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: Unmarshalling maskRect err."); + return false; + } + if (!RSMarshallingHelper::Unmarshalling(data, reviseRect_)) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: Unmarshalling reviseRect err."); + return false; + } +#endif + + if (!data.ReadUint32(skipFrameInterval_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 skipFrameInterval err."); + return false; + } + if (!data.ReadUint32(expectedRefreshRate_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 expectedRefreshRate err."); + return false; + } + int skipFrameStrategy = 0; + if (!data.ReadInt32(skipFrameStrategy){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadInt32 skipFrameStrategy err."); + return false; + } + skipFrameStrategy_ = static_cast(skipFrameStrategy); + if (!data.ReadBool(isEqualVsyncPeriod_){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadBool isEqualVsyncPeriod err."); + return false; + } + int32_t pixelFormat = 0; + if (!data.ReadInt32(pixelFormat){ + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadInt32 pixelFormat err."); + return false; + } + pixelFormat_ = static_cast(pixelFormat); + uint32_t hdrFormat = 0; + if (!data.ReadUint32(hdrFormat)) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 hdrFormat err."); + return false; + } + hdrFormat_ = static_cast(hdrFormat); + if (!data.ReadBool(enableVisibleRect_)) { + ROSEN_LOGE("RSScreenProperty::Unmarshalling: ReadUint32 hdrFormat err."); + return false; + } + return true; +} + +} // namespace Rosen +} // namespace OHOS \ No newline at end of file