Bug 612840. Part 3: Make Layer::CONTENT_NO_TEXT_OVER_TRANSPARENT applicable to all layer types, and set CONTENT_NO_TEXT_OVER_TRANSPARENT on container layers. r=tnikkel,r=vlad

This commit is contained in:
Robert O'Callahan 2010-12-20 14:26:14 +13:00
parent 76d7bbcd27
commit 3259bd6e70
2 changed files with 29 additions and 9 deletions

View File

@ -482,7 +482,6 @@ public:
*/
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).
@ -738,7 +737,7 @@ protected:
mPrevSibling(nsnull),
mImplData(aImplData),
mOpacity(1.0),
mContentFlags(0),
mContentFlags(CONTENT_NO_TEXT_OVER_TRANSPARENT),
mUseClipRect(PR_FALSE)
{}
@ -832,7 +831,9 @@ protected:
, mValidRegion()
, mXResolution(1.0)
, mYResolution(1.0)
{}
{
mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
}
virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
@ -920,7 +921,9 @@ protected:
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

View File

@ -148,8 +148,11 @@ public:
* 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:
/**
@ -1267,18 +1270,23 @@ ContainerState::CollectOldLayers()
}
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.
@ -1307,6 +1315,8 @@ ContainerState::Finish()
// 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
@ -1395,11 +1405,18 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
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();
}