summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/frontend/emu_window.h41
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp41
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h1
3 files changed, 69 insertions, 14 deletions
diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h
index 72294d4d8..13aa14934 100644
--- a/src/core/frontend/emu_window.h
+++ b/src/core/frontend/emu_window.h
@@ -12,6 +12,15 @@
namespace Core::Frontend {
+/// Information for the Graphics Backends signifying what type of screen pointer is in
+/// WindowInformation
+enum class WindowSystemType {
+ Headless,
+ Windows,
+ X11,
+ Wayland,
+};
+
/**
* Represents a drawing context that supports graphics operations.
*/
@@ -76,6 +85,23 @@ public:
std::pair<unsigned, unsigned> min_client_area_size;
};
+ /// Data describing host window system information
+ struct WindowSystemInfo {
+ // Window system type. Determines which GL context or Vulkan WSI is used.
+ WindowSystemType type = WindowSystemType::Headless;
+
+ // Connection to a display server. This is used on X11 and Wayland platforms.
+ void* display_connection = nullptr;
+
+ // Render surface. This is a pointer to the native window handle, which depends
+ // on the platform. e.g. HWND for Windows, Window for X11. If the surface is
+ // set to nullptr, the video backend will run in headless mode.
+ void* render_surface = nullptr;
+
+ // Scale of the render surface. For hidpi systems, this will be >1.
+ float render_surface_scale = 1.0f;
+ };
+
/// Polls window events
virtual void PollEvents() = 0;
@@ -87,10 +113,6 @@ public:
/// Returns if window is shown (not minimized)
virtual bool IsShown() const = 0;
- /// Retrieves Vulkan specific handlers from the window
- virtual void RetrieveVulkanHandlers(void* get_instance_proc_addr, void* instance,
- void* surface) const = 0;
-
/**
* Signal that a touch pressed event has occurred (e.g. mouse click pressed)
* @param framebuffer_x Framebuffer x-coordinate that was pressed
@@ -128,6 +150,13 @@ public:
}
/**
+ * Returns system information about the drawing area.
+ */
+ const WindowSystemInfo& GetWindowInfo() const {
+ return window_info;
+ }
+
+ /**
* Gets the framebuffer layout (width, height, and screen regions)
* @note This method is thread-safe
*/
@@ -142,7 +171,7 @@ public:
void UpdateCurrentFramebufferLayout(unsigned width, unsigned height);
protected:
- EmuWindow();
+ explicit EmuWindow();
virtual ~EmuWindow();
/**
@@ -179,6 +208,8 @@ protected:
client_area_height = size.second;
}
+ WindowSystemInfo window_info;
+
private:
/**
* Handler called when the minimal client area was requested to be changed via SetConfig.
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index ad0e4ff73..f1e3d832a 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -28,6 +28,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
buffer.slot = slot;
buffer.igbp_buffer = igbp_buffer;
buffer.status = Buffer::Status::Free;
+ free_buffers.push_back(slot);
queue.emplace_back(buffer);
buffer_wait_event.writable->Signal();
@@ -35,16 +36,37 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
u32 height) {
- auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
- // Only consider free buffers. Buffers become free once again after they've been Acquired
- // and Released by the compositor, see the NVFlinger::Compose method.
- if (buffer.status != Buffer::Status::Free) {
- return false;
- }
- // Make sure that the parameters match.
- return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
- });
+ if (free_buffers.empty()) {
+ return {};
+ }
+
+ auto f_itr = free_buffers.begin();
+ auto itr = queue.end();
+
+ while (f_itr != free_buffers.end()) {
+ auto slot = *f_itr;
+ itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
+ // Only consider free buffers. Buffers become free once again after they've been
+ // Acquired and Released by the compositor, see the NVFlinger::Compose method.
+ if (buffer.status != Buffer::Status::Free) {
+ return false;
+ }
+
+ if (buffer.slot != slot) {
+ return false;
+ }
+
+ // Make sure that the parameters match.
+ return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
+ });
+
+ if (itr != queue.end()) {
+ free_buffers.erase(f_itr);
+ break;
+ }
+ ++f_itr;
+ }
if (itr == queue.end()) {
return {};
@@ -99,6 +121,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
ASSERT(itr != queue.end());
ASSERT(itr->status == Buffer::Status::Acquired);
itr->status = Buffer::Status::Free;
+ free_buffers.push_back(slot);
buffer_wait_event.writable->Signal();
}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index f3edb6dfb..d5f31e567 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -102,6 +102,7 @@ private:
u32 id;
u64 layer_id;
+ std::list<u32> free_buffers;
std::vector<Buffer> queue;
std::list<u32> queue_sequence;
Kernel::EventPair buffer_wait_event;