summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-06-07 17:25:22 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-06-10 09:24:56 +0200
commit4a189c188ccd2fb5f8d1d5ddadf06cbd6bc0916f (patch)
tree99bff9f015e869b5521836ea5667590939b22a53 /src/plugins/platforms/cocoa
parent4d10e64f2a78e32418a98e1c80c6579ae0779dfc (diff)
QWindowContext / QWindowFormat refactor.
To enable having a single GL context used for multiple drawables we need to de-couple the context class a bit more from the window class in the plugin API. Now contexts are created stand-alone based on a GL format and a share context, and when calling makeCurrent() a desired surface is specified. This maps well to GLX, EGL, Cocoa, AGL, and WGL, which all support this use case. QWindowContext is renamed to QGuiGLContext, and QWindowFormat is renamed to QGuiGLFormat. We have the ability to introduce a pbuffer or similar other offscreen GL drawable abstraction in the future.
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h40
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm92
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm35
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h3
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm8
9 files changed, 149 insertions, 53 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
index 4d330a4294..01d931b662 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -1,26 +1,52 @@
#ifndef QCOCOAGLCONTEXT_H
#define QCOCOAGLCONTEXT_H
+#include <QtCore/QWeakPointer>
#include <QtGui/QPlatformGLContext>
-#include <QtGui/QWindowFormat>
+#include <QtGui/QGuiGLContext>
+#include <QtGui/QWindow>
#include <Cocoa/Cocoa.h>
QT_BEGIN_NAMESPACE
+class QCocoaGLSurface : public QPlatformGLSurface
+{
+public:
+ QCocoaGLSurface(const QGuiGLFormat &format, QWindow *window)
+ : QPlatformGLSurface(format)
+ , window(window)
+ {
+ }
+
+ QWindow *window;
+};
+
class QCocoaGLContext : public QPlatformGLContext
{
public:
- QCocoaGLContext(NSOpenGLView *glView);
- void makeCurrent();
+ QCocoaGLContext(const QGuiGLFormat &format, QPlatformGLContext *share);
+
+ QGuiGLFormat format() const;
+
+ void swapBuffers(const QPlatformGLSurface &surface);
+
+ bool makeCurrent(const QPlatformGLSurface &surface);
void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
- QWindowFormat windowFormat() const;
+
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ void update();
+
static NSOpenGLPixelFormat *createNSOpenGLPixelFormat();
NSOpenGLContext *nsOpenGLContext() const;
+
private:
- NSOpenGLView *m_glView;
+ void setActiveWindow(QWindow *window);
+
+ NSOpenGLContext *m_context;
+ QGuiGLFormat m_format;
+ QWeakPointer<QWindow> m_currentWindow;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 3a87537e64..f9cda1bb37 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -1,66 +1,88 @@
#include "qcocoaglcontext.h"
+#include "qcocoawindow.h"
#include <qdebug.h>
#include <QtCore/private/qcore_mac_p.h>
#import <Cocoa/Cocoa.h>
-QCocoaGLContext::QCocoaGLContext(NSOpenGLView *glView)
-:m_glView(glView)
+QCocoaGLContext::QCocoaGLContext(const QGuiGLFormat &format, QPlatformGLContext *share)
+ : m_format(format)
{
+ NSOpenGLPixelFormat *pixelFormat = createNSOpenGLPixelFormat();
+ NSOpenGLContext *actualShare = share ? static_cast<QCocoaGLContext *>(share)->m_context : 0;
+ m_context = [NSOpenGLContext alloc];
+ [m_context initWithFormat:pixelFormat shareContext:actualShare];
}
-void QCocoaGLContext::makeCurrent()
+// Match up with createNSOpenGLPixelFormat!
+QGuiGLFormat QCocoaGLContext::format() const
{
- [[m_glView openGLContext] makeCurrentContext];
+ return m_format;
}
-void QCocoaGLContext::doneCurrent()
+
+void QCocoaGLContext::swapBuffers(const QPlatformGLSurface &surface)
{
- [NSOpenGLContext clearCurrentContext];
+ QWindow *window = static_cast<const QCocoaGLSurface &>(surface).window;
+ setActiveWindow(window);
+
+ [m_context flushBuffer];
+}
+
+bool QCocoaGLContext::makeCurrent(const QPlatformGLSurface &surface)
+{
+ QWindow *window = static_cast<const QCocoaGLSurface &>(surface).window;
+ setActiveWindow(window);
+
+ [m_context makeCurrentContext];
+ return true;
+}
+
+void QCocoaGLContext::setActiveWindow(QWindow *window)
+{
+ if (window == m_currentWindow.data())
+ return;
+
+ if (m_currentWindow)
+ static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+
+ Q_ASSERT(window->handle());
+
+ m_currentWindow = window;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ cocoaWindow->setCurrentContext(this);
+
+ NSView *view = cocoaWindow->windowSurfaceView();
+ [m_context setView:view];
}
-void QCocoaGLContext::swapBuffers()
+void QCocoaGLContext::doneCurrent()
{
- [[m_glView openGLContext] flushBuffer];
+ if (m_currentWindow)
+ static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+
+ m_currentWindow.clear();
+
+ [NSOpenGLContext clearCurrentContext];
}
-void* QCocoaGLContext::getProcAddress(const QString& procName)
+void (*QCocoaGLContext::getProcAddress(const QByteArray &procName)) ()
{
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, false);
CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url);
- CFStringRef procNameCF = QCFString::toCFStringRef(procName);
+ CFStringRef procNameCF = QCFString::toCFStringRef(QString::fromAscii(procName.constData()));
void *proc = CFBundleGetFunctionPointerForName(bundle, procNameCF);
CFRelease(url);
CFRelease(bundle);
CFRelease(procNameCF);
- return proc;
+ return (void (*) ())proc;
}
-// Match up with createNSOpenGLPixelFormat below!
-QWindowFormat QCocoaGLContext::windowFormat() const
+void QCocoaGLContext::update()
{
- QWindowFormat format;
- format.setRedBufferSize(8);
- format.setGreenBufferSize(8);
- format.setBlueBufferSize(8);
- format.setAlphaBufferSize(8);
-
-/*
- format.setDepthBufferSize(24);
- format.setAccumBufferSize(0);
- format.setStencilBufferSize(8);
- format.setSampleBuffers(false);
- format.setSamples(1);
- format.setDepth(true);
- format.setRgba(true);
- format.setAlpha(true);
- format.setAccum(false);
- format.setStencil(true);
- format.setStereo(false);
- format.setDirectRendering(false);
-*/
- return format;
+ [m_context update];
}
NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat()
@@ -78,6 +100,6 @@ NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat()
NSOpenGLContext *QCocoaGLContext::nsOpenGLContext() const
{
- return [m_glView openGLContext];
+ return m_context;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 3e705e7805..59008b4e3f 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -78,6 +78,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
QWindowSurface *createWindowSurface(QWindow *widget, WId winId) const;
QList<QPlatformScreen *> screens() const { return mScreens; }
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 42ec268964..dfe225ff2e 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -113,6 +113,11 @@ QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const
return new QCocoaWindow(window);
}
+QPlatformGLContext *QCocoaIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+ return new QCocoaGLContext(glFormat, share);
+}
+
QWindowSurface *QCocoaIntegration::createWindowSurface(QWindow *window, WId winId) const
{
return new QCocoaWindowSurface(window, winId);
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 6b86108f75..87d0ec4a0c 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -41,19 +41,20 @@
#include "qcocoanativeinterface.h"
#include "qcocoaglcontext.h"
+#include "qcocoawindow.h"
#include <qbytearray.h>
#include <qwindow.h>
#include "qplatformwindow_qpa.h"
-#include "qwindowformat_qpa.h"
+#include "qguiglformat_qpa.h"
#include "qplatformglcontext_qpa.h"
-#include "qwindowcontext_qpa.h"
+#include "qguiglcontext_qpa.h"
#include <qdebug.h>
void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
if (resourceString == "nsopenglcontext") {
- QPlatformGLContext *platformContext = window->glContext()->handle();
- return static_cast<QCocoaGLContext *>(platformContext)->nsOpenGLContext();
+
+ static_cast<QCocoaWindow *>(window->handle())->currentContext()->nsOpenGLContext();
}
return 0;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index dcf755d009..9d7d37c2ee 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -65,17 +65,22 @@ public:
WId winId() const;
NSView *contentView() const;
+ NSView *windowSurfaceView() const;
+ void windowDidMove();
void windowDidResize();
- QPlatformGLContext *glContext() const;
+ QPlatformGLSurface *createGLSurface() const;
+
+ void setCurrentContext(QCocoaGLContext *context);
+ QCocoaGLContext *currentContext() const;
private:
friend class QCocoaWindowSurface;
NSWindow *m_nsWindow;
QNSView *m_contentView;
NSView *m_windowSurfaceView;
- mutable QCocoaGLContext *m_glContext;
+ QCocoaGLContext *m_glContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index a5ad8c87ae..874790a128 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -84,6 +84,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
QCocoaWindow::~QCocoaWindow()
{
+
}
void QCocoaWindow::setGeometry(const QRect &rect)
@@ -92,6 +93,9 @@ void QCocoaWindow::setGeometry(const QRect &rect)
NSRect bounds = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
[[m_nsWindow contentView]setFrameSize:bounds.size];
+
+ if (m_glContext)
+ m_glContext->update();
}
void QCocoaWindow::setVisible(bool visible)
@@ -131,18 +135,41 @@ NSView *QCocoaWindow::contentView() const
return [m_nsWindow contentView];
}
+NSView *QCocoaWindow::windowSurfaceView() const
+{
+ return m_windowSurfaceView;
+}
+
+void QCocoaWindow::windowDidMove()
+{
+ if (m_glContext)
+ m_glContext->update();
+}
+
void QCocoaWindow::windowDidResize()
{
//jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing...
NSRect rect = [[m_nsWindow contentView]frame];
QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
QWindowSystemInterface::handleGeometryChange(window(),geo);
+
+ if (m_glContext)
+ m_glContext->update();
}
-QPlatformGLContext *QCocoaWindow::glContext() const
+QPlatformGLSurface *QCocoaWindow::createGLSurface() const
+{
+ Q_ASSERT(window()->surfaceType() == QWindow::OpenGLSurface);
+ return new QCocoaGLSurface(window()->glFormat(), window());
+}
+
+void QCocoaWindow::setCurrentContext(QCocoaGLContext *context)
+{
+ m_glContext = context;
+}
+
+QCocoaGLContext *QCocoaWindow::currentContext() const
{
- if (!m_glContext) {
- m_glContext = new QCocoaGLContext(m_windowSurfaceView);
- }
return m_glContext;
}
+
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index 1ea02ac016..5cd226a71d 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -53,7 +53,7 @@
- (void)windowDidResize:(NSNotification *)notification;
- (void)windowWillClose:(NSNotification *)notification;
//- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame;
-//- (void)windowDidMove:(NSNotification *)notification;
+- (void)windowDidMove:(NSNotification *)notification;
//- (BOOL)windowShouldClose:(id)window;
//- (void)windowDidDeminiaturize:(NSNotification *)notification;
//- (void)windowDidBecomeMain:(NSNotification*)notification;
@@ -74,6 +74,7 @@
- (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow;
- (void)windowDidResize:(NSNotification *)notification;
+- (void)windowDidMove:(NSNotification *)notification;
- (void)windowWillClose:(NSNotification *)notification;
@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 54def7e592..6521db5cf7 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -64,6 +64,14 @@
}
}
+- (void)windowDidMove:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowDidMove();
+ }
+}
+
- (void)windowWillClose:(NSNotification *)notification
{
Q_UNUSED(notification);