Remove row crc computation

This computation did not make sense anymore since we began to put the
contents in the Row object. The fact that it worked was a coincidence.

Instead, we set rows as changed() on creation and reset that once they
have been drawn. This will allow in the future for a finer definition
of what to redraw or not.

Also update the PAINTING_ANALYSIS document
This commit is contained in:
Jean-Marc Lasgouttes 2017-11-11 12:40:39 +01:00
parent 4858bb3bb6
commit 9e2da4a3ea
6 changed files with 43 additions and 57 deletions

View File

@ -60,6 +60,42 @@ cursor.
* Clean-up of drawing code * Clean-up of drawing code
** Make SinglePar update flag useful again.
The current code can be very expensive when moving cursor inside a
huge table, for example. We should test the flag again, although this
will probably lead to some glitches here and there.
** Set Row::changed() in a finer way
*** singleParUpdate
When the height of the current paragraph changes, there is no need for
a full screen update. Only the rows after the current one need to have
their position recomputed.
This is also true when scrolling (how to do that?)
*** redoParagraph
It should be possible to check whether the new row is the same as the
old one and keep its changed() status in this case. This would reduce
a lot the amount of stuff to redraw.
** Put labels and friends in the Row as elements
It should not be necessary to access the Paragraph object to draw.
Adding the static elements to Row is a lot of work, but worth it IMO.
** Create a unique row by paragraph and break it afterwards
This should be a performance gain (only if paragraph breaking still
shows as expensive after the rest is done)
** do not add the vertical margin of main text to first/last row
Would make code cleaner. Probably no so difficult.
** When a paragraph ends with a newline, compute correctly the height of the extra row. ** When a paragraph ends with a newline, compute correctly the height of the extra row.
** Merging bv::updateMetrics and tm::metrics ** Merging bv::updateMetrics and tm::metrics

View File

@ -47,8 +47,6 @@
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/textutils.h" #include "support/textutils.h"
#include <boost/crc.hpp>
#include <algorithm> #include <algorithm>
#include <list> #include <list>
#include <stack> #include <stack>
@ -84,42 +82,6 @@ void ParagraphMetrics::reset(Paragraph const & par)
} }
size_t ParagraphMetrics::computeRowSignature(Row const & row,
BufferView const & bv) const
{
boost::crc_32_type crc;
for (pos_type i = row.pos(); i < row.endpos(); ++i) {
if (par_->isInset(i)) {
Inset const * in = par_->getInset(i);
Dimension const d = in->dimension(bv);
int const b[] = { d.wid, d.asc, d.des };
crc.process_bytes(b, sizeof(b));
} else {
char_type const b[] = { par_->getChar(i) };
crc.process_bytes(b, sizeof(char_type));
}
if (bv.buffer().params().track_changes) {
Change change = par_->lookupChange(i);
char_type const b[] = { static_cast<char_type>(change.type) };
// 1 byte is enough to encode Change::Type
crc.process_bytes(b, 1);
}
}
pos_type const b1[] = { row.sel_beg, row.sel_end };
crc.process_bytes(b1, sizeof(b1));
Dimension const & d = row.dimension();
int const b2[] = { row.begin_margin_sel,
row.end_margin_sel,
d.wid, d.asc, d.des };
crc.process_bytes(b2, sizeof(b2));
crc.process_bytes(&row.separator, sizeof(row.separator));
return crc.checksum();
}
void ParagraphMetrics::setPosition(int position) void ParagraphMetrics::setPosition(int position)
{ {
position_ = position; position_ = position;

View File

@ -85,9 +85,6 @@ public:
/// ///
bool hfillExpansion(Row const & row, pos_type pos) const; bool hfillExpansion(Row const & row, pos_type pos) const;
///
size_t computeRowSignature(Row const &, BufferView const & bv) const;
/// ///
int position() const { return position_; } int position() const { return position_; }
void setPosition(int position); void setPosition(int position);

View File

@ -162,20 +162,13 @@ Row::Row()
: separator(0), label_hfill(0), left_margin(0), right_margin(0), : separator(0), label_hfill(0), left_margin(0), right_margin(0),
sel_beg(-1), sel_end(-1), sel_beg(-1), sel_end(-1),
begin_margin_sel(false), end_margin_sel(false), begin_margin_sel(false), end_margin_sel(false),
changed_(false), crc_(0), changed_(true),
pit_(0), pos_(0), end_(0), pit_(0), pos_(0), end_(0),
right_boundary_(false), flushed_(false), rtl_(false), right_boundary_(false), flushed_(false), rtl_(false),
changebar_(false) changebar_(false)
{} {}
void Row::setCrc(size_type crc) const
{
changed_ = crc != crc_;
crc_ = crc;
}
bool Row::isMarginSelected(bool left_margin, DocIterator const & beg, bool Row::isMarginSelected(bool left_margin, DocIterator const & beg,
DocIterator const & end) const DocIterator const & end) const
{ {

View File

@ -139,9 +139,7 @@ public:
/// ///
bool changed() const { return changed_; } bool changed() const { return changed_; }
/// ///
void setChanged(bool c) { changed_ = c; } void changed(bool c) const { changed_ = c; }
///
void setCrc(size_type crc) const;
/// Set the selection begin and end. /// Set the selection begin and end.
/** /**
* This is const because we update the selection status only at draw() * This is const because we update the selection status only at draw()
@ -315,8 +313,6 @@ private:
/// has the Row appearance changed since last drawing? /// has the Row appearance changed since last drawing?
mutable bool changed_; mutable bool changed_;
/// CRC of row contents.
mutable size_type crc_;
/// Index of the paragraph that contains this row /// Index of the paragraph that contains this row
pit_type pit_; pit_type pit_;
/// first pos covered by this row /// first pos covered by this row

View File

@ -468,7 +468,7 @@ bool TextMetrics::redoParagraph(pit_type const pit)
row.pit(pit); row.pit(pit);
need_new_row = breakRow(row, right_margin); need_new_row = breakRow(row, right_margin);
setRowHeight(row); setRowHeight(row);
row.setChanged(false); row.changed(true);
if (row_index || row.endpos() < par.size() if (row_index || row.endpos() < par.size()
|| (row.right_boundary() && par.inInset().lyxCode() != CELL_CODE)) { || (row.right_boundary() && par.inInset().lyxCode() != CELL_CODE)) {
/* If there is more than one row or the row has been /* If there is more than one row or the row has been
@ -1896,8 +1896,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
row.end_margin_sel = sel_end.pit() > pit; row.end_margin_sel = sel_end.pit() > pit;
} }
// Row signature; has row changed since last paint? // has row changed since last paint?
row.setCrc(pm.computeRowSignature(row, *bv_));
bool row_has_changed = row.changed() bool row_has_changed = row.changed()
|| bv_->hadHorizScrollOffset(text_, pit, row.pos()) || bv_->hadHorizScrollOffset(text_, pit, row.pos())
|| bv_->needRepaint(text_, row); || bv_->needRepaint(text_, row);
@ -1915,6 +1914,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
// Paint only the insets if the text itself is // Paint only the insets if the text itself is
// unchanged. // unchanged.
rp.paintOnlyInsets(); rp.paintOnlyInsets();
row.changed(false);
y += row.descent(); y += row.descent();
continue; continue;
} }
@ -1966,6 +1966,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
// Restore full_repaint status. // Restore full_repaint status.
pi.full_repaint = tmp; pi.full_repaint = tmp;
row.changed(false);
} }
//LYXERR(Debug::PAINTING, "."); //LYXERR(Debug::PAINTING, ".");