From d9a7bccd74113827e5d2f090c770445ec08045c5 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:11:34 -0700 Subject: [PATCH 01/38] Update the return value of GLContextFBO. --- shell/gpu/gpu_surface_gl_delegate.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index f9da6a11120fd..dcf1a73f301d6 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -22,6 +22,15 @@ struct GLFrameInfo { uint32_t height; }; +/// NEW: Adding this new struct so that we have information about the FBO's id +/// and existing damage in one place. +/// A structure to represent a frame buffer as composed by an id and existing +/// damage to it (in the case of partial repaint). +struct GLFrameBuffer { + uint32_t fbo_id; + std::optional damage = SkIRect::MakeEmpty(); +}; + // Information passed during presentation of a frame. struct GLPresentInfo { uint32_t fbo_id; @@ -54,8 +63,12 @@ class GPUSurfaceGLDelegate { // context and not any of the contexts dedicated for IO. virtual bool GLContextPresent(const GLPresentInfo& present_info) = 0; - // The ID of the main window bound framebuffer. Typically FBO0. - virtual intptr_t GLContextFBO(GLFrameInfo frame_info) const = 0; + /// NEW: Changing the return type of GLContextFBO so that it can also return + /// the existing damage for that FBO. + // The information about the main window bound framebuffer such as ID and + // existing damage. ID is typically FBO0. Existing damage is only relevant + // when performing partial repaint. + virtual GLFrameBuffer GLContextFBO(GLFrameInfo frame_info) const = 0; // The rendering subsystem assumes that the ID of the main window bound // framebuffer remains constant throughout. If this assumption in incorrect, From 926d6478309cb62aa44d1898cadfb15aa263f6f6 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:22:55 -0700 Subject: [PATCH 02/38] Keep track of the existing damage when requesting new frames and pass down partial repaint information when creating a surface frame with acquire frame. --- shell/gpu/gpu_surface_gl_skia.cc | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index 66bb6636d95d8..810df4e823d5f 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -86,6 +86,12 @@ GPUSurfaceGLSkia::GPUSurfaceGLSkia(sk_sp gr_context, delegate_->GLContextClearCurrent(); valid_ = gr_context != nullptr; + + /// NEW: Turning partial repaint on by default when a GPUSurfaceGLDelegate is + /// created. + // TODO(btrevisan): add functinality to disable partial repaint when desired. + // Partial Repaint is enabled by default. + partial_repaint_enabled_ = true; } GPUSurfaceGLSkia::~GPUSurfaceGLSkia() { @@ -181,10 +187,12 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { GLFrameInfo frame_info = {static_cast(size.width()), static_cast(size.height())}; - const uint32_t fbo_id = delegate_->GLContextFBO(frame_info); + /// NEW: Updating the call to GLContextFBO to account for the FBO's existing + /// damage. + const GLFrameBuffer fbo = delegate_->GLContextFBO(frame_info); onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context size, // root surface size - fbo_id // window FBO ID + fbo.fbo_id // window FBO ID ); if (onscreen_surface == nullptr) { @@ -195,7 +203,8 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { } onscreen_surface_ = std::move(onscreen_surface); - fbo_id_ = fbo_id; + fbo_id_ = fbo.fbo_id; + fbo_existing_damage_ = fbo.damage; return true; } @@ -248,6 +257,13 @@ std::unique_ptr GPUSurfaceGLSkia::AcquireFrame( }; framebuffer_info = delegate_->GLContextFramebufferInfo(); + /// NEW: Populating framebuffer_info with necessary information for partial + /// repaint. + if (partial_repaint_enabled_) { + framebuffer_info.supports_partial_repaint = true; + framebuffer_info.existing_damage = fbo_existing_damage_; + // TODO(btrevisan): confirm if cliping alignment needs to be updated. + } return std::make_unique(surface, std::move(framebuffer_info), submit_callback, std::move(context_switch)); @@ -284,11 +300,13 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, // The FBO has changed, ask the delegate for the new FBO and do a surface // re-wrap. - const uint32_t fbo_id = delegate_->GLContextFBO(frame_info); + /// NEW: Updating the call to GLContextFBO to account for the FBO's existing + /// damage. + const GLFrameBuffer fbo = delegate_->GLContextFBO(frame_info); auto new_onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context current_size, // root surface size - fbo_id // window FBO ID + fbo.fbo_id // window FBO ID ); if (!new_onscreen_surface) { @@ -296,7 +314,8 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, } onscreen_surface_ = std::move(new_onscreen_surface); - fbo_id_ = fbo_id; + fbo_id_ = fbo.fbo_id; + fbo_existing_damage_ = fbo.damage; } return true; From d7259fd07971001c13f1c9984576714b28ff0bee Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:25:48 -0700 Subject: [PATCH 03/38] Add private variables to support partial repaint. --- shell/gpu/gpu_surface_gl_skia.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 90cad241945fd..140deee8eb50f 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -67,6 +67,9 @@ class GPUSurfaceGLSkia : public Surface { sk_sp onscreen_surface_; /// FBO backing the current `onscreen_surface_`. uint32_t fbo_id_ = 0; + /// NEW: Adding fbo_existing_damage_, a private variable that keeps track of + /// the existing damage within the current FBO. + std::optional fbo_existing_damage_ = SkIRect::MakeEmpty(); bool context_owner_ = false; // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. This is a @@ -74,6 +77,9 @@ class GPUSurfaceGLSkia : public Surface { // external view embedder is present. const bool render_to_surface_ = true; bool valid_ = false; + /// NEW: Adding partial_repaint_enabled_, a private variable that says whether + /// partial repaint is turned on or not. + bool partial_repaint_enabled_; // WeakPtrFactory must be the last member. fml::TaskRunnerAffineWeakPtrFactory weak_factory_; From 4458feb280374ee6a19a6f7db890db1cc81ae35c Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:30:40 -0700 Subject: [PATCH 04/38] Update the embedder's GLContextFBO and GLContextPresent function and implement GLContextSetDamageRegion. --- .../platform/embedder/embedder_surface_gl.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index e406ee9ed10fa..dc6dca046a698 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -46,12 +46,17 @@ bool EmbedderSurfaceGL::GLContextClearCurrent() { // |GPUSurfaceGLDelegate| bool EmbedderSurfaceGL::GLContextPresent(const GLPresentInfo& present_info) { - return gl_dispatch_table_.gl_present_callback(present_info.fbo_id); + /// NEW: Pass the damage region (as set by GLContextSetDamageRegion and the + /// frame damage (in present_info) so that the embedder can keep track of it. + return gl_dispatch_table_.gl_present_callback(present_info, damage_region_); } // |GPUSurfaceGLDelegate| -intptr_t EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { - return gl_dispatch_table_.gl_fbo_callback(frame_info); +GLFrameBuffer EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { + /// NEW: updating GLContextFBO to trigger a callback that will not only return + /// the FBO ID but also its existing damage (at least when doing partial + /// partial repaint. + return gl_dispatch_table_.gl_fbo_callback(frame_info);; } // |GPUSurfaceGLDelegate| @@ -107,4 +112,12 @@ sk_sp EmbedderSurfaceGL::CreateResourceContext() const { return nullptr; } +void EmbedderSurfaceGL::GLContextSetDamageRegion( + const std::optional& region) { + /// NEW: Updating the damage_region_ so that it can be passed down to the + /// embedder using present_with_info. + /// NOTE: region here refers to the buffer_damage. + damage_region_ = region; +} + } // namespace flutter From 816f0e19c05d06d0a6936793fa339dcdbc4184eb Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:33:24 -0700 Subject: [PATCH 05/38] Update function prototypes and add damage region. --- shell/platform/embedder/embedder_surface_gl.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index c0a2b6a55d98f..39a38f8b6a3dc 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -18,8 +18,8 @@ class EmbedderSurfaceGL final : public EmbedderSurface, struct GLDispatchTable { std::function gl_make_current_callback; // required std::function gl_clear_current_callback; // required - std::function gl_present_callback; // required - std::function gl_fbo_callback; // required + std::function)> gl_present_callback; // required + std::function gl_fbo_callback; // required std::function gl_make_resource_current_callback; // optional std::function gl_surface_transformation_callback; // optional @@ -37,6 +37,9 @@ class EmbedderSurfaceGL final : public EmbedderSurface, bool valid_ = false; GLDispatchTable gl_dispatch_table_; bool fbo_reset_after_present_; + /// NEW: Adding this private variable to keep track of the damage region of + /// the current buffer so that it can be passed to the present callback.s + std::optional damage_region_ = SkIRect::MakeEmpty(); std::shared_ptr external_view_embedder_; @@ -59,7 +62,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface, bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - intptr_t GLContextFBO(GLFrameInfo frame_info) const override; + GLFrameBuffer GLContextFBO(GLFrameInfo frame_info) const override; // |GPUSurfaceGLDelegate| bool GLContextFBOResetAfterPresent() const override; @@ -70,6 +73,9 @@ class EmbedderSurfaceGL final : public EmbedderSurface, // |GPUSurfaceGLDelegate| GLProcResolver GetGLProcResolver() const override; + // |GPUSurfaceGLDelegate| + void GLContextSetDamageRegion(const std::optional& region) override; + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceGL); }; From 17044741d2786c582b348662c58fdd40b5713fc4 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:38:33 -0700 Subject: [PATCH 06/38] Update the way the embedder handles the fbo and the present callbacks. --- shell/platform/embedder/embedder.cc | 75 ++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index fea4882cc1536..686cb0f51b99a 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -221,6 +221,24 @@ static void* DefaultGLProcResolver(const char* name) { } #endif // FML_OS_LINUX || FML_OS_WIN +/// NEW: Adding this function to make it easier to translate a SkIRect to a +/// FlutterRect. +FlutterRect SkIRectToFlutterRect(const std::optional rect) { + FlutterRect flutter_rect = { + static_cast(rect->fLeft), static_cast(rect->fRight), + static_cast(rect->fTop), static_cast(rect->fBottom)}; + return flutter_rect; +} + +/// NEW: Adding this function to make it easier to translate a FlutterRect back +/// to a SkIRect. +SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { + SkIRect rect = { + static_cast(flutter_rect.left), static_cast(flutter_rect.right), + static_cast(flutter_rect.top), static_cast(flutter_rect.bottom)}; + return rect; +} + static flutter::Shell::CreateCallback InferOpenGLPlatformViewCreationCallback( const FlutterRendererConfig* config, @@ -240,15 +258,40 @@ InferOpenGLPlatformViewCreationCallback( auto gl_clear_current = [ptr = config->open_gl.clear_current, user_data]() -> bool { return ptr(user_data); }; - auto gl_present = [present = config->open_gl.present, - present_with_info = config->open_gl.present_with_info, - user_data](uint32_t fbo_id) -> bool { + /// NEW: Changing the arguments to gl_present callback so that the embedder + /// can receive more information than just the fbo_id (e.g. damage). + /// NOTE: this means that for partial repaint to work, we must have it use the + /// present_with_info callback rather than the present callback. + auto gl_present = + [present = config->open_gl.present, + present_with_info = config->open_gl.present_with_info, + user_data](flutter::GLPresentInfo gl_present_info, std::optional damage_region) -> bool { if (present) { return present(user_data); } else { - FlutterPresentInfo present_info = {}; + FlutterPresentInfo present_info; present_info.struct_size = sizeof(FlutterPresentInfo); - present_info.fbo_id = fbo_id; + present_info.fbo_id = gl_present_info.fbo_id; + + /// Format the frame_damage appropriately. + FlutterDamage frame_damage; + frame_damage.struct_size = sizeof(FlutterDamage); + frame_damage.damage = SkIRectToFlutterRect(gl_present_info.damage); + + /// Format the buffer_damage appropriately. + FlutterDamage buffer_damage; + buffer_damage.struct_size = sizeof(FlutterDamage); + buffer_damage.damage = SkIRectToFlutterRect(damage_region); + + present_info.frame_damage = frame_damage; + present_info.buffer_damage = buffer_damage; + + /// Pass the present_info to the present_with_info callback so that it can + /// correctly only render part of the screen and save the FBO's damage + /// region. + /// NOTE: alternatively, I could create a present callback that is + /// specific to partial repaint / damage tracking and leave + /// present_with_info as it is. return present_with_info(user_data, &present_info); } }; @@ -257,14 +300,30 @@ InferOpenGLPlatformViewCreationCallback( [fbo_callback = config->open_gl.fbo_callback, fbo_with_frame_info_callback = config->open_gl.fbo_with_frame_info_callback, - user_data](flutter::GLFrameInfo gl_frame_info) -> intptr_t { + fbo_with_damage_callback = config->open_gl.fbo_with_damage_callback, + user_data](flutter::GLFrameInfo gl_frame_info) -> flutter::GLFrameBuffer { if (fbo_callback) { - return fbo_callback(user_data); + flutter::GLFrameBuffer fbo; + fbo.fbo_id = fbo_callback(user_data); + return fbo; + } else if (fbo_with_frame_info_callback) { + FlutterFrameInfo frame_info = {}; + frame_info.struct_size = sizeof(FlutterFrameInfo); + frame_info.size = {gl_frame_info.width, gl_frame_info.height}; + + flutter::GLFrameBuffer fbo; + fbo.fbo_id = fbo_with_frame_info_callback(user_data, &frame_info); + return fbo; } else { FlutterFrameInfo frame_info = {}; frame_info.struct_size = sizeof(FlutterFrameInfo); frame_info.size = {gl_frame_info.width, gl_frame_info.height}; - return fbo_with_frame_info_callback(user_data, &frame_info); + + FlutterFrameBuffer fbo = fbo_with_damage_callback(user_data, &frame_info); + flutter::GLFrameBuffer gl_fbo; + gl_fbo.fbo_id = fbo.fbo_id; + gl_fbo.damage = FlutterRectToSkIRect(fbo.damage.damage); + return gl_fbo; } }; From 204dd3b43695aaca21466f0e3df753bbd6e909bb Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:42:31 -0700 Subject: [PATCH 07/38] Add new structs to the embedder to support partial repaint. --- shell/platform/embedder/embedder.h | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 7cc732a8b53db..9d89b88a2ed01 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -377,6 +377,21 @@ typedef struct { FlutterSize lower_left_corner_radius; } FlutterRoundedRect; +/// QUESTION: should damage be a vector of FlutterRect's? Intuitively, this +/// seems like the correct approach since we could have areas that are being +/// rendered in different corners of the screen. However, the partial repaint +/// implemented for android and iOS seems to use only one rectangle. On the +/// other hand, one rectangle might help with reduce the complexity of the +/// rendering process. +/// NEW: Adding new struct so that the embedder can represent the idea of +/// damage in a self-contained way. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterDamage). + size_t struct_size; + // Rectangle that represents the area that needs to be rendered. + FlutterRect damage; +} FlutterDamage; + /// This information is passed to the embedder when requesting a frame buffer /// object. /// @@ -393,6 +408,21 @@ typedef uint32_t (*UIntFrameInfoCallback)( void* /* user data */, const FlutterFrameInfo* /* frame info */); +/// NEW: Adding new struct so that the embedder can represent the idea of +/// a frame buffer in a self-contained way. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterFrameBuffer). + size_t struct_size; + intptr_t fbo_id; + FlutterDamage damage; +} FlutterFrameBuffer; + +/// NEW: adding this type of callback since the return value of the +/// fbo_with_damage callback is a FlutterFrameBuffer (instead of a uintptr). +typedef FlutterFrameBuffer (*FlutterFrameBufferFrameInfoCallback)( + void* /* user data */, + const FlutterFrameInfo* /* frame info */); + /// This information is passed to the embedder when a surface is presented. /// /// See: \ref FlutterOpenGLRendererConfig.present_with_info. @@ -401,6 +431,11 @@ typedef struct { size_t struct_size; /// Id of the fbo backing the surface that was presented. uint32_t fbo_id; + /// NEW: Adding new fields so that present with partial repaint works. + /// Rectangle representing the area that the compositor needs to render. + FlutterDamage frame_damage; + /// Rectangle representing the area that changed since FBO was last used. + FlutterDamage buffer_damage; } FlutterPresentInfo; /// Callback for when a surface is presented. @@ -466,6 +501,7 @@ typedef struct { /// `FlutterPresentInfo` struct that the embedder can use to release any /// resources. The return value indicates success of the present call. BoolPresentInfoCallback present_with_info; + FlutterFrameBufferFrameInfoCallback fbo_with_damage_callback; } FlutterOpenGLRendererConfig; /// Alias for id. From 0135f1d5e083d44b19d442cf6525989657d1bb78 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 12 Jul 2022 13:44:11 -0700 Subject: [PATCH 08/38] Formatting. --- shell/gpu/gpu_surface_gl_delegate.h | 4 ++-- shell/gpu/gpu_surface_gl_skia.h | 2 +- shell/platform/embedder/embedder.cc | 20 ++++++++++--------- shell/platform/embedder/embedder.h | 2 +- .../platform/embedder/embedder_surface_gl.cc | 2 +- shell/platform/embedder/embedder_surface_gl.h | 9 +++++---- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index dcf1a73f301d6..2a1d2542c3e67 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -24,7 +24,7 @@ struct GLFrameInfo { /// NEW: Adding this new struct so that we have information about the FBO's id /// and existing damage in one place. -/// A structure to represent a frame buffer as composed by an id and existing +/// A structure to represent a frame buffer as composed by an id and existing /// damage to it (in the case of partial repaint). struct GLFrameBuffer { uint32_t fbo_id; @@ -65,7 +65,7 @@ class GPUSurfaceGLDelegate { /// NEW: Changing the return type of GLContextFBO so that it can also return /// the existing damage for that FBO. - // The information about the main window bound framebuffer such as ID and + // The information about the main window bound framebuffer such as ID and // existing damage. ID is typically FBO0. Existing damage is only relevant // when performing partial repaint. virtual GLFrameBuffer GLContextFBO(GLFrameInfo frame_info) const = 0; diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 140deee8eb50f..23abb1357cda2 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -67,7 +67,7 @@ class GPUSurfaceGLSkia : public Surface { sk_sp onscreen_surface_; /// FBO backing the current `onscreen_surface_`. uint32_t fbo_id_ = 0; - /// NEW: Adding fbo_existing_damage_, a private variable that keeps track of + /// NEW: Adding fbo_existing_damage_, a private variable that keeps track of /// the existing damage within the current FBO. std::optional fbo_existing_damage_ = SkIRect::MakeEmpty(); bool context_owner_ = false; diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 686cb0f51b99a..97ef307112a76 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -230,12 +230,13 @@ FlutterRect SkIRectToFlutterRect(const std::optional rect) { return flutter_rect; } -/// NEW: Adding this function to make it easier to translate a FlutterRect back +/// NEW: Adding this function to make it easier to translate a FlutterRect back /// to a SkIRect. SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { - SkIRect rect = { - static_cast(flutter_rect.left), static_cast(flutter_rect.right), - static_cast(flutter_rect.top), static_cast(flutter_rect.bottom)}; + SkIRect rect = {static_cast(flutter_rect.left), + static_cast(flutter_rect.right), + static_cast(flutter_rect.top), + static_cast(flutter_rect.bottom)}; return rect; } @@ -262,10 +263,10 @@ InferOpenGLPlatformViewCreationCallback( /// can receive more information than just the fbo_id (e.g. damage). /// NOTE: this means that for partial repaint to work, we must have it use the /// present_with_info callback rather than the present callback. - auto gl_present = - [present = config->open_gl.present, - present_with_info = config->open_gl.present_with_info, - user_data](flutter::GLPresentInfo gl_present_info, std::optional damage_region) -> bool { + auto gl_present = [present = config->open_gl.present, + present_with_info = config->open_gl.present_with_info, + user_data](flutter::GLPresentInfo gl_present_info, + std::optional damage_region) -> bool { if (present) { return present(user_data); } else { @@ -301,7 +302,8 @@ InferOpenGLPlatformViewCreationCallback( fbo_with_frame_info_callback = config->open_gl.fbo_with_frame_info_callback, fbo_with_damage_callback = config->open_gl.fbo_with_damage_callback, - user_data](flutter::GLFrameInfo gl_frame_info) -> flutter::GLFrameBuffer { + user_data]( + flutter::GLFrameInfo gl_frame_info) -> flutter::GLFrameBuffer { if (fbo_callback) { flutter::GLFrameBuffer fbo; fbo.fbo_id = fbo_callback(user_data); diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 9d89b88a2ed01..61839b0326320 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -417,7 +417,7 @@ typedef struct { FlutterDamage damage; } FlutterFrameBuffer; -/// NEW: adding this type of callback since the return value of the +/// NEW: adding this type of callback since the return value of the /// fbo_with_damage callback is a FlutterFrameBuffer (instead of a uintptr). typedef FlutterFrameBuffer (*FlutterFrameBufferFrameInfoCallback)( void* /* user data */, diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index dc6dca046a698..c98ee0a48652c 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -56,7 +56,7 @@ GLFrameBuffer EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { /// NEW: updating GLContextFBO to trigger a callback that will not only return /// the FBO ID but also its existing damage (at least when doing partial /// partial repaint. - return gl_dispatch_table_.gl_fbo_callback(frame_info);; + return gl_dispatch_table_.gl_fbo_callback(frame_info); } // |GPUSurfaceGLDelegate| diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 39a38f8b6a3dc..a7d5ea2fdb778 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -16,10 +16,11 @@ class EmbedderSurfaceGL final : public EmbedderSurface, public GPUSurfaceGLDelegate { public: struct GLDispatchTable { - std::function gl_make_current_callback; // required - std::function gl_clear_current_callback; // required - std::function)> gl_present_callback; // required - std::function gl_fbo_callback; // required + std::function gl_make_current_callback; // required + std::function gl_clear_current_callback; // required + std::function)> + gl_present_callback; // required + std::function gl_fbo_callback; // required std::function gl_make_resource_current_callback; // optional std::function gl_surface_transformation_callback; // optional From adb609bb0ef12ad71284bf23ebebc164d3a6abe3 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Wed, 13 Jul 2022 10:54:15 -0700 Subject: [PATCH 09/38] Adjust the way existing damage is communicated to the rendering backend to avoid having to modify the return value of functions that are being used by other platforms. --- shell/gpu/gpu_surface_gl_delegate.h | 11 +------- shell/gpu/gpu_surface_gl_skia.cc | 17 +++++------- shell/gpu/gpu_surface_gl_skia.h | 3 --- shell/platform/embedder/embedder.cc | 21 +++------------ .../platform/embedder/embedder_surface_gl.cc | 27 +++++++++++++++++-- shell/platform/embedder/embedder_surface_gl.h | 10 +++++-- 6 files changed, 44 insertions(+), 45 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index 2a1d2542c3e67..39a50ce3db712 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -22,15 +22,6 @@ struct GLFrameInfo { uint32_t height; }; -/// NEW: Adding this new struct so that we have information about the FBO's id -/// and existing damage in one place. -/// A structure to represent a frame buffer as composed by an id and existing -/// damage to it (in the case of partial repaint). -struct GLFrameBuffer { - uint32_t fbo_id; - std::optional damage = SkIRect::MakeEmpty(); -}; - // Information passed during presentation of a frame. struct GLPresentInfo { uint32_t fbo_id; @@ -68,7 +59,7 @@ class GPUSurfaceGLDelegate { // The information about the main window bound framebuffer such as ID and // existing damage. ID is typically FBO0. Existing damage is only relevant // when performing partial repaint. - virtual GLFrameBuffer GLContextFBO(GLFrameInfo frame_info) const = 0; + virtual intptr_t GLContextFBO(GLFrameInfo frame_info) const = 0; // The rendering subsystem assumes that the ID of the main window bound // framebuffer remains constant throughout. If this assumption in incorrect, diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index 810df4e823d5f..c5833fb98cdff 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -189,10 +189,10 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { static_cast(size.height())}; /// NEW: Updating the call to GLContextFBO to account for the FBO's existing /// damage. - const GLFrameBuffer fbo = delegate_->GLContextFBO(frame_info); + const intptr_t fbo = delegate_->GLContextFBO(frame_info); onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context size, // root surface size - fbo.fbo_id // window FBO ID + fbo // window FBO ID ); if (onscreen_surface == nullptr) { @@ -203,9 +203,7 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { } onscreen_surface_ = std::move(onscreen_surface); - fbo_id_ = fbo.fbo_id; - fbo_existing_damage_ = fbo.damage; - + fbo_id_ = fbo; return true; } @@ -261,8 +259,6 @@ std::unique_ptr GPUSurfaceGLSkia::AcquireFrame( /// repaint. if (partial_repaint_enabled_) { framebuffer_info.supports_partial_repaint = true; - framebuffer_info.existing_damage = fbo_existing_damage_; - // TODO(btrevisan): confirm if cliping alignment needs to be updated. } return std::make_unique(surface, std::move(framebuffer_info), submit_callback, @@ -302,11 +298,11 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, // re-wrap. /// NEW: Updating the call to GLContextFBO to account for the FBO's existing /// damage. - const GLFrameBuffer fbo = delegate_->GLContextFBO(frame_info); + const intptr_t fbo = delegate_->GLContextFBO(frame_info); auto new_onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context current_size, // root surface size - fbo.fbo_id // window FBO ID + fbo // window FBO ID ); if (!new_onscreen_surface) { @@ -314,8 +310,7 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, } onscreen_surface_ = std::move(new_onscreen_surface); - fbo_id_ = fbo.fbo_id; - fbo_existing_damage_ = fbo.damage; + fbo_id_ = fbo; } return true; diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 23abb1357cda2..f6a57e9a23f64 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -67,9 +67,6 @@ class GPUSurfaceGLSkia : public Surface { sk_sp onscreen_surface_; /// FBO backing the current `onscreen_surface_`. uint32_t fbo_id_ = 0; - /// NEW: Adding fbo_existing_damage_, a private variable that keeps track of - /// the existing damage within the current FBO. - std::optional fbo_existing_damage_ = SkIRect::MakeEmpty(); bool context_owner_ = false; // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. This is a diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 97ef307112a76..0cf9fc2fb364b 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -230,16 +230,6 @@ FlutterRect SkIRectToFlutterRect(const std::optional rect) { return flutter_rect; } -/// NEW: Adding this function to make it easier to translate a FlutterRect back -/// to a SkIRect. -SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { - SkIRect rect = {static_cast(flutter_rect.left), - static_cast(flutter_rect.right), - static_cast(flutter_rect.top), - static_cast(flutter_rect.bottom)}; - return rect; -} - static flutter::Shell::CreateCallback InferOpenGLPlatformViewCreationCallback( const FlutterRendererConfig* config, @@ -303,9 +293,9 @@ InferOpenGLPlatformViewCreationCallback( config->open_gl.fbo_with_frame_info_callback, fbo_with_damage_callback = config->open_gl.fbo_with_damage_callback, user_data]( - flutter::GLFrameInfo gl_frame_info) -> flutter::GLFrameBuffer { + flutter::GLFrameInfo gl_frame_info) -> FlutterFrameBuffer { if (fbo_callback) { - flutter::GLFrameBuffer fbo; + FlutterFrameBuffer fbo; fbo.fbo_id = fbo_callback(user_data); return fbo; } else if (fbo_with_frame_info_callback) { @@ -313,7 +303,7 @@ InferOpenGLPlatformViewCreationCallback( frame_info.struct_size = sizeof(FlutterFrameInfo); frame_info.size = {gl_frame_info.width, gl_frame_info.height}; - flutter::GLFrameBuffer fbo; + FlutterFrameBuffer fbo; fbo.fbo_id = fbo_with_frame_info_callback(user_data, &frame_info); return fbo; } else { @@ -322,10 +312,7 @@ InferOpenGLPlatformViewCreationCallback( frame_info.size = {gl_frame_info.width, gl_frame_info.height}; FlutterFrameBuffer fbo = fbo_with_damage_callback(user_data, &frame_info); - flutter::GLFrameBuffer gl_fbo; - gl_fbo.fbo_id = fbo.fbo_id; - gl_fbo.damage = FlutterRectToSkIRect(fbo.damage.damage); - return gl_fbo; + return fbo; } }; diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index c98ee0a48652c..bc20ed631be4b 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -51,12 +51,35 @@ bool EmbedderSurfaceGL::GLContextPresent(const GLPresentInfo& present_info) { return gl_dispatch_table_.gl_present_callback(present_info, damage_region_); } +/// NEW: Adding this function to make it easier to translate a FlutterRect back +/// to a SkIRect. +SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { + SkIRect rect = {static_cast(flutter_rect.left), + static_cast(flutter_rect.right), + static_cast(flutter_rect.top), + static_cast(flutter_rect.bottom)}; + return rect; +} + // |GPUSurfaceGLDelegate| -GLFrameBuffer EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { +intptr_t EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { /// NEW: updating GLContextFBO to trigger a callback that will not only return /// the FBO ID but also its existing damage (at least when doing partial /// partial repaint. - return gl_dispatch_table_.gl_fbo_callback(frame_info); + FlutterFrameBuffer fbo = gl_dispatch_table_.gl_fbo_callback(frame_info); + existing_damage_ = FlutterRectToSkIRect(fbo.damage.damage); + return fbo.fbo_id; +} + +// |GPUSurfaceGLDelegate| +SurfaceFrame::FramebufferInfo EmbedderSurfaceGL::GLContextFramebufferInfo() + const { + SurfaceFrame::FramebufferInfo res; + res.supports_readback = true; + res.supports_partial_repaint = true; + res.existing_damage = existing_damage_; + // TODO(btrevisan): confirm if cliping alignment needs to be updated. + return res; } // |GPUSurfaceGLDelegate| diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index a7d5ea2fdb778..47d15d7930a23 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -20,7 +20,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface, std::function gl_clear_current_callback; // required std::function)> gl_present_callback; // required - std::function gl_fbo_callback; // required + std::function gl_fbo_callback; // required std::function gl_make_resource_current_callback; // optional std::function gl_surface_transformation_callback; // optional @@ -41,6 +41,9 @@ class EmbedderSurfaceGL final : public EmbedderSurface, /// NEW: Adding this private variable to keep track of the damage region of /// the current buffer so that it can be passed to the present callback.s std::optional damage_region_ = SkIRect::MakeEmpty(); + /// NEW: Adding fbo_existing_damage_, a private variable that keeps track of + /// the existing damage within the current FBO. + mutable std::optional existing_damage_ = SkIRect::MakeEmpty(); std::shared_ptr external_view_embedder_; @@ -63,7 +66,10 @@ class EmbedderSurfaceGL final : public EmbedderSurface, bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - GLFrameBuffer GLContextFBO(GLFrameInfo frame_info) const override; + intptr_t GLContextFBO(GLFrameInfo frame_info) const override; + + // |GPUSurfaceGLDelegate| + SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override; // |GPUSurfaceGLDelegate| bool GLContextFBOResetAfterPresent() const override; From 29514dbf0a0e1a51d98f365cc9b53d7a2042c8f1 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Wed, 13 Jul 2022 11:08:14 -0700 Subject: [PATCH 10/38] Formatting --- shell/gpu/gpu_surface_gl_skia.cc | 4 ++-- shell/platform/embedder/embedder.cc | 3 +-- shell/platform/embedder/embedder_surface_gl.h | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index c5833fb98cdff..a5ff0bc310ffd 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -192,7 +192,7 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { const intptr_t fbo = delegate_->GLContextFBO(frame_info); onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context size, // root surface size - fbo // window FBO ID + fbo // window FBO ID ); if (onscreen_surface == nullptr) { @@ -302,7 +302,7 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, auto new_onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context current_size, // root surface size - fbo // window FBO ID + fbo // window FBO ID ); if (!new_onscreen_surface) { diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 0cf9fc2fb364b..bb26e3f205f8c 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -292,8 +292,7 @@ InferOpenGLPlatformViewCreationCallback( fbo_with_frame_info_callback = config->open_gl.fbo_with_frame_info_callback, fbo_with_damage_callback = config->open_gl.fbo_with_damage_callback, - user_data]( - flutter::GLFrameInfo gl_frame_info) -> FlutterFrameBuffer { + user_data](flutter::GLFrameInfo gl_frame_info) -> FlutterFrameBuffer { if (fbo_callback) { FlutterFrameBuffer fbo; fbo.fbo_id = fbo_callback(user_data); diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 47d15d7930a23..531c833f5760e 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -19,9 +19,9 @@ class EmbedderSurfaceGL final : public EmbedderSurface, std::function gl_make_current_callback; // required std::function gl_clear_current_callback; // required std::function)> - gl_present_callback; // required - std::function gl_fbo_callback; // required - std::function gl_make_resource_current_callback; // optional + gl_present_callback; // required + std::function gl_fbo_callback; // required + std::function gl_make_resource_current_callback; // optional std::function gl_surface_transformation_callback; // optional std::function gl_proc_resolver; // optional From 31a327858291511d115fab4b2d273d5e96fcb020 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Wed, 13 Jul 2022 11:40:58 -0700 Subject: [PATCH 11/38] Update comments. --- shell/gpu/gpu_surface_gl_delegate.h | 6 +----- shell/gpu/gpu_surface_gl_skia.cc | 16 ++++++---------- shell/platform/embedder/embedder_surface_gl.cc | 1 - 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index 39a50ce3db712..f9da6a11120fd 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -54,11 +54,7 @@ class GPUSurfaceGLDelegate { // context and not any of the contexts dedicated for IO. virtual bool GLContextPresent(const GLPresentInfo& present_info) = 0; - /// NEW: Changing the return type of GLContextFBO so that it can also return - /// the existing damage for that FBO. - // The information about the main window bound framebuffer such as ID and - // existing damage. ID is typically FBO0. Existing damage is only relevant - // when performing partial repaint. + // The ID of the main window bound framebuffer. Typically FBO0. virtual intptr_t GLContextFBO(GLFrameInfo frame_info) const = 0; // The rendering subsystem assumes that the ID of the main window bound diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index a5ff0bc310ffd..7ee6842b5dd91 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -187,12 +187,10 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { GLFrameInfo frame_info = {static_cast(size.width()), static_cast(size.height())}; - /// NEW: Updating the call to GLContextFBO to account for the FBO's existing - /// damage. - const intptr_t fbo = delegate_->GLContextFBO(frame_info); + const intptr_t fbo_id = delegate_->GLContextFBO(frame_info); onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context size, // root surface size - fbo // window FBO ID + fbo_id // window FBO ID ); if (onscreen_surface == nullptr) { @@ -203,7 +201,7 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { } onscreen_surface_ = std::move(onscreen_surface); - fbo_id_ = fbo; + fbo_id_ = fbo_id; return true; } @@ -296,13 +294,11 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, // The FBO has changed, ask the delegate for the new FBO and do a surface // re-wrap. - /// NEW: Updating the call to GLContextFBO to account for the FBO's existing - /// damage. - const intptr_t fbo = delegate_->GLContextFBO(frame_info); + const intptr_t fbo_id = delegate_->GLContextFBO(frame_info); auto new_onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context current_size, // root surface size - fbo // window FBO ID + fbo_id // window FBO ID ); if (!new_onscreen_surface) { @@ -310,7 +306,7 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, } onscreen_surface_ = std::move(new_onscreen_surface); - fbo_id_ = fbo; + fbo_id_ = fbo_id; } return true; diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index bc20ed631be4b..6e1451356c8ac 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -76,7 +76,6 @@ SurfaceFrame::FramebufferInfo EmbedderSurfaceGL::GLContextFramebufferInfo() const { SurfaceFrame::FramebufferInfo res; res.supports_readback = true; - res.supports_partial_repaint = true; res.existing_damage = existing_damage_; // TODO(btrevisan): confirm if cliping alignment needs to be updated. return res; From cc4c50de65132b9e1c271df198fb72386ece95d3 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Thu, 14 Jul 2022 17:07:16 -0700 Subject: [PATCH 12/38] Add initial unit tests. --- shell/platform/embedder/embedder.cc | 5 +++-- .../embedder/embedder_struct_macros.h | 4 ++++ .../embedder/tests/embedder_config_builder.cc | 4 ++++ .../embedder/tests/embedder_config_builder.h | 2 ++ .../embedder/tests/embedder_unittests_gl.cc | 22 +++++++++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index bb26e3f205f8c..32936f1d6ee52 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -125,8 +125,9 @@ static bool IsOpenGLRendererConfigValid(const FlutterRendererConfig* config) { if (!SAFE_EXISTS(open_gl_config, make_current) || !SAFE_EXISTS(open_gl_config, clear_current) || - !SAFE_EXISTS_ONE_OF(open_gl_config, fbo_callback, - fbo_with_frame_info_callback) || + !SAFE_EXISTS_ONE_OF_3(open_gl_config, fbo_callback, + fbo_with_frame_info_callback, + fbo_with_damage_callback) || !SAFE_EXISTS_ONE_OF(open_gl_config, present, present_with_info)) { return false; } diff --git a/shell/platform/embedder/embedder_struct_macros.h b/shell/platform/embedder/embedder_struct_macros.h index 8bd3097951286..6079c545abfa1 100644 --- a/shell/platform/embedder/embedder_struct_macros.h +++ b/shell/platform/embedder/embedder_struct_macros.h @@ -29,4 +29,8 @@ #define SAFE_EXISTS_ONE_OF(pointer, member1, member2) \ (SAFE_EXISTS(pointer, member1) != SAFE_EXISTS(pointer, member2)) +#define SAFE_EXISTS_ONE_OF_3(pointer, member1, member2, member3) \ + (((SAFE_EXISTS(pointer, member1) != SAFE_EXISTS(pointer, member2)) != SAFE_EXISTS(pointer, member3)) && \ + !(SAFE_EXISTS(pointer, member1) && SAFE_EXISTS(pointer, member2) && SAFE_EXISTS(pointer, member3))) + #endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index ae7e32f1cc86b..5d878480ab334 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -365,6 +365,10 @@ FlutterCompositor& EmbedderConfigBuilder::GetCompositor() { return compositor_; } +FlutterRendererConfig& EmbedderConfigBuilder::GetRendererConfig() { + return renderer_config_; +} + void EmbedderConfigBuilder::SetRenderTargetType( EmbedderTestBackingStoreProducer::RenderTargetType type) { auto& compositor = context_.GetCompositor(); diff --git a/shell/platform/embedder/tests/embedder_config_builder.h b/shell/platform/embedder/tests/embedder_config_builder.h index 2e2eb182326b6..8d5cbef8ae933 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.h +++ b/shell/platform/embedder/tests/embedder_config_builder.h @@ -104,6 +104,8 @@ class EmbedderConfigBuilder { FlutterCompositor& GetCompositor(); + FlutterRendererConfig& GetRendererConfig(); + void SetRenderTargetType( EmbedderTestBackingStoreProducer::RenderTargetType type); diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 9174461529058..a94a7defb29fd 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -44,6 +44,28 @@ namespace testing { using EmbedderTest = testing::EmbedderTest; +TEST_F(EmbedderTest, CanCreateOpenGLWithFBOWithDamageCallbackOnly) { + auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); + + EmbedderConfigBuilder builder(context); + + builder.SetOpenGLRendererConfig(SkISize::Make(600, 1024)); + + builder.GetRendererConfig().open_gl.fbo_with_damage_callback = [](void* userdata, const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { + // No need to fill in the returned FBO since it will not actually be used. + FlutterFrameBuffer fbo; + return fbo; + }; + + // Make sure other FBO callbacks are not defined. + builder.GetRendererConfig().open_gl.fbo_callback = nullptr; + builder.GetRendererConfig().open_gl.fbo_with_frame_info_callback = nullptr; + + auto engine = builder.LaunchEngine(); + + ASSERT_TRUE(engine.is_valid()); +} + TEST_F(EmbedderTest, CanGetVulkanEmbedderContext) { auto& context = GetEmbedderContext(EmbedderTestContextType::kVulkanContext); EmbedderConfigBuilder builder(context); From 175f053c29cf47cf3e344c4a51c32a05cddb9251 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Fri, 15 Jul 2022 14:20:57 -0700 Subject: [PATCH 13/38] Address design doc and code review feedback --- shell/gpu/gpu_surface_gl_delegate.h | 10 +++++- shell/gpu/gpu_surface_gl_skia.cc | 29 +++++++-------- shell/gpu/gpu_surface_gl_skia.h | 4 +-- shell/platform/embedder/embedder.cc | 32 +++-------------- shell/platform/embedder/embedder.h | 8 +---- .../platform/embedder/embedder_surface_gl.cc | 36 ++++++------------- shell/platform/embedder/embedder_surface_gl.h | 25 ++++--------- 7 files changed, 43 insertions(+), 101 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index f9da6a11120fd..9165b7ed94146 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -35,6 +35,14 @@ struct GLPresentInfo { std::optional presentation_time = std::nullopt; }; +// Information passed when an FBO is requested. +struct GLFBOInfo { + uint32_t fbo_id; + + // Refers to the FBO's damage since it was last used. + const SkIRect existing_damage; +}; + class GPUSurfaceGLDelegate { public: ~GPUSurfaceGLDelegate(); @@ -55,7 +63,7 @@ class GPUSurfaceGLDelegate { virtual bool GLContextPresent(const GLPresentInfo& present_info) = 0; // The ID of the main window bound framebuffer. Typically FBO0. - virtual intptr_t GLContextFBO(GLFrameInfo frame_info) const = 0; + virtual GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const = 0; // The rendering subsystem assumes that the ID of the main window bound // framebuffer remains constant throughout. If this assumption in incorrect, diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index 7ee6842b5dd91..b1131e1fbd740 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -86,12 +86,6 @@ GPUSurfaceGLSkia::GPUSurfaceGLSkia(sk_sp gr_context, delegate_->GLContextClearCurrent(); valid_ = gr_context != nullptr; - - /// NEW: Turning partial repaint on by default when a GPUSurfaceGLDelegate is - /// created. - // TODO(btrevisan): add functinality to disable partial repaint when desired. - // Partial Repaint is enabled by default. - partial_repaint_enabled_ = true; } GPUSurfaceGLSkia::~GPUSurfaceGLSkia() { @@ -187,10 +181,10 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { GLFrameInfo frame_info = {static_cast(size.width()), static_cast(size.height())}; - const intptr_t fbo_id = delegate_->GLContextFBO(frame_info); + const GLFBOInfo fbo_info = delegate_->GLContextFBO(frame_info); onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context size, // root surface size - fbo_id // window FBO ID + fbo_info.fbo_id // window FBO ID ); if (onscreen_surface == nullptr) { @@ -201,7 +195,8 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) { } onscreen_surface_ = std::move(onscreen_surface); - fbo_id_ = fbo_id; + fbo_id_ = fbo_info.fbo_id; + existing_damage_ = fbo_info.existing_damage; return true; } @@ -253,11 +248,10 @@ std::unique_ptr GPUSurfaceGLSkia::AcquireFrame( }; framebuffer_info = delegate_->GLContextFramebufferInfo(); - /// NEW: Populating framebuffer_info with necessary information for partial - /// repaint. - if (partial_repaint_enabled_) { - framebuffer_info.supports_partial_repaint = true; - } + // Partial repaint is enabled by default + framebuffer_info.supports_partial_repaint = true; + framebuffer_info.existing_damage = existing_damage_; + // TODO(btrevisa): figure out whether to set clip alignments. return std::make_unique(surface, std::move(framebuffer_info), submit_callback, std::move(context_switch)); @@ -294,11 +288,11 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, // The FBO has changed, ask the delegate for the new FBO and do a surface // re-wrap. - const intptr_t fbo_id = delegate_->GLContextFBO(frame_info); + const GLFBOInfo fbo__info = delegate_->GLContextFBO(frame_info); auto new_onscreen_surface = WrapOnscreenSurface(context_.get(), // GL context current_size, // root surface size - fbo_id // window FBO ID + fbo__info.fbo_id // window FBO ID ); if (!new_onscreen_surface) { @@ -306,7 +300,8 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, } onscreen_surface_ = std::move(new_onscreen_surface); - fbo_id_ = fbo_id; + fbo_id_ = fbo__info.fbo_id; + existing_damage_ = fbo__info.existing_damage; } return true; diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index f6a57e9a23f64..4317905e19b5e 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -67,6 +67,7 @@ class GPUSurfaceGLSkia : public Surface { sk_sp onscreen_surface_; /// FBO backing the current `onscreen_surface_`. uint32_t fbo_id_ = 0; + SkIRect existing_damage_ = SkIRect::MakeEmpty(); bool context_owner_ = false; // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. This is a @@ -74,9 +75,6 @@ class GPUSurfaceGLSkia : public Surface { // external view embedder is present. const bool render_to_surface_ = true; bool valid_ = false; - /// NEW: Adding partial_repaint_enabled_, a private variable that says whether - /// partial repaint is turned on or not. - bool partial_repaint_enabled_; // WeakPtrFactory must be the last member. fml::TaskRunnerAffineWeakPtrFactory weak_factory_; diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 32936f1d6ee52..0fbf1691ff1d5 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -125,9 +125,8 @@ static bool IsOpenGLRendererConfigValid(const FlutterRendererConfig* config) { if (!SAFE_EXISTS(open_gl_config, make_current) || !SAFE_EXISTS(open_gl_config, clear_current) || - !SAFE_EXISTS_ONE_OF_3(open_gl_config, fbo_callback, - fbo_with_frame_info_callback, - fbo_with_damage_callback) || + !SAFE_EXISTS_ONE_OF(open_gl_config, fbo_callback, + fbo_with_frame_info_callback) || !SAFE_EXISTS_ONE_OF(open_gl_config, present, present_with_info)) { return false; } @@ -250,14 +249,11 @@ InferOpenGLPlatformViewCreationCallback( auto gl_clear_current = [ptr = config->open_gl.clear_current, user_data]() -> bool { return ptr(user_data); }; - /// NEW: Changing the arguments to gl_present callback so that the embedder - /// can receive more information than just the fbo_id (e.g. damage). /// NOTE: this means that for partial repaint to work, we must have it use the /// present_with_info callback rather than the present callback. auto gl_present = [present = config->open_gl.present, present_with_info = config->open_gl.present_with_info, - user_data](flutter::GLPresentInfo gl_present_info, - std::optional damage_region) -> bool { + user_data](flutter::GLPresentInfo gl_present_info) -> bool { if (present) { return present(user_data); } else { @@ -270,20 +266,11 @@ InferOpenGLPlatformViewCreationCallback( frame_damage.struct_size = sizeof(FlutterDamage); frame_damage.damage = SkIRectToFlutterRect(gl_present_info.damage); - /// Format the buffer_damage appropriately. - FlutterDamage buffer_damage; - buffer_damage.struct_size = sizeof(FlutterDamage); - buffer_damage.damage = SkIRectToFlutterRect(damage_region); - present_info.frame_damage = frame_damage; - present_info.buffer_damage = buffer_damage; /// Pass the present_info to the present_with_info callback so that it can /// correctly only render part of the screen and save the FBO's damage /// region. - /// NOTE: alternatively, I could create a present callback that is - /// specific to partial repaint / damage tracking and leave - /// present_with_info as it is. return present_with_info(user_data, &present_info); } }; @@ -292,27 +279,16 @@ InferOpenGLPlatformViewCreationCallback( [fbo_callback = config->open_gl.fbo_callback, fbo_with_frame_info_callback = config->open_gl.fbo_with_frame_info_callback, - fbo_with_damage_callback = config->open_gl.fbo_with_damage_callback, user_data](flutter::GLFrameInfo gl_frame_info) -> FlutterFrameBuffer { if (fbo_callback) { FlutterFrameBuffer fbo; fbo.fbo_id = fbo_callback(user_data); return fbo; - } else if (fbo_with_frame_info_callback) { - FlutterFrameInfo frame_info = {}; - frame_info.struct_size = sizeof(FlutterFrameInfo); - frame_info.size = {gl_frame_info.width, gl_frame_info.height}; - - FlutterFrameBuffer fbo; - fbo.fbo_id = fbo_with_frame_info_callback(user_data, &frame_info); - return fbo; } else { FlutterFrameInfo frame_info = {}; frame_info.struct_size = sizeof(FlutterFrameInfo); frame_info.size = {gl_frame_info.width, gl_frame_info.height}; - - FlutterFrameBuffer fbo = fbo_with_damage_callback(user_data, &frame_info); - return fbo; + return fbo_with_frame_info_callback(user_data, &frame_info); } }; diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 61839b0326320..60d97a897d79d 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -386,8 +386,6 @@ typedef struct { /// NEW: Adding new struct so that the embedder can represent the idea of /// damage in a self-contained way. typedef struct { - /// The size of this struct. Must be sizeof(FlutterDamage). - size_t struct_size; // Rectangle that represents the area that needs to be rendered. FlutterRect damage; } FlutterDamage; @@ -431,11 +429,8 @@ typedef struct { size_t struct_size; /// Id of the fbo backing the surface that was presented. uint32_t fbo_id; - /// NEW: Adding new fields so that present with partial repaint works. /// Rectangle representing the area that the compositor needs to render. FlutterDamage frame_damage; - /// Rectangle representing the area that changed since FBO was last used. - FlutterDamage buffer_damage; } FlutterPresentInfo; /// Callback for when a surface is presented. @@ -494,14 +489,13 @@ typedef struct { /// surface from. When using this variant, the embedder is passed a /// `FlutterFrameInfo` struct that indicates the properties of the surface /// that flutter will acquire from the returned fbo. - UIntFrameInfoCallback fbo_with_frame_info_callback; + FlutterFrameBufferFrameInfoCallback fbo_with_frame_info_callback; /// Specifying one (and only one) of `present` or `present_with_info` is /// required. Specifying both is an error and engine initialization will be /// terminated. When using this variant, the embedder is passed a /// `FlutterPresentInfo` struct that the embedder can use to release any /// resources. The return value indicates success of the present call. BoolPresentInfoCallback present_with_info; - FlutterFrameBufferFrameInfoCallback fbo_with_damage_callback; } FlutterOpenGLRendererConfig; /// Alias for id. diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 6e1451356c8ac..7893d2711c97c 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -46,14 +46,14 @@ bool EmbedderSurfaceGL::GLContextClearCurrent() { // |GPUSurfaceGLDelegate| bool EmbedderSurfaceGL::GLContextPresent(const GLPresentInfo& present_info) { - /// NEW: Pass the damage region (as set by GLContextSetDamageRegion and the - /// frame damage (in present_info) so that the embedder can keep track of it. - return gl_dispatch_table_.gl_present_callback(present_info, damage_region_); + /// NEW: Pass the frame damage (in present_info) so that the embedder can keep + // track of it. + return gl_dispatch_table_.gl_present_callback(present_info); } /// NEW: Adding this function to make it easier to translate a FlutterRect back /// to a SkIRect. -SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { +const SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { SkIRect rect = {static_cast(flutter_rect.left), static_cast(flutter_rect.right), static_cast(flutter_rect.top), @@ -62,23 +62,16 @@ SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { } // |GPUSurfaceGLDelegate| -intptr_t EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { +GLFBOInfo EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { /// NEW: updating GLContextFBO to trigger a callback that will not only return /// the FBO ID but also its existing damage (at least when doing partial /// partial repaint. FlutterFrameBuffer fbo = gl_dispatch_table_.gl_fbo_callback(frame_info); - existing_damage_ = FlutterRectToSkIRect(fbo.damage.damage); - return fbo.fbo_id; -} - -// |GPUSurfaceGLDelegate| -SurfaceFrame::FramebufferInfo EmbedderSurfaceGL::GLContextFramebufferInfo() - const { - SurfaceFrame::FramebufferInfo res; - res.supports_readback = true; - res.existing_damage = existing_damage_; - // TODO(btrevisan): confirm if cliping alignment needs to be updated. - return res; + GLFBOInfo gl_fbo = { + static_cast(fbo.fbo_id), // fbo_id + FlutterRectToSkIRect(fbo.damage.damage), // existing_damage + }; + return gl_fbo; } // |GPUSurfaceGLDelegate| @@ -133,13 +126,4 @@ sk_sp EmbedderSurfaceGL::CreateResourceContext() const { "callback on FlutterOpenGLRendererConfig."; return nullptr; } - -void EmbedderSurfaceGL::GLContextSetDamageRegion( - const std::optional& region) { - /// NEW: Updating the damage_region_ so that it can be passed down to the - /// embedder using present_with_info. - /// NOTE: region here refers to the buffer_damage. - damage_region_ = region; -} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 531c833f5760e..7e6588fe378be 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -16,15 +16,14 @@ class EmbedderSurfaceGL final : public EmbedderSurface, public GPUSurfaceGLDelegate { public: struct GLDispatchTable { - std::function gl_make_current_callback; // required - std::function gl_clear_current_callback; // required - std::function)> - gl_present_callback; // required + std::function gl_make_current_callback; // required + std::function gl_clear_current_callback; // required + std::function gl_present_callback; // required std::function gl_fbo_callback; // required std::function gl_make_resource_current_callback; // optional std::function - gl_surface_transformation_callback; // optional - std::function gl_proc_resolver; // optional + gl_surface_transformation_callback; // optional + std::function gl_proc_resolver; // optional }; EmbedderSurfaceGL( @@ -38,12 +37,6 @@ class EmbedderSurfaceGL final : public EmbedderSurface, bool valid_ = false; GLDispatchTable gl_dispatch_table_; bool fbo_reset_after_present_; - /// NEW: Adding this private variable to keep track of the damage region of - /// the current buffer so that it can be passed to the present callback.s - std::optional damage_region_ = SkIRect::MakeEmpty(); - /// NEW: Adding fbo_existing_damage_, a private variable that keeps track of - /// the existing damage within the current FBO. - mutable std::optional existing_damage_ = SkIRect::MakeEmpty(); std::shared_ptr external_view_embedder_; @@ -66,10 +59,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface, bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - intptr_t GLContextFBO(GLFrameInfo frame_info) const override; - - // |GPUSurfaceGLDelegate| - SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override; + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; // |GPUSurfaceGLDelegate| bool GLContextFBOResetAfterPresent() const override; @@ -80,9 +70,6 @@ class EmbedderSurfaceGL final : public EmbedderSurface, // |GPUSurfaceGLDelegate| GLProcResolver GetGLProcResolver() const override; - // |GPUSurfaceGLDelegate| - void GLContextSetDamageRegion(const std::optional& region) override; - FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceGL); }; From 9db229939466919d84033c7f7a056675da2a650c Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Fri, 15 Jul 2022 14:46:37 -0700 Subject: [PATCH 14/38] fix return type of other function uses. --- shell/common/shell_test_platform_view_gl.cc | 5 +++-- shell/common/shell_test_platform_view_gl.h | 2 +- shell/platform/android/surface/android_surface_mock.cc | 4 ++-- shell/platform/android/surface/android_surface_mock.h | 2 +- .../darwin/macos/framework/Source/FlutterOpenGLRenderer.mm | 2 +- shell/platform/embedder/embedder.cc | 1 - shell/platform/embedder/tests/embedder_config_builder.cc | 6 ++++-- shell/platform/embedder/tests/embedder_test_context_gl.cc | 7 +++++-- shell/platform/embedder/tests/embedder_test_context_gl.h | 3 ++- shell/platform/embedder/tests/embedder_unittests_gl.cc | 3 +-- 10 files changed, 20 insertions(+), 15 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 492354230e8dc..e632c5324fc79 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -5,6 +5,7 @@ #include "flutter/shell/common/shell_test_platform_view_gl.h" #include "flutter/shell/gpu/gpu_surface_gl_skia.h" +#include "shell/gpu/gpu_surface_gl_delegate.h" namespace flutter { namespace testing { @@ -69,8 +70,8 @@ bool ShellTestPlatformViewGL::GLContextPresent( } // |GPUSurfaceGLDelegate| -intptr_t ShellTestPlatformViewGL::GLContextFBO(GLFrameInfo frame_info) const { - return gl_surface_.GetFramebuffer(frame_info.width, frame_info.height); +GLFBOInfo ShellTestPlatformViewGL::GLContextFBO(GLFrameInfo frame_info) const { + return GLFBOInfo{gl_surface_.GetFramebuffer(frame_info.width, frame_info.height)}; } // |GPUSurfaceGLDelegate| diff --git a/shell/common/shell_test_platform_view_gl.h b/shell/common/shell_test_platform_view_gl.h index c890c1e0fc6ec..b4afc1266975b 100644 --- a/shell/common/shell_test_platform_view_gl.h +++ b/shell/common/shell_test_platform_view_gl.h @@ -61,7 +61,7 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - intptr_t GLContextFBO(GLFrameInfo frame_info) const override; + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; // |GPUSurfaceGLDelegate| GLProcResolver GetGLProcResolver() const override; diff --git a/shell/platform/android/surface/android_surface_mock.cc b/shell/platform/android/surface/android_surface_mock.cc index c3a9f38fc8f0c..71be40b318f64 100644 --- a/shell/platform/android/surface/android_surface_mock.cc +++ b/shell/platform/android/surface/android_surface_mock.cc @@ -22,8 +22,8 @@ bool AndroidSurfaceMock::GLContextPresent(const GLPresentInfo& present_info) { return true; } -intptr_t AndroidSurfaceMock::GLContextFBO(GLFrameInfo frame_info) const { - return 0; +GLFBOInfo AndroidSurfaceMock::GLContextFBO(GLFrameInfo frame_info) const { + return GLFBOInfo{0}; } } // namespace flutter diff --git a/shell/platform/android/surface/android_surface_mock.h b/shell/platform/android/surface/android_surface_mock.h index d7363873a9a31..3f326a21920b7 100644 --- a/shell/platform/android/surface/android_surface_mock.h +++ b/shell/platform/android/surface/android_surface_mock.h @@ -51,7 +51,7 @@ class AndroidSurfaceMock final : public GPUSurfaceGLDelegate, bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - intptr_t GLContextFBO(GLFrameInfo frame_info) const override; + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; }; } // namespace flutter diff --git a/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm b/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm index a6abbc4ec5863..b73ef9a7a4134 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm @@ -148,7 +148,7 @@ - (FlutterRendererConfig)createRendererConfig { .open_gl.make_current = reinterpret_cast(OnMakeCurrent), .open_gl.clear_current = reinterpret_cast(OnClearCurrent), .open_gl.present = reinterpret_cast(OnPresent), - .open_gl.fbo_with_frame_info_callback = reinterpret_cast(OnFBO), + .open_gl.fbo_with_frame_info_callback = reinterpret_cast(OnFBO), .open_gl.fbo_reset_after_present = true, .open_gl.make_resource_current = reinterpret_cast(OnMakeResourceCurrent), .open_gl.gl_external_texture_frame_callback = diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 0fbf1691ff1d5..009c686d36fc8 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -263,7 +263,6 @@ InferOpenGLPlatformViewCreationCallback( /// Format the frame_damage appropriately. FlutterDamage frame_damage; - frame_damage.struct_size = sizeof(FlutterDamage); frame_damage.damage = SkIRectToFlutterRect(gl_present_info.damage); present_info.frame_damage = frame_damage; diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 5d878480ab334..cb81e5839e523 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -6,6 +6,7 @@ #include "flutter/runtime/dart_vm.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "shell/gpu/gpu_surface_gl_delegate.h" #include "tests/embedder_test_context.h" #include "third_party/skia/include/core/SkBitmap.h" #include "vulkan/vulkan_core.h" @@ -55,7 +56,7 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( present_info->fbo_id); }; opengl_renderer_config_.fbo_with_frame_info_callback = - [](void* context, const FlutterFrameInfo* frame_info) -> uint32_t { + [](void* context, const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { return reinterpret_cast(context)->GLGetFramebuffer( *frame_info); }; @@ -148,8 +149,9 @@ void EmbedderConfigBuilder::SetOpenGLFBOCallBack() { frame_info.struct_size = sizeof(FlutterFrameInfo); frame_info.size.width = 0; frame_info.size.height = 0; - return reinterpret_cast(context)->GLGetFramebuffer( + FlutterFrameBuffer fbo = reinterpret_cast(context)->GLGetFramebuffer( frame_info); + return fbo.fbo_id; }; #endif } diff --git a/shell/platform/embedder/tests/embedder_test_context_gl.cc b/shell/platform/embedder/tests/embedder_test_context_gl.cc index 9a7bc9bcf1c26..fbdb65ea5ee37 100644 --- a/shell/platform/embedder/tests/embedder_test_context_gl.cc +++ b/shell/platform/embedder/tests/embedder_test_context_gl.cc @@ -10,6 +10,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_assertions.h" #include "flutter/shell/platform/embedder/tests/embedder_test_compositor_gl.h" #include "flutter/testing/testing.h" +#include "shell/gpu/gpu_surface_gl_delegate.h" #include "tests/embedder_test.h" #include "third_party/dart/runtime/bin/elf_loader.h" #include "third_party/skia/include/core/SkSurface.h" @@ -69,7 +70,7 @@ void EmbedderTestContextGL::SetGLPresentCallback(GLPresentCallback callback) { gl_present_callback_ = callback; } -uint32_t EmbedderTestContextGL::GLGetFramebuffer(FlutterFrameInfo frame_info) { +FlutterFrameBuffer EmbedderTestContextGL::GLGetFramebuffer(FlutterFrameInfo frame_info) { FML_CHECK(gl_surface_) << "GL surface must be initialized."; GLGetFBOCallback callback; @@ -83,7 +84,9 @@ uint32_t EmbedderTestContextGL::GLGetFramebuffer(FlutterFrameInfo frame_info) { } const auto size = frame_info.size; - return gl_surface_->GetFramebuffer(size.width, size.height); + FlutterFrameBuffer fbo; + fbo.fbo_id = gl_surface_->GetFramebuffer(size.width, size.height); + return fbo; } bool EmbedderTestContextGL::GLMakeResourceCurrent() { diff --git a/shell/platform/embedder/tests/embedder_test_context_gl.h b/shell/platform/embedder/tests/embedder_test_context_gl.h index 65e2c34c355c2..5dd3b38093b71 100644 --- a/shell/platform/embedder/tests/embedder_test_context_gl.h +++ b/shell/platform/embedder/tests/embedder_test_context_gl.h @@ -7,6 +7,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_context.h" #include "flutter/testing/test_gl_surface.h" +#include "shell/gpu/gpu_surface_gl_delegate.h" namespace flutter { namespace testing { @@ -74,7 +75,7 @@ class EmbedderTestContextGL : public EmbedderTestContext { bool GLPresent(uint32_t fbo_id); - uint32_t GLGetFramebuffer(FlutterFrameInfo frame_info); + FlutterFrameBuffer GLGetFramebuffer(FlutterFrameInfo frame_info); bool GLMakeResourceCurrent(); diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index a94a7defb29fd..62cc399ec141e 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -51,7 +51,7 @@ TEST_F(EmbedderTest, CanCreateOpenGLWithFBOWithDamageCallbackOnly) { builder.SetOpenGLRendererConfig(SkISize::Make(600, 1024)); - builder.GetRendererConfig().open_gl.fbo_with_damage_callback = [](void* userdata, const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { + builder.GetRendererConfig().open_gl.fbo_with_frame_info_callback = [](void* userdata, const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { // No need to fill in the returned FBO since it will not actually be used. FlutterFrameBuffer fbo; return fbo; @@ -59,7 +59,6 @@ TEST_F(EmbedderTest, CanCreateOpenGLWithFBOWithDamageCallbackOnly) { // Make sure other FBO callbacks are not defined. builder.GetRendererConfig().open_gl.fbo_callback = nullptr; - builder.GetRendererConfig().open_gl.fbo_with_frame_info_callback = nullptr; auto engine = builder.LaunchEngine(); From c193aecf06f5ad7f9043c0ab0613fe68bc107914 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 10:43:14 -0700 Subject: [PATCH 15/38] fix compatibility issues. --- shell/platform/android/android_surface_gl_impeller.h | 2 +- shell/platform/android/android_surface_gl_skia.cc | 5 +++-- shell/platform/android/android_surface_gl_skia.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shell/platform/android/android_surface_gl_impeller.h b/shell/platform/android/android_surface_gl_impeller.h index 8bcf14dbee27b..9d2399868da97 100644 --- a/shell/platform/android/android_surface_gl_impeller.h +++ b/shell/platform/android/android_surface_gl_impeller.h @@ -68,7 +68,7 @@ class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate, bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - intptr_t GLContextFBO(GLFrameInfo frame_info) const override; + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; // |GPUSurfaceGLDelegate| sk_sp GetGLInterface() const override; diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 23242c9b3bad4..d4efe282e6b09 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -9,6 +9,7 @@ #include "flutter/fml/logging.h" #include "flutter/fml/memory/ref_ptr.h" +#include "flutter/shell/gpu/gpu_surface_gl_delegate.h" #include "flutter/shell/platform/android/android_egl_surface.h" #include "flutter/shell/platform/android/android_shell_holder.h" @@ -162,10 +163,10 @@ bool AndroidSurfaceGLSkia::GLContextPresent(const GLPresentInfo& present_info) { return onscreen_surface_->SwapBuffers(present_info.damage); } -intptr_t AndroidSurfaceGLSkia::GLContextFBO(GLFrameInfo frame_info) const { +GLFBOInfo AndroidSurfaceGLSkia::GLContextFBO(GLFrameInfo frame_info) const { FML_DCHECK(IsValid()); // The default window bound framebuffer on Android. - return 0; + return GLFBOInfo{0}; } // |GPUSurfaceGLDelegate| diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index 99a910b69b76d..73f36945127f8 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -67,7 +67,7 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - intptr_t GLContextFBO(GLFrameInfo frame_info) const override; + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; // |GPUSurfaceGLDelegate| sk_sp GetGLInterface() const override; From ea3bd1d987b031d500588b9e3f4b49d26e4636a2 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 10:51:59 -0700 Subject: [PATCH 16/38] fix function return value. --- shell/platform/darwin/ios/ios_surface_gl.h | 3 ++- shell/platform/darwin/ios/ios_surface_gl.mm | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/ios/ios_surface_gl.h b/shell/platform/darwin/ios/ios_surface_gl.h index 28ad45eb30f96..5b58558622da9 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.h +++ b/shell/platform/darwin/ios/ios_surface_gl.h @@ -9,6 +9,7 @@ #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/gpu/gpu_surface_gl_skia.h" #import "flutter/shell/platform/darwin/ios/ios_context.h" +#include "shell/gpu/gpu_surface_gl_delegate.h" #import "flutter/shell/platform/darwin/ios/ios_render_target_gl.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" @@ -41,7 +42,7 @@ class IOSSurfaceGL final : public IOSSurface, public GPUSurfaceGLDelegate { bool GLContextPresent(const GLPresentInfo& present_info) override; // |GPUSurfaceGLDelegate| - intptr_t GLContextFBO(GLFrameInfo frame_info) const override; + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; // |GPUSurfaceGLDelegate| SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override; diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index 7c5e7ec8e2c71..d3fa8a71daa68 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -3,6 +3,7 @@ // found in the LICENSE file. #import "flutter/shell/platform/darwin/ios/ios_surface_gl.h" +#include "shell/gpu/gpu_surface_gl_delegate.h" #include "flutter/fml/trace_event.h" #include "flutter/shell/gpu/gpu_surface_gl_skia.h" @@ -51,8 +52,8 @@ } // |GPUSurfaceGLDelegate| -intptr_t IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { - return IsValid() ? render_target_->GetFramebuffer() : GL_NONE; +GLFBOInfo IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { + return IsValid() ? GLFBOInfo{render_target_->GetFramebuffer()} : GLFBOInfo{GL_NONE}; } // |GPUSurfaceGLDelegate| From ede0f2b9c58c721e179f2a0e66f819aa221936e9 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 11:00:06 -0700 Subject: [PATCH 17/38] casting issue --- shell/platform/darwin/ios/ios_surface_gl.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index d3fa8a71daa68..fe8912a085d14 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -53,7 +53,7 @@ // |GPUSurfaceGLDelegate| GLFBOInfo IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { - return IsValid() ? GLFBOInfo{render_target_->GetFramebuffer()} : GLFBOInfo{GL_NONE}; + return IsValid() ? GLFBOInfo{static_cast(render_target_->GetFramebuffer())} : GLFBOInfo{GL_NONE}; } // |GPUSurfaceGLDelegate| From b07cf3110bd6d9161a58f516bf915670bc865834 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 11:15:44 -0700 Subject: [PATCH 18/38] fixes --- shell/common/shell_test_platform_view_gl.cc | 3 ++- shell/gpu/gpu_surface_gl_delegate.h | 2 +- shell/platform/darwin/ios/ios_surface_gl.h | 2 +- shell/platform/darwin/ios/ios_surface_gl.mm | 2 +- shell/platform/windows/flutter_windows_engine.cc | 11 ++++++++--- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index e632c5324fc79..1a5c13cb7e5ab 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -71,7 +71,8 @@ bool ShellTestPlatformViewGL::GLContextPresent( // |GPUSurfaceGLDelegate| GLFBOInfo ShellTestPlatformViewGL::GLContextFBO(GLFrameInfo frame_info) const { - return GLFBOInfo{gl_surface_.GetFramebuffer(frame_info.width, frame_info.height)}; + return GLFBOInfo{ + gl_surface_.GetFramebuffer(frame_info.width, frame_info.height)}; } // |GPUSurfaceGLDelegate| diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index 9165b7ed94146..8df0075f82e9e 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -24,7 +24,7 @@ struct GLFrameInfo { // Information passed during presentation of a frame. struct GLPresentInfo { - uint32_t fbo_id; + intptr_t fbo_id; // Damage is a hint to compositor telling it which parts of front buffer // need to be updated diff --git a/shell/platform/darwin/ios/ios_surface_gl.h b/shell/platform/darwin/ios/ios_surface_gl.h index 5b58558622da9..fd718efc9fd59 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.h +++ b/shell/platform/darwin/ios/ios_surface_gl.h @@ -9,9 +9,9 @@ #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/gpu/gpu_surface_gl_skia.h" #import "flutter/shell/platform/darwin/ios/ios_context.h" -#include "shell/gpu/gpu_surface_gl_delegate.h" #import "flutter/shell/platform/darwin/ios/ios_render_target_gl.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" +#include "shell/gpu/gpu_surface_gl_delegate.h" @class CAEAGLLayer; diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index fe8912a085d14..d3fa8a71daa68 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -53,7 +53,7 @@ // |GPUSurfaceGLDelegate| GLFBOInfo IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { - return IsValid() ? GLFBOInfo{static_cast(render_target_->GetFramebuffer())} : GLFBOInfo{GL_NONE}; + return IsValid() ? GLFBOInfo{render_target_->GetFramebuffer()} : GLFBOInfo{GL_NONE}; } // |GPUSurfaceGLDelegate| diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index ceb4634d433b5..5a09f1bb39758 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -9,6 +9,7 @@ #include #include "flutter/fml/platform/win/wstring_conversion.h" +#include "flutter/shell/gpu/gpu_surface_gl_delegate.h" #include "flutter/shell/platform/common/client_wrapper/binary_messenger_impl.h" #include "flutter/shell/platform/common/path_utils.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" @@ -67,13 +68,17 @@ FlutterRendererConfig GetOpenGLRendererConfig() { }; config.open_gl.fbo_reset_after_present = true; config.open_gl.fbo_with_frame_info_callback = - [](void* user_data, const FlutterFrameInfo* info) -> uint32_t { + [](void* user_data, const FlutterFrameInfo* info) -> FlutterFrameBuffer { auto host = static_cast(user_data); if (host->view()) { - return host->view()->GetFrameBufferId(info->size.width, + FlutterFrameBuffer fbo; + fbo.fbo_id = host->view()->GetFrameBufferId(info->size.width, info->size.height); + return fbo; } else { - return kWindowFrameBufferID; + FlutterFrameBuffer fbo; + fbo.fbo_id = kWindowFrameBufferID; + return fbo; } }; config.open_gl.gl_proc_resolver = [](void* user_data, From 1766c2e91444cbc777695ba902d5125c822a8706 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 11:58:33 -0700 Subject: [PATCH 19/38] fixes --- shell/gpu/gpu_surface_gl_skia.cc | 8 ++++---- shell/platform/android/android_surface_gl_impeller.cc | 5 +++-- .../macos/framework/Source/FlutterOpenGLRenderer.mm | 3 ++- shell/platform/embedder/embedder.cc | 7 ++++--- shell/platform/embedder/embedder_struct_macros.h | 6 +----- shell/platform/embedder/embedder_surface_gl.cc | 4 ++-- shell/platform/embedder/embedder_surface_gl.h | 4 ++-- shell/platform/embedder/tests/embedder_config_builder.cc | 6 +++--- shell/platform/embedder/tests/embedder_test_context_gl.cc | 3 ++- shell/platform/embedder/tests/embedder_unittests_gl.cc | 4 +++- shell/platform/windows/flutter_windows_engine.cc | 4 ++-- 11 files changed, 28 insertions(+), 26 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index b1131e1fbd740..25879a0499cb9 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -271,7 +271,7 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, } GLPresentInfo present_info = { - .fbo_id = fbo_id_, + .fbo_id = static_cast(fbo_id_), .damage = frame.submit_info().frame_damage, .presentation_time = frame.submit_info().presentation_time, }; @@ -290,9 +290,9 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, // re-wrap. const GLFBOInfo fbo__info = delegate_->GLContextFBO(frame_info); auto new_onscreen_surface = - WrapOnscreenSurface(context_.get(), // GL context - current_size, // root surface size - fbo__info.fbo_id // window FBO ID + WrapOnscreenSurface(context_.get(), // GL context + current_size, // root surface size + fbo__info.fbo_id // window FBO ID ); if (!new_onscreen_surface) { diff --git a/shell/platform/android/android_surface_gl_impeller.cc b/shell/platform/android/android_surface_gl_impeller.cc index 28c1cfe55f19e..8eef4f494aca9 100644 --- a/shell/platform/android/android_surface_gl_impeller.cc +++ b/shell/platform/android/android_surface_gl_impeller.cc @@ -10,6 +10,7 @@ #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_delegate.h" #include "flutter/shell/gpu/gpu_surface_gl_impeller.h" namespace flutter { @@ -295,9 +296,9 @@ bool AndroidSurfaceGLImpeller::GLContextPresent( } // |GPUSurfaceGLDelegate| -intptr_t AndroidSurfaceGLImpeller::GLContextFBO(GLFrameInfo frame_info) const { +GLFBOInfo AndroidSurfaceGLImpeller::GLContextFBO(GLFrameInfo frame_info) const { // FBO0 is the default window bound framebuffer in EGL environments. - return 0; + return GLFBOInfo{0}; } // |GPUSurfaceGLDelegate| diff --git a/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm b/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm index b73ef9a7a4134..d20a064a5eff1 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRenderer.mm @@ -148,7 +148,8 @@ - (FlutterRendererConfig)createRendererConfig { .open_gl.make_current = reinterpret_cast(OnMakeCurrent), .open_gl.clear_current = reinterpret_cast(OnClearCurrent), .open_gl.present = reinterpret_cast(OnPresent), - .open_gl.fbo_with_frame_info_callback = reinterpret_cast(OnFBO), + .open_gl.fbo_with_frame_info_callback = + reinterpret_cast(OnFBO), .open_gl.fbo_reset_after_present = true, .open_gl.make_resource_current = reinterpret_cast(OnMakeResourceCurrent), .open_gl.gl_external_texture_frame_callback = diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 009c686d36fc8..3ed75cad7b0c4 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -251,9 +251,10 @@ InferOpenGLPlatformViewCreationCallback( /// NOTE: this means that for partial repaint to work, we must have it use the /// present_with_info callback rather than the present callback. - auto gl_present = [present = config->open_gl.present, - present_with_info = config->open_gl.present_with_info, - user_data](flutter::GLPresentInfo gl_present_info) -> bool { + auto gl_present = + [present = config->open_gl.present, + present_with_info = config->open_gl.present_with_info, + user_data](flutter::GLPresentInfo gl_present_info) -> bool { if (present) { return present(user_data); } else { diff --git a/shell/platform/embedder/embedder_struct_macros.h b/shell/platform/embedder/embedder_struct_macros.h index 6079c545abfa1..11c417fba4fe6 100644 --- a/shell/platform/embedder/embedder_struct_macros.h +++ b/shell/platform/embedder/embedder_struct_macros.h @@ -28,9 +28,5 @@ /// Checks if exactly one of member1 or member2 exists and is non-null. #define SAFE_EXISTS_ONE_OF(pointer, member1, member2) \ (SAFE_EXISTS(pointer, member1) != SAFE_EXISTS(pointer, member2)) - -#define SAFE_EXISTS_ONE_OF_3(pointer, member1, member2, member3) \ - (((SAFE_EXISTS(pointer, member1) != SAFE_EXISTS(pointer, member2)) != SAFE_EXISTS(pointer, member3)) && \ - !(SAFE_EXISTS(pointer, member1) && SAFE_EXISTS(pointer, member2) && SAFE_EXISTS(pointer, member3))) - + #endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 7893d2711c97c..162084f843f41 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -68,8 +68,8 @@ GLFBOInfo EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { /// partial repaint. FlutterFrameBuffer fbo = gl_dispatch_table_.gl_fbo_callback(frame_info); GLFBOInfo gl_fbo = { - static_cast(fbo.fbo_id), // fbo_id - FlutterRectToSkIRect(fbo.damage.damage), // existing_damage + static_cast(fbo.fbo_id), // fbo_id + FlutterRectToSkIRect(fbo.damage.damage), // existing_damage }; return gl_fbo; } diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 7e6588fe378be..c575f1bc29f29 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -22,8 +22,8 @@ class EmbedderSurfaceGL final : public EmbedderSurface, std::function gl_fbo_callback; // required std::function gl_make_resource_current_callback; // optional std::function - gl_surface_transformation_callback; // optional - std::function gl_proc_resolver; // optional + gl_surface_transformation_callback; // optional + std::function gl_proc_resolver; // optional }; EmbedderSurfaceGL( diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index cb81e5839e523..058ffabcfa3c2 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -6,7 +6,6 @@ #include "flutter/runtime/dart_vm.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "shell/gpu/gpu_surface_gl_delegate.h" #include "tests/embedder_test_context.h" #include "third_party/skia/include/core/SkBitmap.h" #include "vulkan/vulkan_core.h" @@ -149,8 +148,9 @@ void EmbedderConfigBuilder::SetOpenGLFBOCallBack() { frame_info.struct_size = sizeof(FlutterFrameInfo); frame_info.size.width = 0; frame_info.size.height = 0; - FlutterFrameBuffer fbo = reinterpret_cast(context)->GLGetFramebuffer( - frame_info); + FlutterFrameBuffer fbo = + reinterpret_cast(context)->GLGetFramebuffer( + frame_info); return fbo.fbo_id; }; #endif diff --git a/shell/platform/embedder/tests/embedder_test_context_gl.cc b/shell/platform/embedder/tests/embedder_test_context_gl.cc index fbdb65ea5ee37..79936e380553b 100644 --- a/shell/platform/embedder/tests/embedder_test_context_gl.cc +++ b/shell/platform/embedder/tests/embedder_test_context_gl.cc @@ -70,7 +70,8 @@ void EmbedderTestContextGL::SetGLPresentCallback(GLPresentCallback callback) { gl_present_callback_ = callback; } -FlutterFrameBuffer EmbedderTestContextGL::GLGetFramebuffer(FlutterFrameInfo frame_info) { +FlutterFrameBuffer EmbedderTestContextGL::GLGetFramebuffer( + FlutterFrameInfo frame_info) { FML_CHECK(gl_surface_) << "GL surface must be initialized."; GLGetFBOCallback callback; diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 62cc399ec141e..17a350c9d9b61 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -51,7 +51,9 @@ TEST_F(EmbedderTest, CanCreateOpenGLWithFBOWithDamageCallbackOnly) { builder.SetOpenGLRendererConfig(SkISize::Make(600, 1024)); - builder.GetRendererConfig().open_gl.fbo_with_frame_info_callback = [](void* userdata, const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { + builder.GetRendererConfig().open_gl.fbo_with_frame_info_callback = + [](void* userdata, + const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { // No need to fill in the returned FBO since it will not actually be used. FlutterFrameBuffer fbo; return fbo; diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 5a09f1bb39758..9504e2b7ba26c 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -72,8 +72,8 @@ FlutterRendererConfig GetOpenGLRendererConfig() { auto host = static_cast(user_data); if (host->view()) { FlutterFrameBuffer fbo; - fbo.fbo_id = host->view()->GetFrameBufferId(info->size.width, - info->size.height); + fbo.fbo_id = + host->view()->GetFrameBufferId(info->size.width, info->size.height); return fbo; } else { FlutterFrameBuffer fbo; From cd34a55e05f94b179e728df79ed137aa7bdb3743 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 12:03:39 -0700 Subject: [PATCH 20/38] static cast fix --- shell/platform/darwin/ios/ios_surface_gl.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index d3fa8a71daa68..fe8912a085d14 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -53,7 +53,7 @@ // |GPUSurfaceGLDelegate| GLFBOInfo IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { - return IsValid() ? GLFBOInfo{render_target_->GetFramebuffer()} : GLFBOInfo{GL_NONE}; + return IsValid() ? GLFBOInfo{static_cast(render_target_->GetFramebuffer())} : GLFBOInfo{GL_NONE}; } // |GPUSurfaceGLDelegate| From 1a0e24f1ad5f6acb33427fe48cd1c34cc6e2fe27 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 12:10:10 -0700 Subject: [PATCH 21/38] formatting --- shell/platform/embedder/embedder_surface_gl.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 162084f843f41..480a39b0b6d28 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -68,8 +68,8 @@ GLFBOInfo EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { /// partial repaint. FlutterFrameBuffer fbo = gl_dispatch_table_.gl_fbo_callback(frame_info); GLFBOInfo gl_fbo = { - static_cast(fbo.fbo_id), // fbo_id - FlutterRectToSkIRect(fbo.damage.damage), // existing_damage + static_cast(fbo.fbo_id), // fbo_id + FlutterRectToSkIRect(fbo.damage.damage), // existing_damage }; return gl_fbo; } From ace9dad36a2df80a641175d484b27318c105f3e1 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 12:10:19 -0700 Subject: [PATCH 22/38] formatting --- shell/platform/embedder/tests/embedder_config_builder.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 058ffabcfa3c2..970df93d30a28 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -55,7 +55,8 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( present_info->fbo_id); }; opengl_renderer_config_.fbo_with_frame_info_callback = - [](void* context, const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { + [](void* context, + const FlutterFrameInfo* frame_info) -> FlutterFrameBuffer { return reinterpret_cast(context)->GLGetFramebuffer( *frame_info); }; From 8f696ffb26d847acd9343647e19431e4b2813cff Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 12:12:10 -0700 Subject: [PATCH 23/38] import fix --- shell/platform/windows/flutter_windows_engine.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 9504e2b7ba26c..45f798ccfbe5a 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -9,7 +9,6 @@ #include #include "flutter/fml/platform/win/wstring_conversion.h" -#include "flutter/shell/gpu/gpu_surface_gl_delegate.h" #include "flutter/shell/platform/common/client_wrapper/binary_messenger_impl.h" #include "flutter/shell/platform/common/path_utils.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" From 467df12cc2a7dd2a658fa41fec7807bacb23af85 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 18 Jul 2022 12:27:45 -0700 Subject: [PATCH 24/38] formatting --- shell/platform/darwin/ios/ios_surface_gl.mm | 3 ++- shell/platform/embedder/embedder_struct_macros.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index fe8912a085d14..8d1486fba44d2 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -53,7 +53,8 @@ // |GPUSurfaceGLDelegate| GLFBOInfo IOSSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { - return IsValid() ? GLFBOInfo{static_cast(render_target_->GetFramebuffer())} : GLFBOInfo{GL_NONE}; + return IsValid() ? GLFBOInfo{static_cast(render_target_->GetFramebuffer())} + : GLFBOInfo{GL_NONE}; } // |GPUSurfaceGLDelegate| diff --git a/shell/platform/embedder/embedder_struct_macros.h b/shell/platform/embedder/embedder_struct_macros.h index 11c417fba4fe6..8bd3097951286 100644 --- a/shell/platform/embedder/embedder_struct_macros.h +++ b/shell/platform/embedder/embedder_struct_macros.h @@ -28,5 +28,5 @@ /// Checks if exactly one of member1 or member2 exists and is non-null. #define SAFE_EXISTS_ONE_OF(pointer, member1, member2) \ (SAFE_EXISTS(pointer, member1) != SAFE_EXISTS(pointer, member2)) - + #endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ From 770fafa94c37c7cabd16995674313ed7fbdcc9f3 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Wed, 20 Jul 2022 22:45:51 -0700 Subject: [PATCH 25/38] update present callback --- examples/glfw/FlutterEmbedderGLFW.cc | 13 +++++++++++-- shell/gpu/gpu_surface_gl_delegate.h | 4 +++- shell/gpu/gpu_surface_gl_skia.cc | 3 ++- shell/platform/embedder/embedder.cc | 6 +++++- shell/platform/embedder/embedder.h | 2 ++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index 8b17b25958fc1..58ea6a27de5dc 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -96,8 +96,17 @@ bool RunFlutter(GLFWwindow* window, glfwMakeContextCurrent(nullptr); // is this even a thing? return true; }; - config.open_gl.present = [](void* userdata) -> bool { - glfwSwapBuffers(static_cast(userdata)); + config.open_gl.present_with_info = [](void* userdata, const FlutterPresentInfo* info) -> bool { + swap_buffers_with_damage_ = + reinterpret_cast( + eglGetProcAddress("eglSwapBuffersWithDamageKHR")); + + info-> + + GLFWwindow* window = static_cast(userdata); + swap_buffers_with_damage_(eglGetDisplay(window), window->context.egl.surface) + + //glfwSwapBuffers(static_cast(userdata)); return true; }; config.open_gl.fbo_callback = [](void*) -> uint32_t { diff --git a/shell/gpu/gpu_surface_gl_delegate.h b/shell/gpu/gpu_surface_gl_delegate.h index 8df0075f82e9e..5451c6d838f1e 100644 --- a/shell/gpu/gpu_surface_gl_delegate.h +++ b/shell/gpu/gpu_surface_gl_delegate.h @@ -28,11 +28,13 @@ struct GLPresentInfo { // Damage is a hint to compositor telling it which parts of front buffer // need to be updated - const std::optional& damage; + const std::optional& frame_damage; // Time at which this frame is scheduled to be presented. This is a hint // that can be passed to the platform to drop queued frames. std::optional presentation_time = std::nullopt; + + const std::optional& buffer_damage; }; // Information passed when an FBO is requested. diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index 25879a0499cb9..91f0b1d2b3063 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -272,8 +272,9 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, GLPresentInfo present_info = { .fbo_id = static_cast(fbo_id_), - .damage = frame.submit_info().frame_damage, + .frame_damage = frame.submit_info().frame_damage, .presentation_time = frame.submit_info().presentation_time, + .buffer_damage = frame.submit_info().buffer_damage }; if (!delegate_->GLContextPresent(present_info)) { return false; diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 3ed75cad7b0c4..7cd2836f4fcde 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -264,10 +264,14 @@ InferOpenGLPlatformViewCreationCallback( /// Format the frame_damage appropriately. FlutterDamage frame_damage; - frame_damage.damage = SkIRectToFlutterRect(gl_present_info.damage); + frame_damage.damage = SkIRectToFlutterRect(gl_present_info.frame_damage); present_info.frame_damage = frame_damage; + FlutterDamage buffer_damage; + frame_damage.damage = SkIRectToFlutterRect(gl_present_info.buffer_damage); + present_info.buffer_damage = buffer_damage; + /// Pass the present_info to the present_with_info callback so that it can /// correctly only render part of the screen and save the FBO's damage /// region. diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 60d97a897d79d..11e9a2661cdb8 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -431,6 +431,8 @@ typedef struct { uint32_t fbo_id; /// Rectangle representing the area that the compositor needs to render. FlutterDamage frame_damage; + /// Rectangle used to set the buffer's damage region. + FlutterDamage buffer_damage; } FlutterPresentInfo; /// Callback for when a surface is presented. From 9a99192db078e49a6d4e2fa853c9d19b9f39c21e Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Wed, 20 Jul 2022 22:53:44 -0700 Subject: [PATCH 26/38] fix affected functions --- shell/gpu/gpu_surface_gl_impeller.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/gpu/gpu_surface_gl_impeller.cc b/shell/gpu/gpu_surface_gl_impeller.cc index 24413147274a6..5bedb17fe5f0e 100644 --- a/shell/gpu/gpu_surface_gl_impeller.cc +++ b/shell/gpu/gpu_surface_gl_impeller.cc @@ -62,10 +62,11 @@ std::unique_ptr GPUSurfaceGLImpeller::AcquireFrame( if (weak) { GLPresentInfo present_info = { .fbo_id = 0, - .damage = std::nullopt, + .frame_damage = std::nullopt, // TODO (https://github.com/flutter/flutter/issues/105597): wire-up // presentation time to impeller backend. .presentation_time = std::nullopt, + .buffer_damage = std::nullopt }; delegate->GLContextPresent(present_info); } From 7ec053b8b8b6ddfd46cc21c7240fecc044b8f0b1 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Thu, 21 Jul 2022 08:33:26 -0700 Subject: [PATCH 27/38] glfw example --- examples/glfw/BUILD.gn | 5 ++++ examples/glfw/CMakeLists.txt | 5 +++- examples/glfw/FlutterEmbedderGLFW.cc | 35 ++++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/examples/glfw/BUILD.gn b/examples/glfw/BUILD.gn index 2ff312c0ee8b5..fe76acb0e63b5 100644 --- a/examples/glfw/BUILD.gn +++ b/examples/glfw/BUILD.gn @@ -14,5 +14,10 @@ if (build_embedder_examples) { "//flutter/shell/platform/embedder:embedder", "//third_party/glfw", ] + + libs = [ + "EGL", + "GLESv2", + ] } } diff --git a/examples/glfw/CMakeLists.txt b/examples/glfw/CMakeLists.txt index 53bca275dc673..cc17cd89d2f74 100644 --- a/examples/glfw/CMakeLists.txt +++ b/examples/glfw/CMakeLists.txt @@ -4,6 +4,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" ) add_executable(flutter_glfw FlutterEmbedderGLFW.cc) +find_package(OpenGL REQUIRED COMPONENTS EGL) +include_directories(${OPENGL_INCLUDE_DIRS}) + ############################################################ # GLFW ############################################################ @@ -12,7 +15,7 @@ option(GLFW_BUILD_TESTS "" OFF) option(GLFW_BUILD_DOCS "" OFF) option(GLFW_INSTALL "" OFF) add_subdirectory(${CMAKE_SOURCE_DIR}/../../../third_party/glfw glfw) -target_link_libraries(flutter_glfw glfw) +target_link_libraries(flutter_glfw glfw OpenGL::EGL) include_directories(${CMAKE_SOURCE_DIR}/../../../third_party/glfw/include) ############################################################ diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index 58ea6a27de5dc..9ba36c2dd65df 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -6,11 +6,19 @@ #include #include +#define GLFW_EXPOSE_NATIVE_EGL + +#include #include "GLFW/glfw3.h" +#include "GLFW/glfw3native.h" #include "embedder.h" +#include +#include + // This value is calculated after the window is created. static double g_pixelRatio = 1.0; + static const size_t kInitialWindowWidth = 800; static const size_t kInitialWindowHeight = 600; @@ -82,6 +90,17 @@ void GLFWwindowSizeCallback(GLFWwindow* window, int width, int height) { &event); } +std::array static RectToInts(EGLDisplay display, + EGLSurface surface, + const FlutterRect rect) { + EGLint height; + eglQuerySurface(display, surface, EGL_HEIGHT, &height); + + std::array res{static_cast(rect.left), height - static_cast(rect.bottom), static_cast(rect.right) - static_cast(rect.left), + static_cast(rect.top) - static_cast(rect.bottom)}; + return res; +} + bool RunFlutter(GLFWwindow* window, const std::string& project_path, const std::string& icudtl_path) { @@ -97,19 +116,27 @@ bool RunFlutter(GLFWwindow* window, return true; }; config.open_gl.present_with_info = [](void* userdata, const FlutterPresentInfo* info) -> bool { - swap_buffers_with_damage_ = + PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage_ = reinterpret_cast( eglGetProcAddress("eglSwapBuffersWithDamageKHR")); - - info-> GLFWwindow* window = static_cast(userdata); - swap_buffers_with_damage_(eglGetDisplay(window), window->context.egl.surface) + + auto rects = RectToInts(glfwGetEGLDisplay(), glfwGetEGLSurface(window), info->frame_damage.damage); + + swap_buffers_with_damage_(glfwGetEGLDisplay(), glfwGetEGLSurface(window), rects.data(), 1); + + std::cout << info->frame_damage.damage.top << ", " << info->frame_damage.damage.bottom << ", " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.right << std::endl; + + // for (auto rect : rects) { + // std::cout << rect.x << ", " << rect.y << std::endl; + // } //glfwSwapBuffers(static_cast(userdata)); return true; }; config.open_gl.fbo_callback = [](void*) -> uint32_t { + //std::cout << fbo.fbo_id << std::endl; return 0; // FBO0 }; config.open_gl.gl_proc_resolver = [](void*, const char* name) -> void* { From 856590f8a7ddb380659e3df8bca502cdfd966c97 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Thu, 21 Jul 2022 09:00:06 -0700 Subject: [PATCH 28/38] glfw example --- examples/glfw/FlutterEmbedderGLFW.cc | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index 9ba36c2dd65df..b0e25ac524ce6 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -116,26 +116,42 @@ bool RunFlutter(GLFWwindow* window, return true; }; config.open_gl.present_with_info = [](void* userdata, const FlutterPresentInfo* info) -> bool { + PFNEGLSETDAMAGEREGIONKHRPROC set_damage_region_ = + reinterpret_cast( + eglGetProcAddress("eglSetDamageRegionKHR")); PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage_ = reinterpret_cast( eglGetProcAddress("eglSwapBuffersWithDamageKHR")); + GLFWwindow* window = static_cast(userdata); + EGLDisplay display = glfwGetEGLDisplay(); + EGLSurface surface = glfwGetEGLSurface(window); - auto rects = RectToInts(glfwGetEGLDisplay(), glfwGetEGLSurface(window), info->frame_damage.damage); + // Set damage region with buffer damage + auto buffer_rects = RectToInts(display, surface, info->buffer_damage.damage); + set_damage_region_(display, surface, buffer_rects.data(), 1); - swap_buffers_with_damage_(glfwGetEGLDisplay(), glfwGetEGLSurface(window), rects.data(), 1); + // Swap buffers with frame damage + auto frame_rects = RectToInts(display, surface, info->frame_damage.damage); + swap_buffers_with_damage_(display, surface, frame_rects.data(), 1); + // Add frame damage to damage history + // TODO std::cout << info->frame_damage.damage.top << ", " << info->frame_damage.damage.bottom << ", " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.right << std::endl; // for (auto rect : rects) { // std::cout << rect.x << ", " << rect.y << std::endl; // } - - //glfwSwapBuffers(static_cast(userdata)); return true; }; config.open_gl.fbo_callback = [](void*) -> uint32_t { + // Get FBO' age + // TODO + + // Given the FBO age, create existing damage region by joining all frame + // damages since FBO was last used + // TODO //std::cout << fbo.fbo_id << std::endl; return 0; // FBO0 }; From 0fabb4519739e304b327a560d710d3f2b989c22f Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Thu, 21 Jul 2022 15:59:47 -0700 Subject: [PATCH 29/38] fix flutterrect to skirect translation --- examples/glfw/FlutterEmbedderGLFW.cc | 39 ++++++++++++------- shell/platform/embedder/embedder.cc | 4 +- .../platform/embedder/embedder_surface_gl.cc | 2 +- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index b0e25ac524ce6..49be45e25e71b 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -115,10 +115,9 @@ bool RunFlutter(GLFWwindow* window, glfwMakeContextCurrent(nullptr); // is this even a thing? return true; }; + /// IS 2 CORRECT? HOW DO I KNOW WHEN IT'S A TRIPLE BUFFER? + //FlutterDamage frame_damage_history[2]; config.open_gl.present_with_info = [](void* userdata, const FlutterPresentInfo* info) -> bool { - PFNEGLSETDAMAGEREGIONKHRPROC set_damage_region_ = - reinterpret_cast( - eglGetProcAddress("eglSetDamageRegionKHR")); PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage_ = reinterpret_cast( eglGetProcAddress("eglSwapBuffersWithDamageKHR")); @@ -128,32 +127,46 @@ bool RunFlutter(GLFWwindow* window, EGLDisplay display = glfwGetEGLDisplay(); EGLSurface surface = glfwGetEGLSurface(window); - // Set damage region with buffer damage - auto buffer_rects = RectToInts(display, surface, info->buffer_damage.damage); - set_damage_region_(display, surface, buffer_rects.data(), 1); - // Swap buffers with frame damage - auto frame_rects = RectToInts(display, surface, info->frame_damage.damage); + FlutterRect empty_rect = {0, 0, 0, 0}; + auto frame_rects = RectToInts(display, surface, empty_rect); swap_buffers_with_damage_(display, surface, frame_rects.data(), 1); // Add frame damage to damage history // TODO - std::cout << info->frame_damage.damage.top << ", " << info->frame_damage.damage.bottom << ", " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.right << std::endl; + std::cout << "Frame Damage: " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.top << ", " << info->frame_damage.damage.right << ", " << info->frame_damage.damage.bottom << std::endl; // for (auto rect : rects) { // std::cout << rect.x << ", " << rect.y << std::endl; // } return true; }; - config.open_gl.fbo_callback = [](void*) -> uint32_t { - // Get FBO' age - // TODO + config.open_gl.fbo_with_frame_info_callback = [](void* userdata, const FlutterFrameInfo* info) -> FlutterFrameBuffer { + //std::cout << info->frame_damage.damage.bottom << ", " << info->frame_damage.damage.top << ", " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.right << std::endl; + + PFNEGLSETDAMAGEREGIONKHRPROC set_damage_region_ = + reinterpret_cast( + eglGetProcAddress("eglSetDamageRegionKHR")); + + GLFWwindow* window = static_cast(userdata); + EGLDisplay display = glfwGetEGLDisplay(); + EGLSurface surface = glfwGetEGLSurface(window); + + FlutterRect empty_rect = {0, 0, 0, 0}; + auto buffer_rects = RectToInts(display, surface, empty_rect); + set_damage_region_(display, surface, buffer_rects.data(), 1); // Given the FBO age, create existing damage region by joining all frame // damages since FBO was last used // TODO //std::cout << fbo.fbo_id << std::endl; - return 0; // FBO0 + FlutterFrameBuffer fbo; + fbo.fbo_id = 0; + FlutterDamage existing_damage; + existing_damage.damage = empty_rect; + fbo.damage = existing_damage; + std::cout << "Existing Damage: " << fbo.damage.damage.left << ", " << fbo.damage.damage.top << ", " << fbo.damage.damage.right << ", " << fbo.damage.damage.bottom << std::endl; + return fbo; // FBO0 }; config.open_gl.gl_proc_resolver = [](void*, const char* name) -> void* { return reinterpret_cast(glfwGetProcAddress(name)); diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 7cd2836f4fcde..abb39c3330337 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -225,8 +225,8 @@ static void* DefaultGLProcResolver(const char* name) { /// FlutterRect. FlutterRect SkIRectToFlutterRect(const std::optional rect) { FlutterRect flutter_rect = { - static_cast(rect->fLeft), static_cast(rect->fRight), - static_cast(rect->fTop), static_cast(rect->fBottom)}; + static_cast(rect->fLeft), static_cast(rect->fTop), + static_cast(rect->fRight), static_cast(rect->fBottom)}; return flutter_rect; } diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 480a39b0b6d28..10129d64f7fe7 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -55,8 +55,8 @@ bool EmbedderSurfaceGL::GLContextPresent(const GLPresentInfo& present_info) { /// to a SkIRect. const SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) { SkIRect rect = {static_cast(flutter_rect.left), - static_cast(flutter_rect.right), static_cast(flutter_rect.top), + static_cast(flutter_rect.right), static_cast(flutter_rect.bottom)}; return rect; } From 75d3fbc028ce25b5d05bcdcbda18d5e08d320923 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Thu, 21 Jul 2022 16:10:18 -0700 Subject: [PATCH 30/38] remove unnecessary lib from the build file --- examples/glfw/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/glfw/BUILD.gn b/examples/glfw/BUILD.gn index fe76acb0e63b5..f7c1fd6df24e2 100644 --- a/examples/glfw/BUILD.gn +++ b/examples/glfw/BUILD.gn @@ -17,7 +17,6 @@ if (build_embedder_examples) { libs = [ "EGL", - "GLESv2", ] } } From 59172ec214b2fc872e78ce010f95f53af45b1ad4 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Thu, 21 Jul 2022 16:13:14 -0700 Subject: [PATCH 31/38] adjust cmakelists.txt --- examples/glfw/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/glfw/CMakeLists.txt b/examples/glfw/CMakeLists.txt index cc17cd89d2f74..5bc1e208f9fd0 100644 --- a/examples/glfw/CMakeLists.txt +++ b/examples/glfw/CMakeLists.txt @@ -4,8 +4,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" ) add_executable(flutter_glfw FlutterEmbedderGLFW.cc) -find_package(OpenGL REQUIRED COMPONENTS EGL) -include_directories(${OPENGL_INCLUDE_DIRS}) ############################################################ # GLFW @@ -14,6 +12,8 @@ option(GLFW_BUILD_EXAMPLES "" OFF) option(GLFW_BUILD_TESTS "" OFF) option(GLFW_BUILD_DOCS "" OFF) option(GLFW_INSTALL "" OFF) +find_package(OpenGL REQUIRED COMPONENTS EGL) +include_directories(${OPENGL_INCLUDE_DIRS}) add_subdirectory(${CMAKE_SOURCE_DIR}/../../../third_party/glfw glfw) target_link_libraries(flutter_glfw glfw OpenGL::EGL) include_directories(${CMAKE_SOURCE_DIR}/../../../third_party/glfw/include) From c5caffffdc2077a5a110c7529b077d871346a26d Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Thu, 21 Jul 2022 16:42:51 -0700 Subject: [PATCH 32/38] fix recttoints --- examples/glfw/CMakeLists.txt | 1 - examples/glfw/FlutterEmbedderGLFW.cc | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/glfw/CMakeLists.txt b/examples/glfw/CMakeLists.txt index 5bc1e208f9fd0..2563bd8bee05a 100644 --- a/examples/glfw/CMakeLists.txt +++ b/examples/glfw/CMakeLists.txt @@ -4,7 +4,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" ) add_executable(flutter_glfw FlutterEmbedderGLFW.cc) - ############################################################ # GLFW ############################################################ diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index 49be45e25e71b..ddbc18f39cf57 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -15,10 +15,8 @@ #include #include - // This value is calculated after the window is created. static double g_pixelRatio = 1.0; - static const size_t kInitialWindowWidth = 800; static const size_t kInitialWindowHeight = 600; @@ -97,7 +95,7 @@ std::array static RectToInts(EGLDisplay display, eglQuerySurface(display, surface, EGL_HEIGHT, &height); std::array res{static_cast(rect.left), height - static_cast(rect.bottom), static_cast(rect.right) - static_cast(rect.left), - static_cast(rect.top) - static_cast(rect.bottom)}; + static_cast(rect.bottom) - static_cast(rect.top)}; return res; } From 7f095841a867dad617aeb98d14b333db3a1213c3 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Fri, 22 Jul 2022 12:52:45 -0700 Subject: [PATCH 33/38] fbo reset after present set to true --- examples/glfw/FlutterEmbedderGLFW.cc | 75 ++++++++++++++++++---------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index ddbc18f39cf57..0143843be6923 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -9,6 +9,7 @@ #define GLFW_EXPOSE_NATIVE_EGL #include +#include #include "GLFW/glfw3.h" #include "GLFW/glfw3native.h" #include "embedder.h" @@ -19,6 +20,11 @@ static double g_pixelRatio = 1.0; static const size_t kInitialWindowWidth = 800; static const size_t kInitialWindowHeight = 600; +// 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; + +std::list damage_history_; static_assert(FLUTTER_ENGINE_VERSION == 1, "This Flutter Embedder was authored against the stable Flutter " @@ -99,6 +105,13 @@ std::array static RectToInts(EGLDisplay display, return res; } +void JoinFlutterRect(FlutterRect* rect, FlutterRect additional_rect) { + rect->left = std::min(rect->left, additional_rect.left); + rect->top = std::min(rect->top, additional_rect.top); + rect->right = std::max(rect->right, additional_rect.right); + rect->bottom = std::max(rect->bottom, additional_rect.bottom); +} + bool RunFlutter(GLFWwindow* window, const std::string& project_path, const std::string& icudtl_path) { @@ -113,63 +126,71 @@ bool RunFlutter(GLFWwindow* window, glfwMakeContextCurrent(nullptr); // is this even a thing? return true; }; - /// IS 2 CORRECT? HOW DO I KNOW WHEN IT'S A TRIPLE BUFFER? - //FlutterDamage frame_damage_history[2]; config.open_gl.present_with_info = [](void* userdata, const FlutterPresentInfo* info) -> bool { + PFNEGLSETDAMAGEREGIONKHRPROC set_damage_region_ = + reinterpret_cast( + eglGetProcAddress("eglSetDamageRegionKHR")); PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage_ = reinterpret_cast( eglGetProcAddress("eglSwapBuffersWithDamageKHR")); - GLFWwindow* window = static_cast(userdata); EGLDisplay display = glfwGetEGLDisplay(); EGLSurface surface = glfwGetEGLSurface(window); + auto buffer_rects = RectToInts(display, surface, info->buffer_damage.damage); + set_damage_region_(display, surface, buffer_rects.data(), 1); + // Swap buffers with frame damage - FlutterRect empty_rect = {0, 0, 0, 0}; - auto frame_rects = RectToInts(display, surface, empty_rect); + auto frame_rects = RectToInts(display, surface, info->frame_damage.damage); swap_buffers_with_damage_(display, surface, frame_rects.data(), 1); + // Add frame damage to damage history - // TODO + damage_history_.push_back(info->frame_damage.damage); + if (damage_history_.size() > kMaxHistorySize) { + damage_history_.pop_front(); + } std::cout << "Frame Damage: " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.top << ", " << info->frame_damage.damage.right << ", " << info->frame_damage.damage.bottom << std::endl; - - // for (auto rect : rects) { - // std::cout << rect.x << ", " << rect.y << std::endl; - // } return true; }; config.open_gl.fbo_with_frame_info_callback = [](void* userdata, const FlutterFrameInfo* info) -> FlutterFrameBuffer { - //std::cout << info->frame_damage.damage.bottom << ", " << info->frame_damage.damage.top << ", " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.right << std::endl; - - PFNEGLSETDAMAGEREGIONKHRPROC set_damage_region_ = - reinterpret_cast( - eglGetProcAddress("eglSetDamageRegionKHR")); - + // Given the FBO age, create existing damage region by joining all frame + // damages since FBO was last used GLFWwindow* window = static_cast(userdata); EGLDisplay display = glfwGetEGLDisplay(); EGLSurface surface = glfwGetEGLSurface(window); - FlutterRect empty_rect = {0, 0, 0, 0}; - auto buffer_rects = RectToInts(display, surface, empty_rect); - set_damage_region_(display, surface, buffer_rects.data(), 1); + EGLint age; + eglQuerySurface(display, surface, EGL_BUFFER_AGE_EXT, &age); + std::cout << "Buffer age: " << age << std::endl; - // Given the FBO age, create existing damage region by joining all frame - // damages since FBO was last used - // TODO - //std::cout << fbo.fbo_id << std::endl; - FlutterFrameBuffer fbo; - fbo.fbo_id = 0; FlutterDamage existing_damage; - existing_damage.damage = empty_rect; + + if (age == 0) { // full repaint + existing_damage.damage = {0, 0, kInitialWindowWidth, kInitialWindowHeight}; + } else { + // join up to (age - 1) last rects from damage history + --age; + existing_damage.damage = {0, 0, 0, 0}; + for (auto i = damage_history_.rbegin(); + i != damage_history_.rend() && age > 0; ++i, --age) { + JoinFlutterRect(&(existing_damage.damage), *i); + } + } + + FlutterFrameBuffer fbo; + fbo.fbo_id = 0; // FBO0 fbo.damage = existing_damage; std::cout << "Existing Damage: " << fbo.damage.damage.left << ", " << fbo.damage.damage.top << ", " << fbo.damage.damage.right << ", " << fbo.damage.damage.bottom << std::endl; - return fbo; // FBO0 + return fbo; }; config.open_gl.gl_proc_resolver = [](void*, const char* name) -> void* { return reinterpret_cast(glfwGetProcAddress(name)); }; + config.open_gl.fbo_reset_after_present = true; + // This directory is generated by `flutter build bundle`. std::string assets_path = project_path + "/build/flutter_assets"; FlutterProjectArgs args = { From 0ebbfac1648212a3d9adc81ecc278b15f7d53634 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 25 Jul 2022 08:01:41 -0700 Subject: [PATCH 34/38] Updates --- flow/layers/container_layer.cc | 1 + shell/common/rasterizer.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/flow/layers/container_layer.cc b/flow/layers/container_layer.cc index ad6fd9126e200..1916608450aee 100644 --- a/flow/layers/container_layer.cc +++ b/flow/layers/container_layer.cc @@ -11,6 +11,7 @@ namespace flutter { ContainerLayer::ContainerLayer() : child_paint_bounds_(SkRect::MakeEmpty()) {} void ContainerLayer::Diff(DiffContext* context, const Layer* old_layer) { + std::cout << "Container layer" << std:endl; auto old_container = static_cast(old_layer); DiffContext::AutoSubtreeRestore subtree(context); DiffChildren(context, old_container); diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 8587d253d1f4d..26e549c25d83a 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -656,6 +656,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( damage = std::make_unique(); if (frame->framebuffer_info().existing_damage && !force_full_repaint) { damage->SetPreviousLayerTree(last_layer_tree_.get()); + std::cout << "prev layer tree was set" << std::endl; damage->AddAdditonalDamage(*frame->framebuffer_info().existing_damage); damage->SetClipAlignment( frame->framebuffer_info().horizontal_clip_alignment, From 96b2d37d9402f3f70e29866fad3b296e199b6515 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 25 Jul 2022 08:02:18 -0700 Subject: [PATCH 35/38] Updates --- examples/glfw/FlutterEmbedderGLFW.cc | 10 +++++----- examples/glfw/main.dart | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index 0143843be6923..e94c803afbb25 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -168,15 +168,15 @@ bool RunFlutter(GLFWwindow* window, FlutterDamage existing_damage; if (age == 0) { // full repaint - existing_damage.damage = {0, 0, kInitialWindowWidth, kInitialWindowHeight}; + existing_damage.damage = {0, 0, 0, 0};//{0, 0, kInitialWindowWidth, kInitialWindowHeight}; } else { // join up to (age - 1) last rects from damage history --age; existing_damage.damage = {0, 0, 0, 0}; - for (auto i = damage_history_.rbegin(); - i != damage_history_.rend() && age > 0; ++i, --age) { - JoinFlutterRect(&(existing_damage.damage), *i); - } + // for (auto i = damage_history_.rbegin(); + // i != damage_history_.rend() && age > 0; ++i, --age) { + // JoinFlutterRect(&(existing_damage.damage), *i); + // } } FlutterFrameBuffer fbo; diff --git a/examples/glfw/main.dart b/examples/glfw/main.dart index f1e74ab50be7c..d73f911dcbe2a 100644 --- a/examples/glfw/main.dart +++ b/examples/glfw/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart' show debugDefaultTargetPlatformOverride; +import 'package:flutter_spinkit/flutter_spinkit.dart'; void main() { // This is a hack to make Flutter think you are running on Google Fuchsia, @@ -109,6 +110,7 @@ class _MyHomePageState extends State { '$_counter', style: Theme.of(context).textTheme.headline4, ), + // SpinKitRotatingCircle(color: Colors.blue, size: 50.0), ], ), ), From 9d00450bb6a987f1e6b6d508db7435592bfead99 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 25 Jul 2022 10:47:33 -0700 Subject: [PATCH 36/38] fix buffer present bug --- shell/platform/embedder/embedder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index abb39c3330337..f2b90c941540f 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -269,7 +269,7 @@ InferOpenGLPlatformViewCreationCallback( present_info.frame_damage = frame_damage; FlutterDamage buffer_damage; - frame_damage.damage = SkIRectToFlutterRect(gl_present_info.buffer_damage); + buffer_damage.damage = SkIRectToFlutterRect(gl_present_info.buffer_damage); present_info.buffer_damage = buffer_damage; /// Pass the present_info to the present_with_info callback so that it can From 0a072c2382fa931b88896365722d58dd252eb208 Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Mon, 25 Jul 2022 21:27:57 -0700 Subject: [PATCH 37/38] updates --- examples/glfw/FlutterEmbedderGLFW.cc | 34 ++++++++++++++++++---------- shell/gpu/gpu_surface_gl_skia.cc | 10 +++++++- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/examples/glfw/FlutterEmbedderGLFW.cc b/examples/glfw/FlutterEmbedderGLFW.cc index e94c803afbb25..8056fb81cf9cd 100644 --- a/examples/glfw/FlutterEmbedderGLFW.cc +++ b/examples/glfw/FlutterEmbedderGLFW.cc @@ -7,6 +7,7 @@ #include #define GLFW_EXPOSE_NATIVE_EGL +#define GLFW_INCLUDE_GLEXT #include #include @@ -138,7 +139,7 @@ bool RunFlutter(GLFWwindow* window, EGLDisplay display = glfwGetEGLDisplay(); EGLSurface surface = glfwGetEGLSurface(window); - auto buffer_rects = RectToInts(display, surface, info->buffer_damage.damage); + auto buffer_rects = RectToInts(display, surface, {0, 0, kInitialWindowWidth, kInitialWindowHeight}); set_damage_region_(display, surface, buffer_rects.data(), 1); // Swap buffers with frame damage @@ -150,7 +151,7 @@ bool RunFlutter(GLFWwindow* window, if (damage_history_.size() > kMaxHistorySize) { damage_history_.pop_front(); } - + std::cout << "Buffer Damage: " << info->buffer_damage.damage.left << ", " << info->buffer_damage.damage.top << ", " << info->buffer_damage.damage.right << ", " << info->buffer_damage.damage.bottom << std::endl; std::cout << "Frame Damage: " << info->frame_damage.damage.left << ", " << info->frame_damage.damage.top << ", " << info->frame_damage.damage.right << ", " << info->frame_damage.damage.bottom << std::endl; return true; }; @@ -162,21 +163,30 @@ bool RunFlutter(GLFWwindow* window, EGLSurface surface = glfwGetEGLSurface(window); EGLint age; - eglQuerySurface(display, surface, EGL_BUFFER_AGE_EXT, &age); + if (glfwExtensionSupported("GL_EXT_buffer_age") == GLFW_TRUE) { + eglQuerySurface(display, surface, EGL_BUFFER_AGE_EXT, &age); + } else { + age = 4; // Virtually no driver should have a swapchain length > 4. + } std::cout << "Buffer age: " << age << std::endl; FlutterDamage existing_damage; + existing_damage.damage = {0, 0, kInitialWindowWidth, kInitialWindowHeight}; - if (age == 0) { // full repaint - existing_damage.damage = {0, 0, 0, 0};//{0, 0, kInitialWindowWidth, kInitialWindowHeight}; - } else { - // join up to (age - 1) last rects from damage history + if (age > 1) { --age; - existing_damage.damage = {0, 0, 0, 0}; - // for (auto i = damage_history_.rbegin(); - // i != damage_history_.rend() && age > 0; ++i, --age) { - // JoinFlutterRect(&(existing_damage.damage), *i); - // } + // join up to (age - 1) last rects from damage history + for (auto i = damage_history_.rbegin(); + i != damage_history_.rend() && age > 0; ++i, --age) { + std::cout << "Damage in history: " << i->left << ", " << i->top << ", " << i->right << ", " << i->bottom << std::endl; + if (i == damage_history_.rbegin()) { + if (i != damage_history_.rend()) { + existing_damage.damage = {i->left, i->top, i->right, i->bottom}; + } + } else { + JoinFlutterRect(&(existing_damage.damage), *i); + } + } } FlutterFrameBuffer fbo; diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index 91f0b1d2b3063..59f26c7c0d814 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -19,6 +19,9 @@ #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrContextOptions.h" +#include +#include + // These are common defines present on all OpenGL headers. However, we don't // want to perform GL header reasolution on each platform we support. So just // define these upfront. It is unlikely we will need more. But, if we do, we can @@ -274,11 +277,16 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame, .fbo_id = static_cast(fbo_id_), .frame_damage = frame.submit_info().frame_damage, .presentation_time = frame.submit_info().presentation_time, - .buffer_damage = frame.submit_info().buffer_damage + .buffer_damage = frame.submit_info().buffer_damage, }; + auto start = std::chrono::high_resolution_clock::now(); if (!delegate_->GLContextPresent(present_info)) { return false; } + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + + std::cout << duration.count() << std::endl; if (delegate_->GLContextFBOResetAfterPresent()) { auto current_size = From 04c32ed6782b7188915348a3e36cea753163744c Mon Sep 17 00:00:00 2001 From: Bernardo Eilert Trevisan Date: Tue, 26 Jul 2022 15:53:01 -0700 Subject: [PATCH 38/38] Udpate dart example. --- examples/glfw/main.dart | 54 ++--------------------------------------- 1 file changed, 2 insertions(+), 52 deletions(-) diff --git a/examples/glfw/main.dart b/examples/glfw/main.dart index d73f911dcbe2a..7ee4c46088308 100644 --- a/examples/glfw/main.dart +++ b/examples/glfw/main.dart @@ -1,7 +1,6 @@ // 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. - import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart' show debugDefaultTargetPlatformOverride; @@ -13,7 +12,6 @@ void main() { debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; runApp(MyApp()); } - class MyApp extends StatelessWidget { // This widget is the root of your application. @override @@ -36,39 +34,20 @@ class MyApp extends StatelessWidget { ); } } - class MyHomePage extends StatefulWidget { MyHomePage({Key? key, required this.title}) : super(key: key); - // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect // how it looks. - // This class is the configuration for the state. It holds the values (in this // case the title) provided by the parent (in this case the App widget) and // used by the build method of the State. Fields in a Widget subclass are // always marked "final". - final String title; - @override _MyHomePageState createState() => _MyHomePageState(); } - class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - @override Widget build(BuildContext context) { // This method is rerun every time setState is called, for instance as done @@ -86,39 +65,10 @@ class _MyHomePageState extends State { body: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - // SpinKitRotatingCircle(color: Colors.blue, size: 50.0), - ], + child: RepaintBoundary( + child: SpinKitRotatingCircle(color: Colors.blue, size: 50.0), ), ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. ); } }