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 all commits
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
1 change: 1 addition & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
../../../flutter/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc
../../../flutter/impeller/entity/contents/filters/inputs/filter_input_unittests.cc
../../../flutter/impeller/entity/contents/test
../../../flutter/impeller/entity/contents/tiled_texture_contents_unittests.cc
../../../flutter/impeller/entity/contents/vertices_contents_unittests.cc
../../../flutter/impeller/entity/entity_pass_target_unittests.cc
../../../flutter/impeller/entity/entity_unittests.cc
Expand Down
6 changes: 6 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2963,11 +2963,13 @@ ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl + ../.
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/conversions.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/dithering.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/external_texture_oes.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/gaussian.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/gradient.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/path.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/prefix_sum.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/texture.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/tile_mode.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/transform.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/types.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/source_options.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3189,6 +3191,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.frag + ../../../fl
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.vert + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill_external.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/tiled_texture_fill.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/tiled_texture_fill_external.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/vertices.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.vert + ../../../flutter/LICENSE
Expand Down Expand Up @@ -5725,11 +5728,13 @@ FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/conversions.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/dithering.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/external_texture_oes.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/gaussian.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/gradient.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/path.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/prefix_sum.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/texture.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/tile_mode.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/transform.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/types.glsl
FILE: ../../../flutter/impeller/compiler/source_options.cc
Expand Down Expand Up @@ -5951,6 +5956,7 @@ FILE: ../../../flutter/impeller/entity/shaders/texture_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/texture_fill.vert
FILE: ../../../flutter/impeller/entity/shaders/texture_fill_external.frag
FILE: ../../../flutter/impeller/entity/shaders/tiled_texture_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/tiled_texture_fill_external.frag
FILE: ../../../flutter/impeller/entity/shaders/vertices.frag
FILE: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.frag
FILE: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.vert
Expand Down
2 changes: 2 additions & 0 deletions impeller/compiler/shader_lib/impeller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ copy("impeller") {
"constants.glsl",
"conversions.glsl",
"dithering.glsl",
"external_texture_oes.glsl",
"gaussian.glsl",
"gradient.glsl",
"path.glsl",
"texture.glsl",
"tile_mode.glsl",
"transform.glsl",
"types.glsl",
]
Expand Down
36 changes: 36 additions & 0 deletions impeller/compiler/shader_lib/impeller/external_texture_oes.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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/tile_mode.glsl>

/// A triangle wave. 0->0, 1->1, 2->0, and so on... works with negative numbers.
float TriangleWave(float x) {
return abs(mod(x + 1, 2) - 1);
}

/// 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.
vec4 IPSampleWithTileModeOES(sampler2D tex,
vec2 coords,
float x_tile_mode,
float y_tile_mode) {
if (x_tile_mode == kTileModeDecal && (coords.x < 0 || coords.x >= 1) ||
y_tile_mode == kTileModeDecal && (coords.y < 0 || coords.y >= 1)) {
return vec4(0);
}

if (x_tile_mode == kTileModeRepeat) {
coords.x = mod(coords.x, 1);
} else if (x_tile_mode == kTileModeMirror) {
coords.x = TriangleWave(coords.x);
}

if (y_tile_mode == kTileModeRepeat) {
coords.y = mod(coords.y, 1);
} else if (y_tile_mode == kTileModeMirror) {
coords.y = TriangleWave(coords.y);
}

return texture(tex, coords);
}
8 changes: 1 addition & 7 deletions impeller/compiler/shader_lib/impeller/texture.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <impeller/branching.glsl>
#include <impeller/conversions.glsl>
#include <impeller/tile_mode.glsl>
#include <impeller/types.glsl>

/// Sample from a texture.
Expand Down Expand Up @@ -35,13 +36,6 @@ vec4 IPSampleLinear(sampler2D texture_sampler,
return IPSample(texture_sampler, coords, y_coord_scale);
}

// These values must correspond to the order of the items in the
// 'Entity::TileMode' enum class.
const float kTileModeClamp = 0;
const float kTileModeRepeat = 1;
const float kTileModeMirror = 2;
const float kTileModeDecal = 3;

/// Remap a float using a tiling mode.
///
/// When `tile_mode` is `kTileModeDecal`, no tiling is applied and `t` is
Expand Down
10 changes: 10 additions & 0 deletions impeller/compiler/shader_lib/impeller/tile_mode.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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.

// These values must correspond to the order of the items in the
// 'Entity::TileMode' enum class.
const float kTileModeClamp = 0;
const float kTileModeRepeat = 1;
const float kTileModeMirror = 2;
const float kTileModeDecal = 3;
2 changes: 2 additions & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impeller_shaders("entity_shaders") {
"shaders/texture_fill.vert",
"shaders/texture_fill_external.frag",
"shaders/tiled_texture_fill.frag",
"shaders/tiled_texture_fill_external.frag",
"shaders/vertices.frag",
"shaders/yuv_to_rgb_filter.frag",
"shaders/yuv_to_rgb_filter.vert",
Expand Down Expand Up @@ -256,6 +257,7 @@ impeller_component("entity_unittests") {
"contents/checkerboard_contents_unittests.cc",
"contents/filters/directional_gaussian_blur_filter_contents_unittests.cc",
"contents/filters/inputs/filter_input_unittests.cc",
"contents/tiled_texture_contents_unittests.cc",
"contents/vertices_contents_unittests.cc",
"entity_pass_target_unittests.cc",
"entity_playground.cc",
Expand Down
3 changes: 3 additions & 0 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,9 @@ ContentContext::ContentContext(
if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
texture_external_pipelines_.CreateDefault(*context_, options);
}
if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
tiled_texture_external_pipelines_.CreateDefault(*context_, options);
}
#endif // IMPELLER_ENABLE_OPENGLES
if (context_->GetCapabilities()->SupportsCompute()) {
auto pipeline_desc =
Expand Down
14 changes: 14 additions & 0 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@

#ifdef IMPELLER_ENABLE_OPENGLES
#include "impeller/entity/texture_fill_external.frag.h"
#include "impeller/entity/tiled_texture_fill_external.frag.h"
#endif // IMPELLER_ENABLE_OPENGLES

#if IMPELLER_ENABLE_3D
Expand Down Expand Up @@ -249,6 +250,10 @@ using UvComputeShaderPipeline = ComputePipelineBuilder<UvComputeShader>;
#ifdef IMPELLER_ENABLE_OPENGLES
using TextureExternalPipeline =
RenderPipelineT<TextureFillVertexShader, TextureFillExternalFragmentShader>;

using TiledTextureExternalPipeline =
RenderPipelineT<TextureFillVertexShader,
TiledTextureFillExternalFragmentShader>;
#endif // IMPELLER_ENABLE_OPENGLES

/// Pipeline state configuration.
Expand Down Expand Up @@ -398,6 +403,13 @@ class ContentContext {
Context::BackendType::kOpenGLES);
return GetPipeline(texture_external_pipelines_, opts);
}

std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTextureExternalPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetContext()->GetBackendType() ==
Context::BackendType::kOpenGLES);
return GetPipeline(tiled_texture_external_pipelines_, opts);
}
#endif // IMPELLER_ENABLE_OPENGLES

std::shared_ptr<Pipeline<PipelineDescriptor>> GetPositionUVPipeline(
Expand Down Expand Up @@ -768,6 +780,8 @@ class ContentContext {
mutable Variants<TexturePipeline> texture_pipelines_;
#ifdef IMPELLER_ENABLE_OPENGLES
mutable Variants<TextureExternalPipeline> texture_external_pipelines_;
mutable Variants<TiledTextureExternalPipeline>
tiled_texture_external_pipelines_;
#endif // IMPELLER_ENABLE_OPENGLES
mutable Variants<PositionUVPipeline> position_uv_pipelines_;
mutable Variants<TiledTexturePipeline> tiled_texture_pipelines_;
Expand Down
69 changes: 54 additions & 15 deletions impeller/entity/contents/tiled_texture_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

#include "impeller/entity/contents/tiled_texture_contents.h"

#include "fml/logging.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/geometry/geometry.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/geometry/path_builder.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/sampler_library.h"
Expand Down Expand Up @@ -78,7 +80,7 @@ std::shared_ptr<Texture> TiledTextureContents::CreateFilterTexture(
return nullptr;
}

SamplerDescriptor TiledTextureContents::CreateDescriptor(
SamplerDescriptor TiledTextureContents::CreateSamplerDescriptor(
const Capabilities& capabilities) const {
SamplerDescriptor descriptor = sampler_descriptor_;
auto width_mode = TileModeToAddressMode(x_tile_mode_, capabilities);
Expand Down Expand Up @@ -119,12 +121,16 @@ bool TiledTextureContents::Render(const ContentContext& renderer,

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

const auto texture_size = texture_->GetSize();
if (texture_size.IsEmpty()) {
return true;
}

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

auto& host_buffer = pass.GetTransientsBuffer();

auto geometry_result = GetGeometry()->GetPositionUVBuffer(
Expand Down Expand Up @@ -153,34 +159,67 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
options.stencil_operation = StencilOperation::kIncrementClamp;
}
options.primitive_type = geometry_result.type;

#ifdef IMPELLER_ENABLE_OPENGLES
if (is_external_texture) {
cmd.pipeline = renderer.GetTiledTextureExternalPipeline(options);
} else {
cmd.pipeline = uses_emulated_tile_mode
? renderer.GetTiledTexturePipeline(options)
: renderer.GetTexturePipeline(options);
}
#else
cmd.pipeline = uses_emulated_tile_mode
? renderer.GetTiledTexturePipeline(options)
: renderer.GetTexturePipeline(options);
#endif // IMPELLER_ENABLE_OPENGLES

cmd.BindVertices(geometry_result.vertex_buffer);
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));

if (uses_emulated_tile_mode) {
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_);
FSExternal::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
} else if (uses_emulated_tile_mode) {
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_);
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
}

if (color_filter_) {
auto filtered_texture = CreateFilterTexture(renderer);
if (!filtered_texture) {
return false;
}
FS::BindTextureSampler(
cmd, filtered_texture,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
CreateDescriptor(renderer.GetDeviceCapabilities())));
} else {
FS::BindTextureSampler(
if (is_external_texture) {
SamplerDescriptor sampler_desc;
// 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_desc.width_address_mode = SamplerAddressMode::kClampToEdge;
sampler_desc.height_address_mode = SamplerAddressMode::kClampToEdge;

// Also, external textures cannot be bound to color filters, so ignore this
// case for now.
FML_DCHECK(!color_filter_)
<< "Color filters are not currently supported for external textures.";

FSExternal::BindSAMPLEREXTERNALOESTextureSampler(
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we cannot actually hit this case with the API we have today (which doesn't allow adding color/image filters directly to external textures) - so perhaps a DCHECK is appropriate.

Copy link
Member Author

Choose a reason for hiding this comment

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

which doesn't allow adding color/image filters directly to external textures

Where is this disallowed? 🤔 There is no separate API for external textures in Aiks.

Copy link
Contributor

Choose a reason for hiding this comment

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

The optimization only applies to color filters that are on the paint object used in the draw call. External texture API does not accept a paint object so all filters need to be applied by a separate composited later

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh I see, you mean how we expose it to plugins/framework. Added a dcheck. We can easily add support later for other customers if requested.

cmd, texture_,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
CreateDescriptor(renderer.GetDeviceCapabilities())));
renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc));
} else {
if (color_filter_) {
auto filtered_texture = CreateFilterTexture(renderer);
if (!filtered_texture) {
return false;
}
FS::BindTextureSampler(
cmd, filtered_texture,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
} else {
FS::BindTextureSampler(
cmd, texture_,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
}
}

if (!pass.AddCommand(std::move(cmd))) {
Expand Down
5 changes: 3 additions & 2 deletions impeller/entity/contents/tiled_texture_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class TiledTextureContents final : public ColorSourceContents {
/// @param color_filter
///
/// When applying a color filter to a tiled texture, we can reduce the
/// size and number of the subpasses required and the shader workloadby
/// size and number of the subpasses required and the shader workload by
/// applying the filter to the untiled image and absorbing the opacity before
/// tiling it into the final location.
///
Expand All @@ -66,7 +66,8 @@ class TiledTextureContents final : public ColorSourceContents {
std::shared_ptr<Texture> CreateFilterTexture(
const ContentContext& renderer) const;

SamplerDescriptor CreateDescriptor(const Capabilities& capabilities) const;
SamplerDescriptor CreateSamplerDescriptor(
const Capabilities& capabilities) const;

bool UsesEmulatedTileMode(const Capabilities& capabilities) const;

Expand Down
Loading