[Impeller] remove emulation of clamp, repeat, and mirror tile modes (flutter/engine#39948)

[Impeller] remove emulation of clamp, repeat, and mirror tile modes
This commit is contained in:
Jonah Williams 2023-02-28 11:02:46 -08:00 committed by GitHub
parent 8ed659cce3
commit 59191dd6c0
6 changed files with 55 additions and 34 deletions

View File

@ -82,7 +82,6 @@ vec2 IPVec2Tile(vec2 coords, float x_tile_mode, float y_tile_mode) {
/// for Decal.
vec4 IPSampleWithTileMode(sampler2D tex,
vec2 coords,
float y_coord_scale,
float x_tile_mode,
float y_tile_mode) {
if (x_tile_mode == kTileModeDecal && (coords.x < 0 || coords.x >= 1) ||
@ -90,19 +89,7 @@ vec4 IPSampleWithTileMode(sampler2D tex,
return vec4(0);
}
return IPSample(tex, IPVec2Tile(coords, x_tile_mode, y_tile_mode),
y_coord_scale);
}
/// Sample a texture, emulating a specific tile mode.
///
/// This is useful for Impeller graphics backend that don't have native support
/// for Decal.
vec4 IPSampleWithTileMode(sampler2D tex,
vec2 coords,
float y_coord_scale,
float tile_mode) {
return IPSampleWithTileMode(tex, coords, y_coord_scale, tile_mode, tile_mode);
return texture(tex, coords);
}
/// Sample a texture, emulating a specific tile mode.

View File

@ -15,6 +15,23 @@
namespace impeller {
static std::optional<SamplerAddressMode> TileModeToAddressMode(
Entity::TileMode tile_mode) {
switch (tile_mode) {
case Entity::TileMode::kClamp:
return SamplerAddressMode::kClampToEdge;
break;
case Entity::TileMode::kMirror:
return SamplerAddressMode::kMirror;
break;
case Entity::TileMode::kRepeat:
return SamplerAddressMode::kRepeat;
break;
case Entity::TileMode::kDecal:
return std::nullopt;
}
}
TiledTextureContents::TiledTextureContents() = default;
TiledTextureContents::~TiledTextureContents() = default;
@ -50,6 +67,19 @@ TiledTextureContents::CreateFilterTexture(
return std::nullopt;
}
SamplerDescriptor TiledTextureContents::CreateDescriptor() const {
SamplerDescriptor descriptor = sampler_descriptor_;
auto width_mode = TileModeToAddressMode(x_tile_mode_);
auto height_mode = TileModeToAddressMode(y_tile_mode_);
if (width_mode.has_value()) {
descriptor.width_address_mode = width_mode.value();
}
if (height_mode.has_value()) {
descriptor.height_address_mode = height_mode.value();
}
return descriptor;
}
bool TiledTextureContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
@ -84,13 +114,13 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.mvp = geometry_result.transform;
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
frame_info.effect_transform = GetInverseMatrix();
frame_info.bounds_origin = geometry->GetCoverage(Matrix())->origin;
frame_info.texture_size = Vector2(static_cast<Scalar>(texture_size.width),
static_cast<Scalar>(texture_size.height));
FS::FragInfo frag_info;
frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
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 = GetAlpha();
@ -110,6 +140,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
cmd.BindVertices(geometry_result.vertex_buffer);
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
if (color_filter_.has_value()) {
auto filtered_texture = CreateFilterTexture(renderer);
if (!filtered_texture.has_value()) {
@ -118,12 +149,12 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
FS::BindTextureSampler(
cmd, filtered_texture.value(),
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
sampler_descriptor_));
CreateDescriptor()));
} else {
FS::BindTextureSampler(
cmd, texture_,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
sampler_descriptor_));
CreateDescriptor()));
}
if (!pass.AddCommand(std::move(cmd))) {
@ -156,9 +187,9 @@ bool TiledTextureContents::RenderVertices(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.mvp = geometry_result.transform;
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
FS::FragInfo frag_info;
frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
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 = GetAlpha();
@ -178,6 +209,7 @@ bool TiledTextureContents::RenderVertices(const ContentContext& renderer,
cmd.BindVertices(geometry_result.vertex_buffer);
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
if (color_filter_.has_value()) {
auto filtered_texture = CreateFilterTexture(renderer);
if (!filtered_texture.has_value()) {
@ -186,12 +218,12 @@ bool TiledTextureContents::RenderVertices(const ContentContext& renderer,
FS::BindTextureSampler(
cmd, filtered_texture.value(),
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
sampler_descriptor_));
CreateDescriptor()));
} else {
FS::BindTextureSampler(
cmd, texture_,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
sampler_descriptor_));
CreateDescriptor()));
}
if (!pass.AddCommand(std::move(cmd))) {

View File

@ -57,6 +57,8 @@ class TiledTextureContents final : public ColorSourceContents {
const Entity& entity,
RenderPass& pass) const;
SamplerDescriptor CreateDescriptor() const;
std::shared_ptr<Texture> texture_;
SamplerDescriptor sampler_descriptor_ = {};
Entity::TileMode x_tile_mode_ = Entity::TileMode::kClamp;

View File

@ -8,7 +8,6 @@
uniform sampler2D texture_sampler;
uniform FragInfo {
float texture_sampler_y_coord_scale;
float x_tile_mode;
float y_tile_mode;
float alpha;
@ -20,13 +19,10 @@ in vec2 v_texture_coords;
out vec4 frag_color;
void main() {
frag_color =
IPSampleWithTileMode(
texture_sampler, // sampler
v_texture_coords, // texture coordinates
frag_info.texture_sampler_y_coord_scale, // y coordinate scale
frag_info.x_tile_mode, // x tile mode
frag_info.y_tile_mode // y tile mode
) *
frag_info.alpha;
frag_color = IPSampleWithTileMode(texture_sampler, // sampler
v_texture_coords, // texture coordinates
frag_info.x_tile_mode, // x tile mode
frag_info.y_tile_mode // y tile mode
) *
frag_info.alpha;
}

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <impeller/texture.glsl>
#include <impeller/transform.glsl>
#include <impeller/types.glsl>
@ -10,6 +11,7 @@ uniform FrameInfo {
mat4 effect_transform;
vec2 bounds_origin;
vec2 texture_size;
float texture_sampler_y_coord_scale;
}
frame_info;
@ -19,7 +21,9 @@ out vec2 v_texture_coords;
void main() {
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
v_texture_coords = IPVec2TransformPosition(
frame_info.effect_transform,
(position - frame_info.bounds_origin) / frame_info.texture_size);
v_texture_coords = IPRemapCoords(
IPVec2TransformPosition(
frame_info.effect_transform,
(position - frame_info.bounds_origin) / frame_info.texture_size),
frame_info.texture_sampler_y_coord_scale);
}

File diff suppressed because one or more lines are too long