author | Robert O'Callahan <robert@ocallahan.org> |
Mon, 20 Dec 2010 14:26:14 +1300 | |
changeset 59481 | bc423fb0aa13fb9c2d261c9993ccf6021fe85ff0 |
parent 59480 | 53bc550efbccbf583419f1027de08c9b4e56b9ba |
child 59482 | 8019b50e514c708e3b633da8b4c394edd4a27f0b |
push id | 17638 |
push user | rocallahan@mozilla.com |
push date | Mon, 20 Dec 2010 01:39:18 +0000 |
treeherder | mozilla-central@302d1d3e2817 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tnikkel, vlad |
bugs | 612840 |
milestone | 2.0b9pre |
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
|
gfx/layers/Layers.h | file | annotate | diff | comparison | revisions | |
layout/base/FrameLayerBuilder.cpp | file | annotate | diff | comparison | revisions |
--- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -477,17 +477,16 @@ public: enum { /** * If this is set, the caller is promising that by the end of this * transaction the entire visible region (as specified by * SetVisibleRegion) will be filled with opaque content. */ CONTENT_OPAQUE = 0x01, /** - * ThebesLayers only! * If this is set, the caller is promising that the visible region * contains no text over transparent pixels (any text, if present, * is over fully opaque pixels). */ CONTENT_NO_TEXT_OVER_TRANSPARENT = 0x02 }; /** * CONSTRUCTION PHASE ONLY @@ -733,17 +732,17 @@ public: protected: Layer(LayerManager* aManager, void* aImplData) : mManager(aManager), mParent(nsnull), mNextSibling(nsnull), mPrevSibling(nsnull), mImplData(aImplData), mOpacity(1.0), - mContentFlags(0), + mContentFlags(CONTENT_NO_TEXT_OVER_TRANSPARENT), mUseClipRect(PR_FALSE) {} void Mutated() { mManager->Mutated(this); } // Print interesting information about this into aTo. Internally // used to implement Dump*() and Log*(). If subclasses have // additional interesting properties, they should override this with @@ -827,17 +826,19 @@ public: } protected: ThebesLayer(LayerManager* aManager, void* aImplData) : Layer(aManager, aImplData) , mValidRegion() , mXResolution(1.0) , mYResolution(1.0) - {} + { + mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT + } virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix); nsIntRegion mValidRegion; // Resolution values tell this to paint its content scaled by // <aXResolution, aYResolution>, into a backing buffer with // dimensions scaled the same. A non-1.0 resolution also tells this // to set scaling factors that compensate for the re-paint @@ -915,17 +916,19 @@ public: PRBool HasMultipleChildren(); protected: ContainerLayer(LayerManager* aManager, void* aImplData) : Layer(aManager, aImplData), mFirstChild(nsnull), mLastChild(nsnull), mUseIntermediateSurface(PR_FALSE) - {} + { + mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT + } /** * A default implementation of ComputeEffectiveTransforms for use by OpenGL * and D3D. */ void DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface); /**
--- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -143,18 +143,21 @@ public: */ void ProcessDisplayItems(const nsDisplayList& aList, const FrameLayerBuilder::Clip& aClip); /** * This finalizes all the open ThebesLayers by popping every element off * mThebesLayerDataStack, then sets the children of the container layer * to be all the layers in mNewChildLayers in that order and removes any * layers as children of the container that aren't in mNewChildLayers. + * @param aTextContentFlags if all child layers have CONTENT_NO_TEXT, adds + * CONTENT_NO_TEXT to *aTextContentFlags. + * Likewise for CONTENT_NO_TEXT_OVER_TRANSPARENT. */ - void Finish(); + void Finish(PRUint32 *aTextContentFlags); protected: /** * We keep a stack of these to represent the ThebesLayers that are * currently available to have display items added to. * We use a stack here because as much as possible we want to * assign display items to existing ThebesLayers, and to the lowest * ThebesLayer in z-order. This reduces the number of layers and @@ -1262,28 +1265,33 @@ ContainerState::CollectOldLayers() } else if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) { NS_ASSERTION(layer->AsThebesLayer(), "Wrong layer type"); mRecycledThebesLayers.AppendElement(static_cast<ThebesLayer*>(layer)); } } } void -ContainerState::Finish() +ContainerState::Finish(PRUint32* aTextContentFlags) { while (!mThebesLayerDataStack.IsEmpty()) { PopThebesLayerData(); } + PRUint32 textContentFlags = Layer::CONTENT_NO_TEXT_OVER_TRANSPARENT; + for (PRUint32 i = 0; i <= mNewChildLayers.Length(); ++i) { // An invariant of this loop is that the layers in mNewChildLayers // with index < i are the first i child layers of mContainerLayer. Layer* layer; if (i < mNewChildLayers.Length()) { layer = mNewChildLayers[i]; + if (!layer->GetVisibleRegion().IsEmpty()) { + textContentFlags &= layer->GetContentFlags(); + } if (!layer->GetParent()) { // This is not currently a child of the container, so just add it // now. Layer* prevChild = i == 0 ? nsnull : mNewChildLayers[i - 1].get(); mContainerLayer->InsertAfter(layer, prevChild); continue; } NS_ASSERTION(layer->GetParent() == mContainerLayer, @@ -1302,16 +1310,18 @@ ContainerState::Finish() while (nextOldChild != layer) { Layer* tmp = nextOldChild; nextOldChild = nextOldChild->GetNextSibling(); mContainerLayer->RemoveChild(tmp); } // If non-null, 'layer' is now in the right place in the list, so we // can just move on to the next one. } + + *aTextContentFlags = textContentFlags; } static void SetHasContainerLayer(nsIFrame* aFrame) { aFrame->AddStateBits(NS_FRAME_HAS_CONTAINER_LAYER); for (nsIFrame* f = aFrame; f && !(f->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT); @@ -1390,21 +1400,28 @@ FrameLayerBuilder::BuildContainerLayerFo // invalidated. state.SetInvalidateAllThebesContent(); } SetHasContainerLayer(aContainerFrame); } Clip clip; state.ProcessDisplayItems(aChildren, clip); - state.Finish(); - PRUint32 flags = aChildren.IsOpaque() && - !aChildren.NeedsTransparentSurface() ? Layer::CONTENT_OPAQUE : 0; + // Set CONTENT_NO_TEXT_OVER_TRANSPARENT if any of our children have it. + // This is suboptimal ... a child could have text that's over transparent + // pixels in its own layer, but over opaque parts of previous siblings. + PRUint32 flags; + state.Finish(&flags); + + if (aChildren.IsOpaque() && !aChildren.NeedsTransparentSurface()) { + flags |= Layer::CONTENT_OPAQUE; + } containerLayer->SetContentFlags(flags); + return containerLayer.forget(); } Layer* FrameLayerBuilder::GetLeafLayerFor(nsDisplayListBuilder* aBuilder, LayerManager* aManager, nsDisplayItem* aItem) {