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 2 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