16
16
#include < qwrendererinterface.h>
17
17
18
18
#include < QSGImageNode>
19
+ #include < QSGSimpleRectNode>
19
20
20
21
#define protected public
21
22
#define private public
@@ -392,7 +393,19 @@ qw_buffer *WBufferRenderer::beginRender(const QSize &pixelSize, qreal devicePixe
392
393
393
394
if (rtd->type == QQuickRenderTargetPrivate::Type::PaintDevice) {
394
395
sgRT.paintDevice = rtd->u .paintDevice ;
396
+
397
+ // // For software renderer, update the dirty parts relative to the last paint device.
398
+ PixmanRegion damage;
399
+ m_damageRing.get_buffer_damage (bufferAge, damage);
400
+ state.dirty = WTools::fromPixmanRegion (damage);
401
+
402
+ if (devicePixelRatio != 1.0 ) {
403
+ state.dirty = QTransform::fromScale (1.0 / devicePixelRatio,
404
+ 1.0 / devicePixelRatio).map (state.dirty );
405
+ }
395
406
} else {
407
+ state.dirty = QRegion ();
408
+
396
409
Q_ASSERT (rtd->type == QQuickRenderTargetPrivate::Type::RhiRenderTarget);
397
410
sgRT.rt = rtd->u .rhiRt ;
398
411
sgRT.cb = wd->redirect .commandBuffer ;
@@ -415,7 +428,6 @@ qw_buffer *WBufferRenderer::beginRender(const QSize &pixelSize, qreal devicePixe
415
428
state.pixelSize = pixelSize;
416
429
state.devicePixelRatio = devicePixelRatio;
417
430
state.bufferAge = bufferAge;
418
- state.lastRT = lastRT;
419
431
state.buffer = buffer;
420
432
state.renderTarget = rt;
421
433
state.sgRenderTarget = sgRT;
@@ -470,6 +482,23 @@ void WBufferRenderer::render(int sourceIndex, const QMatrix4x4 &renderMatrix,
470
482
auto softwareRenderer = dynamic_cast <QSGSoftwareRenderer*>(renderer);
471
483
{ // before render
472
484
if (softwareRenderer) {
485
+ // Avoid do clear before paint, for the software renderer this
486
+ // work is expensive.
487
+ if (m_clearColor.alpha () == 0 )
488
+ preserveColorContents = true ;
489
+ #if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
490
+ softwareRenderer->setClearColorEnabled (!preserveColorContents);
491
+ #else
492
+ auto bn = softwareRenderer->renderableNode (softwareRenderer->m_background );
493
+ if (bn) {
494
+ bn->m_opacity = preserveColorContents ? 0 : 1 ;
495
+ }
496
+ #endif
497
+ if (!state.dirty .isEmpty ()) {
498
+ softwareRenderer->m_dirtyRegion += state.dirty ;
499
+ state.dirty = QRegion ();
500
+ }
501
+
473
502
// because software renderer don't supports viewportRect,
474
503
// so use transform to simulation.
475
504
const auto mapTransform = inputMapToOutput (sourceRect, targetRect,
@@ -565,6 +594,8 @@ void WBufferRenderer::render(int sourceIndex, const QMatrix4x4 &renderMatrix,
565
594
// drawing result is available for use.
566
595
wd->rhi ->finish ();
567
596
} else {
597
+ state.dirty = softwareRenderer->flushRegion ();
598
+
568
599
auto currentImage = getImageFrom (state.renderTarget );
569
600
Q_ASSERT (currentImage && currentImage == softwareRenderer->m_rt .paintDevice );
570
601
currentImage->setDevicePixelRatio (1.0 );
@@ -591,28 +622,6 @@ void WBufferRenderer::render(int sourceIndex, const QMatrix4x4 &renderMatrix,
591
622
pa.fillRect (r, softwareRenderer->clearColor ());
592
623
}
593
624
}
594
-
595
- if (!damage.isEmpty () && state.lastRT .first != state.buffer && !state.lastRT .second .isNull ()) {
596
- auto image = getImageFrom (state.lastRT .second );
597
- Q_ASSERT (image);
598
- Q_ASSERT (image->size () == state.pixelSize );
599
-
600
- // TODO: Don't use the previous render target, we can get the damage region of QtQuick
601
- // before QQuickRenderControl::render for qw_damage_ring, and add dirty region to
602
- // QSGAbstractSoftwareRenderer to force repaint the damage region of current render target.
603
- QPainter pa (currentImage);
604
-
605
- PixmanRegion remainderDamage;
606
- ok = pixman_region32_subtract (remainderDamage, damage, scaledFlushDamage);
607
- Q_ASSERT (ok);
608
-
609
- int count = 0 ;
610
- auto rects = pixman_region32_rectangles (remainderDamage, &count);
611
- for (int i = 0 ; i < count; ++i) {
612
- auto r = rects[i];
613
- pa.drawImage (r.x1 , r.y1 , *image, r.x1 , r.y1 , r.x2 - r.x1 , r.y2 - r.y1 );
614
- }
615
- }
616
625
}
617
626
618
627
if (!isRootItem (source.source ))
@@ -637,6 +646,7 @@ void WBufferRenderer::endRender()
637
646
state.buffer = nullptr ;
638
647
state.renderer = nullptr ;
639
648
state.batchRenderer = nullptr ;
649
+ state.dirty = QRegion ();
640
650
641
651
m_lastBuffer = buffer;
642
652
m_damageRing.rotate ();
0 commit comments