[LyX/master] Add "full" drawing strategy

Jean-Marc Lasgouttes lasgouttes at lyx.org
Tue Jun 11 13:36:47 UTC 2024


Le 11/06/2024 à 15:17, Jean-Marc Lasgouttes a écrit :
> commit f48cf461010daa8aceb220a6762cb50c1192db0d
> Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
> Date:   Sat Jul 15 11:46:25 2023 +0200
> 
>      Add "full" drawing strategy

Riki, would it be OK to backport this change to 2.4.1? I would like to 
know whether it helps people with weird display issues.

The point is to offer a mode where the screen is redrawn fully every 
time (only the drawing, not the metrics computation). The performance 
seems quite reasonable to me, actually.

Having a proper UI for it would be great, but I am procrastinating on that.

JMarc

>      
>      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.
> ---
>   src/BufferView.cpp                  |  3 +++
>   src/LyXRC.cpp                       |  6 +++++-
>   src/LyXRC.h                         |  4 ++--
>   src/frontends/qt/GuiApplication.cpp |  9 +++++----
>   src/frontends/qt/GuiApplication.h   |  4 ++--
>   src/frontends/qt/GuiWorkArea.cpp    | 10 +++++++---
>   6 files changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/src/BufferView.cpp b/src/BufferView.cpp
> index 755e2f7b4e..4e81bcbe3f 100644
> --- a/src/BufferView.cpp
> +++ b/src/BufferView.cpp
> @@ -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;
> diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
> index 9c8decab43..edd9a58240 100644
> --- a/src/LyXRC.cpp
> +++ b/src/LyXRC.cpp
> @@ -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;
> diff --git a/src/LyXRC.h b/src/LyXRC.h
> index c437021c06..753a6f4f61 100644
> --- a/src/LyXRC.h
> +++ b/src/LyXRC.h
> @@ -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)
> diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp
> index 516c970e71..d903e85f5d 100644
> --- a/src/frontends/qt/GuiApplication.cpp
> +++ b/src/frontends/qt/GuiApplication.cpp
> @@ -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");
>   }
> diff --git a/src/frontends/qt/GuiApplication.h b/src/frontends/qt/GuiApplication.h
> index b27964dde4..67ba9590e5 100644
> --- a/src/frontends/qt/GuiApplication.h
> +++ b/src/frontends/qt/GuiApplication.h
> @@ -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
>   	//@{
> diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
> index 8b86615b4e..c136ffee14 100644
> --- a/src/frontends/qt/GuiWorkArea.cpp
> +++ b/src/frontends/qt/GuiWorkArea.cpp
> @@ -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) {



More information about the lyx-devel mailing list