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

208 lines
12 KiB
C
Raw Normal View History

// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
// Copyright © 2005 The Android Open Source Project
// Copyright © 2019-2020 Ryujinx Team and Contributors
#pragma once
#include <kernel/types/KEvent.h>
#include <services/common/parcel.h>
#include "android_types.h"
#include "native_window.h"
namespace skyline::gpu {
class Texture;
}
#define ENUM_CASE(key) \
case ENUM_TYPE::key: \
return #key
#define ENUM_STRING(name, cases) \
constexpr const char *ToString(name value) { \
using ENUM_TYPE = name; \
switch (value) { \
cases \
default: \
return "Unknown"; \
}; \
};
namespace skyline::service::hosbinder {
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferSlot.h;l=52-91
*/
enum class BufferState {
Free,
Dequeued,
Queued,
Acquired,
};
ENUM_STRING(BufferState, ENUM_CASE(Free);ENUM_CASE(Dequeued);ENUM_CASE(Queued);ENUM_CASE(Acquired);
);
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferSlot.h;l=32-138
*/
struct BufferSlot {
BufferState state{BufferState::Free};
u64 frameNumber{}; //!< The amount of frames that have been queued using this slot
bool wasBufferRequested{}; //!< If GraphicBufferProducer::RequestBuffer has been called with this buffer
std::shared_ptr<gpu::Texture> texture{};
std::unique_ptr<GraphicBuffer> graphicBuffer{};
};
/**
2020-09-28 12:05:17 +02:00
* @brief An enumeration of all the possible display IDs
* @url https://switchbrew.org/wiki/Display_services#DisplayName
2020-09-20 21:46:26 +02:00
*/
enum class DisplayId : u64 {
Default, //!< Refers to the default display used by most applications
External, //!< Refers to an external display
Edid, //!< Refers to an external display with EDID capabilities
Internal, //!< Refers to the the internal display
Null, //!< Refers to the null display which is used for discarding data
};
enum class LayerStatus {
Uninitialized, //!< The layer hasn't been initialized
Stray, //!< The layer has been initialized as a stray layer
Managed, //!< The layer has been initialized as a managed layer
};
/**
* @brief An endpoint for the GraphicBufferProducer interface, it approximately implements BufferQueueProducer but also implements the functionality of interfaces called into by it such as GraphicBufferConsumer, Gralloc and so on
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/IGraphicBufferProducer.cpp
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueCore.h
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueCore.cpp
*/
class GraphicBufferProducer {
private:
const DeviceState &state;
std::mutex mutex; //!< Synchronizes access to the buffer queue
constexpr static u8 MaxSlotCount{16}; //!< The maximum amount of buffer slots that a buffer queue can hold, Android supports 64 but they go unused for applications like games so we've lowered this to 16 (https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueDefs.h;l=29)
std::array<BufferSlot, MaxSlotCount> queue;
u8 activeSlotCount{2}; //!< The amount of slots in the queue that can be used
u8 hasBufferCount{}; //!< The amount of slots with buffers attached in the queue
u32 defaultWidth{1}; //!< The assumed width of a buffer if none is supplied in DequeueBuffer
u32 defaultHeight{1}; //!< The assumed height of a buffer if none is supplied in DequeueBuffer
AndroidPixelFormat defaultFormat{AndroidPixelFormat::RGBA8888}; //!< The assumed format of a buffer if none is supplied in DequeueBuffer
NativeWindowApi connectedApi{NativeWindowApi::None}; //!< The API that the producer is currently connected to
u64 frameNumber{}; //!< The amount of frames that have been presented so far
/**
* @return The amount of buffers which have been queued onto the consumer
*/
u8 GetPendingBufferCount();
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h;l=67-80;
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=35-40
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=50-73
*/
AndroidStatus RequestBuffer(i32 slot, GraphicBuffer *&buffer);
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h;l=104-170
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=59-97
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=251-388
*/
AndroidStatus DequeueBuffer(bool async, u32 width, u32 height, AndroidPixelFormat format, u32 usage, i32 &slot, std::optional<AndroidFence> &fence);
/**
* @note Nintendo has added an additional field for swap interval which sets the swap interval of the compositor
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h;l=236-349
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=109-125
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=512-691
*/
AndroidStatus QueueBuffer(i32 slot, i64 timestamp, bool isAutoTimestamp, AndroidRect crop, NativeWindowScalingMode scalingMode, NativeWindowTransform transform, NativeWindowTransform stickyTransform, bool async, u32 swapInterval, const AndroidFence &fence, u32 &width, u32 &height, NativeWindowTransform &transformHint, u32 &pendingBufferCount);
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h;l=351-359
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=127-132
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=693-720
*/
void CancelBuffer(i32 slot, const AndroidFence &fence);
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h;l=361-367
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=134-136
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=722-766
*/
AndroidStatus Query(NativeWindowQuery query, u32 &out);
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h;l=369-405
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=138-148
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=768-831
*/
AndroidStatus Connect(NativeWindowApi api, bool producerControlledByApp, u32 &width, u32 &height, NativeWindowTransform &transformHint, u32 &pendingBufferCount);
/**
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/IGraphicBufferProducer.h;l=407-426
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferQueueProducer.h;l=150-158
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueProducer.cpp;l=833-890
*/
AndroidStatus Disconnect(NativeWindowApi api);
/**
* @brief Similar to AttachBuffer but the slot is explicitly specified and the producer defaults are set based off it
* @note This is an HOS-specific addition to GraphicBufferProducer, it exists so that all allocation of buffers is handled by the client to avoid any shared/transfer memory from the client to loan memory for the buffers which would be quite complicated
*/
AndroidStatus SetPreallocatedBuffer(i32 slot, const GraphicBuffer &graphicBuffer);
public:
std::shared_ptr<kernel::type::KEvent> bufferEvent; //!< Signalled every time a buffer in the queue is freed
DisplayId displayId{DisplayId::Null}; //!< The ID of this display
2020-09-28 12:05:17 +02:00
LayerStatus layerStatus{LayerStatus::Uninitialized}; //!< The status of the single layer the display has
/**
* @brief The transactions supported by android.gui.IGraphicBufferProducer
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/IGraphicBufferProducer.cpp;l=35-49
*/
enum class TransactionCode : u32 {
RequestBuffer = 1,
SetBufferCount = 2,
DequeueBuffer = 3,
DetachBuffer = 4,
DetachNextBuffer = 5,
AttachBuffer = 6,
QueueBuffer = 7,
CancelBuffer = 8,
Query = 9,
Connect = 10,
Disconnect = 11,
SetSidebandStream = 12,
AllocateBuffers = 13,
SetPreallocatedBuffer = 14, //!< A transaction specific to HOS, see the implementation for a description of its functionality
};
GraphicBufferProducer(const DeviceState &state);
/**
2020-09-28 12:05:17 +02:00
* @brief The handler for Binder IPC transactions with IGraphicBufferProducer
* @url https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/IGraphicBufferProducer.cpp;l=277-426
*/
void OnTransact(TransactionCode code, Parcel &in, Parcel &out);
/**
2020-09-28 12:05:17 +02:00
* @brief Sets displayId to a specific display type
* @note displayId has to be DisplayId::Null or this will throw an exception
*/
void SetDisplay(const std::string &name);
/**
2020-09-28 12:05:17 +02:00
* @brief Closes the display by setting displayId to DisplayId::Null
*/
void CloseDisplay();
};
extern std::weak_ptr<GraphicBufferProducer> producer; //!< A globally shared instance of the GraphicsBufferProducer
}
#undef ENUM_CASE