gfx/thebes/gfxBaseSharedMemorySurface.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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;
    24 };
    26 inline SharedImageInfo*
    27 GetShmInfoPtr(const mozilla::ipc::Shmem& aShmem)
    28 {
    29     return reinterpret_cast<SharedImageInfo*>
    30         (aShmem.get<char>() + aShmem.Size<char>() - sizeof(SharedImageInfo));
    31 }
    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 public:
    42     virtual ~gfxBaseSharedMemorySurface()
    43     {
    44         MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface);
    45     }
    47     /**
    48      * Return a new gfxSharedImageSurface around a shmem segment newly
    49      * allocated by this function.  |aAllocator| is the object used to
    50      * allocate the new shmem segment.  Null is returned if creating
    51      * the surface failed.
    52      *
    53      * NB: the *caller* is responsible for freeing the Shmem allocated
    54      * by this function.
    55      */
    56     template<class ShmemAllocator>
    57     static already_AddRefed<Sub>
    58     Create(ShmemAllocator* aAllocator,
    59            const gfxIntSize& aSize,
    60            gfxImageFormat aFormat,
    61            SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
    62     {
    63         return Create<ShmemAllocator, false>(aAllocator, aSize, aFormat, aShmType);
    64     }
    66     /**
    67      * Return a new gfxSharedImageSurface that wraps a shmem segment
    68      * already created by the Create() above.  Bad things will happen
    69      * if an attempt is made to wrap any other shmem segment.  Null is
    70      * returned if creating the surface failed.
    71      */
    72     static already_AddRefed<Sub>
    73     Open(const Shmem& aShmem)
    74     {
    75         SharedImageInfo* shmInfo = GetShmInfoPtr(aShmem);
    76         gfxIntSize size(shmInfo->width, shmInfo->height);
    77         if (!gfxASurface::CheckSurfaceSize(size))
    78             return nullptr;
    80         gfxImageFormat format = (gfxImageFormat)shmInfo->format;
    81         long stride = gfxImageSurface::ComputeStride(size, format);
    83         nsRefPtr<Sub> s =
    84             new Sub(size,
    85                     stride,
    86                     format,
    87                     aShmem);
    88         // We didn't create this Shmem and so don't free it on errors
    89         return (s->CairoStatus() != 0) ? nullptr : s.forget();
    90     }
    92     template<class ShmemAllocator>
    93     static already_AddRefed<Sub>
    94     CreateUnsafe(ShmemAllocator* aAllocator,
    95                  const gfxIntSize& aSize,
    96                  gfxImageFormat aFormat,
    97                  SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
    98     {
    99         return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat, aShmType);
   100     }
   102     Shmem& GetShmem() { return mShmem; }
   104     static bool IsSharedImage(gfxASurface *aSurface)
   105     {
   106         return (aSurface
   107                 && aSurface->GetType() == gfxSurfaceType::Image
   108                 && aSurface->GetData(&SHM_KEY));
   109     }
   111 protected:
   112     gfxBaseSharedMemorySurface(const gfxIntSize& aSize, long aStride, 
   113                                gfxImageFormat aFormat, 
   114                                const Shmem& aShmem)
   115       : Base(aShmem.get<unsigned char>(), aSize, aStride, aFormat)
   116     {
   117         MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface);
   119         mShmem = aShmem;
   120         this->SetData(&SHM_KEY, this, nullptr);
   121     }
   123 private:
   124     void WriteShmemInfo()
   125     {
   126         SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
   127         shmInfo->width = this->mSize.width;
   128         shmInfo->height = this->mSize.height;
   129         shmInfo->format = this->mFormat;
   130         shmInfo->readCount = 0;
   131     }
   133     int32_t
   134     ReadLock()
   135     {
   136         SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
   137         return PR_ATOMIC_INCREMENT(&shmInfo->readCount);
   138     }
   140     int32_t
   141     ReadUnlock()
   142     {
   143         SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
   144         return PR_ATOMIC_DECREMENT(&shmInfo->readCount);
   145     }
   147     int32_t
   148     GetReadCount()
   149     {
   150         SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
   151         return shmInfo->readCount;
   152     }
   154     static size_t GetAlignedSize(const gfxIntSize& aSize, long aStride)
   155     {
   156         #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
   157         return MOZ_ALIGN_WORD(sizeof(SharedImageInfo) + aSize.height * aStride);
   158     }
   160     template<class ShmemAllocator, bool Unsafe>
   161     static already_AddRefed<Sub>
   162     Create(ShmemAllocator* aAllocator,
   163            const gfxIntSize& aSize,
   164            gfxImageFormat aFormat,
   165            SharedMemory::SharedMemoryType aShmType)
   166     {
   167         if (!gfxASurface::CheckSurfaceSize(aSize))
   168             return nullptr;
   170         Shmem shmem;
   171         long stride = gfxImageSurface::ComputeStride(aSize, aFormat);
   172         size_t size = GetAlignedSize(aSize, stride);
   173         if (!Unsafe) {
   174             if (!aAllocator->AllocShmem(size, aShmType, &shmem))
   175                 return nullptr;
   176         } else {
   177             if (!aAllocator->AllocUnsafeShmem(size, aShmType, &shmem))
   178                 return nullptr;
   179         }
   181         nsRefPtr<Sub> s =
   182             new Sub(aSize, stride, aFormat, shmem);
   183         if (s->CairoStatus() != 0) {
   184             aAllocator->DeallocShmem(shmem);
   185             return nullptr;
   186         }
   187         s->WriteShmemInfo();
   188         return s.forget();
   189     }
   191     Shmem mShmem;
   193     // Calling these is very bad, disallow it
   194     gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface&);
   195     gfxBaseSharedMemorySurface& operator=(const gfxBaseSharedMemorySurface&);
   196 };
   198 #endif /* GFX_SHARED_MEMORYSURFACE_H */

mercurial