gfx/layers/ipc/CompositorParent.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set sw=4 ts=8 et tw=80 : */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef mozilla_layers_CompositorParent_h
michael@0 8 #define mozilla_layers_CompositorParent_h
michael@0 9
michael@0 10 // Enable this pref to turn on compositor performance warning.
michael@0 11 // This will print warnings if the compositor isn't meeting
michael@0 12 // its responsiveness objectives:
michael@0 13 // 1) Compose a frame within 15ms of receiving a ScheduleCompositeCall
michael@0 14 // 2) Unless a frame was composited within the throttle threshold in
michael@0 15 // which the deadline will be 15ms + throttle threshold
michael@0 16 //#define COMPOSITOR_PERFORMANCE_WARNING
michael@0 17
michael@0 18 #include <stdint.h> // for uint64_t
michael@0 19 #include "Layers.h" // for Layer
michael@0 20 #include "ShadowLayersManager.h" // for ShadowLayersManager
michael@0 21 #include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
michael@0 22 #include "base/platform_thread.h" // for PlatformThreadId
michael@0 23 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
michael@0 24 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE
michael@0 25 #include "mozilla/Monitor.h" // for Monitor
michael@0 26 #include "mozilla/RefPtr.h" // for RefPtr
michael@0 27 #include "mozilla/TimeStamp.h" // for TimeStamp
michael@0 28 #include "mozilla/ipc/ProtocolUtils.h"
michael@0 29 #include "mozilla/layers/GeckoContentController.h"
michael@0 30 #include "mozilla/layers/LayersMessages.h" // for TargetConfig
michael@0 31 #include "mozilla/layers/PCompositorParent.h"
michael@0 32 #include "nsAutoPtr.h" // for nsRefPtr
michael@0 33 #include "nsISupportsImpl.h"
michael@0 34 #include "nsSize.h" // for nsIntSize
michael@0 35
michael@0 36 class CancelableTask;
michael@0 37 class MessageLoop;
michael@0 38 class gfxContext;
michael@0 39 class nsIWidget;
michael@0 40
michael@0 41 namespace mozilla {
michael@0 42 namespace gfx {
michael@0 43 class DrawTarget;
michael@0 44 }
michael@0 45
michael@0 46 namespace layers {
michael@0 47
michael@0 48 class APZCTreeManager;
michael@0 49 class AsyncCompositionManager;
michael@0 50 class Compositor;
michael@0 51 class LayerManagerComposite;
michael@0 52 class LayerTransactionParent;
michael@0 53
michael@0 54 struct ScopedLayerTreeRegistration
michael@0 55 {
michael@0 56 ScopedLayerTreeRegistration(uint64_t aLayersId,
michael@0 57 Layer* aRoot,
michael@0 58 GeckoContentController* aController);
michael@0 59 ~ScopedLayerTreeRegistration();
michael@0 60
michael@0 61 private:
michael@0 62 uint64_t mLayersId;
michael@0 63 };
michael@0 64
michael@0 65 class CompositorParent MOZ_FINAL : public PCompositorParent,
michael@0 66 public ShadowLayersManager
michael@0 67 {
michael@0 68 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
michael@0 69
michael@0 70 public:
michael@0 71 CompositorParent(nsIWidget* aWidget,
michael@0 72 bool aUseExternalSurfaceSize = false,
michael@0 73 int aSurfaceWidth = -1, int aSurfaceHeight = -1);
michael@0 74
michael@0 75 // IToplevelProtocol::CloneToplevel()
michael@0 76 virtual IToplevelProtocol*
michael@0 77 CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
michael@0 78 base::ProcessHandle aPeerProcess,
michael@0 79 mozilla::ipc::ProtocolCloneContext* aCtx) MOZ_OVERRIDE;
michael@0 80
michael@0 81 virtual bool RecvWillStop() MOZ_OVERRIDE;
michael@0 82 virtual bool RecvStop() MOZ_OVERRIDE;
michael@0 83 virtual bool RecvPause() MOZ_OVERRIDE;
michael@0 84 virtual bool RecvResume() MOZ_OVERRIDE;
michael@0 85 virtual bool RecvNotifyChildCreated(const uint64_t& child) MOZ_OVERRIDE;
michael@0 86 virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
michael@0 87 SurfaceDescriptor* aOutSnapshot) MOZ_OVERRIDE;
michael@0 88 virtual bool RecvFlushRendering() MOZ_OVERRIDE;
michael@0 89
michael@0 90 virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) MOZ_OVERRIDE;
michael@0 91 virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) MOZ_OVERRIDE;
michael@0 92 virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) MOZ_OVERRIDE;
michael@0 93
michael@0 94 virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
michael@0 95
michael@0 96 virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
michael@0 97 const TargetConfig& aTargetConfig,
michael@0 98 bool aIsFirstPaint,
michael@0 99 bool aScheduleComposite) MOZ_OVERRIDE;
michael@0 100 virtual void ForceComposite(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
michael@0 101 virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
michael@0 102 const TimeStamp& aTime) MOZ_OVERRIDE;
michael@0 103 virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
michael@0 104 virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE { return mCompositionManager; }
michael@0 105
michael@0 106 /**
michael@0 107 * This forces the is-first-paint flag to true. This is intended to
michael@0 108 * be called by the widget code when it loses its viewport information
michael@0 109 * (or for whatever reason wants to refresh the viewport information).
michael@0 110 * The information refresh happens because the compositor will call
michael@0 111 * SetFirstPaintViewport on the next frame of composition.
michael@0 112 */
michael@0 113 void ForceIsFirstPaint();
michael@0 114 void Destroy();
michael@0 115
michael@0 116 void NotifyChildCreated(uint64_t aChild);
michael@0 117
michael@0 118 void AsyncRender();
michael@0 119
michael@0 120 // Can be called from any thread
michael@0 121 void ScheduleRenderOnCompositorThread();
michael@0 122 void SchedulePauseOnCompositorThread();
michael@0 123 /**
michael@0 124 * Returns true if a surface was obtained and the resume succeeded; false
michael@0 125 * otherwise.
michael@0 126 */
michael@0 127 bool ScheduleResumeOnCompositorThread(int width, int height);
michael@0 128
michael@0 129 virtual void ScheduleComposition();
michael@0 130 void NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint, bool aScheduleComposite);
michael@0 131
michael@0 132 /**
michael@0 133 * Returns the unique layer tree identifier that corresponds to the root
michael@0 134 * tree of this compositor.
michael@0 135 */
michael@0 136 uint64_t RootLayerTreeId();
michael@0 137
michael@0 138 /**
michael@0 139 * Returns a pointer to the compositor corresponding to the given ID.
michael@0 140 */
michael@0 141 static CompositorParent* GetCompositor(uint64_t id);
michael@0 142
michael@0 143 /**
michael@0 144 * Returns the compositor thread's message loop.
michael@0 145 *
michael@0 146 * This message loop is used by CompositorParent and ImageBridgeParent.
michael@0 147 */
michael@0 148 static MessageLoop* CompositorLoop();
michael@0 149
michael@0 150 /**
michael@0 151 * Creates the compositor thread and the global compositor map.
michael@0 152 */
michael@0 153 static void StartUp();
michael@0 154
michael@0 155 /**
michael@0 156 * Destroys the compositor thread and the global compositor map.
michael@0 157 */
michael@0 158 static void ShutDown();
michael@0 159
michael@0 160 /**
michael@0 161 * Allocate an ID that can be used to refer to a layer tree and
michael@0 162 * associated resources that live only on the compositor thread.
michael@0 163 *
michael@0 164 * Must run on the content main thread.
michael@0 165 */
michael@0 166 static uint64_t AllocateLayerTreeId();
michael@0 167 /**
michael@0 168 * Release compositor-thread resources referred to by |aID|.
michael@0 169 *
michael@0 170 * Must run on the content main thread.
michael@0 171 */
michael@0 172 static void DeallocateLayerTreeId(uint64_t aId);
michael@0 173
michael@0 174 /**
michael@0 175 * Set aController as the pan/zoom callback for the subtree referred
michael@0 176 * to by aLayersId.
michael@0 177 *
michael@0 178 * Must run on content main thread.
michael@0 179 */
michael@0 180 static void SetControllerForLayerTree(uint64_t aLayersId,
michael@0 181 GeckoContentController* aController);
michael@0 182
michael@0 183 /**
michael@0 184 * This returns a reference to the APZCTreeManager to which
michael@0 185 * pan/zoom-related events can be sent.
michael@0 186 */
michael@0 187 static APZCTreeManager* GetAPZCTreeManager(uint64_t aLayersId);
michael@0 188
michael@0 189 /**
michael@0 190 * A new child process has been configured to push transactions
michael@0 191 * directly to us. Transport is to its thread context.
michael@0 192 */
michael@0 193 static PCompositorParent*
michael@0 194 Create(Transport* aTransport, ProcessId aOtherProcess);
michael@0 195
michael@0 196 /**
michael@0 197 * Setup external message loop and thread ID for Compositor.
michael@0 198 * Should be used when CompositorParent should work in existing thread/MessageLoop,
michael@0 199 * for example moving Compositor into native toolkit main thread will allow to avoid
michael@0 200 * extra synchronization and call ::Composite() right from toolkit::Paint event
michael@0 201 */
michael@0 202 static void StartUpWithExistingThread(MessageLoop* aMsgLoop,
michael@0 203 PlatformThreadId aThreadID);
michael@0 204
michael@0 205 struct LayerTreeState {
michael@0 206 LayerTreeState();
michael@0 207 nsRefPtr<Layer> mRoot;
michael@0 208 nsRefPtr<GeckoContentController> mController;
michael@0 209 CompositorParent* mParent;
michael@0 210 LayerManagerComposite* mLayerManager;
michael@0 211 // Pointer to the CrossProcessCompositorParent. Used by APZCs to share
michael@0 212 // their FrameMetrics with the corresponding child process that holds
michael@0 213 // the PCompositorChild
michael@0 214 PCompositorParent* mCrossProcessParent;
michael@0 215 TargetConfig mTargetConfig;
michael@0 216 };
michael@0 217
michael@0 218 /**
michael@0 219 * Lookup the indirect shadow tree for |aId| and return it if it
michael@0 220 * exists. Otherwise null is returned. This must only be called on
michael@0 221 * the compositor thread.
michael@0 222 */
michael@0 223 static const LayerTreeState* GetIndirectShadowTree(uint64_t aId);
michael@0 224
michael@0 225 float ComputeRenderIntegrity();
michael@0 226
michael@0 227 /**
michael@0 228 * Returns true if the calling thread is the compositor thread.
michael@0 229 */
michael@0 230 static bool IsInCompositorThread();
michael@0 231
michael@0 232 private:
michael@0 233 // Private destructor, to discourage deletion outside of Release():
michael@0 234 virtual ~CompositorParent();
michael@0 235
michael@0 236 virtual PLayerTransactionParent*
michael@0 237 AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
michael@0 238 const uint64_t& aId,
michael@0 239 TextureFactoryIdentifier* aTextureFactoryIdentifier,
michael@0 240 bool* aSuccess) MOZ_OVERRIDE;
michael@0 241 virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) MOZ_OVERRIDE;
michael@0 242 virtual void ScheduleTask(CancelableTask*, int);
michael@0 243 void Composite();
michael@0 244 void CompositeToTarget(gfx::DrawTarget* aTarget);
michael@0 245 void ForceComposeToTarget(gfx::DrawTarget* aTarget);
michael@0 246
michael@0 247 void SetEGLSurfaceSize(int width, int height);
michael@0 248
michael@0 249 void InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints);
michael@0 250 void PauseComposition();
michael@0 251 void ResumeComposition();
michael@0 252 void ResumeCompositionAndResize(int width, int height);
michael@0 253 void ForceComposition();
michael@0 254 void CancelCurrentCompositeTask();
michael@0 255
michael@0 256 inline static PlatformThreadId CompositorThreadID();
michael@0 257
michael@0 258 /**
michael@0 259 * Creates a global map referencing each compositor by ID.
michael@0 260 *
michael@0 261 * This map is used by the ImageBridge protocol to trigger
michael@0 262 * compositions without having to keep references to the
michael@0 263 * compositor
michael@0 264 */
michael@0 265 static void CreateCompositorMap();
michael@0 266 static void DestroyCompositorMap();
michael@0 267
michael@0 268 /**
michael@0 269 * Creates the compositor thread.
michael@0 270 *
michael@0 271 * All compositors live on the same thread.
michael@0 272 * The thread is not lazily created on first access to avoid dealing with
michael@0 273 * thread safety. Therefore it's best to create and destroy the thread when
michael@0 274 * we know we areb't using it (So creating/destroying along with gfxPlatform
michael@0 275 * looks like a good place).
michael@0 276 */
michael@0 277 static bool CreateThread();
michael@0 278
michael@0 279 /**
michael@0 280 * Destroys the compositor thread.
michael@0 281 *
michael@0 282 * It is safe to call this fucntion more than once, although the second call
michael@0 283 * will have no effect.
michael@0 284 * This function is not thread-safe.
michael@0 285 */
michael@0 286 static void DestroyThread();
michael@0 287
michael@0 288 /**
michael@0 289 * Add a compositor to the global compositor map.
michael@0 290 */
michael@0 291 static void AddCompositor(CompositorParent* compositor, uint64_t* id);
michael@0 292 /**
michael@0 293 * Remove a compositor from the global compositor map.
michael@0 294 */
michael@0 295 static CompositorParent* RemoveCompositor(uint64_t id);
michael@0 296
michael@0 297 /**
michael@0 298 * Return true if current state allows compositing, that is
michael@0 299 * finishing a layers transaction.
michael@0 300 */
michael@0 301 bool CanComposite();
michael@0 302
michael@0 303 void DidComposite();
michael@0 304
michael@0 305 nsRefPtr<LayerManagerComposite> mLayerManager;
michael@0 306 nsRefPtr<Compositor> mCompositor;
michael@0 307 RefPtr<AsyncCompositionManager> mCompositionManager;
michael@0 308 nsIWidget* mWidget;
michael@0 309 CancelableTask *mCurrentCompositeTask;
michael@0 310 TimeStamp mLastCompose;
michael@0 311 TimeStamp mTestTime;
michael@0 312 bool mIsTesting;
michael@0 313 #ifdef COMPOSITOR_PERFORMANCE_WARNING
michael@0 314 TimeStamp mExpectedComposeStartTime;
michael@0 315 #endif
michael@0 316
michael@0 317 bool mPaused;
michael@0 318
michael@0 319 bool mUseExternalSurfaceSize;
michael@0 320 nsIntSize mEGLSurfaceSize;
michael@0 321
michael@0 322 mozilla::Monitor mPauseCompositionMonitor;
michael@0 323 mozilla::Monitor mResumeCompositionMonitor;
michael@0 324
michael@0 325 uint64_t mCompositorID;
michael@0 326 uint64_t mRootLayerTreeID;
michael@0 327
michael@0 328 bool mOverrideComposeReadiness;
michael@0 329 CancelableTask* mForceCompositionTask;
michael@0 330
michael@0 331 nsRefPtr<APZCTreeManager> mApzcTreeManager;
michael@0 332
michael@0 333 bool mWantDidCompositeEvent;
michael@0 334
michael@0 335 DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
michael@0 336 };
michael@0 337
michael@0 338 } // layers
michael@0 339 } // mozilla
michael@0 340
michael@0 341 #endif // mozilla_layers_CompositorParent_h

mercurial