Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(406)

Unified Diff: cc/output/render_surface_filters.cc

Issue 21154002: Add support for converting cc::FilterOperations into an SkImageFilter (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698