Do not override partial repaint support globally (flutter/engine#35539)

This commit is contained in:
Kaushik Iska 2022-08-19 14:41:46 -04:00 committed by GitHub
parent d6c219efef
commit 7cdcb0f837
8 changed files with 45 additions and 11 deletions

View File

@ -51,7 +51,7 @@ class SurfaceFrame {
// If existing damage is unspecified (nullopt), entire frame will be
// rasterized (no partial redraw). To signal that there is no existing
// damage use an empty SkIRect.
std::optional<SkIRect> existing_damage;
std::optional<SkIRect> existing_damage = std::nullopt;
};
SurfaceFrame(sk_sp<SkSurface> surface,

View File

@ -30,7 +30,7 @@ struct GLFBOInfo {
// This boolean flags whether the returned FBO supports partial repaint.
const bool partial_repaint_enabled;
// The frame buffer's existing damage (i.e. damage since it was last used).
const SkIRect existing_damage;
const std::optional<SkIRect> existing_damage;
};
// Information passed during presentation of a frame.

View File

@ -196,7 +196,6 @@ bool GPUSurfaceGLSkia::CreateOrUpdateSurfaces(const SkISize& size) {
onscreen_surface_ = std::move(onscreen_surface);
fbo_id_ = fbo_info.fbo_id;
supports_partial_repaint_ = fbo_info.partial_repaint_enabled;
existing_damage_ = fbo_info.existing_damage;
return true;
@ -250,9 +249,9 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceGLSkia::AcquireFrame(
};
framebuffer_info = delegate_->GLContextFramebufferInfo();
// Partial repaint is enabled by default
framebuffer_info.supports_partial_repaint = supports_partial_repaint_;
framebuffer_info.existing_damage = existing_damage_;
if (!framebuffer_info.existing_damage.has_value()) {
framebuffer_info.existing_damage = existing_damage_;
}
return std::make_unique<SurfaceFrame>(surface, std::move(framebuffer_info),
submit_callback,
std::move(context_switch));
@ -303,7 +302,6 @@ bool GPUSurfaceGLSkia::PresentSurface(const SurfaceFrame& frame,
onscreen_surface_ = std::move(new_onscreen_surface);
fbo_id_ = fbo_info.fbo_id;
supports_partial_repaint_ = fbo_info.partial_repaint_enabled;
existing_damage_ = fbo_info.existing_damage;
}

View File

@ -67,8 +67,10 @@ class GPUSurfaceGLSkia : public Surface {
sk_sp<SkSurface> onscreen_surface_;
/// FBO backing the current `onscreen_surface_`.
uint32_t fbo_id_ = 0;
// Private variable used to keep track of the current FBO's existing damage.
SkIRect existing_damage_ = SkIRect::MakeEmpty();
// The current FBO's existing damage, as tracked by the GPU surface, delegates
// still have an option of overriding this damage with their own in
// `GLContextFrameBufferInfo`.
std::optional<SkIRect> existing_damage_ = std::nullopt;
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
@ -76,8 +78,6 @@ class GPUSurfaceGLSkia : public Surface {
// external view embedder is present.
const bool render_to_surface_ = true;
bool valid_ = false;
// Partial repaint is on by default.
bool supports_partial_repaint_ = true;
// WeakPtrFactory must be the last member.
fml::TaskRunnerAffineWeakPtrFactory<GPUSurfaceGLSkia> weak_factory_;

View File

@ -167,6 +167,8 @@ GLFBOInfo AndroidSurfaceGLSkia::GLContextFBO(GLFrameInfo frame_info) const {
// The default window bound framebuffer on Android.
return GLFBOInfo{
.fbo_id = 0,
.partial_repaint_enabled = onscreen_surface_->SupportsPartialRepaint(),
.existing_damage = onscreen_surface_->InitialDamage(),
};
}

View File

@ -80,6 +80,17 @@ EmbedderSurfaceGL::GLProcResolver EmbedderSurfaceGL::GetGLProcResolver() const {
return gl_dispatch_table_.gl_proc_resolver;
}
// |GPUSurfaceGLDelegate|
SurfaceFrame::FramebufferInfo EmbedderSurfaceGL::GLContextFramebufferInfo()
const {
// Enable partial repaint by default on the embedders.
auto info = SurfaceFrame::FramebufferInfo{};
info.supports_readback = true;
info.supports_partial_repaint =
gl_dispatch_table_.gl_populate_existing_damage != nullptr;
return info;
}
// |EmbedderSurface|
std::unique_ptr<Surface> EmbedderSurfaceGL::CreateGPUSurface() {
const bool render_to_surface = !external_view_embedder_;

View File

@ -71,6 +71,9 @@ class EmbedderSurfaceGL final : public EmbedderSurface,
// |GPUSurfaceGLDelegate|
GLProcResolver GetGLProcResolver() const override;
// |GPUSurfaceGLDelegate|
SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override;
FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceGL);
};

View File

@ -4065,6 +4065,26 @@ TEST_F(EmbedderTest, ExternalTextureGLRefreshedTooOften) {
EXPECT_TRUE(resolve_called);
}
TEST_F(EmbedderTest,
PresentInfoReceivesNoDamageWhenPopulateExistingDamageIsUndefined) {
auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext);
EmbedderConfigBuilder builder(context);
builder.SetOpenGLRendererConfig(SkISize::Make(800, 600));
builder.SetDartEntrypoint("render_gradient");
builder.GetRendererConfig().open_gl.populate_existing_damage = nullptr;
auto engine = builder.LaunchEngine();
ASSERT_TRUE(engine.is_valid());
// No damage should be passed.
static_cast<EmbedderTestContextGL&>(context).SetGLPresentCallback(
[](FlutterPresentInfo present_info) {
ASSERT_EQ(present_info.frame_damage.damage, nullptr);
ASSERT_EQ(present_info.buffer_damage.damage, nullptr);
});
}
INSTANTIATE_TEST_SUITE_P(
EmbedderTestGlVk,
EmbedderTestMultiBackend,