|
4 | 4 |
|
5 | 5 | #include "impeller/entity/contents/tiled_texture_contents.h"
|
6 | 6 |
|
| 7 | +#include "fml/logging.h" |
7 | 8 | #include "impeller/entity/contents/clip_contents.h"
|
8 | 9 | #include "impeller/entity/contents/content_context.h"
|
9 | 10 | #include "impeller/entity/geometry/geometry.h"
|
10 | 11 | #include "impeller/entity/texture_fill.frag.h"
|
11 | 12 | #include "impeller/entity/texture_fill.vert.h"
|
12 | 13 | #include "impeller/entity/tiled_texture_fill.frag.h"
|
| 14 | +#include "impeller/entity/tiled_texture_fill_external.frag.h" |
13 | 15 | #include "impeller/geometry/path_builder.h"
|
14 | 16 | #include "impeller/renderer/render_pass.h"
|
15 | 17 | #include "impeller/renderer/sampler_library.h"
|
@@ -78,7 +80,7 @@ std::shared_ptr<Texture> TiledTextureContents::CreateFilterTexture(
|
78 | 80 | return nullptr;
|
79 | 81 | }
|
80 | 82 |
|
81 |
| -SamplerDescriptor TiledTextureContents::CreateDescriptor( |
| 83 | +SamplerDescriptor TiledTextureContents::CreateSamplerDescriptor( |
82 | 84 | const Capabilities& capabilities) const {
|
83 | 85 | SamplerDescriptor descriptor = sampler_descriptor_;
|
84 | 86 | auto width_mode = TileModeToAddressMode(x_tile_mode_, capabilities);
|
@@ -119,12 +121,16 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
119 | 121 |
|
120 | 122 | using VS = TextureFillVertexShader;
|
121 | 123 | using FS = TiledTextureFillFragmentShader;
|
| 124 | + using FSExternal = TiledTextureFillExternalFragmentShader; |
122 | 125 |
|
123 | 126 | const auto texture_size = texture_->GetSize();
|
124 | 127 | if (texture_size.IsEmpty()) {
|
125 | 128 | return true;
|
126 | 129 | }
|
127 | 130 |
|
| 131 | + bool is_external_texture = |
| 132 | + texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES; |
| 133 | + |
128 | 134 | auto& host_buffer = pass.GetTransientsBuffer();
|
129 | 135 |
|
130 | 136 | auto geometry_result = GetGeometry()->GetPositionUVBuffer(
|
@@ -153,34 +159,67 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
153 | 159 | options.stencil_operation = StencilOperation::kIncrementClamp;
|
154 | 160 | }
|
155 | 161 | 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 |
156 | 172 | cmd.pipeline = uses_emulated_tile_mode
|
157 | 173 | ? renderer.GetTiledTexturePipeline(options)
|
158 | 174 | : renderer.GetTexturePipeline(options);
|
| 175 | +#endif // IMPELLER_ENABLE_OPENGLES |
159 | 176 |
|
160 | 177 | cmd.BindVertices(geometry_result.vertex_buffer);
|
161 | 178 | VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
162 | 179 |
|
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) { |
164 | 186 | FS::FragInfo frag_info;
|
165 | 187 | frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
|
166 | 188 | frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
|
167 | 189 | FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
|
168 | 190 | }
|
169 | 191 |
|
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( |
181 | 205 | 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 | + } |
184 | 223 | }
|
185 | 224 |
|
186 | 225 | if (!pass.AddCommand(std::move(cmd))) {
|
|
0 commit comments