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

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp

Issue 2641173008: [SPv2] Add CSS mask support (Closed)
Patch Set: Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "core/paint/PaintPropertyTreeBuilder.h" 5 #include "core/paint/PaintPropertyTreeBuilder.h"
6 6
7 #include "core/dom/DOMNodeIds.h" 7 #include "core/dom/DOMNodeIds.h"
8 #include "core/frame/FrameView.h" 8 #include "core/frame/FrameView.h"
9 #include "core/frame/LocalFrame.h" 9 #include "core/frame/LocalFrame.h"
10 #include "core/frame/Settings.h" 10 #include "core/frame/Settings.h"
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 context.current.renderingContextId = 423 context.current.renderingContextId =
424 properties->transform()->renderingContextId(); 424 properties->transform()->renderingContextId();
425 context.current.shouldFlattenInheritedTransform = false; 425 context.current.shouldFlattenInheritedTransform = false;
426 } else { 426 } else {
427 context.current.renderingContextId = 0; 427 context.current.renderingContextId = 0;
428 context.current.shouldFlattenInheritedTransform = true; 428 context.current.shouldFlattenInheritedTransform = true;
429 } 429 }
430 } 430 }
431 } 431 }
432 432
433 void PaintPropertyTreeBuilder::updateMask(
434 const LayoutObject& object,
435 PaintPropertyTreeBuilderContext& context) {
436 DCHECK(object.isBoxModelObject() || object.isSVGChild());
437 const ComputedStyle& style = object.styleRef();
438
439 bool hasMask = false;
440 IntRect maskClip;
441 if (object.isSVGChild()) {
442 // TODO(trchen): Figure out what to do with SVG. SVG may use object
443 // bounding box for mask sizing, but computing it requires property
444 // tree to be built.
445 } else if (style.hasMask()) {
446 // For HTML/CSS objects, the extent of the mask is known as "mask
447 // painting area", which is determined by CSS mask-clip property.
448 // We don't implement mask-clip:margin-box or no-clip currently,
449 // so the maximum we can get is border-box.
450 LayoutRect maximumMaskRegion;
451 if (object.isBox()) {
452 maximumMaskRegion = toLayoutBox(object).borderBoxRect();
453 } else {
454 // For inline elements, depends on the value of box-decoration-break
455 // there could be one box in multiple fragments or multiple boxes.
456 // Either way here we are only interested in the bounding box of them.
457 DCHECK(object.isLayoutInline());
458 maximumMaskRegion = toLayoutInline(object).linesBoundingBox();
459 }
460 maximumMaskRegion.moveBy(context.current.paintOffset);
461 maskClip = enclosingIntRect(maximumMaskRegion);
462 hasMask = true;
463 }
464
465 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) {
466 if (hasMask) {
467 SkBlendMode blendMode = object.isBlendingAllowed()
468 ? WebCoreCompositeToSkiaComposite(
469 CompositeSourceOver, style.blendMode())
470 : SkBlendMode::kSrcOver;
471 float opacity = style.opacity();
472
473 auto& properties = object.getMutableForPainting().ensurePaintProperties();
474 context.forceSubtreeUpdate |= properties.updateMaskClip(
475 context.current.clip, context.current.transform,
476 FloatRoundedRect(maskClip));
477 context.forceSubtreeUpdate |= properties.updateMaskIsolation(
478 context.currentEffect, context.current.transform,
479 properties.maskClip(), CompositorFilterOperations(), opacity,
480 blendMode, CompositingReasonNone, CompositorElementId());
481 context.forceSubtreeUpdate |= properties.updateMaskContent(
482 properties.maskIsolation(), context.current.transform,
483 properties.maskClip(), CompositorFilterOperations(), 1.f,
484 SkBlendMode::kDstIn, CompositingReasonNone, CompositorElementId());
485 } else if (auto* properties =
486 object.getMutableForPainting().paintProperties()) {
487 context.forceSubtreeUpdate |= properties->clearMaskClip();
488 context.forceSubtreeUpdate |= properties->clearMaskIsolation();
489 context.forceSubtreeUpdate |= properties->clearMaskContent();
490 }
491 }
492
493 if (hasMask) {
494 auto& properties = *object.getMutableForPainting().paintProperties();
495 context.inputClipOfCurrentEffect = context.current.clip =
496 context.absolutePosition.clip = context.fixedPosition.clip =
497 properties.maskClip();
498 context.currentEffect = properties.maskIsolation();
499 }
500 }
501
433 void PaintPropertyTreeBuilder::updateEffect( 502 void PaintPropertyTreeBuilder::updateEffect(
434 const LayoutObject& object, 503 const LayoutObject& object,
435 PaintPropertyTreeBuilderContext& context) { 504 PaintPropertyTreeBuilderContext& context) {
436 const ComputedStyle& style = object.styleRef(); 505 const ComputedStyle& style = object.styleRef();
437 506
438 const bool isCSSIsolatedGroup = 507 const bool isCSSIsolatedGroup =
439 object.isBoxModelObject() && style.isStackingContext(); 508 object.isBoxModelObject() && style.isStackingContext();
440 if (!isCSSIsolatedGroup && !object.isSVGChild()) { 509 if (!isCSSIsolatedGroup && !object.isSVGChild()) {
441 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) { 510 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) {
442 if (auto* properties = object.getMutableForPainting().paintProperties()) 511 if (auto* properties = object.getMutableForPainting().paintProperties())
443 context.forceSubtreeUpdate |= properties->clearEffect(); 512 context.forceSubtreeUpdate |= properties->clearEffect();
444 } 513 }
445 return; 514 return;
446 } 515 }
447 516
448 // TODO(trchen): Can't omit effect node if we have 3D children. 517 // TODO(trchen): Can't omit effect node if we have 3D children.
449 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) { 518 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) {
519 bool blendModeAndOpacityAlreadyApplied = false;
trchen 2017/01/21 01:27:08 I feel this blend mode & opacity juggling will mak
chrishtr 2017/01/24 01:16:28 How about just making different nodes for all of t
trchen 2017/02/11 02:35:45 As discussed offline. Kick filter out is the most
520 if (auto* properties = object.getMutableForPainting().paintProperties())
521 blendModeAndOpacityAlreadyApplied = !!properties->maskIsolation();
522
450 bool effectNodeNeeded = false; 523 bool effectNodeNeeded = false;
451 524
452 // Can't omit effect node if we have paint children with exotic blending. 525 // Can't omit effect node if we have paint children with exotic blending.
453 if (object.isSVG()) { 526 if (blendModeAndOpacityAlreadyApplied) {
527 // No-op. The current effect node already isolated for us.
528 } else if (object.isSVG()) {
454 // Yes, including LayoutSVGRoot, because SVG layout objects don't create 529 // Yes, including LayoutSVGRoot, because SVG layout objects don't create
455 // PaintLayer so PaintLayer::hasNonIsolatedDescendantWithBlendMode() 530 // PaintLayer so PaintLayer::hasNonIsolatedDescendantWithBlendMode()
456 // doesn't catch SVG descendants. 531 // doesn't catch SVG descendants.
457 if (SVGLayoutSupport::isIsolationRequired(&object)) 532 if (SVGLayoutSupport::isIsolationRequired(&object))
458 effectNodeNeeded = true; 533 effectNodeNeeded = true;
459 } else if (PaintLayer* layer = toLayoutBoxModelObject(object).layer()) { 534 } else if (PaintLayer* layer = toLayoutBoxModelObject(object).layer()) {
460 if (layer->hasNonIsolatedDescendantWithBlendMode()) 535 if (layer->hasNonIsolatedDescendantWithBlendMode())
461 effectNodeNeeded = true; 536 effectNodeNeeded = true;
462 } 537 }
463 538
464 SkBlendMode blendMode = object.isBlendingAllowed() 539 SkBlendMode blendMode =
465 ? WebCoreCompositeToSkiaComposite( 540 (!blendModeAndOpacityAlreadyApplied && object.isBlendingAllowed())
466 CompositeSourceOver, style.blendMode()) 541 ? WebCoreCompositeToSkiaComposite(CompositeSourceOver,
467 : SkBlendMode::kSrcOver; 542 style.blendMode())
543 : SkBlendMode::kSrcOver;
468 if (blendMode != SkBlendMode::kSrcOver) 544 if (blendMode != SkBlendMode::kSrcOver)
469 effectNodeNeeded = true; 545 effectNodeNeeded = true;
470 546
471 float opacity = style.opacity(); 547 float opacity = blendModeAndOpacityAlreadyApplied ? 1.0f : style.opacity();
472 if (opacity != 1.0f) 548 if (opacity != 1.0f)
473 effectNodeNeeded = true; 549 effectNodeNeeded = true;
474 550
475 CompositorFilterOperations filter; 551 CompositorFilterOperations filter;
476 if (object.isSVGChild()) { 552 if (object.isSVGChild()) {
477 // TODO(trchen): SVG caches filters in SVGResources. Implement it. 553 // TODO(trchen): SVG caches filters in SVGResources. Implement it.
478 } else if (PaintLayer* layer = toLayoutBoxModelObject(object).layer()) { 554 } else if (PaintLayer* layer = toLayoutBoxModelObject(object).layer()) {
479 // TODO(trchen): Eliminate PaintLayer dependency. 555 // TODO(trchen): Eliminate PaintLayer dependency.
480 filter = layer->createCompositorFilterOperationsForFilter(style); 556 filter = layer->createCompositorFilterOperationsForFilter(style);
481 } 557 }
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 void PaintPropertyTreeBuilder::updatePropertiesForSelf( 1031 void PaintPropertyTreeBuilder::updatePropertiesForSelf(
956 const LayoutObject& object, 1032 const LayoutObject& object,
957 PaintPropertyTreeBuilderContext& context) { 1033 PaintPropertyTreeBuilderContext& context) {
958 #if DCHECK_IS_ON() 1034 #if DCHECK_IS_ON()
959 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object, context); 1035 FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object, context);
960 #endif 1036 #endif
961 1037
962 if (object.isBoxModelObject() || object.isSVG()) { 1038 if (object.isBoxModelObject() || object.isSVG()) {
963 updatePaintOffsetTranslation(object, context); 1039 updatePaintOffsetTranslation(object, context);
964 updateTransform(object, context); 1040 updateTransform(object, context);
1041 updateMask(object, context);
965 updateEffect(object, context); 1042 updateEffect(object, context);
966 updateCssClip(object, context); 1043 updateCssClip(object, context);
967 updateLocalBorderBoxContext(object, context); 1044 updateLocalBorderBoxContext(object, context);
968 updateScrollbarPaintOffset(object, context); 1045 updateScrollbarPaintOffset(object, context);
969 } 1046 }
970 1047
971 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) { 1048 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) {
972 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && 1049 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() &&
973 object.paintOffset() != context.current.paintOffset) { 1050 object.paintOffset() != context.current.paintOffset) {
974 object.getMutableForPainting().setShouldDoFullPaintInvalidation( 1051 object.getMutableForPainting().setShouldDoFullPaintInvalidation(
(...skipping 16 matching lines...) Expand all
991 updateOverflowClip(object, context); 1068 updateOverflowClip(object, context);
992 updatePerspective(object, context); 1069 updatePerspective(object, context);
993 updateSvgLocalToBorderBoxTransform(object, context); 1070 updateSvgLocalToBorderBoxTransform(object, context);
994 updateScrollAndScrollTranslation(object, context); 1071 updateScrollAndScrollTranslation(object, context);
995 updateOutOfFlowContext(object, context); 1072 updateOutOfFlowContext(object, context);
996 1073
997 context.forceSubtreeUpdate |= object.subtreeNeedsPaintPropertyUpdate(); 1074 context.forceSubtreeUpdate |= object.subtreeNeedsPaintPropertyUpdate();
998 } 1075 }
999 1076
1000 } // namespace blink 1077 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698