diff options
Diffstat (limited to 'src/quick/items/context2d/qquickcontext2dtexture.cpp')
-rw-r--r-- | src/quick/items/context2d/qquickcontext2dtexture.cpp | 274 |
1 files changed, 73 insertions, 201 deletions
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index 2cb183d715..a315d30f8f 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -50,7 +50,6 @@ #include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObjectFormat> #include <QtCore/QThread> -#include <QtCore/QCoreApplication> QT_BEGIN_NAMESPACE @@ -88,19 +87,14 @@ struct GLAcquireContext { QOpenGLContext *ctx; }; -Q_GLOBAL_STATIC(QThread, globalCanvasThreadRenderInstance) - - QQuickContext2DTexture::QQuickContext2DTexture() : m_context(0) , m_item(0) , m_dirtyCanvas(false) , m_canvasWindowChanged(false) , m_dirtyTexture(false) - , m_threadRendering(false) , m_smooth(false) , m_tiledCanvas(false) - , m_doGrabImage(false) , m_painting(false) { } @@ -117,12 +111,9 @@ QSize QQuickContext2DTexture::textureSize() const void QQuickContext2DTexture::markDirtyTexture() { - const bool inGrab = m_doGrabImage; - m_dirtyTexture = true; updateTexture(); - if (!inGrab) - emit textureChanged(); + emit textureChanged(); } bool QQuickContext2DTexture::setCanvasSize(const QSize &size) @@ -185,8 +176,6 @@ bool QQuickContext2DTexture::setDirtyRect(const QRect &r) void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth) { - lock(); - QSize ts = tileSize; if (ts.width() > canvasSize.width()) ts.setWidth(canvasSize.width()); @@ -209,20 +198,15 @@ void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& setDirtyRect(dirtyRect); setSmooth(smooth); - - unlock(); } -void QQuickContext2DTexture::paintWithoutTiles() +void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb) { - QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer(); - if (!ccb || ccb->isEmpty()) return; QPaintDevice* device = beginPainting(); if (!device) { - delete ccb; endPainting(); return; } @@ -238,100 +222,58 @@ void QQuickContext2DTexture::paintWithoutTiles() p.setCompositionMode(QPainter::CompositionMode_SourceOver); ccb->replay(&p, m_state); - ccb->clear(); - delete ccb; - endPainting(); - markDirtyTexture(); } bool QQuickContext2DTexture::canvasDestroyed() { - bool noCanvas = false; - lock(); - noCanvas = m_item == 0; - unlock(); - return noCanvas; + return m_item == 0; } -void QQuickContext2DTexture::paint() +void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb) { - if (canvasDestroyed()) + if (canvasDestroyed()) { + delete ccb; return; + } GLAcquireContext currentContext(m_context->glContext(), m_context->surface()); - if (m_threadRendering && QThread::currentThread() != globalCanvasThreadRenderInstance()) { - Q_ASSERT(thread() == globalCanvasThreadRenderInstance()); - QMetaObject::invokeMethod(this, "paint", Qt::QueuedConnection); + if (!m_tiledCanvas) { + paintWithoutTiles(ccb); + delete ccb; return; } - if (!m_tiledCanvas) { - paintWithoutTiles(); - } else { - lock(); - QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize))); - unlock(); - - if (!tiledRegion.isEmpty()) { - if (m_threadRendering && !m_doGrabImage) { - QRect dirtyRect; - - lock(); - foreach (QQuickContext2DTile* tile, m_tiles) { - if (tile->dirty()) { - if (dirtyRect.isEmpty()) - dirtyRect = tile->rect(); - else - dirtyRect |= tile->rect(); - } - } - unlock(); + QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize))); + if (!tiledRegion.isEmpty()) { + QRect dirtyRect; + foreach (QQuickContext2DTile* tile, m_tiles) { + if (tile->dirty()) { + if (dirtyRect.isEmpty()) + dirtyRect = tile->rect(); + else + dirtyRect |= tile->rect(); } + } - if (beginPainting()) { - QQuickContext2D::State oldState = m_state; - QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer(); - if (!ccb || ccb->isEmpty()) { - endPainting(); - delete ccb; - return; - } - foreach (QQuickContext2DTile* tile, m_tiles) { - bool dirtyTile = false, dirtyCanvas = false, smooth = false; - - lock(); - dirtyTile = tile->dirty(); - smooth = m_smooth; - dirtyCanvas = m_dirtyCanvas; - unlock(); - - //canvas size or tile size may change during painting tiles - if (dirtyCanvas) { - if (m_threadRendering) - QMetaObject::invokeMethod(this, "paint", Qt::QueuedConnection); - endPainting(); - return; - } else if (dirtyTile) { - ccb->replay(tile->createPainter(smooth), oldState); - tile->drawFinished(); - lock(); - tile->markDirty(false); - unlock(); - } - - compositeTile(tile); + if (beginPainting()) { + QQuickContext2D::State oldState = m_state; + foreach (QQuickContext2DTile* tile, m_tiles) { + if (tile->dirty()) { + ccb->replay(tile->createPainter(m_smooth), oldState); + tile->drawFinished(); + tile->markDirty(false); } - ccb->clear(); - delete ccb; - endPainting(); - m_state = oldState; - markDirtyTexture(); + compositeTile(tile); } + endPainting(); + m_state = oldState; + markDirtyTexture(); } } + delete ccb; } QRect QQuickContext2DTexture::tiledRect(const QRectF& window, const QSize& tileSize) @@ -438,11 +380,15 @@ QQuickContext2DFBOTexture::QQuickContext2DFBOTexture() , m_multisampledFbo(0) , m_paint_device(0) { - m_threadRendering = false; } QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture() { + if (m_multisampledFbo) + m_multisampledFbo->release(); + else if (m_fbo) + m_fbo->release(); + delete m_fbo; delete m_multisampledFbo; delete m_paint_device; @@ -477,14 +423,7 @@ int QQuickContext2DFBOTexture::textureId() const bool QQuickContext2DFBOTexture::updateTexture() { bool textureUpdated = m_dirtyTexture; - m_dirtyTexture = false; - - if (m_doGrabImage) { - grabImage(); - m_condition.wakeOne(); - m_doGrabImage = false; - } return textureUpdated; } @@ -493,13 +432,6 @@ QQuickContext2DTile* QQuickContext2DFBOTexture::createTile() const return new QQuickContext2DFBOTile(); } -void QQuickContext2DFBOTexture::grabImage() -{ - if (m_fbo) { - m_grabedImage = m_fbo->toImage(); - } -} - bool QQuickContext2DFBOTexture::doMultisampling() const { static bool extensionsChecked = false; @@ -515,27 +447,22 @@ bool QQuickContext2DFBOTexture::doMultisampling() const return multisamplingSupported && m_smooth; } -QImage QQuickContext2DFBOTexture::toImage(const QRectF& region) +void QQuickContext2DFBOTexture::grabImage(const QRectF& rf) { - const unsigned long context2d_wait_max = 5000; + Q_ASSERT(rf.isValid()); - m_doGrabImage = true; - if (m_item) // forces a call to updatePaintNode (repaints) - m_item->update(); + if (!m_fbo) { + m_context->setGrabbedImage(QImage()); + return; + } QImage grabbed; - m_mutex.lock(); - bool ok = m_condition.wait(&m_mutex, context2d_wait_max); - - if (!ok) - grabbed = QImage(); + { + GLAcquireContext ctx(m_context->glContext(), m_context->surface()); + grabbed = m_fbo->toImage().mirrored().copy(rf.toRect()); + } - if (region.isValid()) - grabbed = m_grabedImage.copy(region.toRect()); - else - grabbed = m_grabedImage; - m_grabedImage = QImage(); - return grabbed; + m_context->setGrabbedImage(grabbed); } void QQuickContext2DFBOTexture::compositeTile(QQuickContext2DTile* tile) @@ -551,15 +478,17 @@ void QQuickContext2DFBOTexture::compositeTile(QQuickContext2DTile* tile) QOpenGLFramebufferObject::blitFramebuffer(m_fbo, target, t->fbo(), source); } } + QQuickCanvasItem::RenderTarget QQuickContext2DFBOTexture::renderTarget() const { return QQuickCanvasItem::FramebufferObject; } + QPaintDevice* QQuickContext2DFBOTexture::beginPainting() { QQuickContext2DTexture::beginPainting(); - if (m_canvasWindow.size().isEmpty() && !m_threadRendering) { + if (m_canvasWindow.size().isEmpty()) { delete m_fbo; delete m_multisampledFbo; delete m_paint_device; @@ -615,78 +544,27 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting() void QQuickContext2DFBOTexture::endPainting() { QQuickContext2DTexture::endPainting(); - if (m_multisampledFbo) { + if (m_multisampledFbo) QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFbo); - m_multisampledFbo->release(); - } else if (m_fbo) - m_fbo->release(); -} -void qt_quit_context2d_render_thread() -{ - QThread* thread = globalCanvasThreadRenderInstance(); - - if (thread->isRunning()) { - thread->exit(0); - thread->wait(1000); - } } -QQuickContext2DImageTexture::QQuickContext2DImageTexture(bool threadRendering) +QQuickContext2DImageTexture::QQuickContext2DImageTexture() : QQuickContext2DTexture() - , m_texture(new QSGPlainTexture()) + , m_texture(0) { - m_texture->setOwnsTexture(true); - m_texture->setHasMipmaps(false); - - m_threadRendering = threadRendering; - - if (m_threadRendering) { - QThread* thread = globalCanvasThreadRenderInstance(); - moveToThread(thread); - - if (!thread->isRunning()) { - qAddPostRoutine(qt_quit_context2d_render_thread); // XXX: change this method - thread->start(); - } - } } QQuickContext2DImageTexture::~QQuickContext2DImageTexture() { - delete m_texture; + if (m_texture && m_texture->thread() != QThread::currentThread()) + m_texture->deleteLater(); + else + delete m_texture; } int QQuickContext2DImageTexture::textureId() const { - return m_texture->textureId(); -} - -void QQuickContext2DImageTexture::lock() -{ - if (m_threadRendering) - m_mutex.lock(); -} -void QQuickContext2DImageTexture::unlock() -{ - if (m_threadRendering) - m_mutex.unlock(); -} - -void QQuickContext2DImageTexture::wait() -{ - if (m_threadRendering) - m_waitCondition.wait(&m_mutex); -} - -void QQuickContext2DImageTexture::wake() -{ - if (m_threadRendering) - m_waitCondition.wakeOne(); -} - -bool QQuickContext2DImageTexture::supportDirectRendering() const -{ - return !m_threadRendering; + return imageTexture()->textureId(); } QQuickCanvasItem::RenderTarget QQuickContext2DImageTexture::renderTarget() const @@ -696,14 +574,14 @@ QQuickCanvasItem::RenderTarget QQuickContext2DImageTexture::renderTarget() const void QQuickContext2DImageTexture::bind() { - m_texture->bind(); + imageTexture()->bind(); } bool QQuickContext2DImageTexture::updateTexture() { bool textureUpdated = m_dirtyTexture; if (m_dirtyTexture) { - m_texture->setImage(m_image); + imageTexture()->setImage(m_image); m_dirtyTexture = false; } return textureUpdated; @@ -714,26 +592,23 @@ QQuickContext2DTile* QQuickContext2DImageTexture::createTile() const return new QQuickContext2DImageTile(); } -void QQuickContext2DImageTexture::grabImage(const QRect& r) +void QQuickContext2DImageTexture::grabImage(const QRectF& rf) { - m_doGrabImage = true; - paint(); - m_doGrabImage = false; - m_grabedImage = m_image.copy(r); + Q_ASSERT(rf.isValid()); + Q_ASSERT(m_context); + QImage grabbed = m_image.copy(rf.toRect()); + m_context->setGrabbedImage(grabbed); } -QImage QQuickContext2DImageTexture::toImage(const QRectF& rect) +QSGPlainTexture *QQuickContext2DImageTexture::imageTexture() const { - QRect r = rect.isValid() ? rect.toRect() : QRect(QPoint(0, 0), m_canvasWindow.size()); - if (threadRendering()) { - wake(); - QMetaObject::invokeMethod(this, "grabImage", Qt::BlockingQueuedConnection, Q_ARG(QRect, r)); - } else { - QMetaObject::invokeMethod(this, "grabImage", Qt::DirectConnection, Q_ARG(QRect, r)); + if (!m_texture) { + QQuickContext2DImageTexture *that = const_cast<QQuickContext2DImageTexture *>(this); + that->m_texture = new QSGPlainTexture; + that->m_texture->setOwnsTexture(true); + that->m_texture->setHasMipmaps(false); } - QImage image = m_grabedImage; - m_grabedImage = QImage(); - return image; + return m_texture; } QPaintDevice* QQuickContext2DImageTexture::beginPainting() @@ -762,14 +637,11 @@ void QQuickContext2DImageTexture::compositeTile(QQuickContext2DTile* tile) source.moveTo(source.topLeft() - t->rect().topLeft()); target.moveTo(target.topLeft() - m_canvasWindow.topLeft()); - lock(); m_painter.begin(&m_image); m_painter.setCompositionMode(QPainter::CompositionMode_Source); m_painter.drawImage(target, t->image(), source); m_painter.end(); - unlock(); } } QT_END_NAMESPACE - |