summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qglbuffer.cpp32
-rw-r--r--src/opengl/qglbuffer.h2
-rw-r--r--src/opengl/qpixmapdata_x11gl_egl.cpp72
-rw-r--r--src/opengl/qpixmapdata_x11gl_p.h5
-rw-r--r--src/opengl/qwindowsurface_x11gl.cpp54
-rw-r--r--src/opengl/qwindowsurface_x11gl_p.h3
6 files changed, 149 insertions, 19 deletions
diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp
index 7022a53..2ab7c32 100644
--- a/src/opengl/qglbuffer.cpp
+++ b/src/opengl/qglbuffer.cpp
@@ -369,6 +369,38 @@ void QGLBuffer::release() const
glBindBuffer(d->type, 0);
}
+#undef ctx
+
+/*!
+ Binds a raw \a bufferId to the specified buffer \a type
+ in the current QGLContext. Returns false if there is
+ no context current or the GL buffer extension could
+ not be resolved.
+
+ This function is a direct call to \c{glBindBuffer()} for
+ use when the caller does not have a QGLBuffer but does
+ have a raw \a bufferId. It can also be used to release
+ the current buffer when the caller does not know which
+ QGLBuffer object is currently bound:
+
+ \code
+ QGLBuffer::bind(QGLBuffer::VertexBuffer, 0);
+ \endcode
+*/
+bool QGLBuffer::bind(QGLBuffer::Type type, uint bufferId)
+{
+ const QGLContext *ctx = QGLContext::currentContext();
+ if (ctx) {
+ if (qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx))) {
+ glBindBuffer(GLenum(type), GLuint(bufferId));
+ return true;
+ }
+ }
+ return false;
+}
+
+#define ctx d->guard.context()
+
/*!
Returns the GL identifier associated with this buffer; zero if
the buffer has not been created.
diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h
index ecb86e2..a060733 100644
--- a/src/opengl/qglbuffer.h
+++ b/src/opengl/qglbuffer.h
@@ -97,6 +97,8 @@ public:
bool bind() const;
void release() const;
+ static bool bind(QGLBuffer::Type type, uint bufferId);
+
uint bufferId() const;
int size() const;
diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp
index a01eec4..3ab385a 100644
--- a/src/opengl/qpixmapdata_x11gl_egl.cpp
+++ b/src/opengl/qpixmapdata_x11gl_egl.cpp
@@ -41,19 +41,22 @@
#include <QDebug>
-#include <private/qgl_p.h>
-#include <private/qegl_p.h>
-#include <private/qeglproperties_p.h>
-#include <private/qeglcontext_p.h>
+#include <QtGui/private/qt_x11_p.h>
+#include <QtGui/private/qegl_p.h>
+#include <QtGui/private/qeglproperties_p.h>
+#include <QtGui/private/qeglcontext_p.h>
#if !defined(QT_OPENGL_ES_1)
-#include <private/qpaintengineex_opengl2_p.h>
+#include <QtOpenGL/private/qpaintengineex_opengl2_p.h>
#endif
#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
+#include <QtOpenGL/private/qpaintengine_opengl_p.h>
#endif
+#include <QtOpenGL/private/qgl_p.h>
+#include <QtOpenGL/private/qgl_egl_p.h>
+
#include "qpixmapdata_x11gl_p.h"
QT_BEGIN_NAMESPACE
@@ -185,6 +188,60 @@ QX11GLPixmapData::~QX11GLPixmapData()
delete ctx;
}
+
+void QX11GLPixmapData::fill(const QColor &color)
+{
+ if (ctx) {
+ ctx->makeCurrent();
+ glFinish();
+ eglWaitClient();
+ }
+
+ QX11PixmapData::fill(color);
+ XSync(X11->display, False);
+
+ if (ctx) {
+ ctx->makeCurrent();
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+ }
+}
+
+void QX11GLPixmapData::copy(const QPixmapData *data, const QRect &rect)
+{
+ if (ctx) {
+ ctx->makeCurrent();
+ glFinish();
+ eglWaitClient();
+ }
+
+ QX11PixmapData::copy(data, rect);
+ XSync(X11->display, False);
+
+ if (ctx) {
+ ctx->makeCurrent();
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+ }
+}
+
+bool QX11GLPixmapData::scroll(int dx, int dy, const QRect &rect)
+{
+ if (ctx) {
+ ctx->makeCurrent();
+ glFinish();
+ eglWaitClient();
+ }
+
+ bool success = QX11PixmapData::scroll(dx, dy, rect);
+ XSync(X11->display, False);
+
+ if (ctx) {
+ ctx->makeCurrent();
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+ }
+
+ return success;
+}
+
#if !defined(QT_OPENGL_ES_1)
Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_pixmap_2_engine)
#endif
@@ -201,6 +258,8 @@ QPaintEngine* QX11GLPixmapData::paintEngine() const
ctx = new QGLContext(glFormat());
Q_ASSERT(ctx->d_func()->eglContext == 0);
ctx->d_func()->eglContext = hasAlphaChannel() ? argbContext : rgbContext;
+ // Update the glFormat for the QGLContext:
+ qt_glformat_from_eglconfig(ctx->d_func()->glFormat, ctx->d_func()->eglContext->config());
}
QPaintEngine* engine;
@@ -249,6 +308,7 @@ void QX11GLPixmapData::beginPaint()
EGLConfig cfg = ctx->d_func()->eglContext->config();
Q_ASSERT(cfg != QEGL_NO_CONFIG);
+// qDebug("QX11GLPixmapData - using EGL Config ID %d", ctx->d_func()->eglContext->configAttrib(EGL_CONFIG_ID));
EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg);
if (surface == EGL_NO_SURFACE) {
qWarning() << "Error creating EGL surface for pixmap:" << QEgl::errorString();
diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h
index 83cd780..8681336 100644
--- a/src/opengl/qpixmapdata_x11gl_p.h
+++ b/src/opengl/qpixmapdata_x11gl_p.h
@@ -71,6 +71,11 @@ public:
QX11GLPixmapData();
virtual ~QX11GLPixmapData();
+ // Re-implemented from QX11PixmapData:
+ void fill(const QColor &color);
+ void copy(const QPixmapData *data, const QRect &rect);
+ bool scroll(int dx, int dy, const QRect &rect);
+
// Re-implemented from QGLPaintDevice
QPaintEngine* paintEngine() const; // Also re-implements QX11PixmapData::paintEngine
void beginPaint();
diff --git a/src/opengl/qwindowsurface_x11gl.cpp b/src/opengl/qwindowsurface_x11gl.cpp
index 27b91ba..7befe03 100644
--- a/src/opengl/qwindowsurface_x11gl.cpp
+++ b/src/opengl/qwindowsurface_x11gl.cpp
@@ -51,14 +51,16 @@
QT_BEGIN_NAMESPACE
QX11GLWindowSurface::QX11GLWindowSurface(QWidget* window)
- : QWindowSurface(window), m_GC(0), m_window(window)
+ : QWindowSurface(window), m_windowGC(0), m_pixmapGC(0), m_window(window)
{
}
QX11GLWindowSurface::~QX11GLWindowSurface()
{
- if (m_GC)
- XFree(m_GC);
+ if (m_windowGC)
+ XFree(m_windowGC);
+ if (m_pixmapGC)
+ XFree(m_pixmapGC);
}
QPaintDevice *QX11GLWindowSurface::paintDevice()
@@ -92,16 +94,22 @@ void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, co
// for (int i = 0; i < num; ++i)
// qDebug() << ' ' << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height;
- if (m_GC == 0) {
- m_GC = XCreateGC(X11->display, m_window->handle(), 0, 0);
- XSetGraphicsExposures(X11->display, m_GC, False);
+ if (m_windowGC == 0) {
+ m_windowGC = XCreateGC(X11->display, m_window->handle(), 0, 0);
+ XSetGraphicsExposures(X11->display, m_windowGC, False);
}
- XSetClipRectangles(X11->display, m_GC, 0, 0, rects, rectCount, YXBanded);
- XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_GC,
+ XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded);
+ XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC,
boundingRect.x() + offset.x(), boundingRect.y() + offset.y(),
boundingRect.width(), boundingRect.height(),
windowBoundingRect.x(), windowBoundingRect.y());
+
+ QX11GLPixmapData* pmd = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data());
+ Q_ASSERT(pmd->context());
+ pmd->context()->makeCurrent();
+ XSync(X11->display, False);
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
}
void QX11GLWindowSurface::setGeometry(const QRect &rect)
@@ -113,6 +121,8 @@ void QX11GLWindowSurface::setGeometry(const QRect &rect)
QX11GLPixmapData *pd = new QX11GLPixmapData;
pd->resize(newSize.width(), newSize.height());
m_backBuffer = QPixmap(pd);
+ if (window()->testAttribute(Qt::WA_TranslucentBackground))
+ m_backBuffer.fill(Qt::transparent);
}
// if (gc)
@@ -124,10 +134,30 @@ void QX11GLWindowSurface::setGeometry(const QRect &rect)
bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy)
{
- Q_UNUSED(area);
- Q_UNUSED(dx);
- Q_UNUSED(dy);
- return false;
+ if (m_backBuffer.isNull())
+ return false;
+
+ Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class);
+
+ QX11GLPixmapData* pmd = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data());
+ Q_ASSERT(pmd->context());
+ pmd->context()->makeCurrent();
+ glFinish();
+ eglWaitClient();
+
+ if (!m_pixmapGC)
+ m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);
+
+ foreach (const QRect& rect, area.rects()) {
+ XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC,
+ rect.x(), rect.y(), rect.width(), rect.height(),
+ rect.x()+dx, rect.y()+dy);
+ }
+
+ XSync(X11->display, False);
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+
+ return true;
}
/*
diff --git a/src/opengl/qwindowsurface_x11gl_p.h b/src/opengl/qwindowsurface_x11gl_p.h
index 90f3ad5..3a952e8 100644
--- a/src/opengl/qwindowsurface_x11gl_p.h
+++ b/src/opengl/qwindowsurface_x11gl_p.h
@@ -70,7 +70,8 @@ public:
bool scroll(const QRegion &area, int dx, int dy);
private:
- GC m_GC;
+ GC m_windowGC;
+ GC m_pixmapGC;
QPixmap m_backBuffer;
QWidget *m_window;
};