author | Robert O'Callahan <robert@ocallahan.org> |
Mon, 04 Mar 2013 22:56:00 +1300 | |
changeset 127799 | ec3f4cfe3866b48f0f7714a50ae5e621f588bfcd |
parent 127798 | fb7633e8733e0094329fa668b21738f6464e52cf |
child 127800 | d6f4ddf03ffb57f6618e3476f1c264d16e9f1b5f |
push id | 24512 |
push user | ryanvm@gmail.com |
push date | Fri, 05 Apr 2013 20:13:49 +0000 |
treeherder | mozilla-central@139b6ba547fa [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow |
bugs | 841192 |
milestone | 23.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/DisplayItemClip.cpp +++ b/layout/base/DisplayItemClip.cpp @@ -37,16 +37,33 @@ DisplayItemClip::DisplayItemClip(const D static_cast<nsDisplayClipRoundedRect*>(item)->GetRadii(rr->mRadii); } } // FIXME: Optimize away excess rounded rectangles due to the new addition. } void +DisplayItemClip::IntersectWith(const DisplayItemClip& aOther) +{ + if (!aOther.mHaveClipRect) { + return; + } + if (!mHaveClipRect) { + *this = aOther; + return; + } + if (!mClipRect.IntersectRect(mClipRect, aOther.mClipRect)) { + mRoundedClipRects.Clear(); + return; + } + mRoundedClipRects.AppendElements(aOther.mRoundedClipRects); +} + +void DisplayItemClip::ApplyTo(gfxContext* aContext, nsPresContext* aPresContext, uint32_t aBegin, uint32_t aEnd) { int32_t A2D = aPresContext->AppUnitsPerDevPixel(); ApplyRectTo(aContext, A2D); ApplyRoundedRectsTo(aContext, A2D, aBegin, aEnd); }
--- a/layout/base/DisplayItemClip.h +++ b/layout/base/DisplayItemClip.h @@ -53,16 +53,18 @@ public: }; // Constructs a DisplayItemClip that does no clipping at all. DisplayItemClip() : mHaveClipRect(false) {} // Construct as the intersection of aOther and aClipItem. DisplayItemClip(const DisplayItemClip& aOther, nsDisplayItem* aClipItem); + void IntersectWith(const DisplayItemClip& aOther); + // Apply this |DisplayItemClip| to the given gfxContext. Any saving of state // or clearing of other clips must be done by the caller. // See aBegin/aEnd note on ApplyRoundedRectsTo. void ApplyTo(gfxContext* aContext, nsPresContext* aPresContext, uint32_t aBegin = 0, uint32_t aEnd = UINT32_MAX); void ApplyRectTo(gfxContext* aContext, int32_t A2D) const; // Applies the rounded rects in this Clip to aContext @@ -124,18 +126,18 @@ public: return mHaveClipRect == aOther.mHaveClipRect && (!mHaveClipRect || mClipRect.IsEqualInterior(aOther.mClipRect)) && mRoundedClipRects == aOther.mRoundedClipRects; } bool operator!=(const DisplayItemClip& aOther) const { return !(*this == aOther); } - bool HasClip() { return mHaveClipRect; } - const nsRect& GetClipRect() + bool HasClip() const { return mHaveClipRect; } + const nsRect& GetClipRect() const { NS_ASSERTION(HasClip(), "No clip rect!"); return mClipRect; } /** * Find the largest N such that the first N rounded rects in 'this' are * equal to the first N rounded rects in aOther, and N <= aMax.
new file mode 100644 --- /dev/null +++ b/layout/base/DisplayListClipState.cpp @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 20; 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/. */ + +#include "DisplayListClipState.h" + +#include "nsDisplayList.h" + +namespace mozilla { + +const DisplayItemClip* +DisplayListClipState::GetCurrentCombinedClip(nsDisplayListBuilder* aBuilder) +{ + if (mCurrentCombinedClip) { + return mCurrentCombinedClip; + } + if (!mClipContentDescendants && !mClipContainingBlockDescendants) { + return nullptr; + } + void* mem = aBuilder->Allocate(sizeof(DisplayItemClip)); + if (mClipContentDescendants) { + mCurrentCombinedClip = + new (mem) DisplayItemClip(*mClipContentDescendants); + if (mClipContainingBlockDescendants) { + mCurrentCombinedClip->IntersectWith(*mClipContainingBlockDescendants); + } + } else { + mCurrentCombinedClip = + new (mem) DisplayItemClip(*mClipContainingBlockDescendants); + } + return mCurrentCombinedClip; +} + +}
new file mode 100644 --- /dev/null +++ b/layout/base/DisplayListClipState.h @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 20; 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/. */ + +#ifndef DISPLAYLISTCLIPSTATE_H_ +#define DISPLAYLISTCLIPSTATE_H_ + +#include "DisplayItemClip.h" + +class nsIFrame; +class nsDisplayListBuilder; + +namespace mozilla { + +/** + * All clip coordinates are in appunits relative to the reference frame + * for the display item we're building. + */ +class DisplayListClipState { +public: + DisplayListClipState() + : mClipContentDescendants(nullptr) + , mClipContainingBlockDescendants(nullptr) + , mCurrentCombinedClip(nullptr) + {} + + const DisplayItemClip* GetCurrentCombinedClip(nsDisplayListBuilder* aBuilder); + + const DisplayItemClip* GetClipForContainingBlockDescendants() + { + return mClipContainingBlockDescendants; + } + + const DisplayItemClip* GetClipForContentDescendants() + { + return mClipContentDescendants; + } + + void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip) + { + mClipContainingBlockDescendants = aClip; + mCurrentCombinedClip = nullptr; + } + void SetClipForContentDescendants(const DisplayItemClip* aClip) + { + mClipContentDescendants = aClip; + mCurrentCombinedClip = nullptr; + } + +private: + /** + * All content descendants (i.e. following placeholder frames to their + * out-of-flows if necessary) should be clipped by mClipContentDescendants. + * Null if no clipping applies. + */ + const DisplayItemClip* mClipContentDescendants; + /** + * All containing-block descendants (i.e. frame descendants) should be + * clipped by mClipContainingBlockDescendants. + * Null if no clipping applies. + */ + const DisplayItemClip* mClipContainingBlockDescendants; + /** + * The intersection of mClipContentDescendants and + * mClipContainingBlockDescendants. + * Allocated in the nsDisplayListBuilder arena. Null if none has been + * allocated or both mClipContentDescendants and mClipContainingBlockDescendants + * are null. + */ + const DisplayItemClip* mCurrentCombinedClip; +}; + +} + +#endif /* DISPLAYLISTCLIPSTATE_H_ */
--- a/layout/base/Makefile.in +++ b/layout/base/Makefile.in @@ -16,16 +16,18 @@ ifndef _MSC_VER FAIL_ON_WARNINGS = 1 endif # !_MSC_VER EXPORTS_NAMESPACES = mozilla EXPORTS = \ + DisplayItemClip.h \ + DisplayListClipState.h \ FrameLayerBuilder.h \ FramePropertyTable.h \ nsArenaMemoryStats.h \ nsBidi.h \ nsBidiPresUtils.h \ nsCaret.h \ nsCSSFrameConstructor.h \ nsChangeHint.h \ @@ -54,16 +56,17 @@ EXPORTS = \ $(NULL) EXPORTS_mozilla = \ PaintTracker.h \ $(NULL) CPPSRCS = \ DisplayItemClip.cpp \ + DisplayListClipState.cpp \ FrameLayerBuilder.cpp \ FramePropertyTable.cpp \ MaskLayerImageCache.cpp \ nsCSSColorUtils.cpp \ nsCSSFrameConstructor.cpp \ nsCSSRendering.cpp \ nsCSSRenderingBorders.cpp \ nsCaret.cpp \