Flutter Windows Embedder
flutter::AngleSurfaceManager Class Reference

#include <angle_surface_manager.h>

Public Member Functions

virtual ~AngleSurfaceManager ()
 
virtual bool CreateSurface (HWND hwnd, EGLint width, EGLint height)
 
virtual void ResizeSurface (HWND hwnd, EGLint width, EGLint height, bool enable_vsync)
 
void GetSurfaceDimensions (EGLint *width, EGLint *height)
 
virtual void DestroySurface ()
 
bool HasContextCurrent ()
 
virtual bool MakeCurrent ()
 
virtual bool ClearCurrent ()
 
bool ClearContext ()
 
bool MakeResourceCurrent ()
 
EGLBoolean SwapBuffers ()
 
EGLSurface CreateSurfaceFromHandle (EGLenum handle_type, EGLClientBuffer handle, const EGLint *attributes) const
 
EGLDisplay egl_display () const
 
virtual void SetVSyncEnabled (bool enabled)
 
bool GetDevice (ID3D11Device **device)
 

Static Public Member Functions

static std::unique_ptr< AngleSurfaceManagerCreate (bool enable_impeller)
 

Protected Member Functions

 AngleSurfaceManager (bool enable_impeller)
 

Detailed Description

Definition at line 28 of file angle_surface_manager.h.

Constructor & Destructor Documentation

◆ ~AngleSurfaceManager()

flutter::AngleSurfaceManager::~AngleSurfaceManager ( )
virtual

Definition at line 41 of file angle_surface_manager.cc.

41  {
42  CleanUp();
43  --instance_count_;
44 }

◆ AngleSurfaceManager()

flutter::AngleSurfaceManager::AngleSurfaceManager ( bool  enable_impeller)
explicitprotected

Definition at line 33 of file angle_surface_manager.cc.

34  : egl_config_(nullptr),
35  egl_display_(EGL_NO_DISPLAY),
36  egl_context_(EGL_NO_CONTEXT) {
37  initialize_succeeded_ = Initialize(enable_impeller);
38  ++instance_count_;
39 }

Referenced by Create().

Member Function Documentation

◆ ClearContext()

bool flutter::AngleSurfaceManager::ClearContext ( )

Definition at line 322 of file angle_surface_manager.cc.

322  {
323  return (eglMakeCurrent(egl_display_, nullptr, nullptr, egl_context_) ==
324  EGL_TRUE);
325 }

Referenced by ResizeSurface().

◆ ClearCurrent()

bool flutter::AngleSurfaceManager::ClearCurrent ( )
virtual

Definition at line 317 of file angle_surface_manager.cc.

317  {
318  return (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
319  EGL_NO_CONTEXT) == EGL_TRUE);
320 }

◆ Create()

std::unique_ptr< AngleSurfaceManager > flutter::AngleSurfaceManager::Create ( bool  enable_impeller)
static

Definition at line 23 of file angle_surface_manager.cc.

24  {
25  std::unique_ptr<AngleSurfaceManager> manager;
26  manager.reset(new AngleSurfaceManager(enable_impeller));
27  if (!manager->initialize_succeeded_) {
28  return nullptr;
29  }
30  return std::move(manager);
31 }

References AngleSurfaceManager().

◆ CreateSurface()

bool flutter::AngleSurfaceManager::CreateSurface ( HWND  hwnd,
EGLint  width,
EGLint  height 
)
virtual

Definition at line 232 of file angle_surface_manager.cc.

234  {
235  if (!hwnd || !initialize_succeeded_) {
236  return false;
237  }
238 
239  EGLSurface surface = EGL_NO_SURFACE;
240 
241  // Disable ANGLE's automatic surface resizing and provide an explicit size.
242  // The surface will need to be destroyed and re-created if the HWND is
243  // resized.
244  const EGLint surfaceAttributes[] = {
245  EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_WIDTH, width,
246  EGL_HEIGHT, height, EGL_NONE};
247 
248  surface = eglCreateWindowSurface(egl_display_, egl_config_,
249  static_cast<EGLNativeWindowType>(hwnd),
250  surfaceAttributes);
251  if (surface == EGL_NO_SURFACE) {
252  LogEglError("Surface creation failed.");
253  return false;
254  }
255 
256  surface_width_ = width;
257  surface_height_ = height;
258  render_surface_ = surface;
259  return true;
260 }

References LogEglError().

Referenced by flutter::FlutterWindowsView::CreateRenderSurface(), and ResizeSurface().

◆ CreateSurfaceFromHandle()

EGLSurface flutter::AngleSurfaceManager::CreateSurfaceFromHandle ( EGLenum  handle_type,
EGLClientBuffer  handle,
const EGLint *  attributes 
) const

Definition at line 336 of file angle_surface_manager.cc.

339  {
340  return eglCreatePbufferFromClientBuffer(egl_display_, handle_type, handle,
341  egl_config_, attributes);
342 }

◆ DestroySurface()

void flutter::AngleSurfaceManager::DestroySurface ( )
virtual

Definition at line 301 of file angle_surface_manager.cc.

301  {
302  if (egl_display_ != EGL_NO_DISPLAY && render_surface_ != EGL_NO_SURFACE) {
303  eglDestroySurface(egl_display_, render_surface_);
304  }
305  render_surface_ = EGL_NO_SURFACE;
306 }

Referenced by flutter::FlutterWindowsView::DestroyRenderSurface(), and ResizeSurface().

◆ egl_display()

EGLDisplay flutter::AngleSurfaceManager::egl_display ( ) const
inline

Definition at line 88 of file angle_surface_manager.h.

88 { return egl_display_; };

◆ GetDevice()

bool flutter::AngleSurfaceManager::GetDevice ( ID3D11Device **  device)

Definition at line 361 of file angle_surface_manager.cc.

361  {
362  if (!resolved_device_) {
363  PFNEGLQUERYDISPLAYATTRIBEXTPROC egl_query_display_attrib_EXT =
364  reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
365  eglGetProcAddress("eglQueryDisplayAttribEXT"));
366 
367  PFNEGLQUERYDEVICEATTRIBEXTPROC egl_query_device_attrib_EXT =
368  reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
369  eglGetProcAddress("eglQueryDeviceAttribEXT"));
370 
371  if (!egl_query_display_attrib_EXT || !egl_query_device_attrib_EXT) {
372  return false;
373  }
374 
375  EGLAttrib egl_device = 0;
376  EGLAttrib angle_device = 0;
377  if (egl_query_display_attrib_EXT(egl_display_, EGL_DEVICE_EXT,
378  &egl_device) == EGL_TRUE) {
379  if (egl_query_device_attrib_EXT(
380  reinterpret_cast<EGLDeviceEXT>(egl_device),
381  EGL_D3D11_DEVICE_ANGLE, &angle_device) == EGL_TRUE) {
382  resolved_device_ = reinterpret_cast<ID3D11Device*>(angle_device);
383  }
384  }
385  }
386 
387  resolved_device_.CopyTo(device);
388  return (resolved_device_ != nullptr);
389 }

◆ GetSurfaceDimensions()

void flutter::AngleSurfaceManager::GetSurfaceDimensions ( EGLint *  width,
EGLint *  height 
)

Definition at line 286 of file angle_surface_manager.cc.

286  {
287  if (render_surface_ == EGL_NO_SURFACE || !initialize_succeeded_) {
288  *width = 0;
289  *height = 0;
290  return;
291  }
292 
293  // This avoids eglQuerySurface as ideally surfaces would be automatically
294  // sized by ANGLE to avoid expensive surface destroy & re-create. With
295  // automatic sizing, ANGLE could resize the surface before Flutter asks it to,
296  // which would break resize redraw synchronization.
297  *width = surface_width_;
298  *height = surface_height_;
299 }

Referenced by flutter::FlutterWindowsView::OnWindowSizeChanged(), and ResizeSurface().

◆ HasContextCurrent()

bool flutter::AngleSurfaceManager::HasContextCurrent ( )

Definition at line 308 of file angle_surface_manager.cc.

308  {
309  return eglGetCurrentContext() != EGL_NO_CONTEXT;
310 }

◆ MakeCurrent()

bool flutter::AngleSurfaceManager::MakeCurrent ( )
virtual

Definition at line 312 of file angle_surface_manager.cc.

312  {
313  return (eglMakeCurrent(egl_display_, render_surface_, render_surface_,
314  egl_context_) == EGL_TRUE);
315 }

Referenced by SetVSyncEnabled().

◆ MakeResourceCurrent()

bool flutter::AngleSurfaceManager::MakeResourceCurrent ( )

Definition at line 327 of file angle_surface_manager.cc.

327  {
328  return (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
329  egl_resource_context_) == EGL_TRUE);
330 }

◆ ResizeSurface()

void flutter::AngleSurfaceManager::ResizeSurface ( HWND  hwnd,
EGLint  width,
EGLint  height,
bool  enable_vsync 
)
virtual

Definition at line 262 of file angle_surface_manager.cc.

265  {
266  EGLint existing_width, existing_height;
267  GetSurfaceDimensions(&existing_width, &existing_height);
268  if (width != existing_width || height != existing_height) {
269  surface_width_ = width;
270  surface_height_ = height;
271 
272  // TODO: Destroying the surface and re-creating it is expensive.
273  // Ideally this would use ANGLE's automatic surface sizing instead.
274  // See: https://github.com/flutter/flutter/issues/79427
275  ClearContext();
276  DestroySurface();
277  if (!CreateSurface(hwnd, width, height)) {
278  FML_LOG(ERROR)
279  << "AngleSurfaceManager::ResizeSurface failed to create surface";
280  }
281  }
282 
283  SetVSyncEnabled(vsync_enabled);
284 }

References ClearContext(), CreateSurface(), DestroySurface(), GetSurfaceDimensions(), and SetVSyncEnabled().

Referenced by flutter::FlutterWindowsView::GetFrameBufferId().

◆ SetVSyncEnabled()

void flutter::AngleSurfaceManager::SetVSyncEnabled ( bool  enabled)
virtual

Definition at line 344 of file angle_surface_manager.cc.

344  {
345  if (!MakeCurrent()) {
346  LogEglError("Unable to make surface current to update the swap interval");
347  return;
348  }
349 
350  // OpenGL swap intervals can be used to prevent screen tearing.
351  // If enabled, the raster thread blocks until the v-blank.
352  // This is unnecessary if DWM composition is enabled.
353  // See: https://www.khronos.org/opengl/wiki/Swap_Interval
354  // See: https://learn.microsoft.com/windows/win32/dwm/composition-ovw
355  if (eglSwapInterval(egl_display_, enabled ? 1 : 0) != EGL_TRUE) {
356  LogEglError("Unable to update the swap interval");
357  return;
358  }
359 }

References LogEglError(), and MakeCurrent().

Referenced by ResizeSurface().

◆ SwapBuffers()

EGLBoolean flutter::AngleSurfaceManager::SwapBuffers ( )

Definition at line 332 of file angle_surface_manager.cc.

332  {
333  return (eglSwapBuffers(egl_display_, render_surface_));
334 }

Referenced by flutter::FlutterWindowsView::SwapBuffers().


The documentation for this class was generated from the following files:
flutter::AngleSurfaceManager::ClearContext
bool ClearContext()
Definition: angle_surface_manager.cc:322
flutter::AngleSurfaceManager::CreateSurface
virtual bool CreateSurface(HWND hwnd, EGLint width, EGLint height)
Definition: angle_surface_manager.cc:232
LogEglError
static void LogEglError(std::string message)
Definition: angle_surface_manager.cc:13
flutter::AngleSurfaceManager::AngleSurfaceManager
AngleSurfaceManager(bool enable_impeller)
Definition: angle_surface_manager.cc:33
flutter::AngleSurfaceManager::DestroySurface
virtual void DestroySurface()
Definition: angle_surface_manager.cc:301
flutter::AngleSurfaceManager::MakeCurrent
virtual bool MakeCurrent()
Definition: angle_surface_manager.cc:312
flutter::AngleSurfaceManager::SetVSyncEnabled
virtual void SetVSyncEnabled(bool enabled)
Definition: angle_surface_manager.cc:344
flutter::AngleSurfaceManager::GetSurfaceDimensions
void GetSurfaceDimensions(EGLint *width, EGLint *height)
Definition: angle_surface_manager.cc:286