Add "full" drawing strategy

With this patch, 3 draw strategies (set in prefs with
\draw_strategy partial|backingstore|full) are available:

- "partial": only draw the parts of text that have changed since last
  paint event (default for X11 and windows)

- "backingstore": the same, but drawing happens on an offspring
  pixmap; this breaks subpixel rendering (default for Wayland and
  macOS)

- "full": the screen is fully redrawn at each paint event and should
  therefore always be correct; this is presumably slower but
  introducing it will allow to test it.

This would deserve a proper UI eventually.
This commit is contained in:
Jean-Marc Lasgouttes 2023-07-15 11:46:25 +02:00
parent 9ace073cc5
commit f48cf46101
6 changed files with 24 additions and 12 deletions

View File

@ -592,6 +592,9 @@ void BufferView::processUpdateFlags(Update::flags flags)
flags = (flags & ~Update::FitCursor) | Update::ForceDraw;
}
if (lyxrc.draw_strategy == LyXRC::DS_FULL)
flags = flags | Update::ForceDraw;
// Add flags to the the update flags. These will be reset to None
// after the redraw is actually done
d->update_flags_ = d->update_flags_ | flags;

View File

@ -1147,8 +1147,9 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
draw_strategy = DS_PARTIAL;
else if (tmp == "backingstore")
draw_strategy = DS_BACKINGSTORE;
else if (tmp == "full")
draw_strategy = DS_FULL;
else {
draw_strategy = DS_PARTIAL;
LYXERR0("Unrecognized draw strategy " << tmp <<'"');
}
}
@ -2055,6 +2056,9 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
draw_strategy != system_lyxrc.draw_strategy) {
string status;
switch (draw_strategy) {
case DS_FULL:
status = "full";
break;
case DS_PARTIAL:
status = "partial";
break;

View File

@ -580,8 +580,8 @@ public:
BookmarksVisibility bookmarks_visibility = BMK_NONE;
enum DrawStrategy {
// draw all (not implemented yet)
// FS_FULL,
// draw all
DS_FULL,
// draw only what has changed
DS_PARTIAL,
// draw in backing store (only what has changed)

View File

@ -2730,13 +2730,14 @@ Menus & GuiApplication::menus()
}
bool GuiApplication::needsBackingStore() const
bool GuiApplication::noPartialDraw() const
{
/* 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. It is also possible to force the use of the
* backing store for cases like x11 with transparent WM themes.
* store at each update. Therefore, if it not good to use
* "partial" draw strategy in these cases. It is also possible to
* force the use of the backing store for cases like x11 with
* transparent WM themes.
*/
return platformName() == "cocoa" || platformName().contains("wayland");
}

View File

@ -113,8 +113,8 @@ public:
///
Menus & menus();
/// \returns true if painting the workarea requires a backing store.
bool needsBackingStore() const;
/// \returns true the "partial" draw strategy is known to be broken
bool noPartialDraw() const;
/// \name Methods inherited from QApplication class
//@{

View File

@ -131,9 +131,13 @@ GuiWorkArea::Private::Private(GuiWorkArea * parent)
: p(parent), completer_(new GuiCompleter(p, p))
{
use_backingstore_ = lyxrc.draw_strategy == LyXRC::DS_BACKINGSTORE
|| guiApp->needsBackingStore();
LYXERR(Debug::WORKAREA, "Drawing strategy is: "
<< (use_backingstore_ ? "backingstore" : "partial"));
|| (lyxrc.draw_strategy == LyXRC::DS_PARTIAL && guiApp->noPartialDraw());
if (use_backingstore_)
LYXERR(Debug::WORKAREA, "Drawing strategy: partial draw on backing store");
else
LYXERR(Debug::WORKAREA, "Drawing strategy: "
<< (lyxrc.draw_strategy == LyXRC::DS_PARTIAL ? "partial draw"
: "full draw"));
int const time = QApplication::cursorFlashTime() / 2;
if (time > 0) {