gfx/layers/composite/CompositableHost.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef MOZILLA_GFX_BUFFERHOST_H
     7 #define MOZILLA_GFX_BUFFERHOST_H
     9 #include <stdint.h>                     // for uint64_t
    10 #include <stdio.h>                      // for FILE
    11 #include "gfxRect.h"                    // for gfxRect
    12 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    13 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
    14 #include "mozilla/RefPtr.h"             // for RefPtr, RefCounted, etc
    15 #include "mozilla/gfx/Point.h"          // for Point
    16 #include "mozilla/gfx/Rect.h"           // for Rect
    17 #include "mozilla/gfx/Types.h"          // for Filter
    18 #include "mozilla/ipc/ProtocolUtils.h"
    19 #include "mozilla/layers/CompositorTypes.h"  // for TextureInfo, etc
    20 #include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
    21 #include "mozilla/layers/PCompositableParent.h"
    22 #include "mozilla/layers/TextureHost.h" // for TextureHost
    23 #include "mozilla/mozalloc.h"           // for operator delete
    24 #include "nsCOMPtr.h"                   // for already_AddRefed
    25 #include "nsRegion.h"                   // for nsIntRegion
    26 #include "nscore.h"                     // for nsACString
    27 #include "Units.h"                      // for CSSToScreenScale
    29 struct nsIntPoint;
    30 struct nsIntRect;
    32 namespace mozilla {
    33 namespace gfx {
    34 class Matrix4x4;
    35 class DataSourceSurface;
    36 }
    38 namespace layers {
    40 // Some properties of a Layer required for tiling
    41 struct TiledLayerProperties
    42 {
    43   nsIntRegion mVisibleRegion;
    44   nsIntRegion mValidRegion;
    45   CSSToScreenScale mEffectiveResolution;
    46 };
    48 class Layer;
    49 class SurfaceDescriptor;
    50 class Compositor;
    51 class ISurfaceAllocator;
    52 class ThebesBufferData;
    53 class TiledLayerComposer;
    54 class CompositableParentManager;
    55 struct EffectChain;
    57 /**
    58  * A base class for doing CompositableHost and platform dependent task on TextureHost.
    59  */
    60 class CompositableBackendSpecificData
    61 {
    62 protected:
    63   virtual ~CompositableBackendSpecificData() { }
    65 public:
    66   NS_INLINE_DECL_REFCOUNTING(CompositableBackendSpecificData)
    68   CompositableBackendSpecificData()
    69   {
    70   }
    72   virtual void SetCompositor(Compositor* aCompositor) {}
    73   virtual void ClearData()
    74   {
    75     mCurrentReleaseFenceTexture = nullptr;
    76     ClearPendingReleaseFenceTextureList();
    77   }
    79   /**
    80    * Store a texture currently used for Composition.
    81    * This function is called when the texutre might receive ReleaseFence
    82    * as a result of Composition.
    83    */
    84   void SetCurrentReleaseFenceTexture(TextureHost* aTexture)
    85   {
    86     if (mCurrentReleaseFenceTexture) {
    87       mPendingReleaseFenceTextures.push_back(mCurrentReleaseFenceTexture);
    88     }
    89     mCurrentReleaseFenceTexture = aTexture;
    90   }
    92   virtual std::vector< RefPtr<TextureHost> >& GetPendingReleaseFenceTextureList()
    93   {
    94     return mPendingReleaseFenceTextures;
    95   }
    97   virtual void ClearPendingReleaseFenceTextureList()
    98   {
    99     return mPendingReleaseFenceTextures.clear();
   100   }
   101 protected:
   102   /**
   103    * Store a TextureHost currently used for Composition
   104    * and it might receive ReleaseFence for the texutre.
   105    */
   106   RefPtr<TextureHost> mCurrentReleaseFenceTexture;
   107   /**
   108    * Store TextureHosts that might have ReleaseFence to be delivered
   109    * to TextureClient by CompositableHost.
   110    */
   111   std::vector< RefPtr<TextureHost> > mPendingReleaseFenceTextures;
   112 };
   114 /**
   115  * The compositor-side counterpart to CompositableClient. Responsible for
   116  * updating textures and data about textures from IPC and how textures are
   117  * composited (tiling, double buffering, etc.).
   118  *
   119  * Update (for images/canvases) and UpdateThebes (for Thebes) are called during
   120  * the layers transaction to update the Compositbale's textures from the
   121  * content side. The actual update (and any syncronous upload) is done by the
   122  * TextureHost, but it is coordinated by the CompositableHost.
   123  *
   124  * Composite is called by the owning layer when it is composited. CompositableHost
   125  * will use its TextureHost(s) and call Compositor::DrawQuad to do the actual
   126  * rendering.
   127  */
   128 class CompositableHost
   129 {
   130 protected:
   131   virtual ~CompositableHost();
   133 public:
   134   NS_INLINE_DECL_REFCOUNTING(CompositableHost)
   135   CompositableHost(const TextureInfo& aTextureInfo);
   137   static TemporaryRef<CompositableHost> Create(const TextureInfo& aTextureInfo);
   139   virtual CompositableType GetType() = 0;
   141   virtual CompositableBackendSpecificData* GetCompositableBackendSpecificData()
   142   {
   143     return mBackendData;
   144   }
   146   virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
   147   {
   148     mBackendData = aBackendData;
   149   }
   151   // If base class overrides, it should still call the parent implementation
   152   virtual void SetCompositor(Compositor* aCompositor);
   154   // composite the contents of this buffer host to the compositor's surface
   155   virtual void Composite(EffectChain& aEffectChain,
   156                          float aOpacity,
   157                          const gfx::Matrix4x4& aTransform,
   158                          const gfx::Filter& aFilter,
   159                          const gfx::Rect& aClipRect,
   160                          const nsIntRegion* aVisibleRegion = nullptr,
   161                          TiledLayerProperties* aLayerProperties = nullptr) = 0;
   163   /**
   164    * Update the content host.
   165    * aUpdated is the region which should be updated
   166    * aUpdatedRegionBack is the region in aNewBackResult which has been updated
   167    */
   168   virtual bool UpdateThebes(const ThebesBufferData& aData,
   169                             const nsIntRegion& aUpdated,
   170                             const nsIntRegion& aOldValidRegionBack,
   171                             nsIntRegion* aUpdatedRegionBack)
   172   {
   173     NS_ERROR("should be implemented or not used");
   174     return false;
   175   }
   177   /**
   178    * Update the content host using a surface that only contains the updated
   179    * region.
   180    *
   181    * Takes ownership of aSurface, and is responsible for freeing it.
   182    *
   183    * @param aTextureId Texture to update.
   184    * @param aSurface Surface containing the update area. Its contents are relative
   185    *                 to aUpdated.TopLeft()
   186    * @param aUpdated Area of the content host to update.
   187    * @param aBufferRect New area covered by the content host.
   188    * @param aBufferRotation New buffer rotation.
   189    */
   190   virtual void UpdateIncremental(TextureIdentifier aTextureId,
   191                                  SurfaceDescriptor& aSurface,
   192                                  const nsIntRegion& aUpdated,
   193                                  const nsIntRect& aBufferRect,
   194                                  const nsIntPoint& aBufferRotation)
   195   {
   196     MOZ_ASSERT(false, "should be implemented or not used");
   197   }
   199   /**
   200    * Ensure that a suitable texture host exists in this compsitable.
   201    *
   202    * Only used with ContentHostIncremental.
   203    *
   204    * No SurfaceDescriptor or TextureIdentifier is provider as we
   205    * don't have a single surface for the texture contents, and we
   206    * need to allocate our own one to be updated later.
   207    */
   208   virtual bool CreatedIncrementalTexture(ISurfaceAllocator* aAllocator,
   209                                          const TextureInfo& aTextureInfo,
   210                                          const nsIntRect& aBufferRect)
   211   {
   212     NS_ERROR("should be implemented or not used");
   213     return false;
   214   }
   216   /**
   217    * Returns the front buffer.
   218    */
   219   virtual TextureHost* GetAsTextureHost() { return nullptr; }
   221   virtual LayerRenderState GetRenderState() = 0;
   223   virtual void SetPictureRect(const nsIntRect& aPictureRect)
   224   {
   225     MOZ_ASSERT(false, "Should have been overridden");
   226   }
   228   /**
   229    * Adds a mask effect using this texture as the mask, if possible.
   230    * @return true if the effect was added, false otherwise.
   231    */
   232   bool AddMaskEffect(EffectChain& aEffects,
   233                      const gfx::Matrix4x4& aTransform,
   234                      bool aIs3D = false);
   236   void RemoveMaskEffect();
   238   Compositor* GetCompositor() const
   239   {
   240     return mCompositor;
   241   }
   243   Layer* GetLayer() const { return mLayer; }
   244   void SetLayer(Layer* aLayer) { mLayer = aLayer; }
   246   virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; }
   248   typedef uint32_t AttachFlags;
   249   static const AttachFlags NO_FLAGS = 0;
   250   static const AttachFlags ALLOW_REATTACH = 1;
   251   static const AttachFlags KEEP_ATTACHED = 2;
   252   static const AttachFlags FORCE_DETACH = 2;
   254   virtual void Attach(Layer* aLayer,
   255                       Compositor* aCompositor,
   256                       AttachFlags aFlags = NO_FLAGS)
   257   {
   258     MOZ_ASSERT(aCompositor, "Compositor is required");
   259     NS_ASSERTION(aFlags & ALLOW_REATTACH || !mAttached,
   260                  "Re-attaching compositables must be explicitly authorised");
   261     SetCompositor(aCompositor);
   262     SetLayer(aLayer);
   263     mAttached = true;
   264     mKeepAttached = aFlags & KEEP_ATTACHED;
   265   }
   266   // Detach this compositable host from its layer.
   267   // If we are used for async video, then it is not safe to blindly detach since
   268   // we might be re-attached to a different layer. aLayer is the layer which the
   269   // caller expects us to be attached to, we will only detach if we are in fact
   270   // attached to that layer. If we are part of a normal layer, then we will be
   271   // detached in any case. if aLayer is null, then we will only detach if we are
   272   // not async.
   273   // Only force detach if the IPDL tree is being shutdown.
   274   void Detach(Layer* aLayer = nullptr, AttachFlags aFlags = NO_FLAGS)
   275   {
   276     if (!mKeepAttached ||
   277         aLayer == mLayer ||
   278         aFlags & FORCE_DETACH) {
   279       SetLayer(nullptr);
   280       mAttached = false;
   281       mKeepAttached = false;
   282       if (mBackendData) {
   283         mBackendData->ClearData();
   284       }
   285     }
   286   }
   287   bool IsAttached() { return mAttached; }
   289 #ifdef MOZ_DUMP_PAINTING
   290   virtual void Dump(FILE* aFile=nullptr,
   291                     const char* aPrefix="",
   292                     bool aDumpHtml=false) { }
   293   static void DumpTextureHost(FILE* aFile, TextureHost* aTexture);
   295   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() { return nullptr; }
   296 #endif
   298   virtual void PrintInfo(nsACString& aTo, const char* aPrefix) { }
   300   virtual void UseTextureHost(TextureHost* aTexture);
   301   virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
   302                                          TextureHost* aTextureOnWhite);
   304   virtual void RemoveTextureHost(TextureHost* aTexture);
   306   // Called every time this is composited
   307   void BumpFlashCounter() {
   308     mFlashCounter = mFlashCounter >= DIAGNOSTIC_FLASH_COUNTER_MAX
   309                   ? DIAGNOSTIC_FLASH_COUNTER_MAX : mFlashCounter + 1;
   310   }
   312   static PCompositableParent*
   313   CreateIPDLActor(CompositableParentManager* mgr,
   314                   const TextureInfo& textureInfo,
   315                   uint64_t asyncID);
   317   static bool DestroyIPDLActor(PCompositableParent* actor);
   319   static CompositableHost* FromIPDLActor(PCompositableParent* actor);
   321   uint64_t GetCompositorID() const { return mCompositorID; }
   323   uint64_t GetAsyncID() const { return mAsyncID; }
   325   void SetCompositorID(uint64_t aID) { mCompositorID = aID; }
   327   void SetAsyncID(uint64_t aID) { mAsyncID = aID; }
   329 protected:
   330   TextureInfo mTextureInfo;
   331   uint64_t mAsyncID;
   332   uint64_t mCompositorID;
   333   Compositor* mCompositor;
   334   Layer* mLayer;
   335   RefPtr<CompositableBackendSpecificData> mBackendData;
   336   uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true.
   337   bool mAttached;
   338   bool mKeepAttached;
   339 };
   341 /**
   342  * Global CompositableMap, to use in the compositor thread only.
   343  *
   344  * PCompositable and PLayer can, in the case of async textures, be managed by
   345  * different top level protocols. In this case they don't share the same
   346  * communication channel and we can't send an OpAttachCompositable (PCompositable,
   347  * PLayer) message.
   348  *
   349  * In order to attach a layer and the right compositable if the the compositable
   350  * is async, we store references to the async compositables in a CompositableMap
   351  * that is accessed only on the compositor thread. During a layer transaction we
   352  * send the message OpAttachAsyncCompositable(ID, PLayer), and on the compositor
   353  * side we lookup the ID in the map and attach the correspondig compositable to
   354  * the layer.
   355  *
   356  * CompositableMap must be global because the image bridge doesn't have any
   357  * reference to whatever we have created with PLayerTransaction. So, the only way to
   358  * actually connect these two worlds is to have something global that they can
   359  * both query (in the same  thread). The map is not allocated the map on the 
   360  * stack to avoid the badness of static initialization.
   361  *
   362  * Also, we have a compositor/PLayerTransaction protocol/etc. per layer manager, and the
   363  * ImageBridge is used by all the existing compositors that have a video, so
   364  * there isn't an instance or "something" that lives outside the boudaries of a
   365  * given layer manager on the compositor thread except the image bridge and the
   366  * thread itself.
   367  */
   368 namespace CompositableMap {
   369   void Create();
   370   void Destroy();
   371   PCompositableParent* Get(uint64_t aID);
   372   void Set(uint64_t aID, PCompositableParent* aParent);
   373   void Erase(uint64_t aID);
   374   void Clear();
   375 } // CompositableMap
   378 } // namespace
   379 } // namespace
   381 #endif

mercurial