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)
This commit is contained in:
con 2011-04-19 16:15:09 +02:00 committed by Paul Olav Tvete
parent 64fa65df74
commit 95bbf56ff0
6 changed files with 98 additions and 40 deletions

View File

@ -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<QUIKitWindow *>(widget->platformWindow());
platformWindow->ensureNativeWindow();
}

View 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

View 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;

View 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 ----------
@ -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();

View 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);
glGenFramebuffers(1, &mFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, 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);
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);
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);
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 (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
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];

View File

@ -47,27 +47,64 @@
#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)