Bug 784004 - Don't include Layers.h everywhere Part 3 r=nical
authorDavid Zbarsky <dzbarsky@gmail.com>
Tue, 21 Aug 2012 00:06:46 -0400
changeset 108356 3000e30d082c63adf8222aa82e47245646806ea6
parent 108355 d2d18014b3333c25e62f69314952f65198a38c3c
child 108357 d8e82fcec23b6be862182fea27bca7a1701c0665
push id1490
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 18:29:50 +0000
treeherdermozilla-beta@f335e7dacdc1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs784004
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 784004 - Don't include Layers.h everywhere Part 3 r=nical
content/canvas/src/WebGLContext.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLVideoElement.cpp
content/media/Makefile.in
content/media/MediaStreamGraph.cpp
content/media/MediaStreamGraph.h
content/media/VideoFrameContainer.cpp
content/media/VideoFrameContainer.h
content/media/VideoSegment.cpp
content/media/VideoSegment.h
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoder.h
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderReader.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/webrtc/MediaEngineDefault.cpp
content/media/webrtc/MediaEngineWebRTC.cpp
content/media/webrtc/MediaEngineWebRTC.h
content/media/webrtc/MediaEngineWebRTCVideo.cpp
dom/camera/CameraPreview.cpp
dom/plugins/ipc/PluginInstanceParent.h
gfx/layers/GonkIOSurfaceImage.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/ReadbackProcessor.cpp
gfx/layers/ReadbackProcessor.h
gfx/layers/basic/BasicLayersImpl.h
gfx/layers/d3d10/ReadbackManagerD3D10.cpp
gfx/layers/d3d9/ThebesLayerD3D9.cpp
gfx/thebes/gfxBlur.h
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/nsDisplayList.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsVideoFrame.cpp
layout/ipc/RenderFrameParent.cpp
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -37,16 +37,18 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 
+#include "Layers.h"
+
 using namespace mozilla;
 using namespace mozilla::gl;
 using namespace mozilla::layers;
 
 NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
 
 NS_IMETHODIMP
 WebGLMemoryPressureObserver::Observe(nsISupports* aSubject,
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -61,16 +61,18 @@
 #include "nsJSUtils.h"
 #include "MediaStreamGraph.h"
 #include "nsDOMMediaStream.h"
 #include "nsIScriptError.h"
 
 #include "nsCSSParser.h"
 #include "nsIMediaList.h"
 
+#include "ImageContainer.h"
+
 #ifdef MOZ_OGG
 #include "nsOggDecoder.h"
 #endif
 #ifdef MOZ_WAVE
 #include "nsWaveDecoder.h"
 #endif
 #ifdef MOZ_WEBM
 #include "nsWebMDecoder.h"
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/nsHTMLVideoElement.cpp
@@ -15,16 +15,17 @@
 #include "nsError.h"
 #include "nsNodeInfoManager.h"
 #include "plbase64.h"
 #include "nsNetUtil.h"
 #include "prmem.h"
 #include "nsXPCOMStrings.h"
 #include "prlock.h"
 #include "nsThreadUtils.h"
+#include "ImageContainer.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
--- a/content/media/Makefile.in
+++ b/content/media/Makefile.in
@@ -44,16 +44,17 @@ CPPSRCS = \
   nsBuiltinDecoder.cpp \
   nsBuiltinDecoderStateMachine.cpp \
   nsBuiltinDecoderReader.cpp \
   nsDOMMediaStream.cpp \
   nsMediaCache.cpp \
   nsMediaDecoder.cpp \
   StreamBuffer.cpp \
   VideoFrameContainer.cpp \
+  VideoSegment.cpp \
   VideoUtils.cpp \
   $(NULL)
 
 ifdef MOZ_SYDNEYAUDIO
 EXPORTS += \
   nsAudioStream.h \
   $(NULL)
 CPPSRCS += \
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -14,16 +14,17 @@
 #include "nsIObserver.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWidgetsCID.h"
 #include "nsXPCOMCIDInternal.h"
 #include "prlog.h"
 #include "VideoUtils.h"
 #include "mozilla/Attributes.h"
 #include "TrackUnionStream.h"
+#include "ImageContainer.h"
 
 using namespace mozilla::layers;
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gMediaStreamGraphLog;
 #define LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -10,16 +10,17 @@
 #include "nsAudioStream.h"
 #include "nsTArray.h"
 #include "nsIRunnable.h"
 #include "nsISupportsImpl.h"
 #include "StreamBuffer.h"
 #include "TimeVarying.h"
 #include "VideoFrameContainer.h"
 #include "VideoSegment.h"
+#include "nsThreadUtils.h"
 
 class nsDOMMediaStream;
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gMediaStreamGraphLog;
 #endif
--- a/content/media/VideoFrameContainer.cpp
+++ b/content/media/VideoFrameContainer.cpp
@@ -5,21 +5,36 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "VideoFrameContainer.h"
 
 #include "nsHTMLMediaElement.h"
 #include "nsIFrame.h"
 #include "nsDisplayList.h"
 #include "nsSVGEffects.h"
+#include "ImageContainer.h"
 
 using namespace mozilla::layers;
 
 namespace mozilla {
 
+VideoFrameContainer::VideoFrameContainer(nsHTMLMediaElement* aElement,
+                                         already_AddRefed<ImageContainer> aContainer)
+  : mElement(aElement),
+    mImageContainer(aContainer), mMutex("nsVideoFrameContainer"),
+    mIntrinsicSizeChanged(false), mImageSizeChanged(false),
+    mNeedInvalidation(true)
+{
+  NS_ASSERTION(aElement, "aElement must not be null");
+  NS_ASSERTION(mImageContainer, "aContainer must not be null");
+}
+
+VideoFrameContainer::~VideoFrameContainer()
+{}
+
 void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize,
                                           Image* aImage,
                                           TimeStamp aTargetTime)
 {
   MutexAutoLock lock(mMutex);
 
   if (aIntrinsicSize != mIntrinsicSize) {
     mIntrinsicSize = aIntrinsicSize;
@@ -35,16 +50,21 @@ void VideoFrameContainer::SetCurrentFram
   gfxIntSize newFrameSize = mImageContainer->GetCurrentSize();
   if (oldFrameSize != newFrameSize) {
     mImageSizeChanged = true;
   }
 
   mPaintTarget = aTargetTime;
 }
 
+ImageContainer* VideoFrameContainer::GetImageContainer() {
+  return mImageContainer;
+}
+
+
 double VideoFrameContainer::GetFrameDelay()
 {
   MutexAutoLock lock(mMutex);
   return mPaintDelay.ToSeconds();
 }
 
 void VideoFrameContainer::Invalidate()
 {
--- a/content/media/VideoFrameContainer.h
+++ b/content/media/VideoFrameContainer.h
@@ -2,26 +2,32 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 #ifndef VIDEOFRAMECONTAINER_H_
 #define VIDEOFRAMECONTAINER_H_
 
-#include "ImageContainer.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "nsISupportsImpl.h"
 #include "gfxPoint.h"
+#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
 
 class nsHTMLMediaElement;
 
 namespace mozilla {
 
+namespace layers {
+class Image;
+class ImageContainer;
+}
+
 /**
  * This object is used in the decoder backend threads and the main thread
  * to manage the "current video frame" state. This state includes timing data
  * and an intrinsic size (see below).
  * This has to be a thread-safe object since it's accessed by resource decoders
  * and other off-main-thread components. So we can't put this state in the media
  * element itself ... well, maybe we could, but it could be risky and/or
  * confusing.
@@ -29,36 +35,29 @@ namespace mozilla {
 class VideoFrameContainer {
 public:
   typedef mozilla::layers::ImageContainer ImageContainer;
   typedef mozilla::layers::Image Image;
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameContainer)
 
   VideoFrameContainer(nsHTMLMediaElement* aElement,
-                      already_AddRefed<ImageContainer> aContainer)
-    : mElement(aElement),
-      mImageContainer(aContainer), mMutex("nsVideoFrameContainer"),
-      mIntrinsicSizeChanged(false), mImageSizeChanged(false),
-      mNeedInvalidation(true)
-  {
-    NS_ASSERTION(aElement, "aElement must not be null");
-    NS_ASSERTION(mImageContainer, "aContainer must not be null");
-  }
+                      already_AddRefed<ImageContainer> aContainer);
+  ~VideoFrameContainer();
 
   // Call on any thread
   void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage,
                        TimeStamp aTargetTime);
   // Time in seconds by which the last painted video frame was late by.
   // E.g. if the last painted frame should have been painted at time t,
   // but was actually painted at t+n, this returns n in seconds. Threadsafe.
   double GetFrameDelay();
   // Call on main thread
   void Invalidate();
-  ImageContainer* GetImageContainer() { return mImageContainer; }
+  ImageContainer* GetImageContainer();
   void ForgetElement() { mElement = nullptr; }
 
 protected:
   // Non-addreffed pointer to the element. The element calls ForgetElement
   // to clear this reference when the element is destroyed.
   nsHTMLMediaElement* mElement;
   nsRefPtr<ImageContainer> mImageContainer;
 
new file mode 100644
--- /dev/null
+++ b/content/media/VideoSegment.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+#include "VideoSegment.h"
+#include "ImageContainer.h"
+
+namespace mozilla {
+
+using namespace layers;
+
+VideoFrame::VideoFrame(already_AddRefed<Image> aImage, const gfxIntSize& aIntrinsicSize)
+  : mImage(aImage), mIntrinsicSize(aIntrinsicSize)
+{}
+
+VideoFrame::VideoFrame()
+  : mIntrinsicSize(0, 0)
+{}
+
+VideoFrame::~VideoFrame()
+{}
+
+void
+VideoFrame::SetNull() {
+  mImage = nullptr;
+  mIntrinsicSize = gfxIntSize(0, 0);
+}
+
+void
+VideoFrame::TakeFrom(VideoFrame* aFrame)
+{
+  mImage = aFrame->mImage.forget();
+  mIntrinsicSize = aFrame->mIntrinsicSize;
+}
+
+VideoChunk::VideoChunk()
+{}
+
+VideoChunk::~VideoChunk()
+{}
+
+void
+VideoSegment::AppendFrame(already_AddRefed<Image> aImage, TrackTicks aDuration,
+                          const gfxIntSize& aIntrinsicSize)
+{
+  VideoChunk* chunk = AppendChunk(aDuration);
+  VideoFrame frame(aImage, aIntrinsicSize);
+  chunk->mFrame.TakeFrom(&frame);
+}
+
+VideoSegment::VideoSegment()
+  : MediaSegmentBase<VideoSegment, VideoChunk>(VIDEO)
+{}
+
+VideoSegment::~VideoSegment()
+{}
+
+}
--- a/content/media/VideoSegment.h
+++ b/content/media/VideoSegment.h
@@ -2,56 +2,61 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_VIDEOSEGMENT_H_
 #define MOZILLA_VIDEOSEGMENT_H_
 
 #include "MediaSegment.h"
+#include "nsCOMPtr.h"
+#include "gfxPoint.h"
+#include "nsAutoPtr.h"
 #include "ImageContainer.h"
 
 namespace mozilla {
 
+namespace layers {
+class Image;
+}
+
 class VideoFrame {
 public:
   typedef mozilla::layers::Image Image;
 
-  VideoFrame(already_AddRefed<Image> aImage, const gfxIntSize& aIntrinsicSize)
-    : mImage(aImage), mIntrinsicSize(aIntrinsicSize) {}
-  VideoFrame() : mIntrinsicSize(0, 0) {}
+  VideoFrame(already_AddRefed<Image> aImage, const gfxIntSize& aIntrinsicSize);
+  VideoFrame();
+  ~VideoFrame();
 
   bool operator==(const VideoFrame& aFrame) const
   {
     return mImage == aFrame.mImage && mIntrinsicSize == aFrame.mIntrinsicSize;
   }
   bool operator!=(const VideoFrame& aFrame) const
   {
     return !operator==(aFrame);
   }
 
   Image* GetImage() const { return mImage; }
   const gfxIntSize& GetIntrinsicSize() const { return mIntrinsicSize; }
-  void SetNull() { mImage = nullptr; mIntrinsicSize = gfxIntSize(0, 0); }
-  void TakeFrom(VideoFrame* aFrame)
-  {
-    mImage = aFrame->mImage.forget();
-    mIntrinsicSize = aFrame->mIntrinsicSize;
-  }
+  void SetNull();
+  void TakeFrom(VideoFrame* aFrame);
 
 protected:
   // mImage can be null to indicate "no video" (aka "empty frame"). It can
   // still have an intrinsic size in this case.
   nsRefPtr<Image> mImage;
   // The desired size to render the video frame at.
   gfxIntSize mIntrinsicSize;
 };
 
 
 struct VideoChunk {
+  VideoChunk();
+  ~VideoChunk();
   void SliceTo(TrackTicks aStart, TrackTicks aEnd)
   {
     NS_ASSERTION(aStart >= 0 && aStart < aEnd && aEnd <= mDuration,
                  "Slice out of bounds");
     mDuration = aEnd - aStart;
   }
   TrackTicks GetDuration() const { return mDuration; }
   bool CanCombineWithFollowing(const VideoChunk& aOther) const
@@ -68,25 +73,21 @@ struct VideoChunk {
   TrackTicks mDuration;
   VideoFrame mFrame;
 };
 
 class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> {
 public:
   typedef mozilla::layers::Image Image;
 
-  VideoSegment() : MediaSegmentBase<VideoSegment, VideoChunk>(VIDEO) {}
+  VideoSegment();
+  ~VideoSegment();
 
   void AppendFrame(already_AddRefed<Image> aImage, TrackTicks aDuration,
-                   const gfxIntSize& aIntrinsicSize)
-  {
-    VideoChunk* chunk = AppendChunk(aDuration);
-    VideoFrame frame(aImage, aIntrinsicSize);
-    chunk->mFrame.TakeFrom(&frame);
-  }
+                   const gfxIntSize& aIntrinsicSize);
   const VideoFrame* GetFrameAt(TrackTicks aOffset, TrackTicks* aStart = nullptr)
   {
     VideoChunk* c = FindChunkContaining(aOffset, aStart);
     if (!c) {
       return nullptr;
     }
     return &c->mFrame;
   }
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -11,16 +11,17 @@
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsTArray.h"
 #include "VideoUtils.h"
 #include "nsBuiltinDecoder.h"
 #include "nsBuiltinDecoderStateMachine.h"
 #include "nsTimeRanges.h"
 #include "nsContentUtils.h"
+#include "ImageContainer.h"
 
 using namespace mozilla;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gBuiltinDecoderLog;
 #define LOG(type, msg) PR_LOG(gBuiltinDecoderLog, type, msg)
 #else
 #define LOG(type, msg)
@@ -1042,8 +1043,51 @@ bool nsBuiltinDecoder::OnStateMachineThr
 void nsBuiltinDecoder::NotifyAudioAvailableListener()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (mDecoderStateMachine) {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mDecoderStateMachine->NotifyAudioAvailableListener();
   }
 }
+
+nsBuiltinDecoder::OutputMediaStream::OutputMediaStream()
+{
+
+}
+
+nsBuiltinDecoder::OutputMediaStream::~OutputMediaStream()
+{
+
+}
+    
+
+void nsBuiltinDecoder::OutputMediaStream::Init(PRInt64 aInitialTime, SourceMediaStream* aStream, bool aFinishWhenEnded)
+{
+  mLastAudioPacketTime = -1;
+  mLastAudioPacketEndTime = -1;
+  mAudioFramesWrittenBaseTime = aInitialTime;
+  mAudioFramesWritten = 0;
+  mNextVideoTime = aInitialTime;
+  mStream = aStream;
+  mStreamInitialized = false;
+  mFinishWhenEnded = aFinishWhenEnded;
+  mHaveSentFinish = false;
+  mHaveSentFinishAudio = false;
+  mHaveSentFinishVideo = false;
+}
+
+nsBuiltinDecoder::OutputMediaStream::OutputMediaStream(const OutputMediaStream& rhs)
+{
+  mLastAudioPacketTime = rhs.mLastAudioPacketTime;
+  mLastAudioPacketEndTime = rhs.mLastAudioPacketEndTime;
+  mAudioFramesWritten = rhs.mAudioFramesWritten;
+  mAudioFramesWrittenBaseTime = rhs.mAudioFramesWrittenBaseTime;
+  mNextVideoTime = rhs.mNextVideoTime;
+  mLastVideoImage = rhs.mLastVideoImage;
+  mStream = rhs.mStream;
+  mLastVideoImageDisplaySize = rhs.mLastVideoImageDisplaySize;
+  mStreamInitialized = rhs.mStreamInitialized;
+  mFinishWhenEnded = rhs.mFinishWhenEnded;
+  mHaveSentFinish = rhs.mHaveSentFinish;
+  mHaveSentFinishAudio = rhs.mHaveSentFinishAudio;
+  mHaveSentFinishVideo = rhs.mHaveSentFinishVideo;
+}
--- a/content/media/nsBuiltinDecoder.h
+++ b/content/media/nsBuiltinDecoder.h
@@ -197,17 +197,17 @@ destroying the nsBuiltinDecoder object.
 #include "mozilla/ReentrantMonitor.h"
 
 namespace mozilla {
 namespace layers {
 class Image;
 } //namespace
 } //namespace
 
-typedef mozilla::layers::Image Image; 
+typedef mozilla::layers::Image Image;
 
 class nsAudioStream;
 
 static inline bool IsCurrentThread(nsIThread* aThread) {
   return NS_GetCurrentThread() == aThread;
 }
 
 // Decoder backends must implement this class to perform the codec
@@ -375,30 +375,22 @@ public:
 
   virtual void Pause();
   virtual void SetVolume(double aVolume);
   virtual void SetAudioCaptured(bool aCaptured);
 
   virtual void AddOutputStream(SourceMediaStream* aStream, bool aFinishWhenEnded);
   // Protected by mReentrantMonitor. All decoder output is copied to these streams.
   struct OutputMediaStream {
-    void Init(PRInt64 aInitialTime, SourceMediaStream* aStream, bool aFinishWhenEnded)
-    {
-      mLastAudioPacketTime = -1;
-      mLastAudioPacketEndTime = -1;
-      mAudioFramesWrittenBaseTime = aInitialTime;
-      mAudioFramesWritten = 0;
-      mNextVideoTime = aInitialTime;
-      mStream = aStream;
-      mStreamInitialized = false;
-      mFinishWhenEnded = aFinishWhenEnded;
-      mHaveSentFinish = false;
-      mHaveSentFinishAudio = false;
-      mHaveSentFinishVideo = false;
-    }
+    OutputMediaStream();
+    ~OutputMediaStream();
+    OutputMediaStream(const OutputMediaStream& rhs);
+
+    void Init(PRInt64 aInitialTime, SourceMediaStream* aStream, bool aFinishWhenEnded);
+    
     PRInt64 mLastAudioPacketTime; // microseconds
     PRInt64 mLastAudioPacketEndTime; // microseconds
     // Count of audio frames written to the stream
     PRInt64 mAudioFramesWritten;
     // Timestamp of the first audio packet whose frames we wrote.
     PRInt64 mAudioFramesWrittenBaseTime; // microseconds
     // mNextVideoTime is the end timestamp for the last packet sent to the stream.
     // Therefore video packets starting at or after this time need to be copied
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -3,16 +3,17 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 #include "nsBuiltinDecoder.h"
 #include "nsBuiltinDecoderReader.h"
 #include "nsBuiltinDecoderStateMachine.h"
 #include "VideoUtils.h"
+#include "ImageContainer.h"
 
 #include "mozilla/mozalloc.h"
 #include "mozilla/StandardInteger.h"
 
 using namespace mozilla;
 using mozilla::layers::ImageContainer;
 using mozilla::layers::PlanarYCbCrImage;
 
@@ -81,16 +82,52 @@ nsVideoInfo::ValidateVideoRegion(const n
     aPicture.width * aPicture.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
     aPicture.width * aPicture.height != 0 &&
     aDisplay.width <= PlanarYCbCrImage::MAX_DIMENSION &&
     aDisplay.height <= PlanarYCbCrImage::MAX_DIMENSION &&
     aDisplay.width * aDisplay.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
     aDisplay.width * aDisplay.height != 0;
 }
 
+VideoData::  VideoData(PRInt64 aOffset, PRInt64 aTime, PRInt64 aEndTime, PRInt64 aTimecode)
+  : mOffset(aOffset),
+    mTime(aTime),
+    mEndTime(aEndTime),
+    mTimecode(aTimecode),
+    mDuplicate(true),
+    mKeyframe(false)
+{
+  MOZ_COUNT_CTOR(VideoData);
+  NS_ASSERTION(aEndTime >= aTime, "Frame must start before it ends.");
+}
+
+VideoData::VideoData(PRInt64 aOffset,
+          PRInt64 aTime,
+          PRInt64 aEndTime,
+          bool aKeyframe,
+          PRInt64 aTimecode,
+          nsIntSize aDisplay)
+  : mDisplay(aDisplay),
+    mOffset(aOffset),
+    mTime(aTime),
+    mEndTime(aEndTime),
+    mTimecode(aTimecode),
+    mDuplicate(false),
+    mKeyframe(aKeyframe)
+{
+  MOZ_COUNT_CTOR(VideoData);
+  NS_ASSERTION(aEndTime >= aTime, "Frame must start before it ends.");
+}
+
+VideoData::~VideoData()
+{
+  MOZ_COUNT_DTOR(VideoData);
+}
+
+
 VideoData* VideoData::Create(nsVideoInfo& aInfo,
                              ImageContainer* aContainer,
                              PRInt64 aOffset,
                              PRInt64 aTime,
                              PRInt64 aEndTime,
                              const YCbCrBuffer& aBuffer,
                              bool aKeyframe,
                              PRInt64 aTimecode,
@@ -176,16 +213,29 @@ VideoData* VideoData::Create(nsVideoInfo
 
   videoImage->CopyData(data,
                        Y.mOffset, Y.mSkip,
                        Cb.mOffset, Cb.mSkip,
                        Cr.mOffset, Cr.mSkip);
   return v.forget();
 }
 
+void* nsBuiltinDecoderReader::VideoQueueMemoryFunctor::operator()(void* anObject) {
+  const VideoData* v = static_cast<const VideoData*>(anObject);
+  if (!v->mImage) {
+    return nullptr;
+  }
+  NS_ASSERTION(v->mImage->GetFormat() == mozilla::ImageFormat::PLANAR_YCBCR,
+               "Wrong format?");
+  mozilla::layers::PlanarYCbCrImage* vi = static_cast<mozilla::layers::PlanarYCbCrImage*>(v->mImage.get());
+
+  mResult += vi->GetDataSize();
+  return nullptr;
+}
+
 nsBuiltinDecoderReader::nsBuiltinDecoderReader(nsBuiltinDecoder* aDecoder)
   : mDecoder(aDecoder)
 {
   MOZ_COUNT_CTOR(nsBuiltinDecoderReader);
 }
 
 nsBuiltinDecoderReader::~nsBuiltinDecoderReader()
 {
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -6,16 +6,17 @@
 #if !defined(nsBuiltinDecoderReader_h_)
 #define nsBuiltinDecoderReader_h_
 
 #include <nsDeque.h>
 #include "nsSize.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "MediaStreamGraph.h"
 #include "SharedBuffer.h"
+#include "ImageLayers.h"
 
 // Stores info relevant to presenting media frames.
 class nsVideoInfo {
 public:
   nsVideoInfo()
     : mAudioRate(44100),
       mAudioChannels(2),
       mDisplay(0,0),
@@ -169,20 +170,17 @@ public:
   static VideoData* CreateDuplicate(PRInt64 aOffset,
                                     PRInt64 aTime,
                                     PRInt64 aEndTime,
                                     PRInt64 aTimecode)
   {
     return new VideoData(aOffset, aTime, aEndTime, aTimecode);
   }
 
-  ~VideoData()
-  {
-    MOZ_COUNT_DTOR(VideoData);
-  }
+  ~VideoData();
 
   PRInt64 GetEnd() { return mEndTime; }
 
   // Dimensions at which to display the video frame. The picture region
   // will be scaled to this size. This is should be the picture region's
   // dimensions scaled with respect to its aspect ratio.
   nsIntSize mDisplay;
 
@@ -203,45 +201,24 @@ public:
   nsRefPtr<Image> mImage;
 
   // When true, denotes that this frame is identical to the frame that
   // came before; it's a duplicate. mBuffer will be empty.
   bool mDuplicate;
   bool mKeyframe;
 
 public:
-  VideoData(PRInt64 aOffset, PRInt64 aTime, PRInt64 aEndTime, PRInt64 aTimecode)
-    : mOffset(aOffset),
-      mTime(aTime),
-      mEndTime(aEndTime),
-      mTimecode(aTimecode),
-      mDuplicate(true),
-      mKeyframe(false)
-  {
-    MOZ_COUNT_CTOR(VideoData);
-    NS_ASSERTION(aEndTime >= aTime, "Frame must start before it ends.");
-  }
+  VideoData(PRInt64 aOffset, PRInt64 aTime, PRInt64 aEndTime, PRInt64 aTimecode);
 
   VideoData(PRInt64 aOffset,
             PRInt64 aTime,
             PRInt64 aEndTime,
             bool aKeyframe,
             PRInt64 aTimecode,
-            nsIntSize aDisplay)
-    : mDisplay(aDisplay),
-      mOffset(aOffset),
-      mTime(aTime),
-      mEndTime(aEndTime),
-      mTimecode(aTimecode),
-      mDuplicate(false),
-      mKeyframe(aKeyframe)
-  {
-    MOZ_COUNT_CTOR(VideoData);
-    NS_ASSERTION(aEndTime >= aTime, "Frame must start before it ends.");
-  }
+            nsIntSize aDisplay);
 
 };
 
 // Thread and type safe wrapper around nsDeque.
 template <class T>
 class MediaQueueDeallocator : public nsDequeFunctor {
   virtual void* operator() (void* anObject) {
     delete static_cast<T*>(anObject);
@@ -452,28 +429,17 @@ public:
 
   // True if we can seek using only buffered ranges. This is backend dependant.
   virtual bool IsSeekableInBufferedRanges() = 0;
 
   class VideoQueueMemoryFunctor : public nsDequeFunctor {
   public:
     VideoQueueMemoryFunctor() : mResult(0) {}
 
-    virtual void* operator()(void* anObject) {
-      const VideoData* v = static_cast<const VideoData*>(anObject);
-      if (!v->mImage) {
-        return nullptr;
-      }
-      NS_ASSERTION(v->mImage->GetFormat() == mozilla::PLANAR_YCBCR,
-                   "Wrong format?");
-      mozilla::layers::PlanarYCbCrImage* vi = static_cast<mozilla::layers::PlanarYCbCrImage*>(v->mImage.get());
-
-      mResult += vi->GetDataSize();
-      return nullptr;
-    }
+    virtual void* operator()(void* anObject);
 
     PRInt64 mResult;
   };
 
   PRInt64 VideoQueueMemoryInUse() {
     VideoQueueMemoryFunctor functor;
     mVideoQueue.LockedForEach(functor);
     return functor.mResult;
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -10,16 +10,17 @@
 #include "nsBuiltinDecoderReader.h"
 #include "nsBuiltinDecoderStateMachine.h"
 #include "mozilla/mozalloc.h"
 #include "VideoUtils.h"
 #include "nsTimeRanges.h"
 #include "nsDeque.h"
 #include "AudioSegment.h"
 #include "VideoSegment.h"
+#include "ImageContainer.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/StandardInteger.h"
 #include "mozilla/Util.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 
--- a/content/media/webrtc/MediaEngineDefault.cpp
+++ b/content/media/webrtc/MediaEngineDefault.cpp
@@ -3,16 +3,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaEngineDefault.h"
 
 #include "nsCOMPtr.h"
 #include "nsDOMFile.h"
 #include "nsILocalFile.h"
 #include "Layers.h"
+#include "ImageContainer.h"
+#include "ImageTypes.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #include "nsISupportsUtils.h"
 #endif
 
 #define WIDTH 320
 #define HEIGHT 240
--- a/content/media/webrtc/MediaEngineWebRTC.cpp
+++ b/content/media/webrtc/MediaEngineWebRTC.cpp
@@ -1,16 +1,38 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 #include "MediaEngineWebRTC.h"
+#include "ImageContainer.h"
 
 namespace mozilla {
 
+MediaEngineWebRTCVideoSource::MediaEngineWebRTCVideoSource(webrtc::VideoEngine* videoEnginePtr,
+                                                           int index, int aFps)
+  : mVideoEngine(videoEnginePtr)
+  , mCapIndex(index)
+  , mWidth(640)
+  , mHeight(480)
+  , mState(kReleased)
+  , mMonitor("WebRTCCamera.Monitor")
+  , mFps(aFps)
+  , mInitDone(false)
+  , mInSnapshotMode(false)
+  , mSnapshotPath(NULL)
+{
+  Init();
+}
+
+MediaEngineWebRTCVideoSource::~MediaEngineWebRTCVideoSource()
+{
+  Shutdown();
+}
+
 void
 MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources)
 {
   webrtc::ViEBase* ptrViEBase;
   webrtc::ViECapture* ptrViECapture;
 
   if (!mVideoEngine) {
     if (!(mVideoEngine = webrtc::VideoEngine::Create())) {
--- a/content/media/webrtc/MediaEngineWebRTC.h
+++ b/content/media/webrtc/MediaEngineWebRTC.h
@@ -61,29 +61,18 @@ class MediaEngineWebRTCVideoSource : pub
                                      public nsRunnable
 {
 public:
   // ViEExternalRenderer.
   virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int);
   virtual int DeliverFrame(unsigned char*, int, uint32_t, int64_t);
 
   MediaEngineWebRTCVideoSource(webrtc::VideoEngine* videoEnginePtr,
-    int index, int aFps = 30)
-    : mVideoEngine(videoEnginePtr)
-    , mCapIndex(index)
-    , mWidth(640)
-    , mHeight(480)
-    , mState(kReleased)
-    , mMonitor("WebRTCCamera.Monitor")
-    , mFps(aFps)
-    , mInitDone(false)
-    , mInSnapshotMode(false)
-    , mSnapshotPath(NULL) { Init(); }
-
-  ~MediaEngineWebRTCVideoSource() { Shutdown(); }
+    int index, int aFps = 30);
+  ~MediaEngineWebRTCVideoSource();
 
   virtual void GetName(nsAString&);
   virtual void GetUUID(nsAString&);
   virtual MediaEngineVideoOptions GetOptions();
   virtual nsresult Allocate();
   virtual nsresult Deallocate();
   virtual nsresult Start(SourceMediaStream*, TrackID);
   virtual nsresult Stop();
--- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp
@@ -1,14 +1,16 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 #include "MediaEngineWebRTC.h"
 #include "Layers.h"
+#include "ImageTypes.h"
+#include "ImageContainer.h"
 
 namespace mozilla {
 
 /**
  * Webrtc video source.
  */
 NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineWebRTCVideoSource, nsIRunnable)
 
--- a/dom/camera/CameraPreview.cpp
+++ b/dom/camera/CameraPreview.cpp
@@ -1,14 +1,15 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 #include "CameraPreview.h"
 #include "Layers.h"
+#include "ImageContainer.h"
 #define DOM_CAMERA_LOG_LEVEL  3
 #include "CameraCommon.h"
 
 using namespace mozilla;
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(CameraPreview, CameraPreview)
 
 class CameraPreviewListener : public MediaStreamListener
--- a/dom/plugins/ipc/PluginInstanceParent.h
+++ b/dom/plugins/ipc/PluginInstanceParent.h
@@ -22,17 +22,16 @@
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsRect.h"
 #include "gfxASurface.h"
 
 #ifdef MOZ_X11
 class gfxXlibSurface;
 #endif
-#include "mozilla/unused.h"
 #include "nsGUIEvent.h"
 #include "mozilla/unused.h"
 
 namespace mozilla {
 namespace layers {
 class ImageContainer;
 class CompositionNotifySink;
 }
@@ -363,17 +362,17 @@ private:
     // On the plugin side, we use this surface to avoid doing alpha
     // recovery when possible.  This surface is created and owned by
     // the browser, but a "read-only" reference is sent to the plugin.
     //
     // We have explicitly chosen not to provide any guarantees about
     // the consistency of the pixels in |mBackground|.  A plugin may
     // be able to observe partial updates to the background.
     nsRefPtr<gfxASurface>    mBackground;
-    
+
     nsRefPtr<ImageContainer> mImageContainer;
 };
 
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceParent_h
--- a/gfx/layers/GonkIOSurfaceImage.h
+++ b/gfx/layers/GonkIOSurfaceImage.h
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GONKIOSURFACEIMAGE_H
 #define GONKIOSURFACEIMAGE_H
 
 #ifdef MOZ_WIDGET_GONK
 
 #include "mozilla/layers/LayersSurfaces.h"
-#include "ImageLayers.h"
+#include "ImageContainer.h"
 
 #include <ui/GraphicBuffer.h>
 
 namespace mozilla {
 namespace layers {
 
 /**
  * The gralloc buffer maintained by android GraphicBuffer can be
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -22,16 +22,18 @@
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 typedef FrameMetrics::ViewID ViewID;
 const ViewID FrameMetrics::NULL_SCROLL_ID = 0;
 const ViewID FrameMetrics::ROOT_SCROLL_ID = 1;
 const ViewID FrameMetrics::START_SCROLL_ID = 2;
 
+PRUint8 gLayerManagerLayerBuilder;
+
 #ifdef MOZ_LAYERS_HAVE_LOG
 FILE*
 FILEOrDefault(FILE* aFile)
 {
   return aFile ? aFile : stderr;
 }
 #endif // MOZ_LAYERS_HAVE_LOG
 
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -35,17 +35,22 @@
 #else
 struct PRLogModuleInfo;
 #  define MOZ_LAYERS_LOG(_args)
 #endif  // if defined(DEBUG) || defined(PR_LOGGING)
 
 class gfxContext;
 class nsPaintEvent;
 
+extern PRUint8 gLayerManagerLayerBuilder;
+
 namespace mozilla {
+
+class FrameLayerBuilder;
+
 namespace gl {
 class GLContext;
 }
 
 namespace css {
 class ComputedTimingFunction;
 }
 
@@ -77,16 +82,30 @@ class SpecificLayerAttributes;
 /**
  * Base class for userdata objects attached to layers and layer managers.
  */
 class THEBES_API LayerUserData {
 public:
   virtual ~LayerUserData() {}
 };
 
+class LayerManagerLayerBuilder : public LayerUserData {
+public:
+  LayerManagerLayerBuilder(FrameLayerBuilder* aBuilder, bool aDelete = true)
+    : mLayerBuilder(aBuilder)
+    , mDelete(aDelete)
+  {
+    MOZ_COUNT_CTOR(LayerManagerLayerBuilder);
+  }
+  ~LayerManagerLayerBuilder();
+
+  FrameLayerBuilder* mLayerBuilder;
+  bool mDelete;
+};
+
 /*
  * Motivation: For truly smooth animation and video playback, we need to
  * be able to compose frames and render them on a dedicated thread (i.e.
  * off the main thread where DOM manipulation, script execution and layout
  * induce difficult-to-bound latency). This requires Gecko to construct
  * some kind of persistent scene structure (graph or tree) that can be
  * safely transmitted across threads. We have other scenarios (e.g. mobile 
  * browsing) where retaining some rendered data between paints is desired
@@ -181,23 +200,28 @@ public:
   /**
    * Start a new transaction. Nested transactions are not allowed so
    * there must be no transaction currently in progress. 
    * This transaction will render the contents of the layer tree to
    * the given target context. The rendering will be complete when
    * EndTransaction returns.
    */
   virtual void BeginTransactionWithTarget(gfxContext* aTarget) = 0;
-  
+
   enum EndTransactionFlags {
     END_DEFAULT = 0,
     END_NO_IMMEDIATE_REDRAW = 1 << 0,  // Do not perform the drawing phase
     END_NO_COMPOSITE = 1 << 1 // Do not composite after drawing thebes layer contents.
   };
 
+  FrameLayerBuilder* GetLayerBuilder() {
+    LayerManagerLayerBuilder *data = static_cast<LayerManagerLayerBuilder*>(GetUserData(&gLayerManagerLayerBuilder));
+    return data ? data->mLayerBuilder : nullptr;
+  }
+
   /**
    * Attempts to end an "empty transaction". There must have been no
    * changes to the layer tree since the BeginTransaction().
    * It's possible for this to fail; ThebesLayers may need to be updated
    * due to VRAM data being lost, for example. In such cases this method
    * returns false, and the caller must proceed with a normal layer tree
    * update and EndTransaction.
    */
--- a/gfx/layers/ReadbackProcessor.cpp
+++ b/gfx/layers/ReadbackProcessor.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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 http://mozilla.org/MPL/2.0/. */
 
 #include "ReadbackProcessor.h"
+#include "ReadbackLayer.h"
 
 namespace mozilla {
 namespace layers {
 
 void
 ReadbackProcessor::BuildUpdates(ContainerLayer* aContainer)
 {
   NS_ASSERTION(mAllUpdates.IsEmpty(), "Some updates not processed?");
--- a/gfx/layers/ReadbackProcessor.h
+++ b/gfx/layers/ReadbackProcessor.h
@@ -1,23 +1,25 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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 http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_READBACKPROCESSOR_H
 #define GFX_READBACKPROCESSOR_H
 
-#include "ReadbackLayer.h"
 #include "ThebesLayerBuffer.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 namespace layers {
 
+class ContainerLayer;
+class ReadbackLayer;
+
 class ReadbackProcessor {
 public:
   /**
    * Called by the container before processing any child layers. Call this
    * if any child layer might have changed in any way (other than content-only
    * changes to layers other than ColorLayers and ThebesLayers).
    *
    * This method recomputes the relationship between ReadbackLayers and
--- a/gfx/layers/basic/BasicLayersImpl.h
+++ b/gfx/layers/basic/BasicLayersImpl.h
@@ -5,16 +5,17 @@
 
 #ifndef GFX_BASICLAYERSIMPL_H
 #define GFX_BASICLAYERSIMPL_H
 
 #include "ipc/AutoOpenSurface.h"
 #include "ipc/ShadowLayerChild.h"
 #include "BasicLayers.h"
 #include "BasicImplData.h"
+#include "ReadbackLayer.h"
 #include "ReadbackProcessor.h"
 
 namespace mozilla {
 namespace layers {
 
 class BasicContainerLayer;
 class ShadowableLayer;
 
--- a/gfx/layers/d3d10/ReadbackManagerD3D10.cpp
+++ b/gfx/layers/d3d10/ReadbackManagerD3D10.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 http://mozilla.org/MPL/2.0/. */
 
 #include "ReadbackManagerD3D10.h"
 #include "ReadbackProcessor.h"
+#include "ReadbackLayer.h"
 
 #include "nsIThread.h"
 #include "nsThreadUtils.h"
 #include "gfxImageSurface.h"
 
 namespace mozilla {
 namespace layers {
 
--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
@@ -14,16 +14,17 @@
 
 #include "ThebesLayerD3D9.h"
 #include "gfxPlatform.h"
 
 #include "gfxWindowsPlatform.h"
 #include "gfxTeeSurface.h"
 #include "gfxUtils.h"
 #include "ReadbackProcessor.h"
+#include "ReadbackLayer.h"
 
 namespace mozilla {
 namespace layers {
 
 ThebesLayerD3D9::ThebesLayerD3D9(LayerManagerD3D9 *aManager)
   : ThebesLayer(aManager, NULL)
   , LayerD3D9(aManager)
 {
--- a/gfx/thebes/gfxBlur.h
+++ b/gfx/thebes/gfxBlur.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_BLUR_H
 #define GFX_BLUR_H
 
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "gfxTypes.h"
-#include "gfxUtils.h"
 
 namespace mozilla {
   namespace gfx {
     class AlphaBoxBlur;
   }
 }
 
 /**
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -27,16 +27,26 @@
 #ifdef DEBUG
 #include <stdio.h>
 #endif
 
 using namespace mozilla::layers;
 
 namespace mozilla {
 
+FrameLayerBuilder::DisplayItemData::DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState, PRUint32 aGeneration)
+  : mLayer(aLayer)
+  , mDisplayItemKey(aKey)
+  , mContainerLayerGeneration(aGeneration)
+  , mLayerState(aLayerState)
+{}
+
+FrameLayerBuilder::DisplayItemData::~DisplayItemData()
+{}
+
 /**
  * This is the userdata we associate with a layer manager.
  */
 class LayerManagerData : public LayerUserData {
 public:
   LayerManagerData(LayerManager *aManager) :
     mInvalidateAllLayers(false),
     mLayerManager(aManager)
@@ -583,34 +593,33 @@ MaskLayerUserData* GetMaskLayerUserData(
 ThebesDisplayItemLayerUserData* GetThebesDisplayItemLayerUserData(Layer* aLayer)
 {
   return static_cast<ThebesDisplayItemLayerUserData*>(
     aLayer->GetUserData(&gThebesDisplayItemLayerUserData));
 }
 
 } // anonymous namespace
 
-PRUint8 gLayerManagerLayerBuilder;
-
 /* static */ void
 FrameLayerBuilder::Shutdown()
 {
   if (gMaskLayerImageCache) {
     delete gMaskLayerImageCache;
     gMaskLayerImageCache = nullptr;
   }
 }
 
 void
-FrameLayerBuilder::Init(nsDisplayListBuilder* aBuilder)
+FrameLayerBuilder::Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager)
 {
   mRootPresContext = aBuilder->ReferenceFrame()->PresContext()->GetRootPresContext();
   if (mRootPresContext) {
     mInitialDOMGeneration = mRootPresContext->GetDOMGeneration();
   }
+  aManager->SetUserData(&gLayerManagerLayerBuilder, new LayerManagerLayerBuilder(this));
 }
 
 bool
 FrameLayerBuilder::DisplayItemDataEntry::HasNonEmptyContainerLayer()
 {
   if (mIsSharingContainerLayer)
     return true;
   for (PRUint32 i = 0; i < mData.Length(); ++i) {
@@ -2327,17 +2336,17 @@ FrameLayerBuilder::BuildContainerLayerFo
   nsIntRect pixBounds;
   PRInt32 appUnitsPerDevPixel;
   PRUint32 stateFlags =
     (aContainerFrame->GetStateBits() & NS_FRAME_NO_COMPONENT_ALPHA) ?
       ContainerState::NO_COMPONENT_ALPHA : 0;
   PRUint32 flags;
   bool flattenedLayers = false;
   while (true) {
-    ContainerState state(aBuilder, aManager, GetLayerBuilderForManager(aManager),
+    ContainerState state(aBuilder, aManager, aManager->GetLayerBuilder(),
                          aContainerFrame, containerLayer, scaleParameters);
     if (flattenedLayers) {
       state.SetInvalidateAllThebesContent();
     }
 
     if (aManager == mRetainingManager) {
       // If the container frame has a transform and it's contained in the
       // container item's sub-tree, we need to transform the invalid region
@@ -2674,17 +2683,17 @@ FrameLayerBuilder::DrawThebesLayer(Thebe
                                    const nsIntRegion& aRegionToInvalidate,
                                    void* aCallbackData)
 {
   SAMPLE_LABEL("gfx", "DrawThebesLayer");
 
   nsDisplayListBuilder* builder = static_cast<nsDisplayListBuilder*>
     (aCallbackData);
 
-  FrameLayerBuilder *layerBuilder = GetLayerBuilderForManager(aLayer->Manager());
+  FrameLayerBuilder *layerBuilder = aLayer->Manager()->GetLayerBuilder();
 
   if (layerBuilder->CheckDOMModified())
     return;
 
   nsTArray<ClippedDisplayItem> items;
   PRUint32 commonClipCount;
   nsIFrame* containerLayerFrame;
   {
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -6,27 +6,27 @@
 #ifndef FRAMELAYERBUILDER_H_
 #define FRAMELAYERBUILDER_H_
 
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 #include "nsRegion.h"
 #include "nsIFrame.h"
-#include "Layers.h"
 
 class nsDisplayListBuilder;
 class nsDisplayList;
 class nsDisplayItem;
 class gfxContext;
 class nsRootPresContext;
 
 namespace mozilla {
 namespace layers {
 class ContainerLayer;
+class LayerManager;
 class ThebesLayer;
 }
 
 class FrameLayerBuilder;
 
 enum LayerState {
   LAYER_NONE,
   LAYER_INACTIVE,
@@ -35,45 +35,16 @@ enum LayerState {
   // when the layer has rounded rect clips.
   LAYER_ACTIVE_FORCE,
   // Special layer that is metadata only.
   LAYER_ACTIVE_EMPTY,
   // Inactive style layer for rendering SVG effects.
   LAYER_SVG_EFFECTS
 };
 
-class LayerManagerLayerBuilder : public layers::LayerUserData {
-public:
-  LayerManagerLayerBuilder(FrameLayerBuilder* aBuilder, bool aDelete = true)
-    : mLayerBuilder(aBuilder)
-    , mDelete(aDelete)
-  {
-    MOZ_COUNT_CTOR(LayerManagerLayerBuilder);
-  }
-  ~LayerManagerLayerBuilder();
-
-  FrameLayerBuilder* mLayerBuilder;
-  bool mDelete;
-};
-
-extern PRUint8 gLayerManagerLayerBuilder;
-
-class ContainerLayerPresContext : public layers::LayerUserData {
-public:
-  nsPresContext* mPresContext;
-};
-
-extern PRUint8 gContainerLayerPresContext;
-
-static inline FrameLayerBuilder *GetLayerBuilderForManager(layers::LayerManager* aManager)
-{
-  LayerManagerLayerBuilder *data = static_cast<LayerManagerLayerBuilder*>(aManager->GetUserData(&gLayerManagerLayerBuilder));
-  return data ? data->mLayerBuilder : nullptr;
-}
-
 class RefCountedRegion : public RefCounted<RefCountedRegion> {
 public:
   nsRegion mRegion;
 };
 
 /**
  * The FrameLayerBuilder belongs to an nsDisplayListBuilder and is
  * responsible for converting display lists into layer trees.
@@ -110,18 +81,18 @@ public:
  * from the container's transform down to the children. For ThebesLayer
  * children, the scaling can be achieved by changing the size of the layer
  * and drawing into it with increased or decreased resolution. By convention,
  * integer types (nsIntPoint/nsIntSize/nsIntRect/nsIntRegion) are all in layer
  * coordinates, post-scaling, whereas appunit types are all pre-scaling.
  */
 class FrameLayerBuilder {
 public:
-  typedef layers::ContainerLayer ContainerLayer; 
-  typedef layers::Layer Layer; 
+  typedef layers::ContainerLayer ContainerLayer;
+  typedef layers::Layer Layer;
   typedef layers::ThebesLayer ThebesLayer;
   typedef layers::LayerManager LayerManager;
 
   FrameLayerBuilder() :
     mRetainingManager(nullptr),
     mDetectedDOMModification(false),
     mInvalidateAllLayers(false),
     mContainerLayerGeneration(0),
@@ -133,17 +104,17 @@ public:
   }
   ~FrameLayerBuilder()
   {
     MOZ_COUNT_DTOR(FrameLayerBuilder);
   }
 
   static void Shutdown();
 
-  void Init(nsDisplayListBuilder* aBuilder);
+  void Init(nsDisplayListBuilder* aBuilder, LayerManager* aManager);
 
   /**
    * Call this to notify that we have just started a transaction on the
    * retained layer manager aManager.
    */
   void DidBeginRetainedLayerTransaction(LayerManager* aManager);
 
   /**
@@ -469,22 +440,18 @@ public:
 protected:
   /**
    * We store an array of these for each frame that is associated with
    * one or more retained layers. Each DisplayItemData records the layer
    * used to render one of the frame's display items.
    */
   class DisplayItemData {
   public:
-    DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState, PRUint32 aGeneration)
-      : mLayer(aLayer)
-      , mDisplayItemKey(aKey)
-      , mContainerLayerGeneration(aGeneration)
-      , mLayerState(aLayerState)
-    {}
+    DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState, PRUint32 aGeneration);
+    ~DisplayItemData();
 
     nsRefPtr<Layer> mLayer;
     PRUint32        mDisplayItemKey;
     PRUint32        mContainerLayerGeneration;
     LayerState      mLayerState;
   };
 
   static void RemoveFrameFromLayerManager(nsIFrame* aFrame, void* aPropertyValue);
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -979,18 +979,17 @@ void nsDisplayList::PaintForFrame(nsDisp
     if (!aCtx) {
       NS_WARNING("Nowhere to paint into");
       return;
     }
     layerManager = new BasicLayerManager();
   }
 
   FrameLayerBuilder *layerBuilder = new FrameLayerBuilder();
-  layerBuilder->Init(aBuilder);
-  layerManager->SetUserData(&gLayerManagerLayerBuilder, new LayerManagerLayerBuilder(layerBuilder));
+  layerBuilder->Init(aBuilder, layerManager);
 
   if (aFlags & PAINT_FLUSH_LAYERS) {
     FrameLayerBuilder::InvalidateAllLayers(layerManager);
   }
 
   if (doBeginTransaction) {
     if (aCtx) {
       layerManager->BeginTransactionWithTarget(aCtx->ThebesContext());
@@ -2374,17 +2373,17 @@ nsRegion nsDisplayOpacity::GetOpaqueRegi
   return nsRegion();
 }
 
 // nsDisplayOpacity uses layers for rendering
 already_AddRefed<Layer>
 nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
                              LayerManager* aManager,
                              const ContainerParameters& aContainerParameters) {
-  nsRefPtr<Layer> container = GetLayerBuilderForManager(aManager)->
+  nsRefPtr<Layer> container = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
                            aContainerParameters, nullptr);
   if (!container)
     return nullptr;
 
   container->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
   AddAnimationsAndTransitionsToLayer(container, aBuilder,
                                      this, eCSSProperty_opacity);
@@ -2469,17 +2468,17 @@ nsDisplayOwnLayer::~nsDisplayOwnLayer() 
 }
 #endif
 
 // nsDisplayOpacity uses layers for rendering
 already_AddRefed<Layer>
 nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
                               LayerManager* aManager,
                               const ContainerParameters& aContainerParameters) {
-  nsRefPtr<Layer> layer = GetLayerBuilderForManager(aManager)->
+  nsRefPtr<Layer> layer = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
                            aContainerParameters, nullptr);
   return layer.forget();
 }
 
 nsDisplayFixedPosition::nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
                                                nsIFrame* aFrame,
                                                nsIFrame* aFixedPosFrame,
@@ -2611,17 +2610,17 @@ nsDisplayScrollLayer::~nsDisplayScrollLa
   MOZ_COUNT_DTOR(nsDisplayScrollLayer);
 }
 #endif
 
 already_AddRefed<Layer>
 nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
                                  LayerManager* aManager,
                                  const ContainerParameters& aContainerParameters) {
-  nsRefPtr<ContainerLayer> layer = GetLayerBuilderForManager(aManager)->
+  nsRefPtr<ContainerLayer> layer = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
                            aContainerParameters, nullptr);
 
   // Get the already set unique ID for scrolling this content remotely.
   // Or, if not set, generate a new ID.
   nsIContent* content = mScrolledFrame->GetContent();
   ViewID scrollId = nsLayoutUtils::FindIDFor(content);
 
@@ -3395,17 +3394,17 @@ already_AddRefed<Layer> nsDisplayTransfo
 {
   const gfx3DMatrix& newTransformMatrix =
     GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel());
 
   if (!IsFrameVisible(mFrame, newTransformMatrix)) {
     return nullptr;
   }
 
-  nsRefPtr<ContainerLayer> container = GetLayerBuilderForManager(aManager)->
+  nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, *mStoredList.GetList(),
                            aContainerParameters, &newTransformMatrix);
 
   // Add the preserve-3d flag for this layer, BuildContainerLayerFor clears all flags,
   // so we never need to explicitely unset this flag.
   if (mFrame->Preserves3D() || mFrame->Preserves3DChildren()) {
     container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_PRESERVE_3D);
   }
@@ -3833,17 +3832,17 @@ nsDisplaySVGEffects::BuildLayer(nsDispla
   effectProperties.GetClipPathFrame(&isOK);
   effectProperties.GetMaskFrame(&isOK);
   effectProperties.GetFilterFrame(&isOK);
 
   if (!isOK) {
     return nullptr;
   }
 
-  nsRefPtr<ContainerLayer> container = GetLayerBuilderForManager(aManager)->
+  nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
                            aContainerParameters, nullptr);
 
   return container.forget();
 }
 
 bool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                               nsRegion* aVisibleRegion,
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -9,16 +9,17 @@
 #include "nsCOMPtr.h"
 #include "nsIServiceManager.h"
 #include "nsGkAtoms.h"
 
 #include "nsHTMLCanvasFrame.h"
 #include "nsHTMLCanvasElement.h"
 #include "nsDisplayList.h"
 #include "nsLayoutUtils.h"
+#include "Layers.h"
 
 #include "nsTransform2D.h"
 
 #include "gfxContext.h"
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
@@ -258,17 +259,17 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayL
   nsRect area = GetContentRect() - GetPosition() + aItem->ToReferenceFrame();
   nsHTMLCanvasElement* element = static_cast<nsHTMLCanvasElement*>(GetContent());
   nsIntSize canvasSize = GetCanvasSize();
 
   if (canvasSize.width <= 0 || canvasSize.height <= 0 || area.IsEmpty())
     return nullptr;
 
   CanvasLayer* oldLayer = static_cast<CanvasLayer*>
-    (GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
+    (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
   nsRefPtr<CanvasLayer> layer = element->GetCanvasLayer(aBuilder, oldLayer, aManager);
   if (!layer)
     return nullptr;
 
   nsPresContext* presContext = PresContext();
   gfxRect r = gfxRect(presContext->AppUnitsToGfxUnits(area.x),
                       presContext->AppUnitsToGfxUnits(area.y),
                       presContext->AppUnitsToGfxUnits(area.width),
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -1641,17 +1641,17 @@ nsObjectFrame::BuildLayer(nsDisplayListB
     size = gfxIntSize(window->width, window->height);
   }
 
   nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
   gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel());
   // to provide crisper and faster drawing.
   r.Round();
   nsRefPtr<Layer> layer =
-    (GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
+    (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
 
   if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) {
     if (!layer) {
       mInstanceOwner->NotifyPaintWaiter(aBuilder);
       // Initialize ImageLayer
       layer = aManager->CreateImageLayer();
       if (!layer)
         return nullptr;
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -189,17 +189,17 @@ nsVideoFrame::BuildLayer(nsDisplayListBu
                       presContext->AppUnitsToGfxUnits(area.height));
   r = CorrectForAspectRatio(r, videoSize);
   r.Round();
   gfxIntSize scaleHint(static_cast<PRInt32>(r.Width()),
                        static_cast<PRInt32>(r.Height()));
   container->SetScaleHint(scaleHint);
 
   nsRefPtr<ImageLayer> layer = static_cast<ImageLayer*>
-    (GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
+    (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
   if (!layer) {
     layer = aManager->CreateImageLayer();
     if (!layer)
       return nullptr;
   }
 
   layer->SetContainer(container);
   layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this));
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -621,17 +621,17 @@ RenderFrameParent::BuildLayer(nsDisplayL
     return nullptr;
   }
 
   uint64_t id = GetLayerTreeId();
   if (0 != id) {
     MOZ_ASSERT(!GetRootLayer());
 
     nsRefPtr<Layer> layer =
-      (GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
+      (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
     if (!layer) {
       layer = aManager->CreateRefLayer();
     }
     if (!layer) {
       // Probably a temporary layer manager that doesn't know how to
       // use ref layers.
       return nullptr;
     }