From 14df054f9ca384ebe09be1f3fd28e1251a5ff42e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 31 Oct 2024 14:33:15 -0700 Subject: [PATCH] [Impeller] make desktop GL render. (flutter/engine#56274) Fixes https://github.com/flutter/flutter/issues/143387 Will be tested in https://github.com/flutter/flutter/pull/157888 --- .../renderer/backend/gles/buffer_bindings_gles.cc | 14 ++++++++++++-- .../renderer/backend/gles/buffer_bindings_gles.h | 5 +++-- .../renderer/backend/gles/capabilities_gles.cc | 6 +++++- .../renderer/backend/gles/capabilities_gles.h | 4 ++++ .../renderer/backend/gles/proc_table_gles.h | 3 +++ 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc index c893833b46..2b12ecd25d 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc @@ -153,11 +153,17 @@ bool BufferBindingsGLES::ReadUniformsBindings(const ProcTableGLES& gl, bool BufferBindingsGLES::BindVertexAttributes(const ProcTableGLES& gl, size_t binding, - size_t vertex_offset) const { + size_t vertex_offset) { if (binding >= vertex_attrib_arrays_.size()) { return false; } + if (!gl.GetCapabilities()->IsES()) { + FML_DCHECK(vertex_array_object_ == 0); + gl.GenVertexArrays(1, &vertex_array_object_); + gl.BindVertexArray(vertex_array_object_); + } + for (const auto& array : vertex_attrib_arrays_[binding]) { gl.EnableVertexAttribArray(array.index); gl.VertexAttribPointer(array.index, // index @@ -203,12 +209,16 @@ bool BufferBindingsGLES::BindUniformData(const ProcTableGLES& gl, return true; } -bool BufferBindingsGLES::UnbindVertexAttributes(const ProcTableGLES& gl) const { +bool BufferBindingsGLES::UnbindVertexAttributes(const ProcTableGLES& gl) { for (const auto& array : vertex_attrib_arrays_) { for (const auto& attribute : array) { gl.DisableVertexAttribArray(attribute.index); } } + if (!gl.GetCapabilities()->IsES()) { + gl.DeleteVertexArrays(1, &vertex_array_object_); + vertex_array_object_ = 0; + } return true; } diff --git a/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h b/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h index a8954b93ba..65642d8db3 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h +++ b/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h @@ -34,14 +34,14 @@ class BufferBindingsGLES { bool BindVertexAttributes(const ProcTableGLES& gl, size_t binding, - size_t vertex_offset) const; + size_t vertex_offset); bool BindUniformData(const ProcTableGLES& gl, Allocator& transients_allocator, const Bindings& vertex_bindings, const Bindings& fragment_bindings); - bool UnbindVertexAttributes(const ProcTableGLES& gl) const; + bool UnbindVertexAttributes(const ProcTableGLES& gl); private: //---------------------------------------------------------------------------- @@ -61,6 +61,7 @@ class BufferBindingsGLES { using BindingMap = std::unordered_map>; BindingMap binding_map_ = {}; + GLuint vertex_array_object_ = 0; const std::vector& ComputeUniformLocations( const ShaderMetadata* metadata); diff --git a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc index 66b6affcc5..6fe142bbe5 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc @@ -124,10 +124,14 @@ CapabilitiesGLES::CapabilitiesGLES(const ProcTableGLES& gl) { gl.GetIntegerv(GL_MAX_SAMPLES_EXT, &value); supports_offscreen_msaa_ = value >= 4; } - + is_es_ = desc->IsES(); is_angle_ = desc->IsANGLE(); } +bool CapabilitiesGLES::IsES() const { + return is_es_; +} + size_t CapabilitiesGLES::GetMaxTextureUnits(ShaderStage stage) const { switch (stage) { case ShaderStage::kVertex: diff --git a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h index f666992187..199cdf35e0 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h +++ b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h @@ -77,6 +77,9 @@ class CapabilitiesGLES final bool IsANGLE() const; + /// @brief Whether this is an ES GL variant or (if false) desktop GL. + bool IsES() const; + // |Capabilities| bool SupportsOffscreenMSAA() const override; @@ -133,6 +136,7 @@ class CapabilitiesGLES final bool supports_offscreen_msaa_ = false; bool supports_implicit_msaa_ = false; bool is_angle_ = false; + bool is_es_ = false; PixelFormat default_glyph_atlas_format_ = PixelFormat::kUnknown; }; diff --git a/engine/src/flutter/impeller/renderer/backend/gles/proc_table_gles.h b/engine/src/flutter/impeller/renderer/backend/gles/proc_table_gles.h index bfbf32fef2..14086784dc 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/proc_table_gles.h +++ b/engine/src/flutter/impeller/renderer/backend/gles/proc_table_gles.h @@ -101,6 +101,7 @@ struct GLProc { PROC(BindFramebuffer); \ PROC(BindRenderbuffer); \ PROC(BindTexture); \ + PROC(BindVertexArray); \ PROC(BlendEquationSeparate); \ PROC(BlendFuncSeparate); \ PROC(BufferData); \ @@ -120,6 +121,7 @@ struct GLProc { PROC(DeleteRenderbuffers); \ PROC(DeleteShader); \ PROC(DeleteTextures); \ + PROC(DeleteVertexArrays); \ PROC(DepthFunc); \ PROC(DepthMask); \ PROC(DetachShader); \ @@ -138,6 +140,7 @@ struct GLProc { PROC(GenFramebuffers); \ PROC(GenRenderbuffers); \ PROC(GenTextures); \ + PROC(GenVertexArrays); \ PROC(GetActiveUniform); \ PROC(GetBooleanv); \ PROC(GetFloatv); \