Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b4e821b

Browse files
committed
make AndroidSurfaceGL share GrDirectContext within an AndroidContext
1 parent baf34fc commit b4e821b

13 files changed

+108
-34
lines changed

shell/platform/android/android_surface_gl.cc

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ constexpr char kEmulatorRendererPrefix[] =
2020
} // anonymous namespace
2121

2222
AndroidSurfaceGL::AndroidSurfaceGL(
23-
const AndroidContext& android_context,
23+
const std::shared_ptr<AndroidContext>& android_context,
2424
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
25-
: android_context_(static_cast<const AndroidContextGL&>(android_context)),
25+
: AndroidSurface(android_context),
2626
native_window_(nullptr),
2727
onscreen_surface_(nullptr),
2828
offscreen_surface_(nullptr) {
2929
// Acquire the offscreen surface.
30-
offscreen_surface_ = android_context_.CreateOffscreenSurface();
30+
offscreen_surface_ = GLContextPtr()->CreateOffscreenSurface();
3131
if (!offscreen_surface_->IsValid()) {
3232
offscreen_surface_ = nullptr;
3333
}
@@ -39,20 +39,27 @@ void AndroidSurfaceGL::TeardownOnScreenContext() {
3939
// When the onscreen surface is destroyed, the context and the surface
4040
// instance should be deleted. Issue:
4141
// https://github.com/flutter/flutter/issues/64414
42-
android_context_.ClearCurrent();
42+
GLContextPtr()->ClearCurrent();
4343
onscreen_surface_ = nullptr;
4444
}
4545

4646
bool AndroidSurfaceGL::IsValid() const {
47-
return offscreen_surface_ && android_context_.IsValid();
47+
return offscreen_surface_ && GLContextPtr()->IsValid();
4848
}
4949

5050
std::unique_ptr<Surface> AndroidSurfaceGL::CreateGPUSurface(
5151
GrDirectContext* gr_context) {
5252
if (gr_context) {
5353
return std::make_unique<GPUSurfaceGL>(sk_ref_sp(gr_context), this, true);
54+
} else {
55+
sk_sp<GrDirectContext> main_skia_context =
56+
GLContextPtr()->GetMainSkiaContext();
57+
if (!main_skia_context) {
58+
main_skia_context = GPUSurfaceGL::MakeGLContext(this);
59+
GLContextPtr()->SetMainSkiaContext(main_skia_context);
60+
}
61+
return std::make_unique<GPUSurfaceGL>(main_skia_context, this, true);
5462
}
55-
return std::make_unique<GPUSurfaceGL>(this, true);
5663
}
5764

5865
bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) {
@@ -64,12 +71,12 @@ bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) {
6471
return true;
6572
}
6673

67-
android_context_.ClearCurrent();
74+
GLContextPtr()->ClearCurrent();
6875

6976
// Ensure the destructor is called since it destroys the `EGLSurface` before
7077
// creating a new onscreen surface.
7178
onscreen_surface_ = nullptr;
72-
onscreen_surface_ = android_context_.CreateOnscreenSurface(native_window_);
79+
onscreen_surface_ = GLContextPtr()->CreateOnscreenSurface(native_window_);
7380
if (!onscreen_surface_->IsValid()) {
7481
FML_LOG(ERROR) << "Unable to create EGL window surface on resize.";
7582
return false;
@@ -85,7 +92,7 @@ bool AndroidSurfaceGL::ResourceContextMakeCurrent() {
8592

8693
bool AndroidSurfaceGL::ResourceContextClearCurrent() {
8794
FML_DCHECK(IsValid());
88-
return android_context_.ClearCurrent();
95+
return GLContextPtr()->ClearCurrent();
8996
}
9097

9198
bool AndroidSurfaceGL::SetNativeWindow(
@@ -97,7 +104,7 @@ bool AndroidSurfaceGL::SetNativeWindow(
97104
// creating a new onscreen surface.
98105
onscreen_surface_ = nullptr;
99106
// Create the onscreen surface.
100-
onscreen_surface_ = android_context_.CreateOnscreenSurface(window);
107+
onscreen_surface_ = GLContextPtr()->CreateOnscreenSurface(window);
101108
if (!onscreen_surface_->IsValid()) {
102109
return false;
103110
}
@@ -114,7 +121,7 @@ std::unique_ptr<GLContextResult> AndroidSurfaceGL::GLContextMakeCurrent() {
114121

115122
bool AndroidSurfaceGL::GLContextClearCurrent() {
116123
FML_DCHECK(IsValid());
117-
return android_context_.ClearCurrent();
124+
return GLContextPtr()->ClearCurrent();
118125
}
119126

120127
bool AndroidSurfaceGL::GLContextPresent(uint32_t fbo_id) {
@@ -143,7 +150,7 @@ sk_sp<const GrGLInterface> AndroidSurfaceGL::GetGLInterface() const {
143150
reinterpret_cast<const char*>(glGetString(GL_RENDERER));
144151
if (gl_renderer && strncmp(gl_renderer, kEmulatorRendererPrefix,
145152
strlen(kEmulatorRendererPrefix)) == 0) {
146-
EGLContext new_context = android_context_.CreateNewContext();
153+
EGLContext new_context = GLContextPtr()->CreateNewContext();
147154
if (new_context != EGL_NO_CONTEXT) {
148155
EGLContext old_context = eglGetCurrentContext();
149156
EGLDisplay display = eglGetCurrentDisplay();
@@ -162,4 +169,8 @@ sk_sp<const GrGLInterface> AndroidSurfaceGL::GetGLInterface() const {
162169
return GPUSurfaceGLDelegate::GetGLInterface();
163170
}
164171

172+
AndroidContextGL* AndroidSurfaceGL::GLContextPtr() const {
173+
return reinterpret_cast<AndroidContextGL*>(android_context_.get());
174+
}
175+
165176
} // namespace flutter

shell/platform/android/android_surface_gl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace flutter {
2121
class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
2222
public AndroidSurface {
2323
public:
24-
AndroidSurfaceGL(const AndroidContext& android_context,
24+
AndroidSurfaceGL(const std::shared_ptr<AndroidContext>& android_context,
2525
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
2626

2727
~AndroidSurfaceGL() override;
@@ -64,12 +64,12 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
6464
sk_sp<const GrGLInterface> GetGLInterface() const override;
6565

6666
private:
67-
const AndroidContextGL& android_context_;
68-
6967
fml::RefPtr<AndroidNativeWindow> native_window_;
7068
std::unique_ptr<AndroidEGLSurface> onscreen_surface_;
7169
std::unique_ptr<AndroidEGLSurface> offscreen_surface_;
7270

71+
AndroidContextGL* GLContextPtr() const;
72+
7373
FML_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceGL);
7474
};
7575

shell/platform/android/android_surface_software.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ bool GetSkColorType(int32_t buffer_format,
3838
} // anonymous namespace
3939

4040
AndroidSurfaceSoftware::AndroidSurfaceSoftware(
41-
const AndroidContext& android_context,
42-
std::shared_ptr<PlatformViewAndroidJNI> jni_facade) {
41+
const std::shared_ptr<AndroidContext>& android_context,
42+
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
43+
: AndroidSurface(android_context) {
4344
GetSkColorType(WINDOW_FORMAT_RGBA_8888, &target_color_type_,
4445
&target_alpha_type_);
4546
}
@@ -60,6 +61,8 @@ bool AndroidSurfaceSoftware::ResourceContextClearCurrent() {
6061
}
6162

6263
std::unique_ptr<Surface> AndroidSurfaceSoftware::CreateGPUSurface(
64+
// The software AndroidSurface neither uses any passed in Skia context
65+
// nor does it interact with the AndroidContext's raster Skia context.
6366
GrDirectContext* gr_context) {
6467
if (!IsValid()) {
6568
return nullptr;

shell/platform/android/android_surface_software.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace flutter {
1717
class AndroidSurfaceSoftware final : public AndroidSurface,
1818
public GPUSurfaceSoftwareDelegate {
1919
public:
20-
AndroidSurfaceSoftware(const AndroidContext& android_context,
20+
AndroidSurfaceSoftware(const std::shared_ptr<AndroidContext>& android_context,
2121
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
2222

2323
~AndroidSurfaceSoftware() override;

shell/platform/android/android_surface_vulkan.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
namespace flutter {
1414

1515
AndroidSurfaceVulkan::AndroidSurfaceVulkan(
16-
const AndroidContext& android_context,
16+
const std::shared_ptr<AndroidContext>& android_context,
1717
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
18-
: proc_table_(fml::MakeRefCounted<vulkan::VulkanProcTable>()) {}
18+
: AndroidSurface(android_context),
19+
proc_table_(fml::MakeRefCounted<vulkan::VulkanProcTable>()) {}
1920

2021
AndroidSurfaceVulkan::~AndroidSurfaceVulkan() = default;
2122

@@ -29,6 +30,8 @@ void AndroidSurfaceVulkan::TeardownOnScreenContext() {
2930

3031
std::unique_ptr<Surface> AndroidSurfaceVulkan::CreateGPUSurface(
3132
GrDirectContext* gr_context) {
33+
// TODO(https://github.com/flutter/flutter/issues/73597): consume this
34+
// Skia context or create a new one for AndroidContext.
3235
if (!IsValid()) {
3336
return nullptr;
3437
}

shell/platform/android/android_surface_vulkan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace flutter {
2020
class AndroidSurfaceVulkan : public AndroidSurface,
2121
public GPUSurfaceVulkanDelegate {
2222
public:
23-
AndroidSurfaceVulkan(const AndroidContext& android_context,
23+
AndroidSurfaceVulkan(const std::shared_ptr<AndroidContext>& android_context,
2424
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
2525

2626
~AndroidSurfaceVulkan() override;

shell/platform/android/context/BUILD.gn

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@ source_set("context") {
1212

1313
public_configs = [ "//flutter:config" ]
1414

15-
deps = [ "//flutter/fml" ]
15+
deps = [
16+
"//flutter/fml",
17+
"//third_party/skia",
18+
]
1619
}

shell/platform/android/context/android_context.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ namespace flutter {
99
AndroidContext::AndroidContext(AndroidRenderingAPI rendering_api)
1010
: rendering_api_(rendering_api) {}
1111

12-
AndroidContext::~AndroidContext() = default;
12+
AndroidContext::~AndroidContext() {
13+
if (main_context_) {
14+
main_context_->releaseResourcesAndAbandonContext();
15+
}
16+
};
1317

1418
AndroidRenderingAPI AndroidContext::RenderingApi() const {
1519
return rendering_api_;
@@ -19,4 +23,13 @@ bool AndroidContext::IsValid() const {
1923
return true;
2024
}
2125

26+
void AndroidContext::SetMainSkiaContext(
27+
const sk_sp<GrDirectContext>& main_context) {
28+
main_context_ = main_context;
29+
}
30+
31+
sk_sp<GrDirectContext> AndroidContext::GetMainSkiaContext() const {
32+
return main_context_;
33+
}
34+
2235
} // namespace flutter

shell/platform/android/context/android_context.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_H_
77

88
#include "flutter/fml/macros.h"
9+
#include "third_party/skia/include/gpu/GrDirectContext.h"
910

1011
namespace flutter {
1112

@@ -28,9 +29,37 @@ class AndroidContext {
2829

2930
virtual bool IsValid() const;
3031

32+
//----------------------------------------------------------------------------
33+
/// @brief Setter for the Skia context to be used by subsequent
34+
/// AndroidSurfaces.
35+
/// @details This is useful to reduce memory consumption when creating
36+
/// multiple AndroidSurfaces for the same AndroidContext.
37+
///
38+
/// The first AndroidSurface should set this for the
39+
/// AndroidContext if the AndroidContext does not yet have a
40+
/// Skia context to share via GetMainSkiaContext.
41+
///
42+
void SetMainSkiaContext(const sk_sp<GrDirectContext>& main_context);
43+
44+
//----------------------------------------------------------------------------
45+
/// @brief Accessor for the Skia context associated with AndroidSurfaces
46+
/// and the raster thread.
47+
/// @details This context is created lazily by the AndroidSurface based
48+
/// on their respective rendering backend and set on this
49+
/// AndroidContext to share via SetMainSkiaContext.
50+
/// @returns `nullptr` when no Skia context has been set yet by its
51+
/// AndroidSurface via SetMainSkiaContext.
52+
/// @attention The software context doesn't have a Skia context, so this
53+
/// value will be nullptr.
54+
///
55+
sk_sp<GrDirectContext> GetMainSkiaContext() const;
56+
3157
private:
3258
const AndroidRenderingAPI rendering_api_;
3359

60+
// This is the Skia context used for on-screen rendering.
61+
sk_sp<GrDirectContext> main_context_;
62+
3463
FML_DISALLOW_COPY_AND_ASSIGN(AndroidContext);
3564
};
3665

shell/platform/android/platform_view_android.cc

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
namespace flutter {
3030

3131
AndroidSurfaceFactoryImpl::AndroidSurfaceFactoryImpl(
32-
const AndroidContext& context,
32+
const std::shared_ptr<AndroidContext>& context,
3333
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
3434
: android_context_(context), jni_facade_(jni_facade) {}
3535

3636
AndroidSurfaceFactoryImpl::~AndroidSurfaceFactoryImpl() = default;
3737

3838
std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
39-
switch (android_context_.RenderingApi()) {
39+
switch (android_context_->RenderingApi()) {
4040
case AndroidRenderingAPI::kSoftware:
4141
return std::make_unique<AndroidSurfaceSoftware>(android_context_,
4242
jni_facade_);
@@ -68,13 +68,13 @@ PlatformViewAndroid::PlatformViewAndroid(
6868
#if SHELL_ENABLE_VULKAN
6969
android_context_ =
7070
std::make_shared<AndroidContext>(AndroidRenderingAPI::kVulkan);
71-
#else // SHELL_ENABLE_VULKAN
71+
#else // SHELL_ENABLE_VULKAN
7272
android_context_ = std::make_unique<AndroidContextGL>(
7373
AndroidRenderingAPI::kOpenGLES,
7474
fml::MakeRefCounted<AndroidEnvironmentGL>());
7575
#endif // SHELL_ENABLE_VULKAN
7676
}
77-
surface_factory_ = MakeSurfaceFactory(*android_context_, *jni_facade_);
77+
surface_factory_ = MakeSurfaceFactory(android_context_, *jni_facade_);
7878
android_surface_ = MakeSurface(surface_factory_);
7979
}
8080

@@ -87,7 +87,7 @@ PlatformViewAndroid::PlatformViewAndroid(
8787
jni_facade_(jni_facade),
8888
android_context_(android_context),
8989
platform_view_android_delegate_(jni_facade) {
90-
surface_factory_ = MakeSurfaceFactory(*android_context_, *jni_facade_);
90+
surface_factory_ = MakeSurfaceFactory(android_context_, *jni_facade_);
9191
android_surface_ = MakeSurface(surface_factory_);
9292
}
9393

@@ -103,9 +103,9 @@ PlatformViewAndroid::~PlatformViewAndroid() = default;
103103

104104
std::shared_ptr<AndroidSurfaceFactoryImpl>
105105
PlatformViewAndroid::MakeSurfaceFactory(
106-
const AndroidContext& android_context,
106+
const std::shared_ptr<AndroidContext>& android_context,
107107
const PlatformViewAndroidJNI& jni_facade) {
108-
FML_CHECK(android_context.IsValid())
108+
FML_CHECK(android_context->IsValid())
109109
<< "Could not create surface from invalid Android context.";
110110

111111
return std::make_shared<AndroidSurfaceFactoryImpl>(android_context,
@@ -317,7 +317,8 @@ std::unique_ptr<Surface> PlatformViewAndroid::CreateRenderingSurface() {
317317
if (!android_surface_) {
318318
return nullptr;
319319
}
320-
return android_surface_->CreateGPUSurface();
320+
return android_surface_->CreateGPUSurface(
321+
android_context_->GetMainSkiaContext().get());
321322
}
322323

323324
// |PlatformView|

shell/platform/android/platform_view_android.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ namespace flutter {
2525

2626
class AndroidSurfaceFactoryImpl : public AndroidSurfaceFactory {
2727
public:
28-
AndroidSurfaceFactoryImpl(const AndroidContext& context,
28+
AndroidSurfaceFactoryImpl(const std::shared_ptr<AndroidContext>& context,
2929
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
3030

3131
~AndroidSurfaceFactoryImpl() override;
3232

3333
std::unique_ptr<AndroidSurface> CreateSurface() override;
3434

3535
private:
36-
const AndroidContext& android_context_;
36+
const std::shared_ptr<AndroidContext>& android_context_;
3737
std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
3838
};
3939

@@ -171,7 +171,7 @@ class PlatformViewAndroid final : public PlatformView {
171171
void RequestDartDeferredLibrary(intptr_t loading_unit_id) override;
172172

173173
std::shared_ptr<AndroidSurfaceFactoryImpl> MakeSurfaceFactory(
174-
const AndroidContext& android_context,
174+
const std::shared_ptr<AndroidContext>& android_context,
175175
const PlatformViewAndroidJNI& jni_facade);
176176

177177
std::unique_ptr<AndroidSurface> MakeSurface(

shell/platform/android/surface/android_surface.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
namespace flutter {
88

9+
AndroidSurface::AndroidSurface(
10+
const std::shared_ptr<AndroidContext>& android_context) {
11+
android_context_ = android_context;
12+
}
13+
914
AndroidSurface::~AndroidSurface() = default;
1015

1116
} // namespace flutter

shell/platform/android/surface/android_surface.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_H_
66
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_H_
77

8+
#include <memory>
89
#include "flutter/flow/embedded_views.h"
910
#include "flutter/flow/surface.h"
1011
#include "flutter/fml/macros.h"
@@ -35,6 +36,11 @@ class AndroidSurface {
3536
virtual bool ResourceContextClearCurrent() = 0;
3637

3738
virtual bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) = 0;
39+
40+
protected:
41+
explicit AndroidSurface(
42+
const std::shared_ptr<AndroidContext>& android_context);
43+
std::shared_ptr<AndroidContext> android_context_;
3844
};
3945

4046
class AndroidSurfaceFactory {

0 commit comments

Comments
 (0)