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
diff --git a/gm/aaclip.cpp b/gm/aaclip.cpp
index ec29a4f..5742902 100644
--- a/gm/aaclip.cpp
+++ b/gm/aaclip.cpp
@@ -9,203 +9,11 @@
#include "SkCanvas.h"
#include "SkPath.h"
-static void test_quadstroke(SkCanvas* canvas) {
- SkPath path;
- path.moveTo(6, 0);
- path.quadTo(150, 150, 0, 6);
-
- SkPaint paint;
-
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
- canvas->translate(20, 20);
-
-#if 1
- canvas->drawPath(path, paint);
- canvas->translate(100, 0);
-#endif
-
- paint.setStrokeWidth(1.01f);
- canvas->drawPath(path, paint);
-}
-
-static void draw_conic(SkCanvas* canvas, SkScalar weight, const SkPaint& paint) {
- SkPath path;
- path.moveTo(100, 100);
- path.conicTo(300, 100, 300, 300, weight);
- canvas->drawPath(path, paint);
-}
-
-static void test_conic(SkCanvas* canvas) {
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
-
- static const struct {
- SkScalar fWeight;
- SkColor fColor;
- } gRec[] = {
- { 2 , SK_ColorRED },
- { 1 , SK_ColorGREEN },
- { 0.5f, SK_ColorBLUE },
- };
-
- for (SkScalar width = 0; width <= 20; width += 20) {
- canvas->save();
- paint.setStrokeWidth(width);
- for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
- paint.setColor(gRec[i].fColor);
- draw_conic(canvas, gRec[i].fWeight, paint);
- canvas->translate(-30, 30);
- }
- canvas->restore();
- canvas->translate(300, 0);
- }
-}
-
-#include "SkGradientShader.h"
-static void test_shallow_gradient(SkCanvas* canvas, SkScalar width, SkScalar height) {
- SkColor colors[] = { 0xFF7F7F7F, 0xFF7F7F7F, 0xFF000000 };
- SkScalar pos[] = { 0, 0.35f, SK_Scalar1 };
- SkPoint pts[] = { { 0, 0 }, { width, height } };
- SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos,
- SK_ARRAY_COUNT(colors),
- SkShader::kClamp_TileMode);
- SkPaint paint;
- paint.setShader(s)->unref();
- canvas->drawPaint(paint);
-}
-
-#include "SkDashPathEffect.h"
-static void test_giant_dash(SkCanvas* canvas) {
- SkPaint paint;
- const SkScalar intervals[] = { SK_Scalar1, SK_Scalar1 };
-
- paint.setStrokeWidth(2);
- paint.setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref();
-
- SkScalar big = 500 * 1000;
-
- canvas->drawLine(10, 10, big, 10, paint);
- canvas->drawLine(-big, 20, 500, 20, paint);
- canvas->drawLine(-big, 30, big, 30, paint);
-
- const SkScalar intervals2[] = { 20, 5, 10, 5 };
- paint.setPathEffect(new SkDashPathEffect(intervals2, 4, 17))->unref();
-
- canvas->translate(0, 40);
- SkScalar x = -500;
- SkScalar width = 3173;
- for (int i = 0; i < 40; ++i) {
- if (i > 10)
- canvas->drawLine(x, 0, x + width, 0, paint);
- x += 1;
- canvas->translate(0, 4);
- }
-}
-
-
-
-// Reproduces bug found here: http://jsfiddle.net/R8Cu5/1/
-//
-#include "SkGradientShader.h"
-static void test_grad(SkCanvas* canvas) {
- SkPoint pts[] = {
- { 478.544067f, -84.2041016f },
- { 602.455933f, 625.204102f },
- };
- SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, SK_ColorRED, SK_ColorRED };
- SkScalar pos[] = { 0, 0.3f, 0.3f, 1.0f };
- SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 4, SkShader::kClamp_TileMode);
- SkPaint p;
- p.setShader(s)->unref();
- canvas->drawPaint(p);
-}
-
-static SkCanvas* MakeCanvas(const SkIRect& bounds) {
- SkBitmap bm;
- bm.allocN32Pixels(bounds.width(), bounds.height());
- bm.eraseColor(SK_ColorTRANSPARENT);
-
- SkCanvas* canvas = new SkCanvas(bm);
- canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
- return canvas;
-}
-
-#ifdef SK_DEBUG
-static void GetBitmap(const SkCanvas* canvas, SkBitmap* bm) {
- *bm = canvas->getDevice()->accessBitmap(false);
-}
-#endif
-
-static void compare_canvas(const SkCanvas* a, const SkCanvas* b) {
-#ifdef SK_DEBUG
- SkBitmap bma, bmb;
- GetBitmap(a, &bma);
- GetBitmap(b, &bmb);
-
- SkASSERT(bma.width() == bmb.width());
- SkASSERT(bma.height() == bmb.height());
-
- bma.lockPixels();
- bmb.lockPixels();
- for (int y = 0; y < bma.height(); ++y) {
- const SkPMColor* rowa = bma.getAddr32(0, y);
- const SkPMColor* rowb = bmb.getAddr32(0, y);
- SkASSERT(!memcmp(rowa, rowb, bma.width() << 2));
-
- for (int x = 1; x < bma.width() - 1; ++x) {
- SkASSERT(0xFF000000 == rowa[x]);
- SkASSERT(0xFF000000 == rowb[x]);
- }
- }
-#endif
-}
-
-static void drawRectAsPath(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
- SkPath path;
- path.addRect(r);
- canvas->drawPath(path, p);
-}
-
-static void test_maskFromPath(const SkPath& path) {
- SkIRect bounds;
- path.getBounds().roundOut(&bounds);
-
- SkPaint paint;
- paint.setAntiAlias(true);
-
- SkAutoTUnref<SkCanvas> path_canvas(MakeCanvas(bounds));
- path_canvas->drawPath(path, paint);
-
- SkAutoTUnref<SkCanvas> rect_canvas(MakeCanvas(bounds));
- drawRectAsPath(rect_canvas, path.getBounds(), paint);
-
- compare_canvas(path_canvas, rect_canvas);
-}
-
-static void test_mask() {
- for (int i = 1; i <= 20; ++i) {
- const SkScalar dx = SK_Scalar1 / i;
- const SkRect constr = SkRect::MakeWH(dx, SkIntToScalar(2));
- for (int n = 2; n < 20; ++n) {
- SkPath path;
- path.setFillType(SkPath::kEvenOdd_FillType);
- SkRect r = constr;
- while (r.fRight < SkIntToScalar(4)) {
- path.addRect(r);
- r.offset(dx, 0);
- }
- test_maskFromPath(path);
- }
- }
-}
-
/** Draw a 2px border around the target, then red behind the target;
set the clip to match the target, then draw >> the target in blue.
*/
-static void draw (SkCanvas* canvas, SkRect& target, int x, int y) {
+static void draw(SkCanvas* canvas, SkRect& target, int x, int y) {
SkPaint borderPaint;
borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
borderPaint.setAntiAlias(true);
@@ -228,22 +36,22 @@
canvas->restore();
}
-static void draw_square (SkCanvas* canvas, int x, int y) {
+static void draw_square(SkCanvas* canvas, int x, int y) {
SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1));
draw(canvas, target, x, y);
}
-static void draw_column (SkCanvas* canvas, int x, int y) {
+static void draw_column(SkCanvas* canvas, int x, int y) {
SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1));
draw(canvas, target, x, y);
}
-static void draw_bar (SkCanvas* canvas, int x, int y) {
+static void draw_bar(SkCanvas* canvas, int x, int y) {
SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1));
draw(canvas, target, x, y);
}
-static void draw_rect_tests (SkCanvas* canvas) {
+static void draw_rect_tests(SkCanvas* canvas) {
draw_square(canvas, 10, 10);
draw_column(canvas, 30, 10);
draw_bar(canvas, 10, 30);
@@ -272,23 +80,6 @@
}
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
- if (false) { test_quadstroke(canvas); return; }
- if (false) { test_conic(canvas); return; }
- if (false) {
- SkRect bounds;
- canvas->getClipBounds(&bounds);
- test_shallow_gradient(canvas, bounds.width(), bounds.height()); return;
- }
- if (false) {
- test_giant_dash(canvas); return;
- }
- if (false) {
- test_grad(canvas); return;
- }
- if (false) { // avoid bit rot, suppress warning
- test_mask();
- }
-
// Initial pixel-boundary-aligned draw
draw_rect_tests(canvas);
diff --git a/gm/bitmapcopy.cpp b/gm/bitmapcopy.cpp
index 928b403..f210b4a 100644
--- a/gm/bitmapcopy.cpp
+++ b/gm/bitmapcopy.cpp
@@ -62,14 +62,14 @@
virtual void onDraw(SkCanvas* canvas) {
SkPaint paint;
- SkScalar horizMargin(SkIntToScalar(10));
- SkScalar vertMargin(SkIntToScalar(10));
+ SkScalar horizMargin = 10;
+ SkScalar vertMargin = 10;
- SkBitmapDevice devTmp(SkBitmap::kARGB_8888_Config, 40, 40, false);
- SkCanvas canvasTmp(&devTmp);
+ SkBitmap src;
+ src.allocN32Pixels(40, 40);
+ SkCanvas canvasTmp(src);
draw_checks(&canvasTmp, 40, 40);
- SkBitmap src = canvasTmp.getTopDevice()->accessBitmap(false);
for (unsigned i = 0; i < NUM_CONFIGS; ++i) {
if (!src.deepCopyTo(&fDst[i], gConfigs[i])) {
diff --git a/gm/bitmapsource.cpp b/gm/bitmapsource.cpp
index 6d575eb..f40cc15 100644
--- a/gm/bitmapsource.cpp
+++ b/gm/bitmapsource.cpp
@@ -23,8 +23,7 @@
void makeBitmap() {
fBitmap.allocN32Pixels(100, 100);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
diff --git a/gm/deviceproperties.cpp b/gm/deviceproperties.cpp
index 8c4649c..2083946 100644
--- a/gm/deviceproperties.cpp
+++ b/gm/deviceproperties.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
#include "gm.h"
+#include "SkBitmapDevice.h"
#include "SkTypeface.h"
namespace skiagm {
diff --git a/gm/displacement.cpp b/gm/displacement.cpp
index ef6207a..b1f097b 100644
--- a/gm/displacement.cpp
+++ b/gm/displacement.cpp
@@ -33,8 +33,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(80, 80);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
@@ -46,8 +45,7 @@
void make_checkerboard(SkBitmap* bitmap, int w, int h) {
bitmap->allocN32Pixels(w, h);
- SkBitmapDevice device(*bitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(*bitmap);
canvas.clear(0x00000000);
SkPaint darkPaint;
darkPaint.setColor(0xFF804020);
diff --git a/gm/gammatext.cpp b/gm/gammatext.cpp
index 99642f6..7ee55db 100644
--- a/gm/gammatext.cpp
+++ b/gm/gammatext.cpp
@@ -38,14 +38,14 @@
#import <ApplicationServices/ApplicationServices.h>
#define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
-static CGContextRef makeCG(const SkBitmap& bm) {
- if (SkBitmap::kARGB_8888_Config != bm.config() ||
- NULL == bm.getPixels()) {
+static CGContextRef makeCG(const SkImageInfo& info, const void* addr,
+ size_t rowBytes) {
+ if (kPMColor_SkColorType != info.colorType() || NULL == addr) {
return NULL;
}
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
- CGContextRef cg = CGBitmapContextCreate(bm.getPixels(), bm.width(), bm.height(),
- 8, bm.rowBytes(), space, BITMAP_INFO_RGB);
+ CGContextRef cg = CGBitmapContextCreate((void*)addr, info.width(), info.height(),
+ 8, rowBytes, space, BITMAP_INFO_RGB);
CFRelease(space);
CGContextSetAllowsFontSubpixelQuantization(cg, false);
@@ -143,7 +143,15 @@
virtual void onDraw(SkCanvas* canvas) {
#ifdef SK_BUILD_FOR_MAC
- CGContextRef cg = makeCG(canvas->getDevice()->accessBitmap(false));
+ CGContextRef cg = 0;
+ {
+ SkImageInfo info;
+ size_t rowBytes;
+ const void* addr = canvas->peekPixels(&info, &rowBytes);
+ if (addr) {
+ cg = makeCG(info, addr, rowBytes);
+ }
+ }
#endif
drawGrad(canvas);
diff --git a/gm/gm.h b/gm/gm.h
index 4da688c..372b781 100644
--- a/gm/gm.h
+++ b/gm/gm.h
@@ -1,15 +1,14 @@
-
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+
#ifndef skiagm_DEFINED
#define skiagm_DEFINED
#include "SkBitmap.h"
-#include "SkBitmapDevice.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkSize.h"
diff --git a/gm/imagefiltersclipped.cpp b/gm/imagefiltersclipped.cpp
index 82873ab..331ea49 100644
--- a/gm/imagefiltersclipped.cpp
+++ b/gm/imagefiltersclipped.cpp
@@ -35,8 +35,7 @@
void make_checkerboard() {
fCheckerboard.allocN32Pixels(64, 64);
- SkBitmapDevice device(fCheckerboard);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fCheckerboard);
canvas.clear(0x00000000);
SkPaint darkPaint;
darkPaint.setColor(0xFF404040);
@@ -58,10 +57,9 @@
void make_gradient_circle(int width, int height) {
SkScalar x = SkIntToScalar(width / 2);
SkScalar y = SkIntToScalar(height / 2);
- SkScalar radius = SkScalarMul(SkMinScalar(x, y), SkIntToScalar(4) / SkIntToScalar(5));
+ SkScalar radius = SkMinScalar(x, y) * 0.8f;
fGradientCircle.allocN32Pixels(width, height);
- SkBitmapDevice device(fGradientCircle);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fGradientCircle);
canvas.clear(0x00000000);
SkColor colors[2];
colors[0] = SK_ColorWHITE;
diff --git a/gm/imagefiltersgraph.cpp b/gm/imagefiltersgraph.cpp
index 6d5105e..882918c 100644
--- a/gm/imagefiltersgraph.cpp
+++ b/gm/imagefiltersgraph.cpp
@@ -8,6 +8,7 @@
#include "gm.h"
#include "SkArithmeticMode.h"
+#include "SkDevice.h"
#include "SkBitmapSource.h"
#include "SkBlurImageFilter.h"
#include "SkColorFilter.h"
@@ -93,8 +94,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(100, 100);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
diff --git a/gm/imagefiltersscaled.cpp b/gm/imagefiltersscaled.cpp
index a9c4a10..28b3c9f 100644
--- a/gm/imagefiltersscaled.cpp
+++ b/gm/imagefiltersscaled.cpp
@@ -35,8 +35,7 @@
void make_checkerboard() {
fCheckerboard.allocN32Pixels(64, 64);
- SkBitmapDevice device(fCheckerboard);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fCheckerboard);
canvas.clear(0x00000000);
SkPaint darkPaint;
darkPaint.setColor(0xFF404040);
@@ -60,8 +59,7 @@
SkScalar y = SkIntToScalar(height / 2);
SkScalar radius = SkScalarMul(SkMinScalar(x, y), SkIntToScalar(4) / SkIntToScalar(5));
fGradientCircle.allocN32Pixels(width, height);
- SkBitmapDevice device(fGradientCircle);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fGradientCircle);
canvas.clear(0x00000000);
SkColor colors[2];
colors[0] = SK_ColorWHITE;
diff --git a/gm/lighting.cpp b/gm/lighting.cpp
index 1cab553..858976b 100644
--- a/gm/lighting.cpp
+++ b/gm/lighting.cpp
@@ -26,8 +26,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(100, 100);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
@@ -38,7 +37,7 @@
}
virtual SkISize onISize() {
- return make_isize(WIDTH, HEIGHT);
+ return SkISize::Make(WIDTH, HEIGHT);
}
void drawClippedBitmap(SkCanvas* canvas, const SkPaint& paint, int x, int y) {
diff --git a/gm/matrixconvolution.cpp b/gm/matrixconvolution.cpp
index 47a3581..b986cc1 100644
--- a/gm/matrixconvolution.cpp
+++ b/gm/matrixconvolution.cpp
@@ -25,8 +25,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(80, 80);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
diff --git a/gm/morphology.cpp b/gm/morphology.cpp
index 5cfb1c2..a2206b8 100644
--- a/gm/morphology.cpp
+++ b/gm/morphology.cpp
@@ -27,8 +27,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(135, 135);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x0);
SkPaint paint;
paint.setAntiAlias(true);
diff --git a/gm/ninepatchstretch.cpp b/gm/ninepatchstretch.cpp
index a14af00..74cc87f 100644
--- a/gm/ninepatchstretch.cpp
+++ b/gm/ninepatchstretch.cpp
@@ -13,10 +13,7 @@
const int kSize = 2*kFixed + kStretchy;
bitmap->allocN32Pixels(kSize, kSize);
- SkBaseDevice* dev = new SkBitmapDevice(*bitmap);
-
- SkCanvas canvas(dev);
- dev->unref();
+ SkCanvas canvas(*bitmap);
canvas.clear(SK_ColorTRANSPARENT);
SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
diff --git a/gm/offsetimagefilter.cpp b/gm/offsetimagefilter.cpp
index 1b76ba2..0425311 100644
--- a/gm/offsetimagefilter.cpp
+++ b/gm/offsetimagefilter.cpp
@@ -28,8 +28,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(80, 80);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
@@ -40,10 +39,8 @@
}
void make_checkerboard() {
- fCheckerboard.setConfig(SkBitmap::kARGB_8888_Config, 80, 80);
- fCheckerboard.allocPixels();
- SkBitmapDevice device(fCheckerboard);
- SkCanvas canvas(&device);
+ fCheckerboard.allocN32Pixels(80, 80);
+ SkCanvas canvas(fCheckerboard);
canvas.clear(0x00000000);
SkPaint darkPaint;
darkPaint.setColor(0xFF404040);
diff --git a/gm/peekpixels.cpp b/gm/peekpixels.cpp
new file mode 100644
index 0000000..c6744d3
--- /dev/null
+++ b/gm/peekpixels.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkCanvas.h"
+#include "SkPath.h"
+#include "SkSurface.h"
+#include "SkPicture.h"
+
+static void draw_content(SkCanvas* canvas) {
+ SkImageInfo info = canvas->imageInfo();
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ canvas->drawCircle(SkScalarHalf(info.width()), SkScalarHalf(info.height()),
+ SkScalarHalf(info.width()), paint);
+}
+
+class PeekPixelsGM : public skiagm::GM {
+public:
+ PeekPixelsGM() {}
+
+protected:
+ virtual SkString onShortName() SK_OVERRIDE {
+ return SkString("peekpixels");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return SkISize::Make(640, 480);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
+ SkAutoTUnref<SkSurface> surface(canvas->newSurface(info));
+ if (surface.get()) {
+ SkCanvas* surfCanvas = surface->getCanvas();
+
+ draw_content(surfCanvas);
+ SkBitmap bitmap;
+
+ // test peekPixels
+ {
+ SkImageInfo info;
+ size_t rowBytes;
+ const void* addr = surfCanvas->peekPixels(&info, &rowBytes);
+ if (addr && bitmap.installPixels(info, const_cast<void*>(addr),
+ rowBytes, NULL, NULL)) {
+ canvas->drawBitmap(bitmap, 0, 0, NULL);
+ }
+ }
+
+ // test ROCanvasPixels
+ canvas->translate(120, 0);
+ SkAutoROCanvasPixels ropixels(surfCanvas);
+ if (ropixels.asROBitmap(&bitmap)) {
+ canvas->drawBitmap(bitmap, 0, 0, NULL);
+ }
+
+ // test Surface
+ canvas->translate(120, 0);
+ surface->draw(canvas, 0, 0, NULL);
+ }
+ }
+
+ virtual uint32_t onGetFlags() const {
+ // we explicitly test peekPixels and readPixels, neither of which
+ // return something for a picture-backed canvas, so we skip that test.
+ return kSkipPicture_Flag;
+ }
+
+private:
+ typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW(PeekPixelsGM); )
diff --git a/gm/tileimagefilter.cpp b/gm/tileimagefilter.cpp
index d0acad7..319aa3c 100644
--- a/gm/tileimagefilter.cpp
+++ b/gm/tileimagefilter.cpp
@@ -28,8 +28,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(80, 80);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0xFF000000);
SkPaint paint;
paint.setAntiAlias(true);
@@ -41,8 +40,7 @@
void make_checkerboard() {
fCheckerboard.allocN32Pixels(80, 80);
- SkBitmapDevice device(fCheckerboard);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fCheckerboard);
canvas.clear(0x00000000);
SkPaint darkPaint;
darkPaint.setColor(0xFF404040);
diff --git a/gm/xfermodeimagefilter.cpp b/gm/xfermodeimagefilter.cpp
index f843d40..4469618 100644
--- a/gm/xfermodeimagefilter.cpp
+++ b/gm/xfermodeimagefilter.cpp
@@ -30,8 +30,7 @@
void make_bitmap() {
fBitmap.allocN32Pixels(80, 80);
- SkBitmapDevice device(fBitmap);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fBitmap);
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
@@ -43,8 +42,7 @@
void make_checkerboard() {
fCheckerboard.allocN32Pixels(80, 80);
- SkBitmapDevice device(fCheckerboard);
- SkCanvas canvas(&device);
+ SkCanvas canvas(fCheckerboard);
canvas.clear(0x00000000);
SkPaint darkPaint;
darkPaint.setColor(0xFF404040);
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index ca3a7f6..e95f59b 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -121,6 +121,7 @@
'../gm/pathopsinverse.cpp',
'../gm/pathopsskpclip.cpp',
'../gm/pathreverse.cpp',
+ '../gm/peekpixels.cpp',
'../gm/perlinnoise.cpp',
'../gm/pictureimagefilter.cpp',
'../gm/points.cpp',
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 42ef877..b6851de 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -897,4 +897,11 @@
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 e4f9b88..be98c95 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -82,6 +82,8 @@
*/
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 @@
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 7235efb..971e440 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -76,6 +76,12 @@
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 @@
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 @@
///////////////////////////////////////////////////////////////////////////
/**
+ * 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 @@
// 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 @@
};
#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 016e2ba..e3a23be 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -77,6 +77,12 @@
}
/**
+ * 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:
// 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 2f277b7..74c5f08 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -151,6 +151,18 @@
*/
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&);
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 53e15a5..15e56a3 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -1128,8 +1128,9 @@
static SkBitmap capture_bitmap(SkCanvas* canvas) {
SkBitmap bm;
- const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
- src.copyTo(&bm, src.config());
+ if (bm.allocPixels(canvas->imageInfo())) {
+ canvas->readPixels(&bm, 0, 0);
+ }
return bm;
}
diff --git a/samplecode/SampleCircle.cpp b/samplecode/SampleCircle.cpp
index b101a1f..9cc927e 100644
--- a/samplecode/SampleCircle.cpp
+++ b/samplecode/SampleCircle.cpp
@@ -71,12 +71,6 @@
}
}
- static void blowup(SkCanvas* canvas, const SkIRect& src, const SkRect& dst) {
- SkBaseDevice* device = canvas->getDevice();
- const SkBitmap& bm = device->accessBitmap(false);
- canvas->drawBitmapRect(bm, &src, dst, NULL);
- }
-
static void make_poly(SkPath* path, int n) {
if (n <= 0) {
return;
diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp
index 483943d..bc8b873 100644
--- a/samplecode/SampleLayers.cpp
+++ b/samplecode/SampleLayers.cpp
@@ -42,10 +42,10 @@
SkCanvas::LayerIter iter(canvas, true);
int index = 0;
while (!iter.done()) {
- const SkBitmap& bm = iter.device()->accessBitmap(false);
+ SkImageInfo info = iter.device()->imageInfo();
const SkIRect& clip = iter.clip().getBounds();
SkDebugf("Layer[%d] bitmap [%d %d] X=%d Y=%d clip=[%d %d %d %d] alpha=%d\n", index++,
- bm.width(), bm.height(), iter.x(), iter.y(),
+ info.width(), info.height(), iter.x(), iter.y(),
clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
iter.paint().getAlpha());
iter.next();
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 9dde6e1..374bef9 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -54,6 +54,10 @@
SkBitmapDevice::~SkBitmapDevice() {
}
+SkImageInfo SkBitmapDevice::imageInfo() const {
+ return fBitmap.info();
+}
+
void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
SkASSERT(bm.width() == fBitmap.width());
SkASSERT(bm.height() == fBitmap.height());
@@ -386,6 +390,16 @@
return SkSurface::NewRaster(info);
}
+const void* SkBitmapDevice::peekPixels(SkImageInfo* info, size_t* rowBytes) {
+ if (fBitmap.getPixels() && fBitmap.asImageInfo(info)) {
+ if (rowBytes) {
+ *rowBytes = fBitmap.rowBytes();
+ }
+ return fBitmap.getPixels();
+ }
+ return NULL;
+}
+
///////////////////////////////////////////////////////////////////////////////
bool SkBitmapDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index ed8274d..f5e91ff 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -992,6 +992,55 @@
return dev ? dev->newSurface(info) : NULL;
}
+SkImageInfo SkCanvas::imageInfo() const {
+ SkBaseDevice* dev = this->getDevice();
+ if (dev) {
+ return dev->imageInfo();
+ } else {
+ // TODO: need a real unknown for alphatype it seems.
+ SkAlphaType unknownAlphaType = kIgnore_SkAlphaType;
+ return SkImageInfo::Make(0, 0, kUnknown_SkColorType, unknownAlphaType);
+ }
+}
+
+const void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) {
+ return this->onPeekPixels(info, rowBytes);
+}
+
+const void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) {
+ SkBaseDevice* dev = this->getDevice();
+ return dev ? dev->peekPixels(info, rowBytes) : NULL;
+}
+
+SkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) {
+ fAddr = canvas->peekPixels(&fInfo, &fRowBytes);
+ if (NULL == fAddr) {
+ fInfo = canvas->imageInfo();
+ if (kUnknown_SkColorType == fInfo.colorType() ||
+ !fBitmap.allocPixels(fInfo))
+ {
+ return; // failure, fAddr is NULL
+ }
+ fBitmap.lockPixels();
+ if (!canvas->readPixels(&fBitmap, 0, 0)) {
+ return; // failure, fAddr is NULL
+ }
+ fAddr = fBitmap.getPixels();
+ fRowBytes = fBitmap.rowBytes();
+ }
+ SkASSERT(fAddr); // success
+}
+
+bool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const {
+ if (fAddr) {
+ return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes,
+ NULL, NULL);
+ } else {
+ bitmap->reset();
+ return false;
+ }
+}
+
/////////////////////////////////////////////////////////////////////////////
void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap,
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 9ce8b6b..364b106 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -65,6 +65,12 @@
return *fMetaData;
}
+// TODO: should make this guy pure-virtual.
+SkImageInfo SkBaseDevice::imageInfo() const {
+ return SkImageInfo::Make(this->width(), this->height(),
+ kUnknown_SkColorType, kIgnore_SkAlphaType);
+}
+
const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) {
const SkBitmap& bitmap = this->onAccessBitmap();
if (changePixels) {
@@ -117,3 +123,5 @@
}
SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; }
+
+const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 0df120b..eaa5e73 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -221,6 +221,9 @@
protected:
virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
+ const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE {
+ return NULL;
+ }
// Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been
// tweaked by paint.computeFastBounds().
diff --git a/src/image/SkImagePriv.h b/src/image/SkImagePriv.h
index 8883e2c..bf28f59 100644
--- a/src/image/SkImagePriv.h
+++ b/src/image/SkImagePriv.h
@@ -14,8 +14,6 @@
class SkPicture;
extern SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo&);
-extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType);
-extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config);
// Call this if you explicitly want to use/share this pixelRef in the image
extern SkImage* SkNewImageFromPixelRef(const SkImageInfo&, SkPixelRef*,
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index cb029c8..4b5fb68 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -121,3 +121,8 @@
const SkPaint* paint) {
return asSB(this)->onDraw(canvas, x, y, paint);
}
+
+const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) {
+ return this->getCanvas()->peekPixels(info, rowBytes);
+}
+
diff --git a/tests/SkpSkGrTest.cpp b/tests/SkpSkGrTest.cpp
index 02aabbe..d1d38df 100644
--- a/tests/SkpSkGrTest.cpp
+++ b/tests/SkpSkGrTest.cpp
@@ -453,7 +453,11 @@
SkGpuDevice grDevice(context, texture.get());
SkCanvas grCanvas(&grDevice);
drawPict(pic, &grCanvas, fScaleOversized ? scale : 1);
- const SkBitmap& grBitmap = grDevice.accessBitmap(false);
+
+ SkBitmap grBitmap;
+ grBitmap.allocPixels(grCanvas.imageInfo());
+ grCanvas.readPixels(&grBitmap, 0, 0);
+
if (fTestStep == kCompareBits) {
fPixelError = similarBits(grBitmap, bitmap);
int skTime = timePict(pic, &skCanvas);
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index aa457c7..fcd0986 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -22,27 +22,37 @@
enum SurfaceType {
kRaster_SurfaceType,
+ kRasterDirect_SurfaceType,
kGpu_SurfaceType,
kPicture_SurfaceType
};
-static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context) {
- static const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
+static const int gSurfaceSize = 10;
+static SkPMColor gSurfaceStorage[gSurfaceSize * gSurfaceSize];
+
+static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
+ SkImageInfo* requestedInfo = NULL) {
+ static const SkImageInfo info = SkImageInfo::MakeN32Premul(gSurfaceSize,
+ gSurfaceSize);
+
+ if (requestedInfo) {
+ *requestedInfo = info;
+ }
switch (surfaceType) {
- case kRaster_SurfaceType:
- return SkSurface::NewRaster(info);
- case kGpu_SurfaceType:
+ case kRaster_SurfaceType:
+ return SkSurface::NewRaster(info);
+ case kRasterDirect_SurfaceType:
+ return SkSurface::NewRasterDirect(info, gSurfaceStorage,
+ info.minRowBytes());
+ case kGpu_SurfaceType:
#if SK_SUPPORT_GPU
- SkASSERT(NULL != context);
- return SkSurface::NewRenderTarget(context, info);
-#else
- SkASSERT(0);
+ return context ? SkSurface::NewRenderTarget(context, info) : NULL;
#endif
- case kPicture_SurfaceType:
- return SkSurface::NewPicture(info.fWidth, info.fHeight);
+ break;
+ case kPicture_SurfaceType:
+ return SkSurface::NewPicture(info.fWidth, info.fHeight);
}
- SkASSERT(0);
return NULL;
}
@@ -117,14 +127,14 @@
{ kPicture_ImageType, false },
{ kCodec_ImageType, false },
};
-
+
const SkColor color = SK_ColorRED;
const SkPMColor pmcolor = SkPreMultiplyColor(color);
-
+
for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
SkImageInfo info;
size_t rowBytes;
-
+
SkAutoTUnref<SkImage> image(createImage(gRec[i].fType, NULL, color));
if (!image.get()) {
continue; // gpu may not be enabled
@@ -137,13 +147,65 @@
REPORTER_ASSERT(reporter, 10 == info.fHeight);
REPORTER_ASSERT(reporter, kPMColor_SkColorType == info.fColorType);
REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.fAlphaType ||
- kOpaque_SkAlphaType == info.fAlphaType);
+ kOpaque_SkAlphaType == info.fAlphaType);
REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes);
REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
}
}
}
+static void test_canvaspeek(skiatest::Reporter* reporter,
+ GrContextFactory* factory) {
+ static const struct {
+ SurfaceType fType;
+ bool fPeekShouldSucceed;
+ } gRec[] = {
+ { kRaster_SurfaceType, true },
+ { kRasterDirect_SurfaceType, true },
+#if SK_SUPPORT_GPU
+ { kGpu_SurfaceType, false },
+#endif
+ { kPicture_SurfaceType, false },
+ };
+
+ const SkColor color = SK_ColorRED;
+ const SkPMColor pmcolor = SkPreMultiplyColor(color);
+
+ GrContext* context = NULL;
+#if SK_SUPPORT_GPU
+ context = factory->get(GrContextFactory::kNative_GLContextType);
+#endif
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
+ SkImageInfo info, requestInfo;
+ size_t rowBytes;
+
+ SkAutoTUnref<SkSurface> surface(createSurface(gRec[i].fType, context,
+ &requestInfo));
+ surface->getCanvas()->clear(color);
+
+ const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
+ bool success = (NULL != addr);
+ REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
+
+ SkImageInfo info2;
+ size_t rb2;
+ const void* addr2 = surface->peekPixels(&info2, &rb2);
+
+ if (success) {
+ REPORTER_ASSERT(reporter, requestInfo == info);
+ REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= rowBytes);
+ REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
+
+ REPORTER_ASSERT(reporter, addr2 == addr);
+ REPORTER_ASSERT(reporter, info2 == info);
+ REPORTER_ASSERT(reporter, rb2 == rowBytes);
+ } else {
+ REPORTER_ASSERT(reporter, NULL == addr2);
+ }
+ }
+}
+
static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType,
GrContext* context) {
// Verify that the right canvas commands trigger a copy on write
@@ -335,7 +397,10 @@
TestSurfaceWritableAfterSnapshotRelease(reporter, kPicture_SurfaceType, NULL);
TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, NULL, SkSurface::kDiscard_ContentChangeMode);
TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, NULL, SkSurface::kRetain_ContentChangeMode);
+
test_imagepeek(reporter);
+ test_canvaspeek(reporter, factory);
+
#if SK_SUPPORT_GPU
TestGetTexture(reporter, kRaster_SurfaceType, NULL);
TestGetTexture(reporter, kPicture_SurfaceType, NULL);