)]}'
{
  "commit": "c81730e2baa17ee586eab6992ffc0628d88a424f",
  "tree": "4b3192564db81a9a8a80381d87b0effd733737f6",
  "parents": [
    "62cec3c04285da37e5bc17027cd85a81a9a6fb6e"
  ],
  "author": {
    "name": "Matej Knopp",
    "email": "matej.knopp@gmail.com",
    "time": "Wed Apr 17 15:22:20 2024 +0200"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Wed Apr 17 15:22:20 2024 +0200"
  },
  "message": "[macOS] FlutterSurfaceManager should not return surfaces that are in use (#52082)\n\nFixes https://github.com/flutter/flutter/issues/138936\r\n\r\nCurrently the engine hold a single backbuffer per flutter view layer,\r\nwhich gets swapped with front buffer. This however is too optimistic, as\r\nthe front buffer in some cases might not get immediately picked up by\r\nthe compositor. When that happens, during next frame the cache may\r\nreturn a backbuffer that is in fact still being used by the compositor.\r\nRendering to such surface will result in artifacts seen in the video.\r\nThis seems more likely to happen with busy platform thread. It is also\r\nmore likely to happen with the presence of \"heavy\" platform views such\r\nas `WKWebView`.\r\n\r\nIOSurface is able to report when it is being used by the compositor\r\n(`IOSurfaceIsInUse`). This PR ensures that the backing store cache never\r\nreturns surface that is being used by compositor. This may result in\r\ntransiently keeping more surfaces than before, as the compositor\r\nsometimes seems to holds on to the surface longer than it is displayed,\r\nbut that\u0027s preferable outcome to visual glitches.\r\n\r\nThis PR adds `age` field to `FlutterSurface`. When returning buffers to\r\nthe surface cache (during compositor commit), the age of each surface\r\ncurrently present in cache increases by one, while the newly returned\r\nsurfaces have their age set to 0.\r\n\r\nWhen returning surfaces from cache, a surface with lowest age that is\r\nnot in use by compositor is returned.\r\n\r\nSurfaces with age that reaches 30 are evicted from the pool. Reaching\r\nthis age means one of two things:\r\n- When surface is still in use at age 30 it means the compositor is\r\nholding on to it much longer than we expect. In this case just forget\r\nabout the surface, we can\u0027t really do anything about it.\r\n- When surface is not in use at age 30, it means it hasn\u0027t been removed\r\nfrom cache for 29 subsequent frames. That means the cache is holding more\r\nsurfaces than needed.\r\n\r\nRemoving all surfaces from cache after idle period remains unchanged.\r\n\r\nBefore: \r\n\r\n\r\nhttps://github.com/flutter/engine/assets/96958/ba2bfc43-525e-4a88-b37c-61842994d3bc\r\n\r\nAfter:\r\n\r\n\r\nhttps://github.com/flutter/engine/assets/96958/8b5d393e-3031-46b1-b3f0-cb7f63f8d960\r\n\r\n\r\n*If you had to change anything in the [flutter/tests] repo, include a\r\nlink to the migration guide as per the [breaking change policy].*\r\n\r\n## Pre-launch Checklist\r\n\r\n- [x] I read the [Contributor Guide] and followed the process outlined\r\nthere for submitting PRs.\r\n- [x] I read the [Tree Hygiene] wiki page, which explains my\r\nresponsibilities.\r\n- [x] I read and followed the [Flutter Style Guide] and the [C++,\r\nObjective-C, Java style guides].\r\n- [x] I listed at least one issue that this PR fixes in the description\r\nabove.\r\n- [x] I added new tests to check the change I am making or feature I am\r\nadding, or the PR is [test-exempt]. See [testing the engine] for\r\ninstructions on writing and running engine tests.\r\n- [x] I updated/added relevant documentation (doc comments with `///`).\r\n- [x] I signed the [CLA].\r\n- [x] All existing and new tests are passing.\r\n\r\nIf you need help, consider asking for advice on the #hackers-new channel\r\non [Discord].\r\n\r\n\u003c!-- Links --\u003e\r\n[Contributor Guide]:\r\nhttps://github.com/flutter/flutter/wiki/Tree-hygiene#overview\r\n[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene\r\n[test-exempt]:\r\nhttps://github.com/flutter/flutter/wiki/Tree-hygiene#tests\r\n[Flutter Style Guide]:\r\nhttps://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo\r\n[C++, Objective-C, Java style guides]:\r\nhttps://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style\r\n[testing the engine]:\r\nhttps://github.com/flutter/flutter/wiki/Testing-the-engine\r\n[CLA]: https://cla.developers.google.com/\r\n[flutter/tests]: https://github.com/flutter/tests\r\n[breaking change policy]:\r\nhttps://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes\r\n[Discord]: https://github.com/flutter/flutter/wiki/Chat",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "b566e68092dd3b3526dfef2f959875bf7464a2a0",
      "old_mode": 33188,
      "old_path": "shell/platform/darwin/macos/framework/Source/FlutterSurface.h",
      "new_id": "50f6a2ab324466b74c3652405cd606ae8164f175",
      "new_mode": 33188,
      "new_path": "shell/platform/darwin/macos/framework/Source/FlutterSurface.h"
    },
    {
      "type": "modify",
      "old_id": "4b65f2553c31551fa5c489062d72733dc10c5278",
      "old_mode": 33188,
      "old_path": "shell/platform/darwin/macos/framework/Source/FlutterSurface.mm",
      "new_id": "f61f81c5bf0b1aa404d0f5188740ff76da2bb99a",
      "new_mode": 33188,
      "new_path": "shell/platform/darwin/macos/framework/Source/FlutterSurface.mm"
    },
    {
      "type": "modify",
      "old_id": "279d580e2f4cdc18963cb58e62327553624f42db",
      "old_mode": 33188,
      "old_path": "shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h",
      "new_id": "d515741538bc02703897d90f566a55866f1d3e4e",
      "new_mode": 33188,
      "new_path": "shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h"
    },
    {
      "type": "modify",
      "old_id": "bed88bf5810829aced0e3cbdc38438f227a14e6b",
      "old_mode": 33188,
      "old_path": "shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm",
      "new_id": "d87aed4c9e4ce419fb3210077920932a7b071ecb",
      "new_mode": 33188,
      "new_path": "shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm"
    },
    {
      "type": "modify",
      "old_id": "04471eb914863f786b0b3c027ab6982ec2d7c4c4",
      "old_mode": 33188,
      "old_path": "shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm",
      "new_id": "8d6996280e6911adc7a4aee22e436e0c1be2120f",
      "new_mode": 33188,
      "new_path": "shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm"
    }
  ]
}
