Ken Thomases : winemac: Use screen color space for windows covered by OpenGL views.

Alexandre Julliard julliard at winehq.org
Tue Jul 2 14:31:28 CDT 2013


Module: wine
Branch: master
Commit: d30705bdfe1756aa9ac9102a293d96a05afec7b0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d30705bdfe1756aa9ac9102a293d96a05afec7b0

Author: Ken Thomases <ken at codeweavers.com>
Date:   Tue Jul  2 01:24:19 2013 -0500

winemac: Use screen color space for windows covered by OpenGL views.

---

 dlls/winemac.drv/cocoa_window.m |   55 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index 770056e..0e2d7e6 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -158,6 +158,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
 @property (assign, nonatomic) void* imeData;
 @property (nonatomic) BOOL commandDone;
 
+    - (void) updateColorSpace;
+
 @end
 
 
@@ -256,12 +258,14 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             pendingGlContexts = [[NSMutableArray alloc] init];
         [pendingGlContexts addObject:context];
         [self setNeedsDisplay:YES];
+        [(WineWindow*)[self window] updateColorSpace];
     }
 
     - (void) removeGLContext:(WineOpenGLContext*)context
     {
         [glContexts removeObjectIdenticalTo:context];
         [pendingGlContexts removeObjectIdenticalTo:context];
+        [(WineWindow*)[self window] updateColorSpace];
     }
 
     - (void) updateGLContexts
@@ -270,6 +274,11 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             context.needsUpdate = TRUE;
     }
 
+    - (BOOL) hasGLContext
+    {
+        return [glContexts count] || [pendingGlContexts count];
+    }
+
     - (BOOL) acceptsFirstMouse:(NSEvent*)theEvent
     {
         return YES;
@@ -919,7 +928,10 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
                 if (NSEqualSizes(frame.size, oldFrame.size))
                     [self setFrameOrigin:frame.origin];
                 else
+                {
                     [self setFrame:frame display:YES];
+                    [self updateColorSpace];
+                }
 
                 [self updateFullscreen];
 
@@ -1032,6 +1044,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             [self setFrameTopLeftPoint:NSMakePoint(NSMinX(frame), NSMaxY(frame))];
             frame = [self constrainFrameRect:[self frame] toScreen:primaryScreen];
             [self setFrame:frame display:YES];
+            [self updateColorSpace];
         }
 
         if (activate)
@@ -1182,6 +1195,37 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         }
     }
 
+    // We normally use the generic/calibrated RGB color space for the window,
+    // rather than the device color space, to avoid expensive color conversion
+    // which slows down drawing.  However, for windows displaying OpenGL, having
+    // a different color space than the screen greatly reduces frame rates, often
+    // limiting it to the display refresh rate.
+    //
+    // To avoid this, we switch back to the screen color space whenever the
+    // window is covered by a view with an attached OpenGL context.
+    - (void) updateColorSpace
+    {
+        NSRect contentRect = [[self contentView] frame];
+        BOOL coveredByGLView = FALSE;
+        for (WineContentView* view in [[self contentView] subviews])
+        {
+            if ([view hasGLContext])
+            {
+                NSRect frame = [view convertRect:[view bounds] toView:nil];
+                if (NSContainsRect(frame, contentRect))
+                {
+                    coveredByGLView = TRUE;
+                    break;
+                }
+            }
+        }
+
+        if (coveredByGLView)
+            [self setColorSpace:nil];
+        else
+            [self setColorSpace:[NSColorSpace genericRGBColorSpace]];
+    }
+
 
     /*
      * ---------- NSResponder method overrides ----------
@@ -1872,6 +1916,7 @@ macdrv_view macdrv_create_view(macdrv_window w, CGRect rect)
                    name:NSApplicationDidChangeScreenParametersNotification
                  object:NSApp];
         [[window contentView] addSubview:view];
+        [window updateColorSpace];
     });
 
     [pool release];
@@ -1890,6 +1935,7 @@ void macdrv_dispose_view(macdrv_view v)
 
     OnMainThread(^{
         NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+        WineWindow* window = (WineWindow*)[view window];
 
         [nc removeObserver:view
                       name:NSViewGlobalFrameDidChangeNotification
@@ -1899,6 +1945,7 @@ void macdrv_dispose_view(macdrv_view v)
                     object:NSApp];
         [view removeFromSuperview];
         [view release];
+        [window updateColorSpace];
     });
 
     [pool release];
@@ -1923,11 +1970,15 @@ void macdrv_set_view_window_and_frame(macdrv_view v, macdrv_window w, CGRect rec
         BOOL changedWindow = (window && window != [view window]);
         NSRect newFrame = NSRectFromCGRect(rect);
         NSRect oldFrame = [view frame];
+        BOOL needUpdateWindowColorSpace = FALSE;
 
         if (changedWindow)
         {
+            WineWindow* oldWindow = (WineWindow*)[view window];
             [view removeFromSuperview];
+            [oldWindow updateColorSpace];
             [[window contentView] addSubview:view];
+            needUpdateWindowColorSpace = TRUE;
         }
 
         if (!NSEqualRects(oldFrame, newFrame))
@@ -1941,7 +1992,11 @@ void macdrv_set_view_window_and_frame(macdrv_view v, macdrv_window w, CGRect rec
             else
                 [view setFrame:newFrame];
             [view setNeedsDisplay:YES];
+            needUpdateWindowColorSpace = TRUE;
         }
+
+        if (needUpdateWindowColorSpace)
+            [(WineWindow*)[view window] updateColorSpace];
     });
 
     [pool release];




More information about the wine-cvs mailing list