X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=OSX%2FXScreenSaverGLView.m;h=da77021c89f63f489970a054f7b1d8e30d03edcb;hb=7edd66e6bd3209013ee059819747b10b5835635b;hp=f7a58c481bd4f04d2c287fde7092d5ac2e6d9ac1;hpb=f8cf5ac7b2f53510f80a0eaf286a25298be17bfe;p=xscreensaver diff --git a/OSX/XScreenSaverGLView.m b/OSX/XScreenSaverGLView.m index f7a58c48..da77021c 100644 --- a/OSX/XScreenSaverGLView.m +++ b/OSX/XScreenSaverGLView.m @@ -1,13 +1,13 @@ -/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski -* -* Permission to use, copy, modify, distribute, and sell this software and its -* documentation for any purpose is hereby granted without fee, provided that -* the above copyright notice appear in all copies and that both that -* copyright notice and this permission notice appear in supporting -* documentation. No representations are made about the suitability of this -* software for any purpose. It is provided "as is" without express or -* implied warranty. -*/ +/* xscreensaver, Copyright (c) 2006-2014 Jamie Zawinski + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ /* This is a subclass of Apple's ScreenSaverView that knows how to run xscreensaver programs without X11 via the dark magic of the "jwxyz" @@ -47,6 +47,8 @@ extern void check_gl_error (const char *type); # ifndef USE_IPHONE [NSOpenGLContext clearCurrentContext]; # endif // !USE_IPHONE + + clear_gl_error(); // This hack is defunct, don't let this linger. } @@ -80,6 +82,22 @@ extern void check_gl_error (const char *type); } +#ifdef USE_IPHONE +/* With GL programs, drawing at full resolution isn't a problem. + */ +- (CGFloat) hackedContentScaleFactor +{ + NSSize ssize = [[[UIScreen mainScreen] currentMode] size]; + NSSize bsize = [self bounds].size; + + // Ratio of screen size in pixels to view size in points. + GLfloat s = ((ssize.width > ssize.height ? ssize.width : ssize.height) / + (bsize.width > bsize.height ? bsize.width : bsize.height)); + return s; +} +#endif // USE_IPHONE + + - (void) setOglContext: (NSOpenGLContext *) ctx { ogl_ctx = ctx; @@ -87,9 +105,9 @@ extern void check_gl_error (const char *type); # ifdef USE_IPHONE [EAGLContext setCurrentContext: ogl_ctx]; - double s = self.contentScaleFactor; - int w = s * [self frame].size.width; - int h = s * [self frame].size.height; + double s = [self hackedContentScaleFactor]; + int w = s * [self bounds].size.width; + int h = s * [self bounds].size.height; if (gl_framebuffer) glDeleteFramebuffersOES (1, &gl_framebuffer); if (gl_renderbuffer) glDeleteRenderbuffersOES (1, &gl_renderbuffer); @@ -171,11 +189,21 @@ extern void check_gl_error (const char *type); return [CAEAGLLayer class]; } +- (void) swapBuffers +{ + glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer); + [ogl_ctx presentRenderbuffer:GL_RENDERBUFFER_OES]; +} +#endif // USE_IPHONE + + +#ifdef USE_BACKBUFFER + +- (void) initLayer +{ + // Do nothing. +} -/* On MacOS: drawRect does nothing, and animateOneFrame renders. - On iOS GL: drawRect does nothing, and animateOneFrame renders. - On iOS X11: drawRect renders, and animateOneFrame marks the view dirty. - */ - (void)drawRect:(NSRect)rect { } @@ -183,9 +211,15 @@ extern void check_gl_error (const char *type); - (void) animateOneFrame { +# ifdef USE_IPHONE UIGraphicsPushContext (backbuffer); +# endif + [self render_x11]; + +# ifdef USE_IPHONE UIGraphicsPopContext(); +# endif } @@ -195,34 +229,31 @@ extern void check_gl_error (const char *type); and discarded. That's ok, though, because mostly it's just calls to XClearWindow and housekeeping stuff like that. So we make a tiny one. */ -- (void) createBackbuffer +- (void) createBackbuffer:(CGSize)new_size { - // Don't resize the X11 window to match rotation. - // Rotation and scaling are handled in GL. - // - NSRect f = [self frame]; - double s = self.contentScaleFactor; - backbuffer_size.width = (int) (s * f.size.width); - backbuffer_size.height = (int) (s * f.size.height); + backbuffer_size = new_size; if (! backbuffer) { CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); int w = 8; int h = 8; - backbuffer = CGBitmapContextCreate (NULL, w, h, + backbuffer = CGBitmapContextCreate (NULL, w, h, // yup, only 8px x 8px. 8, w*4, cs, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease (cs); } } +# endif // USE_BACKBUFFER -- (void) swapBuffers +/* When changing the device orientation, leave the X11 Window and glViewport + in portrait configuration. OpenGL hacks examine current_device_rotation() + within the scene as needed. + */ +- (BOOL)reshapeRotatedWindow { - glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer); - [ogl_ctx presentRenderbuffer:GL_RENDERBUFFER_OES]; + return NO; } -# endif // USE_IPHONE - (void)dealloc { @@ -240,14 +271,19 @@ extern void check_gl_error (const char *type); */ -// redefine these now since they don't work when not inside an ObjC method. +// redefine NSAssert, etc. here since they don't work when not inside +// an ObjC method. #undef NSAssert #undef NSAssert1 #undef NSAssert2 -#define NSAssert(CC,S) do { if (!(CC)) { NSLog(S); abort();}} while(0) -#define NSAssert1(CC,S,A) do { if (!(CC)) { NSLog(S,A); abort();}} while(0) -#define NSAssert2(CC,S,A,B) do { if (!(CC)) { NSLog(S,A,B);abort();}} while(0) +#define NSASS(S) \ + jwxyz_abort ("%s", [(S) cStringUsingEncoding:NSUTF8StringEncoding]) +#define NSAssert(CC,S) do { if (!(CC)) { NSASS((S)); }} while(0) +#define NSAssert1(CC,S,A) do { if (!(CC)) { \ + NSASS(([NSString stringWithFormat: S, A])); }} while(0) +#define NSAssert2(CC,S,A,B) do { if (!(CC)) { \ + NSASS(([NSString stringWithFormat: S, A, B])); }} while(0) /* Called by OpenGL savers using the XLockmore API. @@ -308,6 +344,7 @@ init_GL (ModeInfo *mi) NSAssert (pixfmt, @"unable to create NSOpenGLPixelFormat"); + // #### Analyze says: "Potential leak of an object stored into pixfmt" ctx = [[NSOpenGLContext alloc] initWithFormat:pixfmt shareContext:nil]; @@ -319,9 +356,8 @@ init_GL (ModeInfo *mi) [ctx setValues:&r forParameter:NSOpenGLCPSwapInterval]; // check_gl_error ("NSOpenGLCPSwapInterval"); // SEGV sometimes. Too early? - // #### "Build and Analyze" says that ctx leaks, because it doesn't - // seem to realize that makeCurrentContext retains it (right?) - // Not sure what to do to make this warning go away. + // #### Analyze says: "Potential leak of an object stored into "ctx" + // But makeCurrentContext retains it (right?) [ctx makeCurrentContext]; check_gl_error ("makeCurrentContext"); @@ -367,9 +403,12 @@ init_GL (ModeInfo *mi) eagl_layer.opaque = TRUE; eagl_layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, - [NSNumber numberWithBool:!dbuf_p], kEAGLDrawablePropertyRetainedBacking, - nil]; + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, + [NSNumber numberWithBool:!dbuf_p], kEAGLDrawablePropertyRetainedBacking, + nil]; + + // Without this, the GL frame buffer is half the screen resolution! + eagl_layer.contentsScale = [UIScreen mainScreen].scale; ogl_ctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; } @@ -377,11 +416,25 @@ init_GL (ModeInfo *mi) if (!ogl_ctx) return 0; [view setOglContext:ogl_ctx]; + // #### Analyze says "Potential leak of an object stored into ogl_ctx" check_gl_error ("OES_init"); + jwzgles_reset (); + # endif // USE_IPHONE + // I don't know why this is necessary, but it beats randomly having some + // textures be upside down. + // + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Caller expects a pointer to an opaque struct... which it dereferences. // Don't ask me, it's historical... static int blort = -1;