]> git.sesse.net Git - vlc/blobdiff - modules/video_output/ios.m
Fix alignment and appearance of ISO standard equalizer centers in Qt GUI
[vlc] / modules / video_output / ios.m
index 8cd5d19764de85d90db007b9469161031d4cb353..b513911ebdab63c39315f6f7693e6c2462a7b2aa 100644 (file)
@@ -1,10 +1,11 @@
 /*****************************************************************************
- * voutgl.m: iOS X OpenGLES provider
+ * ios.m: iOS X OpenGLES provider
  *****************************************************************************
- * Copyright (C) 2001-2009 the VideoLAN team
+ * Copyright (C) 2010-2013 VLC Authors and VideoLAN
  * $Id$
  *
  * Authors: Romain Goyet <romain.goyet at likid dot org>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +29,8 @@
 #import <UIKit/UIKit.h>
 #import <OpenGLES/ES1/gl.h>
 #import <OpenGLES/ES1/glext.h>
-#include <QuartzCore/QuartzCore.h>
+#import <QuartzCore/QuartzCore.h>
+#import <dlfcn.h>
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -39,8 +41,6 @@
 #include <vlc_vout_display.h>
 #include <vlc_opengl.h>
 
-#define USE_OPENGL_ES 1
-
 #include "opengl.h"
 
 /**
@@ -54,6 +54,8 @@ static void PictureRender(vout_display_t *vd, picture_t *pic, subpicture_t *subp
 static void PictureDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture);
 static int Control (vout_display_t *vd, int query, va_list ap);
 
+static void *OurGetProcAddress(vlc_gl_t *, const char *);
+
 static int OpenglClean(vlc_gl_t *gl);
 static void OpenglSwap(vlc_gl_t *gl);
 
@@ -101,6 +103,13 @@ struct vout_display_sys_t
     bool has_first_frame;
 };
 
+static void *OurGetProcAddress(vlc_gl_t *gl, const char *name)
+{
+    VLC_UNUSED(gl);
+
+    return dlsym(RTLD_DEFAULT, name);
+}
+
 // Called from vout thread
 static int Open(vlc_object_t *this)
 {
@@ -148,11 +157,11 @@ static int Open(vlc_object_t *this)
     sys->gl.lock = OpenglClean; // We don't do locking, but sometimes we need to cleanup the framebuffer
     sys->gl.unlock = NULL;
     sys->gl.swap = OpenglSwap;
-       sys->gl.getProcAddress = NULL;
+    sys->gl.getProcAddress = OurGetProcAddress;
     sys->gl.sys = sys;
 
-       sys->vgl = vout_display_opengl_New(&vd->fmt, &sys->gl);
-       if (!sys->vgl)
+    sys->vgl = vout_display_opengl_New(&vd->fmt, NULL, &sys->gl);
+    if (!sys->vgl)
     {
         sys->gl.sys = NULL;
         goto error;
@@ -171,8 +180,11 @@ static int Open(vlc_object_t *this)
     vd->control = Control;
 
     /* */
+    CGRect bounds = sys->glView.layer.bounds;
+    CGFloat scaleFactor = sys->glView.contentScaleFactor;
+    /* we need to multiply the bounds dimensions by the scaleFactor to be save for Retina Displays */
     vout_display_SendEventFullscreen (vd, false);
-    vout_display_SendEventDisplaySize (vd, vd->source.i_visible_width, vd->source.i_visible_height, false);
+    vout_display_SendEventDisplaySize (vd, bounds.size.width * scaleFactor, bounds.size.height * scaleFactor, false);
 
     return VLC_SUCCESS;
 
@@ -210,10 +222,9 @@ void Close(vlc_object_t *this)
 static picture_pool_t *Pool(vout_display_t *vd, unsigned requested_count)
 {
     vout_display_sys_t *sys = vd->sys;
-    VLC_UNUSED(requested_count);
 
     if (!sys->pool)
-        sys->pool = vout_display_opengl_GetPool (sys->vgl);
+        sys->pool = vout_display_opengl_GetPool (sys->vgl, requested_count);
     assert(sys->pool);
     return sys->pool;
 }
@@ -222,8 +233,7 @@ static void PictureRender(vout_display_t *vd, picture_t *pic, subpicture_t *subp
 {
     vout_display_sys_t *sys = vd->sys;
 
-    vout_display_opengl_Prepare( sys->vgl, pic );
-       (void)subpicture;
+    vout_display_opengl_Prepare( sys->vgl, pic, subpicture );
 }
 
 static void PictureDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
@@ -232,7 +242,7 @@ static void PictureDisplay(vout_display_t *vd, picture_t *pic, subpicture_t *sub
     vout_display_opengl_Display(sys->vgl, &vd->fmt );
     picture_Release (pic);
     sys->has_first_frame = true;
-       (void)subpicture;
+    (void)subpicture;
 }
 
 static int Control (vout_display_t *vd, int query, va_list ap)
@@ -241,15 +251,19 @@ static int Control (vout_display_t *vd, int query, va_list ap)
 
     switch (query)
     {
+        case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
+        {
+            [sys->glView performSelectorOnMainThread:@selector(layoutSubviews) withObject:nil waitUntilDone:NO];
+            return VLC_SUCCESS;
+        }
         case VOUT_DISPLAY_CHANGE_FULLSCREEN:
         case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
         case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
         case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
         case VOUT_DISPLAY_CHANGE_ZOOM:
-        case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
         case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
         {
-            return VLC_EGENERIC;
+            return VLC_SUCCESS;
         }
         case VOUT_DISPLAY_HIDE_MOUSE:
             return VLC_SUCCESS;
@@ -283,7 +297,7 @@ static void OpenglSwap(vlc_gl_t *gl)
 {
     vout_display_sys_t *sys = gl->sys;
     EAGLContext *context = [sys->glView context];
-    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
+    [context presentRenderbuffer:GL_RENDERBUFFER];
 }
 
 /*****************************************************************************
@@ -316,11 +330,10 @@ static void OpenglSwap(vlc_gl_t *gl)
 
         eaglLayer.opaque = TRUE;
         eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
-//                                        [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
-                                        kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat,
+                                        kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
                                         nil];
 
-        _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+        _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
         NSAssert(_context && [EAGLContext setCurrentContext:_context], @"Creating context");
 
         // This shouldn't need to be done on the main thread.
@@ -369,6 +382,11 @@ static void OpenglSwap(vlc_gl_t *gl)
     }
 }
 
+/* we don't get the correct scale factor if we don't overwrite this method */
+- (void) drawRect: (CGRect) rect
+{
+}
+
 @end
 
 @implementation VLCOpenGLESVideoView (Private)
@@ -376,22 +394,22 @@ static void OpenglSwap(vlc_gl_t *gl)
     msg_Dbg(_vd, "Creating framebuffer for layer %p with bounds (%.1f,%.1f,%.1f,%.1f)", self.layer, self.layer.bounds.origin.x, self.layer.bounds.origin.y, self.layer.bounds.size.width, self.layer.bounds.size.height);
     [EAGLContext setCurrentContext:_context];
     // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
-    glGenFramebuffersOES(1, &_defaultFramebuffer); // Generate one framebuffer, store it in _defaultFrameBuffer
-    glGenRenderbuffersOES(1, &_colorRenderbuffer);
-    glBindFramebufferOES(GL_FRAMEBUFFER_OES, _defaultFramebuffer);
-    glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer);
+    glGenFramebuffers(1, &_defaultFramebuffer); // Generate one framebuffer, store it in _defaultFrameBuffer
+    glGenRenderbuffers(1, &_colorRenderbuffer);
+    glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer);
+    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
 
     // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer)
     // allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view).
-    [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
-    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _colorRenderbuffer);
+    [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id<EAGLDrawable>)self.layer];
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer);
 
-    GLuint backingWidth, backingHeight;
-    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
-    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+    GLint backingWidth, backingHeight;
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
 
-    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
-        msg_Err(_vd, "Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+        msg_Err(_vd, "Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
     }
     [self _updateViewportWithBackingWitdh:backingWidth andBackingHeight:backingHeight];
 }
@@ -421,6 +439,15 @@ static void OpenglSwap(vlc_gl_t *gl)
             x = width;
             y = (width * videoHeight * sarDen) / (videoWidth * sarNum);
         }
+
+        @synchronized (self)
+        {
+            vout_display_cfg_t cfg_tmp = *(_vd->cfg);
+            cfg_tmp.display.width  = width;
+            cfg_tmp.display.height = height;
+
+            vout_display_SendEventDisplaySize (_vd, width, height, false);
+        }
     }
 
     [EAGLContext setCurrentContext:_context];
@@ -429,9 +456,9 @@ static void OpenglSwap(vlc_gl_t *gl)
 
 - (void)_destroyFramebuffer {
     [EAGLContext setCurrentContext:_context];
-    glDeleteFramebuffersOES(1, &_defaultFramebuffer);
+    glDeleteFramebuffers(1, &_defaultFramebuffer);
     _defaultFramebuffer = 0;
-    glDeleteRenderbuffersOES(1, &_colorRenderbuffer);
+    glDeleteRenderbuffers(1, &_colorRenderbuffer);
     _colorRenderbuffer = 0;
 }
 @end