[Impeller] Fix GLES SurfaceTexture rendering. (#160634)

Fixes https://github.com/flutter/flutter/issues/160480

Both The Impeller and Skia variant of the OES texture rendering use the
same shared code path, so the Impeller code must match the weird 1x1
texture behavior of Skia. In addition, we have to add back the
TiledTextureContents support, since we need to render a texture with a
transform. I had previously tested this but neglected to force the
SurfaceTexture path, so I only tested the ImageReader path which does
not use a transform.
This commit is contained in:
Jonah Williams 2024-12-20 11:44:19 -08:00 committed by GitHub
parent 9eca517c92
commit 2d811593db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 65 additions and 20 deletions

View File

@ -101,8 +101,6 @@ class ColorSourceContents : public Contents {
protected:
using BindFragmentCallback = std::function<bool(RenderPass& pass)>;
using PipelineBuilderMethod = std::shared_ptr<Pipeline<PipelineDescriptor>> (
impeller::ContentContext::*)(ContentContextOptions) const;
using PipelineBuilderCallback =
std::function<PipelineRef(ContentContextOptions)>;
using CreateGeometryCallback =

View File

@ -464,6 +464,7 @@ ContentContext::ContentContext(
#if !defined(FML_OS_MACOSX)
// GLES only shader that is unsupported on macOS.
tiled_texture_external_pipelines_.CreateDefault(*context_, options);
tiled_texture_uv_external_pipelines_.CreateDefault(*context_, options);
#endif // !defined(FML_OS_MACOSX)
texture_downsample_gles_pipelines_.CreateDefault(*context_,
options_trianglestrip);

View File

@ -257,6 +257,9 @@ using VerticesUberShader = RenderPipelineHandle<PorterDuffBlendVertexShader,
using TiledTextureExternalPipeline =
RenderPipelineHandle<TextureFillVertexShader,
TiledTextureFillExternalFragmentShader>;
using TiledTextureUvExternalPipeline =
RenderPipelineHandle<TextureUvFillVertexShader,
TiledTextureFillExternalFragmentShader>;
using TextureDownsampleGlesPipeline =
RenderPipelineHandle<TextureFillVertexShader,
TextureDownsampleGlesFragmentShader>;
@ -469,6 +472,13 @@ class ContentContext {
Context::BackendType::kOpenGLES);
return GetPipeline(tiled_texture_external_pipelines_, opts);
}
PipelineRef GetTiledTextureUvExternalPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetContext()->GetBackendType() ==
Context::BackendType::kOpenGLES);
return GetPipeline(tiled_texture_uv_external_pipelines_, opts);
}
#endif // IMPELLER_ENABLE_OPENGLES
PipelineRef GetTiledTexturePipeline(ContentContextOptions opts) const {
@ -892,6 +902,8 @@ class ContentContext {
tiled_texture_external_pipelines_;
mutable Variants<TextureDownsampleGlesPipeline>
texture_downsample_gles_pipelines_;
mutable Variants<TiledTextureUvExternalPipeline>
tiled_texture_uv_external_pipelines_;
#endif // IMPELLER_ENABLE_OPENGLES
mutable Variants<TiledTexturePipeline> tiled_texture_pipelines_;
mutable Variants<GaussianBlurPipeline> gaussian_blur_pipelines_;

View File

@ -128,6 +128,46 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
Rect::MakeSize(texture_size).GetNormalizingTransform() *
GetInverseEffectTransform();
#ifdef IMPELLER_ENABLE_OPENGLES
using FSExternal = TiledTextureFillExternalFragmentShader;
if (texture_->GetTextureDescriptor().type ==
TextureType::kTextureExternalOES) {
return ColorSourceContents::DrawGeometry<VS>(
renderer, entity, pass,
[&renderer](ContentContextOptions options) {
return renderer.GetTiledTextureUvExternalPipeline(options);
},
frame_info,
[this, &renderer](RenderPass& pass) {
auto& host_buffer = renderer.GetTransientsBuffer();
#ifdef IMPELLER_DEBUG
pass.SetCommandLabel("TextureFill External");
#endif // IMPELLER_DEBUG
FML_DCHECK(!color_filter_);
FSExternal::FragInfo frag_info;
frag_info.x_tile_mode =
static_cast<Scalar>(sampler_descriptor_.width_address_mode);
frag_info.y_tile_mode =
static_cast<Scalar>(sampler_descriptor_.height_address_mode);
frag_info.alpha = GetOpacityFactor();
FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
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;
FSExternal::BindSAMPLEREXTERNALOESTextureSampler(
pass, texture_,
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
sampler_desc));
return true;
});
}
#endif // IMPELLER_ENABLE_OPENGLES
PipelineBuilderCallback pipeline_callback =
[&renderer](ContentContextOptions options) {
return renderer.GetTiledTexturePipeline(options);

View File

@ -14,7 +14,7 @@ frame_info;
in vec2 position;
in vec2 texture_coords;
out vec2 v_texture_coords;
out highp vec2 v_texture_coords;
void main() {
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);

View File

@ -16,7 +16,7 @@ frame_info;
in vec2 position;
out mediump vec2 v_texture_coords;
out highp vec2 v_texture_coords;
void main() {
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);

View File

@ -18,7 +18,7 @@ uniform FragInfo {
}
frag_info;
in mediump vec2 v_texture_coords;
in highp vec2 v_texture_coords;
out f16vec4 frag_color;

View File

@ -5969,7 +5969,7 @@
"longest_path_cycles": [
0.078125,
0.078125,
0.078125,
0.015625,
0.0,
3.0,
0.0
@ -5988,7 +5988,7 @@
"shortest_path_cycles": [
0.078125,
0.078125,
0.078125,
0.015625,
0.0,
3.0,
0.0
@ -5999,7 +5999,7 @@
"total_cycles": [
0.078125,
0.078125,
0.078125,
0.015625,
0.0,
3.0,
0.0
@ -6008,7 +6008,7 @@
"stack_spill_bytes": 0,
"thread_occupancy": 100,
"uniform_registers_used": 16,
"work_registers_used": 8
"work_registers_used": 9
}
}
},
@ -8771,7 +8771,7 @@
"longest_path_cycles": [
0.078125,
0.078125,
0.078125,
0.015625,
0.0,
3.0,
0.0
@ -8790,7 +8790,7 @@
"shortest_path_cycles": [
0.078125,
0.078125,
0.078125,
0.015625,
0.0,
3.0,
0.0
@ -8801,7 +8801,7 @@
"total_cycles": [
0.078125,
0.078125,
0.078125,
0.015625,
0.0,
3.0,
0.0
@ -8810,7 +8810,7 @@
"stack_spill_bytes": 0,
"thread_occupancy": 100,
"uniform_registers_used": 32,
"work_registers_used": 8
"work_registers_used": 9
}
}
}

View File

@ -13,11 +13,6 @@
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLTypes.h"
namespace flutter {

View File

@ -29,8 +29,7 @@ void SurfaceTextureExternalTextureGLImpeller::ProcessFrame(
desc.type = impeller::TextureType::kTextureExternalOES;
desc.storage_mode = impeller::StorageMode::kDevicePrivate;
desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt;
desc.size = {static_cast<int>(bounds.width()),
static_cast<int>(bounds.height())};
desc.size = {1, 1};
desc.mip_count = 1;
texture_ = std::make_shared<impeller::TextureGLES>(
impeller_context_->GetReactor(), desc);