Bug 808469 - Make gfxSharedImageSurface take a template parameter for the base surface type. r=cjones
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 07 Nov 2012 19:56:54 +1300
changeset 120457 877f3c82d44a6337d3c1afff31c82c42c863776e
parent 120456 847cedab81aefaf6a48d7d6273564ef6e943d86e
child 120458 8083f88251535741731f6485c77f895e09b5d78b
push idunknown
push userunknown
push dateunknown
reviewerscjones
bugs808469
milestone19.0a1
Bug 808469 - Make gfxSharedImageSurface take a template parameter for the base surface type. r=cjones
gfx/thebes/Makefile.in
gfx/thebes/gfxBaseSharedMemorySurface.cpp
gfx/thebes/gfxBaseSharedMemorySurface.h
gfx/thebes/gfxImageSurface.h
gfx/thebes/gfxSharedImageSurface.cpp
gfx/thebes/gfxSharedImageSurface.h
--- a/gfx/thebes/Makefile.in
+++ b/gfx/thebes/Makefile.in
@@ -44,16 +44,17 @@ EXPORTS	= \
 	gfxQuaternion.h \
 	gfxRect.h \
 	gfxSkipChars.h \
 	gfxTeeSurface.h \
 	gfxTypes.h \
 	gfxUtils.h \
 	gfxUserFontSet.h \
 	nsSurfaceTexture.h \
+	gfxBaseSharedMemorySurface.h \
 	gfxSharedImageSurface.h \
 	gfxReusableSurfaceWrapper.h \
 	gfxSVGGlyphs.h \
 	$(NULL)
 
 # gfxSVGGlyphs needs nsDOMParser.h
 LOCAL_INCLUDES += \
 	-I$(topsrcdir)/content/base/public \
@@ -174,17 +175,17 @@ CPPSRCS	= \
 	gfxPlatformFontList.cpp \
 	gfxRect.cpp \
 	gfxSkipChars.cpp \
 	gfxTeeSurface.cpp \
 	gfxUserFontSet.cpp \
 	gfxUtils.cpp \
 	gfxScriptItemizer.cpp \
 	gfxHarfBuzzShaper.cpp \
-	gfxSharedImageSurface.cpp \
+	gfxBaseSharedMemorySurface.cpp \
 	gfxReusableSurfaceWrapper.cpp \
 	nsSurfaceTexture.cpp \
 	gfxSVGGlyphs.cpp \
 	$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
 DEFINES += -DMOZ_ENABLE_FREETYPE
 endif
rename from gfx/thebes/gfxSharedImageSurface.cpp
rename to gfx/thebes/gfxBaseSharedMemorySurface.cpp
--- a/gfx/thebes/gfxSharedImageSurface.cpp
+++ b/gfx/thebes/gfxBaseSharedMemorySurface.cpp
@@ -1,95 +1,10 @@
 // vim:set ts=4 sts=4 sw=4 et cin:
 /* -*- 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 "base/basictypes.h"
 #include "gfxSharedImageSurface.h"
-#include "cairo.h"
-
-#define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
-
-using namespace mozilla::ipc;
-
-static const cairo_user_data_key_t SHM_KEY = {0};
-
-struct SharedImageInfo {
-    int32_t width;
-    int32_t height;
-    int32_t format;
-};
-
-static SharedImageInfo*
-GetShmInfoPtr(const Shmem& aShmem)
-{
-    return reinterpret_cast<SharedImageInfo*>
-        (aShmem.get<char>() + aShmem.Size<char>() - sizeof(SharedImageInfo));
-}
-
-gfxSharedImageSurface::~gfxSharedImageSurface()
-{
-    MOZ_COUNT_DTOR(gfxSharedImageSurface);
-}
-
-/*static*/ bool
-gfxSharedImageSurface::IsSharedImage(gfxASurface* aSurface)
-{
-    return (aSurface
-            && aSurface->GetType() == gfxASurface::SurfaceTypeImage
-            && aSurface->GetData(&SHM_KEY));
-}
-
-gfxSharedImageSurface::gfxSharedImageSurface(const gfxIntSize& aSize,
-                                             gfxImageFormat aFormat,
-                                             const Shmem& aShmem)
-{
-    MOZ_COUNT_CTOR(gfxSharedImageSurface);
 
-    mSize = aSize;
-    mFormat = aFormat;
-    mStride = ComputeStride(aSize, aFormat);
-    mShmem = aShmem;
-    mData = aShmem.get<unsigned char>();
-    cairo_surface_t *surface =
-        cairo_image_surface_create_for_data(mData,
-                                            (cairo_format_t)mFormat,
-                                            mSize.width,
-                                            mSize.height,
-                                            mStride);
-    if (surface) {
-        cairo_surface_set_user_data(surface, &SHM_KEY, this, NULL);
-    }
-    Init(surface);
-}
+const cairo_user_data_key_t SHM_KEY = {0};
 
-void
-gfxSharedImageSurface::WriteShmemInfo()
-{
-    SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
-    shmInfo->width = mSize.width;
-    shmInfo->height = mSize.height;
-    shmInfo->format = mFormat;
-}
-
-/*static*/ size_t
-gfxSharedImageSurface::GetAlignedSize(const gfxIntSize& aSize, long aStride)
-{
-   return MOZ_ALIGN_WORD(sizeof(SharedImageInfo) + aSize.height * aStride);
-}
-
-/*static*/ already_AddRefed<gfxSharedImageSurface>
-gfxSharedImageSurface::Open(const Shmem& aShmem)
-{
-    SharedImageInfo* shmInfo = GetShmInfoPtr(aShmem);
-    gfxIntSize size(shmInfo->width, shmInfo->height);
-    if (!CheckSurfaceSize(size))
-        return nullptr;
-
-    nsRefPtr<gfxSharedImageSurface> s =
-        new gfxSharedImageSurface(size,
-                                  (gfxImageFormat)shmInfo->format,
-                                  aShmem);
-    // We didn't create this Shmem and so don't free it on errors
-    return (s->CairoStatus() != 0) ? nullptr : s.forget();
-}
copy from gfx/thebes/gfxSharedImageSurface.h
copy to gfx/thebes/gfxBaseSharedMemorySurface.h
--- a/gfx/thebes/gfxSharedImageSurface.h
+++ b/gfx/thebes/gfxBaseSharedMemorySurface.h
@@ -1,110 +1,172 @@
 // vim:set ts=4 sts=4 sw=4 et cin:
 /* -*- 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/. */
 
-#ifndef GFX_SHARED_IMAGESURFACE_H
-#define GFX_SHARED_IMAGESURFACE_H
+#ifndef GFX_SHARED_MEMORYSURFACE_H
+#define GFX_SHARED_MEMORYSURFACE_H
 
 #include "mozilla/ipc/Shmem.h"
 #include "mozilla/ipc/SharedMemory.h"
 
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
+#include "cairo.h"
 
-class THEBES_API gfxSharedImageSurface : public gfxImageSurface {
+struct SharedImageInfo {
+    int32_t width;
+    int32_t height;
+    int32_t format;
+};
+
+inline SharedImageInfo*
+GetShmInfoPtr(const mozilla::ipc::Shmem& aShmem)
+{
+    return reinterpret_cast<SharedImageInfo*>
+        (aShmem.get<char>() + aShmem.Size<char>() - sizeof(SharedImageInfo));
+}
+
+extern const cairo_user_data_key_t SHM_KEY;
+
+template <typename Base, typename Sub>
+class THEBES_API gfxBaseSharedMemorySurface : public Base {
     typedef mozilla::ipc::SharedMemory SharedMemory;
     typedef mozilla::ipc::Shmem Shmem;
 
 public:
-    virtual ~gfxSharedImageSurface();
+    virtual ~gfxBaseSharedMemorySurface()
+    {
+        MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface);
+    }
 
     /**
      * Return a new gfxSharedImageSurface around a shmem segment newly
      * allocated by this function.  |aAllocator| is the object used to
      * allocate the new shmem segment.  Null is returned if creating
      * the surface failed.
      *
      * NB: the *caller* is responsible for freeing the Shmem allocated
      * by this function.
      */
     template<class ShmemAllocator>
-    static already_AddRefed<gfxSharedImageSurface>
+    static already_AddRefed<Sub>
     Create(ShmemAllocator* aAllocator,
            const gfxIntSize& aSize,
-           gfxImageFormat aFormat,
+           gfxASurface::gfxImageFormat aFormat,
            SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
     {
         return Create<ShmemAllocator, false>(aAllocator, aSize, aFormat, aShmType);
     }
 
     /**
      * Return a new gfxSharedImageSurface that wraps a shmem segment
      * already created by the Create() above.  Bad things will happen
      * if an attempt is made to wrap any other shmem segment.  Null is
      * returned if creating the surface failed.
      */
-    static already_AddRefed<gfxSharedImageSurface>
-    Open(const Shmem& aShmem);
+    static already_AddRefed<Sub>
+    Open(const Shmem& aShmem)
+    {
+        SharedImageInfo* shmInfo = GetShmInfoPtr(aShmem);
+        gfxIntSize size(shmInfo->width, shmInfo->height);
+        if (!gfxASurface::CheckSurfaceSize(size))
+            return nullptr;
+       
+        gfxASurface::gfxImageFormat format = (gfxASurface::gfxImageFormat)shmInfo->format;
+        long stride = gfxImageSurface::ComputeStride(size, format);
+
+        nsRefPtr<Sub> s =
+            new Sub(size,
+                    stride,
+                    format,
+                    aShmem);
+        // We didn't create this Shmem and so don't free it on errors
+        return (s->CairoStatus() != 0) ? nullptr : s.forget();
+    }
 
     template<class ShmemAllocator>
-    static already_AddRefed<gfxSharedImageSurface>
+    static already_AddRefed<Sub>
     CreateUnsafe(ShmemAllocator* aAllocator,
                  const gfxIntSize& aSize,
-                 gfxImageFormat aFormat,
+                 gfxASurface::gfxImageFormat aFormat,
                  SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
     {
         return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat, aShmType);
     }
 
     Shmem& GetShmem() { return mShmem; }
 
-    static bool IsSharedImage(gfxASurface *aSurface);
+    static bool IsSharedImage(gfxASurface *aSurface)
+    {
+        return (aSurface
+                && aSurface->GetType() == gfxASurface::SurfaceTypeImage
+                && aSurface->GetData(&SHM_KEY));
+    }
+
+protected:
+    gfxBaseSharedMemorySurface(const gfxIntSize& aSize, long aStride, 
+                               gfxASurface::gfxImageFormat aFormat, 
+                               const Shmem& aShmem)
+      : Base(aShmem.get<unsigned char>(), aSize, aStride, aFormat)
+    {
+        MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface);
+
+        mShmem = aShmem;
+        this->SetData(&SHM_KEY, this, nullptr);
+    }
 
 private:
-    gfxSharedImageSurface(const gfxIntSize&, gfxImageFormat, const Shmem&);
+    void WriteShmemInfo()
+    {
+        SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
+        shmInfo->width = this->mSize.width;
+        shmInfo->height = this->mSize.height;
+        shmInfo->format = this->mFormat;
+    }
 
-    void WriteShmemInfo();
-
-    static size_t GetAlignedSize(const gfxIntSize&, long aStride);
+    static size_t GetAlignedSize(const gfxIntSize& aSize, long aStride)
+    {
+        #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
+        return MOZ_ALIGN_WORD(sizeof(SharedImageInfo) + aSize.height * aStride);
+    }
 
     template<class ShmemAllocator, bool Unsafe>
-    static already_AddRefed<gfxSharedImageSurface>
+    static already_AddRefed<Sub>
     Create(ShmemAllocator* aAllocator,
            const gfxIntSize& aSize,
-           gfxImageFormat aFormat,
+           gfxASurface::gfxImageFormat aFormat,
            SharedMemory::SharedMemoryType aShmType)
     {
-        if (!CheckSurfaceSize(aSize))
+        if (!gfxASurface::CheckSurfaceSize(aSize))
             return nullptr;
 
         Shmem shmem;
-        long stride = ComputeStride(aSize, aFormat);
+        long stride = gfxImageSurface::ComputeStride(aSize, aFormat);
         size_t size = GetAlignedSize(aSize, stride);
         if (!Unsafe) {
             if (!aAllocator->AllocShmem(size, aShmType, &shmem))
                 return nullptr;
         } else {
             if (!aAllocator->AllocUnsafeShmem(size, aShmType, &shmem))
                 return nullptr;
         }
 
-        nsRefPtr<gfxSharedImageSurface> s =
-            new gfxSharedImageSurface(aSize, aFormat, shmem);
+        nsRefPtr<Sub> s =
+            new Sub(aSize, stride, aFormat, shmem);
         if (s->CairoStatus() != 0) {
             aAllocator->DeallocShmem(shmem);
             return nullptr;
         }
         s->WriteShmemInfo();
         return s.forget();
     }
 
     Shmem mShmem;
 
     // Calling these is very bad, disallow it
-    gfxSharedImageSurface(const gfxSharedImageSurface&);
-    gfxSharedImageSurface& operator=(const gfxSharedImageSurface&);
+    gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface&);
+    gfxBaseSharedMemorySurface& operator=(const gfxBaseSharedMemorySurface&);
 };
 
-#endif /* GFX_SHARED_IMAGESURFACE_H */
+#endif /* GFX_SHARED_MEMORYSURFACE_H */
--- a/gfx/thebes/gfxImageSurface.h
+++ b/gfx/thebes/gfxImageSurface.h
@@ -87,24 +87,24 @@ public:
     already_AddRefed<gfxSubimageSurface> GetSubimage(const gfxRect& aRect);
 
     virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
 
     /** See gfxASurface.h. */
     virtual void MovePixels(const nsIntRect& aSourceRect,
                             const nsIntPoint& aDestTopLeft) MOZ_OVERRIDE;
 
+    static long ComputeStride(const gfxIntSize&, gfxImageFormat);
 protected:
     gfxImageSurface();
     void InitWithData(unsigned char *aData, const gfxIntSize& aSize,
                       long aStride, gfxImageFormat aFormat);
     void InitFromSurface(cairo_surface_t *csurf);
     long ComputeStride() const { return ComputeStride(mSize, mFormat); }
 
-    static long ComputeStride(const gfxIntSize&, gfxImageFormat);
 
     void MakeInvalid();
 
     gfxIntSize mSize;
     bool mOwnsData;
     unsigned char *mData;
     gfxImageFormat mFormat;
     long mStride;
--- a/gfx/thebes/gfxSharedImageSurface.h
+++ b/gfx/thebes/gfxSharedImageSurface.h
@@ -2,109 +2,23 @@
 /* -*- 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/. */
 
 #ifndef GFX_SHARED_IMAGESURFACE_H
 #define GFX_SHARED_IMAGESURFACE_H
 
-#include "mozilla/ipc/Shmem.h"
-#include "mozilla/ipc/SharedMemory.h"
-
-#include "gfxASurface.h"
-#include "gfxImageSurface.h"
-
-class THEBES_API gfxSharedImageSurface : public gfxImageSurface {
-    typedef mozilla::ipc::SharedMemory SharedMemory;
-    typedef mozilla::ipc::Shmem Shmem;
-
-public:
-    virtual ~gfxSharedImageSurface();
-
-    /**
-     * Return a new gfxSharedImageSurface around a shmem segment newly
-     * allocated by this function.  |aAllocator| is the object used to
-     * allocate the new shmem segment.  Null is returned if creating
-     * the surface failed.
-     *
-     * NB: the *caller* is responsible for freeing the Shmem allocated
-     * by this function.
-     */
-    template<class ShmemAllocator>
-    static already_AddRefed<gfxSharedImageSurface>
-    Create(ShmemAllocator* aAllocator,
-           const gfxIntSize& aSize,
-           gfxImageFormat aFormat,
-           SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
-    {
-        return Create<ShmemAllocator, false>(aAllocator, aSize, aFormat, aShmType);
-    }
-
-    /**
-     * Return a new gfxSharedImageSurface that wraps a shmem segment
-     * already created by the Create() above.  Bad things will happen
-     * if an attempt is made to wrap any other shmem segment.  Null is
-     * returned if creating the surface failed.
-     */
-    static already_AddRefed<gfxSharedImageSurface>
-    Open(const Shmem& aShmem);
+#include "gfxBaseSharedMemorySurface.h"
 
-    template<class ShmemAllocator>
-    static already_AddRefed<gfxSharedImageSurface>
-    CreateUnsafe(ShmemAllocator* aAllocator,
-                 const gfxIntSize& aSize,
-                 gfxImageFormat aFormat,
-                 SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
-    {
-        return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat, aShmType);
-    }
-
-    Shmem& GetShmem() { return mShmem; }
-
-    static bool IsSharedImage(gfxASurface *aSurface);
-
+class gfxSharedImageSurface : public gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface>
+{
+  typedef gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface> Super;
+  friend class gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface>;
 private:
-    gfxSharedImageSurface(const gfxIntSize&, gfxImageFormat, const Shmem&);
-
-    void WriteShmemInfo();
-
-    static size_t GetAlignedSize(const gfxIntSize&, long aStride);
-
-    template<class ShmemAllocator, bool Unsafe>
-    static already_AddRefed<gfxSharedImageSurface>
-    Create(ShmemAllocator* aAllocator,
-           const gfxIntSize& aSize,
-           gfxImageFormat aFormat,
-           SharedMemory::SharedMemoryType aShmType)
-    {
-        if (!CheckSurfaceSize(aSize))
-            return nullptr;
-
-        Shmem shmem;
-        long stride = ComputeStride(aSize, aFormat);
-        size_t size = GetAlignedSize(aSize, stride);
-        if (!Unsafe) {
-            if (!aAllocator->AllocShmem(size, aShmType, &shmem))
-                return nullptr;
-        } else {
-            if (!aAllocator->AllocUnsafeShmem(size, aShmType, &shmem))
-                return nullptr;
-        }
-
-        nsRefPtr<gfxSharedImageSurface> s =
-            new gfxSharedImageSurface(aSize, aFormat, shmem);
-        if (s->CairoStatus() != 0) {
-            aAllocator->DeallocShmem(shmem);
-            return nullptr;
-        }
-        s->WriteShmemInfo();
-        return s.forget();
-    }
-
-    Shmem mShmem;
-
-    // Calling these is very bad, disallow it
-    gfxSharedImageSurface(const gfxSharedImageSurface&);
-    gfxSharedImageSurface& operator=(const gfxSharedImageSurface&);
+    gfxSharedImageSurface(const gfxIntSize& aSize, long aStride, 
+                          gfxASurface::gfxImageFormat aFormat, 
+                          const mozilla::ipc::Shmem& aShmem)
+      : Super(aSize, aStride, aFormat, aShmem)
+    {}
 };
 
 #endif /* GFX_SHARED_IMAGESURFACE_H */