Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
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
2 changes: 1 addition & 1 deletion display_list/display_list_image_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ std::shared_ptr<DlImageFilter> DlImageFilter::From(
}

std::shared_ptr<DlImageFilter> DlImageFilter::makeWithLocalMatrix(
const SkMatrix& matrix) {
const SkMatrix& matrix) const {
if (matrix.isIdentity()) {
return shared();
}
Expand Down
10 changes: 5 additions & 5 deletions display_list/display_list_image_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class DlImageFilter
}

virtual std::shared_ptr<DlImageFilter> makeWithLocalMatrix(
const SkMatrix& matrix);
const SkMatrix& matrix) const;

// Return a DlComposeImageFilter pointer to this object iff it is a Compose
// type of ImageFilter, otherwise return nullptr.
Expand Down Expand Up @@ -634,7 +634,7 @@ class DlColorFilterImageFilter final : public DlImageFilter {
}

std::shared_ptr<DlImageFilter> makeWithLocalMatrix(
const SkMatrix& matrix) override {
const SkMatrix& matrix) const override {
return shared();
}

Expand Down Expand Up @@ -764,7 +764,7 @@ class DlUnknownImageFilter final : public DlImageFilter {

SkRect* map_local_bounds(const SkRect& input_bounds,
SkRect& output_bounds) const override {
if (modifies_transparent_black()) {
if (!sk_filter_ || modifies_transparent_black()) {
output_bounds = input_bounds;
return nullptr;
}
Expand All @@ -775,7 +775,7 @@ class DlUnknownImageFilter final : public DlImageFilter {
SkIRect* map_device_bounds(const SkIRect& input_bounds,
const SkMatrix& ctm,
SkIRect& output_bounds) const override {
if (modifies_transparent_black()) {
if (!sk_filter_ || modifies_transparent_black()) {
output_bounds = input_bounds;
return nullptr;
}
Expand All @@ -787,7 +787,7 @@ class DlUnknownImageFilter final : public DlImageFilter {
SkIRect* get_input_device_bounds(const SkIRect& output_bounds,
const SkMatrix& ctm,
SkIRect& input_bounds) const override {
if (modifies_transparent_black()) {
if (!sk_filter_ || modifies_transparent_black()) {
input_bounds = output_bounds;
return nullptr;
}
Expand Down
60 changes: 35 additions & 25 deletions flow/layers/image_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
// found in the LICENSE file.

#include "flutter/flow/layers/image_filter_layer.h"
#include "flutter/display_list/display_list_comparable.h"
#include "flutter/flow/layers/layer.h"
#include "flutter/flow/raster_cache_util.h"

namespace flutter {

ImageFilterLayer::ImageFilterLayer(sk_sp<SkImageFilter> filter)
ImageFilterLayer::ImageFilterLayer(std::shared_ptr<const DlImageFilter> filter)
: CacheableContainerLayer(
RasterCacheUtil::kMinimumRendersBeforeCachingFilterLayer),
filter_(std::move(filter)),
Expand All @@ -19,7 +20,7 @@ void ImageFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
auto* prev = static_cast<const ImageFilterLayer*>(old_layer);
if (!context->IsSubtreeDirty()) {
FML_DCHECK(prev);
if (filter_ != prev->filter_) {
if (NotEquals(filter_, prev->filter_)) {
context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer));
}
}
Expand All @@ -29,9 +30,10 @@ void ImageFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
if (filter) {
// This transform will be applied to every child rect in the subtree
context->PushFilterBoundsAdjustment([filter](SkRect rect) {
return SkRect::Make(
filter->filterBounds(rect.roundOut(), SkMatrix::I(),
SkImageFilter::kForward_MapDirection));
SkIRect filter_out_bounds;
filter->map_device_bounds(rect.roundOut(), SkMatrix::I(),
filter_out_bounds);
return SkRect::Make(filter_out_bounds);
});
}
}
Expand All @@ -50,7 +52,6 @@ void ImageFilterLayer::Preroll(PrerollContext* context,

SkRect child_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_bounds);
context->subtree_can_inherit_opacity = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this line deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It repeats with the next line


// We always paint with a saveLayer (or a cached rendering),
// so we can always apply opacity in any of those cases.
Expand All @@ -61,10 +62,11 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
return;
}

const SkIRect filter_input_bounds = child_bounds.roundOut();
SkIRect filter_output_bounds = filter_->filterBounds(
filter_input_bounds, SkMatrix::I(), SkImageFilter::kForward_MapDirection);
child_bounds = SkRect::Make(filter_output_bounds);
const SkIRect filter_in_bounds = child_bounds.roundOut();
SkIRect filter_out_bounds;
filter_->map_device_bounds(filter_in_bounds, SkMatrix::I(),
filter_out_bounds);
child_bounds = SkRect::Make(filter_out_bounds);

set_paint_bounds(child_bounds);

Expand All @@ -83,23 +85,31 @@ void ImageFilterLayer::Paint(PaintContext& context) const {
FML_DCHECK(needs_painting(context));

AutoCachePaint cache_paint(context);

if (layer_raster_cache_item_->IsCacheChildren()) {
cache_paint.setImageFilter(transformed_filter_);
}
if (layer_raster_cache_item_->Draw(context, cache_paint.sk_paint())) {
return;
if (context.raster_cache) {
if (layer_raster_cache_item_->IsCacheChildren()) {
cache_paint.setImageFilter(transformed_filter_.get());
}
if (layer_raster_cache_item_->Draw(context, cache_paint.sk_paint())) {
return;
}
}

cache_paint.setImageFilter(filter_);

// Normally a save_layer is sized to the current layer bounds, but in this
// case the bounds of the child may not be the same as the filtered version
// so we use the bounds of the child container which do not include any
// modifications that the filter might apply.
Layer::AutoSaveLayer save_layer = Layer::AutoSaveLayer::Create(
context, child_paint_bounds(), cache_paint.sk_paint());
PaintChildren(context);
cache_paint.setImageFilter(filter_.get());
if (context.leaf_nodes_builder) {
FML_DCHECK(context.builder_multiplexer);
context.builder_multiplexer->saveLayer(&child_paint_bounds(),
cache_paint.dl_paint());
PaintChildren(context);
context.builder_multiplexer->restore();
} else {
// Normally a save_layer is sized to the current layer bounds, but in this
// case the bounds of the child may not be the same as the filtered version
// so we use the bounds of the child container which do not include any
// modifications that the filter might apply.
Layer::AutoSaveLayer save_layer = Layer::AutoSaveLayer::Create(
context, child_paint_bounds(), cache_paint.sk_paint());
PaintChildren(context);
}
}

} // namespace flutter
8 changes: 5 additions & 3 deletions flow/layers/image_filter_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
#ifndef FLUTTER_FLOW_LAYERS_IMAGE_FILTER_LAYER_H_
#define FLUTTER_FLOW_LAYERS_IMAGE_FILTER_LAYER_H_

#include <memory>
#include "flutter/flow/layers/cacheable_layer.h"
#include "flutter/flow/layers/layer.h"
#include "include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkImageFilter.h"

namespace flutter {

class ImageFilterLayer : public CacheableContainerLayer {
public:
explicit ImageFilterLayer(sk_sp<SkImageFilter> filter);
explicit ImageFilterLayer(std::shared_ptr<const DlImageFilter> filter);

void Diff(DiffContext* context, const Layer* old_layer) override;

Expand All @@ -22,8 +24,8 @@ class ImageFilterLayer : public CacheableContainerLayer {
void Paint(PaintContext& context) const override;

private:
sk_sp<SkImageFilter> filter_;
sk_sp<SkImageFilter> transformed_filter_;
std::shared_ptr<const DlImageFilter> filter_;
std::shared_ptr<const DlImageFilter> transformed_filter_;

FML_DISALLOW_COPY_AND_ASSIGN(ImageFilterLayer);
};
Expand Down
Loading