Only creates 'onscreen_surface_' when it's not available in 'AndroidSurfaceGL::CreateSnapshotSurface' (flutter/engine#30590)

* Only creates 'onscreen_surface_' when it's not available in 'AndroidSurfaceGL::CreatePbufferSurface'

* Rename the function and add some unit tests

* Update android_surface_gl.h

Co-authored-by: Dan Field <dfield@gmail.com>
This commit is contained in:
ColdPaleLight 2022-01-14 02:17:01 +08:00 committed by GitHub
parent 9ab859182e
commit 03e2fe4a87
6 changed files with 112 additions and 6 deletions

View File

@ -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<flutter::PlatformMessage> message,
int responseId));
MOCK_METHOD2(FlutterViewHandlePlatformMessageResponse,
void(int responseId, std::unique_ptr<fml::Mapping> data));
MOCK_METHOD3(FlutterViewUpdateSemantics,
void(std::vector<uint8_t> buffer,
std::vector<std::string> strings,
std::vector<std::vector<uint8_t>> string_attribute_args));
MOCK_METHOD2(FlutterViewUpdateCustomAccessibilityActions,
void(std::vector<uint8_t> actions_buffer,
std::vector<std::string> 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<PlatformViewAndroidJNI::OverlayMetadata>());
MOCK_METHOD0(FlutterViewDestroyOverlaySurfaces, void());
MOCK_METHOD1(FlutterViewComputePlatformResolvedLocale,
std::unique_ptr<std::vector<std::string>>(
std::vector<std::string> 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<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
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<AndroidContextGL>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners);
auto jni = std::make_shared<MockPlatformViewAndroidJNI>();
auto android_surface =
std::make_unique<AndroidSurfaceGL>(android_context, jni);
auto window = fml::MakeRefCounted<AndroidNativeWindow>(
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<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
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<AndroidContextGL>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners);
auto jni = std::make_shared<MockPlatformViewAndroidJNI>();
auto android_surface =
std::make_unique<AndroidSurfaceGL>(android_context, jni);
EXPECT_EQ(android_surface->GetOnscreenSurface(), nullptr);
android_surface->CreateSnapshotSurface();
EXPECT_NE(android_surface->GetOnscreenSurface(), nullptr);
}
} // namespace android
} // namespace testing
} // namespace flutter

View File

@ -175,8 +175,10 @@ AndroidContextGL* AndroidSurfaceGL::GLContextPtr() const {
return reinterpret_cast<AndroidContextGL*>(android_context_.get());
}
std::unique_ptr<Surface> AndroidSurfaceGL::CreatePbufferSurface() {
onscreen_surface_ = GLContextPtr()->CreatePbufferSurface();
std::unique_ptr<Surface> AndroidSurfaceGL::CreateSnapshotSurface() {
if (!onscreen_surface_ || !onscreen_surface_->IsValid()) {
onscreen_surface_ = GLContextPtr()->CreatePbufferSurface();
}
sk_sp<GrDirectContext> main_skia_context =
GLContextPtr()->GetMainSkiaContext();
if (!main_skia_context) {

View File

@ -49,7 +49,7 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) override;
// |AndroidSurface|
virtual std::unique_ptr<Surface> CreatePbufferSurface() override;
virtual std::unique_ptr<Surface> CreateSnapshotSurface() override;
// |GPUSurfaceGLDelegate|
std::unique_ptr<GLContextResult> GLContextMakeCurrent() override;
@ -66,6 +66,14 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
// |GPUSurfaceGLDelegate|
sk_sp<const GrGLInterface> 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();
}
private:
fml::RefPtr<AndroidNativeWindow> native_window_;
std::unique_ptr<AndroidEGLSurface> onscreen_surface_;

View File

@ -15,7 +15,7 @@ AndroidSurface::AndroidSurface(
AndroidSurface::~AndroidSurface() = default;
std::unique_ptr<Surface> AndroidSurface::CreatePbufferSurface() {
std::unique_ptr<Surface> AndroidSurface::CreateSnapshotSurface() {
return nullptr;
}

View File

@ -37,7 +37,7 @@ class AndroidSurface {
virtual bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) = 0;
virtual std::unique_ptr<Surface> CreatePbufferSurface();
virtual std::unique_ptr<Surface> CreateSnapshotSurface();
protected:
explicit AndroidSurface(

View File

@ -12,7 +12,7 @@ AndroidSnapshotSurfaceProducer::AndroidSnapshotSurfaceProducer(
std::unique_ptr<Surface>
AndroidSnapshotSurfaceProducer::CreateSnapshotSurface() {
return android_surface_.CreatePbufferSurface();
return android_surface_.CreateSnapshotSurface();
}
} // namespace flutter