aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/context2d/qquickcontext2dtexture_p.h
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@digia.com>2013-11-27 17:04:06 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-03 18:06:36 +0100
commit9ad9615d0003c9fb84255152f0cbb473ee2a7a70 (patch)
treec4aba681ddacd7eadb4defe7312e9020b43407c2 /src/quick/items/context2d/qquickcontext2dtexture_p.h
parent9e77d6c31b406e5941a2d287f3c8842954815db4 (diff)
Improve the Canvas threading model
The canvas classes were mixing scene graph resources and GL content across threads. This led to a number of potential crashes in addition to that the FBO based rendering had significant potential for stalling. QQuickContext2DTexture is no longer a QSGTexture with ambiguous ownership. Instead we use textureForNextFrame which is called on the render thread while the GUI is locked to synchronize state from the Context2D's "texture" into the actual QSGTexture. This means that cleanup of the QQuickContext2DTexture and the QSGTexture used for display is no longer in conflict. QQuickPixmap no longer contains a QSGTexture either as these are strictly for use on the scene graph thread. The Images are anyway loaded explicitly as QImage files in QQuickContext2DContext and uploaded again for every Canvas, so relying on the GL paint engine to do the caching will give us the same with less code. I also changed the default strategy to Immediate as that one supports the full API (cooperative does not support readback) and because cooperative is pretty bad for performance since the rendering happens in the sync() step. Task-number: QTBUG-34268 Task-number: QTBUG-31052 Task-number: QTBUG-21935 Task-number: QTBUG-30689 Task-number: QTBUG-29007 Change-Id: Ic540b22d5faa1188e21e56a3beee24191d13f423 Reviewed-by: Mitch Curtis <mitch.curtis@digia.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src/quick/items/context2d/qquickcontext2dtexture_p.h')
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h70
1 files changed, 53 insertions, 17 deletions
diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h
index 2a5b7a318a..cf0e8e3fa9 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h
@@ -58,16 +58,44 @@ QT_BEGIN_NAMESPACE
class QQuickContext2DTile;
class QQuickContext2DCommandBuffer;
-class QQuickContext2DTexture : public QSGDynamicTexture
+class QQuickContext2DTexture : public QObject
{
Q_OBJECT
public:
+ class PaintEvent : public QEvent {
+ public:
+ PaintEvent(QQuickContext2DCommandBuffer *b) : QEvent(QEvent::Type(QEvent::User + 1)), buffer(b) {}
+ QQuickContext2DCommandBuffer *buffer;
+ };
+
+ class CanvasChangeEvent : public QEvent {
+ public:
+ CanvasChangeEvent(const QSize &cSize,
+ const QSize &tSize,
+ const QRect &cWindow,
+ const QRect &dRect,
+ bool sm,
+ bool aa)
+ : QEvent(QEvent::Type(QEvent::User + 2))
+ , canvasSize(cSize)
+ , tileSize(tSize)
+ , canvasWindow(cWindow)
+ , dirtyRect(dRect)
+ , smooth(sm)
+ , antialiasing(aa)
+ {
+ }
+ QSize canvasSize;
+ QSize tileSize;
+ QRect canvasWindow;
+ QRect dirtyRect;
+ bool smooth;
+ bool antialiasing;
+ };
+
QQuickContext2DTexture();
~QQuickContext2DTexture();
- virtual bool hasAlphaChannel() const {return true;}
- virtual bool hasMipmaps() const {return false;}
- virtual QSize textureSize() const;
virtual QQuickCanvasItem::RenderTarget renderTarget() const = 0;
static QRect tiledRect(const QRectF& window, const QSize& tileSize);
@@ -78,15 +106,20 @@ public:
void setAntialiasing(bool antialiasing);
bool setDirtyRect(const QRect &dirtyRect);
bool canvasDestroyed();
+ void setOnCustomThread(bool is) { m_onCustomThread = is; }
+
+ // Called during sync() on the scene graph thread while GUI is blocked.
+ virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame) = 0;
+ bool event(QEvent *e);
Q_SIGNALS:
void textureChanged();
public Q_SLOTS:
- void markDirtyTexture();
- void setItem(QQuickCanvasItem* item);
void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing);
void paint(QQuickContext2DCommandBuffer *ccb);
+ void markDirtyTexture();
+ void setItem(QQuickCanvasItem* item);
virtual void grabImage(const QRectF& region = QRectF()) = 0;
protected:
@@ -110,13 +143,16 @@ protected:
QSize m_tileSize;
QRect m_canvasWindow;
- uint m_dirtyCanvas : 1;
+ QMutex m_mutex;
+ QWaitCondition m_condition;
+
uint m_canvasWindowChanged : 1;
uint m_dirtyTexture : 1;
uint m_smooth : 1;
uint m_antialiasing : 1;
uint m_tiledCanvas : 1;
uint m_painting : 1;
+ uint m_onCustomThread : 1; // Not GUI and not SGRender
};
class QQuickContext2DFBOTexture : public QQuickContext2DTexture
@@ -126,17 +162,16 @@ class QQuickContext2DFBOTexture : public QQuickContext2DTexture
public:
QQuickContext2DFBOTexture();
~QQuickContext2DFBOTexture();
- virtual int textureId() const;
- virtual bool updateTexture();
virtual QQuickContext2DTile* createTile() const;
virtual QPaintDevice* beginPainting();
virtual void endPainting();
QRectF normalizedTextureSubRect() const;
virtual QQuickCanvasItem::RenderTarget renderTarget() const;
virtual void compositeTile(QQuickContext2DTile* tile);
- virtual void bind();
QSize adjustedTileSize(const QSize &ts);
+ QSGTexture *textureForNextFrame(QSGTexture *);
+
public Q_SLOTS:
virtual void grabImage(const QRectF& region = QRectF());
@@ -144,10 +179,12 @@ private:
bool doMultisampling() const;
QOpenGLFramebufferObject *m_fbo;
QOpenGLFramebufferObject *m_multisampledFbo;
- QMutex m_mutex;
- QWaitCondition m_condition;
QSize m_fboSize;
QPaintDevice *m_paint_device;
+
+
+ GLuint m_displayTextures[2];
+ int m_displayTexture;
};
class QSGPlainTexture;
@@ -158,24 +195,23 @@ class QQuickContext2DImageTexture : public QQuickContext2DTexture
public:
QQuickContext2DImageTexture();
~QQuickContext2DImageTexture();
- virtual int textureId() const;
- virtual void bind();
virtual QQuickCanvasItem::RenderTarget renderTarget() const;
- virtual bool updateTexture();
virtual QQuickContext2DTile* createTile() const;
virtual QPaintDevice* beginPainting();
+ virtual void endPainting();
virtual void compositeTile(QQuickContext2DTile* tile);
+ virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame);
+
public Q_SLOTS:
virtual void grabImage(const QRectF& region = QRectF());
private:
- QSGPlainTexture *imageTexture() const;
QImage m_image;
+ QImage m_displayImage;
QPainter m_painter;
- QSGPlainTexture* m_texture;
};
QT_END_NAMESPACE