diff --git a/infra/specs/client.webrtc.json b/infra/specs/client.webrtc.json index 8f884ab4ad..9b5c568aa0 100644 --- a/infra/specs/client.webrtc.json +++ b/infra/specs/client.webrtc.json @@ -8436,7 +8436,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -8464,7 +8464,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8485,7 +8485,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8506,7 +8506,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8527,7 +8527,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8551,7 +8551,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8572,7 +8572,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 2 @@ -8594,7 +8594,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -8616,7 +8616,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -8638,7 +8638,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8659,7 +8659,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8680,7 +8680,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8701,7 +8701,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -8723,7 +8723,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8744,7 +8744,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8765,7 +8765,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8786,7 +8786,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8807,7 +8807,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8850,7 +8850,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -8872,7 +8872,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8893,7 +8893,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -8918,7 +8918,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -8939,7 +8939,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -8960,7 +8960,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -8981,7 +8981,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9005,7 +9005,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9026,7 +9026,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 2 @@ -9048,7 +9048,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 6 @@ -9070,7 +9070,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 4 @@ -9092,7 +9092,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9113,7 +9113,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9134,7 +9134,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9155,7 +9155,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 6 @@ -9177,7 +9177,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9198,7 +9198,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9219,7 +9219,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9240,7 +9240,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9261,7 +9261,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9282,7 +9282,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 4 @@ -9304,7 +9304,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -9325,7 +9325,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, diff --git a/infra/specs/mixins.pyl b/infra/specs/mixins.pyl index 2201698ea7..4ba0430725 100644 --- a/infra/specs/mixins.pyl +++ b/infra/specs/mixins.pyl @@ -322,17 +322,10 @@ } } }, - 'win10-1703': { + 'win10': { 'swarming': { 'dimensions': { - 'os': 'Windows-10-15063' - } - } - }, - 'win7': { - 'swarming': { - 'dimensions': { - 'os': 'Windows-7-SP1' + 'os': 'Windows-10-19042' } } }, diff --git a/infra/specs/mixins_webrtc.pyl b/infra/specs/mixins_webrtc.pyl index e972b5f722..833cbcf3fa 100644 --- a/infra/specs/mixins_webrtc.pyl +++ b/infra/specs/mixins_webrtc.pyl @@ -259,12 +259,5 @@ 'os': 'Windows' } } - }, - 'win10-1703': { - 'swarming': { - 'dimensions': { - 'os': 'Windows-10-15063', - }, - }, - }, + } } diff --git a/infra/specs/test_suites.pyl b/infra/specs/test_suites.pyl index b954bb3f5b..00a699bb31 100644 --- a/infra/specs/test_suites.pyl +++ b/infra/specs/test_suites.pyl @@ -220,13 +220,11 @@ }, 'win_video_capture_tests': { 'video_capture_tests': { - 'remove_mixins': ['win7'], 'mixins': ['win', 'baremetal-pool'], } }, 'win_video_capture_tests_tryserver': { 'video_capture_tests': { - 'remove_mixins': ['win7'], 'mixins': ['win', 'baremetal-try-pool'], } }, diff --git a/infra/specs/tryserver.webrtc.json b/infra/specs/tryserver.webrtc.json index 549fb765cd..b035be44d3 100644 --- a/infra/specs/tryserver.webrtc.json +++ b/infra/specs/tryserver.webrtc.json @@ -12364,7 +12364,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12385,7 +12385,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12406,7 +12406,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12427,7 +12427,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12451,7 +12451,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12472,7 +12472,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 2 @@ -12494,7 +12494,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 6 @@ -12516,7 +12516,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 4 @@ -12538,7 +12538,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12559,7 +12559,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12580,7 +12580,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12601,7 +12601,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 6 @@ -12623,7 +12623,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12644,7 +12644,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12665,7 +12665,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12686,7 +12686,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12707,7 +12707,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12728,7 +12728,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 4 @@ -12750,7 +12750,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12771,7 +12771,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -12800,7 +12800,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -12821,7 +12821,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -12842,7 +12842,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -12863,7 +12863,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -12887,7 +12887,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -12908,7 +12908,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 2 @@ -12930,7 +12930,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -12952,7 +12952,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -12974,7 +12974,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -12995,7 +12995,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13016,7 +13016,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13037,7 +13037,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -13059,7 +13059,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13080,7 +13080,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13101,7 +13101,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13122,7 +13122,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13143,7 +13143,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13164,7 +13164,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -13186,7 +13186,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13207,7 +13207,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13232,7 +13232,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13253,7 +13253,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13274,7 +13274,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13295,7 +13295,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13319,7 +13319,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13340,7 +13340,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 2 @@ -13362,7 +13362,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 6 @@ -13384,7 +13384,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 4 @@ -13406,7 +13406,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13427,7 +13427,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13448,7 +13448,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13469,7 +13469,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 6 @@ -13491,7 +13491,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13512,7 +13512,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13533,7 +13533,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13554,7 +13554,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13575,7 +13575,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13596,7 +13596,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ], "shards": 4 @@ -13618,7 +13618,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13639,7 +13639,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-10-15063" + "os": "Windows-10-19042" } ] }, @@ -13664,7 +13664,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13685,7 +13685,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13706,7 +13706,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13727,7 +13727,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13751,7 +13751,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13772,7 +13772,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 2 @@ -13794,7 +13794,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -13816,7 +13816,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -13838,7 +13838,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13859,7 +13859,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13880,7 +13880,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13901,7 +13901,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -13923,7 +13923,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13944,7 +13944,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13965,7 +13965,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -13986,7 +13986,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14007,7 +14007,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14028,7 +14028,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -14050,7 +14050,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14071,7 +14071,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14096,7 +14096,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14117,7 +14117,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14138,7 +14138,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14159,7 +14159,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14183,7 +14183,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14204,7 +14204,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 2 @@ -14226,7 +14226,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -14248,7 +14248,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -14270,7 +14270,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14291,7 +14291,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14312,7 +14312,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14333,7 +14333,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -14355,7 +14355,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14376,7 +14376,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14397,7 +14397,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14418,7 +14418,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14439,7 +14439,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14460,7 +14460,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -14482,7 +14482,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14503,7 +14503,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14528,7 +14528,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14549,7 +14549,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14570,7 +14570,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14591,7 +14591,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14615,7 +14615,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14636,7 +14636,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 2 @@ -14658,7 +14658,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -14680,7 +14680,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -14702,7 +14702,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14723,7 +14723,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14744,7 +14744,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14765,7 +14765,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 6 @@ -14787,7 +14787,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14808,7 +14808,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14829,7 +14829,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14850,7 +14850,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14871,7 +14871,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14914,7 +14914,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 @@ -14936,7 +14936,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14957,7 +14957,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -14984,7 +14984,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ] }, @@ -15009,7 +15009,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Windows-7-SP1" + "os": "Windows-10-19042" } ], "shards": 4 diff --git a/infra/specs/waterfalls.pyl b/infra/specs/waterfalls.pyl index 062a81cf2c..73c8e9a887 100644 --- a/infra/specs/waterfalls.pyl +++ b/infra/specs/waterfalls.pyl @@ -179,7 +179,7 @@ 'MacArm64 Builder': {}, 'Win (more configs)': { 'os_type': 'win', - 'mixins': ['win7', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'more_configs_tests', }, @@ -188,14 +188,14 @@ 'Win32 Debug (Clang)': {}, 'Win32 Release (Clang)': { 'os_type': 'win', - 'mixins': ['win7', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'win_tests', }, }, 'Win64 ASan': { 'os_type': 'win', - 'mixins': ['win10-1703', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, @@ -581,7 +581,7 @@ }, 'win_asan': { 'os_type': 'win', - 'mixins': ['win10-1703', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, @@ -592,42 +592,42 @@ 'win_compile_x86_clang_rel': {}, 'win_x64_clang_dbg': { 'os_type': 'win', - 'mixins': ['win7', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, }, 'win_x64_clang_dbg_win10': { 'os_type': 'win', - 'mixins': ['win10-1703', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, }, 'win_x64_clang_rel': { 'os_type': 'win', - 'mixins': ['win7', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, }, 'win_x86_clang_dbg': { 'os_type': 'win', - 'mixins': ['win7', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, }, 'win_x86_clang_rel': { 'os_type': 'win', - 'mixins': ['win7', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'win_tests_tryserver', }, }, 'win_x86_more_configs': { 'os_type': 'win', - 'mixins': ['win7', 'x86-64', 'resultdb-json-format'], + 'mixins': ['win10', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'more_configs_tests', }, diff --git a/modules/desktop_capture/BUILD.gn b/modules/desktop_capture/BUILD.gn index 3cc5c07aec..6b3a5f5b22 100644 --- a/modules/desktop_capture/BUILD.gn +++ b/modules/desktop_capture/BUILD.gn @@ -635,8 +635,14 @@ rtc_library("desktop_capture") { "win/wgc_desktop_frame.cc", "win/wgc_desktop_frame.h", ] - libs += [ "dwmapi.lib" ] - deps += [ "../../rtc_base/win:hstring" ] + libs += [ + "dwmapi.lib", + "CoreMessaging.lib", + ] + deps += [ + "../../rtc_base:rtc_event", + "../../rtc_base/win:hstring", + ] } } diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc index f89457372b..0ff2db27c7 100644 --- a/modules/desktop_capture/win/wgc_capture_session.cc +++ b/modules/desktop_capture/win/wgc_capture_session.cc @@ -10,6 +10,7 @@ #include "modules/desktop_capture/win/wgc_capture_session.h" +#include #include #include #include @@ -36,13 +37,13 @@ namespace { // We must use a BGRA pixel format that has 4 bytes per pixel, as required by // the DesktopFrame interface. -const auto kPixelFormat = ABI::Windows::Graphics::DirectX::DirectXPixelFormat:: - DirectXPixelFormat_B8G8R8A8UIntNormalized; +constexpr auto kPixelFormat = ABI::Windows::Graphics::DirectX:: + DirectXPixelFormat::DirectXPixelFormat_B8G8R8A8UIntNormalized; -// We only want 1 buffer in our frame pool to reduce latency. If we had more, -// they would sit in the pool for longer and be stale by the time we are asked -// for a new frame. -const int kNumBuffers = 1; +// The maximum time `GetFrame` will wait for a frame to arrive, if we don't have +// any in the pool. +constexpr int kMaxWaitForFrameMs = 50; +constexpr int kMaxWaitForFirstFrameMs = 500; // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. @@ -54,9 +55,9 @@ enum class StartCaptureResult { kD3dDelayLoadFailed = 4, kD3dDeviceCreationFailed = 5, kFramePoolActivationFailed = 6, - kFramePoolCastFailed = 7, - kGetItemSizeFailed = 8, - kCreateFreeThreadedFailed = 9, + // kFramePoolCastFailed = 7, (deprecated) + // kGetItemSizeFailed = 8, (deprecated) + kCreateFramePoolFailed = 9, kCreateCaptureSessionFailed = 10, kStartCaptureFailed = 11, kMaxValue = kStartCaptureFailed @@ -100,7 +101,9 @@ WgcCaptureSession::WgcCaptureSession(ComPtr d3d11_device, : d3d11_device_(std::move(d3d11_device)), item_(std::move(item)), size_(size) {} -WgcCaptureSession::~WgcCaptureSession() = default; +WgcCaptureSession::~WgcCaptureSession() { + RemoveEventHandlers(); +} HRESULT WgcCaptureSession::StartCapture() { RTC_DCHECK_RUN_ON(&sequence_checker_); @@ -118,12 +121,13 @@ HRESULT WgcCaptureSession::StartCapture() { // Listen for the Closed event, to detect if the source we are capturing is // closed (e.g. application window is closed or monitor is disconnected). If // it is, we should abort the capture. + item_closed_token_ = std::make_unique(); auto closed_handler = Microsoft::WRL::Callback>( this, &WgcCaptureSession::OnItemClosed); - EventRegistrationToken item_closed_token; - HRESULT hr = item_->add_Closed(closed_handler.Get(), &item_closed_token); + HRESULT hr = + item_->add_Closed(closed_handler.Get(), item_closed_token_.get()); if (FAILED(hr)) { RecordStartCaptureResult(StartCaptureResult::kAddClosedFailed); return hr; @@ -157,22 +161,25 @@ HRESULT WgcCaptureSession::StartCapture() { return hr; } - // Cast to FramePoolStatics2 so we can use CreateFreeThreaded and avoid the - // need to have a DispatcherQueue. We don't listen for the FrameArrived event, - // so there's no difference. - ComPtr frame_pool_statics2; - hr = frame_pool_statics->QueryInterface(IID_PPV_ARGS(&frame_pool_statics2)); + hr = frame_pool_statics->Create(direct3d_device_.Get(), kPixelFormat, + kNumBuffers, size_, &frame_pool_); if (FAILED(hr)) { - RecordStartCaptureResult(StartCaptureResult::kFramePoolCastFailed); + RecordStartCaptureResult(StartCaptureResult::kCreateFramePoolFailed); return hr; } - hr = frame_pool_statics2->CreateFreeThreaded( - direct3d_device_.Get(), kPixelFormat, kNumBuffers, size_, &frame_pool_); - if (FAILED(hr)) { - RecordStartCaptureResult(StartCaptureResult::kCreateFreeThreadedFailed); - return hr; - } + frames_in_pool_ = 0; + + // Because `WgcCapturerWin` created a `DispatcherQueue`, and we created + // `frame_pool_` via `Create`, the `FrameArrived` event will be delivered on + // the current thread. + frame_arrived_token_ = std::make_unique(); + auto frame_arrived_handler = + Microsoft::WRL::Callback>( + this, &WgcCaptureSession::OnFrameArrived); + hr = frame_pool_->add_FrameArrived(frame_arrived_handler.Get(), + frame_arrived_token_.get()); hr = frame_pool_->CreateCaptureSession(item_.Get(), &session_); if (FAILED(hr)) { @@ -205,6 +212,10 @@ HRESULT WgcCaptureSession::GetFrame( RTC_DCHECK(is_capture_started_); + if (frames_in_pool_ < 1) + wait_for_frame_event_.Wait(first_frame_ ? kMaxWaitForFirstFrameMs + : kMaxWaitForFrameMs); + ComPtr capture_frame; HRESULT hr = frame_pool_->TryGetNextFrame(&capture_frame); if (FAILED(hr)) { @@ -218,6 +229,9 @@ HRESULT WgcCaptureSession::GetFrame( return hr; } + first_frame_ = false; + --frames_in_pool_; + // We need to get `capture_frame` as an `ID3D11Texture2D` so that we can get // the raw image data in the format required by the `DesktopFrame` interface. ComPtr @@ -358,6 +372,16 @@ HRESULT WgcCaptureSession::CreateMappedTexture( return d3d11_device_->CreateTexture2D(&map_desc, nullptr, &mapped_texture_); } +HRESULT WgcCaptureSession::OnFrameArrived( + WGC::IDirect3D11CaptureFramePool* sender, + IInspectable* event_args) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + RTC_DCHECK_LT(frames_in_pool_, kNumBuffers); + ++frames_in_pool_; + wait_for_frame_event_.Set(); + return S_OK; +} + HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender, IInspectable* event_args) { RTC_DCHECK_RUN_ON(&sequence_checker_); @@ -366,6 +390,8 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender, item_closed_ = true; is_capture_started_ = false; + RemoveEventHandlers(); + mapped_texture_ = nullptr; session_ = nullptr; frame_pool_ = nullptr; @@ -376,4 +402,22 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender, return S_OK; } +void WgcCaptureSession::RemoveEventHandlers() { + HRESULT hr; + if (frame_pool_ && frame_arrived_token_) { + hr = frame_pool_->remove_FrameArrived(*frame_arrived_token_); + frame_arrived_token_.reset(); + if (FAILED(hr)) { + RTC_LOG(LS_WARNING) << "Failed to remove FrameArrived event handler: " + << hr; + } + } + if (item_ && item_closed_token_) { + hr = item_->remove_Closed(*item_closed_token_); + item_closed_token_.reset(); + if (FAILED(hr)) + RTC_LOG(LS_WARNING) << "Failed to remove Closed event handler: " << hr; + } +} + } // namespace webrtc diff --git a/modules/desktop_capture/win/wgc_capture_session.h b/modules/desktop_capture/win/wgc_capture_session.h index 0b9d082823..27d412baf9 100644 --- a/modules/desktop_capture/win/wgc_capture_session.h +++ b/modules/desktop_capture/win/wgc_capture_session.h @@ -21,6 +21,7 @@ #include "api/sequence_checker.h" #include "modules/desktop_capture/desktop_capture_options.h" #include "modules/desktop_capture/win/wgc_capture_source.h" +#include "rtc_base/event.h" namespace webrtc { @@ -48,6 +49,12 @@ class WgcCaptureSession final { return is_capture_started_; } + // We keep 2 buffers in the frame pool to balance the staleness of the frame + // with having to wait for frames to arrive too frequently. Too many buffers + // will lead to a high latency, and too few will lead to poor performance. + // We make this public for tests. + static constexpr int kNumBuffers = 2; + private: // Initializes `mapped_texture_` with the properties of the `src_texture`, // overrides the values of some necessary properties like the @@ -64,6 +71,24 @@ class WgcCaptureSession final { ABI::Windows::Graphics::Capture::IGraphicsCaptureItem* sender, IInspectable* event_args); + // Event handler for `frame_pool_`'s FrameArrived event. + HRESULT OnFrameArrived( + ABI::Windows::Graphics::Capture::IDirect3D11CaptureFramePool* sender, + IInspectable* event_args); + + void RemoveEventHandlers(); + + // We wait on this event in `GetFrame` if there are no frames in the pool. + // `OnFrameArrived` will set the event so we can proceed. + rtc::Event wait_for_frame_event_; + int frames_in_pool_; + + // We're willing to wait for a frame a little longer if it's the first one. + bool first_frame_ = true; + + std::unique_ptr frame_arrived_token_; + std::unique_ptr item_closed_token_; + // A Direct3D11 Device provided by the caller. We use this to create an // IDirect3DDevice, and also to create textures that will hold the image data. Microsoft::WRL::ComPtr d3d11_device_; diff --git a/modules/desktop_capture/win/wgc_capturer_win.cc b/modules/desktop_capture/win/wgc_capturer_win.cc index eacaa893d9..3f44dd53c8 100644 --- a/modules/desktop_capture/win/wgc_capturer_win.cc +++ b/modules/desktop_capture/win/wgc_capturer_win.cc @@ -10,6 +10,7 @@ #include "modules/desktop_capture/win/wgc_capturer_win.h" +#include #include #include @@ -45,7 +46,8 @@ enum class WgcCapturerResult { kSessionStartFailure = 4, kGetFrameFailure = 5, kFrameDropped = 6, - kMaxValue = kFrameDropped + kCreateDispatcherQueueFailure = 7, + kMaxValue = kCreateDispatcherQueueFailure }; void RecordWgcCapturerResult(WgcCapturerResult error) { @@ -57,20 +59,34 @@ void RecordWgcCapturerResult(WgcCapturerResult error) { } // namespace bool IsWgcSupported(CaptureType capture_type) { - if (capture_type == CaptureType::kScreen) { - // A bug in the WGC API `CreateForMonitor` was fixed in 20H1. - if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN10_20H1) + if (!HasActiveDisplay()) { + // There is a bug in `CreateForMonitor` that causes a crash if there are no + // active displays. The crash was fixed in Win11, but we are still unable + // to capture screens without an active display. + if (capture_type == CaptureType::kScreen) return false; - // There is another bug in `CreateForMonitor` that causes a crash if there - // are no active displays. - if (!HasActiveDisplay()) + // There is a bug in the DWM (Desktop Window Manager) that prevents it from + // providing image data if there are no displays attached. This was fixed in + // Windows 11. + if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN11) return false; } + // A bug in the WGC API `CreateForMonitor` prevents capturing the entire + // virtual screen (all monitors simultaneously), this was fixed in 20H1. Since + // we can't assert that we won't be asked to capture the entire virtual + // screen, we report unsupported so we can fallback to another capturer. + if (capture_type == CaptureType::kScreen && + rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN10_20H1) { + return false; + } + if (!ResolveCoreWinRTDelayload()) return false; + // We need to check if the WGC APIs are presesnt on the system. Certain SKUs + // of Windows ship without these APIs. ComPtr api_info_statics; HRESULT hr = GetActivationFactory< @@ -104,6 +120,7 @@ bool IsWgcSupported(CaptureType capture_type) { if (FAILED(hr) || !is_type_present) return false; + // If the APIs are present, we need to check that they are supported. ComPtr capture_session_statics; hr = GetActivationFactory< WGC::IGraphicsCaptureSessionStatics, @@ -224,9 +241,32 @@ void WgcCapturerWin::CaptureFrame() { return; } + HRESULT hr; + if (!dispatcher_queue_created_) { + // Set the apartment type to NONE because this thread should already be COM + // initialized. + DispatcherQueueOptions options{ + sizeof(DispatcherQueueOptions), + DISPATCHERQUEUE_THREAD_TYPE::DQTYPE_THREAD_CURRENT, + DISPATCHERQUEUE_THREAD_APARTMENTTYPE::DQTAT_COM_NONE}; + ComPtr queue_controller; + hr = CreateDispatcherQueueController(options, &queue_controller); + + // If there is already a DispatcherQueue on this thread, that is fine. Its + // lifetime is tied to the thread's, and as long as the thread has one, even + // if we didn't create it, the capture session's events will be delivered on + // this thread. + if (FAILED(hr) && hr != RPC_E_WRONG_THREAD) { + RecordWgcCapturerResult(WgcCapturerResult::kCreateDispatcherQueueFailure); + callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT, + /*frame=*/nullptr); + } else { + dispatcher_queue_created_ = true; + } + } + int64_t capture_start_time_nanos = rtc::TimeNanos(); - HRESULT hr; WgcCaptureSession* capture_session = nullptr; std::map::iterator session_iter = ongoing_captures_.find(capture_source_->GetSourceId()); diff --git a/modules/desktop_capture/win/wgc_capturer_win.h b/modules/desktop_capture/win/wgc_capturer_win.h index ba212b6e69..f1f8f97db7 100644 --- a/modules/desktop_capture/win/wgc_capturer_win.h +++ b/modules/desktop_capture/win/wgc_capturer_win.h @@ -11,6 +11,7 @@ #ifndef MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_ #define MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_ +#include #include #include @@ -109,6 +110,13 @@ class WgcCapturerWin : public DesktopCapturer { bool IsSourceBeingCaptured(SourceId id); private: + // We need to either create or ensure that someone else created a + // `DispatcherQueue` on the current thread so that events will be delivered + // on the current thread rather than an arbitrary thread. A + // `DispatcherQueue`'s lifetime is tied to the thread's, and we don't post + // any work to it, so we don't need to hold a reference. + bool dispatcher_queue_created_ = false; + // Factory to create a WgcCaptureSource for us whenever SelectSource is // called. Initialized at construction with a source-specific implementation. std::unique_ptr source_factory_; diff --git a/modules/desktop_capture/win/wgc_capturer_win_unittest.cc b/modules/desktop_capture/win/wgc_capturer_win_unittest.cc index b83266cda0..9339526ce0 100644 --- a/modules/desktop_capture/win/wgc_capturer_win_unittest.cc +++ b/modules/desktop_capture/win/wgc_capturer_win_unittest.cc @@ -18,12 +18,14 @@ #include "modules/desktop_capture/desktop_capture_types.h" #include "modules/desktop_capture/desktop_capturer.h" #include "modules/desktop_capture/win/test_support/test_window.h" +#include "modules/desktop_capture/win/wgc_capture_session.h" #include "modules/desktop_capture/win/window_capture_utils.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/thread.h" #include "rtc_base/time_utils.h" #include "rtc_base/win/scoped_com_initializer.h" +#include "rtc_base/win/windows_version.h" #include "system_wrappers/include/metrics.h" #include "system_wrappers/include/sleep.h" #include "test/gtest.h" @@ -31,40 +33,54 @@ namespace webrtc { namespace { -const char kWindowThreadName[] = "wgc_capturer_test_window_thread"; -const WCHAR kWindowTitle[] = L"WGC Capturer Test Window"; +constexpr char kWindowThreadName[] = "wgc_capturer_test_window_thread"; +constexpr WCHAR kWindowTitle[] = L"WGC Capturer Test Window"; -const char kCapturerImplHistogram[] = +constexpr char kCapturerImplHistogram[] = "WebRTC.DesktopCapture.Win.DesktopCapturerImpl"; -const char kCapturerResultHistogram[] = +constexpr char kCapturerResultHistogram[] = "WebRTC.DesktopCapture.Win.WgcCapturerResult"; -const int kSuccess = 0; -const int kSessionStartFailure = 4; +constexpr int kSuccess = 0; +constexpr int kSessionStartFailure = 4; -const char kCaptureSessionResultHistogram[] = +constexpr char kCaptureSessionResultHistogram[] = "WebRTC.DesktopCapture.Win.WgcCaptureSessionStartResult"; -const int kSourceClosed = 1; +constexpr int kSourceClosed = 1; -const char kCaptureTimeHistogram[] = +constexpr char kCaptureTimeHistogram[] = "WebRTC.DesktopCapture.Win.WgcCapturerFrameTime"; -const int kSmallWindowWidth = 200; -const int kSmallWindowHeight = 100; -const int kMediumWindowWidth = 300; -const int kMediumWindowHeight = 200; -const int kLargeWindowWidth = 400; -const int kLargeWindowHeight = 500; +// The capturer keeps `kNumBuffers` in its frame pool, so we need to request +// that many frames to clear those out. The next frame will have the new size +// (if the size has changed) so we will resize the frame pool at this point. +// Then, we need to clear any frames that may have delivered to the frame pool +// before the resize. Finally, the next frame will be guaranteed to be the new +// size. +constexpr int kNumCapturesToFlushBuffers = + WgcCaptureSession::kNumBuffers * 2 + 1; + +constexpr int kSmallWindowWidth = 200; +constexpr int kSmallWindowHeight = 100; +constexpr int kMediumWindowWidth = 300; +constexpr int kMediumWindowHeight = 200; +constexpr int kLargeWindowWidth = 400; +constexpr int kLargeWindowHeight = 500; // The size of the image we capture is slightly smaller than the actual size of // the window. -const int kWindowWidthSubtrahend = 14; -const int kWindowHeightSubtrahend = 7; +constexpr int kWindowWidthSubtrahend = 14; +constexpr int kWindowHeightSubtrahend = 7; -// Custom message constants so we can direct our thread to close windows -// and quit running. -const UINT kDestroyWindow = WM_APP; -const UINT kQuitRunning = WM_APP + 1; +// Custom message constants so we can direct our thread to close windows and +// quit running. +constexpr UINT kDestroyWindow = WM_APP; +constexpr UINT kQuitRunning = WM_APP + 1; + +// When testing changes to real windows, sometimes the effects (close or resize) +// don't happen immediately, we want to keep trying until we see the effect but +// only for a reasonable amount of time. +constexpr int kMaxTries = 50; } // namespace @@ -185,20 +201,26 @@ class WgcCapturerWinTest : public ::testing::TestWithParam, return sources[0].id; } - void DoCapture() { - // Sometimes the first few frames are empty becaues the capture engine is - // still starting up. We also may drop a few frames when the window is - // resized or un-minimized. - do { + void DoCapture(int num_captures = 1) { + // Capture the requested number of frames. We expect the first capture to + // always succeed. If we're asked for multiple frames, we do expect to see a + // a couple dropped frames due to resizing the window. + const int max_tries = num_captures == 1 ? 1 : kMaxTries; + int success_count = 0; + for (int i = 0; success_count < num_captures && i < max_tries; i++) { capturer_->CaptureFrame(); - } while (result_ == DesktopCapturer::Result::ERROR_TEMPORARY); + if (result_ == DesktopCapturer::Result::ERROR_PERMANENT) + break; + if (result_ == DesktopCapturer::Result::SUCCESS) + success_count++; + } + total_successful_captures_ += success_count; + EXPECT_EQ(success_count, num_captures); EXPECT_EQ(result_, DesktopCapturer::Result::SUCCESS); EXPECT_TRUE(frame_); - - EXPECT_GT(metrics::NumEvents(kCapturerResultHistogram, kSuccess), - successful_captures_); - ++successful_captures_; + EXPECT_GE(metrics::NumEvents(kCapturerResultHistogram, kSuccess), + total_successful_captures_); } void ValidateFrame(int expected_width, int expected_height) { @@ -206,8 +228,7 @@ class WgcCapturerWinTest : public ::testing::TestWithParam, EXPECT_EQ(frame_->size().height(), expected_height - kWindowHeightSubtrahend); - // Verify the buffer contains as much data as it should, and that the right - // colors are found. + // Verify the buffer contains as much data as it should. int data_length = frame_->stride() * frame_->size().height(); // The first and last pixel should have the same color because they will be @@ -219,7 +240,7 @@ class WgcCapturerWinTest : public ::testing::TestWithParam, EXPECT_EQ(first_pixel, last_pixel); // Let's also check a pixel from the middle of the content area, which the - // TestWindow will paint a consistent color for us to verify. + // test window will paint a consistent color for us to verify. uint8_t* middle_pixel = frame_->data() + (data_length / 2); int sub_pixel_offset = DesktopFrame::kBytesPerPixel / 4; @@ -251,7 +272,7 @@ class WgcCapturerWinTest : public ::testing::TestWithParam, intptr_t source_id_; bool window_open_ = false; DesktopCapturer::Result result_; - int successful_captures_ = 0; + int total_successful_captures_ = 0; std::unique_ptr frame_; std::unique_ptr capturer_; }; @@ -310,13 +331,12 @@ TEST_P(WgcCapturerWinTest, CaptureTime) { capturer_->Start(this); int64_t start_time; - do { - start_time = rtc::TimeNanos(); - capturer_->CaptureFrame(); - } while (result_ == DesktopCapturer::Result::ERROR_TEMPORARY); + start_time = rtc::TimeNanos(); + capturer_->CaptureFrame(); int capture_time_ms = (rtc::TimeNanos() - start_time) / rtc::kNumNanosecsPerMillisec; + EXPECT_EQ(result_, DesktopCapturer::Result::SUCCESS); EXPECT_TRUE(frame_); // The test may measure the time slightly differently than the capturer. So we @@ -332,6 +352,8 @@ INSTANTIATE_TEST_SUITE_P(SourceAgnostic, CaptureType::kScreen)); TEST(WgcCapturerNoMonitorTest, NoMonitors) { + ScopedCOMInitializer com_initializer(ScopedCOMInitializer::kMTA); + EXPECT_TRUE(com_initializer.Succeeded()); if (HasActiveDisplay()) { RTC_LOG(LS_INFO) << "Skip WgcCapturerWinTest designed specifically for " "systems with no monitors"; @@ -341,6 +363,13 @@ TEST(WgcCapturerNoMonitorTest, NoMonitors) { // A bug in `CreateForMonitor` prevents screen capture when no displays are // attached. EXPECT_FALSE(IsWgcSupported(CaptureType::kScreen)); + + // A bug in the DWM (Desktop Window Manager) prevents it from providing image + // data if there are no displays attached. This was fixed in Windows 11. + if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN11) + EXPECT_FALSE(IsWgcSupported(CaptureType::kWindow)); + else + EXPECT_TRUE(IsWgcSupported(CaptureType::kWindow)); } class WgcCapturerMonitorTest : public WgcCapturerWinTest { @@ -452,15 +481,11 @@ TEST_F(WgcCapturerWindowTest, IncreaseWindowSizeMidCapture) { ValidateFrame(kSmallWindowWidth, kSmallWindowHeight); ResizeTestWindow(window_info_.hwnd, kSmallWindowWidth, kMediumWindowHeight); - DoCapture(); - // We don't expect to see the new size until the next capture, as the frame - // pool hadn't had a chance to resize yet to fit the new, larger image. - DoCapture(); + DoCapture(kNumCapturesToFlushBuffers); ValidateFrame(kSmallWindowWidth, kMediumWindowHeight); ResizeTestWindow(window_info_.hwnd, kLargeWindowWidth, kMediumWindowHeight); - DoCapture(); - DoCapture(); + DoCapture(kNumCapturesToFlushBuffers); ValidateFrame(kLargeWindowWidth, kMediumWindowHeight); } @@ -473,13 +498,11 @@ TEST_F(WgcCapturerWindowTest, ReduceWindowSizeMidCapture) { ValidateFrame(kLargeWindowWidth, kLargeWindowHeight); ResizeTestWindow(window_info_.hwnd, kLargeWindowWidth, kMediumWindowHeight); - // We expect to see the new size immediately because the image data has shrunk - // and will fit in the existing buffer. - DoCapture(); + DoCapture(kNumCapturesToFlushBuffers); ValidateFrame(kLargeWindowWidth, kMediumWindowHeight); ResizeTestWindow(window_info_.hwnd, kSmallWindowWidth, kMediumWindowHeight); - DoCapture(); + DoCapture(kNumCapturesToFlushBuffers); ValidateFrame(kSmallWindowWidth, kMediumWindowHeight); } @@ -491,7 +514,7 @@ TEST_F(WgcCapturerWindowTest, MinimizeWindowMidCapture) { // Minmize the window and capture should continue but return temporary errors. MinimizeTestWindow(window_info_.hwnd); - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < 5; ++i) { capturer_->CaptureFrame(); EXPECT_EQ(result_, DesktopCapturer::Result::ERROR_TEMPORARY); } @@ -520,19 +543,24 @@ TEST_F(WgcCapturerWindowTest, CloseWindowMidCapture) { // stops. auto* wgc_capturer = static_cast(capturer_.get()); MSG msg; - while (wgc_capturer->IsSourceBeingCaptured(source_id_)) { + for (int i = 0; + wgc_capturer->IsSourceBeingCaptured(source_id_) && i < kMaxTries; ++i) { // Unlike GetMessage, PeekMessage will not hang if there are no messages in // the queue. PeekMessage(&msg, 0, 0, 0, PM_REMOVE); SleepMs(1); } - // Occasionally, one last frame will have made it into the frame pool before - // the window closed. The first call will consume it, and in that case we need - // to make one more call to CaptureFrame. - capturer_->CaptureFrame(); - if (result_ == DesktopCapturer::Result::SUCCESS) + EXPECT_FALSE(wgc_capturer->IsSourceBeingCaptured(source_id_)); + + // The frame pool can buffer `kNumBuffers` frames. We must consume these + // and then make one more call to CaptureFrame before we expect to see the + // failure. + int num_tries = 0; + do { capturer_->CaptureFrame(); + } while (result_ == DesktopCapturer::Result::SUCCESS && + ++num_tries <= WgcCaptureSession::kNumBuffers); EXPECT_GE(metrics::NumEvents(kCapturerResultHistogram, kSessionStartFailure), 1);