Bug 974197 - Fire MozAfterPaint after the compositor has composited the frame. r=roc

This commit is contained in:
Matt Woodrow 2014-03-07 16:24:32 +13:00
Родитель 90fd035479
Коммит 8e7006914b
19 изменённых файлов: 137 добавлений и 10 удалений

Просмотреть файл

@ -73,6 +73,7 @@
#include "ipc/nsGUIEventIPC.h"
#include "mozilla/gfx/Matrix.h"
#include "UnitTransforms.h"
#include "ClientLayerManager.h"
#include "nsColorPickerProxy.h"
@ -105,6 +106,9 @@ static bool sCpowsEnabled = false;
static int32_t sActiveDurationMs = 10;
static bool sActiveDurationMsSet = false;
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
static TabChildMap* sTabChildren;
TabChildBase::TabChildBase()
: mOldViewportWidth(0.0f)
, mContentDocumentIsDisplayed(false)
@ -669,6 +673,7 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t
, mRemoteFrame(nullptr)
, mManager(aManager)
, mChromeFlags(aChromeFlags)
, mLayersId(0)
, mOuterRect(0, 0, 0, 0)
, mActivePointerId(-1)
, mTapHoldTimer(nullptr)
@ -1293,6 +1298,17 @@ TabChild::DestroyWindow()
mRemoteFrame->Destroy();
mRemoteFrame = nullptr;
}
if (mLayersId != 0) {
MOZ_ASSERT(sTabChildren);
sTabChildren->Remove(mLayersId);
if (!sTabChildren->Count()) {
delete sTabChildren;
sTabChildren = nullptr;
}
mLayersId = 0;
}
}
bool
@ -2387,6 +2403,13 @@ TabChild::InitRenderingState()
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
mRemoteFrame = remoteFrame;
if (id != 0) {
if (!sTabChildren) {
sTabChildren = new TabChildMap;
}
sTabChildren->Put(id, this);
mLayersId = id;
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
@ -2583,6 +2606,26 @@ TabChild::GetFrom(nsIPresShell* aPresShell)
return GetFrom(docShell);
}
TabChild*
TabChild::GetFrom(uint64_t aLayersId)
{
if (!sTabChildren) {
return nullptr;
}
return sTabChildren->Get(aLayersId);
}
void
TabChild::DidComposite()
{
MOZ_ASSERT(mWidget);
MOZ_ASSERT(mWidget->GetLayerManager());
MOZ_ASSERT(mWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT);
ClientLayerManager *manager = static_cast<ClientLayerManager*>(mWidget->GetLayerManager());
manager->DidComposite();
}
NS_IMETHODIMP
TabChild::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText)
{

Просмотреть файл

@ -430,6 +430,9 @@ public:
}
static TabChild* GetFrom(nsIPresShell* aPresShell);
static TabChild* GetFrom(uint64_t aLayersId);
void DidComposite();
static inline TabChild*
GetFrom(nsIDOMWindow* aWindow)
@ -514,6 +517,7 @@ private:
RenderFrameChild* mRemoteFrame;
nsRefPtr<ContentChild> mManager;
uint32_t mChromeFlags;
uint64_t mLayersId;
nsIntRect mOuterRect;
// When we're tracking a possible tap gesture, this is the "down"
// point of the touchstart.

Просмотреть файл

@ -24,6 +24,7 @@
#include "mozilla/layers/SimpleTextureClientPool.h" // for SimpleTextureClientPool
#include "nsAString.h"
#include "nsIWidget.h" // for nsIWidget
#include "nsIWidgetListener.h"
#include "nsTArray.h" // for AutoInfallibleTArray
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#include "TiledLayerBuffer.h"
@ -271,6 +272,21 @@ ClientLayerManager::Composite()
}
}
void
ClientLayerManager::DidComposite()
{
MOZ_ASSERT(mWidget);
nsIWidgetListener *listener = mWidget->GetWidgetListener();
if (listener) {
listener->DidCompositeWindow();
} else {
listener = mWidget->GetAttachedWidgetListener();
if (listener) {
listener->DidCompositeWindow();
}
}
}
void
ClientLayerManager::MakeSnapshotIfRequired()
{

Просмотреть файл

@ -163,6 +163,8 @@ public:
virtual void Composite() MOZ_OVERRIDE;
virtual void DidComposite();
protected:
enum TransactionPhase {
PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD

Просмотреть файл

@ -20,6 +20,7 @@
#include "nsTArray.h" // for nsTArray, nsTArray_Impl
#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop, etc
#include "FrameLayerBuilder.h"
#include "mozilla/dom/TabChild.h"
using mozilla::layers::LayerTransactionChild;
@ -120,6 +121,21 @@ CompositorChild::RecvInvalidateAll()
return true;
}
bool
CompositorChild::RecvDidComposite(const uint64_t& aId)
{
if (mLayerManager) {
MOZ_ASSERT(aId == 0);
mLayerManager->DidComposite();
} else if (aId != 0) {
dom::TabChild *child = dom::TabChild::GetFrom(aId);
if (child) {
child->DidComposite();
}
}
return true;
}
void
CompositorChild::ActorDestroy(ActorDestroyReason aWhy)
{

Просмотреть файл

@ -56,6 +56,8 @@ public:
virtual bool RecvInvalidateAll() MOZ_OVERRIDE;
virtual bool RecvDidComposite(const uint64_t& aId) MOZ_OVERRIDE;
private:
// Private destructor, to discourage deletion outside of Release():
virtual ~CompositorChild();

Просмотреть файл

@ -50,6 +50,7 @@
#endif
#include "GeckoProfiler.h"
#include "mozilla/ipc/ProtocolTypes.h"
#include "mozilla/unused.h"
using namespace base;
using namespace mozilla;
@ -188,6 +189,7 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
, mResumeCompositionMonitor("ResumeCompositionMonitor")
, mOverrideComposeReadiness(false)
, mForceCompositionTask(nullptr)
, mWantDidCompositeEvent(false)
{
NS_ABORT_IF_FALSE(sCompositorThread != nullptr || sCompositorThreadID,
"The compositor thread must be Initialized before instanciating a COmpositorParent.");
@ -522,6 +524,8 @@ CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint,
if (aScheduleComposite) {
ScheduleComposition();
}
mWantDidCompositeEvent = true;
}
// Used when layout.frame_rate is -1. Needs to be kept in sync with
@ -651,6 +655,11 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget)
mLayerManager->SetDebugOverlayWantsNextFrame(false);
mLayerManager->EndEmptyTransaction();
if (!aTarget && mWantDidCompositeEvent) {
DidComposite();
mWantDidCompositeEvent = false;
}
if (mLayerManager->DebugOverlayWantsNextFrame()) {
ScheduleComposition();
}
@ -678,6 +687,20 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget)
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_END);
}
void
CompositorParent::DidComposite()
{
unused << SendDidComposite(0);
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
it != sIndirectLayerTrees.end(); it++) {
LayerTreeState* lts = &it->second;
if (lts->mParent == this && lts->mCrossProcessParent) {
unused << lts->mCrossProcessParent->SendDidComposite(it->first);
}
}
}
void
CompositorParent::ForceComposeToTarget(DrawTarget* aTarget)
{
@ -766,6 +789,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
}
}
mLayerManager->NotifyShadowTreeTransaction();
mWantDidCompositeEvent = true;
}
void

Просмотреть файл

@ -300,6 +300,8 @@ private:
*/
bool CanComposite();
void DidComposite();
nsRefPtr<LayerManagerComposite> mLayerManager;
nsRefPtr<Compositor> mCompositor;
RefPtr<AsyncCompositionManager> mCompositionManager;
@ -328,6 +330,8 @@ private:
nsRefPtr<APZCTreeManager> mApzcTreeManager;
bool mWantDidCompositeEvent;
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
};

Просмотреть файл

@ -40,6 +40,11 @@ child:
// The child should invalidate everything so that the whole window is redrawn.
async InvalidateAll();
// The compositor completed a layers transaction. id is the layers id
// of the child layer tree that was composited (or 0 when notifying
// the root layer tree).
async DidComposite(uint64_t id);
parent:
// The child is about to be destroyed, so perform any necessary cleanup.

Просмотреть файл

@ -5824,11 +5824,7 @@ PresShell::Paint(nsView* aViewToPaint,
NS_ASSERTION(layerManager, "Must be in paint event");
bool shouldInvalidate = layerManager->NeedsWidgetInvalidation();
uint32_t didPaintFlags = aFlags;
if (!shouldInvalidate) {
didPaintFlags |= PAINT_COMPOSITE;
}
nsAutoNotifyDidPaint notifyDidPaint(this, didPaintFlags);
nsAutoNotifyDidPaint notifyDidPaint(this, aFlags);
AutoUpdateHitRegion updateHitRegion(this, frame);
// Whether or not we should set first paint when painting is

Просмотреть файл

@ -9,7 +9,6 @@
document.documentElement.className = '';
}
document.addEventListener("MozReftestInvalidate", setValue);
setTimeout(setValue, 2000); // useful when not running under reftest suite
</script>
<body>
<input type=range id='i' value=100 step=25 style='-moz-appearance:none'>

Просмотреть файл

@ -9,7 +9,6 @@
document.documentElement.className = '';
}
document.addEventListener("MozReftestInvalidate", setValue);
setTimeout(setValue, 2000); // useful when not running under reftest suite
</script>
<body>
<input type=range id='i' value=100 step=25>

Просмотреть файл

@ -9,7 +9,6 @@
document.documentElement.className = '';
}
document.addEventListener("MozReftestInvalidate", setValue);
setTimeout(setValue, 2000); // useful when not running under reftest suite
</script>
<body>
<input type=range id='i' value=50 step=25 style='-moz-appearance:none'>

Просмотреть файл

@ -9,7 +9,6 @@
document.documentElement.className = '';
}
document.addEventListener("MozReftestInvalidate", setValue);
setTimeout(setValue, 2000); // useful when not running under reftest suite
</script>
<body>
<input type=range id='i' value=50 step=25>

Просмотреть файл

@ -12,7 +12,7 @@
};
setTimeout(function() {
document.documentElement.className = "reftest-print"
}, 0);
}, 100);
};
</script>
</head>

Просмотреть файл

@ -370,6 +370,7 @@ public:
virtual void WillPaintWindow(nsIWidget* aWidget) MOZ_OVERRIDE;
virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) MOZ_OVERRIDE;
virtual void DidPaintWindow() MOZ_OVERRIDE;
virtual void DidCompositeWindow() MOZ_OVERRIDE;
virtual void RequestRepaint() MOZ_OVERRIDE;
virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
bool aUseAttachedEvents) MOZ_OVERRIDE;

Просмотреть файл

@ -17,6 +17,7 @@
#include "nsPresArena.h"
#include "nsXULPopupManager.h"
#include "nsIWidgetListener.h"
#include "nsContentUtils.h" // for nsAutoScriptBlocker
using namespace mozilla;
@ -1056,6 +1057,16 @@ nsView::DidPaintWindow()
vm->DidPaintWindow();
}
void
nsView::DidCompositeWindow()
{
nsIPresShell* presShell = mViewManager->GetPresShell();
if (presShell) {
nsAutoScriptBlocker scriptBlocker;
presShell->GetPresContext()->GetDisplayRootPresContext()->GetRootPresContext()->NotifyDidPaintForSubtree(nsIPresShell::PAINT_COMPOSITE);
}
}
void
nsView::RequestRepaint()
{

Просмотреть файл

@ -130,6 +130,8 @@ public:
*/
virtual void DidPaintWindow();
virtual void DidCompositeWindow();
/**
* Request that layout schedules a repaint on the next refresh driver tick.
*/

Просмотреть файл

@ -101,6 +101,11 @@ nsIWidgetListener::DidPaintWindow()
{
}
void
nsIWidgetListener::DidCompositeWindow()
{
}
void
nsIWidgetListener::RequestRepaint()
{