backing store

This commit is contained in:
Jean-Marc Lasgouttes 2019-05-20 18:36:24 +02:00
parent 4c587fb9da
commit 1a2b1a3bfa
2 changed files with 64 additions and 47 deletions

View File

@ -235,13 +235,27 @@ SyntheticMouseEvent::SyntheticMouseEvent()
GuiWorkArea::Private::Private(GuiWorkArea * parent) GuiWorkArea::Private::Private(GuiWorkArea * parent)
: p(parent), buffer_view_(0), lyx_view_(0), : p(parent), buffer_view_(0), lyx_view_(0), caret_(0),
caret_(0), caret_visible_(false), caret_visible_(false), need_resize_(false), preedit_lines_(1),
need_resize_(false), preedit_lines_(1), last_pixel_ratio_(1.0), completer_(new GuiCompleter(p, p)),
last_pixel_ratio_(1.0), dialog_mode_(false), shell_escape_(false), read_only_(false),
completer_(new GuiCompleter(p, p)), dialog_mode_(false), shell_escape_(false), clean_(true), externally_modified_(false)
read_only_(false), clean_(true), externally_modified_(false)
{ {
/* Qt on macOS and Wayland does not respect the
* Qt::WA_OpaquePaintEvent attribute and resets the widget backing
* store at each update. Therefore, we use our own backing store in
* these two cases. */
#if QT_VERSION >= 0x050000
use_backingstore_ = guiApp->platformName() == "cocoa"
|| guiApp->platformName() == "wayland";
#else
# ifdef Q_OS_MAC
use_backingstore_ = true;
# else
use_backingstore_ = false;
# endif
#endif
int const time = QApplication::cursorFlashTime() / 2; int const time = QApplication::cursorFlashTime() / 2;
if (time > 0) { if (time > 0) {
caret_timeout_.setInterval(time); caret_timeout_.setInterval(time);
@ -1261,6 +1275,41 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
} }
void GuiWorkArea::Private::resetScreen()
{
if (use_backingstore_) {
int const pr = p->pixelRatio();
screen_ = QImage(static_cast<int>(pr * p->viewport()->width()),
static_cast<int>(pr * p->viewport()->height()),
QImage::Format_ARGB32_Premultiplied);
# if QT_VERSION >= 0x050000
screen_.setDevicePixelRatio(pr);
# endif
}
}
QPaintDevice * GuiWorkArea::Private::screenDevice()
{
if (use_backingstore_)
return &screen_;
else
return p->viewport();
}
void GuiWorkArea::Private::updateScreen(QRectF const & rc)
{
if (use_backingstore_) {
QPainter qpain(p->viewport());
double const pr = p->pixelRatio();
QRectF const rcs = QRectF(rc.x() * pr, rc.y() * pr,
rc.width() * pr, rc.height() * pr);
qpain.drawImage(rc, screen_, rcs);
}
}
void GuiWorkArea::paintEvent(QPaintEvent * ev) void GuiWorkArea::paintEvent(QPaintEvent * ev)
{ {
// Do not trigger the painting machinery if we are not ready (see // Do not trigger the painting machinery if we are not ready (see

View File

@ -20,14 +20,6 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QTimer> #include <QTimer>
#ifdef Q_OS_MAC
/* Qt on macOS does not respect the Qt::WA_OpaquePaintEvent attribute
* and resets the widget backing store at each update. Therefore, we
* use our own backing store in this case */
#define LYX_BACKINGSTORE 1
#include <QPainter>
#endif
namespace lyx { namespace lyx {
class Buffer; class Buffer;
@ -107,37 +99,12 @@ struct GuiWorkArea::Private
void paintPreeditText(GuiPainter & pain); void paintPreeditText(GuiPainter & pain);
void resetScreen() { /// Prepare screen for next painting
#ifdef LYX_BACKINGSTORE void resetScreen();
int const pr = p->pixelRatio(); /// Where painting takes place
screen_ = QImage(static_cast<int>(pr * p->viewport()->width()), QPaintDevice * screenDevice();
static_cast<int>(pr * p->viewport()->height()), /// Put backingstore to screen if necessary
QImage::Format_ARGB32_Premultiplied); void updateScreen(QRectF const & rc);
# if QT_VERSION >= 0x050000
screen_.setDevicePixelRatio(pr);
# endif
#endif
}
QPaintDevice * screenDevice() {
#ifdef LYX_BACKINGSTORE
return &screen_;
#else
return p->viewport();
#endif
}
#ifdef LYX_BACKINGSTORE
void updateScreen(QRectF const & rc) {
QPainter qpain(p->viewport());
double const pr = p->pixelRatio();
QRectF const rcs = QRectF(rc.x() * pr, rc.y() * pr,
rc.width() * pr, rc.height() * pr);
qpain.drawImage(rc, screen_, rcs);
}
#else
void updateScreen(QRectF const & ) {}
#endif
/// ///
GuiWorkArea * p; GuiWorkArea * p;
@ -146,10 +113,11 @@ struct GuiWorkArea::Private
/// ///
GuiView * lyx_view_; GuiView * lyx_view_;
#ifdef LYX_BACKINGSTORE /// Do we need an intermediate image when painting (for now macOS and Wayland)
bool use_backingstore_;
/// ///
QImage screen_; QImage screen_;
#endif
/// ///
CaretWidget * caret_; CaretWidget * caret_;
/// is the caret currently displayed /// is the caret currently displayed