forked from mirrors/gecko-dev
		
	 2c5cb1519c
			
		
	
	
		2c5cb1519c
		
	
	
	
	
		
			
			Move ApplyOpacity(), CanApplyOpacity(), Paint() and PaintWithClip() methods to nsPaintedDisplayItem Differential Revision: https://phabricator.services.mozilla.com/D30225 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			404 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			404 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| /* rendering objects for replaced elements implemented by a plugin */
 | |
| 
 | |
| #ifndef nsPluginFrame_h___
 | |
| #define nsPluginFrame_h___
 | |
| 
 | |
| #include "mozilla/Attributes.h"
 | |
| #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
 | |
| #  undef RemoveDirectory
 | |
| #  undef LoadIcon
 | |
| #  undef LoadImage
 | |
| #  undef GetObject
 | |
| #endif
 | |
| 
 | |
| class nsPresContext;
 | |
| class nsRootPresContext;
 | |
| class nsDisplayPlugin;
 | |
| class PluginBackgroundSink;
 | |
| class nsPluginInstanceOwner;
 | |
| 
 | |
| namespace mozilla {
 | |
| class PresShell;
 | |
| namespace layers {
 | |
| class ImageContainer;
 | |
| class Layer;
 | |
| class LayerManager;
 | |
| }  // namespace layers
 | |
| }  // namespace mozilla
 | |
| 
 | |
| class PluginFrameDidCompositeObserver;
 | |
| 
 | |
| class nsPluginFrame final : public nsFrame,
 | |
|                             public nsIObjectFrame,
 | |
|                             public nsIReflowCallback {
 | |
|  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::RenderRootStateManager RenderRootStateManager;
 | |
|   typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
 | |
|   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
 | |
| 
 | |
|   NS_DECL_FRAMEARENA_HELPERS(nsPluginFrame)
 | |
|   NS_DECL_QUERYFRAME
 | |
| 
 | |
|   friend nsIFrame* NS_NewObjectFrame(mozilla::PresShell* aPresShell,
 | |
|                                      ComputedStyle* aStyle);
 | |
| 
 | |
|   virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
 | |
|                     nsIFrame* aPrevInFlow) override;
 | |
|   virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
 | |
|   virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
 | |
|   virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
 | |
|                       const ReflowInput& aReflowInput,
 | |
|                       nsReflowStatus& aStatus) override;
 | |
|   virtual void DidReflow(nsPresContext* aPresContext,
 | |
|                          const ReflowInput* aReflowInput) override;
 | |
|   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
 | |
|                                 const nsDisplayListSet& aLists) override;
 | |
| 
 | |
|   virtual nsresult HandleEvent(nsPresContext* aPresContext,
 | |
|                                mozilla::WidgetGUIEvent* aEvent,
 | |
|                                nsEventStatus* aEventStatus) override;
 | |
| 
 | |
|   virtual bool IsFrameOfType(uint32_t aFlags) const override {
 | |
|     return nsFrame::IsFrameOfType(
 | |
|         aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
 | |
|   }
 | |
| 
 | |
| #ifdef DEBUG_FRAME_DUMP
 | |
|   virtual nsresult GetFrameName(nsAString& aResult) const override;
 | |
| #endif
 | |
| 
 | |
|   virtual void DestroyFrom(nsIFrame* aDestructRoot,
 | |
|                            PostDestroyData& aPostDestroyData) override;
 | |
| 
 | |
|   virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
 | |
| 
 | |
|   nsNPAPIPluginInstance* GetPluginInstance() override;
 | |
| 
 | |
|   virtual void SetIsDocumentActive(bool aIsActive) override;
 | |
| 
 | |
|   mozilla::Maybe<Cursor> GetCursor(const nsPoint&) override;
 | |
| 
 | |
|   // APIs used by nsRootPresContext to set up the widget position/size/clip
 | |
|   // region.
 | |
|   /**
 | |
|    * Set the next widget configuration for the plugin to the desired
 | |
|    * position of the plugin's widget, on the assumption that it is not visible
 | |
|    * (clipped out or covered by opaque content).
 | |
|    * This will only be called for plugins which have been registered
 | |
|    * with the root pres context for geometry updates.
 | |
|    * If there is no widget associated with the plugin, this will have no effect.
 | |
|    */
 | |
|   void SetEmptyWidgetConfiguration() {
 | |
|     mNextConfigurationBounds = LayoutDeviceIntRect(0, 0, 0, 0);
 | |
|     mNextConfigurationClipRegion.Clear();
 | |
|   }
 | |
|   /**
 | |
|    * Append the desired widget configuration to aConfigurations.
 | |
|    */
 | |
|   void GetWidgetConfiguration(
 | |
|       nsTArray<nsIWidget::Configuration>* aConfigurations);
 | |
| 
 | |
|   LayoutDeviceIntRect GetWidgetlessClipRect() {
 | |
|     return RegionFromArray(mNextConfigurationClipRegion).GetBounds();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Called after all widget position/size/clip regions have been changed
 | |
|    * (even if there isn't a widget for this plugin).
 | |
|    */
 | |
|   void DidSetWidgetGeometry();
 | |
| 
 | |
|   // accessibility support
 | |
| #ifdef ACCESSIBILITY
 | |
|   virtual mozilla::a11y::AccType AccessibleType() override;
 | |
| #  ifdef XP_WIN
 | |
|   NS_IMETHOD GetPluginPort(HWND* aPort);
 | |
| #  endif
 | |
| #endif
 | |
| 
 | |
|   // local methods
 | |
|   nsresult PrepForDrawing(nsIWidget* aWidget);
 | |
| 
 | |
|   // for a given aRoot, this walks the frame tree looking for the next outFrame
 | |
|   static nsIObjectFrame* GetNextObjectFrame(nsPresContext* aPresContext,
 | |
|                                             nsIFrame* aRoot);
 | |
| 
 | |
|   // nsIReflowCallback
 | |
|   virtual bool ReflowFinished() override;
 | |
|   virtual void ReflowCallbackCanceled() override;
 | |
| 
 | |
|   /**
 | |
|    * Builds either an ImageLayer or a ReadbackLayer, depending on the type
 | |
|    * of aItem (TYPE_PLUGIN or TYPE_PLUGIN_READBACK respectively).
 | |
|    */
 | |
|   already_AddRefed<Layer> BuildLayer(
 | |
|       nsDisplayListBuilder* aBuilder, LayerManager* aManager,
 | |
|       nsDisplayItem* aItem,
 | |
|       const ContainerLayerParameters& aContainerParameters);
 | |
| 
 | |
|   LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
 | |
|                            LayerManager* aManager);
 | |
| 
 | |
|   /**
 | |
|    * Get the rectangle (relative to this frame) which it will paint. Normally
 | |
|    * the frame's content-box but may be smaller if the plugin is rendering
 | |
|    * asynchronously and has a different-sized image temporarily.
 | |
|    */
 | |
|   nsRect GetPaintedRect(const nsDisplayPlugin* aItem) const;
 | |
| 
 | |
|   /**
 | |
|    * If aSupports has a nsPluginFrame, then prepare it for a DocShell swap.
 | |
|    * @see nsSubDocumentFrame::BeginSwapDocShells.
 | |
|    * There will be a call to EndSwapDocShells after we were moved to the
 | |
|    * new view tree.
 | |
|    */
 | |
|   static void BeginSwapDocShells(nsISupports* aSupports, void*);
 | |
|   /**
 | |
|    * If aSupports has a nsPluginFrame, then set it up after a DocShell swap.
 | |
|    * @see nsSubDocumentFrame::EndSwapDocShells.
 | |
|    */
 | |
|   static void EndSwapDocShells(nsISupports* aSupports, void*);
 | |
| 
 | |
|   nsIWidget* GetWidget() override {
 | |
|     if (!mInnerView) {
 | |
|       return nullptr;
 | |
|     }
 | |
|     return mWidget;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Adjust the plugin's idea of its size, using aSize as its new size.
 | |
|    * (aSize must be in twips)
 | |
|    */
 | |
|   void FixupWindow(const nsSize& aSize);
 | |
| 
 | |
|   /*
 | |
|    * Sets up the plugin window and calls SetWindow on the plugin.
 | |
|    */
 | |
|   nsresult CallSetWindow(bool aCheckIsHidden = true);
 | |
| 
 | |
|   void SetInstanceOwner(nsPluginInstanceOwner* aOwner);
 | |
| 
 | |
|   /**
 | |
|    * HandleWheelEventAsDefaultAction() handles eWheel event as default action.
 | |
|    * This should be called only when WantsToHandleWheelEventAsDefaultAction()
 | |
|    * returns true.
 | |
|    */
 | |
|   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,
 | |
|       mozilla::wr::IpcResourceUpdateQueue& aResources,
 | |
|       const StackingContextHelper& aSc,
 | |
|       mozilla::layers::RenderRootStateManager* aManager,
 | |
|       nsDisplayListBuilder* aDisplayListBuilder);
 | |
| 
 | |
|  protected:
 | |
|   explicit nsPluginFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
 | |
|   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,
 | |
|                       ReflowOutput& aDesiredSize);
 | |
| 
 | |
|   bool IsFocusable(int32_t* aTabIndex = nullptr,
 | |
|                    bool aWithMouse = false) override;
 | |
| 
 | |
|   // check attributes and optionally CSS to see if we should display anything
 | |
|   bool IsHidden(bool aCheckVisibilityStyle = true) const;
 | |
| 
 | |
|   bool IsOpaque() const;
 | |
|   bool IsTransparentMode() const;
 | |
|   bool IsPaintedByGecko() const;
 | |
| 
 | |
|   nsIntPoint GetWindowOriginInPixels(bool aWindowless);
 | |
| 
 | |
|   /*
 | |
|    * If this frame is in a remote tab, return the tab offset to
 | |
|    * the origin of the chrome window. In non-e10s, this return 0,0.
 | |
|    * This api sends a sync ipc request so be careful about use.
 | |
|    */
 | |
|   LayoutDeviceIntPoint GetRemoteTabChromeOffset();
 | |
| 
 | |
|   static void PaintPrintPlugin(nsIFrame* aFrame, gfxContext* aRenderingContext,
 | |
|                                const nsRect& aDirtyRect, nsPoint aPt);
 | |
|   void PrintPlugin(gfxContext& aRenderingContext, const nsRect& aDirtyRect);
 | |
|   void PaintPlugin(nsDisplayListBuilder* aBuilder,
 | |
|                    gfxContext& aRenderingContext, const nsRect& aDirtyRect,
 | |
|                    const nsRect& aPluginRect);
 | |
| 
 | |
|   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();
 | |
| 
 | |
|   // Unregisters the plugin for geometry updated with the root pres context
 | |
|   // stored in mRootPresContextRegisteredWith.
 | |
|   void UnregisterPluginForGeometryUpdates();
 | |
| 
 | |
|   static const LayoutDeviceIntRegion RegionFromArray(
 | |
|       const nsTArray<LayoutDeviceIntRect>& aRects) {
 | |
|     LayoutDeviceIntRegion region;
 | |
|     for (uint32_t i = 0; i < aRects.Length(); ++i) {
 | |
|       region.Or(region, aRects[i]);
 | |
|     }
 | |
|     return region;
 | |
|   }
 | |
| 
 | |
|   class PluginEventNotifier : public mozilla::Runnable {
 | |
|    public:
 | |
|     explicit PluginEventNotifier(const nsString& aEventType)
 | |
|         : mozilla::Runnable("nsPluginFrame::PluginEventNotifier"),
 | |
|           mEventType(aEventType) {}
 | |
| 
 | |
|     NS_IMETHOD Run() override;
 | |
| 
 | |
|    private:
 | |
|     nsString mEventType;
 | |
|   };
 | |
| 
 | |
|   nsPluginInstanceOwner* mInstanceOwner;  // WEAK
 | |
|   nsView* mOuterView;
 | |
|   nsView* mInnerView;
 | |
|   nsCOMPtr<nsIWidget> mWidget;
 | |
|   nsIntRect mWindowlessRect;
 | |
|   /**
 | |
|    * This is owned by the ReadbackLayer for this nsPluginFrame. It is
 | |
|    * automatically cleared if the PluginBackgroundSink is destroyed.
 | |
|    */
 | |
|   PluginBackgroundSink* mBackgroundSink;
 | |
| 
 | |
|   /**
 | |
|    * Bounds that we should set the plugin's widget to in the next composite,
 | |
|    * for plugins with widgets. For plugins without widgets, bounds in device
 | |
|    * pixels relative to the nearest frame that's a display list reference frame.
 | |
|    */
 | |
|   LayoutDeviceIntRect mNextConfigurationBounds;
 | |
|   /**
 | |
|    * Clip region that we should set the plugin's widget to
 | |
|    * in the next composite. Only meaningful for plugins with widgets.
 | |
|    */
 | |
|   nsTArray<LayoutDeviceIntRect> mNextConfigurationClipRegion;
 | |
| 
 | |
|   bool mReflowCallbackPosted;
 | |
| 
 | |
|   // We keep this reference to ensure we can always unregister the
 | |
|   // plugins we register on the root PresContext.
 | |
|   // This is only non-null while we have a plugin registered for geometry
 | |
|   // updates.
 | |
|   RefPtr<nsRootPresContext> mRootPresContextRegisteredWith;
 | |
| 
 | |
|   mozilla::UniquePtr<PluginFrameDidCompositeObserver> mDidCompositeObserver;
 | |
| };
 | |
| 
 | |
| class nsDisplayPluginGeometry : public nsDisplayItemGenericGeometry {
 | |
|  public:
 | |
|   nsDisplayPluginGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder)
 | |
|       : nsDisplayItemGenericGeometry(aItem, aBuilder) {}
 | |
| 
 | |
|   // Plugins MozPaintWait event depends on sync decode, so we always want
 | |
|   // to rebuild the display list when sync decoding.
 | |
|   virtual bool InvalidateForSyncDecodeImages() const override { return true; }
 | |
| };
 | |
| 
 | |
| class nsDisplayPlugin final : public nsPaintedDisplayItem {
 | |
|  public:
 | |
|   nsDisplayPlugin(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
 | |
|       : nsPaintedDisplayItem(aBuilder, aFrame) {
 | |
|     MOZ_COUNT_CTOR(nsDisplayPlugin);
 | |
|     aBuilder->SetContainsPluginItem();
 | |
|   }
 | |
| #ifdef NS_BUILD_REFCNT_LOGGING
 | |
|   virtual ~nsDisplayPlugin() { MOZ_COUNT_DTOR(nsDisplayPlugin); }
 | |
| #endif
 | |
| 
 | |
|   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
 | |
|                            bool* aSnap) const override;
 | |
|   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
 | |
|                                    bool* aSnap) const override;
 | |
|   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
 | |
|   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
 | |
|                                  nsRegion* aVisibleRegion) override;
 | |
| 
 | |
|   NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN)
 | |
| 
 | |
|   virtual already_AddRefed<Layer> BuildLayer(
 | |
|       nsDisplayListBuilder* aBuilder, LayerManager* aManager,
 | |
|       const ContainerLayerParameters& aContainerParameters) override {
 | |
|     return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(
 | |
|         aBuilder, aManager, this, aContainerParameters);
 | |
|   }
 | |
| 
 | |
|   virtual LayerState GetLayerState(
 | |
|       nsDisplayListBuilder* aBuilder, LayerManager* aManager,
 | |
|       const ContainerLayerParameters& aParameters) override {
 | |
|     return static_cast<nsPluginFrame*>(mFrame)->GetLayerState(aBuilder,
 | |
|                                                               aManager);
 | |
|   }
 | |
| 
 | |
|   virtual nsDisplayItemGeometry* AllocateGeometry(
 | |
|       nsDisplayListBuilder* aBuilder) override {
 | |
|     return new nsDisplayPluginGeometry(this, aBuilder);
 | |
|   }
 | |
| 
 | |
|   virtual bool CreateWebRenderCommands(
 | |
|       mozilla::wr::DisplayListBuilder& aBuilder,
 | |
|       mozilla::wr::IpcResourceUpdateQueue& aResources,
 | |
|       const StackingContextHelper& aSc,
 | |
|       mozilla::layers::RenderRootStateManager* aManager,
 | |
|       nsDisplayListBuilder* aDisplayListBuilder) override;
 | |
| };
 | |
| 
 | |
| #endif /* nsPluginFrame_h___ */
 |