Bug 835381 - Update libnestegg to 38c83d9d4c0c5c84373aa285bd30094a12d6b6f6. r=kinetik
[gecko.git] / gfx / thebes / gfxBaseSharedMemorySurface.h
blobc6b4b23016f231293c30ddd2cf813492baa57e81
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 "cairo.h"
17 struct SharedImageInfo {
18 int32_t width;
19 int32_t height;
20 int32_t format;
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;
37 public:
38 virtual ~gfxBaseSharedMemorySurface()
40 MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface);
43 /**
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
47 * the surface failed.
49 * NB: the *caller* is responsible for freeing the Shmem allocated
50 * by this function.
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);
62 /**
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))
74 return nullptr;
76 gfxASurface::gfxImageFormat format = (gfxASurface::gfxImageFormat)shmInfo->format;
77 long stride = gfxImageSurface::ComputeStride(size, format);
79 nsRefPtr<Sub> s =
80 new Sub(size,
81 stride,
82 format,
83 aShmem);
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)
102 return (aSurface
103 && aSurface->GetType() == gfxASurface::SurfaceTypeImage
104 && aSurface->GetData(&SHM_KEY));
107 protected:
108 gfxBaseSharedMemorySurface(const gfxIntSize& aSize, long aStride,
109 gfxASurface::gfxImageFormat aFormat,
110 const Shmem& aShmem)
111 : Base(aShmem.get<unsigned char>(), aSize, aStride, aFormat)
113 MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface);
115 mShmem = aShmem;
116 this->SetData(&SHM_KEY, this, nullptr);
119 private:
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))
142 return nullptr;
144 Shmem shmem;
145 long stride = gfxImageSurface::ComputeStride(aSize, aFormat);
146 size_t size = GetAlignedSize(aSize, stride);
147 if (!Unsafe) {
148 if (!aAllocator->AllocShmem(size, aShmType, &shmem))
149 return nullptr;
150 } else {
151 if (!aAllocator->AllocUnsafeShmem(size, aShmType, &shmem))
152 return nullptr;
155 nsRefPtr<Sub> s =
156 new Sub(aSize, stride, aFormat, shmem);
157 if (s->CairoStatus() != 0) {
158 aAllocator->DeallocShmem(shmem);
159 return nullptr;
161 s->WriteShmemInfo();
162 return s.forget();
165 Shmem mShmem;
167 // Calling these is very bad, disallow it
168 gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface&);
169 gfxBaseSharedMemorySurface& operator=(const gfxBaseSharedMemorySurface&);
172 #endif /* GFX_SHARED_MEMORYSURFACE_H */