summaryrefslogtreecommitdiffstats
path: root/layout/style/RuleNodeCacheConditions.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/style/RuleNodeCacheConditions.h')
-rw-r--r--layout/style/RuleNodeCacheConditions.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/layout/style/RuleNodeCacheConditions.h b/layout/style/RuleNodeCacheConditions.h
new file mode 100644
index 000000000..4b1a2349a
--- /dev/null
+++ b/layout/style/RuleNodeCacheConditions.h
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * an object that stores the result of determining whether a style struct that
+ * was computed can be cached in the rule tree, and if so, what the conditions
+ * it relies on are
+ */
+
+#ifndef RuleNodeCacheConditions_h_
+#define RuleNodeCacheConditions_h_
+
+#include "mozilla/Attributes.h"
+#include "nsCoord.h"
+#include "nsTArray.h"
+
+class nsStyleContext;
+
+namespace mozilla {
+
+/**
+ * nsRuleNodeCacheConditions is used to store information about whether
+ * we can store a style struct that we're computing in the rule tree.
+ *
+ * For inherited structs (i.e., structs with inherited properties), we
+ * cache the struct in the rule tree if it does not depend on any data
+ * in the style context tree, and otherwise store it in the style
+ * context tree. This means that for inherited structs, setting any
+ * conditions is equivalent to making the struct uncacheable.
+ *
+ * For reset structs (i.e., structs with non-inherited properties), we
+ * are also able to cache structs in the rule tree conditionally on
+ * certain common conditions. For these structs, setting conditions
+ * (SetFontSizeDependency, SetWritingModeDependency) instead causes the
+ * struct to be stored, with the condition, in the rule tree.
+ */
+class RuleNodeCacheConditions
+{
+public:
+ RuleNodeCacheConditions()
+ : mFontSize(0), mBits(0) {}
+ RuleNodeCacheConditions(const RuleNodeCacheConditions& aOther)
+ : mFontSize(aOther.mFontSize), mBits(aOther.mBits) {}
+ RuleNodeCacheConditions& operator=(const RuleNodeCacheConditions& aOther)
+ {
+ mFontSize = aOther.mFontSize;
+ mBits = aOther.mBits;
+ return *this;
+ }
+ bool operator==(const RuleNodeCacheConditions& aOther) const
+ {
+ return mFontSize == aOther.mFontSize &&
+ mBits == aOther.mBits;
+ }
+ bool operator!=(const RuleNodeCacheConditions& aOther) const
+ {
+ return !(*this == aOther);
+ }
+
+ bool Matches(nsStyleContext* aStyleContext) const;
+
+ /**
+ * Record that the data being computed depend on the font-size
+ * property of the element for which they are being computed.
+ *
+ * Note that we sometimes actually call this when there is a
+ * dependency on the font-size property of the parent element, but we
+ * only do so while computing inherited structs (nsStyleFont), and we
+ * only store reset structs conditionally.
+ */
+ void SetFontSizeDependency(nscoord aCoord)
+ {
+ MOZ_ASSERT(!(mBits & eHaveFontSize) || mFontSize == aCoord);
+ mFontSize = aCoord;
+ mBits |= eHaveFontSize;
+ }
+
+ /**
+ * Record that the data being computed depend on the writing mode of
+ * the element for which they are being computed, which in turn
+ * depends on its 'writing-mode', 'direction', and 'text-orientation'
+ * properties.
+ */
+ void SetWritingModeDependency(uint8_t aWritingMode)
+ {
+ MOZ_ASSERT(!(mBits & eHaveWritingMode) || GetWritingMode() == aWritingMode);
+ mBits |= (static_cast<uint64_t>(aWritingMode) << eWritingModeShift) |
+ eHaveWritingMode;
+ }
+
+ void SetUncacheable()
+ {
+ mBits |= eUncacheable;
+ }
+
+ void Clear()
+ {
+ *this = RuleNodeCacheConditions();
+ }
+
+ bool Cacheable() const
+ {
+ return !(mBits & eUncacheable);
+ }
+
+ bool CacheableWithDependencies() const
+ {
+ return !(mBits & eUncacheable) &&
+ (mBits & eHaveBitsMask) != 0;
+ }
+
+ bool CacheableWithoutDependencies() const
+ {
+ // We're not uncacheable and we have don't have a font-size or
+ // writing mode value.
+ return (mBits & eHaveBitsMask) == 0;
+ }
+
+#ifdef DEBUG
+ void List() const;
+#endif
+
+private:
+ enum {
+ eUncacheable = 0x0001,
+ eHaveFontSize = 0x0002,
+ eHaveWritingMode = 0x0004,
+ eHaveBitsMask = 0x00ff,
+ eWritingModeMask = 0xff00,
+ eWritingModeShift = 8,
+ };
+
+ uint8_t GetWritingMode() const
+ {
+ return static_cast<uint8_t>(
+ (mBits & eWritingModeMask) >> eWritingModeShift);
+ }
+
+ // The font size from which em units are derived.
+ nscoord mFontSize;
+
+ // Values in mBits:
+ // bit 0: are we set to "uncacheable"?
+ // bit 1: do we have a font size value?
+ // bit 2: do we have a writing mode value?
+ // bits 3-7: unused
+ // bits 8-15: writing mode (uint8_t)
+ // bits 16-31: unused
+ uint32_t mBits;
+};
+
+} // namespace mozilla
+
+#endif // !defined(RuleNodeCacheConditions_h_)