Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 55 additions & 4 deletions shell/platform/windows/angle_surface_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "flutter/shell/platform/windows/angle_surface_manager.h"

#include <iostream>
#include <mutex>
#include <vector>

#ifdef WINUWP
Expand Down Expand Up @@ -104,6 +105,8 @@ bool AngleSurfaceManager::Initialize() {
const EGLint d3d11_warp_display_attributes[] = {
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
EGL_TRUE,
EGL_NONE,
Expand Down Expand Up @@ -205,7 +208,27 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target,

EGLSurface surface = EGL_NO_SURFACE;

const EGLint surfaceAttributes[] = {EGL_NONE};
std::vector<EGLint> surface_attributes;

if (!CompositionSupported()) {
// eglPostSubBufferNV during resizing causes significant artifacts on
// Windows 7, so use fixed size surface instead

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this code is touching the resize logic, I wonder if we should also revert eglPostSubBufferNV in the non-UWP composition case as well pending flutter/flutter#76465 being addressed. There are reports of the visual artifacts in cases where WM_NCCALCSIZE is not in use (see the thread in the bug) which means the mainstream case can be subject to the artifacts. If you don't want to address in this PR I will do in a follow-on PR. If the new DComp path in some way depends on eglPostSubBufferNV then we may have to hold off on landing this PR until the above big is correctly fixed. That is currently backed up behind the UWP work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with composition enabled (both direct composition and uwp I believe) and recreating surface during resizing is that every now and then you get brief transparent flashes (even with ClearContext in place). I wasn't able to find any workaround for this. So if you decide to revert eglPostSubBufferNV then it would be better to NOT apply this PR until there's proper solution for manual surface resizing.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a possible fix for the resize present issue which I pinged you about.

// TODO(knopp): This will not be necessary after
// https://github.com/flutter/flutter/issues/76465 is addressed.
surface_attributes.push_back(EGL_FIXED_SIZE_ANGLE);
surface_attributes.push_back(EGL_TRUE);
surface_attributes.push_back(EGL_WIDTH);
surface_attributes.push_back(width);
surface_attributes.push_back(EGL_HEIGHT);
surface_attributes.push_back(height);
} else {
#ifndef WINUWP
surface_attributes.push_back(EGL_DIRECT_COMPOSITION_ANGLE);
surface_attributes.push_back(EGL_TRUE);
#endif
}

surface_attributes.push_back(EGL_NONE);

#ifdef WINUWP
#ifdef USECOREWINDOW
Expand All @@ -217,12 +240,12 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target,
surface = eglCreateWindowSurface(
egl_display_, egl_config_,
static_cast<EGLNativeWindowType>(winrt::get_abi(target)),
surfaceAttributes);
surface_attributes.data());
#else
surface = eglCreateWindowSurface(
egl_display_, egl_config_,
static_cast<EGLNativeWindowType>(std::get<HWND>(*render_target)),
surfaceAttributes);
surface_attributes.data());
#endif
if (surface == EGL_NO_SURFACE) {
LogEglError("Surface creation failed.");
Expand All @@ -244,7 +267,15 @@ void AngleSurfaceManager::ResizeSurface(WindowsRenderTarget* render_target,
// avoiding the need to destory and recreate the underlying SwapChain.
surface_width_ = width;
surface_height_ = height;
eglPostSubBufferNV(egl_display_, render_surface_, 1, 1, width, height);
if (!CompositionSupported()) {
// Withoutcomposition the surface is created with fixed size.
// See AngleSurfaceManager::CreateSurface for details.
ClearContext();
DestroySurface();
CreateSurface(render_target, width, height);
} else {
eglPostSubBufferNV(egl_display_, render_surface_, 1, 1, width, height);
}
}
}

Expand Down Expand Up @@ -288,4 +319,24 @@ EGLBoolean AngleSurfaceManager::SwapBuffers() {
return (eglSwapBuffers(egl_display_, render_surface_));
}

bool AngleSurfaceManager::CompositionSupported() {
#ifdef WINUWP
return true;
#else
static bool supported;
static std::once_flag flag;
std::call_once(flag, [] {
supported = false;
auto dcomp = ::GetModuleHandle(TEXT("dcomp.dll"));
if (dcomp) {
auto address = GetProcAddress(dcomp, "DCompositionCreateDevice");
if (address) {
supported = true;
}
}
});
return supported;
#endif
}

} // namespace flutter
4 changes: 4 additions & 0 deletions shell/platform/windows/angle_surface_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class AngleSurfaceManager {
const EGLint* config,
bool should_log);

// Returns whether current system supports presenting surface through
// direct composition
static bool CompositionSupported();

// EGL representation of native display.
EGLDisplay egl_display_;

Expand Down