Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller] compute UVs in vertex stage. #52106

Merged
merged 12 commits into from
Apr 20, 2024
Merged
2 changes: 1 addition & 1 deletion impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ impeller_shaders("entity_shaders") {
"shaders/gradients/sweep_gradient_fill.frag",
"shaders/texture_fill.frag",
"shaders/texture_fill.vert",
"shaders/texture_uv_fill.vert",
"shaders/tiled_texture_fill.frag",
"shaders/tiled_texture_fill_external.frag",
"shaders/texture_fill_strict_src.frag",
Expand Down Expand Up @@ -79,7 +80,6 @@ impeller_shaders("modern_entity_shaders") {
"shaders/gradients/radial_gradient_ssbo_fill.frag",
"shaders/gradients/sweep_gradient_ssbo_fill.frag",
"shaders/geometry/points.comp",
"shaders/geometry/uv.comp",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 for 1!

]
}

Expand Down
1 change: 0 additions & 1 deletion impeller/entity/contents/clip_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <memory>
#include <vector>

#include "flutter/fml/macros.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/geometry/geometry.h"
Expand Down
10 changes: 2 additions & 8 deletions impeller/entity/contents/color_source_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,7 @@ class ColorSourceContents : public Contents {
RenderPass& pass,
const PipelineBuilderCallback& pipeline_callback,
typename VertexShaderT::FrameInfo frame_info,
const BindFragmentCallback& bind_fragment_callback,
bool enable_uvs = false,
Rect texture_coverage = {},
const Matrix& effect_transform = {}) const {
const BindFragmentCallback& bind_fragment_callback) const {
auto options = OptionsFromPassAndEntity(pass, entity);

GeometryResult::Mode geometry_mode = GetGeometry()->GetResultMode();
Expand Down Expand Up @@ -181,10 +178,7 @@ class ColorSourceContents : public Contents {
}

GeometryResult geometry_result =
enable_uvs
? geometry.GetPositionUVBuffer(texture_coverage, effect_transform,
renderer, entity, pass)
: geometry.GetPositionBuffer(renderer, entity, pass);
geometry.GetPositionBuffer(renderer, entity, pass);
if (geometry_result.vertex_buffer.vertex_count == 0u) {
return true;
}
Expand Down
10 changes: 2 additions & 8 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,7 @@ ContentContext::ContentContext(
? std::make_shared<RenderTargetCache>(
context_->GetResourceAllocator())
: std::move(render_target_allocator)),
host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())),
pending_command_buffers_(std::make_unique<PendingCommandBuffers>()) {
host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())) {
if (!context_ || !context_->IsValid()) {
return;
}
Expand Down Expand Up @@ -423,7 +422,7 @@ ContentContext::ContentContext(
rrect_blur_pipelines_.CreateDefault(*context_, options_trianglestrip);
texture_strict_src_pipelines_.CreateDefault(*context_, options);
position_uv_pipelines_.CreateDefault(*context_, options);
tiled_texture_pipelines_.CreateDefault(*context_, options);
tiled_texture_pipelines_.CreateDefault(*context_, options, {supports_decal});
kernel_decal_pipelines_.CreateDefault(*context_, options_trianglestrip);
kernel_nodecal_pipelines_.CreateDefault(*context_, options_trianglestrip);
border_mask_blur_pipelines_.CreateDefault(*context_, options_trianglestrip);
Expand Down Expand Up @@ -456,11 +455,6 @@ ContentContext::ContentContext(
PointsComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_);
point_field_compute_pipelines_ =
context_->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();

auto uv_pipeline_desc =
UvComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_);
uv_compute_pipelines_ =
context_->GetPipelineLibrary()->GetPipeline(uv_pipeline_desc).Get();
}

is_valid_ = true;
Expand Down
22 changes: 3 additions & 19 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@
#include "impeller/entity/texture_fill.frag.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/entity/texture_fill_strict_src.frag.h"
#include "impeller/entity/texture_uv_fill.vert.h"
#include "impeller/entity/tiled_texture_fill.frag.h"
#include "impeller/entity/uv.comp.h"
#include "impeller/entity/vertices.frag.h"
#include "impeller/entity/yuv_to_rgb_filter.frag.h"

Expand Down Expand Up @@ -132,7 +132,7 @@ using TextureStrictSrcPipeline =
using PositionUVPipeline = RenderPipelineHandle<TextureFillVertexShader,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused

TiledTextureFillFragmentShader>;
using TiledTexturePipeline =
RenderPipelineHandle<TextureFillVertexShader,
RenderPipelineHandle<TextureUvFillVertexShader,
TiledTextureFillFragmentShader>;
using KernelDecalPipeline =
RenderPipelineHandle<KernelVertexShader, KernelDecalFragmentShader>;
Expand Down Expand Up @@ -253,20 +253,13 @@ using FramebufferBlendSoftLightPipeline =

/// Geometry Pipelines
using PointsComputeShaderPipeline = ComputePipelineBuilder<PointsComputeShader>;
using UvComputeShaderPipeline = ComputePipelineBuilder<UvComputeShader>;

#ifdef IMPELLER_ENABLE_OPENGLES
using TiledTextureExternalPipeline =
RenderPipelineHandle<TextureFillVertexShader,
RenderPipelineHandle<TextureUvFillVertexShader,
TiledTextureFillExternalFragmentShader>;
#endif // IMPELLER_ENABLE_OPENGLES

// A struct used to isolate command buffer storage from the content
// context options to preserve const-ness.
struct PendingCommandBuffers {
std::vector<std::shared_ptr<CommandBuffer>> command_buffers;
};

/// Pipeline state configuration.
///
/// Each unique combination of these options requires a different pipeline state
Expand Down Expand Up @@ -727,12 +720,6 @@ class ContentContext {
return point_field_compute_pipelines_;
}

std::shared_ptr<Pipeline<ComputePipelineDescriptor>> GetUvComputePipeline()
const {
FML_DCHECK(GetDeviceCapabilities().SupportsCompute());
return uv_compute_pipelines_;
}

std::shared_ptr<Context> GetContext() const;

const Capabilities& GetDeviceCapabilities() const;
Expand Down Expand Up @@ -997,8 +984,6 @@ class ContentContext {
framebuffer_blend_softlight_pipelines_;
mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
point_field_compute_pipelines_;
mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
uv_compute_pipelines_;

template <class TypedPipeline>
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
Expand Down Expand Up @@ -1058,7 +1043,6 @@ class ContentContext {
#endif // IMPELLER_ENABLE_3D
std::shared_ptr<RenderTargetAllocator> render_target_cache_;
std::shared_ptr<HostBuffer> host_buffer_;
std::unique_ptr<PendingCommandBuffers> pending_command_buffers_;
bool wireframe_ = false;

ContentContext(const ContentContext&) = delete;
Expand Down
43 changes: 5 additions & 38 deletions impeller/entity/contents/texture_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "impeller/entity/texture_fill.frag.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/entity/texture_fill_strict_src.frag.h"
#include "impeller/entity/tiled_texture_fill_external.frag.h"
#include "impeller/geometry/constants.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/vertex_buffer_builder.h"
Expand Down Expand Up @@ -114,7 +113,6 @@ bool TextureContents::Render(const ContentContext& renderer,

using VS = TextureFillVertexShader;
using FS = TextureFillFragmentShader;
using FSExternal = TiledTextureFillExternalFragmentShader;
using FSStrict = TextureFillStrictSrcFragmentShader;

if (destination_rect_.IsEmpty() || source_rect_.IsEmpty() ||
Expand All @@ -124,6 +122,7 @@ bool TextureContents::Render(const ContentContext& renderer,

bool is_external_texture =
texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES;
FML_DCHECK(!is_external_texture);

auto source_rect = capture.AddRect("Source rect", source_rect_);
auto texture_coords =
Expand Down Expand Up @@ -159,46 +158,14 @@ bool TextureContents::Render(const ContentContext& renderer,
}
pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;

std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
#ifdef IMPELLER_ENABLE_OPENGLES
if (is_external_texture) {
pipeline = renderer.GetTiledTextureExternalPipeline(pipeline_options);
}
#endif // IMPELLER_ENABLE_OPENGLES

if (!pipeline) {
if (strict_source_rect_enabled_) {
pipeline = renderer.GetTextureStrictSrcPipeline(pipeline_options);
} else {
pipeline = renderer.GetTexturePipeline(pipeline_options);
}
}
pass.SetPipeline(pipeline);
pass.SetPipeline(strict_source_rect_enabled_
? renderer.GetTextureStrictSrcPipeline(pipeline_options)
: renderer.GetTexturePipeline(pipeline_options));

pass.SetVertexBuffer(vertex_builder.CreateVertexBuffer(host_buffer));
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));

if (is_external_texture) {
FSExternal::FragInfo frag_info;
frag_info.x_tile_mode =
static_cast<int>(sampler_descriptor_.width_address_mode);
frag_info.y_tile_mode =
static_cast<int>(sampler_descriptor_.height_address_mode);
frag_info.alpha = capture.AddScalar("Alpha", GetOpacity());

auto sampler_descriptor = sampler_descriptor_;
// OES_EGL_image_external states that only CLAMP_TO_EDGE is valid, so
// we emulate all other tile modes here by remapping the texture
// coordinates.
sampler_descriptor.width_address_mode = SamplerAddressMode::kClampToEdge;
sampler_descriptor.height_address_mode = SamplerAddressMode::kClampToEdge;

FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform((frag_info)));
FSExternal::BindSAMPLEREXTERNALOESTextureSampler(
pass, texture_,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
sampler_descriptor));
} else if (strict_source_rect_enabled_) {
if (strict_source_rect_enabled_) {
// For a strict source rect, shrink the texture coordinate range by half a
// texel to ensure that linear filtering does not sample anything outside
// the source rect bounds.
Expand Down
39 changes: 10 additions & 29 deletions impeller/entity/contents/tiled_texture_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#include "fml/logging.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/texture_fill.frag.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/entity/tiled_texture_fill.frag.h"
#include "impeller/entity/tiled_texture_fill_external.frag.h"
#include "impeller/renderer/render_pass.h"
Expand Down Expand Up @@ -116,7 +114,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
return true;
}

using VS = TextureFillVertexShader;
using VS = TextureUvFillVertexShader;
using FS = TiledTextureFillFragmentShader;
using FSExternal = TiledTextureFillExternalFragmentShader;

Expand All @@ -128,26 +126,22 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
bool is_external_texture =
texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES;

bool uses_emulated_tile_mode =
UsesEmulatedTileMode(renderer.GetDeviceCapabilities());

VS::FrameInfo frame_info;
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
frame_info.uv_transform =
Rect::MakeSize(texture_size).GetNormalizingTransform() *
GetInverseEffectTransform();

PipelineBuilderMethod pipeline_method;

#ifdef IMPELLER_ENABLE_OPENGLES
if (is_external_texture) {
pipeline_method = &ContentContext::GetTiledTextureExternalPipeline;
} else {
pipeline_method = uses_emulated_tile_mode
? &ContentContext::GetTiledTexturePipeline
: &ContentContext::GetTexturePipeline;
pipeline_method = &ContentContext::GetTiledTexturePipeline;
}
#else
pipeline_method = uses_emulated_tile_mode
? &ContentContext::GetTiledTexturePipeline
: &ContentContext::GetTexturePipeline;
pipeline_method = &ContentContext::GetTiledTexturePipeline;
#endif // IMPELLER_ENABLE_OPENGLES

PipelineBuilderCallback pipeline_callback =
Expand All @@ -156,33 +150,23 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
};
return ColorSourceContents::DrawGeometry<VS>(
renderer, entity, pass, pipeline_callback, frame_info,
[this, &renderer, &is_external_texture,
&uses_emulated_tile_mode](RenderPass& pass) {
[this, &renderer, &is_external_texture](RenderPass& pass) {
auto& host_buffer = renderer.GetTransientsBuffer();

if (uses_emulated_tile_mode) {
pass.SetCommandLabel("TiledTextureFill");
} else {
pass.SetCommandLabel("TextureFill");
}
pass.SetCommandLabel("TextureFill");

if (is_external_texture) {
FSExternal::FragInfo frag_info;
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
frag_info.alpha = GetOpacityFactor();
FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
} else if (uses_emulated_tile_mode) {
} else {
FS::FragInfo frag_info;
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
frag_info.alpha = GetOpacityFactor();
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
} else {
TextureFillFragmentShader::FragInfo frag_info;
frag_info.alpha = GetOpacityFactor();
TextureFillFragmentShader::BindFragInfo(
pass, host_buffer.EmplaceUniform(frag_info));
}

if (is_external_texture) {
Expand Down Expand Up @@ -221,10 +205,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
}

return true;
},
/*enable_uvs=*/true,
/*texture_coverage=*/Rect::MakeSize(texture_size),
/*effect_transform=*/GetInverseEffectTransform());
});
}

std::optional<Snapshot> TiledTextureContents::RenderToSnapshot(
Expand Down
12 changes: 7 additions & 5 deletions impeller/entity/contents/vertices_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ void VerticesUVContents::SetAlpha(Scalar alpha) {
bool VerticesUVContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
using VS = TexturePipeline::VertexShader;
using FS = TexturePipeline::FragmentShader;
using VS = TiledTexturePipeline::VertexShader;
using FS = TiledTexturePipeline::FragmentShader;

auto src_contents = parent_.GetSourceContents();

Expand All @@ -158,21 +158,23 @@ bool VerticesUVContents::Render(const ContentContext& renderer,
if (!coverage.has_value()) {
return false;
}
auto geometry_result = geometry->GetPositionUVBuffer(
coverage.value(), Matrix(), renderer, entity, pass);
auto geometry_result = geometry->GetPositionBuffer(renderer, entity, pass);
auto opts = OptionsFromPassAndEntity(pass, entity);
opts.primitive_type = geometry_result.type;
pass.SetPipeline(renderer.GetTexturePipeline(opts));
pass.SetPipeline(renderer.GetTiledTexturePipeline(opts));
pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer));

VS::FrameInfo frame_info;
frame_info.mvp = geometry_result.transform;
frame_info.texture_sampler_y_coord_scale =
snapshot->texture->GetYCoordScale();
frame_info.uv_transform = coverage.value().GetNormalizingTransform();
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));

FS::FragInfo frag_info;
frag_info.alpha = alpha_ * snapshot->opacity;
frag_info.x_tile_mode = 0;
frag_info.y_tile_mode = 0;
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
FS::BindTextureSampler(pass, snapshot->texture,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
Expand Down
5 changes: 0 additions & 5 deletions impeller/entity/entity_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2830,12 +2830,7 @@ TEST_P(EntityTest, CanComputeGeometryForEmptyPathsWithoutCrashing) {
auto position_result =
geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);

auto uv_result =
geom->GetPositionUVBuffer(Rect::MakeLTRB(0, 0, 100, 100), Matrix(),
*GetContentContext(), entity, render_pass);

EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
EXPECT_EQ(uv_result.vertex_buffer.vertex_count, 0u);

EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
}
Expand Down
Loading