ReadPixelsTest.cpp revision c69809745e6496564639e42ef998ad39adf7dfb8
1c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
2c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com/*
3c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com * Copyright 2011 Google Inc.
4c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com *
5c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
6c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com * found in the LICENSE file.
7c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com */
8c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
9c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "Test.h"
10c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "SkCanvas.h"
11c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "SkRegion.h"
12c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "SkGpuDevice.h"
13c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
14c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
15c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comstatic const int DEV_W = 100, DEV_H = 100;
16c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comstatic const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
17c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comstatic const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1,
18c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                                                DEV_H * SK_Scalar1);
19c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
20c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comnamespace {
21c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comSkPMColor getCanvasColor(int x, int y) {
22c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkASSERT(x >= 0 && x < DEV_W);
23c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkASSERT(y >= 0 && y < DEV_H);
24c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    return SkPackARGB32(0xff, x, y, 0x0);
25c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
26c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
27c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comSkPMColor getBitmapColor(int x, int y, int w, int h) {
28c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int n = y * w + x;
29c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
30c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    U8CPU b = n & 0xff;
31c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    U8CPU g = (n >> 8) & 0xff;
32c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    U8CPU r = (n >> 16) & 0xff;
33c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    return SkPackARGB32(0xff, r, g , b);
34c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
35c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
36c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid fillCanvas(SkCanvas* canvas) {
37c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    static SkBitmap bmp;
38c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    if (bmp.isNull()) {
39c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        bmp.setConfig(SkBitmap::kARGB_8888_Config, DEV_W, DEV_H);
40c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        bool alloc = bmp.allocPixels();
41c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkASSERT(alloc);
42c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkAutoLockPixels alp(bmp);
43c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels());
44c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        for (int y = 0; y < DEV_H; ++y) {
45c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            for (int x = 0; x < DEV_W; ++x) {
46c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel());
47c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                *pixel = getCanvasColor(x, y);
48c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            }
49c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        }
50c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
51c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    canvas->save();
52c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    canvas->setMatrix(SkMatrix::I());
53c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    canvas->clipRect(DEV_RECT_S, SkRegion::kReplace_Op);
54c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkPaint paint;
55c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
56c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    canvas->drawBitmap(bmp, 0, 0, &paint);
57c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    canvas->restore();
58c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
59c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
60c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid fillBitmap(SkBitmap* bitmap) {
61c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkASSERT(bitmap->lockPixelsAreWritable());
62c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkAutoLockPixels alp(*bitmap);
63c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int w = bitmap->width();
64c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int h = bitmap->height();
65c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    intptr_t pixels = reinterpret_cast<intptr_t>(bitmap->getPixels());
66c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    for (int y = 0; y < h; ++y) {
67c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        for (int x = 0; x < w; ++x) {
68c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel());
69c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            *pixel = getBitmapColor(x, y, w, h);
70c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        }
71c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
72c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
73c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
74c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com// checks the bitmap contains correct pixels after the readPixels
75c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com// if the bitmap was prefilled with pixels it checks that these weren't
76c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com// overwritten in the area outside the readPixels.
77c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool checkRead(skiatest::Reporter* reporter,
78c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com               const SkBitmap& bitmap,
79c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com               int x, int y,
80c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com               bool preFilledBmp) {
81c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
82c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkASSERT(!bitmap.isNull());
83c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
84c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int bw = bitmap.width();
85c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int bh = bitmap.height();
86c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
87c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh);
88c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkIRect clippedSrcRect = DEV_RECT;
89c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    if (!clippedSrcRect.intersect(srcRect)) {
90c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        clippedSrcRect.setEmpty();
91c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
92c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
93c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkAutoLockPixels alp(bitmap);
94c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    intptr_t pixels = reinterpret_cast<intptr_t>(bitmap.getPixels());
95c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    for (int by = 0; by < bh; ++by) {
96c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        for (int bx = 0; bx < bw; ++bx) {
97c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            int devx = bx + srcRect.fLeft;
98c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            int devy = by + srcRect.fTop;
99c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
100c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            SkPMColor pixel = *reinterpret_cast<SkPMColor*>(pixels + by * bitmap.rowBytes() + bx * bitmap.bytesPerPixel());
101c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
102c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            if (clippedSrcRect.contains(devx, devy)) {
103c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                REPORTER_ASSERT(reporter, getCanvasColor(devx, devy) == pixel);
104c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                if (getCanvasColor(devx, devy) != pixel) {
105c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    return false;
106c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                }
107c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            } else if (preFilledBmp) {
108c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                REPORTER_ASSERT(reporter, getBitmapColor(bx, by, bw, bh) == pixel);
109c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                if (getBitmapColor(bx, by, bw, bh) != pixel) {
110c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    return false;
111c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                }
112c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            }
113c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        }
114c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
115c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    return true;
116c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
117c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
118c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comenum BitmapInit {
119c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    kFirstBitmapInit = 0,
120c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
121c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    kNoPixels_BitmapInit = kFirstBitmapInit,
122c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    kTight_BitmapInit,
123c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    kRowBytes_BitmapInit,
124c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
125c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    kBitmapInitCnt
126c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com};
127c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
128c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comBitmapInit nextBMI(BitmapInit bmi) {
129c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int x = bmi;
130c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    return static_cast<BitmapInit>(++x);
131c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
132c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
133c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
134c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init) {
135c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int w = rect.width();
136c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int h = rect.height();
137c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    int rowBytes = 0;
138c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    bool alloc = true;
139c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    switch (init) {
140c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        case kNoPixels_BitmapInit:
141c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            alloc = false;
142c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        case kTight_BitmapInit:
143c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            break;
144c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        case kRowBytes_BitmapInit:
145c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            rowBytes = w * sizeof(SkPMColor) + 16 * sizeof(SkPMColor);
146c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            break;
147c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        default:
148c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            SkASSERT(0);
149c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            break;
150c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
151c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h, rowBytes);
152c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    if (alloc) {
153c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        bitmap->allocPixels();
154c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
155c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
156c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
157c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comvoid ReadPixelsTest(skiatest::Reporter* reporter, GrContext* context) {
158c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    SkCanvas canvas;
159c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
160c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    const SkIRect testRects[] = {
161c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // entire thing
162c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        DEV_RECT,
163c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // larger on all sides
164c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10),
165c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // fully contained
166c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4),
167c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // outside top left
168c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, -1, -1),
169c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // touching top left corner
170c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, 0, 0),
171c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping top left corner
172c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4),
173c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping top left and top right corners
174c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, DEV_W  + 10, DEV_H / 4),
175c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // touching entire top edge
176c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, DEV_W  + 10, 0),
177c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping top right corner
178c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W  + 10, DEV_H / 4),
179c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // contained in x, overlapping top edge
180c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W  / 4, DEV_H / 4),
181c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // outside top right corner
182c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1),
183c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // touching top right corner
184c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0),
185c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping top left and bottom left corners
186c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10),
187c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // touching entire left edge
188c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10),
189c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping bottom left corner
190c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10),
191c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // contained in y, overlapping left edge
192c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4),
193c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // outside bottom left corner
194c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10),
195c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // touching bottom left corner
196c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10),
197c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping bottom left and bottom right corners
198c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
199c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // touching entire left edge
200c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10),
201c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping bottom right corner
202c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
203c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        // overlapping top right and bottom right corners
204c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10),
205c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    };
206c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
207c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    for (int dtype = 0; dtype < 2; ++dtype) {
208c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
209c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        if (0 == dtype) {
210c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            canvas.setDevice(new SkDevice(SkBitmap::kARGB_8888_Config, DEV_W, DEV_H, false))->unref();
211c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        } else {
212c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#if SK_SCALAR_IS_FIXED
213c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            // GPU device known not to work in the fixed pt build.
214c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            continue;
215c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#endif
216c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            canvas.setDevice(new SkGpuDevice(context, SkBitmap::kARGB_8888_Config, DEV_W, DEV_H))->unref();
217c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        }
218c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        fillCanvas(&canvas);
219c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
220c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        for (int rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) {
221c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            SkBitmap bmp;
222c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            for (BitmapInit bmi = kFirstBitmapInit; bmi < kBitmapInitCnt; bmi = nextBMI(bmi)) {
223c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
224c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                const SkIRect& srcRect = testRects[rect];
225c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
226c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                init_bitmap(&bmp, srcRect, bmi);
227c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
228c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                // if the bitmap has pixels allocated before the readPixels, note
229c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                // that and fill them with pattern
230c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                bool startsWithPixels = !bmp.isNull();
231c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                if (startsWithPixels) {
232c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    fillBitmap(&bmp);
233c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                }
234c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
235c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                bool success = canvas.readPixels(&bmp, srcRect.fLeft, srcRect.fTop);
236c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
237c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                // determine whether we expected the read to succeed.
238c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                REPORTER_ASSERT(reporter, success == SkIRect::Intersects(srcRect, DEV_RECT));
239c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
240c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                if (success || startsWithPixels) {
241c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    checkRead(reporter, bmp, srcRect.fLeft, srcRect.fTop, startsWithPixels);
242c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                } else {
243c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    // if we had no pixels beforehand and the readPixels failed then
244c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    // our bitmap should still not have any pixels
245c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    REPORTER_ASSERT(reporter, bmp.isNull());
246c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                }
247c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
248c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                // check the old webkit version of readPixels that clips the bitmap size
249c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                SkBitmap wkbmp;
250c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                success = canvas.readPixels(srcRect, &wkbmp);
251c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                SkIRect clippedRect = DEV_RECT;
252c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                if (clippedRect.intersect(srcRect)) {
253c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    REPORTER_ASSERT(reporter, success);
254c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    checkRead(reporter, wkbmp, clippedRect.fLeft, clippedRect.fTop, false);
255c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                } else {
256c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                    REPORTER_ASSERT(reporter, !success);
257c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                }
258c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com            }
259c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com        }
260c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    }
261c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
262c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com}
263c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
264c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com#include "TestClassDef.h"
265c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.comDEFINE_GPUTESTCLASS("ReadPixels", ReadPixelsTestClass, ReadPixelsTest)
266c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com
267