Bumping manifests a=b2g-bump
[gecko.git] / gfx / thebes / gfxBaseSharedMemorySurface.h
blobbf0826727faf48870f9cc5ffe403a75f96bc3b57
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"
15 #include "pratom.h"
17 typedef struct _cairo_user_data_key cairo_user_data_key_t;
19 struct SharedImageInfo {
20 int32_t width;
21 int32_t height;
22 gfxImageFormat format;
23 int32_t readCount;
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;
41 protected:
42 virtual ~gfxBaseSharedMemorySurface()
44 MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface);
47 public:
48 /**
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
52 * the surface failed.
54 * NB: the *caller* is responsible for freeing the Shmem allocated
55 * by this function.
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);
67 /**
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))
79 return nullptr;
81 gfxImageFormat format = (gfxImageFormat)shmInfo->format;
82 long stride = gfxImageSurface::ComputeStride(size, format);
84 nsRefPtr<Sub> s =
85 new Sub(size,
86 stride,
87 format,
88 aShmem);
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)
107 return (aSurface
108 && aSurface->GetType() == gfxSurfaceType::Image
109 && aSurface->GetData(&SHM_KEY));
112 protected:
113 gfxBaseSharedMemorySurface(const gfxIntSize& aSize, long aStride,
114 gfxImageFormat aFormat,
115 const Shmem& aShmem)
116 : Base(aShmem.get<unsigned char>(), aSize, aStride, aFormat)
118 MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface);
120 mShmem = aShmem;
121 this->SetData(&SHM_KEY, this, nullptr);
124 private:
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;
134 int32_t
135 ReadLock()
137 SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
138 return PR_ATOMIC_INCREMENT(&shmInfo->readCount);
141 int32_t
142 ReadUnlock()
144 SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
145 return PR_ATOMIC_DECREMENT(&shmInfo->readCount);
148 int32_t
149 GetReadCount()
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))
169 return nullptr;
171 Shmem shmem;
172 long stride = gfxImageSurface::ComputeStride(aSize, aFormat);
173 size_t size = GetAlignedSize(aSize, stride);
174 if (!Unsafe) {
175 if (!aAllocator->AllocShmem(size, aShmType, &shmem))
176 return nullptr;
177 } else {
178 if (!aAllocator->AllocUnsafeShmem(size, aShmType, &shmem))
179 return nullptr;
182 nsRefPtr<Sub> s =
183 new Sub(aSize, stride, aFormat, shmem);
184 if (s->CairoStatus() != 0) {
185 aAllocator->DeallocShmem(shmem);
186 return nullptr;
188 s->WriteShmemInfo();
189 return s.forget();
192 Shmem mShmem;
194 // Calling these is very bad, disallow it
195 gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface&);
196 gfxBaseSharedMemorySurface& operator=(const gfxBaseSharedMemorySurface&);
199 #endif /* GFX_SHARED_MEMORYSURFACE_H */