Bug 982812 - Use UpdateThemeGeometry for windows region clearing. r=mstange

This commit is contained in:
Matt Woodrow 2014-03-17 16:42:48 +08:00
parent 7add71c341
commit 007105ff82
12 changed files with 40 additions and 50 deletions

View File

@ -30,8 +30,8 @@ class nsIWidget;
// IID for the nsITheme interface
// {b0f3efe9-0bd4-4f6b-8daa-0ec7f6006822}
#define NS_ITHEME_IID \
{ 0x2e49c679, 0x2130, 0x432c, \
{ 0x92, 0xcb, 0xd4, 0x8e, 0x9a, 0xe2, 0x34, 0x75 } }
{ 0x4440b5c7, 0xd8bd, 0x4d9c, \
{ 0x9c, 0x3e, 0xa5, 0xe6, 0x26, 0x81, 0x10, 0xa0 } }
// {D930E29B-6909-44e5-AB4B-AF10D6923705}
#define NS_THEMERENDERER_CID \
{ 0x9020805b, 0x14a3, 0x4125, \
@ -63,8 +63,7 @@ public:
nsIFrame* aFrame,
uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aDirtyRect,
nsIntRegion* aRegionToClear = nullptr) = 0;
const nsRect& aDirtyRect) = 0;
/**
* Get the computed CSS border for the widget, in pixels.

View File

@ -3761,9 +3761,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
rc->Init(presContext->DeviceContext(), aContext);
nsIntRegion temp = builder->GetRegionToClear();
builder->ResetRegionToClear();
if (shouldDrawRectsSeparately) {
nsIntRegionRectIterator it(aRegionToDraw);
while (const nsIntRect* iterRect = it.Next()) {
@ -3805,12 +3802,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
if (!aRegionToInvalidate.IsEmpty()) {
aLayer->AddInvalidRect(aRegionToInvalidate.GetBounds());
}
if (!builder->GetRegionToClear().IsEmpty()) {
aLayer->Manager()->SetRegionToClear(builder->GetRegionToClear());
}
builder->ResetRegionToClear();
builder->AddRegionToClear(temp);
}
bool

View File

@ -2358,6 +2358,7 @@ nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuil
case NS_THEME_WINDOW_TITLEBAR:
case NS_THEME_WINDOW_BUTTON_BOX:
case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON:
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
RegisterThemeGeometry(aBuilder, aFrame);
break;
case NS_THEME_WIN_BORDERLESS_GLASS:
@ -2445,11 +2446,7 @@ nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder,
theme->GetWidgetOverflow(presContext->DeviceContext(), mFrame, mAppearance,
&drawing);
drawing.IntersectRect(drawing, aBounds);
nsIntRegion clear;
theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing, &clear);
MOZ_ASSERT(clear.IsEmpty() || ReferenceFrame() == aBuilder->RootReferenceFrame(),
"Can't add to clear region if we're transformed!");
aBuilder->AddRegionToClear(clear);
theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing);
}
bool nsDisplayThemedBackground::IsWindowActive()

View File

@ -641,10 +641,6 @@ public:
DisplayListClipState& ClipState() { return mClipState; }
void AddRegionToClear(const nsIntRegion& aRegion) { mRegionToClear.Or(mRegionToClear, aRegion); }
const nsIntRegion& GetRegionToClear() { return mRegionToClear; }
void ResetRegionToClear() { mRegionToClear.SetEmpty(); }
private:
void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
const nsRect& aDirtyRect);
@ -678,8 +674,6 @@ private:
const nsIFrame* mCachedReferenceFrame;
nsPoint mCachedOffset;
nsRegion mExcludedGlassRegion;
// Area of the window (in pixels) to clear so the OS can draw them.
nsIntRegion mRegionToClear;
// The display item for the Windows window glass background, if any
nsDisplayItem* mGlassDisplayItem;
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;

View File

@ -34,8 +34,7 @@ public:
nsIFrame* aFrame,
uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aDirtyRect,
nsIntRegion* aRegionToClear);
const nsRect& aDirtyRect);
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,

View File

@ -2080,8 +2080,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aDirtyRect,
nsIntRegion* aRegionToClear)
const nsRect& aDirtyRect)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;

View File

@ -752,8 +752,7 @@ nsNativeThemeGTK::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aDirtyRect,
nsIntRegion* aRegionToClear)
const nsRect& aDirtyRect)
{
GtkWidgetState state;
GtkThemeWidgetType gtkWidgetType;

View File

@ -24,8 +24,7 @@ public:
NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame, uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aDirtyRect,
nsIntRegion* aRegionToClear);
const nsRect& aDirtyRect);
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType, nsIntMargin* aResult);

View File

@ -1536,8 +1536,7 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aDirtyRect,
nsIntRegion* aRegionToClear)
const nsRect& aDirtyRect)
{
HANDLE theme = GetTheme(aWidgetType);
if (!theme)
@ -1568,6 +1567,10 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
case NS_THEME_WIN_BORDERLESS_GLASS:
// Nothing to draw, this is the glass background.
return NS_OK;
case NS_THEME_WINDOW_BUTTON_BOX:
case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
// We handle these through nsIWidget::UpdateThemeGeometries
return NS_OK;
break;
}
}
@ -1900,20 +1903,6 @@ RENDER_AGAIN:
DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect, &clipRect);
}
}
else if ((aWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
nsUXThemeData::CheckForCompositor())
{
// The caption buttons are drawn by the DWM, we just need to clear the area where they
// are because we might have drawn something above them (like a background-image).
NS_ASSERTION(aRegionToClear, "Must have a clear region to set!");
if (aRegionToClear) {
// Create a rounded rectangle to follow the buttons' look.
*aRegionToClear = nsIntRect(dr.X(), dr.Y(), dr.Width(), dr.Height() - 2.0);
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 1.0, dr.YMost() - 2.0, dr.Width() - 1.0, 1.0));
aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 2.0, dr.YMost() - 1.0, dr.Width() - 3.0, 1.0));
}
}
nativeDrawing.EndNativeDrawing();

View File

@ -31,8 +31,7 @@ public:
nsIFrame* aFrame,
uint8_t aWidgetType,
const nsRect& aRect,
const nsRect& aDirtyRect,
nsIntRegion* aRegionToClear);
const nsRect& aDirtyRect);
NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame* aFrame,

View File

@ -127,6 +127,7 @@
#include "nsToolkitCompsCID.h"
#include "nsIAppStartup.h"
#include "mozilla/WindowsVersion.h"
#include "nsThemeConstants.h"
#ifdef MOZ_ENABLE_D3D9_LAYER
#include "LayerManagerD3D9.h"
@ -3556,6 +3557,28 @@ nsWindow::EndRemoteDrawing()
mCompositeDC = nullptr;
}
void
nsWindow::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
{
nsIntRegion clearRegion;
for (size_t i = 0; i < aThemeGeometries.Length(); i++) {
if ((aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
nsUXThemeData::CheckForCompositor())
{
nsIntRect bounds = aThemeGeometries[i].mRect;
clearRegion = nsIntRect(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height() - 2.0);
clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 1.0, bounds.YMost() - 2.0, bounds.Width() - 1.0, 1.0));
clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 2.0, bounds.YMost() - 1.0, bounds.Width() - 3.0, 1.0));
}
}
nsRefPtr<LayerManager> layerManager = GetLayerManager();
if (layerManager) {
layerManager->SetRegionToClear(clearRegion);
}
}
/**************************************************************
**************************************************************
**

View File

@ -196,6 +196,8 @@ public:
mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() MOZ_OVERRIDE;
virtual void EndRemoteDrawing() MOZ_OVERRIDE;
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) MOZ_OVERRIDE;
/**
* Event helpers
*/