Bug 874369 - Use normal memory instead of Shmem when only sharing between processes. r=Bas
☠☠ backed out by 09ff5b55b27a ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 22 May 2013 11:36:39 +0800
changeset 132596 85d108f0b422dc47d7f7a2ed341761b32602f1a7
parent 132595 048352b0310b3ccd4d9adad7a9b41820ba6652da
child 132597 3bfbd1ed214d1ec24f9b726c6c430c97b010fb13
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-esr52@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs874369
milestone24.0a1
Bug 874369 - Use normal memory instead of Shmem when only sharing between processes. r=Bas
gfx/layers/client/TextureClient.cpp
gfx/layers/ipc/ISurfaceAllocator.cpp
gfx/layers/ipc/LayersSurfaces.ipdlh
gfx/layers/ipc/ShadowLayerUtilsMac.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/thebes/gfxQuartzSurface.cpp
gfx/thebes/gfxQuartzSurface.h
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -92,16 +92,17 @@ TextureClientShmem::SetDescriptor(const 
   } else {
     EnsureAllocated(mSize, mContentType);
   }
 
   mSurface = nullptr;
 
   NS_ASSERTION(mDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorGralloc ||
                mDescriptor.type() == SurfaceDescriptor::TShmem ||
+               mDescriptor.type() == SurfaceDescriptor::TMemoryImage ||
                mDescriptor.type() == SurfaceDescriptor::TRGBImage,
                "Invalid surface descriptor");
 }
 
 gfxASurface*
 TextureClientShmem::GetSurface()
 {
   if (!mSurface) {
--- a/gfx/layers/ipc/ISurfaceAllocator.cpp
+++ b/gfx/layers/ipc/ISurfaceAllocator.cpp
@@ -8,16 +8,17 @@
 #include "ISurfaceAllocator.h"
 #include "mozilla/ipc/SharedMemory.h"
 #include "gfxSharedImageSurface.h"
 #include "gfxPlatform.h"
 #include "gfxASurface.h"
 #include "mozilla/layers/LayersSurfaces.h"
 #include "mozilla/layers/SharedPlanarYCbCrImage.h"
 #include "mozilla/layers/SharedRGBImage.h"
+#include "nsXULAppAPI.h"
 
 #ifdef DEBUG
 #include "prenv.h"
 #endif
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
@@ -80,16 +81,27 @@ ISurfaceAllocator::AllocSurfaceDescripto
 #ifdef DEBUG
   tryPlatformSurface = !PR_GetEnv("MOZ_LAYERS_FORCE_SHMEM_SURFACES");
 #endif
   if (tryPlatformSurface &&
       PlatformAllocSurfaceDescriptor(aSize, aContent, aCaps, aBuffer)) {
     return true;
   }
 
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    gfxImageFormat format = aContent == gfxASurface::CONTENT_COLOR_ALPHA ?
+                            gfxASurface::ImageFormatARGB32 :
+                            gfxASurface::ImageFormatRGB24;
+    int32_t stride = gfxASurface::FormatStrideForWidth(format, aSize.width);
+    uint8_t *data = new uint8_t[stride * aSize.height];
+
+    *aBuffer = MemoryImage((uintptr_t)data, aSize, stride, format);
+    return true;
+  }
+
   nsRefPtr<gfxSharedImageSurface> buffer;
   if (!AllocSharedImageSurface(aSize, aContent,
                                getter_AddRefs(buffer))) {
     return false;
   }
 
   *aBuffer = buffer->GetShmem();
   return true;
@@ -117,16 +129,19 @@ ISurfaceAllocator::DestroySharedSurface(
     case SurfaceDescriptor::TYCbCrImage:
       DeallocShmem(aSurface->get_YCbCrImage().data());
       break;
     case SurfaceDescriptor::TRGBImage:
       DeallocShmem(aSurface->get_RGBImage().data());
       break;
     case SurfaceDescriptor::TSurfaceDescriptorD3D10:
       break;
+    case SurfaceDescriptor::TMemoryImage:
+      delete [] (unsigned char *)aSurface->get_MemoryImage().data();
+      break;
     case SurfaceDescriptor::Tnull_t:
     case SurfaceDescriptor::T__None:
       break;
     default:
       NS_RUNTIMEABORT("surface type not implemented!");
   }
   *aSurface = SurfaceDescriptor();
 }
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -78,22 +78,30 @@ struct YCbCrImage {
 // XXX remove RGBImage (see bug 847914)
 struct RGBImage {
   Shmem data;
   nsIntRect picture;
   uint32_t rgbFormat;
   uint64_t owner;
 };
 
+struct MemoryImage {
+  uintptr_t data;
+  gfxIntSize size;
+  uint32_t stride;
+  uint32_t format;
+};
+
 union SurfaceDescriptor {
   Shmem;
   SurfaceDescriptorD3D10;
   SurfaceDescriptorGralloc;
   SurfaceDescriptorX11;
   YCbCrImage;
   RGBImage;
   SharedTextureDescriptor;
   SurfaceStreamDescriptor;
+  MemoryImage;
   null_t;
 };
 
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/ShadowLayerUtilsMac.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsMac.cpp
@@ -27,20 +27,32 @@ ISurfaceAllocator::PlatformAllocSurfaceD
 {
   return false;
 }
 
 /*static*/ already_AddRefed<gfxASurface>
 ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode,
                                              const SurfaceDescriptor& aSurface)
 {
-  if (SurfaceDescriptor::TShmem != aSurface.type()) {
-    return nullptr;
+  if (aSurface.type() == SurfaceDescriptor::TShmem) {
+    return gfxSharedQuartzSurface::Open(aSurface.get_Shmem());
+  } else if (aSurface.type() == SurfaceDescriptor::TMemoryImage) {
+    const MemoryImage& image = aSurface.get_MemoryImage();
+    gfxASurface::gfxImageFormat format
+      = static_cast<gfxASurface::gfxImageFormat>(image.format());
+
+    nsRefPtr<gfxASurface> surf =
+      new gfxQuartzSurface((unsigned char*)image.data(),
+                           image.size(),
+                           image.stride(),
+                           format);
+    return surf.forget();
+
   }
-  return gfxSharedQuartzSurface::Open(aSurface.get_Shmem());
+  return nullptr;
 }
 
 /*static*/ bool
 ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor)
 {
   return false;
 }
 
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -525,16 +525,26 @@ ShadowLayerForwarder::OpenDescriptor(Ope
     uint32_t stride = gfxASurface::BytesPerPixel(rgbFormat) * rgb.picture().width;
     nsIntSize size(rgb.picture().width, rgb.picture().height);
     surf = new gfxImageSurface(rgb.data().get<uint8_t>(),
                                size,
                                stride,
                                rgbFormat);
     return surf.forget();
   }
+  case SurfaceDescriptor::TMemoryImage: {
+    const MemoryImage& image = aSurface.get_MemoryImage();
+    gfxASurface::gfxImageFormat format
+      = static_cast<gfxASurface::gfxImageFormat>(image.format());
+    surf = new gfxImageSurface((unsigned char *)image.data(),
+                               image.size(),
+                               image.stride(),
+                               format);
+    return surf.forget();
+  }
   default:
     NS_ERROR("unexpected SurfaceDescriptor type!");
     return nullptr;
   }
 }
 
 /*static*/ gfxContentType
 ShadowLayerForwarder::GetDescriptorSurfaceContentType(
--- a/gfx/thebes/gfxQuartzSurface.cpp
+++ b/gfx/thebes/gfxQuartzSurface.cpp
@@ -120,16 +120,39 @@ gfxQuartzSurface::gfxQuartzSurface(unsig
     CGContextRetain(mCGContext);
 
     Init(surf);
     if (mSurfaceValid) {
       RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
     }
 }
 
+gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
+                                   const gfxIntSize& aSize,
+                                   long stride,
+                                   gfxImageFormat format,
+                                   bool aForPrinting)
+    : mCGContext(nullptr), mSize(aSize.width, aSize.height), mForPrinting(aForPrinting)
+{
+    if (!CheckSurfaceSize(aSize))
+        MakeInvalid();
+
+    cairo_surface_t *surf = cairo_quartz_surface_create_for_data
+        (data, (cairo_format_t) format, aSize.width, aSize.height, stride);
+
+    mCGContext = cairo_quartz_surface_get_cg_context (surf);
+
+    CGContextRetain(mCGContext);
+
+    Init(surf);
+    if (mSurfaceValid) {
+      RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
+    }
+}
+
 already_AddRefed<gfxASurface>
 gfxQuartzSurface::CreateSimilarSurface(gfxContentType aType,
                                        const gfxIntSize& aSize)
 {
     cairo_surface_t *surface =
         cairo_quartz_surface_create_cg_layer(mSurface, (cairo_content_t)aType,
                                              aSize.width, aSize.height);
     if (cairo_surface_status(surface)) {
--- a/gfx/thebes/gfxQuartzSurface.h
+++ b/gfx/thebes/gfxQuartzSurface.h
@@ -15,16 +15,17 @@ class gfxContext;
 
 class THEBES_API gfxQuartzSurface : public gfxASurface {
 public:
     gfxQuartzSurface(const gfxSize& size, gfxImageFormat format, bool aForPrinting = false);
     gfxQuartzSurface(CGContextRef context, const gfxSize& size, bool aForPrinting = false);
     gfxQuartzSurface(CGContextRef context, const gfxIntSize& size, bool aForPrinting = false);
     gfxQuartzSurface(cairo_surface_t *csurf, bool aForPrinting = false);
     gfxQuartzSurface(unsigned char *data, const gfxSize& size, long stride, gfxImageFormat format, bool aForPrinting = false);
+    gfxQuartzSurface(unsigned char *data, const gfxIntSize& size, long stride, gfxImageFormat format, bool aForPrinting = false);
 
     virtual ~gfxQuartzSurface();
 
     virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
                                                                const gfxIntSize& aSize);
 
     virtual const gfxIntSize GetSize() const { return gfxIntSize(mSize.width, mSize.height); }