mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
Reduced CPU usage for HUDs and when paused
This commit is contained in:
parent
3b72d78ec2
commit
af2afc4cf7
14 changed files with 160 additions and 59 deletions
|
@ -10,6 +10,7 @@ struct RenderSurfaceInfo
|
|||
uint32_t* Buffer = nullptr;
|
||||
uint32_t Width = 0;
|
||||
uint32_t Height = 0;
|
||||
bool IsDirty = true;
|
||||
|
||||
void UpdateSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
|
@ -25,6 +26,7 @@ struct RenderSurfaceInfo
|
|||
void Clear()
|
||||
{
|
||||
memset(Buffer, 0, Width * Height * sizeof(uint32_t));
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
~RenderSurfaceInfo()
|
||||
|
|
|
@ -25,14 +25,52 @@ void DebugHud::ClearScreen()
|
|||
_commands.clear();
|
||||
}
|
||||
|
||||
void DebugHud::Draw(uint32_t* argbBuffer, FrameInfo frameInfo, OverscanDimensions overscan, uint32_t frameNumber, bool autoScale, float forcedScale)
|
||||
bool DebugHud::Draw(uint32_t* argbBuffer, FrameInfo frameInfo, OverscanDimensions overscan, uint32_t frameNumber, bool autoScale, float forcedScale, bool clearAndUpdate)
|
||||
{
|
||||
auto lock = _commandLock.AcquireSafe();
|
||||
for(unique_ptr<DrawCommand> &command : _commands) {
|
||||
command->Draw(argbBuffer, frameInfo, overscan, frameNumber, autoScale, forcedScale);
|
||||
|
||||
bool isDirty = false;
|
||||
if(clearAndUpdate) {
|
||||
unordered_map<uint32_t, uint32_t> drawPixels;
|
||||
drawPixels.reserve(1000);
|
||||
for(unique_ptr<DrawCommand>& command : _commands) {
|
||||
command->Draw(&drawPixels, argbBuffer, frameInfo, overscan, frameNumber, autoScale, forcedScale);
|
||||
}
|
||||
|
||||
isDirty = drawPixels.size() != _drawPixels.size();
|
||||
if(!isDirty) {
|
||||
for(auto keyValue : drawPixels) {
|
||||
auto match = _drawPixels.find(keyValue.first);
|
||||
if(match != _drawPixels.end()) {
|
||||
if(keyValue.second != match->second) {
|
||||
isDirty = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
isDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isDirty) {
|
||||
memset(argbBuffer, 0, frameInfo.Height * frameInfo.Width * sizeof(uint32_t));
|
||||
for(auto keyValue : drawPixels) {
|
||||
argbBuffer[keyValue.first] = keyValue.second;
|
||||
}
|
||||
_drawPixels = drawPixels;
|
||||
}
|
||||
} else {
|
||||
isDirty = true;
|
||||
for(unique_ptr<DrawCommand>& command : _commands) {
|
||||
command->Draw(nullptr, argbBuffer, frameInfo, overscan, frameNumber, autoScale, forcedScale);
|
||||
}
|
||||
}
|
||||
|
||||
_commands.erase(std::remove_if(_commands.begin(), _commands.end(), [](const unique_ptr<DrawCommand>& c) { return c->Expired(); }), _commands.end());
|
||||
_commandCount = (uint32_t)_commands.size();
|
||||
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
void DebugHud::DrawPixel(int x, int y, int color, int frameCount, int startFrame)
|
||||
|
|
|
@ -11,6 +11,7 @@ private:
|
|||
vector<unique_ptr<DrawCommand>> _commands;
|
||||
atomic<uint32_t> _commandCount;
|
||||
SimpleLock _commandLock;
|
||||
unordered_map<uint32_t, uint32_t> _drawPixels;
|
||||
|
||||
public:
|
||||
DebugHud();
|
||||
|
@ -18,7 +19,7 @@ public:
|
|||
|
||||
bool HasCommands() { return _commandCount > 0; }
|
||||
|
||||
void Draw(uint32_t* argbBuffer, FrameInfo frameInfo, OverscanDimensions overscan, uint32_t frameNumber, bool autoScale, float forcedScale = 0);
|
||||
bool Draw(uint32_t* argbBuffer, FrameInfo frameInfo, OverscanDimensions overscan, uint32_t frameNumber, bool autoScale, float forcedScale = 0, bool clearAndUpdate = false);
|
||||
void ClearScreen();
|
||||
|
||||
void DrawPixel(int x, int y, int color, int frameCount, int startFrame = -1);
|
||||
|
|
|
@ -10,6 +10,7 @@ private:
|
|||
bool _disableAutoScale = false;
|
||||
|
||||
protected:
|
||||
unordered_map<uint32_t, uint32_t>* _drawnPixels = nullptr;
|
||||
uint32_t* _argbBuffer = nullptr;
|
||||
FrameInfo _frameInfo = {};
|
||||
OverscanDimensions _overscan = {};
|
||||
|
@ -21,16 +22,33 @@ protected:
|
|||
|
||||
__forceinline void InternalDrawPixel(int32_t offset, int color, uint32_t alpha)
|
||||
{
|
||||
if(alpha != 0xFF000000) {
|
||||
if(_argbBuffer[offset] == 0) {
|
||||
//When drawing on an empty background, premultiply channels & preserve alpha value
|
||||
//This is needed for hardware blending between the HUD and the game screen
|
||||
BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color, true);
|
||||
if(_drawnPixels) {
|
||||
//Log modified pixels
|
||||
if(alpha != 0xFF000000) {
|
||||
if(_drawnPixels->find(offset) == _drawnPixels->end()) {
|
||||
//When drawing on an empty background, premultiply channels & preserve alpha value
|
||||
//This is needed for hardware blending between the HUD and the game screen
|
||||
(*_drawnPixels)[offset] = color;
|
||||
BlendColors((uint8_t*)&(*_drawnPixels)[offset], (uint8_t*)&color, true);
|
||||
} else {
|
||||
BlendColors((uint8_t*)&(*_drawnPixels)[offset], (uint8_t*)&color);
|
||||
}
|
||||
} else {
|
||||
BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color);
|
||||
(*_drawnPixels)[offset] = color;
|
||||
}
|
||||
} else {
|
||||
_argbBuffer[offset] = color;
|
||||
//Draw pixels directly to the buffer
|
||||
if(alpha != 0xFF000000) {
|
||||
if(_argbBuffer[offset] == 0) {
|
||||
//When drawing on an empty background, premultiply channels & preserve alpha value
|
||||
//This is needed for hardware blending between the HUD and the game screen
|
||||
BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color, true);
|
||||
} else {
|
||||
BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color);
|
||||
}
|
||||
} else {
|
||||
_argbBuffer[offset] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +124,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void Draw(uint32_t* argbBuffer, FrameInfo frameInfo, OverscanDimensions &overscan, uint32_t frameNumber, bool autoScale, float forcedScale = 0)
|
||||
void Draw(unordered_map<uint32_t, uint32_t>* drawnPixels, uint32_t* argbBuffer, FrameInfo frameInfo, OverscanDimensions &overscan, uint32_t frameNumber, bool autoScale, float forcedScale = 0)
|
||||
{
|
||||
if(_startFrame < 0) {
|
||||
//When no start frame was specified, start on the next drawn frame
|
||||
|
@ -115,6 +133,7 @@ public:
|
|||
|
||||
if(_startFrame <= (int32_t)frameNumber) {
|
||||
_argbBuffer = argbBuffer;
|
||||
_drawnPixels = drawnPixels;
|
||||
_frameInfo = frameInfo;
|
||||
_overscan = overscan;
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ struct SoftwareRendererSurface
|
|||
uint32_t* Buffer = nullptr;
|
||||
uint32_t Width = 0;
|
||||
uint32_t Height = 0;
|
||||
bool IsDirty = true;
|
||||
};
|
||||
|
||||
struct SoftwareRendererFrame
|
||||
|
@ -78,9 +79,9 @@ void SoftwareRenderer::Render(RenderSurfaceInfo& emuHud, RenderSurfaceInfo& scri
|
|||
}
|
||||
|
||||
SoftwareRendererFrame frame = {
|
||||
{ _textureBuffer[1], _frameWidth, _frameHeight },
|
||||
{ emuHud.Buffer, emuHud.Width, emuHud.Height },
|
||||
{ scriptHud.Buffer, scriptHud.Width, scriptHud.Height }
|
||||
{ _textureBuffer[1], _frameWidth, _frameHeight, true },
|
||||
{ emuHud.Buffer, emuHud.Width, emuHud.Height, emuHud.IsDirty },
|
||||
{ scriptHud.Buffer, scriptHud.Width, scriptHud.Height, scriptHud.IsDirty }
|
||||
};
|
||||
|
||||
_emu->GetNotificationManager()->SendNotification(ConsoleNotificationType::RefreshSoftwareRenderer, &frame);
|
||||
|
|
|
@ -71,7 +71,7 @@ void VideoRenderer::RenderThread()
|
|||
{
|
||||
while(!_stopFlag.load()) {
|
||||
//Wait until a frame is ready, or until 32ms have passed (to allow HUD to update at ~30fps when paused)
|
||||
_waitForRender.Wait(32);
|
||||
bool forceRender = _waitForRender.Wait(32);
|
||||
if(_renderer) {
|
||||
FrameInfo size = _emu->GetVideoDecoder()->GetBaseFrameInfo(true);
|
||||
_scriptHudSurface.UpdateSize(size.Width * _scriptHudScale, size.Height * _scriptHudScale);
|
||||
|
@ -85,17 +85,19 @@ void VideoRenderer::RenderThread()
|
|||
frame = _lastFrame;
|
||||
}
|
||||
|
||||
_emuHudSurface.Clear();
|
||||
_inputHud->DrawControllers(size, frame.InputData);
|
||||
{
|
||||
auto lock = _hudLock.AcquireSafe();
|
||||
_systemHud->Draw(_rendererHud.get(), size.Width, size.Height);
|
||||
}
|
||||
_rendererHud->Draw(_emuHudSurface.Buffer, size, {}, 0, false);
|
||||
|
||||
_emuHudSurface.IsDirty = _rendererHud->Draw(_emuHudSurface.Buffer, size, {}, 0, false, 0, true);
|
||||
_scriptHudSurface.IsDirty = DrawScriptHud(frame);
|
||||
|
||||
DrawScriptHud(frame);
|
||||
|
||||
_renderer->Render(_emuHudSurface, _scriptHudSurface);
|
||||
if(forceRender || _needRedraw || _emuHudSurface.IsDirty || _scriptHudSurface.IsDirty) {
|
||||
_needRedraw = false;
|
||||
_renderer->Render(_emuHudSurface, _scriptHudSurface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,8 +118,9 @@ FrameInfo VideoRenderer::GetEmuHudSize(FrameInfo baseFrameSize)
|
|||
return size;
|
||||
}
|
||||
|
||||
void VideoRenderer::DrawScriptHud(RenderedFrame& frame)
|
||||
bool VideoRenderer::DrawScriptHud(RenderedFrame& frame)
|
||||
{
|
||||
bool needRedraw = false;
|
||||
if(_lastScriptHudFrameNumber != frame.FrameNumber) {
|
||||
//Clear+draw HUD for scripts
|
||||
//-Only when frame number changes (to prevent the HUD from disappearing when paused, etc.)
|
||||
|
@ -125,6 +128,7 @@ void VideoRenderer::DrawScriptHud(RenderedFrame& frame)
|
|||
if(_needScriptHudClear) {
|
||||
_scriptHudSurface.Clear();
|
||||
_needScriptHudClear = false;
|
||||
needRedraw = true;
|
||||
}
|
||||
|
||||
if(_emu->GetScriptHud()->HasCommands()) {
|
||||
|
@ -132,8 +136,10 @@ void VideoRenderer::DrawScriptHud(RenderedFrame& frame)
|
|||
_emu->GetScriptHud()->Draw(_scriptHudSurface.Buffer, size, overscan, frame.FrameNumber, false);
|
||||
_needScriptHudClear = true;
|
||||
_lastScriptHudFrameNumber = frame.FrameNumber;
|
||||
needRedraw = true;
|
||||
}
|
||||
}
|
||||
return needRedraw;
|
||||
}
|
||||
|
||||
std::pair<FrameInfo, OverscanDimensions> VideoRenderer::GetScriptHudSize()
|
||||
|
@ -163,6 +169,7 @@ void VideoRenderer::UpdateFrame(RenderedFrame& frame)
|
|||
|
||||
if(_renderer) {
|
||||
_renderer->UpdateFrame(frame);
|
||||
_needRedraw = true;
|
||||
_waitForRender.Signal();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ private:
|
|||
bool _needScriptHudClear = false;
|
||||
uint32_t _scriptHudScale = 2;
|
||||
uint32_t _lastScriptHudFrameNumber = 0;
|
||||
bool _needRedraw = true;
|
||||
|
||||
RenderedFrame _lastFrame;
|
||||
SimpleLock _frameLock;
|
||||
|
@ -59,7 +60,7 @@ private:
|
|||
safe_ptr<IVideoRecorder> _recorder;
|
||||
|
||||
void RenderThread();
|
||||
void DrawScriptHud(RenderedFrame& frame);
|
||||
bool DrawScriptHud(RenderedFrame& frame);
|
||||
|
||||
FrameInfo GetEmuHudSize(FrameInfo baseFrameSize);
|
||||
|
||||
|
|
|
@ -224,10 +224,14 @@ void SdlRenderer::Render(RenderSurfaceInfo& emuHud, RenderSurfaceInfo& scriptHud
|
|||
auto frameLock = _frameLock.AcquireSafe();
|
||||
if(_frameBuffer && _frameWidth == _requiredWidth && _frameHeight == _requiredHeight) {
|
||||
uint32_t* ppuFrameBuffer = _frameBuffer;
|
||||
for(uint32_t i = 0, iMax = _frameHeight; i < iMax; i++) {
|
||||
memcpy(textureBuffer, ppuFrameBuffer, _frameWidth*_bytesPerPixel);
|
||||
ppuFrameBuffer += _frameWidth;
|
||||
textureBuffer += rowPitch;
|
||||
if(rowPitch != _frameWidth) {
|
||||
for(uint32_t i = 0, iMax = _frameHeight; i < iMax; i++) {
|
||||
memcpy(textureBuffer, ppuFrameBuffer, _frameWidth*_bytesPerPixel);
|
||||
ppuFrameBuffer += _frameWidth;
|
||||
textureBuffer += rowPitch;
|
||||
}
|
||||
} else {
|
||||
memcpy(textureBuffer, ppuFrameBuffer, _frameHeight * _frameWidth * _bytesPerPixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -236,14 +240,18 @@ void SdlRenderer::Render(RenderSurfaceInfo& emuHud, RenderSurfaceInfo& scriptHud
|
|||
|
||||
SDL_UnlockTexture(_sdlTexture);
|
||||
|
||||
UpdateHudTexture(_emuHud, emuHud.Buffer);
|
||||
UpdateHudTexture(_scriptHud, scriptHud.Buffer);
|
||||
if(emuHud.IsDirty) {
|
||||
UpdateHudTexture(_emuHud, emuHud.Buffer);
|
||||
}
|
||||
if(scriptHud.IsDirty) {
|
||||
UpdateHudTexture(_scriptHud, scriptHud.Buffer);
|
||||
}
|
||||
|
||||
SDL_Rect source = {0, 0, (int)_frameWidth, (int)_frameHeight };
|
||||
SDL_Rect dest = {0, 0, (int)_screenWidth, (int)_screenHeight };
|
||||
|
||||
if(SDL_RenderCopy(_sdlRenderer, _sdlTexture, &source, &dest) != 0) {
|
||||
LogSdlError("SDL_RenderCopy failed");
|
||||
LogSdlError("SDL_RenderCopy failed");
|
||||
}
|
||||
|
||||
SDL_Rect scriptHudSource = { 0, 0, (int)_scriptHud.Width, (int)_scriptHud.Height };
|
||||
|
|
|
@ -71,8 +71,12 @@ namespace Mesen.Controls
|
|||
public unsafe void UpdateSoftwareRenderer(SoftwareRendererFrame frameInfo)
|
||||
{
|
||||
UpdateSurface(frameInfo.Frame, _model.FrameSurface, s => _model.FrameSurface = s);
|
||||
UpdateSurface(frameInfo.EmuHud, _model.EmuHudSurface, s => _model.EmuHudSurface = s);
|
||||
UpdateSurface(frameInfo.ScriptHud, _model.ScriptHudSurface, s => _model.ScriptHudSurface = s);
|
||||
if(frameInfo.EmuHud.IsDirty) {
|
||||
UpdateSurface(frameInfo.EmuHud, _model.EmuHudSurface, s => _model.EmuHudSurface = s);
|
||||
}
|
||||
if(frameInfo.ScriptHud.IsDirty) {
|
||||
UpdateSurface(frameInfo.ScriptHud, _model.ScriptHudSurface, s => _model.ScriptHudSurface = s);
|
||||
}
|
||||
|
||||
Dispatcher.UIThread.Post(() => {
|
||||
RenderOptions.SetBitmapInterpolationMode(_frame, ConfigManager.Config.Video.UseBilinearInterpolation ? BitmapInterpolationMode.LowQuality : BitmapInterpolationMode.None);
|
||||
|
|
|
@ -375,6 +375,7 @@ namespace Mesen.Interop
|
|||
public IntPtr FrameBuffer;
|
||||
public UInt32 Width;
|
||||
public UInt32 Height;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool IsDirty;
|
||||
}
|
||||
|
||||
public struct SoftwareRendererFrame
|
||||
|
|
|
@ -12,18 +12,21 @@ AutoResetEvent::~AutoResetEvent()
|
|||
//application is exiting.
|
||||
}
|
||||
|
||||
void AutoResetEvent::Wait(int timeoutDelay)
|
||||
bool AutoResetEvent::Wait(int timeoutDelay)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
bool receivedSignal = false;
|
||||
if(timeoutDelay == 0) {
|
||||
//Wait until signaled
|
||||
_signal.wait(lock, [this] { return _signaled; });
|
||||
receivedSignal = true;
|
||||
} else {
|
||||
//Wait until signaled or timeout
|
||||
auto timeoutTime = std::chrono::system_clock::now() + std::chrono::duration<int, std::milli>(timeoutDelay);
|
||||
_signal.wait_until(lock, timeoutTime, [this] { return _signaled; });
|
||||
receivedSignal = _signal.wait_until(lock, timeoutTime, [this] { return _signaled; });
|
||||
}
|
||||
_signaled = false;
|
||||
return receivedSignal;
|
||||
}
|
||||
|
||||
void AutoResetEvent::Reset()
|
||||
|
|
|
@ -16,6 +16,6 @@ public:
|
|||
~AutoResetEvent();
|
||||
|
||||
void Reset();
|
||||
void Wait(int timeoutDelay = 0);
|
||||
bool Wait(int timeoutDelay = 0);
|
||||
void Signal();
|
||||
};
|
||||
|
|
|
@ -454,10 +454,14 @@ void Renderer::DrawScreen()
|
|||
}
|
||||
uint8_t* surfacePointer = (uint8_t*)dd.pData;
|
||||
uint8_t* videoBuffer = _textureBuffer[1];
|
||||
for(uint32_t i = 0, iMax = _emuFrameHeight; i < iMax; i++) {
|
||||
memcpy(surfacePointer, videoBuffer, rowPitch);
|
||||
videoBuffer += rowPitch;
|
||||
surfacePointer += dd.RowPitch;
|
||||
if(rowPitch != dd.RowPitch) {
|
||||
for(uint32_t i = 0, iMax = _emuFrameHeight; i < iMax; i++) {
|
||||
memcpy(surfacePointer, videoBuffer, rowPitch);
|
||||
videoBuffer += rowPitch;
|
||||
surfacePointer += dd.RowPitch;
|
||||
}
|
||||
} else {
|
||||
memcpy(surfacePointer, videoBuffer, rowPitch * _emuFrameHeight);
|
||||
}
|
||||
_pDeviceContext->Unmap(_pTexture, 0);
|
||||
|
||||
|
@ -496,35 +500,47 @@ bool Renderer::CreateHudTexture(HudRenderInfo& hud, uint32_t newWidth, uint32_t
|
|||
return true;
|
||||
}
|
||||
|
||||
void Renderer::DrawHud(HudRenderInfo& hud, uint32_t* hudBuffer, uint32_t newWidth, uint32_t newHeight)
|
||||
void Renderer::DrawHud(HudRenderInfo& hud, RenderSurfaceInfo& hudSurface)
|
||||
{
|
||||
uint32_t* hudBuffer = hudSurface.Buffer;
|
||||
uint32_t newWidth = hudSurface.Width;
|
||||
uint32_t newHeight = hudSurface.Height;
|
||||
|
||||
if(newWidth == 0 && newHeight == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool needRedraw = hudSurface.IsDirty;
|
||||
if(hud.Width != newWidth || hud.Height != newHeight || !hud.Texture || !hud.Shader) {
|
||||
needRedraw = true;
|
||||
if(!CreateHudTexture(hud, newWidth, newHeight)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Copy buffer to texture
|
||||
uint32_t rowPitch = hud.Width * sizeof(uint32_t);
|
||||
D3D11_MAPPED_SUBRESOURCE dd;
|
||||
HRESULT hr = _pDeviceContext->Map(hud.Texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd);
|
||||
if(FAILED(hr)) {
|
||||
MessageManager::Log("DeviceContext::Map() failed - Error:" + std::to_string(hr));
|
||||
return;
|
||||
if(needRedraw) {
|
||||
//Copy buffer to texture
|
||||
uint32_t rowPitch = hud.Width * sizeof(uint32_t);
|
||||
D3D11_MAPPED_SUBRESOURCE dd;
|
||||
HRESULT hr = _pDeviceContext->Map(hud.Texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd);
|
||||
if(FAILED(hr)) {
|
||||
MessageManager::Log("DeviceContext::Map() failed - Error:" + std::to_string(hr));
|
||||
return;
|
||||
}
|
||||
uint8_t* surfacePointer = (uint8_t*)dd.pData;
|
||||
uint8_t* videoBuffer = (uint8_t*)hudBuffer;
|
||||
if(rowPitch != dd.RowPitch) {
|
||||
for(uint32_t i = 0, iMax = hud.Height; i < iMax; i++) {
|
||||
memcpy(surfacePointer, videoBuffer, rowPitch);
|
||||
videoBuffer += rowPitch;
|
||||
surfacePointer += dd.RowPitch;
|
||||
}
|
||||
} else {
|
||||
memcpy(surfacePointer, videoBuffer, hud.Height * rowPitch);
|
||||
}
|
||||
_pDeviceContext->Unmap(hud.Texture, 0);
|
||||
}
|
||||
uint8_t* surfacePointer = (uint8_t*)dd.pData;
|
||||
uint8_t* videoBuffer = (uint8_t*)hudBuffer;
|
||||
for(uint32_t i = 0, iMax = hud.Height; i < iMax; i++) {
|
||||
memcpy(surfacePointer, videoBuffer, rowPitch);
|
||||
videoBuffer += rowPitch;
|
||||
surfacePointer += dd.RowPitch;
|
||||
}
|
||||
_pDeviceContext->Unmap(hud.Texture, 0);
|
||||
|
||||
|
||||
RECT destRect;
|
||||
destRect.left = _leftMargin;
|
||||
destRect.top = _topMargin;
|
||||
|
@ -562,8 +578,8 @@ void Renderer::Render(RenderSurfaceInfo& emuHud, RenderSurfaceInfo& scriptHud)
|
|||
|
||||
//Draw HUD
|
||||
_spriteBatch->Begin(SpriteSortMode_Immediate, false);
|
||||
DrawHud(_scriptHud, scriptHud.Buffer, scriptHud.Width, scriptHud.Height);
|
||||
DrawHud(_emuHud, emuHud.Buffer, emuHud.Width, emuHud.Height);
|
||||
DrawHud(_scriptHud, scriptHud);
|
||||
DrawHud(_emuHud, emuHud);
|
||||
_spriteBatch->End();
|
||||
|
||||
// Present the information rendered to the back buffer to the front buffer (the screen)
|
||||
|
|
|
@ -82,7 +82,7 @@ private:
|
|||
void DrawScreen();
|
||||
|
||||
bool CreateHudTexture(HudRenderInfo& hud, uint32_t newWidth, uint32_t newHeight);
|
||||
void DrawHud(HudRenderInfo& hud, uint32_t* hudBuffer, uint32_t newWidth, uint32_t newHeight);
|
||||
void DrawHud(HudRenderInfo& hud, RenderSurfaceInfo& hudSurface);
|
||||
|
||||
HRESULT CreateRenderTargetView();
|
||||
void ReleaseRenderTargetView();
|
||||
|
|
Loading…
Add table
Reference in a new issue