From f7504d021f8c09c1d601ebc2309ce17baca17120 Mon Sep 17 00:00:00 2001 From: nhant Date: Fri, 8 May 2026 11:00:33 +0700 Subject: [PATCH 1/3] feat: software-mode external texture support for D3D11-hooked apps --- .../flutter/shell/platform/embedder/BUILD.gn | 2 + .../shell/platform/embedder/embedder.cc | 36 ++++++ .../shell/platform/embedder/embedder.h | 42 +++++++ .../embedder_external_texture_resolver.cc | 13 +++ .../embedder_external_texture_resolver.h | 7 ++ .../embedder_external_texture_software.cc | 104 ++++++++++++++++++ .../embedder_external_texture_software.h | 58 ++++++++++ .../windows/flutter_windows_engine.cc | 13 +++ .../flutter_windows_texture_registrar.cc | 69 ++++++++++-- .../flutter_windows_texture_registrar.h | 14 +++ 10 files changed, 351 insertions(+), 7 deletions(-) create mode 100644 engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.cc create mode 100644 engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.h diff --git a/engine/src/flutter/shell/platform/embedder/BUILD.gn b/engine/src/flutter/shell/platform/embedder/BUILD.gn index 5a430ce408fd3..b36ca4b4b8e12 100644 --- a/engine/src/flutter/shell/platform/embedder/BUILD.gn +++ b/engine/src/flutter/shell/platform/embedder/BUILD.gn @@ -62,6 +62,8 @@ template("embedder_source_set") { "embedder_engine.h", "embedder_external_texture_resolver.cc", "embedder_external_texture_resolver.h", + "embedder_external_texture_software.cc", + "embedder_external_texture_software.h", "embedder_external_view.cc", "embedder_external_view.h", "embedder_external_view_embedder.cc", diff --git a/engine/src/flutter/shell/platform/embedder/embedder.cc b/engine/src/flutter/shell/platform/embedder/embedder.cc index 8bec5367a87b4..0cf5a99652791 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder.cc @@ -2314,6 +2314,42 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, } } #endif + + // Software-mode external texture callback (no GL/Metal required). + // Allows Texture widget to render plugin-provided pixel buffers when + // Flutter falls back to software rasterization. + flutter::EmbedderExternalTextureSoftware::ExternalTextureCallback + external_texture_software_callback; + if (config->type == kSoftware) { + const FlutterSoftwareRendererConfig* software_config = &config->software; + if (SAFE_ACCESS(software_config, external_texture_frame_callback, + nullptr) != nullptr) { + auto sw_user_data = + SAFE_ACCESS(software_config, external_texture_user_data, user_data); + // If embedder did not set the override field (or set it to nullptr), + // fall back to the main engine user_data — every callback reaches + // back into the engine via that pointer. + if (!sw_user_data) { + sw_user_data = user_data; + } + external_texture_software_callback = + [ptr = software_config->external_texture_frame_callback, + sw_user_data](int64_t texture_identifier, size_t width, + size_t height) + -> std::unique_ptr { + std::unique_ptr pixel_buffer = + std::make_unique(); + if (!ptr(sw_user_data, texture_identifier, width, height, + pixel_buffer.get())) { + return nullptr; + } + return pixel_buffer; + }; + external_texture_resolver = std::make_unique( + external_texture_software_callback); + } + } + auto custom_task_runners = SAFE_ACCESS(args, custom_task_runners, nullptr); auto thread_config_callback = [&custom_task_runners]( const fml::Thread::ThreadConfig& config) { diff --git a/engine/src/flutter/shell/platform/embedder/embedder.h b/engine/src/flutter/shell/platform/embedder/embedder.h index 1d656e355baa3..6d1d50d1b0a11 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.h +++ b/engine/src/flutter/shell/platform/embedder/embedder.h @@ -515,6 +515,36 @@ typedef bool (*TextureFrameCallback)(void* /* user data */, size_t /* width */, size_t /* height */, FlutterOpenGLTexture* /* texture out */); + +// A CPU pixel buffer used to deliver an external texture frame in software +// rendering mode. Mirrors the generic shape of FlutterDesktopPixelBuffer but +// is defined here in the embedder layer to keep the renderer-config API +// platform-agnostic. +typedef struct { + /// Pointer to the pixel data. Must be RGBA8888 with row-major layout and + /// |width| * 4 bytes per row. + const uint8_t* buffer; + /// Width of the pixel buffer in pixels. + size_t width; + /// Height of the pixel buffer in pixels. + size_t height; + /// Optional callback invoked when the engine has consumed |buffer|. The + /// embedder must keep |buffer| valid until this callback fires (or until + /// the texture is unregistered). + void (*release_callback)(void* release_context); + /// Opaque data passed to |release_callback|. + void* release_context; +} FlutterSoftwarePixelBuffer; + +// Software-mode external texture callback. Mirrors |TextureFrameCallback| +// but delivers a CPU pixel buffer instead of a GL texture. +typedef bool (*SoftwareTextureFrameCallback)( + void* /* user data */, + int64_t /* texture identifier */, + size_t /* width */, + size_t /* height */, + FlutterSoftwarePixelBuffer* /* pixel buffer out */); + typedef void (*VsyncCallback)(void* /* user data */, intptr_t /* baton */); typedef void (*OnPreEngineRestartCallback)(void* /* user data */); @@ -920,6 +950,18 @@ typedef struct { /// format. The buffer is owned by the Flutter engine and must be copied in /// this callback if needed. SoftwareSurfacePresentCallback surface_present_callback; + + /// Optional callback invoked by the engine to retrieve a pixel buffer for + /// an external texture rendered in software mode. When set, allows the + /// |Texture| widget to render content provided by embedders/plugins even + /// when the engine is using the software rasterizer (e.g. when ANGLE/D3D11 + /// is unavailable on Windows). + /// + /// This field is read using SAFE_ACCESS so older embedders that do not + /// provide it continue to work. + SoftwareTextureFrameCallback external_texture_frame_callback; + /// User data passed back to |external_texture_frame_callback|. + void* external_texture_user_data; } FlutterSoftwareRendererConfig; typedef struct { diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc index 4e4b41b8d4ad2..f7939a7ff14a4 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc @@ -21,6 +21,10 @@ EmbedderExternalTextureResolver::EmbedderExternalTextureResolver( : metal_callback_(std::move(metal_callback)) {} #endif +EmbedderExternalTextureResolver::EmbedderExternalTextureResolver( + EmbedderExternalTextureSoftware::ExternalTextureCallback sw_callback) + : software_callback_(std::move(sw_callback)) {} + std::unique_ptr EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) { #ifdef SHELL_ENABLE_GL @@ -37,6 +41,11 @@ EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) { } #endif + if (software_callback_) { + return std::make_unique(texture_id, + software_callback_); + } + return nullptr; } @@ -53,6 +62,10 @@ bool EmbedderExternalTextureResolver::SupportsExternalTextures() { } #endif + if (software_callback_) { + return true; + } + return false; } diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h index 412301736e566..f3d7458735b92 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h @@ -17,6 +17,8 @@ #include "flutter/shell/platform/embedder/embedder_external_texture_metal.h" #endif +#include "flutter/shell/platform/embedder/embedder_external_texture_software.h" + namespace flutter { class EmbedderExternalTextureResolver { public: @@ -34,6 +36,9 @@ class EmbedderExternalTextureResolver { EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback); #endif + explicit EmbedderExternalTextureResolver( + EmbedderExternalTextureSoftware::ExternalTextureCallback sw_callback); + std::unique_ptr ResolveExternalTexture(int64_t texture_id); bool SupportsExternalTextures(); @@ -47,6 +52,8 @@ class EmbedderExternalTextureResolver { EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback_; #endif + EmbedderExternalTextureSoftware::ExternalTextureCallback software_callback_; + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureResolver); }; } // namespace flutter diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.cc new file mode 100644 index 0000000000000..61430acab0355 --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.cc @@ -0,0 +1,104 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/embedder/embedder_external_texture_software.h" + +#include "flutter/fml/logging.h" +#include "third_party/skia/include/core/SkAlphaType.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkColorType.h" +#include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/core/SkImageInfo.h" +#include "third_party/skia/include/core/SkPixmap.h" +#include "third_party/skia/include/core/SkSize.h" + +namespace flutter { + +EmbedderExternalTextureSoftware::EmbedderExternalTextureSoftware( + int64_t texture_identifier, + const ExternalTextureCallback& callback) + : Texture(texture_identifier), external_texture_callback_(callback) { + FML_DCHECK(external_texture_callback_); +} + +EmbedderExternalTextureSoftware::~EmbedderExternalTextureSoftware() = default; + +// |flutter::Texture| +void EmbedderExternalTextureSoftware::Paint(PaintContext& context, + const SkRect& bounds, + bool freeze, + const DlImageSampling sampling) { + if (last_image_ == nullptr) { + last_image_ = + ResolveTexture(Id(), // + SkISize::Make(bounds.width(), bounds.height()) // + ); + } + + DlCanvas* canvas = context.canvas; + const DlPaint* paint = context.paint; + + if (last_image_) { + SkRect image_bounds = SkRect::Make(last_image_->bounds()); + if (bounds != image_bounds) { + canvas->DrawImageRect(last_image_, image_bounds, bounds, sampling, paint); + } else { + canvas->DrawImage(last_image_, SkPoint{bounds.x(), bounds.y()}, sampling, + paint); + } + } +} + +sk_sp EmbedderExternalTextureSoftware::ResolveTexture( + int64_t texture_id, + const SkISize& size) { + std::unique_ptr pixel_buffer = + external_texture_callback_(texture_id, size.width(), size.height()); + + if (!pixel_buffer || !pixel_buffer->buffer || pixel_buffer->width == 0 || + pixel_buffer->height == 0) { + return nullptr; + } + + SkImageInfo info = SkImageInfo::Make( + static_cast(pixel_buffer->width), + static_cast(pixel_buffer->height), kRGBA_8888_SkColorType, + kPremul_SkAlphaType); + SkPixmap pixmap(info, pixel_buffer->buffer, + pixel_buffer->width * 4 /* row bytes (RGBA) */); + + // Copy the pixels into a Skia-owned SkImage so we can release the source + // buffer immediately. RasterFromPixmapCopy allocates and copies; for very + // high frame rates we could alternatively use RasterFromPixmap with a + // release proc to avoid the copy, but that requires more careful lifetime + // management with the embedder's pixel buffer ownership model. + sk_sp image = SkImages::RasterFromPixmapCopy(pixmap); + + if (pixel_buffer->release_callback) { + pixel_buffer->release_callback(pixel_buffer->release_context); + } + + if (!image) { + FML_LOG(ERROR) << "Could not create software external texture image."; + return nullptr; + } + + return DlImage::Make(std::move(image)); +} + +// |flutter::Texture| +void EmbedderExternalTextureSoftware::OnGrContextCreated() {} + +// |flutter::Texture| +void EmbedderExternalTextureSoftware::OnGrContextDestroyed() {} + +// |flutter::Texture| +void EmbedderExternalTextureSoftware::MarkNewFrameAvailable() { + last_image_ = nullptr; +} + +// |flutter::Texture| +void EmbedderExternalTextureSoftware::OnTextureUnregistered() {} + +} // namespace flutter diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.h new file mode 100644 index 0000000000000..12641c3fe0c15 --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_software.h @@ -0,0 +1,58 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_SOFTWARE_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_SOFTWARE_H_ + +#include "flutter/common/graphics/texture.h" +#include "flutter/fml/macros.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "third_party/skia/include/core/SkSize.h" + +namespace flutter { + +// External texture implementation for software rendering mode. +// Wraps a CPU pixel buffer as a Skia raster image — no GL required. +// Mirrors EmbedderExternalTextureGL but bypasses the OpenGL pipeline so +// embedders can render external textures while Flutter is in software mode. +class EmbedderExternalTextureSoftware : public flutter::Texture { + public: + using ExternalTextureCallback = std::function< + std::unique_ptr(int64_t, size_t, size_t)>; + + EmbedderExternalTextureSoftware(int64_t texture_identifier, + const ExternalTextureCallback& callback); + + ~EmbedderExternalTextureSoftware() override; + + private: + const ExternalTextureCallback& external_texture_callback_; + sk_sp last_image_; + + sk_sp ResolveTexture(int64_t texture_id, const SkISize& size); + + // |flutter::Texture| + void Paint(PaintContext& context, + const SkRect& bounds, + bool freeze, + const DlImageSampling sampling) override; + + // |flutter::Texture| + void OnGrContextCreated() override; + + // |flutter::Texture| + void OnGrContextDestroyed() override; + + // |flutter::Texture| + void MarkNewFrameAvailable() override; + + // |flutter::Texture| + void OnTextureUnregistered() override; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureSoftware); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_SOFTWARE_H_ diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc b/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc index 4402f89e14b86..6606880b22d5f 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_engine.cc @@ -113,6 +113,19 @@ FlutterRendererConfig GetSoftwareRendererConfig() { FML_UNREACHABLE(); return false; }; + // Allow the Texture widget to render plugin-provided pixel buffers while + // Flutter is in software mode. Without this, |Texture| would render black + // because the embedder API has no way to ask back for the pixel data. + config.software.external_texture_frame_callback = + [](void* user_data, int64_t texture_id, size_t width, size_t height, + FlutterSoftwarePixelBuffer* out) -> bool { + auto host = static_cast(user_data); + if (!host->texture_registrar()) { + return false; + } + return host->texture_registrar()->PopulateTextureSoftware( + texture_id, width, height, out); + }; return config; } diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc index f71da67bd9d99..886dc7e76d014 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc @@ -4,6 +4,7 @@ #include "flutter/shell/platform/windows/flutter_windows_texture_registrar.h" +#include #include #include "flutter/fml/logging.h" @@ -14,6 +15,11 @@ namespace { static constexpr int64_t kInvalidTexture = -1; + +// Software-mode texture ids start from a small positive number. They never +// collide with the GL/D3D path's ids because that path stores `this` +// pointers (large heap addresses) cast to int64. +static std::atomic next_software_texture_id{1}; } namespace flutter { @@ -25,20 +31,37 @@ FlutterWindowsTextureRegistrar::FlutterWindowsTextureRegistrar( int64_t FlutterWindowsTextureRegistrar::RegisterTexture( const FlutterDesktopTextureInfo* texture_info) { - if (!gl_) { - return kInvalidTexture; - } - if (texture_info->type == kFlutterDesktopPixelBufferTexture) { if (!texture_info->pixel_buffer_config.callback) { FML_LOG(ERROR) << "Invalid pixel buffer texture callback."; return kInvalidTexture; } - return EmplaceTexture(std::make_unique( - texture_info->pixel_buffer_config.callback, - texture_info->pixel_buffer_config.user_data, gl_)); + // Pixel-buffer textures need to work in BOTH GL and software rendering + // modes — but |gl_| is always non-null (constructed unconditionally in + // FlutterWindowsEngine), so we cannot use it to decide which mode is + // active. Instead, we register the callback in BOTH maps: + // - |textures_| (via EmplaceTexture) for the GL path + // - |software_pixel_buffer_callbacks_| for the software path + // The actual rendering mode is decided by the engine later via the + // appropriate FlutterRendererConfig callback. + auto external_texture = + std::make_unique( + texture_info->pixel_buffer_config.callback, + texture_info->pixel_buffer_config.user_data, gl_); + int64_t texture_id = external_texture->texture_id(); + { + std::lock_guard lock(map_mutex_); + software_pixel_buffer_callbacks_[texture_id] = + texture_info->pixel_buffer_config; + } + return EmplaceTexture(std::move(external_texture)); } else if (texture_info->type == kFlutterDesktopGpuSurfaceTexture) { + if (!gl_) { + // GPU surface textures require a GL context to share with - not + // supported in software mode. + return kInvalidTexture; + } const FlutterDesktopGpuSurfaceTextureConfig* gpu_surface_config = &texture_info->gpu_surface_config; auto surface_type = SAFE_ACCESS(gpu_surface_config, type, @@ -89,6 +112,10 @@ void FlutterWindowsTextureRegistrar::UnregisterTexture(int64_t texture_id, if (it != textures_.end()) { textures_.erase(it); } + auto sw_it = software_pixel_buffer_callbacks_.find(texture_id); + if (sw_it != software_pixel_buffer_callbacks_.end()) { + software_pixel_buffer_callbacks_.erase(sw_it); + } } if (callback) { callback(); @@ -125,4 +152,32 @@ bool FlutterWindowsTextureRegistrar::PopulateTexture( return texture->PopulateTexture(width, height, opengl_texture); } +bool FlutterWindowsTextureRegistrar::PopulateTextureSoftware( + int64_t texture_id, + size_t width, + size_t height, + FlutterSoftwarePixelBuffer* pixel_buffer) { + FlutterDesktopPixelBufferTextureConfig cfg; + { + std::lock_guard lock(map_mutex_); + auto it = software_pixel_buffer_callbacks_.find(texture_id); + if (it == software_pixel_buffer_callbacks_.end()) { + return false; + } + cfg = it->second; + } + + size_t w = width, h = height; + const FlutterDesktopPixelBuffer* src = cfg.callback(w, h, cfg.user_data); + if (!src || !src->buffer) { + return false; + } + pixel_buffer->buffer = src->buffer; + pixel_buffer->width = src->width; + pixel_buffer->height = src->height; + pixel_buffer->release_callback = src->release_callback; + pixel_buffer->release_context = src->release_context; + return true; +} + }; // namespace flutter diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h index e065f0e709744..6f0a01219220d 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h @@ -45,6 +45,15 @@ class FlutterWindowsTextureRegistrar { size_t height, FlutterOpenGLTexture* texture); + // Attempts to populate the given pixel-buffer |pixel_buffer| by invoking the + // callback that was registered via |RegisterTexture| with type + // |kFlutterDesktopPixelBufferTexture|. + // Used by the software renderer path - no GL required. + bool PopulateTextureSoftware(int64_t texture_id, + size_t width, + size_t height, + FlutterSoftwarePixelBuffer* pixel_buffer); + private: FlutterWindowsEngine* engine_ = nullptr; std::shared_ptr gl_; @@ -54,6 +63,11 @@ class FlutterWindowsTextureRegistrar { textures_; std::mutex map_mutex_; + // Pixel-buffer texture callbacks registered while running in software mode + // (when |gl_| is null). Keyed by software-mode texture ids. + std::unordered_map + software_pixel_buffer_callbacks_; + int64_t EmplaceTexture(std::unique_ptr texture); FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindowsTextureRegistrar); From 938e0843acaef6b298addf547700c1fbea5fa07c Mon Sep 17 00:00:00 2001 From: NhaNT <160989306+guide-nhant@users.noreply.github.com> Date: Thu, 28 May 2026 11:48:56 +0700 Subject: [PATCH 2/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../platform/windows/flutter_windows_texture_registrar.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc index 886dc7e76d014..3e5363293cf3f 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.cc @@ -38,12 +38,12 @@ int64_t FlutterWindowsTextureRegistrar::RegisterTexture( } // Pixel-buffer textures need to work in BOTH GL and software rendering - // modes — but |gl_| is always non-null (constructed unconditionally in - // FlutterWindowsEngine), so we cannot use it to decide which mode is - // active. Instead, we register the callback in BOTH maps: + // modes. |gl_| may be null if GL proc lookup failed, and even when it is + // non-null it does not indicate which renderer mode is currently active. + // Instead, register the callback in BOTH maps: // - |textures_| (via EmplaceTexture) for the GL path // - |software_pixel_buffer_callbacks_| for the software path - // The actual rendering mode is decided by the engine later via the + // The actual rendering mode is selected by the engine later via the // appropriate FlutterRendererConfig callback. auto external_texture = std::make_unique( From 1468777b8ba3c9d339f16c890de2f7cc1fb8b79b Mon Sep 17 00:00:00 2001 From: NhaNT <160989306+guide-nhant@users.noreply.github.com> Date: Thu, 28 May 2026 11:49:06 +0700 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../platform/windows/flutter_windows_texture_registrar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h index 6f0a01219220d..32c26e6edb6f3 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_texture_registrar.h @@ -63,8 +63,8 @@ class FlutterWindowsTextureRegistrar { textures_; std::mutex map_mutex_; - // Pixel-buffer texture callbacks registered while running in software mode - // (when |gl_| is null). Keyed by software-mode texture ids. + // Pixel-buffer texture callbacks used by the software texture population + // path. Keyed by software-mode texture ids. std::unordered_map software_pixel_buffer_callbacks_;