diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-08-26 12:50:18 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-08-26 15:33:01 (GMT) |
commit | 6682b9915d80238ce97594909074aef974a74279 (patch) | |
tree | 73fc6b8293df5172b6e0c2e0cee528f80fa65c85 | |
parent | ca57a8122970ed408f50fed05f77d3a973676165 (diff) | |
download | Qt-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.0 | 11 | ||||
-rw-r--r-- | examples/opengl/hellogl_es2/glwidget.cpp | 4 | ||||
-rw-r--r-- | examples/openvg/star/starwidget.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex_p.h | 3 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 39 | ||||
-rw-r--r-- | src/gui/painting/qpainter.h | 3 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 8 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 4 | ||||
-rw-r--r-- | src/opengl/qglpixmapfilter.cpp | 1 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 63 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg_p.h | 3 |
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; |