Changeset 179637 in webkit


Ignore:
Timestamp:
Feb 4, 2015 2:38:46 PM (9 years ago)
Author:
Simon Fraser
Message:

LayoutTestHelper should set the color profile of all displays
https://bugs.webkit.org/show_bug.cgi?id=141260

Reviewed by Tim Horton.

WebKitTestRunner can (erroneously) grab the colorspace of the "main" screen.
which is the screen with the active window. Make things more robust by changing
the colorspace of all displays, not just the main screen, when running layout tests.

  • DumpRenderTree/mac/Configurations/LayoutTestHelper.xcconfig: Enable ARC
  • DumpRenderTree/mac/LayoutTestHelper.m:

(originalColorProfileURLs):
(colorProfileURLForDisplay):
(displayUUIDStrings):
(saveDisplayColorProfiles):
(setDisplayColorProfile):
(restoreDisplayColorProfiles):
(installLayoutTestColorProfile):
(restoreUserColorProfile):
(main):
Store display color profiles by map of UUID strings to URLs (NSUUID and CFUUID are not
toll-free bridged, sadly). Use the map to restore all profiles on exit.
Convert to use more Obj-C types.

Location:
trunk/Tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r179629 r179637  
     12015-02-04  Simon Fraser  <simon.fraser@apple.com>
     2
     3        LayoutTestHelper should set the color profile of all displays
     4        https://bugs.webkit.org/show_bug.cgi?id=141260
     5
     6        Reviewed by Tim Horton.
     7       
     8        WebKitTestRunner can (erroneously) grab the colorspace of the "main" screen.
     9        which is the screen with the active window. Make things more robust by changing
     10        the colorspace of all displays, not just the main screen, when running layout tests.
     11
     12        * DumpRenderTree/mac/Configurations/LayoutTestHelper.xcconfig: Enable ARC
     13        * DumpRenderTree/mac/LayoutTestHelper.m:
     14        (originalColorProfileURLs):
     15        (colorProfileURLForDisplay):
     16        (displayUUIDStrings):
     17        (saveDisplayColorProfiles):
     18        (setDisplayColorProfile):
     19        (restoreDisplayColorProfiles):
     20        (installLayoutTestColorProfile):
     21        (restoreUserColorProfile):
     22        (main):       
     23        Store display color profiles by map of UUID strings to URLs (NSUUID and CFUUID are not
     24        toll-free bridged, sadly). Use the map to restore all profiles on exit.
     25        Convert to use more Obj-C types.
     26
    1272015-02-04  Daniel Bates  <dabates@apple.com>
    228
  • trunk/Tools/DumpRenderTree/mac/LayoutTestHelper.m

    r171277 r179637  
    4646static int installColorProfile = false;
    4747
    48 static CFURLRef sUserColorProfileURL;
     48static NSMutableDictionary *originalColorProfileURLs()
     49{
     50    static NSMutableDictionary *sharedInstance;
     51    if (!sharedInstance)
     52        sharedInstance = [[NSMutableDictionary alloc] init];
     53    return sharedInstance;
     54}
     55
     56static NSURL *colorProfileURLForDisplay(NSString *displayUUIDString)
     57{
     58    CFUUIDRef uuid = CFUUIDCreateFromString(kCFAllocatorDefault, (CFStringRef)displayUUIDString);
     59    CFDictionaryRef deviceInfo = ColorSyncDeviceCopyDeviceInfo(kColorSyncDisplayDeviceClass, uuid);
     60    CFRelease(uuid);
     61    if (!deviceInfo) {
     62        NSLog(@"No display attached to system; not setting main display's color profile.");
     63        return nil;
     64    }
     65
     66    CFURLRef profileURL;
     67    CFDictionaryRef profileInfo = (CFDictionaryRef)CFDictionaryGetValue(deviceInfo, kColorSyncCustomProfiles);
     68    if (profileInfo)
     69        profileURL = (CFURLRef)CFDictionaryGetValue(profileInfo, CFSTR("1"));
     70    else {
     71        profileInfo = (CFDictionaryRef)CFDictionaryGetValue(deviceInfo, kColorSyncFactoryProfiles);
     72        CFDictionaryRef factoryProfile = (CFDictionaryRef)CFDictionaryGetValue(profileInfo, CFSTR("1"));
     73        profileURL = (CFURLRef)CFDictionaryGetValue(factoryProfile, kColorSyncDeviceProfileURL);
     74    }
     75   
     76   
     77    NSURL *url = (NSURL *)CFAutorelease(CFRetain(profileURL));
     78    CFRelease(deviceInfo);
     79    return url;
     80}
     81
     82static NSArray *displayUUIDStrings()
     83{
     84    NSMutableArray *result = [NSMutableArray array];
     85
     86    static const uint32_t maxDisplayCount = 10;
     87    CGDirectDisplayID displayIDs[maxDisplayCount] = { 0 };
     88    uint32_t displayCount = 0;
     89   
     90    CGError err = CGGetActiveDisplayList(maxDisplayCount, displayIDs, &displayCount);
     91    if (err != kCGErrorSuccess) {
     92        NSLog(@"Error %d getting active display list; not setting display color profile.", err);
     93        return nil;
     94    }
     95
     96    if (!displayCount) {
     97        NSLog(@"No display attached to system; not setting display color profile.");
     98        return nil;
     99    }
     100
     101    for (uint32_t i = 0; i < displayCount; ++i) {
     102        CFUUIDRef displayUUIDRef = CGDisplayCreateUUIDFromDisplayID(displayIDs[i]);
     103        [result addObject:(NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, displayUUIDRef))];
     104        CFRelease(displayUUIDRef);
     105    }
     106   
     107    return result;
     108}
     109
     110static void saveDisplayColorProfiles(NSArray *displayUUIDStrings)
     111{
     112    NSMutableDictionary *userColorProfiles = originalColorProfileURLs();
     113
     114    for (NSString *UUIDString in displayUUIDStrings) {
     115        if ([userColorProfiles objectForKey:UUIDString])
     116            continue;
     117       
     118        NSURL *colorProfileURL = colorProfileURLForDisplay(UUIDString);
     119        [userColorProfiles setObject:colorProfileURL forKey:UUIDString];
     120    }
     121}
     122
     123static void setDisplayColorProfile(NSString *displayUUIDString, NSURL *colorProfileURL)
     124{
     125    NSDictionary *profileInfo = @{
     126        (NSString *)kColorSyncDeviceDefaultProfileID : colorProfileURL
     127    };
     128
     129    CFUUIDRef uuid = CFUUIDCreateFromString(kCFAllocatorDefault, (CFStringRef)displayUUIDString);
     130    BOOL success = ColorSyncDeviceSetCustomProfiles(kColorSyncDisplayDeviceClass, uuid, (CFDictionaryRef)profileInfo);
     131    if (!success)
     132        NSLog(@"Failed to set color profile for display %@! Many pixel tests may fail as a result.", displayUUIDString);
     133    CFRelease(uuid);
     134}
     135
     136static void restoreDisplayColorProfiles(NSArray *displayUUIDStrings)
     137{
     138    NSMutableDictionary* userColorProfiles = originalColorProfileURLs();
     139
     140    for (NSString *UUIDString in displayUUIDStrings) {
     141        NSURL *profileURL = [userColorProfiles objectForKey:UUIDString];
     142        if (!profileURL)
     143            continue;
     144       
     145        setDisplayColorProfile(UUIDString, profileURL);
     146    }
     147}
    49148
    50149static void installLayoutTestColorProfile()
     
    54153
    55154    // To make sure we get consistent colors (not dependent on the chosen color
    56     // space of the main display), we force the generic RGB color profile.
     155    // space of the display), we force the generic sRGB color profile on all displays.
    57156    // This causes a change the user can see.
    58    
    59     CFUUIDRef mainDisplayID = CGDisplayCreateUUIDFromDisplayID(CGMainDisplayID());
    60    
    61     if (!sUserColorProfileURL) {
    62         CFDictionaryRef deviceInfo = ColorSyncDeviceCopyDeviceInfo(kColorSyncDisplayDeviceClass, mainDisplayID);
    63 
    64         if (!deviceInfo) {
    65             NSLog(@"No display attached to system; not setting main display's color profile.");
    66             CFRelease(mainDisplayID);
    67             return;
    68         }
    69 
    70         CFDictionaryRef profileInfo = (CFDictionaryRef)CFDictionaryGetValue(deviceInfo, kColorSyncCustomProfiles);
    71         if (profileInfo) {
    72             sUserColorProfileURL = (CFURLRef)CFDictionaryGetValue(profileInfo, CFSTR("1"));
    73             CFRetain(sUserColorProfileURL);
    74         } else {
    75             profileInfo = (CFDictionaryRef)CFDictionaryGetValue(deviceInfo, kColorSyncFactoryProfiles);
    76             CFDictionaryRef factoryProfile = (CFDictionaryRef)CFDictionaryGetValue(profileInfo, CFSTR("1"));
    77             sUserColorProfileURL = (CFURLRef)CFDictionaryGetValue(factoryProfile, kColorSyncDeviceProfileURL);
    78             CFRetain(sUserColorProfileURL);
    79         }
    80        
    81         CFRelease(deviceInfo);
    82     }
     157
     158    NSArray *displays = displayUUIDStrings();
     159    saveDisplayColorProfiles(displays);
    83160
    84161    ColorSyncProfileRef sRGBProfile = ColorSyncProfileCreateWithName(kColorSyncSRGBProfile);
     
    87164    if (!profileURL) {
    88165        NSLog(@"Failed to get URL of Generic RGB color profile! Many pixel tests may fail as a result. Error: %@", error);
    89        
    90         if (sUserColorProfileURL) {
    91             CFRelease(sUserColorProfileURL);
    92             sUserColorProfileURL = 0;
    93         }
    94        
    95         CFRelease(sRGBProfile);
    96         CFRelease(mainDisplayID);
    97         return;
    98     }
    99        
    100     CFMutableDictionaryRef profileInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    101     CFDictionarySetValue(profileInfo, kColorSyncDeviceDefaultProfileID, profileURL);
    102    
    103     if (!ColorSyncDeviceSetCustomProfiles(kColorSyncDisplayDeviceClass, mainDisplayID, profileInfo)) {
    104         NSLog(@"Failed to set color profile for main display! Many pixel tests may fail as a result.");
    105        
    106         if (sUserColorProfileURL) {
    107             CFRelease(sUserColorProfileURL);
    108             sUserColorProfileURL = 0;
    109         }
    110     }
    111    
    112     CFRelease(profileInfo);
    113     CFRelease(sRGBProfile);
    114     CFRelease(mainDisplayID);
     166        return;
     167    }
     168   
     169    for (NSString *displayUUIDString in displays)
     170        setDisplayColorProfile(displayUUIDString, (NSURL *)profileURL);
    115171}
    116172
     
    123179    // But we might as well try to restore the user's color profile, we're going down anyway...
    124180   
    125     if (!sUserColorProfileURL)
    126         return;
    127    
    128     CFUUIDRef mainDisplayID = CGDisplayCreateUUIDFromDisplayID(CGMainDisplayID());
    129     CFMutableDictionaryRef profileInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    130     CFDictionarySetValue(profileInfo, kColorSyncDeviceDefaultProfileID, sUserColorProfileURL);
    131     ColorSyncDeviceSetCustomProfiles(kColorSyncDisplayDeviceClass, mainDisplayID, profileInfo);
    132     CFRelease(mainDisplayID);
    133     CFRelease(profileInfo);
     181    NSArray *displays = displayUUIDStrings();
     182    restoreDisplayColorProfiles(displays);
    134183}
    135184
     
    189238    }
    190239
    191     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    192 
    193240    // Hooks the ways we might get told to clean up...
    194241    signal(SIGINT, simpleSignalHandler);
     
    211258    restoreUserColorProfile();
    212259
    213     [pool release];
    214260    return 0;
    215261}
Note: See TracChangeset for help on using the changeset viewer.