diff options
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 81 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.h | 27 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/vi/display/vi_display.cpp | 50 | ||||
| -rw-r--r-- | src/core/hle/service/vi/display/vi_display.h | 29 | ||||
| -rw-r--r-- | src/core/hle/service/vi/layer/vi_layer.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/vi/layer/vi_layer.h | 57 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 690 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.h | 10 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi_m.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi_m.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi_s.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi_s.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi_u.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi_u.h | 7 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 1 | 
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"  | 
