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

Unified Diff: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp

Issue 1407543003: Preliminary paint property walk implementation for SPv2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..afc807d04c8131cca9bb83b8fd2b4886e6e99cf4
--- /dev/null
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -0,0 +1,184 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/paint/PaintPropertyTreeBuilder.h"
+
+#include "core/frame/FrameView.h"
+#include "core/layout/LayoutView.h"
+#include "core/paint/ObjectPaintProperties.h"
+#include "core/paint/PaintLayer.h"
+#include "platform/graphics/paint/TransformPaintPropertyNode.h"
+#include "platform/transforms/TransformationMatrix.h"
+
+namespace blink {
+
+struct PaintPropertyTreeBuilder::WalkContext {
pdr. 2015/10/14 17:52:07 CurrentPropertyTreeContext?
trchen 2015/10/14 22:51:13 I'm thinking just Context... Being a nested class
+ explicit WalkContext(TransformPaintPropertyNode* newCurrentTransform = nullptr) : currentTransform(newCurrentTransform) { }
+ TransformPaintPropertyNode* currentTransform;
+};
+
+struct PaintPropertyTreeBuilder::WalkContextHTML : public WalkContext {
pdr. 2015/10/14 17:52:07 Does this need to be so abstract? What other subcl
trchen 2015/10/14 22:51:13 I'm thinking of SVG. They are different because th
+ static WalkContextHTML contextForDocumentNode(TransformPaintPropertyNode* fixed, TransformPaintPropertyNode* absolute) { return WalkContextHTML(fixed, absolute); }
+
+ LayoutPoint paintOffset;
+
+ TransformPaintPropertyNode* transformForOutOfFlowPositioned;
+ LayoutPoint paintOffsetForOutOfFlowPositioned;
+
+ TransformPaintPropertyNode* transformForFixedPositioned;
+ LayoutPoint paintOffsetForFixedPositioned;
+private:
+ WalkContextHTML(TransformPaintPropertyNode* fixed, TransformPaintPropertyNode* absolute)
+ : WalkContext(absolute)
+ , transformForOutOfFlowPositioned(absolute)
+ , transformForFixedPositioned(fixed)
+ {
+ }
+};
+
+void PaintPropertyTreeBuilder::buildPropertyTrees(FrameView& rootFrame)
+{
+ walk(rootFrame, WalkContext());
+}
+
+void PaintPropertyTreeBuilder::walk(FrameView& frameView, const WalkContext& context)
+{
+ ObjectPaintProperties& properties = frameView.ensureObjectPaintProperties();
+
+ TransformationMatrix frameTranslate;
+ frameTranslate.translate(frameView.x(), frameView.y());
+ TransformPaintPropertyNode* transformNodeForSelf = new TransformPaintPropertyNode(frameTranslate, FloatPoint3D(), context.currentTransform);
+ properties.setTransformNodeForSelf(adoptRef(transformNodeForSelf));
+
+ TransformationMatrix frameScroll;
+ frameScroll.translate(-frameView.scrollX(), -frameView.scrollY());
+ TransformPaintPropertyNode* transformNodeForDescendants = new TransformPaintPropertyNode(frameScroll, FloatPoint3D(), transformNodeForSelf);
+ properties.setTransformNodeForDescendants(adoptRef(transformNodeForDescendants));
+
+ if (LayoutView* layoutView = frameView.layoutView())
+ walk(*layoutView, WalkContextHTML::contextForDocumentNode(transformNodeForSelf, transformNodeForDescendants));
+}
+
+static bool shouldCreateTransformNodeForSelf(LayoutBoxModelObject& object)
+{
+ // TODO(trchen): Eliminate PaintLayer dependency.
+ PaintLayer* layer = object.layer();
+ if (!layer)
+ return false;
+
+ return layer->paintsWithTransform(GlobalPaintNormalPhase);
+}
+
+static FloatPoint perspectiveOrigin(const LayoutBox& box)
+{
+ const ComputedStyle& style = box.styleRef();
+
+ FloatSize borderBoxSize(box.size());
+ return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()));
+}
+
+void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const WalkContextHTML& context)
+{
+ ASSERT(object.isBox() != object.isLayoutInline()); // Either or.
+
+ WalkContextHTML localContext(context);
+ RefPtr<TransformPaintPropertyNode> newTransformNodeForSelf;
+ RefPtr<TransformPaintPropertyNode> newTransformNodeForDescendants;
+
+ const ComputedStyle& style = object.styleRef();
+ // TODO(trchen): There is some insanity going on with tables. Double check results.
+ switch (style.position()) {
+ case StaticPosition:
+ break;
+ case RelativePosition:
+ localContext.paintOffset += object.offsetForInFlowPosition();
+ break;
+ case AbsolutePosition:
+ localContext.currentTransform = context.transformForOutOfFlowPositioned;
+ localContext.paintOffset = context.paintOffsetForOutOfFlowPositioned;
+ break;
+ case StickyPosition:
+ localContext.paintOffset += object.offsetForInFlowPosition();
+ break;
+ case FixedPosition:
+ localContext.currentTransform = context.transformForFixedPositioned;
+ localContext.paintOffset = context.paintOffsetForFixedPositioned;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ if (object.isBox())
+ localContext.paintOffset += toLayoutBox(object).locationOffset();
+
+ bool hasTransform = object.isBox() && style.hasTransform();
pdr. 2015/10/14 18:44:15 I think it's important to unblock some work that d
trchen 2015/10/14 22:51:13 We need to keep track of paint offset in order to
pdr. 2015/10/15 04:53:52 In order to land this, we will need a ridiculous n
trchen 2015/10/15 23:24:31 IMO without paint offset handling the code will be
+ if (shouldCreateTransformNodeForSelf(object)) {
+ TransformationMatrix matrix;
+ if (hasTransform)
+ style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::IncludeTransformOrigin, ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTransformProperties);
+ matrix.translateRight(localContext.paintOffset.x(), localContext.paintOffset.y());
+ // TODO(jbroman): Put the real transform origin here, instead of using a
+ // matrix with the origin baked in.
+ newTransformNodeForSelf = adoptRef(new TransformPaintPropertyNode(matrix, FloatPoint3D(), localContext.currentTransform));
+ localContext.currentTransform = newTransformNodeForSelf.get();
+ localContext.paintOffset = LayoutPoint();
+ } else {
+ ASSERT(!hasTransform);
+ }
+
+ if (object.isBox() && style.hasPerspective()) {
+ FloatPoint origin = perspectiveOrigin(toLayoutBox(object));
+ TransformationMatrix matrix;
+ matrix.applyPerspective(style.perspective());
+ matrix.translate(-origin.x(), -origin.y());
jbroman 2015/10/14 15:11:58 TransformationMatrix::applyTransformOrigin
trchen 2015/10/14 22:51:13 Done.
+ matrix.translateRight(origin.x(), origin.y());
+ matrix.translateRight(localContext.paintOffset.x(), localContext.paintOffset.y());
+ newTransformNodeForDescendants = adoptRef(new TransformPaintPropertyNode(matrix, FloatPoint3D(), localContext.currentTransform));
+ localContext.currentTransform = newTransformNodeForDescendants.get();
+ localContext.paintOffset = LayoutPoint();
+ }
+
+ if (style.position() != StaticPosition || hasTransform) {
+ localContext.transformForOutOfFlowPositioned = localContext.currentTransform;
+ localContext.paintOffsetForOutOfFlowPositioned = localContext.paintOffset;
+ }
+
+ if (hasTransform) {
+ localContext.transformForFixedPositioned = localContext.currentTransform;
+ localContext.paintOffsetForFixedPositioned = localContext.paintOffset;
+ }
+
+ if (object.hasOverflowClip()) {
+ PaintLayer* layer = object.layer();
+ ASSERT(layer);
+ DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset();
+ if (!scrollOffset.isZero() || layer->scrollsOverflow()) {
+ TransformationMatrix matrix;
+ matrix.translate(-scrollOffset.width(), -scrollOffset.height());
+ newTransformNodeForDescendants = adoptRef(new TransformPaintPropertyNode(matrix, FloatPoint3D(), localContext.currentTransform));
+ localContext.currentTransform = newTransformNodeForDescendants.get();
+ }
+ }
+
+ if (newTransformNodeForSelf || newTransformNodeForDescendants) {
+ ObjectPaintProperties& properties = object.ensureObjectPaintProperties();
+ properties.setTransformNodeForSelf(newTransformNodeForSelf.release());
+ properties.setTransformNodeForDescendants(newTransformNodeForDescendants.release());
+ } else {
+ object.setObjectPaintProperties(nullptr);
+ }
+
+ if (object.isSVGRoot()) {
+ // TODO(trchen): Implement SVG walk.
+ return;
+ }
+
+ for (LayoutObject* child = object.slowFirstChild(); child; child = child->nextSibling()) {
+ if (child->isText())
+ continue;
+ walk(toLayoutBoxModelObject(*child), localContext);
+ }
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698