summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2010-09-28 13:25:37 (GMT)
committerSamuel Rødal <samuel.rodal@nokia.com>2010-09-28 14:52:52 (GMT)
commit8ac7817f7a294428f4eda3c10f519e14fe9d71a0 (patch)
tree00bb41b8e907028788ccd1f3f7ae0568a3fbce07
parent464d895c9997d35c223899165586f1d3a276f054 (diff)
downloadQt-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.c38
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp9
-rw-r--r--src/gui/painting/qrasterdefs_p.h1
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;