diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 15d16e9c87d..2854e04c45e 100755 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -645,6 +645,8 @@ FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan.h FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.cc FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.h FILE: ../../../flutter/shell/platform/android/AndroidManifest.xml +FILE: ../../../flutter/shell/platform/android/android_context.cc +FILE: ../../../flutter/shell/platform/android/android_context.h FILE: ../../../flutter/shell/platform/android/android_context_gl.cc FILE: ../../../flutter/shell/platform/android/android_context_gl.h FILE: ../../../flutter/shell/platform/android/android_environment_gl.cc diff --git a/engine/src/flutter/shell/platform/android/BUILD.gn b/engine/src/flutter/shell/platform/android/BUILD.gn index 077e203f627..77a9b63c4ea 100644 --- a/engine/src/flutter/shell/platform/android/BUILD.gn +++ b/engine/src/flutter/shell/platform/android/BUILD.gn @@ -23,6 +23,8 @@ shared_library("flutter_shell_native") { sources = [ "$root_build_dir/flutter_icu/icudtl.o", + "android_context.cc", + "android_context.h", "android_context_gl.cc", "android_context_gl.h", "android_environment_gl.cc", diff --git a/engine/src/flutter/shell/platform/android/android_context.cc b/engine/src/flutter/shell/platform/android/android_context.cc new file mode 100644 index 00000000000..c59f56186d9 --- /dev/null +++ b/engine/src/flutter/shell/platform/android/android_context.cc @@ -0,0 +1,37 @@ +// 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.h" + +#include "flutter/shell/platform/android/android_context_gl.h" +#include "flutter/shell/platform/android/android_environment_gl.h" + +namespace flutter { + +std::shared_ptr CreateContextGL() { + auto context_gl = std::make_shared( + AndroidRenderingAPI::kOpenGLES, + fml::MakeRefCounted()); + FML_CHECK(context_gl->IsValid()) << "Could not create an Android context GL."; + return context_gl; +} + +AndroidContext::AndroidContext(AndroidRenderingAPI rendering_api) + : rendering_api_(rendering_api) {} + +AndroidContext::~AndroidContext() = default; + +AndroidRenderingAPI AndroidContext::RenderingApi() const { + return rendering_api_; +} + +std::shared_ptr AndroidContext::Create( + AndroidRenderingAPI rendering_api) { + if (rendering_api == AndroidRenderingAPI::kOpenGLES) { + return CreateContextGL(); + } + return std::make_shared(rendering_api); +} + +} // namespace flutter diff --git a/engine/src/flutter/shell/platform/android/android_context.h b/engine/src/flutter/shell/platform/android/android_context.h new file mode 100644 index 00000000000..313d5377c40 --- /dev/null +++ b/engine/src/flutter/shell/platform/android/android_context.h @@ -0,0 +1,43 @@ +// 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_H_ +#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_H_ + +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/ref_counted.h" +#include "flutter/fml/memory/ref_ptr.h" +#include "flutter/shell/common/platform_view.h" + +namespace flutter { + +enum class AndroidRenderingAPI { + kSoftware, + kOpenGLES, + kVulkan, +}; + +//------------------------------------------------------------------------------ +/// @brief Holds state that is shared across Android surfaces. +/// +class AndroidContext { + public: + AndroidContext(AndroidRenderingAPI rendering_api); + + ~AndroidContext(); + + static std::shared_ptr Create( + AndroidRenderingAPI rendering_api); + + AndroidRenderingAPI RenderingApi() const; + + private: + const AndroidRenderingAPI rendering_api_; + + FML_DISALLOW_COPY_AND_ASSIGN(AndroidContext); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_H_ diff --git a/engine/src/flutter/shell/platform/android/android_context_gl.cc b/engine/src/flutter/shell/platform/android/android_context_gl.cc index d3fd715a38a..c1ac748e077 100644 --- a/engine/src/flutter/shell/platform/android/android_context_gl.cc +++ b/engine/src/flutter/shell/platform/android/android_context_gl.cc @@ -105,62 +105,21 @@ static bool TeardownContext(EGLDisplay display, EGLContext context) { return true; } -static bool TeardownSurface(EGLDisplay display, EGLSurface surface) { - if (surface != EGL_NO_SURFACE) { - return eglDestroySurface(display, surface) == EGL_TRUE; - } - - return true; -} - -// For onscreen rendering. -bool AndroidContextGL::CreateWindowSurface( - fml::RefPtr window) { - // The configurations are only required when dealing with extensions or VG. - // We do neither. - - window_ = std::move(window); - EGLDisplay display = environment_->Display(); - - const EGLint attribs[] = {EGL_NONE}; - - surface_ = eglCreateWindowSurface( - display, config_, - reinterpret_cast(window_->handle()), attribs); - return surface_ != EGL_NO_SURFACE; -} - -// For offscreen rendering. -bool AndroidContextGL::CreatePBufferSurface() { - // We only ever create pbuffer surfaces for background resource loading - // contexts. We never bind the pbuffer to anything. - - EGLDisplay display = environment_->Display(); - - const EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; - - surface_ = eglCreatePbufferSurface(display, config_, attribs); - return surface_ != EGL_NO_SURFACE; -} - -AndroidContextGL::AndroidContextGL(fml::RefPtr env, - const AndroidContextGL* share_context) - : environment_(env), - window_(nullptr), - config_(nullptr), - surface_(EGL_NO_SURFACE), - context_(EGL_NO_CONTEXT), - valid_(false) { +AndroidContextGL::AndroidContextGL( + AndroidRenderingAPI rendering_api, + fml::RefPtr environment) + : AndroidContext(AndroidRenderingAPI::kOpenGLES), + environment_(environment), + config_(nullptr) { if (!environment_->IsValid()) { + FML_LOG(ERROR) << "Could not create an Android GL environment."; return; } bool success = false; // Choose a valid configuration. - std::tie(success, config_) = ChooseEGLConfiguration(environment_->Display()); - if (!success) { FML_LOG(ERROR) << "Could not choose an EGL configuration."; LogLastEGLError(); @@ -168,19 +127,18 @@ AndroidContextGL::AndroidContextGL(fml::RefPtr env, } // Create a context for the configuration. - - std::tie(success, context_) = CreateContext( - environment_->Display(), config_, - share_context != nullptr ? share_context->context_ : EGL_NO_CONTEXT); - + std::tie(success, context_) = + CreateContext(environment_->Display(), config_, EGL_NO_CONTEXT); if (!success) { FML_LOG(ERROR) << "Could not create an EGL context"; LogLastEGLError(); return; } - if (!this->CreatePBufferSurface()) { - FML_LOG(ERROR) << "Could not create the EGL surface."; + std::tie(success, resource_context_) = + CreateContext(environment_->Display(), config_, context_); + if (!success) { + FML_LOG(ERROR) << "Could not create an EGL resource context"; LogLastEGLError(); return; } @@ -196,13 +154,34 @@ AndroidContextGL::~AndroidContextGL() { LogLastEGLError(); } - if (!TeardownSurface(environment_->Display(), surface_)) { - FML_LOG(ERROR) - << "Could not tear down the EGL surface. Possible resource leak."; + if (!TeardownContext(environment_->Display(), resource_context_)) { + FML_LOG(ERROR) << "Could not tear down the EGL resource context. Possible " + "resource leak."; LogLastEGLError(); } } +EGLSurface AndroidContextGL::CreateOnscreenSurface( + fml::RefPtr window) const { + EGLDisplay display = environment_->Display(); + + const EGLint attribs[] = {EGL_NONE}; + + return eglCreateWindowSurface( + display, config_, reinterpret_cast(window->handle()), + attribs); +} + +EGLSurface AndroidContextGL::CreateOffscreenSurface() const { + // We only ever create pbuffer surfaces for background resource loading + // contexts. We never bind the pbuffer to anything. + EGLDisplay display = environment_->Display(); + + const EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; + + return eglCreatePbufferSurface(display, config_, attribs); +} + fml::RefPtr AndroidContextGL::Environment() const { return environment_; } @@ -211,8 +190,8 @@ bool AndroidContextGL::IsValid() const { return valid_; } -bool AndroidContextGL::MakeCurrent() { - if (eglMakeCurrent(environment_->Display(), surface_, surface_, context_) != +bool AndroidContextGL::MakeCurrent(EGLSurface& surface) { + if (eglMakeCurrent(environment_->Display(), surface, surface, context_) != EGL_TRUE) { FML_LOG(ERROR) << "Could not make the context current"; LogLastEGLError(); @@ -221,6 +200,16 @@ bool AndroidContextGL::MakeCurrent() { return true; } +bool AndroidContextGL::ResourceMakeCurrent(EGLSurface& surface) { + if (eglMakeCurrent(environment_->Display(), surface, surface, + resource_context_) != EGL_TRUE) { + FML_LOG(ERROR) << "Could not make the context current"; + LogLastEGLError(); + return false; + } + return true; +} + bool AndroidContextGL::ClearCurrent() { if (eglGetCurrentContext() != context_) { return true; @@ -234,18 +223,17 @@ bool AndroidContextGL::ClearCurrent() { return true; } -bool AndroidContextGL::SwapBuffers() { +bool AndroidContextGL::SwapBuffers(EGLSurface& surface) { TRACE_EVENT0("flutter", "AndroidContextGL::SwapBuffers"); - return eglSwapBuffers(environment_->Display(), surface_); + return eglSwapBuffers(environment_->Display(), surface); } -SkISize AndroidContextGL::GetSize() { +SkISize AndroidContextGL::GetSize(EGLSurface& surface) { EGLint width = 0; EGLint height = 0; - if (!eglQuerySurface(environment_->Display(), surface_, EGL_WIDTH, &width) || - !eglQuerySurface(environment_->Display(), surface_, EGL_HEIGHT, - &height)) { + if (!eglQuerySurface(environment_->Display(), surface, EGL_WIDTH, &width) || + !eglQuerySurface(environment_->Display(), surface, EGL_HEIGHT, &height)) { FML_LOG(ERROR) << "Unable to query EGL surface size"; LogLastEGLError(); return SkISize::Make(0, 0); @@ -253,22 +241,11 @@ SkISize AndroidContextGL::GetSize() { return SkISize::Make(width, height); } -bool AndroidContextGL::Resize(const SkISize& size) { - if (size == GetSize()) { - return true; +bool AndroidContextGL::TeardownSurface(EGLSurface& surface) { + if (surface != EGL_NO_SURFACE) { + return eglDestroySurface(environment_->Display(), surface) == EGL_TRUE; } - ClearCurrent(); - - TeardownSurface(environment_->Display(), surface_); - - if (!this->CreateWindowSurface(window_)) { - FML_LOG(ERROR) << "Unable to create EGL window surface on resize."; - return false; - } - - MakeCurrent(); - return true; } diff --git a/engine/src/flutter/shell/platform/android/android_context_gl.h b/engine/src/flutter/shell/platform/android/android_context_gl.h index 50e15aba2ed..606ffe82944 100644 --- a/engine/src/flutter/shell/platform/android/android_context_gl.h +++ b/engine/src/flutter/shell/platform/android/android_context_gl.h @@ -9,47 +9,111 @@ #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/memory/ref_ptr.h" #include "flutter/shell/common/platform_view.h" +#include "flutter/shell/platform/android/android_context.h" #include "flutter/shell/platform/android/android_environment_gl.h" #include "flutter/shell/platform/android/android_native_window.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { -class AndroidContextGL : public fml::RefCountedThreadSafe { +//------------------------------------------------------------------------------ +/// The Android context is used by `AndroidSurfaceGL` to create and manage +/// EGL surfaces. +/// +/// This context binds `EGLContext` to the current rendering thread and to the +/// draw and read `EGLSurface`s. +/// +class AndroidContextGL : public AndroidContext { public: - bool CreateWindowSurface(fml::RefPtr window); - - bool CreatePBufferSurface(); - - fml::RefPtr Environment() const; - - bool IsValid() const; - - bool MakeCurrent(); - - bool ClearCurrent(); - - bool SwapBuffers(); - - SkISize GetSize(); - - bool Resize(const SkISize& size); - - private: - fml::RefPtr environment_; - fml::RefPtr window_; - EGLConfig config_; - EGLSurface surface_; - EGLContext context_; - bool valid_; - - AndroidContextGL(fml::RefPtr env, - const AndroidContextGL* share_context = nullptr); + AndroidContextGL(AndroidRenderingAPI rendering_api, + fml::RefPtr environment); ~AndroidContextGL(); - FML_FRIEND_MAKE_REF_COUNTED(AndroidContextGL); - FML_FRIEND_REF_COUNTED_THREAD_SAFE(AndroidContextGL); + //---------------------------------------------------------------------------- + /// @brief Allocates an new EGL window surface that is used for on-screen + /// pixels. + /// + /// @attention Consumers must tear down the surface by calling + /// `AndroidContextGL::TeardownSurface`. + /// + /// @return The window surface. + /// + EGLSurface CreateOnscreenSurface( + fml::RefPtr window) const; + + //---------------------------------------------------------------------------- + /// @brief Allocates an 1x1 pbuffer surface that is used for making the + /// offscreen current for texture uploads. + /// + /// @attention Consumers must tear down the surface by calling + /// `AndroidContextGL::TeardownSurface`. + /// + /// @return The pbuffer surface. + /// + EGLSurface CreateOffscreenSurface() const; + + //---------------------------------------------------------------------------- + /// @return The Android environment that contains a reference to the + /// display. + /// + fml::RefPtr Environment() const; + + //---------------------------------------------------------------------------- + /// @return Whether the current context is valid. That is, if the EGL + /// contexts + /// were successfully created. + /// + bool IsValid() const; + + //---------------------------------------------------------------------------- + /// @return Whether the current context was successfully clear. + /// + bool ClearCurrent(); + + //---------------------------------------------------------------------------- + /// @brief Binds the EGLContext context to the current rendering thread + /// and to the draw and read surface. + /// + /// @return Whether the surface was made current. + /// + bool MakeCurrent(EGLSurface& surface); + + //---------------------------------------------------------------------------- + /// @brief Binds the resource EGLContext context to the current rendering + /// thread and to the draw and read surface. + /// + /// @return Whether the surface was made current. + /// + bool ResourceMakeCurrent(EGLSurface& surface); + + //---------------------------------------------------------------------------- + /// @brief This only applies to on-screen surfaces such as those created + /// by `AndroidContextGL::CreateOnscreenSurface`. + /// + /// @return Whether the EGL surface color buffer was swapped. + /// + bool SwapBuffers(EGLSurface& surface); + + //---------------------------------------------------------------------------- + /// @return The size of an `EGLSurface`. + /// + SkISize GetSize(EGLSurface& surface); + + //---------------------------------------------------------------------------- + /// @brief Destroys an `EGLSurface`. + /// + /// @return Whether the surface was destroyed. + /// + bool TeardownSurface(EGLSurface& surface); + + private: + fml::RefPtr environment_; + EGLConfig config_; + EGLContext context_; + EGLContext resource_context_; + bool valid_ = false; + FML_DISALLOW_COPY_AND_ASSIGN(AndroidContextGL); }; diff --git a/engine/src/flutter/shell/platform/android/android_surface.cc b/engine/src/flutter/shell/platform/android/android_surface.cc index 958570a822a..711a1e05710 100644 --- a/engine/src/flutter/shell/platform/android/android_surface.cc +++ b/engine/src/flutter/shell/platform/android/android_surface.cc @@ -15,19 +15,24 @@ namespace flutter { std::unique_ptr AndroidSurface::Create( - bool use_software_rendering) { - if (use_software_rendering) { - auto software_surface = std::make_unique(); - return software_surface->IsValid() ? std::move(software_surface) : nullptr; - } + std::shared_ptr android_context) { + std::unique_ptr surface; + switch (android_context->RenderingApi()) { + case AndroidRenderingAPI::kSoftware: + surface = std::make_unique(); + break; + case AndroidRenderingAPI::kOpenGLES: + surface = std::make_unique(android_context); + break; + case AndroidRenderingAPI::kVulkan: #if SHELL_ENABLE_VULKAN - auto vulkan_surface = std::make_unique(); - return vulkan_surface->IsValid() ? std::move(vulkan_surface) : nullptr; -#else // SHELL_ENABLE_VULKAN - auto gl_surface = std::make_unique(); - return gl_surface->IsOffscreenContextValid() ? std::move(gl_surface) - : nullptr; + surface = std::make_unique(); #endif // SHELL_ENABLE_VULKAN + break; + } + FML_CHECK(surface); + return surface->IsValid() ? std::move(surface) : nullptr; + ; } AndroidSurface::~AndroidSurface() = default; diff --git a/engine/src/flutter/shell/platform/android/android_surface.h b/engine/src/flutter/shell/platform/android/android_surface.h index 43f4cf33d0d..9c463c99073 100644 --- a/engine/src/flutter/shell/platform/android/android_surface.h +++ b/engine/src/flutter/shell/platform/android/android_surface.h @@ -12,6 +12,7 @@ #include "flutter/fml/platform/android/jni_weak_ref.h" #include "flutter/shell/common/platform_view.h" #include "flutter/shell/common/surface.h" +#include "flutter/shell/platform/android/android_context.h" #include "flutter/shell/platform/android/android_native_window.h" #include "third_party/skia/include/core/SkSize.h" @@ -19,7 +20,8 @@ namespace flutter { class AndroidSurface { public: - static std::unique_ptr Create(bool use_software_rendering); + static std::unique_ptr Create( + std::shared_ptr android_context); virtual ~AndroidSurface(); @@ -27,9 +29,10 @@ class AndroidSurface { virtual void TeardownOnScreenContext() = 0; - virtual std::unique_ptr CreateGPUSurface() = 0; + virtual std::unique_ptr CreateGPUSurface( + GrContext* gr_context = nullptr) = 0; - virtual bool OnScreenSurfaceResize(const SkISize& size) const = 0; + virtual bool OnScreenSurfaceResize(const SkISize& size) = 0; virtual bool ResourceContextMakeCurrent() = 0; diff --git a/engine/src/flutter/shell/platform/android/android_surface_gl.cc b/engine/src/flutter/shell/platform/android/android_surface_gl.cc index dae803fb6b8..59e5eacffac 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_gl.cc +++ b/engine/src/flutter/shell/platform/android/android_surface_gl.cc @@ -11,120 +11,113 @@ namespace flutter { -static fml::RefPtr CreateResourceLoadingContext() { - auto environment = fml::MakeRefCounted(); - if (!environment->IsValid()) { - return nullptr; +AndroidSurfaceGL::AndroidSurfaceGL( + std::shared_ptr android_context) + : native_window_(nullptr), + onscreen_surface_(nullptr), + offscreen_surface_(nullptr) { + android_context_ = + std::static_pointer_cast(android_context); + // Acquire the offscreen surface. + offscreen_surface_ = android_context_->CreateOffscreenSurface(); + if (offscreen_surface_ == EGL_NO_SURFACE) { + offscreen_surface_ = nullptr; } - - auto context = fml::MakeRefCounted(environment); - if (!context->IsValid()) { - return nullptr; - } - - return context; -} - -AndroidSurfaceGL::AndroidSurfaceGL() { - // Acquire the offscreen context. - offscreen_context_ = CreateResourceLoadingContext(); - - if (!offscreen_context_ || !offscreen_context_->IsValid()) { - offscreen_context_ = nullptr; - } - external_view_embedder_ = std::make_unique(); } -AndroidSurfaceGL::~AndroidSurfaceGL() = default; - -bool AndroidSurfaceGL::IsOffscreenContextValid() const { - return offscreen_context_ && offscreen_context_->IsValid(); +AndroidSurfaceGL::~AndroidSurfaceGL() { + if (offscreen_surface_) { + android_context_->TeardownSurface(offscreen_surface_); + offscreen_surface_ = nullptr; + } + if (onscreen_surface_) { + android_context_->TeardownSurface(onscreen_surface_); + onscreen_surface_ = nullptr; + } } void AndroidSurfaceGL::TeardownOnScreenContext() { - if (onscreen_context_) { - onscreen_context_->ClearCurrent(); - } - onscreen_context_ = nullptr; + android_context_->ClearCurrent(); } bool AndroidSurfaceGL::IsValid() const { - if (!onscreen_context_ || !offscreen_context_) { - return false; + return offscreen_surface_ && android_context_->IsValid(); +} + +std::unique_ptr AndroidSurfaceGL::CreateGPUSurface( + GrContext* gr_context) { + if (gr_context) { + return std::make_unique(sk_ref_sp(gr_context), this, true); + } + return std::make_unique(this, true); +} + +bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) { + FML_DCHECK(IsValid()); + FML_DCHECK(onscreen_surface_); + FML_DCHECK(native_window_); + + if (size == android_context_->GetSize(onscreen_surface_)) { + return true; } - return onscreen_context_->IsValid() && offscreen_context_->IsValid(); -} + android_context_->ClearCurrent(); + android_context_->TeardownSurface(onscreen_surface_); -std::unique_ptr AndroidSurfaceGL::CreateGPUSurface() { - auto surface = std::make_unique(this, true); - return surface->IsValid() ? std::move(surface) : nullptr; -} - -bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) const { - FML_DCHECK(onscreen_context_ && onscreen_context_->IsValid()); - return onscreen_context_->Resize(size); + onscreen_surface_ = android_context_->CreateOnscreenSurface(native_window_); + if (!onscreen_surface_ || onscreen_surface_ == EGL_NO_SURFACE) { + FML_LOG(ERROR) << "Unable to create EGL window surface on resize."; + return false; + } + android_context_->MakeCurrent(onscreen_surface_); + return true; } bool AndroidSurfaceGL::ResourceContextMakeCurrent() { - FML_DCHECK(offscreen_context_ && offscreen_context_->IsValid()); - return offscreen_context_->MakeCurrent(); + FML_DCHECK(IsValid()); + return android_context_->ResourceMakeCurrent(offscreen_surface_); } bool AndroidSurfaceGL::ResourceContextClearCurrent() { - FML_DCHECK(offscreen_context_ && offscreen_context_->IsValid()); - return offscreen_context_->ClearCurrent(); + FML_DCHECK(IsValid()); + return android_context_->ClearCurrent(); } bool AndroidSurfaceGL::SetNativeWindow( fml::RefPtr window) { - // In any case, we want to get rid of our current onscreen context. - onscreen_context_ = nullptr; - - // If the offscreen context has not been setup, we dont have the sharegroup. - // So bail. - if (!offscreen_context_ || !offscreen_context_->IsValid()) { + FML_DCHECK(IsValid()); + FML_DCHECK(window); + native_window_ = window; + // Create the onscreen surface. + onscreen_surface_ = android_context_->CreateOnscreenSurface(window); + if (onscreen_surface_ == EGL_NO_SURFACE) { return false; } - - // Create the onscreen context. - onscreen_context_ = fml::MakeRefCounted( - offscreen_context_->Environment(), - offscreen_context_.get() /* sharegroup */); - - if (!onscreen_context_->IsValid()) { - onscreen_context_ = nullptr; - return false; - } - - if (!onscreen_context_->CreateWindowSurface(std::move(window))) { - onscreen_context_ = nullptr; - return false; - } - return true; } std::unique_ptr AndroidSurfaceGL::GLContextMakeCurrent() { - FML_DCHECK(onscreen_context_ && onscreen_context_->IsValid()); + FML_DCHECK(IsValid()); + FML_DCHECK(onscreen_surface_); auto default_context_result = std::make_unique( - onscreen_context_->MakeCurrent()); + android_context_->MakeCurrent(onscreen_surface_)); return std::move(default_context_result); } bool AndroidSurfaceGL::GLContextClearCurrent() { - FML_DCHECK(onscreen_context_ && onscreen_context_->IsValid()); - return onscreen_context_->ClearCurrent(); + FML_DCHECK(IsValid()); + return android_context_->ClearCurrent(); } bool AndroidSurfaceGL::GLContextPresent() { - FML_DCHECK(onscreen_context_ && onscreen_context_->IsValid()); - return onscreen_context_->SwapBuffers(); + FML_DCHECK(IsValid()); + FML_DCHECK(onscreen_surface_); + return android_context_->SwapBuffers(onscreen_surface_); } intptr_t AndroidSurfaceGL::GLContextFBO() const { - FML_DCHECK(onscreen_context_ && onscreen_context_->IsValid()); + FML_DCHECK(IsValid()); // The default window bound framebuffer on Android. return 0; } diff --git a/engine/src/flutter/shell/platform/android/android_surface_gl.h b/engine/src/flutter/shell/platform/android/android_surface_gl.h index a13156a7734..58188630fb1 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_gl.h +++ b/engine/src/flutter/shell/platform/android/android_surface_gl.h @@ -20,23 +20,21 @@ namespace flutter { class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, public AndroidSurface { public: - AndroidSurfaceGL(); + AndroidSurfaceGL(std::shared_ptr android_context); ~AndroidSurfaceGL() override; - bool IsOffscreenContextValid() const; - // |AndroidSurface| bool IsValid() const override; // |AndroidSurface| - std::unique_ptr CreateGPUSurface() override; + std::unique_ptr CreateGPUSurface(GrContext* gr_context) override; // |AndroidSurface| void TeardownOnScreenContext() override; // |AndroidSurface| - bool OnScreenSurfaceResize(const SkISize& size) const override; + bool OnScreenSurfaceResize(const SkISize& size) override; // |AndroidSurface| bool ResourceContextMakeCurrent() override; @@ -63,9 +61,11 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, ExternalViewEmbedder* GetExternalViewEmbedder() override; private: - fml::RefPtr onscreen_context_; - fml::RefPtr offscreen_context_; + fml::RefPtr native_window_; std::unique_ptr external_view_embedder_; + std::shared_ptr android_context_; + EGLSurface onscreen_surface_; + EGLSurface offscreen_surface_; FML_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceGL); }; diff --git a/engine/src/flutter/shell/platform/android/android_surface_software.cc b/engine/src/flutter/shell/platform/android/android_surface_software.cc index fa1399cf0ad..562bd0937f1 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_software.cc +++ b/engine/src/flutter/shell/platform/android/android_surface_software.cc @@ -57,7 +57,8 @@ bool AndroidSurfaceSoftware::ResourceContextClearCurrent() { return false; } -std::unique_ptr AndroidSurfaceSoftware::CreateGPUSurface() { +std::unique_ptr AndroidSurfaceSoftware::CreateGPUSurface( + GrContext* gr_context) { if (!IsValid()) { return nullptr; } @@ -143,7 +144,7 @@ ExternalViewEmbedder* AndroidSurfaceSoftware::GetExternalViewEmbedder() { void AndroidSurfaceSoftware::TeardownOnScreenContext() {} -bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) const { +bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) { return true; } diff --git a/engine/src/flutter/shell/platform/android/android_surface_software.h b/engine/src/flutter/shell/platform/android/android_surface_software.h index e11f362c31e..dfe3de9fb67 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_software.h +++ b/engine/src/flutter/shell/platform/android/android_surface_software.h @@ -31,13 +31,13 @@ class AndroidSurfaceSoftware final : public AndroidSurface, bool ResourceContextClearCurrent() override; // |AndroidSurface| - std::unique_ptr CreateGPUSurface() override; + std::unique_ptr CreateGPUSurface(GrContext* gr_context) override; // |AndroidSurface| void TeardownOnScreenContext() override; // |AndroidSurface| - bool OnScreenSurfaceResize(const SkISize& size) const override; + bool OnScreenSurfaceResize(const SkISize& size) override; // |AndroidSurface| bool SetNativeWindow(fml::RefPtr window) override; diff --git a/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc b/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc index 601ae4298d0..1ed814ff539 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc +++ b/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc @@ -27,7 +27,8 @@ void AndroidSurfaceVulkan::TeardownOnScreenContext() { // Nothing to do. } -std::unique_ptr AndroidSurfaceVulkan::CreateGPUSurface() { +std::unique_ptr AndroidSurfaceVulkan::CreateGPUSurface( + GrContext* gr_context) { if (!IsValid()) { return nullptr; } @@ -54,7 +55,7 @@ std::unique_ptr AndroidSurfaceVulkan::CreateGPUSurface() { return gpu_surface; } -bool AndroidSurfaceVulkan::OnScreenSurfaceResize(const SkISize& size) const { +bool AndroidSurfaceVulkan::OnScreenSurfaceResize(const SkISize& size) { return true; } diff --git a/engine/src/flutter/shell/platform/android/android_surface_vulkan.h b/engine/src/flutter/shell/platform/android/android_surface_vulkan.h index 146f88598fc..d73addf5bdf 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_vulkan.h +++ b/engine/src/flutter/shell/platform/android/android_surface_vulkan.h @@ -27,13 +27,13 @@ class AndroidSurfaceVulkan : public AndroidSurface, bool IsValid() const override; // |AndroidSurface| - std::unique_ptr CreateGPUSurface() override; + std::unique_ptr CreateGPUSurface(GrContext* gr_context) override; // |AndroidSurface| void TeardownOnScreenContext() override; // |AndroidSurface| - bool OnScreenSurfaceResize(const SkISize& size) const override; + bool OnScreenSurfaceResize(const SkISize& size) override; // |AndroidSurface| bool ResourceContextMakeCurrent() override; diff --git a/engine/src/flutter/shell/platform/android/platform_view_android.cc b/engine/src/flutter/shell/platform/android/platform_view_android.cc index 236ef41ae18..c1e396d043e 100644 --- a/engine/src/flutter/shell/platform/android/platform_view_android.cc +++ b/engine/src/flutter/shell/platform/android/platform_view_android.cc @@ -10,6 +10,7 @@ #include "flutter/fml/synchronization/waitable_event.h" #include "flutter/shell/common/shell_io_manager.h" #include "flutter/shell/gpu/gpu_surface_gl_delegate.h" +#include "flutter/shell/platform/android/android_context.h" #include "flutter/shell/platform/android/android_external_texture_gl.h" #include "flutter/shell/platform/android/android_surface_gl.h" #include "flutter/shell/platform/android/platform_message_response_android.h" @@ -24,8 +25,18 @@ PlatformViewAndroid::PlatformViewAndroid( fml::jni::JavaObjectWeakGlobalRef java_object, bool use_software_rendering) : PlatformView(delegate, std::move(task_runners)), - java_object_(java_object), - android_surface_(AndroidSurface::Create(use_software_rendering)) { + java_object_(java_object) { + std::shared_ptr android_context; + if (use_software_rendering) { + android_context = AndroidContext::Create(AndroidRenderingAPI::kSoftware); + } else { +#if SHELL_ENABLE_VULKAN + android_context = AndroidContext::Create(AndroidRenderingAPI::kVulkan); +#else // SHELL_ENABLE_VULKAN + android_context = AndroidContext::Create(AndroidRenderingAPI::kOpenGLES); +#endif // SHELL_ENABLE_VULKAN + } + android_surface_ = AndroidSurface::Create(android_context); FML_CHECK(android_surface_) << "Could not create an OpenGL, Vulkan or Software surface to setup " "rendering."; diff --git a/engine/src/flutter/shell/platform/android/platform_view_android.h b/engine/src/flutter/shell/platform/android/platform_view_android.h index 74c0bbe6c26..d517e7fda29 100644 --- a/engine/src/flutter/shell/platform/android/platform_view_android.h +++ b/engine/src/flutter/shell/platform/android/platform_view_android.h @@ -75,7 +75,8 @@ class PlatformViewAndroid final : public PlatformView { private: const fml::jni::JavaObjectWeakGlobalRef java_object_; - const std::unique_ptr android_surface_; + + std::unique_ptr android_surface_; // We use id 0 to mean that no response is expected. int next_response_id_ = 1; std::unordered_map>