The branch, properpaint, has been updated. - Log -----------------------------------------------------------------
commit d7f0e0606a7d235c19e39fe0bbc36d0e29598ff4 Author: Jean-Marc Lasgouttes <lasgout...@lyx.org> Date: Tue Oct 17 20:12:04 2017 +0200 Revert "Allow multiple calls to processUpdateFlags before redraw" The concept is good but the many bugs make it too disruptive. This reverts commit e495d7b954cabe7d44872e53daccee633330d639. diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index ec3566e..f734edb 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -60,6 +60,12 @@ cursor. * Clean-up of drawing code +The goal is to make painting with drawing disable fast enough that it +can be used after every metrics computation. Then we can separate real +drawing from metrics. + +Other changes are only clean-ups. + ** When a paragraph ends with a newline, compute correctly the height of the extra row. ** Merging bv::updateMetrics and tm::metrics @@ -70,7 +76,7 @@ insets. We should re-use the bv::updateMetrics logic: + transfer all the logic of bv::updateMetrics to tm. + Main InsetText should not be special. -The difficulty for a tall table cell for example, is that it may be +The difficuly for a tall table cell for example, is that it may be necessary to break the whole contents to know the width of the cell. @@ -107,19 +113,11 @@ DecorationUpdate). It triggers a recomputation of the metrics when either: existing metrics. Note that the Update::SinglePar flag is *never* taken into account. -If a computation of metrics has taken place, Force is removed from the -flags and ForceDraw is added instead. - -It is OK to call processUptateFlags several times before an update. In -this case, the effects are cumulative.processUpdateFlags execute the -metrics-related actions, but defers the actual drawing to the next -paint event. - The screen is drawn (with appropriate update strategy), except when update flag is Update::None. -** Metrics computation (and nodraw drawing phase) +** Metrics computation This is triggered by bv::updateMetrics, which calls tm::redoParagraph for all visible paragraphs. Some Paragraphs above or below the screen (needed @@ -129,9 +127,6 @@ tm::redoParagraph will call Inset::metrics for each inset. In the case of text insets, this will invoke recursively tm::metrics, which redoes all the paragraphs of the inset. -At the end of the function, bv::updatePosCache is called. It triggers -a repaint of the document with a NullPainter (a painter that does -nothing). This has the effect of caching all insets positions. ** Drawing the work area. diff --git a/src/BufferView.cpp b/src/BufferView.cpp index e3b8ffd..70548ed 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -228,8 +228,7 @@ enum ScreenUpdateStrategy { struct BufferView::Private { - Private(BufferView & bv) : update_strategy_(FullScreenUpdate), - update_flags_(Update::Force), + Private(BufferView & bv) : update_strategy_(NoScreenUpdate), wh_(0), cursor_(bv), anchor_pit_(0), anchor_ypos_(0), inlineCompletionUniqueChars_(0), @@ -246,8 +245,6 @@ struct BufferView::Private /// ScreenUpdateStrategy update_strategy_; /// - Update::flags update_flags_; - /// CoordCache coord_cache_; /// Estimated average par height for scrollbar. @@ -450,16 +447,16 @@ bool BufferView::needsFitCursor() const void BufferView::processUpdateFlags(Update::flags flags) { - // The update flags are reset to None after the redraw is actually done - d->update_flags_ = d->update_flags_ | flags; - // This is close to a hot-path. - LYXERR(Debug::PAINTING, "BufferView::processUpdateFlags( " - << ((d->update_flags_ & Update::FitCursor) ? "fitcursor " : "") - << ((d->update_flags_ & Update::Force) ? "forceupdate " : "") - << ((d->update_flags_ & Update::ForceDraw) ? "forcedraw " : "") - << ((d->update_flags_ & Update::SinglePar) ? "singlepar " : "") - << ") buffer: " << &buffer_); + LYXERR(Debug::PAINTING, "BufferView::processUpdateFlags()" + << "[fitcursor = " << (flags & Update::FitCursor) + << ", forceupdate = " << (flags & Update::Force) + << ", singlepar = " << (flags & Update::SinglePar) + << "] buffer: " << &buffer_); + + // FIXME Does this really need doing here? It's done in updateBuffer, and + // if the Buffer doesn't need updating, then do the macros? + buffer_.updateMacros(); // Now do the first drawing step if needed. This consists on updating // the CoordCache in updateMetrics(). @@ -467,26 +464,26 @@ void BufferView::processUpdateFlags(Update::flags flags) // FIXME: is this still true now that Buffer::changed() is used all over? // Case when no explicit update is requested. - if (!d->update_flags_) { + if (!flags) { // no need to redraw anything. d->update_strategy_ = NoScreenUpdate; return; } - if (d->update_flags_ == Update::Decoration) { + if (flags == Update::Decoration) { d->update_strategy_ = DecorationUpdate; buffer_.changed(false); return; } - if (d->update_flags_ == Update::FitCursor - || d->update_flags_ == (Update::Decoration | Update::FitCursor)) { + if (flags == Update::FitCursor + || flags == (Update::Decoration | Update::FitCursor)) { // tell the frontend to update the screen if needed. if (needsFitCursor()) { showCursor(); return; } - if (d->update_flags_ & Update::Decoration) { + if (flags & Update::Decoration) { d->update_strategy_ = DecorationUpdate; buffer_.changed(false); return; @@ -498,21 +495,22 @@ void BufferView::processUpdateFlags(Update::flags flags) return; } - // We test against the flags parameter here to honor explicit metrics requests bool const full_metrics = flags & Update::Force || !singleParUpdate(); if (full_metrics) // We have to update the full screen metrics. updateMetrics(); - if (d->update_flags_ & Update::ForceDraw) - d->update_strategy_ = FullScreenUpdate; - if (!(d->update_flags_ & Update::FitCursor)) { - // Nothing to do anymore. Trigger a redraw and return. + if (!(flags & Update::FitCursor)) { + // Nothing to do anymore. Trigger a redraw and return buffer_.changed(false); return; } + // updateMetrics() does not update paragraph position + // This is done at draw() time. So we need a redraw! + buffer_.changed(false); + if (needsFitCursor()) { // The cursor is off screen so ensure it is visible. // refresh it: @@ -520,9 +518,6 @@ void BufferView::processUpdateFlags(Update::flags flags) } updateHoveredInset(); - - // Trigger a redraw. - buffer_.changed(false); } @@ -2759,8 +2754,7 @@ void BufferView::updateMetrics() << " pit1 = " << pit1 << " pit2 = " << pit2); - // It is not necessary anymore to compute metrics, but a redraw is needed - d->update_flags_ = (d->update_flags_ & ~Update::Force) | Update::ForceDraw; + d->update_strategy_ = FullScreenUpdate; // Now update the positions of insets in the cache. updatePosCache(); @@ -3168,11 +3162,6 @@ void BufferView::draw(frontend::Painter & pain, bool paint_caret) LYXERR(Debug::PAINTING, "Found new anchor pit = " << d->anchor_pit_ << " anchor ypos = " << d->anchor_ypos_); - if (!pain.isNull()) { - // reset the update flags, everything has been done - d->update_flags_ = Update::None; - } - // Remember what has just been done for the next draw() step if (paint_caret) d->caret_slice_ = d->cursor_.top(); diff --git a/src/BufferView.h b/src/BufferView.h index 295ad95..7de6985 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -120,12 +120,11 @@ public: /// \return true if the BufferView is at the bottom of the document. bool isBottomScreen() const; - /// Add \p flags to current updte flags and trigger an update. - /* If this method is invoked several times before the update - * actually takes place, the effect is cumulative. - * \c Update::FitCursor means first to do a FitCursor, and to + /// perform pending metrics updates. + /** \c Update::FitCursor means first to do a FitCursor, and to * force an update if screen position changes. * \c Update::Force means to force an update in any case. + * \retval true if a screen redraw is needed */ void processUpdateFlags(Update::flags flags); diff --git a/src/update_flags.h b/src/update_flags.h index a40e88c..3e877c1 100644 --- a/src/update_flags.h +++ b/src/update_flags.h @@ -21,16 +21,13 @@ namespace Update { /// Recenter the screen around the cursor if is found outside the /// visible area. FitCursor = 1, - /// Force a full screen metrics update and a full draw. + /// Force a full screen metrics update. Force = 2, - /// Force a full redraw (but no metrics computations) - ForceDraw = 4, /// Try to rebreak only the current paragraph metrics. - /// (currently ignored!) - SinglePar = 8, + SinglePar = 4, /// Only the inset decorations need to be redrawn, no text metrics /// update is needed. - Decoration = 16 + Decoration = 8 }; inline flags operator|(flags const f, flags const g) @@ -43,11 +40,6 @@ inline flags operator&(flags const f, flags const g) return static_cast<flags>(int(f) & int(g)); } -inline flags operator~(flags const f) -{ - return static_cast<flags>(~int(f)); -} - } // namespace Update } // namespace lyx ----------------------------------------------------------------------- Summary of changes: development/PAINTING_ANALYSIS | 21 ++++++--------- src/BufferView.cpp | 55 ++++++++++++++++------------------------ src/BufferView.h | 7 ++--- src/update_flags.h | 14 ++-------- 4 files changed, 36 insertions(+), 61 deletions(-) hooks/post-receive -- Repository for new features