Support GL ES 2 with uikit.
authorcon <qtc-committer@nokia.com>
Tue, 19 Apr 2011 14:15:09 +0000 (16:15 +0200)
committerPaul Olav Tvete <paul.tvete@nokia.com>
Wed, 4 May 2011 07:03:49 +0000 (09:03 +0200)
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
src/plugins/platforms/uikit/quikitintegration.mm
src/plugins/platforms/uikit/quikitscreen.mm
src/plugins/platforms/uikit/quikitwindow.h
src/plugins/platforms/uikit/quikitwindow.mm
src/plugins/platforms/uikit/quikitwindowsurface.mm

index 8d2603c..2b9728c 100644 (file)
 - (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<QUIKitWindow *>(widget->platformWindow());
         platformWindow->ensureNativeWindow();
     }
index d4b4192..3a432d1 100644 (file)
@@ -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
index 21494c9..78389f2 100644 (file)
@@ -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;
index 9e73754..5c6496a 100644 (file)
@@ -47,6 +47,8 @@
 #import <UIKit/UIKit.h>
 #import <OpenGLES/ES1/gl.h>
 #import <OpenGLES/ES1/glext.h>
+#import <OpenGLES/ES2/gl.h>
+#import <OpenGLES/ES2/glext.h>
 #import <OpenGLES/EAGL.h>
 
 @interface EAGLView : UIView <UIKeyInput>
@@ -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 ----------
 
 
 @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();
index 52d1846..1f57baa 100644 (file)
@@ -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];
index bb7dcd7..8caa15f 100644 (file)
 
 #include <QtDebug>
 
+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<QUIKitWindow *>(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)