image/src/imgFrame.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial