Implement the DidComposite NPAPI callback. (bug 1217665 part 8, r=mattwoodrow)

--HG--
extra : rebase_source : 4df420dcfb01db1d5fc9136bbb4c428a7ea59266
This commit is contained in:
David Anderson 2015-12-02 11:31:17 -08:00
parent b48603c10c
commit ca5122668a
7 changed files with 106 additions and 14 deletions

View File

@ -249,6 +249,14 @@ nsPluginInstanceOwner::GetImageContainer()
return container.forget();
}
void
nsPluginInstanceOwner::DidComposite()
{
if (mInstance) {
mInstance->DidComposite();
}
}
void
nsPluginInstanceOwner::SetBackgroundUnknown()
{

View File

@ -218,6 +218,8 @@ public:
// Returns the image container that has our currently displayed image.
already_AddRefed<mozilla::layers::ImageContainer> GetImageContainer();
void DidComposite();
/**
* Returns the bounds of the current async-rendered surface. This can only
* change in response to messages received by the event loop (i.e. not during

View File

@ -396,15 +396,25 @@ ClientLayerManager::DidComposite(uint64_t aTransactionId,
const TimeStamp& aCompositeEnd)
{
MOZ_ASSERT(mWidget);
nsIWidgetListener *listener = mWidget->GetWidgetListener();
if (listener) {
listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
// |aTransactionId| will be > 0 if the compositor is acknowledging a shadow
// layers transaction.
if (aTransactionId) {
nsIWidgetListener *listener = mWidget->GetWidgetListener();
if (listener) {
listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
}
listener = mWidget->GetAttachedWidgetListener();
if (listener) {
listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
}
mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
}
listener = mWidget->GetAttachedWidgetListener();
if (listener) {
listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
// These observers fire whether or not we were in a transaction.
for (size_t i = 0; i < mDidCompositeObservers.Length(); i++) {
mDidCompositeObservers[i]->DidComposite();
}
mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
}
void
@ -823,6 +833,20 @@ ClientLayerManager::SetNextPaintSyncId(int32_t aSyncId)
mForwarder->SetPaintSyncId(aSyncId);
}
void
ClientLayerManager::AddDidCompositeObserver(DidCompositeObserver* aObserver)
{
if (!mDidCompositeObservers.Contains(aObserver)) {
mDidCompositeObservers.AppendElement(aObserver);
}
}
void
ClientLayerManager::RemoveDidCompositeObserver(DidCompositeObserver* aObserver)
{
mDidCompositeObservers.RemoveElement(aObserver);
}
ClientLayer::~ClientLayer()
{
if (HasShadow()) {

View File

@ -257,6 +257,14 @@ public:
void SetNextPaintSyncId(int32_t aSyncId);
class DidCompositeObserver {
public:
virtual void DidComposite() = 0;
};
void AddDidCompositeObserver(DidCompositeObserver* aObserver);
void RemoveDidCompositeObserver(DidCompositeObserver* aObserver);
protected:
enum TransactionPhase {
PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
@ -351,6 +359,8 @@ private:
nsAutoTArray<dom::OverfillCallback*,0> mOverfillCallbacks;
mozilla::TimeStamp mTransactionStart;
nsTArray<DidCompositeObserver*> mDidCompositeObservers;
RefPtr<MemoryPressureObserver> mMemoryPressureObserver;
};

View File

@ -1850,10 +1850,9 @@ void
CompositorParent::DidComposite(TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
{
if (mPendingTransaction) {
Unused << SendDidComposite(0, mPendingTransaction, aCompositeStart, aCompositeEnd);
mPendingTransaction = 0;
}
Unused << SendDidComposite(0, mPendingTransaction, aCompositeStart, aCompositeEnd);
mPendingTransaction = 0;
if (mLayerManager) {
nsTArray<ImageCompositeNotification> notifications;
mLayerManager->ExtractImageCompositeNotifications(&notifications);
@ -2175,8 +2174,7 @@ CrossProcessCompositorParent::DidComposite(uint64_t aId,
TimeStamp& aCompositeEnd)
{
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree;
if (layerTree && layerTree->GetPendingTransactionId()) {
if (LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree) {
Unused << SendDidComposite(aId, layerTree->GetPendingTransactionId(), aCompositeStart, aCompositeEnd);
layerTree->SetPendingTransactionId(0);
}

View File

@ -89,6 +89,7 @@ using mozilla::DefaultXDisplay;
#endif
#include "mozilla/dom/TabChild.h"
#include "ClientLayerManager.h"
#ifdef CreateEvent // Thank you MS.
#undef CreateEvent
@ -202,6 +203,9 @@ nsPluginFrame::DestroyFrom(nsIFrame* aDestructRoot)
PresContext()->PresShell()->CancelReflowCallback(this);
}
// Ensure our DidComposite observer is gone.
mDidCompositeObserver = nullptr;
// Tell content owner of the instance to disconnect its frame.
nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
NS_ASSERTION(objContent, "Why not an object loading content?");
@ -700,9 +704,14 @@ nsPluginFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
// nsObjectLoadingContent should be arbitrating frame-ownership via its
// HasNewFrame callback.
mInstanceOwner = aOwner;
// Reset the DidCompositeObserver since the owner changed.
mDidCompositeObserver = nullptr;
if (mInstanceOwner) {
return;
}
UnregisterPluginForGeometryUpdates();
if (mWidget && mInnerView) {
mInnerView->DetachWidgetEventHandler(mWidget);
@ -1393,6 +1402,30 @@ nsPluginFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
return LAYER_ACTIVE;
}
class PluginFrameDidCompositeObserver final : public ClientLayerManager::
DidCompositeObserver
{
public:
PluginFrameDidCompositeObserver(nsPluginInstanceOwner* aOwner, ClientLayerManager* aLayerManager)
: mInstanceOwner(aOwner),
mLayerManager(aLayerManager)
{
}
~PluginFrameDidCompositeObserver() {
mLayerManager->RemoveDidCompositeObserver(this);
}
void DidComposite() override {
mInstanceOwner->DidComposite();
}
bool IsValid(ClientLayerManager* aLayerManager) {
return aLayerManager == mLayerManager;
}
private:
nsPluginInstanceOwner* mInstanceOwner;
RefPtr<ClientLayerManager> mLayerManager;
};
already_AddRefed<Layer>
nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@ -1461,6 +1494,18 @@ nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
imglayer->SetFilter(filter);
layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0);
if (aBuilder->IsPaintingToWindow() &&
aBuilder->GetWidgetLayerManager() &&
aBuilder->GetWidgetLayerManager()->AsClientLayerManager() &&
mInstanceOwner->UseAsyncRendering())
{
RefPtr<ClientLayerManager> lm = aBuilder->GetWidgetLayerManager()->AsClientLayerManager();
if (!mDidCompositeObserver || !mDidCompositeObserver->IsValid(lm)) {
mDidCompositeObserver = new PluginFrameDidCompositeObserver(mInstanceOwner, lm);
}
lm->AddDidCompositeObserver(mDidCompositeObserver);
}
#ifdef MOZ_WIDGET_ANDROID
} else if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_VIDEO) {
nsDisplayPluginVideo* videoItem = reinterpret_cast<nsDisplayPluginVideo*>(aItem);

View File

@ -44,9 +44,12 @@ class LayerManager;
typedef nsFrame nsPluginFrameSuper;
class PluginFrameDidCompositeObserver;
class nsPluginFrame : public nsPluginFrameSuper,
public nsIObjectFrame,
public nsIReflowCallback {
public nsIReflowCallback
{
public:
typedef mozilla::LayerState LayerState;
typedef mozilla::layers::Layer Layer;
@ -323,6 +326,8 @@ private:
// updates.
RefPtr<nsRootPresContext> mRootPresContextRegisteredWith;
nsAutoPtr<PluginFrameDidCompositeObserver> mDidCompositeObserver;
// Tracks windowed plugin visibility during scroll operations. See
// SetScrollVisibility.
bool mIsHiddenDueToScroll;