Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
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
8 changes: 8 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -7242,6 +7242,10 @@ ORIGIN: ../../../flutter/shell/platform/windows/egl/manager.cc + ../../../flutte
ORIGIN: ../../../flutter/shell/platform/windows/egl/manager.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/egl/proc_table.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/egl/proc_table.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/egl/surface.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/egl/surface.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/egl/window_surface.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/egl/window_surface.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/event_watcher.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/event_watcher.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/windows/external_texture.h + ../../../flutter/LICENSE
Expand Down Expand Up @@ -10117,6 +10121,10 @@ FILE: ../../../flutter/shell/platform/windows/egl/manager.cc
FILE: ../../../flutter/shell/platform/windows/egl/manager.h
FILE: ../../../flutter/shell/platform/windows/egl/proc_table.cc
FILE: ../../../flutter/shell/platform/windows/egl/proc_table.h
FILE: ../../../flutter/shell/platform/windows/egl/surface.cc
FILE: ../../../flutter/shell/platform/windows/egl/surface.h
FILE: ../../../flutter/shell/platform/windows/egl/window_surface.cc
FILE: ../../../flutter/shell/platform/windows/egl/window_surface.h
FILE: ../../../flutter/shell/platform/windows/event_watcher.cc
FILE: ../../../flutter/shell/platform/windows/event_watcher.h
FILE: ../../../flutter/shell/platform/windows/external_texture.h
Expand Down
5 changes: 5 additions & 0 deletions shell/platform/windows/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ source_set("flutter_windows_source") {
"egl/manager.h",
"egl/proc_table.cc",
"egl/proc_table.h",
"egl/surface.cc",
"egl/surface.h",
"egl/window_surface.cc",
"egl/window_surface.h",
"event_watcher.cc",
"event_watcher.h",
"external_texture.h",
Expand Down Expand Up @@ -209,6 +213,7 @@ executable("flutter_windows_unittests") {
"testing/egl/mock_context.h",
"testing/egl/mock_manager.h",
"testing/egl/mock_proc_table.h",
"testing/egl/mock_window_surface.h",
"testing/engine_modifier.h",
"testing/flutter_window_test.cc",
"testing/flutter_window_test.h",
Expand Down
25 changes: 20 additions & 5 deletions shell/platform/windows/compositor_opengl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ bool CompositorOpenGL::Present(const FlutterLayer** layers,
return false;
}

if (!engine_->egl_manager()->surface() ||
!engine_->egl_manager()->surface()->IsValid()) {
return false;
}

// Clear the view if there are no layers to present.
if (layers_count == 0) {
// Normally the compositor is initialized when the first backing store is
Expand Down Expand Up @@ -128,7 +133,7 @@ bool CompositorOpenGL::Present(const FlutterLayer** layers,
return false;
}

if (!engine_->egl_manager()->MakeCurrent()) {
if (!engine_->egl_manager()->surface()->MakeCurrent()) {
return false;
}

Expand All @@ -154,7 +159,7 @@ bool CompositorOpenGL::Present(const FlutterLayer** layers,
GL_NEAREST // filter
);

if (!engine_->egl_manager()->SwapBuffers()) {
if (!engine_->egl_manager()->surface()->SwapBuffers()) {
return false;
}

Expand All @@ -165,7 +170,17 @@ bool CompositorOpenGL::Present(const FlutterLayer** layers,
bool CompositorOpenGL::Initialize() {
FML_DCHECK(!is_initialized_);

if (!engine_->egl_manager()->MakeCurrent()) {
egl::Manager* manager = engine_->egl_manager();
if (!manager) {
return false;
}

egl::Surface* surface = manager->surface();
if (!surface || !surface->IsValid()) {
return false;
}

if (!surface->MakeCurrent()) {
return false;
}

Expand All @@ -186,14 +201,14 @@ bool CompositorOpenGL::ClearSurface() {
// Resize the surface if needed.
engine_->view()->OnEmptyFrameGenerated();

if (!engine_->egl_manager()->MakeCurrent()) {
if (!engine_->egl_manager()->surface()->MakeCurrent()) {
return false;
}

gl_->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl_->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

if (!engine_->egl_manager()->SwapBuffers()) {
if (!engine_->egl_manager()->surface()->SwapBuffers()) {
return false;
}

Expand Down
58 changes: 45 additions & 13 deletions shell/platform/windows/compositor_opengl_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "flutter/shell/platform/windows/egl/manager.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/testing/egl/mock_manager.h"
#include "flutter/shell/platform/windows/testing/egl/mock_window_surface.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
Expand Down Expand Up @@ -65,20 +66,29 @@ class CompositorOpenGLTest : public WindowsTest {
protected:
FlutterWindowsEngine* engine() { return engine_.get(); }
egl::MockManager* egl_manager() { return egl_manager_; }
egl::MockWindowSurface* surface() { return surface_.get(); }

void UseHeadlessEngine() {
void UseHeadlessEngine(bool add_surface = true) {
auto egl_manager = std::make_unique<egl::MockManager>();
egl_manager_ = egl_manager.get();

if (add_surface) {
surface_ = std::make_unique<egl::MockWindowSurface>();
EXPECT_CALL(*egl_manager_, surface)
.WillRepeatedly(Return(surface_.get()));
} else {
EXPECT_CALL(*egl_manager_, surface).WillRepeatedly(Return(nullptr));
}

FlutterWindowsEngineBuilder builder{GetContext()};

engine_ = builder.Build();
EngineModifier modifier(engine_.get());
modifier.SetEGLManager(std::move(egl_manager));
}

void UseEngineWithView() {
UseHeadlessEngine();
void UseEngineWithView(bool add_surface = true) {
UseHeadlessEngine(add_surface);

auto window = std::make_unique<MockWindowBindingHandler>();
EXPECT_CALL(*window.get(), SetView).Times(1);
Expand All @@ -92,6 +102,7 @@ class CompositorOpenGLTest : public WindowsTest {
private:
std::unique_ptr<FlutterWindowsEngine> engine_;
std::unique_ptr<FlutterWindowsView> view_;
std::unique_ptr<egl::MockWindowSurface> surface_;
egl::MockManager* egl_manager_;

FML_DISALLOW_COPY_AND_ASSIGN(CompositorOpenGLTest);
Expand All @@ -107,7 +118,8 @@ TEST_F(CompositorOpenGLTest, CreateBackingStore) {
FlutterBackingStoreConfig config = {};
FlutterBackingStore backing_store = {};

EXPECT_CALL(*egl_manager(), MakeCurrent).WillOnce(Return(true));
EXPECT_CALL(*surface(), IsValid).WillOnce(Return(true));
EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(true));
ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
}
Expand All @@ -120,7 +132,8 @@ TEST_F(CompositorOpenGLTest, InitializationFailure) {
FlutterBackingStoreConfig config = {};
FlutterBackingStore backing_store = {};

EXPECT_CALL(*egl_manager(), MakeCurrent).WillOnce(Return(false));
EXPECT_CALL(*surface(), IsValid).WillOnce(Return(true));
EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(false));
EXPECT_FALSE(compositor.CreateBackingStore(config, &backing_store));
}

Expand All @@ -132,16 +145,17 @@ TEST_F(CompositorOpenGLTest, Present) {
FlutterBackingStoreConfig config = {};
FlutterBackingStore backing_store = {};

EXPECT_CALL(*egl_manager(), MakeCurrent).WillOnce(Return(true));
EXPECT_CALL(*surface(), IsValid).WillRepeatedly(Return(true));
EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(true));
ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));

FlutterLayer layer = {};
layer.type = kFlutterLayerContentTypeBackingStore;
layer.backing_store = &backing_store;
const FlutterLayer* layer_ptr = &layer;

EXPECT_CALL(*egl_manager(), MakeCurrent).WillOnce(Return(true));
EXPECT_CALL(*egl_manager(), SwapBuffers).WillOnce(Return(true));
EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(true));
EXPECT_CALL(*surface(), SwapBuffers).WillOnce(Return(true));
EXPECT_TRUE(compositor.Present(&layer_ptr, 1));

ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
Expand All @@ -154,10 +168,9 @@ TEST_F(CompositorOpenGLTest, PresentEmpty) {

// The context will be bound twice: first to initialize the compositor, second
// to clear the surface.
EXPECT_CALL(*egl_manager(), MakeCurrent)
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(*egl_manager(), SwapBuffers).WillOnce(Return(true));
EXPECT_CALL(*surface(), IsValid).WillRepeatedly(Return(true));
EXPECT_CALL(*surface(), MakeCurrent).Times(2).WillRepeatedly(Return(true));
EXPECT_CALL(*surface(), SwapBuffers).WillOnce(Return(true));
EXPECT_TRUE(compositor.Present(nullptr, 0));
}

Expand All @@ -169,7 +182,8 @@ TEST_F(CompositorOpenGLTest, HeadlessPresentIgnored) {
FlutterBackingStoreConfig config = {};
FlutterBackingStore backing_store = {};

EXPECT_CALL(*egl_manager(), MakeCurrent).WillOnce(Return(true));
EXPECT_CALL(*surface(), IsValid).WillOnce(Return(true));
EXPECT_CALL(*surface(), MakeCurrent).WillOnce(Return(true));
ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));

FlutterLayer layer = {};
Expand All @@ -182,5 +196,23 @@ TEST_F(CompositorOpenGLTest, HeadlessPresentIgnored) {
ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
}

TEST_F(CompositorOpenGLTest, NoSurfaceIgnored) {
UseEngineWithView(/*add_surface = */ false);

auto compositor = CompositorOpenGL{engine(), kMockResolver};

FlutterBackingStoreConfig config = {};
FlutterBackingStore backing_store = {};

ASSERT_FALSE(compositor.CreateBackingStore(config, &backing_store));

FlutterLayer layer = {};
layer.type = kFlutterLayerContentTypeBackingStore;
layer.backing_store = nullptr;
const FlutterLayer* layer_ptr = &layer;

EXPECT_FALSE(compositor.Present(&layer_ptr, 1));
}

} // namespace testing
} // namespace flutter
2 changes: 1 addition & 1 deletion shell/platform/windows/egl/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace egl {

// An EGL context to interact with OpenGL.
//
// This enables automatic eror logging and mocking.
// This enables automatic error logging and mocking.
//
// Flutter Windows uses this to create render and resource contexts.
class Context {
Expand Down
Loading