mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 800859. Part 3: Dispatch MozAfterPaint after we've done the COMPOSITE step for the invalidations recorded in the event. r=mattwoodrow
--HG-- extra : rebase_source : 7a204c0930e7a2a35ad99af79d28ebba56f034fe
This commit is contained in:
parent
0f08510fc2
commit
4fa3b26bd8
@ -22,7 +22,7 @@ nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
|
||||
mEvent->message = aEventType;
|
||||
}
|
||||
if (aInvalidateRequests) {
|
||||
mInvalidateRequests.SwapElements(aInvalidateRequests->mRequests);
|
||||
mInvalidateRequests.MoveElementsFrom(aInvalidateRequests->mRequests);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,14 +134,15 @@ nsPresContext::MakeColorPref(const nsString& aColor)
|
||||
bool
|
||||
nsPresContext::IsDOMPaintEventPending()
|
||||
{
|
||||
if (!mInvalidateRequests.mRequests.IsEmpty()) {
|
||||
return true;
|
||||
if (mFireAfterPaintEvents) {
|
||||
return true;
|
||||
}
|
||||
if (GetDisplayRootPresContext()->GetRootPresContext()->mRefreshDriver->ViewManagerFlushIsPending()) {
|
||||
// Since we're promising that there will be a MozAfterPaint event
|
||||
// fired, we record an empty invalidation in case display list
|
||||
// invalidation doesn't invalidate anything further.
|
||||
NotifyInvalidation(nsRect(0, 0, 0, 0), 0);
|
||||
NS_ASSERTION(mFireAfterPaintEvents, "Why aren't we planning to fire the event?");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -2033,7 +2034,7 @@ nsPresContext::EnsureSafeToHandOutCSSRules()
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::FireDOMPaintEvent()
|
||||
nsPresContext::FireDOMPaintEvent(nsInvalidateRequestList* aList)
|
||||
{
|
||||
nsPIDOMWindow* ourWindow = mDocument->GetWindow();
|
||||
if (!ourWindow)
|
||||
@ -2058,9 +2059,7 @@ nsPresContext::FireDOMPaintEvent()
|
||||
// (hopefully it won't, or we're likely to get an infinite loop! At least
|
||||
// it won't be blocking app execution though).
|
||||
NS_NewDOMNotifyPaintEvent(getter_AddRefs(event), this, nullptr,
|
||||
NS_AFTERPAINT,
|
||||
&mInvalidateRequests);
|
||||
mAllInvalidated = false;
|
||||
NS_AFTERPAINT, aList);
|
||||
if (!event) {
|
||||
return;
|
||||
}
|
||||
@ -2199,7 +2198,7 @@ nsPresContext::NotifyInvalidation(const nsRect& aRect, uint32_t aFlags)
|
||||
}
|
||||
|
||||
nsInvalidateRequestList::Request* request =
|
||||
mInvalidateRequests.mRequests.AppendElement();
|
||||
mInvalidateRequestsSinceLastPaint.mRequests.AppendElement();
|
||||
if (!request)
|
||||
return;
|
||||
|
||||
@ -2231,36 +2230,81 @@ nsPresContext::NotifySubDocInvalidation(ContainerLayer* aContainer,
|
||||
}
|
||||
}
|
||||
|
||||
struct NotifyDidPaintSubdocumentCallbackClosure {
|
||||
uint32_t mFlags;
|
||||
bool mNeedsAnotherDidPaintNotification;
|
||||
};
|
||||
static bool
|
||||
NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
NotifyDidPaintSubdocumentCallbackClosure* closure =
|
||||
static_cast<NotifyDidPaintSubdocumentCallbackClosure*>(aData);
|
||||
nsIPresShell* shell = aDocument->GetShell();
|
||||
if (shell) {
|
||||
nsPresContext* pc = shell->GetPresContext();
|
||||
if (pc) {
|
||||
pc->NotifyDidPaintForSubtree();
|
||||
pc->NotifyDidPaintForSubtree(closure->mFlags);
|
||||
if (pc->IsDOMPaintEventPending()) {
|
||||
closure->mNeedsAnotherDidPaintNotification = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class DelayedFireDOMPaintEvent : public nsRunnable {
|
||||
public:
|
||||
DelayedFireDOMPaintEvent(nsPresContext* aPresContext,
|
||||
nsInvalidateRequestList* aList)
|
||||
: mPresContext(aPresContext)
|
||||
{
|
||||
mList.TakeFrom(aList);
|
||||
}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mPresContext->FireDOMPaintEvent(&mList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsPresContext> mPresContext;
|
||||
nsInvalidateRequestList mList;
|
||||
};
|
||||
|
||||
void
|
||||
nsPresContext::NotifyDidPaintForSubtree()
|
||||
nsPresContext::NotifyDidPaintForSubtree(uint32_t aFlags)
|
||||
{
|
||||
if (IsRoot()) {
|
||||
if (!mFireAfterPaintEvents)
|
||||
return;
|
||||
|
||||
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimer();
|
||||
}
|
||||
|
||||
mFireAfterPaintEvents = false;
|
||||
if (!mFireAfterPaintEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
NS_NewRunnableMethod(this, &nsPresContext::FireDOMPaintEvent);
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
if (aFlags & nsIPresShell::PAINT_LAYERS) {
|
||||
mUndeliveredInvalidateRequestsBeforeLastPaint.TakeFrom(
|
||||
&mInvalidateRequestsSinceLastPaint);
|
||||
mAllInvalidated = false;
|
||||
}
|
||||
if (aFlags & nsIPresShell::PAINT_COMPOSITE) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new DelayedFireDOMPaintEvent(this, &mUndeliveredInvalidateRequestsBeforeLastPaint);
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
}
|
||||
|
||||
mDocument->EnumerateSubDocuments(NotifyDidPaintSubdocumentCallback, nullptr);
|
||||
NotifyDidPaintSubdocumentCallbackClosure closure = { aFlags, false };
|
||||
mDocument->EnumerateSubDocuments(NotifyDidPaintSubdocumentCallback, &closure);
|
||||
|
||||
if (!closure.mNeedsAnotherDidPaintNotification &&
|
||||
mInvalidateRequestsSinceLastPaint.IsEmpty() &&
|
||||
mUndeliveredInvalidateRequestsBeforeLastPaint.IsEmpty()) {
|
||||
// Nothing more to do for the moment.
|
||||
mFireAfterPaintEvents = false;
|
||||
} else {
|
||||
if (IsRoot()) {
|
||||
static_cast<nsRootPresContext*>(this)->EnsureEventualDidPaintEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2725,7 +2769,10 @@ NotifyDidPaintForSubtreeCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsPresContext* presContext = (nsPresContext*)aClosure;
|
||||
nsAutoScriptBlocker blockScripts;
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
// This is a fallback if we don't get paint events for some reason
|
||||
// so we'll just pretend both layer painting and compositing happened.
|
||||
presContext->NotifyDidPaintForSubtree(
|
||||
nsIPresShell::PAINT_LAYERS | nsIPresShell::PAINT_COMPOSITE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -110,6 +110,12 @@ public:
|
||||
uint32_t mFlags;
|
||||
};
|
||||
|
||||
void TakeFrom(nsInvalidateRequestList* aList)
|
||||
{
|
||||
mRequests.MoveElementsFrom(aList->mRequests);
|
||||
}
|
||||
bool IsEmpty() { return mRequests.IsEmpty(); }
|
||||
|
||||
nsTArray<Request> mRequests;
|
||||
};
|
||||
|
||||
@ -828,8 +834,9 @@ public:
|
||||
void NotifyInvalidation(const nsRect& aRect, uint32_t aFlags);
|
||||
// aRect is in device pixels
|
||||
void NotifyInvalidation(const nsIntRect& aRect, uint32_t aFlags);
|
||||
void NotifyDidPaintForSubtree();
|
||||
void FireDOMPaintEvent();
|
||||
// aFlags are nsIPresShell::PAINT_ flags
|
||||
void NotifyDidPaintForSubtree(uint32_t aFlags);
|
||||
void FireDOMPaintEvent(nsInvalidateRequestList* aList);
|
||||
|
||||
// Callback for catching invalidations in ContainerLayers
|
||||
// Passed to LayerProperties::ComputeDifference
|
||||
@ -837,7 +844,8 @@ public:
|
||||
const nsIntRegion& aRegion);
|
||||
bool IsDOMPaintEventPending();
|
||||
void ClearMozAfterPaintEvents() {
|
||||
mInvalidateRequests.mRequests.Clear();
|
||||
mInvalidateRequestsSinceLastPaint.mRequests.Clear();
|
||||
mUndeliveredInvalidateRequestsBeforeLastPaint.mRequests.Clear();
|
||||
mAllInvalidated = false;
|
||||
}
|
||||
|
||||
@ -1138,7 +1146,8 @@ protected:
|
||||
|
||||
FramePropertyTable mPropertyTable;
|
||||
|
||||
nsInvalidateRequestList mInvalidateRequests;
|
||||
nsInvalidateRequestList mInvalidateRequestsSinceLastPaint;
|
||||
nsInvalidateRequestList mUndeliveredInvalidateRequestsBeforeLastPaint;
|
||||
|
||||
// container for per-context fonts (downloadable, SVG, etc.)
|
||||
nsUserFontSet* mUserFontSet;
|
||||
@ -1200,6 +1209,8 @@ protected:
|
||||
unsigned mPendingMediaFeatureValuesChanged : 1;
|
||||
unsigned mPrefChangePendingNeedsReflow : 1;
|
||||
unsigned mMayHaveFixedBackgroundFrames : 1;
|
||||
// True if the requests in mInvalidateRequestsSinceLastPaint cover the
|
||||
// entire viewport
|
||||
unsigned mAllInvalidated : 1;
|
||||
|
||||
// Are we currently drawing an SVG glyph?
|
||||
|
@ -5216,19 +5216,22 @@ PresShell::ProcessSynthMouseMoveEvent(bool aFromScroll)
|
||||
class nsAutoNotifyDidPaint
|
||||
{
|
||||
public:
|
||||
nsAutoNotifyDidPaint(bool aWillSendDidPaint)
|
||||
: mWillSendDidPaint(aWillSendDidPaint)
|
||||
nsAutoNotifyDidPaint(PresShell* aShell, uint32_t aFlags)
|
||||
: mShell(aShell), mFlags(aFlags)
|
||||
{
|
||||
}
|
||||
~nsAutoNotifyDidPaint()
|
||||
{
|
||||
if (!mWillSendDidPaint && nsContentUtils::XPConnect()) {
|
||||
mShell->GetPresContext()->NotifyDidPaintForSubtree(mFlags);
|
||||
if (!(mFlags & nsIPresShell::PAINT_WILL_SEND_DID_PAINT) &&
|
||||
nsContentUtils::XPConnect()) {
|
||||
nsContentUtils::XPConnect()->NotifyDidPaint();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool mWillSendDidPaint;
|
||||
PresShell* mShell;
|
||||
uint32_t mFlags;
|
||||
};
|
||||
|
||||
void
|
||||
@ -5240,7 +5243,7 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
|
||||
NS_ASSERTION(aViewToPaint, "null view");
|
||||
|
||||
nsAutoNotifyDidPaint notifyDidPaint((aFlags & PAINT_WILL_SEND_DID_PAINT) != 0);
|
||||
nsAutoNotifyDidPaint notifyDidPaint(this, aFlags);
|
||||
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
|
||||
@ -5309,7 +5312,6 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
}
|
||||
|
||||
frame->UpdatePaintCountForPaintedPresShells();
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -5338,9 +5340,6 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
nsLayoutUtils::PaintFrame(nullptr, frame, aDirtyRegion, bgcolor, flags);
|
||||
|
||||
frame->EndDeferringInvalidatesForDisplayRoot();
|
||||
if (aFlags & PAINT_LAYERS) {
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5356,10 +5355,6 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
}
|
||||
layerManager->EndTransaction(NULL, NULL, (aFlags & PAINT_COMPOSITE) ?
|
||||
LayerManager::END_DEFAULT : LayerManager::END_NO_COMPOSITE);
|
||||
|
||||
if (aFlags & PAINT_LAYERS) {
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
Loading…
Reference in New Issue
Block a user