Bug 808469 - Make gfxSharedImageSurface take a template parameter for the base surface type. r=cjones

--HG--
rename : gfx/thebes/gfxSharedImageSurface.cpp => gfx/thebes/gfxBaseSharedMemorySurface.cpp
rename : gfx/thebes/gfxSharedImageSurface.h => gfx/thebes/gfxBaseSharedMemorySurface.h
This commit is contained in:
Matt Woodrow 2012-11-07 19:56:54 +13:00
parent 192afbdbac
commit 61fe215c09
6 changed files with 195 additions and 193 deletions

View File

@ -49,6 +49,7 @@ EXPORTS = \
gfxUtils.h \
gfxUserFontSet.h \
nsSurfaceTexture.h \
gfxBaseSharedMemorySurface.h \
gfxSharedImageSurface.h \
gfxReusableSurfaceWrapper.h \
gfxSVGGlyphs.h \
@ -179,7 +180,7 @@ CPPSRCS = \
gfxUtils.cpp \
gfxScriptItemizer.cpp \
gfxHarfBuzzShaper.cpp \
gfxSharedImageSurface.cpp \
gfxBaseSharedMemorySurface.cpp \
gfxReusableSurfaceWrapper.cpp \
nsSurfaceTexture.cpp \
gfxSVGGlyphs.cpp \

View File

@ -0,0 +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 "gfxSharedImageSurface.h"
const cairo_user_data_key_t SHM_KEY = {0};

View File

@ -0,0 +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_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"
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 ~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<Sub>
Create(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
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<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<Sub>
CreateUnsafe(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
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)
{
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:
void WriteShmemInfo()
{
SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
shmInfo->width = this->mSize.width;
shmInfo->height = this->mSize.height;
shmInfo->format = this->mFormat;
}
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<Sub>
Create(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxASurface::gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType)
{
if (!gfxASurface::CheckSurfaceSize(aSize))
return nullptr;
Shmem shmem;
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<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
gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface&);
gfxBaseSharedMemorySurface& operator=(const gfxBaseSharedMemorySurface&);
};
#endif /* GFX_SHARED_MEMORYSURFACE_H */

View File

@ -92,6 +92,7 @@ public:
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,
@ -99,7 +100,6 @@ protected:
void InitFromSurface(cairo_surface_t *csurf);
long ComputeStride() const { return ComputeStride(mSize, mFormat); }
static long ComputeStride(const gfxIntSize&, gfxImageFormat);
void MakeInvalid();

View File

@ -1,95 +0,0 @@
// 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);
}
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();
}

View File

@ -7,104 +7,18 @@
#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);
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);
#include "gfxBaseSharedMemorySurface.h"
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 */