提交 13f67343 编写于 作者: A Adam Barth

Add support for backdrop filters in the compositor

Particularly, add support for blur filters to implement backdrop blur effects.
上级 b8151a8d
......@@ -8,6 +8,8 @@ source_set("flow") {
"checkerboard.h",
"instrumentation.cc",
"instrumentation.h",
"layers/backdrop_filter_layer.cc",
"layers/backdrop_filter_layer.h",
"layers/child_scene_layer.cc",
"layers/child_scene_layer.h",
"layers/clip_path_layer.cc",
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flow/layers/backdrop_filter_layer.h"
namespace flow {
BackdropFilterLayer::BackdropFilterLayer() {
}
BackdropFilterLayer::~BackdropFilterLayer() {
}
void BackdropFilterLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
ContainerLayer::Preroll(context, matrix);
set_paint_bounds(context->child_paint_bounds);
}
void BackdropFilterLayer::Paint(PaintContext::ScopedFrame& frame) {
SkCanvas& canvas = frame.canvas();
SkAutoCanvasRestore save(&canvas, false);
canvas.saveLayer(SkCanvas::SaveLayerRec{
&paint_bounds(), nullptr, filter_.get(), 0});
PaintChildren(frame);
}
} // namespace flow
// Copyright 2016 The Chromium 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 FLOW_LAYERS_BACKDROP_FILTER_LAYER_H_
#define FLOW_LAYERS_BACKDROP_FILTER_LAYER_H_
#include "flow/layers/container_layer.h"
namespace flow {
class BackdropFilterLayer : public ContainerLayer {
public:
BackdropFilterLayer();
~BackdropFilterLayer() override;
void set_filter(SkImageFilter* filter) { filter_ = skia::SharePtr(filter); }
protected:
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
skia::RefPtr<SkImageFilter> filter_;
DISALLOW_COPY_AND_ASSIGN(BackdropFilterLayer);
};
} // namespace flow
#endif // FLOW_LAYERS_BACKDROP_FILTER_LAYER_H_
......@@ -13,6 +13,7 @@
#include "sky/engine/core/painting/CanvasImage.h"
#include "sky/engine/core/painting/CanvasPath.h"
#include "sky/engine/core/painting/ColorFilter.h"
#include "sky/engine/core/painting/ImageFilter.h"
#include "sky/engine/core/painting/ImageShader.h"
#include "sky/engine/core/painting/MaskFilter.h"
#include "sky/engine/core/painting/painting.h"
......@@ -50,6 +51,7 @@ void DartUI::InitForGlobal() {
CanvasPath::RegisterNatives(g_natives);
ColorFilter::RegisterNatives(g_natives);
DartRuntimeHooks::RegisterNatives(g_natives);
ImageFilter::RegisterNatives(g_natives);
ImageShader::RegisterNatives(g_natives);
MaskFilter::RegisterNatives(g_natives);
MojoServices::RegisterNatives(g_natives);
......
......@@ -4,6 +4,7 @@
#include "sky/engine/core/compositing/SceneBuilder.h"
#include "flow/layers/backdrop_filter_layer.h"
#include "flow/layers/child_scene_layer.h"
#include "flow/layers/clip_path_layer.h"
#include "flow/layers/clip_rect_layer.h"
......@@ -48,6 +49,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, SceneBuilder);
V(SceneBuilder, pushClipPath) \
V(SceneBuilder, pushOpacity) \
V(SceneBuilder, pushColorFilter) \
V(SceneBuilder, pushBackdropFilter) \
V(SceneBuilder, pushShaderMask) \
V(SceneBuilder, pop) \
V(SceneBuilder, addPicture) \
......@@ -122,6 +124,13 @@ void SceneBuilder::pushColorFilter(CanvasColor color, TransferMode transferMode)
addLayer(std::move(layer));
}
void SceneBuilder::pushBackdropFilter(ImageFilter* filter)
{
std::unique_ptr<flow::BackdropFilterLayer> layer(new flow::BackdropFilterLayer());
layer->set_filter(filter->toSkia());
addLayer(std::move(layer));
}
void SceneBuilder::pushShaderMask(Shader* shader, const Rect& maskRect, TransferMode transferMode)
{
std::unique_ptr<flow::ShaderMaskLayer> layer(new flow::ShaderMaskLayer());
......
......@@ -12,6 +12,7 @@
#include "sky/engine/bindings/exception_state.h"
#include "sky/engine/core/compositing/Scene.h"
#include "sky/engine/core/painting/CanvasPath.h"
#include "sky/engine/core/painting/ImageFilter.h"
#include "sky/engine/core/painting/Offset.h"
#include "sky/engine/core/painting/Paint.h"
#include "sky/engine/core/painting/Picture.h"
......@@ -40,6 +41,7 @@ public:
void pushClipPath(const CanvasPath* path);
void pushOpacity(int alpha);
void pushColorFilter(CanvasColor color, TransferMode transferMode);
void pushBackdropFilter(ImageFilter* filter);
void pushShaderMask(Shader* shader, const Rect& maskRect, TransferMode transferMode);
void pop();
......
......@@ -29,6 +29,8 @@ sky_core_files = [
"painting/ColorFilter.cpp",
"painting/ColorFilter.h",
"painting/FilterQuality.h",
"painting/ImageFilter.cpp",
"painting/ImageFilter.h",
"painting/ImageShader.cpp",
"painting/ImageShader.h",
"painting/MaskFilter.cpp",
......
......@@ -81,6 +81,14 @@ class SceneBuilder extends NativeFieldWrapperClass2 {
/// See [pop] for details about the operation stack.
void pushColorFilter(Color color, TransferMode transferMode) native "SceneBuilder_pushColorFilter";
/// Pushes a backdrop filter operation onto the operation stack.
///
/// The given filter is applied to the current contents of the scene prior to
/// rasterizing the given objects.
///
/// See [pop] for details about the operation stack.
void pushBackdropFilter(ImageFilter filter) native "SceneBuilder_pushBackdropFilter";
/// Pushes a shader mask operation onto the operation stack.
///
/// The given shader is applied to the object's rasterization in the given
......
......@@ -214,6 +214,34 @@ class ColorFilter extends NativeFieldWrapperClass2 {
void _constructor(Color color, TransferMode transferMode) native "ColorFilter_constructor";
}
/// A filter operation to apply to a raster image.
///
/// See [SceneBuilder.pushBackdropFilter].
class ImageFilter extends NativeFieldWrapperClass2 {
void _constructor() native "ImageFilter_constructor";
/// A source filter containing an image.
// ImageFilter.image({ Image image }) {
// _constructor();
// _initImage(image);
// }
// void _initImage(Image image) native "ImageFilter_initImage";
/// A source filter containing a picture.
// ImageFilter.picture({ Picture picture }) {
// _constructor();
// _initPicture(picture);
// }
// void _initPicture(Picture picture) native "ImageFilter_initPicture";
/// Applies a Gaussian blur.
ImageFilter.blur({ double sigmaX: 0.0, double sigmaY: 0.0 }) {
_constructor();
_initBlur(sigmaX, sigmaY);
}
void _initBlur(double sigmaX, double sigmaY) native "ImageFilter_initBlur";
}
/// Base class for objects such as [Gradient] and [ImageShader] which
/// correspond to shaders.
abstract class Shader extends NativeFieldWrapperClass2 { }
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/engine/core/painting/ImageFilter.h"
#include "sky/engine/tonic/dart_args.h"
#include "sky/engine/tonic/dart_binding_macros.h"
#include "sky/engine/tonic/dart_converter.h"
#include "sky/engine/tonic/dart_library_natives.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
#include "third_party/skia/include/effects/SkImageSource.h"
#include "third_party/skia/include/effects/SkPictureImageFilter.h"
namespace blink {
static void ImageFilter_constructor(Dart_NativeArguments args) {
DartCallConstructor(&ImageFilter::create, args);
}
IMPLEMENT_WRAPPERTYPEINFO(ui, ImageFilter);
#define FOR_EACH_BINDING(V) \
V(ImageFilter, initImage) \
V(ImageFilter, initPicture) \
V(ImageFilter, initBlur)
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
void ImageFilter::RegisterNatives(DartLibraryNatives* natives) {
natives->Register({
{ "ImageFilter_constructor", ImageFilter_constructor, 1, true },
FOR_EACH_BINDING(DART_REGISTER_NATIVE)
});
}
PassRefPtr<ImageFilter> ImageFilter::create() {
return adoptRef(new ImageFilter());
}
ImageFilter::ImageFilter() {
}
ImageFilter::~ImageFilter() {
}
void ImageFilter::initImage(CanvasImage* image) {
filter_ = adoptRef(SkImageSource::Create(image->image()));
}
void ImageFilter::initPicture(Picture* picture) {
filter_ = adoptRef(SkPictureImageFilter::Create(picture->toSkia()));
}
void ImageFilter::initBlur(double sigmaX, double sigmaY) {
filter_ = adoptRef(SkBlurImageFilter::Create(sigmaX, sigmaY));
}
} // namespace blink
// Copyright 2016 The Chromium 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 SKY_ENGINE_CORE_PAINTING_IMAGE_FILTER_H_
#define SKY_ENGINE_CORE_PAINTING_IMAGE_FILTER_H_
#include "sky/engine/core/painting/CanvasImage.h"
#include "sky/engine/core/painting/Picture.h"
#include "sky/engine/tonic/dart_wrappable.h"
#include "sky/engine/wtf/PassRefPtr.h"
#include "sky/engine/wtf/ThreadSafeRefCounted.h"
#include "third_party/skia/include/core/SkImageFilter.h"
namespace blink {
class ImageFilter : public ThreadSafeRefCounted<ImageFilter>, public DartWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
~ImageFilter() override;
static PassRefPtr<ImageFilter> create();
void initImage(CanvasImage* image);
void initPicture(Picture*);
void initBlur(double sigmaX, double sigmaY);
SkImageFilter* toSkia() { return filter_.get(); }
static void RegisterNatives(DartLibraryNatives* natives);
private:
ImageFilter();
RefPtr<SkImageFilter> filter_;
};
} // namespace blink
#endif // SKY_ENGINE_CORE_PAINTING_IMAGE_FILTER_H_
......@@ -316,7 +316,7 @@ GraphicsContext* FilterEffectRendererHelper::beginFilterEffect(GraphicsContext*
{
ASSERT(m_filter);
SkiaImageFilterBuilder builder(context);
RefPtr<ImageFilter> imageFilter = builder.build(m_filter->lastEffect().get(), ColorSpaceDeviceRGB);
RefPtr<SkImageFilter> imageFilter = builder.build(m_filter->lastEffect().get(), ColorSpaceDeviceRGB);
if (!imageFilter) {
m_haveFilterEffect = false;
return context;
......
......@@ -378,7 +378,7 @@ void GraphicsContext::beginTransparencyLayer(float opacity, const FloatRect* bou
beginLayer(opacity, immutableState()->compositeOperator(), bounds);
}
void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const FloatRect* bounds, ColorFilterObsolete colorFilter, ImageFilter* imageFilter)
void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const FloatRect* bounds, ColorFilterObsolete colorFilter, SkImageFilter* imageFilter)
{
if (contextDisabled())
return;
......
......@@ -316,7 +316,7 @@ public:
void drawLineForDocumentMarker(const FloatPoint&, float width, DocumentMarkerLineStyle);
void beginTransparencyLayer(float opacity, const FloatRect* = 0);
void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilterObsolete = ColorFilterNone, ImageFilter* = 0);
void beginLayer(float opacity, CompositeOperator, const FloatRect* = 0, ColorFilterObsolete = ColorFilterNone, SkImageFilter* = 0);
void endLayer();
bool hasShadow() const;
......
......@@ -8,7 +8,7 @@
namespace blink {
FloatRect mapImageFilterRect(ImageFilter* filter, const FloatRect& rect)
FloatRect mapImageFilterRect(SkImageFilter* filter, const FloatRect& rect)
{
return filter->computeFastBounds(rect);
}
......
......@@ -11,9 +11,7 @@ class SkImageFilter;
namespace blink {
typedef SkImageFilter ImageFilter;
PLATFORM_EXPORT FloatRect mapImageFilterRect(ImageFilter*, const FloatRect&);
PLATFORM_EXPORT FloatRect mapImageFilterRect(SkImageFilter*, const FloatRect&);
} // namespace blink
......
......@@ -101,10 +101,8 @@ DartWrappable* DartConverterWrappable::FromArguments(Dart_NativeArguments args,
exception = Dart_NewStringFromCString(DartError::kInvalidArgument);
return nullptr;
}
if (!native_fields[DartWrappable::kPeerIndex]) {
exception = Dart_NewStringFromCString(DartError::kInvalidDartWrappable);
if (!native_fields[DartWrappable::kPeerIndex])
return nullptr;
}
return reinterpret_cast<DartWrappable*>(
native_fields[DartWrappable::kPeerIndex]);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册