Skip to content

Commit

Permalink
[Impeller] Add blit pass (flutter#34901)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdero authored Jul 27, 2022
1 parent 9959096 commit 4becf49
Show file tree
Hide file tree
Showing 48 changed files with 1,436 additions and 28 deletions.
14 changes: 14 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,10 @@ FILE: ../../../flutter/impeller/renderer/allocator.cc
FILE: ../../../flutter/impeller/renderer/allocator.h
FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/allocator_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_command_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_command_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_pass_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/blit_pass_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.h
FILE: ../../../flutter/impeller/renderer/backend/gles/capabilities_gles.cc
Expand Down Expand Up @@ -712,6 +716,10 @@ FILE: ../../../flutter/impeller/renderer/backend/gles/texture_gles.cc
FILE: ../../../flutter/impeller/renderer/backend/gles/texture_gles.h
FILE: ../../../flutter/impeller/renderer/backend/metal/allocator_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/allocator_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_command_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_command_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/command_buffer_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/context_mtl.h
Expand Down Expand Up @@ -742,6 +750,8 @@ FILE: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/vulkan/allocator_vk.cc
FILE: ../../../flutter/impeller/renderer/backend/vulkan/allocator_vk.h
FILE: ../../../flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc
FILE: ../../../flutter/impeller/renderer/backend/vulkan/blit_pass_vk.h
FILE: ../../../flutter/impeller/renderer/backend/vulkan/capabilities_vk.cc
FILE: ../../../flutter/impeller/renderer/backend/vulkan/capabilities_vk.h
FILE: ../../../flutter/impeller/renderer/backend/vulkan/command_buffer_vk.cc
Expand Down Expand Up @@ -773,6 +783,10 @@ FILE: ../../../flutter/impeller/renderer/backend/vulkan/texture_vk.h
FILE: ../../../flutter/impeller/renderer/backend/vulkan/vertex_descriptor_vk.cc
FILE: ../../../flutter/impeller/renderer/backend/vulkan/vertex_descriptor_vk.h
FILE: ../../../flutter/impeller/renderer/backend/vulkan/vk.h
FILE: ../../../flutter/impeller/renderer/blit_command.cc
FILE: ../../../flutter/impeller/renderer/blit_command.h
FILE: ../../../flutter/impeller/renderer/blit_pass.cc
FILE: ../../../flutter/impeller/renderer/blit_pass.h
FILE: ../../../flutter/impeller/renderer/buffer.cc
FILE: ../../../flutter/impeller/renderer/buffer.h
FILE: ../../../flutter/impeller/renderer/buffer_view.cc
Expand Down
6 changes: 6 additions & 0 deletions impeller/display_list/display_list_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "impeller/geometry/path_builder.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/vertices.h"
#include "impeller/renderer/formats.h"
#include "impeller/typographer/backends/skia/text_frame_skia.h"

#include "third_party/skia/include/core/SkColor.h"
Expand Down Expand Up @@ -778,6 +779,11 @@ static impeller::SamplerDescriptor ToSamplerDescriptor(
desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
desc.label = "Linear Sampler";
break;
case flutter::DlImageSampling::kMipmapLinear:
desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
desc.mip_filter = impeller::MipFilter::kLinear;
desc.label = "Mipmap Linear Sampler";
break;
default:
break;
}
Expand Down
2 changes: 2 additions & 0 deletions impeller/fixtures/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ impeller_shaders("shader_fixtures") {
"impeller.vert",
"instanced_draw.frag",
"instanced_draw.vert",
"mipmaps.frag",
"mipmaps.vert",
"simple.vert",
"test_texture.frag",
"test_texture.vert",
Expand Down
18 changes: 18 additions & 0 deletions impeller/fixtures/mipmaps.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

uniform FragInfo {
float lod;
}
frag_info;

uniform sampler2D tex;

in vec2 v_uv;

out vec4 frag_color;

void main() {
frag_color = textureLod(tex, v_uv, frag_info.lod);
}
18 changes: 18 additions & 0 deletions impeller/fixtures/mipmaps.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

uniform VertInfo {
mat4 mvp;
}
vert_info;

in vec2 vertex_position;
in vec2 uv;

out vec2 v_uv;

void main() {
gl_Position = vert_info.mvp * vec4(vertex_position, 0.0, 1.0);
v_uv = uv;
}
6 changes: 4 additions & 2 deletions impeller/playground/playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@ std::optional<DecompressedImage> Playground::LoadFixtureImageRGBA(
}

std::shared_ptr<Texture> Playground::CreateTextureForFixture(
const char* fixture_name) const {
const char* fixture_name,
bool enable_mipmapping) const {
auto image = LoadFixtureImageRGBA(fixture_name);
if (!image.has_value()) {
return nullptr;
Expand All @@ -343,7 +344,8 @@ std::shared_ptr<Texture> Playground::CreateTextureForFixture(
auto texture_descriptor = TextureDescriptor{};
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
texture_descriptor.size = image->GetSize();
texture_descriptor.mip_count = 1u;
texture_descriptor.mip_count =
enable_mipmapping ? image->GetSize().MipCount() : 1u;

auto texture =
renderer_->GetContext()->GetPermanentsAllocator()->CreateTexture(
Expand Down
3 changes: 2 additions & 1 deletion impeller/playground/playground.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class Playground : public ::testing::TestWithParam<PlaygroundBackend> {
const char* fixture_name) const;

std::shared_ptr<Texture> CreateTextureForFixture(
const char* fixture_name) const;
const char* fixture_name,
bool enable_mipmapping = false) const;

std::shared_ptr<Texture> CreateTextureCubeForFixture(
std::array<const char*, 6> fixture_names) const;
Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ impeller_component("renderer") {
sources = [
"allocator.cc",
"allocator.h",
"blit_command.cc",
"blit_command.h",
"blit_pass.cc",
"blit_pass.h",
"buffer.cc",
"buffer.h",
"buffer_view.cc",
Expand Down
9 changes: 8 additions & 1 deletion impeller/renderer/backend/gles/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ impeller_component("gles") {
sources = [
"allocator_gles.cc",
"allocator_gles.h",
"blit_command_gles.cc",
"blit_command_gles.h",
"blit_pass_gles.cc",
"blit_pass_gles.h",
"buffer_bindings_gles.cc",
"buffer_bindings_gles.h",
"capabilities_gles.cc",
Expand Down Expand Up @@ -60,8 +64,11 @@ impeller_component("gles") {
if (!is_android && !is_fuchsia) {
public_configs = [ ":gles_config" ]
sources += [
"//third_party/angle/include/GLES2/gl2.h",
"//third_party/angle/include/GLES2/gl2ext.h",

# The GLES3 API is a superset of GLES2. Although we target GLES2, we use
# some GLES3 features if the driver supports them.
"//third_party/angle/include/GLES3/gl3.h",
]
}

Expand Down
134 changes: 134 additions & 0 deletions impeller/renderer/backend/gles/blit_command_gles.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/renderer/backend/gles/blit_command_gles.h"

#include "flutter/fml/closure.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/backend/gles/texture_gles.h"

namespace impeller {

BlitEncodeGLES::~BlitEncodeGLES() = default;

static void DeleteFBO(const ProcTableGLES& gl, GLuint fbo, GLenum type) {
if (fbo != GL_NONE) {
gl.BindFramebuffer(type, GL_NONE);
gl.DeleteFramebuffers(1u, &fbo);
}
};

static std::optional<GLuint> ConfigureFBO(
const ProcTableGLES& gl,
const std::shared_ptr<Texture>& texture,
GLenum fbo_type) {
auto handle = TextureGLES::Cast(texture.get())->GetGLHandle();
if (!handle.has_value()) {
return std::nullopt;
}

if (TextureGLES::Cast(*texture).IsWrapped()) {
// The texture is attached to the default FBO, so there's no need to
// create/configure one.
gl.BindFramebuffer(fbo_type, 0);
return 0;
}

GLuint fbo;
gl.GenFramebuffers(1u, &fbo);
gl.BindFramebuffer(fbo_type, fbo);

if (!TextureGLES::Cast(*texture).SetAsFramebufferAttachment(
fbo_type, fbo, TextureGLES::AttachmentPoint::kColor0)) {
VALIDATION_LOG << "Could not attach texture to framebuffer.";
DeleteFBO(gl, fbo, fbo_type);
return std::nullopt;
}

if (gl.CheckFramebufferStatus(fbo_type) != GL_FRAMEBUFFER_COMPLETE) {
VALIDATION_LOG << "Could not create a complete frambuffer.";
DeleteFBO(gl, fbo, fbo_type);
return std::nullopt;
}

return fbo;
};

BlitCopyTextureToTextureCommandGLES::~BlitCopyTextureToTextureCommandGLES() =
default;

std::string BlitCopyTextureToTextureCommandGLES::GetLabel() const {
return label;
}

bool BlitCopyTextureToTextureCommandGLES::Encode(
const ReactorGLES& reactor) const {
const auto& gl = reactor.GetProcTable();

// glBlitFramebuffer is a GLES3 proc. Since we target GLES2, we need to
// emulate the blit when it's not available in the driver.
if (!gl.BlitFramebuffer.IsAvailable()) {
// TODO(bdero): Emulate the blit using a raster draw call here.
FML_LOG(ERROR) << "Texture blit fallback not implemented yet for GLES2.";
return false;
}

GLuint read_fbo = GL_NONE;
GLuint draw_fbo = GL_NONE;
fml::ScopedCleanupClosure delete_fbos([&gl, &read_fbo, &draw_fbo]() {
DeleteFBO(gl, read_fbo, GL_READ_FRAMEBUFFER);
DeleteFBO(gl, draw_fbo, GL_DRAW_FRAMEBUFFER);
});

{
auto read = ConfigureFBO(gl, source, GL_READ_FRAMEBUFFER);
if (!read.has_value()) {
return false;
}
read_fbo = read.value();
}

{
auto draw = ConfigureFBO(gl, destination, GL_DRAW_FRAMEBUFFER);
if (!draw.has_value()) {
return false;
}
draw_fbo = draw.value();
}

gl.Disable(GL_SCISSOR_TEST);
gl.Disable(GL_DEPTH_TEST);
gl.Disable(GL_STENCIL_TEST);

gl.BlitFramebuffer(source_region.origin.x, // srcX0
source_region.origin.y, // srcY0
source_region.size.width, // srcX1
source_region.size.height, // srcY1
destination_origin.x, // dstX0
destination_origin.y, // dstY0
source_region.size.width, // dstX1
source_region.size.height, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_NEAREST // filter
);

return true;
};

BlitGenerateMipmapCommandGLES::~BlitGenerateMipmapCommandGLES() = default;

std::string BlitGenerateMipmapCommandGLES::GetLabel() const {
return label;
}

bool BlitGenerateMipmapCommandGLES::Encode(const ReactorGLES& reactor) const {
auto texture_gles = TextureGLES::Cast(texture.get());
if (!texture_gles->GenerateMipmaps()) {
return false;
}

return true;
};

} // namespace impeller
41 changes: 41 additions & 0 deletions impeller/renderer/backend/gles/blit_command_gles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include "impeller/base/backend_cast.h"
#include "impeller/renderer/backend/gles/reactor_gles.h"
#include "impeller/renderer/blit_command.h"

namespace impeller {

/// Mixin for dispatching GLES commands.
struct BlitEncodeGLES : BackendCast<BlitEncodeGLES, BlitCommand> {
virtual ~BlitEncodeGLES();

virtual std::string GetLabel() const = 0;

[[nodiscard]] virtual bool Encode(const ReactorGLES& reactor) const = 0;
};

struct BlitCopyTextureToTextureCommandGLES
: public BlitEncodeGLES,
public BlitCopyTextureToTextureCommand {
~BlitCopyTextureToTextureCommandGLES() override;

std::string GetLabel() const override;

[[nodiscard]] bool Encode(const ReactorGLES& reactor) const override;
};

struct BlitGenerateMipmapCommandGLES : public BlitEncodeGLES,
public BlitGenerateMipmapCommand {
~BlitGenerateMipmapCommandGLES() override;

std::string GetLabel() const override;

[[nodiscard]] bool Encode(const ReactorGLES& reactor) const override;
};

} // namespace impeller
Loading

0 comments on commit 4becf49

Please sign in to comment.