gfx/thebes/gfxASurface.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: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef GFX_ASURFACE_H
michael@0 7 #define GFX_ASURFACE_H
michael@0 8
michael@0 9 #include "mozilla/MemoryReporting.h"
michael@0 10 #include "gfxTypes.h"
michael@0 11 #include "mozilla/Scoped.h"
michael@0 12 #include "nscore.h"
michael@0 13 #include "nsSize.h"
michael@0 14
michael@0 15 #ifdef MOZILLA_INTERNAL_API
michael@0 16 #include "nsStringFwd.h"
michael@0 17 #else
michael@0 18 #include "nsStringAPI.h"
michael@0 19 #endif
michael@0 20
michael@0 21 class gfxImageSurface;
michael@0 22 struct nsIntPoint;
michael@0 23 struct nsIntRect;
michael@0 24 struct gfxRect;
michael@0 25 struct gfxPoint;
michael@0 26
michael@0 27 template <typename T>
michael@0 28 struct already_AddRefed;
michael@0 29
michael@0 30 /**
michael@0 31 * A surface is something you can draw on. Instantiate a subclass of this
michael@0 32 * abstract class, and use gfxContext to draw on this surface.
michael@0 33 */
michael@0 34 class gfxASurface {
michael@0 35 public:
michael@0 36 #ifdef MOZILLA_INTERNAL_API
michael@0 37 nsrefcnt AddRef(void);
michael@0 38 nsrefcnt Release(void);
michael@0 39
michael@0 40 // These functions exist so that browsercomps can refcount a gfxASurface
michael@0 41 virtual nsrefcnt AddRefExternal(void);
michael@0 42 virtual nsrefcnt ReleaseExternal(void);
michael@0 43 #else
michael@0 44 virtual nsrefcnt AddRef(void);
michael@0 45 virtual nsrefcnt Release(void);
michael@0 46 #endif
michael@0 47
michael@0 48 public:
michael@0 49
michael@0 50 /** Wrap the given cairo surface and return a gfxASurface for it.
michael@0 51 * This adds a reference to csurf (owned by the returned gfxASurface).
michael@0 52 */
michael@0 53 static already_AddRefed<gfxASurface> Wrap(cairo_surface_t *csurf, const gfxIntSize& aSize = gfxIntSize(-1, -1));
michael@0 54
michael@0 55 /*** this DOES NOT addref the surface */
michael@0 56 cairo_surface_t *CairoSurface() {
michael@0 57 return mSurface;
michael@0 58 }
michael@0 59
michael@0 60 gfxSurfaceType GetType() const;
michael@0 61
michael@0 62 gfxContentType GetContentType() const;
michael@0 63
michael@0 64 void SetDeviceOffset(const gfxPoint& offset);
michael@0 65 gfxPoint GetDeviceOffset() const;
michael@0 66
michael@0 67 virtual bool GetRotateForLandscape() { return false; }
michael@0 68
michael@0 69 void Flush() const;
michael@0 70 void MarkDirty();
michael@0 71 void MarkDirty(const gfxRect& r);
michael@0 72
michael@0 73 /* Printing backend functions */
michael@0 74 virtual nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName);
michael@0 75 virtual nsresult EndPrinting();
michael@0 76 virtual nsresult AbortPrinting();
michael@0 77 virtual nsresult BeginPage();
michael@0 78 virtual nsresult EndPage();
michael@0 79
michael@0 80 void SetData(const cairo_user_data_key_t *key,
michael@0 81 void *user_data,
michael@0 82 thebes_destroy_func_t destroy);
michael@0 83 void *GetData(const cairo_user_data_key_t *key);
michael@0 84
michael@0 85 virtual void Finish();
michael@0 86
michael@0 87 /**
michael@0 88 * Create an offscreen surface that can be efficiently copied into
michael@0 89 * this surface (at least if tiling is not involved).
michael@0 90 * Returns null on error.
michael@0 91 */
michael@0 92 virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
michael@0 93 const nsIntSize& aSize);
michael@0 94
michael@0 95 /**
michael@0 96 * Returns an image surface for this surface, or nullptr if not supported.
michael@0 97 * This will not copy image data, just wraps an image surface around
michael@0 98 * pixel data already available in memory.
michael@0 99 */
michael@0 100 virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
michael@0 101
michael@0 102 /**
michael@0 103 * Returns a read-only ARGB32 image surface for this surface. If this is an
michael@0 104 * optimized surface this may require a copy.
michael@0 105 * Returns null on error.
michael@0 106 */
michael@0 107 virtual already_AddRefed<gfxImageSurface> GetAsReadableARGB32ImageSurface();
michael@0 108
michael@0 109 /**
michael@0 110 * Creates a new ARGB32 image surface with the same contents as this surface.
michael@0 111 * Returns null on error.
michael@0 112 */
michael@0 113 already_AddRefed<gfxImageSurface> CopyToARGB32ImageSurface();
michael@0 114
michael@0 115 int CairoStatus();
michael@0 116
michael@0 117 /* Make sure that the given dimensions don't overflow a 32-bit signed int
michael@0 118 * using 4 bytes per pixel; optionally, make sure that either dimension
michael@0 119 * doesn't exceed the given limit.
michael@0 120 */
michael@0 121 static bool CheckSurfaceSize(const nsIntSize& sz, int32_t limit = 0);
michael@0 122
michael@0 123 /* Provide a stride value that will respect all alignment requirements of
michael@0 124 * the accelerated image-rendering code.
michael@0 125 */
michael@0 126 static int32_t FormatStrideForWidth(gfxImageFormat format, int32_t width);
michael@0 127
michael@0 128 /* Return the default set of context flags for this surface; these are
michael@0 129 * hints to the context about any special rendering considerations. See
michael@0 130 * gfxContext::SetFlag for documentation.
michael@0 131 */
michael@0 132 virtual int32_t GetDefaultContextFlags() const { return 0; }
michael@0 133
michael@0 134 static gfxContentType ContentFromFormat(gfxImageFormat format);
michael@0 135
michael@0 136 void SetSubpixelAntialiasingEnabled(bool aEnabled);
michael@0 137 bool GetSubpixelAntialiasingEnabled();
michael@0 138
michael@0 139 /**
michael@0 140 * Record number of bytes for given surface type. Use positive bytes
michael@0 141 * for allocations and negative bytes for deallocations.
michael@0 142 */
michael@0 143 static void RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
michael@0 144 int32_t aBytes);
michael@0 145
michael@0 146 /**
michael@0 147 * Same as above, but use current surface type as returned by GetType().
michael@0 148 * The bytes will be accumulated until RecordMemoryFreed is called,
michael@0 149 * in which case the value that was recorded for this surface will
michael@0 150 * be freed.
michael@0 151 */
michael@0 152 void RecordMemoryUsed(int32_t aBytes);
michael@0 153 void RecordMemoryFreed();
michael@0 154
michael@0 155 virtual int32_t KnownMemoryUsed() { return mBytesRecorded; }
michael@0 156
michael@0 157 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
michael@0 158 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
michael@0 159 // gfxASurface has many sub-classes. This method indicates if a sub-class
michael@0 160 // is capable of measuring its own size accurately. If not, the caller
michael@0 161 // must fall back to a computed size. (Note that gfxASurface can actually
michael@0 162 // measure itself, but we must |return false| here because it serves as the
michael@0 163 // (conservative) default for all the sub-classes. Therefore, this
michael@0 164 // function should only be called on a |gfxASurface*| that actually points
michael@0 165 // to a sub-class of gfxASurface.)
michael@0 166 virtual bool SizeOfIsMeasured() const { return false; }
michael@0 167
michael@0 168 /**
michael@0 169 * Where does this surface's memory live? By default, we say it's in this
michael@0 170 * process's heap.
michael@0 171 */
michael@0 172 virtual gfxMemoryLocation GetMemoryLocation() const;
michael@0 173
michael@0 174 static int32_t BytePerPixelFromFormat(gfxImageFormat format);
michael@0 175
michael@0 176 virtual const nsIntSize GetSize() const;
michael@0 177
michael@0 178 /**
michael@0 179 * Debug functions to encode the current image as a PNG and export it.
michael@0 180 */
michael@0 181
michael@0 182 /**
michael@0 183 * Writes a binary PNG file.
michael@0 184 */
michael@0 185 void WriteAsPNG(const char* aFile);
michael@0 186
michael@0 187 /**
michael@0 188 * Write as a PNG encoded Data URL to a file.
michael@0 189 */
michael@0 190 void DumpAsDataURL(FILE* aOutput = stdout);
michael@0 191
michael@0 192 /**
michael@0 193 * Write as a PNG encoded Data URL to stdout.
michael@0 194 */
michael@0 195 void PrintAsDataURL();
michael@0 196
michael@0 197 /**
michael@0 198 * Copy a PNG encoded Data URL to the clipboard.
michael@0 199 */
michael@0 200 void CopyAsDataURL();
michael@0 201
michael@0 202 void WriteAsPNG_internal(FILE* aFile, bool aBinary);
michael@0 203
michael@0 204 void SetOpaqueRect(const gfxRect& aRect);
michael@0 205
michael@0 206 const gfxRect& GetOpaqueRect() {
michael@0 207 if (!!mOpaqueRect)
michael@0 208 return *mOpaqueRect;
michael@0 209 return GetEmptyOpaqueRect();
michael@0 210 }
michael@0 211
michael@0 212 /**
michael@0 213 * Move the pixels in |aSourceRect| to |aDestTopLeft|. Like with
michael@0 214 * memmove(), |aSourceRect| and the rectangle defined by
michael@0 215 * |aDestTopLeft| are allowed to overlap, and the effect is
michael@0 216 * equivalent to copying |aSourceRect| to a scratch surface and
michael@0 217 * then back to |aDestTopLeft|.
michael@0 218 *
michael@0 219 * |aSourceRect| and the destination rectangle defined by
michael@0 220 * |aDestTopLeft| are clipped to this surface's bounds.
michael@0 221 */
michael@0 222 virtual void MovePixels(const nsIntRect& aSourceRect,
michael@0 223 const nsIntPoint& aDestTopLeft);
michael@0 224
michael@0 225 /**
michael@0 226 * Mark the surface as being allowed/not allowed to be used as a source.
michael@0 227 */
michael@0 228 void SetAllowUseAsSource(bool aAllow) { mAllowUseAsSource = aAllow; }
michael@0 229 bool GetAllowUseAsSource() { return mAllowUseAsSource; }
michael@0 230
michael@0 231 static uint8_t BytesPerPixel(gfxImageFormat aImageFormat);
michael@0 232
michael@0 233 protected:
michael@0 234 gfxASurface();
michael@0 235
michael@0 236 static gfxASurface* GetSurfaceWrapper(cairo_surface_t *csurf);
michael@0 237 static void SetSurfaceWrapper(cairo_surface_t *csurf, gfxASurface *asurf);
michael@0 238
michael@0 239 /**
michael@0 240 * An implementation of MovePixels that assumes the backend can
michael@0 241 * internally handle this operation and doesn't allocate any
michael@0 242 * temporary surfaces.
michael@0 243 */
michael@0 244 void FastMovePixels(const nsIntRect& aSourceRect,
michael@0 245 const nsIntPoint& aDestTopLeft);
michael@0 246
michael@0 247 // NB: Init() *must* be called from within subclass's
michael@0 248 // constructors. It's unsafe to call it after the ctor finishes;
michael@0 249 // leaks and use-after-frees are possible.
michael@0 250 void Init(cairo_surface_t *surface, bool existingSurface = false);
michael@0 251
michael@0 252 // out-of-line helper to allow GetOpaqueRect() to be inlined
michael@0 253 // without including gfxRect.h here
michael@0 254 static const gfxRect& GetEmptyOpaqueRect();
michael@0 255
michael@0 256 virtual ~gfxASurface();
michael@0 257
michael@0 258 cairo_surface_t *mSurface;
michael@0 259 mozilla::ScopedDeletePtr<gfxRect> mOpaqueRect;
michael@0 260
michael@0 261 private:
michael@0 262 static void SurfaceDestroyFunc(void *data);
michael@0 263
michael@0 264 int32_t mFloatingRefs;
michael@0 265 int32_t mBytesRecorded;
michael@0 266
michael@0 267 protected:
michael@0 268 bool mSurfaceValid;
michael@0 269 bool mAllowUseAsSource;
michael@0 270 };
michael@0 271
michael@0 272 /**
michael@0 273 * An Unknown surface; used to wrap unknown cairo_surface_t returns from cairo
michael@0 274 */
michael@0 275 class gfxUnknownSurface : public gfxASurface {
michael@0 276 public:
michael@0 277 gfxUnknownSurface(cairo_surface_t *surf, const gfxIntSize& aSize)
michael@0 278 : mSize(aSize)
michael@0 279 {
michael@0 280 Init(surf, true);
michael@0 281 }
michael@0 282
michael@0 283 virtual ~gfxUnknownSurface() { }
michael@0 284 virtual const nsIntSize GetSize() const { return mSize; }
michael@0 285
michael@0 286 private:
michael@0 287 nsIntSize mSize;
michael@0 288 };
michael@0 289
michael@0 290 #endif /* GFX_ASURFACE_H */

mercurial