OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 // |
| 5 // Test cases for PPB_Graphics2D functions. |
| 6 // As most of them return void, the test automatically confirms that |
| 7 // there is no crash while requiring a visual inspection of the painted output. |
| 8 |
| 9 #include <string.h> |
| 10 |
| 11 #include "native_client/src/include/nacl_macros.h" |
| 12 #include "native_client/src/shared/platform/nacl_check.h" |
| 13 #include "native_client/tests/ppapi_test_lib/get_browser_interface.h" |
| 14 #include "native_client/tests/ppapi_test_lib/test_interface.h" |
| 15 #include "ppapi/c/dev/ppb_testing_dev.h" |
| 16 #include "ppapi/c/pp_bool.h" |
| 17 #include "ppapi/c/pp_errors.h" |
| 18 #include "ppapi/c/pp_point.h" |
| 19 #include "ppapi/c/pp_rect.h" |
| 20 #include "ppapi/c/pp_size.h" |
| 21 #include "ppapi/c/ppb_core.h" |
| 22 #include "ppapi/c/ppb_graphics_2d.h" |
| 23 #include "ppapi/c/ppb_image_data.h" |
| 24 #include "ppapi/c/ppb_instance.h" |
| 25 #include "ppapi/c/ppb_url_loader.h" |
| 26 |
| 27 namespace { |
| 28 |
| 29 const PP_Bool kAlwaysOpaque = PP_TRUE; |
| 30 const PP_Bool kNotAlwaysOpaque = PP_FALSE; |
| 31 const PP_Size kNegativeWidth = PP_MakeSize(-1, 1); |
| 32 const PP_Size kNegativeHeight = PP_MakeSize(1, -1); |
| 33 const PP_Size kZeroPixels = PP_MakeSize(0, 0); |
| 34 const PP_Size kOnePixel = PP_MakeSize(1, 1); |
| 35 const PP_Size k90x90 = PP_MakeSize(90, 90); |
| 36 const PP_Size k60x60 = PP_MakeSize(60, 60); |
| 37 const PP_Size k30x30 = PP_MakeSize(30, 30); |
| 38 const PP_Size k2500x2500 = PP_MakeSize(2500, 2500); |
| 39 const PP_Size k100000x100000 = PP_MakeSize(100000, 100000); |
| 40 const PP_Point kOrigin = PP_MakePoint(0, 0); |
| 41 const PP_Rect kBadRect = { PP_MakePoint(-1, -1), PP_MakeSize(-1, -1) }; |
| 42 const PP_Rect* kEntireImage = NULL; |
| 43 const PP_Bool kInitToZero = PP_TRUE; |
| 44 |
| 45 // TODO(polina, nfullagar): allow specification of non-premultipled colors |
| 46 // and provide alpha premultiplcation in FormatColor(). This will be required |
| 47 // when future PPAPI pixel formats are extended to include non-premultipled |
| 48 // or ignored alpha. |
| 49 |
| 50 struct ColorPremul { uint32_t A, R, G, B; }; // Use premultipled Alpha. |
| 51 const ColorPremul kSheerRed = { 0x88, 0x88, 0x00, 0x00 }; |
| 52 const ColorPremul kSheerBlue = { 0x88, 0x00, 0x00, 0x88 }; |
| 53 const ColorPremul kSheerGray = { 0x77, 0x55, 0x55, 0x55 }; |
| 54 const ColorPremul kOpaqueGreen = { 0xFF, 0x00, 0xFF, 0x00 }; |
| 55 const ColorPremul kOpaqueBlack = { 0xFF, 0x00, 0x00, 0x00 }; |
| 56 const ColorPremul kOpaqueWhite = { 0xFF, 0xFF, 0xFF, 0xFF }; |
| 57 const ColorPremul kOpaqueYellow = { 0xFF, 0xFF, 0xFF, 0x00 }; |
| 58 const int kBytesPerPixel = sizeof(uint32_t); // 4 bytes for BGRA or RGBA. |
| 59 |
| 60 // Assumes premultipled Alpha. |
| 61 uint32_t FormatColor(PP_ImageDataFormat format, ColorPremul color) { |
| 62 if (format == PP_IMAGEDATAFORMAT_BGRA_PREMUL) |
| 63 return (color.A << 24) | (color.R << 16) | (color.G << 8) | (color.B); |
| 64 else if (format == PP_IMAGEDATAFORMAT_RGBA_PREMUL) |
| 65 return (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R); |
| 66 else |
| 67 NACL_NOTREACHED(); |
| 68 } |
| 69 |
| 70 // Make graphics2d contexts for each test the same size, so we can layer |
| 71 // the images without invalidating the previous ones. |
| 72 PP_Resource CreateGraphics2D_90x90() { |
| 73 PP_Resource graphics2d = PPBGraphics2D()->Create( |
| 74 pp_instance(), &k90x90, kNotAlwaysOpaque); |
| 75 CHECK(graphics2d != kInvalidResource); |
| 76 PPBInstance()->BindGraphics(pp_instance(), graphics2d); |
| 77 return graphics2d; |
| 78 } |
| 79 |
| 80 PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color, void** bmp) { |
| 81 PP_ImageDataFormat image_format = PPBImageData()->GetNativeImageDataFormat(); |
| 82 uint32_t formatted_pixel_color = FormatColor(image_format, pixel_color); |
| 83 PP_Resource image_data = PPBImageData()->Create( |
| 84 pp_instance(), image_format, &size, kInitToZero); |
| 85 CHECK(image_data != kInvalidResource); |
| 86 PP_ImageDataDesc image_desc; |
| 87 CHECK(PPBImageData()->Describe(image_data, &image_desc) == PP_TRUE); |
| 88 *bmp = NULL; |
| 89 *bmp = PPBImageData()->Map(image_data); |
| 90 CHECK(*bmp != NULL); |
| 91 uint32_t* bmp_words = static_cast<uint32_t*>(*bmp); |
| 92 int num_pixels = image_desc.stride / kBytesPerPixel * image_desc.size.height; |
| 93 for (int i = 0; i < num_pixels; i++) |
| 94 bmp_words[i] = formatted_pixel_color; |
| 95 return image_data; |
| 96 } |
| 97 |
| 98 PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color) { |
| 99 void* bitmap = NULL; |
| 100 return CreateImageData(size, pixel_color, &bitmap); |
| 101 } |
| 102 |
| 103 struct FlushData { |
| 104 FlushData(PP_Resource g, PP_Resource i) : graphics2d(g), image_data(i) {} |
| 105 PP_Resource graphics2d; |
| 106 PP_Resource image_data; |
| 107 }; |
| 108 |
| 109 void FlushCallback(void* user_data, int32_t result); |
| 110 int g_expected_flush_calls = 0; |
| 111 PP_CompletionCallback MakeTestableFlushCallback(const char* name, |
| 112 PP_Resource graphics2d, |
| 113 PP_Resource image_data, |
| 114 int num_calls) { |
| 115 g_expected_flush_calls = num_calls; |
| 116 void* user_data = new FlushData(graphics2d, image_data); |
| 117 return MakeTestableCompletionCallback(name, FlushCallback, user_data); |
| 118 } |
| 119 |
| 120 void FlushCallback(void* user_data, int32_t result) { |
| 121 --g_expected_flush_calls; |
| 122 CHECK(g_expected_flush_calls >= 0); |
| 123 CHECK(user_data != NULL); |
| 124 CHECK(result == PP_OK); |
| 125 |
| 126 FlushData* data = static_cast<FlushData*>(user_data); |
| 127 PP_Resource graphics2d = data->graphics2d; |
| 128 PP_Resource image_data = data->image_data; |
| 129 if (g_expected_flush_calls == 0) { |
| 130 PPBCore()->ReleaseResource(graphics2d); |
| 131 PPBCore()->ReleaseResource(image_data); |
| 132 delete data; |
| 133 } else { |
| 134 PPBGraphics2D()->PaintImageData(graphics2d, image_data, &kOrigin, NULL); |
| 135 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 136 "FlushAnimationCallback", |
| 137 graphics2d, image_data, g_expected_flush_calls); |
| 138 CHECK(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); |
| 139 } |
| 140 } |
| 141 |
| 142 bool IsEqualSize(PP_Size size1, PP_Size size2) { |
| 143 return (size1.width == size2.width && size1.height == size2.height); |
| 144 } |
| 145 |
| 146 bool IsSquareOnScreen(PP_Resource graphics2d, PP_Point origin, PP_Size square, |
| 147 ColorPremul color) { |
| 148 PP_Size size; |
| 149 PP_Bool dummy; |
| 150 CHECK(PP_TRUE == PPBGraphics2D()->Describe(graphics2d, &size, &dummy)); |
| 151 |
| 152 void* bitmap = NULL; |
| 153 PP_Resource image = CreateImageData(size, kOpaqueBlack, &bitmap); |
| 154 |
| 155 PP_ImageDataDesc image_desc; |
| 156 CHECK(PP_TRUE == PPBImageData()->Describe(image, &image_desc)); |
| 157 int32_t stride = image_desc.stride / kBytesPerPixel; // width + padding. |
| 158 uint32_t expected_color = FormatColor(image_desc.format, color); |
| 159 CHECK(origin.x >= 0 && origin.y >= 0 && |
| 160 (origin.x + square.width) <= stride && |
| 161 (origin.y + square.height) <= image_desc.size.height); |
| 162 |
| 163 CHECK(PP_TRUE == PPBTestingDev()->ReadImageData(graphics2d, image, &kOrigin)); |
| 164 bool found_error = false; |
| 165 for (int y = origin.y; y < origin.y + square.height && !found_error; y++) { |
| 166 for (int x = origin.x; x < origin.x + square.width && !found_error; x++) { |
| 167 uint32_t pixel_color = static_cast<uint32_t*>(bitmap)[stride * y + x]; |
| 168 found_error = (pixel_color != expected_color); |
| 169 } |
| 170 } |
| 171 |
| 172 PPBCore()->ReleaseResource(image); |
| 173 return !found_error; |
| 174 } |
| 175 |
| 176 //////////////////////////////////////////////////////////////////////////////// |
| 177 // Test Cases |
| 178 //////////////////////////////////////////////////////////////////////////////// |
| 179 |
| 180 // Tests PPB_Graphics2D::Create(). |
| 181 void TestCreate() { |
| 182 PP_Resource graphics2d = kInvalidResource; |
| 183 const PPB_Graphics2D* ppb = PPBGraphics2D(); |
| 184 |
| 185 // Invalid instance and size -> invalid resource. |
| 186 graphics2d = ppb->Create(kInvalidInstance, &k30x30, kAlwaysOpaque); |
| 187 EXPECT(graphics2d == kInvalidResource); |
| 188 graphics2d = ppb->Create(kInvalidInstance, &k30x30, kNotAlwaysOpaque); |
| 189 EXPECT(graphics2d == kInvalidResource); |
| 190 graphics2d = ppb->Create(kNotAnInstance, &k30x30, kAlwaysOpaque); |
| 191 EXPECT(graphics2d == kInvalidResource); |
| 192 graphics2d = ppb->Create(kNotAnInstance, &k30x30, kNotAlwaysOpaque); |
| 193 EXPECT(graphics2d == kInvalidResource); |
| 194 graphics2d = ppb->Create(pp_instance(), &k100000x100000, kAlwaysOpaque); |
| 195 EXPECT(graphics2d == kInvalidResource); |
| 196 graphics2d = ppb->Create(pp_instance(), &k100000x100000, kNotAlwaysOpaque); |
| 197 EXPECT(graphics2d == kInvalidResource); |
| 198 graphics2d = ppb->Create(pp_instance(), &kZeroPixels, kAlwaysOpaque); |
| 199 EXPECT(graphics2d == kInvalidResource); |
| 200 graphics2d = ppb->Create(pp_instance(), &kZeroPixels, kNotAlwaysOpaque); |
| 201 EXPECT(graphics2d == kInvalidResource); |
| 202 graphics2d = ppb->Create(pp_instance(), &kNegativeWidth, kAlwaysOpaque); |
| 203 EXPECT(graphics2d == kInvalidResource); |
| 204 graphics2d = ppb->Create(pp_instance(), &kNegativeHeight, kNotAlwaysOpaque); |
| 205 EXPECT(graphics2d == kInvalidResource); |
| 206 // NULL size -> Internal error in rpc method. |
| 207 graphics2d = ppb->Create(pp_instance(), NULL, kAlwaysOpaque); |
| 208 EXPECT(graphics2d == kInvalidResource); |
| 209 graphics2d = ppb->Create(pp_instance(), NULL, kNotAlwaysOpaque); |
| 210 EXPECT(graphics2d == kInvalidResource); |
| 211 |
| 212 // Valid instance and size -> valid resource. |
| 213 graphics2d = ppb->Create(pp_instance(), &kOnePixel, kAlwaysOpaque); |
| 214 EXPECT(graphics2d != kInvalidResource); |
| 215 PPBCore()->ReleaseResource(graphics2d); |
| 216 graphics2d = ppb->Create(pp_instance(), &kOnePixel, kNotAlwaysOpaque); |
| 217 EXPECT(graphics2d != kInvalidResource); |
| 218 PPBCore()->ReleaseResource(graphics2d); |
| 219 graphics2d = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque); |
| 220 EXPECT(graphics2d != kInvalidResource); |
| 221 PPBCore()->ReleaseResource(graphics2d); |
| 222 graphics2d = ppb->Create(pp_instance(), &k30x30, kNotAlwaysOpaque); |
| 223 EXPECT(graphics2d != kInvalidResource); |
| 224 PPBCore()->ReleaseResource(graphics2d); |
| 225 graphics2d = ppb->Create(pp_instance(), &k2500x2500, kAlwaysOpaque); |
| 226 EXPECT(graphics2d != kInvalidResource); |
| 227 PPBCore()->ReleaseResource(graphics2d); |
| 228 graphics2d = ppb->Create(pp_instance(), &k2500x2500, kNotAlwaysOpaque); |
| 229 EXPECT(graphics2d != kInvalidResource); |
| 230 PPBCore()->ReleaseResource(graphics2d); |
| 231 |
| 232 TEST_PASSED; |
| 233 } |
| 234 |
| 235 // Tests PPB_Graphics2D::IsGraphics2D(). |
| 236 void TestIsGraphics2D() { |
| 237 // Invalid / non-existent / non-Graphics2D resource -> false. |
| 238 EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(kInvalidResource)); |
| 239 EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(kNotAResource)); |
| 240 PP_Resource url_loader = PPBURLLoader()->Create(pp_instance()); |
| 241 CHECK(url_loader != kInvalidResource); |
| 242 EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(url_loader)); |
| 243 PPBCore()->ReleaseResource(url_loader); |
| 244 |
| 245 // Current Graphics2D resource -> true. |
| 246 PP_Resource graphics2d = PPBGraphics2D()->Create( |
| 247 pp_instance(), &k30x30, kAlwaysOpaque); |
| 248 EXPECT(PP_TRUE == PPBGraphics2D()->IsGraphics2D(graphics2d)); |
| 249 |
| 250 // Released Graphis2D resource -> false. |
| 251 PPBCore()->ReleaseResource(graphics2d); |
| 252 EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(graphics2d)); |
| 253 |
| 254 TEST_PASSED; |
| 255 } |
| 256 |
| 257 // Tests PPB_Graphics2D::Describe(). |
| 258 void TestDescribe() { |
| 259 PP_Resource graphics2d = kInvalidResource; |
| 260 const PPB_Graphics2D* ppb = PPBGraphics2D(); |
| 261 struct PP_Size size = k90x90; |
| 262 PP_Bool is_always_opaque = PP_TRUE; |
| 263 |
| 264 // Valid resource -> output = configuration, true. |
| 265 graphics2d = ppb->Create(pp_instance(), &k30x30, kNotAlwaysOpaque); |
| 266 EXPECT(PP_TRUE == ppb->Describe(graphics2d, &size, &is_always_opaque)); |
| 267 EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, k30x30)); |
| 268 PPBCore()->ReleaseResource(graphics2d); |
| 269 |
| 270 graphics2d = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque); |
| 271 EXPECT(PP_TRUE == ppb->Describe(graphics2d, &size, &is_always_opaque)); |
| 272 EXPECT(is_always_opaque == PP_TRUE && IsEqualSize(size, k30x30)); |
| 273 PPBCore()->ReleaseResource(graphics2d); |
| 274 |
| 275 // NULL outputs -> output = unchanged, false. |
| 276 EXPECT(PP_FALSE == ppb->Describe(graphics2d, NULL, &is_always_opaque)); |
| 277 EXPECT(PP_FALSE == ppb->Describe(graphics2d, &size, NULL)); |
| 278 EXPECT(is_always_opaque == PP_TRUE && IsEqualSize(size, k30x30)); |
| 279 |
| 280 // Invalid / non-existent resource -> output = 0, false. |
| 281 EXPECT(PP_FALSE == ppb->Describe(kInvalidResource, &size, &is_always_opaque)); |
| 282 EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, kZeroPixels)); |
| 283 |
| 284 is_always_opaque = PP_TRUE; |
| 285 size = k90x90; |
| 286 EXPECT(PP_FALSE == ppb->Describe(kNotAResource, &size, &is_always_opaque)); |
| 287 EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, kZeroPixels)); |
| 288 |
| 289 TEST_PASSED; |
| 290 } |
| 291 |
| 292 // Tests PPB_Graphics2D::PaintImageData() with specified image rect. |
| 293 // Draws a blue square in the top right corner. |
| 294 // Requires a visual inspection. |
| 295 void TestPaintImageData() { |
| 296 const PPB_Graphics2D* ppb = PPBGraphics2D(); |
| 297 PP_Resource graphics2d = CreateGraphics2D_90x90(); |
| 298 PP_Resource image_data = CreateImageData(k60x60, kSheerBlue); |
| 299 PP_Resource image_data_noop = CreateImageData(k60x60, kOpaqueBlack); |
| 300 PP_Rect src_rect = { PP_MakePoint(30, 30), k30x30 }; |
| 301 PP_Point top_left = PP_MakePoint(30, -30); // target origin = (60, 0); |
| 302 PP_Point clip_up = PP_MakePoint(0, -31); // target origin = (30, -1) |
| 303 PP_Point clip_left = PP_MakePoint(-31, 0); // target origin = (-1, 30) |
| 304 PP_Point clip_right = PP_MakePoint(31, 0); // target origin = (61, 30) |
| 305 PP_Point clip_down = PP_MakePoint(0, 31); // target origin = (30, 61) |
| 306 |
| 307 // Valid args -> copies to backing store and paints to screen after Flush(). |
| 308 ppb->PaintImageData(graphics2d, image_data, &top_left, &src_rect); |
| 309 |
| 310 // Invalid args -> no effect, no crash. |
| 311 ppb->PaintImageData(kInvalidResource, image_data_noop, &top_left, &src_rect); |
| 312 ppb->PaintImageData(kNotAResource, image_data_noop, &top_left, &src_rect); |
| 313 ppb->PaintImageData(graphics2d, kInvalidResource, &top_left, &src_rect); |
| 314 ppb->PaintImageData(graphics2d, kNotAResource, &top_left, &src_rect); |
| 315 ppb->PaintImageData(graphics2d, image_data_noop, &clip_up, &src_rect); |
| 316 ppb->PaintImageData(graphics2d, image_data_noop, &clip_left, &src_rect); |
| 317 ppb->PaintImageData(graphics2d, image_data_noop, &clip_right, &src_rect); |
| 318 ppb->PaintImageData(graphics2d, image_data_noop, &clip_down, &src_rect); |
| 319 ppb->PaintImageData(graphics2d, image_data_noop, &kOrigin, &kBadRect); |
| 320 // NULL top_left - > Internal error in rpc method. |
| 321 ppb->PaintImageData(graphics2d, image_data_noop, NULL, &src_rect); |
| 322 ppb->PaintImageData(kInvalidResource, kNotAResource, NULL, &src_rect); |
| 323 |
| 324 // Paints backing store image to screen only after Flush(). |
| 325 PP_Point top_right = PP_MakePoint(60, 0); |
| 326 EXPECT(!IsSquareOnScreen(graphics2d, top_right, k30x30, kSheerBlue)); |
| 327 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 328 "PaintImageDataFlushCallback", graphics2d, image_data, 1); |
| 329 EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); |
| 330 EXPECT(IsSquareOnScreen(graphics2d, top_right, k30x30, kSheerBlue)); |
| 331 |
| 332 // This should have no effect on Flush(). |
| 333 ppb->PaintImageData(graphics2d, image_data_noop, &top_left, &src_rect); |
| 334 PPBCore()->ReleaseResource(image_data_noop); |
| 335 |
| 336 TEST_PASSED; |
| 337 } |
| 338 |
| 339 // Tests PPB_Graphics2D::PaintImageData() with default rect for entire image. |
| 340 // Draws a yellow square in the bottom left corner. |
| 341 // Requires a visual inspection. |
| 342 void TestPaintImageDataEntire() { |
| 343 const PPB_Graphics2D* ppb = PPBGraphics2D(); |
| 344 PP_Resource graphics2d = CreateGraphics2D_90x90(); |
| 345 PP_Resource image_data = CreateImageData(k30x30, kOpaqueYellow); |
| 346 PP_Resource image_data_noop = CreateImageData(k30x30, kOpaqueBlack); |
| 347 PP_Point bottom_left = PP_MakePoint(0, 60); |
| 348 PP_Point clip_up = PP_MakePoint(0, -1); |
| 349 PP_Point clip_left = PP_MakePoint(-1, 0); |
| 350 PP_Point clip_right = PP_MakePoint(61, 0); |
| 351 PP_Point clip_down = PP_MakePoint(0, 61); |
| 352 |
| 353 // Valid args -> copies to backing store. |
| 354 ppb->PaintImageData(graphics2d, image_data, &bottom_left, kEntireImage); |
| 355 |
| 356 // Invalid args -> no effect, no crash. |
| 357 ppb->PaintImageData( |
| 358 kInvalidResource, image_data_noop, &bottom_left, kEntireImage); |
| 359 ppb->PaintImageData( |
| 360 kNotAResource, image_data_noop, &bottom_left, kEntireImage); |
| 361 ppb->PaintImageData(graphics2d, kInvalidResource, &bottom_left, kEntireImage); |
| 362 ppb->PaintImageData(graphics2d, kNotAResource, &bottom_left, kEntireImage); |
| 363 ppb->PaintImageData(graphics2d, image_data_noop, &clip_up, kEntireImage); |
| 364 ppb->PaintImageData(graphics2d, image_data_noop, &clip_left, kEntireImage); |
| 365 ppb->PaintImageData(graphics2d, image_data_noop, &clip_right, kEntireImage); |
| 366 ppb->PaintImageData(graphics2d, image_data_noop, &clip_down, kEntireImage); |
| 367 // NULL top_left - > Internal error in rpc method. |
| 368 ppb->PaintImageData(graphics2d, image_data_noop, NULL, kEntireImage); |
| 369 ppb->PaintImageData(kInvalidResource, kNotAResource, NULL, kEntireImage); |
| 370 |
| 371 // Paints backing store image to the screen only after Flush(). |
| 372 EXPECT(!IsSquareOnScreen(graphics2d, bottom_left, k30x30, kOpaqueYellow)); |
| 373 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 374 "PaintImageDataEntireFlushCallback", graphics2d, image_data, 1); |
| 375 EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); |
| 376 EXPECT(IsSquareOnScreen(graphics2d, bottom_left, k30x30, kOpaqueYellow)); |
| 377 |
| 378 // This should have no effect on Flush(). |
| 379 ppb->PaintImageData(graphics2d, image_data_noop, &bottom_left, kEntireImage); |
| 380 PPBCore()->ReleaseResource(image_data_noop); |
| 381 |
| 382 TEST_PASSED; |
| 383 } |
| 384 |
| 385 // Tests PPB_Graphics2D::Scroll() with specified image rect. |
| 386 // Draws a white square at the top left, then in the middle. |
| 387 // Requires a visual inspection. |
| 388 void TestScroll() { |
| 389 const PPB_Graphics2D* ppb = PPBGraphics2D(); |
| 390 PP_Resource graphics2d = CreateGraphics2D_90x90(); |
| 391 PP_Resource image_data = CreateImageData(k30x30, kOpaqueWhite); |
| 392 PP_Rect src_rect = { kOrigin, k30x30 }; |
| 393 PP_Rect clip_rect = { kOrigin, k60x60 }; |
| 394 PP_Point middle = PP_MakePoint(30, 30); |
| 395 ppb->PaintImageData(graphics2d, image_data, &kOrigin, &src_rect); |
| 396 |
| 397 // Valid args -> scrolls backing store and paints to screen after Flush(). |
| 398 ppb->Scroll(graphics2d, &clip_rect, &middle); |
| 399 |
| 400 // Invalid args -> no effect, no crash. |
| 401 ppb->Scroll(kInvalidResource, &clip_rect, &middle); |
| 402 ppb->Scroll(kNotAResource, &clip_rect, &middle); |
| 403 ppb->Scroll(graphics2d, &clip_rect, NULL); // Internal error in rpc method. |
| 404 |
| 405 // Paints backing store image to the sreen only after Flush(). |
| 406 EXPECT(!IsSquareOnScreen(graphics2d, middle, k30x30, kOpaqueWhite)); |
| 407 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 408 "ScrollFlushCallback", graphics2d, image_data, 1); |
| 409 EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); |
| 410 EXPECT(IsSquareOnScreen(graphics2d, middle, k30x30, kOpaqueWhite)); |
| 411 |
| 412 TEST_PASSED; |
| 413 } |
| 414 |
| 415 // Tests PPB_Graphics2D::Scroll() with default rect for entire image.. |
| 416 // Draws a green square in the top left, then bottom right. |
| 417 // Requires a visual inspection. |
| 418 void TestScrollEntire() { |
| 419 const PPB_Graphics2D* ppb = PPBGraphics2D(); |
| 420 PP_Resource graphics2d = CreateGraphics2D_90x90(); |
| 421 PP_Resource image_data = CreateImageData(k30x30, kOpaqueGreen); |
| 422 PP_Point bottom_right = PP_MakePoint(60, 60); |
| 423 ppb->PaintImageData(graphics2d, image_data, &kOrigin, kEntireImage); |
| 424 |
| 425 // Valid args -> scrolls backing store and paints to screen after Flush(). |
| 426 ppb->Scroll(graphics2d, kEntireImage, &bottom_right); |
| 427 |
| 428 // Invalid args -> no crash. |
| 429 ppb->Scroll(kInvalidResource, kEntireImage, &bottom_right); |
| 430 ppb->Scroll(kNotAResource, kEntireImage, &bottom_right); |
| 431 ppb->Scroll(graphics2d, kEntireImage, NULL); // Internal error in rpc method. |
| 432 |
| 433 // Paints backing store image to the screen only after Flush(). |
| 434 EXPECT(!IsSquareOnScreen(graphics2d, bottom_right, k30x30, kOpaqueGreen)); |
| 435 ppb->Scroll(graphics2d, kEntireImage, &bottom_right); |
| 436 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 437 "ScrollEntireFlushCallback", graphics2d, image_data, 1); |
| 438 EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc)); |
| 439 EXPECT(IsSquareOnScreen(graphics2d, bottom_right, k30x30, kOpaqueGreen)); |
| 440 |
| 441 TEST_PASSED; |
| 442 } |
| 443 |
| 444 // Tests PPB_Graphics2D::ReplaceContents(). |
| 445 // Colors the entire graphics area gray. |
| 446 // Requires a visual inspection. |
| 447 void TestReplaceContents() { |
| 448 PP_Resource graphics2d = CreateGraphics2D_90x90(); |
| 449 PP_Resource image_data = CreateImageData(k90x90, kSheerGray); |
| 450 PP_Resource image_data_noop = CreateImageData(k90x90, kOpaqueBlack); |
| 451 PP_Resource image_data_size_mismatch = CreateImageData(k30x30, kOpaqueBlack); |
| 452 |
| 453 // Valid args -> replaces backing store. |
| 454 PPBGraphics2D()->ReplaceContents(graphics2d, image_data); |
| 455 |
| 456 // Invalid args -> no effect, no crash. |
| 457 PPBGraphics2D()->ReplaceContents(kInvalidResource, image_data_noop); |
| 458 PPBGraphics2D()->ReplaceContents(kNotAResource, image_data_noop); |
| 459 PPBGraphics2D()->ReplaceContents(graphics2d, kInvalidResource); |
| 460 PPBGraphics2D()->ReplaceContents(graphics2d, kNotAResource); |
| 461 PPBGraphics2D()->ReplaceContents(kInvalidResource, kNotAResource); |
| 462 PPBGraphics2D()->ReplaceContents(graphics2d, image_data_size_mismatch); |
| 463 |
| 464 // Paints backing store image to the screen only after Flush(). |
| 465 EXPECT(!IsSquareOnScreen(graphics2d, kOrigin, k90x90, kSheerGray)); |
| 466 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 467 "ReplaceContentsFlushCallback", graphics2d, image_data, 1); |
| 468 EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); |
| 469 EXPECT(IsSquareOnScreen(graphics2d, kOrigin, k90x90, kSheerGray)); |
| 470 |
| 471 // This should have no effect on Flush(). |
| 472 PPBGraphics2D()->ReplaceContents(graphics2d, image_data_noop); |
| 473 PPBCore()->ReleaseResource(image_data_noop); |
| 474 PPBCore()->ReleaseResource(image_data_size_mismatch); |
| 475 |
| 476 TEST_PASSED; |
| 477 } |
| 478 |
| 479 // Tests PPB_Graphics2D::Flush(). |
| 480 void TestFlush() { |
| 481 PP_Resource graphics2d = PPBGraphics2D()->Create( |
| 482 pp_instance(), &k90x90, kAlwaysOpaque); |
| 483 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 484 "FlushCallback", graphics2d, kInvalidResource, 1); |
| 485 |
| 486 // Invalid args -> PP_ERROR_BAD..., no callback. |
| 487 EXPECT(PP_ERROR_BADRESOURCE == PPBGraphics2D()->Flush(kInvalidResource, cc)); |
| 488 EXPECT(PP_ERROR_BADRESOURCE == PPBGraphics2D()->Flush(kNotAResource, cc)); |
| 489 EXPECT(PP_ERROR_BADARGUMENT == |
| 490 PPBGraphics2D()->Flush(graphics2d, PP_BlockUntilComplete())); |
| 491 |
| 492 // Valid args -> PP_OK_COMPLETIONPENDING, expect callback. |
| 493 EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); |
| 494 |
| 495 // Duplicate call -> PP_ERROR_INPROGRESS, no callback. |
| 496 EXPECT(PP_ERROR_INPROGRESS == PPBGraphics2D()->Flush(graphics2d, cc)); |
| 497 |
| 498 TEST_PASSED; |
| 499 } |
| 500 |
| 501 // Tests continious Paint/Flush chaining. |
| 502 void TestFlushAnimation() { |
| 503 PP_Resource graphics2d = CreateGraphics2D_90x90(); |
| 504 PP_Resource image_data = CreateImageData(k30x30, kSheerRed); |
| 505 |
| 506 PPBGraphics2D()->PaintImageData(graphics2d, image_data, &kOrigin, NULL); |
| 507 PP_CompletionCallback cc = MakeTestableFlushCallback( |
| 508 "FlushAnimationCallback", graphics2d, image_data, 10); |
| 509 EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc)); |
| 510 |
| 511 TEST_PASSED; |
| 512 } |
| 513 |
| 514 // Stress testing of a large number of resources. |
| 515 void TestStress() { |
| 516 // TODO(nfullagar): Increase the number of resources once the cause of the |
| 517 // stress test flake is fixed. |
| 518 const int kManyResources = 100; |
| 519 PP_Resource graphics2d[kManyResources]; |
| 520 const PPB_Graphics2D* ppb = PPBGraphics2D(); |
| 521 |
| 522 for (int i = 0; i < kManyResources; i++) { |
| 523 graphics2d[i] = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque); |
| 524 EXPECT(graphics2d[i] != kInvalidResource); |
| 525 EXPECT(PP_TRUE == ppb->IsGraphics2D(graphics2d[i])); |
| 526 } |
| 527 for (int i = 0; i < kManyResources; i++) { |
| 528 PPBCore()->ReleaseResource(graphics2d[i]); |
| 529 EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(graphics2d[i])); |
| 530 } |
| 531 |
| 532 TEST_PASSED; |
| 533 } |
| 534 |
| 535 } // namespace |
| 536 |
| 537 void SetupTests() { |
| 538 RegisterTest("TestCreate", TestCreate); |
| 539 RegisterTest("TestIsGraphics2D", TestIsGraphics2D); |
| 540 RegisterTest("TestDescribe", TestDescribe); |
| 541 RegisterTest("TestPaintImageData", TestPaintImageData); |
| 542 RegisterTest("TestPaintImageDataEntire", TestPaintImageDataEntire); |
| 543 RegisterTest("TestScroll", TestScroll); |
| 544 RegisterTest("TestScrollEntire", TestScrollEntire); |
| 545 RegisterTest("TestReplaceContents", TestReplaceContents); |
| 546 RegisterTest("TestFlush", TestFlush); |
| 547 RegisterTest("TestFlushAnimation", TestFlushAnimation); |
| 548 RegisterTest("TestStress", TestStress); |
| 549 } |
| 550 |
| 551 void SetupPluginInterfaces() { |
| 552 // none |
| 553 } |
OLD | NEW |