1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef GFX_BASICLAYERS_H 8 #define GFX_BASICLAYERS_H 9 10 #include <stdint.h> // for INT32_MAX, int32_t 11 #include "Layers.h" // for Layer (ptr only), etc 12 #include "gfxTypes.h" 13 #include "gfxContext.h" // for gfxContext 14 #include "mozilla/Attributes.h" // for override 15 #include "mozilla/WidgetUtils.h" // for ScreenRotation 16 #include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc 17 #include "mozilla/TimeStamp.h" 18 #include "nsAString.h" 19 #include "nsCOMPtr.h" // for already_AddRefed 20 #include "nsISupportsImpl.h" // for gfxContext::AddRef, etc 21 #include "nsRegion.h" // for nsIntRegion 22 #include "nscore.h" // for nsAString, etc 23 24 class nsIWidget; 25 26 namespace mozilla { 27 namespace layers { 28 29 class ImageFactory; 30 class ImageLayer; 31 class PaintLayerContext; 32 class ReadbackLayer; 33 34 /** 35 * This is a cairo/Thebes-only, main-thread-only implementation of layers. 36 * 37 * In each transaction, the client sets up the layer tree and then during 38 * the drawing phase, each PaintedLayer is painted directly into the target 39 * context (with appropriate clipping and Push/PopGroups performed 40 * between layers). 41 */ 42 class BasicLayerManager final : public LayerManager { 43 public: 44 enum BasicLayerManagerType { BLM_WIDGET, BLM_OFFSCREEN, BLM_INACTIVE }; 45 /** 46 * Construct a BasicLayerManager which will have no default 47 * target context. SetDefaultTarget or BeginTransactionWithTarget 48 * must be called for any rendering to happen. PaintedLayers will not 49 * be retained. 50 */ 51 explicit BasicLayerManager(BasicLayerManagerType aType); 52 /** 53 * Construct a BasicLayerManager which will have no default 54 * target context. SetDefaultTarget or BeginTransactionWithTarget 55 * must be called for any rendering to happen. PaintedLayers will be 56 * retained; that is, we will try to retain the visible contents of 57 * PaintedLayers as cairo surfaces. We create PaintedLayer buffers by 58 * creating similar surfaces to the default target context, or to 59 * aWidget's GetThebesSurface if there is no default target context, or 60 * to the passed-in context if there is no widget and no default 61 * target context. 62 * 63 * This does not keep a strong reference to the widget, so the caller 64 * must ensure that the widget outlives the layer manager or call 65 * ClearWidget before the widget dies. 66 */ 67 explicit BasicLayerManager(nsIWidget* aWidget); 68 69 protected: 70 virtual ~BasicLayerManager(); 71 72 public: AsBasicLayerManager()73 BasicLayerManager* AsBasicLayerManager() override { return this; } 74 75 /** 76 * Set the default target context that will be used when BeginTransaction 77 * is called. This can only be called outside a transaction. 78 * 79 * aDoubleBuffering can request double-buffering for drawing to the 80 * default target. When BUFFERED, the layer manager avoids blitting 81 * temporary results to aContext and then overpainting them with final 82 * results, by using a temporary buffer when necessary. In BUFFERED 83 * mode we always completely overwrite the contents of aContext's 84 * destination surface (within the clip region) using OP_SOURCE. 85 */ 86 void SetDefaultTarget(gfxContext* aContext); 87 virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, 88 ScreenRotation aRotation); GetDefaultTarget()89 gfxContext* GetDefaultTarget() { return mDefaultTarget; } 90 GetRetainerWidget()91 nsIWidget* GetRetainerWidget() { return mWidget; } ClearRetainerWidget()92 void ClearRetainerWidget() { mWidget = nullptr; } 93 IsWidgetLayerManager()94 virtual bool IsWidgetLayerManager() override { return mWidget != nullptr; } IsInactiveLayerManager()95 virtual bool IsInactiveLayerManager() override { 96 return mType == BLM_INACTIVE; 97 } 98 99 virtual bool BeginTransaction(const nsCString& aURL = nsCString()) override; 100 virtual bool BeginTransactionWithTarget( 101 gfxContext* aTarget, const nsCString& aURL = nsCString()) override; 102 virtual bool EndEmptyTransaction( 103 EndTransactionFlags aFlags = END_DEFAULT) override; 104 virtual void EndTransaction( 105 DrawPaintedLayerCallback aCallback, void* aCallbackData, 106 EndTransactionFlags aFlags = END_DEFAULT) override; 107 void AbortTransaction(); 108 109 virtual void SetRoot(Layer* aLayer) override; 110 111 virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override; 112 virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override; 113 virtual already_AddRefed<ImageLayer> CreateImageLayer() override; 114 virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override; 115 virtual already_AddRefed<ColorLayer> CreateColorLayer() override; 116 virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() override; 117 virtual ImageFactory* GetImageFactory(); 118 GetBackendType()119 virtual LayersBackend GetBackendType() override { 120 return LayersBackend::LAYERS_BASIC; 121 } GetBackendName(nsAString & name)122 virtual void GetBackendName(nsAString& name) override { 123 name.AssignLiteral("Basic"); 124 } 125 InConstruction()126 bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; } 127 #ifdef DEBUG InDrawing()128 bool InDrawing() { return mPhase == PHASE_DRAWING; } InForward()129 bool InForward() { return mPhase == PHASE_FORWARD; } 130 #endif InTransaction()131 bool InTransaction() { return mPhase != PHASE_NONE; } 132 GetTarget()133 gfxContext* GetTarget() { return mTarget; } SetTarget(gfxContext * aTarget)134 void SetTarget(gfxContext* aTarget) { 135 mUsingDefaultTarget = false; 136 mTarget = aTarget; 137 } IsRetained()138 bool IsRetained() { return mWidget != nullptr; } 139 Name()140 virtual const char* Name() const override { return "Basic"; } 141 142 // Clear the cached contents of this layer tree. 143 virtual void ClearCachedResources(Layer* aSubtree = nullptr) override; 144 SetTransactionIncomplete()145 void SetTransactionIncomplete() { mTransactionIncomplete = true; } IsTransactionIncomplete()146 bool IsTransactionIncomplete() { return mTransactionIncomplete; } 147 148 struct PushedGroup { PushedGroupPushedGroup149 PushedGroup() 150 : mFinalTarget(nullptr), 151 mNeedsClipToVisibleRegion(false), 152 mOperator(gfx::CompositionOp::OP_COUNT), 153 mOpacity(0.0f) {} 154 gfxContext* mFinalTarget; 155 RefPtr<gfxContext> mGroupTarget; 156 nsIntRegion mVisibleRegion; 157 bool mNeedsClipToVisibleRegion; 158 gfx::IntPoint mGroupOffset; 159 gfx::CompositionOp mOperator; 160 gfx::Float mOpacity; 161 RefPtr<gfx::SourceSurface> mMaskSurface; 162 gfx::Matrix mMaskTransform; 163 }; 164 165 // Construct a PushedGroup for a specific layer. 166 // Return false if it has some errors in PushGroupForLayer(). Then, the 167 // "aGroupResult" is unavailable for future using. 168 bool PushGroupForLayer(gfxContext* aContext, Layer* aLayerContext, 169 const nsIntRegion& aRegion, PushedGroup& aGroupResult); 170 171 void PopGroupForLayer(PushedGroup& aGroup); 172 IsCompositingCheap()173 virtual bool IsCompositingCheap() override { return false; } GetMaxTextureSize()174 virtual int32_t GetMaxTextureSize() const override { return INT32_MAX; } CompositorMightResample()175 bool CompositorMightResample() { return mCompositorMightResample; } 176 GetCompositionTime()177 TimeStamp GetCompositionTime() const { return mCompositionTime; } 178 179 protected: 180 enum TransactionPhase { 181 PHASE_NONE, 182 PHASE_CONSTRUCTION, 183 PHASE_DRAWING, 184 PHASE_FORWARD 185 }; 186 TransactionPhase mPhase; 187 188 // This is the main body of the PaintLayer routine which will if it has 189 // children, recurse into PaintLayer() otherwise it will paint using the 190 // underlying Paint() method of the Layer. It will not do both. 191 void PaintSelfOrChildren(PaintLayerContext& aPaintContext, 192 gfxContext* aGroupTarget); 193 194 // Paint the group onto the underlying target. This is used by PaintLayer to 195 // flush the group to the underlying target. 196 void FlushGroup(PaintLayerContext& aPaintContext, 197 bool aNeedsClipToVisibleRegion); 198 199 // Paints aLayer to mTarget. 200 void PaintLayer(gfxContext* aTarget, Layer* aLayer, 201 DrawPaintedLayerCallback aCallback, void* aCallbackData); 202 203 // Clear the contents of a layer 204 void ClearLayer(Layer* aLayer); 205 206 bool EndTransactionInternal(DrawPaintedLayerCallback aCallback, 207 void* aCallbackData, 208 EndTransactionFlags aFlags = END_DEFAULT); 209 210 void FlashWidgetUpdateArea(gfxContext* aContext); 211 SetCompositionTime(TimeStamp aTimeStamp)212 void SetCompositionTime(TimeStamp aTimeStamp) { 213 mCompositionTime = aTimeStamp; 214 } 215 216 // Widget whose surface should be used as the basis for PaintedLayer 217 // buffers. 218 nsIWidget* mWidget; 219 // The default context for BeginTransaction. 220 RefPtr<gfxContext> mDefaultTarget; 221 // The context to draw into. 222 RefPtr<gfxContext> mTarget; 223 // Image factory we use. 224 RefPtr<ImageFactory> mFactory; 225 226 BufferMode mDoubleBuffering; 227 BasicLayerManagerType mType; 228 bool mUsingDefaultTarget; 229 bool mTransactionIncomplete; 230 bool mCompositorMightResample; 231 232 TimeStamp mCompositionTime; 233 }; 234 235 } // namespace layers 236 } // namespace mozilla 237 238 #endif /* GFX_BASICLAYERS_H */ 239