image/src/imgFrame.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  *
     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 imgFrame_h
     8 #define imgFrame_h
    10 #include "mozilla/MemoryReporting.h"
    11 #include "mozilla/Mutex.h"
    12 #include "mozilla/VolatileBuffer.h"
    13 #include "nsRect.h"
    14 #include "nsPoint.h"
    15 #include "nsSize.h"
    16 #include "gfxPattern.h"
    17 #include "gfxDrawable.h"
    18 #include "gfxImageSurface.h"
    19 #if defined(XP_WIN)
    20 #include "gfxWindowsSurface.h"
    21 #elif defined(XP_MACOSX)
    22 #include "gfxQuartzImageSurface.h"
    23 #endif
    24 #include "nsAutoPtr.h"
    25 #include "imgIContainer.h"
    26 #include "gfxColor.h"
    28 /*
    29  * This creates a gfxImageSurface which will unlock the buffer on destruction
    30  */
    32 class LockedImageSurface
    33 {
    34 public:
    35   static gfxImageSurface *
    36   CreateSurface(mozilla::VolatileBuffer *vbuf,
    37                 const gfxIntSize& size,
    38                 gfxImageFormat format);
    39   static mozilla::TemporaryRef<mozilla::VolatileBuffer>
    40   AllocateBuffer(const gfxIntSize& size, gfxImageFormat format);
    41 };
    43 class imgFrame
    44 {
    45 public:
    46   imgFrame();
    47   ~imgFrame();
    49   nsresult Init(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, gfxImageFormat aFormat, uint8_t aPaletteDepth = 0);
    50   nsresult Optimize();
    52   bool Draw(gfxContext *aContext, GraphicsFilter aFilter,
    53             const gfxMatrix &aUserSpaceToImageSpace, const gfxRect& aFill,
    54             const nsIntMargin &aPadding, const nsIntRect &aSubimage,
    55             uint32_t aImageFlags = imgIContainer::FLAG_NONE);
    57   nsresult ImageUpdated(const nsIntRect &aUpdateRect);
    58   bool GetIsDirty() const;
    60   nsIntRect GetRect() const;
    61   gfxImageFormat GetFormat() const;
    62   bool GetNeedsBackground() const;
    63   uint32_t GetImageBytesPerRow() const;
    64   uint32_t GetImageDataLength() const;
    65   bool GetIsPaletted() const;
    66   bool GetHasAlpha() const;
    67   void GetImageData(uint8_t **aData, uint32_t *length) const;
    68   uint8_t* GetImageData() const;
    69   void GetPaletteData(uint32_t **aPalette, uint32_t *length) const;
    70   uint32_t* GetPaletteData() const;
    72   int32_t GetRawTimeout() const;
    73   void SetRawTimeout(int32_t aTimeout);
    75   int32_t GetFrameDisposalMethod() const;
    76   void SetFrameDisposalMethod(int32_t aFrameDisposalMethod);
    77   int32_t GetBlendMethod() const;
    78   void SetBlendMethod(int32_t aBlendMethod);
    79   bool ImageComplete() const;
    81   void SetHasNoAlpha();
    82   void SetAsNonPremult(bool aIsNonPremult);
    84   bool GetCompositingFailed() const;
    85   void SetCompositingFailed(bool val);
    87   nsresult LockImageData();
    88   nsresult UnlockImageData();
    89   void ApplyDirtToSurfaces();
    91   void SetDiscardable();
    93   nsresult GetSurface(gfxASurface **aSurface)
    94   {
    95     *aSurface = ThebesSurface();
    96     NS_IF_ADDREF(*aSurface);
    97     return NS_OK;
    98   }
   100   nsresult GetPattern(gfxPattern **aPattern)
   101   {
   102     if (mSinglePixel)
   103       *aPattern = new gfxPattern(mSinglePixelColor);
   104     else
   105       *aPattern = new gfxPattern(ThebesSurface());
   106     NS_ADDREF(*aPattern);
   107     return NS_OK;
   108   }
   110   bool IsSinglePixel()
   111   {
   112     return mSinglePixel;
   113   }
   115   gfxASurface* CachedThebesSurface()
   116   {
   117     if (mOptSurface)
   118       return mOptSurface;
   119 #if defined(XP_WIN)
   120     if (mWinSurface)
   121       return mWinSurface;
   122 #elif defined(XP_MACOSX)
   123     if (mQuartzSurface)
   124       return mQuartzSurface;
   125 #endif
   126     if (mImageSurface)
   127       return mImageSurface;
   128     return nullptr;
   129   }
   131   gfxASurface* ThebesSurface()
   132   {
   133     gfxASurface *sur = CachedThebesSurface();
   134     if (sur)
   135       return sur;
   136     if (mVBuf) {
   137       mozilla::VolatileBufferPtr<uint8_t> ref(mVBuf);
   138       if (ref.WasBufferPurged())
   139         return nullptr;
   141       gfxImageSurface *imgSur =
   142         LockedImageSurface::CreateSurface(mVBuf, mSize, mFormat);
   143 #if defined(XP_MACOSX)
   144       // Manually addref and release to make sure the cairo surface isn't lost
   145       NS_ADDREF(imgSur);
   146       gfxQuartzImageSurface *quartzSur = new gfxQuartzImageSurface(imgSur);
   147       // quartzSur does not hold on to the gfxImageSurface
   148       NS_RELEASE(imgSur);
   149       return quartzSur;
   150 #else
   151       return imgSur;
   152 #endif
   153     }
   154     // We can return null here if we're single pixel optimized
   155     // or a paletted image. However, one has to check for paletted
   156     // image data first before attempting to get a surface, so
   157     // this is only valid for single pixel optimized images
   158     MOZ_ASSERT(mSinglePixel, "No image surface and not a single pixel!");
   159     return nullptr;
   160   }
   162   size_t SizeOfExcludingThisWithComputedFallbackIfHeap(
   163            gfxMemoryLocation aLocation,
   164            mozilla::MallocSizeOf aMallocSizeOf) const;
   166   uint8_t GetPaletteDepth() const { return mPaletteDepth; }
   167   uint32_t PaletteDataLength() const {
   168     if (!mPaletteDepth)
   169       return 0;
   171     return ((1 << mPaletteDepth) * sizeof(uint32_t));
   172   }
   174 private: // methods
   176   struct SurfaceWithFormat {
   177     nsRefPtr<gfxDrawable> mDrawable;
   178     gfxImageFormat mFormat;
   179     SurfaceWithFormat() {}
   180     SurfaceWithFormat(gfxDrawable* aDrawable, gfxImageFormat aFormat)
   181      : mDrawable(aDrawable), mFormat(aFormat) {}
   182     bool IsValid() { return !!mDrawable; }
   183   };
   185   SurfaceWithFormat SurfaceForDrawing(bool               aDoPadding,
   186                                       bool               aDoPartialDecode,
   187                                       bool               aDoTile,
   188                                       const nsIntMargin& aPadding,
   189                                       gfxMatrix&         aUserSpaceToImageSpace,
   190                                       gfxRect&           aFill,
   191                                       gfxRect&           aSubimage,
   192                                       gfxRect&           aSourceRect,
   193                                       gfxRect&           aImageRect,
   194                                       gfxASurface*       aSurface);
   196 private: // data
   197   nsRefPtr<gfxImageSurface> mImageSurface;
   198   nsRefPtr<gfxASurface> mOptSurface;
   199 #if defined(XP_WIN)
   200   nsRefPtr<gfxWindowsSurface> mWinSurface;
   201 #elif defined(XP_MACOSX)
   202   nsRefPtr<gfxQuartzImageSurface> mQuartzSurface;
   203 #endif
   205   nsRefPtr<gfxASurface> mDrawSurface;
   207   nsIntSize    mSize;
   208   nsIntPoint   mOffset;
   210   nsIntRect    mDecoded;
   212   mutable mozilla::Mutex mDirtyMutex;
   214   // The palette and image data for images that are paletted, since Cairo
   215   // doesn't support these images.
   216   // The paletted data comes first, then the image data itself.
   217   // Total length is PaletteDataLength() + GetImageDataLength().
   218   uint8_t*     mPalettedImageData;
   220   // Note that the data stored in gfxRGBA is *non-alpha-premultiplied*.
   221   gfxRGBA      mSinglePixelColor;
   223   int32_t      mTimeout; // -1 means display forever
   224   int32_t      mDisposalMethod;
   226   /** Indicates how many readers currently have locked this frame */
   227   int32_t mLockCount;
   229   mozilla::RefPtr<mozilla::VolatileBuffer> mVBuf;
   231   gfxImageFormat mFormat;
   232   uint8_t      mPaletteDepth;
   233   int8_t       mBlendMethod;
   234   bool mSinglePixel;
   235   bool mFormatChanged;
   236   bool mCompositingFailed;
   237   bool mNonPremult;
   238   bool mDiscardable;
   240   /** Have we called DiscardTracker::InformAllocation()? */
   241   bool mInformedDiscardTracker;
   243   bool mDirty;
   244 };
   246 namespace mozilla {
   247 namespace image {
   248   // An RAII class to ensure it's easy to balance locks and unlocks on
   249   // imgFrames.
   250   class AutoFrameLocker
   251   {
   252   public:
   253     AutoFrameLocker(imgFrame* frame)
   254       : mFrame(frame)
   255       , mSucceeded(NS_SUCCEEDED(frame->LockImageData()))
   256     {}
   258     ~AutoFrameLocker()
   259     {
   260       if (mSucceeded) {
   261         mFrame->UnlockImageData();
   262       }
   263     }
   265     // Whether the lock request succeeded.
   266     bool Succeeded() { return mSucceeded; }
   268   private:
   269     imgFrame* mFrame;
   270     bool mSucceeded;
   271   };
   272 }
   273 }
   275 #endif /* imgFrame_h */

mercurial