QQuickContext2DTexture::QQuickContext2DTexture()
: m_context(0)
, m_item(0)
- , m_canvasSize(QSize(1, 1))
- , m_tileSize(QSize(1, 1))
- , m_canvasWindow(QRect(0, 0, 1, 1))
, m_dirtyCanvas(false)
+ , m_canvasWindowChanged(false)
, m_dirtyTexture(false)
, m_threadRendering(false)
, m_smooth(false)
{
if (m_canvasWindow != r) {
m_canvasWindow = r;
+ m_canvasWindowChanged = true;
return true;
}
return false;
return QRect();
}
- QRect r = tiledRect(window, m_tileSize);
+ QRect r = tiledRect(window, adjustedTileSize(m_tileSize));
const int tw = m_tileSize.width();
const int th = m_tileSize.height();
m_tiles.clear();
}
+QSize QQuickContext2DTexture::adjustedTileSize(const QSize &ts)
+{
+ return ts;
+}
+
+static inline QSize npotAdjustedSize(const QSize &size)
+{
+ static bool checked = false;
+ static bool npotSupported = false;
+
+ if (!checked) {
+ npotSupported = QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
+ checked = true;
+ }
+
+ if (npotSupported) {
+ return QSize(qMax(QT_MINIMUM_FBO_SIZE, size.width()),
+ qMax(QT_MINIMUM_FBO_SIZE, size.height()));
+ }
+
+ return QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width())),
+ qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
+}
+
QQuickContext2DFBOTexture::QQuickContext2DFBOTexture()
: QQuickContext2DTexture()
, m_fbo(0)
delete m_paint_device;
}
-bool QQuickContext2DFBOTexture::setCanvasSize(const QSize &size)
+QSize QQuickContext2DFBOTexture::adjustedTileSize(const QSize &ts)
{
- QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width()))
- , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
-
- if (m_canvasSize != s) {
- m_canvasSize = s;
- m_dirtyCanvas = true;
- return true;
- }
- return false;
-}
-
-bool QQuickContext2DFBOTexture::setTileSize(const QSize &size)
-{
- QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width()))
- , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
- if (m_tileSize != s) {
- m_tileSize = s;
- m_dirtyCanvas = true;
- return true;
- }
- return false;
-}
-
-bool QQuickContext2DFBOTexture::setCanvasWindow(const QRect& canvasWindow)
-{
- QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().width()))
- , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().height())));
-
-
- bool doChanged = false;
- if (m_fboSize != s) {
- m_fboSize = s;
- doChanged = true;
- }
-
- if (m_canvasWindow != canvasWindow)
- m_canvasWindow = canvasWindow;
-
- return doChanged;
+ return npotAdjustedSize(ts);
}
void QQuickContext2DFBOTexture::bind()
m_fbo = 0;
m_multisampledFbo = 0;
return 0;
- } else if (!m_fbo || m_fbo->size() != m_fboSize) {
+ } else if (!m_fbo || m_canvasWindowChanged) {
delete m_fbo;
delete m_multisampledFbo;
+
+ m_fboSize = npotAdjustedSize(m_canvasWindow.size());
+ m_canvasWindowChanged = false;
+
if (doMultisampling()) {
{
QOpenGLFramebufferObjectFormat format;
if (m_canvasWindow.size().isEmpty())
return 0;
- if (m_image.size() != m_canvasWindow.size()) {
+ if (m_canvasWindowChanged) {
m_image = QImage(m_canvasWindow.size(), QImage::Format_ARGB32_Premultiplied);
m_image.fill(0x00000000);
+ m_canvasWindowChanged = false;
}
return &m_image;
virtual QImage toImage(const QRectF& region = QRectF()) = 0;
static QRect tiledRect(const QRectF& window, const QSize& tileSize);
- virtual bool setCanvasSize(const QSize &size);
- virtual bool setTileSize(const QSize &size);
- virtual bool setCanvasWindow(const QRect& canvasWindow);
+ bool setCanvasSize(const QSize &size);
+ bool setTileSize(const QSize &size);
+ bool setCanvasWindow(const QRect& canvasWindow);
void setSmooth(bool smooth);
bool setDirtyRect(const QRect &dirtyRect);
virtual void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
virtual void compositeTile(QQuickContext2DTile* tile) = 0;
void clearTiles();
+ virtual QSize adjustedTileSize(const QSize &ts);
QRect createTiles(const QRect& window);
QList<QQuickContext2DTile*> m_tiles;
QRect m_canvasWindow;
uint m_dirtyCanvas : 1;
+ uint m_canvasWindowChanged : 1;
uint m_dirtyTexture : 1;
uint m_threadRendering : 1;
uint m_smooth : 1;
virtual QQuickCanvasItem::RenderTarget renderTarget() const;
virtual void compositeTile(QQuickContext2DTile* tile);
virtual void bind();
- virtual bool setCanvasSize(const QSize &size);
- virtual bool setTileSize(const QSize &size);
- virtual bool setCanvasWindow(const QRect& canvasWindow);
+ QSize adjustedTileSize(const QSize &ts);
+
private Q_SLOTS:
void grabImage();