summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qgl.cpp47
-rw-r--r--src/opengl/qgl_egl.cpp31
-rw-r--r--src/opengl/qgl_p.h3
-rw-r--r--src/opengl/qglextensions_p.h2
-rw-r--r--src/opengl/qglshaderprogram.cpp4
-rw-r--r--src/opengl/qpixmapdata_gl_p.h2
-rw-r--r--src/opengl/qwindowsurface_gl.cpp24
-rw-r--r--src/opengl/qwindowsurface_gl_p.h4
8 files changed, 85 insertions, 32 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 9effb34..fc28a73 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2092,6 +2092,16 @@ void QGLContextPrivate::syncGlState()
}
#undef ctx
+#ifdef QT_NO_EGL
+void QGLContextPrivate::swapRegion(const QRegion *)
+{
+ static bool firstWarning = true;
+ if (firstWarning) {
+ qWarning() << "::swapRegion called but not supported!";
+ firstWarning = false;
+ }
+}
+#endif
/*!
\overload
@@ -2246,6 +2256,13 @@ static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum textu
}
}
+#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
+QGLExtensionFuncs& QGLContextPrivate::extensionFuncs(const QGLContext *)
+{
+ return qt_extensionFuncs;
+}
+#endif
+
QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul,
GLenum texture_format)
{
@@ -2357,9 +2374,6 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
&& target == GL_TEXTURE_2D
&& (options & QGLContext::MipmapBindOption))
{
-#ifdef QGL_BIND_TEXTURE_DEBUG
- printf(" - generating mipmaps (%d ms)\n", time.elapsed());
-#endif
#if !defined(QT_OPENGL_ES_2)
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
#ifndef QT_OPENGL_ES
@@ -2373,6 +2387,9 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
glTexParameterf(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption
? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST);
+#ifdef QGL_BIND_TEXTURE_DEBUG
+ printf(" - generating mipmaps (%d ms)\n", time.elapsed());
+#endif
} else {
glTexParameterf(target, GL_TEXTURE_MIN_FILTER, filtering);
}
@@ -2397,7 +2414,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
if (premul) {
img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied);
#ifdef QGL_BIND_TEXTURE_DEBUG
- printf(" - converting ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed());
+ printf(" - converted ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed());
#endif
}
break;
@@ -2405,7 +2422,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
if (!premul) {
img = img.convertToFormat(target_format = QImage::Format_ARGB32);
#ifdef QGL_BIND_TEXTURE_DEBUG
- printf(" - converting ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed());
+ printf(" - converted ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed());
#endif
}
break;
@@ -2422,20 +2439,17 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
? QImage::Format_ARGB32_Premultiplied
: QImage::Format_ARGB32);
#ifdef QGL_BIND_TEXTURE_DEBUG
- printf(" - converting to 32-bit alpha format (%d ms)\n", time.elapsed());
+ printf(" - converted to 32-bit alpha format (%d ms)\n", time.elapsed());
#endif
} else {
img = img.convertToFormat(QImage::Format_RGB32);
#ifdef QGL_BIND_TEXTURE_DEBUG
- printf(" - converting to 32-bit (%d ms)\n", time.elapsed());
+ printf(" - converted to 32-bit (%d ms)\n", time.elapsed());
#endif
}
}
if (options & QGLContext::InvertedYBindOption) {
-#ifdef QGL_BIND_TEXTURE_DEBUG
- printf(" - flipping bits over y (%d ms)\n", time.elapsed());
-#endif
if (img.isDetached()) {
int ipl = img.bytesPerLine() / 4;
int h = img.height();
@@ -2452,17 +2466,20 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
// data twice. This version should only do it once.
img = img.mirrored();
}
+#ifdef QGL_BIND_TEXTURE_DEBUG
+ printf(" - flipped bits over y (%d ms)\n", time.elapsed());
+#endif
}
if (externalFormat == GL_RGBA) {
-#ifdef QGL_BIND_TEXTURE_DEBUG
- printf(" - doing byte swapping (%d ms)\n", time.elapsed());
-#endif
// The only case where we end up with a depth different from
// 32 in the switch above is for the RGB16 case, where we set
// the format to GL_RGB
Q_ASSERT(img.depth() == 32);
qgl_byteSwapImage(img, pixel_type);
+#ifdef QGL_BIND_TEXTURE_DEBUG
+ printf(" - did byte swapping (%d ms)\n", time.elapsed());
+#endif
}
#ifdef QT_OPENGL_ES
// OpenGL/ES requires that the internal and external formats be
@@ -2491,7 +2508,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#ifdef QGL_BIND_TEXTURE_DEBUG
static int totalUploadTime = 0;
totalUploadTime += time.elapsed();
- printf(" - upload done in (%d ms) time=%d\n", time.elapsed(), totalUploadTime);
+ printf(" - upload done in %d ms, (accumulated: %d ms)\n", time.elapsed(), totalUploadTime);
#endif
@@ -5187,6 +5204,8 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
glExtensions |= NVFloatBuffer;
if (extensions.match("GL_ARB_pixel_buffer_object"))
glExtensions |= PixelBufferObject;
+ if (extensions.match("GL_IMG_texture_format_BGRA8888"))
+ glExtensions |= BGRATextureFormat;
#if defined(QT_OPENGL_ES_2)
glExtensions |= FramebufferObject;
glExtensions |= GenerateMipmap;
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index 0a19531..3763926 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -138,7 +138,7 @@ void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config)
format.setDepthBufferSize(depthSize);
format.setStencilBufferSize(stencilSize);
format.setSamples(sampleCount);
- format.setPlane(level + 1); // EGL calls level 0 "normal" whereas Qt calls 1 "normal"
+ format.setPlane(level);
format.setDirectRendering(true); // All EGL contexts are direct-rendered
format.setRgba(true); // EGL doesn't support colour index rendering
format.setStereo(false); // EGL doesn't support stereo buffers
@@ -232,17 +232,20 @@ void QGLContextPrivate::destroyEglSurfaceForDevice()
if (eglSurface != EGL_NO_SURFACE) {
#ifdef Q_WS_X11
// Make sure we don't call eglDestroySurface on a surface which
- // was created for a different winId:
+ // was created for a different winId. This applies only to QGLWidget
+ // paint device, so make sure this is the one we're operating on
+ // (as opposed to a QGLWindowSurface use case).
if (paintDevice && paintDevice->devType() == QInternal::Widget) {
- QGLWidget* w = static_cast<QGLWidget*>(paintDevice);
-
- if (w->d_func()->eglSurfaceWindowId == w->winId())
- eglDestroySurface(eglContext->display(), eglSurface);
- else
- qWarning("WARNING: Potential EGL surface leak!");
- } else
+ QWidget *w = static_cast<QWidget *>(paintDevice);
+ if (QGLWidget *wgl = qobject_cast<QGLWidget *>(w)) {
+ if (wgl->d_func()->eglSurfaceWindowId != wgl->winId()) {
+ qWarning("WARNING: Potential EGL surface leak! Not destroying surface.");
+ return;
+ }
+ }
+ }
#endif
- eglDestroySurface(eglContext->display(), eglSurface);
+ eglDestroySurface(eglContext->display(), eglSurface);
eglSurface = EGL_NO_SURFACE;
}
}
@@ -271,6 +274,14 @@ EGLSurface QGLContextPrivate::eglSurfaceForDevice() const
return eglSurface;
}
+void QGLContextPrivate::swapRegion(const QRegion *region)
+{
+ if (!valid || !eglContext)
+ return;
+
+ eglContext->swapBuffersRegion2NOK(eglSurfaceForDevice(), region);
+}
+
void QGLWidget::setMouseTracking(bool enable)
{
QWidget::setMouseTracking(enable);
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index cd5dbbe..32feacd 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -334,6 +334,7 @@ public:
void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
void syncGlState(); // Makes sure the GL context's state is what we think it is
+ void swapRegion(const QRegion *region);
#if defined(Q_WS_WIN)
void updateFormatVersion();
@@ -415,7 +416,7 @@ public:
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
static QGLExtensionFuncs qt_extensionFuncs;
- static inline QGLExtensionFuncs& extensionFuncs(const QGLContext *) { return qt_extensionFuncs; }
+ static Q_OPENGL_EXPORT QGLExtensionFuncs& extensionFuncs(const QGLContext *);
#endif
static void setCurrentContext(QGLContext *context);
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index 7597b33..6259cca 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -882,7 +882,7 @@ bool qt_resolve_frag_program_extensions(QGLContext *ctx);
bool qt_resolve_glsl_extensions(QGLContext *ctx);
#ifndef QT_NO_EGL
-bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx);
+Q_OPENGL_EXPORT bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx);
#endif
QT_END_NAMESPACE
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 83b4b21..c7689b8 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -1490,7 +1490,7 @@ void QGLShaderProgram::setAttributeArray
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
- glVertexAttribPointer(location, tupleSize, type, GL_FALSE,
+ glVertexAttribPointer(location, tupleSize, type, GL_TRUE,
stride, values);
}
}
@@ -1634,7 +1634,7 @@ void QGLShaderProgram::setAttributeBuffer
Q_D(QGLShaderProgram);
Q_UNUSED(d);
if (location != -1) {
- glVertexAttribPointer(location, tupleSize, type, GL_FALSE, stride,
+ glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
reinterpret_cast<const void *>(offset));
}
}
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index c239bcb..736a28e 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -96,7 +96,7 @@ private:
};
-class QGLPixmapData : public QPixmapData
+class Q_OPENGL_EXPORT QGLPixmapData : public QPixmapData
{
public:
QGLPixmapData(PixelType type);
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 7efa9bc..e9da452 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -354,8 +354,22 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
ctx->create(qt_gl_share_widget()->context());
#ifndef QT_NO_EGL
- if (ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR) != EGL_BUFFER_PRESERVED)
+ static bool checkedForNOKSwapRegion = false;
+ static bool haveNOKSwapRegion = false;
+
+ if (!checkedForNOKSwapRegion) {
+ haveNOKSwapRegion = QEgl::hasExtension("EGL_NOK_swap_region2");
+ checkedForNOKSwapRegion = true;
+
+ if (haveNOKSwapRegion)
+ qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates.";
+ }
+
+ if (ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR) != EGL_BUFFER_PRESERVED &&
+ ! haveNOKSwapRegion)
setPartialUpdateSupport(false); // Force full-screen updates
+ else
+ setPartialUpdateSupport(true);
#endif
widgetPrivate->extraData()->glContext = ctx;
@@ -480,8 +494,14 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
}
}
#endif
+ if (d_ptr->paintedRegion.boundingRect() != geometry()) {
+ // Emits warning if not supported. Should never happen unless
+ // setPartialUpdateSupport(true) has been called.
+ context()->d_func()->swapRegion(&d_ptr->paintedRegion);
+ } else
+ context()->swapBuffers();
+
d_ptr->paintedRegion = QRegion();
- context()->swapBuffers();
} else {
glFlush();
}
diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h
index 8ea714c..5e670fe 100644
--- a/src/opengl/qwindowsurface_gl_p.h
+++ b/src/opengl/qwindowsurface_gl_p.h
@@ -66,6 +66,8 @@ class QRegion;
class QWidget;
struct QGLWindowSurfacePrivate;
+Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget();
+
class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice
{
public:
@@ -77,7 +79,7 @@ public:
QGLWindowSurfacePrivate* d;
};
-class QGLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice
+class Q_OPENGL_EXPORT QGLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice
{
Q_OBJECT
public: