author | Robert O'Callahan <robert@ocallahan.org> |
Mon, 20 Dec 2010 14:26:14 +1300 | |
changeset 59482 | 8019b50e514c708e3b633da8b4c394edd4a27f0b |
parent 59481 | bc423fb0aa13fb9c2d261c9993ccf6021fe85ff0 |
child 59483 | f1ac5add876dcc639fe7b5eff6186514df88e356 |
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 | 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
|
--- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -199,17 +199,16 @@ Layer::CanUseOpaqueSurface() // doesn't need an alpha channel, we can use an opaque surface for this // layer too. Any transparent areas must be covered by something else // in the container. ContainerLayer* parent = GetParent(); return parent && parent->GetFirstChild() == this && parent->CanUseOpaqueSurface(); } - #ifdef MOZ_IPC // NB: eventually these methods will be defined unconditionally, and // can be moved into Layers.h const nsIntRect* Layer::GetEffectiveClipRect() { if (ShadowLayer* shadow = AsShadowLayer()) { return shadow->GetShadowClipRect(); @@ -438,18 +437,18 @@ Layer::PrintInfo(nsACString& aTo, const AppendToString(aTo, mVisibleRegion, " [visible=", "]"); } if (1.0 != mOpacity) { aTo.AppendPrintf(" [opacity=%g]", mOpacity); } if (GetContentFlags() & CONTENT_OPAQUE) { aTo += " [opaqueContent]"; } - if (GetContentFlags() & CONTENT_NO_TEXT_OVER_TRANSPARENT) { - aTo += " [noTextOverTransparent]"; + if (GetContentFlags() & CONTENT_COMPONENT_ALPHA) { + aTo += " [componentAlpha]"; } return aTo; } nsACString& ThebesLayer::PrintInfo(nsACString& aTo, const char* aPrefix) {
--- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -477,30 +477,35 @@ 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, /** - * 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). + * If this is set, the caller is notifying that the contents of this layer + * require per-component alpha for optimal fidelity. However, there is no + * guarantee that component alpha will be supported for this layer at + * paint time. + * This should never be set at the same time as CONTENT_OPAQUE. */ - CONTENT_NO_TEXT_OVER_TRANSPARENT = 0x02 + CONTENT_COMPONENT_ALPHA = 0x02 }; /** * CONSTRUCTION PHASE ONLY * This lets layout make some promises about what will be drawn into the * visible region of the ThebesLayer. This enables internal quality * and performance optimizations. */ void SetContentFlags(PRUint32 aFlags) { + NS_ASSERTION((aFlags & (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA)) != + (CONTENT_OPAQUE | CONTENT_COMPONENT_ALPHA), + "Can't be opaque and require component alpha"); mContentFlags = aFlags; Mutated(); } /** * CONSTRUCTION PHASE ONLY * Tell this layer which region will be visible. The visible region * is a region which contains all the contents of the layer that can * actually affect the rendering of the window. It can exclude areas @@ -732,17 +737,17 @@ public: protected: Layer(LayerManager* aManager, void* aImplData) : mManager(aManager), mParent(nsnull), mNextSibling(nsnull), mPrevSibling(nsnull), mImplData(aImplData), mOpacity(1.0), - mContentFlags(CONTENT_NO_TEXT_OVER_TRANSPARENT), + mContentFlags(0), 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
--- a/gfx/layers/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -464,17 +464,17 @@ BasicThebesLayer::Paint(gfxContext* aCon PRBool canUseOpaqueSurface = CanUseOpaqueSurface(); Buffer::ContentType contentType = canUseOpaqueSurface ? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA; float opacity = GetEffectiveOpacity(); if (!BasicManager()->IsRetained() || (!canUseOpaqueSurface && - !(mContentFlags & CONTENT_NO_TEXT_OVER_TRANSPARENT) && + (mContentFlags & CONTENT_COMPONENT_ALPHA) && !MustRetainContent())) { mValidRegion.SetEmpty(); mBuffer.Clear(); nsIntRegion toDraw = IntersectWithClip(mVisibleRegion, target); if (!toDraw.IsEmpty()) { target->Save(); gfxUtils::ClipToRegionSnapped(target, toDraw);
--- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -143,19 +143,18 @@ 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. + * @param aTextContentFlags if any child layer has CONTENT_COMPONENT_ALPHA, + * set *aTextContentFlags to CONTENT_COMPONENT_ALPHA */ 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 @@ -164,17 +163,17 @@ protected: * makes it more likely a display item will be rendered to an opaque * layer, giving us the best chance of getting subpixel AA. */ class ThebesLayerData { public: ThebesLayerData() : mActiveScrolledRoot(nsnull), mLayer(nsnull), mIsSolidColorInVisibleRegion(PR_FALSE), - mHasTextOverTransparent(PR_FALSE), + mNeedComponentAlpha(PR_FALSE), mForceTransparentSurface(PR_FALSE) {} /** * Record that an item has been added to the ThebesLayer, so we * need to update our regions. * @param aVisibleRect the area of the item that's visible * @param aDrawRect the area of the item that would be drawn if it * was completely visible * @param aOpaqueRect if non-null, the area of the item that's opaque. @@ -238,17 +237,17 @@ protected: /** * True if every pixel in mVisibleRegion will have color mSolidColor. */ PRPackedBool mIsSolidColorInVisibleRegion; /** * True if there is any text visible in the layer that's over * transparent pixels in the layer. */ - PRPackedBool mHasTextOverTransparent; + PRPackedBool mNeedComponentAlpha; /** * Set if the layer should be treated as transparent, even if its entire * area is covered by opaque display items. For example, this needs to * be set if something is going to "punch holes" in the layer by clearing * part of its surface. */ PRPackedBool mForceTransparentSurface; }; @@ -863,19 +862,24 @@ ContainerState::PopThebesLayerData() NS_ASSERTION(userData, "where did our user data go?"); if (userData->mForcedBackgroundColor != backgroundColor) { // Invalidate the entire target ThebesLayer since we're changing // the background color data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion()); } userData->mForcedBackgroundColor = backgroundColor; } - PRUint32 flags = - ((isOpaque && !data->mForceTransparentSurface) ? Layer::CONTENT_OPAQUE : 0) | - (data->mHasTextOverTransparent ? 0 : Layer::CONTENT_NO_TEXT_OVER_TRANSPARENT); + PRUint32 flags; + if (isOpaque && !data->mForceTransparentSurface) { + flags = Layer::CONTENT_OPAQUE; + } else if (data->mNeedComponentAlpha) { + flags = Layer::CONTENT_COMPONENT_ALPHA; + } else { + flags = 0; + } layer->SetContentFlags(flags); if (lastIndex > 0) { // Since we're going to pop off the last ThebesLayerData, the // mVisibleAboveRegion of the second-to-last item will need to include // the regions of the last item. ThebesLayerData* nextData = mThebesLayerDataStack[lastIndex - 1]; nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion, @@ -928,17 +932,17 @@ ContainerState::ThebesLayerData::Accumul // we see doesn't get discarded. nsIntRegion tmp; tmp.Or(mOpaqueRegion, aDrawRect); if (tmp.GetNumRects() <= 4) { mOpaqueRegion = tmp; } } else if (aItem->HasText()) { if (!mOpaqueRegion.Contains(aVisibleRect)) { - mHasTextOverTransparent = PR_TRUE; + mNeedComponentAlpha = PR_TRUE; } } mForceTransparentSurface = mForceTransparentSurface || forceTransparentSurface; } already_AddRefed<ThebesLayer> ContainerState::FindThebesLayerFor(nsDisplayItem* aItem, const nsIntRect& aVisibleRect, @@ -1271,26 +1275,26 @@ ContainerState::CollectOldLayers() void ContainerState::Finish(PRUint32* aTextContentFlags) { while (!mThebesLayerDataStack.IsEmpty()) { PopThebesLayerData(); } - PRUint32 textContentFlags = Layer::CONTENT_NO_TEXT_OVER_TRANSPARENT; + PRUint32 textContentFlags = 0; 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(); + textContentFlags |= layer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA; } 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; } @@ -1401,24 +1405,25 @@ FrameLayerBuilder::BuildContainerLayerFo state.SetInvalidateAllThebesContent(); } SetHasContainerLayer(aContainerFrame); } Clip clip; state.ProcessDisplayItems(aChildren, clip); - // Set CONTENT_NO_TEXT_OVER_TRANSPARENT if any of our children have it. + // Set CONTENT_COMPONENT_ALPHA 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; + // Clear CONTENT_COMPONENT_ALPHA + flags = Layer::CONTENT_OPAQUE; } containerLayer->SetContentFlags(flags); return containerLayer.forget(); } Layer* FrameLayerBuilder::GetLeafLayerFor(nsDisplayListBuilder* aBuilder,