| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include "core/core.h"
- #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
- #include "core/hle/service/nvdrv/nvdrv_interface.h"
- #include "core/hle/service/nvnflinger/display.h"
- #include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
- #include "core/hle/service/nvnflinger/surface_flinger.h"
- #include "core/hle/service/sm/sm.h"
- #include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
- #include "core/hle/service/nvnflinger/buffer_queue_core.h"
- #include "core/hle/service/nvnflinger/buffer_queue_producer.h"
- namespace Service::Nvnflinger {
- SurfaceFlinger::SurfaceFlinger(Core::System& system, HosBinderDriverServer& server)
- : m_system(system), m_server(server), m_context(m_system, "SurfaceFlinger") {
- nvdrv = m_system.ServiceManager().GetService<Nvidia::NVDRV>("nvdrv:s", true)->GetModule();
- disp_fd = nvdrv->Open("/dev/nvdisp_disp0", {});
- }
- SurfaceFlinger::~SurfaceFlinger() {
- nvdrv->Close(disp_fd);
- }
- void SurfaceFlinger::AddDisplay(u64 display_id) {
- m_displays.emplace_back(display_id);
- }
- void SurfaceFlinger::RemoveDisplay(u64 display_id) {
- std::erase_if(m_displays, [&](auto& display) { return display.id == display_id; });
- }
- bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
- u64 display_id) {
- auto* const display = this->FindDisplay(display_id);
- if (!display || !display->stack.HasLayers()) {
- return false;
- }
- *out_swap_interval =
- m_composer.ComposeLocked(out_compose_speed_scale, *display,
- *nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd));
- return true;
- }
- void SurfaceFlinger::CreateLayer(s32 consumer_binder_id) {
- auto binder = std::static_pointer_cast<android::BufferQueueConsumer>(
- m_server.TryGetBinder(consumer_binder_id));
- if (!binder) {
- return;
- }
- auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(binder));
- buffer_item_consumer->Connect(false);
- m_layers.layers.emplace_back(
- std::make_shared<Layer>(std::move(buffer_item_consumer), consumer_binder_id));
- }
- void SurfaceFlinger::DestroyLayer(s32 consumer_binder_id) {
- std::erase_if(m_layers.layers,
- [&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
- }
- void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) {
- auto* const display = this->FindDisplay(display_id);
- auto layer = this->FindLayer(consumer_binder_id);
- if (!display || !layer) {
- return;
- }
- display->stack.layers.emplace_back(std::move(layer));
- }
- void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id) {
- auto* const display = this->FindDisplay(display_id);
- if (!display) {
- return;
- }
- m_composer.RemoveLayerLocked(*display, consumer_binder_id);
- std::erase_if(display->stack.layers,
- [&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
- }
- void SurfaceFlinger::SetLayerVisibility(s32 consumer_binder_id, bool visible) {
- if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
- layer->visible = visible;
- return;
- }
- }
- void SurfaceFlinger::SetLayerBlending(s32 consumer_binder_id, LayerBlending blending) {
- if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
- layer->blending = blending;
- return;
- }
- }
- Display* SurfaceFlinger::FindDisplay(u64 display_id) {
- for (auto& display : m_displays) {
- if (display.id == display_id) {
- return &display;
- }
- }
- return nullptr;
- }
- std::shared_ptr<Layer> SurfaceFlinger::FindLayer(s32 consumer_binder_id) {
- for (auto& layer : m_layers.layers) {
- if (layer->consumer_id == consumer_binder_id) {
- return layer;
- }
- }
- return nullptr;
- }
- void SurfaceFlinger::CreateBufferQueue(s32* out_consumer_binder_id, s32* out_producer_binder_id) {
- auto& nvmap = nvdrv->GetContainer().GetNvMapFile();
- auto core = std::make_shared<android::BufferQueueCore>();
- auto producer = std::make_shared<android::BufferQueueProducer>(m_context, core, nvmap);
- auto consumer = std::make_shared<android::BufferQueueConsumer>(core);
- *out_consumer_binder_id = m_server.RegisterBinder(std::move(consumer));
- *out_producer_binder_id = m_server.RegisterBinder(std::move(producer));
- }
- void SurfaceFlinger::DestroyBufferQueue(s32 consumer_binder_id, s32 producer_binder_id) {
- m_server.UnregisterBinder(producer_binder_id);
- m_server.UnregisterBinder(consumer_binder_id);
- }
- } // namespace Service::Nvnflinger
|