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
This commit is contained in:
parent
e1df56579f
commit
c3bd8af6d5
219
gm/aaclip.cpp
219
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 @@ static void draw (SkCanvas* canvas, SkRect& target, int x, int y) {
|
||||
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 @@ protected:
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -62,14 +62,14 @@ protected:
|
||||
|
||||
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])) {
|
||||
|
@ -23,8 +23,7 @@ protected:
|
||||
|
||||
void makeBitmap() {
|
||||
fBitmap.allocN32Pixels(100, 100);
|
||||
SkBitmapDevice device(fBitmap);
|
||||
SkCanvas canvas(&device);
|
||||
SkCanvas canvas(fBitmap);
|
||||
canvas.clear(0x00000000);
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#include "gm.h"
|
||||
#include "SkBitmapDevice.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
namespace skiagm {
|
||||
|
@ -33,8 +33,7 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
|
||||
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);
|
||||
|
@ -38,14 +38,14 @@ static bool setFont(SkPaint* paint, const char name[]) {
|
||||
#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 @@ protected:
|
||||
|
||||
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);
|
||||
|
3
gm/gm.h
3
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"
|
||||
|
@ -35,8 +35,7 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
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;
|
||||
|
@ -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 @@ protected:
|
||||
|
||||
void make_bitmap() {
|
||||
fBitmap.allocN32Pixels(100, 100);
|
||||
SkBitmapDevice device(fBitmap);
|
||||
SkCanvas canvas(&device);
|
||||
SkCanvas canvas(fBitmap);
|
||||
canvas.clear(0x00000000);
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
|
@ -35,8 +35,7 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
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;
|
||||
|
@ -26,8 +26,7 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
}
|
||||
|
||||
virtual SkISize onISize() {
|
||||
return make_isize(WIDTH, HEIGHT);
|
||||
return SkISize::Make(WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
void drawClippedBitmap(SkCanvas* canvas, const SkPaint& paint, int x, int y) {
|
||||
|
@ -25,8 +25,7 @@ protected:
|
||||
|
||||
void make_bitmap() {
|
||||
fBitmap.allocN32Pixels(80, 80);
|
||||
SkBitmapDevice device(fBitmap);
|
||||
SkCanvas canvas(&device);
|
||||
SkCanvas canvas(fBitmap);
|
||||
canvas.clear(0x00000000);
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
|
@ -27,8 +27,7 @@ protected:
|
||||
|
||||
void make_bitmap() {
|
||||
fBitmap.allocN32Pixels(135, 135);
|
||||
SkBitmapDevice device(fBitmap);
|
||||
SkCanvas canvas(&device);
|
||||
SkCanvas canvas(fBitmap);
|
||||
canvas.clear(0x0);
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
|
@ -13,10 +13,7 @@ static void make_bitmap(SkBitmap* bitmap, SkIRect* center) {
|
||||
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));
|
||||
|
@ -28,8 +28,7 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
}
|
||||
|
||||
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);
|
||||
|
78
gm/peekpixels.cpp
Normal file
78
gm/peekpixels.cpp
Normal file
@ -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); )
|
@ -28,8 +28,7 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
|
||||
void make_checkerboard() {
|
||||
fCheckerboard.allocN32Pixels(80, 80);
|
||||
SkBitmapDevice device(fCheckerboard);
|
||||
SkCanvas canvas(&device);
|
||||
SkCanvas canvas(fCheckerboard);
|
||||
canvas.clear(0x00000000);
|
||||
SkPaint darkPaint;
|
||||
darkPaint.setColor(0xFF404040);
|
||||
|
@ -30,8 +30,7 @@ protected:
|
||||
|
||||
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 @@ protected:
|
||||
|
||||
void make_checkerboard() {
|
||||
fCheckerboard.allocN32Pixels(80, 80);
|
||||
SkBitmapDevice device(fCheckerboard);
|
||||
SkCanvas canvas(&device);
|
||||
SkCanvas canvas(fCheckerboard);
|
||||
canvas.clear(0x00000000);
|
||||
SkPaint darkPaint;
|
||||
darkPaint.setColor(0xFF404040);
|
||||
|
@ -168,8 +168,11 @@ private:
|
||||
if (NULL == layerCanvas) {
|
||||
canvas->restore();
|
||||
} else {
|
||||
SkBitmap bitmap = layerCanvas->getDevice()->accessBitmap(false);
|
||||
canvas->drawBitmap(bitmap, 0, 0);
|
||||
SkAutoROCanvasPixels ropixels(layerCanvas);
|
||||
SkBitmap bitmap;
|
||||
if (ropixels.asROBitmap(&bitmap)) {
|
||||
canvas->drawBitmap(bitmap, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
@ -125,6 +134,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
|
||||
@ -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
|
||||
|
@ -76,6 +76,12 @@ public:
|
||||
return fLeakyProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -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.
|
||||
|
@ -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&);
|
||||
|
@ -1128,8 +1128,9 @@ void SampleWindow::listTitles() {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -71,12 +71,6 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -42,10 +42,10 @@ static void dump_layers(const char label[], SkCanvas* canvas) {
|
||||
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();
|
||||
|
@ -54,6 +54,10 @@ SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, b
|
||||
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 @@ SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info) {
|
||||
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) {
|
||||
|
@ -992,6 +992,55 @@ SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) {
|
||||
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,
|
||||
|
@ -65,6 +65,12 @@ SkMetaData& SkBaseDevice::getMetaData() {
|
||||
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 @@ bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y,
|
||||
}
|
||||
|
||||
SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; }
|
||||
|
||||
const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; }
|
||||
|
@ -221,6 +221,9 @@ public:
|
||||
|
||||
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().
|
||||
|
@ -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*,
|
||||
|
@ -121,3 +121,8 @@ void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -453,7 +453,11 @@ void TestResult::testOne() {
|
||||
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);
|
||||
|
@ -22,27 +22,37 @@ class GrContext;
|
||||
|
||||
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 @@ static void test_imagepeek(skiatest::Reporter* reporter) {
|
||||
{ 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 @@ static void test_imagepeek(skiatest::Reporter* reporter) {
|
||||
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 @@ DEF_GPUTEST(Surface, reporter, factory) {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user