1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/client/ClientLayerManager.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,299 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; 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 GFX_CLIENTLAYERMANAGER_H 1.10 +#define GFX_CLIENTLAYERMANAGER_H 1.11 + 1.12 +#include <stdint.h> // for int32_t 1.13 +#include "Layers.h" 1.14 +#include "gfxContext.h" // for gfxContext 1.15 +#include "mozilla/Attributes.h" // for MOZ_OVERRIDE 1.16 +#include "mozilla/LinkedList.h" // For LinkedList 1.17 +#include "mozilla/WidgetUtils.h" // for ScreenRotation 1.18 +#include "mozilla/gfx/Rect.h" // for Rect 1.19 +#include "mozilla/layers/CompositorTypes.h" 1.20 +#include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc 1.21 +#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder, etc 1.22 +#include "nsAutoPtr.h" // for nsRefPtr 1.23 +#include "nsCOMPtr.h" // for already_AddRefed 1.24 +#include "nsDebug.h" // for NS_ABORT_IF_FALSE 1.25 +#include "nsISupportsImpl.h" // for Layer::Release, etc 1.26 +#include "nsRect.h" // for nsIntRect 1.27 +#include "nsTArray.h" // for nsTArray 1.28 +#include "nscore.h" // for nsAString 1.29 + 1.30 +class nsIWidget; 1.31 + 1.32 +namespace mozilla { 1.33 +namespace layers { 1.34 + 1.35 +class ClientThebesLayer; 1.36 +class CompositorChild; 1.37 +class ImageLayer; 1.38 +class PLayerChild; 1.39 +class TextureClientPool; 1.40 +class SimpleTextureClientPool; 1.41 + 1.42 +class ClientLayerManager : public LayerManager 1.43 +{ 1.44 + typedef nsTArray<nsRefPtr<Layer> > LayerRefArray; 1.45 + 1.46 +public: 1.47 + ClientLayerManager(nsIWidget* aWidget); 1.48 + virtual ~ClientLayerManager(); 1.49 + 1.50 + virtual ShadowLayerForwarder* AsShadowForwarder() 1.51 + { 1.52 + return mForwarder; 1.53 + } 1.54 + 1.55 + virtual int32_t GetMaxTextureSize() const; 1.56 + 1.57 + virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation); 1.58 + virtual void BeginTransactionWithTarget(gfxContext* aTarget); 1.59 + virtual void BeginTransaction(); 1.60 + virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT); 1.61 + virtual void EndTransaction(DrawThebesLayerCallback aCallback, 1.62 + void* aCallbackData, 1.63 + EndTransactionFlags aFlags = END_DEFAULT); 1.64 + 1.65 + virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_CLIENT; } 1.66 + virtual LayersBackend GetCompositorBackendType() MOZ_OVERRIDE 1.67 + { 1.68 + return AsShadowForwarder()->GetCompositorBackendType(); 1.69 + } 1.70 + virtual void GetBackendName(nsAString& name); 1.71 + virtual const char* Name() const { return "Client"; } 1.72 + 1.73 + virtual void SetRoot(Layer* aLayer); 1.74 + 1.75 + virtual void Mutated(Layer* aLayer); 1.76 + 1.77 + virtual already_AddRefed<ThebesLayer> CreateThebesLayer(); 1.78 + virtual already_AddRefed<ThebesLayer> CreateThebesLayerWithHint(ThebesLayerCreationHint aHint); 1.79 + virtual already_AddRefed<ContainerLayer> CreateContainerLayer(); 1.80 + virtual already_AddRefed<ImageLayer> CreateImageLayer(); 1.81 + virtual already_AddRefed<CanvasLayer> CreateCanvasLayer(); 1.82 + virtual already_AddRefed<ColorLayer> CreateColorLayer(); 1.83 + virtual already_AddRefed<RefLayer> CreateRefLayer(); 1.84 + 1.85 + TextureFactoryIdentifier GetTextureFactoryIdentifier() 1.86 + { 1.87 + return mForwarder->GetTextureFactoryIdentifier(); 1.88 + } 1.89 + 1.90 + virtual void FlushRendering() MOZ_OVERRIDE; 1.91 + void SendInvalidRegion(const nsIntRegion& aRegion); 1.92 + 1.93 + virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize) MOZ_OVERRIDE; 1.94 + 1.95 + virtual void StopFrameTimeRecording(uint32_t aStartIndex, 1.96 + nsTArray<float>& aFrameIntervals) MOZ_OVERRIDE; 1.97 + 1.98 + virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return false; } 1.99 + 1.100 + ShadowableLayer* Hold(Layer* aLayer); 1.101 + 1.102 + bool HasShadowManager() const { return mForwarder->HasShadowManager(); } 1.103 + 1.104 + virtual bool IsCompositingCheap(); 1.105 + virtual bool HasShadowManagerInternal() const { return HasShadowManager(); } 1.106 + 1.107 + virtual void SetIsFirstPaint() MOZ_OVERRIDE; 1.108 + 1.109 + TextureClientPool *GetTexturePool(gfx::SurfaceFormat aFormat); 1.110 + SimpleTextureClientPool *GetSimpleTileTexturePool(gfx::SurfaceFormat aFormat); 1.111 + 1.112 + // Drop cached resources and ask our shadow manager to do the same, 1.113 + // if we have one. 1.114 + virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE; 1.115 + 1.116 + void SetRepeatTransaction() { mRepeatTransaction = true; } 1.117 + bool GetRepeatTransaction() { return mRepeatTransaction; } 1.118 + 1.119 + bool IsRepeatTransaction() { return mIsRepeatTransaction; } 1.120 + 1.121 + void SetTransactionIncomplete() { mTransactionIncomplete = true; } 1.122 + 1.123 + bool HasShadowTarget() { return !!mShadowTarget; } 1.124 + 1.125 + void SetShadowTarget(gfxContext *aTarget) { mShadowTarget = aTarget; } 1.126 + 1.127 + bool CompositorMightResample() { return mCompositorMightResample; } 1.128 + 1.129 + DrawThebesLayerCallback GetThebesLayerCallback() const 1.130 + { return mThebesLayerCallback; } 1.131 + 1.132 + void* GetThebesLayerCallbackData() const 1.133 + { return mThebesLayerCallbackData; } 1.134 + 1.135 + CompositorChild *GetRemoteRenderer(); 1.136 + 1.137 + /** 1.138 + * Called for each iteration of a progressive tile update. Fills 1.139 + * aCompositionBounds and aZoom with the current scale and composition bounds 1.140 + * being used to composite the layers in this manager, to determine what area 1.141 + * intersects with the target composition bounds. 1.142 + * aDrawingCritical will be true if the current drawing operation is using 1.143 + * the critical displayport. 1.144 + * Returns true if the update should continue, or false if it should be 1.145 + * cancelled. 1.146 + * This is only called if gfxPlatform::UseProgressiveTilePainting() returns 1.147 + * true. 1.148 + */ 1.149 + bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, 1.150 + ParentLayerRect& aCompositionBounds, 1.151 + CSSToParentLayerScale& aZoom, 1.152 + bool aDrawingCritical); 1.153 + 1.154 + bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; } 1.155 +#ifdef DEBUG 1.156 + bool InDrawing() { return mPhase == PHASE_DRAWING; } 1.157 + bool InForward() { return mPhase == PHASE_FORWARD; } 1.158 +#endif 1.159 + bool InTransaction() { return mPhase != PHASE_NONE; } 1.160 + 1.161 + void SetNeedsComposite(bool aNeedsComposite) 1.162 + { 1.163 + mNeedsComposite = aNeedsComposite; 1.164 + } 1.165 + bool NeedsComposite() const { return mNeedsComposite; } 1.166 + 1.167 + virtual void Composite() MOZ_OVERRIDE; 1.168 + 1.169 + virtual void DidComposite(); 1.170 + 1.171 +protected: 1.172 + enum TransactionPhase { 1.173 + PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD 1.174 + }; 1.175 + TransactionPhase mPhase; 1.176 + 1.177 +private: 1.178 + /** 1.179 + * Forward transaction results to the parent context. 1.180 + */ 1.181 + void ForwardTransaction(bool aScheduleComposite); 1.182 + 1.183 + /** 1.184 + * Take a snapshot of the parent context, and copy 1.185 + * it into mShadowTarget. 1.186 + */ 1.187 + void MakeSnapshotIfRequired(); 1.188 + 1.189 + void ClearLayer(Layer* aLayer); 1.190 + 1.191 + bool EndTransactionInternal(DrawThebesLayerCallback aCallback, 1.192 + void* aCallbackData, 1.193 + EndTransactionFlags); 1.194 + 1.195 + // The bounds of |mTarget| in device pixels. 1.196 + nsIntRect mTargetBounds; 1.197 + 1.198 + LayerRefArray mKeepAlive; 1.199 + 1.200 + nsIWidget* mWidget; 1.201 + 1.202 + /* Thebes layer callbacks; valid at the end of a transaciton, 1.203 + * while rendering */ 1.204 + DrawThebesLayerCallback mThebesLayerCallback; 1.205 + void *mThebesLayerCallbackData; 1.206 + 1.207 + // When we're doing a transaction in order to draw to a non-default 1.208 + // target, the layers transaction is only performed in order to send 1.209 + // a PLayers:Update. We save the original non-default target to 1.210 + // mShadowTarget, and then perform the transaction using 1.211 + // mDummyTarget as the render target. After the transaction ends, 1.212 + // we send a message to our remote side to capture the actual pixels 1.213 + // being drawn to the default target, and then copy those pixels 1.214 + // back to mShadowTarget. 1.215 + nsRefPtr<gfxContext> mShadowTarget; 1.216 + 1.217 + // Sometimes we draw to targets that don't natively support 1.218 + // landscape/portrait orientation. When we need to implement that 1.219 + // ourselves, |mTargetRotation| describes the induced transform we 1.220 + // need to apply when compositing content to our target. 1.221 + ScreenRotation mTargetRotation; 1.222 + 1.223 + // Used to repeat the transaction right away (to avoid rebuilding 1.224 + // a display list) to support progressive drawing. 1.225 + bool mRepeatTransaction; 1.226 + bool mIsRepeatTransaction; 1.227 + bool mTransactionIncomplete; 1.228 + bool mCompositorMightResample; 1.229 + bool mNeedsComposite; 1.230 + 1.231 + RefPtr<ShadowLayerForwarder> mForwarder; 1.232 + nsAutoTArray<RefPtr<TextureClientPool>,2> mTexturePools; 1.233 + 1.234 + // indexed by gfx::SurfaceFormat 1.235 + nsTArray<RefPtr<SimpleTextureClientPool> > mSimpleTilePools; 1.236 +}; 1.237 + 1.238 +class ClientLayer : public ShadowableLayer 1.239 +{ 1.240 +public: 1.241 + ClientLayer() 1.242 + { 1.243 + MOZ_COUNT_CTOR(ClientLayer); 1.244 + } 1.245 + 1.246 + ~ClientLayer(); 1.247 + 1.248 + void SetShadow(PLayerChild* aShadow) 1.249 + { 1.250 + NS_ABORT_IF_FALSE(!mShadow, "can't have two shadows (yet)"); 1.251 + mShadow = aShadow; 1.252 + } 1.253 + 1.254 + virtual void Disconnect() 1.255 + { 1.256 + // This is an "emergency Disconnect()", called when the compositing 1.257 + // process has died. |mShadow| and our Shmem buffers are 1.258 + // automatically managed by IPDL, so we don't need to explicitly 1.259 + // free them here (it's hard to get that right on emergency 1.260 + // shutdown anyway). 1.261 + mShadow = nullptr; 1.262 + } 1.263 + 1.264 + virtual void ClearCachedResources() { } 1.265 + 1.266 + virtual void RenderLayer() = 0; 1.267 + 1.268 + virtual ClientThebesLayer* AsThebes() { return nullptr; } 1.269 + 1.270 + static inline ClientLayer * 1.271 + ToClientLayer(Layer* aLayer) 1.272 + { 1.273 + return static_cast<ClientLayer*>(aLayer->ImplData()); 1.274 + } 1.275 +}; 1.276 + 1.277 +// Create a shadow layer (PLayerChild) for aLayer, if we're forwarding 1.278 +// our layer tree to a parent process. Record the new layer creation 1.279 +// in the current open transaction as a side effect. 1.280 +template<typename CreatedMethod> void 1.281 +CreateShadowFor(ClientLayer* aLayer, 1.282 + ClientLayerManager* aMgr, 1.283 + CreatedMethod aMethod) 1.284 +{ 1.285 + PLayerChild* shadow = aMgr->AsShadowForwarder()->ConstructShadowFor(aLayer); 1.286 + // XXX error handling 1.287 + NS_ABORT_IF_FALSE(shadow, "failed to create shadow"); 1.288 + 1.289 + aLayer->SetShadow(shadow); 1.290 + (aMgr->AsShadowForwarder()->*aMethod)(aLayer); 1.291 + aMgr->Hold(aLayer->AsLayer()); 1.292 +} 1.293 + 1.294 +#define CREATE_SHADOW(_type) \ 1.295 + CreateShadowFor(layer, this, \ 1.296 + &ShadowLayerForwarder::Created ## _type ## Layer) 1.297 + 1.298 + 1.299 +} 1.300 +} 1.301 + 1.302 +#endif /* GFX_CLIENTLAYERMANAGER_H */