OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/output/render_surface_filters.h" | 5 #include "cc/output/render_surface_filters.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "cc/output/filter_operation.h" | 10 #include "cc/output/filter_operation.h" |
11 #include "cc/output/filter_operations.h" | 11 #include "cc/output/filter_operations.h" |
12 #include "skia/ext/refptr.h" | 12 #include "skia/ext/refptr.h" |
13 #include "third_party/skia/include/core/SkCanvas.h" | 13 #include "third_party/skia/include/core/SkCanvas.h" |
14 #include "third_party/skia/include/core/SkFlattenableBuffers.h" | |
15 #include "third_party/skia/include/core/SkImageFilter.h" | |
14 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | 16 #include "third_party/skia/include/effects/SkBlurImageFilter.h" |
17 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" | |
15 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 18 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
19 #include "third_party/skia/include/effects/SkComposeImageFilter.h" | |
20 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" | |
16 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" | 21 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" |
17 #include "third_party/skia/include/gpu/SkGpuDevice.h" | 22 #include "third_party/skia/include/gpu/SkGpuDevice.h" |
18 #include "third_party/skia/include/gpu/SkGrPixelRef.h" | 23 #include "third_party/skia/include/gpu/SkGrPixelRef.h" |
19 #include "ui/gfx/size_f.h" | 24 #include "ui/gfx/size_f.h" |
20 | 25 |
21 namespace cc { | 26 namespace cc { |
22 | 27 |
23 namespace { | 28 namespace { |
24 | 29 |
25 void GetBrightnessMatrix(float amount, SkScalar matrix[20]) { | 30 void GetBrightnessMatrix(float amount, SkScalar matrix[20]) { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 GetOpacityMatrix(op.amount(), matrix); | 227 GetOpacityMatrix(op.amount(), matrix); |
223 return true; | 228 return true; |
224 } | 229 } |
225 case FilterOperation::COLOR_MATRIX: { | 230 case FilterOperation::COLOR_MATRIX: { |
226 memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); | 231 memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); |
227 return true; | 232 return true; |
228 } | 233 } |
229 case FilterOperation::BLUR: | 234 case FilterOperation::BLUR: |
230 case FilterOperation::DROP_SHADOW: | 235 case FilterOperation::DROP_SHADOW: |
231 case FilterOperation::ZOOM: | 236 case FilterOperation::ZOOM: |
237 case FilterOperation::REFERENCE: | |
232 return false; | 238 return false; |
233 } | 239 } |
234 NOTREACHED(); | 240 NOTREACHED(); |
235 return false; | 241 return false; |
236 } | 242 } |
237 | 243 |
244 skia::RefPtr<SkImageFilter> CreateMatrixImageFilter( | |
245 const SkScalar matrix[20], | |
246 skia::RefPtr<SkImageFilter> input) { | |
danakj
2013/09/09 22:04:50
const&?
ajuma
2013/09/10 21:17:58
Done.
| |
247 skia::RefPtr<SkColorFilter> color_filter = | |
248 skia::AdoptRef(new SkColorMatrixFilter(matrix)); | |
249 return skia::AdoptRef( | |
250 SkColorFilterImageFilter::Create(color_filter.get(), input.get())); | |
251 } | |
252 | |
238 class FilterBufferState { | 253 class FilterBufferState { |
239 public: | 254 public: |
240 FilterBufferState(GrContext* gr_context, | 255 FilterBufferState(GrContext* gr_context, |
241 gfx::SizeF size, | 256 gfx::SizeF size, |
242 unsigned texture_id) | 257 unsigned texture_id) |
243 : gr_context_(gr_context), | 258 : gr_context_(gr_context), |
244 current_texture_(0) { | 259 current_texture_(0) { |
245 // Wrap the source texture in a Ganesh platform texture. | 260 // Wrap the source texture in a Ganesh platform texture. |
246 GrBackendTextureDesc backend_texture_description; | 261 GrBackendTextureDesc backend_texture_description; |
247 backend_texture_description.fWidth = size.width(); | 262 backend_texture_description.fWidth = size.width(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 accumulated_color_matrix)); | 367 accumulated_color_matrix)); |
353 } | 368 } |
354 have_accumulated_color_matrix = false; | 369 have_accumulated_color_matrix = false; |
355 | 370 |
356 switch (op.type()) { | 371 switch (op.type()) { |
357 case FilterOperation::BLUR: | 372 case FilterOperation::BLUR: |
358 case FilterOperation::DROP_SHADOW: | 373 case FilterOperation::DROP_SHADOW: |
359 case FilterOperation::ZOOM: | 374 case FilterOperation::ZOOM: |
360 new_list.Append(op); | 375 new_list.Append(op); |
361 break; | 376 break; |
377 case FilterOperation::REFERENCE: | |
378 // Not supported on this code path. | |
379 NOTREACHED(); | |
362 case FilterOperation::BRIGHTNESS: | 380 case FilterOperation::BRIGHTNESS: |
363 case FilterOperation::SATURATING_BRIGHTNESS: | 381 case FilterOperation::SATURATING_BRIGHTNESS: |
364 case FilterOperation::CONTRAST: | 382 case FilterOperation::CONTRAST: |
365 case FilterOperation::GRAYSCALE: | 383 case FilterOperation::GRAYSCALE: |
366 case FilterOperation::SEPIA: | 384 case FilterOperation::SEPIA: |
367 case FilterOperation::SATURATE: | 385 case FilterOperation::SATURATE: |
368 case FilterOperation::HUE_ROTATE: | 386 case FilterOperation::HUE_ROTATE: |
369 case FilterOperation::INVERT: | 387 case FilterOperation::INVERT: |
370 case FilterOperation::OPACITY: | 388 case FilterOperation::OPACITY: |
371 case FilterOperation::COLOR_MATRIX: | 389 case FilterOperation::COLOR_MATRIX: |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
439 (height - (height / op.amount())) / 2.f, | 457 (height - (height / op.amount())) / 2.f, |
440 width / op.amount(), | 458 width / op.amount(), |
441 height / op.amount()), | 459 height / op.amount()), |
442 op.zoom_inset())); | 460 op.zoom_inset())); |
443 paint.setImageFilter(zoom_filter.get()); | 461 paint.setImageFilter(zoom_filter.get()); |
444 canvas->saveLayer(NULL, &paint); | 462 canvas->saveLayer(NULL, &paint); |
445 canvas->drawBitmap(state.Source(), 0, 0); | 463 canvas->drawBitmap(state.Source(), 0, 0); |
446 canvas->restore(); | 464 canvas->restore(); |
447 break; | 465 break; |
448 } | 466 } |
467 case FilterOperation::REFERENCE: | |
449 case FilterOperation::BRIGHTNESS: | 468 case FilterOperation::BRIGHTNESS: |
450 case FilterOperation::SATURATING_BRIGHTNESS: | 469 case FilterOperation::SATURATING_BRIGHTNESS: |
451 case FilterOperation::CONTRAST: | 470 case FilterOperation::CONTRAST: |
452 case FilterOperation::GRAYSCALE: | 471 case FilterOperation::GRAYSCALE: |
453 case FilterOperation::SEPIA: | 472 case FilterOperation::SEPIA: |
454 case FilterOperation::SATURATE: | 473 case FilterOperation::SATURATE: |
455 case FilterOperation::HUE_ROTATE: | 474 case FilterOperation::HUE_ROTATE: |
456 case FilterOperation::INVERT: | 475 case FilterOperation::INVERT: |
457 case FilterOperation::OPACITY: | 476 case FilterOperation::OPACITY: |
458 NOTREACHED(); | 477 NOTREACHED(); |
459 break; | 478 break; |
460 } | 479 } |
461 state.Swap(); | 480 state.Swap(); |
462 } | 481 } |
463 return state.Source(); | 482 return state.Source(); |
464 } | 483 } |
465 | 484 |
485 skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter( | |
486 const FilterOperations& filters, | |
487 gfx::SizeF size) { | |
488 skia::RefPtr<SkImageFilter> image_filter; | |
489 SkScalar matrix[20]; | |
490 for (size_t i = 0; i < filters.size(); ++i) { | |
491 const FilterOperation& op = filters.at(i); | |
492 switch (op.type()) { | |
493 case FilterOperation::GRAYSCALE: | |
494 GetGrayscaleMatrix(1 - op.amount(), matrix); | |
danakj
2013/09/09 22:04:50
1.f here and below
ajuma
2013/09/10 21:17:58
Done.
| |
495 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
496 break; | |
497 case FilterOperation::SEPIA: | |
498 GetSepiaMatrix(1 - op.amount(), matrix); | |
499 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
500 break; | |
501 case FilterOperation::SATURATE: | |
502 GetSaturateMatrix(op.amount(), matrix); | |
503 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
504 break; | |
505 case FilterOperation::HUE_ROTATE: | |
506 GetHueRotateMatrix(op.amount(), matrix); | |
507 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
508 break; | |
509 case FilterOperation::INVERT: | |
510 GetInvertMatrix(op.amount(), matrix); | |
511 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
512 break; | |
513 case FilterOperation::OPACITY: | |
514 GetOpacityMatrix(op.amount(), matrix); | |
515 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
516 break; | |
517 case FilterOperation::BRIGHTNESS: | |
518 GetBrightnessMatrix(op.amount(), matrix); | |
519 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
520 break; | |
521 case FilterOperation::CONTRAST: | |
522 GetContrastMatrix(op.amount(), matrix); | |
523 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
524 break; | |
525 case FilterOperation::BLUR: | |
526 image_filter = skia::AdoptRef(new SkBlurImageFilter( | |
527 op.amount(), op.amount(), image_filter.get())); | |
528 break; | |
529 case FilterOperation::DROP_SHADOW: | |
530 image_filter = skia::AdoptRef(new SkDropShadowImageFilter( | |
531 SkIntToScalar(op.drop_shadow_offset().x()), | |
532 SkIntToScalar(op.drop_shadow_offset().y()), | |
533 SkIntToScalar(op.amount()), | |
534 op.drop_shadow_color(), | |
535 image_filter.get())); | |
536 break; | |
537 case FilterOperation::COLOR_MATRIX: | |
538 image_filter = CreateMatrixImageFilter(op.matrix(), image_filter); | |
539 break; | |
540 case FilterOperation::ZOOM: { | |
541 skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( | |
542 new SkMagnifierImageFilter( | |
543 SkRect::MakeXYWH( | |
544 (size.width() - (size.width() / op.amount())) / 2.f, | |
545 (size.height() - (size.height() / op.amount())) / 2.f, | |
546 size.width() / op.amount(), | |
547 size.height() / op.amount()), | |
548 op.zoom_inset())); | |
549 if (image_filter.get()) { | |
550 // TODO(ajuma): When there's a 1-input version of | |
551 // SkMagnifierImageFilter, use that to handle the input filter | |
552 // instead of using an SkComposeImageFilter. | |
553 image_filter = skia::AdoptRef(new SkComposeImageFilter( | |
554 zoom_filter.get(), image_filter.get())); | |
555 } else { | |
556 image_filter = zoom_filter; | |
557 } | |
558 break; | |
559 } | |
560 case FilterOperation::SATURATING_BRIGHTNESS: | |
561 GetSaturatingBrightnessMatrix(op.amount(), matrix); | |
562 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
563 break; | |
564 case FilterOperation::REFERENCE: { | |
565 skia::RefPtr<SkColorFilter> cf; | |
566 | |
567 { | |
568 SkColorFilter* colorfilter_rawptr = NULL; | |
569 op.image_filter()->asColorFilter(&colorfilter_rawptr); | |
570 cf = skia::AdoptRef(colorfilter_rawptr); | |
571 } | |
572 | |
573 if (cf && cf->asColorMatrix(matrix) && | |
574 !op.image_filter()->getInput(0)) { | |
575 image_filter = CreateMatrixImageFilter(matrix, image_filter); | |
576 } else if (image_filter.get()) { | |
danakj
2013/09/09 22:04:50
do you mean else if (op.image_filter())? if so, m
ajuma
2013/09/10 21:17:58
No, this is checking if we've already build up a p
| |
577 image_filter = skia::AdoptRef(new SkComposeImageFilter( | |
578 op.image_filter().get(), image_filter.get())); | |
579 } else { | |
580 image_filter = op.image_filter(); | |
581 } | |
582 break; | |
583 } | |
584 } | |
585 } | |
586 return image_filter; | |
587 } | |
588 | |
466 } // namespace cc | 589 } // namespace cc |
OLD | NEW |