summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-08-26 12:50:18 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-08-26 15:33:01 (GMT)
commit6682b9915d80238ce97594909074aef974a74279 (patch)
tree73fc6b8293df5172b6e0c2e0cee528f80fa65c85
parentca57a8122970ed408f50fed05f77d3a973676165 (diff)
downloadQt-6682b9915d80238ce97594909074aef974a74279.zip
Qt-6682b9915d80238ce97594909074aef974a74279.tar.gz
Qt-6682b9915d80238ce97594909074aef974a74279.tar.bz2
Improved QPainter API for allowing native painting in GL / VG.
Previously we were using QPaintEngine::syncState() which is not ideal naming-wise, since it actually prepares for native painting instead of syncing the painter's state to native state. Reviewed-by: Trond
-rw-r--r--dist/changes-4.6.011
-rw-r--r--examples/opengl/hellogl_es2/glwidget.cpp4
-rw-r--r--examples/openvg/star/starwidget.cpp4
-rw-r--r--src/gui/painting/qpaintengineex_p.h3
-rw-r--r--src/gui/painting/qpainter.cpp39
-rw-r--r--src/gui/painting/qpainter.h3
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp8
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h4
-rw-r--r--src/opengl/qglpixmapfilter.cpp1
-rw-r--r--src/openvg/qpaintengine_vg.cpp63
-rw-r--r--src/openvg/qpaintengine_vg_p.h3
11 files changed, 100 insertions, 43 deletions
diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0
index 8c2c2c8..194d670 100644
--- a/dist/changes-4.6.0
+++ b/dist/changes-4.6.0
@@ -49,10 +49,13 @@ information about a particular change.
this is that Nokia focuses on OpenGL for desktop hardware accelerated
rendering.
- - When mixing OpenGL and QPainter calls you need to first call syncState()
- on the paint engine, for example "painter->paintEngine()->syncState()".
- This is to ensure that the engine flushes any pending drawing and sets up
- the GL modelview/projection matrices properly.
+ - When mixing OpenGL and QPainter calls you need to surround your custom
+ OpenGL calls with QPainter::beginNativePainting() and
+ QPainter::endNativePainting().
+ This is to ensure that the paint engine flushes any pending drawing and sets
+ up the GL modelview/projection matrices properly before you can issue custom
+ OpenGL calls, and to let the paint engine synchronize to the painter state
+ before resuming regular QPainter based drawing.
- Graphics View has undergone heavy optimization work, and as a result of
this work, the following behavior changes were introduced.
diff --git a/examples/opengl/hellogl_es2/glwidget.cpp b/examples/opengl/hellogl_es2/glwidget.cpp
index 9a2a83e..50a7797 100644
--- a/examples/opengl/hellogl_es2/glwidget.cpp
+++ b/examples/opengl/hellogl_es2/glwidget.cpp
@@ -266,7 +266,7 @@ void GLWidget::paintGL()
QPainter painter;
painter.begin(this);
- painter.paintEngine()->syncState();
+ painter.beginNativePainting();
glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -302,6 +302,8 @@ void GLWidget::paintGL()
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
+ painter.endNativePainting();
+
if (m_showBubbles)
foreach (Bubble *bubble, bubbles) {
bubble->drawBubble(&painter);
diff --git a/examples/openvg/star/starwidget.cpp b/examples/openvg/star/starwidget.cpp
index 1a64fc9..ab11bdb 100644
--- a/examples/openvg/star/starwidget.cpp
+++ b/examples/openvg/star/starwidget.cpp
@@ -91,7 +91,7 @@ void StarWidget::paintEvent(QPaintEvent *)
// Flush the state changes to the OpenVG implementation
// and prepare to perform raw OpenVG calls.
- painter.paintEngine()->syncState();
+ painter.beginNativePainting();
// Cache the path if we haven't already.
if (path == VG_INVALID_HANDLE) {
@@ -109,7 +109,7 @@ void StarWidget::paintEvent(QPaintEvent *)
vgDrawPath(path, VG_FILL_PATH | VG_STROKE_PATH);
// Restore normal QPainter operations.
- painter.paintEngine()->syncState();
+ painter.endNativePainting();
painter.end();
}
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index cf3aad7..1ba2153 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -204,6 +204,9 @@ public:
virtual void sync() {}
+ virtual void beginNativePainting() {}
+ virtual void endNativePainting() {}
+
virtual QPixmapFilter *createPixmapFilter(int /*type*/) const { return 0; }
protected:
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index e1a6e80..cba4ad9 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1889,6 +1889,45 @@ QPaintEngine *QPainter::paintEngine() const
return d->engine;
}
+/*!
+ Flushes the painting pipeline and prepares for the user issuing
+ native painting commands. Must be followed by a call to
+ endNativePainting().
+
+ \sa endNativePainting()
+*/
+void QPainter::beginNativePainting()
+{
+ Q_D(QPainter);
+ if (!d->engine) {
+ qWarning("QPainter::beginNativePainting: Painter not active");
+ return;
+ }
+
+ if (d->extended)
+ d->extended->beginNativePainting();
+}
+
+/*!
+ Restores the painter after manually issuing native painting commands.
+ Lets the painter restore any native state that it relies on before
+ calling any other painter commands.
+
+ \sa beginNativePainting()
+*/
+void QPainter::endNativePainting()
+{
+ Q_D(const QPainter);
+ if (!d->engine) {
+ qWarning("QPainter::beginNativePainting: Painter not active");
+ return;
+ }
+
+ if (d->extended)
+ d->extended->endNativePainting();
+ else
+ d->engine->syncState();
+}
/*!
Returns the font metrics for the painter if the painter is
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 14d1cf8..1bb97c6 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -423,6 +423,9 @@ public:
static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = 0);
static void restoreRedirected(const QPaintDevice *device);
+ void beginNativePainting();
+ void endNativePainting();
+
#ifdef QT3_SUPPORT
inline QT3_SUPPORT void setBackgroundColor(const QColor &color) { setBackground(color); }
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 136a078..ca33101 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -675,7 +675,7 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
-void QGL2PaintEngineEx::sync()
+void QGL2PaintEngineEx::beginNativePainting()
{
Q_D(QGL2PaintEngineEx);
ensureActive();
@@ -721,6 +721,12 @@ void QGL2PaintEngineEx::sync()
d->needsSync = true;
}
+void QGL2PaintEngineEx::endNativePainting()
+{
+ Q_D(QGL2PaintEngineEx);
+ d->needsSync = true;
+}
+
const QGLContext *QGL2PaintEngineEx::context()
{
Q_D(QGL2PaintEngineEx);
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 7b734e3..2eec4d5 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -133,7 +133,9 @@ public:
inline const QOpenGL2PaintEngineState *state() const {
return static_cast<const QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
}
- virtual void sync();
+
+ void beginNativePainting();
+ void endNativePainting();
const QGLContext* context();
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index df7811e..83fddd1 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -338,7 +338,6 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const
QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
- engine->syncState();
painter->save();
// ensure GL_LINEAR filtering is used
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index d2c7b8b..09eb646 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -3072,43 +3072,42 @@ void QVGPaintEngine::setState(QPainterState *s)
}
}
-// Called from QPaintEngine::syncState() to force a state flush.
-// This should be called before and after raw VG operations.
-void QVGPaintEngine::updateState(const QPaintEngineState &state)
+void QVGPaintEngine::beginNativePainting()
{
- Q_UNUSED(state);
Q_D(QVGPaintEngine);
- if (!(d->rawVG)) {
- // About to enter raw VG mode: flush pending changes and make
- // sure that all matrices are set to the current transformation.
- QVGPainterState *s = this->state();
- d->ensurePen(s->pen);
- d->ensureBrush(s->brush);
- d->ensurePathTransform();
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, d->imageTransform);
+ // About to enter raw VG mode: flush pending changes and make
+ // sure that all matrices are set to the current transformation.
+ QVGPainterState *s = this->state();
+ d->ensurePen(s->pen);
+ d->ensureBrush(s->brush);
+ d->ensurePathTransform();
+ d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, d->imageTransform);
#if !defined(QVG_NO_DRAW_GLYPHS)
- d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform);
+ d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform);
#endif
- d->rawVG = true;
- } else {
- // Exiting raw VG mode: force all state values to be
- // explicitly set on the VG engine to undo any changes
- // that were made by the raw VG function calls.
- QPaintEngine::DirtyFlags dirty = d->dirty;
- d->clearModes();
- d->forcePenChange = true;
- d->forceBrushChange = true;
- d->penType = (VGPaintType)0;
- d->brushType = (VGPaintType)0;
- d->clearColor = QColor();
- d->fillPaint = d->brushPaint;
- restoreState(QPaintEngine::AllDirty);
- d->dirty = dirty;
- d->rawVG = false;
- vgSetPaint(d->penPaint, VG_STROKE_PATH);
- vgSetPaint(d->brushPaint, VG_FILL_PATH);
- }
+ d->rawVG = true;
+}
+
+void QVGPaintEngine::endNativePainting()
+{
+ Q_D(QVGPaintEngine);
+ // Exiting raw VG mode: force all state values to be
+ // explicitly set on the VG engine to undo any changes
+ // that were made by the raw VG function calls.
+ QPaintEngine::DirtyFlags dirty = d->dirty;
+ d->clearModes();
+ d->forcePenChange = true;
+ d->forceBrushChange = true;
+ d->penType = (VGPaintType)0;
+ d->brushType = (VGPaintType)0;
+ d->clearColor = QColor();
+ d->fillPaint = d->brushPaint;
+ restoreState(QPaintEngine::AllDirty);
+ d->dirty = dirty;
+ d->rawVG = false;
+ vgSetPaint(d->penPaint, VG_STROKE_PATH);
+ vgSetPaint(d->brushPaint, VG_FILL_PATH);
}
QPixmapFilter *QVGPaintEngine::createPixmapFilter(int type) const
diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h
index 469ec9e..f0a7838 100644
--- a/src/openvg/qpaintengine_vg_p.h
+++ b/src/openvg/qpaintengine_vg_p.h
@@ -140,7 +140,8 @@ public:
QVGPainterState *state() { return static_cast<QVGPainterState *>(QPaintEngineEx::state()); }
const QVGPainterState *state() const { return static_cast<const QVGPainterState *>(QPaintEngineEx::state()); }
- void updateState(const QPaintEngineState &state);
+ void beginNativePainting();
+ void endNativePainting();
QPixmapFilter *createPixmapFilter(int type) const;