diff options
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qglbuffer.cpp | 32 | ||||
-rw-r--r-- | src/opengl/qglbuffer.h | 2 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_x11gl_egl.cpp | 72 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_x11gl_p.h | 5 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_x11gl.cpp | 54 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_x11gl_p.h | 3 |
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; }; |