diff --git a/pcsx2/Recording/VirtualPad/VirtualPad.cpp b/pcsx2/Recording/VirtualPad/VirtualPad.cpp index 74ec45e7bb..abb5530eac 100644 --- a/pcsx2/Recording/VirtualPad/VirtualPad.cpp +++ b/pcsx2/Recording/VirtualPad/VirtualPad.cpp @@ -200,6 +200,13 @@ void VirtualPad::Render(wxDC &dc) bdc.DrawBitmap(virtualPadData.background.image, virtualPadData.background.coords, true); clearScreenRequired = false; + // NOTE - there is yet another (and I think final) micro-optimization that can be done: + // It can be assumed that if the element has already been drawn to the screen (and not cleared) that we can skip rendering it + // + // For example - you hold a single button for several frames, it will currently draw that every frame + // despite the screen never being cleared, this is not strictly necessary. + // + // After some tests, the performance impact is well within reason, and on the hardware renderer modes, is almost non-existant. while (!renderQueue.empty()) { VirtualPadElement *element = renderQueue.front(); element->Render(bdc); diff --git a/pcsx2/Recording/VirtualPad/VirtualPad.h b/pcsx2/Recording/VirtualPad/VirtualPad.h index e67c71f5bc..c23ff0e97f 100644 --- a/pcsx2/Recording/VirtualPad/VirtualPad.h +++ b/pcsx2/Recording/VirtualPad/VirtualPad.h @@ -18,6 +18,11 @@ #include #include +#include "wx/window.h" +#include "wx/frame.h" +#include "wx/checkbox.h" +#include "Pcsx2Types.h" + #include "Recording/PadData.h" #include "Recording/VirtualPad/VirtualPadData.h" diff --git a/pcsx2/Recording/VirtualPad/VirtualPadResources.cpp b/pcsx2/Recording/VirtualPad/VirtualPadResources.cpp index fec70cb5f5..822d7526c5 100644 --- a/pcsx2/Recording/VirtualPad/VirtualPadResources.cpp +++ b/pcsx2/Recording/VirtualPad/VirtualPadResources.cpp @@ -18,31 +18,44 @@ #include #include "Recording/VirtualPad/VirtualPadResources.h" +#include "Recording/PadData.h" void ControllerNormalButton::UpdateGuiElement(std::queue *renderQueue, bool &clearScreenRequired) { ControllerNormalButton &button = *this; - if (button.renderRequired) + if (button.widgetUpdateRequired) { button.pressedBox->SetValue(button.pressed); - clearScreenRequired = true; } + if (button.pressed) { renderQueue->push(this); + } + else if (button.currentlyRendered) + { + button.currentlyRendered = false; + clearScreenRequired = true; } } void ControllerPressureButton::UpdateGuiElement(std::queue *renderQueue, bool &clearScreenRequired) { ControllerPressureButton &button = *this; - if (button.renderRequired) + if (button.widgetUpdateRequired) { button.pressureSpinner->SetValue(button.pressure); clearScreenRequired = true; } - if (button.pressed) { + + if (button.pressed) + { renderQueue->push(this); + } + else if (button.currentlyRendered) + { + button.currentlyRendered = false; + clearScreenRequired = true; } } @@ -51,23 +64,24 @@ void AnalogStick::UpdateGuiElement(std::queue *renderQueue, AnalogStick &analogStick = *this; // Update the GUI elements that need updating // If either vector has changed, we need to redraw the graphics - if (analogStick.xVector.renderRequired) + if (analogStick.xVector.widgetUpdateRequired) { analogStick.xVector.slider->SetValue(analogStick.xVector.val); analogStick.xVector.spinner->SetValue(analogStick.xVector.val); - clearScreenRequired = true; } - if (analogStick.yVector.renderRequired) + if (analogStick.yVector.widgetUpdateRequired) { analogStick.yVector.slider->SetValue(analogStick.yVector.val); analogStick.yVector.spinner->SetValue(analogStick.yVector.val); - clearScreenRequired = true; } - // TODO constant for neutral position - if (!(analogStick.xVector.val == 127 && analogStick.yVector.val == 127)) + if (!(analogStick.xVector.val == PadData::ANALOG_VECTOR_NEUTRAL && analogStick.yVector.val == PadData::ANALOG_VECTOR_NEUTRAL)) { renderQueue->push(this); - } + } + else if (analogStick.currentlyRendered) { + analogStick.currentlyRendered = false; + clearScreenRequired = true; + } } void ControllerNormalButton::Render(wxDC &dc) @@ -75,6 +89,7 @@ void ControllerNormalButton::Render(wxDC &dc) ControllerNormalButton &button = *this; ImageFile &img = button.icon; dc.DrawBitmap(img.image, img.coords, true); + button.currentlyRendered = true; } void ControllerPressureButton::Render(wxDC &dc) @@ -82,6 +97,7 @@ void ControllerPressureButton::Render(wxDC &dc) ControllerPressureButton &button = *this; ImageFile &img = button.icon; dc.DrawBitmap(img.image, img.coords, true); + button.currentlyRendered = true; } void AnalogStick::Render(wxDC &dc) @@ -105,6 +121,7 @@ void AnalogStick::Render(wxDC &dc) dc.DrawLine(analogPos.centerCoords, analogPos.endCoords); dc.DrawCircle(analogPos.endCoords, wxCoord(analogPos.lineThickness)); dc.SetPen(wxNullPen); + analogStick.currentlyRendered = true; } // TODO - duplicate code between this and the pressure button, inheritance should be able to remove it diff --git a/pcsx2/Recording/VirtualPad/VirtualPadResources.h b/pcsx2/Recording/VirtualPad/VirtualPadResources.h index 4795dafbff..3f80b669dc 100644 --- a/pcsx2/Recording/VirtualPad/VirtualPadResources.h +++ b/pcsx2/Recording/VirtualPad/VirtualPadResources.h @@ -33,7 +33,7 @@ struct AnalogVector u8 val = 127; - bool renderRequired = false; + bool widgetUpdateRequired = false; bool isControllerBypassed = false; u8 prevVal = 127; @@ -53,6 +53,8 @@ struct AnalogPosition class VirtualPadElement { public: + bool currentlyRendered = false; + virtual void UpdateGuiElement(std::queue *renderQueue, bool &clearScreenRequired) = 0; virtual void Render(wxDC &dc) = 0; };