Bug 1390440 - Support nsDisplayPlugin for webrender layers-free mode. r=mattwoodrow
MozReview-Commit-ID: 2DoBo7OkTsb
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -52,16 +52,17 @@
#ifdef XP_WIN
#include "gfxWindowsNativeDrawing.h"
#include "gfxWindowsSurface.h"
#endif
#include "Layers.h"
#include "ReadbackLayer.h"
#include "ImageContainer.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
// accessibility support
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
#endif
#include "mozilla/Logging.h"
@@ -1037,16 +1038,30 @@ nsDisplayPlugin::GetOpaqueRegion(nsDispl
// We can treat this as opaque
result = bounds;
}
}
return result;
}
+bool
+nsDisplayPlugin::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ return static_cast<nsPluginFrame*>(mFrame)->CreateWebRenderCommands(this,
+ aBuilder,
+ aSc,
+ aManager,
+ aDisplayListBuilder);
+}
+
nsresult
nsPluginFrame::PluginEventNotifier::Run() {
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
obsSvc->NotifyObservers(nullptr, "plugin-changed-event", mEventType.get());
return NS_OK;
}
@@ -1350,52 +1365,105 @@ public:
return aLayerManager == mLayerManager;
}
private:
nsPluginInstanceOwner* mInstanceOwner;
RefPtr<LayerManager> mLayerManager;
};
-already_AddRefed<Layer>
-nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
- LayerManager* aManager,
- nsDisplayItem* aItem,
- const ContainerLayerParameters& aContainerParameters)
+bool
+nsPluginFrame::GetBounds(nsDisplayItem* aItem, IntSize& aSize, gfxRect& aRect)
{
if (!mInstanceOwner)
- return nullptr;
+ return false;
NPWindow* window = nullptr;
mInstanceOwner->GetWindow(window);
if (!window)
- return nullptr;
+ return false;
if (window->width <= 0 || window->height <= 0)
- return nullptr;
+ return false;
#if defined(XP_MACOSX)
// window is in "display pixels", but size needs to be in device pixels
// window must be in "display pixels"
double scaleFactor = 1.0;
if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) {
scaleFactor = 1.0;
}
size_t intScaleFactor = ceil(scaleFactor);
#else
size_t intScaleFactor = 1;
#endif
- IntSize size(window->width * intScaleFactor, window->height * intScaleFactor);
+ aSize = IntSize(window->width * intScaleFactor, window->height * intScaleFactor);
nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
- gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel());
+ aRect = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel());
// to provide crisper and faster drawing.
- r.Round();
+ aRect.Round();
+
+ return true;
+}
+
+bool
+nsPluginFrame::CreateWebRenderCommands(nsDisplayItem* aItem,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ IntSize size;
+ gfxRect r;
+ if (!GetBounds(aItem, size, r)) {
+ return true;
+ }
+
+ RefPtr<ImageContainer> container;
+ // Image for Windowed plugins that support window capturing for scroll
+ // operations or async windowless rendering.
+ container = mInstanceOwner->GetImageContainer();
+ if (!container) {
+ // This can occur if our instance is gone or if the current plugin
+ // configuration does not require a backing image layer.
+ return true;
+ }
+
+#ifdef XP_MACOSX
+ if (!mInstanceOwner->UseAsyncRendering()) {
+ mInstanceOwner->DoCocoaEventDrawRect(r, nullptr);
+ }
+#endif
+
+ RefPtr<LayerManager> lm = aDisplayListBuilder->GetWidgetLayerManager();
+ if (!mDidCompositeObserver || !mDidCompositeObserver->IsValid(lm)) {
+ mDidCompositeObserver = MakeUnique<PluginFrameDidCompositeObserver>(mInstanceOwner, lm);
+ }
+ lm->AddDidCompositeObserver(mDidCompositeObserver.get());
+
+ LayerRect dest(r.x, r.y, size.width, size.height);
+ return aManager->PushImage(aItem, container, aBuilder, aSc, dest);
+}
+
+
+already_AddRefed<Layer>
+nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
+ LayerManager* aManager,
+ nsDisplayItem* aItem,
+ const ContainerLayerParameters& aContainerParameters)
+{
+ IntSize size;
+ gfxRect r;
+ if (!GetBounds(aItem, size, r)) {
+ return nullptr;
+ }
+
RefPtr<Layer> layer =
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
if (aItem->GetType() == DisplayItemType::TYPE_PLUGIN) {
RefPtr<ImageContainer> container;
// Image for Windowed plugins that support window capturing for scroll
// operations or async windowless rendering.
container = mInstanceOwner->GetImageContainer();
--- a/layout/generic/nsPluginFrame.h
+++ b/layout/generic/nsPluginFrame.h
@@ -12,16 +12,18 @@
#include "mozilla/EventForwards.h"
#include "mozilla/UniquePtr.h"
#include "nsIObjectFrame.h"
#include "nsFrame.h"
#include "nsRegion.h"
#include "nsDisplayList.h"
#include "nsIReflowCallback.h"
#include "Units.h"
+#include "mozilla/layers/StackingContextHelper.h"
+#include "mozilla/webrender/WebRenderAPI.h"
#ifdef XP_WIN
#include <windows.h> // For HWND :(
// Undo the windows.h damage
#undef GetMessage
#undef CreateEvent
#undef GetClassName
#undef GetBinaryType
@@ -55,16 +57,19 @@ class nsPluginFrame final
public:
typedef mozilla::LayerState LayerState;
typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::layers::ImageContainer ImageContainer;
+ typedef mozilla::layers::StackingContextHelper StackingContextHelper;
+ typedef mozilla::layers::WebRenderLayerManager WebRenderLayerManager;
+ typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
NS_DECL_FRAMEARENA_HELPERS(nsPluginFrame)
NS_DECL_QUERYFRAME
friend nsIFrame* NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
virtual void Init(nsIContent* aContent,
@@ -216,16 +221,21 @@ public:
void HandleWheelEventAsDefaultAction(mozilla::WidgetWheelEvent* aEvent);
/**
* WantsToHandleWheelEventAsDefaultAction() returns true if the plugin
* may want to handle wheel events as default action.
*/
bool WantsToHandleWheelEventAsDefaultAction() const;
+ bool CreateWebRenderCommands(nsDisplayItem* aItem,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder);
protected:
explicit nsPluginFrame(nsStyleContext* aContext);
virtual ~nsPluginFrame();
// NOTE: This frame class does not inherit from |nsLeafFrame|, so
// this is not a virtual method implementation.
void GetDesiredSize(nsPresContext* aPresContext,
const ReflowInput& aReflowInput,
@@ -262,16 +272,17 @@ protected:
void NotifyPluginReflowObservers();
friend class nsPluginInstanceOwner;
friend class nsDisplayPlugin;
friend class PluginBackgroundSink;
nsView* GetViewInternal() const override { return mOuterView; }
void SetViewInternal(nsView* aView) override { mOuterView = aView; }
+ bool GetBounds(nsDisplayItem* aItem, mozilla::gfx::IntSize& aSize, gfxRect& aRect);
private:
// Registers the plugin for a geometry update, and requests a geometry
// update. This caches the root pres context in
// mRootPresContextRegisteredWith, so that we can be sure we unregister
// from the right root prest context in UnregisterPluginForGeometryUpdates.
void RegisterPluginForGeometryUpdates();
@@ -372,11 +383,17 @@ public:
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override
{
return static_cast<nsPluginFrame*>(mFrame)->GetLayerState(aBuilder,
aManager);
}
+
+ virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
};
#endif /* nsPluginFrame_h___ */