Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added Reload
Empty file.
12 changes: 10 additions & 2 deletions examples/glfw/FlutterEmbedderGLFW.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,16 @@ bool RunFlutter(GLFWwindow* window,
glfwMakeContextCurrent(nullptr); // is this even a thing?
return true;
};
config.open_gl.present = [](void* userdata) -> bool {
glfwSwapBuffers(static_cast<GLFWwindow*>(userdata));
config.open_gl.present_with_info = [](void* userdata, FlutterPresentInfo* present_info) -> bool {
// Check if damage exists
if (present_info->fbo_damage.empty()) {
// Render only damaged regions
// TODO(btrevisan): verify extensions.
eglSwapBuffersWithDamageKHR(static_cast<GLFWwindow*>(userdata), present_info->fbo_damage);
} else {
// Otherwise, render the entire screen
glfwSwapBuffers(static_cast<GLFWwindow*>(userdata));
}
return true;
};
config.open_gl.fbo_callback = [](void*) -> uint32_t {
Expand Down
6 changes: 6 additions & 0 deletions shell/gpu/gpu_surface_gl_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ SurfaceFrame::FramebufferInfo GPUSurfaceGLDelegate::GLContextFramebufferInfo()
const {
SurfaceFrame::FramebufferInfo res;
res.supports_readback = true;
// By default, partial repaint is enabled for every frame.
// TODO(btrevisan): Implement deactivation of partial repaint in cases that
// do not benefit from it (e.g. when damage takes over most of the frame).
res.supports_partial_repaint = true;
// TODO(btrevisan): make sure that when there is existing damage, it is set.
res.existing_damage = SkIRect::MakeEmpty();
return res;
}

Expand Down
4 changes: 4 additions & 0 deletions shell/gpu/gpu_surface_gl_skia.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceGLSkia::AcquireFrame(
};

framebuffer_info = delegate_->GLContextFramebufferInfo();
// CHECK IF PARTIAL REPAINT IS ENABLED
// CALCULATE ACCUMULATED DAMAGE (I.E. ARE IN CURRENT FBO THAT LAGS BEHIND FRONT BUFFER)
// SET ACCUMULATED DAMAGE TO FBO_INFO EXISTING_DAMAGE
// SET SUPPORTS_PARTIAL_REPAINT TO TRUE
return std::make_unique<SurfaceFrame>(surface, std::move(framebuffer_info),
submit_callback,
std::move(context_switch));
Expand Down
18 changes: 14 additions & 4 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,25 @@ 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 {
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 {
FlutterPresentInfo present_info = {};
present_info.struct_size = sizeof(FlutterPresentInfo);
present_info.fbo_id = fbo_id;
present_info.fbo_id = gl_present_info.fbo_id;

FlutterDamage fbo_damage = {};
fbo_damage.struct_size = sizeof(FlutterDamage);
fbo_damage.damage = std::vector<FlutterRect>{
FlutterRect{static_cast<double>(gl_present_info.damage->fLeft),
static_cast<double>(gl_present_info.damage->fRight),
static_cast<double>(gl_present_info.damage->fTop),
static_cast<double>(gl_present_info.damage->fBottom)}};
present_info.fbo_damage = fbo_damage;
return present_with_info(user_data, &present_info);
}
};
Expand Down
11 changes: 11 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <vector>

// This file defines an Application Binary Interface (ABI), which requires more
// stability than regular code to remain functional for exchanging messages
Expand Down Expand Up @@ -377,6 +378,14 @@ typedef struct {
FlutterSize lower_left_corner_radius;
} FlutterRoundedRect;

/// A strucutre to represent damage as rectangles.
typedef struct {
/// The size of this struct. Must be sizeof(FlutterDamage).
size_t struct_size;
// Vector of rectangles representing the areas that need to be repainted.
std::vector<FlutterRect> damage;
} FlutterDamage;

/// This information is passed to the embedder when requesting a frame buffer
/// object.
///
Expand All @@ -401,6 +410,8 @@ typedef struct {
size_t struct_size;
/// Id of the fbo backing the surface that was presented.
uint32_t fbo_id;
// A vector of rectangles representing the areas that need to be repainted.
FlutterDamage fbo_damage;
} FlutterPresentInfo;

/// Callback for when a surface is presented.
Expand Down
17 changes: 16 additions & 1 deletion shell/platform/embedder/embedder_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ EmbedderSurfaceGL::EmbedderSurfaceGL(
}

valid_ = true;

// if (HasExtension(extensions, "EGL_KHR_partial_update")) {
// set_damage_region_ = reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(
// eglGetProcAddress("eglSetDamageRegionKHR"));
// }
}

EmbedderSurfaceGL::~EmbedderSurfaceGL() = default;
Expand All @@ -46,7 +51,7 @@ bool EmbedderSurfaceGL::GLContextClearCurrent() {

// |GPUSurfaceGLDelegate|
bool EmbedderSurfaceGL::GLContextPresent(const GLPresentInfo& present_info) {
return gl_dispatch_table_.gl_present_callback(present_info.fbo_id);
return gl_dispatch_table_.gl_present_callback(present_info);
}

// |GPUSurfaceGLDelegate|
Expand All @@ -59,6 +64,16 @@ bool EmbedderSurfaceGL::GLContextFBOResetAfterPresent() const {
return fbo_reset_after_present_;
}

// |GPUSurfaceGLDelegate|
void EmbedderSurfaceGL::GLContextSetDamageRegion(
const std::optional<SkIRect>& region) {
// TODO(btrevisan): add checks.
FML_DCHECK(IsValid());

// The region given here is the buffer damage.
// onscreen_surface_->SetDamageRegion(region);
}

// |GPUSurfaceGLDelegate|
SkMatrix EmbedderSurfaceGL::GLContextSurfaceTransformation() const {
auto callback = gl_dispatch_table_.gl_surface_transformation_callback;
Expand Down
6 changes: 5 additions & 1 deletion shell/platform/embedder/embedder_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface,
struct GLDispatchTable {
std::function<bool(void)> gl_make_current_callback; // required
std::function<bool(void)> gl_clear_current_callback; // required
std::function<bool(uint32_t)> gl_present_callback; // required
std::function<bool(GLPresentInfo)> gl_present_callback; // required
std::function<intptr_t(GLFrameInfo)> gl_fbo_callback; // required
std::function<bool(void)> gl_make_resource_current_callback; // optional
std::function<SkMatrix(void)>
Expand All @@ -37,6 +37,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface,
bool valid_ = false;
GLDispatchTable gl_dispatch_table_;
bool fbo_reset_after_present_;
// auto set_damage_region_ = nullptr;

std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder_;

Expand Down Expand Up @@ -64,6 +65,9 @@ class EmbedderSurfaceGL final : public EmbedderSurface,
// |GPUSurfaceGLDelegate|
bool GLContextFBOResetAfterPresent() const override;

// |GPUSurfaceGLDelegate|
void GLContextSetDamageRegion(const std::optional<SkIRect>& region) override;

// |GPUSurfaceGLDelegate|
SkMatrix GLContextSurfaceTransformation() const override;

Expand Down