Bug 73781

Boudewijn Rempt boud at valdyas.org
Mon Feb 9 21:55:45 CET 2004


I've been trying to speed up Krita's drawing a bit, first by implementing the 
big overlay layer idea. However, this both doesn't give much of a speedup,
and doesn't work correctly, and gives extra problems with compositing of brush 
strokes. Here's the code I've been working with:

In kis_painter.cc, I added a buffered transaction that creates a temporary,
visible layer, and blits the contents of that layer onto the target layer
when the transaction is ended::

void KisPainter::beginBufferedTransaction(const QString & customName) {
	m_dab = new KisLayer(m_device -> width(), 
			     m_device -> height(),
			     m_device -> typeWithAlpha(),
			     "temporary layer");

	m_dab -> setOpacity(OPACITY_TRANSPARENT);
	m_dab -> visible(true);
	beginTransaction(customName);
}

KCommand *KisPainter::endBufferedTransaction() 
{
	bitBlt( m_dirtyRect.x(), m_dirtyRect.y(), 
 		COMPOSITE_NORMAL, 
 		m_dab.data(), m_dirtyRect.x(), m_dirtyRect.y(), m_dirtyRect.width(), 
		m_dirtyRect.height() );
	delete m_dab;
	m_dab = 0;
	return endTransaction();
}

And a buffered paintLine and paintAt that now calls setPixel on the temporary 
layer directly:

void KisPainter::paintBufferedAt(const QPoint & pos,
				 const Q_INT32 pressure,
				 const Q_INT32 /*xTilt*/,
				 const Q_INT32 /*yTilt*/)
{
	Q_INT32 x1 = pos.x() - m_hotSpotX;
	Q_INT32 y1 = pos.y() - m_hotSpotY;
	Q_INT32 calibratedPressure = pressure / 2;

	KisAlphaMask * mask = m_brush -> mask(calibratedPressure);
	m_brushWidth = mask -> width();
	m_brushHeight = mask -> height();

	for (int y = 0; y < mask -> height(); y++) {
		for (int x = 0; x < mask -> width(); x++) {
			m_dab -> setPixel(x1 + x, y1 + y, m_paintColor, mask -> alphaAt(x, y));
		}
	}

	m_dirtyRect = QRect(x1,
			    y1,
			    m_brushWidth,
			    m_brushHeight);
}

In the paint tool, kis_tool_brush.cc, I call these methods just like I did 
with the unbuffered methods before, e.g:

void KisToolBrush::mousePress(QMouseEvent *e)
{
        if (!m_subject) return;

        if (!m_subject->currentBrush()) return;

        if (e->button() == QMouseEvent::LeftButton) {
		m_mode = PAINT;
		initPaint(e -> pos());
		m_painter -> paintBufferedAt(e->pos(), 128, 0, 0);
		// XXX: get the rect that should be notified
		m_currentImage -> notify( m_painter -> dirtyRect() );
         }
}

void KisToolBrush::initPaint(const QPoint & pos)
{
	m_dragStart = pos;
	m_dragDist = 0;

	// Create painter
	KisPaintDeviceSP device;
	if (m_currentImage && (device = m_currentImage -> activeDevice())) {
		if (m_painter)
			delete m_painter;
		m_painter = new KisPainter( device );
		m_painter -> beginBufferedTransaction(i18n("brush"));
	}

	m_painter -> setPaintColor(m_subject -> fgColor());
	m_painter -> setBrush(m_subject -> currentBrush());
}

void KisToolBrush::endPaint() 
{
	m_mode = HOVER;
	KisPaintDeviceSP device;
	if (m_currentImage && (device = m_currentImage -> activeDevice())) {
		KisUndoAdapter *adapter = m_currentImage -> undoAdapter();
		if (adapter && m_painter) {
			// If painting in mouse release, make sure painter
			// is destructed or end()ed
			adapter -> addCommand(m_painter->endBufferedTransaction());
		}
		delete m_painter;
		m_painter = 0;

	}
}
void KisToolBrush::mouseRelease(QMouseEvent* e)
{
	if (e->button() == QMouseEvent::LeftButton && m_mode == PAINT) {
		endPaint();
        }
}


void KisToolBrush::mouseMove(QMouseEvent *e)
{
	if (m_mode == PAINT) {
		paintLine(m_dragStart, e -> pos(), 128, 0, 0);
	}
}


void KisToolBrush::paintLine(const QPoint & pos1,
			     const QPoint & pos2,
			     const Q_INT32 pressure,
			     const Q_INT32 xtilt,
			     const Q_INT32 ytilt)
{

	m_dragDist = m_painter -> paintBufferedLine(pos1, pos2, pressure, xtilt, 
ytilt, m_dragDist);
	m_currentImage -> notify();// m_painter -> dirtyRect() );
	m_dragStart = pos2;
}


However, I don't see anything appearing on screen unless I move the layer 
about a bit, which means that there's something wrong with updating the 
display -- and I get corrupted tiles here and there, and besides, the circles
are hardly any better...

So, unless someone else has a bright idea, I'll call it a day for this idea, 
and will go back to the small dabs.
-- 
Boudewijn Rempt | http://www.valdyas.org/fading/index.cgi


More information about the kimageshop mailing list