Bug 1022612. Part 43: Fix up SuppressComponentAlpha to allow component alpha in inactive layers over opaque parts of the chrome window. r=mattwoodrow

--HG--
extra : rebase_source : a15fb640c4fe7917321bcea5cdf2dc5e6087a140
This commit is contained in:
Robert O'Callahan 2014-07-15 16:23:37 +12:00
Родитель 5a87f018a5
Коммит 420f0b3320
4 изменённых файлов: 32 добавлений и 30 удалений

Просмотреть файл

@ -2212,21 +2212,22 @@ ContainerState::PopThebesLayerData()
}
static bool
SuppressComponentAlpha(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem)
IsItemAreaInWindowOpaqueRegion(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
const nsRect& aComponentAlphaBounds)
{
// Suppress component alpha for items in the toplevel window chrome that
// aren't transformed.
nsIFrame* f = aItem->Frame();
nsIFrame* ref = aBuilder->RootReferenceFrame();
if (f->PresContext() != ref->PresContext())
return false;
for (nsIFrame* t = f; t; t = t->GetParent()) {
if (t->IsTransformed())
return false;
if (!aItem->Frame()->PresContext()->IsChrome()) {
// Assume that Web content is always in the window opaque region.
return true;
}
return true;
if (aItem->ReferenceFrame() != aBuilder->RootReferenceFrame()) {
// aItem is probably in some transformed subtree.
// We're not going to bother figuring out where this landed, we're just
// going to assume it might have landed over a transparent part of
// the window.
return false;
}
return aBuilder->GetWindowOpaqueRegion().Contains(aComponentAlphaBounds);
}
void
@ -2338,10 +2339,11 @@ ThebesLayerData::Accumulate(ContainerState* aState,
nsIntRect componentAlphaRect =
aState->ScaleToOutsidePixels(componentAlpha, false).Intersect(aVisibleRect);
if (!mOpaqueRegion.Contains(componentAlphaRect)) {
if (SuppressComponentAlpha(aState->mBuilder, aItem)) {
aItem->DisableComponentAlpha();
} else {
if (IsItemAreaInWindowOpaqueRegion(aState->mBuilder, aItem,
componentAlpha.Intersect(aItem->GetVisibleRect()))) {
mNeedComponentAlpha = true;
} else {
aItem->DisableComponentAlpha();
}
}
}
@ -2603,8 +2605,8 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
// Add opaque areas to the "exclude glass" region. Only do this for
// ThebesLayers which are direct children of the root layer; this means
// they can't have transforms or opacity wrapping them.
if (!mContainerLayer->GetParent() && mBuilder->HasGlass()) {
mBuilder->AddExcludedGlassRegion(opaqueClipped);
if (!mContainerLayer->GetParent()) {
mBuilder->AddWindowOpaqueRegion(opaqueClipped);
}
opaquePixels = ScaleRegionToInsidePixels(opaqueClipped, snapOpaque);
if (aFixedPosFrame && ItemCoversScrollableArea(aItem, opaque)) {

Просмотреть файл

@ -667,11 +667,15 @@ public:
* -moz-win-exclude-glass style. Used in setting glass margins on
* Windows.
*/
void AddExcludedGlassRegion(const nsRegion& bounds) {
mExcludedGlassRegion.Or(mExcludedGlassRegion, bounds);
void AddWindowOpaqueRegion(const nsRegion& bounds) {
mWindowOpaqueRegion.Or(mWindowOpaqueRegion, bounds);
}
const nsRegion& GetExcludedGlassRegion() {
return mExcludedGlassRegion;
/**
* Returns the window opaque region built so far. This may be incomplete
* since the opaque region is built during layer construction.
*/
const nsRegion& GetWindowOpaqueRegion() {
return mWindowOpaqueRegion;
}
void SetGlassDisplayItem(nsDisplayItem* aItem) {
if (mGlassDisplayItem) {
@ -684,10 +688,6 @@ public:
mGlassDisplayItem = aItem;
}
}
// Call this only after we've finished building the display list
bool HasGlass() {
return mGlassDisplayItem != nullptr;
}
bool NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem) {
return aItem == mGlassDisplayItem;
}
@ -747,7 +747,7 @@ private:
nsPoint mCurrentOffsetToReferenceFrame;
// Relative to mCurrentFrame.
nsRect mDirtyRect;
nsRegion mExcludedGlassRegion;
nsRegion mWindowOpaqueRegion;
// The display item for the Windows window glass background, if any
nsDisplayItem* mGlassDisplayItem;
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;

Просмотреть файл

@ -3021,7 +3021,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
!(aFlags & PAINT_DOCUMENT_RELATIVE)) {
nsIWidget *widget = aFrame->GetNearestWidget();
if (widget) {
nsRegion excludedRegion = builder.GetExcludedGlassRegion();
nsRegion excludedRegion = builder.GetWindowOpaqueRegion();
nsIntRegion windowRegion(excludedRegion.ToNearestPixels(presContext->AppUnitsPerDevPixel()));
widget->UpdateOpaqueRegion(windowRegion);
}

Просмотреть файл

@ -1320,8 +1320,8 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// in calculating glass margins on Windows.
const nsStyleDisplay* styles = StyleDisplay();
if (styles && styles->mAppearance == NS_THEME_WIN_EXCLUDE_GLASS) {
nsRect rect = nsRect(aBuilder->ToReferenceFrame(this), GetSize());
aBuilder->AddExcludedGlassRegion(rect);
aBuilder->AddWindowOpaqueRegion(
nsRect(aBuilder->ToReferenceFrame(this), GetSize()));
}
}