gfx/layers/composite/CompositableHost.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/layers/composite/CompositableHost.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,381 @@
     1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef MOZILLA_GFX_BUFFERHOST_H
    1.10 +#define MOZILLA_GFX_BUFFERHOST_H
    1.11 +
    1.12 +#include <stdint.h>                     // for uint64_t
    1.13 +#include <stdio.h>                      // for FILE
    1.14 +#include "gfxRect.h"                    // for gfxRect
    1.15 +#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    1.16 +#include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
    1.17 +#include "mozilla/RefPtr.h"             // for RefPtr, RefCounted, etc
    1.18 +#include "mozilla/gfx/Point.h"          // for Point
    1.19 +#include "mozilla/gfx/Rect.h"           // for Rect
    1.20 +#include "mozilla/gfx/Types.h"          // for Filter
    1.21 +#include "mozilla/ipc/ProtocolUtils.h"
    1.22 +#include "mozilla/layers/CompositorTypes.h"  // for TextureInfo, etc
    1.23 +#include "mozilla/layers/LayersTypes.h"  // for LayerRenderState, etc
    1.24 +#include "mozilla/layers/PCompositableParent.h"
    1.25 +#include "mozilla/layers/TextureHost.h" // for TextureHost
    1.26 +#include "mozilla/mozalloc.h"           // for operator delete
    1.27 +#include "nsCOMPtr.h"                   // for already_AddRefed
    1.28 +#include "nsRegion.h"                   // for nsIntRegion
    1.29 +#include "nscore.h"                     // for nsACString
    1.30 +#include "Units.h"                      // for CSSToScreenScale
    1.31 +
    1.32 +struct nsIntPoint;
    1.33 +struct nsIntRect;
    1.34 +
    1.35 +namespace mozilla {
    1.36 +namespace gfx {
    1.37 +class Matrix4x4;
    1.38 +class DataSourceSurface;
    1.39 +}
    1.40 +
    1.41 +namespace layers {
    1.42 +
    1.43 +// Some properties of a Layer required for tiling
    1.44 +struct TiledLayerProperties
    1.45 +{
    1.46 +  nsIntRegion mVisibleRegion;
    1.47 +  nsIntRegion mValidRegion;
    1.48 +  CSSToScreenScale mEffectiveResolution;
    1.49 +};
    1.50 +
    1.51 +class Layer;
    1.52 +class SurfaceDescriptor;
    1.53 +class Compositor;
    1.54 +class ISurfaceAllocator;
    1.55 +class ThebesBufferData;
    1.56 +class TiledLayerComposer;
    1.57 +class CompositableParentManager;
    1.58 +struct EffectChain;
    1.59 +
    1.60 +/**
    1.61 + * A base class for doing CompositableHost and platform dependent task on TextureHost.
    1.62 + */
    1.63 +class CompositableBackendSpecificData
    1.64 +{
    1.65 +protected:
    1.66 +  virtual ~CompositableBackendSpecificData() { }
    1.67 +
    1.68 +public:
    1.69 +  NS_INLINE_DECL_REFCOUNTING(CompositableBackendSpecificData)
    1.70 +
    1.71 +  CompositableBackendSpecificData()
    1.72 +  {
    1.73 +  }
    1.74 +
    1.75 +  virtual void SetCompositor(Compositor* aCompositor) {}
    1.76 +  virtual void ClearData()
    1.77 +  {
    1.78 +    mCurrentReleaseFenceTexture = nullptr;
    1.79 +    ClearPendingReleaseFenceTextureList();
    1.80 +  }
    1.81 +
    1.82 +  /**
    1.83 +   * Store a texture currently used for Composition.
    1.84 +   * This function is called when the texutre might receive ReleaseFence
    1.85 +   * as a result of Composition.
    1.86 +   */
    1.87 +  void SetCurrentReleaseFenceTexture(TextureHost* aTexture)
    1.88 +  {
    1.89 +    if (mCurrentReleaseFenceTexture) {
    1.90 +      mPendingReleaseFenceTextures.push_back(mCurrentReleaseFenceTexture);
    1.91 +    }
    1.92 +    mCurrentReleaseFenceTexture = aTexture;
    1.93 +  }
    1.94 +
    1.95 +  virtual std::vector< RefPtr<TextureHost> >& GetPendingReleaseFenceTextureList()
    1.96 +  {
    1.97 +    return mPendingReleaseFenceTextures;
    1.98 +  }
    1.99 +
   1.100 +  virtual void ClearPendingReleaseFenceTextureList()
   1.101 +  {
   1.102 +    return mPendingReleaseFenceTextures.clear();
   1.103 +  }
   1.104 +protected:
   1.105 +  /**
   1.106 +   * Store a TextureHost currently used for Composition
   1.107 +   * and it might receive ReleaseFence for the texutre.
   1.108 +   */
   1.109 +  RefPtr<TextureHost> mCurrentReleaseFenceTexture;
   1.110 +  /**
   1.111 +   * Store TextureHosts that might have ReleaseFence to be delivered
   1.112 +   * to TextureClient by CompositableHost.
   1.113 +   */
   1.114 +  std::vector< RefPtr<TextureHost> > mPendingReleaseFenceTextures;
   1.115 +};
   1.116 +
   1.117 +/**
   1.118 + * The compositor-side counterpart to CompositableClient. Responsible for
   1.119 + * updating textures and data about textures from IPC and how textures are
   1.120 + * composited (tiling, double buffering, etc.).
   1.121 + *
   1.122 + * Update (for images/canvases) and UpdateThebes (for Thebes) are called during
   1.123 + * the layers transaction to update the Compositbale's textures from the
   1.124 + * content side. The actual update (and any syncronous upload) is done by the
   1.125 + * TextureHost, but it is coordinated by the CompositableHost.
   1.126 + *
   1.127 + * Composite is called by the owning layer when it is composited. CompositableHost
   1.128 + * will use its TextureHost(s) and call Compositor::DrawQuad to do the actual
   1.129 + * rendering.
   1.130 + */
   1.131 +class CompositableHost
   1.132 +{
   1.133 +protected:
   1.134 +  virtual ~CompositableHost();
   1.135 +
   1.136 +public:
   1.137 +  NS_INLINE_DECL_REFCOUNTING(CompositableHost)
   1.138 +  CompositableHost(const TextureInfo& aTextureInfo);
   1.139 +
   1.140 +  static TemporaryRef<CompositableHost> Create(const TextureInfo& aTextureInfo);
   1.141 +
   1.142 +  virtual CompositableType GetType() = 0;
   1.143 +
   1.144 +  virtual CompositableBackendSpecificData* GetCompositableBackendSpecificData()
   1.145 +  {
   1.146 +    return mBackendData;
   1.147 +  }
   1.148 +
   1.149 +  virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
   1.150 +  {
   1.151 +    mBackendData = aBackendData;
   1.152 +  }
   1.153 +
   1.154 +  // If base class overrides, it should still call the parent implementation
   1.155 +  virtual void SetCompositor(Compositor* aCompositor);
   1.156 +
   1.157 +  // composite the contents of this buffer host to the compositor's surface
   1.158 +  virtual void Composite(EffectChain& aEffectChain,
   1.159 +                         float aOpacity,
   1.160 +                         const gfx::Matrix4x4& aTransform,
   1.161 +                         const gfx::Filter& aFilter,
   1.162 +                         const gfx::Rect& aClipRect,
   1.163 +                         const nsIntRegion* aVisibleRegion = nullptr,
   1.164 +                         TiledLayerProperties* aLayerProperties = nullptr) = 0;
   1.165 +
   1.166 +  /**
   1.167 +   * Update the content host.
   1.168 +   * aUpdated is the region which should be updated
   1.169 +   * aUpdatedRegionBack is the region in aNewBackResult which has been updated
   1.170 +   */
   1.171 +  virtual bool UpdateThebes(const ThebesBufferData& aData,
   1.172 +                            const nsIntRegion& aUpdated,
   1.173 +                            const nsIntRegion& aOldValidRegionBack,
   1.174 +                            nsIntRegion* aUpdatedRegionBack)
   1.175 +  {
   1.176 +    NS_ERROR("should be implemented or not used");
   1.177 +    return false;
   1.178 +  }
   1.179 +
   1.180 +  /**
   1.181 +   * Update the content host using a surface that only contains the updated
   1.182 +   * region.
   1.183 +   *
   1.184 +   * Takes ownership of aSurface, and is responsible for freeing it.
   1.185 +   *
   1.186 +   * @param aTextureId Texture to update.
   1.187 +   * @param aSurface Surface containing the update area. Its contents are relative
   1.188 +   *                 to aUpdated.TopLeft()
   1.189 +   * @param aUpdated Area of the content host to update.
   1.190 +   * @param aBufferRect New area covered by the content host.
   1.191 +   * @param aBufferRotation New buffer rotation.
   1.192 +   */
   1.193 +  virtual void UpdateIncremental(TextureIdentifier aTextureId,
   1.194 +                                 SurfaceDescriptor& aSurface,
   1.195 +                                 const nsIntRegion& aUpdated,
   1.196 +                                 const nsIntRect& aBufferRect,
   1.197 +                                 const nsIntPoint& aBufferRotation)
   1.198 +  {
   1.199 +    MOZ_ASSERT(false, "should be implemented or not used");
   1.200 +  }
   1.201 +
   1.202 +  /**
   1.203 +   * Ensure that a suitable texture host exists in this compsitable.
   1.204 +   *
   1.205 +   * Only used with ContentHostIncremental.
   1.206 +   *
   1.207 +   * No SurfaceDescriptor or TextureIdentifier is provider as we
   1.208 +   * don't have a single surface for the texture contents, and we
   1.209 +   * need to allocate our own one to be updated later.
   1.210 +   */
   1.211 +  virtual bool CreatedIncrementalTexture(ISurfaceAllocator* aAllocator,
   1.212 +                                         const TextureInfo& aTextureInfo,
   1.213 +                                         const nsIntRect& aBufferRect)
   1.214 +  {
   1.215 +    NS_ERROR("should be implemented or not used");
   1.216 +    return false;
   1.217 +  }
   1.218 +
   1.219 +  /**
   1.220 +   * Returns the front buffer.
   1.221 +   */
   1.222 +  virtual TextureHost* GetAsTextureHost() { return nullptr; }
   1.223 +
   1.224 +  virtual LayerRenderState GetRenderState() = 0;
   1.225 +
   1.226 +  virtual void SetPictureRect(const nsIntRect& aPictureRect)
   1.227 +  {
   1.228 +    MOZ_ASSERT(false, "Should have been overridden");
   1.229 +  }
   1.230 +
   1.231 +  /**
   1.232 +   * Adds a mask effect using this texture as the mask, if possible.
   1.233 +   * @return true if the effect was added, false otherwise.
   1.234 +   */
   1.235 +  bool AddMaskEffect(EffectChain& aEffects,
   1.236 +                     const gfx::Matrix4x4& aTransform,
   1.237 +                     bool aIs3D = false);
   1.238 +
   1.239 +  void RemoveMaskEffect();
   1.240 +
   1.241 +  Compositor* GetCompositor() const
   1.242 +  {
   1.243 +    return mCompositor;
   1.244 +  }
   1.245 +
   1.246 +  Layer* GetLayer() const { return mLayer; }
   1.247 +  void SetLayer(Layer* aLayer) { mLayer = aLayer; }
   1.248 +
   1.249 +  virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; }
   1.250 +
   1.251 +  typedef uint32_t AttachFlags;
   1.252 +  static const AttachFlags NO_FLAGS = 0;
   1.253 +  static const AttachFlags ALLOW_REATTACH = 1;
   1.254 +  static const AttachFlags KEEP_ATTACHED = 2;
   1.255 +  static const AttachFlags FORCE_DETACH = 2;
   1.256 +
   1.257 +  virtual void Attach(Layer* aLayer,
   1.258 +                      Compositor* aCompositor,
   1.259 +                      AttachFlags aFlags = NO_FLAGS)
   1.260 +  {
   1.261 +    MOZ_ASSERT(aCompositor, "Compositor is required");
   1.262 +    NS_ASSERTION(aFlags & ALLOW_REATTACH || !mAttached,
   1.263 +                 "Re-attaching compositables must be explicitly authorised");
   1.264 +    SetCompositor(aCompositor);
   1.265 +    SetLayer(aLayer);
   1.266 +    mAttached = true;
   1.267 +    mKeepAttached = aFlags & KEEP_ATTACHED;
   1.268 +  }
   1.269 +  // Detach this compositable host from its layer.
   1.270 +  // If we are used for async video, then it is not safe to blindly detach since
   1.271 +  // we might be re-attached to a different layer. aLayer is the layer which the
   1.272 +  // caller expects us to be attached to, we will only detach if we are in fact
   1.273 +  // attached to that layer. If we are part of a normal layer, then we will be
   1.274 +  // detached in any case. if aLayer is null, then we will only detach if we are
   1.275 +  // not async.
   1.276 +  // Only force detach if the IPDL tree is being shutdown.
   1.277 +  void Detach(Layer* aLayer = nullptr, AttachFlags aFlags = NO_FLAGS)
   1.278 +  {
   1.279 +    if (!mKeepAttached ||
   1.280 +        aLayer == mLayer ||
   1.281 +        aFlags & FORCE_DETACH) {
   1.282 +      SetLayer(nullptr);
   1.283 +      mAttached = false;
   1.284 +      mKeepAttached = false;
   1.285 +      if (mBackendData) {
   1.286 +        mBackendData->ClearData();
   1.287 +      }
   1.288 +    }
   1.289 +  }
   1.290 +  bool IsAttached() { return mAttached; }
   1.291 +
   1.292 +#ifdef MOZ_DUMP_PAINTING
   1.293 +  virtual void Dump(FILE* aFile=nullptr,
   1.294 +                    const char* aPrefix="",
   1.295 +                    bool aDumpHtml=false) { }
   1.296 +  static void DumpTextureHost(FILE* aFile, TextureHost* aTexture);
   1.297 +
   1.298 +  virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() { return nullptr; }
   1.299 +#endif
   1.300 +
   1.301 +  virtual void PrintInfo(nsACString& aTo, const char* aPrefix) { }
   1.302 +
   1.303 +  virtual void UseTextureHost(TextureHost* aTexture);
   1.304 +  virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
   1.305 +                                         TextureHost* aTextureOnWhite);
   1.306 +
   1.307 +  virtual void RemoveTextureHost(TextureHost* aTexture);
   1.308 +
   1.309 +  // Called every time this is composited
   1.310 +  void BumpFlashCounter() {
   1.311 +    mFlashCounter = mFlashCounter >= DIAGNOSTIC_FLASH_COUNTER_MAX
   1.312 +                  ? DIAGNOSTIC_FLASH_COUNTER_MAX : mFlashCounter + 1;
   1.313 +  }
   1.314 +
   1.315 +  static PCompositableParent*
   1.316 +  CreateIPDLActor(CompositableParentManager* mgr,
   1.317 +                  const TextureInfo& textureInfo,
   1.318 +                  uint64_t asyncID);
   1.319 +
   1.320 +  static bool DestroyIPDLActor(PCompositableParent* actor);
   1.321 +
   1.322 +  static CompositableHost* FromIPDLActor(PCompositableParent* actor);
   1.323 +
   1.324 +  uint64_t GetCompositorID() const { return mCompositorID; }
   1.325 +
   1.326 +  uint64_t GetAsyncID() const { return mAsyncID; }
   1.327 +
   1.328 +  void SetCompositorID(uint64_t aID) { mCompositorID = aID; }
   1.329 +
   1.330 +  void SetAsyncID(uint64_t aID) { mAsyncID = aID; }
   1.331 +
   1.332 +protected:
   1.333 +  TextureInfo mTextureInfo;
   1.334 +  uint64_t mAsyncID;
   1.335 +  uint64_t mCompositorID;
   1.336 +  Compositor* mCompositor;
   1.337 +  Layer* mLayer;
   1.338 +  RefPtr<CompositableBackendSpecificData> mBackendData;
   1.339 +  uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true.
   1.340 +  bool mAttached;
   1.341 +  bool mKeepAttached;
   1.342 +};
   1.343 +
   1.344 +/**
   1.345 + * Global CompositableMap, to use in the compositor thread only.
   1.346 + *
   1.347 + * PCompositable and PLayer can, in the case of async textures, be managed by
   1.348 + * different top level protocols. In this case they don't share the same
   1.349 + * communication channel and we can't send an OpAttachCompositable (PCompositable,
   1.350 + * PLayer) message.
   1.351 + *
   1.352 + * In order to attach a layer and the right compositable if the the compositable
   1.353 + * is async, we store references to the async compositables in a CompositableMap
   1.354 + * that is accessed only on the compositor thread. During a layer transaction we
   1.355 + * send the message OpAttachAsyncCompositable(ID, PLayer), and on the compositor
   1.356 + * side we lookup the ID in the map and attach the correspondig compositable to
   1.357 + * the layer.
   1.358 + *
   1.359 + * CompositableMap must be global because the image bridge doesn't have any
   1.360 + * reference to whatever we have created with PLayerTransaction. So, the only way to
   1.361 + * actually connect these two worlds is to have something global that they can
   1.362 + * both query (in the same  thread). The map is not allocated the map on the 
   1.363 + * stack to avoid the badness of static initialization.
   1.364 + *
   1.365 + * Also, we have a compositor/PLayerTransaction protocol/etc. per layer manager, and the
   1.366 + * ImageBridge is used by all the existing compositors that have a video, so
   1.367 + * there isn't an instance or "something" that lives outside the boudaries of a
   1.368 + * given layer manager on the compositor thread except the image bridge and the
   1.369 + * thread itself.
   1.370 + */
   1.371 +namespace CompositableMap {
   1.372 +  void Create();
   1.373 +  void Destroy();
   1.374 +  PCompositableParent* Get(uint64_t aID);
   1.375 +  void Set(uint64_t aID, PCompositableParent* aParent);
   1.376 +  void Erase(uint64_t aID);
   1.377 +  void Clear();
   1.378 +} // CompositableMap
   1.379 +
   1.380 +
   1.381 +} // namespace
   1.382 +} // namespace
   1.383 +
   1.384 +#endif

mercurial