forked from firka/flutter
[Impeller] [Android] Refactor the Android context/surface implementation to work more like Skia. (flutter/engine#41059)
Noticed this while working on https://github.com/flutter/flutter/issues/124181 In Impeller right now, Android creates a context for each surface - but in Skia, Android creates one context and shares it across surfaces. For the multiple-engine scenario this matters. This also makes it possible for Android to provide the impeller::Context independently of surface creation.
This commit is contained in:
@@ -226,9 +226,9 @@
|
||||
../../../flutter/shell/common/variable_refresh_rate_display_unittests.cc
|
||||
../../../flutter/shell/common/vsync_waiter_unittests.cc
|
||||
../../../flutter/shell/platform/android/.gitignore
|
||||
../../../flutter/shell/platform/android/android_context_gl_impeller_unittests.cc
|
||||
../../../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
|
||||
|
||||
@@ -2226,6 +2226,8 @@ ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_impeller.cc +
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_impeller.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_skia.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_skia.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_display.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_display.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/android/android_egl_surface.cc + ../../../flutter/LICENSE
|
||||
@@ -4843,6 +4845,8 @@ FILE: ../../../flutter/shell/platform/android/android_context_gl_impeller.cc
|
||||
FILE: ../../../flutter/shell/platform/android/android_context_gl_impeller.h
|
||||
FILE: ../../../flutter/shell/platform/android/android_context_gl_skia.cc
|
||||
FILE: ../../../flutter/shell/platform/android/android_context_gl_skia.h
|
||||
FILE: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.cc
|
||||
FILE: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.h
|
||||
FILE: ../../../flutter/shell/platform/android/android_display.cc
|
||||
FILE: ../../../flutter/shell/platform/android/android_display.h
|
||||
FILE: ../../../flutter/shell/platform/android/android_egl_surface.cc
|
||||
|
||||
@@ -39,9 +39,9 @@ executable("flutter_shell_native_unittests") {
|
||||
visibility = [ "*" ]
|
||||
testonly = true
|
||||
sources = [
|
||||
"android_context_gl_impeller_unittests.cc",
|
||||
"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",
|
||||
]
|
||||
@@ -72,6 +72,8 @@ source_set("flutter_shell_native_src") {
|
||||
"android_context_gl_impeller.h",
|
||||
"android_context_gl_skia.cc",
|
||||
"android_context_gl_skia.h",
|
||||
"android_context_vulkan_impeller.cc",
|
||||
"android_context_vulkan_impeller.h",
|
||||
"android_display.cc",
|
||||
"android_display.h",
|
||||
"android_egl_surface.cc",
|
||||
|
||||
@@ -4,15 +4,228 @@
|
||||
|
||||
#include "flutter/shell/platform/android/android_context_gl_impeller.h"
|
||||
|
||||
#include "flutter/impeller/renderer/backend/gles/context_gles.h"
|
||||
#include "flutter/impeller/renderer/backend/gles/proc_table_gles.h"
|
||||
#include "flutter/impeller/renderer/backend/gles/reactor_gles.h"
|
||||
#include "flutter/impeller/toolkit/egl/context.h"
|
||||
#include "flutter/impeller/toolkit/egl/surface.h"
|
||||
#include "impeller/entity/gles/entity_shaders_gles.h"
|
||||
#include "impeller/scene/shaders/gles/scene_shaders_gles.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
AndroidContextGLImpeller::AndroidContextGLImpeller()
|
||||
: AndroidContext(AndroidRenderingAPI::kOpenGLES) {}
|
||||
class AndroidContextGLImpeller::ReactorWorker final
|
||||
: public impeller::ReactorGLES::Worker {
|
||||
public:
|
||||
ReactorWorker() = default;
|
||||
|
||||
// |impeller::ReactorGLES::Worker|
|
||||
~ReactorWorker() override = default;
|
||||
|
||||
// |impeller::ReactorGLES::Worker|
|
||||
bool CanReactorReactOnCurrentThreadNow(
|
||||
const impeller::ReactorGLES& reactor) const override {
|
||||
impeller::ReaderLock lock(mutex_);
|
||||
auto found = reactions_allowed_.find(std::this_thread::get_id());
|
||||
if (found == reactions_allowed_.end()) {
|
||||
return false;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
void SetReactionsAllowedOnCurrentThread(bool allowed) {
|
||||
impeller::WriterLock lock(mutex_);
|
||||
reactions_allowed_[std::this_thread::get_id()] = allowed;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable impeller::RWMutex mutex_;
|
||||
std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(ReactorWorker);
|
||||
};
|
||||
|
||||
static std::shared_ptr<impeller::Context> CreateImpellerContext(
|
||||
const std::shared_ptr<impeller::ReactorGLES::Worker>& worker) {
|
||||
auto proc_table = std::make_unique<impeller::ProcTableGLES>(
|
||||
impeller::egl::CreateProcAddressResolver());
|
||||
|
||||
if (!proc_table->IsValid()) {
|
||||
FML_LOG(ERROR) << "Could not create OpenGL proc table.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
|
||||
std::make_shared<fml::NonOwnedMapping>(
|
||||
impeller_entity_shaders_gles_data,
|
||||
impeller_entity_shaders_gles_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(
|
||||
impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length),
|
||||
};
|
||||
|
||||
auto context =
|
||||
impeller::ContextGLES::Create(std::move(proc_table), shader_mappings);
|
||||
if (!context) {
|
||||
FML_LOG(ERROR) << "Could not create OpenGLES Impeller Context.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!context->AddReactorWorker(worker).has_value()) {
|
||||
FML_LOG(ERROR) << "Could not add reactor worker.";
|
||||
return nullptr;
|
||||
}
|
||||
FML_LOG(ERROR) << "Using the Impeller rendering backend.";
|
||||
return context;
|
||||
}
|
||||
|
||||
AndroidContextGLImpeller::AndroidContextGLImpeller(
|
||||
std::unique_ptr<impeller::egl::Display> display)
|
||||
: AndroidContext(AndroidRenderingAPI::kOpenGLES),
|
||||
reactor_worker_(std::shared_ptr<ReactorWorker>(new ReactorWorker())),
|
||||
display_(std::move(display)) {
|
||||
if (!display_ || !display_->IsValid()) {
|
||||
FML_DLOG(ERROR) << "Could not create context with invalid EGL display.";
|
||||
return;
|
||||
}
|
||||
|
||||
impeller::egl::ConfigDescriptor desc;
|
||||
desc.api = impeller::egl::API::kOpenGLES2;
|
||||
desc.color_format = impeller::egl::ColorFormat::kRGBA8888;
|
||||
desc.depth_bits = impeller::egl::DepthBits::kZero;
|
||||
desc.stencil_bits = impeller::egl::StencilBits::kEight;
|
||||
desc.samples = impeller::egl::Samples::kFour;
|
||||
|
||||
desc.surface_type = impeller::egl::SurfaceType::kWindow;
|
||||
std::unique_ptr<impeller::egl::Config> onscreen_config =
|
||||
display_->ChooseConfig(desc);
|
||||
if (!onscreen_config) {
|
||||
// Fallback for Android emulator.
|
||||
desc.samples = impeller::egl::Samples::kOne;
|
||||
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.";
|
||||
} else {
|
||||
FML_DLOG(ERROR) << "Could not choose onscreen config.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
desc.surface_type = impeller::egl::SurfaceType::kPBuffer;
|
||||
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);
|
||||
if (!onscreen_context) {
|
||||
FML_DLOG(ERROR) << "Could not create onscreen context.";
|
||||
return;
|
||||
}
|
||||
|
||||
auto offscreen_context =
|
||||
display_->CreateContext(*offscreen_config, onscreen_context.get());
|
||||
if (!offscreen_context) {
|
||||
FML_DLOG(ERROR) << "Could not create offscreen context.";
|
||||
return;
|
||||
}
|
||||
|
||||
// Creating the impeller::Context requires a current context, which requires
|
||||
// some surface.
|
||||
auto offscreen_surface =
|
||||
display_->CreatePixelBufferSurface(*offscreen_config, 1u, 1u);
|
||||
if (!offscreen_context->MakeCurrent(*offscreen_surface)) {
|
||||
FML_DLOG(ERROR) << "Could not make offscreen context current.";
|
||||
return;
|
||||
}
|
||||
|
||||
auto impeller_context = CreateImpellerContext(reactor_worker_);
|
||||
|
||||
if (!impeller_context) {
|
||||
FML_DLOG(ERROR) << "Could not create Impeller context.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!offscreen_context->ClearCurrent()) {
|
||||
FML_DLOG(ERROR) << "Could not clear offscreen context.";
|
||||
return;
|
||||
}
|
||||
// Setup context listeners.
|
||||
impeller::egl::Context::LifecycleListener listener =
|
||||
[worker =
|
||||
reactor_worker_](impeller::egl ::Context::LifecycleEvent event) {
|
||||
switch (event) {
|
||||
case impeller::egl::Context::LifecycleEvent::kDidMakeCurrent:
|
||||
worker->SetReactionsAllowedOnCurrentThread(true);
|
||||
break;
|
||||
case impeller::egl::Context::LifecycleEvent::kWillClearCurrent:
|
||||
worker->SetReactionsAllowedOnCurrentThread(false);
|
||||
break;
|
||||
}
|
||||
};
|
||||
if (!onscreen_context->AddLifecycleListener(listener).has_value() ||
|
||||
!offscreen_context->AddLifecycleListener(listener).has_value()) {
|
||||
FML_DLOG(ERROR) << "Could not add lifecycle listeners";
|
||||
}
|
||||
|
||||
onscreen_config_ = std::move(onscreen_config);
|
||||
offscreen_config_ = std::move(offscreen_config);
|
||||
onscreen_context_ = std::move(onscreen_context);
|
||||
offscreen_context_ = std::move(offscreen_context);
|
||||
SetImpellerContext(impeller_context);
|
||||
|
||||
is_valid_ = true;
|
||||
}
|
||||
|
||||
AndroidContextGLImpeller::~AndroidContextGLImpeller() = default;
|
||||
|
||||
bool AndroidContextGLImpeller::IsValid() const {
|
||||
return true;
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
bool AndroidContextGLImpeller::ResourceContextClearCurrent() {
|
||||
if (!offscreen_context_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return offscreen_context_->ClearCurrent();
|
||||
}
|
||||
|
||||
bool AndroidContextGLImpeller::ResourceContextMakeCurrent(
|
||||
impeller::egl::Surface* offscreen_surface) {
|
||||
if (!offscreen_context_ || !offscreen_surface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return offscreen_context_->MakeCurrent(*offscreen_surface);
|
||||
}
|
||||
|
||||
std::unique_ptr<impeller::egl::Surface>
|
||||
AndroidContextGLImpeller::CreateOffscreenSurface() {
|
||||
return display_->CreatePixelBufferSurface(*offscreen_config_, 1u, 1u);
|
||||
}
|
||||
|
||||
bool AndroidContextGLImpeller::OnscreenContextMakeCurrent(
|
||||
impeller::egl::Surface* onscreen_surface) {
|
||||
if (!onscreen_surface || !onscreen_context_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return onscreen_context_->MakeCurrent(*onscreen_surface);
|
||||
}
|
||||
|
||||
bool AndroidContextGLImpeller::OnscreenContextClearCurrent() {
|
||||
if (!onscreen_context_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return onscreen_context_->ClearCurrent();
|
||||
}
|
||||
|
||||
std::unique_ptr<impeller::egl::Surface>
|
||||
AndroidContextGLImpeller::CreateOnscreenSurface(EGLNativeWindowType window) {
|
||||
return display_->CreateWindowSurface(*onscreen_config_, window);
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@@ -6,20 +6,40 @@
|
||||
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_GL_IMPELLER_H_
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/impeller/toolkit/egl/display.h"
|
||||
#include "flutter/shell/platform/android/context/android_context.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class AndroidContextGLImpeller : public AndroidContext {
|
||||
public:
|
||||
AndroidContextGLImpeller();
|
||||
explicit AndroidContextGLImpeller(
|
||||
std::unique_ptr<impeller::egl::Display> display);
|
||||
|
||||
~AndroidContextGLImpeller();
|
||||
|
||||
// |AndroidContext|
|
||||
bool IsValid() const override;
|
||||
|
||||
bool ResourceContextMakeCurrent(impeller::egl::Surface* offscreen_surface);
|
||||
bool ResourceContextClearCurrent();
|
||||
std::unique_ptr<impeller::egl::Surface> CreateOffscreenSurface();
|
||||
bool OnscreenContextMakeCurrent(impeller::egl::Surface* onscreen_surface);
|
||||
bool OnscreenContextClearCurrent();
|
||||
std::unique_ptr<impeller::egl::Surface> CreateOnscreenSurface(
|
||||
EGLNativeWindowType window);
|
||||
|
||||
private:
|
||||
class ReactorWorker;
|
||||
|
||||
std::shared_ptr<ReactorWorker> reactor_worker_;
|
||||
std::unique_ptr<impeller::egl::Display> display_;
|
||||
std::unique_ptr<impeller::egl::Config> onscreen_config_;
|
||||
std::unique_ptr<impeller::egl::Config> offscreen_config_;
|
||||
std::unique_ptr<impeller::egl::Context> onscreen_context_;
|
||||
std::unique_ptr<impeller::egl::Context> offscreen_context_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(AndroidContextGLImpeller);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "flutter/shell/platform/android/android_surface_gl_impeller.h"
|
||||
#include "flutter/shell/platform/android/jni/jni_mock.h"
|
||||
#include "flutter/shell/platform/android/android_context_gl_impeller.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -24,10 +23,7 @@ class MockDisplay : public impeller::egl::Display {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST(AndroidSurfaceGLImpeller, MSAAFirstAttempt) {
|
||||
auto context =
|
||||
std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
|
||||
auto jni = std::make_shared<JNIMock>();
|
||||
TEST(AndroidContextGLImpeller, MSAAFirstAttempt) {
|
||||
auto display = std::make_unique<MockDisplay>();
|
||||
EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true));
|
||||
auto first_result = std::make_unique<Config>(ConfigDescriptor(), EGLConfig());
|
||||
@@ -46,15 +42,11 @@ TEST(AndroidSurfaceGLImpeller, MSAAFirstAttempt) {
|
||||
.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);
|
||||
auto context = std::make_unique<AndroidContextGLImpeller>(std::move(display));
|
||||
ASSERT_TRUE(context);
|
||||
}
|
||||
|
||||
TEST(AndroidSurfaceGLImpeller, FallbackForEmulator) {
|
||||
auto context =
|
||||
std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
|
||||
auto jni = std::make_shared<JNIMock>();
|
||||
TEST(AndroidContextGLImpeller, FallbackForEmulator) {
|
||||
auto display = std::make_unique<MockDisplay>();
|
||||
EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true));
|
||||
std::unique_ptr<Config> first_result;
|
||||
@@ -81,9 +73,8 @@ TEST(AndroidSurfaceGLImpeller, FallbackForEmulator) {
|
||||
.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);
|
||||
auto context = std::make_unique<AndroidContextGLImpeller>(std::move(display));
|
||||
ASSERT_TRUE(context);
|
||||
}
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "flutter/shell/platform/android/android_egl_surface.h"
|
||||
#include "flutter/shell/platform/android/android_environment_gl.h"
|
||||
#include "flutter/shell/platform/android/android_surface_gl_skia.h"
|
||||
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -14,55 +13,6 @@ 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_METHOD0(GetDisplayWidth, double());
|
||||
MOCK_METHOD0(GetDisplayHeight, double());
|
||||
MOCK_METHOD0(GetDisplayDensity, double());
|
||||
MOCK_METHOD1(RequestDartDeferredLibrary, bool(int loading_unit_id));
|
||||
};
|
||||
|
||||
TaskRunners MakeTaskRunners(const std::string& thread_label,
|
||||
const ThreadHost& thread_host) {
|
||||
@@ -131,9 +81,8 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNotNull) {
|
||||
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
|
||||
auto android_context = std::make_shared<AndroidContextGLSkia>(
|
||||
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);
|
||||
auto jni = std::make_shared<MockPlatformViewAndroidJNI>();
|
||||
auto android_surface =
|
||||
std::make_unique<AndroidSurfaceGLSkia>(android_context, jni);
|
||||
std::make_unique<AndroidSurfaceGLSkia>(android_context);
|
||||
auto window = fml::MakeRefCounted<AndroidNativeWindow>(
|
||||
nullptr, /*is_fake_window=*/true);
|
||||
android_surface->SetNativeWindow(window);
|
||||
@@ -159,9 +108,8 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNull) {
|
||||
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
|
||||
auto android_context = std::make_shared<AndroidContextGLSkia>(
|
||||
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);
|
||||
auto jni = std::make_shared<MockPlatformViewAndroidJNI>();
|
||||
auto android_surface =
|
||||
std::make_unique<AndroidSurfaceGLSkia>(android_context, jni);
|
||||
std::make_unique<AndroidSurfaceGLSkia>(android_context);
|
||||
EXPECT_EQ(android_surface->GetOnscreenSurface(), nullptr);
|
||||
android_surface->CreateSnapshotSurface();
|
||||
EXPECT_NE(android_surface->GetOnscreenSurface(), nullptr);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/shell/platform/android/android_context_vulkan_impeller.h"
|
||||
|
||||
#include "flutter/fml/paths.h"
|
||||
#include "flutter/impeller/entity/vk/entity_shaders_vk.h"
|
||||
#include "flutter/impeller/entity/vk/modern_shaders_vk.h"
|
||||
#include "flutter/impeller/renderer/backend/vulkan/context_vk.h"
|
||||
#include "flutter/impeller/scene/shaders/vk/scene_shaders_vk.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
static std::shared_ptr<impeller::Context> CreateImpellerContext(
|
||||
const fml::RefPtr<vulkan::VulkanProcTable>& proc_table,
|
||||
const std::shared_ptr<fml::ConcurrentMessageLoop>& concurrent_loop,
|
||||
bool enable_vulkan_validation) {
|
||||
std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data,
|
||||
impeller_entity_shaders_vk_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_vk_data,
|
||||
impeller_scene_shaders_vk_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_vk_data,
|
||||
impeller_modern_shaders_vk_length),
|
||||
};
|
||||
|
||||
PFN_vkGetInstanceProcAddr instance_proc_addr =
|
||||
proc_table->NativeGetInstanceProcAddr();
|
||||
|
||||
impeller::ContextVK::Settings settings;
|
||||
settings.proc_address_callback = instance_proc_addr;
|
||||
settings.shader_libraries_data = std::move(shader_mappings);
|
||||
settings.cache_directory = fml::paths::GetCachesDirectory();
|
||||
settings.worker_task_runner = concurrent_loop->GetTaskRunner();
|
||||
settings.enable_validation = enable_vulkan_validation;
|
||||
return impeller::ContextVK::Create(std::move(settings));
|
||||
}
|
||||
|
||||
AndroidContextVulkanImpeller::AndroidContextVulkanImpeller(
|
||||
bool enable_validation)
|
||||
: AndroidContext(AndroidRenderingAPI::kVulkan),
|
||||
proc_table_(fml::MakeRefCounted<vulkan::VulkanProcTable>()),
|
||||
workers_(fml::ConcurrentMessageLoop::Create()) {
|
||||
auto impeller_context =
|
||||
CreateImpellerContext(proc_table_, workers_, enable_validation);
|
||||
SetImpellerContext(impeller_context);
|
||||
is_valid_ =
|
||||
proc_table_->HasAcquiredMandatoryProcAddresses() && impeller_context;
|
||||
}
|
||||
|
||||
AndroidContextVulkanImpeller::~AndroidContextVulkanImpeller() = default;
|
||||
|
||||
bool AndroidContextVulkanImpeller::IsValid() const {
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_VULKAN_IMPELLER_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_VULKAN_IMPELLER_H_
|
||||
|
||||
#include "flutter/fml/concurrent_message_loop.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/impeller/toolkit/egl/display.h"
|
||||
#include "flutter/shell/platform/android/context/android_context.h"
|
||||
#include "flutter/vulkan/procs/vulkan_proc_table.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class AndroidContextVulkanImpeller : public AndroidContext {
|
||||
public:
|
||||
explicit AndroidContextVulkanImpeller(bool enable_validation);
|
||||
|
||||
~AndroidContextVulkanImpeller();
|
||||
|
||||
// |AndroidContext|
|
||||
bool IsValid() const override;
|
||||
|
||||
private:
|
||||
fml::RefPtr<vulkan::VulkanProcTable> proc_table_;
|
||||
std::shared_ptr<fml::ConcurrentMessageLoop> workers_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(AndroidContextVulkanImpeller);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_VULKAN_IMPELLER_H_
|
||||
@@ -5,184 +5,21 @@
|
||||
#include "flutter/shell/platform/android/android_surface_gl_impeller.h"
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "flutter/impeller/renderer/backend/gles/context_gles.h"
|
||||
#include "flutter/impeller/renderer/backend/gles/proc_table_gles.h"
|
||||
#include "flutter/impeller/toolkit/egl/context.h"
|
||||
#include "flutter/impeller/toolkit/egl/surface.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_gl_impeller.h"
|
||||
#include "impeller/entity/gles/entity_shaders_gles.h"
|
||||
#include "impeller/scene/shaders/gles/scene_shaders_gles.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class AndroidSurfaceGLImpeller::ReactorWorker final
|
||||
: public impeller::ReactorGLES::Worker {
|
||||
public:
|
||||
ReactorWorker() = default;
|
||||
|
||||
// |impeller::ReactorGLES::Worker|
|
||||
~ReactorWorker() override = default;
|
||||
|
||||
// |impeller::ReactorGLES::Worker|
|
||||
bool CanReactorReactOnCurrentThreadNow(
|
||||
const impeller::ReactorGLES& reactor) const override {
|
||||
impeller::ReaderLock lock(mutex_);
|
||||
auto found = reactions_allowed_.find(std::this_thread::get_id());
|
||||
if (found == reactions_allowed_.end()) {
|
||||
return false;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
void SetReactionsAllowedOnCurrentThread(bool allowed) {
|
||||
impeller::WriterLock lock(mutex_);
|
||||
reactions_allowed_[std::this_thread::get_id()] = allowed;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable impeller::RWMutex mutex_;
|
||||
std::map<std::thread::id, bool> reactions_allowed_ IPLR_GUARDED_BY(mutex_);
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(ReactorWorker);
|
||||
};
|
||||
|
||||
static std::shared_ptr<impeller::Context> CreateImpellerContext(
|
||||
const std::shared_ptr<impeller::ReactorGLES::Worker>& worker) {
|
||||
auto proc_table = std::make_unique<impeller::ProcTableGLES>(
|
||||
impeller::egl::CreateProcAddressResolver());
|
||||
|
||||
if (!proc_table->IsValid()) {
|
||||
FML_LOG(ERROR) << "Could not create OpenGL proc table.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
|
||||
std::make_shared<fml::NonOwnedMapping>(
|
||||
impeller_entity_shaders_gles_data,
|
||||
impeller_entity_shaders_gles_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(
|
||||
impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length),
|
||||
};
|
||||
|
||||
auto context =
|
||||
impeller::ContextGLES::Create(std::move(proc_table), shader_mappings);
|
||||
if (!context) {
|
||||
FML_LOG(ERROR) << "Could not create OpenGLES Impeller Context.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!context->AddReactorWorker(worker).has_value()) {
|
||||
FML_LOG(ERROR) << "Could not add reactor worker.";
|
||||
return nullptr;
|
||||
}
|
||||
FML_LOG(ERROR) << "Using the Impeller rendering backend.";
|
||||
return context;
|
||||
}
|
||||
|
||||
AndroidSurfaceGLImpeller::AndroidSurfaceGLImpeller(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
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())),
|
||||
display_(std::move(display)) {
|
||||
if (!display_->IsValid()) {
|
||||
FML_DLOG(ERROR) << "Could not create surface with invalid Display.";
|
||||
return;
|
||||
}
|
||||
const std::shared_ptr<AndroidContextGLImpeller>& android_context)
|
||||
: android_context_(android_context) {
|
||||
offscreen_surface_ = android_context_->CreateOffscreenSurface();
|
||||
|
||||
impeller::egl::ConfigDescriptor desc;
|
||||
desc.api = impeller::egl::API::kOpenGLES2;
|
||||
desc.color_format = impeller::egl::ColorFormat::kRGBA8888;
|
||||
desc.depth_bits = impeller::egl::DepthBits::kZero;
|
||||
desc.stencil_bits = impeller::egl::StencilBits::kEight;
|
||||
desc.samples = impeller::egl::Samples::kFour;
|
||||
|
||||
desc.surface_type = impeller::egl::SurfaceType::kWindow;
|
||||
std::unique_ptr<impeller::egl::Config> onscreen_config =
|
||||
display_->ChooseConfig(desc);
|
||||
if (!onscreen_config) {
|
||||
// Fallback for Android emulator.
|
||||
desc.samples = impeller::egl::Samples::kOne;
|
||||
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.";
|
||||
} else {
|
||||
FML_DLOG(ERROR) << "Could not choose onscreen config.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
desc.surface_type = impeller::egl::SurfaceType::kPBuffer;
|
||||
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);
|
||||
if (!onscreen_context) {
|
||||
FML_DLOG(ERROR) << "Could not create onscreen context.";
|
||||
return;
|
||||
}
|
||||
|
||||
auto offscreen_context =
|
||||
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);
|
||||
if (!offscreen_surface) {
|
||||
if (!offscreen_surface_) {
|
||||
FML_DLOG(ERROR) << "Could not create offscreen surface.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!offscreen_context->MakeCurrent(*offscreen_surface)) {
|
||||
FML_DLOG(ERROR) << "Could not make offscreen context current.";
|
||||
return;
|
||||
}
|
||||
|
||||
auto impeller_context = CreateImpellerContext(reactor_worker_);
|
||||
|
||||
if (!impeller_context) {
|
||||
FML_DLOG(ERROR) << "Could not create Impeller context.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!offscreen_context->ClearCurrent()) {
|
||||
FML_DLOG(ERROR) << "Could not clear offscreen context.";
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup context listeners.
|
||||
impeller::egl::Context::LifecycleListener listener =
|
||||
[worker =
|
||||
reactor_worker_](impeller::egl ::Context::LifecycleEvent event) {
|
||||
switch (event) {
|
||||
case impeller::egl::Context::LifecycleEvent::kDidMakeCurrent:
|
||||
worker->SetReactionsAllowedOnCurrentThread(true);
|
||||
break;
|
||||
case impeller::egl::Context::LifecycleEvent::kWillClearCurrent:
|
||||
worker->SetReactionsAllowedOnCurrentThread(false);
|
||||
break;
|
||||
}
|
||||
};
|
||||
if (!onscreen_context->AddLifecycleListener(listener).has_value() ||
|
||||
!offscreen_context->AddLifecycleListener(listener).has_value()) {
|
||||
FML_DLOG(ERROR) << "Could not add lifecycle listeners";
|
||||
}
|
||||
|
||||
onscreen_config_ = std::move(onscreen_config);
|
||||
offscreen_config_ = std::move(offscreen_config);
|
||||
offscreen_surface_ = std::move(offscreen_surface);
|
||||
onscreen_context_ = std::move(onscreen_context);
|
||||
offscreen_context_ = std::move(offscreen_context);
|
||||
impeller_context_ = std::move(impeller_context);
|
||||
|
||||
// The onscreen surface will be acquired once the native window is set.
|
||||
|
||||
is_valid_ = true;
|
||||
@@ -198,10 +35,10 @@ bool AndroidSurfaceGLImpeller::IsValid() const {
|
||||
// |AndroidSurface|
|
||||
std::unique_ptr<Surface> AndroidSurfaceGLImpeller::CreateGPUSurface(
|
||||
GrDirectContext* gr_context) {
|
||||
auto surface =
|
||||
std::make_unique<GPUSurfaceGLImpeller>(this, // delegate
|
||||
impeller_context_ // context
|
||||
);
|
||||
auto surface = std::make_unique<GPUSurfaceGLImpeller>(
|
||||
this, // delegate
|
||||
android_context_->GetImpellerContext() // context
|
||||
);
|
||||
if (!surface->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -223,20 +60,15 @@ bool AndroidSurfaceGLImpeller::OnScreenSurfaceResize(const SkISize& size) {
|
||||
|
||||
// |AndroidSurface|
|
||||
bool AndroidSurfaceGLImpeller::ResourceContextMakeCurrent() {
|
||||
if (!offscreen_context_ || !offscreen_surface_) {
|
||||
if (!offscreen_surface_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return offscreen_context_->MakeCurrent(*offscreen_surface_);
|
||||
return android_context_->ResourceContextMakeCurrent(offscreen_surface_.get());
|
||||
}
|
||||
|
||||
// |AndroidSurface|
|
||||
bool AndroidSurfaceGLImpeller::ResourceContextClearCurrent() {
|
||||
if (!offscreen_context_ || !offscreen_surface_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return offscreen_context_->ClearCurrent();
|
||||
return android_context_->ResourceContextClearCurrent();
|
||||
}
|
||||
|
||||
// |AndroidSurface|
|
||||
@@ -254,7 +86,7 @@ std::unique_ptr<Surface> AndroidSurfaceGLImpeller::CreateSnapshotSurface() {
|
||||
// |AndroidSurface|
|
||||
std::shared_ptr<impeller::Context>
|
||||
AndroidSurfaceGLImpeller::GetImpellerContext() {
|
||||
return impeller_context_;
|
||||
return android_context_->GetImpellerContext();
|
||||
}
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
@@ -264,20 +96,20 @@ AndroidSurfaceGLImpeller::GLContextMakeCurrent() {
|
||||
}
|
||||
|
||||
bool AndroidSurfaceGLImpeller::OnGLContextMakeCurrent() {
|
||||
if (!onscreen_surface_ || !onscreen_context_) {
|
||||
if (!onscreen_surface_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return onscreen_context_->MakeCurrent(*onscreen_surface_);
|
||||
return android_context_->OnscreenContextMakeCurrent(onscreen_surface_.get());
|
||||
}
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
bool AndroidSurfaceGLImpeller::GLContextClearCurrent() {
|
||||
if (!onscreen_surface_ || !onscreen_context_) {
|
||||
if (!onscreen_surface_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return onscreen_context_->ClearCurrent();
|
||||
return android_context_->OnscreenContextClearCurrent();
|
||||
}
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
@@ -326,8 +158,8 @@ bool AndroidSurfaceGLImpeller::
|
||||
return false;
|
||||
}
|
||||
onscreen_surface_.reset();
|
||||
auto onscreen_surface = display_->CreateWindowSurface(
|
||||
*onscreen_config_, native_window_->handle());
|
||||
auto onscreen_surface =
|
||||
android_context_->CreateOnscreenSurface(native_window_->handle());
|
||||
if (!onscreen_surface) {
|
||||
FML_DLOG(ERROR) << "Could not create onscreen surface.";
|
||||
return false;
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/impeller/renderer/context.h"
|
||||
#include "flutter/impeller/toolkit/egl/display.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
|
||||
#include "flutter/shell/platform/android/android_context_gl_impeller.h"
|
||||
#include "flutter/shell/platform/android/surface/android_native_window.h"
|
||||
#include "flutter/shell/platform/android/surface/android_surface.h"
|
||||
|
||||
@@ -17,10 +17,8 @@ namespace flutter {
|
||||
class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate,
|
||||
public AndroidSurface {
|
||||
public:
|
||||
AndroidSurfaceGLImpeller(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
|
||||
std::unique_ptr<impeller::egl::Display> display);
|
||||
explicit AndroidSurfaceGLImpeller(
|
||||
const std::shared_ptr<AndroidContextGLImpeller>& android_context);
|
||||
|
||||
// |AndroidSurface|
|
||||
~AndroidSurfaceGLImpeller() override;
|
||||
@@ -75,17 +73,9 @@ class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate,
|
||||
sk_sp<const GrGLInterface> GetGLInterface() const override;
|
||||
|
||||
private:
|
||||
class ReactorWorker;
|
||||
|
||||
std::shared_ptr<ReactorWorker> reactor_worker_;
|
||||
std::unique_ptr<impeller::egl::Display> display_;
|
||||
std::unique_ptr<impeller::egl::Config> onscreen_config_;
|
||||
std::unique_ptr<impeller::egl::Config> offscreen_config_;
|
||||
std::shared_ptr<AndroidContextGLImpeller> android_context_;
|
||||
std::unique_ptr<impeller::egl::Surface> onscreen_surface_;
|
||||
std::unique_ptr<impeller::egl::Surface> offscreen_surface_;
|
||||
std::unique_ptr<impeller::egl::Context> onscreen_context_;
|
||||
std::unique_ptr<impeller::egl::Context> offscreen_context_;
|
||||
std::shared_ptr<impeller::Context> impeller_context_;
|
||||
fml::RefPtr<AndroidNativeWindow> native_window_;
|
||||
|
||||
bool is_valid_ = false;
|
||||
|
||||
@@ -21,14 +21,13 @@ constexpr char kEmulatorRendererPrefix[] =
|
||||
} // anonymous namespace
|
||||
|
||||
AndroidSurfaceGLSkia::AndroidSurfaceGLSkia(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade)
|
||||
: AndroidSurface(android_context),
|
||||
const std::shared_ptr<AndroidContextGLSkia>& android_context)
|
||||
: android_context_(android_context),
|
||||
native_window_(nullptr),
|
||||
onscreen_surface_(nullptr),
|
||||
offscreen_surface_(nullptr) {
|
||||
// Acquire the offscreen surface.
|
||||
offscreen_surface_ = GLContextPtr()->CreateOffscreenSurface();
|
||||
offscreen_surface_ = android_context_->CreateOffscreenSurface();
|
||||
if (!offscreen_surface_->IsValid()) {
|
||||
offscreen_surface_ = nullptr;
|
||||
}
|
||||
@@ -40,12 +39,12 @@ void AndroidSurfaceGLSkia::TeardownOnScreenContext() {
|
||||
// When the onscreen surface is destroyed, the context and the surface
|
||||
// instance should be deleted. Issue:
|
||||
// https://github.com/flutter/flutter/issues/64414
|
||||
GLContextPtr()->ClearCurrent();
|
||||
android_context_->ClearCurrent();
|
||||
onscreen_surface_ = nullptr;
|
||||
}
|
||||
|
||||
bool AndroidSurfaceGLSkia::IsValid() const {
|
||||
return offscreen_surface_ && GLContextPtr()->IsValid();
|
||||
return offscreen_surface_ && android_context_->IsValid();
|
||||
}
|
||||
|
||||
std::unique_ptr<Surface> AndroidSurfaceGLSkia::CreateGPUSurface(
|
||||
@@ -55,10 +54,10 @@ std::unique_ptr<Surface> AndroidSurfaceGLSkia::CreateGPUSurface(
|
||||
true);
|
||||
} else {
|
||||
sk_sp<GrDirectContext> main_skia_context =
|
||||
GLContextPtr()->GetMainSkiaContext();
|
||||
android_context_->GetMainSkiaContext();
|
||||
if (!main_skia_context) {
|
||||
main_skia_context = GPUSurfaceGLSkia::MakeGLContext(this);
|
||||
GLContextPtr()->SetMainSkiaContext(main_skia_context);
|
||||
android_context_->SetMainSkiaContext(main_skia_context);
|
||||
}
|
||||
return std::make_unique<GPUSurfaceGLSkia>(main_skia_context, this, true);
|
||||
}
|
||||
@@ -73,12 +72,12 @@ bool AndroidSurfaceGLSkia::OnScreenSurfaceResize(const SkISize& size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
GLContextPtr()->ClearCurrent();
|
||||
android_context_->ClearCurrent();
|
||||
|
||||
// Ensure the destructor is called since it destroys the `EGLSurface` before
|
||||
// creating a new onscreen surface.
|
||||
onscreen_surface_ = nullptr;
|
||||
onscreen_surface_ = GLContextPtr()->CreateOnscreenSurface(native_window_);
|
||||
onscreen_surface_ = android_context_->CreateOnscreenSurface(native_window_);
|
||||
if (!onscreen_surface_->IsValid()) {
|
||||
FML_LOG(ERROR) << "Unable to create EGL window surface on resize.";
|
||||
return false;
|
||||
@@ -109,7 +108,7 @@ bool AndroidSurfaceGLSkia::SetNativeWindow(
|
||||
// creating a new onscreen surface.
|
||||
onscreen_surface_ = nullptr;
|
||||
// Create the onscreen surface.
|
||||
onscreen_surface_ = GLContextPtr()->CreateOnscreenSurface(window);
|
||||
onscreen_surface_ = android_context_->CreateOnscreenSurface(window);
|
||||
if (!onscreen_surface_->IsValid()) {
|
||||
return false;
|
||||
}
|
||||
@@ -127,7 +126,7 @@ std::unique_ptr<GLContextResult> AndroidSurfaceGLSkia::GLContextMakeCurrent() {
|
||||
|
||||
bool AndroidSurfaceGLSkia::GLContextClearCurrent() {
|
||||
FML_DCHECK(IsValid());
|
||||
return GLContextPtr()->ClearCurrent();
|
||||
return android_context_->ClearCurrent();
|
||||
}
|
||||
|
||||
SurfaceFrame::FramebufferInfo AndroidSurfaceGLSkia::GLContextFramebufferInfo()
|
||||
@@ -186,7 +185,7 @@ sk_sp<const GrGLInterface> AndroidSurfaceGLSkia::GetGLInterface() const {
|
||||
reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
if (gl_renderer && strncmp(gl_renderer, kEmulatorRendererPrefix,
|
||||
strlen(kEmulatorRendererPrefix)) == 0) {
|
||||
EGLContext new_context = GLContextPtr()->CreateNewContext();
|
||||
EGLContext new_context = android_context_->CreateNewContext();
|
||||
if (new_context != EGL_NO_CONTEXT) {
|
||||
EGLContext old_context = eglGetCurrentContext();
|
||||
EGLDisplay display = eglGetCurrentDisplay();
|
||||
@@ -205,19 +204,15 @@ sk_sp<const GrGLInterface> AndroidSurfaceGLSkia::GetGLInterface() const {
|
||||
return GPUSurfaceGLDelegate::GetGLInterface();
|
||||
}
|
||||
|
||||
AndroidContextGLSkia* AndroidSurfaceGLSkia::GLContextPtr() const {
|
||||
return reinterpret_cast<AndroidContextGLSkia*>(android_context_.get());
|
||||
}
|
||||
|
||||
std::unique_ptr<Surface> AndroidSurfaceGLSkia::CreateSnapshotSurface() {
|
||||
if (!onscreen_surface_ || !onscreen_surface_->IsValid()) {
|
||||
onscreen_surface_ = GLContextPtr()->CreatePbufferSurface();
|
||||
onscreen_surface_ = android_context_->CreatePbufferSurface();
|
||||
}
|
||||
sk_sp<GrDirectContext> main_skia_context =
|
||||
GLContextPtr()->GetMainSkiaContext();
|
||||
android_context_->GetMainSkiaContext();
|
||||
if (!main_skia_context) {
|
||||
main_skia_context = GPUSurfaceGLSkia::MakeGLContext(this);
|
||||
GLContextPtr()->SetMainSkiaContext(main_skia_context);
|
||||
android_context_->SetMainSkiaContext(main_skia_context);
|
||||
}
|
||||
|
||||
return std::make_unique<GPUSurfaceGLSkia>(main_skia_context, this, true);
|
||||
|
||||
@@ -21,9 +21,8 @@ namespace flutter {
|
||||
class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate,
|
||||
public AndroidSurface {
|
||||
public:
|
||||
AndroidSurfaceGLSkia(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade);
|
||||
explicit AndroidSurfaceGLSkia(
|
||||
const std::shared_ptr<AndroidContextGLSkia>& android_context);
|
||||
|
||||
~AndroidSurfaceGLSkia() override;
|
||||
|
||||
@@ -82,16 +81,11 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate,
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<AndroidContextGLSkia> android_context_;
|
||||
fml::RefPtr<AndroidNativeWindow> native_window_;
|
||||
std::unique_ptr<AndroidEGLSurface> onscreen_surface_;
|
||||
std::unique_ptr<AndroidEGLSurface> offscreen_surface_;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Takes the super class AndroidSurface's AndroidContext and
|
||||
/// return a raw pointer to an AndroidContextGL.
|
||||
///
|
||||
AndroidContextGLSkia* GLContextPtr() const;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceGLSkia);
|
||||
};
|
||||
|
||||
|
||||
@@ -40,10 +40,7 @@ bool GetSkColorType(int32_t buffer_format,
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
AndroidSurfaceSoftware::AndroidSurfaceSoftware(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade)
|
||||
: AndroidSurface(android_context) {
|
||||
AndroidSurfaceSoftware::AndroidSurfaceSoftware() {
|
||||
GetSkColorType(WINDOW_FORMAT_RGBA_8888, &target_color_type_,
|
||||
&target_alpha_type_);
|
||||
}
|
||||
|
||||
@@ -19,9 +19,7 @@ namespace flutter {
|
||||
class AndroidSurfaceSoftware final : public AndroidSurface,
|
||||
public GPUSurfaceSoftwareDelegate {
|
||||
public:
|
||||
AndroidSurfaceSoftware(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade);
|
||||
AndroidSurfaceSoftware();
|
||||
|
||||
~AndroidSurfaceSoftware() override;
|
||||
|
||||
|
||||
@@ -10,52 +10,16 @@
|
||||
#include "flutter/fml/concurrent_message_loop.h"
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "flutter/fml/memory/ref_ptr.h"
|
||||
#include "flutter/fml/paths.h"
|
||||
#include "flutter/impeller/renderer/backend/vulkan/context_vk.h"
|
||||
#include "flutter/shell/gpu/gpu_surface_vulkan_impeller.h"
|
||||
#include "flutter/vulkan/vulkan_native_surface_android.h"
|
||||
#include "impeller/entity/vk/entity_shaders_vk.h"
|
||||
#include "impeller/entity/vk/modern_shaders_vk.h"
|
||||
#include "impeller/scene/shaders/vk/scene_shaders_vk.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
static std::shared_ptr<impeller::Context> CreateImpellerContext(
|
||||
const fml::RefPtr<vulkan::VulkanProcTable>& proc_table,
|
||||
const std::shared_ptr<fml::ConcurrentMessageLoop>& concurrent_loop,
|
||||
bool enable_vulkan_validation) {
|
||||
std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data,
|
||||
impeller_entity_shaders_vk_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_vk_data,
|
||||
impeller_scene_shaders_vk_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_vk_data,
|
||||
impeller_modern_shaders_vk_length),
|
||||
};
|
||||
|
||||
PFN_vkGetInstanceProcAddr instance_proc_addr =
|
||||
proc_table->NativeGetInstanceProcAddr();
|
||||
|
||||
impeller::ContextVK::Settings settings;
|
||||
settings.proc_address_callback = instance_proc_addr;
|
||||
settings.shader_libraries_data = std::move(shader_mappings);
|
||||
settings.cache_directory = fml::paths::GetCachesDirectory();
|
||||
settings.worker_task_runner = concurrent_loop->GetTaskRunner();
|
||||
settings.enable_validation = enable_vulkan_validation;
|
||||
return impeller::ContextVK::Create(std::move(settings));
|
||||
}
|
||||
|
||||
AndroidSurfaceVulkanImpeller::AndroidSurfaceVulkanImpeller(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
|
||||
bool enable_vulkan_validation)
|
||||
: AndroidSurface(android_context),
|
||||
proc_table_(fml::MakeRefCounted<vulkan::VulkanProcTable>()),
|
||||
workers_(fml::ConcurrentMessageLoop::Create()) {
|
||||
impeller_context_ =
|
||||
CreateImpellerContext(proc_table_, workers_, enable_vulkan_validation);
|
||||
is_valid_ =
|
||||
proc_table_->HasAcquiredMandatoryProcAddresses() && impeller_context_;
|
||||
const std::shared_ptr<AndroidContextVulkanImpeller>& android_context)
|
||||
: android_context_(android_context) {
|
||||
is_valid_ = android_context_->IsValid();
|
||||
}
|
||||
|
||||
AndroidSurfaceVulkanImpeller::~AndroidSurfaceVulkanImpeller() = default;
|
||||
@@ -79,7 +43,8 @@ std::unique_ptr<Surface> AndroidSurfaceVulkanImpeller::CreateGPUSurface(
|
||||
}
|
||||
|
||||
std::unique_ptr<GPUSurfaceVulkanImpeller> gpu_surface =
|
||||
std::make_unique<GPUSurfaceVulkanImpeller>(impeller_context_);
|
||||
std::make_unique<GPUSurfaceVulkanImpeller>(
|
||||
android_context_->GetImpellerContext());
|
||||
|
||||
if (!gpu_surface->IsValid()) {
|
||||
return nullptr;
|
||||
@@ -105,7 +70,8 @@ bool AndroidSurfaceVulkanImpeller::SetNativeWindow(
|
||||
native_window_ = std::move(window);
|
||||
bool success = native_window_ && native_window_->IsValid();
|
||||
if (success) {
|
||||
auto& context_vk = impeller::ContextVK::Cast(*impeller_context_);
|
||||
auto& context_vk =
|
||||
impeller::ContextVK::Cast(*android_context_->GetImpellerContext());
|
||||
auto surface = context_vk.CreateAndroidSurface(native_window_->handle());
|
||||
|
||||
if (!surface) {
|
||||
@@ -122,7 +88,7 @@ bool AndroidSurfaceVulkanImpeller::SetNativeWindow(
|
||||
|
||||
std::shared_ptr<impeller::Context>
|
||||
AndroidSurfaceVulkanImpeller::GetImpellerContext() {
|
||||
return impeller_context_;
|
||||
return android_context_->GetImpellerContext();
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@@ -7,18 +7,16 @@
|
||||
#include "flutter/fml/concurrent_message_loop.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/impeller/renderer/context.h"
|
||||
#include "flutter/shell/platform/android/android_context_vulkan_impeller.h"
|
||||
#include "flutter/shell/platform/android/surface/android_native_window.h"
|
||||
#include "flutter/shell/platform/android/surface/android_surface.h"
|
||||
#include "flutter/vulkan/procs/vulkan_proc_table.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
class AndroidSurfaceVulkanImpeller : public AndroidSurface {
|
||||
public:
|
||||
AndroidSurfaceVulkanImpeller(
|
||||
const std::shared_ptr<AndroidContext>& android_context,
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
|
||||
bool enable_vulkan_validation);
|
||||
explicit AndroidSurfaceVulkanImpeller(
|
||||
const std::shared_ptr<AndroidContextVulkanImpeller>& android_context);
|
||||
|
||||
~AndroidSurfaceVulkanImpeller() override;
|
||||
|
||||
@@ -48,10 +46,8 @@ class AndroidSurfaceVulkanImpeller : public AndroidSurface {
|
||||
bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) override;
|
||||
|
||||
private:
|
||||
fml::RefPtr<vulkan::VulkanProcTable> proc_table_;
|
||||
std::shared_ptr<AndroidContextVulkanImpeller> android_context_;
|
||||
fml::RefPtr<AndroidNativeWindow> native_window_;
|
||||
std::shared_ptr<fml::ConcurrentMessageLoop> workers_;
|
||||
std::shared_ptr<impeller::Context> impeller_context_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceVulkanImpeller);
|
||||
|
||||
@@ -15,6 +15,7 @@ source_set("context") {
|
||||
|
||||
deps = [
|
||||
"//flutter/fml",
|
||||
"//flutter/impeller/renderer",
|
||||
"//third_party/skia",
|
||||
]
|
||||
|
||||
|
||||
@@ -32,4 +32,13 @@ sk_sp<GrDirectContext> AndroidContext::GetMainSkiaContext() const {
|
||||
return main_context_;
|
||||
}
|
||||
|
||||
std::shared_ptr<impeller::Context> AndroidContext::GetImpellerContext() const {
|
||||
return impeller_context_;
|
||||
}
|
||||
|
||||
void AndroidContext::SetImpellerContext(
|
||||
const std::shared_ptr<impeller::Context>& context) {
|
||||
impeller_context_ = context;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "flutter/fml/task_runner.h"
|
||||
#include "flutter/impeller/renderer/context.h"
|
||||
#include "third_party/skia/include/gpu/GrDirectContext.h"
|
||||
|
||||
namespace flutter {
|
||||
@@ -14,6 +15,7 @@ namespace flutter {
|
||||
enum class AndroidRenderingAPI {
|
||||
kSoftware,
|
||||
kOpenGLES,
|
||||
kVulkan,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -54,12 +56,25 @@ class AndroidContext {
|
||||
///
|
||||
sk_sp<GrDirectContext> GetMainSkiaContext() const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Accessor for the Impeller context associated with
|
||||
/// AndroidSurfaces and the raster thread.
|
||||
///
|
||||
std::shared_ptr<impeller::Context> GetImpellerContext() const;
|
||||
|
||||
protected:
|
||||
/// Intended to be called from a subclass constructor after setup work for the
|
||||
/// context has completed.
|
||||
void SetImpellerContext(const std::shared_ptr<impeller::Context>& context);
|
||||
|
||||
private:
|
||||
const AndroidRenderingAPI rendering_api_;
|
||||
|
||||
// This is the Skia context used for on-screen rendering.
|
||||
sk_sp<GrDirectContext> main_context_;
|
||||
|
||||
std::shared_ptr<impeller::Context> impeller_context_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(AndroidContext);
|
||||
};
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) {
|
||||
auto frame_size = SkISize::Make(1000, 1000);
|
||||
SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window, frame_size, framebuffer_info]() {
|
||||
[gr_context, window, frame_size, framebuffer_info]() {
|
||||
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
|
||||
SkSurface::MakeNull(1000, 1000), framebuffer_info,
|
||||
[](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
|
||||
@@ -284,8 +284,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) {
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_1))))
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_2))));
|
||||
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
|
||||
@@ -472,7 +471,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) {
|
||||
auto frame_size = SkISize::Make(1000, 1000);
|
||||
SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window, frame_size, framebuffer_info]() {
|
||||
[gr_context, window, frame_size, framebuffer_info]() {
|
||||
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
|
||||
SkSurface::MakeNull(1000, 1000), framebuffer_info,
|
||||
[](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
|
||||
@@ -485,8 +484,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) {
|
||||
.Times(1 /* frames */)
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_1))));
|
||||
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
|
||||
@@ -571,7 +569,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) {
|
||||
auto frame_size = SkISize::Make(1000, 1000);
|
||||
SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window, frame_size, framebuffer_info]() {
|
||||
[gr_context, window, frame_size, framebuffer_info]() {
|
||||
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
|
||||
SkSurface::MakeNull(1000, 1000), framebuffer_info,
|
||||
[](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
|
||||
@@ -584,8 +582,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) {
|
||||
.Times(1 /* frames */)
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_1))));
|
||||
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
|
||||
@@ -675,7 +672,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) {
|
||||
auto frame_size = SkISize::Make(1000, 1000);
|
||||
SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window, frame_size, framebuffer_info]() {
|
||||
[gr_context, window, frame_size, framebuffer_info]() {
|
||||
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
|
||||
SkSurface::MakeNull(1000, 1000), framebuffer_info,
|
||||
[](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
|
||||
@@ -688,8 +685,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) {
|
||||
.Times(1 /* frames */)
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_1))));
|
||||
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
|
||||
@@ -764,7 +760,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) {
|
||||
auto frame_size = SkISize::Make(1000, 1000);
|
||||
SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window, frame_size, framebuffer_info]() {
|
||||
[gr_context, window, frame_size, framebuffer_info]() {
|
||||
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
|
||||
SkSurface::MakeNull(1000, 1000), framebuffer_info,
|
||||
[](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
|
||||
@@ -776,8 +772,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) {
|
||||
EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_1))));
|
||||
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
|
||||
@@ -853,7 +848,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) {
|
||||
auto frame_size = SkISize::Make(1000, 1000);
|
||||
SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window, frame_size, framebuffer_info]() {
|
||||
[gr_context, window, frame_size, framebuffer_info]() {
|
||||
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
|
||||
SkSurface::MakeNull(1000, 1000), framebuffer_info,
|
||||
[](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
|
||||
@@ -865,8 +860,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) {
|
||||
EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_1))));
|
||||
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
|
||||
@@ -978,7 +972,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) {
|
||||
auto gr_context = GrDirectContext::MakeMock(nullptr);
|
||||
auto frame_size = SkISize::Make(1000, 1000);
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window, frame_size]() {
|
||||
[gr_context, window, frame_size]() {
|
||||
SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
auto surface_frame_1 = std::make_unique<SurfaceFrame>(
|
||||
SkSurface::MakeNull(1000, 1000), framebuffer_info,
|
||||
@@ -991,8 +985,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) {
|
||||
EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame_1))));
|
||||
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
|
||||
.WillOnce(Return(ByMove(std::move(surface_mock))));
|
||||
|
||||
@@ -50,10 +50,9 @@ TEST(SurfacePool, GetLayerAllocateOneLayer) {
|
||||
ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
|
||||
0, window))));
|
||||
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window]() {
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto surface_factory =
|
||||
std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
|
||||
EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
@@ -82,10 +81,9 @@ TEST(SurfacePool, GetUnusedLayers) {
|
||||
ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
|
||||
0, window))));
|
||||
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window]() {
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto surface_factory =
|
||||
std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
|
||||
EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
@@ -118,9 +116,8 @@ TEST(SurfacePool, GetLayerRecycle) {
|
||||
|
||||
auto gr_context_2 = GrDirectContext::MakeMock(nullptr);
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context_1, gr_context_2, window]() {
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
[gr_context_1, gr_context_2, window]() {
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
// Allocate two GPU surfaces for each gr context.
|
||||
EXPECT_CALL(*android_surface_mock,
|
||||
CreateGPUSurface(gr_context_1.get()));
|
||||
@@ -166,10 +163,9 @@ TEST(SurfacePool, GetLayerAllocateTwoLayers) {
|
||||
ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
|
||||
1, window))));
|
||||
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window]() {
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto surface_factory =
|
||||
std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
|
||||
EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
@@ -206,10 +202,9 @@ TEST(SurfacePool, DestroyLayers) {
|
||||
ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
|
||||
0, window))));
|
||||
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window]() {
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto surface_factory =
|
||||
std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
|
||||
EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
@@ -236,10 +231,9 @@ TEST(SurfacePool, DestroyLayersFrameSizeChanged) {
|
||||
|
||||
auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
|
||||
|
||||
auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
|
||||
[&android_context, gr_context, window]() {
|
||||
auto android_surface_mock =
|
||||
std::make_unique<AndroidSurfaceMock>(android_context);
|
||||
auto surface_factory =
|
||||
std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
|
||||
auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
|
||||
EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
|
||||
EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
|
||||
EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
|
||||
|
||||
@@ -31,37 +31,29 @@ namespace flutter {
|
||||
|
||||
AndroidSurfaceFactoryImpl::AndroidSurfaceFactoryImpl(
|
||||
const std::shared_ptr<AndroidContext>& context,
|
||||
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
|
||||
bool enable_impeller,
|
||||
bool enable_vulkan_validation)
|
||||
: android_context_(context),
|
||||
jni_facade_(std::move(jni_facade)),
|
||||
enable_impeller_(enable_impeller),
|
||||
enable_vulkan_validation_(enable_vulkan_validation) {}
|
||||
bool enable_impeller)
|
||||
: android_context_(context), enable_impeller_(enable_impeller) {}
|
||||
|
||||
AndroidSurfaceFactoryImpl::~AndroidSurfaceFactoryImpl() = default;
|
||||
|
||||
std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
|
||||
switch (android_context_->RenderingApi()) {
|
||||
case AndroidRenderingAPI::kSoftware:
|
||||
return std::make_unique<AndroidSurfaceSoftware>(android_context_,
|
||||
jni_facade_);
|
||||
return std::make_unique<AndroidSurfaceSoftware>();
|
||||
case AndroidRenderingAPI::kOpenGLES:
|
||||
if (enable_impeller_) {
|
||||
// TODO(kaushikiska@): Enable this after wiring a preference for Vulkan backend.
|
||||
#if false
|
||||
return std::make_unique<AndroidSurfaceVulkanImpeller>(
|
||||
android_context_, jni_facade_, enable_vulkan_validation_);
|
||||
|
||||
#else
|
||||
return std::make_unique<AndroidSurfaceGLImpeller>(
|
||||
android_context_, jni_facade_,
|
||||
std::make_unique<impeller::egl::Display>());
|
||||
#endif
|
||||
std::static_pointer_cast<AndroidContextGLImpeller>(
|
||||
android_context_));
|
||||
} else {
|
||||
return std::make_unique<AndroidSurfaceGLSkia>(android_context_,
|
||||
jni_facade_);
|
||||
return std::make_unique<AndroidSurfaceGLSkia>(
|
||||
std::static_pointer_cast<AndroidContextGLSkia>(android_context_));
|
||||
}
|
||||
case AndroidRenderingAPI::kVulkan:
|
||||
FML_DCHECK(enable_impeller_);
|
||||
return std::make_unique<AndroidSurfaceVulkanImpeller>(
|
||||
std::static_pointer_cast<AndroidContextVulkanImpeller>(
|
||||
android_context_));
|
||||
default:
|
||||
FML_DCHECK(false);
|
||||
return nullptr;
|
||||
@@ -72,12 +64,20 @@ static std::shared_ptr<flutter::AndroidContext> CreateAndroidContext(
|
||||
bool use_software_rendering,
|
||||
const flutter::TaskRunners& task_runners,
|
||||
uint8_t msaa_samples,
|
||||
bool enable_impeller) {
|
||||
bool enable_impeller,
|
||||
bool enable_vulkan_validation) {
|
||||
if (use_software_rendering) {
|
||||
return std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
|
||||
}
|
||||
if (enable_impeller) {
|
||||
return std::make_unique<AndroidContextGLImpeller>();
|
||||
// TODO(kaushikiska@): Enable this after wiring a preference for Vulkan
|
||||
// backend.
|
||||
#if false
|
||||
return std::make_unique<AndroidContextVulkanImpeller>(enable_vulkan_validation);
|
||||
#else
|
||||
return std::make_unique<AndroidContextGLImpeller>(
|
||||
std::make_unique<impeller::egl::Display>());
|
||||
#endif
|
||||
}
|
||||
return std::make_unique<AndroidContextGLSkia>(
|
||||
AndroidRenderingAPI::kOpenGLES, //
|
||||
@@ -101,7 +101,8 @@ PlatformViewAndroid::PlatformViewAndroid(
|
||||
use_software_rendering,
|
||||
task_runners,
|
||||
msaa_samples,
|
||||
delegate.OnPlatformViewGetSettings().enable_impeller)) {}
|
||||
delegate.OnPlatformViewGetSettings().enable_impeller,
|
||||
delegate.OnPlatformViewGetSettings().enable_vulkan_validation)) {}
|
||||
|
||||
PlatformViewAndroid::PlatformViewAndroid(
|
||||
PlatformView::Delegate& delegate,
|
||||
@@ -117,10 +118,8 @@ PlatformViewAndroid::PlatformViewAndroid(
|
||||
FML_CHECK(android_context_->IsValid())
|
||||
<< "Could not create surface from invalid Android context.";
|
||||
surface_factory_ = std::make_shared<AndroidSurfaceFactoryImpl>(
|
||||
android_context_, //
|
||||
jni_facade_, //
|
||||
delegate.OnPlatformViewGetSettings().enable_impeller, //
|
||||
delegate.OnPlatformViewGetSettings().enable_vulkan_validation //
|
||||
android_context_, //
|
||||
delegate.OnPlatformViewGetSettings().enable_impeller //
|
||||
);
|
||||
android_surface_ = surface_factory_->CreateSurface();
|
||||
FML_CHECK(android_surface_ && android_surface_->IsValid())
|
||||
|
||||
@@ -27,9 +27,7 @@ namespace flutter {
|
||||
class AndroidSurfaceFactoryImpl : public AndroidSurfaceFactory {
|
||||
public:
|
||||
AndroidSurfaceFactoryImpl(const std::shared_ptr<AndroidContext>& context,
|
||||
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
|
||||
bool enable_impeller,
|
||||
bool enable_vulkan_validation);
|
||||
bool enable_impeller);
|
||||
|
||||
~AndroidSurfaceFactoryImpl() override;
|
||||
|
||||
@@ -37,9 +35,7 @@ class AndroidSurfaceFactoryImpl : public AndroidSurfaceFactory {
|
||||
|
||||
private:
|
||||
const std::shared_ptr<AndroidContext>& android_context_;
|
||||
std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
|
||||
const bool enable_impeller_;
|
||||
const bool enable_vulkan_validation_;
|
||||
};
|
||||
|
||||
class PlatformViewAndroid final : public PlatformView {
|
||||
|
||||
@@ -7,11 +7,7 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
AndroidSurface::AndroidSurface(
|
||||
const std::shared_ptr<AndroidContext>& android_context) {
|
||||
FML_DCHECK(android_context->IsValid());
|
||||
android_context_ = android_context;
|
||||
}
|
||||
AndroidSurface::AndroidSurface() = default;
|
||||
|
||||
AndroidSurface::~AndroidSurface() = default;
|
||||
|
||||
|
||||
@@ -46,9 +46,7 @@ class AndroidSurface {
|
||||
virtual std::shared_ptr<impeller::Context> GetImpellerContext();
|
||||
|
||||
protected:
|
||||
explicit AndroidSurface(
|
||||
const std::shared_ptr<AndroidContext>& android_context);
|
||||
std::shared_ptr<AndroidContext> android_context_;
|
||||
AndroidSurface();
|
||||
};
|
||||
|
||||
class AndroidSurfaceFactory {
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
AndroidSurfaceMock::AndroidSurfaceMock(
|
||||
const std::shared_ptr<AndroidContext>& android_context)
|
||||
: AndroidSurface(android_context) {}
|
||||
|
||||
std::unique_ptr<GLContextResult> AndroidSurfaceMock::GLContextMakeCurrent() {
|
||||
return std::make_unique<GLContextDefaultResult>(/*static_result=*/true);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,6 @@ namespace flutter {
|
||||
class AndroidSurfaceMock final : public GPUSurfaceGLDelegate,
|
||||
public AndroidSurface {
|
||||
public:
|
||||
explicit AndroidSurfaceMock(
|
||||
const std::shared_ptr<AndroidContext>& android_context);
|
||||
|
||||
MOCK_METHOD(bool, IsValid, (), (const, override));
|
||||
|
||||
MOCK_METHOD(void, TeardownOnScreenContext, (), (override));
|
||||
|
||||
Reference in New Issue
Block a user