From dfdbeb82aed676ff7c46c3728af567731fbb5972 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 20 Sep 2024 15:07:17 -0700 Subject: [PATCH 1/3] [Impeller] fix Impeller on windows. --- shell/platform/embedder/embedder.cc | 37 ++++++++++++--- shell/platform/windows/compositor_opengl.cc | 23 ++++++++-- shell/platform/windows/compositor_opengl.h | 6 ++- .../windows/compositor_opengl_unittests.cc | 29 +++++++++--- shell/platform/windows/egl/manager.cc | 45 ++++--------------- shell/platform/windows/egl/manager.h | 6 +-- .../windows/flutter_windows_engine.cc | 5 ++- .../windows/flutter_windows_unittests.cc | 2 +- .../windows/testing/egl/mock_manager.h | 2 +- 9 files changed, 96 insertions(+), 59 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index dc61d43393e8c..a3a3014924e92 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -1038,6 +1038,23 @@ static sk_sp MakeSkSurfaceFromBackingStore( #endif } +#if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING) +static std::optional FlutterFormatToImpellerPixelFormat( + uint32_t format) { + switch (format) { + case GL_BGRA8_EXT: + return impeller::PixelFormat::kB8G8R8A8UNormInt; + case GL_RGBA8: + return impeller::PixelFormat::kR8G8B8A8UNormInt; + default: + FML_LOG(ERROR) << "Cannot convert format " << format + << " to impeller::PixelFormat."; + return std::nullopt; + } +} + +#endif // defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING) + static std::unique_ptr MakeRenderTargetFromBackingStoreImpeller( FlutterBackingStore backing_store, @@ -1046,34 +1063,40 @@ MakeRenderTargetFromBackingStoreImpeller( const FlutterBackingStoreConfig& config, const FlutterOpenGLFramebuffer* framebuffer) { #if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING) + auto format = FlutterFormatToImpellerPixelFormat(framebuffer->target); + if (!format.has_value()) { + return nullptr; + } const auto& gl_context = impeller::ContextGLES::Cast(*aiks_context->GetContext()); const auto size = impeller::ISize(config.size.width, config.size.height); impeller::TextureDescriptor color0_tex; - color0_tex.type = impeller::TextureType::kTexture2D; - color0_tex.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + color0_tex.type = impeller::TextureType::kTexture2DMultisample; + color0_tex.format = format.value(); color0_tex.size = size; color0_tex.usage = static_cast( impeller::TextureUsage::kRenderTarget); - color0_tex.sample_count = impeller::SampleCount::kCount1; + color0_tex.sample_count = impeller::SampleCount::kCount4; color0_tex.storage_mode = impeller::StorageMode::kDevicePrivate; impeller::ColorAttachment color0; color0.texture = impeller::TextureGLES::WrapFBO( gl_context.GetReactor(), color0_tex, framebuffer->name); + color0.resolve_texture = color0.texture; color0.clear_color = impeller::Color::DarkSlateGray(); color0.load_action = impeller::LoadAction::kClear; - color0.store_action = impeller::StoreAction::kStore; + color0.store_action = impeller::StoreAction::kMultisampleResolve; impeller::TextureDescriptor depth_stencil_texture_desc; - depth_stencil_texture_desc.type = impeller::TextureType::kTexture2D; - depth_stencil_texture_desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + depth_stencil_texture_desc.type = + impeller::TextureType::kTexture2DMultisample; + depth_stencil_texture_desc.format = impeller::PixelFormat::kD24UnormS8Uint; depth_stencil_texture_desc.size = size; depth_stencil_texture_desc.usage = static_cast( impeller::TextureUsage::kRenderTarget); - depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount1; + depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount4; auto depth_stencil_tex = std::make_shared( gl_context.GetReactor(), depth_stencil_texture_desc, diff --git a/shell/platform/windows/compositor_opengl.cc b/shell/platform/windows/compositor_opengl.cc index dfefb09ba2e47..9405f64741f18 100644 --- a/shell/platform/windows/compositor_opengl.cc +++ b/shell/platform/windows/compositor_opengl.cc @@ -23,8 +23,9 @@ struct FramebufferBackingStore { } // namespace CompositorOpenGL::CompositorOpenGL(FlutterWindowsEngine* engine, - impeller::ProcTableGLES::Resolver resolver) - : engine_(engine), resolver_(resolver) {} + impeller::ProcTableGLES::Resolver resolver, + bool enable_impeller) + : engine_(engine), resolver_(resolver), enable_impeller_(enable_impeller) {} bool CompositorOpenGL::CreateBackingStore( const FlutterBackingStoreConfig& config, @@ -53,6 +54,23 @@ bool CompositorOpenGL::CreateBackingStore( gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, store->texture_id, 0); + // Set up depth/stencil attachment for impeller renderer. + if (enable_impeller_) { + GLuint tex_id; + gl_->GenTextures(1, &tex_id); + gl_->BindTexture(GL_TEXTURE_2D, tex_id); + gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, config.size.width, + config.size.height, 0, GL_DEPTH_STENCIL, + GL_UNSIGNED_INT_24_8, nullptr); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_TEXTURE_2D, tex_id, 0); + gl_->BindTexture(GL_TEXTURE_2D, 0); + } + result->type = kFlutterBackingStoreTypeOpenGL; result->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer; result->open_gl.framebuffer.name = store->framebuffer_id; @@ -131,7 +149,6 @@ bool CompositorOpenGL::Present(FlutterWindowsView* view, // Prevents regressions like: https://github.com/flutter/flutter/issues/140828 // See OpenGL specification version 4.6, section 18.3.1. gl_->Disable(GL_SCISSOR_TEST); - gl_->BindFramebuffer(GL_READ_FRAMEBUFFER, source_id); gl_->BindFramebuffer(GL_DRAW_FRAMEBUFFER, kWindowFrameBufferId); diff --git a/shell/platform/windows/compositor_opengl.h b/shell/platform/windows/compositor_opengl.h index d5b813da9653d..18451c467604d 100644 --- a/shell/platform/windows/compositor_opengl.h +++ b/shell/platform/windows/compositor_opengl.h @@ -19,7 +19,8 @@ namespace flutter { class CompositorOpenGL : public Compositor { public: CompositorOpenGL(FlutterWindowsEngine* engine, - impeller::ProcTableGLES::Resolver resolver); + impeller::ProcTableGLES::Resolver resolver, + bool enable_impeller); /// |Compositor| bool CreateBackingStore(const FlutterBackingStoreConfig& config, @@ -59,6 +60,9 @@ class CompositorOpenGL : public Compositor { // the compositor is initialized. TextureFormat format_; + // Whether the Impeller rendering backend is enabled. + bool enable_impeller_ = false; + // Initialize the compositor. This must run on the raster thread. bool Initialize(); diff --git a/shell/platform/windows/compositor_opengl_unittests.cc b/shell/platform/windows/compositor_opengl_unittests.cc index a7bc210866ae9..37099e24163c5 100644 --- a/shell/platform/windows/compositor_opengl_unittests.cc +++ b/shell/platform/windows/compositor_opengl_unittests.cc @@ -125,7 +125,22 @@ class CompositorOpenGLTest : public WindowsTest { TEST_F(CompositorOpenGLTest, CreateBackingStore) { UseHeadlessEngine(); - auto compositor = CompositorOpenGL{engine(), kMockResolver}; + auto compositor = + CompositorOpenGL{engine(), kMockResolver, /*enable_impeller=*/false}; + + FlutterBackingStoreConfig config = {}; + FlutterBackingStore backing_store = {}; + + EXPECT_CALL(*render_context(), MakeCurrent).WillOnce(Return(true)); + ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store)); + ASSERT_TRUE(compositor.CollectBackingStore(&backing_store)); +} + +TEST_F(CompositorOpenGLTest, CreateBackingStoreImpeller) { + UseHeadlessEngine(); + + auto compositor = + CompositorOpenGL{engine(), kMockResolver, /*enable_impeller=*/true}; FlutterBackingStoreConfig config = {}; FlutterBackingStore backing_store = {}; @@ -138,7 +153,8 @@ TEST_F(CompositorOpenGLTest, CreateBackingStore) { TEST_F(CompositorOpenGLTest, InitializationFailure) { UseHeadlessEngine(); - auto compositor = CompositorOpenGL{engine(), kMockResolver}; + auto compositor = + CompositorOpenGL{engine(), kMockResolver, /*enable_impeller=*/false}; FlutterBackingStoreConfig config = {}; FlutterBackingStore backing_store = {}; @@ -150,7 +166,8 @@ TEST_F(CompositorOpenGLTest, InitializationFailure) { TEST_F(CompositorOpenGLTest, Present) { UseEngineWithView(); - auto compositor = CompositorOpenGL{engine(), kMockResolver}; + auto compositor = + CompositorOpenGL{engine(), kMockResolver, /*enable_impeller=*/false}; FlutterBackingStoreConfig config = {}; FlutterBackingStore backing_store = {}; @@ -174,7 +191,8 @@ TEST_F(CompositorOpenGLTest, Present) { TEST_F(CompositorOpenGLTest, PresentEmpty) { UseEngineWithView(); - auto compositor = CompositorOpenGL{engine(), kMockResolver}; + auto compositor = + CompositorOpenGL{engine(), kMockResolver, /*enable_impeller=*/false}; // The context will be bound twice: first to initialize the compositor, second // to clear the surface. @@ -188,7 +206,8 @@ TEST_F(CompositorOpenGLTest, PresentEmpty) { TEST_F(CompositorOpenGLTest, NoSurfaceIgnored) { UseEngineWithView(/*add_surface = */ false); - auto compositor = CompositorOpenGL{engine(), kMockResolver}; + auto compositor = + CompositorOpenGL{engine(), kMockResolver, /*enable_impeller=*/false}; FlutterBackingStoreConfig config = {}; FlutterBackingStore backing_store = {}; diff --git a/shell/platform/windows/egl/manager.cc b/shell/platform/windows/egl/manager.cc index 2b827f863f803..dee75a47df546 100644 --- a/shell/platform/windows/egl/manager.cc +++ b/shell/platform/windows/egl/manager.cc @@ -14,23 +14,23 @@ namespace egl { int Manager::instance_count_ = 0; -std::unique_ptr Manager::Create(bool enable_impeller) { +std::unique_ptr Manager::Create() { std::unique_ptr manager; - manager.reset(new Manager(enable_impeller)); + manager.reset(new Manager()); if (!manager->IsValid()) { return nullptr; } return std::move(manager); } -Manager::Manager(bool enable_impeller) { +Manager::Manager() { ++instance_count_; if (!InitializeDisplay()) { return; } - if (!InitializeConfig(enable_impeller)) { + if (!InitializeConfig()) { return; } @@ -140,46 +140,19 @@ bool Manager::InitializeDisplay() { FML_UNREACHABLE(); } -bool Manager::InitializeConfig(bool enable_impeller) { +bool Manager::InitializeConfig() { const EGLint config_attributes[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, EGL_NONE}; - const EGLint impeller_config_attributes[] = { - EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 8, - EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4, EGL_NONE}; - const EGLint impeller_config_attributes_no_msaa[] = { - EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 8, - EGL_NONE}; - - EGLBoolean result; EGLint num_config = 0; - if (enable_impeller) { - // First try the MSAA configuration. - result = ::eglChooseConfig(display_, impeller_config_attributes, &config_, - 1, &num_config); - - if (result == EGL_TRUE && num_config > 0) { - return true; - } + EGLBoolean result = + ::eglChooseConfig(display_, config_attributes, &config_, 1, &num_config); - // Next fall back to disabled MSAA. - result = ::eglChooseConfig(display_, impeller_config_attributes_no_msaa, - &config_, 1, &num_config); - if (result == EGL_TRUE && num_config == 0) { - return true; - } - } else { - result = ::eglChooseConfig(display_, config_attributes, &config_, 1, - &num_config); - - if (result == EGL_TRUE && num_config > 0) { - return true; - } + if (result == EGL_TRUE && num_config > 0) { + return true; } LogEGLError("Failed to choose EGL config"); diff --git a/shell/platform/windows/egl/manager.h b/shell/platform/windows/egl/manager.h index 4ef289549d9ef..b2fb50677391c 100644 --- a/shell/platform/windows/egl/manager.h +++ b/shell/platform/windows/egl/manager.h @@ -30,7 +30,7 @@ namespace egl { // destroy surfaces class Manager { public: - static std::unique_ptr Create(bool enable_impeller); + static std::unique_ptr Create(); virtual ~Manager(); @@ -74,7 +74,7 @@ class Manager { protected: // Creates a new surface manager retaining reference to the passed-in target // for the lifetime of the manager. - explicit Manager(bool enable_impeller); + explicit Manager(); private: // Number of active instances of Manager @@ -84,7 +84,7 @@ class Manager { bool InitializeDisplay(); // Initialize the EGL configs. - bool InitializeConfig(bool enable_impeller); + bool InitializeConfig(); // Initialize the EGL render and resource contexts. bool InitializeContexts(); diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 11885cb6cda91..d08591a10b520 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -194,7 +194,7 @@ FlutterWindowsEngine::FlutterWindowsEngine( enable_impeller_ = std::find(switches.begin(), switches.end(), "--enable-impeller=true") != switches.end(); - egl_manager_ = egl::Manager::Create(enable_impeller_); + egl_manager_ = egl::Manager::Create(); window_proc_delegate_manager_ = std::make_unique(); window_proc_delegate_manager_->RegisterTopLevelWindowProcDelegate( [](HWND hwnd, UINT msg, WPARAM wpar, LPARAM lpar, void* user_data, @@ -393,7 +393,8 @@ bool FlutterWindowsEngine::Run(std::string_view entrypoint) { // TODO(schectman) Pass the platform view manager to the compositor // constructors: https://github.com/flutter/flutter/issues/143375 - compositor_ = std::make_unique(this, resolver); + compositor_ = + std::make_unique(this, resolver, enable_impeller_); } else { compositor_ = std::make_unique(); } diff --git a/shell/platform/windows/flutter_windows_unittests.cc b/shell/platform/windows/flutter_windows_unittests.cc index 6d0befe60c628..72ffc7a6bf694 100644 --- a/shell/platform/windows/flutter_windows_unittests.cc +++ b/shell/platform/windows/flutter_windows_unittests.cc @@ -31,7 +31,7 @@ namespace { // An EGL manager that initializes EGL but fails to create surfaces. class HalfBrokenEGLManager : public egl::Manager { public: - HalfBrokenEGLManager() : egl::Manager(/*enable_impeller = */ false) {} + HalfBrokenEGLManager() : egl::Manager() {} std::unique_ptr CreateWindowSurface(HWND hwnd, size_t width, size_t height) override { diff --git a/shell/platform/windows/testing/egl/mock_manager.h b/shell/platform/windows/testing/egl/mock_manager.h index 1bde275416e16..aa3fb48c87ac1 100644 --- a/shell/platform/windows/testing/egl/mock_manager.h +++ b/shell/platform/windows/testing/egl/mock_manager.h @@ -16,7 +16,7 @@ namespace egl { /// Mock for the |Manager| base class. class MockManager : public flutter::egl::Manager { public: - MockManager() : Manager(false) {} + MockManager() : Manager() {} MOCK_METHOD(std::unique_ptr, CreateWindowSurface, From 724a2853e1c891ab1147bc69d8ca6773e9e0b9d6 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 20 Sep 2024 21:23:30 -0700 Subject: [PATCH 2/3] use renderbuffer and multisampled color texture. --- shell/platform/embedder/embedder.cc | 26 ++++++++++++--- shell/platform/windows/compositor_opengl.cc | 37 ++++++++++++--------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index a3a3014924e92..77950a37eaae8 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -1070,24 +1070,36 @@ MakeRenderTargetFromBackingStoreImpeller( const auto& gl_context = impeller::ContextGLES::Cast(*aiks_context->GetContext()); + const bool implicit_msaa = aiks_context->GetContext() + ->GetCapabilities() + ->SupportsImplicitResolvingMSAA(); const auto size = impeller::ISize(config.size.width, config.size.height); impeller::TextureDescriptor color0_tex; - color0_tex.type = impeller::TextureType::kTexture2DMultisample; + if (implicit_msaa) { + color0_tex.type = impeller::TextureType::kTexture2DMultisample; + color0_tex.sample_count = impeller::SampleCount::kCount4; + } else { + color0_tex.type = impeller::TextureType::kTexture2D; + color0_tex.sample_count = impeller::SampleCount::kCount1; + } color0_tex.format = format.value(); color0_tex.size = size; color0_tex.usage = static_cast( impeller::TextureUsage::kRenderTarget); - color0_tex.sample_count = impeller::SampleCount::kCount4; color0_tex.storage_mode = impeller::StorageMode::kDevicePrivate; impeller::ColorAttachment color0; color0.texture = impeller::TextureGLES::WrapFBO( gl_context.GetReactor(), color0_tex, framebuffer->name); - color0.resolve_texture = color0.texture; color0.clear_color = impeller::Color::DarkSlateGray(); color0.load_action = impeller::LoadAction::kClear; - color0.store_action = impeller::StoreAction::kMultisampleResolve; + if (implicit_msaa) { + color0.store_action = impeller::StoreAction::kMultisampleResolve; + color0.resolve_texture = color0.texture; + } else { + color0.store_action = impeller::StoreAction::kStore; + } impeller::TextureDescriptor depth_stencil_texture_desc; depth_stencil_texture_desc.type = @@ -1096,7 +1108,11 @@ MakeRenderTargetFromBackingStoreImpeller( depth_stencil_texture_desc.size = size; depth_stencil_texture_desc.usage = static_cast( impeller::TextureUsage::kRenderTarget); - depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount4; + if (implicit_msaa) { + depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount4; + } else { + depth_stencil_texture_desc.sample_count = impeller::SampleCount::kCount1; + } auto depth_stencil_tex = std::make_shared( gl_context.GetReactor(), depth_stencil_texture_desc, diff --git a/shell/platform/windows/compositor_opengl.cc b/shell/platform/windows/compositor_opengl.cc index 9405f64741f18..e78e1da098cb7 100644 --- a/shell/platform/windows/compositor_opengl.cc +++ b/shell/platform/windows/compositor_opengl.cc @@ -51,24 +51,31 @@ bool CompositorOpenGL::CreateBackingStore( GL_UNSIGNED_BYTE, nullptr); gl_->BindTexture(GL_TEXTURE_2D, 0); - gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - store->texture_id, 0); + if (enable_impeller_) { + gl_->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + store->texture_id, 0, 4); + } else { + gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, store->texture_id, 0); + } // Set up depth/stencil attachment for impeller renderer. if (enable_impeller_) { - GLuint tex_id; - gl_->GenTextures(1, &tex_id); - gl_->BindTexture(GL_TEXTURE_2D, tex_id); - gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, config.size.width, - config.size.height, 0, GL_DEPTH_STENCIL, - GL_UNSIGNED_INT_24_8, nullptr); - gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - GL_TEXTURE_2D, tex_id, 0); - gl_->BindTexture(GL_TEXTURE_2D, 0); + GLuint depth_stencil; + gl_->GenRenderbuffers(1, &depth_stencil); + gl_->BindRenderbuffer(GL_RENDERBUFFER, depth_stencil); + gl_->RenderbufferStorageMultisampleEXT( + GL_RENDERBUFFER, // target + 4, // samples + GL_DEPTH24_STENCIL8, // internal format + config.size.width, // width + config.size.height // height + ); + gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, depth_stencil); + gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, depth_stencil); } result->type = kFlutterBackingStoreTypeOpenGL; From 94b51a2366898db7eb39d22351efaca857ef3e04 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 24 Sep 2024 11:03:38 -0700 Subject: [PATCH 3/3] loic review. --- shell/platform/windows/compositor_opengl.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/shell/platform/windows/compositor_opengl.cc b/shell/platform/windows/compositor_opengl.cc index e78e1da098cb7..515959085c2be 100644 --- a/shell/platform/windows/compositor_opengl.cc +++ b/shell/platform/windows/compositor_opengl.cc @@ -52,16 +52,13 @@ bool CompositorOpenGL::CreateBackingStore( gl_->BindTexture(GL_TEXTURE_2D, 0); if (enable_impeller_) { + // Impeller requries that its onscreen surface is Multisampled and already + // has depth/stencil attached in order for anti-aliasing to work. gl_->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, store->texture_id, 0, 4); - } else { - gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, store->texture_id, 0); - } - // Set up depth/stencil attachment for impeller renderer. - if (enable_impeller_) { + // Set up depth/stencil attachment for impeller renderer. GLuint depth_stencil; gl_->GenRenderbuffers(1, &depth_stencil); gl_->BindRenderbuffer(GL_RENDERBUFFER, depth_stencil); @@ -76,6 +73,10 @@ bool CompositorOpenGL::CreateBackingStore( GL_RENDERBUFFER, depth_stencil); gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth_stencil); + + } else { + gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, store->texture_id, 0); } result->type = kFlutterBackingStoreTypeOpenGL;