Diff
Modified: trunk/Source/WebCore/ChangeLog (142403 => 142404)
--- trunk/Source/WebCore/ChangeLog 2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/ChangeLog 2013-02-10 16:04:43 UTC (rev 142404)
@@ -1,3 +1,59 @@
+2013-02-10 Andreas Kling <[email protected]>
+
+ RenderStyle should use copy-on-write inheritance for NinePieceImage.
+ <http://webkit.org/b/109366>
+
+ Reviewed by Antti Koivisto.
+
+ Refactor NinePieceImage to hold a copy-on-write DataRef like other RenderStyle substructures.
+ This allows us to avoids copying the NinePieceImageData when one RenderStyle inherits from another
+ but modifies something in the substructure holding the NinePieceImage (typically StyleSurroundData.)
+
+ Also made RenderStyle not copy-on-write its StyleSurroundData prematurely when doing a no-op write
+ to a border-image related value.
+
+ 1.23 MB progression on Membuster3.
+
+ * rendering/style/NinePieceImage.cpp:
+ (WebCore::defaultData):
+ (WebCore::NinePieceImage::NinePieceImage):
+ (WebCore::NinePieceImageData::NinePieceImageData):
+ (WebCore::NinePieceImageData::operator==):
+ * rendering/style/NinePieceImage.h:
+ (WebCore::NinePieceImageData::create):
+ (WebCore::NinePieceImageData::copy):
+ (NinePieceImageData):
+ (NinePieceImage):
+ (WebCore::NinePieceImage::operator==):
+ (WebCore::NinePieceImage::operator!=):
+ (WebCore::NinePieceImage::hasImage):
+ (WebCore::NinePieceImage::image):
+ (WebCore::NinePieceImage::setImage):
+ (WebCore::NinePieceImage::imageSlices):
+ (WebCore::NinePieceImage::setImageSlices):
+ (WebCore::NinePieceImage::fill):
+ (WebCore::NinePieceImage::setFill):
+ (WebCore::NinePieceImage::borderSlices):
+ (WebCore::NinePieceImage::setBorderSlices):
+ (WebCore::NinePieceImage::outset):
+ (WebCore::NinePieceImage::setOutset):
+ (WebCore::NinePieceImage::horizontalRule):
+ (WebCore::NinePieceImage::setHorizontalRule):
+ (WebCore::NinePieceImage::verticalRule):
+ (WebCore::NinePieceImage::setVerticalRule):
+ (WebCore::NinePieceImage::copyImageSlicesFrom):
+ (WebCore::NinePieceImage::copyBorderSlicesFrom):
+ (WebCore::NinePieceImage::copyOutsetFrom):
+ (WebCore::NinePieceImage::copyRepeatFrom):
+ (WebCore::NinePieceImage::setMaskDefaults):
+ (WebCore::NinePieceImage::computeOutset):
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::setBorderImageSource):
+ (WebCore::RenderStyle::setBorderImageSlices):
+ (WebCore::RenderStyle::setBorderImageWidth):
+ (WebCore::RenderStyle::setBorderImageOutset):
+ * rendering/style/RenderStyle.h:
+
2013-02-10 Kent Tamura <[email protected]>
Unreviewed, rolling out r142343.
Modified: trunk/Source/WebCore/rendering/style/NinePieceImage.cpp (142403 => 142404)
--- trunk/Source/WebCore/rendering/style/NinePieceImage.cpp 2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/NinePieceImage.cpp 2013-02-10 16:04:43 UTC (rev 142404)
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll ([email protected])
* (C) 2000 Antti Koivisto ([email protected])
* (C) 2000 Dirk Mueller ([email protected])
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,16 +26,63 @@
namespace WebCore {
-bool NinePieceImageData::operator==(const NinePieceImageData& o) const
+static DataRef<NinePieceImageData>& defaultData()
{
- return StyleImage::imagesEquivalent(m_image.get(), o.m_image.get()) && m_imageSlices == o.m_imageSlices && m_fill == o.m_fill
- && m_borderSlices == o.m_borderSlices && m_outset == o.m_outset && m_horizontalRule == o.m_horizontalRule && m_verticalRule == o.m_verticalRule;
+ static DataRef<NinePieceImageData>* data = "" DataRef<NinePieceImageData>;
+ if (!data->get())
+ data->init();
+ return *data;
}
-const NinePieceImageData& NinePieceImage::defaultData()
+NinePieceImage::NinePieceImage()
+ : m_data(defaultData())
{
- DEFINE_STATIC_LOCAL(NinePieceImageData, data, ());
- return data;
}
+NinePieceImage::NinePieceImage(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule)
+{
+ m_data.init();
+ m_data.access()->image = image;
+ m_data.access()->imageSlices = imageSlices;
+ m_data.access()->borderSlices = borderSlices;
+ m_data.access()->outset = outset;
+ m_data.access()->fill = fill;
+ m_data.access()->horizontalRule = horizontalRule;
+ m_data.access()->verticalRule = verticalRule;
}
+
+NinePieceImageData::NinePieceImageData()
+ : fill(false)
+ , horizontalRule(StretchImageRule)
+ , verticalRule(StretchImageRule)
+ , image(0)
+ , imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
+ , borderSlices(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative))
+ , outset(0)
+{
+}
+
+NinePieceImageData::NinePieceImageData(const NinePieceImageData& other)
+ : RefCounted<NinePieceImageData>()
+ , fill(other.fill)
+ , horizontalRule(other.horizontalRule)
+ , verticalRule(other.verticalRule)
+ , image(other.image)
+ , imageSlices(other.imageSlices)
+ , borderSlices(other.borderSlices)
+ , outset(other.outset)
+{
+}
+
+bool NinePieceImageData::operator==(const NinePieceImageData& other) const
+{
+ return StyleImage::imagesEquivalent(image.get(), other.image.get())
+ && imageSlices == other.imageSlices
+ && fill == other.fill
+ && borderSlices == other.borderSlices
+ && outset == other.outset
+ && horizontalRule == other.horizontalRule
+ && verticalRule == other.verticalRule;
+}
+
+}
Modified: trunk/Source/WebCore/rendering/style/NinePieceImage.h (142403 => 142404)
--- trunk/Source/WebCore/rendering/style/NinePieceImage.h 2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/NinePieceImage.h 2013-02-10 16:04:43 UTC (rev 142404)
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll ([email protected])
* (C) 2000 Antti Koivisto ([email protected])
* (C) 2000 Dirk Mueller ([email protected])
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +24,7 @@
#ifndef NinePieceImage_h
#define NinePieceImage_h
+#include "DataRef.h"
#include "LayoutUnit.h"
#include "LengthBox.h"
#include "StyleImage.h"
@@ -34,149 +35,95 @@
StretchImageRule, RoundImageRule, SpaceImageRule, RepeatImageRule
};
-class NinePieceImageData {
- WTF_MAKE_FAST_ALLOCATED;
+class NinePieceImageData : public RefCounted<NinePieceImageData> {
public:
- NinePieceImageData()
- : m_image(0)
- , m_imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
- , m_borderSlices(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative))
- , m_outset(0)
- , m_fill(false)
- , m_horizontalRule(StretchImageRule)
- , m_verticalRule(StretchImageRule)
- {
- }
+ static PassRefPtr<NinePieceImageData> create() { return adoptRef(new NinePieceImageData); }
+ PassRefPtr<NinePieceImageData> copy() const { return adoptRef(new NinePieceImageData(*this)); }
- NinePieceImageData(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule h, ENinePieceImageRule v)
- : m_image(image)
- , m_imageSlices(imageSlices)
- , m_borderSlices(borderSlices)
- , m_outset(outset)
- , m_fill(fill)
- , m_horizontalRule(h)
- , m_verticalRule(v)
- {
- }
-
bool operator==(const NinePieceImageData&) const;
bool operator!=(const NinePieceImageData& o) const { return !(*this == o); }
- RefPtr<StyleImage> m_image;
- LengthBox m_imageSlices;
- LengthBox m_borderSlices;
- LengthBox m_outset;
- bool m_fill : 1;
- unsigned m_horizontalRule : 2; // ENinePieceImageRule
- unsigned m_verticalRule : 2; // ENinePieceImageRule
+ bool fill : 1;
+ unsigned horizontalRule : 2; // ENinePieceImageRule
+ unsigned verticalRule : 2; // ENinePieceImageRule
+ RefPtr<StyleImage> image;
+ LengthBox imageSlices;
+ LengthBox borderSlices;
+ LengthBox outset;
+
+private:
+ NinePieceImageData();
+ NinePieceImageData(const NinePieceImageData&);
};
class NinePieceImage {
public:
- NinePieceImage() { }
+ NinePieceImage();
+ NinePieceImage(PassRefPtr<StyleImage>, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule);
- NinePieceImage(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule h, ENinePieceImageRule v)
- : m_data(adoptPtr(new NinePieceImageData(image, imageSlices, fill, borderSlices, outset, h, v)))
- { }
+ bool operator==(const NinePieceImage& other) const { return m_data == other.m_data; }
+ bool operator!=(const NinePieceImage& other) const { return m_data != other.m_data; }
- NinePieceImage(const NinePieceImage& other)
- {
- *this = other;
- }
-
- void operator=(const NinePieceImage& other)
- {
- if (!other.m_data) {
- m_data.clear();
- return;
- }
- const NinePieceImageData& otherData = other.data();
- m_data = adoptPtr(new NinePieceImageData(otherData.m_image, otherData.m_imageSlices, otherData.m_fill, otherData.m_borderSlices, otherData.m_outset, static_cast<ENinePieceImageRule>(otherData.m_horizontalRule), static_cast<ENinePieceImageRule>(otherData.m_verticalRule)));
- }
-
- bool operator==(const NinePieceImage& other) const { return data() == other.data(); }
- bool operator!=(const NinePieceImage& other) const { return !(*this == other); }
-
- bool hasImage() const { return m_data && m_data->m_image; }
- StyleImage* image() const { return m_data ? m_data->m_image.get() : 0; }
- void setImage(PassRefPtr<StyleImage> image) { ensureData(); m_data->m_image = image; }
+ bool hasImage() const { return m_data->image; }
+ StyleImage* image() const { return m_data->image.get(); }
+ void setImage(PassRefPtr<StyleImage> image) { m_data.access()->image = image; }
- const LengthBox& imageSlices() const { return data().m_imageSlices; }
- void setImageSlices(const LengthBox& slices) { ensureData(); m_data->m_imageSlices = slices; }
+ const LengthBox& imageSlices() const { return m_data->imageSlices; }
+ void setImageSlices(const LengthBox& slices) { m_data.access()->imageSlices = slices; }
- bool fill() const { return data().m_fill; }
- void setFill(bool fill) { ensureData(); m_data->m_fill = fill; }
+ bool fill() const { return m_data->fill; }
+ void setFill(bool fill) { m_data.access()->fill = fill; }
- const LengthBox& borderSlices() const { return data().m_borderSlices; }
- void setBorderSlices(const LengthBox& slices) { ensureData(); m_data->m_borderSlices = slices; }
+ const LengthBox& borderSlices() const { return m_data->borderSlices; }
+ void setBorderSlices(const LengthBox& slices) { m_data.access()->borderSlices = slices; }
- const LengthBox& outset() const { return data().m_outset; }
- void setOutset(const LengthBox& outset) { ensureData(); m_data->m_outset = outset; }
-
- static LayoutUnit computeOutset(Length outsetSide, LayoutUnit borderSide)
- {
- if (outsetSide.isRelative())
- return outsetSide.value() * borderSide;
- return outsetSide.value();
- }
+ const LengthBox& outset() const { return m_data->outset; }
+ void setOutset(const LengthBox& outset) { m_data.access()->outset = outset; }
- ENinePieceImageRule horizontalRule() const { return static_cast<ENinePieceImageRule>(data().m_horizontalRule); }
- void setHorizontalRule(ENinePieceImageRule rule) { ensureData(); m_data->m_horizontalRule = rule; }
+ ENinePieceImageRule horizontalRule() const { return static_cast<ENinePieceImageRule>(m_data->horizontalRule); }
+ void setHorizontalRule(ENinePieceImageRule rule) { m_data.access()->horizontalRule = rule; }
- ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(data().m_verticalRule); }
- void setVerticalRule(ENinePieceImageRule rule) { ensureData(); m_data->m_verticalRule = rule; }
+ ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(m_data->verticalRule); }
+ void setVerticalRule(ENinePieceImageRule rule) { m_data.access()->verticalRule = rule; }
void copyImageSlicesFrom(const NinePieceImage& other)
{
- ensureData();
- m_data->m_imageSlices = other.data().m_imageSlices;
- m_data->m_fill = other.data().m_fill;
+ m_data.access()->imageSlices = other.m_data->imageSlices;
+ m_data.access()->fill = other.m_data->fill;
}
void copyBorderSlicesFrom(const NinePieceImage& other)
{
- ensureData();
- m_data->m_borderSlices = other.data().m_borderSlices;
+ m_data.access()->borderSlices = other.m_data->borderSlices;
}
void copyOutsetFrom(const NinePieceImage& other)
{
- ensureData();
- m_data->m_outset = other.data().m_outset;
+ m_data.access()->outset = other.m_data->outset;
}
void copyRepeatFrom(const NinePieceImage& other)
{
- ensureData();
- m_data->m_horizontalRule = other.data().m_horizontalRule;
- m_data->m_verticalRule = other.data().m_verticalRule;
+ m_data.access()->horizontalRule = other.m_data->horizontalRule;
+ m_data.access()->verticalRule = other.m_data->verticalRule;
}
void setMaskDefaults()
{
- ensureData();
- m_data->m_imageSlices = LengthBox(0);
- m_data->m_fill = true;
- m_data->m_borderSlices = LengthBox();
+ m_data.access()->imageSlices = LengthBox(0);
+ m_data.access()->fill = true;
+ m_data.access()->borderSlices = LengthBox();
}
-private:
- static const NinePieceImageData& defaultData();
-
- void ensureData()
+ static LayoutUnit computeOutset(Length outsetSide, LayoutUnit borderSide)
{
- if (!m_data)
- m_data = adoptPtr(new NinePieceImageData);
+ if (outsetSide.isRelative())
+ return outsetSide.value() * borderSide;
+ return outsetSide.value();
}
- const NinePieceImageData& data() const
- {
- if (m_data)
- return *m_data;
- return defaultData();
- }
-
- OwnPtr<NinePieceImageData> m_data;
+private:
+ DataRef<NinePieceImageData> m_data;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (142403 => 142404)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2013-02-10 16:04:43 UTC (rev 142404)
@@ -1606,6 +1606,34 @@
NinePieceImage::computeOutset(image.outset().left(), borderLeftWidth()));
}
+void RenderStyle::setBorderImageSource(PassRefPtr<StyleImage> image)
+{
+ if (surround->border.m_image.image() == image.get())
+ return;
+ surround.access()->border.m_image.setImage(image);
+}
+
+void RenderStyle::setBorderImageSlices(LengthBox slices)
+{
+ if (surround->border.m_image.imageSlices() == slices)
+ return;
+ surround.access()->border.m_image.setImageSlices(slices);
+}
+
+void RenderStyle::setBorderImageWidth(LengthBox slices)
+{
+ if (surround->border.m_image.borderSlices() == slices)
+ return;
+ surround.access()->border.m_image.setBorderSlices(slices);
+}
+
+void RenderStyle::setBorderImageOutset(LengthBox outset)
+{
+ if (surround->border.m_image.outset() == outset)
+ return;
+ surround.access()->border.m_image.setOutset(outset);
+}
+
void RenderStyle::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (142403 => 142404)
--- trunk/Source/WebCore/rendering/style/RenderStyle.h 2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h 2013-02-10 16:04:43 UTC (rev 142404)
@@ -1020,10 +1020,10 @@
void setBackgroundSizeLength(LengthSize s) { SET_VAR(m_background, m_background.m_sizeLength, s); }
void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b); }
- void setBorderImageSource(PassRefPtr<StyleImage> v) { surround.access()->border.m_image.setImage(v); }
- void setBorderImageSlices(LengthBox slices) { surround.access()->border.m_image.setImageSlices(slices); }
- void setBorderImageWidth(LengthBox slices) { surround.access()->border.m_image.setBorderSlices(slices); }
- void setBorderImageOutset(LengthBox outset) { surround.access()->border.m_image.setOutset(outset); }
+ void setBorderImageSource(PassRefPtr<StyleImage>);
+ void setBorderImageSlices(LengthBox);
+ void setBorderImageWidth(LengthBox);
+ void setBorderImageOutset(LengthBox);
void setBorderTopLeftRadius(LengthSize s) { SET_VAR(surround, border.m_topLeft, s); }
void setBorderTopRightRadius(LengthSize s) { SET_VAR(surround, border.m_topRight, s); }