blob: 6e363fcaaaffab8cf97758a5e20093c6a0625107 [file] [log] [blame]
bsalomon@google.comc6980972011-11-02 19:57:21 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Test.h"
robertphillips@google.com73672252013-08-29 12:40:26 +00009#include "SkBitmapDevice.h"
bsalomon@google.comc6980972011-11-02 19:57:21 +000010#include "SkCanvas.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000011#include "SkColorPriv.h"
reed@google.com4b163ed2012-08-07 21:35:13 +000012#include "SkMathPriv.h"
bsalomon@google.comc6980972011-11-02 19:57:21 +000013#include "SkRegion.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000014#if SK_SUPPORT_GPU
bsalomon@google.comc6980972011-11-02 19:57:21 +000015#include "SkGpuDevice.h"
bsalomon@google.com67b915d2013-02-04 16:13:32 +000016#include "GrContextFactory.h"
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000017#endif
bsalomon@google.comc6980972011-11-02 19:57:21 +000018
bsalomon@google.comc6980972011-11-02 19:57:21 +000019static const int DEV_W = 100, DEV_H = 100;
20static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
rmistry@google.comd6176b02012-08-23 18:14:13 +000021static const SkRect DEV_RECT_S = SkRect::MakeWH(DEV_W * SK_Scalar1,
bsalomon@google.comc6980972011-11-02 19:57:21 +000022 DEV_H * SK_Scalar1);
23
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +000024static SkPMColor getCanvasColor(int x, int y) {
bsalomon@google.comc6980972011-11-02 19:57:21 +000025 SkASSERT(x >= 0 && x < DEV_W);
26 SkASSERT(y >= 0 && y < DEV_H);
bsalomon@google.com6850eab2011-11-03 20:29:47 +000027
28 U8CPU r = x;
29 U8CPU g = y;
30 U8CPU b = 0xc;
31
32 U8CPU a = 0xff;
bsalomon@google.comc4364992011-11-07 15:54:49 +000033 switch ((x+y) % 5) {
bsalomon@google.com6850eab2011-11-03 20:29:47 +000034 case 0:
35 a = 0xff;
36 break;
37 case 1:
38 a = 0x80;
39 break;
40 case 2:
41 a = 0xCC;
42 break;
43 case 4:
44 a = 0x01;
45 break;
46 case 3:
47 a = 0x00;
48 break;
49 }
50 return SkPremultiplyARGBInline(a, r, g, b);
bsalomon@google.comc6980972011-11-02 19:57:21 +000051}
rmistry@google.comd6176b02012-08-23 18:14:13 +000052
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +000053static SkPMColor getBitmapColor(int x, int y, int w) {
bsalomon@google.comc6980972011-11-02 19:57:21 +000054 int n = y * w + x;
bsalomon@google.com6850eab2011-11-03 20:29:47 +000055
bsalomon@google.comc6980972011-11-02 19:57:21 +000056 U8CPU b = n & 0xff;
57 U8CPU g = (n >> 8) & 0xff;
58 U8CPU r = (n >> 16) & 0xff;
59 return SkPackARGB32(0xff, r, g , b);
60}
61
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +000062static SkPMColor convertConfig8888ToPMColor(SkCanvas::Config8888 config8888,
63 uint32_t color,
64 bool* premul) {
bsalomon@google.com6850eab2011-11-03 20:29:47 +000065 const uint8_t* c = reinterpret_cast<uint8_t*>(&color);
66 U8CPU a,r,g,b;
bsalomon@google.comc4364992011-11-07 15:54:49 +000067 *premul = false;
bsalomon@google.com6850eab2011-11-03 20:29:47 +000068 switch (config8888) {
69 case SkCanvas::kNative_Premul_Config8888:
70 return color;
71 case SkCanvas::kNative_Unpremul_Config8888:
bsalomon@google.comc4364992011-11-07 15:54:49 +000072 *premul = true;
bsalomon@google.com6850eab2011-11-03 20:29:47 +000073 a = SkGetPackedA32(color);
74 r = SkGetPackedR32(color);
75 g = SkGetPackedG32(color);
76 b = SkGetPackedB32(color);
77 break;
78 case SkCanvas::kBGRA_Unpremul_Config8888:
bsalomon@google.comc4364992011-11-07 15:54:49 +000079 *premul = true; // fallthru
bsalomon@google.com6850eab2011-11-03 20:29:47 +000080 case SkCanvas::kBGRA_Premul_Config8888:
81 a = static_cast<U8CPU>(c[3]);
82 r = static_cast<U8CPU>(c[2]);
83 g = static_cast<U8CPU>(c[1]);
84 b = static_cast<U8CPU>(c[0]);
85 break;
86 case SkCanvas::kRGBA_Unpremul_Config8888:
bsalomon@google.comc4364992011-11-07 15:54:49 +000087 *premul = true; // fallthru
bsalomon@google.com6850eab2011-11-03 20:29:47 +000088 case SkCanvas::kRGBA_Premul_Config8888:
89 a = static_cast<U8CPU>(c[3]);
90 r = static_cast<U8CPU>(c[0]);
91 g = static_cast<U8CPU>(c[1]);
92 b = static_cast<U8CPU>(c[2]);
93 break;
bsalomon@google.comccaa0022012-09-25 19:55:07 +000094 default:
95 SkDEBUGFAIL("Unexpected Config8888");
96 return 0;
bsalomon@google.com6850eab2011-11-03 20:29:47 +000097 }
bsalomon@google.comc4364992011-11-07 15:54:49 +000098 if (*premul) {
bsalomon@google.com6850eab2011-11-03 20:29:47 +000099 r = SkMulDiv255Ceiling(r, a);
100 g = SkMulDiv255Ceiling(g, a);
101 b = SkMulDiv255Ceiling(b, a);
102 }
103 return SkPackARGB32(a, r, g, b);
104}
105
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +0000106static void fillCanvas(SkCanvas* canvas) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000107 static SkBitmap bmp;
108 if (bmp.isNull()) {
109 bmp.setConfig(SkBitmap::kARGB_8888_Config, DEV_W, DEV_H);
reed@google.com44a42ea2012-10-01 17:54:05 +0000110 SkDEBUGCODE(bool alloc =) bmp.allocPixels();
bsalomon@google.comc6980972011-11-02 19:57:21 +0000111 SkASSERT(alloc);
112 SkAutoLockPixels alp(bmp);
113 intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels());
114 for (int y = 0; y < DEV_H; ++y) {
115 for (int x = 0; x < DEV_W; ++x) {
116 SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel());
117 *pixel = getCanvasColor(x, y);
118 }
119 }
120 }
121 canvas->save();
122 canvas->setMatrix(SkMatrix::I());
123 canvas->clipRect(DEV_RECT_S, SkRegion::kReplace_Op);
124 SkPaint paint;
125 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
126 canvas->drawBitmap(bmp, 0, 0, &paint);
127 canvas->restore();
128}
rmistry@google.comd6176b02012-08-23 18:14:13 +0000129
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +0000130static void fillBitmap(SkBitmap* bitmap) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000131 SkASSERT(bitmap->lockPixelsAreWritable());
132 SkAutoLockPixels alp(*bitmap);
133 int w = bitmap->width();
134 int h = bitmap->height();
135 intptr_t pixels = reinterpret_cast<intptr_t>(bitmap->getPixels());
136 for (int y = 0; y < h; ++y) {
137 for (int x = 0; x < w; ++x) {
138 SkPMColor* pixel = reinterpret_cast<SkPMColor*>(pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel());
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000139 *pixel = getBitmapColor(x, y, w);
bsalomon@google.comc6980972011-11-02 19:57:21 +0000140 }
141 }
142}
143
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +0000144static bool checkPixel(SkPMColor a, SkPMColor b, bool didPremulConversion) {
bsalomon@google.comc4364992011-11-07 15:54:49 +0000145 if (!didPremulConversion) {
146 return a == b;
147 }
148 int32_t aA = static_cast<int32_t>(SkGetPackedA32(a));
149 int32_t aR = static_cast<int32_t>(SkGetPackedR32(a));
150 int32_t aG = static_cast<int32_t>(SkGetPackedG32(a));
151 int32_t aB = SkGetPackedB32(a);
152
153 int32_t bA = static_cast<int32_t>(SkGetPackedA32(b));
154 int32_t bR = static_cast<int32_t>(SkGetPackedR32(b));
155 int32_t bG = static_cast<int32_t>(SkGetPackedG32(b));
156 int32_t bB = static_cast<int32_t>(SkGetPackedB32(b));
157
158 return aA == bA &&
159 SkAbs32(aR - bR) <= 1 &&
160 SkAbs32(aG - bG) <= 1 &&
161 SkAbs32(aB - bB) <= 1;
162}
163
bsalomon@google.comc6980972011-11-02 19:57:21 +0000164// checks the bitmap contains correct pixels after the readPixels
165// if the bitmap was prefilled with pixels it checks that these weren't
166// overwritten in the area outside the readPixels.
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +0000167static bool checkRead(skiatest::Reporter* reporter,
168 const SkBitmap& bitmap,
169 int x, int y,
170 bool checkCanvasPixels,
171 bool checkBitmapPixels,
172 SkCanvas::Config8888 config8888) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000173 SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
174 SkASSERT(!bitmap.isNull());
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000175 SkASSERT(checkCanvasPixels || checkBitmapPixels);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000176
bsalomon@google.comc6980972011-11-02 19:57:21 +0000177 int bw = bitmap.width();
178 int bh = bitmap.height();
179
180 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bw, bh);
181 SkIRect clippedSrcRect = DEV_RECT;
182 if (!clippedSrcRect.intersect(srcRect)) {
183 clippedSrcRect.setEmpty();
184 }
bsalomon@google.comc6980972011-11-02 19:57:21 +0000185 SkAutoLockPixels alp(bitmap);
186 intptr_t pixels = reinterpret_cast<intptr_t>(bitmap.getPixels());
187 for (int by = 0; by < bh; ++by) {
188 for (int bx = 0; bx < bw; ++bx) {
189 int devx = bx + srcRect.fLeft;
190 int devy = by + srcRect.fTop;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000191
bsalomon@google.comc4364992011-11-07 15:54:49 +0000192 uint32_t pixel = *reinterpret_cast<SkPMColor*>(pixels + by * bitmap.rowBytes() + bx * bitmap.bytesPerPixel());
bsalomon@google.comc6980972011-11-02 19:57:21 +0000193
194 if (clippedSrcRect.contains(devx, devy)) {
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000195 if (checkCanvasPixels) {
196 SkPMColor canvasPixel = getCanvasColor(devx, devy);
bsalomon@google.comc4364992011-11-07 15:54:49 +0000197 bool didPremul;
198 SkPMColor pmPixel = convertConfig8888ToPMColor(config8888, pixel, &didPremul);
199 bool check;
200 REPORTER_ASSERT(reporter, check = checkPixel(pmPixel, canvasPixel, didPremul));
201 if (!check) {
bsalomon@google.com72f3dca2012-08-17 13:32:06 +0000202 return false;
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000203 }
bsalomon@google.comc6980972011-11-02 19:57:21 +0000204 }
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000205 } else if (checkBitmapPixels) {
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000206 REPORTER_ASSERT(reporter, getBitmapColor(bx, by, bw) == pixel);
207 if (getBitmapColor(bx, by, bw) != pixel) {
bsalomon@google.com72f3dca2012-08-17 13:32:06 +0000208 return false;
bsalomon@google.comc6980972011-11-02 19:57:21 +0000209 }
210 }
211 }
212 }
bsalomon@google.com72f3dca2012-08-17 13:32:06 +0000213 return true;
bsalomon@google.comc6980972011-11-02 19:57:21 +0000214}
215
216enum BitmapInit {
217 kFirstBitmapInit = 0,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000218
bsalomon@google.comc6980972011-11-02 19:57:21 +0000219 kNoPixels_BitmapInit = kFirstBitmapInit,
220 kTight_BitmapInit,
221 kRowBytes_BitmapInit,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000222
bsalomon@google.comc6980972011-11-02 19:57:21 +0000223 kBitmapInitCnt
224};
225
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +0000226static BitmapInit nextBMI(BitmapInit bmi) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000227 int x = bmi;
228 return static_cast<BitmapInit>(++x);
229}
230
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +0000231static void init_bitmap(SkBitmap* bitmap, const SkIRect& rect, BitmapInit init) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000232 int w = rect.width();
233 int h = rect.height();
234 int rowBytes = 0;
235 bool alloc = true;
236 switch (init) {
237 case kNoPixels_BitmapInit:
238 alloc = false;
239 case kTight_BitmapInit:
240 break;
241 case kRowBytes_BitmapInit:
242 rowBytes = w * sizeof(SkPMColor) + 16 * sizeof(SkPMColor);
243 break;
244 default:
245 SkASSERT(0);
246 break;
247 }
248 bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h, rowBytes);
249 if (alloc) {
250 bitmap->allocPixels();
251 }
252}
253
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +0000254static void ReadPixelsTest(skiatest::Reporter* reporter, GrContextFactory* factory) {
bsalomon@google.comc6980972011-11-02 19:57:21 +0000255 const SkIRect testRects[] = {
256 // entire thing
257 DEV_RECT,
258 // larger on all sides
259 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H + 10),
260 // fully contained
261 SkIRect::MakeLTRB(DEV_W / 4, DEV_H / 4, 3 * DEV_W / 4, 3 * DEV_H / 4),
262 // outside top left
263 SkIRect::MakeLTRB(-10, -10, -1, -1),
264 // touching top left corner
265 SkIRect::MakeLTRB(-10, -10, 0, 0),
266 // overlapping top left corner
267 SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H / 4),
268 // overlapping top left and top right corners
269 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, DEV_H / 4),
270 // touching entire top edge
271 SkIRect::MakeLTRB(-10, -10, DEV_W + 10, 0),
272 // overlapping top right corner
273 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H / 4),
274 // contained in x, overlapping top edge
275 SkIRect::MakeLTRB(DEV_W / 4, -10, 3 * DEV_W / 4, DEV_H / 4),
276 // outside top right corner
277 SkIRect::MakeLTRB(DEV_W + 1, -10, DEV_W + 10, -1),
278 // touching top right corner
279 SkIRect::MakeLTRB(DEV_W, -10, DEV_W + 10, 0),
280 // overlapping top left and bottom left corners
281 SkIRect::MakeLTRB(-10, -10, DEV_W / 4, DEV_H + 10),
282 // touching entire left edge
283 SkIRect::MakeLTRB(-10, -10, 0, DEV_H + 10),
284 // overlapping bottom left corner
285 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W / 4, DEV_H + 10),
286 // contained in y, overlapping left edge
287 SkIRect::MakeLTRB(-10, DEV_H / 4, DEV_W / 4, 3 * DEV_H / 4),
288 // outside bottom left corner
289 SkIRect::MakeLTRB(-10, DEV_H + 1, -1, DEV_H + 10),
290 // touching bottom left corner
291 SkIRect::MakeLTRB(-10, DEV_H, 0, DEV_H + 10),
292 // overlapping bottom left and bottom right corners
293 SkIRect::MakeLTRB(-10, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
294 // touching entire left edge
295 SkIRect::MakeLTRB(0, DEV_H, DEV_W, DEV_H + 10),
296 // overlapping bottom right corner
297 SkIRect::MakeLTRB(3 * DEV_W / 4, 3 * DEV_H / 4, DEV_W + 10, DEV_H + 10),
298 // overlapping top right and bottom right corners
299 SkIRect::MakeLTRB(3 * DEV_W / 4, -10, DEV_W + 10, DEV_H + 10),
300 };
301
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000302 for (int dtype = 0; dtype < 3; ++dtype) {
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000303 int glCtxTypeCnt = 1;
304#if SK_SUPPORT_GPU
305 if (0 != dtype) {
306 glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt;
bsalomon@google.comc6980972011-11-02 19:57:21 +0000307 }
djsollen@google.com8688e5b2012-01-09 13:02:20 +0000308#endif
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000309 for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000310 SkAutoTUnref<SkBaseDevice> device;
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000311 if (0 == dtype) {
skia.committer@gmail.com772c4e62013-08-30 07:01:34 +0000312 device.reset(new SkBitmapDevice(SkBitmap::kARGB_8888_Config,
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000313 DEV_W, DEV_H, false));
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000314 } else {
315#if SK_SUPPORT_GPU
316 GrContextFactory::GLContextType type =
317 static_cast<GrContextFactory::GLContextType>(glCtxType);
318 if (!GrContextFactory::IsRenderingGLContext(type)) {
319 continue;
bsalomon@google.comc6980972011-11-02 19:57:21 +0000320 }
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000321 GrContext* context = factory->get(type);
322 if (NULL == context) {
323 continue;
324 }
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000325 GrTextureDesc desc;
326 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
327 desc.fWidth = DEV_W;
328 desc.fHeight = DEV_H;
bsalomon@google.comfec0bc32013-02-07 14:43:04 +0000329 desc.fConfig = kSkia8888_GrPixelConfig;
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000330 desc.fOrigin = 1 == dtype ? kBottomLeft_GrSurfaceOrigin
331 : kTopLeft_GrSurfaceOrigin;
332 GrAutoScratchTexture ast(context, desc, GrContext::kExact_ScratchTexMatch);
333 SkAutoTUnref<GrTexture> tex(ast.detach());
334 device.reset(new SkGpuDevice(context, tex));
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000335#else
336 continue;
337#endif
338 }
339 SkCanvas canvas(device);
340 fillCanvas(&canvas);
341
342 static const SkCanvas::Config8888 gReadConfigs[] = {
343 SkCanvas::kNative_Premul_Config8888,
344 SkCanvas::kNative_Unpremul_Config8888,
commit-bot@chromium.org28621512013-08-07 19:43:45 +0000345
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000346 SkCanvas::kBGRA_Premul_Config8888,
347 SkCanvas::kBGRA_Unpremul_Config8888,
commit-bot@chromium.org28621512013-08-07 19:43:45 +0000348
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000349 SkCanvas::kRGBA_Premul_Config8888,
350 SkCanvas::kRGBA_Unpremul_Config8888,
351 };
352 for (size_t rect = 0; rect < SK_ARRAY_COUNT(testRects); ++rect) {
353 const SkIRect& srcRect = testRects[rect];
354 for (BitmapInit bmi = kFirstBitmapInit;
355 bmi < kBitmapInitCnt;
356 bmi = nextBMI(bmi)) {
357 for (size_t c = 0; c < SK_ARRAY_COUNT(gReadConfigs); ++c) {
358 SkCanvas::Config8888 config8888 = gReadConfigs[c];
359 SkBitmap bmp;
360 init_bitmap(&bmp, srcRect, bmi);
361
362 // if the bitmap has pixels allocated before the readPixels,
363 // note that and fill them with pattern
364 bool startsWithPixels = !bmp.isNull();
365 if (startsWithPixels) {
366 fillBitmap(&bmp);
367 }
368 uint32_t idBefore = canvas.getDevice()->accessBitmap(false).getGenerationID();
369 bool success =
370 canvas.readPixels(&bmp, srcRect.fLeft,
371 srcRect.fTop, config8888);
372 uint32_t idAfter = canvas.getDevice()->accessBitmap(false).getGenerationID();
373
374 // we expect to succeed when the read isn't fully clipped
375 // out.
376 bool expectSuccess = SkIRect::Intersects(srcRect, DEV_RECT);
377 // determine whether we expected the read to succeed.
378 REPORTER_ASSERT(reporter, success == expectSuccess);
379 // read pixels should never change the gen id
380 REPORTER_ASSERT(reporter, idBefore == idAfter);
381
382 if (success || startsWithPixels) {
383 checkRead(reporter, bmp, srcRect.fLeft, srcRect.fTop,
384 success, startsWithPixels, config8888);
385 } else {
386 // if we had no pixels beforehand and the readPixels
387 // failed then our bitmap should still not have pixels
388 REPORTER_ASSERT(reporter, bmp.isNull());
389 }
390 }
391 // check the old webkit version of readPixels that clips the
392 // bitmap size
393 SkBitmap wkbmp;
394 bool success = canvas.readPixels(srcRect, &wkbmp);
395 SkIRect clippedRect = DEV_RECT;
396 if (clippedRect.intersect(srcRect)) {
397 REPORTER_ASSERT(reporter, success);
398 checkRead(reporter, wkbmp, clippedRect.fLeft,
399 clippedRect.fTop, true, false,
400 SkCanvas::kNative_Premul_Config8888);
401 } else {
402 REPORTER_ASSERT(reporter, !success);
403 }
bsalomon@google.comc6980972011-11-02 19:57:21 +0000404 }
405 }
406 }
407 }
408}
bsalomon@google.comc6980972011-11-02 19:57:21 +0000409
410#include "TestClassDef.h"
411DEFINE_GPUTESTCLASS("ReadPixels", ReadPixelsTestClass, ReadPixelsTest)