From 499f597c8a219ef7bbdfa20f8c6a228af7c86611 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Thu, 30 Dec 2021 15:47:18 +0800 Subject: [PATCH 1/3] Only creates 'onscreen_surface_' when it's not available in 'AndroidSurfaceGL::CreatePbufferSurface' --- shell/platform/android/android_surface_gl.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shell/platform/android/android_surface_gl.cc b/shell/platform/android/android_surface_gl.cc index 224b2280d22e2..2b2e7990c9223 100644 --- a/shell/platform/android/android_surface_gl.cc +++ b/shell/platform/android/android_surface_gl.cc @@ -176,7 +176,9 @@ AndroidContextGL* AndroidSurfaceGL::GLContextPtr() const { } std::unique_ptr AndroidSurfaceGL::CreatePbufferSurface() { - onscreen_surface_ = GLContextPtr()->CreatePbufferSurface(); + if (!onscreen_surface_ || !onscreen_surface_->IsValid()) { + onscreen_surface_ = GLContextPtr()->CreatePbufferSurface(); + } sk_sp main_skia_context = GLContextPtr()->GetMainSkiaContext(); if (!main_skia_context) { From 822d4af8ef11d795c983261b9094dd6b746b4928 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Thu, 13 Jan 2022 21:50:43 +0800 Subject: [PATCH 2/3] Rename the function and add some unit tests --- .../android/android_context_gl_unittests.cc | 96 +++++++++++++++++++ shell/platform/android/android_surface_gl.cc | 2 +- shell/platform/android/android_surface_gl.h | 6 +- .../android/surface/android_surface.cc | 2 +- .../android/surface/android_surface.h | 2 +- .../surface/snapshot_surface_producer.cc | 2 +- 6 files changed, 105 insertions(+), 5 deletions(-) diff --git a/shell/platform/android/android_context_gl_unittests.cc b/shell/platform/android/android_context_gl_unittests.cc index 2278acd6b37eb..4205864189a0b 100644 --- a/shell/platform/android/android_context_gl_unittests.cc +++ b/shell/platform/android/android_context_gl_unittests.cc @@ -4,12 +4,62 @@ #include "flutter/shell/common/thread_host.h" #include "flutter/shell/platform/android/android_context_gl.h" #include "flutter/shell/platform/android/android_environment_gl.h" +#include "flutter/shell/platform/android/android_surface_gl.h" +#include "flutter/shell/platform/android/jni/platform_view_android_jni.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" namespace flutter { namespace testing { namespace android { namespace { +class MockPlatformViewAndroidJNI : public PlatformViewAndroidJNI { + public: + MOCK_METHOD2(FlutterViewHandlePlatformMessage, + void(std::unique_ptr message, + int responseId)); + MOCK_METHOD2(FlutterViewHandlePlatformMessageResponse, + void(int responseId, std::unique_ptr data)); + MOCK_METHOD3(FlutterViewUpdateSemantics, + void(std::vector buffer, + std::vector strings, + std::vector> string_attribute_args)); + MOCK_METHOD2(FlutterViewUpdateCustomAccessibilityActions, + void(std::vector actions_buffer, + std::vector strings)); + MOCK_METHOD0(FlutterViewOnFirstFrame, void()); + MOCK_METHOD0(FlutterViewOnPreEngineRestart, void()); + MOCK_METHOD2(SurfaceTextureAttachToGLContext, + void(JavaLocalRef surface_texture, int textureId)); + MOCK_METHOD1(SurfaceTextureUpdateTexImage, + void(JavaLocalRef surface_texture)); + MOCK_METHOD2(SurfaceTextureGetTransformMatrix, + void(JavaLocalRef surface_texture, SkMatrix& transform)); + MOCK_METHOD1(SurfaceTextureDetachFromGLContext, + void(JavaLocalRef surface_texture)); + MOCK_METHOD8(FlutterViewOnDisplayPlatformView, + void(int view_id, + int x, + int y, + int width, + int height, + int viewWidth, + int viewHeight, + MutatorsStack mutators_stack)); + MOCK_METHOD5(FlutterViewDisplayOverlaySurface, + void(int surface_id, int x, int y, int width, int height)); + MOCK_METHOD0(FlutterViewBeginFrame, void()); + MOCK_METHOD0(FlutterViewEndFrame, void()); + MOCK_METHOD0(FlutterViewCreateOverlaySurface, + std::unique_ptr()); + MOCK_METHOD0(FlutterViewDestroyOverlaySurfaces, void()); + MOCK_METHOD1(FlutterViewComputePlatformResolvedLocale, + std::unique_ptr>( + std::vector supported_locales_data)); + MOCK_METHOD0(GetDisplayRefreshRate, double()); + MOCK_METHOD1(RequestDartDeferredLibrary, bool(int loading_unit_id)); +}; + TaskRunners MakeTaskRunners(const std::string& thread_label, const ThreadHost& thread_host) { fml::MessageLoop::EnsureInitializedForCurrentThread(); @@ -62,6 +112,52 @@ TEST(AndroidContextGl, CreateSingleThread) { context.reset(); EXPECT_TRUE(main_context->abandoned()); } + +TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNotNull) { + GrMockOptions main_context_options; + sk_sp main_context = + GrDirectContext::MakeMock(&main_context_options); + auto environment = fml::MakeRefCounted(); + std::string thread_label = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + ThreadHost thread_host(thread_label, ThreadHost::Type::UI | + ThreadHost::Type::RASTER | + ThreadHost::Type::IO); + TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); + auto android_context = std::make_shared( + AndroidRenderingAPI::kOpenGLES, environment, task_runners); + auto jni = std::make_shared(); + auto android_surface = + std::make_unique(android_context, jni); + auto window = fml::MakeRefCounted( + nullptr, /*is_fake_window=*/true); + android_surface->SetNativeWindow(window); + auto onscreen_surface = android_surface->GetOnscreenSurface(); + EXPECT_NE(onscreen_surface, nullptr); + android_surface->CreateSnapshotSurface(); + EXPECT_EQ(onscreen_surface, android_surface->GetOnscreenSurface()); +} + +TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNull) { + GrMockOptions main_context_options; + sk_sp main_context = + GrDirectContext::MakeMock(&main_context_options); + auto environment = fml::MakeRefCounted(); + std::string thread_label = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + ThreadHost thread_host(thread_label, ThreadHost::Type::UI | + ThreadHost::Type::RASTER | + ThreadHost::Type::IO); + TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); + auto android_context = std::make_shared( + AndroidRenderingAPI::kOpenGLES, environment, task_runners); + auto jni = std::make_shared(); + auto android_surface = + std::make_unique(android_context, jni); + EXPECT_EQ(android_surface->GetOnscreenSurface(), nullptr); + android_surface->CreateSnapshotSurface(); + EXPECT_NE(android_surface->GetOnscreenSurface(), nullptr); +} } // namespace android } // namespace testing } // namespace flutter diff --git a/shell/platform/android/android_surface_gl.cc b/shell/platform/android/android_surface_gl.cc index 2b2e7990c9223..a94b873aec8a7 100644 --- a/shell/platform/android/android_surface_gl.cc +++ b/shell/platform/android/android_surface_gl.cc @@ -175,7 +175,7 @@ AndroidContextGL* AndroidSurfaceGL::GLContextPtr() const { return reinterpret_cast(android_context_.get()); } -std::unique_ptr AndroidSurfaceGL::CreatePbufferSurface() { +std::unique_ptr AndroidSurfaceGL::CreateSnapshotSurface() { if (!onscreen_surface_ || !onscreen_surface_->IsValid()) { onscreen_surface_ = GLContextPtr()->CreatePbufferSurface(); } diff --git a/shell/platform/android/android_surface_gl.h b/shell/platform/android/android_surface_gl.h index 31ea82727bf52..26f7817de2565 100644 --- a/shell/platform/android/android_surface_gl.h +++ b/shell/platform/android/android_surface_gl.h @@ -49,7 +49,7 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, bool SetNativeWindow(fml::RefPtr window) override; // |AndroidSurface| - virtual std::unique_ptr CreatePbufferSurface() override; + virtual std::unique_ptr CreateSnapshotSurface() override; // |GPUSurfaceGLDelegate| std::unique_ptr GLContextMakeCurrent() override; @@ -66,6 +66,10 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, // |GPUSurfaceGLDelegate| sk_sp GetGLInterface() const override; + AndroidEGLSurface* GetOnscreenSurface() const { + return onscreen_surface_.get(); + } + private: fml::RefPtr native_window_; std::unique_ptr onscreen_surface_; diff --git a/shell/platform/android/surface/android_surface.cc b/shell/platform/android/surface/android_surface.cc index 22162544f88b5..dbecfe69dc382 100644 --- a/shell/platform/android/surface/android_surface.cc +++ b/shell/platform/android/surface/android_surface.cc @@ -15,7 +15,7 @@ AndroidSurface::AndroidSurface( AndroidSurface::~AndroidSurface() = default; -std::unique_ptr AndroidSurface::CreatePbufferSurface() { +std::unique_ptr AndroidSurface::CreateSnapshotSurface() { return nullptr; } diff --git a/shell/platform/android/surface/android_surface.h b/shell/platform/android/surface/android_surface.h index 70cee01bfe380..632b84ea14c1e 100644 --- a/shell/platform/android/surface/android_surface.h +++ b/shell/platform/android/surface/android_surface.h @@ -37,7 +37,7 @@ class AndroidSurface { virtual bool SetNativeWindow(fml::RefPtr window) = 0; - virtual std::unique_ptr CreatePbufferSurface(); + virtual std::unique_ptr CreateSnapshotSurface(); protected: explicit AndroidSurface( diff --git a/shell/platform/android/surface/snapshot_surface_producer.cc b/shell/platform/android/surface/snapshot_surface_producer.cc index 5ec41e85471ee..3ca4c37f3ce6a 100644 --- a/shell/platform/android/surface/snapshot_surface_producer.cc +++ b/shell/platform/android/surface/snapshot_surface_producer.cc @@ -12,7 +12,7 @@ AndroidSnapshotSurfaceProducer::AndroidSnapshotSurfaceProducer( std::unique_ptr AndroidSnapshotSurfaceProducer::CreateSnapshotSurface() { - return android_surface_.CreatePbufferSurface(); + return android_surface_.CreateSnapshotSurface(); } } // namespace flutter From 87b3d63155c6da031d4dc27eba8523a4ee3cb23e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 13 Jan 2022 09:16:36 -0800 Subject: [PATCH 3/3] Update android_surface_gl.h --- shell/platform/android/android_surface_gl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shell/platform/android/android_surface_gl.h b/shell/platform/android/android_surface_gl.h index 26f7817de2565..e078d2363e6b2 100644 --- a/shell/platform/android/android_surface_gl.h +++ b/shell/platform/android/android_surface_gl.h @@ -66,6 +66,10 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, // |GPUSurfaceGLDelegate| sk_sp GetGLInterface() const override; + // Obtain a raw pointer to the on-screen AndroidEGLSurface. + // + // This method is intended for use in tests. Callers must not + // delete the returned pointer. AndroidEGLSurface* GetOnscreenSurface() const { return onscreen_surface_.get(); }