Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,8 @@ ORIGIN: ../../../flutter/impeller/geometry/constants.h + ../../../flutter/LICENS
ORIGIN: ../../../flutter/impeller/geometry/geometry_benchmarks.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/gradient.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/gradient.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/half.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/half.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/matrix.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/matrix.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/matrix_decomposition.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3828,6 +3830,8 @@ FILE: ../../../flutter/impeller/geometry/constants.h
FILE: ../../../flutter/impeller/geometry/geometry_benchmarks.cc
FILE: ../../../flutter/impeller/geometry/gradient.cc
FILE: ../../../flutter/impeller/geometry/gradient.h
FILE: ../../../flutter/impeller/geometry/half.cc
FILE: ../../../flutter/impeller/geometry/half.h
FILE: ../../../flutter/impeller/geometry/matrix.cc
FILE: ../../../flutter/impeller/geometry/matrix.h
FILE: ../../../flutter/impeller/geometry/matrix_decomposition.cc
Expand Down
16 changes: 16 additions & 0 deletions impeller/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,22 @@ Compiler::Compiler(const fml::Mapping& source_mapping,
switch (source_options.target_platform) {
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kMetalIOS:
spirv_options.SetOptimizationLevel(
shaderc_optimization_level::shaderc_optimization_level_performance);
if (source_options.use_half_textures) {
spirv_options.SetTargetEnvironment(
shaderc_target_env::shaderc_target_env_opengl,
shaderc_env_version::shaderc_env_version_opengl_4_5);
spirv_options.SetTargetSpirv(
shaderc_spirv_version::shaderc_spirv_version_1_0);
} else {
spirv_options.SetTargetEnvironment(
shaderc_target_env::shaderc_target_env_vulkan,
shaderc_env_version::shaderc_env_version_vulkan_1_1);
spirv_options.SetTargetSpirv(
shaderc_spirv_version::shaderc_spirv_version_1_3);
}
break;
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
spirv_options.SetOptimizationLevel(
Expand Down
1 change: 1 addition & 0 deletions impeller/compiler/impellerc_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bool Main(const fml::CommandLine& command_line) {
options.json_format = switches.json_format;
options.gles_language_version = switches.gles_language_version;
options.metal_version = switches.metal_version;
options.use_half_textures = switches.use_half_textures;

Reflector::Options reflector_options;
reflector_options.target_platform = switches.target_platform;
Expand Down
75 changes: 75 additions & 0 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "impeller/compiler/code_gen_template.h"
#include "impeller/compiler/uniform_sorter.h"
#include "impeller/compiler/utilities.h"
#include "impeller/geometry/half.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/scalar.h"

Expand Down Expand Up @@ -534,6 +535,11 @@ static std::optional<KnownType> ReadKnownScalarType(
.name = "Scalar",
.byte_size = sizeof(Scalar),
};
case spirv_cross::SPIRType::BaseType::Half:
return KnownType{
.name = "Half",
.byte_size = sizeof(Half),
};
case spirv_cross::SPIRType::BaseType::UInt:
return KnownType{
.name = "uint32_t",
Expand Down Expand Up @@ -767,6 +773,75 @@ std::vector<StructMember> Reflector::ReadStructMembers(
continue;
}

// Tightly packed half Point (vec2).
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
member.width == sizeof(float) * 4 && //
member.columns == 1 && //
member.vecsize == 2 //
) {
uint32_t stride =
GetArrayStride<sizeof(HalfVector2)>(struct_type, member, i);
uint32_t element_padding = stride - sizeof(HalfVector2);
result.emplace_back(StructMember{
"HalfVector2", // type
BaseTypeToString(member.basetype), // basetype
GetMemberNameAtIndex(struct_type, i), // name
struct_member_offset, // offset
sizeof(HalfVector2), // size
stride * array_elements.value_or(1), // byte_length
array_elements, // array_elements
element_padding, // element_padding
});
current_byte_offset += stride * array_elements.value_or(1);
continue;
}

// Tightly packed Half Float Vector3.
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
member.width == sizeof(float) * 4 && //
member.columns == 1 && //
member.vecsize == 3 //
) {
uint32_t stride =
GetArrayStride<sizeof(HalfVector3)>(struct_type, member, i);
uint32_t element_padding = stride - sizeof(HalfVector3);
result.emplace_back(StructMember{
"HalfVector3", // type
BaseTypeToString(member.basetype), // basetype
GetMemberNameAtIndex(struct_type, i), // name
struct_member_offset, // offset
sizeof(HalfVector3), // size
stride * array_elements.value_or(1), // byte_length
array_elements, // array_elements
element_padding, // element_padding
});
current_byte_offset += stride * array_elements.value_or(1);
continue;
}

// Tightly packed Half Float Vector4.
if (member.basetype == spirv_cross::SPIRType::BaseType::Half && //
member.width == sizeof(float) * 4 && //
member.columns == 1 && //
member.vecsize == 4 //
) {
uint32_t stride =
GetArrayStride<sizeof(HalfVector4)>(struct_type, member, i);
uint32_t element_padding = stride - sizeof(HalfVector4);
result.emplace_back(StructMember{
"HalfVector4", // type
BaseTypeToString(member.basetype), // basetype
GetMemberNameAtIndex(struct_type, i), // name
struct_member_offset, // offset
sizeof(HalfVector4), // size
stride * array_elements.value_or(1), // byte_length
array_elements, // array_elements
element_padding, // element_padding
});
current_byte_offset += stride * array_elements.value_or(1);
continue;
}

// Other isolated scalars (like bool, int, float/Scalar, etc..).
{
auto maybe_known_type = ReadKnownScalarType(member.basetype);
Expand Down
138 changes: 71 additions & 67 deletions impeller/compiler/shader_lib/impeller/blending.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,48 @@

#include <impeller/branching.glsl>
#include <impeller/constants.glsl>
#include <impeller/types.glsl>

//------------------------------------------------------------------------------
/// HSV utilities.
///

float IPLuminosity(vec3 color) {
return color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
float16_t IPLuminosity(f16vec3 color) {
return color.r * 0.3hf + color.g * 0.59hf + color.b * 0.11hf;
}

/// Scales the color's luma by the amount necessary to place the color
/// components in a 1-0 range.
vec3 IPClipColor(vec3 color) {
float lum = IPLuminosity(color);
float mn = min(min(color.r, color.g), color.b);
float mx = max(max(color.r, color.g), color.b);
f16vec3 IPClipColor(f16vec3 color) {
float16_t lum = IPLuminosity(color);
float16_t mn = min(min(color.r, color.g), color.b);
float16_t mx = max(max(color.r, color.g), color.b);
// `lum - mn` and `mx - lum` will always be >= 0 in the following conditions,
// so adding a tiny value is enough to make these divisions safe.
if (mn < 0) {
color = lum + (((color - lum) * lum) / (lum - mn + kEhCloseEnough));
if (mn < 0.0hf) {
color = lum + (((color - lum) * lum) / (lum - mn + kEhCloseEnoughHf));
}
if (mx > 1) {
color = lum + (((color - lum) * (1 - lum)) / (mx - lum + kEhCloseEnough));
if (mx > 1.0hf) {
color =
lum + (((color - lum) * (1.0hf - lum)) / (mx - lum + kEhCloseEnoughHf));
}
return color;
}

vec3 IPSetLuminosity(vec3 color, float luminosity) {
float relative_lum = luminosity - IPLuminosity(color);
f16vec3 IPSetLuminosity(f16vec3 color, float16_t luminosity) {
float16_t relative_lum = luminosity - IPLuminosity(color);
return IPClipColor(color + relative_lum);
}

float IPSaturation(vec3 color) {
float16_t IPSaturation(f16vec3 color) {
return max(max(color.r, color.g), color.b) -
min(min(color.r, color.g), color.b);
}

vec3 IPSetSaturation(vec3 color, float saturation) {
float mn = min(min(color.r, color.g), color.b);
float mx = max(max(color.r, color.g), color.b);
return (mn < mx) ? ((color - mn) * saturation) / (mx - mn) : vec3(0);
f16vec3 IPSetSaturation(f16vec3 color, float16_t saturation) {
float16_t mn = min(min(color.r, color.g), color.b);
float16_t mx = max(max(color.r, color.g), color.b);
return (mn < mx) ? ((color - mn) * saturation) / (mx - mn) : f16vec3(0.0hf);
}

//------------------------------------------------------------------------------
Expand All @@ -58,134 +60,136 @@ vec3 IPSetSaturation(vec3 color, float saturation) {
/// applied to the destination using `SourceOver` alpha compositing.
///

vec3 IPBlendScreen(vec3 dst, vec3 src) {
f16vec3 IPBlendScreen(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingscreen
return dst + src - (dst * src);
}

vec3 IPBlendHardLight(vec3 dst, vec3 src) {
f16vec3 IPBlendHardLight(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinghardlight
return IPVec3Choose(dst * (2 * src), IPBlendScreen(dst, 2 * src - 1), src);
return IPVec3ChooseHf(dst * (2.0hf * src),
IPBlendScreen(dst, 2.0hf * src - 1.0hf), src);
}

vec3 IPBlendOverlay(vec3 dst, vec3 src) {
f16vec3 IPBlendOverlay(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingoverlay
// HardLight, but with reversed parameters.
return IPBlendHardLight(src, dst);
}

vec3 IPBlendDarken(vec3 dst, vec3 src) {
f16vec3 IPBlendDarken(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingdarken
return min(dst, src);
}

vec3 IPBlendLighten(vec3 dst, vec3 src) {
f16vec3 IPBlendLighten(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinglighten
return max(dst, src);
}

vec3 IPBlendColorDodge(vec3 dst, vec3 src) {
f16vec3 IPBlendColorDodge(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolordodge

vec3 color = min(vec3(1), dst / (1 - src));
f16vec3 color = min(f16vec3(1.0hf), dst / (1.0hf - src));

if (dst.r < kEhCloseEnough) {
color.r = 0;
if (dst.r < kEhCloseEnoughHf) {
color.r = 0.0hf;
}
if (dst.g < kEhCloseEnough) {
color.g = 0;
if (dst.g < kEhCloseEnoughHf) {
color.g = 0.0hf;
}
if (dst.b < kEhCloseEnough) {
color.b = 0;
if (dst.b < kEhCloseEnoughHf) {
color.b = 0.0hf;
}

if (1 - src.r < kEhCloseEnough) {
color.r = 1;
if (1.0hf - src.r < kEhCloseEnoughHf) {
color.r = 1.0hf;
}
if (1 - src.g < kEhCloseEnough) {
color.g = 1;
if (1.0hf - src.g < kEhCloseEnoughHf) {
color.g = 1.0hf;
}
if (1 - src.b < kEhCloseEnough) {
color.b = 1;
if (1.0hf - src.b < kEhCloseEnoughHf) {
color.b = 1.0hf;
}

return color;
}

vec3 IPBlendColorBurn(vec3 dst, vec3 src) {
f16vec3 IPBlendColorBurn(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolorburn

vec3 color = 1 - min(vec3(1), (1 - dst) / src);
f16vec3 color = 1.0hf - min(f16vec3(1.0hf), (1.0hf - dst) / src);

if (1 - dst.r < kEhCloseEnough) {
color.r = 1;
if (1.0hf - dst.r < kEhCloseEnoughHf) {
color.r = 1.0hf;
}
if (1 - dst.g < kEhCloseEnough) {
color.g = 1;
if (1.0hf - dst.g < kEhCloseEnoughHf) {
color.g = 1.0hf;
}
if (1 - dst.b < kEhCloseEnough) {
color.b = 1;
if (1.0hf - dst.b < kEhCloseEnoughHf) {
color.b = 1.0hf;
}

if (src.r < kEhCloseEnough) {
color.r = 0;
if (src.r < kEhCloseEnoughHf) {
color.r = 0.0hf;
}
if (src.g < kEhCloseEnough) {
color.g = 0;
if (src.g < kEhCloseEnoughHf) {
color.g = 0.0hf;
}
if (src.b < kEhCloseEnough) {
color.b = 0;
if (src.b < kEhCloseEnoughHf) {
color.b = 0.0hf;
}

return color;
}

vec3 IPBlendSoftLight(vec3 dst, vec3 src) {
f16vec3 IPBlendSoftLight(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingsoftlight

vec3 D = IPVec3ChooseCutoff(((16 * dst - 12) * dst + 4) * dst, //
sqrt(dst), //
dst, //
0.25);
f16vec3 D =
IPVec3ChooseCutoffHf(((16.0hf * dst - 12.0hf) * dst + 4.0hf) * dst, //
sqrt(dst), //
dst, //
0.25hf);

return IPVec3Choose(dst - (1 - 2 * src) * dst * (1 - dst), //
dst + (2 * src - 1) * (D - dst), //
src);
return IPVec3ChooseHf(dst - (1.0hf - 2.0hf * src) * dst * (1.0hf - dst), //
dst + (2.0hf * src - 1.0hf) * (D - dst), //
src);
}

vec3 IPBlendDifference(vec3 dst, vec3 src) {
f16vec3 IPBlendDifference(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingdifference
return abs(dst - src);
}

vec3 IPBlendExclusion(vec3 dst, vec3 src) {
f16vec3 IPBlendExclusion(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingexclusion
return dst + src - 2 * dst * src;
return dst + src - 2.0hf * dst * src;
}

vec3 IPBlendMultiply(vec3 dst, vec3 src) {
f16vec3 IPBlendMultiply(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingmultiply
return dst * src;
}

vec3 IPBlendHue(vec3 dst, vec3 src) {
f16vec3 IPBlendHue(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendinghue
return IPSetLuminosity(IPSetSaturation(src, IPSaturation(dst)),
IPLuminosity(dst));
}

vec3 IPBlendSaturation(vec3 dst, vec3 src) {
f16vec3 IPBlendSaturation(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingsaturation
return IPSetLuminosity(IPSetSaturation(dst, IPSaturation(src)),
IPLuminosity(dst));
}

vec3 IPBlendColor(vec3 dst, vec3 src) {
f16vec3 IPBlendColor(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingcolor
return IPSetLuminosity(src, IPLuminosity(dst));
}

vec3 IPBlendLuminosity(vec3 dst, vec3 src) {
f16vec3 IPBlendLuminosity(f16vec3 dst, f16vec3 src) {
// https://www.w3.org/TR/compositing-1/#blendingluminosity
return IPSetLuminosity(dst, IPLuminosity(src));
}
Expand Down
Loading