mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Replace FML_OS_PHYSICAL_IOS compile check with runtime capabilties check based on metal GPU family. (flutter/engine#40124)
[Impeller] Replace FML_OS_PHYSICAL_IOS compile check with runtime capabilties check based on metal GPU family.
This commit is contained in:
parent
bf7cfcf102
commit
aa6c168e5f
@ -100,10 +100,4 @@
|
||||
#error Please add support for your architecture in flutter/fml/build_config.h
|
||||
#endif
|
||||
|
||||
#if defined(FML_OS_IOS)
|
||||
#if !defined(FML_OS_IOS_SIMULATOR)
|
||||
#define FML_OS_PHYSICAL_IOS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // FLUTTER_FML_BUILD_CONFIG_H_
|
||||
|
||||
@ -42,7 +42,7 @@ static uint32_t ParseMSLVersion(const std::string& msl_version) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (major < 1 || minor < 2) {
|
||||
if (major < 1 || (major == 1 && minor < 2)) {
|
||||
std::cerr << "--metal-version version must be at least 1.2. Have "
|
||||
<< msl_version << std::endl;
|
||||
}
|
||||
|
||||
@ -77,26 +77,40 @@ impeller_shaders("modern_entity_shaders") {
|
||||
"shaders/radial_gradient_ssbo_fill.frag",
|
||||
"shaders/sweep_gradient_ssbo_fill.frag",
|
||||
]
|
||||
if (is_ios && !use_ios_simulator) {
|
||||
shaders += [
|
||||
"shaders/blending/ios/framebuffer_blend.vert",
|
||||
"shaders/blending/ios/framebuffer_blend_color.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_colorburn.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_colordodge.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_darken.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_difference.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_exclusion.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_hardlight.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_hue.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_lighten.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_luminosity.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_multiply.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_overlay.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_saturation.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_screen.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_softlight.frag",
|
||||
]
|
||||
}
|
||||
|
||||
impeller_shaders("framebuffer_blend_entity_shaders") {
|
||||
name = "framebuffer_blend"
|
||||
|
||||
if (is_mac && !is_ios) {
|
||||
# Note: this needs to correspond to the Apple7 Support family
|
||||
# for M1 and M2.
|
||||
metal_version = "2.3"
|
||||
}
|
||||
|
||||
# This version is to disable malioc checks.
|
||||
if (impeller_enable_opengles) {
|
||||
gles_language_version = "460"
|
||||
}
|
||||
|
||||
shaders = [
|
||||
"shaders/blending/ios/framebuffer_blend.vert",
|
||||
"shaders/blending/ios/framebuffer_blend_color.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_colorburn.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_colordodge.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_darken.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_difference.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_exclusion.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_hardlight.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_hue.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_lighten.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_luminosity.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_multiply.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_overlay.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_saturation.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_screen.frag",
|
||||
"shaders/blending/ios/framebuffer_blend_softlight.frag",
|
||||
]
|
||||
}
|
||||
|
||||
impeller_component("entity") {
|
||||
@ -143,6 +157,8 @@ impeller_component("entity") {
|
||||
"contents/filters/srgb_to_linear_filter_contents.h",
|
||||
"contents/filters/yuv_to_rgb_filter_contents.cc",
|
||||
"contents/filters/yuv_to_rgb_filter_contents.h",
|
||||
"contents/framebuffer_blend_contents.cc",
|
||||
"contents/framebuffer_blend_contents.h",
|
||||
"contents/gradient_generator.cc",
|
||||
"contents/gradient_generator.h",
|
||||
"contents/linear_gradient_contents.cc",
|
||||
@ -179,15 +195,9 @@ impeller_component("entity") {
|
||||
"inline_pass_context.h",
|
||||
]
|
||||
|
||||
if (is_ios && !use_ios_simulator) {
|
||||
sources += [
|
||||
"contents/framebuffer_blend_contents.cc",
|
||||
"contents/framebuffer_blend_contents.h",
|
||||
]
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
":entity_shaders",
|
||||
":framebuffer_blend_entity_shaders",
|
||||
":modern_entity_shaders",
|
||||
"../archivist",
|
||||
"../image",
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "impeller/entity/contents/content_context.h"
|
||||
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
||||
#include "impeller/entity/contents/filters/filter_contents.h"
|
||||
#include "impeller/entity/contents/framebuffer_blend_contents.h"
|
||||
#include "impeller/entity/contents/texture_contents.h"
|
||||
#include "impeller/entity/entity.h"
|
||||
#include "impeller/entity/geometry.h"
|
||||
@ -22,10 +23,6 @@
|
||||
#include "impeller/renderer/sampler_library.h"
|
||||
#include "impeller/renderer/vertex_buffer_builder.h"
|
||||
|
||||
#ifdef FML_OS_PHYSICAL_IOS
|
||||
#include "impeller/entity/contents/framebuffer_blend_contents.h"
|
||||
#endif
|
||||
|
||||
namespace impeller {
|
||||
|
||||
AtlasContents::AtlasContents() = default;
|
||||
@ -224,38 +221,39 @@ bool AtlasContents::Render(const ContentContext& renderer,
|
||||
dst_contents->SetSubAtlas(sub_atlas);
|
||||
dst_contents->SetCoverage(sub_coverage);
|
||||
|
||||
#ifdef FML_OS_PHYSICAL_IOS
|
||||
auto new_texture = renderer.MakeSubpass(
|
||||
"Atlas Blend", sub_atlas->size,
|
||||
[&](const ContentContext& context, RenderPass& pass) {
|
||||
Entity entity;
|
||||
entity.SetContents(dst_contents);
|
||||
entity.SetBlendMode(BlendMode::kSource);
|
||||
if (!entity.Render(context, pass)) {
|
||||
return false;
|
||||
}
|
||||
if (blend_mode_ >= Entity::kLastPipelineBlendMode) {
|
||||
auto contents = std::make_shared<FramebufferBlendContents>();
|
||||
contents->SetBlendMode(blend_mode_);
|
||||
contents->SetChildContents(src_contents);
|
||||
entity.SetContents(std::move(contents));
|
||||
std::shared_ptr<Texture> new_texture;
|
||||
if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
|
||||
new_texture = renderer.MakeSubpass(
|
||||
"Atlas Blend", sub_atlas->size,
|
||||
[&](const ContentContext& context, RenderPass& pass) {
|
||||
Entity entity;
|
||||
entity.SetContents(dst_contents);
|
||||
entity.SetBlendMode(BlendMode::kSource);
|
||||
if (!entity.Render(context, pass)) {
|
||||
return false;
|
||||
}
|
||||
if (blend_mode_ >= Entity::kLastPipelineBlendMode) {
|
||||
auto contents = std::make_shared<FramebufferBlendContents>();
|
||||
contents->SetBlendMode(blend_mode_);
|
||||
contents->SetChildContents(src_contents);
|
||||
entity.SetContents(std::move(contents));
|
||||
entity.SetBlendMode(BlendMode::kSource);
|
||||
return entity.Render(context, pass);
|
||||
}
|
||||
entity.SetContents(src_contents);
|
||||
entity.SetBlendMode(blend_mode_);
|
||||
return entity.Render(context, pass);
|
||||
}
|
||||
entity.SetContents(src_contents);
|
||||
entity.SetBlendMode(blend_mode_);
|
||||
return entity.Render(context, pass);
|
||||
});
|
||||
#else
|
||||
auto contents = ColorFilterContents::MakeBlend(
|
||||
blend_mode_,
|
||||
{FilterInput::Make(dst_contents), FilterInput::Make(src_contents)});
|
||||
auto snapshot = contents->RenderToSnapshot(renderer, entity);
|
||||
if (!snapshot.has_value()) {
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
auto contents = ColorFilterContents::MakeBlend(
|
||||
blend_mode_,
|
||||
{FilterInput::Make(dst_contents), FilterInput::Make(src_contents)});
|
||||
auto snapshot = contents->RenderToSnapshot(renderer, entity);
|
||||
if (!snapshot.has_value()) {
|
||||
return false;
|
||||
}
|
||||
new_texture = snapshot.value().texture;
|
||||
}
|
||||
auto new_texture = snapshot.value().texture;
|
||||
#endif
|
||||
|
||||
auto child_contents = AtlasTextureContents(*this);
|
||||
child_contents.SetAlpha(alpha_);
|
||||
|
||||
@ -183,6 +183,38 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
|
||||
sweep_gradient_ssbo_fill_pipelines_[{}] =
|
||||
CreateDefaultPipeline<SweepGradientSSBOFillPipeline>(*context_);
|
||||
}
|
||||
if (context_->GetDeviceCapabilities().SupportsFramebufferFetch()) {
|
||||
framebuffer_blend_color_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendColorPipeline>(*context_);
|
||||
framebuffer_blend_colorburn_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendColorBurnPipeline>(*context_);
|
||||
framebuffer_blend_colordodge_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendColorDodgePipeline>(*context_);
|
||||
framebuffer_blend_darken_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendDarkenPipeline>(*context_);
|
||||
framebuffer_blend_difference_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendDifferencePipeline>(*context_);
|
||||
framebuffer_blend_exclusion_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendExclusionPipeline>(*context_);
|
||||
framebuffer_blend_hardlight_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendHardLightPipeline>(*context_);
|
||||
framebuffer_blend_hue_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendHuePipeline>(*context_);
|
||||
framebuffer_blend_lighten_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendLightenPipeline>(*context_);
|
||||
framebuffer_blend_luminosity_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendLuminosityPipeline>(*context_);
|
||||
framebuffer_blend_multiply_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendMultiplyPipeline>(*context_);
|
||||
framebuffer_blend_overlay_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendOverlayPipeline>(*context_);
|
||||
framebuffer_blend_saturation_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendSaturationPipeline>(*context_);
|
||||
framebuffer_blend_screen_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendScreenPipeline>(*context_);
|
||||
framebuffer_blend_softlight_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendSoftLightPipeline>(*context_);
|
||||
}
|
||||
|
||||
blend_color_pipelines_[{}] =
|
||||
CreateDefaultPipeline<BlendColorPipeline>(*context_);
|
||||
@ -213,39 +245,6 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
|
||||
CreateDefaultPipeline<BlendScreenPipeline>(*context_);
|
||||
blend_softlight_pipelines_[{}] =
|
||||
CreateDefaultPipeline<BlendSoftLightPipeline>(*context_);
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
framebuffer_blend_color_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendColorPipeline>(*context_);
|
||||
framebuffer_blend_colorburn_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendColorBurnPipeline>(*context_);
|
||||
framebuffer_blend_colordodge_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendColorDodgePipeline>(*context_);
|
||||
framebuffer_blend_darken_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendDarkenPipeline>(*context_);
|
||||
framebuffer_blend_difference_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendDifferencePipeline>(*context_);
|
||||
framebuffer_blend_exclusion_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendExclusionPipeline>(*context_);
|
||||
framebuffer_blend_hardlight_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendHardLightPipeline>(*context_);
|
||||
framebuffer_blend_hue_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendHuePipeline>(*context_);
|
||||
framebuffer_blend_lighten_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendLightenPipeline>(*context_);
|
||||
framebuffer_blend_luminosity_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendLuminosityPipeline>(*context_);
|
||||
framebuffer_blend_multiply_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendMultiplyPipeline>(*context_);
|
||||
framebuffer_blend_overlay_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendOverlayPipeline>(*context_);
|
||||
framebuffer_blend_saturation_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendSaturationPipeline>(*context_);
|
||||
framebuffer_blend_screen_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendScreenPipeline>(*context_);
|
||||
framebuffer_blend_softlight_pipelines_[{}] =
|
||||
CreateDefaultPipeline<FramebufferBlendSoftLightPipeline>(*context_);
|
||||
#endif // FML_OS_PHYSICAL_IOS
|
||||
|
||||
sweep_gradient_fill_pipelines_[{}] =
|
||||
CreateDefaultPipeline<SweepGradientFillPipeline>(*context_);
|
||||
rrect_blur_pipelines_[{}] =
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
#include "impeller/entity/advanced_blend_saturation.frag.h"
|
||||
#include "impeller/entity/advanced_blend_screen.frag.h"
|
||||
#include "impeller/entity/advanced_blend_softlight.frag.h"
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
|
||||
#include "impeller/entity/framebuffer_blend.vert.h"
|
||||
#include "impeller/entity/framebuffer_blend_color.frag.h"
|
||||
#include "impeller/entity/framebuffer_blend_colorburn.frag.h"
|
||||
@ -95,7 +95,6 @@
|
||||
#include "impeller/entity/framebuffer_blend_saturation.frag.h"
|
||||
#include "impeller/entity/framebuffer_blend_screen.frag.h"
|
||||
#include "impeller/entity/framebuffer_blend_softlight.frag.h"
|
||||
#endif // FML_OS_PHYSICAL_IOS
|
||||
|
||||
namespace impeller {
|
||||
|
||||
@ -202,8 +201,7 @@ using BlendScreenPipeline = RenderPipelineT<AdvancedBlendVertexShader,
|
||||
using BlendSoftLightPipeline =
|
||||
RenderPipelineT<AdvancedBlendVertexShader,
|
||||
AdvancedBlendSoftlightFragmentShader>;
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
// iOS only advanced blends.
|
||||
// Framebuffer Advanced Blends
|
||||
using FramebufferBlendColorPipeline =
|
||||
RenderPipelineT<FramebufferBlendVertexShader,
|
||||
FramebufferBlendColorFragmentShader>;
|
||||
@ -249,7 +247,6 @@ using FramebufferBlendScreenPipeline =
|
||||
using FramebufferBlendSoftLightPipeline =
|
||||
RenderPipelineT<FramebufferBlendVertexShader,
|
||||
FramebufferBlendSoftlightFragmentShader>;
|
||||
#endif // FML_OS_PHYSICAL_IOS
|
||||
|
||||
/// Pipeline state configuration.
|
||||
///
|
||||
@ -516,83 +513,97 @@ class ContentContext {
|
||||
ContentContextOptions opts) const {
|
||||
return GetPipeline(blend_softlight_pipelines_, opts);
|
||||
}
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
// iOS advanced blends.
|
||||
|
||||
// Framebuffer Advanced Blends
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendColorPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_color_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_darken_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_difference_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> GetFramebufferBlendHuePipeline(
|
||||
ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_hue_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_lighten_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_multiply_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_overlay_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_saturation_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_screen_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
|
||||
return GetPipeline(framebuffer_blend_softlight_pipelines_, opts);
|
||||
}
|
||||
#endif // FML_OS_PHYSICAL_IOS
|
||||
|
||||
std::shared_ptr<Context> GetContext() const;
|
||||
|
||||
@ -669,7 +680,7 @@ class ContentContext {
|
||||
mutable Variants<BlendSaturationPipeline> blend_saturation_pipelines_;
|
||||
mutable Variants<BlendScreenPipeline> blend_screen_pipelines_;
|
||||
mutable Variants<BlendSoftLightPipeline> blend_softlight_pipelines_;
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
// Framebuffer Advanced blends.
|
||||
mutable Variants<FramebufferBlendColorPipeline>
|
||||
framebuffer_blend_color_pipelines_;
|
||||
mutable Variants<FramebufferBlendColorBurnPipeline>
|
||||
@ -700,7 +711,6 @@ class ContentContext {
|
||||
framebuffer_blend_screen_pipelines_;
|
||||
mutable Variants<FramebufferBlendSoftLightPipeline>
|
||||
framebuffer_blend_softlight_pipelines_;
|
||||
#endif // FML_OS_PHYSICAL_IOS
|
||||
|
||||
template <class TypedPipeline>
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
|
||||
|
||||
@ -32,6 +32,10 @@ std::optional<Rect> FramebufferBlendContents::GetCoverage(
|
||||
bool FramebufferBlendContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
if (!renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
using VS = FramebufferBlendScreenPipeline::VertexShader;
|
||||
using FS = FramebufferBlendScreenPipeline::FragmentShader;
|
||||
|
||||
|
||||
@ -16,9 +16,7 @@
|
||||
#include "impeller/entity/contents/content_context.h"
|
||||
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
||||
#include "impeller/entity/contents/filters/inputs/filter_input.h"
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
#include "impeller/entity/contents/framebuffer_blend_contents.h"
|
||||
#endif
|
||||
#include "impeller/entity/contents/texture_contents.h"
|
||||
#include "impeller/entity/entity.h"
|
||||
#include "impeller/entity/inline_pass_context.h"
|
||||
@ -44,12 +42,9 @@ void EntityPass::SetDelegate(std::unique_ptr<EntityPassDelegate> delegate) {
|
||||
}
|
||||
|
||||
void EntityPass::AddEntity(Entity entity) {
|
||||
#ifndef FML_OS_PHYSICAL_IOS
|
||||
if (entity.GetBlendMode() > Entity::kLastPipelineBlendMode) {
|
||||
reads_from_pass_texture_ += 1;
|
||||
blend_reads_from_pass_texture_ += 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
elements_.emplace_back(std::move(entity));
|
||||
}
|
||||
|
||||
@ -135,16 +130,12 @@ EntityPass* EntityPass::AddSubpass(std::unique_ptr<EntityPass> pass) {
|
||||
FML_DCHECK(pass->superpass_ == nullptr);
|
||||
pass->superpass_ = this;
|
||||
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
if (pass->backdrop_filter_proc_.has_value()) {
|
||||
reads_from_pass_texture_ += 1;
|
||||
filter_reads_from_pass_texture_ += 1;
|
||||
}
|
||||
#else
|
||||
if (pass->blend_mode_ > Entity::kLastPipelineBlendMode ||
|
||||
pass->backdrop_filter_proc_.has_value()) {
|
||||
reads_from_pass_texture_ += 1;
|
||||
if (pass->blend_mode_ > Entity::kLastPipelineBlendMode) {
|
||||
blend_reads_from_pass_texture_ += 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto subpass_pointer = pass.get();
|
||||
elements_.emplace_back(std::move(pass));
|
||||
@ -199,9 +190,15 @@ static RenderTarget CreateRenderTarget(ContentContext& renderer,
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t EntityPass::ComputeTotalReads(ContentContext& renderer) const {
|
||||
return renderer.GetDeviceCapabilities().SupportsFramebufferFetch()
|
||||
? filter_reads_from_pass_texture_
|
||||
: filter_reads_from_pass_texture_ + blend_reads_from_pass_texture_;
|
||||
}
|
||||
|
||||
bool EntityPass::Render(ContentContext& renderer,
|
||||
const RenderTarget& render_target) const {
|
||||
if (reads_from_pass_texture_ > 0) {
|
||||
if (ComputeTotalReads(renderer) > 0) {
|
||||
auto offscreen_target =
|
||||
CreateRenderTarget(renderer, render_target.GetRenderTargetSize(), true);
|
||||
if (!OnRender(renderer, offscreen_target.GetRenderTargetSize(),
|
||||
@ -357,7 +354,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
auto subpass_target =
|
||||
CreateRenderTarget(renderer, //
|
||||
ISize(subpass_coverage->size), //
|
||||
subpass->reads_from_pass_texture_ > 0);
|
||||
subpass->ComputeTotalReads(renderer) > 0);
|
||||
|
||||
auto subpass_texture = subpass_target.GetRenderTargetTexture();
|
||||
|
||||
@ -420,7 +417,7 @@ bool EntityPass::OnRender(ContentContext& renderer,
|
||||
|
||||
auto context = renderer.GetContext();
|
||||
InlinePassContext pass_context(context, render_target,
|
||||
reads_from_pass_texture_,
|
||||
ComputeTotalReads(renderer),
|
||||
std::move(collapsed_parent_pass));
|
||||
if (!pass_context.IsValid()) {
|
||||
return false;
|
||||
@ -552,46 +549,45 @@ bool EntityPass::OnRender(ContentContext& renderer,
|
||||
///
|
||||
|
||||
if (result.entity.GetBlendMode() > Entity::kLastPipelineBlendMode) {
|
||||
#if FML_OS_PHYSICAL_IOS
|
||||
auto src_contents = result.entity.GetContents();
|
||||
auto contents = std::make_shared<FramebufferBlendContents>();
|
||||
contents->SetChildContents(src_contents);
|
||||
contents->SetBlendMode(result.entity.GetBlendMode());
|
||||
result.entity.SetContents(std::move(contents));
|
||||
result.entity.SetBlendMode(BlendMode::kSource);
|
||||
if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
|
||||
auto src_contents = result.entity.GetContents();
|
||||
auto contents = std::make_shared<FramebufferBlendContents>();
|
||||
contents->SetChildContents(src_contents);
|
||||
contents->SetBlendMode(result.entity.GetBlendMode());
|
||||
result.entity.SetContents(std::move(contents));
|
||||
result.entity.SetBlendMode(BlendMode::kSource);
|
||||
} else {
|
||||
// End the active pass and flush the buffer before rendering "advanced"
|
||||
// blends. Advanced blends work by binding the current render target
|
||||
// texture as an input ("destination"), blending with a second texture
|
||||
// input ("source"), writing the result to an intermediate texture, and
|
||||
// finally copying the data from the intermediate texture back to the
|
||||
// render target texture. And so all of the commands that have written
|
||||
// to the render target texture so far need to execute before it's bound
|
||||
// for blending (otherwise the blend pass will end up executing before
|
||||
// all the previous commands in the active pass).
|
||||
|
||||
#else
|
||||
// End the active pass and flush the buffer before rendering "advanced"
|
||||
// blends. Advanced blends work by binding the current render target
|
||||
// texture as an input ("destination"), blending with a second texture
|
||||
// input ("source"), writing the result to an intermediate texture, and
|
||||
// finally copying the data from the intermediate texture back to the
|
||||
// render target texture. And so all of the commands that have written
|
||||
// to the render target texture so far need to execute before it's bound
|
||||
// for blending (otherwise the blend pass will end up executing before
|
||||
// all the previous commands in the active pass).
|
||||
if (!pass_context.EndPass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pass_context.EndPass()) {
|
||||
return false;
|
||||
// Amend an advanced blend filter to the contents, attaching the pass
|
||||
// texture.
|
||||
auto texture = pass_context.GetTexture();
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FilterInput::Vector inputs = {
|
||||
FilterInput::Make(texture,
|
||||
result.entity.GetTransformation().Invert()),
|
||||
FilterInput::Make(result.entity.GetContents())};
|
||||
auto contents = ColorFilterContents::MakeBlend(
|
||||
result.entity.GetBlendMode(), inputs);
|
||||
contents->SetCoverageCrop(result.entity.GetCoverage());
|
||||
result.entity.SetContents(std::move(contents));
|
||||
result.entity.SetBlendMode(BlendMode::kSource);
|
||||
}
|
||||
|
||||
// Amend an advanced blend filter to the contents, attaching the pass
|
||||
// texture.
|
||||
auto texture = pass_context.GetTexture();
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FilterInput::Vector inputs = {
|
||||
FilterInput::Make(texture,
|
||||
result.entity.GetTransformation().Invert()),
|
||||
FilterInput::Make(result.entity.GetContents())};
|
||||
auto contents =
|
||||
ColorFilterContents::MakeBlend(result.entity.GetBlendMode(), inputs);
|
||||
contents->SetCoverageCrop(result.entity.GetCoverage());
|
||||
result.entity.SetContents(std::move(contents));
|
||||
result.entity.SetBlendMode(BlendMode::kSource);
|
||||
#endif // FML_OS_PHYSICAL_IOS
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@ -118,12 +118,18 @@ class EntityPass {
|
||||
BlendMode blend_mode_ = BlendMode::kSourceOver;
|
||||
bool cover_whole_screen_ = false;
|
||||
|
||||
/// This value is incremented whenever something is added to the pass that
|
||||
/// These value are incremented whenever something is added to the pass that
|
||||
/// requires reading from the backdrop texture. Currently, this can happen in
|
||||
/// the following scenarios:
|
||||
/// 1. An entity with an "advanced blend" is added to the pass.
|
||||
/// 2. A subpass with a backdrop filter is added to the pass.
|
||||
uint32_t reads_from_pass_texture_ = 0;
|
||||
/// These are tracked as separate values because we may ignore
|
||||
/// blend_reads_from_pass_texture_ if the device supports framebuffer based
|
||||
/// advanced blends.
|
||||
uint32_t filter_reads_from_pass_texture_ = 0;
|
||||
uint32_t blend_reads_from_pass_texture_ = 0;
|
||||
|
||||
uint32_t ComputeTotalReads(ContentContext& renderer) const;
|
||||
|
||||
std::optional<BackdropFilterProc> backdrop_filter_proc_ = std::nullopt;
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
#ifdef IMPELLER_TARGET_METAL_IOS
|
||||
#ifdef IMPELLER_TARGET_METAL
|
||||
layout(set = 0,
|
||||
binding = 0,
|
||||
input_attachment_index = 0) uniform subpassInput uSub;
|
||||
|
||||
@ -40,6 +40,7 @@ impeller_component("playground") {
|
||||
|
||||
public_deps = [
|
||||
"../entity:entity_shaders",
|
||||
"../entity:framebuffer_blend_entity_shaders",
|
||||
"../entity:modern_entity_shaders",
|
||||
"../fixtures:shader_fixtures",
|
||||
"../renderer",
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include "flutter/fml/mapping.h"
|
||||
#include "impeller/entity/mtl/entity_shaders.h"
|
||||
#include "impeller/entity/mtl/framebuffer_blend_shaders.h"
|
||||
#include "impeller/entity/mtl/modern_shaders.h"
|
||||
#include "impeller/fixtures/mtl/fixtures_shaders.h"
|
||||
#include "impeller/fixtures/mtl/subgroup_fixtures_shaders.h"
|
||||
@ -38,6 +39,9 @@ ShaderLibraryMappingsForPlayground() {
|
||||
impeller_entity_shaders_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_data,
|
||||
impeller_modern_shaders_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(
|
||||
impeller_framebuffer_blend_shaders_data,
|
||||
impeller_framebuffer_blend_shaders_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_fixtures_shaders_data,
|
||||
impeller_fixtures_shaders_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(
|
||||
|
||||
@ -78,6 +78,7 @@ ContextGLES::ContextGLES(std::unique_ptr<ProcTableGLES> gl,
|
||||
.SetSupportsSSBO(false)
|
||||
.SetSupportsTextureToTextureBlits(
|
||||
reactor_->GetProcTable().BlitFramebuffer.IsAvailable())
|
||||
.SetSupportsFramebufferFetch(false)
|
||||
.SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt)
|
||||
.SetDefaultStencilFormat(PixelFormat::kS8UInt)
|
||||
.Build();
|
||||
|
||||
@ -51,6 +51,8 @@ class ContextMTL final : public Context,
|
||||
|
||||
ContextMTL(id<MTLDevice> device, NSArray<id<MTLLibrary>>* shader_libraries);
|
||||
|
||||
bool SupportsFramebufferFetch() const;
|
||||
|
||||
// |Context|
|
||||
bool IsValid() const override;
|
||||
|
||||
|
||||
@ -96,6 +96,7 @@ ContextMTL::ContextMTL(id<MTLDevice> device,
|
||||
.SetSupportsOffscreenMSAA(true)
|
||||
.SetSupportsSSBO(true)
|
||||
.SetSupportsTextureToTextureBlits(true)
|
||||
.SetSupportsFramebufferFetch(SupportsFramebufferFetch())
|
||||
.SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt)
|
||||
.SetDefaultStencilFormat(PixelFormat::kS8UInt)
|
||||
.Build();
|
||||
@ -104,6 +105,25 @@ ContextMTL::ContextMTL(id<MTLDevice> device,
|
||||
is_valid_ = true;
|
||||
}
|
||||
|
||||
bool ContextMTL::SupportsFramebufferFetch() const {
|
||||
// The iOS simulator lies about supporting framebuffer fetch.
|
||||
#if FML_OS_IOS_SIMULATOR
|
||||
return false;
|
||||
#endif // FML_OS_IOS_SIMULATOR
|
||||
|
||||
if (@available(macOS 10.15, iOS 13, tvOS 13, *)) {
|
||||
return [device_ supportsFamily:MTLGPUFamilyApple2];
|
||||
}
|
||||
// According to
|
||||
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf , Apple2
|
||||
// corresponds to iOS GPU family 2, which supports A8 devices.
|
||||
#if FML_OS_IOS
|
||||
return [device_ supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v1];
|
||||
#else
|
||||
return false;
|
||||
#endif // FML_OS_IOS
|
||||
}
|
||||
|
||||
static NSArray<id<MTLLibrary>>* MTLShaderLibraryFromFilePaths(
|
||||
id<MTLDevice> device,
|
||||
const std::vector<std::string>& libraries_paths) {
|
||||
|
||||
@ -554,6 +554,7 @@ ContextVK::ContextVK(
|
||||
.SetSupportsOffscreenMSAA(true)
|
||||
.SetSupportsSSBO(false)
|
||||
.SetSupportsTextureToTextureBlits(true)
|
||||
.SetSupportsFramebufferFetch(false)
|
||||
.SetDefaultColorFormat(PixelFormat::kB8G8R8A8UNormInt)
|
||||
.SetDefaultStencilFormat(PixelFormat::kS8UInt)
|
||||
.Build();
|
||||
|
||||
@ -10,12 +10,14 @@ IDeviceCapabilities::IDeviceCapabilities(bool has_threading_restrictions,
|
||||
bool supports_offscreen_msaa,
|
||||
bool supports_ssbo,
|
||||
bool supports_texture_to_texture_blits,
|
||||
bool supports_framebuffer_fetch,
|
||||
PixelFormat default_color_format,
|
||||
PixelFormat default_stencil_format)
|
||||
: has_threading_restrictions_(has_threading_restrictions),
|
||||
supports_offscreen_msaa_(supports_offscreen_msaa),
|
||||
supports_ssbo_(supports_ssbo),
|
||||
supports_texture_to_texture_blits_(supports_texture_to_texture_blits),
|
||||
supports_framebuffer_fetch_(supports_framebuffer_fetch),
|
||||
default_color_format_(default_color_format),
|
||||
default_stencil_format_(default_stencil_format) {}
|
||||
|
||||
@ -37,6 +39,10 @@ bool IDeviceCapabilities::SupportsTextureToTextureBlits() const {
|
||||
return supports_texture_to_texture_blits_;
|
||||
}
|
||||
|
||||
bool IDeviceCapabilities::SupportsFramebufferFetch() const {
|
||||
return supports_framebuffer_fetch_;
|
||||
}
|
||||
|
||||
PixelFormat IDeviceCapabilities::GetDefaultColorFormat() const {
|
||||
return default_color_format_;
|
||||
}
|
||||
@ -73,6 +79,12 @@ DeviceCapabilitiesBuilder::SetSupportsTextureToTextureBlits(bool value) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
DeviceCapabilitiesBuilder&
|
||||
DeviceCapabilitiesBuilder::SetSupportsFramebufferFetch(bool value) {
|
||||
supports_framebuffer_fetch_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DeviceCapabilitiesBuilder& DeviceCapabilitiesBuilder::SetDefaultColorFormat(
|
||||
PixelFormat value) {
|
||||
default_color_format_ = value;
|
||||
@ -96,6 +108,7 @@ std::unique_ptr<IDeviceCapabilities> DeviceCapabilitiesBuilder::Build() {
|
||||
supports_offscreen_msaa_, //
|
||||
supports_ssbo_, //
|
||||
supports_texture_to_texture_blits_, //
|
||||
supports_framebuffer_fetch_, //
|
||||
*default_color_format_, //
|
||||
*default_stencil_format_ //
|
||||
);
|
||||
|
||||
@ -23,6 +23,8 @@ class IDeviceCapabilities {
|
||||
|
||||
bool SupportsTextureToTextureBlits() const;
|
||||
|
||||
bool SupportsFramebufferFetch() const;
|
||||
|
||||
PixelFormat GetDefaultColorFormat() const;
|
||||
|
||||
PixelFormat GetDefaultStencilFormat() const;
|
||||
@ -32,6 +34,7 @@ class IDeviceCapabilities {
|
||||
bool supports_offscreen_msaa,
|
||||
bool supports_ssbo,
|
||||
bool supports_texture_to_texture_blits,
|
||||
bool supports_framebuffer_fetch,
|
||||
PixelFormat default_color_format,
|
||||
PixelFormat default_stencil_format);
|
||||
|
||||
@ -41,6 +44,7 @@ class IDeviceCapabilities {
|
||||
bool supports_offscreen_msaa_ = false;
|
||||
bool supports_ssbo_ = false;
|
||||
bool supports_texture_to_texture_blits_ = false;
|
||||
bool supports_framebuffer_fetch_ = false;
|
||||
PixelFormat default_color_format_;
|
||||
PixelFormat default_stencil_format_;
|
||||
|
||||
@ -61,6 +65,8 @@ class DeviceCapabilitiesBuilder {
|
||||
|
||||
DeviceCapabilitiesBuilder& SetSupportsTextureToTextureBlits(bool value);
|
||||
|
||||
DeviceCapabilitiesBuilder& SetSupportsFramebufferFetch(bool value);
|
||||
|
||||
DeviceCapabilitiesBuilder& SetDefaultColorFormat(PixelFormat value);
|
||||
|
||||
DeviceCapabilitiesBuilder& SetDefaultStencilFormat(PixelFormat value);
|
||||
@ -72,6 +78,7 @@ class DeviceCapabilitiesBuilder {
|
||||
bool supports_offscreen_msaa_ = false;
|
||||
bool supports_ssbo_ = false;
|
||||
bool supports_texture_to_texture_blits_ = false;
|
||||
bool supports_framebuffer_fetch_ = false;
|
||||
std::optional<PixelFormat> default_color_format_ = std::nullopt;
|
||||
std::optional<PixelFormat> default_stencil_format_ = std::nullopt;
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "flutter/shell/common/context_options.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
|
||||
#include "impeller/entity/mtl/entity_shaders.h"
|
||||
#include "impeller/entity/mtl/framebuffer_blend_shaders.h"
|
||||
#include "impeller/entity/mtl/modern_shaders.h"
|
||||
#include "impeller/scene/shaders/mtl/scene_shaders.h"
|
||||
|
||||
@ -23,6 +24,8 @@ static std::shared_ptr<impeller::ContextMTL> CreateImpellerContext() {
|
||||
impeller_scene_shaders_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_data,
|
||||
impeller_modern_shaders_length),
|
||||
std::make_shared<fml::NonOwnedMapping>(impeller_framebuffer_blend_shaders_data,
|
||||
impeller_framebuffer_blend_shaders_length),
|
||||
};
|
||||
auto context = impeller::ContextMTL::Create(shader_mappings, "Impeller Library");
|
||||
if (!context) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user