From 95bbf56ff076d003eddf7a7f9f1030d2c683ca01 Mon Sep 17 00:00:00 2001 From: con Date: Tue, 19 Apr 2011 16:15:09 +0200 Subject: [PATCH] Support GL ES 2 with uikit. For GL ES 2 teach the paint device about the fact that it is doing rendering backed by a framebuffer object, not a system framebuffer (which doesn't exist). (cherry picked from commit 3b437a7706efbaaafdc4861393cbe21354cf4ee2) --- src/plugins/platforms/uikit/quikiteventloop.mm | 7 +- src/plugins/platforms/uikit/quikitintegration.mm | 2 +- src/plugins/platforms/uikit/quikitscreen.mm | 4 +- src/plugins/platforms/uikit/quikitwindow.h | 11 +++- src/plugins/platforms/uikit/quikitwindow.mm | 77 +++++++++++++--------- src/plugins/platforms/uikit/quikitwindowsurface.mm | 43 +++++++++++- 6 files changed, 101 insertions(+), 43 deletions(-) diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm index 8d2603c..2b9728c 100644 --- a/src/plugins/platforms/uikit/quikiteventloop.mm +++ b/src/plugins/platforms/uikit/quikiteventloop.mm @@ -69,13 +69,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Q_UNUSED(launchOptions) + Q_UNUSED(application) foreach (QWidget *widget, qApp->topLevelWidgets()) { - QRect geom = widget->geometry(); - CGRect bar = application.statusBarFrame; - if (geom.y() <= bar.size.height) { - geom.setY(bar.size.height); - widget->setGeometry(geom); - } QUIKitWindow *platformWindow = static_cast(widget->platformWindow()); platformWindow->ensureNativeWindow(); } diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm index d4b4192..3a432d1 100644 --- a/src/plugins/platforms/uikit/quikitintegration.mm +++ b/src/plugins/platforms/uikit/quikitintegration.mm @@ -66,7 +66,7 @@ QUIKitIntegration::~QUIKitIntegration() QPixmapData *QUIKitIntegration::createPixmapData(QPixmapData::PixelType type) const { - return new QRasterPixmapData(type); + return new QRasterPixmapData(type); } QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm index 21494c9..78389f2 100644 --- a/src/plugins/platforms/uikit/quikitscreen.mm +++ b/src/plugins/platforms/uikit/quikitscreen.mm @@ -54,7 +54,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex]; CGRect bounds = [screen bounds]; - m_geometry = QRect(0, 0, bounds.size.width, bounds.size.height); + m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); m_format = QImage::Format_ARGB32; @@ -62,7 +62,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) const qreal inch = 25.4; qreal dpi = 160.; - int dragDistance = 14; + int dragDistance = 12; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { dpi = 132.; dragDistance = 10; diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h index 9e73754..5c6496a 100644 --- a/src/plugins/platforms/uikit/quikitwindow.h +++ b/src/plugins/platforms/uikit/quikitwindow.h @@ -47,6 +47,8 @@ #import #import #import +#import +#import #import @interface EAGLView : UIView @@ -59,6 +61,7 @@ GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + id delegate; // ------- Text Input ---------- UITextAutocapitalizationType autocapitalizationType; UITextAutocorrectionType autocorrectionType; @@ -77,6 +80,8 @@ - (void)setWindow:(QPlatformWindow *)window; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; +@property (readonly,getter=fbo) GLint fbo; +@property (nonatomic, assign) id delegate; // ------- Text Input ---------- @@ -90,6 +95,10 @@ @end +@protocol EAGLViewDelegate +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; +@end + class EAGLPlatformContext; QT_BEGIN_NAMESPACE @@ -103,7 +112,7 @@ public: ~QUIKitWindow(); UIWindow *nativeWindow() const { return mWindow; } - UIView *nativeView() const { return mView; } + EAGLView *nativeView() const { return mView; } void setGeometry(const QRect &rect); UIWindow *ensureNativeWindow(); diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm index 52d1846..1f57baa 100644 --- a/src/plugins/platforms/uikit/quikitwindow.mm +++ b/src/plugins/platforms/uikit/quikitwindow.mm @@ -79,7 +79,11 @@ public: mFormat.setStereo(false); mFormat.setDirectRendering(false); +#if defined(QT_OPENGL_ES_2) + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; +#else EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; +#endif [mView setContext:aContext]; } @@ -116,6 +120,8 @@ private: @implementation EAGLView +@synthesize delegate; + + (Class)layerClass { return [CAEAGLLayer class]; @@ -156,8 +162,8 @@ private: { if (mContext) { [EAGLContext setCurrentContext:mContext]; - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer); - [mContext presentRenderbuffer:GL_RENDERBUFFER_OES]; + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext presentRenderbuffer:GL_RENDERBUFFER]; } } @@ -167,15 +173,15 @@ private: { [EAGLContext setCurrentContext:mContext]; if (mFramebuffer) { - glDeleteFramebuffersOES(1, &mFramebuffer); + glDeleteFramebuffers(1, &mFramebuffer); mFramebuffer = 0; } if (mColorRenderbuffer) { - glDeleteRenderbuffersOES(1, &mColorRenderbuffer); + glDeleteRenderbuffers(1, &mColorRenderbuffer); mColorRenderbuffer = 0; } if (mDepthRenderbuffer) { - glDeleteRenderbuffersOES(1, &mDepthRenderbuffer); + glDeleteRenderbuffers(1, &mDepthRenderbuffer); mDepthRenderbuffer = 0; } } @@ -186,24 +192,27 @@ private: if (mContext && !mFramebuffer) { [EAGLContext setCurrentContext:mContext]; - glGenFramebuffersOES(1, &mFramebuffer); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer); - - glGenRenderbuffersOES(1, &mColorRenderbuffer); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer); - [mContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mFramebufferWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mFramebufferHeight); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mColorRenderbuffer); - - glGenRenderbuffersOES(1, &mDepthRenderbuffer); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer); - glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer); - - if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glGenRenderbuffers(1, &mColorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); + + glGenRenderbuffers(1, &mDepthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { + [delegate eaglView:self usesFramebuffer:mFramebuffer]; + } } } @@ -214,11 +223,16 @@ private: [EAGLContext setCurrentContext:mContext]; if (!mFramebuffer) [self createFramebuffer]; - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); } } +- (GLint)fbo +{ + return mFramebuffer; +} + - (void)setWindow:(QPlatformWindow *)window { mWindow = window; @@ -322,6 +336,7 @@ QUIKitWindow::QUIKitWindow(QWidget *tlw) : CGRect screenBounds = [mScreen->uiScreen() bounds]; QRect geom(screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height); setGeometry(geom); + mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; // TODO ensure the native window if the application is already running } @@ -334,7 +349,7 @@ QUIKitWindow::~QUIKitWindow() void QUIKitWindow::setGeometry(const QRect &rect) { - if (mWindow) { + if (mWindow && rect != geometry()) { mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); mView.frame = CGRectMake(0, 0, rect.width(), rect.height()); [mView deleteFramebuffer]; @@ -347,14 +362,16 @@ UIWindow *QUIKitWindow::ensureNativeWindow() { if (!mWindow) { // window - QRect geom = geometry(); - CGRect frame = CGRectMake(geom.x(), geom.y(), geom.width(), geom.height()); - mWindow = [[UIWindow alloc] initWithFrame:frame]; + CGRect frame = [mScreen->uiScreen() applicationFrame]; + QRect geom = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + widget()->setGeometry(geom); + mWindow = [[UIWindow alloc] init]; mWindow.screen = mScreen->uiScreen(); - mWindow.frame = frame; // for some reason setting the screen resets frame.origin + mWindow.frame = frame; // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards // view - mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, geom.width(), geom.height())]; + [mView deleteFramebuffer]; + mView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); // fill [mView setMultipleTouchEnabled:YES]; [mView setWindow:this]; [mWindow addSubview:mView]; diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.mm b/src/plugins/platforms/uikit/quikitwindowsurface.mm index bb7dcd7..8caa15f 100644 --- a/src/plugins/platforms/uikit/quikitwindowsurface.mm +++ b/src/plugins/platforms/uikit/quikitwindowsurface.mm @@ -47,27 +47,64 @@ #include +class EAGLPaintDevice; + +@interface PaintDeviceHelper : NSObject { + EAGLPaintDevice *device; +} + +@property (nonatomic, assign) EAGLPaintDevice *device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; + +@end + class EAGLPaintDevice : public QGLPaintDevice { public: EAGLPaintDevice(QPlatformWindow *window) :QGLPaintDevice(), mWindow(window) { +#if defined(QT_OPENGL_ES_2) + helper = [[PaintDeviceHelper alloc] init]; + helper.device = this; + EAGLView *view = static_cast(window)->nativeView(); + view.delegate = helper; + m_thisFBO = view.fbo; +#endif } + ~EAGLPaintDevice() + { +#if defined(QT_OPENGL_ES_2) + [helper release]; +#endif + } + + void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } int devType() const { return QInternal::OpenGL; } QSize size() const { return mWindow->geometry().size(); } QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); } QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } - void beginPaint(){ - QGLPaintDevice::beginPaint(); - } private: QPlatformWindow *mWindow; + PaintDeviceHelper *helper; }; +@implementation PaintDeviceHelper +@synthesize device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +{ + Q_UNUSED(view) + if (device) + device->setFramebuffer(buffer); +} + +@end + QT_BEGIN_NAMESPACE QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window) -- 2.7.4