Chromium Code Reviews| Index: cc/output/render_surface_filters.cc |
| diff --git a/cc/output/render_surface_filters.cc b/cc/output/render_surface_filters.cc |
| index fa84e67f4d3913dd66ef067eb55d72e031c6cd20..7325f83abd304f95719f0262e39f8c55e10c6da3 100644 |
| --- a/cc/output/render_surface_filters.cc |
| +++ b/cc/output/render_surface_filters.cc |
| @@ -11,9 +11,13 @@ |
| #include "cc/output/filter_operations.h" |
| #include "skia/ext/refptr.h" |
| #include "third_party/skia/include/core/SkCanvas.h" |
| +#include "third_party/skia/include/core/SkFlattenableBuffers.h" |
| +#include "third_party/skia/include/core/SkImageFilter.h" |
| #include "third_party/skia/include/effects/SkBlurImageFilter.h" |
| +#include "third_party/skia/include/effects/SkColorFilterImageFilter.h" |
| #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
| #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" |
| +#include "third_party/skia/include/effects/SkTestImageFilters.h" |
|
ajuma
2013/07/31 18:40:37
This is for SkComposeImageFilter, used to connect
Stephen White
2013/07/31 19:18:51
Yes, I think it should be broken out into its own
ajuma
2013/09/09 17:35:36
Done.
|
| #include "third_party/skia/include/gpu/SkGpuDevice.h" |
| #include "third_party/skia/include/gpu/SkGrPixelRef.h" |
| #include "ui/gfx/size_f.h" |
| @@ -231,6 +235,15 @@ bool GetColorMatrix(const FilterOperation& op, SkScalar matrix[20]) { |
| } |
| } |
| +skia::RefPtr<SkImageFilter> CreateMatrixImageFilter( |
| + const SkScalar matrix[20], |
| + skia::RefPtr<SkImageFilter> input) { |
| + skia::RefPtr<SkColorFilter> color_filter = |
| + skia::AdoptRef(new SkColorMatrixFilter(matrix)); |
| + return skia::AdoptRef( |
| + SkColorFilterImageFilter::Create(color_filter.get(), input.get())); |
| +} |
| + |
| class FilterBufferState { |
| public: |
| FilterBufferState(GrContext* gr_context, |
| @@ -309,6 +322,71 @@ class FilterBufferState { |
| skia::RefPtr<SkCanvas> canvas_; |
| }; |
| +class DropShadowImageFilter : public SkImageFilter { |
|
ajuma
2013/07/31 18:40:37
This is copied from Blink. SkiaImageFilterBuilder
ajuma
2013/09/09 17:35:36
This is no longer needed, since DropShadowImageFil
|
| + public: |
| + DropShadowImageFilter(SkScalar dx, |
| + SkScalar dy, |
| + SkScalar sigma, |
| + SkColor color, |
| + SkImageFilter* input) |
| + : SkImageFilter(input), |
| + dx_(dx), |
| + dy_(dy), |
| + sigma_(sigma), |
| + color_(color) { } |
| + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DropShadowImageFilter) |
| + |
| + protected: |
| + explicit DropShadowImageFilter(SkFlattenableReadBuffer& buffer) |
| + : SkImageFilter(buffer) { |
| + dx_ = buffer.readScalar(); |
| + dy_ = buffer.readScalar(); |
| + sigma_ = buffer.readScalar(); |
| + color_ = buffer.readColor(); |
| + } |
| + |
| + virtual void flatten(SkFlattenableWriteBuffer& buffer) const OVERRIDE { |
| + buffer.writeScalar(dx_); |
| + buffer.writeScalar(dy_); |
| + buffer.writeScalar(sigma_); |
| + buffer.writeColor(color_); |
| + } |
| + |
| + virtual bool onFilterImage(Proxy* proxy, |
| + const SkBitmap& source, |
| + const SkMatrix& matrix, |
| + SkBitmap* result, |
| + SkIPoint* loc) OVERRIDE { |
| + SkBitmap src = source; |
| + if (getInput(0) && |
| + !getInput(0)->filterImage(proxy, source, matrix, &src, loc)) |
| + return false; |
| + |
| + skia::RefPtr<SkDevice> device = skia::AdoptRef( |
| + proxy->createDevice(src.width(), src.height())); |
| + SkCanvas canvas(device.get()); |
| + |
| + skia::RefPtr<SkImageFilter> blurFilter = skia::AdoptRef( |
| + new SkBlurImageFilter(sigma_, sigma_)); |
| + skia::RefPtr<SkColorFilter> colorFilter = skia::AdoptRef( |
| + SkColorFilter::CreateModeFilter(color_, SkXfermode::kSrcIn_Mode)); |
| + SkPaint paint; |
| + paint.setImageFilter(blurFilter.get()); |
| + paint.setColorFilter(colorFilter.get()); |
| + paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); |
| + canvas.saveLayer(0, &paint); |
|
Stephen White
2013/07/31 19:18:51
FYI, we can probably get rid of the saveLayer()/re
|
| + canvas.drawBitmap(src, dx_, dy_); |
|
ajuma
2013/07/31 18:40:37
The version of DropShadowImageFilter currently in
Stephen White
2013/07/31 19:18:51
Yeah, I think that was when we had TopDown texture
|
| + canvas.restore(); |
| + canvas.drawBitmap(src, 0, 0); |
| + *result = device.get()->accessBitmap(false); |
| + return true; |
| + } |
| + |
| + private: |
| + SkScalar dx_, dy_, sigma_; |
| + SkColor color_; |
| +}; |
| + |
| } // namespace |
| FilterOperations RenderSurfaceFilters::Optimize( |
| @@ -355,6 +433,9 @@ FilterOperations RenderSurfaceFilters::Optimize( |
| case FilterOperation::ZOOM: |
| new_list.Append(op); |
| break; |
| + case FilterOperation::REFERENCE: |
| + // Not supported on this code path. |
| + NOTREACHED(); |
| case FilterOperation::BRIGHTNESS: |
| case FilterOperation::SATURATING_BRIGHTNESS: |
| case FilterOperation::CONTRAST: |
| @@ -442,6 +523,7 @@ SkBitmap RenderSurfaceFilters::Apply(const FilterOperations& filters, |
| canvas->restore(); |
| break; |
| } |
| + case FilterOperation::REFERENCE: |
| case FilterOperation::BRIGHTNESS: |
| case FilterOperation::SATURATING_BRIGHTNESS: |
| case FilterOperation::CONTRAST: |
| @@ -459,4 +541,91 @@ SkBitmap RenderSurfaceFilters::Apply(const FilterOperations& filters, |
| return state.Source(); |
| } |
| +skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( |
| + const FilterOperations& filters) { |
| + skia::RefPtr<SkImageFilter> image_filter; |
| + SkScalar matrix[20]; |
| + for (size_t i = 0; i < filters.size(); ++i) { |
| + const FilterOperation& op = filters.at(i); |
| + switch (op.type()) { |
| + case FilterOperation::GRAYSCALE: |
| + GetGrayscaleMatrix(1 - op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::SEPIA: |
| + GetSepiaMatrix(1 - op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::SATURATE: |
| + GetSaturateMatrix(op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::HUE_ROTATE: |
| + GetHueRotateMatrix(op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::INVERT: |
| + GetInvertMatrix(op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::OPACITY: |
| + GetOpacityMatrix(op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::BRIGHTNESS: |
| + GetBrightnessMatrix(op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::CONTRAST: |
| + GetContrastMatrix(op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::BLUR: |
| + image_filter = skia::AdoptRef(new SkBlurImageFilter( |
| + op.amount(), op.amount(), image_filter.get())); |
| + break; |
| + case FilterOperation::DROP_SHADOW: |
| + image_filter = skia::AdoptRef(new DropShadowImageFilter( |
| + SkIntToScalar(op.drop_shadow_offset().x()), |
| + SkIntToScalar(op.drop_shadow_offset().y()), |
| + SkIntToScalar(op.amount()), |
| + op.drop_shadow_color(), |
| + image_filter.get())); |
| + break; |
| + case FilterOperation::COLOR_MATRIX: |
| + image_filter = CreateMatrixImageFilter(op.matrix(), image_filter); |
| + break; |
| + case FilterOperation::ZOOM: |
| + // TODO(ajuma): Add support for this. Note that zoom filter operations |
| + // are only used for background filters right now. |
|
ajuma
2013/07/31 18:40:37
Is this worth doing? That is, are there any plans
Stephen White
2013/07/31 19:18:51
Check with zork@ about this filter; I think it's o
ajuma
2013/09/09 17:35:36
I've added the code that was missing here for ZOOM
|
| + NOTREACHED(); |
| + case FilterOperation::SATURATING_BRIGHTNESS: |
| + GetSaturatingBrightnessMatrix(op.amount(), matrix); |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + break; |
| + case FilterOperation::REFERENCE: { |
| + skia::RefPtr<SkColorFilter> cf; |
| + |
| + { |
| + SkColorFilter* colorfilter_rawptr = NULL; |
| + op.image_filter()->asColorFilter(&colorfilter_rawptr); |
| + cf = skia::AdoptRef(colorfilter_rawptr); |
| + } |
| + |
| + if (cf && cf->asColorMatrix(matrix) && |
| + !op.image_filter()->getInput(0)) { |
| + image_filter = CreateMatrixImageFilter(matrix, image_filter); |
| + } else if (image_filter.get()) { |
| + image_filter = skia::AdoptRef(new SkComposeImageFilter( |
| + op.image_filter().get(), image_filter.get())); |
|
ajuma
2013/07/31 18:40:37
The plan is to use a no-op filter as the SourceGra
Stephen White
2013/07/31 19:18:51
That seems reasonable. I like the use of the SkCom
|
| + } else { |
| + image_filter = op.image_filter(); |
| + } |
| + break; |
| + } |
| + } |
| + } |
| + return image_filter; |
| +} |
| + |
| } // namespace cc |