]> git.sesse.net Git - vlc/blobdiff - modules/video_output/caopengllayer.m
Win32 Vout: if a crop/aspect ratio is received, force the texture update
[vlc] / modules / video_output / caopengllayer.m
index a867bb67e75e2800351ae69f789bd60dac1b2e85..6e80ec91fbb510584820d786e122c298b8fef2d9 100644 (file)
@@ -120,16 +120,7 @@ static int Open (vlc_object_t *p_this)
     if (container)
         vout_display_DeleteWindow(vd, NULL);
     else {
-        vout_window_cfg_t wnd_cfg;
-
-        memset(&wnd_cfg, 0, sizeof(wnd_cfg));
-        wnd_cfg.type = VOUT_WINDOW_TYPE_NSOBJECT;
-        wnd_cfg.x = var_InheritInteger(vd, "video-x");
-        wnd_cfg.y = var_InheritInteger(vd, "video-y");
-        wnd_cfg.height = vd->cfg->display.height;
-        wnd_cfg.width = vd->cfg->display.width;
-
-        sys->embed = vout_display_NewWindow(vd, &wnd_cfg);
+        sys->embed = vout_display_NewWindow(vd, VOUT_WINDOW_TYPE_NSOBJECT);
         if (sys->embed)
             container = sys->embed->handle.nsobject;
 
@@ -142,29 +133,32 @@ static int Open (vlc_object_t *p_this)
     /* store for later, released in Close() */
     sys->container = [container retain];
 
-       dispatch_sync(dispatch_get_main_queue(), ^{
-               [CATransaction begin];
-               sys->cgLayer = [[VLCCAOpenGLLayer alloc] init];
-               [sys->cgLayer setVoutDisplay:vd];
-               [sys->cgLayer display];         // TODO: Find a better way to wait until we get a context
-           if ([container respondsToSelector:@selector(addVoutLayer:)]) {
-               msg_Dbg(vd, "container implements implicit protocol");
-               [container addVoutLayer:sys->cgLayer];
-           } else if ([container respondsToSelector:@selector(addSublayer:)] || [container isKindOfClass:[CALayer class]]) {
-               msg_Dbg(vd, "container doesn't implement implicit protocol, fallback mode used");
-               [container addSublayer:sys->cgLayer];
-           } else {
-               msg_Err(vd, "Provided NSObject container isn't compatible");
-                       [sys->cgLayer release];
-                       sys->cgLayer = nil;
-           }
-               [CATransaction commit];
-       });
+    [CATransaction begin];
+    sys->cgLayer = [[VLCCAOpenGLLayer alloc] init];
+    [sys->cgLayer setVoutDisplay:vd];
+
+    [sys->cgLayer performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:YES];
+
+    if ([container respondsToSelector:@selector(addVoutLayer:)]) {
+        msg_Dbg(vd, "container implements implicit protocol");
+        [container addVoutLayer:sys->cgLayer];
+    } else if ([container respondsToSelector:@selector(addSublayer:)] || [container isKindOfClass:[CALayer class]]) {
+        msg_Dbg(vd, "container doesn't implement implicit protocol, fallback mode used");
+        [container addSublayer:sys->cgLayer];
+    } else {
+        msg_Err(vd, "Provided NSObject container isn't compatible");
+        [sys->cgLayer release];
+        sys->cgLayer = nil;
+        [CATransaction commit];
+        goto bailout;
+    }
+    [CATransaction commit];
 
     if (!sys->cgLayer)
         goto bailout;
 
-    assert(sys->glContext);
+    if (!sys->glContext)
+        msg_Warn(vd, "we might not have an OpenGL context yet");
 
     /* Initialize common OpenGL video display */
     sys->gl.lock = OpenglLock;
@@ -185,7 +179,7 @@ static int Open (vlc_object_t *p_this)
     /* setup vout display */
     vout_display_info_t info = vd->info;
     info.subpicture_chromas = subpicture_chromas;
-    info.has_hide_mouse = false;
+    info.has_hide_mouse = true;
     vd->info = info;
 
     vd->pool    = Pool;
@@ -200,7 +194,7 @@ static int Open (vlc_object_t *p_this)
     else
         outputSize = [sys->container visibleRect].size;
     vout_display_SendEventFullscreen(vd, false);
-    vout_display_SendEventDisplaySize(vd, (int)outputSize.width, (int)outputSize.height, false);
+    vout_display_SendEventDisplaySize(vd, (int)outputSize.width, (int)outputSize.height);
 
     [pool release];
     return VLC_SUCCESS;
@@ -253,6 +247,11 @@ static void PictureRender (vout_display_t *vd, picture_t *pic, subpicture_t *sub
 {
     vout_display_sys_t *sys = vd->sys;
 
+    if (pic == NULL) {
+        msg_Warn(vd, "invalid pic, skipping frame");
+        return;
+    }
+
     @synchronized (sys->cgLayer) {
         vout_display_opengl_Prepare(sys->vgl, pic, subpicture);
     }
@@ -292,7 +291,6 @@ static int Control (vout_display_t *vd, int query, va_list ap)
         case VOUT_DISPLAY_CHANGE_ZOOM:
         case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
         case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
-        case VOUT_DISPLAY_CHANGE_FULLSCREEN:
         {
             const vout_display_cfg_t *cfg;
             const video_format_t *source;
@@ -308,7 +306,7 @@ static int Control (vout_display_t *vd, int query, va_list ap)
             /* we always use our current frame here */
             vout_display_cfg_t cfg_tmp = *cfg;
             [CATransaction lock];
-            CGRect bounds = [sys->cgLayer bounds];
+            CGRect bounds = [sys->cgLayer visibleRect];
             [CATransaction unlock];
             cfg_tmp.display.width = bounds.size.width;
             cfg_tmp.display.height = bounds.size.height;
@@ -320,17 +318,22 @@ static int Control (vout_display_t *vd, int query, va_list ap)
             return VLC_SUCCESS;
         }
 
-        case VOUT_DISPLAY_GET_OPENGL:
+        case VOUT_DISPLAY_HIDE_MOUSE:
+        {
+            [NSCursor setHiddenUntilMouseMoves: YES];
+            return VLC_SUCCESS;
+        }
+
+        case VOUT_DISPLAY_CHANGE_WINDOW_STATE:
         {
-            vlc_gl_t **gl = va_arg (ap, vlc_gl_t **);
-            *gl = &sys->gl;
             return VLC_SUCCESS;
         }
 
         case VOUT_DISPLAY_RESET_PICTURES:
-            assert (0);
+            vlc_assert_unreachable ();
         default:
             msg_Err (vd, "Unhandled request %d", query);
+        case VOUT_DISPLAY_CHANGE_FULLSCREEN:
             return VLC_EGENERIC;
     }
 
@@ -392,7 +395,8 @@ static void *OurGetProcAddress (vlc_gl_t *gl, const char *name)
     self = [super init];
     if (self) {
         [CATransaction lock];
-        [self setAutoresizingMask: kCALayerWidthSizable | kCALayerHeightSizable];
+        self.needsDisplayOnBoundsChange = YES;
+        self.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
         self.asynchronous = NO;
         [CATransaction unlock];
     }
@@ -409,9 +413,10 @@ static void *OurGetProcAddress (vlc_gl_t *gl, const char *name)
 {
     [super resizeWithOldSuperlayerSize: size];
 
-    CGRect bounds = self.bounds;
+    CGSize boundsSize = self.visibleRect.size;
+
     if (_vd)
-        vout_display_SendEventDisplaySize(_vd, bounds.size.width, bounds.size.height, _vd->cfg->is_fullscreen);
+        vout_display_SendEventDisplaySize(_vd, boundsSize.width, boundsSize.height);
 }
 
 - (BOOL)canDrawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
@@ -432,7 +437,8 @@ static void *OurGetProcAddress (vlc_gl_t *gl, const char *name)
     if (!sys->vgl)
         return;
 
-    CGRect bounds = [self bounds];
+    CGRect bounds = [self visibleRect];
+
     // x / y are top left corner, but we need the lower left one
     glViewport (sys->place.x, bounds.size.height - (sys->place.y + sys->place.height), sys->place.width, sys->place.height);
 
@@ -471,4 +477,45 @@ static void *OurGetProcAddress (vlc_gl_t *gl, const char *name)
     // do not release anything here, we do that when closing the module
 }
 
+- (void)mouseButtonDown:(int)buttonNumber
+{
+    @synchronized (self) {
+        if (_vd) {
+            if (buttonNumber == 0)
+                vout_display_SendEventMousePressed (_vd, MOUSE_BUTTON_LEFT);
+            else if (buttonNumber == 1)
+                vout_display_SendEventMousePressed (_vd, MOUSE_BUTTON_RIGHT);
+            else
+                vout_display_SendEventMousePressed (_vd, MOUSE_BUTTON_CENTER);
+        }
+    }
+}
+
+- (void)mouseButtonUp:(int)buttonNumber
+{
+    @synchronized (self) {
+        if (_vd) {
+            if (buttonNumber == 0)
+                vout_display_SendEventMouseReleased (_vd, MOUSE_BUTTON_LEFT);
+            else if (buttonNumber == 1)
+                vout_display_SendEventMouseReleased (_vd, MOUSE_BUTTON_RIGHT);
+            else
+                vout_display_SendEventMouseReleased (_vd, MOUSE_BUTTON_CENTER);
+        }
+    }
+}
+
+- (void)mouseMovedToX:(double)xValue Y:(double)yValue
+{
+    @synchronized (self) {
+        if (_vd) {
+            vout_display_SendMouseMovedDisplayCoordinates (_vd,
+                                                           ORIENT_NORMAL,
+                                                           xValue,
+                                                           yValue,
+                                                           &_vd->sys->place);
+        }
+    }
+}
+
 @end