Try to reuse the same QImage and just update the content.

But it requires some magic to trigger an update (calling bits()).

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2021-01-14 16:06:25 +00:00
parent e80fee86c5
commit d250cc817e
7 changed files with 64 additions and 75 deletions

View file

@ -34,14 +34,9 @@ void Emulator::refreshScreen(const bool force)
} }
} }
bool Emulator::saveScreen(const QString & filename) const void Emulator::loadVideoSettings(QImage * screenBuffer)
{ {
return ui->video->getScreen().save(filename); ui->video->loadVideoSettings(screenBuffer);
}
void Emulator::loadVideoSettings()
{
ui->video->loadVideoSettings();
} }
void Emulator::unloadVideoSettings() void Emulator::unloadVideoSettings()
@ -49,11 +44,6 @@ void Emulator::unloadVideoSettings()
ui->video->unloadVideoSettings(); ui->video->unloadVideoSettings();
} }
void Emulator::displayLogo()
{
ui->video->displayLogo();
}
void Emulator::setVideoSize(QMdiSubWindow * window, const QSize & size) void Emulator::setVideoSize(QMdiSubWindow * window, const QSize & size)
{ {
window->showNormal(); window->showNormal();

View file

@ -4,6 +4,7 @@
#include <QFrame> #include <QFrame>
class QMdiSubWindow; class QMdiSubWindow;
class QImage;
namespace Ui { namespace Ui {
class Emulator; class Emulator;
@ -20,10 +21,8 @@ public:
void redrawScreen(); // regenerate image and repaint void redrawScreen(); // regenerate image and repaint
void refreshScreen(const bool force); void refreshScreen(const bool force);
bool saveScreen(const QString & filename) const; void loadVideoSettings(QImage * screenBuffer);
void loadVideoSettings();
void unloadVideoSettings(); void unloadVideoSettings();
void displayLogo();
void setZoom(QMdiSubWindow * window, const int x); void setZoom(QMdiSubWindow * window, const int x);
void set43AspectRatio(QMdiSubWindow * window); void set43AspectRatio(QMdiSubWindow * window);

View file

@ -524,7 +524,7 @@ void QApple::on_actionScreenshot_triggered()
} }
else else
{ {
const bool ok = myFrame->saveScreen(filename); const bool ok = myFrame->SaveScreen(filename);
if (!ok) if (!ok)
{ {
const QString message = QString::fromUtf8("Cannot save screenshot to %1").arg(filename); const QString message = QString::fromUtf8("Cannot save screenshot to %1").arg(filename);

View file

@ -4,12 +4,14 @@
#include "Core.h" #include "Core.h"
#include "Utilities.h" #include "Utilities.h"
#include "Interface.h"
#include <QMdiSubWindow> #include <QMdiSubWindow>
#include <QPainter>
QtFrame::QtFrame(Emulator * emulator, QMdiSubWindow * window) : myEmulator(emulator), myWindow(window), myForceRepaint(false) QtFrame::QtFrame(Emulator * emulator, QMdiSubWindow * window) : myEmulator(emulator), myWindow(window), myForceRepaint(false)
{ {
myLogo = QImage(":/resources/APPLEWINLOGO.BMP").mirrored(false, true);
} }
void QtFrame::SetForceRepaint(const bool force) void QtFrame::SetForceRepaint(const bool force)
@ -17,6 +19,12 @@ void QtFrame::SetForceRepaint(const bool force)
myForceRepaint = force; myForceRepaint = force;
} }
void QtFrame::DisplayLogo()
{
QPainter painter(&myFrameBuffer);
painter.drawImage(mySX, mySY, myLogo);
}
void QtFrame::VideoPresentScreen() void QtFrame::VideoPresentScreen()
{ {
myEmulator->refreshScreen(myForceRepaint); myEmulator->refreshScreen(myForceRepaint);
@ -33,10 +41,25 @@ void QtFrame::FrameRefreshStatus(int drawflags)
void QtFrame::Initialize() void QtFrame::Initialize()
{ {
LinuxFrame::Initialize(); static_assert(sizeof(bgra_t) == 4, "Invalid size of bgra_t");
Video & video = GetVideo();
mySX = video.GetFrameBufferBorderWidth();
mySY = video.GetFrameBufferBorderHeight();
mySW = video.GetFrameBufferBorderlessWidth();
mySH = video.GetFrameBufferBorderlessHeight();
const int width = video.GetFrameBufferWidth();
const int height = video.GetFrameBufferHeight();
myFrameBuffer = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
uchar * bits = myFrameBuffer.bits();
video.Initialize(bits);
FrameRefreshStatus(DRAW_TITLE); FrameRefreshStatus(DRAW_TITLE);
myEmulator->loadVideoSettings(); myEmulator->loadVideoSettings(&myFrameBuffer);
myEmulator->displayLogo(); DisplayLogo();
} }
void QtFrame::Destroy() void QtFrame::Destroy()
@ -55,7 +78,8 @@ void QtFrame::Set43Ratio()
myEmulator->set43AspectRatio(myWindow); myEmulator->set43AspectRatio(myWindow);
} }
bool QtFrame::saveScreen(const QString & filename) const bool QtFrame::SaveScreen(const QString & filename) const
{ {
return myEmulator->saveScreen(filename); QImage screen = myFrameBuffer.copy(mySX, mySY, mySW, mySH);
return screen.save(filename);
} }

View file

@ -2,8 +2,8 @@
#define QTFRAME_H #define QTFRAME_H
#include "linux/linuxframe.h" #include "linux/linuxframe.h"
#include <memory>
#include <QString> #include <QString>
#include <QImage>
class Emulator; class Emulator;
class QMdiSubWindow; class QMdiSubWindow;
@ -17,16 +17,25 @@ public:
virtual void FrameRefreshStatus(int drawflags); virtual void FrameRefreshStatus(int drawflags);
virtual void Initialize(); virtual void Initialize();
virtual void Destroy(); virtual void Destroy();
virtual void DisplayLogo();
void SetForceRepaint(const bool force); void SetForceRepaint(const bool force);
void SetZoom(const int x); void SetZoom(const int x);
void Set43Ratio(); void Set43Ratio();
bool saveScreen(const QString & filename) const;
bool SaveScreen(const QString & filename) const;
private: private:
Emulator * myEmulator; Emulator * myEmulator;
QMdiSubWindow * myWindow; QMdiSubWindow * myWindow;
bool myForceRepaint; bool myForceRepaint;
QImage myLogo;
QImage myFrameBuffer;
int mySX;
int mySY;
int mySW;
int mySH;
}; };
#endif // QTFRAME_H #endif // QTFRAME_H

View file

@ -16,22 +16,17 @@
QVideo::QVideo(QWidget *parent) : QVIDEO_BASECLASS(parent) QVideo::QVideo(QWidget *parent) : QVIDEO_BASECLASS(parent)
{ {
this->setMouseTracking(true); this->setMouseTracking(true);
myLogo = QImage(":/resources/APPLEWINLOGO.BMP").mirrored(false, true);
} }
void QVideo::loadVideoSettings() void QVideo::loadVideoSettings(QImage * screenBuffer)
{ {
myFrameBuffer = screenBuffer;
Video & video = GetVideo(); Video & video = GetVideo();
mySX = video.GetFrameBufferBorderWidth(); mySX = video.GetFrameBufferBorderWidth();
mySY = video.GetFrameBufferBorderHeight(); mySY = video.GetFrameBufferBorderHeight();
mySW = video.GetFrameBufferBorderlessWidth(); mySW = video.GetFrameBufferBorderlessWidth();
mySH = video.GetFrameBufferBorderlessHeight(); mySH = video.GetFrameBufferBorderlessHeight();
myWidth = video.GetFrameBufferWidth();
myHeight = video.GetFrameBufferHeight();
myFrameBuffer = video.GetFrameBuffer();
} }
void QVideo::unloadVideoSettings() void QVideo::unloadVideoSettings()
@ -39,31 +34,11 @@ void QVideo::unloadVideoSettings()
myFrameBuffer = nullptr; myFrameBuffer = nullptr;
} }
QImage QVideo::getScreenImage() const
{
QImage frameBuffer(myFrameBuffer, myWidth, myHeight, QImage::Format_ARGB32_Premultiplied);
return frameBuffer;
}
QImage QVideo::getScreen() const
{
QImage frameBuffer = getScreenImage();
QImage screen = frameBuffer.copy(mySX, mySY, mySW, mySH);
return screen;
}
void QVideo::displayLogo()
{
QImage frameBuffer = getScreenImage();
QPainter painter(&frameBuffer);
painter.drawImage(mySX, mySY, myLogo);
}
void QVideo::paintEvent(QPaintEvent *) void QVideo::paintEvent(QPaintEvent *)
{ {
QImage frameBuffer = getScreenImage(); if (myFrameBuffer)
{
myFrameBuffer->bits(); // triggers a refresh of the QImage
const QSize actual = size(); const QSize actual = size();
const double scaleX = double(actual.width()) / mySW; const double scaleX = double(actual.width()) / mySW;
@ -76,8 +51,8 @@ void QVideo::paintEvent(QPaintEvent *)
// scale and flip vertically // scale and flip vertically
const QTransform transform(scaleX, 0.0, 0.0, -scaleY, 0.0, actual.height()); const QTransform transform(scaleX, 0.0, 0.0, -scaleY, 0.0, actual.height());
painter.setTransform(transform); painter.setTransform(transform);
painter.drawImage(0, 0, *myFrameBuffer, mySX, mySY, mySW, mySH);
painter.drawImage(0, 0, frameBuffer, mySX, mySY, mySW, mySH); }
} }
} }

View file

@ -12,10 +12,8 @@ class QVideo : public QVIDEO_BASECLASS
public: public:
explicit QVideo(QWidget *parent = nullptr); explicit QVideo(QWidget *parent = nullptr);
QImage getScreen() const; void loadVideoSettings(QImage * screenBuffer);
void loadVideoSettings();
void unloadVideoSettings(); void unloadVideoSettings();
void displayLogo();
signals: signals:
@ -32,18 +30,12 @@ protected:
virtual void mouseReleaseEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event);
private: private:
QImage myLogo; QImage * myFrameBuffer;
int mySX; int mySX;
int mySY; int mySY;
int mySW; int mySW;
int mySH; int mySH;
int myWidth;
int myHeight;
quint8 * myFrameBuffer;
QImage getScreenImage() const;
}; };
#endif // QVIDEO_H #endif // QVIDEO_H