mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Provide fragment uniform data through varyings for solid color, glyph atlas, texture shaders. (flutter/engine#43838)
From experimentation, providing these values through varyings runs substantially faster on Pixel devices. Alternative solutions to use f16 or push constants did not improve things substantially. These subset of shaders are used very heavily and so they benefit from this change more substantially. I don't think this is applicable to all shaders as there is going to be an additional varying interpolation cost. See also: [go/impeller-slow-fragment-shader](http://goto.google.com/impeller-slow-fragment-shader)
This commit is contained in:
parent
a9eb2fe5f3
commit
949e91bbba
@ -9,6 +9,12 @@
|
||||
#extension GL_AMD_gpu_shader_half_float_fetch : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable
|
||||
|
||||
#ifdef IMPELLER_TARGET_OPENGLES
|
||||
#define IMPELLER_MAYBE_FLAT
|
||||
#else
|
||||
#define IMPELLER_MAYBE_FLAT flat
|
||||
#endif
|
||||
|
||||
#ifndef IMPELLER_TARGET_METAL_IOS
|
||||
|
||||
precision mediump sampler2D;
|
||||
|
||||
@ -338,16 +338,13 @@ bool AtlasTextureContents::Render(const ContentContext& renderer,
|
||||
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
entity.GetTransformation();
|
||||
frame_info.texture_sampler_y_coord_scale = texture->GetYCoordScale();
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.alpha = alpha_;
|
||||
frame_info.alpha = alpha_;
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
cmd.pipeline = renderer.GetTexturePipeline(options);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
|
||||
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
||||
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
|
||||
FS::BindTextureSampler(cmd, texture,
|
||||
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
|
||||
parent_.GetSamplerDescriptor()));
|
||||
|
||||
@ -80,16 +80,13 @@ bool ClipContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = ClipPipeline::VertexShader;
|
||||
using FS = ClipPipeline::FragmentShader;
|
||||
|
||||
VS::FrameInfo info;
|
||||
|
||||
Command cmd;
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
// The color really doesn't matter.
|
||||
frag_info.color = Color::SkyBlue();
|
||||
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
info.color = Color::SkyBlue();
|
||||
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
@ -182,7 +179,6 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = ClipPipeline::VertexShader;
|
||||
using FS = ClipPipeline::FragmentShader;
|
||||
|
||||
Command cmd;
|
||||
cmd.label = "Restore Clip";
|
||||
@ -208,13 +204,9 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
|
||||
|
||||
VS::FrameInfo info;
|
||||
info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize());
|
||||
info.color = Color::SkyBlue();
|
||||
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
// The color really doesn't matter.
|
||||
frag_info.color = Color::SkyBlue();
|
||||
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
pass.AddCommand(std::move(cmd));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -54,7 +54,6 @@ bool SolidColorContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = SolidFillPipeline::VertexShader;
|
||||
using FS = SolidFillPipeline::FragmentShader;
|
||||
|
||||
Command cmd;
|
||||
cmd.label = "Solid Fill";
|
||||
@ -75,12 +74,9 @@ bool SolidColorContents::Render(const ContentContext& renderer,
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = geometry_result.transform;
|
||||
frame_info.color = GetColor().Premultiply();
|
||||
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.color = GetColor().Premultiply();
|
||||
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
if (!pass.AddCommand(std::move(cmd))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -125,6 +125,7 @@ bool TextContents::Render(const ContentContext& renderer,
|
||||
frame_info.is_translation_scale =
|
||||
entity.GetTransformation().IsTranslationScaleOnly();
|
||||
frame_info.entity_transform = entity.GetTransformation();
|
||||
frame_info.text_color = ToVector(color.Premultiply());
|
||||
|
||||
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
|
||||
@ -143,10 +144,6 @@ bool TextContents::Render(const ContentContext& renderer,
|
||||
}
|
||||
sampler_desc.mip_filter = MipFilter::kNearest;
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.text_color = ToVector(color.Premultiply());
|
||||
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
FS::BindGlyphAtlasSampler(
|
||||
cmd, // command
|
||||
atlas->GetTexture(), // texture
|
||||
|
||||
@ -135,9 +135,7 @@ bool TextureContents::Render(const ContentContext& renderer,
|
||||
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
|
||||
entity.GetTransformation();
|
||||
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.alpha = GetOpacity();
|
||||
frame_info.alpha = GetOpacity();
|
||||
|
||||
Command cmd;
|
||||
cmd.label = "Texture Fill";
|
||||
@ -155,7 +153,6 @@ bool TextureContents::Render(const ContentContext& renderer,
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
|
||||
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
||||
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
|
||||
FS::BindTextureSampler(cmd, texture_,
|
||||
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
|
||||
sampler_descriptor_));
|
||||
|
||||
@ -136,6 +136,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp = geometry_result.transform;
|
||||
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
|
||||
frame_info.alpha = GetOpacityFactor();
|
||||
|
||||
Command cmd;
|
||||
cmd.label = uses_emulated_tile_mode ? "TiledTextureFill" : "TextureFill";
|
||||
@ -158,13 +159,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
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_);
|
||||
frag_info.alpha = GetOpacityFactor();
|
||||
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
|
||||
} else {
|
||||
TextureFillFragmentShader::FragInfo frag_info;
|
||||
frag_info.alpha = GetOpacityFactor();
|
||||
TextureFillFragmentShader::BindFragInfo(
|
||||
cmd, host_buffer.EmplaceUniform(frag_info));
|
||||
}
|
||||
|
||||
if (color_filter_) {
|
||||
|
||||
@ -144,12 +144,9 @@ bool VerticesUVContents::Render(const ContentContext& renderer,
|
||||
frame_info.mvp = geometry_result.transform;
|
||||
frame_info.texture_sampler_y_coord_scale =
|
||||
snapshot->texture->GetYCoordScale();
|
||||
frame_info.alpha = alpha_ * snapshot->opacity;
|
||||
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.alpha = alpha_ * snapshot->opacity;
|
||||
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
|
||||
|
||||
FS::BindTextureSampler(cmd, snapshot->texture,
|
||||
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
|
||||
snapshot->sampler_descriptor));
|
||||
|
||||
@ -857,7 +857,6 @@ TEST_P(EntityTest, BlendingModeOptions) {
|
||||
auto draw_rect = [&context, &pass, &world_matrix](
|
||||
Rect rect, Color color, BlendMode blend_mode) -> bool {
|
||||
using VS = SolidFillPipeline::VertexShader;
|
||||
using FS = SolidFillPipeline::FragmentShader;
|
||||
|
||||
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
|
||||
{
|
||||
@ -884,14 +883,10 @@ TEST_P(EntityTest, BlendingModeOptions) {
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.mvp =
|
||||
Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
|
||||
frame_info.color = color.Premultiply();
|
||||
VS::BindFrameInfo(cmd,
|
||||
pass.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.color = color.Premultiply();
|
||||
FS::BindFragInfo(cmd,
|
||||
pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
return pass.AddCommand(std::move(cmd));
|
||||
};
|
||||
|
||||
|
||||
@ -8,16 +8,13 @@ precision mediump float;
|
||||
|
||||
uniform f16sampler2D glyph_atlas_sampler;
|
||||
|
||||
uniform FragInfo {
|
||||
f16vec4 text_color;
|
||||
}
|
||||
frag_info;
|
||||
|
||||
in highp vec2 v_uv;
|
||||
|
||||
IMPELLER_MAYBE_FLAT in f16vec4 v_text_color;
|
||||
|
||||
out f16vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
f16vec4 value = texture(glyph_atlas_sampler, v_uv);
|
||||
frag_color = value.aaaa * frag_info.text_color;
|
||||
frag_color = value.aaaa * v_text_color;
|
||||
}
|
||||
|
||||
@ -3,12 +3,14 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <impeller/transform.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
uniform FrameInfo {
|
||||
mat4 mvp;
|
||||
mat4 entity_transform;
|
||||
vec2 atlas_size;
|
||||
vec2 offset;
|
||||
f16vec4 text_color;
|
||||
float is_translation_scale;
|
||||
}
|
||||
frame_info;
|
||||
@ -23,6 +25,8 @@ in vec2 glyph_position;
|
||||
|
||||
out vec2 v_uv;
|
||||
|
||||
IMPELLER_MAYBE_FLAT out f16vec4 v_text_color;
|
||||
|
||||
mat4 basis(mat4 m) {
|
||||
return mat4(m[0][0], m[0][1], m[0][2], 0.0, //
|
||||
m[1][0], m[1][1], m[1][2], 0.0, //
|
||||
@ -77,4 +81,5 @@ void main() {
|
||||
|
||||
gl_Position = frame_info.mvp * position;
|
||||
v_uv = uv_origin + unit_position * uv_size;
|
||||
v_text_color = frame_info.text_color;
|
||||
}
|
||||
|
||||
@ -8,16 +8,13 @@ precision mediump float;
|
||||
|
||||
uniform f16sampler2D glyph_atlas_sampler;
|
||||
|
||||
uniform FragInfo {
|
||||
f16vec4 text_color;
|
||||
}
|
||||
frag_info;
|
||||
|
||||
in highp vec2 v_uv;
|
||||
|
||||
IMPELLER_MAYBE_FLAT in f16vec4 v_text_color;
|
||||
|
||||
out f16vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
f16vec4 value = texture(glyph_atlas_sampler, v_uv);
|
||||
frag_color = value * frag_info.text_color.aaaa;
|
||||
frag_color = value * v_text_color.aaaa;
|
||||
}
|
||||
|
||||
@ -6,13 +6,10 @@ precision mediump float;
|
||||
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
uniform FragInfo {
|
||||
f16vec4 color;
|
||||
}
|
||||
frag_info;
|
||||
IMPELLER_MAYBE_FLAT in f16vec4 v_color;
|
||||
|
||||
out f16vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
frag_color = frag_info.color;
|
||||
frag_color = v_color;
|
||||
}
|
||||
|
||||
@ -6,11 +6,15 @@
|
||||
|
||||
uniform FrameInfo {
|
||||
mat4 mvp;
|
||||
f16vec4 color;
|
||||
}
|
||||
frame_info;
|
||||
|
||||
in vec2 position;
|
||||
|
||||
IMPELLER_MAYBE_FLAT out f16vec4 v_color;
|
||||
|
||||
void main() {
|
||||
v_color = frame_info.color;
|
||||
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@ -9,17 +9,13 @@ precision mediump float;
|
||||
|
||||
uniform f16sampler2D texture_sampler;
|
||||
|
||||
uniform FragInfo {
|
||||
float16_t alpha;
|
||||
}
|
||||
frag_info;
|
||||
|
||||
in highp vec2 v_texture_coords;
|
||||
IMPELLER_MAYBE_FLAT in float16_t v_alpha;
|
||||
|
||||
out f16vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
f16vec4 sampled =
|
||||
texture(texture_sampler, v_texture_coords, kDefaultMipBiasHalf);
|
||||
frag_color = sampled * frag_info.alpha;
|
||||
frag_color = sampled * v_alpha;
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
uniform FrameInfo {
|
||||
mat4 mvp;
|
||||
float texture_sampler_y_coord_scale;
|
||||
float16_t alpha;
|
||||
}
|
||||
frame_info;
|
||||
|
||||
@ -15,9 +16,11 @@ in vec2 position;
|
||||
in vec2 texture_coords;
|
||||
|
||||
out vec2 v_texture_coords;
|
||||
IMPELLER_MAYBE_FLAT out float16_t v_alpha;
|
||||
|
||||
void main() {
|
||||
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
|
||||
v_alpha = frame_info.alpha;
|
||||
v_texture_coords =
|
||||
IPRemapCoords(texture_coords, frame_info.texture_sampler_y_coord_scale);
|
||||
}
|
||||
|
||||
@ -12,11 +12,11 @@ uniform f16sampler2D texture_sampler;
|
||||
uniform FragInfo {
|
||||
float16_t x_tile_mode;
|
||||
float16_t y_tile_mode;
|
||||
float16_t alpha;
|
||||
}
|
||||
frag_info;
|
||||
|
||||
in highp vec2 v_texture_coords;
|
||||
IMPELLER_MAYBE_FLAT in float16_t v_alpha;
|
||||
|
||||
out f16vec4 frag_color;
|
||||
|
||||
@ -27,5 +27,5 @@ void main() {
|
||||
frag_info.x_tile_mode, // x tile mode
|
||||
frag_info.y_tile_mode // y tile mode
|
||||
) *
|
||||
frag_info.alpha;
|
||||
v_alpha;
|
||||
}
|
||||
|
||||
@ -131,7 +131,6 @@ TEST_P(ComputeSubgroupTest, PathPlayground) {
|
||||
}
|
||||
|
||||
using VS = SolidFillPipeline::VertexShader;
|
||||
using FS = SolidFillPipeline::FragmentShader;
|
||||
|
||||
Command cmd;
|
||||
cmd.label = "Draw Stroke";
|
||||
@ -164,13 +163,10 @@ TEST_P(ComputeSubgroupTest, PathPlayground) {
|
||||
auto world_matrix = Matrix::MakeScale(GetContentScale());
|
||||
frame_info.mvp =
|
||||
Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
|
||||
frame_info.color = Color::Red().Premultiply();
|
||||
VS::BindFrameInfo(cmd,
|
||||
pass.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.color = Color::Red().Premultiply();
|
||||
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
if (!pass.AddCommand(std::move(cmd))) {
|
||||
return false;
|
||||
}
|
||||
@ -339,7 +335,6 @@ TEST_P(ComputeSubgroupTest, LargePath) {
|
||||
}
|
||||
|
||||
using VS = SolidFillPipeline::VertexShader;
|
||||
using FS = SolidFillPipeline::FragmentShader;
|
||||
|
||||
Command cmd;
|
||||
cmd.label = "Draw Stroke";
|
||||
@ -372,13 +367,10 @@ TEST_P(ComputeSubgroupTest, LargePath) {
|
||||
auto world_matrix = Matrix::MakeScale(GetContentScale());
|
||||
frame_info.mvp =
|
||||
Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
|
||||
frame_info.color = Color::Red().Premultiply();
|
||||
VS::BindFrameInfo(cmd,
|
||||
pass.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.color = Color::Red().Premultiply();
|
||||
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
if (!pass.AddCommand(std::move(cmd))) {
|
||||
return false;
|
||||
}
|
||||
@ -427,7 +419,6 @@ TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) {
|
||||
}
|
||||
|
||||
using VS = SolidFillPipeline::VertexShader;
|
||||
using FS = SolidFillPipeline::FragmentShader;
|
||||
|
||||
Command cmd;
|
||||
cmd.label = "Draw Stroke";
|
||||
@ -460,13 +451,10 @@ TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) {
|
||||
auto world_matrix = Matrix::MakeScale(GetContentScale());
|
||||
frame_info.mvp =
|
||||
Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
|
||||
frame_info.color = Color::Red().Premultiply();
|
||||
VS::BindFrameInfo(cmd,
|
||||
pass.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.color = Color::Red().Premultiply();
|
||||
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
if (!pass.AddCommand(std::move(cmd))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user