Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 739b2fe

Browse files
authored
[Impeller] Add support for external GL textures to TiledTextureContents. (#47586)
1 parent 85c1419 commit 739b2fe

File tree

15 files changed

+484
-24
lines changed

15 files changed

+484
-24
lines changed

ci/licenses_golden/excluded_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc
144144
../../../flutter/impeller/entity/contents/filters/inputs/filter_input_unittests.cc
145145
../../../flutter/impeller/entity/contents/test
146+
../../../flutter/impeller/entity/contents/tiled_texture_contents_unittests.cc
146147
../../../flutter/impeller/entity/contents/vertices_contents_unittests.cc
147148
../../../flutter/impeller/entity/entity_pass_target_unittests.cc
148149
../../../flutter/impeller/entity/entity_unittests.cc

ci/licenses_golden/licenses_flutter

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2965,11 +2965,13 @@ ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl + ../.
29652965
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl + ../../../flutter/LICENSE
29662966
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/conversions.glsl + ../../../flutter/LICENSE
29672967
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/dithering.glsl + ../../../flutter/LICENSE
2968+
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/external_texture_oes.glsl + ../../../flutter/LICENSE
29682969
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/gaussian.glsl + ../../../flutter/LICENSE
29692970
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/gradient.glsl + ../../../flutter/LICENSE
29702971
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/path.glsl + ../../../flutter/LICENSE
29712972
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/prefix_sum.glsl + ../../../flutter/LICENSE
29722973
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/texture.glsl + ../../../flutter/LICENSE
2974+
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/tile_mode.glsl + ../../../flutter/LICENSE
29732975
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/transform.glsl + ../../../flutter/LICENSE
29742976
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/types.glsl + ../../../flutter/LICENSE
29752977
ORIGIN: ../../../flutter/impeller/compiler/source_options.cc + ../../../flutter/LICENSE
@@ -3193,6 +3195,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.frag + ../../../fl
31933195
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.vert + ../../../flutter/LICENSE
31943196
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill_external.frag + ../../../flutter/LICENSE
31953197
ORIGIN: ../../../flutter/impeller/entity/shaders/tiled_texture_fill.frag + ../../../flutter/LICENSE
3198+
ORIGIN: ../../../flutter/impeller/entity/shaders/tiled_texture_fill_external.frag + ../../../flutter/LICENSE
31963199
ORIGIN: ../../../flutter/impeller/entity/shaders/vertices.frag + ../../../flutter/LICENSE
31973200
ORIGIN: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.frag + ../../../flutter/LICENSE
31983201
ORIGIN: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.vert + ../../../flutter/LICENSE
@@ -5734,11 +5737,13 @@ FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl
57345737
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl
57355738
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/conversions.glsl
57365739
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/dithering.glsl
5740+
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/external_texture_oes.glsl
57375741
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/gaussian.glsl
57385742
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/gradient.glsl
57395743
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/path.glsl
57405744
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/prefix_sum.glsl
57415745
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/texture.glsl
5746+
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/tile_mode.glsl
57425747
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/transform.glsl
57435748
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/types.glsl
57445749
FILE: ../../../flutter/impeller/compiler/source_options.cc
@@ -5962,6 +5967,7 @@ FILE: ../../../flutter/impeller/entity/shaders/texture_fill.frag
59625967
FILE: ../../../flutter/impeller/entity/shaders/texture_fill.vert
59635968
FILE: ../../../flutter/impeller/entity/shaders/texture_fill_external.frag
59645969
FILE: ../../../flutter/impeller/entity/shaders/tiled_texture_fill.frag
5970+
FILE: ../../../flutter/impeller/entity/shaders/tiled_texture_fill_external.frag
59655971
FILE: ../../../flutter/impeller/entity/shaders/vertices.frag
59665972
FILE: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.frag
59675973
FILE: ../../../flutter/impeller/entity/shaders/yuv_to_rgb_filter.vert

impeller/compiler/shader_lib/impeller/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ copy("impeller") {
1010
"constants.glsl",
1111
"conversions.glsl",
1212
"dithering.glsl",
13+
"external_texture_oes.glsl",
1314
"gaussian.glsl",
1415
"gradient.glsl",
1516
"path.glsl",
1617
"texture.glsl",
18+
"tile_mode.glsl",
1719
"transform.glsl",
1820
"types.glsl",
1921
]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include <impeller/tile_mode.glsl>
6+
7+
/// A triangle wave. 0->0, 1->1, 2->0, and so on... works with negative numbers.
8+
float TriangleWave(float x) {
9+
return abs(mod(x + 1, 2) - 1);
10+
}
11+
12+
/// OES_EGL_image_external states that only CLAMP_TO_EDGE is valid, so we
13+
/// emulate all other tile modes here by remapping the texture coordinates.
14+
vec4 IPSampleWithTileModeOES(sampler2D tex,
15+
vec2 coords,
16+
float x_tile_mode,
17+
float y_tile_mode) {
18+
if (x_tile_mode == kTileModeDecal && (coords.x < 0 || coords.x >= 1) ||
19+
y_tile_mode == kTileModeDecal && (coords.y < 0 || coords.y >= 1)) {
20+
return vec4(0);
21+
}
22+
23+
if (x_tile_mode == kTileModeRepeat) {
24+
coords.x = mod(coords.x, 1);
25+
} else if (x_tile_mode == kTileModeMirror) {
26+
coords.x = TriangleWave(coords.x);
27+
}
28+
29+
if (y_tile_mode == kTileModeRepeat) {
30+
coords.y = mod(coords.y, 1);
31+
} else if (y_tile_mode == kTileModeMirror) {
32+
coords.y = TriangleWave(coords.y);
33+
}
34+
35+
return texture(tex, coords);
36+
}

impeller/compiler/shader_lib/impeller/texture.glsl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <impeller/branching.glsl>
99
#include <impeller/conversions.glsl>
10+
#include <impeller/tile_mode.glsl>
1011
#include <impeller/types.glsl>
1112

1213
/// Sample from a texture.
@@ -35,13 +36,6 @@ vec4 IPSampleLinear(sampler2D texture_sampler,
3536
return IPSample(texture_sampler, coords, y_coord_scale);
3637
}
3738

38-
// These values must correspond to the order of the items in the
39-
// 'Entity::TileMode' enum class.
40-
const float kTileModeClamp = 0;
41-
const float kTileModeRepeat = 1;
42-
const float kTileModeMirror = 2;
43-
const float kTileModeDecal = 3;
44-
4539
/// Remap a float using a tiling mode.
4640
///
4741
/// When `tile_mode` is `kTileModeDecal`, no tiling is applied and `t` is
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// These values must correspond to the order of the items in the
6+
// 'Entity::TileMode' enum class.
7+
const float kTileModeClamp = 0;
8+
const float kTileModeRepeat = 1;
9+
const float kTileModeMirror = 2;
10+
const float kTileModeDecal = 3;

impeller/entity/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impeller_shaders("entity_shaders") {
5151
"shaders/texture_fill.vert",
5252
"shaders/texture_fill_external.frag",
5353
"shaders/tiled_texture_fill.frag",
54+
"shaders/tiled_texture_fill_external.frag",
5455
"shaders/vertices.frag",
5556
"shaders/yuv_to_rgb_filter.frag",
5657
"shaders/yuv_to_rgb_filter.vert",
@@ -259,6 +260,7 @@ impeller_component("entity_unittests") {
259260
"contents/filters/directional_gaussian_blur_filter_contents_unittests.cc",
260261
"contents/filters/gaussian_blur_filter_contents_unittests.cc",
261262
"contents/filters/inputs/filter_input_unittests.cc",
263+
"contents/tiled_texture_contents_unittests.cc",
262264
"contents/vertices_contents_unittests.cc",
263265
"entity_pass_target_unittests.cc",
264266
"entity_playground.cc",

impeller/entity/contents/content_context.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ ContentContext::ContentContext(
340340
if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
341341
texture_external_pipelines_.CreateDefault(*context_, options);
342342
}
343+
if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
344+
tiled_texture_external_pipelines_.CreateDefault(*context_, options);
345+
}
343346
#endif // IMPELLER_ENABLE_OPENGLES
344347
if (context_->GetCapabilities()->SupportsCompute()) {
345348
auto pipeline_desc =

impeller/entity/contents/content_context.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484

8585
#ifdef IMPELLER_ENABLE_OPENGLES
8686
#include "impeller/entity/texture_fill_external.frag.h"
87+
#include "impeller/entity/tiled_texture_fill_external.frag.h"
8788
#endif // IMPELLER_ENABLE_OPENGLES
8889

8990
#if IMPELLER_ENABLE_3D
@@ -249,6 +250,10 @@ using UvComputeShaderPipeline = ComputePipelineBuilder<UvComputeShader>;
249250
#ifdef IMPELLER_ENABLE_OPENGLES
250251
using TextureExternalPipeline =
251252
RenderPipelineT<TextureFillVertexShader, TextureFillExternalFragmentShader>;
253+
254+
using TiledTextureExternalPipeline =
255+
RenderPipelineT<TextureFillVertexShader,
256+
TiledTextureFillExternalFragmentShader>;
252257
#endif // IMPELLER_ENABLE_OPENGLES
253258

254259
/// Pipeline state configuration.
@@ -398,6 +403,13 @@ class ContentContext {
398403
Context::BackendType::kOpenGLES);
399404
return GetPipeline(texture_external_pipelines_, opts);
400405
}
406+
407+
std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTextureExternalPipeline(
408+
ContentContextOptions opts) const {
409+
FML_DCHECK(GetContext()->GetBackendType() ==
410+
Context::BackendType::kOpenGLES);
411+
return GetPipeline(tiled_texture_external_pipelines_, opts);
412+
}
401413
#endif // IMPELLER_ENABLE_OPENGLES
402414

403415
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPositionUVPipeline(
@@ -768,6 +780,8 @@ class ContentContext {
768780
mutable Variants<TexturePipeline> texture_pipelines_;
769781
#ifdef IMPELLER_ENABLE_OPENGLES
770782
mutable Variants<TextureExternalPipeline> texture_external_pipelines_;
783+
mutable Variants<TiledTextureExternalPipeline>
784+
tiled_texture_external_pipelines_;
771785
#endif // IMPELLER_ENABLE_OPENGLES
772786
mutable Variants<PositionUVPipeline> position_uv_pipelines_;
773787
mutable Variants<TiledTexturePipeline> tiled_texture_pipelines_;

impeller/entity/contents/tiled_texture_contents.cc

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

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

7+
#include "fml/logging.h"
78
#include "impeller/entity/contents/clip_contents.h"
89
#include "impeller/entity/contents/content_context.h"
910
#include "impeller/entity/geometry/geometry.h"
1011
#include "impeller/entity/texture_fill.frag.h"
1112
#include "impeller/entity/texture_fill.vert.h"
1213
#include "impeller/entity/tiled_texture_fill.frag.h"
14+
#include "impeller/entity/tiled_texture_fill_external.frag.h"
1315
#include "impeller/geometry/path_builder.h"
1416
#include "impeller/renderer/render_pass.h"
1517
#include "impeller/renderer/sampler_library.h"
@@ -78,7 +80,7 @@ std::shared_ptr<Texture> TiledTextureContents::CreateFilterTexture(
7880
return nullptr;
7981
}
8082

81-
SamplerDescriptor TiledTextureContents::CreateDescriptor(
83+
SamplerDescriptor TiledTextureContents::CreateSamplerDescriptor(
8284
const Capabilities& capabilities) const {
8385
SamplerDescriptor descriptor = sampler_descriptor_;
8486
auto width_mode = TileModeToAddressMode(x_tile_mode_, capabilities);
@@ -119,12 +121,16 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
119121

120122
using VS = TextureFillVertexShader;
121123
using FS = TiledTextureFillFragmentShader;
124+
using FSExternal = TiledTextureFillExternalFragmentShader;
122125

123126
const auto texture_size = texture_->GetSize();
124127
if (texture_size.IsEmpty()) {
125128
return true;
126129
}
127130

131+
bool is_external_texture =
132+
texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES;
133+
128134
auto& host_buffer = pass.GetTransientsBuffer();
129135

130136
auto geometry_result = GetGeometry()->GetPositionUVBuffer(
@@ -153,34 +159,67 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
153159
options.stencil_operation = StencilOperation::kIncrementClamp;
154160
}
155161
options.primitive_type = geometry_result.type;
162+
163+
#ifdef IMPELLER_ENABLE_OPENGLES
164+
if (is_external_texture) {
165+
cmd.pipeline = renderer.GetTiledTextureExternalPipeline(options);
166+
} else {
167+
cmd.pipeline = uses_emulated_tile_mode
168+
? renderer.GetTiledTexturePipeline(options)
169+
: renderer.GetTexturePipeline(options);
170+
}
171+
#else
156172
cmd.pipeline = uses_emulated_tile_mode
157173
? renderer.GetTiledTexturePipeline(options)
158174
: renderer.GetTexturePipeline(options);
175+
#endif // IMPELLER_ENABLE_OPENGLES
159176

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

163-
if (uses_emulated_tile_mode) {
180+
if (is_external_texture) {
181+
FSExternal::FragInfo frag_info;
182+
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
183+
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
184+
FSExternal::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
185+
} else if (uses_emulated_tile_mode) {
164186
FS::FragInfo frag_info;
165187
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
166188
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
167189
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
168190
}
169191

170-
if (color_filter_) {
171-
auto filtered_texture = CreateFilterTexture(renderer);
172-
if (!filtered_texture) {
173-
return false;
174-
}
175-
FS::BindTextureSampler(
176-
cmd, filtered_texture,
177-
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
178-
CreateDescriptor(renderer.GetDeviceCapabilities())));
179-
} else {
180-
FS::BindTextureSampler(
192+
if (is_external_texture) {
193+
SamplerDescriptor sampler_desc;
194+
// OES_EGL_image_external states that only CLAMP_TO_EDGE is valid, so we
195+
// emulate all other tile modes here by remapping the texture coordinates.
196+
sampler_desc.width_address_mode = SamplerAddressMode::kClampToEdge;
197+
sampler_desc.height_address_mode = SamplerAddressMode::kClampToEdge;
198+
199+
// Also, external textures cannot be bound to color filters, so ignore this
200+
// case for now.
201+
FML_DCHECK(!color_filter_)
202+
<< "Color filters are not currently supported for external textures.";
203+
204+
FSExternal::BindSAMPLEREXTERNALOESTextureSampler(
181205
cmd, texture_,
182-
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
183-
CreateDescriptor(renderer.GetDeviceCapabilities())));
206+
renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc));
207+
} else {
208+
if (color_filter_) {
209+
auto filtered_texture = CreateFilterTexture(renderer);
210+
if (!filtered_texture) {
211+
return false;
212+
}
213+
FS::BindTextureSampler(
214+
cmd, filtered_texture,
215+
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
216+
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
217+
} else {
218+
FS::BindTextureSampler(
219+
cmd, texture_,
220+
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
221+
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
222+
}
184223
}
185224

186225
if (!pass.AddCommand(std::move(cmd))) {

0 commit comments

Comments
 (0)