提交 f01bea30 编写于 作者: O Ojan Vafai

Move transforms from RenderLayer to RenderBox.

This is more member data on RenderLayer that is now only
used by RenderBox.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/965013003
上级 c8912dd1
......@@ -149,10 +149,52 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
layer()->styleChanged(diff, oldStyle);
}
updateTransform(oldStyle);
if (needsLayout() && oldStyle)
RenderBlock::removePercentHeightDescendantIfNeeded(this);
}
void RenderBox::updateTransformationMatrix()
{
if (m_transform) {
m_transform->makeIdentity();
style()->applyTransform(*m_transform, pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
// FIXME(sky): We shouldn't need to do this once Skia has 4x4 matrix support.
// Until then, 3d transforms don't work right.
m_transform->makeAffine();
}
}
void RenderBox::updateTransform(const RenderStyle* oldStyle)
{
if (oldStyle && style()->transformDataEquivalent(*oldStyle))
return;
// hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
// so check style too.
bool localHasTransform = hasTransform() && style()->hasTransform();
bool had3DTransform = has3DTransform();
bool hadTransform = m_transform;
if (localHasTransform != hadTransform) {
if (localHasTransform)
m_transform = adoptPtr(new TransformationMatrix);
else
m_transform.clear();
// Layers with transforms act as clip rects roots, so clear the cached clip rects here.
layer()->clipper().clearClipRectsIncludingDescendants();
} else if (localHasTransform) {
layer()->clipper().clearClipRectsIncludingDescendants(AbsoluteClipRects);
}
updateTransformationMatrix();
if (had3DTransform != has3DTransform())
layer()->dirty3DTransformedDescendantStatus();
}
// TODO(ojan): Inline this into styleDidChange,
void RenderBox::updateFromStyle()
{
......@@ -246,9 +288,8 @@ void RenderBox::absoluteQuads(Vector<FloatQuad>& quads) const
void RenderBox::updateLayerTransformAfterLayout()
{
// Transform-origin depends on box size, so we need to update the layer transform after layout.
if (hasLayer())
layer()->updateTransformationMatrix();
// Transform-origin depends on box size, so we need to update the transform after layout.
updateTransformationMatrix();
}
LayoutUnit RenderBox::constrainLogicalWidthByMinMax(LayoutUnit logicalWidth, LayoutUnit availableWidth, RenderBlock* cb) const
......@@ -548,11 +589,11 @@ bool RenderBox::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer
HitTestLocation localHitTestLocation = hitTestLocation;
// We need transform state for the first time, or to offset the container state, or to accumulate the new transform.
if (layer()->transform() || transformState || layer()->has3DTransformedDescendant() || layer()->preserves3D())
if (transform() || transformState || layer()->has3DTransformedDescendant() || style()->preserves3D())
localTransformState = createLocalTransformState(rootLayer, containerLayer, localHitTestRect, localHitTestLocation, transformState);
// Apply a transform if we have one.
if (layer()->transform()) {
if (transform()) {
// The RenderView cannot have transforms.
ASSERT(parent());
// Make sure the parent's clip rects have been calculated.
......@@ -596,7 +637,7 @@ bool RenderBox::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer
}
RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
if (localTransformState && !layer()->preserves3D()) {
if (localTransformState && !style()->preserves3D()) {
// Keep a copy of the pre-flattening state, for computing z-offsets for the container
unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
// This layer is flattening, so flatten the state passed to descendants.
......@@ -610,7 +651,7 @@ bool RenderBox::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer
double* zOffsetForContentsPtr = 0;
bool depthSortDescendants = false;
if (layer()->preserves3D()) {
if (style()->preserves3D()) {
depthSortDescendants = true;
// Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
......@@ -720,9 +761,7 @@ void RenderBox::paintLayer(GraphicsContext* context, const LayerPaintingInfo& pa
if (!opacity())
return;
TransformationMatrix* layerTransform = layer()->transform();
if (!layerTransform) {
if (!transform()) {
paintLayerContents(context, paintingInfo);
return;
}
......@@ -731,7 +770,7 @@ void RenderBox::paintLayer(GraphicsContext* context, const LayerPaintingInfo& pa
ASSERT(layer()->parent());
// If the transform can't be inverted, then don't paint anything.
if (!layerTransform->isInvertible())
if (!transform()->isInvertible())
return;
// Make sure the parent's clip rects have been calculated.
......@@ -746,20 +785,20 @@ void RenderBox::paintLayer(GraphicsContext* context, const LayerPaintingInfo& pa
// the accumulated error for sub-pixel layout.
LayoutPoint delta;
layer()->convertToLayerCoords(paintingInfo.rootLayer, delta);
TransformationMatrix transform(*layerTransform);
TransformationMatrix localTransform(*transform());
IntPoint roundedDelta = roundedIntPoint(delta);
transform.translateRight(roundedDelta.x(), roundedDelta.y());
localTransform.translateRight(roundedDelta.x(), roundedDelta.y());
LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
// Apply the transform.
GraphicsContextStateSaver stateSaver(*context, false);
if (!transform.isIdentity()) {
if (!localTransform.isIdentity()) {
stateSaver.save();
context->concatCTM(transform.toAffineTransform());
context->concatCTM(localTransform.toAffineTransform());
}
// Now do a paint with the root layer shifted to be us.
LayerPaintingInfo transformedPaintingInfo(layer(), enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)),
LayerPaintingInfo transformedPaintingInfo(layer(), enclosingIntRect(localTransform.inverse().mapRect(paintingInfo.paintDirtyRect)),
adjustedSubPixelAccumulation);
paintLayerContents(context, transformedPaintingInfo);
......@@ -785,7 +824,7 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
// paintDirtyRect, and that should cut down on the amount we have to paint. Still it
// would be better to respect clips.
if (rootLayer != layer && layer->transform()) {
if (rootLayer != layer && layer->renderer()->transform()) {
// The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
// the transformed layer and all of its children.
const RenderLayer* rootLayerForTransform = rootLayer;
......@@ -796,7 +835,7 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
IntPoint pixelSnappedDelta = roundedIntPoint(delta);
TransformationMatrix transform;
transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
transform = transform * *layer->transform();
transform = transform * *layer->renderer()->transform();
// We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
// paints unfragmented.y
......@@ -3013,8 +3052,8 @@ LayoutRect RenderBox::layoutOverflowRectForPropagation() const
if (!hasOverflowClip())
rect.unite(layoutOverflowRect());
if (hasLayer() && layer()->transform())
rect = layer()->transform()->mapRect(rect);
if (transform())
rect = transform()->mapRect(rect);
return rect;
}
......
......@@ -33,6 +33,7 @@ struct LayerPaintingInfo;
struct PaintInfo;
class HitTestingTransformState;
class RenderBlockFlow;
class TransformationMatrix;
enum SizeType { MainOrPreferredSize, MinSize, MaxSize };
enum AvailableLogicalHeightType { ExcludeMarginBorderPadding, IncludeMarginBorderPadding };
......@@ -217,6 +218,10 @@ public:
void updateLayerTransformAfterLayout();
// This transform has the transform-origin baked in.
TransformationMatrix* transform() const { return m_transform.get(); }
bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
LayoutUnit contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
LayoutUnit contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }
LayoutUnit contentLogicalWidth() const { return contentWidth(); }
......@@ -485,6 +490,8 @@ protected:
void updateIntrinsicContentLogicalHeight(LayoutUnit intrinsicContentLogicalHeight) const { m_intrinsicContentLogicalHeight = intrinsicContentLogicalHeight; }
private:
void updateTransformationMatrix();
void updateTransform(const RenderStyle* oldStyle);
void updateFromStyle();
void updateFilters();
......@@ -557,7 +564,9 @@ protected:
// Our overflow information.
OwnPtr<RenderOverflow> m_overflow;
// TODO(ojan): Move these two into RenderBoxRareData.
OwnPtr<FilterEffectRenderer> m_filterRenderer;
OwnPtr<TransformationMatrix> m_transform;
private:
OwnPtr<RenderLayer> m_layer;
......
......@@ -2324,7 +2324,7 @@ const RenderObject* RenderBoxModelObject::pushMappingToContainer(const RenderBox
return 0;
bool isInline = isRenderInline();
bool hasTransform = !isInline && hasLayer() && toRenderBox(this)->layer()->transform();
bool hasTransform = !isInline && isBox() && toRenderBox(this)->transform();
LayoutSize adjustmentForSkippedAncestor;
if (ancestorSkipped) {
......
......@@ -102,46 +102,6 @@ void RenderLayer::updateLayerPositionsAfterLayout()
m_clipper.clearClipRectsIncludingDescendants();
}
void RenderLayer::updateTransformationMatrix()
{
if (m_transform) {
RenderBox* box = renderer();
m_transform->makeIdentity();
box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
// FIXME(sky): We shouldn't need to do this once Skia has 4x4 matrix support.
// Until then, 3d transforms don't work right.
m_transform->makeAffine();
}
}
void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle)
{
if (oldStyle && newStyle->transformDataEquivalent(*oldStyle))
return;
// hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
// so check style too.
bool hasTransform = renderer()->hasTransform() && newStyle->hasTransform();
bool had3DTransform = has3DTransform();
bool hadTransform = m_transform;
if (hasTransform != hadTransform) {
if (hasTransform)
m_transform = adoptPtr(new TransformationMatrix);
else
m_transform.clear();
// Layers with transforms act as clip rects roots, so clear the cached clip rects here.
m_clipper.clearClipRectsIncludingDescendants();
} else if (hasTransform) {
m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects);
}
updateTransformationMatrix();
if (had3DTransform != has3DTransform())
dirty3DTransformedDescendantStatus();
}
void RenderLayer::dirty3DTransformedDescendantStatus()
{
......@@ -153,7 +113,7 @@ void RenderLayer::dirty3DTransformedDescendantStatus()
// This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
// Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
while (stackingNode && stackingNode->layer()->preserves3D()) {
while (stackingNode && stackingNode->layer()->renderer()->style()->preserves3D()) {
stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
stackingNode = stackingNode->ancestorStackingContextNode();
}
......@@ -178,10 +138,10 @@ bool RenderLayer::update3DTransformedDescendantStatus()
// If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
// the m_has3DTransformedDescendant set.
if (preserves3D())
return has3DTransform() || m_has3DTransformedDescendant;
if (renderer()->style()->preserves3D())
return renderer()->has3DTransform() || m_has3DTransformedDescendant;
return has3DTransform();
return renderer()->has3DTransform();
}
IntSize RenderLayer::size() const
......@@ -571,8 +531,8 @@ LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLay
LayoutRect localClipRect = clipper().localClipRect();
if (localClipRect != PaintInfo::infiniteRect()) {
if (transform())
localClipRect = transform()->mapRect(localClipRect);
if (renderer()->transform())
localClipRect = renderer()->transform()->mapRect(localClipRect);
LayoutPoint delta;
convertToLayerCoords(ancestorLayer, delta);
......@@ -592,8 +552,8 @@ LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLay
// https://bugs.webkit.org/show_bug.cgi?id=81239
m_renderer->style()->filterOutsets().expandRect(result);
if (transform())
result = transform()->mapRect(result);
if (renderer()->transform())
result = renderer()->transform()->mapRect(result);
LayoutPoint delta;
convertToLayerCoords(ancestorLayer, delta);
......@@ -614,8 +574,6 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle
// Overlay scrollbars can make this layer self-painting so we need
// to recompute the bit once scrollbars have been updated.
m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
updateTransform(oldStyle, renderer()->style());
}
} // namespace blink
......@@ -55,12 +55,7 @@
namespace blink {
class FilterOperations;
class HitTestRequest;
class HitTestResult;
class HitTestingTransformState;
class RenderStyle;
class TransformationMatrix;
enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius };
enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf };
......@@ -103,7 +98,6 @@ public:
bool isRootLayer() const { return m_isRootLayer; }
void updateLayerPositionsAfterLayout();
void updateTransformationMatrix();
RenderLayerStackingNode* stackingNode() { return m_stackingNode.get(); }
const RenderLayerStackingNode* stackingNode() const { return m_stackingNode.get(); }
......@@ -125,19 +119,10 @@ public:
LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const;
LayoutRect boundingBoxForCompositing(const RenderLayer* ancestorLayer = 0) const;
// This transform has the transform-origin baked in.
TransformationMatrix* transform() const { return m_transform.get(); }
bool preserves3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
// Both updates the status, and returns true if descendants of this have 3d.
bool update3DTransformedDescendantStatus();
// FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
bool shouldPreserve3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
void* operator new(size_t);
// Only safe to call from RenderBox::destroyLayer()
void operator delete(void*);
......@@ -154,7 +139,6 @@ public:
void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&);
private:
// Bounding box in the coordinates of this layer.
LayoutRect logicalBoundingBox() const;
......@@ -165,10 +149,9 @@ private:
bool shouldBeSelfPaintingLayer() const;
void updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle);
void dirty3DTransformedDescendantStatus();
private:
LayerType m_layerType;
// Self-painting layer is an optimization where we avoid the heavy RenderLayer painting
......@@ -191,8 +174,6 @@ private:
RenderLayer* m_first;
RenderLayer* m_last;
OwnPtr<TransformationMatrix> m_transform;
RenderLayerClipper m_clipper; // FIXME: Lazily allocate?
OwnPtr<RenderLayerStackingNode> m_stackingNode;
};
......
......@@ -317,7 +317,7 @@ RenderLayer* RenderLayerClipper::clippingRootForPainting() const
current = current->compositingContainer();
ASSERT(current);
if (current->transform())
if (current->renderer()->transform())
return const_cast<RenderLayer*>(current);
}
......
......@@ -1418,16 +1418,16 @@ bool RenderObject::shouldUseTransformFromContainer(const RenderObject* container
{
// hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform,
// so check the layer's transform directly.
return (hasLayer() && toRenderBox(this)->layer()->transform()) || (containerObject && containerObject->style()->hasPerspective());
return (isBox() && toRenderBox(this)->transform()) || (containerObject && containerObject->style()->hasPerspective());
}
void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
{
transform.makeIdentity();
transform.translate(offsetInContainer.width().toFloat(), offsetInContainer.height().toFloat());
RenderLayer* layer = hasLayer() ? toRenderBox(this)->layer() : 0;
if (layer && layer->transform())
transform.multiply(*layer->transform());
TransformationMatrix* localTransform = isBox() ? toRenderBox(this)->transform() : 0;
if (localTransform)
transform.multiply(*localTransform);
if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) {
// Perpsective on the container affects us, so we have to factor it in here.
......
......@@ -353,7 +353,7 @@ IntRect RenderView::documentRect() const
{
FloatRect overflowRect(unscaledDocumentRect());
if (hasTransform())
overflowRect = layer()->transform()->mapRect(overflowRect);
overflowRect = transform()->mapRect(overflowRect);
return IntRect(overflowRect);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册