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

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

Issue 1829493002: [SPv2] Implement CSS clip property (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move fixedpos clip to updateOutOfFlowContext Created 4 years, 9 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/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "core/layout/LayoutPart.h" 8 #include "core/layout/LayoutPart.h"
9 #include "core/layout/LayoutView.h" 9 #include "core/layout/LayoutView.h"
10 #include "core/paint/ObjectPaintProperties.h" 10 #include "core/paint/ObjectPaintProperties.h"
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context) 207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context)
208 { 208 {
209 const ComputedStyle& style = object.styleRef(); 209 const ComputedStyle& style = object.styleRef();
210 if (!style.hasOpacity()) 210 if (!style.hasOpacity())
211 return nullptr; 211 return nullptr;
212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); 212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect);
213 context.currentEffect = newEffectNode.get(); 213 context.currentEffect = newEffectNode.get();
214 return newEffectNode.release(); 214 return newEffectNode.release();
215 } 215 }
216 216
217 static PassRefPtr<ClipPaintPropertyNode> createCSSClipIfNeeded(const LayoutObjec t& object, PaintPropertyTreeBuilderContext& context)
218 {
219 if (!object.hasClip())
220 return nullptr;
221 ASSERT(object.canContainAbsolutePositionObjects());
222
223 // Create clip node for descendants that are not fixed position.
224 // We don't have to setup context.clipForAbsolutePosition here because this object must be
225 // a container for absolute position descendants, and will copy from in-flow context later
226 // at updateOutOfFlowContext() step.
227 LayoutRect clipRect = toLayoutBox(object).clipRect(context.paintOffset);
228 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = ClipPaintPropertyNode: :create(
229 context.currentTransform,
230 FloatRoundedRect(FloatRect(clipRect)),
231 context.currentClip);
232 context.currentClip = newClipNodeForCSSClip.get();
233
234 return newClipNodeForCSSClip.release();
235 }
236
217 // TODO(trchen): Remove this once we bake the paint offset into frameRect. 237 // TODO(trchen): Remove this once we bake the paint offset into frameRect.
218 static PassRefPtr<TransformPaintPropertyNode> createScrollbarPaintOffsetIfNeeded (const LayoutObject& object, PaintPropertyTreeBuilderContext& context) 238 static PassRefPtr<TransformPaintPropertyNode> createScrollbarPaintOffsetIfNeeded (const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
219 { 239 {
220 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); 240 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset);
221 if (roundedPaintOffset == IntPoint()) 241 if (roundedPaintOffset == IntPoint())
222 return nullptr; 242 return nullptr;
223 243
224 if (!object.isBoxModelObject()) 244 if (!object.isBoxModelObject())
225 return nullptr; 245 return nullptr;
226 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge tScrollableArea(); 246 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge tScrollableArea();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 if (scrollOffset.isZero() && !layer->scrollsOverflow()) 322 if (scrollOffset.isZero() && !layer->scrollsOverflow())
303 return nullptr; 323 return nullptr;
304 324
305 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( 325 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create(
306 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), 326 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()),
307 FloatPoint3D(), context.currentTransform); 327 FloatPoint3D(), context.currentTransform);
308 context.currentTransform = newTransformNodeForScrollTranslation.get(); 328 context.currentTransform = newTransformNodeForScrollTranslation.get();
309 return newTransformNodeForScrollTranslation.release(); 329 return newTransformNodeForScrollTranslation.release();
310 } 330 }
311 331
312 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree BuilderContext& context) 332 static void updateOutOfFlowContext(RefPtr<ClipPaintPropertyNode>& newClipNodeFor CSSClipFixedPosition, const LayoutObject& object, PaintPropertyTreeBuilderContex t& context, ClipPaintPropertyNode* newClipNodeForCSSClip)
jbroman 2016/03/23 17:16:51 This argument order is very surprising to me. Norm
trchen 2016/03/24 00:53:58 Done. I learned Intel syntax when I was young and
313 { 333 {
314 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the currentTransform is 334 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the currentTransform is
315 // up-to-date for all children of the svg root element. Additionally, inside SVG, all positioning 335 // up-to-date for all children of the svg root element. Additionally, inside SVG, all positioning
316 // uses transforms. Therefore, we only need to check createdNewTransform and isSVGRoot() to 336 // uses transforms. Therefore, we only need to check createdNewTransform and isSVGRoot() to
317 // ensure out-of-flow and fixed positioning is correct at the svg->html boun dary. 337 // ensure out-of-flow and fixed positioning is correct at the svg->html boun dary.
318 338
319 if (object.canContainAbsolutePositionObjects()) { 339 if (object.canContainAbsolutePositionObjects()) {
320 context.transformForAbsolutePosition = context.currentTransform; 340 context.transformForAbsolutePosition = context.currentTransform;
321 context.paintOffsetForAbsolutePosition = context.paintOffset; 341 context.paintOffsetForAbsolutePosition = context.paintOffset;
322 context.clipForAbsolutePosition = context.currentClip; 342 context.clipForAbsolutePosition = context.currentClip;
323 } 343 }
324 344
325 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram eView 345 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram eView
326 // paint properties for rootLayerScrolls. 346 // paint properties for rootLayerScrolls.
327 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { 347 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) {
328 context.transformForFixedPosition = context.currentTransform; 348 context.transformForFixedPosition = context.currentTransform;
329 context.paintOffsetForFixedPosition = context.paintOffset; 349 context.paintOffsetForFixedPosition = context.paintOffset;
330 context.clipForFixedPosition = context.currentClip; 350 context.clipForFixedPosition = context.currentClip;
351 } else if (newClipNodeForCSSClip) {
352 // CSS clip applies to all descendants, even if this object is not a con taining block
353 // ancestor of the descendant. It is okay for absolute-position descenda nts because
354 // having CSS clip implies being absolute position container. However fo r fixed-position
355 // descendants we need to insert the clip here if we are not a containin g block ancestor
356 // of them.
357
358 // Before we actually create anything, check whether in-flow context and fixed-position
359 // context has exactly the same clip. Reuse if possible.
360 if (context.clipForFixedPosition == newClipNodeForCSSClip->parent()) {
361 context.clipForFixedPosition = newClipNodeForCSSClip;
362 return;
363 }
364
365 newClipNodeForCSSClipFixedPosition = ClipPaintPropertyNode::create(
366 const_cast<TransformPaintPropertyNode*>(newClipNodeForCSSClip->local TransformSpace()),
jbroman 2016/03/23 17:16:51 const_cast makes me sad. I suspect one of these th
trchen 2016/03/24 00:53:58 I don't know... We need it non-const only for refe
jbroman 2016/03/24 01:03:39 Oh, weird. Both Chromium's and Skia's have it as m
367 newClipNodeForCSSClip->clipRect(),
368 context.clipForFixedPosition);
369 context.clipForFixedPosition = newClipNodeForCSSClipFixedPosition.get();
331 } 370 }
332 } 371 }
333 372
334 static PassOwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordTreeCon textIfNeeded(LayoutObject& object, const PaintPropertyTreeBuilderContext& contex t) 373 static PassOwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordTreeCon textIfNeeded(LayoutObject& object, const PaintPropertyTreeBuilderContext& contex t)
335 { 374 {
336 // Note: Currently only layer painter makes use of the pre-computed context. 375 // Note: Currently only layer painter makes use of the pre-computed context.
337 // This condition may be loosened with no adverse effects beside memory use. 376 // This condition may be loosened with no adverse effects beside memory use.
338 if (!object.hasLayer()) 377 if (!object.hasLayer())
339 return nullptr; 378 return nullptr;
340 379
341 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordedContext = ad optPtr(new ObjectPaintProperties::LocalBorderBoxProperties); 380 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> recordedContext = ad optPtr(new ObjectPaintProperties::LocalBorderBoxProperties);
342 recordedContext->paintOffset = context.paintOffset; 381 recordedContext->paintOffset = context.paintOffset;
343 recordedContext->transform = context.currentTransform; 382 recordedContext->transform = context.currentTransform;
344 recordedContext->clip = context.currentClip; 383 recordedContext->clip = context.currentClip;
345 recordedContext->effect = context.currentEffect; 384 recordedContext->effect = context.currentEffect;
346 return recordedContext.release(); 385 return recordedContext.release();
347 } 386 }
348 387
349 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre eBuilderContext& context) 388 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre eBuilderContext& context)
350 { 389 {
351 PaintPropertyTreeBuilderContext localContext(context); 390 PaintPropertyTreeBuilderContext localContext(context);
352 391
353 deriveBorderBoxFromContainerContext(object, localContext); 392 deriveBorderBoxFromContainerContext(object, localContext);
354 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); 393 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext);
355 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); 394 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext);
356 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); 395 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext);
396 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = createCSSClipIfNeeded( object, localContext);
357 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext = recordTreeContextIfNeeded(object, localContext); 397 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext = recordTreeContextIfNeeded(object, localContext);
358 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset = createScrollbarPaintOffsetIfNeeded(object, localContext); 398 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset = createScrollbarPaintOffsetIfNeeded(object, localContext);
359 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli pIfNeeded(object, localContext); 399 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli pIfNeeded(object, localContext);
360 // TODO(trchen): Insert flattening transform here, as specified by 400 // TODO(trchen): Insert flattening transform here, as specified by
361 // http://www.w3.org/TR/css3-transforms/#transform-style-property 401 // http://www.w3.org/TR/css3-transforms/#transform-style-property
362 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); 402 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext);
363 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); 403 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext);
364 updateOutOfFlowContext(object, localContext); 404 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClipFixedPosition;
405 updateOutOfFlowContext(newClipNodeForCSSClipFixedPosition, object, localCont ext, newClipNodeForCSSClip.get());
365 406
366 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newClipNodeForOverflowClip || newTransformNodeForPerspecti ve || newTransformNodeForScrollTranslation || newTransformNodeForScrollbarPaintO ffset || newRecordedContext) { 407 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newClipNodeForCSSClip || newClipNodeForCSSClipFixedPositio n || newClipNodeForOverflowClip || newTransformNodeForPerspective || newTransfor mNodeForScrollTranslation || newTransformNodeForScrollbarPaintOffset || newRecor dedContext) {
367 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( 408 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create(
368 newTransformNodeForPaintOffsetTranslation.release(), 409 newTransformNodeForPaintOffsetTranslation.release(),
369 newTransformNodeForTransform.release(), 410 newTransformNodeForTransform.release(),
370 newEffectNode.release(), 411 newEffectNode.release(),
412 newClipNodeForCSSClip.release(),
413 newClipNodeForCSSClipFixedPosition.release(),
371 newClipNodeForOverflowClip.release(), 414 newClipNodeForOverflowClip.release(),
372 newTransformNodeForPerspective.release(), 415 newTransformNodeForPerspective.release(),
373 newTransformNodeForScrollTranslation.release(), 416 newTransformNodeForScrollTranslation.release(),
374 newTransformNodeForScrollbarPaintOffset.release(), 417 newTransformNodeForScrollbarPaintOffset.release(),
375 newRecordedContext.release()); 418 newRecordedContext.release());
376 object.setObjectPaintProperties(updatedPaintProperties.release()); 419 object.setObjectPaintProperties(updatedPaintProperties.release());
377 } else { 420 } else {
378 object.clearObjectPaintProperties(); 421 object.clearObjectPaintProperties();
379 } 422 }
380 423
381 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { 424 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) {
382 if (child->isBoxModelObject() || child->isSVG()) 425 if (child->isBoxModelObject() || child->isSVG())
383 walk(*child, localContext); 426 walk(*child, localContext);
384 } 427 }
385 428
386 if (object.isLayoutPart()) { 429 if (object.isLayoutPart()) {
387 Widget* widget = toLayoutPart(object).widget(); 430 Widget* widget = toLayoutPart(object).widget();
388 if (widget && widget->isFrameView()) 431 if (widget && widget->isFrameView())
389 walk(*toFrameView(widget), localContext); 432 walk(*toFrameView(widget), localContext);
390 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 433 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
391 } 434 }
392 } 435 }
393 436
394 } // namespace blink 437 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698