diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2010-09-28 13:25:37 (GMT) |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2010-09-28 14:52:52 (GMT) |
commit | 8ac7817f7a294428f4eda3c10f519e14fe9d71a0 (patch) | |
tree | 00bb41b8e907028788ccd1f3f7ae0568a3fbce07 | |
parent | 464d895c9997d35c223899165586f1d3a276f054 (diff) | |
download | Qt-8ac7817f7a294428f4eda3c10f519e14fe9d71a0.zip Qt-8ac7817f7a294428f4eda3c10f519e14fe9d71a0.tar.gz Qt-8ac7817f7a294428f4eda3c10f519e14fe9d71a0.tar.bz2 |
Fixed antialiased rasterization bug in raster engine.
When rasterization in the gray raster fails due to out of memory there
might already have been a number of spans flushed. To avoid flushing
these spans multiple times and thus getting overdraw artifacts we need
to keep track of how many spans to skip when we redo the rasterization.
This fixes the rendering error in arthur test paths_aa.qps
Reviewed-by: Yoann Lopes
-rw-r--r-- | src/gui/painting/qgrayraster.c | 38 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qrasterdefs_p.h | 1 |
3 files changed, 41 insertions, 7 deletions
diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index f348f7f..d0e25a9 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -317,6 +317,7 @@ PCell* ycells; int ycount; + int skip_spans; } TWorker, *PWorker; @@ -330,7 +331,12 @@ } TRaster, *PRaster; - + int q_gray_rendered_spans(TRaster *raster) + { + if ( raster && raster->worker ) + return raster->worker->skip_spans > 0 ? 0 : -raster->worker->skip_spans; + return 0; + } /*************************************************************************/ /* */ @@ -1178,6 +1184,7 @@ { QT_FT_Span* span; int coverage; + int skip; /* compute the coverage line's coverage, depending on the */ @@ -1228,9 +1235,16 @@ if ( ras.num_gray_spans >= QT_FT_MAX_GRAY_SPANS ) { - if ( ras.render_span ) - ras.render_span( ras.num_gray_spans, ras.gray_spans, + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; + /* ras.render_span( span->y, ras.gray_spans, count ); */ #ifdef DEBUG_GRAYS @@ -1600,7 +1614,8 @@ TBand* volatile band; int volatile n, num_bands; TPos volatile min, max, max_y; - QT_FT_BBox* clip; + QT_FT_BBox* clip; + int skip; ras.num_gray_spans = 0; @@ -1741,9 +1756,15 @@ } } - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, + ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; if ( ras.band_shoot > 8 && ras.band_size > 16 ) ras.band_size = ras.band_size / 2; @@ -1764,6 +1785,9 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + if ( raster->worker ) + raster->worker->skip_spans = params->skip_spans; + // If raster object and raster buffer are allocated, but // raster size isn't of the minimum size, indicate out of // memory. diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 09a87aa..36e1082 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4148,6 +4148,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, rasterize(outline, callback, (void *)spanData, rasterBuffer); } +extern "C" { + int q_gray_rendered_spans(QT_FT_Raster raster); +} + void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *) @@ -4212,10 +4216,13 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, bool done = false; int error; + int rendered_spans = 0; + while (!done) { rasterParams.flags |= (QT_FT_RASTER_FLAG_AA | QT_FT_RASTER_FLAG_DIRECT); rasterParams.gray_spans = callback; + rasterParams.skip_spans = rendered_spans; error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams); // Out of memory, reallocate some more and try again... @@ -4244,6 +4251,8 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, #endif Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. + rendered_spans += q_gray_rendered_spans(*grayRaster.data()); + qt_ft_grays_raster.raster_done(*grayRaster.data()); qt_ft_grays_raster.raster_new(grayRaster.data()); qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); diff --git a/src/gui/painting/qrasterdefs_p.h b/src/gui/painting/qrasterdefs_p.h index 19a0b16..4131e4b 100644 --- a/src/gui/painting/qrasterdefs_p.h +++ b/src/gui/painting/qrasterdefs_p.h @@ -1088,6 +1088,7 @@ QT_FT_BEGIN_HEADER QT_FT_Raster_BitSet_Func bit_set; /* doesn't work! */ void* user; QT_FT_BBox clip_box; + int skip_spans; } QT_FT_Raster_Params; |