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
Show all changes
47 commits
Select commit Hold shift + click to select a range
a69e0f3
Create GLFBOInfo.
betrevisan Jul 30, 2022
a28f3a9
Update FlutterPresentInfo with frame and buffer damage
betrevisan Jul 30, 2022
030e54e
Update GLContextFBO prototype to return a GLFBOInfo.
betrevisan Jul 30, 2022
dde31a1
Update affected functions by updates to GLPresentInfo
betrevisan Jul 30, 2022
b035be5
Update the behavior of GL Skia to account for dirty region management.
betrevisan Jul 30, 2022
7f4bd47
Updated affected functions by the changes to the return value of GLCo…
betrevisan Jul 30, 2022
89b112c
Create FlutterDamage.
betrevisan Jul 30, 2022
10df5e3
Update FlutterPresentInfo fields.
betrevisan Jul 30, 2022
ab17275
Add new callback fbo_with_damage_callback.
betrevisan Jul 30, 2022
a30e016
Update dispatch table.
betrevisan Jul 30, 2022
e532950
Add check to make sure gl_fbo_with_damage_callback was passed.
betrevisan Jul 30, 2022
2b23637
Update GLContextPresent and GLContextFBO.
betrevisan Jul 30, 2022
de95990
Update open gl default renderer config for tests.
betrevisan Jul 30, 2022
98d2d6a
Add GetRendererConfig function.
betrevisan Jul 30, 2022
c6b8668
Update GLPresent used in tests.
betrevisan Jul 30, 2022
b50677d
Add fbo_with_damage_callback to tests.
betrevisan Jul 30, 2022
a865ab3
Add unittests to check valid fbo_with_damage callback.
betrevisan Jul 30, 2022
8f95371
Add unittests for partial repaint.
betrevisan Jul 30, 2022
8fd3a9d
Add unittest to make sure fbo with damage receives the correct inform…
betrevisan Jul 30, 2022
ae1481f
Add log message if the user did not define an fbo_with_damage callback.
betrevisan Jul 30, 2022
e6e1154
Add auxiliar functions.
betrevisan Jul 30, 2022
f4d5043
Update behavior of present callback within the embedder.
betrevisan Jul 30, 2022
c2ce2af
Update behavior of fbo with damage callback within the embedder.
betrevisan Jul 30, 2022
ef0cc25
Formatting.
betrevisan Jul 30, 2022
6a64daa
Update the fbo_with_damage_callback.
betrevisan Aug 1, 2022
931e53e
Documenting.
betrevisan Aug 1, 2022
3f97449
Update auxiliary functions as static functions.
betrevisan Aug 1, 2022
1092807
Force full repaint when the user tries to do partial repaint with mul…
betrevisan Aug 1, 2022
ecec224
Update construction of information passed to the present callback.
betrevisan Aug 1, 2022
c1be604
Fix static function warning.
betrevisan Aug 1, 2022
bde9b09
Fix static function error.
betrevisan Aug 1, 2022
104b7ca
Rename fbo_with_damage_callback to populate_existing_damage_callback.
betrevisan Aug 1, 2022
324237c
Merging DRM PR.
betrevisan Aug 3, 2022
7ea0fd0
Update fields of FlutterVulkanImage
betrevisan Aug 3, 2022
bca988f
Update PresentImage arguments.
betrevisan Aug 4, 2022
5f8367d
Update Vulkan GPU
betrevisan Aug 4, 2022
7947203
Update behavior of PresetImage.
betrevisan Aug 4, 2022
f8171c6
Update Vulkan dispatch table.
betrevisan Aug 4, 2022
8a2f8ed
Update embedder.cc's Vulkan callbacks.
betrevisan Aug 4, 2022
e01445e
Update embedder.h Vulkan structs.
betrevisan Aug 4, 2022
3a24ce6
Fix acquire frame bug.
betrevisan Aug 4, 2022
0348e34
Formatting.
betrevisan Aug 4, 2022
fae834a
Fix unused function error.
betrevisan Aug 4, 2022
6422343
Documenting.
betrevisan Aug 5, 2022
88f5391
Formatting.
betrevisan Aug 5, 2022
b5d36ee
Merge branch 'main' into drm-embedder-vulkan
betrevisan Aug 19, 2022
0777614
Update gpu_surface_gl_skia.h
betrevisan Aug 19, 2022
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
26 changes: 23 additions & 3 deletions shell/gpu/gpu_surface_vulkan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ bool GPUSurfaceVulkan::IsValid() {
return skia_context_ != nullptr;
}

// Auxiliary function used to translate rectangles of type FlutterRect to
// SkIRect.
static const SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) {
SkIRect rect = {static_cast<int32_t>(flutter_rect.left),
static_cast<int32_t>(flutter_rect.top),
static_cast<int32_t>(flutter_rect.right),
static_cast<int32_t>(flutter_rect.bottom)};
return rect;
}

std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame(
const SkISize& frame_size) {
if (!IsValid()) {
Expand Down Expand Up @@ -61,7 +71,7 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame(
}

SurfaceFrame::SubmitCallback callback = [image = image, delegate = delegate_](
const SurfaceFrame&,
const SurfaceFrame& frame,
SkCanvas* canvas) -> bool {
TRACE_EVENT0("flutter", "GPUSurfaceVulkan::PresentImage");
if (canvas == nullptr) {
Expand All @@ -72,10 +82,20 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame(
canvas->flush();

return delegate->PresentImage(reinterpret_cast<VkImage>(image.image),
static_cast<VkFormat>(image.format));
static_cast<VkFormat>(image.format),
*frame.submit_info().buffer_damage,
*frame.submit_info().frame_damage);
};

SurfaceFrame::FramebufferInfo framebuffer_info{.supports_readback = true};
SurfaceFrame::FramebufferInfo framebuffer_info{
.supports_readback = true,
};

if (image.partial_repaint_enabled) {
framebuffer_info.supports_partial_repaint = true;
framebuffer_info.existing_damage =
FlutterRectToSkIRect(image.image_damage.damage[0]);
}

return std::make_unique<SurfaceFrame>(
std::move(surface), std::move(framebuffer_info), std::move(callback));
Expand Down
6 changes: 5 additions & 1 deletion shell/gpu/gpu_surface_vulkan_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "flutter/vulkan/vulkan_device.h"
#include "flutter/vulkan/vulkan_image.h"
#include "flutter/vulkan/vulkan_proc_table.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkSize.h"

namespace flutter {
Expand Down Expand Up @@ -42,7 +43,10 @@ class GPUSurfaceVulkanDelegate {
/// @brief Called by the engine once a frame has been rendered to the image
/// and it's ready to be bound for further reading/writing.
///
virtual bool PresentImage(VkImage image, VkFormat format) = 0;
virtual bool PresentImage(VkImage image,
VkFormat format,
SkIRect image_damage_skrect,
SkIRect frame_damage_skrect) = 0;
};

} // namespace flutter
Expand Down
46 changes: 43 additions & 3 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ static void* DefaultGLProcResolver(const char* name) {
}
#endif // FML_OS_LINUX || FML_OS_WIN

#ifdef SHELL_ENABLE_GL
#if defined(SHELL_ENABLE_GL) || defined(SHELL_ENABLE_VULKAN)
// Auxiliary function used to translate rectangles of type SkIRect to
// FlutterRect.
static FlutterRect SkIRectToFlutterRect(const SkIRect sk_rect) {
Expand All @@ -238,7 +238,9 @@ static FlutterRect SkIRectToFlutterRect(const SkIRect sk_rect) {
static_cast<double>(sk_rect.fBottom)};
return flutter_rect;
}
#endif

#ifdef SHELL_ENABLE_GL
// Auxiliary function used to translate rectangles of type FlutterRect to
// SkIRect.
static const SkIRect FlutterRectToSkIRect(FlutterRect flutter_rect) {
Expand Down Expand Up @@ -548,16 +550,54 @@ InferVulkanPlatformViewCreationCallback(
static_cast<uint32_t>(frame_size.height())},
};

return ptr(user_data, &frame_info);
FlutterVulkanImage next_image = ptr(user_data, &frame_info);

// Verify that at least one damage rectangle was provided.
if (next_image.image_damage.damage == nullptr ||
next_image.image_damage.num_rects <= 0) {
FML_LOG(INFO) << "No damage was provided. Forcing full repaint.";
next_image.partial_repaint_enabled = false;
} else if (next_image.image_damage.num_rects > 1) {
// Log message notifying users that multi-damage is not yet available in
// case they try to make use of it.
FML_LOG(INFO) << "Damage with multiple rectangles not yet supported. "
"Repainting the whole frame.";
next_image.partial_repaint_enabled = false;
} else {
next_image.partial_repaint_enabled = true;
}
return next_image;
};

auto vulkan_present_image_callback =
[ptr = config->vulkan.present_image_callback, user_data](
VkImage image, VkFormat format) -> bool {
VkImage image, VkFormat format, SkIRect image_damage_skrect,
SkIRect frame_damage_skrect) -> bool {
const size_t num_rects = 1;

std::array<FlutterRect, num_rects> image_damage_rect = {
SkIRectToFlutterRect(image_damage_skrect)};
std::array<FlutterRect, num_rects> frame_damage_rect = {
SkIRectToFlutterRect(frame_damage_skrect)};

FlutterDamage image_damage{
.struct_size = sizeof(FlutterDamage),
.num_rects = image_damage_rect.size(),
.damage = image_damage_rect.data(),
};

FlutterDamage frame_damage{
.struct_size = sizeof(FlutterDamage),
.num_rects = frame_damage_rect.size(),
.damage = frame_damage_rect.data(),
};

FlutterVulkanImage image_desc = {
.struct_size = sizeof(FlutterVulkanImage),
.image = reinterpret_cast<uint64_t>(image),
.format = static_cast<uint32_t>(format),
.image_damage = image_damage,
.frame_damage = frame_damage,
};
return ptr(user_data, &image_desc);
};
Expand Down
22 changes: 20 additions & 2 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,18 @@ typedef struct {
FlutterVulkanImageHandle image;
/// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM).
uint32_t format;
/// Upon request, it represents the existing damage to the present image. At
/// present time, it represents the regions that need to be rendered.
FlutterDamage image_damage;
/// This field is used at present time to represent the regions that have
/// changed between this frame and the previous one. This is important so that
/// the user can keep track of images' existing damage.
FlutterDamage frame_damage;
/// This boolean is used to flag to the rendering backend whether partial
/// is enabled or not. Partial repaint should be enabled by default. It might
/// be disabled when the embedder does not receive the required information
/// to execute dirty region management.
bool partial_repaint_enabled;
} FlutterVulkanImage;

/// Callback to fetch a Vulkan function pointer for a given instance. Normally,
Expand Down Expand Up @@ -751,13 +763,19 @@ typedef struct {
/// The callback invoked when resolving Vulkan function pointers.
FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback;
/// The callback invoked when the engine requests a VkImage from the embedder
/// for rendering the next frame.
/// for rendering the next frame. If using partial repaint, the user must
/// define this callback to fill in the value of image_damage of the image
/// being returned with the image's existing damage. If no image_damage is
/// given, the Embedder will do a full repaint.
/// Not used if a FlutterCompositor is supplied in FlutterProjectArgs.
FlutterVulkanImageCallback get_next_image_callback;
/// The callback invoked when a VkImage has been written to and is ready for
/// use by the embedder. Prior to calling this callback, the engine performs
/// a host sync, and so the VkImage can be used in a pipeline by the embedder
/// without any additional synchronization.
/// without any additional synchronization. If using partial reapint, the user
/// must use the image and frame damages passed through the given
/// FlutterVulkanImage to render only the damage areas of the screen and to
/// keep track of a damage history.
/// Not used if a FlutterCompositor is supplied in FlutterProjectArgs.
FlutterVulkanPresentCallback present_image_callback;

Expand Down
1 change: 0 additions & 1 deletion shell/platform/embedder/embedder_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ bool EmbedderSurfaceGL::GLContextPresent(const GLPresentInfo& present_info) {

// |GPUSurfaceGLDelegate|
GLFBOInfo EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
// Get the FBO ID using the gl_fbo_callback and then get exiting damage by
// passing that ID to the gl_populate_existing_damage.
return gl_dispatch_table_.gl_populate_existing_damage(
gl_dispatch_table_.gl_fbo_callback(frame_info));
Expand Down
8 changes: 6 additions & 2 deletions shell/platform/embedder/embedder_surface_vulkan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,12 @@ FlutterVulkanImage EmbedderSurfaceVulkan::AcquireImage(const SkISize& size) {
}

// |GPUSurfaceVulkanDelegate|
bool EmbedderSurfaceVulkan::PresentImage(VkImage image, VkFormat format) {
return vulkan_dispatch_table_.present_image(image, format);
bool EmbedderSurfaceVulkan::PresentImage(VkImage image,
VkFormat format,
SkIRect image_damage_skrect,
SkIRect frame_damage_skrect) {
return vulkan_dispatch_table_.present_image(
image, format, image_damage_skrect, frame_damage_skrect);
}

// |EmbedderSurface|
Expand Down
10 changes: 8 additions & 2 deletions shell/platform/embedder/embedder_surface_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface,
get_instance_proc_address; // required
std::function<FlutterVulkanImage(const SkISize& frame_size)>
get_next_image; // required
std::function<bool(VkImage image, VkFormat format)>
std::function<bool(VkImage image,
VkFormat format,
SkIRect image_damage_skrect,
SkIRect frame_damage_skrect)>
present_image; // required
};

Expand All @@ -51,7 +54,10 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface,
FlutterVulkanImage AcquireImage(const SkISize& size) override;

// |GPUSurfaceVulkanDelegate|
bool PresentImage(VkImage image, VkFormat format) override;
bool PresentImage(VkImage image,
VkFormat format,
SkIRect image_damage_skrect,
SkIRect frame_damage_skrect) override;

private:
bool valid_ = false;
Expand Down