michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef GFX_BASICLAYERS_H michael@0: #define GFX_BASICLAYERS_H michael@0: michael@0: #include // for INT32_MAX, int32_t michael@0: #include "Layers.h" // for Layer (ptr only), etc michael@0: #include "gfxTypes.h" michael@0: #include "gfxCachedTempSurface.h" // for gfxCachedTempSurface michael@0: #include "gfxContext.h" // for gfxContext michael@0: #include "mozilla/Attributes.h" // for MOZ_OVERRIDE michael@0: #include "mozilla/WidgetUtils.h" // for ScreenRotation michael@0: #include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc michael@0: #include "nsAString.h" michael@0: #include "nsAutoPtr.h" // for nsRefPtr michael@0: #include "nsCOMPtr.h" // for already_AddRefed michael@0: #include "nsISupportsImpl.h" // for gfxContext::AddRef, etc michael@0: #include "nsRegion.h" // for nsIntRegion michael@0: #include "nscore.h" // for nsAString, etc michael@0: michael@0: class gfxPattern; michael@0: class nsIWidget; michael@0: michael@0: namespace mozilla { michael@0: namespace layers { michael@0: michael@0: class BasicShadowableLayer; michael@0: class ImageFactory; michael@0: class ImageLayer; michael@0: class PaintLayerContext; michael@0: class ReadbackLayer; michael@0: class ReadbackProcessor; michael@0: michael@0: /** michael@0: * This is a cairo/Thebes-only, main-thread-only implementation of layers. michael@0: * michael@0: * In each transaction, the client sets up the layer tree and then during michael@0: * the drawing phase, each ThebesLayer is painted directly into the target michael@0: * context (with appropriate clipping and Push/PopGroups performed michael@0: * between layers). michael@0: */ michael@0: class BasicLayerManager : michael@0: public LayerManager michael@0: { michael@0: public: michael@0: /** michael@0: * Construct a BasicLayerManager which will have no default michael@0: * target context. SetDefaultTarget or BeginTransactionWithTarget michael@0: * must be called for any rendering to happen. ThebesLayers will not michael@0: * be retained. michael@0: */ michael@0: BasicLayerManager(); michael@0: /** michael@0: * Construct a BasicLayerManager which will have no default michael@0: * target context. SetDefaultTarget or BeginTransactionWithTarget michael@0: * must be called for any rendering to happen. ThebesLayers will be michael@0: * retained; that is, we will try to retain the visible contents of michael@0: * ThebesLayers as cairo surfaces. We create ThebesLayer buffers by michael@0: * creating similar surfaces to the default target context, or to michael@0: * aWidget's GetThebesSurface if there is no default target context, or michael@0: * to the passed-in context if there is no widget and no default michael@0: * target context. michael@0: * michael@0: * This does not keep a strong reference to the widget, so the caller michael@0: * must ensure that the widget outlives the layer manager or call michael@0: * ClearWidget before the widget dies. michael@0: */ michael@0: BasicLayerManager(nsIWidget* aWidget); michael@0: virtual ~BasicLayerManager(); michael@0: michael@0: /** michael@0: * Set the default target context that will be used when BeginTransaction michael@0: * is called. This can only be called outside a transaction. michael@0: * michael@0: * aDoubleBuffering can request double-buffering for drawing to the michael@0: * default target. When BUFFERED, the layer manager avoids blitting michael@0: * temporary results to aContext and then overpainting them with final michael@0: * results, by using a temporary buffer when necessary. In BUFFERED michael@0: * mode we always completely overwrite the contents of aContext's michael@0: * destination surface (within the clip region) using OPERATOR_SOURCE. michael@0: */ michael@0: void SetDefaultTarget(gfxContext* aContext); michael@0: virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation); michael@0: gfxContext* GetDefaultTarget() { return mDefaultTarget; } michael@0: michael@0: nsIWidget* GetRetainerWidget() { return mWidget; } michael@0: void ClearRetainerWidget() { mWidget = nullptr; } michael@0: michael@0: virtual bool IsWidgetLayerManager() { return mWidget != nullptr; } michael@0: michael@0: virtual void BeginTransaction(); michael@0: virtual void BeginTransactionWithTarget(gfxContext* aTarget); michael@0: virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT); michael@0: virtual void EndTransaction(DrawThebesLayerCallback aCallback, michael@0: void* aCallbackData, michael@0: EndTransactionFlags aFlags = END_DEFAULT); michael@0: virtual bool AreComponentAlphaLayersEnabled() { return !IsWidgetLayerManager(); } michael@0: michael@0: void AbortTransaction(); michael@0: michael@0: virtual void SetRoot(Layer* aLayer); michael@0: michael@0: virtual already_AddRefed CreateThebesLayer(); michael@0: virtual already_AddRefed CreateContainerLayer(); michael@0: virtual already_AddRefed CreateImageLayer(); michael@0: virtual already_AddRefed CreateCanvasLayer(); michael@0: virtual already_AddRefed CreateColorLayer(); michael@0: virtual already_AddRefed CreateReadbackLayer(); michael@0: virtual ImageFactory *GetImageFactory(); michael@0: michael@0: virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_BASIC; } michael@0: virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Basic"); } michael@0: michael@0: bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; } michael@0: #ifdef DEBUG michael@0: bool InDrawing() { return mPhase == PHASE_DRAWING; } michael@0: bool InForward() { return mPhase == PHASE_FORWARD; } michael@0: #endif michael@0: bool InTransaction() { return mPhase != PHASE_NONE; } michael@0: michael@0: gfxContext* GetTarget() { return mTarget; } michael@0: void SetTarget(gfxContext* aTarget) { mUsingDefaultTarget = false; mTarget = aTarget; } michael@0: bool IsRetained() { return mWidget != nullptr; } michael@0: michael@0: virtual const char* Name() const { return "Basic"; } michael@0: michael@0: // Clear the cached contents of this layer tree. michael@0: virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE; michael@0: michael@0: void SetTransactionIncomplete() { mTransactionIncomplete = true; } michael@0: bool IsTransactionIncomplete() { return mTransactionIncomplete; } michael@0: michael@0: already_AddRefed PushGroupForLayer(gfxContext* aContext, Layer* aLayer, michael@0: const nsIntRegion& aRegion, michael@0: bool* aNeedsClipToVisibleRegion); michael@0: already_AddRefed PushGroupWithCachedSurface(gfxContext *aTarget, michael@0: gfxContentType aContent); michael@0: void PopGroupToSourceWithCachedSurface(gfxContext *aTarget, gfxContext *aPushed); michael@0: michael@0: virtual bool IsCompositingCheap() { return false; } michael@0: virtual int32_t GetMaxTextureSize() const { return INT32_MAX; } michael@0: bool CompositorMightResample() { return mCompositorMightResample; } michael@0: michael@0: protected: michael@0: enum TransactionPhase { michael@0: PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD michael@0: }; michael@0: TransactionPhase mPhase; michael@0: michael@0: // This is the main body of the PaintLayer routine which will if it has michael@0: // children, recurse into PaintLayer() otherwise it will paint using the michael@0: // underlying Paint() method of the Layer. It will not do both. michael@0: void PaintSelfOrChildren(PaintLayerContext& aPaintContext, gfxContext* aGroupTarget); michael@0: michael@0: // Paint the group onto the underlying target. This is used by PaintLayer to michael@0: // flush the group to the underlying target. michael@0: void FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipToVisibleRegion); michael@0: michael@0: // Paints aLayer to mTarget. michael@0: void PaintLayer(gfxContext* aTarget, michael@0: Layer* aLayer, michael@0: DrawThebesLayerCallback aCallback, michael@0: void* aCallbackData, michael@0: ReadbackProcessor* aReadback); michael@0: michael@0: // Clear the contents of a layer michael@0: void ClearLayer(Layer* aLayer); michael@0: michael@0: bool EndTransactionInternal(DrawThebesLayerCallback aCallback, michael@0: void* aCallbackData, michael@0: EndTransactionFlags aFlags = END_DEFAULT); michael@0: michael@0: void FlashWidgetUpdateArea(gfxContext* aContext); michael@0: michael@0: void RenderDebugOverlay(); michael@0: michael@0: // Widget whose surface should be used as the basis for ThebesLayer michael@0: // buffers. michael@0: nsIWidget* mWidget; michael@0: // The default context for BeginTransaction. michael@0: nsRefPtr mDefaultTarget; michael@0: // The context to draw into. michael@0: nsRefPtr mTarget; michael@0: // Image factory we use. michael@0: nsRefPtr mFactory; michael@0: michael@0: // Cached surface for double buffering michael@0: gfxCachedTempSurface mCachedSurface; michael@0: michael@0: BufferMode mDoubleBuffering; michael@0: bool mUsingDefaultTarget; michael@0: bool mCachedSurfaceInUse; michael@0: bool mTransactionIncomplete; michael@0: bool mCompositorMightResample; michael@0: }; michael@0: michael@0: } michael@0: } michael@0: michael@0: #endif /* GFX_BASICLAYERS_H */