author Matt Woodrow <>
Fri, 16 Nov 2018 15:13:56 +1300
changeset 503771 52a798ad6583b97fb3faf68f1849e7098d9ce4ae
parent 500731 ad0782d7c503f33cfb554d08dedc96287e1ed3f2
child 516186 cab981ef743b8e637d7d1bfcab49df0d4caaf3fb
permissions -rw-r--r--
Bug 1507680 - Record detailed statistics about slow WebRender frames in about:support. r=jrmuizel MozReview-Commit-ID: 84SjN1RvvAA Differential Revision:

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=8 et :
/* 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 */

include LayersSurfaces;
include LayersMessages;
include PlatformWidgetTypes;
include protocol PAPZ;
include protocol PAPZCTreeManager;
include protocol PBrowser;
include protocol PCompositorManager;
include protocol PCompositorWidget;
include protocol PLayerTransaction;
include protocol PTexture;
include protocol PWebRenderBridge;
include "mozilla/GfxMessageUtils.h";
include "mozilla/layers/LayersMessageUtils.h";
include "mozilla/layers/WebRenderMessageUtils.h";

using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
using struct mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
using mozilla::layers::ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
using mozilla::layers::MaybeZoomConstraints from "mozilla/layers/ZoomConstraints.h";
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
using mozilla::CSSIntRegion from "Units.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::LayoutDeviceIntRegion from "Units.h";
using mozilla::LayoutDeviceIntSize from "Units.h";
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
using class mozilla::layers::FrameUniformityData from "mozilla/layers/FrameUniformityData.h";
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::IdNamespace from "mozilla/webrender/WebRenderTypes.h";
using base::ProcessId from "base/process.h";
using mozilla::wr::MaybeExternalImageId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::WebRenderError from "mozilla/webrender/WebRenderTypes.h";
using mozilla::layers::LayersObserverEpoch from "mozilla/layers/LayersTypes.h";
using mozilla::layers::TransactionId from "mozilla/layers/LayersTypes.h";

namespace mozilla {
namespace layers {

struct FrameStats {
  TransactionId id;
  TimeStamp compositeStart;
  TimeStamp renderStart;
  TimeStamp compositeEnd;
  int32_t contentFrameTime;
  double resourceUploadTime;
  double gpuCacheUploadTime;
  TimeStamp transactionStart;
  TimeStamp refreshStart;
  TimeStamp fwdTime;
  TimeStamp sceneBuiltTime;
  uint32_t skippedComposites;
  nsCString url;

 * The PCompositorBridge protocol is a top-level protocol for the compositor.
 * There is an instance of the protocol for each compositor, plus one for each
 * content process. In other words:
 * - There is a CompositorBridgeParent/CompositorBridgeChild pair created
 *   for each "top level browser window", which has its own compositor. The
 *   CompositorBridgeChild instance lives in the UI process, and the
 *   CompositorBridgeParent lives in the GPU process (if there is one) or the
 *   UI process otherwise.
 * - There is also a CrossProcessCompositorBridgeParent/CompositorBridgeChild
 *   pair created for each content process. The CrossProcessCompositorBridgeParent
 *   lives in the GPU process (if there is one) or the UI process otherwise. The
 *   CompositorBridgeChild is a singleton in the content process. Note that
 *   a given content process may have multiple browser instances (represented
 *   by TabChild instances), that are attached to different windows, and therefore
 *   rendered by different compositors. This means that when a browser instance
 *   sends messages via its CompositorBridgeChild, the corresponding
 *   CrossProcessCompositorBridgeParent has to use the layers id in the message
 *   to find the correct compositor or CompositorBridgeParent to pass the message
 *   on to.
 * One of the main goals of this protocol is to manage the PLayerTransaction sub-
 * protocol, which is per-browser. A lot of the functions in the protocol are
 * basically multiplexing/demultiplexing stuff in PLayerTransaction.
sync protocol PCompositorBridge
  manager PCompositorManager;

  manages PAPZ;
  manages PAPZCTreeManager;
  // A Compositor manages a single Layer Manager (PLayerTransaction)
  manages PLayerTransaction;
  manages PTexture;
  manages PCompositorWidget;
  manages PWebRenderBridge;

  // The child should invalidate retained layers. This is used for local
  // compositor device resets, such as in CompositorD3D9, and ensures that
  // TextureSources are recreated.
  async InvalidateLayers(LayersId layersId);

  // The compositor completed a layers transaction. id is the layers id
  // of the child layer tree that was composited (or 0 when notifying
  // the root layer tree).
  // transactionId is the id of the transaction before this composite, or 0
  // if there was no transaction since the last composite.
  async DidComposite(LayersId id, TransactionId transactionId,
                     TimeStamp compositeStart, TimeStamp compositeEnd);

  async NotifyFrameStats(FrameStats[] aFrameStats);

   * Parent informs the child that the graphics objects are ready for
   * compositing.  This usually means that the graphics objects (textures
   * and the like) are available on the GPU.  This is used for chrome UI.
   * @see RequestNotifyAfterRemotePaint
   * @see PBrowser
  async RemotePaintIsReady();

   * Bounce plugin widget configurations over to the main thread for
   * application on the widgets. Used on Windows and Linux in managing
   * plugin widgets.
  async UpdatePluginConfigurations(LayoutDeviceIntPoint aContentOffset,
                                   LayoutDeviceIntRegion aVisibleRegion,
                                   PluginWindowData[] aPlugins);

   * Captures an image for all visible child plugins of a given widget for use
   * during scrolling.
   * @param aParentWidget parent of widgets to be captured
  async CaptureAllPlugins(uintptr_t aParentWidget);

   * Hides all registered plugin widgets associated with a particular chrome
   * widget.
  async HideAllPlugins(uintptr_t aParentWidget);

  async ParentAsyncMessages(AsyncParentMessageData[] aMessages);

  async ObserveLayersUpdate(LayersId aLayersId, LayersObserverEpoch aEpoch, bool aActive);

  async __delete__();

  // Must be called before Initialize().
  async PCompositorWidget(CompositorWidgetInitData aInitData);

  // When out-of-process, this must be called to finish initialization.
  sync Initialize(LayersId rootLayerTreeId);

  // Must be called after Initialize(), and only succeeds if AsyncPanZoomEnabled() is true.
  async PAPZ(LayersId layersId);
  async PAPZCTreeManager(LayersId layersId);

   * Confirmation callback for UpdatePluginConfigurations and HideAllPlugins.
  async RemotePluginsReady();

  // Child requests frame uniformity measurements
  sync GetFrameUniformity() returns (FrameUniformityData data);

  // The child is about to be destroyed, so perform any necessary cleanup.
  sync WillClose();

  // Pause/resume the compositor. These are intended to be used on mobile, when
  // the compositor needs to pause/resume in lockstep with the application.
  sync Pause();
  sync Resume();

  // See bug 1316632 comment #33 for why this has to be sync. Otherwise,
  // there are ordering issues with SendPLayerTransactionConstructor.
  sync NotifyChildCreated(LayersId id)
    returns (CompositorOptions compositorOptions);

  // This version of NotifyChildCreated also performs a layer tree mapping.
  // See bug 1316632 comment #33 for why this has to be sync. Otherwise,
  // there are ordering issues with SendPLayerTransactionConstructor.
  sync MapAndNotifyChildCreated(LayersId id, ProcessId owner)
    returns (CompositorOptions compositorOptions);

  async AdoptChild(LayersId id);

  // Same as NotifyChildCreated, but used when child processes need to
  // reassociate layers. This must be synchronous to ensure that the
  // association happens before PLayerTransactions are sent over the
  // cross-process bridge.
  sync NotifyChildRecreated(LayersId id)
    returns (CompositorOptions compositorOptions);

  // Make a snapshot of the content that would have been drawn to our
  // render target at the time this message is received.  If the size
  // or format of |inSnapshot| doesn't match our render target,
  // results are undefined.
  // NB: this message will result in animations, transforms, effects,
  // and so forth being interpolated.  That's what we want to happen.
  sync MakeSnapshot(SurfaceDescriptor inSnapshot, IntRect dirtyRect);

  // Make sure any pending composites are started immediately and
  // block until they are completed.
  sync FlushRendering();

  // Same as FlushRendering, but asynchronous, since not all platforms require
  // synchronous repaints on resize.
  async FlushRenderingAsync();

  // Make sure any pending composites have been received.
  sync WaitOnTransactionProcessed();

  // Force an additional frame presentation to be executed. This is used to
  // work around a windows presentation bug (See Bug 1232042)
  async ForcePresent();

  sync StartFrameTimeRecording(int32_t bufferSize)
    returns (uint32_t startIndex);

  sync StopFrameTimeRecording(uint32_t startIndex)
    returns (float[] intervals);

  // layersBackendHints is an ordered list of preffered backends where
  // layersBackendHints[0] is the best backend. If any hints are LayersBackend::LAYERS_NONE
  // that hint is ignored.
  async PLayerTransaction(LayersBackend[] layersBackendHints, LayersId id);

  // Notify the compositor that a region of the screen has been invalidated.
  async NotifyRegionInvalidated(nsIntRegion region);

   * The child (content/chrome thread) requests that the parent inform it when
   * the graphics objects are ready to display.
   * @see PBrowser
   * @see RemotePaintIsReady
  async RequestNotifyAfterRemotePaint();

   * Sent when the child has finished CaptureAllPlugins.
  async AllPluginsCaptured();

  async PTexture(SurfaceDescriptor aSharedData, ReadLockDescriptor aReadLock, LayersBackend aBackend, TextureFlags aTextureFlags, LayersId id, uint64_t aSerial, MaybeExternalImageId aExternalImageId);

  sync SyncWithCompositor();

  // The pipelineId is the same as the layersId
  async PWebRenderBridge(PipelineId pipelineId, LayoutDeviceIntSize aSize);

  sync CheckContentOnlyTDR(uint32_t sequenceNum)
    returns (bool isContentOnlyTDR);

  // Send back Compositor Frame Metrics from APZCs so tiled layers can
  // update progressively.
  async SharedCompositorFrameMetrics(Handle metrics, CrossProcessMutexHandle mutex, LayersId aLayersId, uint32_t aAPZCId);
  async ReleaseSharedCompositorFrameMetrics(ViewID aId, uint32_t aAPZCId);
  async NotifyWebRenderError(WebRenderError error);

} // layers
} // mozilla