1 // vim:set ts=4 sts=4 sw=4 et cin:
2 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef GFX_SHARED_MEMORYSURFACE_H
8 #define GFX_SHARED_MEMORYSURFACE_H
10 #include "mozilla/ipc/Shmem.h"
11 #include "mozilla/ipc/SharedMemory.h"
13 #include "gfxASurface.h"
14 #include "gfxImageSurface.h"
17 struct SharedImageInfo
{
23 inline SharedImageInfo
*
24 GetShmInfoPtr(const mozilla::ipc::Shmem
& aShmem
)
26 return reinterpret_cast<SharedImageInfo
*>
27 (aShmem
.get
<char>() + aShmem
.Size
<char>() - sizeof(SharedImageInfo
));
30 extern const cairo_user_data_key_t SHM_KEY
;
32 template <typename Base
, typename Sub
>
33 class THEBES_API gfxBaseSharedMemorySurface
: public Base
{
34 typedef mozilla::ipc::SharedMemory SharedMemory
;
35 typedef mozilla::ipc::Shmem Shmem
;
38 virtual ~gfxBaseSharedMemorySurface()
40 MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface
);
44 * Return a new gfxSharedImageSurface around a shmem segment newly
45 * allocated by this function. |aAllocator| is the object used to
46 * allocate the new shmem segment. Null is returned if creating
49 * NB: the *caller* is responsible for freeing the Shmem allocated
52 template<class ShmemAllocator
>
53 static already_AddRefed
<Sub
>
54 Create(ShmemAllocator
* aAllocator
,
55 const gfxIntSize
& aSize
,
56 gfxASurface::gfxImageFormat aFormat
,
57 SharedMemory::SharedMemoryType aShmType
= SharedMemory::TYPE_BASIC
)
59 return Create
<ShmemAllocator
, false>(aAllocator
, aSize
, aFormat
, aShmType
);
63 * Return a new gfxSharedImageSurface that wraps a shmem segment
64 * already created by the Create() above. Bad things will happen
65 * if an attempt is made to wrap any other shmem segment. Null is
66 * returned if creating the surface failed.
68 static already_AddRefed
<Sub
>
69 Open(const Shmem
& aShmem
)
71 SharedImageInfo
* shmInfo
= GetShmInfoPtr(aShmem
);
72 gfxIntSize
size(shmInfo
->width
, shmInfo
->height
);
73 if (!gfxASurface::CheckSurfaceSize(size
))
76 gfxASurface::gfxImageFormat format
= (gfxASurface::gfxImageFormat
)shmInfo
->format
;
77 long stride
= gfxImageSurface::ComputeStride(size
, format
);
84 // We didn't create this Shmem and so don't free it on errors
85 return (s
->CairoStatus() != 0) ? nullptr : s
.forget();
88 template<class ShmemAllocator
>
89 static already_AddRefed
<Sub
>
90 CreateUnsafe(ShmemAllocator
* aAllocator
,
91 const gfxIntSize
& aSize
,
92 gfxASurface::gfxImageFormat aFormat
,
93 SharedMemory::SharedMemoryType aShmType
= SharedMemory::TYPE_BASIC
)
95 return Create
<ShmemAllocator
, true>(aAllocator
, aSize
, aFormat
, aShmType
);
98 Shmem
& GetShmem() { return mShmem
; }
100 static bool IsSharedImage(gfxASurface
*aSurface
)
103 && aSurface
->GetType() == gfxASurface::SurfaceTypeImage
104 && aSurface
->GetData(&SHM_KEY
));
108 gfxBaseSharedMemorySurface(const gfxIntSize
& aSize
, long aStride
,
109 gfxASurface::gfxImageFormat aFormat
,
111 : Base(aShmem
.get
<unsigned char>(), aSize
, aStride
, aFormat
)
113 MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface
);
116 this->SetData(&SHM_KEY
, this, nullptr);
120 void WriteShmemInfo()
122 SharedImageInfo
* shmInfo
= GetShmInfoPtr(mShmem
);
123 shmInfo
->width
= this->mSize
.width
;
124 shmInfo
->height
= this->mSize
.height
;
125 shmInfo
->format
= this->mFormat
;
128 static size_t GetAlignedSize(const gfxIntSize
& aSize
, long aStride
)
130 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
131 return MOZ_ALIGN_WORD(sizeof(SharedImageInfo
) + aSize
.height
* aStride
);
134 template<class ShmemAllocator
, bool Unsafe
>
135 static already_AddRefed
<Sub
>
136 Create(ShmemAllocator
* aAllocator
,
137 const gfxIntSize
& aSize
,
138 gfxASurface::gfxImageFormat aFormat
,
139 SharedMemory::SharedMemoryType aShmType
)
141 if (!gfxASurface::CheckSurfaceSize(aSize
))
145 long stride
= gfxImageSurface::ComputeStride(aSize
, aFormat
);
146 size_t size
= GetAlignedSize(aSize
, stride
);
148 if (!aAllocator
->AllocShmem(size
, aShmType
, &shmem
))
151 if (!aAllocator
->AllocUnsafeShmem(size
, aShmType
, &shmem
))
156 new Sub(aSize
, stride
, aFormat
, shmem
);
157 if (s
->CairoStatus() != 0) {
158 aAllocator
->DeallocShmem(shmem
);
167 // Calling these is very bad, disallow it
168 gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface
&);
169 gfxBaseSharedMemorySurface
& operator=(const gfxBaseSharedMemorySurface
&);
172 #endif /* GFX_SHARED_MEMORYSURFACE_H */