diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-02-13 17:14:46 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-02-13 17:14:46 +0000 |
commit | c3bd8af6d5722e854feca70c40d92f4954c5b67b (patch) | |
tree | d66f5fa5e139469c523882685cd1dfb4c8f83529 /include/core | |
parent | e1df56579f815fe1f788380e9342abe5284bab51 (diff) |
add peekPixels to SkCanvas and SkSurface
fix reference to SkBaseDevice, which was only a problem in no-gpu build
This reverts commit 4fa44a6bf73891b21917fb90d02beef9143bffa3.
R=reed@google.com
Author: reed@chromium.org
Review URL: https://codereview.chromium.org/163603003
git-svn-id: http://skia.googlecode.com/svn/trunk@13432 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core')
-rw-r--r-- | include/core/SkBitmap.h | 7 | ||||
-rw-r--r-- | include/core/SkBitmapDevice.h | 3 | ||||
-rw-r--r-- | include/core/SkCanvas.h | 77 | ||||
-rw-r--r-- | include/core/SkDevice.h | 11 | ||||
-rw-r--r-- | include/core/SkSurface.h | 12 |
5 files changed, 105 insertions, 5 deletions
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h index 42ef8778bf..b6851def98 100644 --- a/include/core/SkBitmap.h +++ b/include/core/SkBitmap.h @@ -897,4 +897,11 @@ inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const { return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)]; } +/////////////////////////////////////////////////////////////////////////////// +// +// Helpers until we can fully deprecate SkBitmap::Config +// +extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType); +extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config); + #endif diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h index e4f9b88a5e..be98c95882 100644 --- a/include/core/SkBitmapDevice.h +++ b/include/core/SkBitmapDevice.h @@ -82,6 +82,8 @@ public: */ virtual SkBitmap::Config config() const SK_OVERRIDE { return fBitmap.config(); } + virtual SkImageInfo imageInfo() const SK_OVERRIDE; + /** * DEPRECATED: This will be made protected once WebKit stops using it. * Instead use Canvas' writePixels method. @@ -278,6 +280,7 @@ private: virtual void flush() SK_OVERRIDE {} virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; + virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE; SkBitmap fBitmap; diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index b1d415f724..d2e37054c7 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 @@ -1021,6 +1044,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 @@ -1208,4 +1234,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 diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 016e2babc8..e3a23be6ca 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -77,6 +77,12 @@ public: } /** + * Return ImageInfo for this device. If the canvas is not backed by pixels + * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. + */ + virtual SkImageInfo imageInfo() const; + + /** * Return the bounds of the device in the coordinate space of the root * canvas. The root device will have its top-left at 0,0, but other devices * such as those associated with saveLayer may have a non-zero origin. @@ -369,7 +375,10 @@ protected: protected: // default impl returns NULL virtual SkSurface* newSurface(const SkImageInfo&); - + + // default impl returns NULL + virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes); + /** * Leaky properties are those which the device should be applying but it isn't. * These properties will be applied by the draw, when and as it can. diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h index 2f277b755d..74c5f083f4 100644 --- a/include/core/SkSurface.h +++ b/include/core/SkSurface.h @@ -151,6 +151,18 @@ public: */ void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); + /** + * If the surface 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 surface object is in scope, and no API call is made on the surface + * or its canvas. + * + * On failure, returns NULL and the info and rowBytes parameters are + * ignored. + */ + const void* peekPixels(SkImageInfo* info, size_t* rowBytes); + protected: SkSurface(int width, int height); SkSurface(const SkImageInfo&); |