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:
parent
64fa65df74
commit
95bbf56ff0
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user