[Impeller] Specify default border color for texture wrap mode that clamps. (#46806)

Fixes https://github.com/flutter/flutter/issues/136153
diff --git a/impeller/renderer/backend/gles/gles.h b/impeller/renderer/backend/gles/gles.h
index e14116e..9022cd0 100644
--- a/impeller/renderer/backend/gles/gles.h
+++ b/impeller/renderer/backend/gles/gles.h
@@ -6,7 +6,11 @@
 
 // IWYU pragma: begin_exports
 #include "GLES3/gl3.h"
-#define GL_CLAMP_TO_BORDER 0x812D
+
+// Defines for extension enums.
+#define IMPELLER_GL_CLAMP_TO_BORDER 0x812D
+#define IMPELLER_GL_TEXTURE_BORDER_COLOR 0x1004
+
 #define GL_GLEXT_PROTOTYPES
 #include "GLES2/gl2ext.h"
 // IWYU pragma: end_exports
diff --git a/impeller/renderer/backend/gles/proc_table_gles.h b/impeller/renderer/backend/gles/proc_table_gles.h
index 22945e6..bbf94a2 100644
--- a/impeller/renderer/backend/gles/proc_table_gles.h
+++ b/impeller/renderer/backend/gles/proc_table_gles.h
@@ -175,6 +175,7 @@
   PROC(StencilOpSeparate);                   \
   PROC(TexImage2D);                          \
   PROC(TexParameteri);                       \
+  PROC(TexParameterfv);                      \
   PROC(Uniform1fv);                          \
   PROC(Uniform1i);                           \
   PROC(Uniform2fv);                          \
diff --git a/impeller/renderer/backend/gles/sampler_gles.cc b/impeller/renderer/backend/gles/sampler_gles.cc
index 19d4e0f..729add5 100644
--- a/impeller/renderer/backend/gles/sampler_gles.cc
+++ b/impeller/renderer/backend/gles/sampler_gles.cc
@@ -64,9 +64,10 @@
       return GL_MIRRORED_REPEAT;
     case SamplerAddressMode::kDecal:
       if (supports_decal_sampler_address_mode) {
-        return GL_CLAMP_TO_BORDER;
+        return IMPELLER_GL_CLAMP_TO_BORDER;
+      } else {
+        return GL_CLAMP_TO_EDGE;
       }
-      break;
   }
   FML_UNREACHABLE();
 }
@@ -96,18 +97,28 @@
     mip_filter = desc.mip_filter;
   }
 
-  gl.TexParameteri(target.value(), GL_TEXTURE_MIN_FILTER,
+  gl.TexParameteri(*target, GL_TEXTURE_MIN_FILTER,
                    ToParam(desc.min_filter, mip_filter));
-  gl.TexParameteri(target.value(), GL_TEXTURE_MAG_FILTER,
-                   ToParam(desc.mag_filter));
-  gl.TexParameteri(
-      target.value(), GL_TEXTURE_WRAP_S,
-      ToAddressMode(desc.width_address_mode,
-                    gl.GetCapabilities()->SupportsDecalSamplerAddressMode()));
-  gl.TexParameteri(
-      target.value(), GL_TEXTURE_WRAP_T,
-      ToAddressMode(desc.height_address_mode,
-                    gl.GetCapabilities()->SupportsDecalSamplerAddressMode()));
+  gl.TexParameteri(*target, GL_TEXTURE_MAG_FILTER, ToParam(desc.mag_filter));
+
+  const auto supports_decal_mode =
+      gl.GetCapabilities()->SupportsDecalSamplerAddressMode();
+
+  const auto wrap_s =
+      ToAddressMode(desc.width_address_mode, supports_decal_mode);
+  const auto wrap_t =
+      ToAddressMode(desc.height_address_mode, supports_decal_mode);
+
+  gl.TexParameteri(*target, GL_TEXTURE_WRAP_S, wrap_s);
+  gl.TexParameteri(*target, GL_TEXTURE_WRAP_T, wrap_t);
+
+  if (wrap_s == IMPELLER_GL_CLAMP_TO_BORDER ||
+      wrap_t == IMPELLER_GL_CLAMP_TO_BORDER) {
+    // Transparent black.
+    const GLfloat border_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+    gl.TexParameterfv(*target, IMPELLER_GL_TEXTURE_BORDER_COLOR, border_color);
+  }
+
   return true;
 }
 
diff --git a/impeller/renderer/backend/metal/sampler_library_mtl.mm b/impeller/renderer/backend/metal/sampler_library_mtl.mm
index c9099c5..fa65591 100644
--- a/impeller/renderer/backend/metal/sampler_library_mtl.mm
+++ b/impeller/renderer/backend/metal/sampler_library_mtl.mm
@@ -29,7 +29,9 @@
   desc.sAddressMode = ToMTLSamplerAddressMode(descriptor.width_address_mode);
   desc.tAddressMode = ToMTLSamplerAddressMode(descriptor.height_address_mode);
   desc.rAddressMode = ToMTLSamplerAddressMode(descriptor.depth_address_mode);
-
+  if (@available(iOS 14.0, macos 10.12, *)) {
+    desc.borderColor = MTLSamplerBorderColorTransparentBlack;
+  }
   if (!descriptor.label.empty()) {
     desc.label = @(descriptor.label.c_str());
   }