/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef GFX_LayerManagerComposite_H #define GFX_LayerManagerComposite_H #include // for int32_t, uint32_t #include "GLDefs.h" // for GLenum #include "Layers.h" #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/Attributes.h" // for MOZ_OVERRIDE #include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/gfx/Rect.h" // for Rect #include "mozilla/gfx/Types.h" // for SurfaceFormat #include "mozilla/layers/CompositorTypes.h" #include "mozilla/layers/LayersTypes.h" // for LayersBackend, etc #include "nsAString.h" #include "nsAutoPtr.h" // for nsRefPtr #include "nsCOMPtr.h" // for already_AddRefed #include "nsDebug.h" // for NS_ASSERTION #include "nsISupportsImpl.h" // for Layer::AddRef, etc #include "nsRect.h" // for nsIntRect #include "nsRegion.h" // for nsIntRegion #include "nscore.h" // for nsAString, etc #include "LayerTreeInvalidation.h" class gfxASurface; class gfxContext; struct nsIntPoint; struct nsIntSize; #ifdef XP_WIN #include #endif namespace mozilla { namespace gfx { class DrawTarget; } namespace gl { class GLContext; class TextureImage; } namespace layers { class CanvasLayerComposite; class ColorLayerComposite; class CompositableHost; class Compositor; class ContainerLayerComposite; class EffectChain; class ImageLayer; class ImageLayerComposite; class LayerComposite; class RefLayerComposite; class SurfaceDescriptor; class ThebesLayerComposite; class TiledLayerComposer; class TextRenderer; struct FPSState; class LayerManagerComposite : public LayerManager { public: LayerManagerComposite(Compositor* aCompositor); ~LayerManagerComposite(); virtual void Destroy() MOZ_OVERRIDE; /** * return True if initialization was succesful, false when it was not. */ bool Initialize(); /** * Sets the clipping region for this layer manager. This is important on * windows because using OGL we no longer have GDI's native clipping. Therefor * widget must tell us what part of the screen is being invalidated, * and we should clip to this. * * \param aClippingRegion Region to clip to. Setting an empty region * will disable clipping. */ void SetClippingRegion(const nsIntRegion& aClippingRegion) { mClippingRegion = aClippingRegion; } /** * LayerManager implementation. */ virtual LayerManagerComposite* AsLayerManagerComposite() MOZ_OVERRIDE { return this; } void UpdateRenderBounds(const nsIntRect& aRect); virtual void BeginTransaction() MOZ_OVERRIDE; virtual void BeginTransactionWithTarget(gfxContext* aTarget) MOZ_OVERRIDE { MOZ_CRASH("Use BeginTransactionWithDrawTarget"); } void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget); virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE; virtual void EndTransaction(DrawThebesLayerCallback aCallback, void* aCallbackData, EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE; virtual void SetRoot(Layer* aLayer) MOZ_OVERRIDE { mRoot = aLayer; } // XXX[nrc]: never called, we should move this logic to ClientLayerManager // (bug 946926). virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE; virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE { MOZ_CRASH("Call on compositor, not LayerManagerComposite"); } virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE; virtual already_AddRefed CreateThebesLayer() MOZ_OVERRIDE; virtual already_AddRefed CreateContainerLayer() MOZ_OVERRIDE; virtual already_AddRefed CreateImageLayer() MOZ_OVERRIDE; virtual already_AddRefed CreateColorLayer() MOZ_OVERRIDE; virtual already_AddRefed CreateCanvasLayer() MOZ_OVERRIDE; already_AddRefed CreateThebesLayerComposite(); already_AddRefed CreateContainerLayerComposite(); already_AddRefed CreateImageLayerComposite(); already_AddRefed CreateColorLayerComposite(); already_AddRefed CreateCanvasLayerComposite(); already_AddRefed CreateRefLayerComposite(); virtual LayersBackend GetBackendType() MOZ_OVERRIDE { MOZ_CRASH("Shouldn't be called for composited layer manager"); } virtual void GetBackendName(nsAString& name) MOZ_OVERRIDE { MOZ_CRASH("Shouldn't be called for composited layer manager"); } virtual already_AddRefed CreateOptimalMaskSurface(const gfx::IntSize &aSize) MOZ_OVERRIDE; virtual const char* Name() const MOZ_OVERRIDE { return ""; } enum WorldTransforPolicy { ApplyWorldTransform, DontApplyWorldTransform }; /** * Setup World transform matrix. * Transform will be ignored if it is not PreservesAxisAlignedRectangles * or has non integer scale */ void SetWorldTransform(const gfx::Matrix& aMatrix); gfx::Matrix& GetWorldTransform(void); /** * RAII helper class to add a mask effect with the compositable from aMaskLayer * to the EffectChain aEffect and notify the compositable when we are done. */ class AutoAddMaskEffect { public: AutoAddMaskEffect(Layer* aMaskLayer, EffectChain& aEffect, bool aIs3D = false); ~AutoAddMaskEffect(); private: CompositableHost* mCompositable; }; /** * Creates a DrawTarget which is optimized for inter-operating with this * layermanager. */ virtual TemporaryRef CreateDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat) MOZ_OVERRIDE; /** * Calculates the 'completeness' of the rendering that intersected with the * screen on the last render. This is only useful when progressive tile * drawing is enabled, otherwise this will always return 1.0. * This function's expense scales with the size of the layer tree and the * complexity of individual layers' valid regions. */ float ComputeRenderIntegrity(); /** * returns true if PlatformAllocBuffer will return a buffer that supports * direct texturing */ static bool SupportsDirectTexturing(); static void PlatformSyncBeforeReplyUpdate(); void AddInvalidRegion(const nsIntRegion& aRegion) { mInvalidRegion.Or(mInvalidRegion, aRegion); } Compositor* GetCompositor() const { return mCompositor; } /** * LayerManagerComposite provides sophisticated debug overlays * that can request a next frame. */ bool DebugOverlayWantsNextFrame() { return mDebugOverlayWantsNextFrame; } void SetDebugOverlayWantsNextFrame(bool aVal) { mDebugOverlayWantsNextFrame = aVal; } void NotifyShadowTreeTransaction(); TextRenderer* GetTextRenderer() { return mTextRenderer; } private: /** Region we're clipping our current drawing to. */ nsIntRegion mClippingRegion; nsIntRect mRenderBounds; /** Current root layer. */ LayerComposite* RootLayer() const; /** * Recursive helper method for use by ComputeRenderIntegrity. Subtracts * any incomplete rendering on aLayer from aScreenRegion. Any low-precision * rendering is included in aLowPrecisionScreenRegion. aTransform is the * accumulated transform of intermediate surfaces beneath aLayer. */ static void ComputeRenderIntegrityInternal(Layer* aLayer, nsIntRegion& aScreenRegion, nsIntRegion& aLowPrecisionScreenRegion, const gfx3DMatrix& aTransform); /** * Render the current layer tree to the active target. */ void Render(); /** * Render debug overlays such as the FPS/FrameCounter above the frame. */ void RenderDebugOverlay(const gfx::Rect& aBounds); void WorldTransformRect(nsIntRect& aRect); RefPtr mCompositor; nsAutoPtr mClonedLayerTreeProperties; /** * Context target, nullptr when drawing directly to our swap chain. */ RefPtr mTarget; gfx::Matrix mWorldMatrix; nsIntRegion mInvalidRegion; nsAutoPtr mFPS; bool mInTransaction; bool mIsCompositorReady; bool mDebugOverlayWantsNextFrame; RefPtr mTextRenderer; bool mGeometryChanged; }; /** * Composite layers are for use with OMTC on the compositor thread only. There * must be corresponding Basic layers on the content thread. For composite * layers, the layer manager only maintains the layer tree, all rendering is * done by a Compositor (see Compositor.h). As such, composite layers are * platform-independent and can be used on any platform for which there is a * Compositor implementation. * * The composite layer tree reflects exactly the basic layer tree. To * composite to screen, the layer manager walks the layer tree calling render * methods which in turn call into their CompositableHosts' Composite methods. * These call Compositor::DrawQuad to do the rendering. * * Mostly, layers are updated during the layers transaction. This is done from * CompositableClient to CompositableHost without interacting with the layer. * * A reference to the Compositor is stored in LayerManagerComposite. */ class LayerComposite { public: LayerComposite(LayerManagerComposite* aManager); virtual ~LayerComposite(); virtual LayerComposite* GetFirstChildComposite() { return nullptr; } /* Do NOT call this from the generic LayerComposite destructor. Only from the * concrete class destructor */ virtual void Destroy(); virtual Layer* GetLayer() = 0; virtual void RenderLayer(const nsIntRect& aClipRect) = 0; virtual bool SetCompositableHost(CompositableHost*) { // We must handle this gracefully, see bug 967824 NS_WARNING("called SetCompositableHost for a layer type not accepting a compositable"); return false; } virtual CompositableHost* GetCompositableHost() = 0; virtual void CleanupResources() = 0; virtual TiledLayerComposer* GetTiledLayerComposer() { return nullptr; } virtual void DestroyFrontBuffer() { } /** * The following methods are * * CONSTRUCTION PHASE ONLY * * They are analogous to the Layer interface. */ void SetShadowVisibleRegion(const nsIntRegion& aRegion) { mShadowVisibleRegion = aRegion; } void SetShadowOpacity(float aOpacity) { mShadowOpacity = aOpacity; } void SetShadowClipRect(const nsIntRect* aRect) { mUseShadowClipRect = aRect != nullptr; if (aRect) { mShadowClipRect = *aRect; } } void SetShadowTransform(const gfx::Matrix4x4& aMatrix) { mShadowTransform = aMatrix; } void SetShadowTransformSetByAnimation(bool aSetByAnimation) { mShadowTransformSetByAnimation = aSetByAnimation; } void SetLayerComposited(bool value) { mLayerComposited = value; } void SetClearRect(const nsIntRect& aRect) { mClearRect = aRect; } // These getters can be used anytime. float GetShadowOpacity() { return mShadowOpacity; } const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nullptr; } const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; } const gfx::Matrix4x4& GetShadowTransform() { return mShadowTransform; } bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; } bool HasLayerBeenComposited() { return mLayerComposited; } nsIntRect GetClearRect() { return mClearRect; } protected: gfx::Matrix4x4 mShadowTransform; nsIntRegion mShadowVisibleRegion; nsIntRect mShadowClipRect; LayerManagerComposite* mCompositeManager; RefPtr mCompositor; float mShadowOpacity; bool mUseShadowClipRect; bool mShadowTransformSetByAnimation; bool mDestroyed; bool mLayerComposited; nsIntRect mClearRect; }; } /* layers */ } /* mozilla */ #endif /* GFX_LayerManagerComposite_H */