Add initial support for 4x MSAA in OpenGLES backend. (#46381)

Initial support _towards_ https://github.com/flutter/flutter/issues/130045.

This updates the `PROC_TABLE`, and adds (and supports) `Type::kRenderBufferMultisampled`.

The type remains unused in the actual engine, and will be in a follow-up PR once we like this one!

/cc @chinmaygarde
diff --git a/impeller/renderer/backend/gles/gles.h b/impeller/renderer/backend/gles/gles.h
index 599e3c9..9bacfc8 100644
--- a/impeller/renderer/backend/gles/gles.h
+++ b/impeller/renderer/backend/gles/gles.h
@@ -4,6 +4,8 @@
 
 #pragma once
 
+// IWYU pragma: begin_exports
 #include "GLES3/gl3.h"
 #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 0af4000..eac2b77 100644
--- a/impeller/renderer/backend/gles/proc_table_gles.h
+++ b/impeller/renderer/backend/gles/proc_table_gles.h
@@ -6,12 +6,10 @@
 
 #include <functional>
 #include <string>
-#include <vector>
 
 #include "flutter/fml/logging.h"
 #include "flutter/fml/macros.h"
 #include "flutter/fml/mapping.h"
-#include "flutter/fml/trace_event.h"
 #include "impeller/renderer/backend/gles/capabilities_gles.h"
 #include "impeller/renderer/backend/gles/description_gles.h"
 #include "impeller/renderer/backend/gles/gles.h"
@@ -170,11 +168,13 @@
 
 #define FOR_EACH_IMPELLER_GLES3_PROC(PROC) PROC(BlitFramebuffer);
 
-#define FOR_EACH_IMPELLER_EXT_PROC(PROC) \
-  PROC(DiscardFramebufferEXT);           \
-  PROC(PushDebugGroupKHR);               \
-  PROC(PopDebugGroupKHR);                \
-  PROC(ObjectLabelKHR);
+#define FOR_EACH_IMPELLER_EXT_PROC(PROC)   \
+  PROC(DiscardFramebufferEXT);             \
+  PROC(FramebufferTexture2DMultisampleEXT) \
+  PROC(PushDebugGroupKHR);                 \
+  PROC(PopDebugGroupKHR);                  \
+  PROC(ObjectLabelKHR);                    \
+  PROC(RenderbufferStorageMultisampleEXT);
 
 enum class DebugResourceType {
   kTexture,
@@ -188,7 +188,7 @@
 class ProcTableGLES {
  public:
   using Resolver = std::function<void*(const char* function_name)>;
-  ProcTableGLES(Resolver resolver);
+  explicit ProcTableGLES(Resolver resolver);
 
   ~ProcTableGLES();
 
diff --git a/impeller/renderer/backend/gles/render_pass_gles.cc b/impeller/renderer/backend/gles/render_pass_gles.cc
index 65ce6c2..735f8a8 100644
--- a/impeller/renderer/backend/gles/render_pass_gles.cc
+++ b/impeller/renderer/backend/gles/render_pass_gles.cc
@@ -4,10 +4,7 @@
 
 #include "impeller/renderer/backend/gles/render_pass_gles.h"
 
-#include <algorithm>
-
 #include "flutter/fml/trace_event.h"
-#include "impeller/base/config.h"
 #include "impeller/base/validation.h"
 #include "impeller/renderer/backend/gles/device_buffer_gles.h"
 #include "impeller/renderer/backend/gles/formats_gles.h"
diff --git a/impeller/renderer/backend/gles/texture_gles.cc b/impeller/renderer/backend/gles/texture_gles.cc
index 6c01e6b..1ea904c 100644
--- a/impeller/renderer/backend/gles/texture_gles.cc
+++ b/impeller/renderer/backend/gles/texture_gles.cc
@@ -10,7 +10,6 @@
 #include "flutter/fml/mapping.h"
 #include "flutter/fml/trace_event.h"
 #include "impeller/base/allocation.h"
-#include "impeller/base/config.h"
 #include "impeller/base/validation.h"
 #include "impeller/core/formats.h"
 #include "impeller/renderer/backend/gles/formats_gles.h"
@@ -33,6 +32,8 @@
     case TextureGLES::Type::kTexture:
       return HandleType::kTexture;
     case TextureGLES::Type::kRenderBuffer:
+    // MSAA textures are treated as render buffers.
+    case TextureGLES::Type::kRenderBufferMultisampled:
       return HandleType::kRenderBuffer;
   }
   FML_UNREACHABLE();
@@ -383,7 +384,7 @@
       }
 
     } break;
-    case Type::kRenderBuffer:
+    case Type::kRenderBuffer: {
       auto render_buffer_format =
           ToRenderBufferFormat(GetTextureDescriptor().format);
       if (!render_buffer_format.has_value()) {
@@ -399,7 +400,27 @@
                                size.height                    // height
         );
       }
+    } break;
+    case Type::kRenderBufferMultisampled: {
+      auto render_buffer_msaa =
+          ToRenderBufferFormat(GetTextureDescriptor().format);
+      if (!render_buffer_msaa.has_value()) {
+        VALIDATION_LOG << "Invalid format for render-buffer MSAA image.";
+        return;
+      }
+      gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
+      {
+        TRACE_EVENT0("impeller", "RenderBufferStorageInitialization");
+        gl.RenderbufferStorageMultisampleEXT(
+            GL_RENDERBUFFER,             // target
+            4,                           // samples
+            render_buffer_msaa.value(),  // internal format
+            size.width,                  // width
+            size.height                  // height
+        );
+      }
       break;
+    }
   }
 }
 
@@ -426,6 +447,8 @@
       gl.BindTexture(target.value(), handle.value());
     } break;
     case Type::kRenderBuffer:
+    // MSAA textures are treated as render buffers.
+    case Type::kRenderBufferMultisampled:
       gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value());
       break;
   }
@@ -510,6 +533,18 @@
                                  handle.value()    // render-buffer
       );
       break;
+    case Type::kRenderBufferMultisampled:
+      // Assume that when MSAA is enabled, we're using 4x MSAA.
+      FML_DCHECK(GetTextureDescriptor().sample_count == SampleCount::kCount4);
+      gl.FramebufferTexture2DMultisampleEXT(
+          target,                    // target
+          ToAttachmentPoint(point),  // attachment
+          GL_TEXTURE_2D,             // textarget
+          handle.value(),            // texture
+          0,                         // level
+          4                          // samples
+      );
+      break;
   }
   return true;
 }
diff --git a/impeller/renderer/backend/gles/texture_gles.h b/impeller/renderer/backend/gles/texture_gles.h
index e2d2ae3..effee19 100644
--- a/impeller/renderer/backend/gles/texture_gles.h
+++ b/impeller/renderer/backend/gles/texture_gles.h
@@ -18,6 +18,7 @@
   enum class Type {
     kTexture,
     kRenderBuffer,
+    kRenderBufferMultisampled,
   };
 
   enum class IsWrapped {