Bug 1230047 (part 2) - Make several PaintWindow() functions use LayoutDevice coordinates. r=kats.

Specifically, the PaintWindow() functions in the following classes:
- nsIWidgetListener, and its subclasses nsView and nsWebBrowser;
- nsChildView;
- nsWindow (the one in widget/uikit/);
- nsViewManager.
This commit is contained in:
Nicholas Nethercote 2015-12-02 21:45:41 -08:00
parent 209e8be54e
commit ecc2b60c48
18 changed files with 52 additions and 42 deletions

View File

@ -1729,7 +1729,7 @@ nsWebBrowser::WindowLowered(nsIWidget* aWidget)
} }
bool bool
nsWebBrowser::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) nsWebBrowser::PaintWindow(nsIWidget* aWidget, LayoutDeviceIntRegion aRegion)
{ {
LayerManager* layerManager = aWidget->GetLayerManager(); LayerManager* layerManager = aWidget->GetLayerManager();
NS_ASSERTION(layerManager, "Must be in paint event"); NS_ASSERTION(layerManager, "Must be in paint event");
@ -1737,7 +1737,7 @@ nsWebBrowser::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion)
layerManager->BeginTransaction(); layerManager->BeginTransaction();
RefPtr<PaintedLayer> root = layerManager->CreatePaintedLayer(); RefPtr<PaintedLayer> root = layerManager->CreatePaintedLayer();
if (root) { if (root) {
nsIntRect dirtyRect = aRegion.GetBounds(); nsIntRect dirtyRect = aRegion.GetBounds().ToUnknownRect();
root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(dirtyRect)); root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(dirtyRect));
layerManager->SetRoot(root); layerManager->SetRoot(root);
} }

View File

@ -122,7 +122,8 @@ protected:
// nsIWidgetListener // nsIWidgetListener
virtual void WindowRaised(nsIWidget* aWidget); virtual void WindowRaised(nsIWidget* aWidget);
virtual void WindowLowered(nsIWidget* aWidget); virtual void WindowLowered(nsIWidget* aWidget);
virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) override; virtual bool PaintWindow(nsIWidget* aWidget,
mozilla::LayoutDeviceIntRegion aRegion) override;
protected: protected:
RefPtr<nsDocShellTreeOwner> mDocShellTreeOwner; RefPtr<nsDocShellTreeOwner> mDocShellTreeOwner;

View File

@ -15,15 +15,6 @@ static_assert((int(NS_SIDE_TOP) == 0) &&
(int(NS_SIDE_LEFT) == 3), (int(NS_SIDE_LEFT) == 3),
"The mozilla::css::Side sequence must match the nsMargin nscoord sequence"); "The mozilla::css::Side sequence must match the nsMargin nscoord sequence");
nsRect
ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel)
{
return nsRect(NSIntPixelsToAppUnits(aRect.x, aAppUnitsPerPixel),
NSIntPixelsToAppUnits(aRect.y, aAppUnitsPerPixel),
NSIntPixelsToAppUnits(aRect.width, aAppUnitsPerPixel),
NSIntPixelsToAppUnits(aRect.height, aAppUnitsPerPixel));
}
const mozilla::gfx::IntRect& GetMaxSizedIntRect() { const mozilla::gfx::IntRect& GetMaxSizedIntRect() {
static const mozilla::gfx::IntRect r(0, 0, INT32_MAX, INT32_MAX); static const mozilla::gfx::IntRect r(0, 0, INT32_MAX, INT32_MAX);
return r; return r;

View File

@ -303,8 +303,15 @@ nsRect::RemoveResolution(const float aResolution) const
const mozilla::gfx::IntRect& GetMaxSizedIntRect(); const mozilla::gfx::IntRect& GetMaxSizedIntRect();
// app units are integer multiples of pixels, so no rounding needed // app units are integer multiples of pixels, so no rounding needed
template<class units>
nsRect nsRect
ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel); ToAppUnits(const mozilla::gfx::IntRectTyped<units>& aRect, nscoord aAppUnitsPerPixel)
{
return nsRect(NSIntPixelsToAppUnits(aRect.x, aAppUnitsPerPixel),
NSIntPixelsToAppUnits(aRect.y, aAppUnitsPerPixel),
NSIntPixelsToAppUnits(aRect.width, aAppUnitsPerPixel),
NSIntPixelsToAppUnits(aRect.height, aAppUnitsPerPixel));
}
#ifdef DEBUG #ifdef DEBUG
// Diagnostics // Diagnostics

View File

@ -1062,7 +1062,7 @@ nsView::WillPaintWindow(nsIWidget* aWidget)
} }
bool bool
nsView::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) nsView::PaintWindow(nsIWidget* aWidget, LayoutDeviceIntRegion aRegion)
{ {
NS_ASSERTION(this == nsView::GetViewFor(aWidget), "wrong view for widget?"); NS_ASSERTION(this == nsView::GetViewFor(aWidget), "wrong view for widget?");

View File

@ -59,6 +59,7 @@ public:
friend class nsViewManager; friend class nsViewManager;
typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect; typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
@ -382,7 +383,8 @@ public:
virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) override; virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) override;
virtual bool RequestWindowClose(nsIWidget* aWidget) override; virtual bool RequestWindowClose(nsIWidget* aWidget) override;
virtual void WillPaintWindow(nsIWidget* aWidget) override; virtual void WillPaintWindow(nsIWidget* aWidget) override;
virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) override; virtual bool PaintWindow(nsIWidget* aWidget,
LayoutDeviceIntRegion aRegion) override;
virtual void DidPaintWindow() override; virtual void DidPaintWindow() override;
virtual void DidCompositeWindow(const mozilla::TimeStamp& aCompositeStart, virtual void DidCompositeWindow(const mozilla::TimeStamp& aCompositeStart,
const mozilla::TimeStamp& aCompositeEnd) override; const mozilla::TimeStamp& aCompositeEnd) override;

View File

@ -281,7 +281,7 @@ nsView* nsViewManager::GetDisplayRootFor(nsView* aView)
aContext may be null, in which case layers should be used for aContext may be null, in which case layers should be used for
rendering. rendering.
*/ */
void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion) void nsViewManager::Refresh(nsView* aView, const LayoutDeviceIntRegion& aRegion)
{ {
NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager"); NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
@ -291,6 +291,7 @@ void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion)
// damageRegion is the damaged area, in twips, relative to the view origin // damageRegion is the damaged area, in twips, relative to the view origin
nsRegion damageRegion = aRegion.ToAppUnits(AppUnitsPerDevPixel()); nsRegion damageRegion = aRegion.ToAppUnits(AppUnitsPerDevPixel());
// move region from widget coordinates into view coordinates // move region from widget coordinates into view coordinates
damageRegion.MoveBy(-aView->ViewToWidgetOffset()); damageRegion.MoveBy(-aView->ViewToWidgetOffset());
@ -714,7 +715,8 @@ void nsViewManager::WillPaintWindow(nsIWidget* aWidget)
} }
} }
bool nsViewManager::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) bool nsViewManager::PaintWindow(nsIWidget* aWidget,
LayoutDeviceIntRegion aRegion)
{ {
if (!aWidget || !mContext) if (!aWidget || !mContext)
return false; return false;

View File

@ -28,6 +28,7 @@ public:
friend class nsView; friend class nsView;
typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect; typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
@ -346,7 +347,7 @@ private:
void InvalidateViews(nsView *aView); void InvalidateViews(nsView *aView);
// aView is the view for aWidget and aRegion is relative to aWidget. // aView is the view for aWidget and aRegion is relative to aWidget.
void Refresh(nsView *aView, const nsIntRegion& aRegion); void Refresh(nsView* aView, const LayoutDeviceIntRegion& aRegion);
// Utilities // Utilities
@ -380,7 +381,7 @@ private:
bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; } bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; }
void WillPaintWindow(nsIWidget* aWidget); void WillPaintWindow(nsIWidget* aWidget);
bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion); bool PaintWindow(nsIWidget* aWidget, LayoutDeviceIntRegion aRegion);
void DidPaintWindow(); void DidPaintWindow();
// Call this when you need to let the viewmanager know that it now has // Call this when you need to let the viewmanager know that it now has

View File

@ -999,7 +999,7 @@ PuppetWidget::Paint()
ctx->Clip(); ctx->Clip();
AutoLayerManagerSetup setupLayerManager(this, ctx, AutoLayerManagerSetup setupLayerManager(this, ctx,
BufferMode::BUFFER_NONE); BufferMode::BUFFER_NONE);
GetCurrentWidgetListener()->PaintWindow(this, region.ToUnknownRegion()); GetCurrentWidgetListener()->PaintWindow(this, region);
if (mTabChild) { if (mTabChild) {
mTabChild->NotifyPainted(); mTabChild->NotifyPainted();
} }

View File

@ -476,7 +476,7 @@ public:
virtual bool DispatchWindowEvent(mozilla::WidgetGUIEvent& event); virtual bool DispatchWindowEvent(mozilla::WidgetGUIEvent& event);
void WillPaintWindow(); void WillPaintWindow();
bool PaintWindow(nsIntRegion aRegion); bool PaintWindow(LayoutDeviceIntRegion aRegion);
#ifdef ACCESSIBILITY #ifdef ACCESSIBILITY
already_AddRefed<mozilla::a11y::Accessible> GetDocumentAccessible(); already_AddRefed<mozilla::a11y::Accessible> GetDocumentAccessible();

View File

@ -1488,7 +1488,7 @@ void nsChildView::WillPaintWindow()
} }
} }
bool nsChildView::PaintWindow(nsIntRegion aRegion) bool nsChildView::PaintWindow(LayoutDeviceIntRegion aRegion)
{ {
nsCOMPtr<nsIWidget> widget = GetWidgetForListenerEvents(); nsCOMPtr<nsIWidget> widget = GetWidgetForListenerEvents();
@ -3756,10 +3756,10 @@ NSEvent* gLastDragMouseDownEvent = nil;
if (mGeckoChild->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) { if (mGeckoChild->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
nsBaseWidget::AutoLayerManagerSetup nsBaseWidget::AutoLayerManagerSetup
setupLayerManager(mGeckoChild, targetContext, BufferMode::BUFFER_NONE); setupLayerManager(mGeckoChild, targetContext, BufferMode::BUFFER_NONE);
painted = mGeckoChild->PaintWindow(region.ToUnknownRegion()); painted = mGeckoChild->PaintWindow(region);
} else if (mGeckoChild->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) { } else if (mGeckoChild->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
// We only need this so that we actually get DidPaintWindow fired // We only need this so that we actually get DidPaintWindow fired
painted = mGeckoChild->PaintWindow(region.ToUnknownRegion()); painted = mGeckoChild->PaintWindow(region);
} }
targetContext = nullptr; targetContext = nullptr;
@ -3830,7 +3830,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
mGeckoChild->GetBounds(geckoBounds); mGeckoChild->GetBounds(geckoBounds);
LayoutDeviceIntRegion region(geckoBounds); LayoutDeviceIntRegion region(geckoBounds);
mGeckoChild->PaintWindow(region.ToUnknownRegion()); mGeckoChild->PaintWindow(region);
// Force OpenGL to refresh the very first time we draw. This works around a // Force OpenGL to refresh the very first time we draw. This works around a
// Mac OS X bug that stops windows updating on OS X when we use OpenGL. // Mac OS X bug that stops windows updating on OS X when we use OpenGL.

View File

@ -2213,7 +2213,7 @@ nsWindow::OnExposeEvent(cairo_t *cr)
// If this widget uses OMTC... // If this widget uses OMTC...
if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) { if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
listener->PaintWindow(this, region.ToUnknownRegion()); listener->PaintWindow(this, region);
listener->DidPaintWindow(); listener->DidPaintWindow();
return TRUE; return TRUE;
} }
@ -2277,7 +2277,7 @@ nsWindow::OnExposeEvent(cairo_t *cr)
{ {
if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) { if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering); AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering);
painted = listener->PaintWindow(this, region.ToUnknownRegion()); painted = listener->PaintWindow(this, region);
} }
} }

View File

@ -96,7 +96,7 @@ nsIWidgetListener::WillPaintWindow(nsIWidget* aWidget)
bool bool
nsIWidgetListener::PaintWindow(nsIWidget* aWidget, nsIWidgetListener::PaintWindow(nsIWidget* aWidget,
nsIntRegion aRegion) LayoutDeviceIntRegion aRegion)
{ {
return false; return false;
} }

View File

@ -11,6 +11,7 @@
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "nsRegionFwd.h" #include "nsRegionFwd.h"
#include "Units.h"
class nsView; class nsView;
class nsIPresShell; class nsIPresShell;
@ -128,7 +129,8 @@ public:
* This is called at a time when it is not OK to change the geometry of * This is called at a time when it is not OK to change the geometry of
* this widget or of other widgets. * this widget or of other widgets.
*/ */
virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion); virtual bool PaintWindow(nsIWidget* aWidget,
mozilla::LayoutDeviceIntRegion aRegion);
/** /**
* Indicates that a paint occurred. * Indicates that a paint occurred.

View File

@ -875,7 +875,8 @@ nsWindow::OnPaint()
switch (GetLayerManager()->GetBackendType()) { switch (GetLayerManager()->GetBackendType()) {
case mozilla::layers::LayersBackend::LAYERS_CLIENT: { case mozilla::layers::LayersBackend::LAYERS_CLIENT: {
nsIntRegion region(nsIntRect(0, 0, mWidget->width(), mWidget->height())); LayoutDeviceIntRegion region(
LayoutDeviceIntRect(0, 0, mWidget->width(), mWidget->height()));
listener->PaintWindow(this, region); listener->PaintWindow(this, region);
break; break;
} }

View File

@ -91,7 +91,7 @@ public:
} }
void WillPaintWindow(); void WillPaintWindow();
bool PaintWindow(nsIntRegion aRegion); bool PaintWindow(LayoutDeviceIntRegion aRegion);
bool HasModalDescendents() { return false; } bool HasModalDescendents() { return false; }

View File

@ -282,7 +282,7 @@ private:
mGeckoChild->GetBounds(geckoBounds); mGeckoChild->GetBounds(geckoBounds);
LayoutDeviceIntRegion region(geckoBounds); LayoutDeviceIntRegion region(geckoBounds);
mGeckoChild->PaintWindow(region.ToUnknownRegion()); mGeckoChild->PaintWindow(region);
} }
// Called asynchronously after setNeedsDisplay in order to avoid entering the // Called asynchronously after setNeedsDisplay in order to avoid entering the
@ -344,10 +344,11 @@ private:
CGContextSaveGState(aContext); CGContextSaveGState(aContext);
nsIntRegion region = nsIntRect(NSToIntRound(aRect.origin.x * scale), LayoutDeviceIntRegion region =
NSToIntRound(aRect.origin.y * scale), LayoutDeviceIntRect(NSToIntRound(aRect.origin.x * scale),
NSToIntRound(aRect.size.width * scale), NSToIntRound(aRect.origin.y * scale),
NSToIntRound(aRect.size.height * scale)); NSToIntRound(aRect.size.width * scale),
NSToIntRound(aRect.size.height * scale));
// Create Cairo objects. // Create Cairo objects.
RefPtr<gfxQuartzSurface> targetSurface; RefPtr<gfxQuartzSurface> targetSurface;
@ -376,10 +377,10 @@ private:
} }
// Set up the clip region. // Set up the clip region.
nsIntRegionRectIterator iter(region); LayoutDeviceIntRegion::RectIterator iter(region);
targetContext->NewPath(); targetContext->NewPath();
for (;;) { for (;;) {
const nsIntRect* r = iter.Next(); const LayoutDeviceIntRect* r = iter.Next();
if (!r) if (!r)
break; break;
targetContext->Rectangle(gfxRect(r->x, r->y, r->width, r->height)); targetContext->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
@ -730,7 +731,7 @@ void nsWindow::WillPaintWindow()
} }
} }
bool nsWindow::PaintWindow(nsIntRegion aRegion) bool nsWindow::PaintWindow(LayoutDeviceIntRegion aRegion)
{ {
if (!mWidgetListener) if (!mWidgetListener)
return false; return false;

View File

@ -406,8 +406,9 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
{ {
AutoLayerManagerSetup AutoLayerManagerSetup
setupLayerManager(this, thebesContext, doubleBuffering); setupLayerManager(this, thebesContext, doubleBuffering);
result = listener->PaintWindow(this, region); result = listener->PaintWindow(
this, LayoutDeviceIntRegion::FromUnknownRegion(region));
} }
#ifdef MOZ_XUL #ifdef MOZ_XUL
@ -514,7 +515,8 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
} }
break; break;
case LayersBackend::LAYERS_CLIENT: case LayersBackend::LAYERS_CLIENT:
result = listener->PaintWindow(this, region); result = listener->PaintWindow(
this, LayoutDeviceIntRegion::FromUnknownRegion(region));
break; break;
default: default:
NS_ERROR("Unknown layers backend used!"); NS_ERROR("Unknown layers backend used!");