skyline/app/src/main/cpp/skyline/services/hosbinder/IHOSBinderDriver.h

106 lines
4.5 KiB
C++

// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <services/base_service.h>
#include "GraphicBufferProducer.h"
namespace skyline::service::hosbinder {
/**
* @brief A display identifier specific to HOS, translated to a corresponding Android display internally
* @url https://switchbrew.org/wiki/Display_services#DisplayName
*/
enum class DisplayId : u64 {
Default, //!< Automatically determines the default display
External, //!< Refers to an external display, if any
Edid, //!< Refers to an external display with EDID capabilities
Internal, //!< Refers to the internal display on the Switch
Null, //!< A placeholder display which doesn't refer to any display
};
ENUM_STRING(DisplayId, {
ENUM_CASE(Default);
ENUM_CASE(External);
ENUM_CASE(Edid);
ENUM_CASE(Internal);
ENUM_CASE(Null);
})
/**
* @brief nvnflinger:dispdrv or nns::hosbinder::IHOSBinderDriver is a translation layer between Android Binder IPC and HOS IPC to communicate with the Android display stack
*/
class IHOSBinderDriver : public BaseService {
private:
DisplayId displayId{DisplayId::Null}; //!< The ID of the display that the layer is connected to
constexpr static i32 InitialStrongReferenceCount{std::numeric_limits<i32>::min()}; //!< Initial value for the strong reference count, weak references will keep the object alive till the strong reference count is first mutated
i32 layerStrongReferenceCount; //!< The amount of strong references to the layer object
i32 layerWeakReferenceCount; //!< The amount of weak references to the layer object, these only matter when there are no strong references
constexpr static u64 DefaultLayerId{1}; //!< The VI ID of the default (and only) layer in our surface stack
constexpr static u32 DefaultBinderLayerHandle{1}; //!< The handle as assigned by SurfaceFlinger of the default layer
std::optional<GraphicBufferProducer> layer; //!< The IGraphicBufferProducer backing the layer (NativeWindow)
public:
IHOSBinderDriver(const DeviceState &state, ServiceManager &manager);
/**
* @brief Emulates the transaction of parcels between a IGraphicBufferProducer and the application
* @url https://switchbrew.org/wiki/Nvnflinger_services#TransactParcel
*/
Result TransactParcel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Adjusts the reference counts to the underlying Android reference counted object
* @url https://switchbrew.org/wiki/Nvnflinger_services#AdjustRefcount
*/
Result AdjustRefcount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Adjusts the reference counts to the underlying binder, it's stubbed as we aren't using the real symbols
* @url https://switchbrew.org/wiki/Nvnflinger_services#GetNativeHandle
*/
Result GetNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @note This will throw an exception if another display was opened and not closed
*/
DisplayId OpenDisplay(std::string_view name);
/**
* @note This **must** be called prior to opening a different Display
*/
void CloseDisplay(DisplayId id);
/**
* @return An ID that can be utilized to refer to the layer
* @note This will throw an exception if the specified display has not been opened
*/
u64 CreateLayer(DisplayId displayId);
/**
* @return A parcel with a flattened IBinder to the IGraphicBufferProducer of the layer
* @note This will throw an exception if the specified display has not been opened
*/
Parcel OpenLayer(DisplayId displayId, u64 layerId);
/**
* @note This **must** be called prior to destroying the layer
*/
void CloseLayer(u64 layerId);
/**
* @note This **must** be called prior to opening a different Display
*/
void DestroyLayer(u64 layerId);
SERVICE_DECL(
SFUNC(0x0, IHOSBinderDriver, TransactParcel),
SFUNC(0x1, IHOSBinderDriver, AdjustRefcount),
SFUNC(0x2, IHOSBinderDriver, GetNativeHandle),
SFUNC(0x3, IHOSBinderDriver, TransactParcel)
)
};
}