gfx/layers/composite/CompositableHost.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial