blob: f279f7f926bd82d12b421b8ccad2bdaca25f3a15 [file] [log] [blame]
// 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.
#pragma once
#include <optional>
#include "impeller/entity/contents/filters/color_filter_contents.h"
#include "impeller/entity/contents/filters/inputs/filter_input.h"
#include "impeller/geometry/color.h"
namespace impeller {
constexpr std::array<std::array<Scalar, 5>, 15> kPorterDuffCoefficients = {{
{0, 0, 0, 0, 0}, // Clear
{1, 0, 0, 0, 0}, // Source
{0, 0, 1, 0, 0}, // Destination
{1, 0, 1, -1, 0}, // SourceOver
{1, -1, 1, 0, 0}, // DestinationOver
{0, 1, 0, 0, 0}, // SourceIn
{0, 0, 0, 1, 0}, // DestinationIn
{1, -1, 0, 0, 0}, // SourceOut
{0, 0, 1, -1, 0}, // DestinationOut
{0, 1, 1, -1, 0}, // SourceATop
{1, -1, 0, 1, 0}, // DestinationATop
{1, -1, 1, -1, 0}, // Xor
{1, 0, 1, 0, 0}, // Plus
{0, 0, 0, 0, 1}, // Modulate
{0, 0, 1, 0, -1}, // Screen
}};
std::optional<BlendMode> InvertPorterDuffBlend(BlendMode blend_mode);
class BlendFilterContents : public ColorFilterContents {
public:
using AdvancedBlendProc =
std::function<std::optional<Entity>(const FilterInput::Vector& inputs,
const ContentContext& renderer,
const Entity& entity,
const Rect& coverage,
BlendMode blend_mode,
std::optional<Color> foreground_color,
bool absorb_opacity,
std::optional<Scalar> alpha)>;
BlendFilterContents();
~BlendFilterContents() override;
void SetBlendMode(BlendMode blend_mode);
/// @brief Sets a source color which is blended after all of the inputs have
/// been blended.
void SetForegroundColor(std::optional<Color> color);
private:
// |FilterContents|
std::optional<Entity> RenderFilter(
const FilterInput::Vector& inputs,
const ContentContext& renderer,
const Entity& entity,
const Matrix& effect_transform,
const Rect& coverage,
const std::optional<Rect>& coverage_hint) const override;
/// @brief Optimized advanced blend that avoids a second subpass when there is
/// only a single input and a foreground color.
///
/// These contents cannot absorb opacity.
std::optional<Entity> CreateForegroundAdvancedBlend(
const std::shared_ptr<FilterInput>& input,
const ContentContext& renderer,
const Entity& entity,
const Rect& coverage,
Color foreground_color,
BlendMode blend_mode,
std::optional<Scalar> alpha,
bool absorb_opacity) const;
/// @brief Optimized porter-duff blend that avoids a second subpass when there
/// is only a single input and a foreground color.
///
/// These contents cannot absorb opacity.
std::optional<Entity> CreateForegroundPorterDuffBlend(
const std::shared_ptr<FilterInput>& input,
const ContentContext& renderer,
const Entity& entity,
const Rect& coverage,
Color foreground_color,
BlendMode blend_mode,
std::optional<Scalar> alpha,
bool absorb_opacity) const;
BlendMode blend_mode_ = BlendMode::kSourceOver;
AdvancedBlendProc advanced_blend_proc_;
std::optional<Color> foreground_color_;
FML_DISALLOW_COPY_AND_ASSIGN(BlendFilterContents);
};
} // namespace impeller