mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Reland: Compute UVs in vertex stage. (flutter/engine#52303)
Compute texture UVs in the vertex stage. Reland of https://github.com/flutter/engine/pull/52106 which was reverted to investigate golden failures during the x64 to arm64 mac switch.
This commit is contained in:
parent
4d092e34c1
commit
feca43deaf
@ -40397,7 +40397,6 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/kernel.vert + ../
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/kernel_decal.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/kernel_nodecal.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/geometry/points.comp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/geometry/uv.comp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag + ../../../flutter/LICENSE
|
||||
@ -40419,6 +40418,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/solid_fill.vert + ../../../flut
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill.vert + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_fill_strict_src.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/texture_uv_fill.vert + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/tiled_texture_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/tiled_texture_fill_external.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/vertices.frag + ../../../flutter/LICENSE
|
||||
@ -43279,7 +43279,6 @@ FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/kernel.vert
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/kernel_decal.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/kernel_nodecal.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/geometry/points.comp
|
||||
FILE: ../../../flutter/impeller/entity/shaders/geometry/uv.comp
|
||||
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert
|
||||
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag
|
||||
@ -43301,6 +43300,7 @@ FILE: ../../../flutter/impeller/entity/shaders/solid_fill.vert
|
||||
FILE: ../../../flutter/impeller/entity/shaders/texture_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/texture_fill.vert
|
||||
FILE: ../../../flutter/impeller/entity/shaders/texture_fill_strict_src.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/texture_uv_fill.vert
|
||||
FILE: ../../../flutter/impeller/entity/shaders/tiled_texture_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/tiled_texture_fill_external.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/vertices.frag
|
||||
|
||||
@ -901,14 +901,12 @@ static bool UseColorSourceContents(
|
||||
const std::shared_ptr<VerticesGeometry>& vertices,
|
||||
const Paint& paint) {
|
||||
// If there are no vertex color or texture coordinates. Or if there
|
||||
// are vertex coordinates then only if the contents are an image or
|
||||
// a solid color.
|
||||
// are vertex coordinates but its just a color.
|
||||
if (vertices->HasVertexColors()) {
|
||||
return false;
|
||||
}
|
||||
if (vertices->HasTextureCoordinates() &&
|
||||
(paint.color_source.GetType() == ColorSource::Type::kImage ||
|
||||
paint.color_source.GetType() == ColorSource::Type::kColor)) {
|
||||
(paint.color_source.GetType() == ColorSource::Type::kColor)) {
|
||||
return true;
|
||||
}
|
||||
return !vertices->HasTextureCoordinates();
|
||||
@ -928,8 +926,7 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
|
||||
entity.SetTransform(GetCurrentTransform());
|
||||
entity.SetBlendMode(paint.blend_mode);
|
||||
|
||||
// If there are no vertex color or texture coordinates. Or if there
|
||||
// are vertex coordinates then only if the contents are an image.
|
||||
// If there are no vertex colors.
|
||||
if (UseColorSourceContents(vertices, paint)) {
|
||||
entity.SetContents(CreateContentsForGeometryWithFilters(paint, vertices));
|
||||
AddRenderEntityToCurrentPass(std::move(entity));
|
||||
@ -945,7 +942,6 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
|
||||
contents->SetBlendMode(blend_mode);
|
||||
contents->SetAlpha(paint.color.alpha);
|
||||
contents->SetGeometry(vertices);
|
||||
|
||||
contents->SetEffectTransform(image_data.effect_transform);
|
||||
contents->SetTexture(image_data.texture);
|
||||
contents->SetTileMode(image_data.x_tile_mode, image_data.y_tile_mode);
|
||||
|
||||
@ -39,6 +39,7 @@ impeller_shaders("entity_shaders") {
|
||||
"shaders/gradients/sweep_gradient_fill.frag",
|
||||
"shaders/texture_fill.frag",
|
||||
"shaders/texture_fill.vert",
|
||||
"shaders/texture_uv_fill.vert",
|
||||
"shaders/tiled_texture_fill.frag",
|
||||
"shaders/tiled_texture_fill_external.frag",
|
||||
"shaders/texture_fill_strict_src.frag",
|
||||
@ -81,7 +82,6 @@ impeller_shaders("modern_entity_shaders") {
|
||||
"shaders/gradients/radial_gradient_ssbo_fill.frag",
|
||||
"shaders/gradients/sweep_gradient_ssbo_fill.frag",
|
||||
"shaders/geometry/points.comp",
|
||||
"shaders/geometry/uv.comp",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/entity/contents/contents.h"
|
||||
#include "impeller/entity/entity.h"
|
||||
#include "impeller/entity/geometry/geometry.h"
|
||||
|
||||
@ -118,10 +118,7 @@ class ColorSourceContents : public Contents {
|
||||
RenderPass& pass,
|
||||
const PipelineBuilderCallback& pipeline_callback,
|
||||
typename VertexShaderT::FrameInfo frame_info,
|
||||
const BindFragmentCallback& bind_fragment_callback,
|
||||
bool enable_uvs = false,
|
||||
Rect texture_coverage = {},
|
||||
const Matrix& effect_transform = {}) const {
|
||||
const BindFragmentCallback& bind_fragment_callback) const {
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
|
||||
GeometryResult::Mode geometry_mode = GetGeometry()->GetResultMode();
|
||||
@ -181,10 +178,7 @@ class ColorSourceContents : public Contents {
|
||||
}
|
||||
|
||||
GeometryResult geometry_result =
|
||||
enable_uvs
|
||||
? geometry.GetPositionUVBuffer(texture_coverage, effect_transform,
|
||||
renderer, entity, pass)
|
||||
: geometry.GetPositionBuffer(renderer, entity, pass);
|
||||
geometry.GetPositionBuffer(renderer, entity, pass);
|
||||
if (geometry_result.vertex_buffer.vertex_count == 0u) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -260,8 +260,7 @@ ContentContext::ContentContext(
|
||||
? std::make_shared<RenderTargetCache>(
|
||||
context_->GetResourceAllocator())
|
||||
: std::move(render_target_allocator)),
|
||||
host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())),
|
||||
pending_command_buffers_(std::make_unique<PendingCommandBuffers>()) {
|
||||
host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())) {
|
||||
if (!context_ || !context_->IsValid()) {
|
||||
return;
|
||||
}
|
||||
@ -422,8 +421,7 @@ ContentContext::ContentContext(
|
||||
|
||||
rrect_blur_pipelines_.CreateDefault(*context_, options_trianglestrip);
|
||||
texture_strict_src_pipelines_.CreateDefault(*context_, options);
|
||||
position_uv_pipelines_.CreateDefault(*context_, options);
|
||||
tiled_texture_pipelines_.CreateDefault(*context_, options);
|
||||
tiled_texture_pipelines_.CreateDefault(*context_, options, {supports_decal});
|
||||
kernel_decal_pipelines_.CreateDefault(*context_, options_trianglestrip);
|
||||
kernel_nodecal_pipelines_.CreateDefault(*context_, options_trianglestrip);
|
||||
border_mask_blur_pipelines_.CreateDefault(*context_, options_trianglestrip);
|
||||
@ -445,7 +443,7 @@ ContentContext::ContentContext(
|
||||
yuv_to_rgb_filter_pipelines_.CreateDefault(*context_, options_trianglestrip);
|
||||
porter_duff_blend_pipelines_.CreateDefault(*context_, options_trianglestrip,
|
||||
{supports_decal});
|
||||
vertices_uber_shader_.CreateDefault(*context_, options);
|
||||
vertices_uber_shader_.CreateDefault(*context_, options, {supports_decal});
|
||||
// GLES only shader that is unsupported on macOS.
|
||||
#if defined(IMPELLER_ENABLE_OPENGLES) && !defined(FML_OS_MACOSX)
|
||||
if (GetContext()->GetBackendType() == Context::BackendType::kOpenGLES) {
|
||||
@ -457,11 +455,6 @@ ContentContext::ContentContext(
|
||||
PointsComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_);
|
||||
point_field_compute_pipelines_ =
|
||||
context_->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
|
||||
|
||||
auto uv_pipeline_desc =
|
||||
UvComputeShaderPipeline::MakeDefaultPipelineDescriptor(*context_);
|
||||
uv_compute_pipelines_ =
|
||||
context_->GetPipelineLibrary()->GetPipeline(uv_pipeline_desc).Get();
|
||||
}
|
||||
|
||||
is_valid_ = true;
|
||||
|
||||
@ -57,8 +57,8 @@
|
||||
#include "impeller/entity/texture_fill.frag.h"
|
||||
#include "impeller/entity/texture_fill.vert.h"
|
||||
#include "impeller/entity/texture_fill_strict_src.frag.h"
|
||||
#include "impeller/entity/texture_uv_fill.vert.h"
|
||||
#include "impeller/entity/tiled_texture_fill.frag.h"
|
||||
#include "impeller/entity/uv.comp.h"
|
||||
#include "impeller/entity/vertices.frag.h"
|
||||
#include "impeller/entity/yuv_to_rgb_filter.frag.h"
|
||||
|
||||
@ -132,10 +132,8 @@ using TexturePipeline =
|
||||
using TextureStrictSrcPipeline =
|
||||
RenderPipelineHandle<TextureFillVertexShader,
|
||||
TextureFillStrictSrcFragmentShader>;
|
||||
using PositionUVPipeline = RenderPipelineHandle<TextureFillVertexShader,
|
||||
TiledTextureFillFragmentShader>;
|
||||
using TiledTexturePipeline =
|
||||
RenderPipelineHandle<TextureFillVertexShader,
|
||||
RenderPipelineHandle<TextureUvFillVertexShader,
|
||||
TiledTextureFillFragmentShader>;
|
||||
using KernelDecalPipeline =
|
||||
RenderPipelineHandle<KernelVertexShader, KernelDecalFragmentShader>;
|
||||
@ -260,20 +258,13 @@ using VerticesUberShader =
|
||||
|
||||
/// Geometry Pipelines
|
||||
using PointsComputeShaderPipeline = ComputePipelineBuilder<PointsComputeShader>;
|
||||
using UvComputeShaderPipeline = ComputePipelineBuilder<UvComputeShader>;
|
||||
|
||||
#ifdef IMPELLER_ENABLE_OPENGLES
|
||||
using TiledTextureExternalPipeline =
|
||||
RenderPipelineHandle<TextureFillVertexShader,
|
||||
RenderPipelineHandle<TextureUvFillVertexShader,
|
||||
TiledTextureFillExternalFragmentShader>;
|
||||
#endif // IMPELLER_ENABLE_OPENGLES
|
||||
|
||||
// A struct used to isolate command buffer storage from the content
|
||||
// context options to preserve const-ness.
|
||||
struct PendingCommandBuffers {
|
||||
std::vector<std::shared_ptr<CommandBuffer>> command_buffers;
|
||||
};
|
||||
|
||||
/// Pipeline state configuration.
|
||||
///
|
||||
/// Each unique combination of these options requires a different pipeline state
|
||||
@ -485,11 +476,6 @@ class ContentContext {
|
||||
}
|
||||
#endif // IMPELLER_ENABLE_OPENGLES
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPositionUVPipeline(
|
||||
ContentContextOptions opts) const {
|
||||
return GetPipeline(position_uv_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTexturePipeline(
|
||||
ContentContextOptions opts) const {
|
||||
return GetPipeline(tiled_texture_pipelines_, opts);
|
||||
@ -739,12 +725,6 @@ class ContentContext {
|
||||
return point_field_compute_pipelines_;
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<ComputePipelineDescriptor>> GetUvComputePipeline()
|
||||
const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsCompute());
|
||||
return uv_compute_pipelines_;
|
||||
}
|
||||
|
||||
std::shared_ptr<Context> GetContext() const;
|
||||
|
||||
const Capabilities& GetDeviceCapabilities() const;
|
||||
@ -944,7 +924,6 @@ class ContentContext {
|
||||
mutable Variants<TiledTextureExternalPipeline>
|
||||
tiled_texture_external_pipelines_;
|
||||
#endif // IMPELLER_ENABLE_OPENGLES
|
||||
mutable Variants<PositionUVPipeline> position_uv_pipelines_;
|
||||
mutable Variants<TiledTexturePipeline> tiled_texture_pipelines_;
|
||||
mutable Variants<KernelDecalPipeline> kernel_decal_pipelines_;
|
||||
mutable Variants<KernelPipeline> kernel_nodecal_pipelines_;
|
||||
@ -1010,8 +989,6 @@ class ContentContext {
|
||||
mutable Variants<VerticesUberShader> vertices_uber_shader_;
|
||||
mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
|
||||
point_field_compute_pipelines_;
|
||||
mutable std::shared_ptr<Pipeline<ComputePipelineDescriptor>>
|
||||
uv_compute_pipelines_;
|
||||
|
||||
template <class TypedPipeline>
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
|
||||
@ -1071,7 +1048,6 @@ class ContentContext {
|
||||
#endif // IMPELLER_ENABLE_3D
|
||||
std::shared_ptr<RenderTargetAllocator> render_target_cache_;
|
||||
std::shared_ptr<HostBuffer> host_buffer_;
|
||||
std::unique_ptr<PendingCommandBuffers> pending_command_buffers_;
|
||||
bool wireframe_ = false;
|
||||
|
||||
ContentContext(const ContentContext&) = delete;
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include "impeller/entity/texture_fill.frag.h"
|
||||
#include "impeller/entity/texture_fill.vert.h"
|
||||
#include "impeller/entity/texture_fill_strict_src.frag.h"
|
||||
#include "impeller/entity/tiled_texture_fill_external.frag.h"
|
||||
#include "impeller/geometry/constants.h"
|
||||
#include "impeller/renderer/render_pass.h"
|
||||
#include "impeller/renderer/vertex_buffer_builder.h"
|
||||
@ -114,7 +113,6 @@ bool TextureContents::Render(const ContentContext& renderer,
|
||||
|
||||
using VS = TextureFillVertexShader;
|
||||
using FS = TextureFillFragmentShader;
|
||||
using FSExternal = TiledTextureFillExternalFragmentShader;
|
||||
using FSStrict = TextureFillStrictSrcFragmentShader;
|
||||
|
||||
if (destination_rect_.IsEmpty() || source_rect_.IsEmpty() ||
|
||||
@ -122,8 +120,9 @@ bool TextureContents::Render(const ContentContext& renderer,
|
||||
return true; // Nothing to render.
|
||||
}
|
||||
|
||||
bool is_external_texture =
|
||||
[[maybe_unused]] bool is_external_texture =
|
||||
texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES;
|
||||
FML_DCHECK(!is_external_texture);
|
||||
|
||||
auto source_rect = capture.AddRect("Source rect", source_rect_);
|
||||
auto texture_coords =
|
||||
@ -159,46 +158,14 @@ bool TextureContents::Render(const ContentContext& renderer,
|
||||
}
|
||||
pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
|
||||
#ifdef IMPELLER_ENABLE_OPENGLES
|
||||
if (is_external_texture) {
|
||||
pipeline = renderer.GetTiledTextureExternalPipeline(pipeline_options);
|
||||
}
|
||||
#endif // IMPELLER_ENABLE_OPENGLES
|
||||
|
||||
if (!pipeline) {
|
||||
if (strict_source_rect_enabled_) {
|
||||
pipeline = renderer.GetTextureStrictSrcPipeline(pipeline_options);
|
||||
} else {
|
||||
pipeline = renderer.GetTexturePipeline(pipeline_options);
|
||||
}
|
||||
}
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.SetPipeline(strict_source_rect_enabled_
|
||||
? renderer.GetTextureStrictSrcPipeline(pipeline_options)
|
||||
: renderer.GetTexturePipeline(pipeline_options));
|
||||
|
||||
pass.SetVertexBuffer(vertex_builder.CreateVertexBuffer(host_buffer));
|
||||
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
|
||||
|
||||
if (is_external_texture) {
|
||||
FSExternal::FragInfo frag_info;
|
||||
frag_info.x_tile_mode =
|
||||
static_cast<int>(sampler_descriptor_.width_address_mode);
|
||||
frag_info.y_tile_mode =
|
||||
static_cast<int>(sampler_descriptor_.height_address_mode);
|
||||
frag_info.alpha = capture.AddScalar("Alpha", GetOpacity());
|
||||
|
||||
auto sampler_descriptor = sampler_descriptor_;
|
||||
// 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_descriptor.width_address_mode = SamplerAddressMode::kClampToEdge;
|
||||
sampler_descriptor.height_address_mode = SamplerAddressMode::kClampToEdge;
|
||||
|
||||
FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform((frag_info)));
|
||||
FSExternal::BindSAMPLEREXTERNALOESTextureSampler(
|
||||
pass, texture_,
|
||||
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
|
||||
sampler_descriptor));
|
||||
} else if (strict_source_rect_enabled_) {
|
||||
if (strict_source_rect_enabled_) {
|
||||
// For a strict source rect, shrink the texture coordinate range by half a
|
||||
// texel to ensure that linear filtering does not sample anything outside
|
||||
// the source rect bounds.
|
||||
|
||||
@ -6,8 +6,6 @@
|
||||
|
||||
#include "fml/logging.h"
|
||||
#include "impeller/entity/contents/content_context.h"
|
||||
#include "impeller/entity/texture_fill.frag.h"
|
||||
#include "impeller/entity/texture_fill.vert.h"
|
||||
#include "impeller/entity/tiled_texture_fill.frag.h"
|
||||
#include "impeller/entity/tiled_texture_fill_external.frag.h"
|
||||
#include "impeller/renderer/render_pass.h"
|
||||
@ -116,7 +114,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
return true;
|
||||
}
|
||||
|
||||
using VS = TextureFillVertexShader;
|
||||
using VS = TextureUvFillVertexShader;
|
||||
using FS = TiledTextureFillFragmentShader;
|
||||
using FSExternal = TiledTextureFillExternalFragmentShader;
|
||||
|
||||
@ -128,11 +126,11 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
bool is_external_texture =
|
||||
texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES;
|
||||
|
||||
bool uses_emulated_tile_mode =
|
||||
UsesEmulatedTileMode(renderer.GetDeviceCapabilities());
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
|
||||
frame_info.uv_transform =
|
||||
Rect::MakeSize(texture_size).GetNormalizingTransform() *
|
||||
GetInverseEffectTransform();
|
||||
|
||||
PipelineBuilderMethod pipeline_method;
|
||||
|
||||
@ -140,14 +138,10 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
if (is_external_texture) {
|
||||
pipeline_method = &ContentContext::GetTiledTextureExternalPipeline;
|
||||
} else {
|
||||
pipeline_method = uses_emulated_tile_mode
|
||||
? &ContentContext::GetTiledTexturePipeline
|
||||
: &ContentContext::GetTexturePipeline;
|
||||
pipeline_method = &ContentContext::GetTiledTexturePipeline;
|
||||
}
|
||||
#else
|
||||
pipeline_method = uses_emulated_tile_mode
|
||||
? &ContentContext::GetTiledTexturePipeline
|
||||
: &ContentContext::GetTexturePipeline;
|
||||
pipeline_method = &ContentContext::GetTiledTexturePipeline;
|
||||
#endif // IMPELLER_ENABLE_OPENGLES
|
||||
|
||||
PipelineBuilderCallback pipeline_callback =
|
||||
@ -156,15 +150,10 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
};
|
||||
return ColorSourceContents::DrawGeometry<VS>(
|
||||
renderer, entity, pass, pipeline_callback, frame_info,
|
||||
[this, &renderer, &is_external_texture,
|
||||
&uses_emulated_tile_mode](RenderPass& pass) {
|
||||
[this, &renderer, &is_external_texture](RenderPass& pass) {
|
||||
auto& host_buffer = renderer.GetTransientsBuffer();
|
||||
|
||||
if (uses_emulated_tile_mode) {
|
||||
pass.SetCommandLabel("TiledTextureFill");
|
||||
} else {
|
||||
pass.SetCommandLabel("TextureFill");
|
||||
}
|
||||
pass.SetCommandLabel("TextureFill");
|
||||
|
||||
if (is_external_texture) {
|
||||
FSExternal::FragInfo frag_info;
|
||||
@ -172,17 +161,12 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
|
||||
frag_info.alpha = GetOpacityFactor();
|
||||
FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
|
||||
} else if (uses_emulated_tile_mode) {
|
||||
} else {
|
||||
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(pass, host_buffer.EmplaceUniform(frag_info));
|
||||
} else {
|
||||
TextureFillFragmentShader::FragInfo frag_info;
|
||||
frag_info.alpha = GetOpacityFactor();
|
||||
TextureFillFragmentShader::BindFragInfo(
|
||||
pass, host_buffer.EmplaceUniform(frag_info));
|
||||
}
|
||||
|
||||
if (is_external_texture) {
|
||||
@ -221,10 +205,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
/*enable_uvs=*/true,
|
||||
/*texture_coverage=*/Rect::MakeSize(texture_size),
|
||||
/*effect_transform=*/GetInverseEffectTransform());
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<Snapshot> TiledTextureContents::RenderToSnapshot(
|
||||
|
||||
@ -152,7 +152,7 @@ bool VerticesUVContents::Render(const ContentContext& renderer,
|
||||
|
||||
pass.SetCommandLabel("VerticesUV");
|
||||
auto& host_buffer = renderer.GetTransientsBuffer();
|
||||
const std::shared_ptr<Geometry>& geometry = parent_.GetGeometry();
|
||||
const std::shared_ptr<VerticesGeometry>& geometry = parent_.GetGeometry();
|
||||
|
||||
auto coverage = src_contents->GetCoverage(Entity{});
|
||||
if (!coverage.has_value()) {
|
||||
@ -333,7 +333,8 @@ bool VerticesSimpleBlendContents::Render(const ContentContext& renderer,
|
||||
frag_info.dst_coeff = blend_coefficients[2];
|
||||
frag_info.dst_coeff_src_alpha = blend_coefficients[3];
|
||||
frag_info.dst_coeff_src_color = blend_coefficients[4];
|
||||
// Only used on devices that do not natively support advanced blends.
|
||||
|
||||
// These values are ignored if the platform supports native decal mode.
|
||||
frag_info.tmx = static_cast<int>(tile_mode_x_);
|
||||
frag_info.tmy = static_cast<int>(tile_mode_y_);
|
||||
|
||||
@ -366,6 +367,10 @@ bool VerticesSimpleBlendContents::Render(const ContentContext& renderer,
|
||||
frag_info.alpha = alpha_;
|
||||
frag_info.blend_mode = static_cast<int>(blend_mode);
|
||||
|
||||
// These values are ignored if the platform supports native decal mode.
|
||||
frag_info.tmx = static_cast<int>(tile_mode_x_);
|
||||
frag_info.tmy = static_cast<int>(tile_mode_y_);
|
||||
|
||||
auto& host_buffer = renderer.GetTransientsBuffer();
|
||||
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
|
||||
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
|
||||
|
||||
@ -2831,12 +2831,7 @@ TEST_P(EntityTest, CanComputeGeometryForEmptyPathsWithoutCrashing) {
|
||||
auto position_result =
|
||||
geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
|
||||
|
||||
auto uv_result =
|
||||
geom->GetPositionUVBuffer(Rect::MakeLTRB(0, 0, 100, 100), Matrix(),
|
||||
*GetContentContext(), entity, render_pass);
|
||||
|
||||
EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
|
||||
EXPECT_EQ(uv_result.vertex_buffer.vertex_count, 0u);
|
||||
|
||||
EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
|
||||
}
|
||||
|
||||
@ -44,31 +44,6 @@ GeometryResult CircleGeometry::GetPositionBuffer(const ContentContext& renderer,
|
||||
return ComputePositionGeometry(renderer, generator, entity, pass);
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult CircleGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
auto& transform = entity.GetTransform();
|
||||
auto uv_transform =
|
||||
texture_coverage.GetNormalizingTransform() * effect_transform;
|
||||
|
||||
Scalar half_width = stroke_width_ < 0 ? 0.0
|
||||
: LineGeometry::ComputePixelHalfWidth(
|
||||
transform, stroke_width_);
|
||||
std::shared_ptr<Tessellator> tessellator = renderer.GetTessellator();
|
||||
|
||||
// We call the StrokedCircle method which will simplify to a
|
||||
// FilledCircleGenerator if the inner_radius is <= 0.
|
||||
auto generator =
|
||||
tessellator->StrokedCircle(transform, center_, radius_, half_width);
|
||||
|
||||
return ComputePositionUVGeometry(renderer, generator, uv_transform, entity,
|
||||
pass);
|
||||
}
|
||||
|
||||
GeometryVertexType CircleGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
|
||||
@ -39,13 +39,6 @@ class CircleGeometry final : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
Point center_;
|
||||
Scalar radius_;
|
||||
Scalar stroke_width_;
|
||||
|
||||
@ -33,18 +33,6 @@ GeometryResult CoverGeometry::GetPositionBuffer(const ContentContext& renderer,
|
||||
};
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult CoverGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
auto rect = Rect::MakeSize(pass.GetRenderTargetSize());
|
||||
return ComputeUVGeometryForRect(rect, texture_coverage, effect_transform,
|
||||
renderer, entity, pass);
|
||||
}
|
||||
|
||||
GeometryVertexType CoverGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
|
||||
@ -34,13 +34,6 @@ class CoverGeometry final : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
CoverGeometry(const CoverGeometry&) = delete;
|
||||
|
||||
CoverGeometry& operator=(const CoverGeometry&) = delete;
|
||||
|
||||
@ -22,20 +22,6 @@ GeometryResult EllipseGeometry::GetPositionBuffer(
|
||||
entity, pass);
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult EllipseGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
return ComputePositionUVGeometry(
|
||||
renderer,
|
||||
renderer.GetTessellator()->FilledEllipse(entity.GetTransform(), bounds_),
|
||||
texture_coverage.GetNormalizingTransform() * effect_transform, entity,
|
||||
pass);
|
||||
}
|
||||
|
||||
GeometryVertexType EllipseGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
|
||||
@ -37,13 +37,6 @@ class EllipseGeometry final : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
Rect bounds_;
|
||||
|
||||
EllipseGeometry(const EllipseGeometry&) = delete;
|
||||
|
||||
@ -54,53 +54,6 @@ GeometryResult FillPathGeometry::GetPositionBuffer(
|
||||
};
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult FillPathGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = TextureFillVertexShader;
|
||||
|
||||
const auto& bounding_box = path_.GetBoundingBox();
|
||||
if (bounding_box.has_value() && bounding_box->IsEmpty()) {
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangle,
|
||||
.vertex_buffer =
|
||||
VertexBuffer{
|
||||
.vertex_buffer = {},
|
||||
.vertex_count = 0,
|
||||
.index_type = IndexType::k16bit,
|
||||
},
|
||||
.transform = pass.GetOrthographicTransform() * entity.GetTransform(),
|
||||
};
|
||||
}
|
||||
|
||||
auto uv_transform =
|
||||
texture_coverage.GetNormalizingTransform() * effect_transform;
|
||||
|
||||
auto points = renderer.GetTessellator()->TessellateConvex(
|
||||
path_, entity.GetTransform().GetMaxBasisLength());
|
||||
|
||||
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
|
||||
vertex_builder.Reserve(points.size());
|
||||
for (auto i = 0u; i < points.size(); i++) {
|
||||
VS::PerVertexData data;
|
||||
data.position = points[i];
|
||||
data.texture_coords = uv_transform * points[i];
|
||||
vertex_builder.AppendVertex(data);
|
||||
}
|
||||
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer =
|
||||
vertex_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()),
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
.mode = GetResultMode(),
|
||||
};
|
||||
}
|
||||
|
||||
GeometryResult::Mode FillPathGeometry::GetResultMode() const {
|
||||
const auto& bounding_box = path_.GetBoundingBox();
|
||||
if (path_.IsConvex() ||
|
||||
|
||||
@ -35,13 +35,6 @@ class FillPathGeometry final : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult::Mode GetResultMode() const override;
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "fml/status.h"
|
||||
#include "impeller/entity/contents/content_context.h"
|
||||
#include "impeller/entity/geometry/circle_geometry.h"
|
||||
#include "impeller/entity/geometry/cover_geometry.h"
|
||||
@ -54,120 +53,6 @@ GeometryResult Geometry::ComputePositionGeometry(
|
||||
};
|
||||
}
|
||||
|
||||
GeometryResult Geometry::ComputePositionUVGeometry(
|
||||
const ContentContext& renderer,
|
||||
const Tessellator::VertexGenerator& generator,
|
||||
const Matrix& uv_transform,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) {
|
||||
using VT = TextureFillVertexShader::PerVertexData;
|
||||
|
||||
size_t count = generator.GetVertexCount();
|
||||
|
||||
return GeometryResult{
|
||||
.type = generator.GetTriangleType(),
|
||||
.vertex_buffer =
|
||||
{
|
||||
.vertex_buffer = renderer.GetTransientsBuffer().Emplace(
|
||||
count * sizeof(VT), alignof(VT),
|
||||
[&generator, &uv_transform](uint8_t* buffer) {
|
||||
auto vertices = reinterpret_cast<VT*>(buffer);
|
||||
generator.GenerateVertices(
|
||||
[&vertices, &uv_transform](const Point& p) { //
|
||||
*vertices++ = {
|
||||
.position = p,
|
||||
.texture_coords = uv_transform * p,
|
||||
};
|
||||
});
|
||||
FML_DCHECK(vertices == reinterpret_cast<VT*>(buffer) +
|
||||
generator.GetVertexCount());
|
||||
}),
|
||||
.vertex_count = count,
|
||||
.index_type = IndexType::kNone,
|
||||
},
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
};
|
||||
}
|
||||
|
||||
VertexBufferBuilder<TextureFillVertexShader::PerVertexData>
|
||||
ComputeUVGeometryCPU(
|
||||
VertexBufferBuilder<SolidFillVertexShader::PerVertexData>& input,
|
||||
Point texture_origin,
|
||||
Size texture_coverage,
|
||||
Matrix effect_transform) {
|
||||
VertexBufferBuilder<TextureFillVertexShader::PerVertexData> vertex_builder;
|
||||
vertex_builder.Reserve(input.GetVertexCount());
|
||||
input.IterateVertices(
|
||||
[&vertex_builder, &texture_coverage, &effect_transform,
|
||||
&texture_origin](SolidFillVertexShader::PerVertexData old_vtx) {
|
||||
TextureFillVertexShader::PerVertexData data;
|
||||
data.position = old_vtx.position;
|
||||
data.texture_coords = effect_transform *
|
||||
(old_vtx.position - texture_origin) /
|
||||
texture_coverage;
|
||||
vertex_builder.AppendVertex(data);
|
||||
});
|
||||
return vertex_builder;
|
||||
}
|
||||
|
||||
GeometryResult ComputeUVGeometryForRect(Rect source_rect,
|
||||
Rect texture_bounds,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) {
|
||||
auto& host_buffer = renderer.GetTransientsBuffer();
|
||||
|
||||
// Calculate UV-specific transform based on texture coverage and effect.
|
||||
// For example, if the texture is 100x100 and the effect transform is
|
||||
// scaling by 2.0, texture_bounds.GetNormalizingTransform() will result in a
|
||||
// Matrix that scales by 0.01, and then if the effect_transform is
|
||||
// Matrix::MakeScale(Vector2{2, 2}), the resulting uv_transform will have x
|
||||
// and y basis vectors with scale 0.02.
|
||||
auto uv_transform = texture_bounds.GetNormalizingTransform() * //
|
||||
effect_transform;
|
||||
|
||||
// Allocate space for vertex and UV data (4 vertices)
|
||||
// 0: position
|
||||
// 1: UV
|
||||
// 2: position
|
||||
// 3: UV
|
||||
// etc.
|
||||
Point data[8];
|
||||
|
||||
// Get the raw points from the rect and transform them into UV space.
|
||||
auto points = source_rect.GetPoints();
|
||||
for (auto i = 0u, j = 0u; i < 8; i += 2, j++) {
|
||||
// Store original coordinates.
|
||||
data[i] = points[j];
|
||||
|
||||
// Store transformed UV coordinates.
|
||||
data[i + 1] = uv_transform * points[j];
|
||||
}
|
||||
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer =
|
||||
{
|
||||
.vertex_buffer = host_buffer.Emplace(
|
||||
/*buffer=*/data,
|
||||
/*length=*/16 * sizeof(float),
|
||||
/*align=*/alignof(float)),
|
||||
.vertex_count = 4,
|
||||
.index_type = IndexType::kNone,
|
||||
},
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
};
|
||||
}
|
||||
|
||||
GeometryResult Geometry::GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
GeometryResult::Mode Geometry::GetResultMode() const {
|
||||
return GeometryResult::Mode::kNormal;
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "impeller/core/vertex_buffer.h"
|
||||
#include "impeller/entity/contents/content_context.h"
|
||||
#include "impeller/entity/entity.h"
|
||||
#include "impeller/entity/texture_fill.vert.h"
|
||||
#include "impeller/renderer/render_pass.h"
|
||||
#include "impeller/renderer/vertex_buffer_builder.h"
|
||||
|
||||
@ -52,34 +51,6 @@ enum GeometryVertexType {
|
||||
kUV,
|
||||
};
|
||||
|
||||
/// @brief Compute UV geometry for a VBB that contains only position geometry.
|
||||
///
|
||||
/// texture_origin should be set to 0, 0 for stroke and stroke based geometry,
|
||||
/// like the point field.
|
||||
VertexBufferBuilder<TextureFillVertexShader::PerVertexData>
|
||||
ComputeUVGeometryCPU(
|
||||
VertexBufferBuilder<SolidFillVertexShader::PerVertexData>& input,
|
||||
Point texture_origin,
|
||||
Size texture_coverage,
|
||||
Matrix effect_transform);
|
||||
|
||||
/// @brief Computes geometry and UV coordinates for a rectangle to be rendered.
|
||||
///
|
||||
/// UV is the horizontal and vertical coordinates within the texture.
|
||||
///
|
||||
/// @param source_rect The rectangle to be rendered.
|
||||
/// @param texture_bounds The local space bounding box of the geometry.
|
||||
/// @param effect_transform The transform to apply to the UV coordinates.
|
||||
/// @param renderer The content context to use for allocating buffers.
|
||||
/// @param entity The entity to use for the transform.
|
||||
/// @param pass The render pass to use for the transform.
|
||||
GeometryResult ComputeUVGeometryForRect(Rect source_rect,
|
||||
Rect texture_bounds,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass);
|
||||
|
||||
class Geometry {
|
||||
public:
|
||||
static std::shared_ptr<Geometry> MakeFillPath(
|
||||
@ -122,12 +93,6 @@ class Geometry {
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const = 0;
|
||||
|
||||
virtual GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const = 0;
|
||||
|
||||
virtual GeometryResult::Mode GetResultMode() const;
|
||||
|
||||
virtual GeometryVertexType GetVertexType() const = 0;
|
||||
@ -156,13 +121,6 @@ class Geometry {
|
||||
const Tessellator::VertexGenerator& generator,
|
||||
const Entity& entity,
|
||||
RenderPass& pass);
|
||||
|
||||
static GeometryResult ComputePositionUVGeometry(
|
||||
const ContentContext& renderer,
|
||||
const Tessellator::VertexGenerator& generator,
|
||||
const Matrix& uv_transform,
|
||||
const Entity& entity,
|
||||
RenderPass& pass);
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -61,21 +61,6 @@ class ImpellerEntityUnitTestAccessor {
|
||||
return StrokePathGeometry::GenerateSolidStrokeVertices(
|
||||
polyline, stroke_width, miter_limit, stroke_join, stroke_cap, scale);
|
||||
}
|
||||
|
||||
static std::vector<TextureFillVertexShader::PerVertexData>
|
||||
GenerateSolidStrokeVerticesUV(const Path::Polyline& polyline,
|
||||
Scalar stroke_width,
|
||||
Scalar miter_limit,
|
||||
Join stroke_join,
|
||||
Cap stroke_cap,
|
||||
Scalar scale,
|
||||
Point texture_origin,
|
||||
Size texture_size,
|
||||
const Matrix& effect_transform) {
|
||||
return StrokePathGeometry::GenerateSolidStrokeVerticesUV(
|
||||
polyline, stroke_width, miter_limit, stroke_join, stroke_cap, scale,
|
||||
texture_origin, texture_size, effect_transform);
|
||||
}
|
||||
};
|
||||
|
||||
namespace testing {
|
||||
@ -142,95 +127,6 @@ TEST(EntityGeometryTest, RoundRectGeometryCoversArea) {
|
||||
EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 30, 99, 70)));
|
||||
}
|
||||
|
||||
TEST(EntityGeometryTest, StrokePathGeometryTransformOfLine) {
|
||||
auto path =
|
||||
PathBuilder().AddLine(Point(100, 100), Point(200, 100)).TakePath();
|
||||
auto points = std::make_unique<std::vector<Point>>();
|
||||
auto polyline =
|
||||
path.CreatePolyline(1.0f, std::move(points),
|
||||
[&points](Path::Polyline::PointBufferPtr reclaimed) {
|
||||
points = std::move(reclaimed);
|
||||
});
|
||||
|
||||
auto vertices = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
|
||||
polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0);
|
||||
|
||||
std::vector<SolidFillVertexShader::PerVertexData> expected = {
|
||||
{.position = Point(100.0f, 105.0f)}, //
|
||||
{.position = Point(100.0f, 95.0f)}, //
|
||||
{.position = Point(100.0f, 105.0f)}, //
|
||||
{.position = Point(100.0f, 95.0f)}, //
|
||||
{.position = Point(200.0f, 105.0f)}, //
|
||||
{.position = Point(200.0f, 95.0f)}, //
|
||||
{.position = Point(200.0f, 105.0f)}, //
|
||||
{.position = Point(200.0f, 95.0f)}, //
|
||||
};
|
||||
|
||||
EXPECT_SOLID_VERTICES_NEAR(vertices, expected);
|
||||
|
||||
{
|
||||
auto uv_vertices =
|
||||
ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV(
|
||||
polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0, //
|
||||
Point(50.0f, 40.0f), Size(20.0f, 40.0f), Matrix());
|
||||
// uvx = (x - 50) / 20
|
||||
// uvy = (y - 40) / 40
|
||||
auto uv = [](const Point& p) {
|
||||
return Point((p.x - 50.0f) / 20.0f, //
|
||||
(p.y - 40.0f) / 40.0f);
|
||||
};
|
||||
std::vector<TextureFillVertexShader::PerVertexData> uv_expected;
|
||||
for (size_t i = 0; i < expected.size(); i++) {
|
||||
auto p = expected[i].position;
|
||||
uv_expected.push_back({.position = p, .texture_coords = uv(p)});
|
||||
}
|
||||
|
||||
EXPECT_TEXTURE_VERTICES_NEAR(uv_vertices, uv_expected);
|
||||
}
|
||||
|
||||
{
|
||||
auto uv_vertices =
|
||||
ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV(
|
||||
polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0, //
|
||||
Point(50.0f, 40.0f), Size(20.0f, 40.0f),
|
||||
Matrix::MakeScale({8.0f, 4.0f, 1.0f}));
|
||||
// uvx = ((x * 8) - 50) / 20
|
||||
// uvy = ((y * 4) - 40) / 40
|
||||
auto uv = [](const Point& p) {
|
||||
return Point(((p.x * 8.0f) - 50.0f) / 20.0f,
|
||||
((p.y * 4.0f) - 40.0f) / 40.0f);
|
||||
};
|
||||
std::vector<TextureFillVertexShader::PerVertexData> uv_expected;
|
||||
for (size_t i = 0; i < expected.size(); i++) {
|
||||
auto p = expected[i].position;
|
||||
uv_expected.push_back({.position = p, .texture_coords = uv(p)});
|
||||
}
|
||||
|
||||
EXPECT_TEXTURE_VERTICES_NEAR(uv_vertices, uv_expected);
|
||||
}
|
||||
|
||||
{
|
||||
auto uv_vertices =
|
||||
ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV(
|
||||
polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0, //
|
||||
Point(50.0f, 40.0f), Size(20.0f, 40.0f),
|
||||
Matrix::MakeTranslation({8.0f, 4.0f}));
|
||||
// uvx = ((x + 8) - 50) / 20
|
||||
// uvy = ((y + 4) - 40) / 40
|
||||
auto uv = [](const Point& p) {
|
||||
return Point(((p.x + 8.0f) - 50.0f) / 20.0f,
|
||||
((p.y + 4.0f) - 40.0f) / 40.0f);
|
||||
};
|
||||
std::vector<TextureFillVertexShader::PerVertexData> uv_expected;
|
||||
for (size_t i = 0; i < expected.size(); i++) {
|
||||
auto p = expected[i].position;
|
||||
uv_expected.push_back({.position = p, .texture_coords = uv(p)});
|
||||
}
|
||||
|
||||
EXPECT_TEXTURE_VERTICES_NEAR(uv_vertices, uv_expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EntityGeometryTest, GeometryResultHasReasonableDefaults) {
|
||||
GeometryResult result;
|
||||
EXPECT_EQ(result.type, PrimitiveType::kTriangleStrip);
|
||||
|
||||
@ -108,58 +108,6 @@ GeometryResult LineGeometry::GetPositionBuffer(const ContentContext& renderer,
|
||||
};
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult LineGeometry::GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
auto& host_buffer = renderer.GetTransientsBuffer();
|
||||
using VT = TextureFillVertexShader::PerVertexData;
|
||||
|
||||
auto& transform = entity.GetTransform();
|
||||
auto radius = ComputePixelHalfWidth(transform, width_);
|
||||
|
||||
auto uv_transform =
|
||||
texture_coverage.GetNormalizingTransform() * effect_transform;
|
||||
|
||||
if (cap_ == Cap::kRound) {
|
||||
std::shared_ptr<Tessellator> tessellator = renderer.GetTessellator();
|
||||
auto generator = tessellator->RoundCapLine(transform, p0_, p1_, radius);
|
||||
return ComputePositionUVGeometry(renderer, generator, uv_transform, entity,
|
||||
pass);
|
||||
}
|
||||
|
||||
Point corners[4];
|
||||
if (!ComputeCorners(corners, transform, cap_ == Cap::kSquare)) {
|
||||
return kEmptyResult;
|
||||
}
|
||||
|
||||
size_t count = 4;
|
||||
BufferView vertex_buffer =
|
||||
host_buffer.Emplace(count * sizeof(VT), alignof(VT),
|
||||
[&uv_transform, &corners](uint8_t* buffer) {
|
||||
auto vertices = reinterpret_cast<VT*>(buffer);
|
||||
for (auto& corner : corners) {
|
||||
*vertices++ = {
|
||||
.position = corner,
|
||||
.texture_coords = uv_transform * corner,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer =
|
||||
{
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.vertex_count = count,
|
||||
.index_type = IndexType::kNone,
|
||||
},
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
};
|
||||
}
|
||||
|
||||
GeometryVertexType LineGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
|
||||
@ -57,13 +57,6 @@ class LineGeometry final : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
Point p0_;
|
||||
Point p1_;
|
||||
Scalar width_;
|
||||
|
||||
@ -34,33 +34,6 @@ GeometryResult PointFieldGeometry::GetPositionBuffer(
|
||||
};
|
||||
}
|
||||
|
||||
GeometryResult PointFieldGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
if (renderer.GetDeviceCapabilities().SupportsCompute()) {
|
||||
return GetPositionBufferGPU(renderer, entity, pass, texture_coverage,
|
||||
effect_transform);
|
||||
}
|
||||
|
||||
auto vtx_builder = GetPositionBufferCPU(renderer, entity, pass);
|
||||
if (!vtx_builder.has_value()) {
|
||||
return {};
|
||||
}
|
||||
auto uv_vtx_builder =
|
||||
ComputeUVGeometryCPU(vtx_builder.value(), {0, 0},
|
||||
texture_coverage.GetSize(), effect_transform);
|
||||
|
||||
auto& host_buffer = renderer.GetTransientsBuffer();
|
||||
return {
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer = uv_vtx_builder.CreateVertexBuffer(host_buffer),
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
};
|
||||
}
|
||||
|
||||
std::optional<VertexBufferBuilder<SolidFillVertexShader::PerVertexData>>
|
||||
PointFieldGeometry::GetPositionBufferCPU(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
@ -127,9 +100,7 @@ PointFieldGeometry::GetPositionBufferCPU(const ContentContext& renderer,
|
||||
GeometryResult PointFieldGeometry::GetPositionBufferGPU(
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass,
|
||||
std::optional<Rect> texture_coverage,
|
||||
std::optional<Matrix> effect_transform) const {
|
||||
RenderPass& pass) const {
|
||||
FML_DCHECK(renderer.GetDeviceCapabilities().SupportsCompute());
|
||||
if (radius_ < 0.0) {
|
||||
return {};
|
||||
@ -186,33 +157,6 @@ GeometryResult PointFieldGeometry::GetPositionBufferGPU(
|
||||
output = geometry_buffer;
|
||||
}
|
||||
|
||||
if (texture_coverage.has_value() && effect_transform.has_value()) {
|
||||
BufferView geometry_uv_buffer = host_buffer.Emplace(
|
||||
nullptr, total * sizeof(Vector4),
|
||||
std::max(DefaultUniformAlignment(), alignof(Vector4)));
|
||||
|
||||
using UV = UvComputeShader;
|
||||
|
||||
compute_pass->AddBufferMemoryBarrier();
|
||||
compute_pass->SetCommandLabel("UV Geometry");
|
||||
compute_pass->SetPipeline(renderer.GetUvComputePipeline());
|
||||
|
||||
UV::FrameInfo frame_info;
|
||||
frame_info.count = total;
|
||||
frame_info.effect_transform = effect_transform.value();
|
||||
frame_info.texture_origin = {0, 0};
|
||||
frame_info.texture_size = Vector2(texture_coverage.value().GetSize());
|
||||
|
||||
UV::BindFrameInfo(*compute_pass, host_buffer.EmplaceUniform(frame_info));
|
||||
UV::BindGeometryData(*compute_pass, geometry_buffer);
|
||||
UV::BindGeometryUVData(*compute_pass, geometry_uv_buffer);
|
||||
|
||||
if (!compute_pass->Compute(ISize(total, 1)).ok()) {
|
||||
return {};
|
||||
}
|
||||
output = geometry_uv_buffer;
|
||||
}
|
||||
|
||||
if (!compute_pass->EncodeCommands()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -23,25 +23,15 @@ class PointFieldGeometry final : public Geometry {
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryVertexType GetVertexType() const override;
|
||||
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
GeometryResult GetPositionBufferGPU(
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass,
|
||||
std::optional<Rect> texture_coverage = std::nullopt,
|
||||
std::optional<Matrix> effect_transform = std::nullopt) const;
|
||||
GeometryResult GetPositionBufferGPU(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
std::optional<VertexBufferBuilder<SolidFillVertexShader::PerVertexData>>
|
||||
GetPositionBufferCPU(const ContentContext& renderer,
|
||||
|
||||
@ -25,16 +25,6 @@ GeometryResult RectGeometry::GetPositionBuffer(const ContentContext& renderer,
|
||||
};
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult RectGeometry::GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
return ComputeUVGeometryForRect(rect_, texture_coverage, effect_transform,
|
||||
renderer, entity, pass);
|
||||
}
|
||||
|
||||
GeometryVertexType RectGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
|
||||
@ -32,13 +32,6 @@ class RectGeometry final : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
private:
|
||||
Rect rect_;
|
||||
|
||||
|
||||
@ -19,21 +19,6 @@ GeometryResult RoundRectGeometry::GetPositionBuffer(
|
||||
entity, pass);
|
||||
}
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult RoundRectGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
return ComputePositionUVGeometry(
|
||||
renderer,
|
||||
renderer.GetTessellator()->FilledRoundRect(entity.GetTransform(), bounds_,
|
||||
radii_),
|
||||
texture_coverage.GetNormalizingTransform() * effect_transform, entity,
|
||||
pass);
|
||||
}
|
||||
|
||||
GeometryVertexType RoundRectGeometry::GetVertexType() const {
|
||||
return GeometryVertexType::kPosition;
|
||||
}
|
||||
|
||||
@ -37,13 +37,6 @@ class RoundRectGeometry final : public Geometry {
|
||||
// |Geometry|
|
||||
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
const Rect bounds_;
|
||||
const Size radii_;
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include "impeller/core/buffer_view.h"
|
||||
#include "impeller/core/formats.h"
|
||||
#include "impeller/entity/geometry/geometry.h"
|
||||
#include "impeller/entity/texture_fill.vert.h"
|
||||
#include "impeller/geometry/path_builder.h"
|
||||
#include "impeller/geometry/path_component.h"
|
||||
|
||||
@ -45,49 +44,6 @@ class PositionWriter {
|
||||
std::vector<SolidFillVertexShader::PerVertexData> data_ = {};
|
||||
};
|
||||
|
||||
class PositionUVWriter {
|
||||
public:
|
||||
PositionUVWriter(const Point& texture_origin,
|
||||
const Size& texture_size,
|
||||
const Matrix& effect_transform)
|
||||
: texture_origin_(texture_origin),
|
||||
texture_size_(texture_size),
|
||||
effect_transform_(effect_transform) {}
|
||||
|
||||
const std::vector<TextureFillVertexShader::PerVertexData>& GetData() {
|
||||
if (effect_transform_.IsIdentity()) {
|
||||
auto origin = texture_origin_;
|
||||
auto scale = 1.0 / texture_size_;
|
||||
|
||||
for (auto& pvd : data_) {
|
||||
pvd.texture_coords = (pvd.position - origin) * scale;
|
||||
}
|
||||
} else {
|
||||
auto texture_rect = Rect::MakeOriginSize(texture_origin_, texture_size_);
|
||||
Matrix uv_transform =
|
||||
texture_rect.GetNormalizingTransform() * effect_transform_;
|
||||
|
||||
for (auto& pvd : data_) {
|
||||
pvd.texture_coords = uv_transform * pvd.position;
|
||||
}
|
||||
}
|
||||
return data_;
|
||||
}
|
||||
|
||||
void AppendVertex(const Point& point) {
|
||||
data_.emplace_back(TextureFillVertexShader::PerVertexData{
|
||||
.position = point,
|
||||
// .texture_coords = default, will be filled in during |GetData()|
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<TextureFillVertexShader::PerVertexData> data_ = {};
|
||||
const Point texture_origin_;
|
||||
const Size texture_size_;
|
||||
const Matrix effect_transform_;
|
||||
};
|
||||
|
||||
template <typename VertexWriter>
|
||||
class StrokeGenerator {
|
||||
public:
|
||||
@ -525,27 +481,6 @@ StrokePathGeometry::GenerateSolidStrokeVertices(const Path::Polyline& polyline,
|
||||
return vtx_builder.GetData();
|
||||
}
|
||||
|
||||
std::vector<TextureFillVertexShader::PerVertexData>
|
||||
StrokePathGeometry::GenerateSolidStrokeVerticesUV(
|
||||
const Path::Polyline& polyline,
|
||||
Scalar stroke_width,
|
||||
Scalar miter_limit,
|
||||
Join stroke_join,
|
||||
Cap stroke_cap,
|
||||
Scalar scale,
|
||||
Point texture_origin,
|
||||
Size texture_size,
|
||||
const Matrix& effect_transform) {
|
||||
auto scaled_miter_limit = stroke_width * miter_limit * 0.5f;
|
||||
auto join_proc = GetJoinProc<PositionUVWriter>(stroke_join);
|
||||
auto cap_proc = GetCapProc<PositionUVWriter>(stroke_cap);
|
||||
StrokeGenerator stroke_generator(polyline, stroke_width, scaled_miter_limit,
|
||||
join_proc, cap_proc, scale);
|
||||
PositionUVWriter vtx_builder(texture_origin, texture_size, effect_transform);
|
||||
stroke_generator.Generate(vtx_builder);
|
||||
return vtx_builder.GetData();
|
||||
}
|
||||
|
||||
StrokePathGeometry::StrokePathGeometry(const Path& path,
|
||||
Scalar stroke_width,
|
||||
Scalar miter_limit,
|
||||
@ -619,52 +554,6 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
|
||||
};
|
||||
}
|
||||
|
||||
GeometryResult StrokePathGeometry::GetPositionUVBuffer(
|
||||
Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
if (stroke_width_ < 0.0) {
|
||||
return {};
|
||||
}
|
||||
auto determinant = entity.GetTransform().GetDeterminant();
|
||||
if (determinant == 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
|
||||
Scalar stroke_width = std::max(stroke_width_, min_size);
|
||||
|
||||
auto& host_buffer = renderer.GetTransientsBuffer();
|
||||
auto scale = entity.GetTransform().GetMaxBasisLength();
|
||||
auto polyline = renderer.GetTessellator()->CreateTempPolyline(path_, scale);
|
||||
|
||||
PositionUVWriter writer(Point{0, 0}, texture_coverage.GetSize(),
|
||||
effect_transform);
|
||||
CreateSolidStrokeVertices(writer, polyline, stroke_width,
|
||||
miter_limit_ * stroke_width_ * 0.5f,
|
||||
GetJoinProc<PositionUVWriter>(stroke_join_),
|
||||
GetCapProc<PositionUVWriter>(stroke_cap_), scale);
|
||||
|
||||
BufferView buffer_view = host_buffer.Emplace(
|
||||
writer.GetData().data(),
|
||||
writer.GetData().size() * sizeof(TextureFillVertexShader::PerVertexData),
|
||||
alignof(TextureFillVertexShader::PerVertexData));
|
||||
|
||||
return GeometryResult{
|
||||
.type = PrimitiveType::kTriangleStrip,
|
||||
.vertex_buffer =
|
||||
{
|
||||
.vertex_buffer = buffer_view,
|
||||
.vertex_count = writer.GetData().size(),
|
||||
.index_type = IndexType::kNone,
|
||||
},
|
||||
.transform = entity.GetShaderTransform(pass),
|
||||
.mode = GeometryResult::Mode::kPreventOverdraw,
|
||||
};
|
||||
}
|
||||
|
||||
GeometryResult::Mode StrokePathGeometry::GetResultMode() const {
|
||||
return GeometryResult::Mode::kPreventOverdraw;
|
||||
}
|
||||
|
||||
@ -34,13 +34,6 @@ class StrokePathGeometry final : public Geometry {
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult::Mode GetResultMode() const override;
|
||||
|
||||
@ -59,17 +52,6 @@ class StrokePathGeometry final : public Geometry {
|
||||
Cap stroke_cap,
|
||||
Scalar scale);
|
||||
|
||||
static std::vector<TextureFillVertexShader::PerVertexData>
|
||||
GenerateSolidStrokeVerticesUV(const Path::Polyline& polyline,
|
||||
Scalar stroke_width,
|
||||
Scalar miter_limit,
|
||||
Join stroke_join,
|
||||
Cap stroke_cap,
|
||||
Scalar scale,
|
||||
Point texture_origin,
|
||||
Size texture_size,
|
||||
const Matrix& effect_transform);
|
||||
|
||||
friend class ImpellerBenchmarkAccessor;
|
||||
friend class ImpellerEntityUnitTestAccessor;
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
#include "impeller/core/buffer_view.h"
|
||||
#include "impeller/entity/contents/content_context.h"
|
||||
#include "impeller/geometry/color.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
|
||||
@ -37,12 +37,11 @@ class VerticesGeometry final : public Geometry {
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
|
||||
Matrix effect_transform,
|
||||
const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const override;
|
||||
RenderPass& pass) const;
|
||||
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionBuffer(const ContentContext& renderer,
|
||||
|
||||
@ -3,12 +3,17 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <impeller/blending.glsl>
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
#include "blend_select.glsl"
|
||||
|
||||
layout(constant_id = 0) const float supports_decal = 1.0;
|
||||
|
||||
uniform FragInfo {
|
||||
float16_t alpha;
|
||||
float16_t blend_mode;
|
||||
float tmx;
|
||||
float tmy;
|
||||
}
|
||||
frag_info;
|
||||
|
||||
@ -19,13 +24,24 @@ in mediump f16vec4 v_color;
|
||||
|
||||
out f16vec4 frag_color;
|
||||
|
||||
f16vec4 Sample(f16sampler2D texture_sampler,
|
||||
vec2 texture_coords,
|
||||
float tmx,
|
||||
float tmy) {
|
||||
if (supports_decal > 0.0) {
|
||||
return texture(texture_sampler, texture_coords);
|
||||
}
|
||||
return IPHalfSampleWithTileMode(texture_sampler, texture_coords, tmx, tmy);
|
||||
}
|
||||
|
||||
// A shader that implements the required src/dst blending for drawVertices and
|
||||
// drawAtlas advanced blends without requiring an offscreen render pass. This is
|
||||
// done in a single shader to reduce the permutations of PSO needed at runtime
|
||||
// for rarely used features.
|
||||
void main() {
|
||||
f16vec4 dst = IPHalfUnpremultiply(v_color);
|
||||
f16vec4 src = IPHalfUnpremultiply(texture(texture_sampler, v_texture_coords));
|
||||
f16vec4 src = IPHalfUnpremultiply(
|
||||
Sample(texture_sampler, v_texture_coords, frag_info.tmx, frag_info.tmy));
|
||||
f16vec3 blend_result =
|
||||
AdvancedBlend(dst.rgb, src.rgb, int(frag_info.blend_mode - 14.0));
|
||||
frag_color = IPApplyBlendedColor(dst, src, blend_result);
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
// Unused, see See PointFieldGeometry::GetPositionBuffer
|
||||
layout(local_size_x = 16) in;
|
||||
|
||||
layout(std430) readonly buffer GeometryData {
|
||||
// Size of this input data is frame_info.count;
|
||||
vec2 points[];
|
||||
}
|
||||
geometry_data;
|
||||
|
||||
layout(std430) writeonly buffer GeometryUVData {
|
||||
// Size of this output data is frame_info.count;
|
||||
// x,y is the original geometry.
|
||||
// u,v is the texture UV.
|
||||
vec4 points_uv[];
|
||||
}
|
||||
geometry_uv_data;
|
||||
|
||||
uniform FrameInfo {
|
||||
uint count;
|
||||
mat4 effect_transform;
|
||||
vec2 texture_origin;
|
||||
vec2 texture_size;
|
||||
}
|
||||
frame_info;
|
||||
|
||||
vec2 project_point(mat4 m, vec2 v) {
|
||||
float w = v.x * m[0][3] + v.y * m[1][3] + m[3][3];
|
||||
vec2 result = vec2(v.x * m[0][0] + v.y * m[1][0] + m[3][0],
|
||||
v.x * m[0][1] + v.y * m[1][1] + m[3][1]);
|
||||
|
||||
// This is Skia's behavior, but it may be reasonable to allow UB for the w=0
|
||||
// case.
|
||||
if (w != 0) {
|
||||
w = 1 / w;
|
||||
}
|
||||
return result * w;
|
||||
}
|
||||
|
||||
void main() {
|
||||
uint ident = gl_GlobalInvocationID.x;
|
||||
if (ident >= frame_info.count) {
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 point = geometry_data.points[ident];
|
||||
|
||||
vec2 coverage_coords =
|
||||
(point - frame_info.texture_origin) / frame_info.texture_size;
|
||||
vec2 texture_coords =
|
||||
project_point(frame_info.effect_transform, coverage_coords);
|
||||
|
||||
geometry_uv_data.points_uv[ident] = vec4(point, texture_coords);
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <impeller/conversions.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
// A shader that computes texture UVs from a normalizing transform.
|
||||
uniform FrameInfo {
|
||||
mat4 mvp;
|
||||
// A normlizing transform created from the texture bounds and effect transform
|
||||
mat4 uv_transform;
|
||||
float texture_sampler_y_coord_scale;
|
||||
}
|
||||
frame_info;
|
||||
|
||||
in vec2 position;
|
||||
|
||||
out vec2 v_texture_coords;
|
||||
|
||||
void main() {
|
||||
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
|
||||
vec2 texture_coords = (frame_info.uv_transform * vec4(position, 0.0, 1.0)).xy;
|
||||
v_texture_coords =
|
||||
IPRemapCoords(texture_coords, frame_info.texture_sampler_y_coord_scale);
|
||||
}
|
||||
@ -7,6 +7,8 @@ precision mediump float;
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
layout(constant_id = 0) const float supports_decal = 1.0;
|
||||
|
||||
uniform f16sampler2D texture_sampler;
|
||||
|
||||
uniform FragInfo {
|
||||
@ -21,11 +23,18 @@ in highp vec2 v_texture_coords;
|
||||
out f16vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
frag_color =
|
||||
IPHalfSampleWithTileMode(texture_sampler, // sampler
|
||||
v_texture_coords, // texture coordinates
|
||||
float16_t(frag_info.x_tile_mode), // x tile mode
|
||||
float16_t(frag_info.y_tile_mode) // y tile mode
|
||||
) *
|
||||
float16_t(frag_info.alpha);
|
||||
if (supports_decal == 1.0) {
|
||||
frag_color = texture(texture_sampler, // sampler
|
||||
v_texture_coords, // texture coordinates
|
||||
float16_t(kDefaultMipBias)) *
|
||||
float16_t(frag_info.alpha);
|
||||
} else {
|
||||
frag_color = IPHalfSampleWithTileMode(
|
||||
texture_sampler, // sampler
|
||||
v_texture_coords, // texture coordinates
|
||||
float16_t(frag_info.x_tile_mode), // x tile mode
|
||||
float16_t(frag_info.y_tile_mode) // y tile mode
|
||||
) *
|
||||
float16_t(frag_info.alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#include "flutter/benchmarking/benchmarking.h"
|
||||
|
||||
#include "flutter/impeller/entity/solid_fill.vert.h"
|
||||
#include "flutter/impeller/entity/texture_fill.vert.h"
|
||||
|
||||
#include "impeller/entity/geometry/stroke_path_geometry.h"
|
||||
#include "impeller/geometry/path.h"
|
||||
@ -26,21 +25,6 @@ class ImpellerBenchmarkAccessor {
|
||||
return StrokePathGeometry::GenerateSolidStrokeVertices(
|
||||
polyline, stroke_width, miter_limit, stroke_join, stroke_cap, scale);
|
||||
}
|
||||
|
||||
static std::vector<TextureFillVertexShader::PerVertexData>
|
||||
GenerateSolidStrokeVerticesUV(const Path::Polyline& polyline,
|
||||
Scalar stroke_width,
|
||||
Scalar miter_limit,
|
||||
Join stroke_join,
|
||||
Cap stroke_cap,
|
||||
Scalar scale,
|
||||
Point texture_origin,
|
||||
Size texture_size,
|
||||
const Matrix& effect_transform) {
|
||||
return StrokePathGeometry::GenerateSolidStrokeVerticesUV(
|
||||
polyline, stroke_width, miter_limit, stroke_join, stroke_cap, scale,
|
||||
texture_origin, texture_size, effect_transform);
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
@ -97,28 +81,16 @@ static void BM_Polyline(benchmark::State& state, Args&&... args) {
|
||||
state.counters["TotalPointCount"] = point_count;
|
||||
}
|
||||
|
||||
enum class UVMode {
|
||||
kNoUV,
|
||||
kUVRect,
|
||||
kUVRectTx,
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
static void BM_StrokePolyline(benchmark::State& state, Args&&... args) {
|
||||
auto args_tuple = std::make_tuple(std::move(args)...);
|
||||
auto path = std::get<Path>(args_tuple);
|
||||
auto cap = std::get<Cap>(args_tuple);
|
||||
auto join = std::get<Join>(args_tuple);
|
||||
auto generate_uv = std::get<UVMode>(args_tuple);
|
||||
|
||||
const Scalar stroke_width = 5.0f;
|
||||
const Scalar miter_limit = 10.0f;
|
||||
const Scalar scale = 1.0f;
|
||||
const Point texture_origin = Point(0, 0);
|
||||
const Size texture_size = Size(100, 100);
|
||||
const Matrix effect_transform = (generate_uv == UVMode::kUVRectTx)
|
||||
? Matrix::MakeScale({2.0f, 2.0f, 1.0f})
|
||||
: Matrix();
|
||||
|
||||
auto points = std::make_unique<std::vector<Point>>();
|
||||
points->reserve(2048);
|
||||
@ -131,16 +103,9 @@ static void BM_StrokePolyline(benchmark::State& state, Args&&... args) {
|
||||
size_t point_count = 0u;
|
||||
size_t single_point_count = 0u;
|
||||
while (state.KeepRunning()) {
|
||||
if (generate_uv == UVMode::kNoUV) {
|
||||
auto vertices = ImpellerBenchmarkAccessor::GenerateSolidStrokeVertices(
|
||||
polyline, stroke_width, miter_limit, join, cap, scale);
|
||||
single_point_count = vertices.size();
|
||||
} else {
|
||||
auto vertices = ImpellerBenchmarkAccessor::GenerateSolidStrokeVerticesUV(
|
||||
polyline, stroke_width, miter_limit, join, cap, scale, //
|
||||
texture_origin, texture_size, effect_transform);
|
||||
single_point_count = vertices.size();
|
||||
}
|
||||
auto vertices = ImpellerBenchmarkAccessor::GenerateSolidStrokeVertices(
|
||||
polyline, stroke_width, miter_limit, join, cap, scale);
|
||||
single_point_count = vertices.size();
|
||||
point_count += single_point_count;
|
||||
}
|
||||
state.counters["SinglePointCount"] = single_point_count;
|
||||
@ -167,7 +132,7 @@ static void BM_Convex(benchmark::State& state, Args&&... args) {
|
||||
|
||||
#define MAKE_STROKE_BENCHMARK_CAPTURE(path, cap, join, closed, uvname, uvtype) \
|
||||
BENCHMARK_CAPTURE(BM_StrokePolyline, stroke_##path##_##cap##_##join##uvname, \
|
||||
Create##path(closed), Cap::k##cap, Join::k##join, uvtype)
|
||||
Create##path(closed), Cap::k##cap, Join::k##join)
|
||||
|
||||
#define MAKE_STROKE_BENCHMARK_CAPTURE_CAPS_JOINS(path, uvname, uvtype) \
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE(path, Butt, Bevel, false, uvname, uvtype); \
|
||||
@ -176,22 +141,12 @@ static void BM_Convex(benchmark::State& state, Args&&... args) {
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE(path, Square, Bevel, false, uvname, uvtype); \
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE(path, Round, Bevel, false, uvname, uvtype)
|
||||
|
||||
#define MAKE_STROKE_BENCHMARK_CAPTURE_UVS(path) \
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE_CAPS_JOINS(path, , UVMode::kNoUV); \
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE_CAPS_JOINS(path, _uv, UVMode::kUVRectTx); \
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE_CAPS_JOINS(path, _uvNoTx, UVMode::kUVRect)
|
||||
|
||||
BENCHMARK_CAPTURE(BM_Polyline, cubic_polyline, CreateCubic(true), false);
|
||||
BENCHMARK_CAPTURE(BM_Polyline, cubic_polyline_tess, CreateCubic(true), true);
|
||||
BENCHMARK_CAPTURE(BM_Polyline,
|
||||
unclosed_cubic_polyline,
|
||||
CreateCubic(false),
|
||||
false);
|
||||
BENCHMARK_CAPTURE(BM_Polyline,
|
||||
unclosed_cubic_polyline_tess,
|
||||
CreateCubic(false),
|
||||
true);
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE_UVS(Cubic);
|
||||
|
||||
BENCHMARK_CAPTURE(BM_Polyline, quad_polyline, CreateQuadratic(true), false);
|
||||
BENCHMARK_CAPTURE(BM_Polyline, quad_polyline_tess, CreateQuadratic(true), true);
|
||||
@ -199,16 +154,9 @@ BENCHMARK_CAPTURE(BM_Polyline,
|
||||
unclosed_quad_polyline,
|
||||
CreateQuadratic(false),
|
||||
false);
|
||||
BENCHMARK_CAPTURE(BM_Polyline,
|
||||
unclosed_quad_polyline_tess,
|
||||
CreateQuadratic(false),
|
||||
true);
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE_UVS(Quadratic);
|
||||
|
||||
BENCHMARK_CAPTURE(BM_Convex, rrect_convex, CreateRRect(), true);
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE(RRect, Butt, Bevel, , , UVMode::kNoUV);
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE(RRect, Butt, Bevel, , _uv, UVMode::kUVRectTx);
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE(RRect, Butt, Bevel, , _uvNoTx, UVMode::kUVRect);
|
||||
MAKE_STROKE_BENCHMARK_CAPTURE(RRect, Butt, Bevel, , , );
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
@ -5710,12 +5710,169 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/texture_uv_fill.vert.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/gles/texture_uv_fill.vert.gles",
|
||||
"has_uniform_computation": true,
|
||||
"type": "Vertex",
|
||||
"variants": {
|
||||
"Position": {
|
||||
"fp16_arithmetic": 0,
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.140625,
|
||||
0.140625,
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
0.0
|
||||
],
|
||||
"pipelines": [
|
||||
"arith_total",
|
||||
"arith_fma",
|
||||
"arith_cvt",
|
||||
"arith_sfu",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.140625,
|
||||
0.140625,
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.140625,
|
||||
0.140625,
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 28,
|
||||
"work_registers_used": 32
|
||||
},
|
||||
"Varying": {
|
||||
"fp16_arithmetic": 0,
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.078125,
|
||||
0.078125,
|
||||
0.015625,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
"pipelines": [
|
||||
"arith_total",
|
||||
"arith_fma",
|
||||
"arith_cvt",
|
||||
"arith_sfu",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.078125,
|
||||
0.078125,
|
||||
0.015625,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.078125,
|
||||
0.078125,
|
||||
0.015625,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 16,
|
||||
"work_registers_used": 9
|
||||
}
|
||||
}
|
||||
},
|
||||
"Mali-T880": {
|
||||
"core": "Mali-T880",
|
||||
"filename": "flutter/impeller/entity/gles/texture_uv_fill.vert.gles",
|
||||
"has_uniform_computation": false,
|
||||
"type": "Vertex",
|
||||
"variants": {
|
||||
"Main": {
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
3.299999952316284,
|
||||
4.0,
|
||||
0.0
|
||||
],
|
||||
"pipelines": [
|
||||
"arithmetic",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
3.299999952316284,
|
||||
4.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
3.3333332538604736,
|
||||
4.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 7,
|
||||
"work_registers_used": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/tiled_texture_fill.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/gles/tiled_texture_fill.frag.gles",
|
||||
"has_side_effects": false,
|
||||
"has_uniform_computation": true,
|
||||
"has_uniform_computation": false,
|
||||
"modifies_coverage": false,
|
||||
"reads_color_buffer": false,
|
||||
"type": "Fragment",
|
||||
@ -5723,17 +5880,17 @@
|
||||
"uses_late_zs_update": false,
|
||||
"variants": {
|
||||
"Main": {
|
||||
"fp16_arithmetic": 33,
|
||||
"fp16_arithmetic": 100,
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"arith_total",
|
||||
"arith_cvt"
|
||||
"varying",
|
||||
"texture"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.265625,
|
||||
0.046875,
|
||||
0.03125,
|
||||
0.265625,
|
||||
0.046875,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
@ -5753,22 +5910,22 @@
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.0625,
|
||||
0.03125,
|
||||
0.0625,
|
||||
0.03125,
|
||||
0.015625,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
0.25
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arith_total",
|
||||
"arith_cvt"
|
||||
"varying",
|
||||
"texture"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.265625,
|
||||
0.046875,
|
||||
0.03125,
|
||||
0.265625,
|
||||
0.046875,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
@ -5792,10 +5949,12 @@
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"arithmetic"
|
||||
"arithmetic",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
3.299999952316284,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
@ -5805,18 +5964,21 @@
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"arithmetic"
|
||||
"arithmetic",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
1.3200000524520874,
|
||||
1.0,
|
||||
0.0
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arithmetic"
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"total_cycles": [
|
||||
3.6666667461395264,
|
||||
0.6666666865348816,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
@ -6085,7 +6247,7 @@
|
||||
"longest_path_cycles": [
|
||||
1.2625000476837158,
|
||||
1.2625000476837158,
|
||||
0.699999988079071,
|
||||
0.675000011920929,
|
||||
0.3125,
|
||||
0.0,
|
||||
0.5,
|
||||
@ -6104,10 +6266,10 @@
|
||||
"varying"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.390625,
|
||||
0.421875,
|
||||
0.421875,
|
||||
0.375,
|
||||
0.390625,
|
||||
0.0,
|
||||
0.0625,
|
||||
0.0,
|
||||
0.5,
|
||||
0.25
|
||||
@ -6119,7 +6281,7 @@
|
||||
"total_cycles": [
|
||||
3.862499952316284,
|
||||
3.862499952316284,
|
||||
2.825000047683716,
|
||||
2.799999952316284,
|
||||
0.9375,
|
||||
0.0,
|
||||
0.5,
|
||||
@ -8925,6 +9087,118 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/texture_uv_fill.vert.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/texture_uv_fill.vert.vkspv",
|
||||
"has_uniform_computation": true,
|
||||
"type": "Vertex",
|
||||
"variants": {
|
||||
"Position": {
|
||||
"fp16_arithmetic": 0,
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
0.0
|
||||
],
|
||||
"pipelines": [
|
||||
"arith_total",
|
||||
"arith_fma",
|
||||
"arith_cvt",
|
||||
"arith_sfu",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.125,
|
||||
0.125,
|
||||
0.0,
|
||||
0.0,
|
||||
2.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 40,
|
||||
"work_registers_used": 32
|
||||
},
|
||||
"Varying": {
|
||||
"fp16_arithmetic": 0,
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.078125,
|
||||
0.078125,
|
||||
0.015625,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
"pipelines": [
|
||||
"arith_total",
|
||||
"arith_fma",
|
||||
"arith_cvt",
|
||||
"arith_sfu",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.078125,
|
||||
0.078125,
|
||||
0.015625,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.078125,
|
||||
0.078125,
|
||||
0.015625,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 32,
|
||||
"work_registers_used": 9
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/tiled_texture_fill.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -8938,20 +9212,18 @@
|
||||
"uses_late_zs_update": false,
|
||||
"variants": {
|
||||
"Main": {
|
||||
"fp16_arithmetic": 33,
|
||||
"fp16_arithmetic": 100,
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"arith_total",
|
||||
"arith_cvt",
|
||||
"varying",
|
||||
"texture"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.25,
|
||||
0.03125,
|
||||
0.25,
|
||||
0.0625,
|
||||
0.03125,
|
||||
0.015625,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
0.25
|
||||
@ -8966,28 +9238,27 @@
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"varying"
|
||||
"varying",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.140625,
|
||||
0.03125,
|
||||
0.140625,
|
||||
0.0625,
|
||||
0.03125,
|
||||
0.015625,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
0.25
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arith_total",
|
||||
"arith_cvt",
|
||||
"varying",
|
||||
"texture"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.25,
|
||||
0.03125,
|
||||
0.25,
|
||||
0.0625,
|
||||
0.03125,
|
||||
0.015625,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
0.25
|
||||
@ -8996,7 +9267,7 @@
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 4,
|
||||
"work_registers_used": 7
|
||||
"work_registers_used": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9073,69 +9344,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/uv.comp.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/uv.comp.vkspv",
|
||||
"has_uniform_computation": true,
|
||||
"type": "Compute",
|
||||
"variants": {
|
||||
"Main": {
|
||||
"fp16_arithmetic": 0,
|
||||
"has_stack_spilling": false,
|
||||
"performance": {
|
||||
"longest_path_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.1875,
|
||||
0.1875,
|
||||
0.125,
|
||||
0.0625,
|
||||
2.0,
|
||||
0.0
|
||||
],
|
||||
"pipelines": [
|
||||
"arith_total",
|
||||
"arith_fma",
|
||||
"arith_cvt",
|
||||
"arith_sfu",
|
||||
"load_store",
|
||||
"texture"
|
||||
],
|
||||
"shortest_path_bound_pipelines": [
|
||||
"arith_total",
|
||||
"arith_cvt"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.046875,
|
||||
0.0,
|
||||
0.046875,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.1875,
|
||||
0.1875,
|
||||
0.125,
|
||||
0.0625,
|
||||
2.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"shared_storage_used": 0,
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 24,
|
||||
"work_registers_used": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/vertices.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user