diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-09-28 05:06:56 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-09-28 05:06:56 (GMT) |
commit | bfd5b875701e36d8aa2637548a67511d6d1082d0 (patch) | |
tree | cbcbded97c90f0afa731df0da18158d8ef4dd595 /src/opengl | |
parent | 3a927312dbb797f03b351067210b83784c7132cb (diff) | |
parent | 7b796b4dcdebfba55c4754d241edb334217fc550 (diff) | |
download | Qt-bfd5b875701e36d8aa2637548a67511d6d1082d0.zip Qt-bfd5b875701e36d8aa2637548a67511d6d1082d0.tar.gz Qt-bfd5b875701e36d8aa2637548a67511d6d1082d0.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 30 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 33 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 3 | ||||
-rw-r--r-- | src/opengl/qgl_x11.cpp | 4 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject.cpp | 105 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject_p.h | 5 |
6 files changed, 92 insertions, 88 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index cb1ca8e..acc68d3 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -864,32 +864,6 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) if (do_vectorpath_cache) path.makeCacheable(); - if (!device->format().stencil()) { - // If there is no stencil buffer, triangulate the path instead. - - QRectF bbox = path.controlPointRect(); - // If the path doesn't fit within these limits, it is possible that the triangulation will fail. - bool withinLimits = (bbox.left() > -0x8000 * inverseScale) - && (bbox.right() < 0x8000 * inverseScale) - && (bbox.top() > -0x8000 * inverseScale) - && (bbox.bottom() < 0x8000 * inverseScale); - if (withinLimits) { - QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale)); - - QVarLengthArray<float> vertices(polys.vertices.size()); - for (int i = 0; i < polys.vertices.size(); ++i) - vertices[i] = float(inverseScale * polys.vertices.at(i)); - - prepareForDraw(currentBrush.isOpaque()); - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData()); - glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.constData()); - } else { - // We can't handle big, concave painter paths with OpenGL without stencil buffer. - qWarning("Painter path exceeds +/-32767 pixels."); - } - return; - } - // The path is too complicated & needs the stencil technique vertexCoordinateArray.clear(); vertexCoordinateArray.addPath(path, inverseScale, false); @@ -1338,7 +1312,7 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c QGLRect srcRect(src.left(), top, src.right(), bottom); bool isBitmap = pixmap.isQBitmap(); - bool isOpaque = !isBitmap && !pixmap.hasAlphaChannel(); + bool isOpaque = !isBitmap && !pixmap.hasAlpha(); d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); @@ -1813,7 +1787,7 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen transferMode(ImageArrayDrawingMode); bool isBitmap = pixmap.isQBitmap(); - bool isOpaque = !isBitmap && (!pixmap.hasAlphaChannel() || (hints & QPainter::OpaqueHint)) && allOpaque; + bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque; updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 15070d4..0d1a66e 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1689,9 +1689,6 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) workaround_brokenFBOReadBack = false; workaroundsCached = false; - workaround_brokenTextureFromPixmap = false; - workaround_brokenTextureFromPixmap_init = false; - for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) vertexAttributeArraysEnabledState[i] = false; } @@ -2577,34 +2574,18 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, } } -#if defined(Q_WS_X11) - // Try to use texture_from_pixmap +#if defined(Q_WS_X11) && !defined(QT_NO_EGL) + // Only try to use texture_from_pixmap under X11/EGL const QX11Info *xinfo = qt_x11Info(paintDevice); if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType && xinfo && xinfo->screen() == pixmap.x11Info().screen() && target == GL_TEXTURE_2D) { - if (!workaround_brokenTextureFromPixmap_init) { - workaround_brokenTextureFromPixmap_init = true; - - const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION))); - const int pos = versionString.indexOf("NVIDIA "); - - if (pos >= 0) { - const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA ")); - - if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256")) - workaround_brokenTextureFromPixmap = true; - } - } - - if (!workaround_brokenTextureFromPixmap) { - texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); - if (texture) { - texture->options |= QGLContext::MemoryManagedBindOption; - texture->boundPixmap = pd; - boundPixmaps.insert(pd, QPixmap(pixmap)); - } + texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); + if (texture) { + texture->options |= QGLContext::MemoryManagedBindOption; + texture->boundPixmap = pd; + boundPixmaps.insert(pd, QPixmap(pixmap)); } } #endif diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 623eeaf..6323ce2 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -401,9 +401,6 @@ public: uint workaround_brokenFBOReadBack : 1; uint workaroundsCached : 1; - uint workaround_brokenTextureFromPixmap : 1; - uint workaround_brokenTextureFromPixmap_init : 1; - QPaintDevice *paintDevice; QColor transpColor; QGLContext *q_ptr; diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index f3a4c95..7f4c670 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -1776,6 +1776,10 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, cons QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); + // We can't use TFP if the pixmap has a separate X11 mask + if (pixmapData->x11_mask) + return 0; + if (!qt_resolveTextureFromPixmap(paintDevice)) return 0; diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index adbba85..6c9b288 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -324,10 +324,6 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f, fboFormat.setStencil(true); } else if (attachment == QGLFramebufferObject::Depth) { fboFormat.setDepth(true); - fboFormat.setStencil(false); - } else { - fboFormat.setDepth(false); - fboFormat.setStencil(false); } GLenum format = f->format().internalTextureFormat(); @@ -472,13 +468,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); } + // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a + // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer + // might not be supported while separate buffers are, according to QTBUG-12861. + if (attachment == QGLFramebufferObject::CombinedDepthStencil && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) { // depth and stencil buffer needs another extension - glGenRenderbuffers(1, &depth_stencil_buffer); - Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer)); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer); - Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer)); + glGenRenderbuffers(1, &depth_buffer); + Q_ASSERT(!glIsRenderbuffer(depth_buffer)); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); + Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); @@ -486,24 +486,26 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); - GLint i = 0; - glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); + stencil_buffer = depth_buffer; glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_stencil_buffer); + GL_RENDERBUFFER_EXT, depth_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_stencil_buffer); - fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; + GL_RENDERBUFFER_EXT, stencil_buffer); valid = checkFramebufferStatus(); - if (!valid) - glDeleteRenderbuffers(1, &depth_stencil_buffer); - } else if (attachment == QGLFramebufferObject::Depth - || attachment == QGLFramebufferObject::CombinedDepthStencil) + if (!valid) { + glDeleteRenderbuffers(1, &depth_buffer); + stencil_buffer = depth_buffer = 0; + } + } + + if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil + || (attachment == QGLFramebufferObject::Depth))) { - glGenRenderbuffers(1, &depth_stencil_buffer); - Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer)); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer); - Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer)); + glGenRenderbuffers(1, &depth_buffer); + Q_ASSERT(!glIsRenderbuffer(depth_buffer)); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); + Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES #define GL_DEPTH_COMPONENT16 0x81A5 @@ -521,14 +523,53 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } - GLint i = 0; - glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_stencil_buffer); - fbo_attachment = QGLFramebufferObject::Depth; + GL_RENDERBUFFER_EXT, depth_buffer); valid = checkFramebufferStatus(); - if (!valid) - glDeleteRenderbuffers(1, &depth_stencil_buffer); + if (!valid) { + glDeleteRenderbuffers(1, &depth_buffer); + depth_buffer = 0; + } + } + + if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) { + glGenRenderbuffers(1, &stencil_buffer); + Q_ASSERT(!glIsRenderbuffer(stencil_buffer)); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer); + Q_ASSERT(glIsRenderbuffer(stencil_buffer)); + if (samples != 0 && glRenderbufferStorageMultisampleEXT) { +#ifdef QT_OPENGL_ES + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + GL_STENCIL_INDEX8_EXT, size.width(), size.height()); +#else + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + GL_STENCIL_INDEX, size.width(), size.height()); +#endif + } else { +#ifdef QT_OPENGL_ES + glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, + size.width(), size.height()); +#else + glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, + size.width(), size.height()); +#endif + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, stencil_buffer); + valid = checkFramebufferStatus(); + if (!valid) { + glDeleteRenderbuffers(1, &stencil_buffer); + stencil_buffer = 0; + } + } + + // The FBO might have become valid after removing the depth or stencil buffer. + valid = checkFramebufferStatus(); + + if (depth_buffer && stencil_buffer) { + fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; + } else if (depth_buffer) { + fbo_attachment = QGLFramebufferObject::Depth; } else { fbo_attachment = QGLFramebufferObject::NoAttachment; } @@ -539,6 +580,10 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, glDeleteRenderbuffers(1, &color_buffer); else glDeleteTextures(1, &texture); + if (depth_buffer) + glDeleteRenderbuffers(1, &depth_buffer); + if (stencil_buffer && depth_buffer != stencil_buffer) + glDeleteRenderbuffers(1, &stencil_buffer); glDeleteFramebuffers(1, &fbo); fbo_guard.setId(0); } @@ -821,8 +866,10 @@ QGLFramebufferObject::~QGLFramebufferObject() glDeleteTextures(1, &d->texture); if (d->color_buffer) glDeleteRenderbuffers(1, &d->color_buffer); - if (d->depth_stencil_buffer) - glDeleteRenderbuffers(1, &d->depth_stencil_buffer); + if (d->depth_buffer) + glDeleteRenderbuffers(1, &d->depth_buffer); + if (d->stencil_buffer && d->stencil_buffer != d->depth_buffer) + glDeleteRenderbuffers(1, &d->stencil_buffer); GLuint fbo = d->fbo(); glDeleteFramebuffers(1, &fbo); } diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h index d8ff012..58b4e9e 100644 --- a/src/opengl/qglframebufferobject_p.h +++ b/src/opengl/qglframebufferobject_p.h @@ -126,7 +126,7 @@ private: class QGLFramebufferObjectPrivate { public: - QGLFramebufferObjectPrivate() : fbo_guard(0), texture(0), depth_stencil_buffer(0) + QGLFramebufferObjectPrivate() : fbo_guard(0), texture(0), depth_buffer(0), stencil_buffer(0) , color_buffer(0), valid(false), engine(0) {} ~QGLFramebufferObjectPrivate() {} @@ -136,7 +136,8 @@ public: bool checkFramebufferStatus() const; QGLSharedResourceGuard fbo_guard; GLuint texture; - GLuint depth_stencil_buffer; + GLuint depth_buffer; + GLuint stencil_buffer; GLuint color_buffer; GLenum target; QSize size; |