Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
[Impeller] remove mip usage for blur downsample, cap at 1/4
  • Loading branch information
jonahwilliams committed Jul 8, 2024
commit 2f8244a0c7f31b17e0ab902c754e50435dc446ac
1 change: 1 addition & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impeller_shaders("entity_shaders") {
"shaders/blending/vertices_uber.frag",
"shaders/gradients/fast_gradient.vert",
"shaders/gradients/fast_gradient.frag",
"shaders/texture_downsample.frag",
]
}

Expand Down
1 change: 1 addition & 0 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ ContentContext::ContentContext(
{static_cast<Scalar>(BlendSelectValues::kSoftLight), supports_decal});
}

texture_downsample_pipelines_.CreateDefault(*context_, options_trianglestrip);
rrect_blur_pipelines_.CreateDefault(*context_, options_trianglestrip);
texture_strict_src_pipelines_.CreateDefault(*context_, options);
tiled_texture_pipelines_.CreateDefault(*context_, options, {supports_decal});
Expand Down
10 changes: 10 additions & 0 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "impeller/entity/solid_fill.vert.h"
#include "impeller/entity/srgb_to_linear_filter.frag.h"
#include "impeller/entity/sweep_gradient_fill.frag.h"
#include "impeller/entity/texture_downsample.frag.h"
#include "impeller/entity/texture_fill.frag.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/entity/texture_fill_strict_src.frag.h"
Expand Down Expand Up @@ -110,6 +111,9 @@ using RRectBlurPipeline =
RenderPipelineHandle<RrectBlurVertexShader, RrectBlurFragmentShader>;
using TexturePipeline =
RenderPipelineHandle<TextureFillVertexShader, TextureFillFragmentShader>;
using TextureDownsamplePipeline =
RenderPipelineHandle<TextureFillVertexShader,
TextureDownsampleFragmentShader>;
using TextureStrictSrcPipeline =
RenderPipelineHandle<TextureFillVertexShader,
TextureFillStrictSrcFragmentShader>;
Expand Down Expand Up @@ -590,6 +594,11 @@ class ContentContext {
return GetPipeline(blend_softlight_pipelines_, opts);
}

std::shared_ptr<Pipeline<PipelineDescriptor>> GetDownsamplePipeline(
ContentContextOptions opts) const {
return GetPipeline(texture_downsample_pipelines_, opts);
}

// Framebuffer Advanced Blends
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendColorPipeline(ContentContextOptions opts) const {
Expand Down Expand Up @@ -881,6 +890,7 @@ class ContentContext {
sweep_gradient_ssbo_fill_pipelines_;
mutable Variants<RRectBlurPipeline> rrect_blur_pipelines_;
mutable Variants<TexturePipeline> texture_pipelines_;
mutable Variants<TextureDownsamplePipeline> texture_downsample_pipelines_;
mutable Variants<TextureStrictSrcPipeline> texture_strict_src_pipelines_;
#ifdef IMPELLER_ENABLE_OPENGLES
mutable Variants<TiledTextureExternalPipeline>
Expand Down
139 changes: 94 additions & 45 deletions impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "flutter/fml/make_copyable.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/texture_downsample.frag.h"
#include "impeller/entity/texture_fill.frag.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/renderer/render_pass.h"
Expand All @@ -19,7 +20,7 @@ namespace impeller {
using GaussianBlurVertexShader = GaussianBlurPipeline::VertexShader;
using GaussianBlurFragmentShader = GaussianBlurPipeline::FragmentShader;

const int32_t GaussianBlurFilterContents::kBlurFilterRequiredMipCount = 4;
const int32_t GaussianBlurFilterContents::kBlurFilterRequiredMipCount = 1;

namespace {

Expand Down Expand Up @@ -242,6 +243,11 @@ DownsamplePassArgs CalculateDownsamplePassArgs(
Scalar desired_scalar =
std::min(GaussianBlurFilterContents::CalculateScale(scaled_sigma.x),
GaussianBlurFilterContents::CalculateScale(scaled_sigma.y));

if (desired_scalar < 0.25) {
desired_scalar = 0.25;
}

// TODO(jonahwilliams): If desired_scalar is 1.0 and we fully acquired the
// gutter from the expanded_coverage_hint, we can skip the downsample pass.
// pass.
Expand Down Expand Up @@ -327,50 +333,93 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
const SamplerDescriptor& sampler_descriptor,
const DownsamplePassArgs& pass_args,
Entity::TileMode tile_mode) {
ContentContext::SubpassCallback subpass_callback =
[&](const ContentContext& renderer, RenderPass& pass) {
HostBuffer& host_buffer = renderer.GetTransientsBuffer();

pass.SetCommandLabel("Gaussian blur downsample");
auto pipeline_options = OptionsFromPass(pass);
pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;
pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options));

TextureFillVertexShader::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1));
frame_info.texture_sampler_y_coord_scale = 1.0;

TextureFillFragmentShader::FragInfo frag_info;
frag_info.alpha = 1.0;

const Quad& uvs = pass_args.uvs;
BindVertices<TextureFillVertexShader>(pass, host_buffer,
{
{Point(0, 0), uvs[0]},
{Point(1, 0), uvs[1]},
{Point(0, 1), uvs[2]},
{Point(1, 1), uvs[3]},
});

SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear;
linear_sampler_descriptor.min_filter = MinMagFilter::kLinear;
TextureFillVertexShader::BindFrameInfo(
pass, host_buffer.EmplaceUniform(frame_info));
TextureFillFragmentShader::BindFragInfo(
pass, host_buffer.EmplaceUniform(frag_info));
TextureFillFragmentShader::BindTextureSampler(
pass, input_texture,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
linear_sampler_descriptor));

return pass.Draw().ok();
};
fml::StatusOr<RenderTarget> render_target =
renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size,
command_buffer, subpass_callback);
return render_target;
if (pass_args.effective_scalar.x >= 0.5) {
ContentContext::SubpassCallback subpass_callback =
[&](const ContentContext& renderer, RenderPass& pass) {
HostBuffer& host_buffer = renderer.GetTransientsBuffer();

pass.SetCommandLabel("Gaussian blur downsample");
auto pipeline_options = OptionsFromPass(pass);
pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;
pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options));

TextureFillVertexShader::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1));
frame_info.texture_sampler_y_coord_scale = 1.0;

TextureFillFragmentShader::FragInfo frag_info;
frag_info.alpha = 1.0;

const Quad& uvs = pass_args.uvs;
BindVertices<TextureFillVertexShader>(pass, host_buffer,
{
{Point(0, 0), uvs[0]},
{Point(1, 0), uvs[1]},
{Point(0, 1), uvs[2]},
{Point(1, 1), uvs[3]},
});

SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear;
linear_sampler_descriptor.min_filter = MinMagFilter::kLinear;
TextureFillVertexShader::BindFrameInfo(
pass, host_buffer.EmplaceUniform(frame_info));
TextureFillFragmentShader::BindFragInfo(
pass, host_buffer.EmplaceUniform(frag_info));
TextureFillFragmentShader::BindTextureSampler(
pass, input_texture,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
linear_sampler_descriptor));

return pass.Draw().ok();
};
return renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size,
command_buffer, subpass_callback);
} else {
ContentContext::SubpassCallback subpass_callback =
[&](const ContentContext& renderer, RenderPass& pass) {
HostBuffer& host_buffer = renderer.GetTransientsBuffer();

pass.SetCommandLabel("Gaussian blur downsample");
auto pipeline_options = OptionsFromPass(pass);
pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;
pass.SetPipeline(renderer.GetDownsamplePipeline(pipeline_options));

TextureFillVertexShader::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1));
frame_info.texture_sampler_y_coord_scale = 1.0;

TextureDownsampleFragmentShader::FragInfo frag_info;
frag_info.pixel_size = Vector2(1.0 / input_texture->GetSize());

const Quad& uvs = pass_args.uvs;
BindVertices<TextureFillVertexShader>(pass, host_buffer,
{
{Point(0, 0), uvs[0]},
{Point(1, 0), uvs[1]},
{Point(0, 1), uvs[2]},
{Point(1, 1), uvs[3]},
});

SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear;
linear_sampler_descriptor.min_filter = MinMagFilter::kLinear;
TextureFillVertexShader::BindFrameInfo(
pass, host_buffer.EmplaceUniform(frame_info));
TextureDownsampleFragmentShader::BindFragInfo(
pass, host_buffer.EmplaceUniform(frag_info));
TextureDownsampleFragmentShader::BindTextureSampler(
pass, input_texture,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
linear_sampler_descriptor));

return pass.Draw().ok();
};
return renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size,
command_buffer, subpass_callback);
}
}

fml::StatusOr<RenderTarget> MakeBlurSubpass(
Expand Down
40 changes: 40 additions & 0 deletions impeller/entity/shaders/texture_downsample.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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.

precision mediump float;

#include <impeller/constants.glsl>
#include <impeller/types.glsl>

uniform f16sampler2D texture_sampler;

uniform FragInfo {
vec2 pixel_size;
}
frag_info;

in highp vec2 v_texture_coords;

out f16vec4 frag_color;

void main() {
f16vec4 lt = texture(texture_sampler, v_texture_coords - frag_info.pixel_size,
float16_t(kDefaultMipBias)) *
0.25hf;
f16vec4 rt = texture(texture_sampler,
v_texture_coords + vec2(-frag_info.pixel_size.x,
frag_info.pixel_size.y),
float16_t(kDefaultMipBias)) *
0.25hf;
f16vec4 lb = texture(texture_sampler,
v_texture_coords + vec2(frag_info.pixel_size.x,
-frag_info.pixel_size.y),
float16_t(kDefaultMipBias)) *
0.25hf;
f16vec4 rb = texture(texture_sampler, v_texture_coords + frag_info.pixel_size,
float16_t(kDefaultMipBias)) *
0.25hf;

frag_color = lt + rb + lb + rb;
}