Bug 826817. Part 1: Send WillPaintWindow/DidPaintWindow from all widget implementations. r=tnikkel

This commit is contained in:
Robert O'Callahan 2013-01-28 13:34:03 -06:00
parent 5696641282
commit 1ada24c301
5 changed files with 54 additions and 16 deletions

View File

@ -1014,6 +1014,8 @@ nsWindow::DrawTo(gfxASurface *targetSurface, const nsIntRect &invalidRect)
bool painted = false;
nsIntRegion region = invalidRect;
mWidgetListener->WillPaintWindow(this, true);
switch (GetLayerManager(nullptr)->GetBackendType()) {
case mozilla::layers::LAYERS_BASIC: {
@ -1024,7 +1026,8 @@ nsWindow::DrawTo(gfxASurface *targetSurface, const nsIntRect &invalidRect)
AutoLayerManagerSetup
setupLayerManager(this, ctx, mozilla::layers::BUFFER_NONE);
painted = mWidgetListener->PaintWindow(this, region, 0);
painted = mWidgetListener->PaintWindow(this, region,
nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
}
// XXX uhh.. we can't just ignore this because we no longer have
@ -1044,7 +1047,8 @@ nsWindow::DrawTo(gfxASurface *targetSurface, const nsIntRect &invalidRect)
static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager(nullptr))->
SetClippingRegion(nsIntRegion(boundsRect));
painted = mWidgetListener->PaintWindow(this, region, 0);
painted = mWidgetListener->PaintWindow(this, region,
nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
break;
}
@ -1052,6 +1056,8 @@ nsWindow::DrawTo(gfxASurface *targetSurface, const nsIntRect &invalidRect)
NS_ERROR("Invalid layer manager");
}
mWidgetListener->DidPaintWindow();
// We had no covering child, so make sure we draw all the children,
// starting from index 0.
coveringChildIndex = 0;

View File

@ -1489,30 +1489,36 @@ bool nsChildView::DispatchWindowEvent(nsGUIEvent &event)
bool nsChildView::PaintWindow(nsIntRegion aRegion, bool aIsAlternate)
{
nsIWidget* widget = this;
nsIWidgetListener* listener = mWidgetListener;
nsCOMPtr<nsIWidget> widget = this;
// If there is no listener, use the parent popup's listener if that exists.
if (!listener && mParentWidget) {
if (!mWidgetListener && mParentWidget) {
nsWindowType type;
mParentWidget->GetWindowType(type);
if (type == eWindowType_popup) {
widget = mParentWidget;
listener = mParentWidget->GetWidgetListener();
}
}
nsIWidgetListener* listener = widget->GetWidgetListener();
if (!listener)
return false;
bool returnValue = false;
bool oldDispatchPaint = mIsDispatchPaint;
mIsDispatchPaint = true;
uint32_t flags = nsIWidgetListener::SENT_WILL_PAINT;
uint32_t flags =
nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT;
if (aIsAlternate) {
flags |= nsIWidgetListener::PAINT_IS_ALTERNATE;
}
returnValue = listener->PaintWindow(widget, aRegion, flags);
listener = widget->GetWidgetListener();
if (listener) {
listener->DidPaintWindow();
}
mIsDispatchPaint = oldDispatchPaint;
return returnValue;
}

View File

@ -222,14 +222,22 @@ nsWindow::DoDraw(void)
nsIntRegion region = gWindowToRedraw->mDirtyRegion;
gWindowToRedraw->mDirtyRegion.SetEmpty();
nsIWidgetListener* listener = gWindowToRedraw->GetWidgetListener();
if (listener) {
listener->WillPaintWindow(gWindowToRedraw, true);
}
LayerManager* lm = gWindowToRedraw->GetLayerManager();
if (mozilla::layers::LAYERS_OPENGL == lm->GetBackendType()) {
LayerManagerOGL* oglm = static_cast<LayerManagerOGL*>(lm);
oglm->SetClippingRegion(region);
oglm->SetWorldTransform(sRotationMatrix);
if (nsIWidgetListener* listener = gWindowToRedraw->GetWidgetListener())
listener->PaintWindow(gWindowToRedraw, region, 0);
listener = gWindowToRedraw->GetWidgetListener();
if (listener) {
listener->PaintWindow(gWindowToRedraw, region,
nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
}
} else if (mozilla::layers::LAYERS_BASIC == lm->GetBackendType()) {
MOZ_ASSERT(sFramebufferOpen || sUsingOMTC);
nsRefPtr<gfxASurface> targetSurface;
@ -249,8 +257,11 @@ nsWindow::DoDraw(void)
gWindowToRedraw, ctx, mozilla::layers::BUFFER_NONE,
ScreenRotation(EffectiveScreenRotation()));
if (nsIWidgetListener* listener = gWindowToRedraw->GetWidgetListener())
listener->PaintWindow(gWindowToRedraw, region, 0);
listener = gWindowToRedraw->GetWidgetListener();
if (listener) {
listener->PaintWindow(gWindowToRedraw, region,
nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
}
}
if (!sUsingOMTC) {
@ -260,6 +271,11 @@ nsWindow::DoDraw(void)
} else {
NS_RUNTIMEABORT("Unexpected layer manager type");
}
listener = gWindowToRedraw->GetWidgetListener();
if (listener) {
listener->DidPaintWindow();
}
}
nsEventStatus

View File

@ -113,13 +113,17 @@ public:
virtual bool RequestWindowClose(nsIWidget* aWidget) { return false; }
/*
* Indicate that a paint is about to occur on this window.
* Indicate that a paint is about to occur on this window. This is called
* at a time when it's OK to change the geometry of this widget or of
* other widgets.
*/
virtual void WillPaintWindow(nsIWidget* aWidget, bool aWillSendDidPaint) { }
/**
* Paint the specified region of the window. Returns true if the
* notification was handled.
* This is called at a time when it is not OK to change the geometry of
* this widget or of other widgets.
*/
enum {
SENT_WILL_PAINT = 1 << 0, /* WillPaintWindow has already been called */
@ -129,7 +133,9 @@ public:
virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion, uint32_t aFlags) { return false; }
/**
* On some platforms, indicates that a paint occurred.
* Indicates that a paint occurred.
* This is called at a time when it is OK to change the geometry of
* this widget or of other widgets.
*/
virtual void DidPaintWindow() { }

View File

@ -521,21 +521,25 @@ PuppetWidget::Paint()
mDirtyRegion.SetEmpty();
mPaintTask.Revoke();
{
mAttachedWidgetListener->WillPaintWindow(this, true);
if (mAttachedWidgetListener) {
#ifdef DEBUG
debug_DumpPaintEvent(stderr, this, region,
nsAutoCString("PuppetWidget"), 0);
#endif
if (mozilla::layers::LAYERS_D3D10 == mLayerManager->GetBackendType()) {
mAttachedWidgetListener->PaintWindow(this, region, nsIWidgetListener::WILL_SEND_DID_PAINT);
mAttachedWidgetListener->PaintWindow(this, region,
nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
} else {
nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
ctx->Rectangle(gfxRect(0,0,0,0));
ctx->Clip();
AutoLayerManagerSetup setupLayerManager(this, ctx,
BUFFER_NONE);
mAttachedWidgetListener->PaintWindow(this, region, nsIWidgetListener::WILL_SEND_DID_PAINT);
mAttachedWidgetListener->PaintWindow(this, region,
nsIWidgetListener::SENT_WILL_PAINT | nsIWidgetListener::WILL_SEND_DID_PAINT);
mTabChild->NotifyPainted();
}
}