1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/thebes/gfxASurface.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,290 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef GFX_ASURFACE_H 1.10 +#define GFX_ASURFACE_H 1.11 + 1.12 +#include "mozilla/MemoryReporting.h" 1.13 +#include "gfxTypes.h" 1.14 +#include "mozilla/Scoped.h" 1.15 +#include "nscore.h" 1.16 +#include "nsSize.h" 1.17 + 1.18 +#ifdef MOZILLA_INTERNAL_API 1.19 +#include "nsStringFwd.h" 1.20 +#else 1.21 +#include "nsStringAPI.h" 1.22 +#endif 1.23 + 1.24 +class gfxImageSurface; 1.25 +struct nsIntPoint; 1.26 +struct nsIntRect; 1.27 +struct gfxRect; 1.28 +struct gfxPoint; 1.29 + 1.30 +template <typename T> 1.31 +struct already_AddRefed; 1.32 + 1.33 +/** 1.34 + * A surface is something you can draw on. Instantiate a subclass of this 1.35 + * abstract class, and use gfxContext to draw on this surface. 1.36 + */ 1.37 +class gfxASurface { 1.38 +public: 1.39 +#ifdef MOZILLA_INTERNAL_API 1.40 + nsrefcnt AddRef(void); 1.41 + nsrefcnt Release(void); 1.42 + 1.43 + // These functions exist so that browsercomps can refcount a gfxASurface 1.44 + virtual nsrefcnt AddRefExternal(void); 1.45 + virtual nsrefcnt ReleaseExternal(void); 1.46 +#else 1.47 + virtual nsrefcnt AddRef(void); 1.48 + virtual nsrefcnt Release(void); 1.49 +#endif 1.50 + 1.51 +public: 1.52 + 1.53 + /** Wrap the given cairo surface and return a gfxASurface for it. 1.54 + * This adds a reference to csurf (owned by the returned gfxASurface). 1.55 + */ 1.56 + static already_AddRefed<gfxASurface> Wrap(cairo_surface_t *csurf, const gfxIntSize& aSize = gfxIntSize(-1, -1)); 1.57 + 1.58 + /*** this DOES NOT addref the surface */ 1.59 + cairo_surface_t *CairoSurface() { 1.60 + return mSurface; 1.61 + } 1.62 + 1.63 + gfxSurfaceType GetType() const; 1.64 + 1.65 + gfxContentType GetContentType() const; 1.66 + 1.67 + void SetDeviceOffset(const gfxPoint& offset); 1.68 + gfxPoint GetDeviceOffset() const; 1.69 + 1.70 + virtual bool GetRotateForLandscape() { return false; } 1.71 + 1.72 + void Flush() const; 1.73 + void MarkDirty(); 1.74 + void MarkDirty(const gfxRect& r); 1.75 + 1.76 + /* Printing backend functions */ 1.77 + virtual nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName); 1.78 + virtual nsresult EndPrinting(); 1.79 + virtual nsresult AbortPrinting(); 1.80 + virtual nsresult BeginPage(); 1.81 + virtual nsresult EndPage(); 1.82 + 1.83 + void SetData(const cairo_user_data_key_t *key, 1.84 + void *user_data, 1.85 + thebes_destroy_func_t destroy); 1.86 + void *GetData(const cairo_user_data_key_t *key); 1.87 + 1.88 + virtual void Finish(); 1.89 + 1.90 + /** 1.91 + * Create an offscreen surface that can be efficiently copied into 1.92 + * this surface (at least if tiling is not involved). 1.93 + * Returns null on error. 1.94 + */ 1.95 + virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType, 1.96 + const nsIntSize& aSize); 1.97 + 1.98 + /** 1.99 + * Returns an image surface for this surface, or nullptr if not supported. 1.100 + * This will not copy image data, just wraps an image surface around 1.101 + * pixel data already available in memory. 1.102 + */ 1.103 + virtual already_AddRefed<gfxImageSurface> GetAsImageSurface(); 1.104 + 1.105 + /** 1.106 + * Returns a read-only ARGB32 image surface for this surface. If this is an 1.107 + * optimized surface this may require a copy. 1.108 + * Returns null on error. 1.109 + */ 1.110 + virtual already_AddRefed<gfxImageSurface> GetAsReadableARGB32ImageSurface(); 1.111 + 1.112 + /** 1.113 + * Creates a new ARGB32 image surface with the same contents as this surface. 1.114 + * Returns null on error. 1.115 + */ 1.116 + already_AddRefed<gfxImageSurface> CopyToARGB32ImageSurface(); 1.117 + 1.118 + int CairoStatus(); 1.119 + 1.120 + /* Make sure that the given dimensions don't overflow a 32-bit signed int 1.121 + * using 4 bytes per pixel; optionally, make sure that either dimension 1.122 + * doesn't exceed the given limit. 1.123 + */ 1.124 + static bool CheckSurfaceSize(const nsIntSize& sz, int32_t limit = 0); 1.125 + 1.126 + /* Provide a stride value that will respect all alignment requirements of 1.127 + * the accelerated image-rendering code. 1.128 + */ 1.129 + static int32_t FormatStrideForWidth(gfxImageFormat format, int32_t width); 1.130 + 1.131 + /* Return the default set of context flags for this surface; these are 1.132 + * hints to the context about any special rendering considerations. See 1.133 + * gfxContext::SetFlag for documentation. 1.134 + */ 1.135 + virtual int32_t GetDefaultContextFlags() const { return 0; } 1.136 + 1.137 + static gfxContentType ContentFromFormat(gfxImageFormat format); 1.138 + 1.139 + void SetSubpixelAntialiasingEnabled(bool aEnabled); 1.140 + bool GetSubpixelAntialiasingEnabled(); 1.141 + 1.142 + /** 1.143 + * Record number of bytes for given surface type. Use positive bytes 1.144 + * for allocations and negative bytes for deallocations. 1.145 + */ 1.146 + static void RecordMemoryUsedForSurfaceType(gfxSurfaceType aType, 1.147 + int32_t aBytes); 1.148 + 1.149 + /** 1.150 + * Same as above, but use current surface type as returned by GetType(). 1.151 + * The bytes will be accumulated until RecordMemoryFreed is called, 1.152 + * in which case the value that was recorded for this surface will 1.153 + * be freed. 1.154 + */ 1.155 + void RecordMemoryUsed(int32_t aBytes); 1.156 + void RecordMemoryFreed(); 1.157 + 1.158 + virtual int32_t KnownMemoryUsed() { return mBytesRecorded; } 1.159 + 1.160 + virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.161 + virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.162 + // gfxASurface has many sub-classes. This method indicates if a sub-class 1.163 + // is capable of measuring its own size accurately. If not, the caller 1.164 + // must fall back to a computed size. (Note that gfxASurface can actually 1.165 + // measure itself, but we must |return false| here because it serves as the 1.166 + // (conservative) default for all the sub-classes. Therefore, this 1.167 + // function should only be called on a |gfxASurface*| that actually points 1.168 + // to a sub-class of gfxASurface.) 1.169 + virtual bool SizeOfIsMeasured() const { return false; } 1.170 + 1.171 + /** 1.172 + * Where does this surface's memory live? By default, we say it's in this 1.173 + * process's heap. 1.174 + */ 1.175 + virtual gfxMemoryLocation GetMemoryLocation() const; 1.176 + 1.177 + static int32_t BytePerPixelFromFormat(gfxImageFormat format); 1.178 + 1.179 + virtual const nsIntSize GetSize() const; 1.180 + 1.181 + /** 1.182 + * Debug functions to encode the current image as a PNG and export it. 1.183 + */ 1.184 + 1.185 + /** 1.186 + * Writes a binary PNG file. 1.187 + */ 1.188 + void WriteAsPNG(const char* aFile); 1.189 + 1.190 + /** 1.191 + * Write as a PNG encoded Data URL to a file. 1.192 + */ 1.193 + void DumpAsDataURL(FILE* aOutput = stdout); 1.194 + 1.195 + /** 1.196 + * Write as a PNG encoded Data URL to stdout. 1.197 + */ 1.198 + void PrintAsDataURL(); 1.199 + 1.200 + /** 1.201 + * Copy a PNG encoded Data URL to the clipboard. 1.202 + */ 1.203 + void CopyAsDataURL(); 1.204 + 1.205 + void WriteAsPNG_internal(FILE* aFile, bool aBinary); 1.206 + 1.207 + void SetOpaqueRect(const gfxRect& aRect); 1.208 + 1.209 + const gfxRect& GetOpaqueRect() { 1.210 + if (!!mOpaqueRect) 1.211 + return *mOpaqueRect; 1.212 + return GetEmptyOpaqueRect(); 1.213 + } 1.214 + 1.215 + /** 1.216 + * Move the pixels in |aSourceRect| to |aDestTopLeft|. Like with 1.217 + * memmove(), |aSourceRect| and the rectangle defined by 1.218 + * |aDestTopLeft| are allowed to overlap, and the effect is 1.219 + * equivalent to copying |aSourceRect| to a scratch surface and 1.220 + * then back to |aDestTopLeft|. 1.221 + * 1.222 + * |aSourceRect| and the destination rectangle defined by 1.223 + * |aDestTopLeft| are clipped to this surface's bounds. 1.224 + */ 1.225 + virtual void MovePixels(const nsIntRect& aSourceRect, 1.226 + const nsIntPoint& aDestTopLeft); 1.227 + 1.228 + /** 1.229 + * Mark the surface as being allowed/not allowed to be used as a source. 1.230 + */ 1.231 + void SetAllowUseAsSource(bool aAllow) { mAllowUseAsSource = aAllow; } 1.232 + bool GetAllowUseAsSource() { return mAllowUseAsSource; } 1.233 + 1.234 + static uint8_t BytesPerPixel(gfxImageFormat aImageFormat); 1.235 + 1.236 +protected: 1.237 + gfxASurface(); 1.238 + 1.239 + static gfxASurface* GetSurfaceWrapper(cairo_surface_t *csurf); 1.240 + static void SetSurfaceWrapper(cairo_surface_t *csurf, gfxASurface *asurf); 1.241 + 1.242 + /** 1.243 + * An implementation of MovePixels that assumes the backend can 1.244 + * internally handle this operation and doesn't allocate any 1.245 + * temporary surfaces. 1.246 + */ 1.247 + void FastMovePixels(const nsIntRect& aSourceRect, 1.248 + const nsIntPoint& aDestTopLeft); 1.249 + 1.250 + // NB: Init() *must* be called from within subclass's 1.251 + // constructors. It's unsafe to call it after the ctor finishes; 1.252 + // leaks and use-after-frees are possible. 1.253 + void Init(cairo_surface_t *surface, bool existingSurface = false); 1.254 + 1.255 + // out-of-line helper to allow GetOpaqueRect() to be inlined 1.256 + // without including gfxRect.h here 1.257 + static const gfxRect& GetEmptyOpaqueRect(); 1.258 + 1.259 + virtual ~gfxASurface(); 1.260 + 1.261 + cairo_surface_t *mSurface; 1.262 + mozilla::ScopedDeletePtr<gfxRect> mOpaqueRect; 1.263 + 1.264 +private: 1.265 + static void SurfaceDestroyFunc(void *data); 1.266 + 1.267 + int32_t mFloatingRefs; 1.268 + int32_t mBytesRecorded; 1.269 + 1.270 +protected: 1.271 + bool mSurfaceValid; 1.272 + bool mAllowUseAsSource; 1.273 +}; 1.274 + 1.275 +/** 1.276 + * An Unknown surface; used to wrap unknown cairo_surface_t returns from cairo 1.277 + */ 1.278 +class gfxUnknownSurface : public gfxASurface { 1.279 +public: 1.280 + gfxUnknownSurface(cairo_surface_t *surf, const gfxIntSize& aSize) 1.281 + : mSize(aSize) 1.282 + { 1.283 + Init(surf, true); 1.284 + } 1.285 + 1.286 + virtual ~gfxUnknownSurface() { } 1.287 + virtual const nsIntSize GetSize() const { return mSize; } 1.288 + 1.289 +private: 1.290 + nsIntSize mSize; 1.291 +}; 1.292 + 1.293 +#endif /* GFX_ASURFACE_H */