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 idunknown
push userunknown
push dateunknown
reviewersnical
bugs784004
milestone17.0a1
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;
     }