summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp81
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h27
-rw-r--r--src/core/hle/service/service.cpp6
-rw-r--r--src/core/hle/service/service.h4
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp50
-rw-r--r--src/core/hle/service/vi/display/vi_display.h29
-rw-r--r--src/core/hle/service/vi/layer/vi_layer.cpp6
-rw-r--r--src/core/hle/service/vi/layer/vi_layer.h57
-rw-r--r--src/core/hle/service/vi/vi.cpp690
-rw-r--r--src/core/hle/service/vi/vi.h10
-rw-r--r--src/core/hle/service/vi/vi_m.cpp9
-rw-r--r--src/core/hle/service/vi/vi_m.h7
-rw-r--r--src/core/hle/service/vi/vi_s.cpp9
-rw-r--r--src/core/hle/service/vi/vi_s.h7
-rw-r--r--src/core/hle/service/vi/vi_u.cpp9
-rw-r--r--src/core/hle/service/vi/vi_u.h7
-rw-r--r--src/video_core/gpu.h1
17 files changed, 286 insertions, 723 deletions
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 01e69de30..e21dc902a 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -1,6 +1,5 @@
-// Copyright 2018 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright 2021 yuzu Emulator Project
#include <algorithm>
#include <optional>
@@ -16,8 +15,11 @@
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/nvdrv.h"
-#include "core/hle/service/nvflinger/buffer_queue.h"
+#include "core/hle/service/nvflinger/buffer_item_consumer.h"
+#include "core/hle/service/nvflinger/buffer_queue_core.h"
+#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
#include "core/hle/service/nvflinger/nvflinger.h"
+#include "core/hle/service/nvflinger/ui/graphic_buffer.h"
#include "core/hle/service/vi/display/vi_display.h"
#include "core/hle/service/vi/layer/vi_layer.h"
#include "video_core/gpu.h"
@@ -53,13 +55,14 @@ void NVFlinger::SplitVSync(std::stop_token stop_token) {
}
}
-NVFlinger::NVFlinger(Core::System& system_)
- : system(system_), service_context(system_, "nvflinger") {
- displays.emplace_back(0, "Default", service_context, system);
- displays.emplace_back(1, "External", service_context, system);
- displays.emplace_back(2, "Edid", service_context, system);
- displays.emplace_back(3, "Internal", service_context, system);
- displays.emplace_back(4, "Null", service_context, system);
+NVFlinger::NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_)
+ : system(system_), service_context(system_, "nvflinger"),
+ hos_binder_driver_server(hos_binder_driver_server_) {
+ displays.emplace_back(0, "Default", hos_binder_driver_server, service_context, system);
+ displays.emplace_back(1, "External", hos_binder_driver_server, service_context, system);
+ displays.emplace_back(2, "Edid", hos_binder_driver_server, service_context, system);
+ displays.emplace_back(3, "Internal", hos_binder_driver_server, service_context, system);
+ displays.emplace_back(4, "Null", hos_binder_driver_server, service_context, system);
guard = std::make_shared<std::mutex>();
// Schedule the screen composition events
@@ -83,12 +86,15 @@ NVFlinger::NVFlinger(Core::System& system_)
}
NVFlinger::~NVFlinger() {
- for (auto& buffer_queue : buffer_queues) {
- buffer_queue->Disconnect();
- }
if (!system.IsMulticore()) {
system.CoreTiming().UnscheduleEvent(composition_event, 0);
}
+
+ for (auto& display : displays) {
+ for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
+ display.GetLayer(layer).Core().NotifyShutdown();
+ }
+ }
}
void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
@@ -125,10 +131,8 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
}
void NVFlinger::CreateLayerAtId(VI::Display& display, u64 layer_id) {
- const u32 buffer_queue_id = next_buffer_queue_id++;
- buffer_queues.emplace_back(
- std::make_unique<BufferQueue>(system.Kernel(), buffer_queue_id, layer_id, service_context));
- display.CreateLayer(layer_id, *buffer_queues.back());
+ const auto buffer_id = next_buffer_queue_id++;
+ display.CreateLayer(layer_id, buffer_id);
}
void NVFlinger::CloseLayer(u64 layer_id) {
@@ -147,7 +151,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) {
return std::nullopt;
}
- return layer->GetBufferQueue().GetId();
+ return layer->GetBinderId();
}
Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) {
@@ -161,18 +165,6 @@ Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) {
return &display->GetVSyncEvent();
}
-BufferQueue* NVFlinger::FindBufferQueue(u32 id) {
- const auto lock_guard = Lock();
- const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(),
- [id](const auto& queue) { return queue->GetId() == id; });
-
- if (itr == buffer_queues.end()) {
- return nullptr;
- }
-
- return itr->get();
-}
-
VI::Display* NVFlinger::FindDisplay(u64 display_id) {
const auto itr =
std::find_if(displays.begin(), displays.end(),
@@ -246,23 +238,22 @@ void NVFlinger::Compose() {
// TODO(Subv): Support more than 1 layer.
VI::Layer& layer = display.GetLayer(0);
- auto& buffer_queue = layer.GetBufferQueue();
- // Search for a queued buffer and acquire it
- auto buffer = buffer_queue.AcquireBuffer();
+ android::BufferItem buffer{};
+ const auto status = layer.GetConsumer().AcquireBuffer(&buffer, 0, false);
- if (!buffer) {
+ if (status != android::Status::NoError) {
continue;
}
- const auto& igbp_buffer = buffer->get().igbp_buffer;
+ const auto& igbp_buffer = *buffer.graphic_buffer;
if (!system.IsPoweredOn()) {
return; // We are likely shutting down
}
auto& gpu = system.GPU();
- const auto& multi_fence = buffer->get().multi_fence;
+ const auto& multi_fence = buffer.fence;
guard->unlock();
for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
const auto& fence = multi_fence.fences[fence_id];
@@ -278,12 +269,18 @@ void NVFlinger::Compose() {
auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>("/dev/nvdisp_disp0");
ASSERT(nvdisp);
- nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.external_format,
- igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride,
- buffer->get().transform, buffer->get().crop_rect);
+ Common::Rectangle<int> crop_rect{
+ static_cast<int>(buffer.crop.Left()), static_cast<int>(buffer.crop.Top()),
+ static_cast<int>(buffer.crop.Right()), static_cast<int>(buffer.crop.Bottom())};
+
+ nvdisp->flip(igbp_buffer.BufferId(), igbp_buffer.Offset(), igbp_buffer.ExternalFormat(),
+ igbp_buffer.Width(), igbp_buffer.Height(), igbp_buffer.Stride(),
+ static_cast<android::BufferTransformFlags>(buffer.transform), crop_rect);
+
+ swap_interval = buffer.swap_interval;
- swap_interval = buffer->get().swap_interval;
- buffer_queue.ReleaseBuffer(buffer->get().slot);
+ auto fence = android::Fence::NoFence();
+ layer.GetConsumer().ReleaseBuffer(buffer, fence);
}
}
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 7935cf773..5112ae136 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -1,6 +1,5 @@
-// Copyright 2018 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright 2021 yuzu Emulator Project
#pragma once
@@ -9,6 +8,7 @@
#include <mutex>
#include <optional>
#include <thread>
+#include <unordered_map>
#include <vector>
#include "common/common_types.h"
@@ -37,13 +37,16 @@ class Display;
class Layer;
} // namespace Service::VI
-namespace Service::NVFlinger {
+namespace android {
+class BufferQueueCore;
+class BufferQueueProducer;
+} // namespace android
-class BufferQueue;
+namespace Service::NVFlinger {
class NVFlinger final {
public:
- explicit NVFlinger(Core::System& system_);
+ explicit NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_);
~NVFlinger();
/// Sets the NVDrv module instance to use to send buffers to the GPU.
@@ -72,9 +75,6 @@ public:
/// If an invalid display ID is provided, then nullptr is returned.
[[nodiscard]] Kernel::KReadableEvent* FindVsyncEvent(u64 display_id);
- /// Obtains a buffer queue identified by the ID.
- [[nodiscard]] BufferQueue* FindBufferQueue(u32 id);
-
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
/// finished.
void Compose();
@@ -82,6 +82,12 @@ public:
[[nodiscard]] s64 GetNextTicks() const;
private:
+ struct Layer {
+ std::unique_ptr<android::BufferQueueCore> core;
+ std::unique_ptr<android::BufferQueueProducer> producer;
+ };
+
+private:
[[nodiscard]] std::unique_lock<std::mutex> Lock() const {
return std::unique_lock{*guard};
}
@@ -111,7 +117,6 @@ private:
std::shared_ptr<Nvidia::Module> nvdrv;
std::list<VI::Display> displays;
- std::vector<std::unique_ptr<BufferQueue>> buffer_queues;
/// Id to use for the next layer that is created, this counter is shared among all displays.
u64 next_layer_id = 1;
@@ -131,6 +136,8 @@ private:
std::jthread vsync_thread;
KernelHelpers::ServiceContext service_context;
+
+ HosBinderDriverServer& hos_binder_driver_server;
};
} // namespace Service::NVFlinger
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index eb1138313..ab3286db9 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -49,6 +49,7 @@
#include "core/hle/service/npns/npns.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvdrv/nvdrv.h"
+#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
#include "core/hle/service/nvflinger/nvflinger.h"
#include "core/hle/service/olsc/olsc.h"
#include "core/hle/service/pcie/pcie.h"
@@ -230,7 +231,8 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& sessi
/// Initialize Services
Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system)
- : nv_flinger{std::make_unique<NVFlinger::NVFlinger>(system)} {
+ : hos_binder_driver_server{std::make_unique<NVFlinger::HosBinderDriverServer>(system)},
+ nv_flinger{std::make_unique<NVFlinger::NVFlinger>(system, *hos_binder_driver_server)} {
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
// here and pass it into the respective InstallInterfaces functions.
@@ -290,7 +292,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
SSL::InstallInterfaces(*sm, system);
Time::InstallInterfaces(system);
USB::InstallInterfaces(*sm, system);
- VI::InstallInterfaces(*sm, system, *nv_flinger);
+ VI::InstallInterfaces(*sm, system, *nv_flinger, *hos_binder_driver_server);
WLAN::InstallInterfaces(*sm, system);
}
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index c9d6b879d..b9ab2c465 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -33,8 +33,9 @@ class FileSystemController;
}
namespace NVFlinger {
+class HosBinderDriverServer;
class NVFlinger;
-}
+} // namespace NVFlinger
namespace SM {
class ServiceManager;
@@ -236,6 +237,7 @@ public:
~Services();
private:
+ std::unique_ptr<NVFlinger::HosBinderDriverServer> hos_binder_driver_server;
std::unique_ptr<NVFlinger::NVFlinger> nv_flinger;
};
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index b7705c02a..558022511 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -13,14 +13,34 @@
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/nvflinger/buffer_item_consumer.h"
+#include "core/hle/service/nvflinger/buffer_queue_consumer.h"
+#include "core/hle/service/nvflinger/buffer_queue_core.h"
+#include "core/hle/service/nvflinger/buffer_queue_producer.h"
+#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
#include "core/hle/service/vi/display/vi_display.h"
#include "core/hle/service/vi/layer/vi_layer.h"
namespace Service::VI {
-Display::Display(u64 id, std::string name_, KernelHelpers::ServiceContext& service_context_,
- Core::System& system_)
- : display_id{id}, name{std::move(name_)}, service_context{service_context_} {
+struct BufferQueue {
+ std::shared_ptr<android::BufferQueueCore> core;
+ std::unique_ptr<android::BufferQueueProducer> producer;
+ std::unique_ptr<android::BufferQueueConsumer> consumer;
+};
+
+static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_context) {
+ auto buffer_queue_core = std::make_shared<android::BufferQueueCore>();
+ return {buffer_queue_core,
+ std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core),
+ std::make_unique<android::BufferQueueConsumer>(buffer_queue_core)};
+}
+
+Display::Display(u64 id, std::string name_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_,
+ KernelHelpers::ServiceContext& service_context_, Core::System& system_)
+ : display_id{id}, name{std::move(name_)}, hos_binder_driver_server{hos_binder_driver_server_},
+ service_context{service_context_} {
vsync_event = service_context.CreateEvent(fmt::format("Display VSync Event {}", id));
}
@@ -44,21 +64,29 @@ void Display::SignalVSyncEvent() {
vsync_event->GetWritableEvent().Signal();
}
-void Display::CreateLayer(u64 layer_id, NVFlinger::BufferQueue& buffer_queue) {
- // TODO(Subv): Support more than 1 layer.
+void Display::CreateLayer(u64 layer_id, u32 binder_id) {
ASSERT_MSG(layers.empty(), "Only one layer is supported per display at the moment");
- layers.emplace_back(std::make_shared<Layer>(layer_id, buffer_queue));
+ auto [core, producer, consumer] = CreateBufferQueue(service_context);
+
+ auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(consumer));
+ buffer_item_consumer->Connect(false);
+
+ layers.emplace_back(std::make_unique<Layer>(layer_id, binder_id, *core, *producer,
+ std::move(buffer_item_consumer)));
+
+ hos_binder_driver_server.RegisterProducer(std::move(producer));
}
void Display::CloseLayer(u64 layer_id) {
- std::erase_if(layers, [layer_id](const auto& layer) { return layer->GetID() == layer_id; });
+ std::erase_if(layers,
+ [layer_id](const auto& layer) { return layer->GetLayerId() == layer_id; });
}
Layer* Display::FindLayer(u64 layer_id) {
const auto itr =
- std::find_if(layers.begin(), layers.end(), [layer_id](const std::shared_ptr<Layer>& layer) {
- return layer->GetID() == layer_id;
+ std::find_if(layers.begin(), layers.end(), [layer_id](const std::unique_ptr<Layer>& layer) {
+ return layer->GetLayerId() == layer_id;
});
if (itr == layers.end()) {
@@ -70,8 +98,8 @@ Layer* Display::FindLayer(u64 layer_id) {
const Layer* Display::FindLayer(u64 layer_id) const {
const auto itr =
- std::find_if(layers.begin(), layers.end(), [layer_id](const std::shared_ptr<Layer>& layer) {
- return layer->GetID() == layer_id;
+ std::find_if(layers.begin(), layers.end(), [layer_id](const std::unique_ptr<Layer>& layer) {
+ return layer->GetLayerId() == layer_id;
});
if (itr == layers.end()) {
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h
index 329f4ba86..9cf324395 100644
--- a/src/core/hle/service/vi/display/vi_display.h
+++ b/src/core/hle/service/vi/display/vi_display.h
@@ -15,12 +15,17 @@ namespace Kernel {
class KEvent;
}
-namespace Service::NVFlinger {
-class BufferQueue;
+namespace android {
+class BufferQueueProducer;
}
+
namespace Service::KernelHelpers {
class ServiceContext;
-} // namespace Service::KernelHelpers
+}
+
+namespace Service::NVFlinger {
+class HosBinderDriverServer;
+}
namespace Service::VI {
@@ -35,12 +40,13 @@ public:
/// Constructs a display with a given unique ID and name.
///
/// @param id The unique ID for this display.
+ /// @param hos_binder_driver_server_ NVFlinger HOSBinderDriver server instance.
/// @param service_context_ The ServiceContext for the owning service.
/// @param name_ The name for this display.
/// @param system_ The global system instance.
///
- Display(u64 id, std::string name_, KernelHelpers::ServiceContext& service_context_,
- Core::System& system_);
+ Display(u64 id, std::string name_, NVFlinger::HosBinderDriverServer& hos_binder_driver_server_,
+ KernelHelpers::ServiceContext& service_context_, Core::System& system_);
~Display();
/// Gets the unique ID assigned to this display.
@@ -64,6 +70,10 @@ public:
/// Gets a layer for this display based off an index.
const Layer& GetLayer(std::size_t index) const;
+ std::size_t GetNumLayers() const {
+ return layers.size();
+ }
+
/// Gets the readable vsync event.
Kernel::KReadableEvent& GetVSyncEvent();
@@ -72,10 +82,10 @@ public:
/// Creates and adds a layer to this display with the given ID.
///
- /// @param layer_id The ID to assign to the created layer.
- /// @param buffer_queue The buffer queue for the layer instance to use.
+ /// @param layer_id The ID to assign to the created layer.
+ /// @param binder_id The ID assigned to the buffer queue.
///
- void CreateLayer(u64 layer_id, NVFlinger::BufferQueue& buffer_queue);
+ void CreateLayer(u64 layer_id, u32 binder_id);
/// Closes and removes a layer from this display with the given ID.
///
@@ -104,9 +114,10 @@ public:
private:
u64 display_id;
std::string name;
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server;
KernelHelpers::ServiceContext& service_context;
- std::vector<std::shared_ptr<Layer>> layers;
+ std::vector<std::unique_ptr<Layer>> layers;
Kernel::KEvent* vsync_event{};
};
diff --git a/src/core/hle/service/vi/layer/vi_layer.cpp b/src/core/hle/service/vi/layer/vi_layer.cpp
index 9bc382587..93858e91f 100644
--- a/src/core/hle/service/vi/layer/vi_layer.cpp
+++ b/src/core/hle/service/vi/layer/vi_layer.cpp
@@ -6,7 +6,11 @@
namespace Service::VI {
-Layer::Layer(u64 id, NVFlinger::BufferQueue& queue) : layer_id{id}, buffer_queue{queue} {}
+Layer::Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_,
+ android::BufferQueueProducer& binder_,
+ std::shared_ptr<android::BufferItemConsumer>&& consumer_)
+ : layer_id{layer_id_}, binder_id{binder_id_}, core{core_}, binder{binder_}, consumer{std::move(
+ consumer_)} {}
Layer::~Layer() = default;
diff --git a/src/core/hle/service/vi/layer/vi_layer.h b/src/core/hle/service/vi/layer/vi_layer.h
index ebdd85505..079ec4dda 100644
--- a/src/core/hle/service/vi/layer/vi_layer.h
+++ b/src/core/hle/service/vi/layer/vi_layer.h
@@ -4,11 +4,15 @@
#pragma once
+#include <memory>
+
#include "common/common_types.h"
-namespace Service::NVFlinger {
-class BufferQueue;
-}
+namespace android {
+class BufferItemConsumer;
+class BufferQueueCore;
+class BufferQueueProducer;
+} // namespace android
namespace Service::VI {
@@ -17,10 +21,13 @@ class Layer {
public:
/// Constructs a layer with a given ID and buffer queue.
///
- /// @param id The ID to assign to this layer.
- /// @param queue The buffer queue for this layer to use.
+ /// @param layer_id_ The ID to assign to this layer.
+ /// @param binder_id_ The binder ID to assign to this layer.
+ /// @param binder_ The buffer producer queue for this layer to use.
///
- Layer(u64 id, NVFlinger::BufferQueue& queue);
+ Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_,
+ android::BufferQueueProducer& binder_,
+ std::shared_ptr<android::BufferItemConsumer>&& consumer_);
~Layer();
Layer(const Layer&) = delete;
@@ -30,23 +37,47 @@ public:
Layer& operator=(Layer&&) = delete;
/// Gets the ID for this layer.
- u64 GetID() const {
+ u64 GetLayerId() const {
return layer_id;
}
+ /// Gets the binder ID for this layer.
+ u32 GetBinderId() const {
+ return binder_id;
+ }
+
/// Gets a reference to the buffer queue this layer is using.
- NVFlinger::BufferQueue& GetBufferQueue() {
- return buffer_queue;
+ android::BufferQueueProducer& GetBufferQueue() {
+ return binder;
}
/// Gets a const reference to the buffer queue this layer is using.
- const NVFlinger::BufferQueue& GetBufferQueue() const {
- return buffer_queue;
+ const android::BufferQueueProducer& GetBufferQueue() const {
+ return binder;
+ }
+
+ android::BufferItemConsumer& GetConsumer() {
+ return *consumer;
+ }
+
+ const android::BufferItemConsumer& GetConsumer() const {
+ return *consumer;
+ }
+
+ android::BufferQueueCore& Core() {
+ return core;
+ }
+
+ const android::BufferQueueCore& Core() const {
+ return core;
}
private:
- u64 layer_id;
- NVFlinger::BufferQueue& buffer_queue;
+ const u64 layer_id;
+ const u32 binder_id;
+ android::BufferQueueCore& core;
+ android::BufferQueueProducer& binder;
+ std::shared_ptr<android::BufferItemConsumer> consumer;
};
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 75ee3e5e4..e49e1ae28 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -22,8 +22,11 @@
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/service/nvdrv/nvdata.h"
-#include "core/hle/service/nvflinger/buffer_queue.h"
+#include "core/hle/service/nvflinger/binder.h"
+#include "core/hle/service/nvflinger/buffer_queue_producer.h"
+#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
#include "core/hle/service/nvflinger/nvflinger.h"
+#include "core/hle/service/nvflinger/parcel.h"
#include "core/hle/service/service.h"
#include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_m.h"
@@ -57,447 +60,24 @@ struct DisplayInfo {
};
static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size");
-class Parcel {
+class NativeWindow final {
public:
- // This default size was chosen arbitrarily.
- static constexpr std::size_t DefaultBufferSize = 0x40;
- Parcel() : buffer(DefaultBufferSize) {}
- explicit Parcel(std::vector<u8> data) : buffer(std::move(data)) {}
- virtual ~Parcel() = default;
-
- template <typename T>
- T Read() {
- static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
- ASSERT(read_index + sizeof(T) <= buffer.size());
-
- T val;
- std::memcpy(&val, buffer.data() + read_index, sizeof(T));
- read_index += sizeof(T);
- read_index = Common::AlignUp(read_index, 4);
- return val;
- }
-
- template <typename T>
- T ReadUnaligned() {
- static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
- ASSERT(read_index + sizeof(T) <= buffer.size());
-
- T val;
- std::memcpy(&val, buffer.data() + read_index, sizeof(T));
- read_index += sizeof(T);
- return val;
- }
-
- std::vector<u8> ReadBlock(std::size_t length) {
- ASSERT(read_index + length <= buffer.size());
- const u8* const begin = buffer.data() + read_index;
- const u8* const end = begin + length;
- std::vector<u8> data(begin, end);
- read_index += length;
- read_index = Common::AlignUp(read_index, 4);
- return data;
- }
-
- std::u16string ReadInterfaceToken() {
- [[maybe_unused]] const u32 unknown = Read<u32_le>();
- const u32 length = Read<u32_le>();
-
- std::u16string token{};
-
- for (u32 ch = 0; ch < length + 1; ++ch) {
- token.push_back(ReadUnaligned<u16_le>());
- }
-
- read_index = Common::AlignUp(read_index, 4);
-
- return token;
- }
-
- template <typename T>
- void Write(const T& val) {
- static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
-
- if (buffer.size() < write_index + sizeof(T)) {
- buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize);
- }
-
- std::memcpy(buffer.data() + write_index, &val, sizeof(T));
- write_index += sizeof(T);
- write_index = Common::AlignUp(write_index, 4);
- }
-
- template <typename T>
- void WriteObject(const T& val) {
- static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
-
- const u32_le size = static_cast<u32>(sizeof(val));
- Write(size);
- // TODO(Subv): Support file descriptors.
- Write<u32_le>(0); // Fd count.
- Write(val);
- }
-
- void Deserialize() {
- ASSERT(buffer.size() > sizeof(Header));
-
- Header header{};
- std::memcpy(&header, buffer.data(), sizeof(Header));
-
- read_index = header.data_offset;
- DeserializeData();
- }
-
- std::vector<u8> Serialize() {
- ASSERT(read_index == 0);
- write_index = sizeof(Header);
-
- SerializeData();
-
- Header header{};
- header.data_size = static_cast<u32_le>(write_index - sizeof(Header));
- header.data_offset = sizeof(Header);
- header.objects_size = 4;
- header.objects_offset = static_cast<u32>(sizeof(Header) + header.data_size);
- std::memcpy(buffer.data(), &header, sizeof(Header));
-
- return buffer;
- }
-
-protected:
- virtual void SerializeData() {}
-
- virtual void DeserializeData() {}
-
-private:
- struct Header {
- u32_le data_size;
- u32_le data_offset;
- u32_le objects_size;
- u32_le objects_offset;
- };
- static_assert(sizeof(Header) == 16, "ParcelHeader has wrong size");
-
- std::vector<u8> buffer;
- std::size_t read_index = 0;
- std::size_t write_index = 0;
-};
-
-class NativeWindow : public Parcel {
-public:
- explicit NativeWindow(u32 id) {
- data.id = id;
- }
- ~NativeWindow() override = default;
-
-protected:
- void SerializeData() override {
- Write(data);
- }
-
-private:
- struct Data {
- u32_le magic = 2;
- u32_le process_id = 1;
- u32_le id;
- INSERT_PADDING_WORDS(3);
- std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'};
- INSERT_PADDING_WORDS(2);
- };
- static_assert(sizeof(Data) == 0x28, "ParcelData has wrong size");
-
- Data data{};
-};
-
-class IGBPConnectRequestParcel : public Parcel {
-public:
- explicit IGBPConnectRequestParcel(std::vector<u8> buffer_) : Parcel(std::move(buffer_)) {
- Deserialize();
- }
-
- void DeserializeData() override {
- [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
- data = Read<Data>();
- }
-
- struct Data {
- u32_le unk;
- u32_le api;
- u32_le producer_controlled_by_app;
- };
-
- Data data;
-};
-
-class IGBPConnectResponseParcel : public Parcel {
-public:
- explicit IGBPConnectResponseParcel(u32 width, u32 height) {
- data.width = width;
- data.height = height;
- }
- ~IGBPConnectResponseParcel() override = default;
-
-protected:
- void SerializeData() override {
- Write(data);
- }
-
-private:
- struct Data {
- u32_le width;
- u32_le height;
- u32_le transform_hint;
- u32_le num_pending_buffers;
- u32_le status;
- };
- static_assert(sizeof(Data) == 20, "ParcelData has wrong size");
-
- Data data{};
-};
-
-/// Represents a parcel containing one int '0' as its data
-/// Used by DetachBuffer and Disconnect
-class IGBPEmptyResponseParcel : public Parcel {
-protected:
- void SerializeData() override {
- Write(data);
- }
-
-private:
- struct Data {
- u32_le unk_0{};
- };
-
- Data data{};
-};
-
-class IGBPSetPreallocatedBufferRequestParcel : public Parcel {
-public:
- explicit IGBPSetPreallocatedBufferRequestParcel(std::vector<u8> buffer_)
- : Parcel(std::move(buffer_)) {
- Deserialize();
- }
-
- void DeserializeData() override {
- [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
- data = Read<Data>();
- if (data.contains_object != 0) {
- buffer_container = Read<BufferContainer>();
- }
- }
-
- struct Data {
- u32_le slot;
- u32_le contains_object;
- };
-
- struct BufferContainer {
- u32_le graphic_buffer_length;
- INSERT_PADDING_WORDS(1);
- NVFlinger::IGBPBuffer buffer{};
- };
-
- Data data{};
- BufferContainer buffer_container{};
-};
-
-class IGBPSetPreallocatedBufferResponseParcel : public Parcel {
-protected:
- void SerializeData() override {
- // TODO(Subv): Find out what this means
- Write<u32>(0);
- }
-};
-
-class IGBPCancelBufferRequestParcel : public Parcel {
-public:
- explicit IGBPCancelBufferRequestParcel(std::vector<u8> buffer_) : Parcel(std::move(buffer_)) {
- Deserialize();
- }
-
- void DeserializeData() override {
- [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
- data = Read<Data>();
- }
-
- struct Data {
- u32_le slot;
- Service::Nvidia::MultiFence multi_fence;
- };
-
- Data data;
-};
-
-class IGBPCancelBufferResponseParcel : public Parcel {
-protected:
- void SerializeData() override {
- Write<u32>(0); // Success
- }
-};
-
-class IGBPDequeueBufferRequestParcel : public Parcel {
-public:
- explicit IGBPDequeueBufferRequestParcel(std::vector<u8> buffer_) : Parcel(std::move(buffer_)) {
- Deserialize();
- }
-
- void DeserializeData() override {
- [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
- data = Read<Data>();
- }
-
- struct Data {
- u32_le pixel_format;
- u32_le width;
- u32_le height;
- u32_le get_frame_timestamps;
- u32_le usage;
- };
-
- Data data;
-};
-
-class IGBPDequeueBufferResponseParcel : public Parcel {
-public:
- explicit IGBPDequeueBufferResponseParcel(u32 slot_, Nvidia::MultiFence& multi_fence_)
- : slot(slot_), multi_fence(multi_fence_) {}
-
-protected:
- void SerializeData() override {
- Write(slot);
- Write<u32_le>(1);
- WriteObject(multi_fence);
- Write<u32_le>(0);
- }
-
- u32_le slot;
- Service::Nvidia::MultiFence multi_fence;
-};
-
-class IGBPRequestBufferRequestParcel : public Parcel {
-public:
- explicit IGBPRequestBufferRequestParcel(std::vector<u8> buffer_) : Parcel(std::move(buffer_)) {
- Deserialize();
- }
-
- void DeserializeData() override {
- [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
- slot = Read<u32_le>();
- }
-
- u32_le slot;
-};
-
-class IGBPRequestBufferResponseParcel : public Parcel {
-public:
- explicit IGBPRequestBufferResponseParcel(NVFlinger::IGBPBuffer buffer_) : buffer(buffer_) {}
- ~IGBPRequestBufferResponseParcel() override = default;
-
-protected:
- void SerializeData() override {
- // TODO(Subv): Figure out what this value means, writing non-zero here will make libnx
- // try to read an IGBPBuffer object from the parcel.
- Write<u32_le>(1);
- WriteObject(buffer);
- Write<u32_le>(0);
- }
-
- NVFlinger::IGBPBuffer buffer;
-};
-
-class IGBPQueueBufferRequestParcel : public Parcel {
-public:
- explicit IGBPQueueBufferRequestParcel(std::vector<u8> buffer_) : Parcel(std::move(buffer_)) {
- Deserialize();
- }
-
- void DeserializeData() override {
- [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
- data = Read<Data>();
- }
-
- struct Data {
- u32_le slot;
- INSERT_PADDING_WORDS(3);
- u32_le timestamp;
- s32_le is_auto_timestamp;
- s32_le crop_top;
- s32_le crop_left;
- s32_le crop_right;
- s32_le crop_bottom;
- s32_le scaling_mode;
- NVFlinger::BufferQueue::BufferTransformFlags transform;
- u32_le sticky_transform;
- INSERT_PADDING_WORDS(1);
- u32_le swap_interval;
- Service::Nvidia::MultiFence multi_fence;
-
- Common::Rectangle<int> GetCropRect() const {
- return {crop_left, crop_top, crop_right, crop_bottom};
- }
- };
- static_assert(sizeof(Data) == 96, "ParcelData has wrong size");
-
- Data data;
-};
-
-class IGBPQueueBufferResponseParcel : public Parcel {
-public:
- explicit IGBPQueueBufferResponseParcel(u32 width, u32 height) {
- data.width = width;
- data.height = height;
- }
- ~IGBPQueueBufferResponseParcel() override = default;
-
-protected:
- void SerializeData() override {
- Write(data);
- }
-
-private:
- struct Data {
- u32_le width;
- u32_le height;
- u32_le transform_hint;
- u32_le num_pending_buffers;
- u32_le status;
- };
- static_assert(sizeof(Data) == 20, "ParcelData has wrong size");
-
- Data data{};
-};
-
-class IGBPQueryRequestParcel : public Parcel {
-public:
- explicit IGBPQueryRequestParcel(std::vector<u8> buffer_) : Parcel(std::move(buffer_)) {
- Deserialize();
- }
-
- void DeserializeData() override {
- [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
- type = Read<u32_le>();
- }
-
- u32 type;
-};
-
-class IGBPQueryResponseParcel : public Parcel {
-public:
- explicit IGBPQueryResponseParcel(u32 value_) : value{value_} {}
- ~IGBPQueryResponseParcel() override = default;
-
-protected:
- void SerializeData() override {
- Write(value);
- }
+ constexpr explicit NativeWindow(u32 id_) : id{id_} {}
private:
- u32_le value;
+ const u32 magic = 2;
+ const u32 process_id = 1;
+ const u32 id;
+ const INSERT_PADDING_WORDS(3);
+ const std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'};
+ const INSERT_PADDING_WORDS(2);
};
+static_assert(sizeof(NativeWindow) == 0x28, "ParcelData has wrong size");
class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> {
public:
- explicit IHOSBinderDriver(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
- : ServiceFramework{system_, "IHOSBinderDriver"}, nv_flinger(nv_flinger_) {
+ explicit IHOSBinderDriver(Core::System& system_, NVFlinger::HosBinderDriverServer& server_)
+ : ServiceFramework{system_, "IHOSBinderDriver"}, server(server_) {
static const FunctionInfo functions[] = {
{0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},
{1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"},
@@ -508,147 +88,16 @@ public:
}
private:
- enum class TransactionId {
- RequestBuffer = 1,
- SetBufferCount = 2,
- DequeueBuffer = 3,
- DetachBuffer = 4,
- DetachNextBuffer = 5,
- AttachBuffer = 6,
- QueueBuffer = 7,
- CancelBuffer = 8,
- Query = 9,
- Connect = 10,
- Disconnect = 11,
-
- AllocateBuffers = 13,
- SetPreallocatedBuffer = 14,
-
- GetBufferHistory = 17
- };
-
void TransactParcel(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u32 id = rp.Pop<u32>();
- const auto transaction = static_cast<TransactionId>(rp.Pop<u32>());
+ const auto transaction = static_cast<android::TransactionId>(rp.Pop<u32>());
const u32 flags = rp.Pop<u32>();
LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
transaction, flags);
- auto& buffer_queue = *nv_flinger.FindBufferQueue(id);
-
- switch (transaction) {
- case TransactionId::Connect: {
- IGBPConnectRequestParcel request{ctx.ReadBuffer()};
- IGBPConnectResponseParcel response{static_cast<u32>(DisplayResolution::UndockedWidth),
- static_cast<u32>(DisplayResolution::UndockedHeight)};
-
- buffer_queue.Connect();
-
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::SetPreallocatedBuffer: {
- IGBPSetPreallocatedBufferRequestParcel request{ctx.ReadBuffer()};
-
- buffer_queue.SetPreallocatedBuffer(request.data.slot, request.buffer_container.buffer);
-
- IGBPSetPreallocatedBufferResponseParcel response{};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::DequeueBuffer: {
- IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()};
- const u32 width{request.data.width};
- const u32 height{request.data.height};
-
- do {
- if (auto result = buffer_queue.DequeueBuffer(width, height); result) {
- // Buffer is available
- IGBPDequeueBufferResponseParcel response{result->first, *result->second};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- } while (buffer_queue.IsConnected());
-
- break;
- }
- case TransactionId::RequestBuffer: {
- IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()};
-
- auto& buffer = buffer_queue.RequestBuffer(request.slot);
- IGBPRequestBufferResponseParcel response{buffer};
- ctx.WriteBuffer(response.Serialize());
-
- break;
- }
- case TransactionId::QueueBuffer: {
- IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()};
-
- buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
- request.data.GetCropRect(), request.data.swap_interval,
- request.data.multi_fence);
-
- IGBPQueueBufferResponseParcel response{1280, 720};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::Query: {
- IGBPQueryRequestParcel request{ctx.ReadBuffer()};
-
- const u32 value =
- buffer_queue.Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type));
-
- IGBPQueryResponseParcel response{value};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::CancelBuffer: {
- IGBPCancelBufferRequestParcel request{ctx.ReadBuffer()};
-
- buffer_queue.CancelBuffer(request.data.slot, request.data.multi_fence);
-
- IGBPCancelBufferResponseParcel response{};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::Disconnect: {
- LOG_WARNING(Service_VI, "(STUBBED) called, transaction=Disconnect");
- const auto buffer = ctx.ReadBuffer();
-
- buffer_queue.Disconnect();
-
- IGBPEmptyResponseParcel response{};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::DetachBuffer: {
- const auto buffer = ctx.ReadBuffer();
-
- IGBPEmptyResponseParcel response{};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::SetBufferCount: {
- LOG_WARNING(Service_VI, "(STUBBED) called, transaction=SetBufferCount");
- [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
-
- IGBPEmptyResponseParcel response{};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- case TransactionId::GetBufferHistory: {
- LOG_WARNING(Service_VI, "(STUBBED) called, transaction=GetBufferHistory");
- [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
-
- IGBPEmptyResponseParcel response{};
- ctx.WriteBuffer(response.Serialize());
- break;
- }
- default:
- ASSERT_MSG(false, "Unimplemented");
- }
+ server.TryGetProducer(id)->Transact(ctx, transaction, flags);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -674,13 +123,13 @@ private:
LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown);
- // TODO(Subv): Find out what this actually is.
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
- rb.PushCopyObjects(nv_flinger.FindBufferQueue(id)->GetBufferWaitEvent());
+ rb.PushCopyObjects(server.TryGetProducer(id)->GetNativeHandle());
}
- NVFlinger::NVFlinger& nv_flinger;
+private:
+ NVFlinger::HosBinderDriverServer& server;
};
class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> {
@@ -937,7 +386,40 @@ private:
class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {
public:
- explicit IApplicationDisplayService(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
+ IApplicationDisplayService(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_)
+ : ServiceFramework{system_, "IApplicationDisplayService"}, nv_flinger{nv_flinger_},
+ hos_binder_driver_server{hos_binder_driver_server_} {
+
+ static const FunctionInfo functions[] = {
+ {100, &IApplicationDisplayService::GetRelayService, "GetRelayService"},
+ {101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"},
+ {102, &IApplicationDisplayService::GetManagerDisplayService,
+ "GetManagerDisplayService"},
+ {103, &IApplicationDisplayService::GetIndirectDisplayTransactionService,
+ "GetIndirectDisplayTransactionService"},
+ {1000, &IApplicationDisplayService::ListDisplays, "ListDisplays"},
+ {1010, &IApplicationDisplayService::OpenDisplay, "OpenDisplay"},
+ {1011, &IApplicationDisplayService::OpenDefaultDisplay, "OpenDefaultDisplay"},
+ {1020, &IApplicationDisplayService::CloseDisplay, "CloseDisplay"},
+ {1101, &IApplicationDisplayService::SetDisplayEnabled, "SetDisplayEnabled"},
+ {1102, &IApplicationDisplayService::GetDisplayResolution, "GetDisplayResolution"},
+ {2020, &IApplicationDisplayService::OpenLayer, "OpenLayer"},
+ {2021, &IApplicationDisplayService::CloseLayer, "CloseLayer"},
+ {2030, &IApplicationDisplayService::CreateStrayLayer, "CreateStrayLayer"},
+ {2031, &IApplicationDisplayService::DestroyStrayLayer, "DestroyStrayLayer"},
+ {2101, &IApplicationDisplayService::SetLayerScalingMode, "SetLayerScalingMode"},
+ {2102, &IApplicationDisplayService::ConvertScalingMode, "ConvertScalingMode"},
+ {2450, &IApplicationDisplayService::GetIndirectLayerImageMap,
+ "GetIndirectLayerImageMap"},
+ {2451, nullptr, "GetIndirectLayerImageCropMap"},
+ {2460, &IApplicationDisplayService::GetIndirectLayerImageRequiredMemoryInfo,
+ "GetIndirectLayerImageRequiredMemoryInfo"},
+ {5202, &IApplicationDisplayService::GetDisplayVsyncEvent, "GetDisplayVsyncEvent"},
+ {5203, nullptr, "GetDisplayVsyncEventForDebug"},
+ };
+ RegisterHandlers(functions);
+ }
private:
enum class ConvertedScaleMode : u64 {
@@ -961,7 +443,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IHOSBinderDriver>(system, nv_flinger);
+ rb.PushIpcInterface<IHOSBinderDriver>(system, hos_binder_driver_server);
}
void GetSystemDisplayService(Kernel::HLERequestContext& ctx) {
@@ -985,7 +467,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IHOSBinderDriver>(system, nv_flinger);
+ rb.PushIpcInterface<IHOSBinderDriver>(system, hos_binder_driver_server);
}
void OpenDisplay(Kernel::HLERequestContext& ctx) {
@@ -1089,7 +571,7 @@ private:
void ListDisplays(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_VI, "(STUBBED) called");
- DisplayInfo display_info;
+ const DisplayInfo display_info;
ctx.WriteBuffer(&display_info, sizeof(DisplayInfo));
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
@@ -1124,8 +606,8 @@ private:
return;
}
- NativeWindow native_window{*buffer_queue_id};
- const auto buffer_size = ctx.WriteBuffer(native_window.Serialize());
+ const auto parcel = android::Parcel{NativeWindow{*buffer_queue_id}};
+ const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
@@ -1170,8 +652,8 @@ private:
return;
}
- NativeWindow native_window{*buffer_queue_id};
- const auto buffer_size = ctx.WriteBuffer(native_window.Serialize());
+ const auto parcel = android::Parcel{NativeWindow{*buffer_queue_id}};
+ const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
@@ -1287,39 +769,9 @@ private:
}
NVFlinger::NVFlinger& nv_flinger;
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server;
};
-IApplicationDisplayService::IApplicationDisplayService(Core::System& system_,
- NVFlinger::NVFlinger& nv_flinger_)
- : ServiceFramework{system_, "IApplicationDisplayService"}, nv_flinger{nv_flinger_} {
- static const FunctionInfo functions[] = {
- {100, &IApplicationDisplayService::GetRelayService, "GetRelayService"},
- {101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"},
- {102, &IApplicationDisplayService::GetManagerDisplayService, "GetManagerDisplayService"},
- {103, &IApplicationDisplayService::GetIndirectDisplayTransactionService,
- "GetIndirectDisplayTransactionService"},
- {1000, &IApplicationDisplayService::ListDisplays, "ListDisplays"},
- {1010, &IApplicationDisplayService::OpenDisplay, "OpenDisplay"},
- {1011, &IApplicationDisplayService::OpenDefaultDisplay, "OpenDefaultDisplay"},
- {1020, &IApplicationDisplayService::CloseDisplay, "CloseDisplay"},
- {1101, &IApplicationDisplayService::SetDisplayEnabled, "SetDisplayEnabled"},
- {1102, &IApplicationDisplayService::GetDisplayResolution, "GetDisplayResolution"},
- {2020, &IApplicationDisplayService::OpenLayer, "OpenLayer"},
- {2021, &IApplicationDisplayService::CloseLayer, "CloseLayer"},
- {2030, &IApplicationDisplayService::CreateStrayLayer, "CreateStrayLayer"},
- {2031, &IApplicationDisplayService::DestroyStrayLayer, "DestroyStrayLayer"},
- {2101, &IApplicationDisplayService::SetLayerScalingMode, "SetLayerScalingMode"},
- {2102, &IApplicationDisplayService::ConvertScalingMode, "ConvertScalingMode"},
- {2450, &IApplicationDisplayService::GetIndirectLayerImageMap, "GetIndirectLayerImageMap"},
- {2451, nullptr, "GetIndirectLayerImageCropMap"},
- {2460, &IApplicationDisplayService::GetIndirectLayerImageRequiredMemoryInfo,
- "GetIndirectLayerImageRequiredMemoryInfo"},
- {5202, &IApplicationDisplayService::GetDisplayVsyncEvent, "GetDisplayVsyncEvent"},
- {5203, nullptr, "GetDisplayVsyncEventForDebug"},
- };
- RegisterHandlers(functions);
-}
-
static bool IsValidServiceAccess(Permission permission, Policy policy) {
if (permission == Permission::User) {
return policy == Policy::User;
@@ -1333,7 +785,9 @@ static bool IsValidServiceAccess(Permission permission, Policy policy) {
}
void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system,
- NVFlinger::NVFlinger& nv_flinger, Permission permission) {
+ NVFlinger::NVFlinger& nv_flinger,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server,
+ Permission permission) {
IPC::RequestParser rp{ctx};
const auto policy = rp.PopEnum<Policy>();
@@ -1346,14 +800,18 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System&
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger);
+ rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger, hos_binder_driver_server);
}
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system,
- NVFlinger::NVFlinger& nv_flinger) {
- std::make_shared<VI_M>(system, nv_flinger)->InstallAsService(service_manager);
- std::make_shared<VI_S>(system, nv_flinger)->InstallAsService(service_manager);
- std::make_shared<VI_U>(system, nv_flinger)->InstallAsService(service_manager);
+ NVFlinger::NVFlinger& nv_flinger,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server) {
+ std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server)
+ ->InstallAsService(service_manager);
+ std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server)
+ ->InstallAsService(service_manager);
+ std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server)
+ ->InstallAsService(service_manager);
}
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index 2fd7f8e61..d68f2646b 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -15,8 +15,9 @@ class HLERequestContext;
}
namespace Service::NVFlinger {
+class HosBinderDriverServer;
class NVFlinger;
-}
+} // namespace Service::NVFlinger
namespace Service::SM {
class ServiceManager;
@@ -47,11 +48,14 @@ enum class Policy {
namespace detail {
void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system,
- NVFlinger::NVFlinger& nv_flinger, Permission permission);
+ NVFlinger::NVFlinger& nv_flinger,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server,
+ Permission permission);
} // namespace detail
/// Registers all VI services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system,
- NVFlinger::NVFlinger& nv_flinger);
+ NVFlinger::NVFlinger& nv_flinger,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server);
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_m.cpp b/src/core/hle/service/vi/vi_m.cpp
index 87db1c416..be0255f3d 100644
--- a/src/core/hle/service/vi/vi_m.cpp
+++ b/src/core/hle/service/vi/vi_m.cpp
@@ -8,8 +8,10 @@
namespace Service::VI {
-VI_M::VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
- : ServiceFramework{system_, "vi:m"}, nv_flinger{nv_flinger_} {
+VI_M::VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_)
+ : ServiceFramework{system_, "vi:m"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{
+ hos_binder_driver_server_} {
static const FunctionInfo functions[] = {
{2, &VI_M::GetDisplayService, "GetDisplayService"},
{3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -22,7 +24,8 @@ VI_M::~VI_M() = default;
void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_VI, "called");
- detail::GetDisplayServiceImpl(ctx, system, nv_flinger, Permission::Manager);
+ detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server,
+ Permission::Manager);
}
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_m.h b/src/core/hle/service/vi/vi_m.h
index d79c41beb..efbd34e09 100644
--- a/src/core/hle/service/vi/vi_m.h
+++ b/src/core/hle/service/vi/vi_m.h
@@ -15,20 +15,23 @@ class HLERequestContext;
}
namespace Service::NVFlinger {
+class HosBinderDriverServer;
class NVFlinger;
-}
+} // namespace Service::NVFlinger
namespace Service::VI {
class VI_M final : public ServiceFramework<VI_M> {
public:
- explicit VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
+ explicit VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_);
~VI_M() override;
private:
void GetDisplayService(Kernel::HLERequestContext& ctx);
NVFlinger::NVFlinger& nv_flinger;
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server;
};
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_s.cpp b/src/core/hle/service/vi/vi_s.cpp
index 5cd22f7df..7996a6811 100644
--- a/src/core/hle/service/vi/vi_s.cpp
+++ b/src/core/hle/service/vi/vi_s.cpp
@@ -8,8 +8,10 @@
namespace Service::VI {
-VI_S::VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
- : ServiceFramework{system_, "vi:s"}, nv_flinger{nv_flinger_} {
+VI_S::VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_)
+ : ServiceFramework{system_, "vi:s"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{
+ hos_binder_driver_server_} {
static const FunctionInfo functions[] = {
{1, &VI_S::GetDisplayService, "GetDisplayService"},
{3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -22,7 +24,8 @@ VI_S::~VI_S() = default;
void VI_S::GetDisplayService(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_VI, "called");
- detail::GetDisplayServiceImpl(ctx, system, nv_flinger, Permission::System);
+ detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server,
+ Permission::System);
}
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_s.h b/src/core/hle/service/vi/vi_s.h
index 5f1f8f290..3812c5061 100644
--- a/src/core/hle/service/vi/vi_s.h
+++ b/src/core/hle/service/vi/vi_s.h
@@ -15,20 +15,23 @@ class HLERequestContext;
}
namespace Service::NVFlinger {
+class HosBinderDriverServer;
class NVFlinger;
-}
+} // namespace Service::NVFlinger
namespace Service::VI {
class VI_S final : public ServiceFramework<VI_S> {
public:
- explicit VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
+ explicit VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_);
~VI_S() override;
private:
void GetDisplayService(Kernel::HLERequestContext& ctx);
NVFlinger::NVFlinger& nv_flinger;
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server;
};
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_u.cpp b/src/core/hle/service/vi/vi_u.cpp
index 0079d51f0..57c888313 100644
--- a/src/core/hle/service/vi/vi_u.cpp
+++ b/src/core/hle/service/vi/vi_u.cpp
@@ -8,8 +8,10 @@
namespace Service::VI {
-VI_U::VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_)
- : ServiceFramework{system_, "vi:u"}, nv_flinger{nv_flinger_} {
+VI_U::VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_)
+ : ServiceFramework{system_, "vi:u"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{
+ hos_binder_driver_server_} {
static const FunctionInfo functions[] = {
{0, &VI_U::GetDisplayService, "GetDisplayService"},
{1, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -22,7 +24,8 @@ VI_U::~VI_U() = default;
void VI_U::GetDisplayService(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_VI, "called");
- detail::GetDisplayServiceImpl(ctx, system, nv_flinger, Permission::User);
+ detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server,
+ Permission::User);
}
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_u.h b/src/core/hle/service/vi/vi_u.h
index 8e3885c73..b08e56576 100644
--- a/src/core/hle/service/vi/vi_u.h
+++ b/src/core/hle/service/vi/vi_u.h
@@ -15,20 +15,23 @@ class HLERequestContext;
}
namespace Service::NVFlinger {
+class HosBinderDriverServer;
class NVFlinger;
-}
+} // namespace Service::NVFlinger
namespace Service::VI {
class VI_U final : public ServiceFramework<VI_U> {
public:
- explicit VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_);
+ explicit VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server_);
~VI_U() override;
private:
void GetDisplayService(Kernel::HLERequestContext& ctx);
NVFlinger::NVFlinger& nv_flinger;
+ NVFlinger::HosBinderDriverServer& hos_binder_driver_server;
};
} // namespace Service::VI
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 26b8ea233..97c029140 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -8,6 +8,7 @@
#include "common/bit_field.h"
#include "common/common_types.h"
+#include "core/hle/service/nvdrv/nvdata.h"
#include "video_core/cdma_pusher.h"
#include "video_core/framebuffer_config.h"