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

Side by Side Diff: sky/engine/core/rendering/RenderBox.cpp

Issue 899753003: Walk render tree instead of render layers for paint. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: address review comments Created 5 years, 10 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
« no previous file with comments | « sky/engine/core/rendering/RenderBox.h ('k') | sky/engine/core/rendering/RenderFlexibleBox.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 19 matching lines...) Expand all
30 #include <algorithm> 30 #include <algorithm>
31 #include "sky/engine/core/dom/Document.h" 31 #include "sky/engine/core/dom/Document.h"
32 #include "sky/engine/core/editing/htmlediting.h" 32 #include "sky/engine/core/editing/htmlediting.h"
33 #include "sky/engine/core/frame/FrameHost.h" 33 #include "sky/engine/core/frame/FrameHost.h"
34 #include "sky/engine/core/frame/FrameView.h" 34 #include "sky/engine/core/frame/FrameView.h"
35 #include "sky/engine/core/frame/LocalFrame.h" 35 #include "sky/engine/core/frame/LocalFrame.h"
36 #include "sky/engine/core/frame/Settings.h" 36 #include "sky/engine/core/frame/Settings.h"
37 #include "sky/engine/core/html/HTMLElement.h" 37 #include "sky/engine/core/html/HTMLElement.h"
38 #include "sky/engine/core/page/EventHandler.h" 38 #include "sky/engine/core/page/EventHandler.h"
39 #include "sky/engine/core/page/Page.h" 39 #include "sky/engine/core/page/Page.h"
40 #include "sky/engine/core/rendering/FilterEffectRenderer.h"
40 #include "sky/engine/core/rendering/HitTestResult.h" 41 #include "sky/engine/core/rendering/HitTestResult.h"
41 #include "sky/engine/core/rendering/PaintInfo.h" 42 #include "sky/engine/core/rendering/PaintInfo.h"
42 #include "sky/engine/core/rendering/RenderFlexibleBox.h" 43 #include "sky/engine/core/rendering/RenderFlexibleBox.h"
43 #include "sky/engine/core/rendering/RenderGeometryMap.h" 44 #include "sky/engine/core/rendering/RenderGeometryMap.h"
44 #include "sky/engine/core/rendering/RenderInline.h" 45 #include "sky/engine/core/rendering/RenderInline.h"
45 #include "sky/engine/core/rendering/RenderLayer.h" 46 #include "sky/engine/core/rendering/RenderLayer.h"
46 #include "sky/engine/core/rendering/RenderView.h" 47 #include "sky/engine/core/rendering/RenderView.h"
47 #include "sky/engine/platform/LengthFunctions.h" 48 #include "sky/engine/platform/LengthFunctions.h"
48 #include "sky/engine/platform/geometry/FloatQuad.h" 49 #include "sky/engine/platform/geometry/FloatQuad.h"
49 #include "sky/engine/platform/geometry/TransformState.h" 50 #include "sky/engine/platform/geometry/TransformState.h"
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 updateHitTestResult(result, locationInContainer.point() - toLayoutSize(a djustedLocation)); 382 updateHitTestResult(result, locationInContainer.point() - toLayoutSize(a djustedLocation));
382 if (!result.addNodeToRectBasedTestResult(node(), request, locationInCont ainer, boundsRect)) 383 if (!result.addNodeToRectBasedTestResult(node(), request, locationInCont ainer, boundsRect))
383 return true; 384 return true;
384 } 385 }
385 386
386 return false; 387 return false;
387 } 388 }
388 389
389 // --------------------- painting stuff ------------------------------- 390 // --------------------- painting stuff -------------------------------
390 391
391 void RenderBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 392 static inline bool compareZIndex(RenderBox* first, RenderBox* second)
393 {
394 return first->style()->zIndex() < second->style()->zIndex();
395 }
396
397 void RenderBox::paintLayer(GraphicsContext* context, RenderLayer* rootLayer, con st IntRect& rect)
398 {
399 // If this layer is totally invisible then there is nothing to paint.
400 // TODO(ojan): Return false from isSelfPainting and then ASSERT(!opacity()) here.
401 if (!opacity())
402 return;
403
404 LayerPaintingInfo paintingInfo(rootLayer, rect, LayoutSize());
405
406 if (!layer()->paintsWithTransform()) {
407 paintLayerContents(context, paintingInfo, rect);
408 return;
409 }
410
411 TransformationMatrix layerTransform = layer()->renderableTransform();
412 // If the transform can't be inverted, then don't paint anything.
413 if (!layerTransform.isInvertible())
414 return;
415
416 // If we have a transparency layer enclosing us and we are the root of a tra nsform, then we need to establish the transparency
417 // layer from the parent now, assuming there is a parent
418 if (layer()->isTransparent()) {
419 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branchin g since the
420 // RenderView can't be transformed in sky.
421 if (layer()->parent())
422 layer()->parent()->beginTransparencyLayers(context, paintingInfo.roo tLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation);
423 else
424 layer()->beginTransparencyLayers(context, paintingInfo.rootLayer, pa intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation);
425 }
426
427 // Make sure the parent's clip rects have been calculated.
428 ClipRect clipRect;
429 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branching si nce the
430 // RenderView can't be transformed in sky.
431 if (layer()->parent()) {
432 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, PaintingClipRe cts);
433 clipRect = layer()->clipper().backgroundClipRect(clipRectsContext);
434 clipRect.intersect(paintingInfo.paintDirtyRect);
435
436 // Push the parent coordinate space's clip.
437 layer()->parent()->clipToRect(paintingInfo, context, clipRect);
438 }
439
440 // This involves subtracting out the position of the layer in our current co ordinate space, but preserving
441 // the accumulated error for sub-pixel layout.
442 LayoutPoint delta;
443 layer()->convertToLayerCoords(paintingInfo.rootLayer, delta);
444 TransformationMatrix transform(layer()->renderableTransform());
445 IntPoint roundedDelta = roundedIntPoint(delta);
446 transform.translateRight(roundedDelta.x(), roundedDelta.y());
447 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
448
449 // Apply the transform.
450 GraphicsContextStateSaver stateSaver(*context, false);
451 if (!transform.isIdentity()) {
452 stateSaver.save();
453 context->concatCTM(transform.toAffineTransform());
454 }
455
456 // Now do a paint with the root layer shifted to be us.
457 LayerPaintingInfo transformedPaintingInfo(layer(), enclosingIntRect(transfor m.inverse().mapRect(paintingInfo.paintDirtyRect)),
458 adjustedSubPixelAccumulation);
459 paintLayerContents(context, transformedPaintingInfo, rect);
460
461 // Restore the clip.
462 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branching si nce the
463 // RenderView can't be transformed in sky.
464 if (layer()->parent())
465 layer()->parent()->restoreClip(context, paintingInfo.paintDirtyRect, cli pRect);
466 }
467
468 void RenderBox::paintLayerContents(GraphicsContext* context, const LayerPainting Info& paintingInfo, const IntRect& rect)
469 {
470 float deviceScaleFactor = blink::deviceScaleFactor(frame());
471 context->setDeviceScaleFactor(deviceScaleFactor);
472
473 GraphicsContext* transparencyLayerContext = context;
474
475 LayoutPoint offsetFromRoot;
476 layer()->convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
477
478 LayoutRect rootRelativeBounds;
479 bool rootRelativeBoundsComputed = false;
480
481 // Apply clip-path to context.
482 GraphicsContextStateSaver clipStateSaver(*context, false);
483
484 // Clip-path, like border radius, must not be applied to the contents of a c omposited-scrolling container.
485 // It must, however, still be applied to the mask layer, so that the composi tor can properly mask the
486 // scrolling contents and scrollbars.
487 // TODO(ojan): This style null check doesn't make sense. We should always ha ve a style.
488 if (hasClipPath() && style()) {
489 ASSERT(style()->clipPath());
490 if (style()->clipPath()->type() == ClipPathOperation::SHAPE) {
491 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()- >clipPath());
492 if (clipPath->isValid()) {
493 clipStateSaver.save();
494
495 if (!rootRelativeBoundsComputed) {
496 rootRelativeBounds = layer()->physicalBoundingBoxIncludingRe flectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
497 rootRelativeBoundsComputed = true;
498 }
499
500 context->clipPath(clipPath->path(rootRelativeBounds), clipPath-> windRule());
501 }
502 }
503 }
504
505 LayerPaintingInfo localPaintingInfo(paintingInfo);
506 FilterEffectRendererHelper filterPainter(layer()->filterRenderer() && layer( )->paintsWithFilters());
507
508 LayoutRect layerBounds;
509 // FIXME(sky): Remove foregroundRect. It's unused.
510 ClipRect contentRect, foregroundRect;
511 ClipRectsContext clipRectsContext(localPaintingInfo.rootLayer, PaintingClipR ects, localPaintingInfo.subPixelAccumulation);
512 layer()->clipper().calculateRects(clipRectsContext, localPaintingInfo.paintD irtyRect,
513 layerBounds, contentRect, foregroundRect,
514 &offsetFromRoot);
515
516 bool shouldPaintContent = layer()->intersectsDamageRect(layerBounds, content Rect.rect(), localPaintingInfo.rootLayer, &offsetFromRoot);
517
518 bool haveTransparency = layer()->isTransparent();
519
520 if (filterPainter.haveFilterEffect()) {
521 ASSERT(layer()->filterInfo());
522
523 if (!rootRelativeBoundsComputed)
524 rootRelativeBounds = layer()->physicalBoundingBoxIncludingReflection AndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
525
526 if (filterPainter.prepareFilterEffect(layer(), rootRelativeBounds, paint ingInfo.paintDirtyRect)) {
527 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
528 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
529 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that
530 // beginTransparencyLayers will only create a single lazy transparen cy layer, even though it is called twice in this method.
531 // With deferred filters, we don't need a separate context, but we d o need to do transparency and clipping before starting
532 // filter processing.
533 // FIXME: when the legacy path is removed, remove the transparencyLa yerContext as well.
534 if (haveTransparency) {
535 // If we have a filter and transparency, we have to eagerly star t a transparency layer here, rather than risk a child layer lazily starts one af ter filter processing.
536 layer()->beginTransparencyLayers(context, localPaintingInfo.root Layer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation);
537 }
538 // We'll handle clipping to the dirty rect before filter rasterizati on.
539 // Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets.
540 // FIXME: It is incorrect to just clip to the damageRect here once m ultiple fragments are involved.
541 layer()->clipToRect(localPaintingInfo, context, contentRect);
542 // Subsequent code should not clip to the dirty rect, since we've al ready
543 // done it above, and doing it later will defeat the outsets.
544 localPaintingInfo.clipToDirtyRect = false;
545
546 context = filterPainter.beginFilterEffect(context);
547 }
548 }
549
550 LayoutPoint layerLocation = toPoint(layerBounds.location() - location() + lo calPaintingInfo.subPixelAccumulation);
551
552 if (shouldPaintContent) {
553 bool contentRectIsEmpty = contentRect.isEmpty();
554
555 // Begin transparency if we have something to paint.
556 if (haveTransparency && !contentRectIsEmpty)
557 layer()->beginTransparencyLayers(transparencyLayerContext, localPain tingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.subPixelAccum ulation);
558
559 // Optimize clipping for the single fragment case.
560 bool shouldClip = localPaintingInfo.clipToDirtyRect && !contentRectIsEmp ty;
561 if (shouldClip)
562 layer()->clipToRect(localPaintingInfo, context, contentRect);
563
564 // TODO(ojan): We probably should have already set shouldPaintContent to false if the rect is empty.
565 if (!contentRectIsEmpty) {
566 Vector<RenderBox*> layers;
567
568 PaintInfo paintInfo(context, pixelSnappedIntRect(contentRect.rect()) , localPaintingInfo.rootLayer->renderer());
569 paint(paintInfo, layerLocation, layers);
570
571 std::stable_sort(layers.begin(), layers.end(), compareZIndex);
572 for (auto& box : layers) {
573 box->paintLayer(context, paintingInfo.rootLayer, rect);
574 }
575 }
576
577 if (shouldClip)
578 layer()->restoreClip(context, localPaintingInfo.paintDirtyRect, cont entRect);
579 }
580
581 if (filterPainter.hasStartedFilterEffect()) {
582 context = filterPainter.applyFilterEffect();
583 layer()->restoreClip(transparencyLayerContext, localPaintingInfo.paintDi rtyRect, contentRect);
584 }
585
586 // Make sure that we now use the original transparency context.
587 ASSERT(transparencyLayerContext == context);
588
589 // End our transparency layer
590 if (haveTransparency && layer()->usedTransparency()) {
591 context->endLayer();
592 context->restore();
593 layer()->clearUsedTransparency();
594 }
595 }
596
597 void RenderBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, Vect or<RenderBox*>& layers)
392 { 598 {
393 LayoutPoint adjustedPaintOffset = paintOffset + location(); 599 LayoutPoint adjustedPaintOffset = paintOffset + location();
394 for (RenderObject* child = slowFirstChild(); child; child = child->nextSibli ng()) 600 for (RenderObject* child = slowFirstChild(); child; child = child->nextSibli ng())
395 child->paint(paintInfo, adjustedPaintOffset); 601 child->paint(paintInfo, adjustedPaintOffset, layers);
396 } 602 }
397 603
398 void RenderBox::paintRootBoxFillLayers(const PaintInfo& paintInfo) 604 void RenderBox::paintRootBoxFillLayers(const PaintInfo& paintInfo)
399 { 605 {
400 const FillLayer& bgLayer = style()->backgroundLayers(); 606 const FillLayer& bgLayer = style()->backgroundLayers();
401 Color bgColor = resolveColor(CSSPropertyBackgroundColor); 607 Color bgColor = resolveColor(CSSPropertyBackgroundColor);
402 608
403 paintFillLayers(paintInfo, bgColor, bgLayer, view()->backgroundRect(this), B ackgroundBleedNone, this); 609 paintFillLayers(paintInfo, bgColor, bgLayer, view()->backgroundRect(this), B ackgroundBleedNone, this);
404 } 610 }
405 611
(...skipping 2282 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 2894
2689 RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style) 2895 RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style)
2690 { 2896 {
2691 backgroundColor = style.colorIncludingFallback(CSSPropertyBackgroundColor); 2897 backgroundColor = style.colorIncludingFallback(CSSPropertyBackgroundColor);
2692 hasBackground = backgroundColor.alpha() || style.hasBackgroundImage(); 2898 hasBackground = backgroundColor.alpha() || style.hasBackgroundImage();
2693 ASSERT(hasBackground == style.hasBackground()); 2899 ASSERT(hasBackground == style.hasBackground());
2694 hasBorder = style.hasBorder(); 2900 hasBorder = style.hasBorder();
2695 } 2901 }
2696 2902
2697 } // namespace blink 2903 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/rendering/RenderBox.h ('k') | sky/engine/core/rendering/RenderFlexibleBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698