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

Commit 6530580

Browse files
author
Jonah Williams
authored
[Impeller] actually fix external texture for GLES. (#55414)
Goldens are working! and incorrect! use the other texture contents to hopefully fix them. Ratther the the transform, we actually expect to use the src and dst rect to position/transform the texture. Tiled Texture contents does not support a src rect, so switch it to the regular texture contents.
1 parent c558459 commit 6530580

File tree

7 files changed

+103
-120
lines changed

7 files changed

+103
-120
lines changed

impeller/aiks/canvas.cc

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -744,24 +744,6 @@ void Canvas::DrawImageRect(const std::shared_ptr<Texture>& image,
744744
return;
745745
}
746746

747-
if (image->GetTextureDescriptor().type == TextureType::kTextureExternalOES) {
748-
auto texture_contents = std::make_shared<TiledTextureContents>();
749-
texture_contents->SetTexture(image);
750-
texture_contents->SetGeometry(Geometry::MakeRect(dest));
751-
texture_contents->SetSamplerDescriptor(std::move(sampler));
752-
texture_contents->SetInheritedOpacity(paint.color.alpha);
753-
754-
std::shared_ptr<Contents> contents = texture_contents;
755-
756-
Entity entity;
757-
entity.SetBlendMode(paint.blend_mode);
758-
entity.SetContents(paint.WithFilters(contents));
759-
entity.SetTransform(GetCurrentTransform());
760-
761-
AddRenderEntityToCurrentPass(std::move(entity));
762-
return;
763-
}
764-
765747
auto texture_contents = TextureContents::MakeRect(dest);
766748
texture_contents->SetTexture(image);
767749
texture_contents->SetSourceRect(source);

impeller/entity/contents/content_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ using VerticesUberShader = RenderPipelineHandle<PorterDuffBlendVertexShader,
237237

238238
#ifdef IMPELLER_ENABLE_OPENGLES
239239
using TiledTextureExternalPipeline =
240-
RenderPipelineHandle<TextureUvFillVertexShader,
240+
RenderPipelineHandle<TextureFillVertexShader,
241241
TiledTextureFillExternalFragmentShader>;
242242
#endif // IMPELLER_ENABLE_OPENGLES
243243

impeller/entity/contents/texture_contents.cc

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "impeller/entity/texture_fill.frag.h"
1515
#include "impeller/entity/texture_fill.vert.h"
1616
#include "impeller/entity/texture_fill_strict_src.frag.h"
17+
#include "impeller/entity/tiled_texture_fill_external.frag.h"
1718
#include "impeller/geometry/constants.h"
1819
#include "impeller/renderer/render_pass.h"
1920
#include "impeller/renderer/vertex_buffer_builder.h"
@@ -118,9 +119,11 @@ bool TextureContents::Render(const ContentContext& renderer,
118119
return true; // Nothing to render.
119120
}
120121

121-
[[maybe_unused]] bool is_external_texture =
122+
#ifdef IMPELLER_ENABLE_OPENGLES
123+
using FSExternal = TiledTextureFillExternalFragmentShader;
124+
bool is_external_texture =
122125
texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES;
123-
FML_DCHECK(!is_external_texture);
126+
#endif // IMPELLER_ENABLE_OPENGLES
124127

125128
auto texture_coords =
126129
Rect::MakeSize(texture_->GetSize()).Project(source_rect_);
@@ -159,9 +162,21 @@ bool TextureContents::Render(const ContentContext& renderer,
159162
pipeline_options.depth_write_enabled =
160163
stencil_enabled_ && pipeline_options.blend_mode == BlendMode::kSource;
161164

165+
#ifdef IMPELLER_ENABLE_OPENGLES
166+
if (is_external_texture) {
167+
pass.SetPipeline(
168+
renderer.GetTiledTextureExternalPipeline(pipeline_options));
169+
} else {
170+
pass.SetPipeline(
171+
strict_source_rect_enabled_
172+
? renderer.GetTextureStrictSrcPipeline(pipeline_options)
173+
: renderer.GetTexturePipeline(pipeline_options));
174+
}
175+
#else
162176
pass.SetPipeline(strict_source_rect_enabled_
163177
? renderer.GetTextureStrictSrcPipeline(pipeline_options)
164178
: renderer.GetTexturePipeline(pipeline_options));
179+
#endif // IMPELLER_ENABLE_OPENGLES
165180

166181
pass.SetVertexBuffer(vertex_buffer);
167182
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
@@ -181,6 +196,26 @@ bool TextureContents::Render(const ContentContext& renderer,
181196
pass, texture_,
182197
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
183198
sampler_descriptor_));
199+
#ifdef IMPELLER_ENABLE_OPENGLES
200+
} else if (is_external_texture) {
201+
FSExternal::FragInfo frag_info;
202+
frag_info.x_tile_mode =
203+
static_cast<Scalar>(sampler_descriptor_.width_address_mode);
204+
frag_info.y_tile_mode =
205+
static_cast<Scalar>(sampler_descriptor_.height_address_mode);
206+
frag_info.alpha = GetOpacity();
207+
FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
208+
209+
SamplerDescriptor sampler_desc;
210+
// OES_EGL_image_external states that only CLAMP_TO_EDGE is valid, so
211+
// we emulate all other tile modes here by remapping the texture
212+
// coordinates.
213+
sampler_desc.width_address_mode = SamplerAddressMode::kClampToEdge;
214+
sampler_desc.height_address_mode = SamplerAddressMode::kClampToEdge;
215+
FSExternal::BindSAMPLEREXTERNALOESTextureSampler(
216+
pass, texture_,
217+
renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc));
218+
#endif // IMPELLER_ENABLE_OPENGLES
184219
} else {
185220
FS::FragInfo frag_info;
186221
frag_info.alpha = GetOpacity();

impeller/entity/contents/tiled_texture_contents.cc

Lines changed: 25 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -116,96 +116,52 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
116116

117117
using VS = TextureUvFillVertexShader;
118118
using FS = TiledTextureFillFragmentShader;
119-
using FSExternal = TiledTextureFillExternalFragmentShader;
120119

121120
const auto texture_size = texture_->GetSize();
122121
if (texture_size.IsEmpty()) {
123122
return true;
124123
}
125124

126-
bool is_external_texture =
127-
texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES;
128-
129125
VS::FrameInfo frame_info;
130126
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
131127
frame_info.uv_transform =
132128
Rect::MakeSize(texture_size).GetNormalizingTransform() *
133129
GetInverseEffectTransform();
134130

135-
PipelineBuilderMethod pipeline_method;
136-
137-
#ifdef IMPELLER_ENABLE_OPENGLES
138-
if (is_external_texture) {
139-
pipeline_method = &ContentContext::GetTiledTextureExternalPipeline;
140-
} else {
141-
pipeline_method = &ContentContext::GetTiledTexturePipeline;
142-
}
143-
#else
144-
pipeline_method = &ContentContext::GetTiledTexturePipeline;
145-
#endif // IMPELLER_ENABLE_OPENGLES
146-
147131
PipelineBuilderCallback pipeline_callback =
148-
[&renderer, &pipeline_method](ContentContextOptions options) {
149-
return (renderer.*pipeline_method)(options);
132+
[&renderer](ContentContextOptions options) {
133+
return renderer.GetTiledTexturePipeline(options);
150134
};
151135
return ColorSourceContents::DrawGeometry<VS>(
152136
renderer, entity, pass, pipeline_callback, frame_info,
153-
[this, &renderer, &is_external_texture, &entity](RenderPass& pass) {
137+
[this, &renderer, &entity](RenderPass& pass) {
154138
auto& host_buffer = renderer.GetTransientsBuffer();
155-
139+
#ifdef IMPELLER_DEBUG
156140
pass.SetCommandLabel("TextureFill");
157-
158-
if (is_external_texture) {
159-
FSExternal::FragInfo frag_info;
160-
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
161-
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
162-
frag_info.alpha =
163-
GetOpacityFactor() *
164-
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
165-
FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
141+
#endif // IMPELLER_DEBUG
142+
143+
FS::FragInfo frag_info;
144+
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
145+
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
146+
frag_info.alpha =
147+
GetOpacityFactor() *
148+
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
149+
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
150+
151+
if (color_filter_) {
152+
auto filtered_texture = CreateFilterTexture(renderer);
153+
if (!filtered_texture) {
154+
return false;
155+
}
156+
FS::BindTextureSampler(
157+
pass, filtered_texture,
158+
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
159+
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
166160
} else {
167-
FS::FragInfo frag_info;
168-
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
169-
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
170-
frag_info.alpha =
171-
GetOpacityFactor() *
172-
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
173-
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
174-
}
175-
176-
if (is_external_texture) {
177-
SamplerDescriptor sampler_desc;
178-
// OES_EGL_image_external states that only CLAMP_TO_EDGE is valid, so
179-
// we emulate all other tile modes here by remapping the texture
180-
// coordinates.
181-
sampler_desc.width_address_mode = SamplerAddressMode::kClampToEdge;
182-
sampler_desc.height_address_mode = SamplerAddressMode::kClampToEdge;
183-
184-
// Also, external textures cannot be bound to color filters, so ignore
185-
// this case for now.
186-
FML_DCHECK(!color_filter_) << "Color filters are not currently "
187-
"supported for external textures.";
188-
189-
FSExternal::BindSAMPLEREXTERNALOESTextureSampler(
161+
FS::BindTextureSampler(
190162
pass, texture_,
191163
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
192-
sampler_desc));
193-
} else {
194-
if (color_filter_) {
195-
auto filtered_texture = CreateFilterTexture(renderer);
196-
if (!filtered_texture) {
197-
return false;
198-
}
199-
FS::BindTextureSampler(
200-
pass, filtered_texture,
201-
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
202-
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
203-
} else {
204-
FS::BindTextureSampler(
205-
pass, texture_,
206-
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
207-
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
208-
}
164+
CreateSamplerDescriptor(renderer.GetDeviceCapabilities())));
209165
}
210166

211167
return true;

impeller/entity/contents/tiled_texture_contents_unittests.cc

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "impeller/core/formats.h"
88
#include "impeller/core/texture_descriptor.h"
99
#include "impeller/entity/contents/test/recording_render_pass.h"
10+
#include "impeller/entity/contents/texture_contents.h"
1011
#include "impeller/entity/contents/tiled_texture_contents.h"
1112
#include "impeller/entity/entity_playground.h"
1213
#include "impeller/playground/playground_test.h"
@@ -44,8 +45,14 @@ TEST_P(EntityTest, TiledTextureContentsRendersWithCorrectPipeline) {
4445
const std::vector<Command>& commands = recording_pass->GetCommands();
4546

4647
ASSERT_EQ(commands.size(), 1u);
48+
#ifdef IMPELLER_DEBUG
4749
EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
4850
"TextureFill Pipeline") != std::string::npos);
51+
#endif // IMPELLER_DEBUG
52+
auto options = OptionsFromPassAndEntity(*recording_pass, {});
53+
options.primitive_type = PrimitiveType::kTriangleStrip;
54+
EXPECT_EQ(commands[0].pipeline,
55+
GetContentContext()->GetTiledTexturePipeline(options));
4956

5057
if (GetParam() == PlaygroundBackend::kMetal) {
5158
recording_pass->EncodeCommands();
@@ -67,10 +74,10 @@ TEST_P(EntityTest, TiledTextureContentsRendersWithCorrectPipelineExternalOES) {
6774
texture_desc.storage_mode = StorageMode::kDevicePrivate;
6875
auto texture =
6976
GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
70-
71-
TiledTextureContents contents;
72-
contents.SetTexture(texture);
73-
contents.SetGeometry(Geometry::MakeCover());
77+
auto contents = TextureContents::MakeRect(Rect::MakeSize(texture->GetSize()));
78+
contents->SetTexture(texture);
79+
contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
80+
contents->SetStrictSourceRect(false);
7481

7582
auto content_context = GetContentContext();
7683
auto buffer = content_context->GetContext()->CreateCommandBuffer();
@@ -80,12 +87,15 @@ TEST_P(EntityTest, TiledTextureContentsRendersWithCorrectPipelineExternalOES) {
8087
/*mip_count=*/1);
8188
auto render_pass = buffer->CreateRenderPass(render_target);
8289

83-
ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
90+
ASSERT_TRUE(contents->Render(*GetContentContext(), {}, *render_pass));
8491
const std::vector<Command>& commands = render_pass->GetCommands();
8592

8693
ASSERT_EQ(commands.size(), 1u);
87-
EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
88-
"TiledTextureFillExternal Pipeline") != std::string::npos);
94+
95+
auto options = OptionsFromPassAndEntity(*render_pass, {});
96+
options.primitive_type = PrimitiveType::kTriangleStrip;
97+
EXPECT_EQ(commands[0].pipeline,
98+
GetContentContext()->GetTiledTextureExternalPipeline(options));
8999
}
90100
#endif
91101

impeller/entity/shaders/tiled_texture_fill_external.frag

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ uniform FragInfo {
1515
}
1616
frag_info;
1717

18-
in vec2 v_texture_coords;
18+
in highp vec2 v_texture_coords;
1919

2020
out vec4 frag_color;
2121

0 commit comments

Comments
 (0)