)]}'
{
  "commit": "00cf9011ae3f07bbd7fb0309eaa4fb3886b592a4",
  "tree": "5517ca46f8bf297584c42516d004a0812fc16c7b",
  "parents": [
    "a8fade335f54b8f567913e08c2476a0825f81248"
  ],
  "author": {
    "name": "Brandon DeRosier",
    "email": "bdero@google.com",
    "time": "Tue Jun 09 11:04:59 2026 -0700"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Tue Jun 09 18:04:59 2026 +0000"
  },
  "message": "[Flutter GPU] Allow attaching specific texture mip levels and slices for rendering (#187685)\n\nFixes flutter/flutter#150455\n\nSurfaces the Impeller HAL support for rendering into a specific texture\nmip level and slice (landed in #187470) to Flutter GPU.\n\n- Adds `mipLevel` and `slice` (both default 0) to `ColorAttachment` and\n`DepthStencilAttachment`. They select the subresource of the attachment\ntexture to render into: a non-zero mip level, a cube map face, or both.\n- Validates, in Dart and unconditionally, that each attachment\u0027s\n`mipLevel` and `slice` are in range (including the MSAA resolve texture)\nand that all attachments resolve to the same size. Out-of-range\nsubresources and size mismatches are undefined behavior in release,\nwhere the engine-side checks are compiled out.\n- Adds `GpuContext.doesSupportFramebufferRenderMipmap`, lifted onto the\nbase `Capabilities` interface so it can be queried. Rendering into a\ncube face is always available. Rendering into a non-zero mip level\nreturns true on Metal and Vulkan and false on GLES: the GLES texture\nstorage path yields an incomplete framebuffer for a non-base mip\nattachment, so the capability is conservative until that is reworked\n(tracked separately). Cube face rendering on GLES is unaffected.\n\nTests cover rendering into a cube slice, rendering into a non-zero mip\nlevel (gated on the capability), and the range and size validation.\n\n## Pre-launch Checklist\n\n- [x] I read the [Contributor Guide] and followed the process outlined\nthere for submitting PRs.\n- [x] I read the [AI contribution guidelines] and understand my\nresponsibilities, or I am not using AI tools.\n- [x] I read the [Tree Hygiene] wiki page, which explains my\nresponsibilities.\n- [x] I read and followed the [Flutter Style Guide], including [Features\nwe expect every widget to implement].\n- [x] I signed the [CLA].\n- [x] I listed at least one issue that this PR fixes in the description\nabove.\n- [x] I updated/added relevant documentation (doc comments with `///`).\n- [x] I added new tests to check the change I am making, or this PR is\n[test-exempt].\n- [x] I followed the [breaking change policy] and added [Data Driven\nFixes] where supported.\n- [ ] All existing and new tests are passing.\n\n\u003c!-- Links --\u003e\n[Contributor Guide]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview\n[AI contribution guidelines]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines\n[Tree Hygiene]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md\n[test-exempt]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests\n[Flutter Style Guide]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md\n[Features we expect every widget to implement]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement\n[CLA]: https://cla.developers.google.com/\n[breaking change policy]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes\n[Data Driven Fixes]:\nhttps://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "5c0f4673e956775a20482ad07c411b71bd1515a5",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc",
      "new_id": "200f6d9bc87b8890a748ab82964a553194a34999",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc"
    },
    {
      "type": "modify",
      "old_id": "21c00363560f8f9ab0b716b119d9890515df47d9",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h",
      "new_id": "28d5fabc60e90e30d31e24b54ae0d242072c2143",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h"
    },
    {
      "type": "modify",
      "old_id": "e1cb178a9163657466c2929a9455b96a4b397b36",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc",
      "new_id": "4c00888683432da13517250cc4c0c82c3f368038",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc"
    },
    {
      "type": "modify",
      "old_id": "17716a35785e250c96f3b95986bbab21bf5cc5ba",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc",
      "new_id": "191fc8c407e544c9cbebf7c9ab8321ad279bfeca",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc"
    },
    {
      "type": "modify",
      "old_id": "ece2f5194d74eef7d28ae6c5c8ea07fb09e47f2b",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.h",
      "new_id": "223fe2b1bc54029d6a35f3b25a18363c779bd4c0",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/backend/vulkan/capabilities_vk.h"
    },
    {
      "type": "modify",
      "old_id": "74423496f293c4f3e09f9bfa052e5998a70ce1f8",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/capabilities.cc",
      "new_id": "1851d80b92f0c9c29b07ac3ac0f555f2df7e3a17",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/capabilities.cc"
    },
    {
      "type": "modify",
      "old_id": "f7d1ecbffa2503010f2de6cca207a9990eccc378",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/capabilities.h",
      "new_id": "3a89fe4d03c16ace66b671d537abfb3b2af9fa05",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/capabilities.h"
    },
    {
      "type": "modify",
      "old_id": "c753bf5fe0d87c8b7f6dcce7cd44cde3f4adc6e9",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/impeller/renderer/testing/mocks.h",
      "new_id": "32ad9949426f10d285558209196e7d1aa239de41",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/impeller/renderer/testing/mocks.h"
    },
    {
      "type": "modify",
      "old_id": "7a6e81fb2930951bbe8775248015cb0bb063dd2b",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/lib/gpu/context.cc",
      "new_id": "5945187830dc5de8995dbd959e7e5d599f48d372",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/lib/gpu/context.cc"
    },
    {
      "type": "modify",
      "old_id": "56672a00f8666ac304c188c3b04302c9ff6d36d7",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/lib/gpu/context.h",
      "new_id": "b6693dcc456dfbd4ab91fc4ae6838c9502da7451",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/lib/gpu/context.h"
    },
    {
      "type": "modify",
      "old_id": "dd67e488249c50e7eeda2665a25c5a5c2e1e4489",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/lib/gpu/lib/src/context.dart",
      "new_id": "5273e13eb71a4db267eed9f76b9eec88f3e4f55d",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/lib/gpu/lib/src/context.dart"
    },
    {
      "type": "modify",
      "old_id": "b9d6db41844d567f50aab020073e3673e3bddf68",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/lib/gpu/lib/src/render_pass.dart",
      "new_id": "4ade61c7330a14c8271b54533e6d7ca8fa551a51",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/lib/gpu/lib/src/render_pass.dart"
    },
    {
      "type": "modify",
      "old_id": "5903621a8643d7d690970f0613d7f5b5afc93181",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/lib/gpu/lib/src/texture.dart",
      "new_id": "06ff2f4fdbbf37868fe564f5ea1830dc38e1330c",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/lib/gpu/lib/src/texture.dart"
    },
    {
      "type": "modify",
      "old_id": "643e219d766d62ad45f7ee408a88ac2a3a34110b",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/lib/gpu/render_pass.cc",
      "new_id": "c355a588deb141d18ae9d7b23042a3ee0032fcdf",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/lib/gpu/render_pass.cc"
    },
    {
      "type": "modify",
      "old_id": "a0b4c55fd5a537ef6a2f956618279bd961c9b439",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/lib/gpu/render_pass.h",
      "new_id": "4a80aa63b814541a4652844e1f90904eace27307",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/lib/gpu/render_pass.h"
    },
    {
      "type": "modify",
      "old_id": "94053c962c695738d155140cb4b35507398cd14f",
      "old_mode": 33188,
      "old_path": "engine/src/flutter/testing/dart/gpu_test.dart",
      "new_id": "8a57c959fc9bfb4f7667537bd50d72f8e8b92be3",
      "new_mode": 33188,
      "new_path": "engine/src/flutter/testing/dart/gpu_test.dart"
    }
  ]
}
