зеркало из https://github.com/mozilla/gecko-dev.git
Bug 602757. Part 2: Detect display items over the transparent part of a window, and disable usage of component alpha (i.e., subpixel antialiasing) for those items. r=tnikkel,a=blocking
This commit is contained in:
Родитель
64c483c0b7
Коммит
b81ded8225
|
@ -895,6 +895,29 @@ ContainerState::PopThebesLayerData()
|
|||
mThebesLayerDataStack.RemoveElementAt(lastIndex);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
SuppressComponentAlpha(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem)
|
||||
{
|
||||
const nsRegion* windowTransparentRegion = aBuilder->GetFinalTransparentRegion();
|
||||
if (!windowTransparentRegion || windowTransparentRegion->IsEmpty())
|
||||
return PR_FALSE;
|
||||
|
||||
// Suppress component alpha for items in the toplevel window that are over
|
||||
// the window translucent area
|
||||
nsIFrame* f = aItem->GetUnderlyingFrame();
|
||||
nsIFrame* ref = aBuilder->ReferenceFrame();
|
||||
if (f->PresContext() != ref->PresContext())
|
||||
return PR_FALSE;
|
||||
|
||||
for (nsIFrame* t = f; t; t = t->GetParent()) {
|
||||
if (t->IsTransformed())
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return windowTransparentRegion->Intersects(aItem->GetBounds(aBuilder));
|
||||
}
|
||||
|
||||
void
|
||||
ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem,
|
||||
|
@ -937,7 +960,11 @@ ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
} else if (aItem->HasText()) {
|
||||
if (!mOpaqueRegion.Contains(aVisibleRect)) {
|
||||
mNeedComponentAlpha = PR_TRUE;
|
||||
if (SuppressComponentAlpha(aBuilder, aItem)) {
|
||||
aItem->DisableComponentAlpha();
|
||||
} else {
|
||||
mNeedComponentAlpha = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
mForceTransparentSurface = mForceTransparentSurface || forceTransparentSurface;
|
||||
|
|
|
@ -73,6 +73,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
|||
: mReferenceFrame(aReferenceFrame),
|
||||
mIgnoreScrollFrame(nsnull),
|
||||
mCurrentTableItem(nsnull),
|
||||
mFinalTransparentRegion(nsnull),
|
||||
mMode(aMode),
|
||||
mBuildCaret(aBuildCaret),
|
||||
mIgnoreSuppression(PR_FALSE),
|
||||
|
|
|
@ -338,6 +338,19 @@ public:
|
|||
*/
|
||||
FrameLayerBuilder* LayerBuilder() { return &mLayerBuilder; }
|
||||
|
||||
/**
|
||||
* Get the area of the final transparent region.
|
||||
*/
|
||||
const nsRegion* GetFinalTransparentRegion() { return mFinalTransparentRegion; }
|
||||
/**
|
||||
* Record the area of the final transparent region after all visibility
|
||||
* calculations were performed.
|
||||
*/
|
||||
void SetFinalTransparentRegion(const nsRegion& aFinalTransparentRegion)
|
||||
{
|
||||
mFinalTransparentRegion = &aFinalTransparentRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we need to descend into this frame when building
|
||||
* the display list, even though it doesn't intersect the dirty
|
||||
|
@ -422,6 +435,7 @@ private:
|
|||
nsAutoTArray<PresShellState,8> mPresShellStates;
|
||||
nsAutoTArray<nsIFrame*,100> mFramesMarkedForDisplay;
|
||||
nsDisplayTableItem* mCurrentTableItem;
|
||||
const nsRegion* mFinalTransparentRegion;
|
||||
Mode mMode;
|
||||
PRPackedBool mBuildCaret;
|
||||
PRPackedBool mIgnoreSuppression;
|
||||
|
@ -702,6 +716,11 @@ public:
|
|||
*/
|
||||
virtual PRBool HasText() { return PR_FALSE; }
|
||||
|
||||
/**
|
||||
* Disable usage of component alpha. Currently only relevant for items that have text.
|
||||
*/
|
||||
virtual void DisableComponentAlpha() {}
|
||||
|
||||
protected:
|
||||
friend class nsDisplayList;
|
||||
|
||||
|
|
|
@ -1409,11 +1409,8 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
|
|||
PRUint32 flags = nsDisplayList::PAINT_DEFAULT;
|
||||
if (aFlags & PAINT_WIDGET_LAYERS) {
|
||||
flags |= nsDisplayList::PAINT_USE_WIDGET_LAYERS;
|
||||
nsIWidget *widget = aFrame->GetNearestWidget();
|
||||
PRInt32 pixelRatio = presContext->AppUnitsPerDevPixel();
|
||||
nsIntRegion visibleWindowRegion(visibleRegion.ToOutsidePixels(pixelRatio));
|
||||
nsIntRegion dirtyWindowRegion(aDirtyRegion.ToOutsidePixels(pixelRatio));
|
||||
|
||||
nsIWidget *widget = aFrame->GetNearestWidget();
|
||||
if (willFlushRetainedLayers) {
|
||||
// The caller wanted to paint from retained layers, but set up
|
||||
// the paint in such a way that we can't use them. We're going
|
||||
|
@ -1426,6 +1423,10 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
|
|||
} else if (widget && !(aFlags & PAINT_DOCUMENT_RELATIVE)) {
|
||||
// XXX we should simplify this API now that dirtyWindowRegion always
|
||||
// covers the entire window
|
||||
PRInt32 pixelRatio = presContext->AppUnitsPerDevPixel();
|
||||
nsIntRegion visibleWindowRegion(visibleRegion.ToOutsidePixels(pixelRatio));
|
||||
nsIntRegion dirtyWindowRegion(aDirtyRegion.ToOutsidePixels(pixelRatio));
|
||||
builder.SetFinalTransparentRegion(visibleRegion);
|
||||
widget->UpdatePossiblyTransparentRegion(dirtyWindowRegion, visibleWindowRegion);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4039,7 +4039,8 @@ nsTextFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
class nsDisplayText : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplayText(nsDisplayListBuilder* aBuilder, nsTextFrame* aFrame) :
|
||||
nsDisplayItem(aBuilder, aFrame) {
|
||||
nsDisplayItem(aBuilder, aFrame),
|
||||
mDisableSubpixelAA(PR_FALSE) {
|
||||
MOZ_COUNT_CTOR(nsDisplayText);
|
||||
}
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
|
@ -4062,6 +4063,10 @@ public:
|
|||
NS_DISPLAY_DECL_NAME("Text", TYPE_TEXT)
|
||||
|
||||
virtual PRBool HasText() { return PR_TRUE; }
|
||||
|
||||
virtual void DisableComponentAlpha() { mDisableSubpixelAA = PR_TRUE; }
|
||||
|
||||
PRPackedBool mDisableSubpixelAA;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -4073,8 +4078,11 @@ nsDisplayText::Paint(nsDisplayListBuilder* aBuilder,
|
|||
nsRect extraVisible = mVisibleRect;
|
||||
nscoord appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
extraVisible.Inflate(appUnitsPerDevPixel, appUnitsPerDevPixel);
|
||||
static_cast<nsTextFrame*>(mFrame)->
|
||||
PaintText(aCtx, ToReferenceFrame(), extraVisible);
|
||||
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
|
||||
|
||||
gfxContextAutoDisableSubpixelAntialiasing disable(aCtx->ThebesContext(),
|
||||
mDisableSubpixelAA);
|
||||
f->PaintText(aCtx, ToReferenceFrame(), extraVisible);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -333,7 +333,9 @@ class nsDisplayXULTextBox : public nsDisplayItem {
|
|||
public:
|
||||
nsDisplayXULTextBox(nsDisplayListBuilder* aBuilder,
|
||||
nsTextBoxFrame* aFrame) :
|
||||
nsDisplayItem(aBuilder, aFrame) {
|
||||
nsDisplayItem(aBuilder, aFrame),
|
||||
mDisableSubpixelAA(PR_FALSE)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayXULTextBox);
|
||||
}
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
|
@ -348,12 +350,18 @@ public:
|
|||
NS_DISPLAY_DECL_NAME("XULTextBox", TYPE_XUL_TEXT_BOX)
|
||||
|
||||
virtual PRBool HasText() { return PR_TRUE; }
|
||||
|
||||
virtual void DisableComponentAlpha() { mDisableSubpixelAA = PR_TRUE; }
|
||||
|
||||
PRPackedBool mDisableSubpixelAA;
|
||||
};
|
||||
|
||||
void
|
||||
nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx)
|
||||
{
|
||||
gfxContextAutoDisableSubpixelAntialiasing disable(aCtx->ThebesContext(),
|
||||
mDisableSubpixelAA);
|
||||
static_cast<nsTextBoxFrame*>(mFrame)->
|
||||
PaintTitle(*aCtx, mVisibleRect, ToReferenceFrame());
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче