michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef GFXCOWSURFACEWRAPPER michael@0: #define GFXCOWSURFACEWRAPPER michael@0: michael@0: #include "gfxImageSurface.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsAutoPtr.h" michael@0: michael@0: michael@0: /** michael@0: * Provides an interface to implement a cross thread/process wrapper for a michael@0: * gfxImageSurface that has copy-on-write semantics. michael@0: * michael@0: * Only the owner thread can write to the surface and acquire michael@0: * read locks. Destroying a gfxReusableSurfaceWrapper releases michael@0: * a read lock. michael@0: * michael@0: * OMTC Usage: michael@0: * 1) Content creates a writable copy of this surface michael@0: * wrapper which will be optimized to the same wrapper if there michael@0: * are no readers. michael@0: * 2) The surface is sent from content to the compositor once michael@0: * or potentially many times, each increasing a read lock. michael@0: * 3) When the compositor receives the surface, it adopts the michael@0: * read lock. michael@0: * 4) Once the compositor has processed the surface and uploaded michael@0: * the content, it then releases the read lock by dereferencing michael@0: * its wrapper. michael@0: */ michael@0: class gfxReusableSurfaceWrapper { michael@0: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxReusableSurfaceWrapper) michael@0: public: michael@0: michael@0: /** michael@0: * Returns a read-only pointer to the image data. michael@0: */ michael@0: virtual const unsigned char* GetReadOnlyData() const = 0; michael@0: michael@0: /** michael@0: * Returns the image surface format. michael@0: */ michael@0: virtual gfxImageFormat Format() = 0; michael@0: michael@0: /** michael@0: * Returns a writable copy of the image. michael@0: * If necessary this will copy the wrapper. If there are no contention michael@0: * the same wrapper will be returned. A ReadLock must be held when michael@0: * calling this function, and calling it will give up this lock. michael@0: */ michael@0: virtual gfxReusableSurfaceWrapper* GetWritable(gfxImageSurface** aSurface) = 0; michael@0: michael@0: /** michael@0: * A read only lock count is recorded, any attempts to michael@0: * call GetWritable() while this count is greater than one will michael@0: * create a new surface/wrapper pair. michael@0: * michael@0: * When a surface's read count falls to zero, its memory will be michael@0: * deallocated. It is the responsibility of the user to make sure michael@0: * that all locks are matched with an equal number of unlocks. michael@0: */ michael@0: virtual void ReadLock() = 0; michael@0: virtual void ReadUnlock() = 0; michael@0: michael@0: /** michael@0: * Types for each implementation of gfxReusableSurfaceWrapper. michael@0: */ michael@0: enum Type { michael@0: TYPE_SHARED_IMAGE, michael@0: TYPE_IMAGE, michael@0: michael@0: TYPE_MAX michael@0: }; michael@0: michael@0: /** michael@0: * Returns a unique ID for each implementation of gfxReusableSurfaceWrapper. michael@0: */ michael@0: virtual Type GetType() = 0; michael@0: michael@0: protected: michael@0: // Protected destructor, to discourage deletion outside of Release(): michael@0: virtual ~gfxReusableSurfaceWrapper() {} michael@0: michael@0: NS_DECL_OWNINGTHREAD michael@0: }; michael@0: michael@0: #endif // GFXCOWSURFACEWRAPPER