gfx/layers/composite/TextureHost.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_TEXTUREHOST_H
     7 #define MOZILLA_GFX_TEXTUREHOST_H
     9 #include <stddef.h>                     // for size_t
    10 #include <stdint.h>                     // for uint64_t, uint32_t, uint8_t
    11 #include "gfxTypes.h"
    12 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    13 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
    14 #include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef, etc
    15 #include "mozilla/gfx/2D.h"             // for DataSourceSurface
    16 #include "mozilla/gfx/Point.h"          // for IntSize, IntPoint
    17 #include "mozilla/gfx/Types.h"          // for SurfaceFormat, etc
    18 #include "mozilla/layers/CompositorTypes.h"  // for TextureFlags, etc
    19 #include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
    20 #include "mozilla/mozalloc.h"           // for operator delete
    21 #include "nsCOMPtr.h"                   // for already_AddRefed
    22 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
    23 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
    24 #include "nsRegion.h"                   // for nsIntRegion
    25 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
    26 #include "nscore.h"                     // for nsACString
    27 #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
    29 class gfxReusableSurfaceWrapper;
    30 struct nsIntPoint;
    31 struct nsIntSize;
    32 struct nsIntRect;
    34 namespace mozilla {
    35 namespace ipc {
    36 class Shmem;
    37 }
    39 namespace layers {
    41 class Compositor;
    42 class CompositableHost;
    43 class CompositableBackendSpecificData;
    44 class SurfaceDescriptor;
    45 class ISurfaceAllocator;
    46 class TextureHostOGL;
    47 class TextureSourceOGL;
    48 class TextureSourceD3D9;
    49 class TextureSourceD3D11;
    50 class TextureSourceBasic;
    51 class DataTextureSource;
    52 class PTextureParent;
    53 class TextureParent;
    55 /**
    56  * A view on a TextureHost where the texture is internally represented as tiles
    57  * (contrast with a tiled buffer, where each texture is a tile). For iteration by
    58  * the texture's buffer host.
    59  * This is only useful when the underlying surface is too big to fit in one
    60  * device texture, which forces us to split it in smaller parts.
    61  * Tiled Compositable is a different thing.
    62  */
    63 class TileIterator
    64 {
    65 public:
    66   virtual void BeginTileIteration() = 0;
    67   virtual void EndTileIteration() {};
    68   virtual nsIntRect GetTileRect() = 0;
    69   virtual size_t GetTileCount() = 0;
    70   virtual bool NextTile() = 0;
    71 };
    73 /**
    74  * TextureSource is the interface for texture objects that can be composited
    75  * by a given compositor backend. Since the drawing APIs are different
    76  * between backends, the TextureSource interface is split into different
    77  * interfaces (TextureSourceOGL, etc.), and TextureSource mostly provide
    78  * access to these interfaces.
    79  *
    80  * This class is used on the compositor side.
    81  */
    82 class TextureSource
    83 {
    84 protected:
    85   virtual ~TextureSource();
    87 public:
    88   NS_INLINE_DECL_REFCOUNTING(TextureSource)
    90   TextureSource();
    92   /**
    93    * Return the size of the texture in texels.
    94    * If this is a tile iterator, GetSize must return the size of the current tile.
    95    */
    96   virtual gfx::IntSize GetSize() const = 0;
    98   /**
    99    * Return the pixel format of this texture
   100    */
   101   virtual gfx::SurfaceFormat GetFormat() const { return gfx::SurfaceFormat::UNKNOWN; }
   103   /**
   104    * Cast to a TextureSource for for each backend..
   105    */
   106   virtual TextureSourceOGL* AsSourceOGL() { return nullptr; }
   107   virtual TextureSourceD3D9* AsSourceD3D9() { return nullptr; }
   108   virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
   109   virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
   111   /**
   112    * Cast to a DataTextureSurce.
   113    */
   114   virtual DataTextureSource* AsDataTextureSource() { return nullptr; }
   116   /**
   117    * In some rare cases we currently need to consider a group of textures as one
   118    * TextureSource, that can be split in sub-TextureSources.
   119    */
   120   virtual TextureSource* GetSubSource(int index) { return nullptr; }
   122   /**
   123    * Overload this if the TextureSource supports big textures that don't fit in
   124    * one device texture and must be tiled internally.
   125    */
   126   virtual TileIterator* AsTileIterator() { return nullptr; }
   128   virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData);
   130 protected:
   131   RefPtr<CompositableBackendSpecificData> mCompositableBackendData;
   132 };
   134 /**
   135  * XXX - merge this class with TextureSource when deprecated texture classes
   136  * are completely removed.
   137  */
   138 class NewTextureSource : public TextureSource
   139 {
   140 public:
   141   NewTextureSource()
   142   {
   143     MOZ_COUNT_CTOR(NewTextureSource);
   144   }
   145   virtual ~NewTextureSource()
   146   {
   147     MOZ_COUNT_DTOR(NewTextureSource);
   148   }
   150   /**
   151    * Should be overridden in order to deallocate the data that is associated
   152    * with the rendering backend, such as GL textures.
   153    */
   154   virtual void DeallocateDeviceData() = 0;
   156   virtual void SetCompositor(Compositor* aCompositor) {}
   158   void SetNextSibling(NewTextureSource* aTexture)
   159   {
   160     mNextSibling = aTexture;
   161   }
   163   NewTextureSource* GetNextSibling() const
   164   {
   165     return mNextSibling;
   166   }
   168   // temporary adapter to use the same SubSource API as the old TextureSource
   169   virtual TextureSource* GetSubSource(int index) MOZ_OVERRIDE
   170   {
   171     switch (index) {
   172       case 0: return this;
   173       case 1: return GetNextSibling();
   174       case 2: return GetNextSibling() ? GetNextSibling()->GetNextSibling() : nullptr;
   175     }
   176     return nullptr;
   177   }
   179 protected:
   180   RefPtr<NewTextureSource> mNextSibling;
   181 };
   183 /**
   184  * Interface for TextureSources that can be updated from a DataSourceSurface.
   185  *
   186  * All backend should implement at least one DataTextureSource.
   187  */
   188 class DataTextureSource : public NewTextureSource
   189 {
   190 public:
   191   DataTextureSource()
   192     : mUpdateSerial(0)
   193   {}
   195   virtual DataTextureSource* AsDataTextureSource() MOZ_OVERRIDE { return this; }
   197   /**
   198    * Upload a (portion of) surface to the TextureSource.
   199    *
   200    * The DataTextureSource doesn't own aSurface, although it owns and manage
   201    * the device texture it uploads to internally.
   202    */
   203   virtual bool Update(gfx::DataSourceSurface* aSurface,
   204                       nsIntRegion* aDestRegion = nullptr,
   205                       gfx::IntPoint* aSrcOffset = nullptr) = 0;
   207   /**
   208    * A facility to avoid reuploading when it is not necessary.
   209    * The caller of Update can use GetUpdateSerial to see if the number has changed
   210    * since last update, and call SetUpdateSerial after each successful update.
   211    * The caller is responsible for managing the update serial except when the
   212    * texture data is deallocated in which case the TextureSource should always
   213    * reset the update serial to zero.
   214    */
   215   uint32_t GetUpdateSerial() const { return mUpdateSerial; }
   216   void SetUpdateSerial(uint32_t aValue) { mUpdateSerial = aValue; }
   218   // By default at least set the update serial to zero.
   219   // overloaded versions should do that too.
   220   virtual void DeallocateDeviceData() MOZ_OVERRIDE
   221   {
   222     SetUpdateSerial(0);
   223   }
   225 #ifdef DEBUG
   226   /**
   227    * Provide read access to the data as a DataSourceSurface.
   228    *
   229    * This is expected to be very slow and should be used for mostly debugging.
   230    * XXX - implement everywhere and make it pure virtual.
   231    */
   232   virtual TemporaryRef<gfx::DataSourceSurface> ReadBack() { return nullptr; };
   233 #endif
   235 private:
   236   uint32_t mUpdateSerial;
   237 };
   239 /**
   240  * TextureHost is a thin abstraction over texture data that need to be shared
   241  * between the content process and the compositor process. It is the
   242  * compositor-side half of a TextureClient/TextureHost pair. A corresponding
   243  * TextureClient lives on the content-side.
   244  *
   245  * TextureHost only knows how to deserialize or synchronize generic image data
   246  * (SurfaceDescriptor) and provide access to one or more TextureSource objects
   247  * (these provide the necessary APIs for compositor backends to composite the
   248  * image).
   249  *
   250  * A TextureHost implementation corresponds to one SurfaceDescriptor type, as
   251  * opposed to TextureSource that corresponds to device textures.
   252  * This means that for YCbCr planes, even though they are represented as
   253  * 3 textures internally (3 TextureSources), we use 1 TextureHost and not 3,
   254  * because the 3 planes are stored in the same buffer of shared memory, before
   255  * they are uploaded separately.
   256  *
   257  * There is always one and only one TextureHost per TextureClient, and the
   258  * TextureClient/Host pair only owns one buffer of image data through its
   259  * lifetime. This means that the lifetime of the underlying shared data
   260  * matches the lifetime of the TextureClient/Host pair. It also means
   261  * TextureClient/Host do not implement double buffering, which is the
   262  * reponsibility of the compositable (which would use two Texture pairs).
   263  *
   264  * The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
   265  *
   266  */
   267 class TextureHost
   268   : public AtomicRefCountedWithFinalize<TextureHost>
   269 {
   270   /**
   271    * Called once, just before the destructor.
   272    *
   273    * Here goes the shut-down code that uses virtual methods.
   274    * Must only be called by Release().
   275    */
   276   void Finalize();
   278   friend class AtomicRefCountedWithFinalize<TextureHost>;
   279 public:
   280   TextureHost(TextureFlags aFlags);
   282   virtual ~TextureHost();
   284   /**
   285    * Factory method.
   286    */
   287   static TemporaryRef<TextureHost> Create(const SurfaceDescriptor& aDesc,
   288                                           ISurfaceAllocator* aDeallocator,
   289                                           TextureFlags aFlags);
   291   /**
   292    * Tell to TextureChild that TextureHost is recycled.
   293    * This function should be called from TextureHost's RecycleCallback.
   294    * If SetRecycleCallback is set to TextureHost.
   295    * TextureHost can be recycled by calling RecycleCallback
   296    * when reference count becomes one.
   297    * One reference count is always added by TextureChild.
   298    */
   299   void CompositorRecycle();
   301   /**
   302    * Lock the texture host for compositing.
   303    */
   304   virtual bool Lock() { return true; }
   306   /**
   307    * Unlock the texture host after compositing.
   308    */
   309   virtual void Unlock() {}
   311   /**
   312    * Note that the texture host format can be different from its corresponding
   313    * texture source's. For example a ShmemTextureHost can have the ycbcr
   314    * format and produce 3 "alpha" textures sources.
   315    */
   316   virtual gfx::SurfaceFormat GetFormat() const = 0;
   318   /**
   319    * Return a list of TextureSources for use with a Compositor.
   320    *
   321    * This can trigger texture uploads, so do not call it inside transactions
   322    * so as to not upload textures while the main thread is blocked.
   323    * Must not be called while this TextureHost is not sucessfully Locked.
   324    */
   325   virtual NewTextureSource* GetTextureSources() = 0;
   327   /**
   328    * Is called before compositing if the shared data has changed since last
   329    * composition.
   330    * This method should be overload in cases like when we need to do a texture
   331    * upload for example.
   332    *
   333    * @param aRegion The region that has been changed, if nil, it means that the
   334    * entire surface should be updated.
   335    */
   336   virtual void Updated(const nsIntRegion* aRegion = nullptr) {}
   338   /**
   339    * Sets this TextureHost's compositor.
   340    * A TextureHost can change compositor on certain occasions, in particular if
   341    * it belongs to an async Compositable.
   342    * aCompositor can be null, in which case the TextureHost must cleanup  all
   343    * of it's device textures.
   344    */
   345   virtual void SetCompositor(Compositor* aCompositor) {}
   347   /**
   348    * Should be overridden in order to deallocate the data that is associated
   349    * with the rendering backend, such as GL textures.
   350    */
   351   virtual void DeallocateDeviceData() {}
   353   /**
   354    * Should be overridden in order to deallocate the data that is shared with
   355    * the content side, such as shared memory.
   356    */
   357   virtual void DeallocateSharedData() {}
   359   /**
   360    * Should be overridden in order to force the TextureHost to drop all references
   361    * to it's shared data.
   362    *
   363    * This is important to ensure the correctness of the deallocation protocol.
   364    */
   365   virtual void ForgetSharedData() {}
   367   virtual gfx::IntSize GetSize() const = 0;
   369   /**
   370    * Debug facility.
   371    * XXX - cool kids use Moz2D. See bug 882113.
   372    */
   373   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() = 0;
   375   /**
   376    * XXX - Flags should only be set at creation time, this will be removed.
   377    */
   378   void SetFlags(TextureFlags aFlags) { mFlags = aFlags; }
   380   /**
   381    * XXX - Flags should only be set at creation time, this will be removed.
   382    */
   383   void AddFlag(TextureFlags aFlag) { mFlags |= aFlag; }
   385   TextureFlags GetFlags() { return mFlags; }
   387   /**
   388    * Allocate and deallocate a TextureParent actor.
   389    *
   390    * TextureParent< is an implementation detail of TextureHost that is not
   391    * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
   392    * are for use with the managing IPDL protocols only (so that they can
   393    * implement AllocPTextureParent and DeallocPTextureParent).
   394    */
   395   static PTextureParent* CreateIPDLActor(ISurfaceAllocator* aAllocator,
   396                                          const SurfaceDescriptor& aSharedData,
   397                                          TextureFlags aFlags);
   398   static bool DestroyIPDLActor(PTextureParent* actor);
   400   /**
   401    * Destroy the TextureChild/Parent pair.
   402    */
   403   static bool SendDeleteIPDLActor(PTextureParent* actor);
   405   /**
   406    * Get the TextureHost corresponding to the actor passed in parameter.
   407    */
   408   static TextureHost* AsTextureHost(PTextureParent* actor);
   410   /**
   411    * Return a pointer to the IPDLActor.
   412    *
   413    * This is to be used with IPDL messages only. Do not store the returned
   414    * pointer.
   415    */
   416   PTextureParent* GetIPDLActor();
   418   /**
   419    * Specific to B2G's Composer2D
   420    * XXX - more doc here
   421    */
   422   virtual LayerRenderState GetRenderState()
   423   {
   424     // By default we return an empty render state, this should be overridden
   425     // by the TextureHost implementations that are used on B2G with Composer2D
   426     return LayerRenderState();
   427   }
   429   virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData);
   431   // If a texture host holds a reference to shmem, it should override this method
   432   // to forget about the shmem _without_ releasing it.
   433   virtual void OnShutdown() {}
   435   // Forget buffer actor. Used only for hacky fix for bug 966446. 
   436   virtual void ForgetBufferActor() {}
   438   virtual const char *Name() { return "TextureHost"; }
   439   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
   441   /**
   442    * Indicates whether the TextureHost implementation is backed by an
   443    * in-memory buffer. The consequence of this is that locking the
   444    * TextureHost does not contend with locking the texture on the client side.
   445    */
   446   virtual bool HasInternalBuffer() const { return false; }
   448   /**
   449    * Cast to a TextureHost for each backend.
   450    */
   451   virtual TextureHostOGL* AsHostOGL() { return nullptr; }
   453 protected:
   454   PTextureParent* mActor;
   455   TextureFlags mFlags;
   456   RefPtr<CompositableBackendSpecificData> mCompositableBackendData;
   458   friend class TextureParent;
   459 };
   461 /**
   462  * TextureHost that wraps a random access buffer such as a Shmem or some raw
   463  * memory.
   464  *
   465  * This TextureHost is backend-independent and the backend-specific bits are
   466  * in the TextureSource.
   467  * This class must be inherited to implement GetBuffer and DeallocSharedData
   468  * (see ShmemTextureHost and MemoryTextureHost)
   469  *
   470  * Uploads happen when Lock is called.
   471  *
   472  * BufferTextureHost supports YCbCr and flavours of RGBA images (RGBX, A, etc.).
   473  */
   474 class BufferTextureHost : public TextureHost
   475 {
   476 public:
   477   BufferTextureHost(gfx::SurfaceFormat aFormat,
   478                     TextureFlags aFlags);
   480   ~BufferTextureHost();
   482   virtual uint8_t* GetBuffer() = 0;
   484   virtual size_t GetBufferSize() = 0;
   486   virtual void Updated(const nsIntRegion* aRegion = nullptr) MOZ_OVERRIDE;
   488   virtual bool Lock() MOZ_OVERRIDE;
   490   virtual void Unlock() MOZ_OVERRIDE;
   492   virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE;
   494   virtual void DeallocateDeviceData() MOZ_OVERRIDE;
   496   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
   498   /**
   499    * Return the format that is exposed to the compositor when calling
   500    * GetTextureSources.
   501    *
   502    * If the shared format is YCbCr and the compositor does not support it,
   503    * GetFormat will be RGB32 (even though mFormat is SurfaceFormat::YUV).
   504    */
   505   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
   507   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
   509   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
   511   virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; }
   513 protected:
   514   bool Upload(nsIntRegion *aRegion = nullptr);
   515   bool MaybeUpload(nsIntRegion *aRegion = nullptr);
   517   Compositor* mCompositor;
   518   RefPtr<DataTextureSource> mFirstSource;
   519   nsIntRegion mMaybeUpdatedRegion;
   520   gfx::IntSize mSize;
   521   // format of the data that is shared with the content process.
   522   gfx::SurfaceFormat mFormat;
   523   uint32_t mUpdateSerial;
   524   bool mLocked;
   525   bool mPartialUpdate;
   526 };
   528 /**
   529  * TextureHost that wraps shared memory.
   530  * the corresponding texture on the client side is ShmemTextureClient.
   531  * This TextureHost is backend-independent.
   532  */
   533 class ShmemTextureHost : public BufferTextureHost
   534 {
   535 public:
   536   ShmemTextureHost(const mozilla::ipc::Shmem& aShmem,
   537                    gfx::SurfaceFormat aFormat,
   538                    ISurfaceAllocator* aDeallocator,
   539                    TextureFlags aFlags);
   541   ~ShmemTextureHost();
   543   virtual void DeallocateSharedData() MOZ_OVERRIDE;
   545   virtual void ForgetSharedData() MOZ_OVERRIDE;
   547   virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
   549   virtual size_t GetBufferSize() MOZ_OVERRIDE;
   551   virtual const char *Name() MOZ_OVERRIDE { return "ShmemTextureHost"; }
   553   virtual void OnShutdown() MOZ_OVERRIDE;
   555 protected:
   556   mozilla::ipc::Shmem* mShmem;
   557   RefPtr<ISurfaceAllocator> mDeallocator;
   558 };
   560 /**
   561  * TextureHost that wraps raw memory.
   562  * The corresponding texture on the client side is MemoryTextureClient.
   563  * Can obviously not be used in a cross process setup.
   564  * This TextureHost is backend-independent.
   565  */
   566 class MemoryTextureHost : public BufferTextureHost
   567 {
   568 public:
   569   MemoryTextureHost(uint8_t* aBuffer,
   570                     gfx::SurfaceFormat aFormat,
   571                     TextureFlags aFlags);
   573   ~MemoryTextureHost();
   575   virtual void DeallocateSharedData() MOZ_OVERRIDE;
   577   virtual void ForgetSharedData() MOZ_OVERRIDE;
   579   virtual uint8_t* GetBuffer() MOZ_OVERRIDE;
   581   virtual size_t GetBufferSize() MOZ_OVERRIDE;
   583   virtual const char *Name() MOZ_OVERRIDE { return "MemoryTextureHost"; }
   585 protected:
   586   uint8_t* mBuffer;
   587 };
   589 class MOZ_STACK_CLASS AutoLockTextureHost
   590 {
   591 public:
   592   AutoLockTextureHost(TextureHost* aTexture)
   593     : mTexture(aTexture)
   594   {
   595     mLocked = mTexture ? mTexture->Lock() : false;
   596   }
   598   ~AutoLockTextureHost()
   599   {
   600     if (mTexture && mLocked) {
   601       mTexture->Unlock();
   602     }
   603   }
   605   bool Failed() { return mTexture && !mLocked; }
   607 private:
   608   RefPtr<TextureHost> mTexture;
   609   bool mLocked;
   610 };
   612 /**
   613  * This can be used as an offscreen rendering target by the compositor, and
   614  * subsequently can be used as a source by the compositor.
   615  */
   616 class CompositingRenderTarget : public TextureSource
   617 {
   618 public:
   619   CompositingRenderTarget(const gfx::IntPoint& aOrigin)
   620     : mOrigin(aOrigin)
   621   {}
   622   virtual ~CompositingRenderTarget() {}
   624 #ifdef MOZ_DUMP_PAINTING
   625   virtual TemporaryRef<gfx::DataSourceSurface> Dump(Compositor* aCompositor) { return nullptr; }
   626 #endif
   628   const gfx::IntPoint& GetOrigin() { return mOrigin; }
   630 private:
   631   gfx::IntPoint mOrigin;
   632 };
   634 /**
   635  * Creates a TextureHost that can be used with any of the existing backends
   636  * Not all SurfaceDescriptor types are supported
   637  */
   638 TemporaryRef<TextureHost>
   639 CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
   640                                     ISurfaceAllocator* aDeallocator,
   641                                     TextureFlags aFlags);
   643 }
   644 }
   646 #endif

mercurial