blob: 562f306034ebd880304d9efc5469a440b7081220 [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.
#ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_FILTERS_BLEND_FILTER_CONTENTS_H_
#define FLUTTER_IMPELLER_ENTITY_CONTENTS_FILTERS_BLEND_FILTER_CONTENTS_H_
#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,
ColorFilterContents::AbsorbOpacity 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,
ColorFilterContents::AbsorbOpacity 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,
ColorFilterContents::AbsorbOpacity absorb_opacity) const;
BlendMode blend_mode_ = BlendMode::kSourceOver;
AdvancedBlendProc advanced_blend_proc_;
std::optional<Color> foreground_color_;
BlendFilterContents(const BlendFilterContents&) = delete;
BlendFilterContents& operator=(const BlendFilterContents&) = delete;
};
} // namespace impeller
#endif // FLUTTER_IMPELLER_ENTITY_CONTENTS_FILTERS_BLEND_FILTER_CONTENTS_H_