diff -r 000000000000 -r 6474c204b198 gfx/layers/composite/LayerManagerComposite.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/layers/composite/LayerManagerComposite.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,412 @@ +/* -*- 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/2D.h" +#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 "mozilla/RefPtr.h" +#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 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 +{ + typedef mozilla::gfx::DrawTarget DrawTarget; + typedef mozilla::gfx::IntSize IntSize; + typedef mozilla::gfx::SurfaceFormat SurfaceFormat; + +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 TemporaryRef + CreateOptimalMaskDrawTarget(const 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 */