mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix flutter#40068 Redraw issues on resize/minimize/maximize on Windows and startup in release (flutter/engine#20357)
* Fix redraw issues * Address CR feedback. * Fix build * CR feedback
This commit is contained in:
parent
1b949f741f
commit
a1d268a61b
@ -169,14 +169,22 @@ void AngleSurfaceManager::CleanUp() {
|
||||
}
|
||||
}
|
||||
|
||||
bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target) {
|
||||
bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target,
|
||||
EGLint width,
|
||||
EGLint height) {
|
||||
if (!render_target || !initialize_succeeded_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
|
||||
const EGLint surfaceAttributes[] = {EGL_NONE};
|
||||
// Disable Angle's automatic surface sizing logic and provide and exlicit
|
||||
// size. AngleSurfaceManager is responsible for initiating Angle surface size
|
||||
// changes to avoid race conditions with rendering when automatic mode is
|
||||
// used.
|
||||
const EGLint surfaceAttributes[] = {
|
||||
EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_WIDTH, width,
|
||||
EGL_HEIGHT, height, EGL_NONE};
|
||||
|
||||
surface = eglCreateWindowSurface(
|
||||
egl_display_, egl_config_,
|
||||
@ -190,6 +198,26 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AngleSurfaceManager::ResizeSurface(WindowsRenderTarget* render_target,
|
||||
EGLint width,
|
||||
EGLint height) {
|
||||
EGLint existing_width, existing_height;
|
||||
GetSurfaceDimensions(&existing_width, &existing_height);
|
||||
if (width != existing_width || height != existing_height) {
|
||||
// Destroy existing surface with previous stale dimensions and create new
|
||||
// surface at new size. Since the Windows compositor retains the front
|
||||
// buffer until the new surface has been presented, no need to manually
|
||||
// preserve the previous surface contents. This resize approach could be
|
||||
// further optimized if Angle exposed a public entrypoint for
|
||||
// SwapChain11::reset or SwapChain11::resize.
|
||||
DestroySurface();
|
||||
if (!CreateSurface(render_target, width, height)) {
|
||||
std::cerr << "AngleSurfaceManager::ResizeSurface failed to create surface"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AngleSurfaceManager::GetSurfaceDimensions(EGLint* width, EGLint* height) {
|
||||
if (render_surface_ == EGL_NO_SURFACE || !initialize_succeeded_) {
|
||||
width = 0;
|
||||
|
||||
@ -23,6 +23,8 @@ namespace flutter {
|
||||
// destroy surfaces
|
||||
class AngleSurfaceManager {
|
||||
public:
|
||||
// Creates a new surface manager retaining reference to the passed-in target
|
||||
// for the lifetime of the manager.
|
||||
AngleSurfaceManager();
|
||||
~AngleSurfaceManager();
|
||||
|
||||
@ -32,8 +34,19 @@ class AngleSurfaceManager {
|
||||
|
||||
// Creates an EGLSurface wrapper and backing DirectX 11 SwapChain
|
||||
// asociated with window, in the appropriate format for display.
|
||||
// Target represents the visual entity to bind to.
|
||||
bool CreateSurface(WindowsRenderTarget* render_target);
|
||||
// Target represents the visual entity to bind to. Width and
|
||||
// height represent dimensions surface is created at.
|
||||
bool CreateSurface(WindowsRenderTarget* render_target,
|
||||
EGLint width,
|
||||
EGLint height);
|
||||
|
||||
// Resizes backing surface from current size to newly requested size
|
||||
// based on width and height for the specific case when width and height do
|
||||
// not match current surface dimensions. Target represents the visual entity
|
||||
// to bind to.
|
||||
void ResizeSurface(WindowsRenderTarget* render_target,
|
||||
EGLint width,
|
||||
EGLint height);
|
||||
|
||||
// queries EGL for the dimensions of surface in physical
|
||||
// pixels returning width and height as out params.
|
||||
|
||||
@ -65,6 +65,9 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Must happen after engine is running.
|
||||
state->view->SendInitialBounds();
|
||||
return state.release();
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@ void FlutterWindowsView::SetEngine(
|
||||
|
||||
void FlutterWindowsView::OnWindowSizeChanged(size_t width,
|
||||
size_t height) const {
|
||||
surface_manager_->ResizeSurface(GetRenderTarget(), width, height);
|
||||
SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
|
||||
}
|
||||
|
||||
@ -127,6 +128,13 @@ void FlutterWindowsView::SendWindowMetrics(size_t width,
|
||||
auto result = FlutterEngineSendWindowMetricsEvent(engine_->engine(), &event);
|
||||
}
|
||||
|
||||
void FlutterWindowsView::SendInitialBounds() {
|
||||
PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
|
||||
|
||||
SendWindowMetrics(bounds.width, bounds.height,
|
||||
binding_handler_->GetDpiScale());
|
||||
}
|
||||
|
||||
// Set's |event_data|'s phase to either kMove or kHover depending on the current
|
||||
// primary mouse button state.
|
||||
void FlutterWindowsView::SetEventPhaseFromCursorButtonState(
|
||||
@ -263,7 +271,9 @@ bool FlutterWindowsView::SwapBuffers() {
|
||||
}
|
||||
|
||||
void FlutterWindowsView::CreateRenderSurface() {
|
||||
surface_manager_->CreateSurface(render_target_.get());
|
||||
PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
|
||||
surface_manager_->CreateSurface(GetRenderTarget(), bounds.width,
|
||||
bounds.height);
|
||||
}
|
||||
|
||||
void FlutterWindowsView::DestroyRenderSurface() {
|
||||
@ -272,7 +282,7 @@ void FlutterWindowsView::DestroyRenderSurface() {
|
||||
}
|
||||
}
|
||||
|
||||
WindowsRenderTarget* FlutterWindowsView::GetRenderTarget() {
|
||||
WindowsRenderTarget* FlutterWindowsView::GetRenderTarget() const {
|
||||
return render_target_.get();
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate {
|
||||
void DestroyRenderSurface();
|
||||
|
||||
// Return the currently configured WindowsRenderTarget.
|
||||
WindowsRenderTarget* GetRenderTarget();
|
||||
WindowsRenderTarget* GetRenderTarget() const;
|
||||
|
||||
// Returns the engine backing this view.
|
||||
FlutterWindowsEngine* GetEngine();
|
||||
@ -63,6 +63,9 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate {
|
||||
bool MakeResourceCurrent();
|
||||
bool SwapBuffers();
|
||||
|
||||
// Send initial bounds to embedder. Must occur after engine has initialized.
|
||||
void SendInitialBounds();
|
||||
|
||||
// |WindowBindingHandlerDelegate|
|
||||
void OnWindowSizeChanged(size_t width, size_t height) const override;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user