From: Justin McPherson Date: Tue, 28 Feb 2012 05:08:43 +0000 (+1000) Subject: Use NPOT support if available. X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=eab48686b2ec6df8cd179c9472eda4e8c3505cef;p=konrad%2Fqtdeclarative.git Use NPOT support if available. In QQuickContext2DTexture. Change-Id: If0311450658a837b7e2665c041ec2846e3c8c2dd Reviewed-by: Yunqiao Yin --- diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index 28460e2..7d9f65a 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -75,10 +75,8 @@ Q_GLOBAL_STATIC(QThread, globalCanvasThreadRenderInstance) 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) @@ -144,6 +142,7 @@ bool QQuickContext2DTexture::setCanvasWindow(const QRect& r) { if (m_canvasWindow != r) { m_canvasWindow = r; + m_canvasWindowChanged = true; return true; } return false; @@ -331,7 +330,7 @@ QRect QQuickContext2DTexture::createTiles(const QRect& window) 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(); @@ -379,6 +378,30 @@ void QQuickContext2DTexture::clearTiles() 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) @@ -395,47 +418,9 @@ QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture() 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() @@ -550,9 +535,13 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting() 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; @@ -719,9 +708,10 @@ QPaintDevice* QQuickContext2DImageTexture::beginPainting() 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; diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h index 9e00ece..81b239d 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture_p.h +++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h @@ -81,9 +81,9 @@ public: 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); @@ -104,6 +104,7 @@ protected: virtual void compositeTile(QQuickContext2DTile* tile) = 0; void clearTiles(); + virtual QSize adjustedTileSize(const QSize &ts); QRect createTiles(const QRect& window); QList m_tiles; @@ -117,6 +118,7 @@ protected: QRect m_canvasWindow; uint m_dirtyCanvas : 1; + uint m_canvasWindowChanged : 1; uint m_dirtyTexture : 1; uint m_threadRendering : 1; uint m_smooth : 1; @@ -144,9 +146,8 @@ public: 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();