aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-13 15:11:11 +0000
committerGravatar mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-13 15:11:11 +0000
commitb2d93a91222dac2edb3c19128fd58fa2e74272aa (patch)
tree542e5234ce9408bb85fe36ae131746376eb3ae53 /include
parentdeee496cd30070e52556dcb538c2e5eb39b66b81 (diff)
add peekPixels to SkCanvas and SkSurface
Diffstat (limited to 'include')
-rw-r--r--include/core/SkBitmap.h7
-rw-r--r--include/core/SkBitmapDevice.h3
-rw-r--r--include/core/SkCanvas.h77
-rw-r--r--include/core/SkDevice.h11
-rw-r--r--include/core/SkSurface.h12
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 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
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&);