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 typedef struct _cairo_user_data_key cairo_user_data_key_t
;
19 struct SharedImageInfo
{
22 gfxImageFormat format
;
26 inline SharedImageInfo
*
27 GetShmInfoPtr(const mozilla::ipc::Shmem
& aShmem
)
29 return reinterpret_cast<SharedImageInfo
*>
30 (aShmem
.get
<char>() + aShmem
.Size
<char>() - sizeof(SharedImageInfo
));
33 extern const cairo_user_data_key_t SHM_KEY
;
35 template <typename Base
, typename Sub
>
36 class gfxBaseSharedMemorySurface
: public Base
{
37 typedef mozilla::ipc::SharedMemory SharedMemory
;
38 typedef mozilla::ipc::Shmem Shmem
;
39 friend class gfxReusableSharedImageSurfaceWrapper
;
42 virtual ~gfxBaseSharedMemorySurface()
44 MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface
);
49 * Return a new gfxSharedImageSurface around a shmem segment newly
50 * allocated by this function. |aAllocator| is the object used to
51 * allocate the new shmem segment. Null is returned if creating
54 * NB: the *caller* is responsible for freeing the Shmem allocated
57 template<class ShmemAllocator
>
58 static already_AddRefed
<Sub
>
59 Create(ShmemAllocator
* aAllocator
,
60 const gfxIntSize
& aSize
,
61 gfxImageFormat aFormat
,
62 SharedMemory::SharedMemoryType aShmType
= SharedMemory::TYPE_BASIC
)
64 return Create
<ShmemAllocator
, false>(aAllocator
, aSize
, aFormat
, aShmType
);
68 * Return a new gfxSharedImageSurface that wraps a shmem segment
69 * already created by the Create() above. Bad things will happen
70 * if an attempt is made to wrap any other shmem segment. Null is
71 * returned if creating the surface failed.
73 static already_AddRefed
<Sub
>
74 Open(const Shmem
& aShmem
)
76 SharedImageInfo
* shmInfo
= GetShmInfoPtr(aShmem
);
77 gfxIntSize
size(shmInfo
->width
, shmInfo
->height
);
78 if (!gfxASurface::CheckSurfaceSize(size
))
81 gfxImageFormat format
= (gfxImageFormat
)shmInfo
->format
;
82 long stride
= gfxImageSurface::ComputeStride(size
, format
);
89 // We didn't create this Shmem and so don't free it on errors
90 return (s
->CairoStatus() != 0) ? nullptr : s
.forget();
93 template<class ShmemAllocator
>
94 static already_AddRefed
<Sub
>
95 CreateUnsafe(ShmemAllocator
* aAllocator
,
96 const gfxIntSize
& aSize
,
97 gfxImageFormat aFormat
,
98 SharedMemory::SharedMemoryType aShmType
= SharedMemory::TYPE_BASIC
)
100 return Create
<ShmemAllocator
, true>(aAllocator
, aSize
, aFormat
, aShmType
);
103 Shmem
& GetShmem() { return mShmem
; }
105 static bool IsSharedImage(gfxASurface
*aSurface
)
108 && aSurface
->GetType() == gfxSurfaceType::Image
109 && aSurface
->GetData(&SHM_KEY
));
113 gfxBaseSharedMemorySurface(const gfxIntSize
& aSize
, long aStride
,
114 gfxImageFormat aFormat
,
116 : Base(aShmem
.get
<unsigned char>(), aSize
, aStride
, aFormat
)
118 MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface
);
121 this->SetData(&SHM_KEY
, this, nullptr);
125 void WriteShmemInfo()
127 SharedImageInfo
* shmInfo
= GetShmInfoPtr(mShmem
);
128 shmInfo
->width
= this->mSize
.width
;
129 shmInfo
->height
= this->mSize
.height
;
130 shmInfo
->format
= this->mFormat
;
131 shmInfo
->readCount
= 0;
137 SharedImageInfo
* shmInfo
= GetShmInfoPtr(mShmem
);
138 return PR_ATOMIC_INCREMENT(&shmInfo
->readCount
);
144 SharedImageInfo
* shmInfo
= GetShmInfoPtr(mShmem
);
145 return PR_ATOMIC_DECREMENT(&shmInfo
->readCount
);
151 SharedImageInfo
* shmInfo
= GetShmInfoPtr(mShmem
);
152 return shmInfo
->readCount
;
155 static size_t GetAlignedSize(const gfxIntSize
& aSize
, long aStride
)
157 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
158 return MOZ_ALIGN_WORD(sizeof(SharedImageInfo
) + aSize
.height
* aStride
);
161 template<class ShmemAllocator
, bool Unsafe
>
162 static already_AddRefed
<Sub
>
163 Create(ShmemAllocator
* aAllocator
,
164 const gfxIntSize
& aSize
,
165 gfxImageFormat aFormat
,
166 SharedMemory::SharedMemoryType aShmType
)
168 if (!gfxASurface::CheckSurfaceSize(aSize
))
172 long stride
= gfxImageSurface::ComputeStride(aSize
, aFormat
);
173 size_t size
= GetAlignedSize(aSize
, stride
);
175 if (!aAllocator
->AllocShmem(size
, aShmType
, &shmem
))
178 if (!aAllocator
->AllocUnsafeShmem(size
, aShmType
, &shmem
))
183 new Sub(aSize
, stride
, aFormat
, shmem
);
184 if (s
->CairoStatus() != 0) {
185 aAllocator
->DeallocShmem(shmem
);
194 // Calling these is very bad, disallow it
195 gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface
&);
196 gfxBaseSharedMemorySurface
& operator=(const gfxBaseSharedMemorySurface
&);
199 #endif /* GFX_SHARED_MEMORYSURFACE_H */