Skip to content

Commit

Permalink
Adds AndroidSurfaceGLImpeller unit tests (#40979)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaaclarke committed Apr 17, 2023
1 parent a7df2eb commit b2d0738
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 25 deletions.
1 change: 1 addition & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@
../../../flutter/shell/platform/android/.gitignore
../../../flutter/shell/platform/android/android_context_gl_unittests.cc
../../../flutter/shell/platform/android/android_shell_holder_unittests.cc
../../../flutter/shell/platform/android/android_surface_gl_impeller_unittests.cc
../../../flutter/shell/platform/android/apk_asset_provider_unittests.cc
../../../flutter/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc
../../../flutter/shell/platform/android/external_view_embedder/surface_pool_unittests.cc
Expand Down
20 changes: 10 additions & 10 deletions impeller/toolkit/egl/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ class Display {
public:
Display();

~Display();
virtual ~Display();

bool IsValid() const;
virtual bool IsValid() const;

std::unique_ptr<Config> ChooseConfig(ConfigDescriptor config) const;
virtual std::unique_ptr<Config> ChooseConfig(ConfigDescriptor config) const;

std::unique_ptr<Context> CreateContext(const Config& config,
const Context* share_context);
virtual std::unique_ptr<Context> CreateContext(const Config& config,
const Context* share_context);

std::unique_ptr<Surface> CreateWindowSurface(const Config& config,
EGLNativeWindowType window);
virtual std::unique_ptr<Surface> CreateWindowSurface(
const Config& config,
EGLNativeWindowType window);

std::unique_ptr<Surface> CreatePixelBufferSurface(const Config& config,
size_t width,
size_t height);
virtual std::unique_ptr<Surface>
CreatePixelBufferSurface(const Config& config, size_t width, size_t height);

private:
EGLDisplay display_ = EGL_NO_DISPLAY;
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ executable("flutter_shell_native_unittests") {
sources = [
"android_context_gl_unittests.cc",
"android_shell_holder_unittests.cc",
"android_surface_gl_impeller_unittests.cc",
"apk_asset_provider_unittests.cc",
"flutter_shell_native_unittests.cc",
]
public_configs = [ "//flutter:config" ]
deps = [
":flutter_shell_native_src",
"//flutter/shell/platform/android/jni:jni_mock",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
Expand Down
24 changes: 12 additions & 12 deletions shell/platform/android/android_surface_gl_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,13 @@ static std::shared_ptr<impeller::Context> CreateImpellerContext(

AndroidSurfaceGLImpeller::AndroidSurfaceGLImpeller(
const std::shared_ptr<AndroidContext>& android_context,
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade)
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
std::unique_ptr<impeller::egl::Display> display)
: AndroidSurface(android_context),
reactor_worker_(std::shared_ptr<ReactorWorker>(new ReactorWorker())) {
auto display = std::make_unique<impeller::egl::Display>();
if (!display->IsValid()) {
FML_DLOG(ERROR) << "Could not create EGL display.";
reactor_worker_(std::shared_ptr<ReactorWorker>(new ReactorWorker())),
display_(std::move(display)) {
if (!display_->IsValid()) {
FML_DLOG(ERROR) << "Could not create surface with invalid Display.";
return;
}

Expand All @@ -99,11 +100,11 @@ AndroidSurfaceGLImpeller::AndroidSurfaceGLImpeller(

desc.surface_type = impeller::egl::SurfaceType::kWindow;
std::unique_ptr<impeller::egl::Config> onscreen_config =
display->ChooseConfig(desc);
display_->ChooseConfig(desc);
if (!onscreen_config) {
// Fallback for Android emulator.
desc.samples = impeller::egl::Samples::kOne;
onscreen_config = display->ChooseConfig(desc);
onscreen_config = display_->ChooseConfig(desc);
if (onscreen_config) {
FML_LOG(INFO) << "Warning: This device doesn't support MSAA for onscreen "
"framebuffers. Falling back to a single sample.";
Expand All @@ -114,27 +115,27 @@ AndroidSurfaceGLImpeller::AndroidSurfaceGLImpeller(
}

desc.surface_type = impeller::egl::SurfaceType::kPBuffer;
auto offscreen_config = display->ChooseConfig(desc);
auto offscreen_config = display_->ChooseConfig(desc);
if (!offscreen_config) {
FML_DLOG(ERROR) << "Could not choose offscreen config.";
return;
}

auto onscreen_context = display->CreateContext(*onscreen_config, nullptr);
auto onscreen_context = display_->CreateContext(*onscreen_config, nullptr);
if (!onscreen_context) {
FML_DLOG(ERROR) << "Could not create onscreen context.";
return;
}

auto offscreen_context =
display->CreateContext(*offscreen_config, onscreen_context.get());
display_->CreateContext(*offscreen_config, onscreen_context.get());
if (!offscreen_context) {
FML_DLOG(ERROR) << "Could not create offscreen context.";
return;
}

auto offscreen_surface =
display->CreatePixelBufferSurface(*offscreen_config, 1u, 1u);
display_->CreatePixelBufferSurface(*offscreen_config, 1u, 1u);
if (!offscreen_surface) {
FML_DLOG(ERROR) << "Could not create offscreen surface.";
return;
Expand Down Expand Up @@ -175,7 +176,6 @@ AndroidSurfaceGLImpeller::AndroidSurfaceGLImpeller(
FML_DLOG(ERROR) << "Could not add lifecycle listeners";
}

display_ = std::move(display);
onscreen_config_ = std::move(onscreen_config);
offscreen_config_ = std::move(offscreen_config);
offscreen_surface_ = std::move(offscreen_surface);
Expand Down
3 changes: 2 additions & 1 deletion shell/platform/android/android_surface_gl_impeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate,
public:
AndroidSurfaceGLImpeller(
const std::shared_ptr<AndroidContext>& android_context,
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade);
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
std::unique_ptr<impeller::egl::Display> display);

// |AndroidSurface|
~AndroidSurfaceGLImpeller() override;
Expand Down
89 changes: 89 additions & 0 deletions shell/platform/android/android_surface_gl_impeller_unittests.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include "flutter/shell/platform/android/android_surface_gl_impeller.h"
#include "flutter/shell/platform/android/jni/jni_mock.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace flutter {
namespace testing {

using ::testing::_;
using ::testing::AllOf;
using ::testing::ByMove;
using ::testing::Field;
using ::testing::Matcher;
using ::testing::Return;

using ::impeller::egl::Config;
using ::impeller::egl::ConfigDescriptor;

namespace {
class MockDisplay : public impeller::egl::Display {
public:
MOCK_CONST_METHOD0(IsValid, bool());
MOCK_CONST_METHOD1(ChooseConfig, std::unique_ptr<Config>(ConfigDescriptor));
};
} // namespace

TEST(AndroidSurfaceGLImpeller, MSAAFirstAttempt) {
auto context =
std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
auto jni = std::make_shared<JNIMock>();
auto display = std::make_unique<MockDisplay>();
EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true));
auto first_result = std::make_unique<Config>(ConfigDescriptor(), EGLConfig());
auto second_result =
std::make_unique<Config>(ConfigDescriptor(), EGLConfig());
EXPECT_CALL(
*display,
ChooseConfig(Matcher<ConfigDescriptor>(AllOf(
Field(&ConfigDescriptor::samples, impeller::egl::Samples::kFour),
Field(&ConfigDescriptor::surface_type,
impeller::egl::SurfaceType::kWindow)))))
.WillOnce(Return(ByMove(std::move(first_result))));
EXPECT_CALL(*display, ChooseConfig(Matcher<ConfigDescriptor>(
Field(&ConfigDescriptor::surface_type,
impeller::egl::SurfaceType::kPBuffer))))
.WillOnce(Return(ByMove(std::move(second_result))));
ON_CALL(*display, ChooseConfig(_))
.WillByDefault(Return(ByMove(std::unique_ptr<Config>())));
auto surface = std::make_unique<AndroidSurfaceGLImpeller>(context, jni,
std::move(display));
ASSERT_TRUE(surface);
}

TEST(AndroidSurfaceGLImpeller, FallbackForEmulator) {
auto context =
std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
auto jni = std::make_shared<JNIMock>();
auto display = std::make_unique<MockDisplay>();
EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true));
std::unique_ptr<Config> first_result;
auto second_result =
std::make_unique<Config>(ConfigDescriptor(), EGLConfig());
auto third_result = std::make_unique<Config>(ConfigDescriptor(), EGLConfig());
EXPECT_CALL(
*display,
ChooseConfig(Matcher<ConfigDescriptor>(AllOf(
Field(&ConfigDescriptor::samples, impeller::egl::Samples::kFour),
Field(&ConfigDescriptor::surface_type,
impeller::egl::SurfaceType::kWindow)))))
.WillOnce(Return(ByMove(std::move(first_result))));
EXPECT_CALL(
*display,
ChooseConfig(Matcher<ConfigDescriptor>(
AllOf(Field(&ConfigDescriptor::samples, impeller::egl::Samples::kOne),
Field(&ConfigDescriptor::surface_type,
impeller::egl::SurfaceType::kWindow)))))
.WillOnce(Return(ByMove(std::move(second_result))));
EXPECT_CALL(*display, ChooseConfig(Matcher<ConfigDescriptor>(
Field(&ConfigDescriptor::surface_type,
impeller::egl::SurfaceType::kPBuffer))))
.WillOnce(Return(ByMove(std::move(third_result))));
ON_CALL(*display, ChooseConfig(_))
.WillByDefault(Return(ByMove(std::unique_ptr<Config>())));
auto surface = std::make_unique<AndroidSurfaceGLImpeller>(context, jni,
std::move(display));
ASSERT_TRUE(surface);
}
} // namespace testing
} // namespace flutter
5 changes: 3 additions & 2 deletions shell/platform/android/platform_view_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
android_context_, jni_facade_, enable_vulkan_validation_);

#else
return std::make_unique<AndroidSurfaceGLImpeller>(android_context_,
jni_facade_);
return std::make_unique<AndroidSurfaceGLImpeller>(
android_context_, jni_facade_,
std::make_unique<impeller::egl::Display>());
#endif
} else {
return std::make_unique<AndroidSurfaceGLSkia>(android_context_,
Expand Down

0 comments on commit b2d0738

Please sign in to comment.