|  | 
|  | 1 | +//import XCTest | 
|  | 2 | +// | 
|  | 3 | +//import Cocoa | 
|  | 4 | +// | 
|  | 5 | +//@_silgen_name("CGSMainConnectionID") | 
|  | 6 | +//func CGSMainConnectionID() -> CGSConnectionID | 
|  | 7 | +// | 
|  | 8 | +//let CGS_CONNECTION = CGSMainConnectionID() | 
|  | 9 | +//typealias CGSConnectionID = UInt32 | 
|  | 10 | +//typealias CGSSpaceID = UInt64 | 
|  | 11 | +// | 
|  | 12 | +//struct CGSWindowCaptureOptions: OptionSet { | 
|  | 13 | +//    let rawValue: UInt32 | 
|  | 14 | +//    static let ignoreGlobalClipShape = CGSWindowCaptureOptions(rawValue: 1 << 11) | 
|  | 15 | +//    // on a retina display, 1px is spread on 4px, so nominalResolution is 1/4 of bestResolution | 
|  | 16 | +//    static let nominalResolution = CGSWindowCaptureOptions(rawValue: 1 << 9) | 
|  | 17 | +//    static let bestResolution = CGSWindowCaptureOptions(rawValue: 1 << 8) | 
|  | 18 | +//} | 
|  | 19 | +// | 
|  | 20 | +//@_silgen_name("CGSHWCaptureWindowList") | 
|  | 21 | +//func CGSHWCaptureWindowList(_ cid: CGSConnectionID, _ windowList: inout CGWindowID, _ windowCount: UInt32, _ options: CGSWindowCaptureOptions) -> Unmanaged<CFArray> | 
|  | 22 | +// | 
|  | 23 | +//typealias CGWindow = [CFString: Any] | 
|  | 24 | +// | 
|  | 25 | +//class Playground { | 
|  | 26 | +//    static var batchId = 0 | 
|  | 27 | +//    static var startTime: UInt64! | 
|  | 28 | +//    static var wid: CGWindowID! | 
|  | 29 | +//    static let dispatchGroup = DispatchGroup() | 
|  | 30 | +//    static let dispatchSemaphore = DispatchSemaphore(value: 8) | 
|  | 31 | +//    // DispatchQueue.global() | 
|  | 32 | +//    //     1: 21.4 | 
|  | 33 | +//    //     2: 11.2 | 
|  | 34 | +//    //     3: 8.1 | 
|  | 35 | +//    //     5: 6.5 // 3.2 | 
|  | 36 | +//    //     8: 5.9  // 3.1 | 
|  | 37 | +//    //     10: 5.5 // 3.0 | 
|  | 38 | +//    //     15: 5.2 // 3.3 | 
|  | 39 | +//    //     20: 5.2 | 
|  | 40 | +//    //     30: 5.2 | 
|  | 41 | +//    //     40: 5.2 | 
|  | 42 | +//    //     50: 5.6 | 
|  | 43 | +//    //     60: 10.7 | 
|  | 44 | +//    //     no-cap: 93 // 93.3 | 
|  | 45 | +//    // custom-concurrent-queue no-cap: 91.3 | 
|  | 46 | +//    // custom DispatchQueue (serial) | 
|  | 47 | +//    //     no-cap: 5.1 // 3.2 | 
|  | 48 | +//    //     no-cap qos:.userInteractive: 6.0 | 
|  | 49 | +//    //     no-cap qos:.userInteractive autoreleaseFrequency:.inherit: 6.0 | 
|  | 50 | +//    //     no-cap qos:.userInteractive autoreleaseFrequency:.workItem: 5.9 | 
|  | 51 | +//    //     no-cap qos:.userInteractive autoreleaseFrequency:.never: 6.3 | 
|  | 52 | +//    // no second queue. Only 1 global() queue in dispatchTasksThenCleanup: 11 // 3.3 | 
|  | 53 | +//    // no second queue. Only 1 DispatchQueue (serial) in dispatchTasksThenCleanup: 12.2 | 
|  | 54 | +// | 
|  | 55 | +//    static func dispatchTasksThenCleanup(_ batchId: Int,  _ expectation: XCTestExpectation) { | 
|  | 56 | +//        DispatchQueue.init(label: "test").async { | 
|  | 57 | +//            print("orchestrator start \(batchId)") | 
|  | 58 | +//            for taskId in 0..<100 { | 
|  | 59 | +////                dispatchSemaphore.wait() | 
|  | 60 | +////                DispatchQueue.global().async { | 
|  | 61 | +//                    defer { | 
|  | 62 | +////                        dispatchSemaphore.signal() | 
|  | 63 | +//                        dispatchGroup.leave() | 
|  | 64 | +//                    } | 
|  | 65 | +//                    dispatchGroup.enter() | 
|  | 66 | +//                    print("task start \(batchId) \(taskId)") | 
|  | 67 | +//                    task(batchId, taskId) | 
|  | 68 | +//                    print("task stop \(batchId) \(taskId)") | 
|  | 69 | +////                } | 
|  | 70 | +//            } | 
|  | 71 | +//            dispatchGroup.notify(queue: .main) { | 
|  | 72 | +//                cleanup(expectation) | 
|  | 73 | +//            } | 
|  | 74 | +//            print("orchestrator stop \(batchId)") | 
|  | 75 | +//        } | 
|  | 76 | +//    } | 
|  | 77 | +// | 
|  | 78 | +//    static func start(_ expectation1: XCTestExpectation, _ expectation2: XCTestExpectation) { | 
|  | 79 | +//        let windows = CGWindowListCopyWindowInfo([.excludeDesktopElements, .optionOnScreenOnly], kCGNullWindowID) as! [CGWindow] | 
|  | 80 | +//        let window = windows.first { ($0[kCGWindowName] as? String) == "~" } | 
|  | 81 | +//        wid = window?[kCGWindowNumber] as? CGWindowID | 
|  | 82 | +//        startTime = DispatchTime.now().uptimeNanoseconds | 
|  | 83 | +//        dispatchTasksThenCleanup(batchId, expectation1) | 
|  | 84 | +//        batchId += 1 | 
|  | 85 | +//        dispatchTasksThenCleanup(batchId, expectation2) | 
|  | 86 | +//        batchId += 1 | 
|  | 87 | +//    } | 
|  | 88 | +// | 
|  | 89 | +//    static func task(_ batchId: Int, _ taskId: Int) { | 
|  | 90 | +//        //Thread.sleep(forTimeInterval: 10)//Double(Int.random(in: 1...5))) | 
|  | 91 | +//        let _ = screenshot() | 
|  | 92 | +//    } | 
|  | 93 | +// | 
|  | 94 | +//    static func cleanup(_ expectation: XCTestExpectation) { | 
|  | 95 | +//        let timePassedInSeconds = Double(DispatchTime.now().uptimeNanoseconds - startTime) / 1_000_000_000 | 
|  | 96 | +//        print("cleanup", timePassedInSeconds) | 
|  | 97 | +//        expectation.fulfill() | 
|  | 98 | +//    } | 
|  | 99 | +// | 
|  | 100 | +//    static func screenshot() -> CGImage? { | 
|  | 101 | +//        print("CGSHWCaptureWindowList start") | 
|  | 102 | +//        var windowId_ = wid! | 
|  | 103 | +//        let list = CGSHWCaptureWindowList(CGS_CONNECTION, &windowId_, 1, [.ignoreGlobalClipShape, .bestResolution]).takeRetainedValue() as! [CGImage] | 
|  | 104 | +//        print(list.first != nil) | 
|  | 105 | +//        return list.first | 
|  | 106 | +////        let windowId_ = wid! | 
|  | 107 | +////        let image = CGWindowListCreateImage(.null, .optionIncludingWindow, windowId_, [.boundsIgnoreFraming, .bestResolution]) | 
|  | 108 | +////        print(image != nil) | 
|  | 109 | +////        return image | 
|  | 110 | +//    } | 
|  | 111 | +//} | 
|  | 112 | +// | 
|  | 113 | +//final class ConcurrentScreenshots: XCTestCase { | 
|  | 114 | +//    func testBench() throws { | 
|  | 115 | +////        let options = XCTMeasureOptions() | 
|  | 116 | +////        options.iterationCount = 1 | 
|  | 117 | +////        self.measure(options: options) { | 
|  | 118 | +//        let expectation1 = XCTestExpectation() | 
|  | 119 | +//        let expectation2 = XCTestExpectation() | 
|  | 120 | +//        Playground.start(expectation1, expectation2) | 
|  | 121 | +//        wait(for: [expectation1, expectation2], timeout: 100) | 
|  | 122 | +////    } | 
|  | 123 | +//    } | 
|  | 124 | +//} | 
0 commit comments