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