mirror of https://github.com/PCSX2/pcsx2.git
GS: Remove GSWnd and use GL::Context
This commit is contained in:
parent
198fc2629e
commit
5ba70c8c20
|
@ -664,7 +664,6 @@ set(pcsx2GSSources
|
|||
GS/Renderers/OpenGL/GSTextureCacheOGL.cpp
|
||||
GS/Renderers/OpenGL/GSTextureOGL.cpp
|
||||
GS/Window/GSSetting.cpp
|
||||
GS/Window/GSWnd.cpp
|
||||
)
|
||||
|
||||
# GS headers
|
||||
|
@ -734,7 +733,6 @@ set(pcsx2GSHeaders
|
|||
GS/Window/GSDialog.h
|
||||
GS/Window/GSSetting.h
|
||||
GS/Window/GSSettingsDlg.h
|
||||
GS/Window/GSWnd.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
@ -807,16 +805,12 @@ if(WIN32)
|
|||
GS/Window/GSCaptureDlg.cpp
|
||||
GS/Window/GSDialog.cpp
|
||||
GS/Window/GSSettingsDlg.cpp
|
||||
GS/Window/GSWndDX.cpp
|
||||
GS/Window/GSWndWGL.cpp
|
||||
)
|
||||
list(APPEND pcsx2GSHeaders
|
||||
GS/Renderers/DX11/GSDevice11.h
|
||||
GS/Renderers/DX11/GSRendererDX11.h
|
||||
GS/Renderers/DX11/GSTexture11.h
|
||||
GS/Renderers/DX11/GSTextureCache11.h
|
||||
GS/Window/GSWndDX.h
|
||||
GS/Window/GSWndWGL.h
|
||||
)
|
||||
else(WIN32)
|
||||
list(APPEND pcsx2SPU2Sources
|
||||
|
@ -902,12 +896,10 @@ else(WIN32)
|
|||
list(APPEND pcsx2GSSources
|
||||
GS/GS_res.cpp
|
||||
GS/Window/GSLinuxDialog.cpp
|
||||
GS/Window/GSWndEGL.cpp
|
||||
)
|
||||
|
||||
list(APPEND pcsx2GSHeaders
|
||||
GS/GS_res.h
|
||||
GS/Window/GSWndEGL.h
|
||||
)
|
||||
endif(WIN32)
|
||||
|
||||
|
@ -1394,14 +1386,9 @@ if(Linux)
|
|||
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||
PkgConfig::AIO
|
||||
PkgConfig::EGL
|
||||
PkgConfig::LIBUDEV
|
||||
ALSA::ALSA
|
||||
)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||
PkgConfig::EGL
|
||||
)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
|
100
pcsx2/GS/GS.cpp
100
pcsx2/GS/GS.cpp
|
@ -30,8 +30,6 @@
|
|||
|
||||
#include "Renderers/DX11/GSRendererDX11.h"
|
||||
#include "Renderers/DX11/GSDevice11.h"
|
||||
#include "Window/GSWndDX.h"
|
||||
#include "Window/GSWndWGL.h"
|
||||
#include "Window/GSSettingsDlg.h"
|
||||
|
||||
|
||||
|
@ -39,8 +37,6 @@ static HRESULT s_hr = E_FAIL;
|
|||
|
||||
#else
|
||||
|
||||
#include "GS/Window/GSWndEGL.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <gtk/gtk.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
@ -64,6 +60,13 @@ static bool s_exclusive = true;
|
|||
static std::string s_renderer_name;
|
||||
bool gsopen_done = false; // crash guard for GSgetTitleInfo2 and GSKeyEvent (replace with lock?)
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
static std::atomic_bool s_gs_window_resized{false};
|
||||
static std::mutex s_gs_window_resized_lock;
|
||||
static int s_new_gs_window_width = 0;
|
||||
static int s_new_gs_window_height = 0;
|
||||
#endif
|
||||
|
||||
void GSsetBaseMem(uint8* mem)
|
||||
{
|
||||
s_basemem = mem;
|
||||
|
@ -126,6 +129,11 @@ void GSclose()
|
|||
{
|
||||
gsopen_done = false;
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
// Make sure we don't have any leftover resize events from our last open.
|
||||
s_gs_window_resized.store(false);
|
||||
#endif
|
||||
|
||||
if (s_gs == NULL)
|
||||
return;
|
||||
|
||||
|
@ -136,11 +144,6 @@ void GSclose()
|
|||
delete s_gs->m_dev;
|
||||
|
||||
s_gs->m_dev = NULL;
|
||||
|
||||
if (s_gs->m_wnd)
|
||||
{
|
||||
s_gs->m_wnd->Detach();
|
||||
}
|
||||
}
|
||||
|
||||
int _GSopen(const WindowInfo& wi, const char* title, GSRendererType renderer, int threads = -1)
|
||||
|
@ -177,60 +180,7 @@ int _GSopen(const WindowInfo& wi, const char* title, GSRendererType renderer, in
|
|||
theApp.SetCurrentRendererType(renderer);
|
||||
}
|
||||
|
||||
std::shared_ptr<GSWnd> window;
|
||||
{
|
||||
// Select the window first to detect the GL requirement
|
||||
std::vector<std::shared_ptr<GSWnd>> wnds;
|
||||
switch (renderer)
|
||||
{
|
||||
case GSRendererType::OGL_HW:
|
||||
case GSRendererType::OGL_SW:
|
||||
#if defined(__unix__)
|
||||
if (std::shared_ptr<GSWndEGL> wnd = GSWndEGL::CreateForPlatform(wi); wnd)
|
||||
wnds.push_back(std::move(wnd));
|
||||
#elif defined(__APPLE__)
|
||||
// No windows available for macOS at the moment
|
||||
#else
|
||||
wnds.push_back(std::make_shared<GSWndWGL>());
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
#ifdef _WIN32
|
||||
wnds.push_back(std::make_shared<GSWndDX>());
|
||||
#elif defined(__APPLE__)
|
||||
// No windows available for macOS at the moment
|
||||
#else
|
||||
wnds.push_back(std::make_shared<GSWndEGL_X11>());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto& wnd : wnds)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!wnd->Attach(wi))
|
||||
continue;
|
||||
|
||||
window = wnd; // Previous code will throw if window isn't supported
|
||||
break;
|
||||
}
|
||||
catch (GSRecoverableError)
|
||||
{
|
||||
wnd->Detach();
|
||||
}
|
||||
}
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GSclose();
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
std::string renderer_name;
|
||||
|
||||
switch (renderer)
|
||||
{
|
||||
default:
|
||||
|
@ -288,8 +238,6 @@ int _GSopen(const WindowInfo& wi, const char* title, GSRendererType renderer, in
|
|||
if (s_gs == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
s_gs->m_wnd = window;
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
|
@ -300,7 +248,7 @@ int _GSopen(const WindowInfo& wi, const char* title, GSRendererType renderer, in
|
|||
s_gs->SetRegsMem(s_basemem);
|
||||
s_gs->SetVSync(s_vsync);
|
||||
|
||||
if (!s_gs->CreateDevice(dev))
|
||||
if (!s_gs->CreateDevice(dev, wi))
|
||||
{
|
||||
// This probably means the user has DX11 configured with a video card that is only DX9
|
||||
// compliant. Cound mean drivr issues of some sort also, but to be sure, that's the most
|
||||
|
@ -756,6 +704,28 @@ void GSsetExclusive(int enabled)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
void GSResizeWindow(int width, int height)
|
||||
{
|
||||
std::unique_lock lock(s_gs_window_resized_lock);
|
||||
s_new_gs_window_width = width;
|
||||
s_new_gs_window_height = height;
|
||||
s_gs_window_resized.store(true);
|
||||
}
|
||||
|
||||
bool GSCheckForWindowResize(int* new_width, int* new_height)
|
||||
{
|
||||
if (!s_gs_window_resized.load())
|
||||
return false;
|
||||
|
||||
std::unique_lock lock(s_gs_window_resized_lock);
|
||||
*new_width = s_new_gs_window_width;
|
||||
*new_height = s_new_gs_window_height;
|
||||
s_gs_window_resized.store(false);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string format(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "common/Pcsx2Types.h"
|
||||
#include "common/WindowInfo.h"
|
||||
#include "GS_types.h"
|
||||
#include "Window/GSSetting.h"
|
||||
#include "SaveState.h"
|
||||
|
@ -1794,6 +1795,12 @@ void GSsetFrameSkip(int frameskip);
|
|||
void GSsetVsync(int vsync);
|
||||
void GSsetExclusive(int enabled);
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
// Needed for window resizing in wx. Can be safely called from the UI thread.
|
||||
void GSResizeWindow(int width, int height);
|
||||
bool GSCheckForWindowResize(int* new_width, int* new_height);
|
||||
#endif
|
||||
|
||||
class GSApp
|
||||
{
|
||||
std::string m_section;
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
#include "GSDevice.h"
|
||||
|
||||
GSDevice::GSDevice()
|
||||
: m_wnd()
|
||||
, m_vsync(false)
|
||||
: m_vsync(false)
|
||||
, m_rbswapped(false)
|
||||
, m_backbuffer(NULL)
|
||||
, m_merge(NULL)
|
||||
|
@ -46,10 +45,8 @@ GSDevice::~GSDevice()
|
|||
delete m_target_tmp;
|
||||
}
|
||||
|
||||
bool GSDevice::Create(const std::shared_ptr<GSWnd>& wnd)
|
||||
bool GSDevice::Create(const WindowInfo& wi)
|
||||
{
|
||||
m_wnd = wnd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -73,27 +70,19 @@ bool GSDevice::Reset(int w, int h)
|
|||
m_target_tmp = NULL;
|
||||
|
||||
m_current = NULL; // current is special, points to other textures, no need to delete
|
||||
|
||||
return m_wnd != NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSDevice::Present(const GSVector4i& r, int shader)
|
||||
{
|
||||
const GSVector4i cr = m_wnd->GetClientRect();
|
||||
|
||||
const int w = std::max<int>(cr.width(), 1);
|
||||
const int h = std::max<int>(cr.height(), 1);
|
||||
|
||||
if (!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h)
|
||||
{
|
||||
if (!Reset(w, h))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GL_PUSH("Present");
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
int new_width, new_height;
|
||||
if (GSCheckForWindowResize(&new_width, &new_height) && !Reset(new_width, new_height))
|
||||
return;
|
||||
#endif
|
||||
|
||||
// FIXME is it mandatory, it could be slow
|
||||
ClearRenderTarget(m_backbuffer, 0);
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "common/WindowInfo.h"
|
||||
#include "GSFastList.h"
|
||||
#include "GS/Window/GSWnd.h"
|
||||
#include "GSTexture.h"
|
||||
#include "GSVertex.h"
|
||||
#include "GS/GSAlignedClass.h"
|
||||
|
@ -145,7 +145,6 @@ protected:
|
|||
static const int m_NO_BLEND = 0;
|
||||
static const int m_MERGE_BLEND = m_blendMap.size() - 1;
|
||||
|
||||
std::shared_ptr<GSWnd> m_wnd;
|
||||
int m_vsync;
|
||||
bool m_rbswapped;
|
||||
GSTexture* m_backbuffer;
|
||||
|
@ -190,7 +189,7 @@ public:
|
|||
DontCare
|
||||
};
|
||||
|
||||
virtual bool Create(const std::shared_ptr<GSWnd>& wnd);
|
||||
virtual bool Create(const WindowInfo& wi);
|
||||
virtual bool Reset(int w, int h);
|
||||
virtual bool IsLost(bool update = false) { return false; }
|
||||
virtual void Present(const GSVector4i& r, int shader);
|
||||
|
@ -247,6 +246,8 @@ public:
|
|||
bool ResizeTarget(GSTexture** t);
|
||||
|
||||
bool IsRBSwapped() { return m_rbswapped; }
|
||||
int GetBackbufferWidth() const { return m_backbuffer ? m_backbuffer->GetWidth() : 0; }
|
||||
int GetBackbufferHeight() const { return m_backbuffer ? m_backbuffer->GetHeight() : 0; }
|
||||
|
||||
void AgePool();
|
||||
void PurgePool();
|
||||
|
|
|
@ -31,7 +31,6 @@ GSRenderer::GSRenderer()
|
|||
, m_control_key(false)
|
||||
, m_texture_shuffle(false)
|
||||
, m_real_size(0, 0)
|
||||
, m_wnd()
|
||||
, m_dev(NULL)
|
||||
{
|
||||
m_GStitleInfoBuffer[0] = 0;
|
||||
|
@ -56,12 +55,12 @@ GSRenderer::~GSRenderer()
|
|||
delete m_dev;
|
||||
}
|
||||
|
||||
bool GSRenderer::CreateDevice(GSDevice* dev)
|
||||
bool GSRenderer::CreateDevice(GSDevice* dev, const WindowInfo& wi)
|
||||
{
|
||||
ASSERT(dev);
|
||||
ASSERT(!m_dev);
|
||||
|
||||
if (!dev->Create(m_wnd))
|
||||
if (!dev->Create(wi))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -468,7 +467,7 @@ void GSRenderer::VSync(int field)
|
|||
|
||||
// This will scale the OSD to the window's size.
|
||||
// Will maintiain the font size no matter what size the window is.
|
||||
GSVector4i window_size = m_wnd->GetClientRect();
|
||||
GSVector4i window_size(0, 0, m_dev->GetBackbufferWidth(), m_dev->GetBackbufferHeight());
|
||||
m_dev->m_osd.m_real_size.x = window_size.v[2];
|
||||
m_dev->m_osd.m_real_size.y = window_size.v[3];
|
||||
|
||||
|
@ -568,8 +567,7 @@ bool GSRenderer::MakeSnapshot(const std::string& path)
|
|||
|
||||
bool GSRenderer::BeginCapture(std::string& filename)
|
||||
{
|
||||
const GSVector4i crect(m_wnd->GetClientRect());
|
||||
GSVector4i disp = ComputeDrawRectangle(crect.z, crect.w);
|
||||
GSVector4i disp = ComputeDrawRectangle(m_dev->GetBackbufferWidth(), m_dev->GetBackbufferHeight());
|
||||
float aspect = (float)disp.width() / std::max(1, disp.height());
|
||||
|
||||
return m_capture.BeginCapture(GetTvRefreshRate(), GetInternalResolution(), aspect, filename);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "GS/GS.h"
|
||||
#include "GS/Window/GSWnd.h"
|
||||
#include "GS/GSState.h"
|
||||
#include "GS/GSCapture.h"
|
||||
|
||||
|
@ -48,14 +47,13 @@ protected:
|
|||
virtual GSTexture* GetFeedbackOutput() { return nullptr; }
|
||||
|
||||
public:
|
||||
std::shared_ptr<GSWnd> m_wnd;
|
||||
GSDevice* m_dev;
|
||||
|
||||
public:
|
||||
GSRenderer();
|
||||
virtual ~GSRenderer();
|
||||
|
||||
virtual bool CreateDevice(GSDevice* dev);
|
||||
virtual bool CreateDevice(GSDevice* dev, const WindowInfo& wi);
|
||||
virtual void ResetDevice();
|
||||
virtual void VSync(int field);
|
||||
virtual bool MakeSnapshot(const std::string& path);
|
||||
|
|
|
@ -74,11 +74,11 @@ bool GSDevice11::SetFeatureLevel(D3D_FEATURE_LEVEL level, bool compat_mode)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice11::Create(const std::shared_ptr<GSWnd>& wnd)
|
||||
bool GSDevice11::Create(const WindowInfo& wi)
|
||||
{
|
||||
bool nvidia_vendor = false;
|
||||
|
||||
if (!__super::Create(wnd))
|
||||
if (!__super::Create(wi))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ bool GSDevice11::Create(const std::shared_ptr<GSWnd>& wnd)
|
|||
swapchain_description.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
const HRESULT result = factory->CreateSwapChainForHwnd(
|
||||
m_dev.get(), reinterpret_cast<HWND>(m_wnd->GetHandle()),
|
||||
m_dev.get(), reinterpret_cast<HWND>(wi.window_handle),
|
||||
&swapchain_description, nullptr, nullptr, m_swapchain.put());
|
||||
|
||||
if (FAILED(result))
|
||||
|
@ -382,7 +382,7 @@ bool GSDevice11::Create(const std::shared_ptr<GSWnd>& wnd)
|
|||
|
||||
//
|
||||
|
||||
Reset(1, 1);
|
||||
Reset(wi.surface_width, wi.surface_height);
|
||||
|
||||
//
|
||||
|
||||
|
|
|
@ -525,7 +525,7 @@ public:
|
|||
bool SetFeatureLevel(D3D_FEATURE_LEVEL level, bool compat_mode);
|
||||
void GetFeatureLevel(D3D_FEATURE_LEVEL& level) const { level = m_shader.level; }
|
||||
|
||||
bool Create(const std::shared_ptr<GSWnd>& wnd);
|
||||
bool Create(const WindowInfo& wi);
|
||||
bool Reset(int w, int h);
|
||||
void Flip();
|
||||
void SetVSync(int vsync) final;
|
||||
|
|
|
@ -24,11 +24,6 @@ GSRendererDX11::GSRendererDX11()
|
|||
ResetStates();
|
||||
}
|
||||
|
||||
bool GSRendererDX11::CreateDevice(GSDevice* dev)
|
||||
{
|
||||
return GSRenderer::CreateDevice(dev);
|
||||
}
|
||||
|
||||
void GSRendererDX11::SetupIA(const float& sx, const float& sy)
|
||||
{
|
||||
GSDevice11* dev = (GSDevice11*)m_dev;
|
||||
|
|
|
@ -58,6 +58,4 @@ public:
|
|||
virtual ~GSRendererDX11() {}
|
||||
|
||||
void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) final;
|
||||
|
||||
bool CreateDevice(GSDevice* dev);
|
||||
};
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "GSDeviceNull.h"
|
||||
|
||||
bool GSDeviceNull::Create(const std::shared_ptr<GSWnd>& wnd)
|
||||
bool GSDeviceNull::Create(const WindowInfo& wi)
|
||||
{
|
||||
if (!GSDevice::Create(wnd))
|
||||
if (!GSDevice::Create(wi))
|
||||
return false;
|
||||
|
||||
Reset(1, 1);
|
||||
|
|
|
@ -30,6 +30,6 @@ private:
|
|||
public:
|
||||
GSDeviceNull() {}
|
||||
|
||||
bool Create(const std::shared_ptr<GSWnd>& wnd);
|
||||
bool Create(const WindowInfo& wi);
|
||||
bool Reset(int w, int h);
|
||||
};
|
||||
|
|
|
@ -305,9 +305,27 @@ GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, int format)
|
|||
return t;
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::Create(const std::shared_ptr<GSWnd>& wnd)
|
||||
bool GSDeviceOGL::Create(const WindowInfo& wi)
|
||||
{
|
||||
std::vector<char> shader;
|
||||
|
||||
m_gl_context = GL::Context::Create(wi, GL::Context::GetAllVersionsList());
|
||||
if (!m_gl_context || !m_gl_context->MakeCurrent())
|
||||
return false;
|
||||
|
||||
// Check openGL requirement as soon as possible so we can switch to another
|
||||
// renderer/device
|
||||
try
|
||||
{
|
||||
GLLoader::check_gl_requirements();
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
printf("GS error: Exception caught in GSDeviceOGL::Create: %s", ex.what());
|
||||
m_gl_context->DoneCurrent();
|
||||
return false;
|
||||
}
|
||||
|
||||
// ****************************************************************
|
||||
// Debug helper
|
||||
// ****************************************************************
|
||||
|
@ -584,11 +602,10 @@ bool GSDeviceOGL::Create(const std::shared_ptr<GSWnd>& wnd)
|
|||
// ****************************************************************
|
||||
// Finish window setup and backbuffer
|
||||
// ****************************************************************
|
||||
if (!GSDevice::Create(wnd))
|
||||
if (!GSDevice::Create(wi))
|
||||
return false;
|
||||
|
||||
const GSVector4i rect = wnd->GetClientRect();
|
||||
Reset(rect.z, rect.w);
|
||||
Reset(wi.surface_width, wi.surface_height);
|
||||
|
||||
// Basic to ensure structures are correctly packed
|
||||
static_assert(sizeof(VSSelector) == 4, "Wrong VSSelector size");
|
||||
|
@ -645,19 +662,20 @@ bool GSDeviceOGL::Reset(int w, int h)
|
|||
// Opengl allocate the backbuffer with the window. The render is done in the backbuffer when
|
||||
// there isn't any FBO. Only a dummy texture is created to easily detect when the rendering is done
|
||||
// in the backbuffer
|
||||
m_backbuffer = new GSTextureOGL(GSTextureOGL::Backbuffer, w, h, 0, m_fbo_read, false);
|
||||
|
||||
m_gl_context->ResizeSurface(w, h);
|
||||
m_backbuffer = new GSTextureOGL(GSTextureOGL::Backbuffer, m_gl_context->GetSurfaceWidth(),
|
||||
m_gl_context->GetSurfaceHeight(), 0, m_fbo_read, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetVSync(int vsync)
|
||||
{
|
||||
m_wnd->SetVSync(vsync);
|
||||
m_gl_context->SetSwapInterval(vsync);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::Flip()
|
||||
{
|
||||
m_wnd->Flip();
|
||||
m_gl_context->SwapBuffers();
|
||||
|
||||
if (GLLoader::in_replayer)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "common/GL/Context.h"
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GSTextureOGL.h"
|
||||
#include "GS/GS.h"
|
||||
|
@ -464,6 +465,7 @@ public:
|
|||
static int m_shader_reg;
|
||||
|
||||
private:
|
||||
std::unique_ptr<GL::Context> m_gl_context;
|
||||
int m_force_texture_clear;
|
||||
int m_mipmap;
|
||||
TriFiltering m_filter;
|
||||
|
@ -581,10 +583,10 @@ public:
|
|||
// Used by OpenGL, so the same calling convention is required.
|
||||
static void APIENTRY DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id, GLenum gl_severity, GLsizei gl_length, const GLchar* gl_message, const void* userParam);
|
||||
|
||||
bool Create(const std::shared_ptr<GSWnd>& wnd);
|
||||
bool Reset(int w, int h);
|
||||
void Flip();
|
||||
void SetVSync(int vsync);
|
||||
bool Create(const WindowInfo& wi) override;
|
||||
bool Reset(int w, int h) override;
|
||||
void Flip() override;
|
||||
void SetVSync(int vsync) override;
|
||||
|
||||
void DrawPrimitive() final;
|
||||
void DrawPrimitive(int offset, int count);
|
||||
|
|
|
@ -33,11 +33,6 @@ GSRendererOGL::GSRendererOGL()
|
|||
ResetStates();
|
||||
}
|
||||
|
||||
bool GSRendererOGL::CreateDevice(GSDevice* dev)
|
||||
{
|
||||
return GSRenderer::CreateDevice(dev);
|
||||
}
|
||||
|
||||
void GSRendererOGL::SetupIA(const float& sx, const float& sy)
|
||||
{
|
||||
GL_PUSH("IA");
|
||||
|
|
|
@ -71,8 +71,6 @@ public:
|
|||
GSRendererOGL();
|
||||
virtual ~GSRendererOGL() {}
|
||||
|
||||
bool CreateDevice(GSDevice* dev);
|
||||
|
||||
void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) final;
|
||||
|
||||
PRIM_OVERLAP PrimitiveOverlap();
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSWnd.h"
|
||||
|
||||
void GSWndGL::PopulateGlFunction()
|
||||
{
|
||||
if (!gladLoadGL())
|
||||
throw GSRecoverableError();
|
||||
|
||||
// Check openGL requirement as soon as possible so we can switch to another
|
||||
// renderer/device
|
||||
GLLoader::check_gl_requirements();
|
||||
}
|
||||
|
||||
void GSWndGL::FullContextInit()
|
||||
{
|
||||
CreateContext(3, 3);
|
||||
AttachContext();
|
||||
PopulateGlFunction();
|
||||
PopulateWndGlFunction();
|
||||
}
|
||||
|
||||
void GSWndGL::SetVSync(int vsync)
|
||||
{
|
||||
if (!HasLateVsyncSupport() && vsync < 0)
|
||||
m_vsync = -vsync; // Late vsync not supported, fallback to standard vsync
|
||||
else
|
||||
m_vsync = vsync;
|
||||
|
||||
// The WGL/GLX/EGL swap interval function must be called on the rendering
|
||||
// thread or else the change won't be properly applied.
|
||||
m_vsync_change_requested = true;
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "common/WindowInfo.h"
|
||||
#include "GS/GS.h"
|
||||
#include "GS/GSVector.h"
|
||||
|
||||
class GSWnd
|
||||
{
|
||||
public:
|
||||
GSWnd() = default;
|
||||
virtual ~GSWnd() = default;
|
||||
|
||||
virtual bool Attach(const WindowInfo& wi) = 0;
|
||||
virtual void Detach() = 0;
|
||||
|
||||
virtual void* GetHandle() = 0;
|
||||
virtual GSVector4i GetClientRect() = 0;
|
||||
|
||||
virtual void AttachContext() {}
|
||||
virtual void DetachContext() {}
|
||||
|
||||
virtual void Flip() {}
|
||||
virtual void SetVSync(int vsync) {}
|
||||
};
|
||||
|
||||
class GSWndGL : public GSWnd
|
||||
{
|
||||
protected:
|
||||
bool m_ctx_attached;
|
||||
std::atomic<bool> m_vsync_change_requested;
|
||||
std::atomic<int> m_vsync;
|
||||
|
||||
bool IsContextAttached() const { return m_ctx_attached; }
|
||||
void PopulateGlFunction();
|
||||
virtual void PopulateWndGlFunction() = 0;
|
||||
void FullContextInit();
|
||||
virtual void CreateContext(int major, int minor) = 0;
|
||||
|
||||
virtual void SetSwapInterval() = 0;
|
||||
virtual bool HasLateVsyncSupport() = 0;
|
||||
|
||||
public:
|
||||
GSWndGL()
|
||||
: m_ctx_attached(false)
|
||||
, m_vsync_change_requested(false)
|
||||
, m_vsync(0)
|
||||
{
|
||||
}
|
||||
virtual ~GSWndGL() override = default;
|
||||
|
||||
void SetVSync(int vsync) final;
|
||||
};
|
|
@ -1,53 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSWndDX.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
GSWndDX::GSWndDX()
|
||||
: m_hWnd(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
GSWndDX::~GSWndDX()
|
||||
{
|
||||
}
|
||||
|
||||
bool GSWndDX::Attach(const WindowInfo& wi)
|
||||
{
|
||||
if (wi.type != WindowInfo::Type::Win32)
|
||||
return false;
|
||||
|
||||
// TODO: subclass
|
||||
|
||||
m_hWnd = static_cast<HWND>(wi.window_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSWndDX::Detach()
|
||||
{
|
||||
m_hWnd = {};
|
||||
}
|
||||
|
||||
GSVector4i GSWndDX::GetClientRect()
|
||||
{
|
||||
GSVector4i r;
|
||||
|
||||
::GetClientRect(m_hWnd, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSWnd.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
class GSWndDX final : public GSWnd
|
||||
{
|
||||
HWND m_hWnd;
|
||||
|
||||
public:
|
||||
GSWndDX();
|
||||
~GSWndDX() override;
|
||||
|
||||
bool Attach(const WindowInfo& wi) override;
|
||||
void Detach() override;
|
||||
|
||||
void* GetHandle() override { return m_hWnd; }
|
||||
GSVector4i GetClientRect() override;
|
||||
};
|
||||
#endif
|
|
@ -1,313 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSWndEGL.h"
|
||||
|
||||
#if defined(__unix__)
|
||||
|
||||
std::shared_ptr<GSWndEGL> GSWndEGL::CreateForPlatform(const WindowInfo& wi)
|
||||
{
|
||||
// Check the supported extension
|
||||
const char* client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
if (!client_extensions)
|
||||
{
|
||||
fprintf(stderr, "EGL: Client extension not supported\n");
|
||||
return nullptr;
|
||||
}
|
||||
fprintf(stdout, "EGL: Supported extensions: %s\n", client_extensions);
|
||||
|
||||
// Check platform extensions are supported (Note: there are core in 1.5)
|
||||
if (!strstr(client_extensions, "EGL_EXT_platform_base"))
|
||||
{
|
||||
fprintf(stderr, "EGL: Dynamic platform selection isn't supported\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Finally we can select the platform
|
||||
#if GS_EGL_X11
|
||||
if (strstr(client_extensions, "EGL_EXT_platform_x11") && wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
fprintf(stdout, "EGL: select X11 platform\n");
|
||||
return std::make_shared<GSWndEGL_X11>();
|
||||
}
|
||||
#endif
|
||||
#if GS_EGL_WL
|
||||
if (strstr(client_extensions, "EGL_EXT_platform_wayland") && wi.type == WindowInfo::Type::Wayland)
|
||||
{
|
||||
fprintf(stdout, "EGL: select Wayland platform\n");
|
||||
return std::make_shared<GSWndEGL_WL>();
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "EGL: no compatible platform found for wintype %u\n", static_cast<unsigned>(wi.type));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
GSWndEGL::GSWndEGL(int platform)
|
||||
: m_native_window(nullptr), m_platform(platform)
|
||||
{
|
||||
}
|
||||
|
||||
void GSWndEGL::CreateContext(int major, int minor)
|
||||
{
|
||||
EGLConfig eglConfig;
|
||||
EGLint numConfigs = 0;
|
||||
EGLint contextAttribs[] =
|
||||
{
|
||||
EGL_CONTEXT_MAJOR_VERSION_KHR, major,
|
||||
EGL_CONTEXT_MINOR_VERSION_KHR, minor,
|
||||
#ifdef ENABLE_OGL_DEBUG
|
||||
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR,
|
||||
#else
|
||||
// Open Source isn't happy with an unsupported flags...
|
||||
//EGL_CONTEXT_FLAGS_KHR, GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR,
|
||||
#endif
|
||||
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLint NullContextAttribs[] = {EGL_NONE};
|
||||
EGLint attrList[] = {
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 0,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
BindAPI();
|
||||
|
||||
eglChooseConfig(m_eglDisplay, attrList, &eglConfig, 1, &numConfigs);
|
||||
if (numConfigs == 0)
|
||||
{
|
||||
fprintf(stderr, "EGL: Failed to get a frame buffer config! (0x%x)\n", eglGetError());
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
|
||||
m_eglSurface = eglCreatePlatformWindowSurface(m_eglDisplay, eglConfig, m_native_window, nullptr);
|
||||
if (m_eglSurface == EGL_NO_SURFACE)
|
||||
{
|
||||
fprintf(stderr, "EGL: Failed to get a window surface (0x%x)\n", eglGetError());
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
|
||||
m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
|
||||
EGLint status = eglGetError();
|
||||
if (status == EGL_BAD_ATTRIBUTE || status == EGL_BAD_MATCH)
|
||||
{
|
||||
// Radeon/Gallium don't support advance attribute. Fallback to random value
|
||||
// Note: Intel gives an EGL_BAD_MATCH. I don't know why but let's by stubborn and retry.
|
||||
fprintf(stderr, "EGL: warning your driver doesn't support advance openGL context attributes\n");
|
||||
m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, NullContextAttribs);
|
||||
status = eglGetError();
|
||||
}
|
||||
if (m_eglContext == EGL_NO_CONTEXT)
|
||||
{
|
||||
fprintf(stderr, "EGL: Failed to create the context\n");
|
||||
fprintf(stderr, "EGL STATUS: %x\n", status);
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
|
||||
{
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
}
|
||||
|
||||
void GSWndEGL::AttachContext()
|
||||
{
|
||||
if (!IsContextAttached())
|
||||
{
|
||||
// The setting of the API is local to a thread. This function
|
||||
// can be called from 2 threads.
|
||||
BindAPI();
|
||||
|
||||
//fprintf(stderr, "Attach the context\n");
|
||||
eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
|
||||
m_ctx_attached = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GSWndEGL::DetachContext()
|
||||
{
|
||||
if (IsContextAttached())
|
||||
{
|
||||
//fprintf(stderr, "Detach the context\n");
|
||||
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
m_ctx_attached = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GSWndEGL::PopulateWndGlFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void GSWndEGL::BindAPI()
|
||||
{
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
EGLenum api = eglQueryAPI();
|
||||
if (api != EGL_OPENGL_API)
|
||||
{
|
||||
fprintf(stderr, "EGL: Failed to bind the OpenGL API got 0x%x instead\n", api);
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
}
|
||||
|
||||
bool GSWndEGL::Attach(const WindowInfo& wi)
|
||||
{
|
||||
m_native_window = AttachNativeWindow(wi);
|
||||
if (!m_native_window)
|
||||
return false;
|
||||
|
||||
OpenEGLDisplay();
|
||||
|
||||
FullContextInit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSWndEGL::Detach()
|
||||
{
|
||||
// Actually the destructor is not called when there is only a GSclose/GSshutdown
|
||||
// The window still need to be closed
|
||||
DetachContext();
|
||||
eglDestroyContext(m_eglDisplay, m_eglContext);
|
||||
m_eglContext = nullptr;
|
||||
|
||||
eglDestroySurface(m_eglDisplay, m_eglSurface);
|
||||
m_eglSurface = nullptr;
|
||||
|
||||
CloseEGLDisplay();
|
||||
|
||||
DestroyNativeResources();
|
||||
}
|
||||
|
||||
GSVector4i GSWndEGL::GetClientRect()
|
||||
{
|
||||
EGLint h = 0;
|
||||
EGLint w = 0;
|
||||
eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &h);
|
||||
eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &w);
|
||||
|
||||
return GSVector4i(0, 0, w, h);
|
||||
}
|
||||
|
||||
void GSWndEGL::SetSwapInterval()
|
||||
{
|
||||
// 0 -> disable vsync
|
||||
// n -> wait n frame
|
||||
eglSwapInterval(m_eglDisplay, m_vsync);
|
||||
}
|
||||
|
||||
void GSWndEGL::Flip()
|
||||
{
|
||||
if (m_vsync_change_requested.exchange(false))
|
||||
SetSwapInterval();
|
||||
|
||||
eglSwapBuffers(m_eglDisplay, m_eglSurface);
|
||||
}
|
||||
|
||||
void GSWndEGL::CloseEGLDisplay()
|
||||
{
|
||||
eglReleaseThread();
|
||||
eglTerminate(m_eglDisplay);
|
||||
}
|
||||
|
||||
void GSWndEGL::OpenEGLDisplay()
|
||||
{
|
||||
// We only need a native display when we manage the window ourself.
|
||||
// By default, EGL will create its own native display. This way the driver knows
|
||||
// that display will be thread safe and so it can enable multithread optimization.
|
||||
void* native_display = nullptr;
|
||||
m_eglDisplay = eglGetPlatformDisplay(m_platform, native_display, nullptr);
|
||||
if (m_eglDisplay == EGL_NO_DISPLAY)
|
||||
{
|
||||
fprintf(stderr, "EGL: Failed to open a display! (0x%x)\n", eglGetError());
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
|
||||
if (!eglInitialize(m_eglDisplay, nullptr, nullptr))
|
||||
{
|
||||
fprintf(stderr, "EGL: Failed to initialize the display! (0x%x)\n", eglGetError());
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// X11 platform
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#if GS_EGL_X11
|
||||
|
||||
GSWndEGL_X11::GSWndEGL_X11()
|
||||
: GSWndEGL(EGL_PLATFORM_X11_KHR), m_NativeWindow(0)
|
||||
{
|
||||
}
|
||||
|
||||
void* GSWndEGL_X11::AttachNativeWindow(const WindowInfo& wi)
|
||||
{
|
||||
if (wi.type != WindowInfo::Type::X11)
|
||||
return nullptr;
|
||||
|
||||
m_NativeWindow = reinterpret_cast<Window>(wi.window_handle);
|
||||
return &m_NativeWindow;
|
||||
}
|
||||
|
||||
void GSWndEGL_X11::DestroyNativeResources()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Wayland platform (just a place holder)
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#if GS_EGL_WL
|
||||
|
||||
GSWndEGL_WL::GSWndEGL_WL()
|
||||
: GSWndEGL(EGL_PLATFORM_WAYLAND_KHR), m_NativeWindow(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void* GSWndEGL_WL::AttachNativeWindow(const WindowInfo& wi)
|
||||
{
|
||||
if (wi.type != WindowInfo::Type::Wayland)
|
||||
return nullptr;
|
||||
|
||||
m_NativeWindow = wl_egl_window_create(static_cast<wl_surface*>(wi.window_handle),
|
||||
static_cast<int>(wi.surface_width),
|
||||
static_cast<int>(wi.surface_height));
|
||||
if (!m_NativeWindow)
|
||||
{
|
||||
std::fprintf(stderr, "Failed to create walyand EGL window\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_NativeWindow;
|
||||
}
|
||||
|
||||
void GSWndEGL_WL::DestroyNativeResources()
|
||||
{
|
||||
if (m_NativeWindow)
|
||||
{
|
||||
wl_egl_window_destroy(m_NativeWindow);
|
||||
m_NativeWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,111 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GSWnd.h"
|
||||
|
||||
#if defined(__unix__)
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#define GS_EGL_X11 1
|
||||
#define GS_EGL_WL 0
|
||||
|
||||
class GSWndEGL : public GSWndGL
|
||||
{
|
||||
void* m_native_window;
|
||||
|
||||
EGLDisplay m_eglDisplay;
|
||||
EGLSurface m_eglSurface;
|
||||
EGLContext m_eglContext;
|
||||
|
||||
int m_platform;
|
||||
|
||||
void PopulateWndGlFunction();
|
||||
void CreateContext(int major, int minor);
|
||||
void BindAPI();
|
||||
|
||||
void SetSwapInterval() final;
|
||||
bool HasLateVsyncSupport() final { return false; }
|
||||
|
||||
void OpenEGLDisplay();
|
||||
void CloseEGLDisplay();
|
||||
|
||||
public:
|
||||
GSWndEGL(int platform);
|
||||
virtual ~GSWndEGL(){};
|
||||
|
||||
static std::shared_ptr<GSWndEGL> CreateForPlatform(const WindowInfo& wi);
|
||||
|
||||
bool Attach(const WindowInfo& wi) final;
|
||||
void Detach() final;
|
||||
|
||||
virtual void* AttachNativeWindow(const WindowInfo& wi) = 0;
|
||||
virtual void DestroyNativeResources() = 0;
|
||||
|
||||
GSVector4i GetClientRect();
|
||||
|
||||
void AttachContext() final;
|
||||
void DetachContext() final;
|
||||
|
||||
void Flip() final;
|
||||
};
|
||||
|
||||
#if GS_EGL_X11
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
|
||||
class GSWndEGL_X11 final : public GSWndEGL
|
||||
{
|
||||
Window m_NativeWindow;
|
||||
|
||||
public:
|
||||
GSWndEGL_X11();
|
||||
virtual ~GSWndEGL_X11() final = default;
|
||||
|
||||
void* GetHandle() final { return reinterpret_cast<void*>(m_NativeWindow); }
|
||||
|
||||
void* AttachNativeWindow(const WindowInfo& wi) final;
|
||||
void DestroyNativeResources() final;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if GS_EGL_WL
|
||||
|
||||
// Which include ?
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-server.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland-egl.h>
|
||||
|
||||
class GSWndEGL_WL final : public GSWndEGL
|
||||
{
|
||||
wl_egl_window* m_NativeWindow;
|
||||
|
||||
public:
|
||||
GSWndEGL_WL();
|
||||
virtual ~GSWndEGL_WL() final = default;
|
||||
|
||||
void* GetHandle() final { return reinterpret_cast<void*>(m_NativeWindow); }
|
||||
|
||||
void* AttachNativeWindow(const WindowInfo& wi) final;
|
||||
void DestroyNativeResources() final;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,231 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "GSWndWGL.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static void win_error(const wchar_t* msg, bool fatal = true)
|
||||
{
|
||||
DWORD errorID = ::GetLastError();
|
||||
if (errorID)
|
||||
fprintf(stderr, "WIN API ERROR:%ld\t", errorID);
|
||||
|
||||
if (fatal)
|
||||
{
|
||||
MessageBox(NULL, msg, L"ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
throw GSRecoverableError();
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR:%ls\n", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GSWndWGL::GSWndWGL()
|
||||
: m_NativeWindow(nullptr), m_NativeDisplay(nullptr), m_context(nullptr), m_has_late_vsync(false)
|
||||
{
|
||||
}
|
||||
|
||||
void GSWndWGL::CreateContext(int major, int minor)
|
||||
{
|
||||
if (!m_NativeDisplay || !m_NativeWindow)
|
||||
{
|
||||
win_error(L"Wrong display/window", false);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ASSERT(major >= 3);
|
||||
|
||||
// GL2 context are quite easy but we need GL3 which is another painful story...
|
||||
m_context = wglCreateContext(m_NativeDisplay);
|
||||
if (!m_context)
|
||||
win_error(L"Failed to create a 2.0 context");
|
||||
|
||||
// FIXME test it
|
||||
// Note: albeit every tutorial said that we need an opengl context to use the GL function wglCreateContextAttribsARB
|
||||
// On linux it works without the extra temporary context, not sure the limitation still applied
|
||||
AttachContext();
|
||||
|
||||
if (!gladLoadWGLLoader([](const char* name) { return static_cast<void*>(wglGetProcAddress(name)); }, m_NativeDisplay))
|
||||
win_error(L"Failed to load WGL");
|
||||
|
||||
// Create a context
|
||||
int context_attribs[] =
|
||||
{
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, major,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, minor,
|
||||
// FIXME : Request a debug context to ease opengl development
|
||||
// Note: don't support deprecated feature (pre openg 3.1)
|
||||
//GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
|
||||
#ifdef ENABLE_OGL_DEBUG
|
||||
| WGL_CONTEXT_DEBUG_BIT_ARB
|
||||
#else
|
||||
| GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
|
||||
#endif
|
||||
,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
HGLRC context30 = wglCreateContextAttribsARB(m_NativeDisplay, NULL, context_attribs);
|
||||
if (!context30)
|
||||
{
|
||||
win_error(L"Failed to create a 3.x context with standard flags", false);
|
||||
// retry with more compatible option for (Mesa on Windows, OpenGL on WINE)
|
||||
context_attribs[2 * 2 + 1] = 0;
|
||||
|
||||
context30 = wglCreateContextAttribsARB(m_NativeDisplay, NULL, context_attribs);
|
||||
}
|
||||
|
||||
DetachContext();
|
||||
wglDeleteContext(m_context);
|
||||
|
||||
if (!context30)
|
||||
win_error(L"Failed to create a 3.x context with compatible flags");
|
||||
|
||||
m_context = context30;
|
||||
fprintf(stdout, "3.x GL context successfully created\n");
|
||||
}
|
||||
|
||||
void GSWndWGL::AttachContext()
|
||||
{
|
||||
if (!IsContextAttached())
|
||||
{
|
||||
wglMakeCurrent(m_NativeDisplay, m_context);
|
||||
m_ctx_attached = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GSWndWGL::DetachContext()
|
||||
{
|
||||
if (IsContextAttached())
|
||||
{
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
m_ctx_attached = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GSWndWGL::PopulateWndGlFunction()
|
||||
{
|
||||
m_has_late_vsync = GLAD_WGL_EXT_swap_control_tear;
|
||||
}
|
||||
|
||||
bool GSWndWGL::Attach(const WindowInfo& wi)
|
||||
{
|
||||
if (wi.type != WindowInfo::Type::Win32)
|
||||
return false;
|
||||
|
||||
m_NativeWindow = static_cast<HWND>(wi.window_handle);
|
||||
|
||||
OpenWGLDisplay();
|
||||
|
||||
FullContextInit();
|
||||
|
||||
UpdateWindow(m_NativeWindow);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSWndWGL::Detach()
|
||||
{
|
||||
// Actually the destructor is not called when there is only a GSclose/GSshutdown
|
||||
// The window still need to be closed
|
||||
DetachContext();
|
||||
|
||||
if (m_context)
|
||||
wglDeleteContext(m_context);
|
||||
m_context = NULL;
|
||||
|
||||
CloseWGLDisplay();
|
||||
}
|
||||
|
||||
void GSWndWGL::OpenWGLDisplay()
|
||||
{
|
||||
GLuint PixelFormat; // Holds The Results After Searching For A Match
|
||||
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
|
||||
{
|
||||
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
||||
1, // Version Number
|
||||
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
||||
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
||||
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
||||
PFD_TYPE_RGBA, // Request An RGBA Format
|
||||
32, // Select Our Color Depth
|
||||
0, 0, 0, 0, 0, 0, // Color Bits Ignored
|
||||
0, // 8bit Alpha Buffer
|
||||
0, // Shift Bit Ignored
|
||||
0, // No Accumulation Buffer
|
||||
0, 0, 0, 0, // Accumulation Bits Ignored
|
||||
0, // 24Bit Z-Buffer (Depth Buffer)
|
||||
8, // 8bit Stencil Buffer
|
||||
0, // No Auxiliary Buffer
|
||||
PFD_MAIN_PLANE, // Main Drawing Layer
|
||||
0, // Reserved
|
||||
0, 0, 0 // Layer Masks Ignored
|
||||
};
|
||||
|
||||
m_NativeDisplay = GetDC(m_NativeWindow);
|
||||
if (!m_NativeDisplay)
|
||||
win_error(L"(1) Can't Create A GL Device Context.");
|
||||
|
||||
PixelFormat = ChoosePixelFormat(m_NativeDisplay, &pfd);
|
||||
if (!PixelFormat)
|
||||
win_error(L"(2) Can't Find A Suitable PixelFormat.");
|
||||
|
||||
if (!SetPixelFormat(m_NativeDisplay, PixelFormat, &pfd))
|
||||
win_error(L"(3) Can't Set The PixelFormat.", false);
|
||||
}
|
||||
|
||||
void GSWndWGL::CloseWGLDisplay()
|
||||
{
|
||||
if (m_NativeDisplay && !ReleaseDC(m_NativeWindow, m_NativeDisplay))
|
||||
win_error(L"Release Device Context Failed.");
|
||||
|
||||
m_NativeDisplay = NULL;
|
||||
}
|
||||
|
||||
//Same as DX
|
||||
GSVector4i GSWndWGL::GetClientRect()
|
||||
{
|
||||
GSVector4i r;
|
||||
|
||||
::GetClientRect(m_NativeWindow, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//TODO: check extensions supported or not
|
||||
//FIXME : extension allocation
|
||||
void GSWndWGL::SetSwapInterval()
|
||||
{
|
||||
// m_swapinterval uses an integer as parameter
|
||||
// 0 -> disable vsync
|
||||
// n -> wait n frame
|
||||
if (GLAD_WGL_EXT_swap_control)
|
||||
wglSwapIntervalEXT(m_vsync);
|
||||
}
|
||||
|
||||
void GSWndWGL::Flip()
|
||||
{
|
||||
if (m_vsync_change_requested.exchange(false))
|
||||
SetSwapInterval();
|
||||
|
||||
SwapBuffers(m_NativeDisplay);
|
||||
}
|
||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GSWnd.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "glad_wgl.h"
|
||||
|
||||
class GSWndWGL final : public GSWndGL
|
||||
{
|
||||
HWND m_NativeWindow;
|
||||
HDC m_NativeDisplay;
|
||||
HGLRC m_context;
|
||||
bool m_has_late_vsync;
|
||||
|
||||
void PopulateWndGlFunction();
|
||||
void CreateContext(int major, int minor);
|
||||
|
||||
void CloseWGLDisplay();
|
||||
void OpenWGLDisplay();
|
||||
|
||||
void SetSwapInterval();
|
||||
bool HasLateVsyncSupport() { return m_has_late_vsync; }
|
||||
|
||||
public:
|
||||
GSWndWGL();
|
||||
~GSWndWGL() override = default;
|
||||
|
||||
bool Attach(const WindowInfo& wi) override;
|
||||
void Detach() override;
|
||||
|
||||
void* GetHandle() override { return m_NativeWindow; }
|
||||
GSVector4i GetClientRect() override;
|
||||
|
||||
void AttachContext() override;
|
||||
void DetachContext() override;
|
||||
|
||||
void Flip() override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -54,6 +54,10 @@
|
|||
#ifdef __WXGTK__
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
#include <gdk/gdkwayland.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Safe to remove these lines when this is handled properly.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "AppSaveStates.h"
|
||||
#include "Counters.h"
|
||||
#include "GS.h"
|
||||
#include "GS/GS.h"
|
||||
#include "MainFrame.h"
|
||||
#include "MSWstuff.h"
|
||||
#ifdef _WIN32
|
||||
|
@ -245,7 +246,7 @@ GSPanel::~GSPanel()
|
|||
//CoreThread.Suspend( false ); // Just in case...!
|
||||
|
||||
#ifdef WAYLAND_API
|
||||
WaylandDestroySubsurface();
|
||||
WaylandDestroySubsurface();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -265,11 +266,6 @@ std::optional<WindowInfo> GSPanel::GetWindowInfo()
|
|||
{
|
||||
WindowInfo ret;
|
||||
|
||||
const wxSize gs_vp_size(GetClientSize());
|
||||
ret.surface_scale = static_cast<float>(GetContentScaleFactor());
|
||||
ret.surface_width = static_cast<u32>(gs_vp_size.GetWidth());
|
||||
ret.surface_height = static_cast<u32>(gs_vp_size.GetHeight());
|
||||
|
||||
#if defined(_WIN32)
|
||||
ret.type = WindowInfo::Type::Win32;
|
||||
ret.window_handle = GetHandle();
|
||||
|
@ -327,6 +323,20 @@ std::optional<WindowInfo> GSPanel::GetWindowInfo()
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
const wxSize gs_vp_size(GetClientSize());
|
||||
ret.surface_scale = static_cast<float>(GetContentScaleFactor());
|
||||
ret.surface_width = static_cast<u32>(gs_vp_size.GetWidth());
|
||||
ret.surface_height = static_cast<u32>(gs_vp_size.GetHeight());
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// GTK seems to not scale coordinates?
|
||||
if (ret.type == WindowInfo::Type::X11)
|
||||
{
|
||||
ret.surface_width = static_cast<u32>(ret.surface_width * ret.surface_scale);
|
||||
ret.surface_height = static_cast<u32>(ret.surface_height * ret.surface_scale);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -334,6 +344,28 @@ void GSPanel::OnResize(wxSizeEvent& event)
|
|||
{
|
||||
if( IsBeingDeleted() ) return;
|
||||
event.Skip();
|
||||
|
||||
if (g_gs_window_info.type == WindowInfo::Type::Surfaceless)
|
||||
return;
|
||||
|
||||
const wxSize gs_vp_size(GetClientSize());
|
||||
const float scale = GetContentScaleFactor();
|
||||
int width = gs_vp_size.GetWidth();
|
||||
int height = gs_vp_size.GetHeight();
|
||||
|
||||
#ifdef __WXGTK__
|
||||
if (g_gs_window_info.type == WindowInfo::Type::X11)
|
||||
{
|
||||
width = static_cast<int>(width * scale);
|
||||
height = static_cast<int>(height * scale);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_gs_window_info.surface_width = width;
|
||||
g_gs_window_info.surface_height = height;
|
||||
g_gs_window_info.surface_scale = scale;
|
||||
|
||||
GSResizeWindow(width, height);
|
||||
}
|
||||
|
||||
void GSPanel::OnCloseWindow(wxCloseEvent& evt)
|
||||
|
@ -565,94 +597,92 @@ void GSPanel::OnLeftDclick(wxMouseEvent& evt)
|
|||
|
||||
void GSPanel::WaylandGlobalRegistryAddHandler(void* data, wl_registry* registry, uint32_t id, const char* interface, uint32_t version)
|
||||
{
|
||||
GSPanel* pnl = static_cast<GSPanel*>(data);
|
||||
if (std::strcmp(interface, wl_compositor_interface.name) == 0)
|
||||
{
|
||||
pnl->m_wl_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, id, &wl_compositor_interface, wl_compositor_interface.version));
|
||||
}
|
||||
else if (std::strcmp(interface, wl_subcompositor_interface.name) == 0)
|
||||
{
|
||||
pnl->m_wl_subcompositor = static_cast<wl_subcompositor*>(wl_registry_bind(registry, id, &wl_subcompositor_interface, wl_subcompositor_interface.version));
|
||||
}
|
||||
GSPanel* pnl = static_cast<GSPanel*>(data);
|
||||
if (std::strcmp(interface, wl_compositor_interface.name) == 0)
|
||||
{
|
||||
pnl->m_wl_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, id, &wl_compositor_interface, wl_compositor_interface.version));
|
||||
}
|
||||
else if (std::strcmp(interface, wl_subcompositor_interface.name) == 0)
|
||||
{
|
||||
pnl->m_wl_subcompositor = static_cast<wl_subcompositor*>(wl_registry_bind(registry, id, &wl_subcompositor_interface, wl_subcompositor_interface.version));
|
||||
}
|
||||
}
|
||||
|
||||
void GSPanel::WaylandGlobalRegistryRemoveHandler(void* data, wl_registry* registry, uint32_t id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool GSPanel::WaylandCreateSubsurface(wl_display* display, wl_surface* surface)
|
||||
{
|
||||
static constexpr wl_registry_listener registry_listener = {
|
||||
&GSPanel::WaylandGlobalRegistryAddHandler,
|
||||
&GSPanel::WaylandGlobalRegistryRemoveHandler
|
||||
};
|
||||
static constexpr wl_registry_listener registry_listener = {
|
||||
&GSPanel::WaylandGlobalRegistryAddHandler,
|
||||
&GSPanel::WaylandGlobalRegistryRemoveHandler};
|
||||
|
||||
wl_registry* registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||
wl_display_flush(display);
|
||||
wl_display_roundtrip(display);
|
||||
if (!m_wl_compositor || !m_wl_subcompositor)
|
||||
{
|
||||
Console.Error("Missing wl_compositor or wl_subcompositor");
|
||||
return false;
|
||||
}
|
||||
wl_registry* registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||
wl_display_flush(display);
|
||||
wl_display_roundtrip(display);
|
||||
if (!m_wl_compositor || !m_wl_subcompositor)
|
||||
{
|
||||
Console.Error("Missing wl_compositor or wl_subcompositor");
|
||||
return false;
|
||||
}
|
||||
|
||||
wl_registry_destroy(registry);
|
||||
wl_registry_destroy(registry);
|
||||
|
||||
m_wl_child_surface = wl_compositor_create_surface(m_wl_compositor);
|
||||
if (!m_wl_child_surface)
|
||||
{
|
||||
Console.Error("Failed to create compositor surface");
|
||||
return false;
|
||||
}
|
||||
m_wl_child_surface = wl_compositor_create_surface(m_wl_compositor);
|
||||
if (!m_wl_child_surface)
|
||||
{
|
||||
Console.Error("Failed to create compositor surface");
|
||||
return false;
|
||||
}
|
||||
|
||||
wl_region* input_region = wl_compositor_create_region(m_wl_compositor);
|
||||
if (!input_region)
|
||||
{
|
||||
Console.Error("Failed to create input region");
|
||||
return false;
|
||||
}
|
||||
wl_surface_set_input_region(m_wl_child_surface, input_region);
|
||||
wl_region_destroy(input_region);
|
||||
wl_region* input_region = wl_compositor_create_region(m_wl_compositor);
|
||||
if (!input_region)
|
||||
{
|
||||
Console.Error("Failed to create input region");
|
||||
return false;
|
||||
}
|
||||
wl_surface_set_input_region(m_wl_child_surface, input_region);
|
||||
wl_region_destroy(input_region);
|
||||
|
||||
m_wl_child_subsurface = wl_subcompositor_get_subsurface(m_wl_subcompositor, m_wl_child_surface, surface);
|
||||
if (!m_wl_child_subsurface)
|
||||
{
|
||||
Console.Error("Failed to create subsurface");
|
||||
return false;
|
||||
}
|
||||
m_wl_child_subsurface = wl_subcompositor_get_subsurface(m_wl_subcompositor, m_wl_child_surface, surface);
|
||||
if (!m_wl_child_subsurface)
|
||||
{
|
||||
Console.Error("Failed to create subsurface");
|
||||
return false;
|
||||
}
|
||||
|
||||
// we want to present asynchronously to the surrounding window
|
||||
wl_subsurface_set_desync(m_wl_child_subsurface);
|
||||
return true;
|
||||
// we want to present asynchronously to the surrounding window
|
||||
wl_subsurface_set_desync(m_wl_child_subsurface);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSPanel::WaylandDestroySubsurface()
|
||||
{
|
||||
if (m_wl_child_subsurface)
|
||||
{
|
||||
wl_subsurface_destroy(m_wl_child_subsurface);
|
||||
m_wl_child_subsurface = nullptr;
|
||||
}
|
||||
if (m_wl_child_subsurface)
|
||||
{
|
||||
wl_subsurface_destroy(m_wl_child_subsurface);
|
||||
m_wl_child_subsurface = nullptr;
|
||||
}
|
||||
|
||||
if (m_wl_child_surface)
|
||||
{
|
||||
wl_surface_destroy(m_wl_child_surface);
|
||||
m_wl_child_surface = nullptr;
|
||||
}
|
||||
if (m_wl_child_surface)
|
||||
{
|
||||
wl_surface_destroy(m_wl_child_surface);
|
||||
m_wl_child_surface = nullptr;
|
||||
}
|
||||
|
||||
if (m_wl_subcompositor)
|
||||
{
|
||||
wl_subcompositor_destroy(m_wl_subcompositor);
|
||||
m_wl_subcompositor = nullptr;
|
||||
}
|
||||
if (m_wl_subcompositor)
|
||||
{
|
||||
wl_subcompositor_destroy(m_wl_subcompositor);
|
||||
m_wl_subcompositor = nullptr;
|
||||
}
|
||||
|
||||
if (m_wl_compositor)
|
||||
{
|
||||
wl_compositor_destroy(m_wl_compositor);
|
||||
m_wl_compositor = nullptr;
|
||||
}
|
||||
if (m_wl_compositor)
|
||||
{
|
||||
wl_compositor_destroy(m_wl_compositor);
|
||||
m_wl_compositor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -514,12 +514,6 @@
|
|||
<ClCompile Include="GS\Renderers\Common\GSVertexList.cpp" />
|
||||
<ClCompile Include="GS\Renderers\SW\GSVertexSW.cpp" />
|
||||
<ClCompile Include="GS\Renderers\Common\GSVertexTrace.cpp" />
|
||||
<ClCompile Include="GS\Window\GSWnd.cpp" />
|
||||
<ClCompile Include="GS\Window\GSWndDX.cpp" />
|
||||
<ClCompile Include="GS\Window\GSWndEGL.cpp">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GS\Window\GSWndWGL.cpp" />
|
||||
<ClCompile Include="Utilities\FileUtils.cpp" />
|
||||
<ClCompile Include="Dump.cpp" />
|
||||
<ClCompile Include="x86\iMisc.cpp" />
|
||||
|
@ -886,10 +880,6 @@
|
|||
<ClInclude Include="GS\Renderers\Common\GSVertexList.h" />
|
||||
<ClInclude Include="GS\Renderers\SW\GSVertexSW.h" />
|
||||
<ClInclude Include="GS\Renderers\Common\GSVertexTrace.h" />
|
||||
<ClInclude Include="GS\Window\GSWnd.h" />
|
||||
<ClInclude Include="GS\Window\GSWndDX.h" />
|
||||
<ClInclude Include="GS\Window\GSWndEGL.h" />
|
||||
<ClInclude Include="GS\Window\GSWndWGL.h" />
|
||||
<ClInclude Include="GS\resource.h" />
|
||||
<ClInclude Include="IPU\IPUdma.h" />
|
||||
<ClInclude Include="Mdec.h" />
|
||||
|
|
|
@ -1628,18 +1628,6 @@
|
|||
<ClCompile Include="GS\Window\GSSettingsDlg.cpp">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GS\Window\GSWndDX.cpp">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GS\Window\GSWndEGL.cpp">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GS\Window\GSWndWGL.cpp">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GS\Window\GSWnd.cpp">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gui\wxAppWithHelpers.cpp">
|
||||
<Filter>AppHost</Filter>
|
||||
</ClCompile>
|
||||
|
@ -2730,18 +2718,6 @@
|
|||
<ClInclude Include="GS\Window\GSSettingsDlg.h">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GS\Window\GSWndDX.h">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GS\Window\GSWndEGL.h">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GS\Window\GSWndWGL.h">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GS\Window\GSWnd.h">
|
||||
<Filter>System\Ps2\GS\Window</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gui\wxAppWithHelpers.h">
|
||||
<Filter>AppHost</Filter>
|
||||
</ClInclude>
|
||||
|
|
Loading…
Reference in New Issue