Linux: Fixed black screen when loading a game with nvidia drivers
This commit is contained in:
parent
8f5354b44d
commit
ba79209bd5
2 changed files with 38 additions and 27 deletions
|
@ -5,13 +5,18 @@
|
||||||
#include "../Core/VideoDecoder.h"
|
#include "../Core/VideoDecoder.h"
|
||||||
#include "../Core/EmulationSettings.h"
|
#include "../Core/EmulationSettings.h"
|
||||||
|
|
||||||
SimpleLock SdlRenderer::_reinitLock;
|
|
||||||
SimpleLock SdlRenderer::_frameLock;
|
SimpleLock SdlRenderer::_frameLock;
|
||||||
|
|
||||||
SdlRenderer::SdlRenderer(shared_ptr<Console> console, void* windowHandle, bool registerAsMessageManager) : BaseRenderer(console, registerAsMessageManager), _windowHandle(windowHandle)
|
SdlRenderer::SdlRenderer(shared_ptr<Console> console, void* windowHandle, bool registerAsMessageManager) : BaseRenderer(console, registerAsMessageManager), _windowHandle(windowHandle)
|
||||||
{
|
{
|
||||||
_frameBuffer = nullptr;
|
_frameBuffer = nullptr;
|
||||||
SetScreenSize(256,240);
|
_requiredWidth = 256;
|
||||||
|
_requiredHeight = 240;
|
||||||
|
|
||||||
|
shared_ptr<VideoRenderer> videoRenderer = _console->GetVideoRenderer();
|
||||||
|
if(videoRenderer) {
|
||||||
|
_console->GetVideoRenderer()->RegisterRenderingDevice(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SdlRenderer::~SdlRenderer()
|
SdlRenderer::~SdlRenderer()
|
||||||
|
@ -20,7 +25,10 @@ SdlRenderer::~SdlRenderer()
|
||||||
if(videoRenderer) {
|
if(videoRenderer) {
|
||||||
videoRenderer->UnregisterRenderingDevice(this);
|
videoRenderer->UnregisterRenderingDevice(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto lock = _frameLock.AcquireSafe();
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
delete[] _frameBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlRenderer::SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight)
|
void SdlRenderer::SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight)
|
||||||
|
@ -69,7 +77,8 @@ bool SdlRenderer::Init()
|
||||||
|
|
||||||
_sdlTexture = SDL_CreateTexture(_sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, _nesFrameWidth, _nesFrameHeight);
|
_sdlTexture = SDL_CreateTexture(_sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, _nesFrameWidth, _nesFrameHeight);
|
||||||
if(!_sdlTexture) {
|
if(!_sdlTexture) {
|
||||||
log("[SDL] Failed to create texture.");
|
string msg = "[SDL] Failed to create texture: " + std::to_string(_nesFrameWidth) + "x" + std::to_string(_nesFrameHeight);
|
||||||
|
log(msg.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +87,6 @@ bool SdlRenderer::Init()
|
||||||
|
|
||||||
SDL_SetWindowSize(_sdlWindow, _screenWidth, _screenHeight);
|
SDL_SetWindowSize(_sdlWindow, _screenWidth, _screenHeight);
|
||||||
|
|
||||||
_frameBuffer = new uint32_t[_nesFrameHeight*_nesFrameWidth];
|
|
||||||
memset(_frameBuffer, 0, _nesFrameHeight*_nesFrameWidth*_bytesPerPixel);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,10 +100,6 @@ void SdlRenderer::Cleanup()
|
||||||
SDL_DestroyRenderer(_sdlRenderer);
|
SDL_DestroyRenderer(_sdlRenderer);
|
||||||
_sdlRenderer = nullptr;
|
_sdlRenderer = nullptr;
|
||||||
}
|
}
|
||||||
if(_frameBuffer) {
|
|
||||||
delete[] _frameBuffer;
|
|
||||||
_frameBuffer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlRenderer::Reset()
|
void SdlRenderer::Reset()
|
||||||
|
@ -116,8 +118,6 @@ void SdlRenderer::SetScreenSize(uint32_t width, uint32_t height)
|
||||||
_console->GetVideoDecoder()->GetScreenSize(screenSize, false);
|
_console->GetVideoDecoder()->GetScreenSize(screenSize, false);
|
||||||
|
|
||||||
if(_screenHeight != (uint32_t)screenSize.Height || _screenWidth != (uint32_t)screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _resizeFilter != _console->GetSettings()->GetVideoResizeFilter() || _vsyncEnabled != _console->GetSettings()->CheckFlag(EmulationFlags::VerticalSync)) {
|
if(_screenHeight != (uint32_t)screenSize.Height || _screenWidth != (uint32_t)screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _resizeFilter != _console->GetSettings()->GetVideoResizeFilter() || _vsyncEnabled != _console->GetSettings()->CheckFlag(EmulationFlags::VerticalSync)) {
|
||||||
_reinitLock.Acquire();
|
|
||||||
|
|
||||||
_vsyncEnabled = _console->GetSettings()->CheckFlag(EmulationFlags::VerticalSync);
|
_vsyncEnabled = _console->GetSettings()->CheckFlag(EmulationFlags::VerticalSync);
|
||||||
|
|
||||||
_nesFrameHeight = height;
|
_nesFrameHeight = height;
|
||||||
|
@ -133,14 +133,21 @@ void SdlRenderer::SetScreenSize(uint32_t width, uint32_t height)
|
||||||
_screenBufferSize = _screenHeight*_screenWidth;
|
_screenBufferSize = _screenHeight*_screenWidth;
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
_reinitLock.Release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdlRenderer::UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height)
|
void SdlRenderer::UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
SetScreenSize(width, height);
|
|
||||||
_frameLock.Acquire();
|
_frameLock.Acquire();
|
||||||
|
if(_frameBuffer == nullptr || _requiredWidth != width || _requiredHeight != height) {
|
||||||
|
_requiredWidth = width;
|
||||||
|
_requiredHeight = height;
|
||||||
|
|
||||||
|
delete[] _frameBuffer;
|
||||||
|
_frameBuffer = new uint32_t[width*height];
|
||||||
|
memset(_frameBuffer, 0, width*height*4);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(_frameBuffer, frameBuffer, width*height*_bytesPerPixel);
|
memcpy(_frameBuffer, frameBuffer, width*height*_bytesPerPixel);
|
||||||
_frameChanged = true;
|
_frameChanged = true;
|
||||||
_frameLock.Release();
|
_frameLock.Release();
|
||||||
|
@ -148,10 +155,12 @@ void SdlRenderer::UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height
|
||||||
|
|
||||||
void SdlRenderer::Render()
|
void SdlRenderer::Render()
|
||||||
{
|
{
|
||||||
|
SetScreenSize(_requiredWidth, _requiredHeight);
|
||||||
|
|
||||||
if(!_sdlRenderer || !_sdlTexture) {
|
if(!_sdlRenderer || !_sdlTexture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool paused = _console->IsPaused() && _console->IsRunning();
|
bool paused = _console->IsPaused() && _console->IsRunning();
|
||||||
bool disableOverlay = _console->GetSettings()->CheckFlag(EmulationFlags::HidePauseOverlay);
|
bool disableOverlay = _console->GetSettings()->CheckFlag(EmulationFlags::HidePauseOverlay);
|
||||||
shared_ptr<Debugger> debugger = _console->GetDebugger(false);
|
shared_ptr<Debugger> debugger = _console->GetDebugger(false);
|
||||||
|
@ -161,8 +170,6 @@ void SdlRenderer::Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_noUpdateCount > 10 || _frameChanged || paused || IsMessageShown()) {
|
if(_noUpdateCount > 10 || _frameChanged || paused || IsMessageShown()) {
|
||||||
auto lock = _reinitLock.AcquireSafe();
|
|
||||||
|
|
||||||
SDL_RenderClear(_sdlRenderer);
|
SDL_RenderClear(_sdlRenderer);
|
||||||
|
|
||||||
uint8_t *textureBuffer;
|
uint8_t *textureBuffer;
|
||||||
|
@ -170,11 +177,13 @@ void SdlRenderer::Render()
|
||||||
SDL_LockTexture(_sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch);
|
SDL_LockTexture(_sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch);
|
||||||
{
|
{
|
||||||
auto frameLock = _frameLock.AcquireSafe();
|
auto frameLock = _frameLock.AcquireSafe();
|
||||||
uint32_t* ppuFrameBuffer = _frameBuffer;
|
if(_frameBuffer && _nesFrameWidth == _requiredWidth && _nesFrameHeight == _requiredHeight) {
|
||||||
for(uint32_t i = 0, iMax = _nesFrameHeight; i < iMax; i++) {
|
uint32_t* ppuFrameBuffer = _frameBuffer;
|
||||||
memcpy(textureBuffer, ppuFrameBuffer, _nesFrameWidth*_bytesPerPixel);
|
for(uint32_t i = 0, iMax = _nesFrameHeight; i < iMax; i++) {
|
||||||
ppuFrameBuffer += _nesFrameWidth;
|
memcpy(textureBuffer, ppuFrameBuffer, _nesFrameWidth*_bytesPerPixel);
|
||||||
textureBuffer += rowPitch;
|
ppuFrameBuffer += _nesFrameWidth;
|
||||||
|
textureBuffer += rowPitch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_UnlockTexture(_sdlTexture);
|
SDL_UnlockTexture(_sdlTexture);
|
||||||
|
@ -247,4 +256,4 @@ float SdlRenderer::MeasureString(std::wstring text)
|
||||||
bool SdlRenderer::ContainsCharacter(wchar_t character)
|
bool SdlRenderer::ContainsCharacter(wchar_t character)
|
||||||
{
|
{
|
||||||
return _spriteFont->ContainsCharacter(character);
|
return _spriteFont->ContainsCharacter(character);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Console;
|
||||||
class SdlRenderer : public IRenderingDevice, public BaseRenderer
|
class SdlRenderer : public IRenderingDevice, public BaseRenderer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
void* _windowHandle;
|
void* _windowHandle = nullptr;
|
||||||
SDL_Window* _sdlWindow = nullptr;
|
SDL_Window* _sdlWindow = nullptr;
|
||||||
SDL_Renderer *_sdlRenderer = nullptr;
|
SDL_Renderer *_sdlRenderer = nullptr;
|
||||||
SDL_Texture *_sdlTexture = nullptr;
|
SDL_Texture *_sdlTexture = nullptr;
|
||||||
|
@ -36,8 +36,7 @@ private:
|
||||||
VideoResizeFilter _resizeFilter = VideoResizeFilter::NearestNeighbor;
|
VideoResizeFilter _resizeFilter = VideoResizeFilter::NearestNeighbor;
|
||||||
|
|
||||||
static SimpleLock _frameLock;
|
static SimpleLock _frameLock;
|
||||||
static SimpleLock _reinitLock;
|
uint32_t* _frameBuffer = nullptr;
|
||||||
uint32_t* _frameBuffer;
|
|
||||||
|
|
||||||
const uint32_t _bytesPerPixel = 4;
|
const uint32_t _bytesPerPixel = 4;
|
||||||
uint32_t _screenBufferSize = 0;
|
uint32_t _screenBufferSize = 0;
|
||||||
|
@ -45,6 +44,9 @@ private:
|
||||||
bool _frameChanged = true;
|
bool _frameChanged = true;
|
||||||
uint32_t _noUpdateCount = 0;
|
uint32_t _noUpdateCount = 0;
|
||||||
|
|
||||||
|
uint32_t _requiredHeight = 0;
|
||||||
|
uint32_t _requiredWidth = 0;
|
||||||
|
|
||||||
uint32_t _nesFrameHeight = 0;
|
uint32_t _nesFrameHeight = 0;
|
||||||
uint32_t _nesFrameWidth = 0;
|
uint32_t _nesFrameWidth = 0;
|
||||||
uint32_t _newFrameBufferSize = 0;
|
uint32_t _newFrameBufferSize = 0;
|
||||||
|
@ -71,4 +73,4 @@ public:
|
||||||
void DrawString(std::wstring message, int x, int y, uint8_t r = 255, uint8_t g = 255, uint8_t b = 255, uint8_t opacity = 255) override;
|
void DrawString(std::wstring message, int x, int y, uint8_t r = 255, uint8_t g = 255, uint8_t b = 255, uint8_t opacity = 255) override;
|
||||||
|
|
||||||
void SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) override;
|
void SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) override;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue