diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 0c7d5d6f72776..8717991c10a06 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -63,9 +63,7 @@ bool ShellTestPlatformViewGL::GLContextClearCurrent() { } // |GPUSurfaceGLDelegate| -bool ShellTestPlatformViewGL::GLContextPresent( - uint32_t fbo_id, - const std::optional& damage) { +bool ShellTestPlatformViewGL::GLContextPresent(uint32_t fbo_id) { return gl_surface_.Present(); } diff --git a/shell/common/shell_test_platform_view_gl.h b/shell/common/shell_test_platform_view_gl.h index 0484969885f23..d072dd9731b9c 100644 --- a/shell/common/shell_test_platform_view_gl.h +++ b/shell/common/shell_test_platform_view_gl.h @@ -58,8 +58,7 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, bool GLContextClearCurrent() override; // |GPUSurfaceGLDelegate| - bool GLContextPresent(uint32_t fbo_id, - const std::optional& damage) override; + bool GLContextPresent(uint32_t fbo_id) override; // |GPUSurfaceGLDelegate| intptr_t GLContextFBO(GLFrameInfo frame_info) const override; diff --git a/shell/gpu/gpu_surface_gl.cc b/shell/gpu/gpu_surface_gl.cc index 218eb76e97b7e..6e81d0a0ae4f0 100644 --- a/shell/gpu/gpu_surface_gl.cc +++ b/shell/gpu/gpu_surface_gl.cc @@ -242,7 +242,7 @@ std::unique_ptr GPUSurfaceGL::AcquireFrame(const SkISize& size) { SurfaceFrame::SubmitCallback submit_callback = [weak = weak_factory_.GetWeakPtr()](const SurfaceFrame& surface_frame, SkCanvas* canvas) { - return weak ? weak->PresentSurface(surface_frame, canvas) : false; + return weak ? weak->PresentSurface(canvas) : false; }; framebuffer_info = delegate_->GLContextFramebufferInfo(); @@ -251,19 +251,17 @@ std::unique_ptr GPUSurfaceGL::AcquireFrame(const SkISize& size) { std::move(context_switch)); } -bool GPUSurfaceGL::PresentSurface(const SurfaceFrame& frame, SkCanvas* canvas) { +bool GPUSurfaceGL::PresentSurface(SkCanvas* canvas) { if (delegate_ == nullptr || canvas == nullptr || context_ == nullptr) { return false; } - delegate_->GLContextSetDamageRegion(frame.submit_info().buffer_damage); - { TRACE_EVENT0("flutter", "SkCanvas::Flush"); onscreen_surface_->getCanvas()->flush(); } - if (!delegate_->GLContextPresent(fbo_id_, frame.submit_info().frame_damage)) { + if (!delegate_->GLContextPresent(fbo_id_)) { return false; } diff --git a/shell/gpu/gpu_surface_gl.h b/shell/gpu/gpu_surface_gl.h index 390d78bbb9cc1..fd641149decec 100644 --- a/shell/gpu/gpu_surface_gl.h +++ b/shell/gpu/gpu_surface_gl.h @@ -60,7 +60,7 @@ class GPUSurfaceGL : public Surface { const SkISize& untransformed_size, const SkMatrix& root_surface_transformation); - bool PresentSurface(const SurfaceFrame& frame, SkCanvas* canvas); + bool PresentSurface(SkCanvas* canvas); GPUSurfaceGLDelegate* delegate_; sk_sp context_; diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index 35739d5019f8c..58a600347feb6 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -5,8 +5,6 @@ #ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_GL_DELEGATE_H_ #define FLUTTER_SHELL_GPU_GPU_SURFACE_GL_DELEGATE_H_ -#include - #include "flutter/common/graphics/gl_context_switch.h" #include "flutter/flow/embedded_views.h" #include "flutter/fml/macros.h" @@ -33,17 +31,9 @@ class GPUSurfaceGLDelegate { // either the GPU or IO threads. virtual bool GLContextClearCurrent() = 0; - // Inform the GL Context that there's going to be no writing beyond - // the specified region - virtual void GLContextSetDamageRegion(const std::optional& region) {} - // Called to present the main GL surface. This is only called for the main GL // context and not any of the contexts dedicated for IO. - // - // Damage is a hint to compositor telling it which parts of front buffer - // need to be updated - virtual bool GLContextPresent(uint32_t fbo_id, - const std::optional& damage) = 0; + virtual bool GLContextPresent(uint32_t fbo_id) = 0; // The ID of the main window bound framebuffer. Typically FBO0. virtual intptr_t GLContextFBO(GLFrameInfo frame_info) const = 0; diff --git a/shell/platform/android/android_context_gl.cc b/shell/platform/android/android_context_gl.cc index c70136d23c864..2af9f46463cdf 100644 --- a/shell/platform/android/android_context_gl.cc +++ b/shell/platform/android/android_context_gl.cc @@ -6,12 +6,8 @@ #include -#include #include -// required to get API level -#include - #include "flutter/fml/trace_event.h" namespace flutter { @@ -109,135 +105,10 @@ static bool TeardownContext(EGLDisplay display, EGLContext context) { return true; } -class AndroidEGLSurfaceDamage { - public: - void init(EGLDisplay display, EGLContext context) { - if (GetAPILevel() < 28) { - // Disable partial repaint for devices older than Android 9. There - // are old devices that have extensions below available but the - // implementation causes glitches (i.e. Xperia Z3 with Android 6). - partial_redraw_supported_ = false; - return; - } - - const char* extensions = eglQueryString(display, EGL_EXTENSIONS); - - if (HasExtension(extensions, "EGL_KHR_partial_update")) { - set_damage_region_ = reinterpret_cast( - eglGetProcAddress("eglSetDamageRegionKHR")); - } - - if (HasExtension(extensions, "EGL_EXT_swap_buffers_with_damage")) { - swap_buffers_with_damage_ = - reinterpret_cast( - eglGetProcAddress("eglSwapBuffersWithDamageEXT")); - } else if (HasExtension(extensions, "EGL_KHR_swap_buffers_with_damage")) { - swap_buffers_with_damage_ = - reinterpret_cast( - eglGetProcAddress("eglSwapBuffersWithDamageKHR")); - } - - partial_redraw_supported_ = - set_damage_region_ != nullptr && swap_buffers_with_damage_ != nullptr; - } - - static int GetAPILevel() { - char sdk_version_string[PROP_VALUE_MAX]; - if (__system_property_get("ro.build.version.sdk", sdk_version_string)) { - return atoi(sdk_version_string); - } else { - return -1; - } - } - - void SetDamageRegion(EGLDisplay display, - EGLSurface surface, - const std::optional& region) { - if (set_damage_region_ && region) { - auto rects = RectToInts(display, surface, *region); - set_damage_region_(display, surface, rects.data(), 1); - } - } - - // Maximum damage history - for triple buffering we need to store damage for - // last two frames; Some Android devices (Pixel 4) use quad buffering. - static const int kMaxHistorySize = 10; - - bool SupportsPartialRepaint() const { return partial_redraw_supported_; } - - std::optional InitialDamage(EGLDisplay display, EGLSurface surface) { - if (!partial_redraw_supported_) { - return std::nullopt; - } - - EGLint age; - eglQuerySurface(display, surface, EGL_BUFFER_AGE_EXT, &age); - - if (age == 0) { // full repaint - return std::nullopt; - } else { - // join up to (age - 1) last rects from damage history - --age; - auto res = SkIRect::MakeEmpty(); - for (auto i = damage_history_.rbegin(); - i != damage_history_.rend() && age > 0; ++i, --age) { - res.join(*i); - } - return res; - } - } - - bool SwapBuffersWithDamage(EGLDisplay display, - EGLSurface surface, - const std::optional& damage) { - if (swap_buffers_with_damage_ && damage) { - damage_history_.push_back(*damage); - if (damage_history_.size() > kMaxHistorySize) { - damage_history_.pop_front(); - } - auto rects = RectToInts(display, surface, *damage); - return swap_buffers_with_damage_(display, surface, rects.data(), 1); - } else { - return eglSwapBuffers(display, surface); - } - } - - private: - std::array static RectToInts(EGLDisplay display, - EGLSurface surface, - const SkIRect& rect) { - EGLint height; - eglQuerySurface(display, surface, EGL_HEIGHT, &height); - - std::array res{rect.left(), height - rect.bottom(), rect.width(), - rect.height()}; - return res; - } - - PFNEGLSETDAMAGEREGIONKHRPROC set_damage_region_ = nullptr; - PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage_ = nullptr; - - bool partial_redraw_supported_; - - bool HasExtension(const char* extensions, const char* name) { - const char* r = strstr(extensions, name); - auto len = strlen(name); - // check that the extension name is terminated by space or null terminator - return r != nullptr && (r[len] == ' ' || r[len] == 0); - } - - std::list damage_history_; -}; - AndroidEGLSurface::AndroidEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context) - : surface_(surface), - display_(display), - context_(context), - damage_(std::make_unique()) { - damage_->init(display_, context); -} + : surface_(surface), display_(display), context_(context) {} AndroidEGLSurface::~AndroidEGLSurface() { [[maybe_unused]] auto result = eglDestroySurface(display_, surface_); @@ -257,23 +128,9 @@ bool AndroidEGLSurface::MakeCurrent() const { return true; } -void AndroidEGLSurface::SetDamageRegion( - const std::optional& buffer_damage) { - damage_->SetDamageRegion(display_, surface_, buffer_damage); -} - -bool AndroidEGLSurface::SwapBuffers( - const std::optional& surface_damage) { +bool AndroidEGLSurface::SwapBuffers() { TRACE_EVENT0("flutter", "AndroidContextGL::SwapBuffers"); - return damage_->SwapBuffersWithDamage(display_, surface_, surface_damage); -} - -bool AndroidEGLSurface::SupportsPartialRepaint() const { - return damage_->SupportsPartialRepaint(); -} - -std::optional AndroidEGLSurface::InitialDamage() { - return damage_->InitialDamage(display_, surface_); + return eglSwapBuffers(display_, surface_); } SkISize AndroidEGLSurface::GetSize() const { diff --git a/shell/platform/android/android_context_gl.h b/shell/platform/android/android_context_gl.h index 38f172807441e..08668e488ca4d 100644 --- a/shell/platform/android/android_context_gl.h +++ b/shell/platform/android/android_context_gl.h @@ -23,8 +23,6 @@ namespace flutter { /// This can be used in conjunction to unique_ptr to provide better guarantees /// about the lifespan of the `EGLSurface` object. /// -class AndroidEGLSurfaceDamage; - class AndroidEGLSurface { public: AndroidEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context); @@ -45,35 +43,13 @@ class AndroidEGLSurface { /// bool MakeCurrent() const; - //---------------------------------------------------------------------------- - /// - /// @return Whether target surface supports partial repaint. - /// - bool SupportsPartialRepaint() const; - - //---------------------------------------------------------------------------- - /// @brief This is the minimal area that needs to be repainted to get - /// correct result. - /// - /// With double or triple buffering this buffer content may lag behind - /// current front buffer and the rect accounts for accumulated damage. - /// - /// @return The area of current surface where it is behind front buffer. - /// - std::optional InitialDamage(); - - //---------------------------------------------------------------------------- - /// @brief Sets the damage region for current surface. Corresponds to - // eglSetDamageRegionKHR - void SetDamageRegion(const std::optional& buffer_damage); - //---------------------------------------------------------------------------- /// @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(const std::optional& surface_damage); + bool SwapBuffers(); //---------------------------------------------------------------------------- /// @return The size of an `EGLSurface`. @@ -84,7 +60,6 @@ class AndroidEGLSurface { const EGLSurface surface_; const EGLDisplay display_; const EGLContext context_; - std::unique_ptr damage_; }; //------------------------------------------------------------------------------ diff --git a/shell/platform/android/android_surface_gl.cc b/shell/platform/android/android_surface_gl.cc index 39599e2e10f8e..0015265152fd4 100644 --- a/shell/platform/android/android_surface_gl.cc +++ b/shell/platform/android/android_surface_gl.cc @@ -126,27 +126,10 @@ bool AndroidSurfaceGL::GLContextClearCurrent() { return GLContextPtr()->ClearCurrent(); } -SurfaceFrame::FramebufferInfo AndroidSurfaceGL::GLContextFramebufferInfo() - const { - FML_DCHECK(IsValid()); - SurfaceFrame::FramebufferInfo res; - res.supports_readback = true; - res.supports_partial_repaint = onscreen_surface_->SupportsPartialRepaint(); - res.existing_damage = onscreen_surface_->InitialDamage(); - return res; -} - -void AndroidSurfaceGL::GLContextSetDamageRegion( - const std::optional& region) { - FML_DCHECK(IsValid()); - onscreen_surface_->SetDamageRegion(region); -} - -bool AndroidSurfaceGL::GLContextPresent(uint32_t fbo_id, - const std::optional& damage) { +bool AndroidSurfaceGL::GLContextPresent(uint32_t fbo_id) { FML_DCHECK(IsValid()); FML_DCHECK(onscreen_surface_); - return onscreen_surface_->SwapBuffers(damage); + return onscreen_surface_->SwapBuffers(); } intptr_t AndroidSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { diff --git a/shell/platform/android/android_surface_gl.h b/shell/platform/android/android_surface_gl.h index 92ddd6361a9cb..e078d2363e6b2 100644 --- a/shell/platform/android/android_surface_gl.h +++ b/shell/platform/android/android_surface_gl.h @@ -58,14 +58,7 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate, bool GLContextClearCurrent() override; // |GPUSurfaceGLDelegate| - SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override; - - // |GPUSurfaceGLDelegate| - void GLContextSetDamageRegion(const std::optional& region) override; - - // |GPUSurfaceGLDelegate| - bool GLContextPresent(uint32_t fbo_id, - const std::optional& damage) override; + bool GLContextPresent(uint32_t fbo_id) override; // |GPUSurfaceGLDelegate| intptr_t GLContextFBO(GLFrameInfo frame_info) const override; diff --git a/shell/platform/android/surface/android_surface_mock.cc b/shell/platform/android/surface/android_surface_mock.cc index 515d867f23ff1..a0b08cb4892d6 100644 --- a/shell/platform/android/surface/android_surface_mock.cc +++ b/shell/platform/android/surface/android_surface_mock.cc @@ -18,9 +18,7 @@ bool AndroidSurfaceMock::GLContextClearCurrent() { return true; } -bool AndroidSurfaceMock::GLContextPresent( - uint32_t fbo_id, - const std::optional& damage) { +bool AndroidSurfaceMock::GLContextPresent(uint32_t fbo_id) { return true; } diff --git a/shell/platform/android/surface/android_surface_mock.h b/shell/platform/android/surface/android_surface_mock.h index 04a6b2e03f1ee..f710133f64c5d 100644 --- a/shell/platform/android/surface/android_surface_mock.h +++ b/shell/platform/android/surface/android_surface_mock.h @@ -48,8 +48,7 @@ class AndroidSurfaceMock final : public GPUSurfaceGLDelegate, bool GLContextClearCurrent() override; // |GPUSurfaceGLDelegate| - bool GLContextPresent(uint32_t fbo_id, - const std::optional& damage) override; + bool GLContextPresent(uint32_t fbo_id) override; // |GPUSurfaceGLDelegate| intptr_t GLContextFBO(GLFrameInfo frame_info) const override; diff --git a/shell/platform/darwin/ios/ios_surface_gl.h b/shell/platform/darwin/ios/ios_surface_gl.h index 3ea6fc407394b..54a0584a7e0af 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.h +++ b/shell/platform/darwin/ios/ios_surface_gl.h @@ -38,7 +38,7 @@ class IOSSurfaceGL final : public IOSSurface, public GPUSurfaceGLDelegate { bool GLContextClearCurrent() override; // |GPUSurfaceGLDelegate| - bool GLContextPresent(uint32_t fbo_id, const std::optional& damage) override; + bool GLContextPresent(uint32_t fbo_id) override; // |GPUSurfaceGLDelegate| intptr_t GLContextFBO(GLFrameInfo frame_info) const override; diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index fb1658e2bbe76..9b6bb6a99aa1e 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -86,7 +86,7 @@ } // |GPUSurfaceGLDelegate| -bool IOSSurfaceGL::GLContextPresent(uint32_t fbo_id, const std::optional& damage) { +bool IOSSurfaceGL::GLContextPresent(uint32_t fbo_id) { TRACE_EVENT0("flutter", "IOSSurfaceGL::GLContextPresent"); return IsValid() && render_target_->PresentRenderBuffer(); } diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index dfe67e290b0bf..69c75cb2e7462 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -45,8 +45,7 @@ bool EmbedderSurfaceGL::GLContextClearCurrent() { } // |GPUSurfaceGLDelegate| -bool EmbedderSurfaceGL::GLContextPresent(uint32_t fbo_id, - const std::optional& damage) { +bool EmbedderSurfaceGL::GLContextPresent(uint32_t fbo_id) { return gl_dispatch_table_.gl_present_callback(fbo_id); } diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 16700702810e3..6f07bcce9ef51 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -56,8 +56,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface, bool GLContextClearCurrent() override; // |GPUSurfaceGLDelegate| - bool GLContextPresent(uint32_t fbo_id, - const std::optional& damage) override; + bool GLContextPresent(uint32_t fbo_id) override; // |GPUSurfaceGLDelegate| intptr_t GLContextFBO(GLFrameInfo frame_info) const override;