[Impeller] don't use glFramebufferBlit for onscreen restore. (#163327)
With the OpenGLES backend, we use the MSAA render to texture extension. This means that the offscreen textures are multisample and implicitly resolved when sampled from. This implicit resolve does not occur in the blit command used to restore to the onscreen, which can trigger a crash in the GLES driver. In other backends, the onscreen is also multisample and the blit is OK. Fixes https://github.com/flutter/flutter/issues/163304
This commit is contained in:
parent
9393aae393
commit
3e219d1cd8
@ -1681,6 +1681,14 @@ std::shared_ptr<Texture> Canvas::FlipBackdrop(Point global_pass_position,
|
||||
return input_texture;
|
||||
}
|
||||
|
||||
bool Canvas::SupportsBlitToOnscreen() const {
|
||||
return renderer_.GetContext()
|
||||
->GetCapabilities()
|
||||
->SupportsTextureToTextureBlits() &&
|
||||
renderer_.GetContext()->GetBackendType() !=
|
||||
Context::BackendType::kOpenGLES;
|
||||
}
|
||||
|
||||
bool Canvas::BlitToOnscreen(bool is_onscreen) {
|
||||
auto command_buffer = renderer_.GetContext()->CreateCommandBuffer();
|
||||
command_buffer->SetLabel("EntityPass Root Command Buffer");
|
||||
@ -1688,9 +1696,7 @@ bool Canvas::BlitToOnscreen(bool is_onscreen) {
|
||||
.inline_pass_context->GetPassTarget()
|
||||
.GetRenderTarget();
|
||||
|
||||
if (renderer_.GetContext()
|
||||
->GetCapabilities()
|
||||
->SupportsTextureToTextureBlits()) {
|
||||
if (SupportsBlitToOnscreen()) {
|
||||
auto blit_pass = command_buffer->CreateBlitPass();
|
||||
blit_pass->AddCopy(offscreen_target.GetRenderTargetTexture(),
|
||||
render_target_.GetRenderTargetTexture());
|
||||
|
@ -251,6 +251,16 @@ class Canvas {
|
||||
// Visible for testing.
|
||||
bool RequiresReadback() const { return requires_readback_; }
|
||||
|
||||
// Whether the current device has the capabilities to blit an offscreen
|
||||
// texture into the onscreen.
|
||||
//
|
||||
// This requires the availibility of the blit framebuffer command, but is
|
||||
// disabled for GLES. A simple glBlitFramebuffer does not support resolving
|
||||
// different sample counts which may be present in GLES when using MSAA.
|
||||
//
|
||||
// Visible for testing.
|
||||
bool SupportsBlitToOnscreen() const;
|
||||
|
||||
private:
|
||||
ContentContext& renderer_;
|
||||
RenderTarget render_target_;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "impeller/display_list/canvas.h"
|
||||
#include "impeller/display_list/dl_vertices_geometry.h"
|
||||
#include "impeller/geometry/geometry_asserts.h"
|
||||
#include "impeller/playground/playground.h"
|
||||
#include "impeller/renderer/render_target.h"
|
||||
|
||||
namespace impeller {
|
||||
@ -372,5 +373,17 @@ TEST_P(AiksTest, DrawVerticesWithEmptyTextureCoordinates) {
|
||||
ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
|
||||
}
|
||||
|
||||
TEST_P(AiksTest, SupportsBlitToOnscreen) {
|
||||
ContentContext context(GetContext(), nullptr);
|
||||
auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
|
||||
/*requires_readback=*/true);
|
||||
|
||||
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
||||
EXPECT_FALSE(canvas->SupportsBlitToOnscreen());
|
||||
} else {
|
||||
EXPECT_TRUE(canvas->SupportsBlitToOnscreen());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
Loading…
x
Reference in New Issue
Block a user