surface_flinger.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "core/core.h"
  4. #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
  5. #include "core/hle/service/nvdrv/nvdrv_interface.h"
  6. #include "core/hle/service/nvnflinger/display.h"
  7. #include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
  8. #include "core/hle/service/nvnflinger/surface_flinger.h"
  9. #include "core/hle/service/sm/sm.h"
  10. #include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
  11. #include "core/hle/service/nvnflinger/buffer_queue_core.h"
  12. #include "core/hle/service/nvnflinger/buffer_queue_producer.h"
  13. namespace Service::Nvnflinger {
  14. SurfaceFlinger::SurfaceFlinger(Core::System& system, HosBinderDriverServer& server)
  15. : m_system(system), m_server(server), m_context(m_system, "SurfaceFlinger") {
  16. nvdrv = m_system.ServiceManager().GetService<Nvidia::NVDRV>("nvdrv:s", true)->GetModule();
  17. disp_fd = nvdrv->Open("/dev/nvdisp_disp0", {});
  18. }
  19. SurfaceFlinger::~SurfaceFlinger() {
  20. nvdrv->Close(disp_fd);
  21. }
  22. void SurfaceFlinger::AddDisplay(u64 display_id) {
  23. m_displays.emplace_back(display_id);
  24. }
  25. void SurfaceFlinger::RemoveDisplay(u64 display_id) {
  26. std::erase_if(m_displays, [&](auto& display) { return display.id == display_id; });
  27. }
  28. bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
  29. u64 display_id) {
  30. auto* const display = this->FindDisplay(display_id);
  31. if (!display || !display->stack.HasLayers()) {
  32. return false;
  33. }
  34. *out_swap_interval =
  35. m_composer.ComposeLocked(out_compose_speed_scale, *display,
  36. *nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd));
  37. return true;
  38. }
  39. void SurfaceFlinger::CreateLayer(s32 consumer_binder_id) {
  40. auto binder = std::static_pointer_cast<android::BufferQueueConsumer>(
  41. m_server.TryGetBinder(consumer_binder_id));
  42. if (!binder) {
  43. return;
  44. }
  45. auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(binder));
  46. buffer_item_consumer->Connect(false);
  47. m_layers.layers.emplace_back(
  48. std::make_shared<Layer>(std::move(buffer_item_consumer), consumer_binder_id));
  49. }
  50. void SurfaceFlinger::DestroyLayer(s32 consumer_binder_id) {
  51. std::erase_if(m_layers.layers,
  52. [&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
  53. }
  54. void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) {
  55. auto* const display = this->FindDisplay(display_id);
  56. auto layer = this->FindLayer(consumer_binder_id);
  57. if (!display || !layer) {
  58. return;
  59. }
  60. display->stack.layers.emplace_back(std::move(layer));
  61. }
  62. void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id) {
  63. auto* const display = this->FindDisplay(display_id);
  64. if (!display) {
  65. return;
  66. }
  67. m_composer.RemoveLayerLocked(*display, consumer_binder_id);
  68. std::erase_if(display->stack.layers,
  69. [&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
  70. }
  71. void SurfaceFlinger::SetLayerVisibility(s32 consumer_binder_id, bool visible) {
  72. if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
  73. layer->visible = visible;
  74. return;
  75. }
  76. }
  77. void SurfaceFlinger::SetLayerBlending(s32 consumer_binder_id, LayerBlending blending) {
  78. if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
  79. layer->blending = blending;
  80. return;
  81. }
  82. }
  83. Display* SurfaceFlinger::FindDisplay(u64 display_id) {
  84. for (auto& display : m_displays) {
  85. if (display.id == display_id) {
  86. return &display;
  87. }
  88. }
  89. return nullptr;
  90. }
  91. std::shared_ptr<Layer> SurfaceFlinger::FindLayer(s32 consumer_binder_id) {
  92. for (auto& layer : m_layers.layers) {
  93. if (layer->consumer_id == consumer_binder_id) {
  94. return layer;
  95. }
  96. }
  97. return nullptr;
  98. }
  99. void SurfaceFlinger::CreateBufferQueue(s32* out_consumer_binder_id, s32* out_producer_binder_id) {
  100. auto& nvmap = nvdrv->GetContainer().GetNvMapFile();
  101. auto core = std::make_shared<android::BufferQueueCore>();
  102. auto producer = std::make_shared<android::BufferQueueProducer>(m_context, core, nvmap);
  103. auto consumer = std::make_shared<android::BufferQueueConsumer>(core);
  104. *out_consumer_binder_id = m_server.RegisterBinder(std::move(consumer));
  105. *out_producer_binder_id = m_server.RegisterBinder(std::move(producer));
  106. }
  107. void SurfaceFlinger::DestroyBufferQueue(s32 consumer_binder_id, s32 producer_binder_id) {
  108. m_server.UnregisterBinder(producer_binder_id);
  109. m_server.UnregisterBinder(consumer_binder_id);
  110. }
  111. } // namespace Service::Nvnflinger