mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 539356 - Part 8b - Move painting of retained layers to the view manager flush, and only composite on the paint event. r=roc
This commit is contained in:
parent
7aaf9816cd
commit
46e6f3d27b
@ -309,6 +309,9 @@ public:
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags = END_DEFAULT) = 0;
|
||||
|
||||
virtual bool HasShadowManagerInternal() const { return false; }
|
||||
bool HasShadowManager() const { return HasShadowManagerInternal(); }
|
||||
|
||||
bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
|
||||
|
||||
/**
|
||||
|
@ -148,8 +148,6 @@ public:
|
||||
void PopGroupToSourceWithCachedSurface(gfxContext *aTarget, gfxContext *aPushed);
|
||||
|
||||
virtual bool IsCompositingCheap() { return false; }
|
||||
virtual bool HasShadowManagerInternal() const { return false; }
|
||||
bool HasShadowManager() const { return HasShadowManagerInternal(); }
|
||||
virtual PRInt32 GetMaxTextureSize() const { return PR_INT32_MAX; }
|
||||
|
||||
protected:
|
||||
|
@ -199,7 +199,7 @@ LayerManagerD3D10::Initialize(bool force)
|
||||
mInputLayout = attachments->mInputLayout;
|
||||
}
|
||||
|
||||
if (HasShadowManager()) {
|
||||
if (LayerManager::HasShadowManager()) {
|
||||
reporter.SetSuccessful();
|
||||
return true;
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
||||
layerManager->SetRoot(root);
|
||||
layerBuilder->WillEndTransaction(layerManager);
|
||||
layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
|
||||
aBuilder);
|
||||
aBuilder, (aFlags & PAINT_NO_COMPOSITE) ? LayerManager::END_NO_COMPOSITE : LayerManager::END_DEFAULT);
|
||||
layerBuilder->DidEndTransaction(layerManager);
|
||||
|
||||
if (aFlags & PAINT_FLUSH_LAYERS) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "FrameLayerBuilder.h"
|
||||
#include "nsThemeConstants.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
|
||||
@ -1155,7 +1156,8 @@ public:
|
||||
PAINT_DEFAULT = 0,
|
||||
PAINT_USE_WIDGET_LAYERS = 0x01,
|
||||
PAINT_FLUSH_LAYERS = 0x02,
|
||||
PAINT_EXISTING_TRANSACTION = 0x04
|
||||
PAINT_EXISTING_TRANSACTION = 0x04,
|
||||
PAINT_NO_COMPOSITE = 0x08
|
||||
};
|
||||
void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
|
||||
PRUint32 aFlags) const;
|
||||
|
@ -1208,9 +1208,12 @@ public:
|
||||
*/
|
||||
virtual void SynthesizeMouseMove(bool aFromScroll) = 0;
|
||||
|
||||
virtual void Paint(nsIView* aViewToPaint, nsIWidget* aWidget,
|
||||
const nsRegion& aDirtyRegion, const nsIntRegion& aIntDirtyRegion,
|
||||
bool aWillSendDidPaint) = 0;
|
||||
enum PaintType {
|
||||
PaintType_Composite,
|
||||
PaintType_NoComposite
|
||||
};
|
||||
virtual void Paint(nsIView* aViewToPaint, const nsRegion& aDirtyRegion,
|
||||
PaintType aType, bool aWillSendDidPaint) = 0;
|
||||
virtual nsresult HandleEvent(nsIFrame* aFrame,
|
||||
nsGUIEvent* aEvent,
|
||||
bool aDontRetargetEvents,
|
||||
|
@ -1783,6 +1783,9 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
|
||||
if (aFlags & PAINT_EXISTING_TRANSACTION) {
|
||||
flags |= nsDisplayList::PAINT_EXISTING_TRANSACTION;
|
||||
}
|
||||
if (aFlags & PAINT_NO_COMPOSITE) {
|
||||
flags |= nsDisplayList::PAINT_NO_COMPOSITE;
|
||||
}
|
||||
|
||||
list.PaintRoot(&builder, aRenderingContext, flags);
|
||||
|
||||
|
@ -596,7 +596,8 @@ public:
|
||||
PAINT_HIDE_CARET = 0x20,
|
||||
PAINT_ALL_CONTINUATIONS = 0x40,
|
||||
PAINT_TO_WINDOW = 0x80,
|
||||
PAINT_EXISTING_TRANSACTION = 0x100
|
||||
PAINT_EXISTING_TRANSACTION = 0x100,
|
||||
PAINT_NO_COMPOSITE = 0x200
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5203,9 +5203,8 @@ private:
|
||||
|
||||
void
|
||||
PresShell::Paint(nsIView* aViewToPaint,
|
||||
nsIWidget* aWidgetToPaint,
|
||||
const nsRegion& aDirtyRegion,
|
||||
const nsIntRegion& aIntDirtyRegion,
|
||||
PaintType aType,
|
||||
bool aWillSendDidPaint)
|
||||
{
|
||||
#ifdef NS_FUNCTION_TIMER
|
||||
@ -5222,7 +5221,6 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
SAMPLE_LABEL("Paint", "PresShell::Paint");
|
||||
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
|
||||
NS_ASSERTION(aViewToPaint, "null view");
|
||||
NS_ASSERTION(aWidgetToPaint, "Can't paint without a widget");
|
||||
|
||||
nsAutoNotifyDidPaint notifyDidPaint(aWillSendDidPaint);
|
||||
|
||||
@ -5233,14 +5231,13 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
|
||||
bool isRetainingManager;
|
||||
LayerManager* layerManager =
|
||||
aWidgetToPaint->GetLayerManager(&isRetainingManager);
|
||||
aViewToPaint->GetWidget()->GetLayerManager(&isRetainingManager);
|
||||
NS_ASSERTION(layerManager, "Must be in paint event");
|
||||
|
||||
if (mIsFirstPaint) {
|
||||
layerManager->SetIsFirstPaint();
|
||||
mIsFirstPaint = false;
|
||||
}
|
||||
layerManager->BeginTransaction();
|
||||
|
||||
if (frame && isRetainingManager) {
|
||||
// Try to do an empty transaction, if the frame tree does not
|
||||
@ -5249,21 +5246,32 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
// draws the window title bar on Mac), because a) it won't work
|
||||
// and b) below we don't want to clear NS_FRAME_UPDATE_LAYER_TREE,
|
||||
// that will cause us to forget to update the real layer manager!
|
||||
if (!(frame->GetStateBits() & NS_FRAME_UPDATE_LAYER_TREE)) {
|
||||
if (layerManager->EndEmptyTransaction()) {
|
||||
frame->UpdatePaintCountForPaintedPresShells();
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
if (aType == PaintType_Composite) {
|
||||
if (layerManager->HasShadowManager()) {
|
||||
return;
|
||||
}
|
||||
layerManager->BeginTransaction();
|
||||
if (layerManager->EndEmptyTransaction()) {
|
||||
return;
|
||||
}
|
||||
NS_WARNING("Must complete empty transaction when compositing!");
|
||||
} else {
|
||||
layerManager->BeginTransaction();
|
||||
}
|
||||
|
||||
frame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
|
||||
} else {
|
||||
layerManager->BeginTransaction();
|
||||
}
|
||||
if (frame) {
|
||||
frame->ClearPresShellsFromLastPaint();
|
||||
}
|
||||
|
||||
nscolor bgcolor = ComputeBackstopColor(aViewToPaint);
|
||||
PRUint32 flags = nsLayoutUtils::PAINT_WIDGET_LAYERS | nsLayoutUtils::PAINT_EXISTING_TRANSACTION;
|
||||
if (aType == PaintType_NoComposite) {
|
||||
flags |= nsLayoutUtils::PAINT_NO_COMPOSITE;
|
||||
}
|
||||
|
||||
if (frame) {
|
||||
// Defer invalidates that are triggered during painting, and discard
|
||||
@ -5273,12 +5281,12 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
frame->BeginDeferringInvalidatesForDisplayRoot(aDirtyRegion);
|
||||
|
||||
// We can paint directly into the widget using its layer manager.
|
||||
nsLayoutUtils::PaintFrame(nsnull, frame, aDirtyRegion, bgcolor,
|
||||
nsLayoutUtils::PAINT_WIDGET_LAYERS |
|
||||
nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
|
||||
nsLayoutUtils::PaintFrame(nsnull, frame, aDirtyRegion, bgcolor, flags);
|
||||
|
||||
frame->EndDeferringInvalidatesForDisplayRoot();
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
if (aType != PaintType_Composite) {
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5292,9 +5300,13 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
root->SetVisibleRegion(bounds);
|
||||
layerManager->SetRoot(root);
|
||||
}
|
||||
layerManager->EndTransaction(NULL, NULL);
|
||||
layerManager->EndTransaction(NULL, NULL, aType == PaintType_NoComposite ?
|
||||
LayerManager::END_NO_COMPOSITE :
|
||||
LayerManager::END_DEFAULT);
|
||||
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
if (aType != PaintType_Composite) {
|
||||
presContext->NotifyDidPaintForSubtree();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -184,9 +184,8 @@ public:
|
||||
|
||||
//nsIViewObserver interface
|
||||
|
||||
virtual void Paint(nsIView* aViewToPaint, nsIWidget* aWidget,
|
||||
const nsRegion& aDirtyRegion, const nsIntRegion& aIntDirtyRegion,
|
||||
bool aWillSendDidPaint);
|
||||
virtual void Paint(nsIView* aViewToPaint, const nsRegion& aDirtyRegion,
|
||||
PaintType aType, bool aWillSendDidPaint);
|
||||
virtual nsresult HandleEvent(nsIFrame* aFrame,
|
||||
nsGUIEvent* aEvent,
|
||||
bool aDontRetargetEvents,
|
||||
|
@ -411,8 +411,14 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
|
||||
}
|
||||
|
||||
if (mViewManagerFlushIsPending) {
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Starting ProcessPendingUpdates\n");
|
||||
#endif
|
||||
mViewManagerFlushIsPending = false;
|
||||
mPresContext->GetPresShell()->GetViewManager()->ProcessPendingUpdates();
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("Ending ProcessPendingUpdates\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mThrottled ||
|
||||
|
@ -300,11 +300,9 @@ nsIView* nsIViewManager::GetDisplayRootFor(nsIView* aView)
|
||||
aContext may be null, in which case layers should be used for
|
||||
rendering.
|
||||
*/
|
||||
void nsViewManager::Refresh(nsView *aView, nsIWidget *aWidget,
|
||||
const nsIntRegion& aRegion,
|
||||
void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion,
|
||||
bool aWillSendDidPaint)
|
||||
{
|
||||
NS_ASSERTION(aView == nsView::GetViewFor(aWidget), "view widget mismatch");
|
||||
NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
|
||||
|
||||
// damageRegion is the damaged area, in twips, relative to the view origin
|
||||
@ -337,8 +335,14 @@ void nsViewManager::Refresh(nsView *aView, nsIWidget *aWidget,
|
||||
"Widgets that we paint must all be display roots");
|
||||
|
||||
if (mPresShell) {
|
||||
mPresShell->Paint(aView, aWidget, damageRegion, aRegion,
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("--COMPOSITE-- %p\n", mPresShell);
|
||||
#endif
|
||||
mPresShell->Paint(aView, damageRegion, nsIPresShell::PaintType_Composite,
|
||||
aWillSendDidPaint);
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("--ENDCOMPOSITE--\n");
|
||||
#endif
|
||||
mozilla::StartupTimeline::RecordOnce(mozilla::StartupTimeline::FIRST_PAINT);
|
||||
}
|
||||
|
||||
@ -374,6 +378,17 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
||||
// Push out updates after we've processed the children; ensures that
|
||||
// damage is applied based on the final widget geometry
|
||||
if (aFlushDirtyRegion) {
|
||||
nsIWidget *widget = aView->GetWidget();
|
||||
if (widget) {
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
|
||||
#endif
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
mPresShell->Paint(aView, nsRegion(), nsIPresShell::PaintType_NoComposite, false);
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("---- PAINT END ----\n");
|
||||
#endif
|
||||
}
|
||||
FlushDirtyRegionToWidget(aView);
|
||||
}
|
||||
}
|
||||
@ -767,7 +782,7 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
|
||||
break;
|
||||
|
||||
// Paint.
|
||||
Refresh(view, event->widget, event->region, event->willSendDidPaint);
|
||||
Refresh(view, event->region, event->willSendDidPaint);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -129,8 +129,7 @@ private:
|
||||
void InvalidateViews(nsView *aView);
|
||||
|
||||
// aView is the view for aWidget and aRegion is relative to aWidget.
|
||||
void Refresh(nsView *aView, nsIWidget *aWidget, const nsIntRegion& aRegion,
|
||||
bool aWillSendDidPaint);
|
||||
void Refresh(nsView *aView, const nsIntRegion& aRegion, bool aWillSendDidPaint);
|
||||
|
||||
void InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut);
|
||||
void InvalidateHorizontalBandDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut,
|
||||
|
Loading…
Reference in New Issue
Block a user