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-29 10:05:16 (GMT)
commit413ca01cc5c2f74e34ddc8d4917e65d5318aa58e (patch)
tree74a7079c3b70a77d493af1a15f784e66cdd4e929
parentd3838fdda64a09fe6fc5c9054f460ce43fdc6f95 (diff)
downloadQt-413ca01cc5c2f74e34ddc8d4917e65d5318aa58e.zip
Qt-413ca01cc5c2f74e34ddc8d4917e65d5318aa58e.tar.gz
Qt-413ca01cc5c2f74e34ddc8d4917e65d5318aa58e.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 19cef49..9356037 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;
@@ -331,7 +332,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;
+ }
/*************************************************************************/
/* */
@@ -1179,6 +1185,7 @@
{
QT_FT_Span* span;
int coverage;
+ int skip;
/* compute the coverage line's coverage, depending on the */
@@ -1229,9 +1236,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
@@ -1601,7 +1615,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;
@@ -1742,9 +1757,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;
@@ -1765,6 +1786,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 4d803c7..f6339ed 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;