Bug 974197 - Fire MozAfterPaint after the compositor runs. r=roc

This commit is contained in:
Matt Woodrow 2014-02-25 12:55:39 +13:00
parent ccfbb9a146
commit bdb53ca253
14 changed files with 123 additions and 5 deletions

View File

@ -74,6 +74,7 @@
#include "nsILoadContext.h"
#include "ipc/nsGUIEventIPC.h"
#include "mozilla/gfx/Matrix.h"
#include "ClientLayerManager.h"
#include "nsColorPickerProxy.h"
@ -106,6 +107,9 @@ static bool sCpowsEnabled = false;
static int32_t sActiveDurationMs = 10;
static bool sActiveDurationMsSet = false;
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
static TabChildMap* sTabChildren;
NS_IMETHODIMP
ContentListener::HandleEvent(nsIDOMEvent* aEvent)
{
@ -280,6 +284,7 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t
, mManager(aManager)
, mTabChildGlobal(nullptr)
, mChromeFlags(aChromeFlags)
, mLayersId(0)
, mOuterRect(0, 0, 0, 0)
, mInnerSize(0, 0)
, mActivePointerId(-1)
@ -1185,6 +1190,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
@ -2395,6 +2411,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();
@ -2601,6 +2624,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)
{

View File

@ -381,6 +381,9 @@ public:
}
static TabChild* GetFrom(nsIPresShell* aPresShell);
static TabChild* GetFrom(uint64_t aLayersId);
void DidComposite();
static inline TabChild*
GetFrom(nsIDOMWindow* aWindow)
@ -498,6 +501,7 @@ private:
nsRefPtr<ContentChild> mManager;
nsRefPtr<TabChildGlobal> mTabChildGlobal;
uint32_t mChromeFlags;
uint64_t mLayersId;
nsIntRect mOuterRect;
ScreenIntSize mInnerSize;
// When we're tracking a possible tap gesture, this is the "down"

View File

@ -22,6 +22,7 @@
#include "mozilla/layers/LayerTransactionChild.h"
#include "nsAString.h"
#include "nsIWidget.h" // for nsIWidget
#include "nsIWidgetListener.h"
#include "nsTArray.h" // for AutoInfallibleTArray
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#ifdef MOZ_WIDGET_ANDROID
@ -264,6 +265,16 @@ ClientLayerManager::Composite()
}
}
void
ClientLayerManager::DidComposite()
{
MOZ_ASSERT(mWidget);
nsIWidgetListener *listener = mWidget->GetWidgetListener();
if (listener) {
listener->DidCompositeWindow();
}
}
void
ClientLayerManager::MakeSnapshotIfRequired()
{

View File

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

View File

@ -20,6 +20,7 @@
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
#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)
{

View File

@ -57,6 +57,8 @@ public:
virtual bool RecvInvalidateAll() MOZ_OVERRIDE;
virtual bool RecvDidComposite(const uint64_t& aId) MOZ_OVERRIDE;
protected:
virtual PLayerTransactionChild*
AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,

View File

@ -50,6 +50,7 @@
#endif
#include "GeckoProfiler.h"
#include "mozilla/ipc/ProtocolTypes.h"
#include "mozilla/unused.h"
using namespace base;
using namespace mozilla;
@ -659,6 +660,8 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget)
mLayerManager->SetDebugOverlayWantsNextFrame(false);
mLayerManager->EndEmptyTransaction();
DidComposite();
if (mLayerManager->DebugOverlayWantsNextFrame()) {
ScheduleComposition();
}
@ -679,6 +682,21 @@ 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)
{

View File

@ -297,6 +297,8 @@ private:
*/
bool CanComposite();
void DidComposite();
nsRefPtr<LayerManagerComposite> mLayerManager;
nsRefPtr<Compositor> mCompositor;
RefPtr<AsyncCompositionManager> mCompositionManager;

View File

@ -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.

View File

@ -5835,11 +5835,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

View File

@ -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;

View File

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

View File

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

View File

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