Bug 557671: Properly make image layers threadsafe by guarding the active image. r=roc
authorBas Schouten <bschouten@mozilla.com>
Thu, 08 Apr 2010 09:29:55 +0200
changeset 40576 afca4a8ad1279cd57b3e5a94a6c4123a3d310bff
parent 40575 d294c76984c6c00c3b06f72fbc322f9ac81272da
child 40577 dae132705f35b3a3ad6dee7dc9381360385bc8c8
push id12679
push userbschouten@mozilla.com
push dateThu, 08 Apr 2010 07:32:20 +0000
treeherdermozilla-central@dae132705f35 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs557671
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 557671: Properly make image layers threadsafe by guarding the active image. r=roc
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.h
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -37,16 +37,24 @@
 
 #include "ImageLayerOGL.h"
 #include "gfxImageSurface.h"
 #include "glWrapper.h"
 
 namespace mozilla {
 namespace layers {
 
+using mozilla::MutexAutoLock;
+
+ImageContainerOGL::ImageContainerOGL(LayerManagerOGL *aManager)
+  : ImageContainer(aManager)
+  , mActiveImageLock("mozilla.layers.ImageContainerOGL.mActiveImageLock")
+{
+}
+
 already_AddRefed<Image>
 ImageContainerOGL::CreateImage(const Image::Format *aFormats,
                                PRUint32 aNumFormats)
 {
   if (!aNumFormats) {
     return nsnull;
   }
   nsRefPtr<Image> img;
@@ -56,22 +64,26 @@ ImageContainerOGL::CreateImage(const Ima
     img = new CairoImageOGL(static_cast<LayerManagerOGL*>(mManager));
   }
   return img.forget();    
 }
 
 void
 ImageContainerOGL::SetCurrentImage(Image *aImage)
 {
+  MutexAutoLock lock(mActiveImageLock);
+
   mActiveImage = aImage;
 }
 
 already_AddRefed<Image>
 ImageContainerOGL::GetCurrentImage()
 {
+  MutexAutoLock lock(mActiveImageLock);
+
   nsRefPtr<Image> retval = mActiveImage;
   return retval.forget();
 }
 
 already_AddRefed<gfxASurface>
 ImageContainerOGL::GetCurrentAsSurface(gfxIntSize *aSize)
 {
   return nsnull;
@@ -186,20 +198,16 @@ PlanarYCbCrImageOGL::~PlanarYCbCrImageOG
     delete [] mData.mCbChannel;
     delete [] mData.mCrChannel;
   }
 }
 
 void
 PlanarYCbCrImageOGL::SetData(const PlanarYCbCrImage::Data &aData)
 {
-  /**
-   * XXX - Should do something more clever here, also introduce thread safety
-   * there's potential race conditions in this class.
-   */
   mData = aData;
   mData.mCbChannel = new PRUint8[aData.mCbCrStride * aData.mCbCrSize.height];
   mData.mCrChannel = new PRUint8[aData.mCbCrStride * aData.mCbCrSize.height];
   mData.mYChannel = new PRUint8[aData.mYStride * aData.mYSize.height];
   memcpy(mData.mCbChannel, aData.mCbChannel, aData.mCbCrStride * aData.mCbCrSize.height);
   memcpy(mData.mCrChannel, aData.mCrChannel, aData.mCbCrStride * aData.mCbCrSize.height);
   memcpy(mData.mYChannel, aData.mYChannel, aData.mYStride * aData.mYSize.height);
 
@@ -314,20 +322,16 @@ CairoImageOGL::~CairoImageOGL()
   if (mTexture) {
     sglWrapper.DeleteTextures(1, &mTexture);
   }
 }
 
 void
 CairoImageOGL::SetData(const CairoImage::Data &aData)
 {
-  /**
-   * XXX - Should make sure this happens on the correct thread. Since this
-   * is supposed to be threadsafe.
-   */
   mSize = aData.mSize;
   mManager->MakeCurrent();
 
   nsRefPtr<gfxImageSurface> imageSurface =
     new gfxImageSurface(aData.mSize, gfxASurface::ImageFormatARGB32);
 
   nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
 
--- a/gfx/layers/opengl/ImageLayerOGL.h
+++ b/gfx/layers/opengl/ImageLayerOGL.h
@@ -35,39 +35,41 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_IMAGELAYEROGL_H
 #define GFX_IMAGELAYEROGL_H
 
 #include "LayerManagerOGL.h"
 #include "ImageLayers.h"
+#include "mozilla/Mutex.h"
 
 namespace mozilla {
 namespace layers {
 
 class THEBES_API ImageContainerOGL : public ImageContainer
 {
 public:
-  ImageContainerOGL(LayerManagerOGL *aManager)
-    : ImageContainer(aManager)
-  { }
-
+  ImageContainerOGL(LayerManagerOGL *aManager);
   virtual ~ImageContainerOGL() {}
 
   virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats,
                                               PRUint32 aNumFormats);
 
   virtual void SetCurrentImage(Image* aImage);
 
   virtual already_AddRefed<Image> GetCurrentImage();
 
   virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize);
 private:
+  typedef mozilla::Mutex Mutex;
+
   nsRefPtr<Image> mActiveImage;
+
+  Mutex mActiveImageLock;
 };
 
 class THEBES_API ImageLayerOGL : public ImageLayer,
                                  public LayerOGL
 {
 public:
   ImageLayerOGL(LayerManagerOGL *aManager)
     : ImageLayer(aManager, NULL)