Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4becf49

Browse files
authored
[Impeller] Add blit pass (#34901)
1 parent 9959096 commit 4becf49

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1436
-28
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,10 @@ FILE: ../../../flutter/impeller/renderer/allocator.cc
671671
FILE: ../../../flutter/impeller/renderer/allocator.h
672672
FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.cc
673673
FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.h
674+
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_command_gles.cc
675+
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_command_gles.h
676+
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_pass_gles.cc
677+
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_pass_gles.h
674678
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc
675679
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h
676680
FILE: ../../../flutter/impeller/renderer/backend/gles/capabilities_gles.cc
@@ -712,6 +716,10 @@ FILE: ../../../flutter/impeller/renderer/backend/gles/texture_gles.cc
712716
FILE: ../../../flutter/impeller/renderer/backend/gles/texture_gles.h
713717
FILE: ../../../flutter/impeller/renderer/backend/metal/allocator_mtl.h
714718
FILE: ../../../flutter/impeller/renderer/backend/metal/allocator_mtl.mm
719+
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_command_mtl.h
720+
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_command_mtl.mm
721+
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.h
722+
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm
715723
FILE: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.h
716724
FILE: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.mm
717725
FILE: ../../../flutter/impeller/renderer/backend/metal/context_mtl.h
@@ -742,6 +750,8 @@ FILE: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.h
742750
FILE: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm
743751
FILE: ../../../flutter/impeller/renderer/backend/vulkan/allocator_vk.cc
744752
FILE: ../../../flutter/impeller/renderer/backend/vulkan/allocator_vk.h
753+
FILE: ../../../flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc
754+
FILE: ../../../flutter/impeller/renderer/backend/vulkan/blit_pass_vk.h
745755
FILE: ../../../flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc
746756
FILE: ../../../flutter/impeller/renderer/backend/vulkan/capabilities_vk.h
747757
FILE: ../../../flutter/impeller/renderer/backend/vulkan/command_buffer_vk.cc
@@ -773,6 +783,10 @@ FILE: ../../../flutter/impeller/renderer/backend/vulkan/texture_vk.h
773783
FILE: ../../../flutter/impeller/renderer/backend/vulkan/vertex_descriptor_vk.cc
774784
FILE: ../../../flutter/impeller/renderer/backend/vulkan/vertex_descriptor_vk.h
775785
FILE: ../../../flutter/impeller/renderer/backend/vulkan/vk.h
786+
FILE: ../../../flutter/impeller/renderer/blit_command.cc
787+
FILE: ../../../flutter/impeller/renderer/blit_command.h
788+
FILE: ../../../flutter/impeller/renderer/blit_pass.cc
789+
FILE: ../../../flutter/impeller/renderer/blit_pass.h
776790
FILE: ../../../flutter/impeller/renderer/buffer.cc
777791
FILE: ../../../flutter/impeller/renderer/buffer.h
778792
FILE: ../../../flutter/impeller/renderer/buffer_view.cc

impeller/display_list/display_list_dispatcher.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "impeller/geometry/path_builder.h"
2323
#include "impeller/geometry/scalar.h"
2424
#include "impeller/geometry/vertices.h"
25+
#include "impeller/renderer/formats.h"
2526
#include "impeller/typographer/backends/skia/text_frame_skia.h"
2627

2728
#include "third_party/skia/include/core/SkColor.h"
@@ -778,6 +779,11 @@ static impeller::SamplerDescriptor ToSamplerDescriptor(
778779
desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
779780
desc.label = "Linear Sampler";
780781
break;
782+
case flutter::DlImageSampling::kMipmapLinear:
783+
desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
784+
desc.mip_filter = impeller::MipFilter::kLinear;
785+
desc.label = "Mipmap Linear Sampler";
786+
break;
781787
default:
782788
break;
783789
}

impeller/fixtures/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ impeller_shaders("shader_fixtures") {
1616
"impeller.vert",
1717
"instanced_draw.frag",
1818
"instanced_draw.vert",
19+
"mipmaps.frag",
20+
"mipmaps.vert",
1921
"simple.vert",
2022
"test_texture.frag",
2123
"test_texture.vert",

impeller/fixtures/mipmaps.frag

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
uniform FragInfo {
6+
float lod;
7+
}
8+
frag_info;
9+
10+
uniform sampler2D tex;
11+
12+
in vec2 v_uv;
13+
14+
out vec4 frag_color;
15+
16+
void main() {
17+
frag_color = textureLod(tex, v_uv, frag_info.lod);
18+
}

impeller/fixtures/mipmaps.vert

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
uniform VertInfo {
6+
mat4 mvp;
7+
}
8+
vert_info;
9+
10+
in vec2 vertex_position;
11+
in vec2 uv;
12+
13+
out vec2 v_uv;
14+
15+
void main() {
16+
gl_Position = vert_info.mvp * vec4(vertex_position, 0.0, 1.0);
17+
v_uv = uv;
18+
}

impeller/playground/playground.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ std::optional<DecompressedImage> Playground::LoadFixtureImageRGBA(
334334
}
335335

336336
std::shared_ptr<Texture> Playground::CreateTextureForFixture(
337-
const char* fixture_name) const {
337+
const char* fixture_name,
338+
bool enable_mipmapping) const {
338339
auto image = LoadFixtureImageRGBA(fixture_name);
339340
if (!image.has_value()) {
340341
return nullptr;
@@ -343,7 +344,8 @@ std::shared_ptr<Texture> Playground::CreateTextureForFixture(
343344
auto texture_descriptor = TextureDescriptor{};
344345
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
345346
texture_descriptor.size = image->GetSize();
346-
texture_descriptor.mip_count = 1u;
347+
texture_descriptor.mip_count =
348+
enable_mipmapping ? image->GetSize().MipCount() : 1u;
347349

348350
auto texture =
349351
renderer_->GetContext()->GetPermanentsAllocator()->CreateTexture(

impeller/playground/playground.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class Playground : public ::testing::TestWithParam<PlaygroundBackend> {
5757
const char* fixture_name) const;
5858

5959
std::shared_ptr<Texture> CreateTextureForFixture(
60-
const char* fixture_name) const;
60+
const char* fixture_name,
61+
bool enable_mipmapping = false) const;
6162

6263
std::shared_ptr<Texture> CreateTextureCubeForFixture(
6364
std::array<const char*, 6> fixture_names) const;

impeller/renderer/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ impeller_component("renderer") {
88
sources = [
99
"allocator.cc",
1010
"allocator.h",
11+
"blit_command.cc",
12+
"blit_command.h",
13+
"blit_pass.cc",
14+
"blit_pass.h",
1115
"buffer.cc",
1216
"buffer.h",
1317
"buffer_view.cc",

impeller/renderer/backend/gles/BUILD.gn

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ impeller_component("gles") {
1616
sources = [
1717
"allocator_gles.cc",
1818
"allocator_gles.h",
19+
"blit_command_gles.cc",
20+
"blit_command_gles.h",
21+
"blit_pass_gles.cc",
22+
"blit_pass_gles.h",
1923
"buffer_bindings_gles.cc",
2024
"buffer_bindings_gles.h",
2125
"capabilities_gles.cc",
@@ -60,8 +64,11 @@ impeller_component("gles") {
6064
if (!is_android && !is_fuchsia) {
6165
public_configs = [ ":gles_config" ]
6266
sources += [
63-
"//third_party/angle/include/GLES2/gl2.h",
6467
"//third_party/angle/include/GLES2/gl2ext.h",
68+
69+
# The GLES3 API is a superset of GLES2. Although we target GLES2, we use
70+
# some GLES3 features if the driver supports them.
71+
"//third_party/angle/include/GLES3/gl3.h",
6572
]
6673
}
6774

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "impeller/renderer/backend/gles/blit_command_gles.h"
6+
7+
#include "flutter/fml/closure.h"
8+
#include "impeller/base/validation.h"
9+
#include "impeller/renderer/backend/gles/texture_gles.h"
10+
11+
namespace impeller {
12+
13+
BlitEncodeGLES::~BlitEncodeGLES() = default;
14+
15+
static void DeleteFBO(const ProcTableGLES& gl, GLuint fbo, GLenum type) {
16+
if (fbo != GL_NONE) {
17+
gl.BindFramebuffer(type, GL_NONE);
18+
gl.DeleteFramebuffers(1u, &fbo);
19+
}
20+
};
21+
22+
static std::optional<GLuint> ConfigureFBO(
23+
const ProcTableGLES& gl,
24+
const std::shared_ptr<Texture>& texture,
25+
GLenum fbo_type) {
26+
auto handle = TextureGLES::Cast(texture.get())->GetGLHandle();
27+
if (!handle.has_value()) {
28+
return std::nullopt;
29+
}
30+
31+
if (TextureGLES::Cast(*texture).IsWrapped()) {
32+
// The texture is attached to the default FBO, so there's no need to
33+
// create/configure one.
34+
gl.BindFramebuffer(fbo_type, 0);
35+
return 0;
36+
}
37+
38+
GLuint fbo;
39+
gl.GenFramebuffers(1u, &fbo);
40+
gl.BindFramebuffer(fbo_type, fbo);
41+
42+
if (!TextureGLES::Cast(*texture).SetAsFramebufferAttachment(
43+
fbo_type, fbo, TextureGLES::AttachmentPoint::kColor0)) {
44+
VALIDATION_LOG << "Could not attach texture to framebuffer.";
45+
DeleteFBO(gl, fbo, fbo_type);
46+
return std::nullopt;
47+
}
48+
49+
if (gl.CheckFramebufferStatus(fbo_type) != GL_FRAMEBUFFER_COMPLETE) {
50+
VALIDATION_LOG << "Could not create a complete frambuffer.";
51+
DeleteFBO(gl, fbo, fbo_type);
52+
return std::nullopt;
53+
}
54+
55+
return fbo;
56+
};
57+
58+
BlitCopyTextureToTextureCommandGLES::~BlitCopyTextureToTextureCommandGLES() =
59+
default;
60+
61+
std::string BlitCopyTextureToTextureCommandGLES::GetLabel() const {
62+
return label;
63+
}
64+
65+
bool BlitCopyTextureToTextureCommandGLES::Encode(
66+
const ReactorGLES& reactor) const {
67+
const auto& gl = reactor.GetProcTable();
68+
69+
// glBlitFramebuffer is a GLES3 proc. Since we target GLES2, we need to
70+
// emulate the blit when it's not available in the driver.
71+
if (!gl.BlitFramebuffer.IsAvailable()) {
72+
// TODO(bdero): Emulate the blit using a raster draw call here.
73+
FML_LOG(ERROR) << "Texture blit fallback not implemented yet for GLES2.";
74+
return false;
75+
}
76+
77+
GLuint read_fbo = GL_NONE;
78+
GLuint draw_fbo = GL_NONE;
79+
fml::ScopedCleanupClosure delete_fbos([&gl, &read_fbo, &draw_fbo]() {
80+
DeleteFBO(gl, read_fbo, GL_READ_FRAMEBUFFER);
81+
DeleteFBO(gl, draw_fbo, GL_DRAW_FRAMEBUFFER);
82+
});
83+
84+
{
85+
auto read = ConfigureFBO(gl, source, GL_READ_FRAMEBUFFER);
86+
if (!read.has_value()) {
87+
return false;
88+
}
89+
read_fbo = read.value();
90+
}
91+
92+
{
93+
auto draw = ConfigureFBO(gl, destination, GL_DRAW_FRAMEBUFFER);
94+
if (!draw.has_value()) {
95+
return false;
96+
}
97+
draw_fbo = draw.value();
98+
}
99+
100+
gl.Disable(GL_SCISSOR_TEST);
101+
gl.Disable(GL_DEPTH_TEST);
102+
gl.Disable(GL_STENCIL_TEST);
103+
104+
gl.BlitFramebuffer(source_region.origin.x, // srcX0
105+
source_region.origin.y, // srcY0
106+
source_region.size.width, // srcX1
107+
source_region.size.height, // srcY1
108+
destination_origin.x, // dstX0
109+
destination_origin.y, // dstY0
110+
source_region.size.width, // dstX1
111+
source_region.size.height, // dstY1
112+
GL_COLOR_BUFFER_BIT, // mask
113+
GL_NEAREST // filter
114+
);
115+
116+
return true;
117+
};
118+
119+
BlitGenerateMipmapCommandGLES::~BlitGenerateMipmapCommandGLES() = default;
120+
121+
std::string BlitGenerateMipmapCommandGLES::GetLabel() const {
122+
return label;
123+
}
124+
125+
bool BlitGenerateMipmapCommandGLES::Encode(const ReactorGLES& reactor) const {
126+
auto texture_gles = TextureGLES::Cast(texture.get());
127+
if (!texture_gles->GenerateMipmaps()) {
128+
return false;
129+
}
130+
131+
return true;
132+
};
133+
134+
} // namespace impeller

0 commit comments

Comments
 (0)