diff options
author | mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-02-13 15:11:11 +0000 |
---|---|---|
committer | mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-02-13 15:11:11 +0000 |
commit | b2d93a91222dac2edb3c19128fd58fa2e74272aa (patch) | |
tree | 542e5234ce9408bb85fe36ae131746376eb3ae53 /include/core/SkCanvas.h | |
parent | deee496cd30070e52556dcb538c2e5eb39b66b81 (diff) |
add peekPixels to SkCanvas and SkSurface
clone of https://codereview.chromium.org/159723006/
Review URL: https://codereview.chromium.org/161733002
git-svn-id: http://skia.googlecode.com/svn/trunk@13427 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core/SkCanvas.h')
-rw-r--r-- | include/core/SkCanvas.h | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 7235efb2f0..971e4402d8 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -76,6 +76,12 @@ public: SkMetaData& getMetaData(); + /** + * Return ImageInfo for this canvas. If the canvas is not backed by pixels + * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. + */ + SkImageInfo imageInfo() const; + /////////////////////////////////////////////////////////////////////////// /** @@ -84,16 +90,19 @@ public: void flush(); /** + * DEPRECATED: call imageInfo() instead. * Return the width/height of the underlying device. The current drawable * area may be small (due to clipping or saveLayer). For a canvas with * no device, 0,0 will be returned. */ SkISize getDeviceSize() const; - /** Return the canvas' device object, which may be null. The device holds - the bitmap of the pixels that the canvas draws into. The reference count - of the returned device is not changed by this call. - */ + /** + * DEPRECATED. + * Return the canvas' device object, which may be null. The device holds + * the bitmap of the pixels that the canvas draws into. The reference count + * of the returned device is not changed by this call. + */ SkBaseDevice* getDevice() const; /** @@ -126,6 +135,20 @@ public: /////////////////////////////////////////////////////////////////////////// /** + * If the canvas has pixels (and is not recording to a picture or other + * non-raster target) and has direct access to its pixels (i.e. they are in + * local RAM) return the const-address of those pixels, and if not null, + * return the ImageInfo and rowBytes. The returned address is only valid + * while the canvas object is in scope and unchanged. Any API calls made on + * canvas (or its parent surface if any) will invalidate the + * returned address (and associated information). + * + * On failure, returns NULL and the info and rowBytes parameters are + * ignored. + */ + const void* peekPixels(SkImageInfo* info, size_t* rowBytes); + + /** * This enum can be used with read/writePixels to perform a pixel ops to or * from an 8888 config other than Skia's native config (SkPMColor). There * are three byte orders supported: native, BGRA, and RGBA. Each has a @@ -1019,6 +1042,9 @@ protected: // default impl defers to getDevice()->newSurface(info) virtual SkSurface* onNewSurface(const SkImageInfo&); + // default impl defers to its device + virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes); + // Returns the canvas to be used by DrawIter. Default implementation // returns this. Subclasses that encapsulate an indirect canvas may // need to overload this method. The impl must keep track of this, as it @@ -1206,4 +1232,47 @@ private: }; #define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock) +/** + * If the caller wants read-only access to the pixels in a canvas, it can just + * call canvas->peekPixels(), since that is the fastest way to "peek" at the + * pixels on a raster-backed canvas. + * + * If the canvas has pixels, but they are not readily available to the CPU + * (e.g. gpu-backed), then peekPixels() will fail, but readPixels() will + * succeed (though be slower, since it will return a copy of the pixels). + * + * SkAutoROCanvasPixels encapsulates these two techniques, trying first to call + * peekPixels() (for performance), but if that fails, calling readPixels() and + * storing the copy locally. + * + * The caller must respect the restrictions associated with peekPixels(), since + * that may have been called: The returned information is invalidated if... + * - any API is called on the canvas (or its parent surface if present) + * - the canvas goes out of scope + */ +class SkAutoROCanvasPixels : SkNoncopyable { +public: + SkAutoROCanvasPixels(SkCanvas* canvas); + + // returns NULL on failure + const void* addr() const { return fAddr; } + + // undefined if addr() == NULL + size_t rowBytes() const { return fRowBytes; } + + // undefined if addr() == NULL + const SkImageInfo& info() const { return fInfo; } + + // helper that, if returns true, installs the pixels into the bitmap. Note + // that the bitmap may reference the address returned by peekPixels(), so + // the caller must respect the restrictions associated with peekPixels(). + bool asROBitmap(SkBitmap*) const; + +private: + SkBitmap fBitmap; // used if peekPixels() fails + const void* fAddr; // NULL on failure + SkImageInfo fInfo; + size_t fRowBytes; +}; + #endif |