diff options
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 47 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 3 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 6 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 43 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl_p.h | 7 |
5 files changed, 86 insertions, 20 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index fe70020f03..8bf31824bb 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -805,6 +805,7 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->setBrush(&brush); d->fill(path); d->setBrush(&(state()->brush)); // reset back to the state's brush @@ -814,6 +815,7 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QGL2PaintEngineEx); + ensureActive(); if (pen.style() == Qt::NoPen) return; @@ -832,7 +834,6 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) d->setBrush(&(state()->brush)); } else return QPaintEngineEx::stroke(path, pen); - } void QGL2PaintEngineEx::penChanged() @@ -887,6 +888,7 @@ void QGL2PaintEngineEx::transformChanged() void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; @@ -905,6 +907,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const Qt::ImageConversionFlags) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; @@ -921,6 +924,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) { Q_D(QGL2PaintEngineEx); + ensureActive(); QOpenGLPaintEngineState *s = state(); const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); @@ -974,6 +978,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte const QImage &image = cache->image(); int margin = cache->glyphMargin(); + if (image.isNull()) + return; + ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); @@ -1085,6 +1092,16 @@ bool QGL2PaintEngineEx::end() { Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; + if (ctx->d_ptr->active_engine != this) { + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(d->last_engine); + if (engine) { + QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr); + p->transferMode(DefaultMode); + p->drawable.doneCurrent(); + } + d->drawable.makeCurrent(); + } + glUseProgram(0); d->transferMode(DefaultMode); d->drawable.swapBuffers(); @@ -1106,6 +1123,31 @@ bool QGL2PaintEngineEx::end() return false; } +void QGL2PaintEngineEx::ensureActive() +{ + Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + + if (isActive() && ctx->d_ptr->active_engine != this) { + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine); + if (engine) { + QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr); + p->transferMode(DefaultMode); + p->drawable.doneCurrent(); + } + d->drawable.makeCurrent(); + + ctx->d_ptr->active_engine = this; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + + glViewport(0, 0, d->width, d->height); + setState(state()); + d->updateDepthClip(); + } +} + /////////////////////////////////// State/Clipping stolen from QOpenGLPaintEngine ////////////////////////////////////////// @@ -1246,6 +1288,7 @@ void QGL2PaintEngineExPrivate::updateDepthClip() Q_Q(QGL2PaintEngineEx); + q->ensureActive(); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); @@ -1305,7 +1348,7 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) QOpenGLPaintEngineState *old_state = state(); const bool needsDepthClipUpdate = !old_state || s->clipEnabled != old_state->clipEnabled - || s->clipEnabled && s->clipRegion != old_state->clipRegion; + || (s->clipEnabled && s->clipRegion != old_state->clipRegion); QPaintEngineEx::setState(s); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 10e5337439..b31f68538f 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -80,6 +80,8 @@ public: bool begin(QPaintDevice *device); bool end(); + void ensureActive(); + virtual void fill(const QVectorPath &path, const QBrush &brush); virtual void stroke(const QVectorPath &path, const QPen &pen); virtual void clip(const QVectorPath &path, Qt::ClipOperation op); @@ -102,7 +104,6 @@ public: Type type() const { return OpenGL; } - // State stuff is just for clipping and ripped off from QGLPaintEngine void setState(QPainterState *s); QPainterState *createState(QPainterState *orig) const; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 64048f29e2..d1cf35d862 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4289,6 +4289,8 @@ void QGLDrawable::swapBuffers() if (widget) { if (widget->autoBufferSwap()) widget->swapBuffers(); + } else if (pixmapData) { + pixmapData->swapBuffers(); } else { glFlush(); } @@ -4297,7 +4299,7 @@ void QGLDrawable::swapBuffers() void QGLDrawable::makeCurrent() { if (pixmapData) - pixmapData->beginPaint(); + pixmapData->makeCurrent(); else if (widget) widget->makeCurrent(); else if (buffer) @@ -4321,7 +4323,7 @@ QGLPixmapData *QGLDrawable::copyOnBegin() const void QGLDrawable::doneCurrent() { if (pixmapData) - pixmapData->endPaint(); + pixmapData->doneCurrent(); else if (fbo && !wasBound) fbo->release(); } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 0656880c95..1c5056d41f 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -246,13 +246,13 @@ QImage QGLPixmapData::toImage() const return QImage(); if (m_renderFbo) - return m_renderFbo->toImage().copy(0, m_renderFbo->height() - m_height, m_width, m_height); + copyBackFromRenderFbo(true); else if (!m_source.isNull()) return m_source; else if (m_dirty) return QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); - - ensureCreated(); + else + ensureCreated(); QGLShareContextScope ctx(qt_gl_share_widget()->context()); extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); @@ -269,15 +269,7 @@ struct TextureBuffer static QVector<TextureBuffer> textureBufferStack; static int currentTextureBuffer = 0; -void QGLPixmapData::beginPaint() -{ - if (!isValid()) - return; - - m_renderFbo->bind(); -} - -void QGLPixmapData::endPaint() +void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const { if (!isValid()) return; @@ -308,6 +300,16 @@ void QGLPixmapData::endPaint() GL_COLOR_BUFFER_BIT, GL_NEAREST); + if (keepCurrentFboBound) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ctx->d_ptr->current_fbo); +} + +void QGLPixmapData::swapBuffers() +{ + if (!isValid()) + return; + + copyBackFromRenderFbo(false); m_renderFbo->release(); --currentTextureBuffer; @@ -316,6 +318,18 @@ void QGLPixmapData::endPaint() m_engine = 0; } +void QGLPixmapData::makeCurrent() +{ + if (isValid() && m_renderFbo) + m_renderFbo->bind(); +} + +void QGLPixmapData::doneCurrent() +{ + if (isValid() && m_renderFbo) + m_renderFbo->release(); +} + static TextureBuffer createTextureBuffer(const QSize &size, QGL2PaintEngineEx *engine = 0) { TextureBuffer buffer; @@ -382,7 +396,10 @@ QPaintEngine* QGLPixmapData::paintEngine() const GLuint QGLPixmapData::bind() const { - ensureCreated(); + if (m_renderFbo) + copyBackFromRenderFbo(true); + else + ensureCreated(); GLuint id = m_textureId; glBindTexture(qt_gl_preferredTextureTarget(), id); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index b1b31f7029..7dda653235 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -97,8 +97,9 @@ public: QGLFramebufferObject *fbo() const; - void beginPaint(); - void endPaint(); + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; @@ -107,6 +108,8 @@ private: QGLPixmapData(const QGLPixmapData &other); QGLPixmapData &operator=(const QGLPixmapData &other); + void copyBackFromRenderFbo(bool keepCurrentFboBound) const; + static bool useFramebufferObjects(); int m_width; |