| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/tests/test_graphics_2d.h" | 5 #include "ppapi/tests/test_graphics_2d.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include <set> | 10 #include <set> |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 // A NOP flush callback for use in various tests. | 31 // A NOP flush callback for use in various tests. |
| 32 void FlushCallbackNOP(void* data, int32_t result) { | 32 void FlushCallbackNOP(void* data, int32_t result) { |
| 33 } | 33 } |
| 34 | 34 |
| 35 void FlushCallbackQuitMessageLoop(void* data, int32_t result) { | 35 void FlushCallbackQuitMessageLoop(void* data, int32_t result) { |
| 36 static_cast<TestGraphics2D*>(data)->QuitMessageLoop(); | 36 static_cast<TestGraphics2D*>(data)->QuitMessageLoop(); |
| 37 } | 37 } |
| 38 | 38 |
| 39 bool CanFlushContext(pp::Instance* instance, pp::Graphics2D* context) { |
| 40 TestCompletionCallback callback(instance->pp_instance()); |
| 41 callback.WaitForResult(context->Flush(callback.GetCallback())); |
| 42 return (callback.result() == PP_OK); |
| 43 } |
| 44 |
| 45 bool CanFlushContextC(pp::Instance* instance, PP_Resource graphics_2d, |
| 46 const PPB_Graphics2D_1_1* graphics_2d_if) { |
| 47 TestCompletionCallback callback(instance->pp_instance()); |
| 48 callback.WaitForResult(graphics_2d_if->Flush( |
| 49 graphics_2d, callback.GetCallback().pp_completion_callback())); |
| 50 return (callback.result() == PP_OK); |
| 51 } |
| 52 |
| 39 } // namespace | 53 } // namespace |
| 40 | 54 |
| 41 TestGraphics2D::TestGraphics2D(TestingInstance* instance) | 55 TestGraphics2D::TestGraphics2D(TestingInstance* instance) |
| 42 : TestCase(instance), | 56 : TestCase(instance), |
| 43 is_view_changed_(false), | 57 is_view_changed_(false), |
| 44 post_quit_on_view_changed_(false) { | 58 post_quit_on_view_changed_(false) { |
| 45 } | 59 } |
| 46 | 60 |
| 47 bool TestGraphics2D::Init() { | 61 bool TestGraphics2D::Init() { |
| 48 graphics_2d_interface_ = static_cast<const PPB_Graphics2D*>( | 62 graphics_2d_interface_ = static_cast<const PPB_Graphics2D*>( |
| 49 pp::Module::Get()->GetBrowserInterface(PPB_GRAPHICS_2D_INTERFACE)); | 63 pp::Module::Get()->GetBrowserInterface(PPB_GRAPHICS_2D_INTERFACE_1_1)); |
| 50 image_data_interface_ = static_cast<const PPB_ImageData*>( | 64 image_data_interface_ = static_cast<const PPB_ImageData*>( |
| 51 pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE)); | 65 pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE_1_0)); |
| 52 return graphics_2d_interface_ && image_data_interface_ && | 66 return graphics_2d_interface_ && image_data_interface_ && |
| 53 CheckTestingInterface(); | 67 CheckTestingInterface(); |
| 54 } | 68 } |
| 55 | 69 |
| 56 void TestGraphics2D::RunTests(const std::string& filter) { | 70 void TestGraphics2D::RunTests(const std::string& filter) { |
| 57 RUN_TEST(InvalidResource, filter); | 71 RUN_TEST(InvalidResource, filter); |
| 58 RUN_TEST(InvalidSize, filter); | 72 RUN_TEST(InvalidSize, filter); |
| 59 RUN_TEST(Humongous, filter); | 73 RUN_TEST(Humongous, filter); |
| 60 RUN_TEST(InitToZero, filter); | 74 RUN_TEST(InitToZero, filter); |
| 61 RUN_TEST(Describe, filter); | 75 RUN_TEST(Describe, filter); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 87 uint32_t color) const { | 101 uint32_t color) const { |
| 88 pp::ImageData readback(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 102 pp::ImageData readback(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 89 dc.size(), false); | 103 dc.size(), false); |
| 90 if (readback.is_null()) | 104 if (readback.is_null()) |
| 91 return false; | 105 return false; |
| 92 if (!ReadImageData(dc, &readback, pp::Point(0, 0))) | 106 if (!ReadImageData(dc, &readback, pp::Point(0, 0))) |
| 93 return false; | 107 return false; |
| 94 return IsSquareInImage(readback, 0, pp::Rect(dc.size()), color); | 108 return IsSquareInImage(readback, 0, pp::Rect(dc.size()), color); |
| 95 } | 109 } |
| 96 | 110 |
| 97 bool TestGraphics2D::ResourceHealthCheck(pp::Instance* instance, | 111 std::string TestGraphics2D::FlushAndWaitForDone(pp::Graphics2D* context) { |
| 98 pp::Graphics2D* context) { | 112 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 99 TestCompletionCallback callback(instance->pp_instance(), callback_type()); | |
| 100 callback.WaitForResult(context->Flush(callback.GetCallback())); | 113 callback.WaitForResult(context->Flush(callback.GetCallback())); |
| 101 if (callback.result() < 0) | 114 CHECK_CALLBACK_BEHAVIOR(callback); |
| 102 return callback.result() != PP_ERROR_FAILED; | 115 ASSERT_EQ(PP_OK, callback.result()); |
| 103 else if (callback.result() == 0) | 116 PASS(); |
| 104 return false; | |
| 105 return true; | |
| 106 } | |
| 107 | |
| 108 bool TestGraphics2D::ResourceHealthCheckForC(pp::Instance* instance, | |
| 109 PP_Resource graphics_2d) { | |
| 110 TestCompletionCallback callback(instance->pp_instance(), callback_type()); | |
| 111 callback.WaitForResult(graphics_2d_interface_->Flush( | |
| 112 graphics_2d, callback.GetCallback().pp_completion_callback())); | |
| 113 if (callback.result() < 0) | |
| 114 return callback.result() != PP_ERROR_FAILED; | |
| 115 else if (callback.result() == 0) | |
| 116 return false; | |
| 117 return true; | |
| 118 } | |
| 119 | |
| 120 bool TestGraphics2D::FlushAndWaitForDone(pp::Graphics2D* context) { | |
| 121 int32_t flags = (force_async_ ? 0 : PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
| 122 pp::CompletionCallback cc(&FlushCallbackQuitMessageLoop, this, flags); | |
| 123 int32_t rv = context->Flush(cc); | |
| 124 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | |
| 125 return false; | |
| 126 if (rv == PP_OK) | |
| 127 return true; | |
| 128 if (rv != PP_OK_COMPLETIONPENDING) | |
| 129 return false; | |
| 130 testing_interface_->RunMessageLoop(instance_->pp_instance()); | |
| 131 return true; | |
| 132 } | 117 } |
| 133 | 118 |
| 134 void TestGraphics2D::FillRectInImage(pp::ImageData* image, | 119 void TestGraphics2D::FillRectInImage(pp::ImageData* image, |
| 135 const pp::Rect& rect, | 120 const pp::Rect& rect, |
| 136 uint32_t color) const { | 121 uint32_t color) const { |
| 137 for (int y = rect.y(); y < rect.bottom(); y++) { | 122 for (int y = rect.y(); y < rect.bottom(); y++) { |
| 138 uint32_t* row = image->GetAddr32(pp::Point(rect.x(), y)); | 123 uint32_t* row = image->GetAddr32(pp::Point(rect.x(), y)); |
| 139 for (int pixel = 0; pixel < rect.width(); pixel++) | 124 for (int pixel = 0; pixel < rect.width(); pixel++) |
| 140 row[pixel] = color; | 125 row[pixel] = color; |
| 141 } | 126 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 | 196 |
| 212 | 197 |
| 213 PP_Resource TestGraphics2D::ReplaceContentsAndReturnID( | 198 PP_Resource TestGraphics2D::ReplaceContentsAndReturnID( |
| 214 pp::Graphics2D* dc, | 199 pp::Graphics2D* dc, |
| 215 const pp::Size& size) { | 200 const pp::Size& size) { |
| 216 pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, true); | 201 pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, true); |
| 217 | 202 |
| 218 PP_Resource id = image.pp_resource(); | 203 PP_Resource id = image.pp_resource(); |
| 219 | 204 |
| 220 dc->ReplaceContents(&image); | 205 dc->ReplaceContents(&image); |
| 221 if (!FlushAndWaitForDone(dc)) | 206 std::string result = FlushAndWaitForDone(dc); |
| 207 if (!result.empty()) |
| 222 return 0; | 208 return 0; |
| 223 | 209 |
| 224 return id; | 210 return id; |
| 225 } | 211 } |
| 226 | 212 |
| 227 // Test all the functions with an invalid handle. Most of these just check for | 213 // Test all the functions with an invalid handle. Most of these just check for |
| 228 // a crash since the browser don't return a value. | 214 // a crash since the browser don't return a value. |
| 229 std::string TestGraphics2D::TestInvalidResource() { | 215 std::string TestGraphics2D::TestInvalidResource() { |
| 230 pp::Graphics2D null_context; | 216 pp::Graphics2D null_context; |
| 231 pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 217 pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 257 graphics_2d_interface_->Scroll(null_context.pp_resource(), | 243 graphics_2d_interface_->Scroll(null_context.pp_resource(), |
| 258 NULL, &zero_ten); | 244 NULL, &zero_ten); |
| 259 | 245 |
| 260 // ReplaceContents. | 246 // ReplaceContents. |
| 261 graphics_2d_interface_->ReplaceContents(image.pp_resource(), | 247 graphics_2d_interface_->ReplaceContents(image.pp_resource(), |
| 262 image.pp_resource()); | 248 image.pp_resource()); |
| 263 graphics_2d_interface_->ReplaceContents(null_context.pp_resource(), | 249 graphics_2d_interface_->ReplaceContents(null_context.pp_resource(), |
| 264 image.pp_resource()); | 250 image.pp_resource()); |
| 265 | 251 |
| 266 // Flush. | 252 // Flush. |
| 267 if (graphics_2d_interface_->Flush( | 253 TestCompletionCallback cb(instance_->pp_instance(), PP_OPTIONAL); |
| 268 image.pp_resource(), | 254 cb.WaitForResult( |
| 269 PP_MakeOptionalCompletionCallback(&FlushCallbackNOP, NULL)) == PP_OK) | 255 graphics_2d_interface_->Flush(image.pp_resource(), |
| 270 return "Flush succeeded with a different resource"; | 256 cb.GetCallback().pp_completion_callback())); |
| 271 if (graphics_2d_interface_->Flush( | 257 ASSERT_EQ(PP_ERROR_BADRESOURCE, cb.result()); |
| 272 null_context.pp_resource(), | 258 cb.WaitForResult( |
| 273 PP_MakeOptionalCompletionCallback(&FlushCallbackNOP, NULL)) == PP_OK) | 259 graphics_2d_interface_->Flush(null_context.pp_resource(), |
| 274 return "Flush succeeded with a NULL resource"; | 260 cb.GetCallback().pp_completion_callback())); |
| 261 ASSERT_EQ(PP_ERROR_BADRESOURCE, cb.result()); |
| 275 | 262 |
| 276 // ReadImageData. | 263 // ReadImageData. |
| 277 if (testing_interface_->ReadImageData(image.pp_resource(), | 264 ASSERT_FALSE(testing_interface_->ReadImageData(image.pp_resource(), |
| 278 image.pp_resource(), | 265 image.pp_resource(), |
| 279 &zero_zero)) | 266 &zero_zero)); |
| 280 return "ReadImageData succeeded with a different resource"; | 267 ASSERT_FALSE(testing_interface_->ReadImageData(null_context.pp_resource(), |
| 281 if (testing_interface_->ReadImageData(null_context.pp_resource(), | 268 image.pp_resource(), |
| 282 image.pp_resource(), | 269 &zero_zero)); |
| 283 &zero_zero)) | |
| 284 return "ReadImageData succeeded with a NULL resource"; | |
| 285 | 270 |
| 286 PASS(); | 271 PASS(); |
| 287 } | 272 } |
| 288 | 273 |
| 289 std::string TestGraphics2D::TestInvalidSize() { | 274 std::string TestGraphics2D::TestInvalidSize() { |
| 290 pp::Graphics2D a(instance_, pp::Size(16, 0), false); | 275 pp::Graphics2D a(instance_, pp::Size(16, 0), false); |
| 291 if (ResourceHealthCheck(instance_, &a)) | 276 ASSERT_FALSE(CanFlushContext(instance_, &a)); |
| 292 return "0 height accepted"; | |
| 293 | 277 |
| 294 pp::Graphics2D b(instance_, pp::Size(0, 16), false); | 278 pp::Graphics2D b(instance_, pp::Size(0, 16), false); |
| 295 if (ResourceHealthCheck(instance_, &b)) | 279 ASSERT_FALSE(CanFlushContext(instance_, &b)); |
| 296 return "0 height accepted"; | |
| 297 | 280 |
| 298 // Need to use the C API since pp::Size prevents negative sizes. | 281 // Need to use the C API since pp::Size prevents negative sizes. |
| 299 PP_Size size; | 282 PP_Size size; |
| 300 size.width = 16; | 283 size.width = 16; |
| 301 size.height = -16; | 284 size.height = -16; |
| 302 PP_Resource graphics = graphics_2d_interface_->Create( | 285 PP_Resource graphics = graphics_2d_interface_->Create( |
| 303 instance_->pp_instance(), &size, PP_FALSE); | 286 instance_->pp_instance(), &size, PP_FALSE); |
| 304 ASSERT_FALSE(ResourceHealthCheckForC(instance_, graphics)); | 287 ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_)); |
| 288 pp::Module::Get()->core()->ReleaseResource(graphics); |
| 305 | 289 |
| 306 size.width = -16; | 290 size.width = -16; |
| 307 size.height = 16; | 291 size.height = 16; |
| 308 graphics = graphics_2d_interface_->Create( | 292 graphics = graphics_2d_interface_->Create( |
| 309 instance_->pp_instance(), &size, PP_FALSE); | 293 instance_->pp_instance(), &size, PP_FALSE); |
| 310 ASSERT_FALSE(ResourceHealthCheckForC(instance_, graphics)); | 294 ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_)); |
| 295 pp::Module::Get()->core()->ReleaseResource(graphics); |
| 311 | 296 |
| 312 // Overflow to negative size | 297 // Overflow to negative size |
| 313 size.width = std::numeric_limits<int32_t>::max(); | 298 size.width = std::numeric_limits<int32_t>::max(); |
| 314 size.height = std::numeric_limits<int32_t>::max(); | 299 size.height = std::numeric_limits<int32_t>::max(); |
| 315 graphics = graphics_2d_interface_->Create( | 300 graphics = graphics_2d_interface_->Create( |
| 316 instance_->pp_instance(), &size, PP_FALSE); | 301 instance_->pp_instance(), &size, PP_FALSE); |
| 317 ASSERT_FALSE(ResourceHealthCheckForC(instance_, graphics)); | 302 ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_)); |
| 303 pp::Module::Get()->core()->ReleaseResource(graphics); |
| 318 | 304 |
| 319 PASS(); | 305 PASS(); |
| 320 } | 306 } |
| 321 | 307 |
| 322 std::string TestGraphics2D::TestHumongous() { | 308 std::string TestGraphics2D::TestHumongous() { |
| 323 pp::Graphics2D a(instance_, pp::Size(100000, 100000), false); | 309 pp::Graphics2D a(instance_, pp::Size(100000, 100000), false); |
| 324 if (ResourceHealthCheck(instance_, &a)) | 310 ASSERT_FALSE(CanFlushContext(instance_, &a)); |
| 325 return "Humongous device created"; | |
| 326 PASS(); | 311 PASS(); |
| 327 } | 312 } |
| 328 | 313 |
| 329 std::string TestGraphics2D::TestInitToZero() { | 314 std::string TestGraphics2D::TestInitToZero() { |
| 330 const int w = 15, h = 17; | 315 const int w = 15, h = 17; |
| 331 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 316 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 332 if (dc.is_null()) | 317 ASSERT_FALSE(dc.is_null()); |
| 333 return "Failure creating a boring device"; | |
| 334 | 318 |
| 335 // Make an image with nonzero data in it (so we can test that zeros were | 319 // Make an image with nonzero data in it (so we can test that zeros were |
| 336 // actually read versus ReadImageData being a NOP). | 320 // actually read versus ReadImageData being a NOP). |
| 337 pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 321 pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 338 pp::Size(w, h), true); | 322 pp::Size(w, h), true); |
| 339 if (image.is_null()) | 323 ASSERT_FALSE(image.is_null()); |
| 340 return "Failure to allocate an image"; | |
| 341 memset(image.data(), 0xFF, image.stride() * image.size().height() * 4); | 324 memset(image.data(), 0xFF, image.stride() * image.size().height() * 4); |
| 342 | 325 |
| 343 // Read out the initial data from the device & check. | 326 // Read out the initial data from the device & check. |
| 344 if (!ReadImageData(dc, &image, pp::Point(0, 0))) | 327 ASSERT_TRUE(ReadImageData(dc, &image, pp::Point(0, 0))); |
| 345 return "Couldn't read image data"; | 328 ASSERT_TRUE(IsSquareInImage(image, 0, pp::Rect(0, 0, w, h), 0)); |
| 346 if (!IsSquareInImage(image, 0, pp::Rect(0, 0, w, h), 0)) | |
| 347 return "Got a nonzero pixel"; | |
| 348 | 329 |
| 349 PASS(); | 330 PASS(); |
| 350 } | 331 } |
| 351 | 332 |
| 352 std::string TestGraphics2D::TestDescribe() { | 333 std::string TestGraphics2D::TestDescribe() { |
| 353 const int w = 15, h = 17; | 334 const int w = 15, h = 17; |
| 354 const bool always_opaque = (::rand() % 2 == 1); | 335 const bool always_opaque = (::rand() % 2 == 1); |
| 355 pp::Graphics2D dc(instance_, pp::Size(w, h), always_opaque); | 336 pp::Graphics2D dc(instance_, pp::Size(w, h), always_opaque); |
| 356 if (dc.is_null()) | 337 ASSERT_FALSE(dc.is_null()); |
| 357 return "Failure creating a boring device"; | |
| 358 | 338 |
| 359 PP_Size size; | 339 PP_Size size; |
| 360 size.width = -1; | 340 size.width = -1; |
| 361 size.height = -1; | 341 size.height = -1; |
| 362 PP_Bool is_always_opaque = PP_FALSE; | 342 PP_Bool is_always_opaque = PP_FALSE; |
| 363 if (!graphics_2d_interface_->Describe(dc.pp_resource(), &size, | 343 ASSERT_TRUE(graphics_2d_interface_->Describe(dc.pp_resource(), &size, |
| 364 &is_always_opaque)) | 344 &is_always_opaque)); |
| 365 return "Describe failed"; | 345 ASSERT_EQ(w, size.width); |
| 366 if (size.width != w || size.height != h || | 346 ASSERT_EQ(h, size.height); |
| 367 is_always_opaque != PP_FromBool(always_opaque)) | 347 ASSERT_EQ(PP_FromBool(always_opaque), is_always_opaque); |
| 368 return "Mismatch of data."; | |
| 369 | 348 |
| 370 PASS(); | 349 PASS(); |
| 371 } | 350 } |
| 372 | 351 |
| 373 std::string TestGraphics2D::TestScale() { | 352 std::string TestGraphics2D::TestScale() { |
| 374 // Tests GetScale/SetScale | 353 // Tests GetScale/SetScale |
| 375 const int w = 20, h = 16; | 354 const int w = 20, h = 16; |
| 376 const float scale = 1.0f/2.0f; | 355 const float scale = 1.0f/2.0f; |
| 377 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 356 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 378 if (dc.is_null()) | 357 ASSERT_FALSE(dc.is_null()); |
| 379 return "Failure creating a boring device"; | 358 ASSERT_EQ(1.0, dc.GetScale()); |
| 380 if (dc.GetScale() != 1.0f) | 359 ASSERT_TRUE(dc.SetScale(scale)); |
| 381 return "GetScale returned unexpected value before SetScale"; | 360 ASSERT_EQ(scale, dc.GetScale()); |
| 382 if (!dc.SetScale(scale)) | |
| 383 return "SetScale failed"; | |
| 384 if (dc.GetScale() != scale) | |
| 385 return "GetScale mismatch with prior SetScale"; | |
| 386 // Try setting a few invalid scale factors. Ensure that we catch these errors | 361 // Try setting a few invalid scale factors. Ensure that we catch these errors |
| 387 // and don't change the actual scale | 362 // and don't change the actual scale |
| 388 if (dc.SetScale(-1.0f)) | 363 ASSERT_FALSE(dc.SetScale(-1.0f)); |
| 389 return "SetScale(-1f) did not fail"; | 364 ASSERT_FALSE(dc.SetScale(0.0f)); |
| 390 if (dc.SetScale(0.0f)) | 365 ASSERT_EQ(scale, dc.GetScale()); |
| 391 return "SetScale(0.0f) did not fail"; | |
| 392 if (dc.GetScale() != scale) | |
| 393 return "SetScale with invalid parameter overwrote the scale"; | |
| 394 | 366 |
| 395 // Verify that the context has the specified number of pixels, despite the | 367 // Verify that the context has the specified number of pixels, despite the |
| 396 // non-identity scale | 368 // non-identity scale |
| 397 PP_Size size; | 369 PP_Size size; |
| 398 size.width = -1; | 370 size.width = -1; |
| 399 size.height = -1; | 371 size.height = -1; |
| 400 PP_Bool is_always_opaque = PP_FALSE; | 372 PP_Bool is_always_opaque = PP_FALSE; |
| 401 if (!graphics_2d_interface_->Describe(dc.pp_resource(), &size, | 373 ASSERT_TRUE(graphics_2d_interface_->Describe(dc.pp_resource(), &size, |
| 402 &is_always_opaque)) | 374 &is_always_opaque)); |
| 403 return "Describe failed"; | 375 ASSERT_EQ(w, size.width); |
| 404 if (size.width != w || size.height != h || | 376 ASSERT_EQ(h, size.height); |
| 405 is_always_opaque != PP_FromBool(false)) | 377 ASSERT_EQ(PP_FALSE, is_always_opaque); |
| 406 return "Mismatch of data."; | |
| 407 | 378 |
| 408 PASS(); | 379 PASS(); |
| 409 } | 380 } |
| 410 | 381 |
| 411 std::string TestGraphics2D::TestPaint() { | 382 std::string TestGraphics2D::TestPaint() { |
| 412 const int w = 15, h = 17; | 383 const int w = 15, h = 17; |
| 413 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 384 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 414 if (dc.is_null()) | 385 ASSERT_FALSE(dc.is_null()); |
| 415 return "Failure creating a boring device"; | |
| 416 | 386 |
| 417 // Make sure the device background is 0. | 387 // Make sure the device background is 0. |
| 418 if (!IsDCUniformColor(dc, 0)) | 388 ASSERT_TRUE(IsDCUniformColor(dc, 0)); |
| 419 return "Bad initial color"; | |
| 420 | 389 |
| 421 // Fill the backing store with white. | 390 // Fill the backing store with white. |
| 422 const uint32_t background_color = 0xFFFFFFFF; | 391 const uint32_t background_color = 0xFFFFFFFF; |
| 423 pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 392 pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 424 pp::Size(w, h), false); | 393 pp::Size(w, h), false); |
| 425 FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color); | 394 FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color); |
| 426 dc.PaintImageData(background, pp::Point(0, 0)); | 395 dc.PaintImageData(background, pp::Point(0, 0)); |
| 427 if (!FlushAndWaitForDone(&dc)) | 396 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 428 return "Couldn't flush to fill backing store"; | |
| 429 | 397 |
| 430 // Make an image to paint with that's opaque white and enqueue a paint. | 398 // Make an image to paint with that's opaque white and enqueue a paint. |
| 431 const int fill_w = 2, fill_h = 3; | 399 const int fill_w = 2, fill_h = 3; |
| 432 pp::ImageData fill(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 400 pp::ImageData fill(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 433 pp::Size(fill_w, fill_h), true); | 401 pp::Size(fill_w, fill_h), true); |
| 434 if (fill.is_null()) | 402 ASSERT_FALSE(fill.is_null()); |
| 435 return "Failure to allocate fill image"; | |
| 436 FillRectInImage(&fill, pp::Rect(fill.size()), background_color); | 403 FillRectInImage(&fill, pp::Rect(fill.size()), background_color); |
| 437 const int paint_x = 4, paint_y = 5; | 404 const int paint_x = 4, paint_y = 5; |
| 438 dc.PaintImageData(fill, pp::Point(paint_x, paint_y)); | 405 dc.PaintImageData(fill, pp::Point(paint_x, paint_y)); |
| 439 | 406 |
| 440 // Validate that nothing has been actually painted. | 407 // Validate that nothing has been actually painted. |
| 441 if (!IsDCUniformColor(dc, background_color)) | 408 ASSERT_TRUE(IsDCUniformColor(dc, background_color)); |
| 442 return "Image updated before flush (or failure in readback)."; | |
| 443 | 409 |
| 444 // The paint hasn't been flushed so we can still change the bitmap. Fill with | 410 // The paint hasn't been flushed so we can still change the bitmap. Fill with |
| 445 // 50% blue. This will also verify that the backing store is replaced | 411 // 50% blue. This will also verify that the backing store is replaced |
| 446 // with the contents rather than blended. | 412 // with the contents rather than blended. |
| 447 const uint32_t fill_color = 0x80000080; | 413 const uint32_t fill_color = 0x80000080; |
| 448 FillRectInImage(&fill, pp::Rect(fill.size()), fill_color); | 414 FillRectInImage(&fill, pp::Rect(fill.size()), fill_color); |
| 449 if (!FlushAndWaitForDone(&dc)) | 415 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 450 return "Couldn't flush 50% blue paint"; | |
| 451 | 416 |
| 452 if (!IsSquareInDC(dc, background_color, | 417 ASSERT_TRUE(IsSquareInDC(dc, background_color, |
| 453 pp::Rect(paint_x, paint_y, fill_w, fill_h), | 418 pp::Rect(paint_x, paint_y, fill_w, fill_h), |
| 454 fill_color)) | 419 fill_color)); |
| 455 return "Image not painted properly."; | |
| 456 | 420 |
| 457 // Reset the DC to blank white & paint our image slightly off the buffer. | 421 // Reset the DC to blank white & paint our image slightly off the buffer. |
| 458 // This should succeed. We also try painting the same thing where the | 422 // This should succeed. We also try painting the same thing where the |
| 459 // dirty rect falls outeside of the device, which should fail. | 423 // dirty rect falls outeside of the device, which should fail. |
| 460 dc.PaintImageData(background, pp::Point(0, 0)); | 424 dc.PaintImageData(background, pp::Point(0, 0)); |
| 461 const int second_paint_x = -1, second_paint_y = -2; | 425 const int second_paint_x = -1, second_paint_y = -2; |
| 462 dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y)); | 426 dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y)); |
| 463 dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y), | 427 dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y), |
| 464 pp::Rect(-second_paint_x, -second_paint_y, 1, 1)); | 428 pp::Rect(-second_paint_x, -second_paint_y, 1, 1)); |
| 465 if (!FlushAndWaitForDone(&dc)) | 429 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 466 return "Couldn't flush second paint"; | |
| 467 | 430 |
| 468 // Now we should have a little bit of the image peeking out the top left. | 431 // Now we should have a little bit of the image peeking out the top left. |
| 469 if (!IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1), | 432 ASSERT_TRUE(IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1), |
| 470 fill_color)) | 433 fill_color)); |
| 471 return "Partially offscreen paint failed."; | |
| 472 | 434 |
| 473 // Now repaint that top left pixel by doing a subset of the source image. | 435 // Now repaint that top left pixel by doing a subset of the source image. |
| 474 pp::ImageData subset(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 436 pp::ImageData subset(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 475 pp::Size(w, h), false); | 437 pp::Size(w, h), false); |
| 476 uint32_t subset_color = 0x80808080; | 438 uint32_t subset_color = 0x80808080; |
| 477 const int subset_x = 2, subset_y = 1; | 439 const int subset_x = 2, subset_y = 1; |
| 478 *subset.GetAddr32(pp::Point(subset_x, subset_y)) = subset_color; | 440 *subset.GetAddr32(pp::Point(subset_x, subset_y)) = subset_color; |
| 479 dc.PaintImageData(subset, pp::Point(-subset_x, -subset_y), | 441 dc.PaintImageData(subset, pp::Point(-subset_x, -subset_y), |
| 480 pp::Rect(subset_x, subset_y, 1, 1)); | 442 pp::Rect(subset_x, subset_y, 1, 1)); |
| 481 if (!FlushAndWaitForDone(&dc)) | 443 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 482 return "Couldn't flush repaint"; | 444 ASSERT_TRUE(IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1), |
| 483 if (!IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1), | 445 subset_color)); |
| 484 subset_color)) | |
| 485 return "Subset paint failed."; | |
| 486 | 446 |
| 487 PASS(); | 447 PASS(); |
| 488 } | 448 } |
| 489 | 449 |
| 490 std::string TestGraphics2D::TestScroll() { | 450 std::string TestGraphics2D::TestScroll() { |
| 491 const int w = 115, h = 117; | 451 const int w = 115, h = 117; |
| 492 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 452 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 493 if (dc.is_null()) | 453 ASSERT_FALSE(dc.is_null()); |
| 494 return "Failure creating a boring device."; | 454 ASSERT_TRUE(instance_->BindGraphics(dc)); |
| 495 if (!instance_->BindGraphics(dc)) | |
| 496 return "Failure to bind the boring device."; | |
| 497 | 455 |
| 498 // Make sure the device background is 0. | 456 // Make sure the device background is 0. |
| 499 if (!IsDCUniformColor(dc, 0)) | 457 ASSERT_TRUE(IsDCUniformColor(dc, 0)); |
| 500 return "Bad initial color."; | |
| 501 | 458 |
| 502 const int image_width = 15, image_height = 23; | 459 const int image_width = 15, image_height = 23; |
| 503 pp::ImageData test_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 460 pp::ImageData test_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 504 pp::Size(image_width, image_height), false); | 461 pp::Size(image_width, image_height), false); |
| 505 FillImageWithGradient(&test_image); | 462 FillImageWithGradient(&test_image); |
| 506 pp::ImageData no_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 463 pp::ImageData no_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 507 pp::Size(image_width, image_height), false); | 464 pp::Size(image_width, image_height), false); |
| 508 FillRectInImage(&no_image, pp::Rect(0, 0, image_width, image_height), 0); | 465 FillRectInImage(&no_image, pp::Rect(0, 0, image_width, image_height), 0); |
| 509 pp::ImageData readback_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 466 pp::ImageData readback_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 510 pp::Size(image_width, image_height), false); | 467 pp::Size(image_width, image_height), false); |
| 511 pp::ImageData readback_scroll(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 468 pp::ImageData readback_scroll(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 512 pp::Size(image_width, image_height), false); | 469 pp::Size(image_width, image_height), false); |
| 513 | 470 |
| 514 if (test_image.size() != pp::Size(image_width, image_height)) | 471 ASSERT_EQ(pp::Size(image_width, image_height), test_image.size()); |
| 515 return "Wrong test image size\n"; | |
| 516 | 472 |
| 517 int image_x = 51, image_y = 72; | 473 int image_x = 51, image_y = 72; |
| 518 dc.PaintImageData(test_image, pp::Point(image_x, image_y)); | 474 dc.PaintImageData(test_image, pp::Point(image_x, image_y)); |
| 519 if (!FlushAndWaitForDone(&dc)) | 475 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 520 return "Couldn't flush to fill backing store."; | |
| 521 | 476 |
| 522 // Test Case 1. Incorrect usage when scrolling image to a free space. | 477 // Test Case 1. Incorrect usage when scrolling image to a free space. |
| 523 // The clip area is *not* the area to shift around within the graphics device | 478 // The clip area is *not* the area to shift around within the graphics device |
| 524 // by specified amount. It's the area to which the scroll is limited. So if | 479 // by specified amount. It's the area to which the scroll is limited. So if |
| 525 // the clip area is the size of the image and the amount points to free space, | 480 // the clip area is the size of the image and the amount points to free space, |
| 526 // the scroll won't result in additional images. | 481 // the scroll won't result in additional images. |
| 527 int dx = -40, dy = -48; | 482 int dx = -40, dy = -48; |
| 528 int scroll_x = image_x + dx, scroll_y = image_y + dy; | 483 int scroll_x = image_x + dx, scroll_y = image_y + dy; |
| 529 pp::Rect clip(image_x, image_y, image_width, image_height); | 484 pp::Rect clip(image_x, image_y, image_width, image_height); |
| 530 dc.Scroll(clip, pp::Point(dx, dy)); | 485 dc.Scroll(clip, pp::Point(dx, dy)); |
| 531 if (!FlushAndWaitForDone(&dc)) | 486 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 532 return "TC1, Couldn't flush to scroll."; | 487 ASSERT_TRUE( |
| 533 if (!ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))) | 488 ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); |
| 534 return "TC1, Couldn't read back scrolled image data."; | 489 ASSERT_TRUE(CompareImages(no_image, readback_scroll)); |
| 535 if (!CompareImages(no_image, readback_scroll)) | |
| 536 return "TC1, Read back scrolled image is not the same as no image."; | |
| 537 | 490 |
| 538 // Test Case 2. | 491 // Test Case 2. |
| 539 // The amount is intended to place the image in the free space outside | 492 // The amount is intended to place the image in the free space outside |
| 540 // of the original, but the clip area extends beyond the graphics device area. | 493 // of the original, but the clip area extends beyond the graphics device area. |
| 541 // This scroll is invalid and will be a noop. | 494 // This scroll is invalid and will be a noop. |
| 542 scroll_x = 11, scroll_y = 24; | 495 scroll_x = 11, scroll_y = 24; |
| 543 clip = pp::Rect(0, 0, w, h + 1); | 496 clip = pp::Rect(0, 0, w, h + 1); |
| 544 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); | 497 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); |
| 545 if (!FlushAndWaitForDone(&dc)) | 498 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 546 return "TC2, Couldn't flush to scroll."; | 499 ASSERT_TRUE( |
| 547 if (!ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))) | 500 ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); |
| 548 return "TC2, Couldn't read back scrolled image data."; | 501 ASSERT_TRUE(CompareImages(no_image, readback_scroll)); |
| 549 if (!CompareImages(no_image, readback_scroll)) | |
| 550 return "TC2, Read back scrolled image is not the same as no image."; | |
| 551 | 502 |
| 552 // Test Case 3. | 503 // Test Case 3. |
| 553 // The amount is intended to place the image in the free space outside | 504 // The amount is intended to place the image in the free space outside |
| 554 // of the original, but the clip area does not cover the image, | 505 // of the original, but the clip area does not cover the image, |
| 555 // so there is nothing to scroll. | 506 // so there is nothing to scroll. |
| 556 scroll_x = 11, scroll_y = 24; | 507 scroll_x = 11, scroll_y = 24; |
| 557 clip = pp::Rect(0, 0, image_x, image_y); | 508 clip = pp::Rect(0, 0, image_x, image_y); |
| 558 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); | 509 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); |
| 559 if (!FlushAndWaitForDone(&dc)) | 510 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 560 return "TC3, Couldn't flush to scroll."; | 511 ASSERT_TRUE( |
| 561 if (!ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))) | 512 ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); |
| 562 return "TC3, Couldn't read back scrolled image data."; | 513 ASSERT_TRUE(CompareImages(no_image, readback_scroll)); |
| 563 if (!CompareImages(no_image, readback_scroll)) | |
| 564 return "TC3, Read back scrolled image is not the same as no image."; | |
| 565 | 514 |
| 566 // Test Case 4. | 515 // Test Case 4. |
| 567 // Same as TC3, but the clip covers part of the image. | 516 // Same as TC3, but the clip covers part of the image. |
| 568 // This part will be scrolled to the intended origin. | 517 // This part will be scrolled to the intended origin. |
| 569 int part_w = image_width / 2, part_h = image_height / 2; | 518 int part_w = image_width / 2, part_h = image_height / 2; |
| 570 clip = pp::Rect(0, 0, image_x + part_w, image_y + part_h); | 519 clip = pp::Rect(0, 0, image_x + part_w, image_y + part_h); |
| 571 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); | 520 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); |
| 572 if (!FlushAndWaitForDone(&dc)) | 521 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 573 return "TC4, Couldn't flush to scroll."; | 522 ASSERT_TRUE( |
| 574 if (!ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))) | 523 ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); |
| 575 return "TC4, Couldn't read back scrolled image data."; | 524 ASSERT_FALSE(CompareImages(test_image, readback_scroll)); |
| 576 if (CompareImages(test_image, readback_scroll)) | |
| 577 return "TC4, Read back scrolled image is the same as test image."; | |
| 578 pp::Rect part_rect(part_w, part_h); | 525 pp::Rect part_rect(part_w, part_h); |
| 579 if (!CompareImageRect(test_image, part_rect, readback_scroll, part_rect)) | 526 ASSERT_TRUE( |
| 580 return "TC4, Read back scrolled image is not the same as part test image."; | 527 CompareImageRect(test_image, part_rect, readback_scroll, part_rect)); |
| 581 | 528 |
| 582 // Test Case 5 | 529 // Test Case 5 |
| 583 // Same as TC3, but the clip area covers the entire image. | 530 // Same as TC3, but the clip area covers the entire image. |
| 584 // It will be scrolled to the intended origin. | 531 // It will be scrolled to the intended origin. |
| 585 clip = pp::Rect(0, 0, image_x + image_width, image_y + image_height); | 532 clip = pp::Rect(0, 0, image_x + image_width, image_y + image_height); |
| 586 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); | 533 dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); |
| 587 if (!FlushAndWaitForDone(&dc)) | 534 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 588 return "TC5, Couldn't flush to scroll."; | 535 ASSERT_TRUE( |
| 589 if (!ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))) | 536 ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); |
| 590 return "TC5, Couldn't read back scrolled image data."; | 537 ASSERT_TRUE(CompareImages(test_image, readback_scroll)); |
| 591 if (!CompareImages(test_image, readback_scroll)) | |
| 592 return "TC5, Read back scrolled image is not the same as test image."; | |
| 593 | 538 |
| 594 // Note that the undefined area left by the scroll does not actually get | 539 // Note that the undefined area left by the scroll does not actually get |
| 595 // cleared, so the original image is still there. This is not guaranteed and | 540 // cleared, so the original image is still there. This is not guaranteed and |
| 596 // is not something for users to rely on, but we can test for this here, so | 541 // is not something for users to rely on, but we can test for this here, so |
| 597 // we know when the underlying behavior changes. | 542 // we know when the underlying behavior changes. |
| 598 if (!ReadImageData(dc, &readback_image, pp::Point(image_x, image_y))) | 543 ASSERT_TRUE(ReadImageData(dc, &readback_image, pp::Point(image_x, image_y))); |
| 599 return "Couldn't read back original image data."; | 544 ASSERT_TRUE(CompareImages(test_image, readback_image)); |
| 600 if (!CompareImages(test_image, readback_image)) | |
| 601 return "Read back original image is not the same as test image."; | |
| 602 | 545 |
| 603 // Test Case 6. | 546 // Test Case 6. |
| 604 // Scroll image to an overlapping space. The clip area is limited | 547 // Scroll image to an overlapping space. The clip area is limited |
| 605 // to the image, so this will just modify its area. | 548 // to the image, so this will just modify its area. |
| 606 dx = 6; | 549 dx = 6; |
| 607 dy = 9; | 550 dy = 9; |
| 608 scroll_x = image_x + dx; | 551 scroll_x = image_x + dx; |
| 609 scroll_y = image_y + dy; | 552 scroll_y = image_y + dy; |
| 610 clip = pp::Rect(image_x, image_y, image_width, image_height); | 553 clip = pp::Rect(image_x, image_y, image_width, image_height); |
| 611 dc.Scroll(clip, pp::Point(dx, dy)); | 554 dc.Scroll(clip, pp::Point(dx, dy)); |
| 612 if (!FlushAndWaitForDone(&dc)) | 555 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 613 return "TC6, Couldn't flush to scroll."; | 556 ASSERT_TRUE(ReadImageData(dc, &readback_image, pp::Point(image_x, image_y))); |
| 614 if (!ReadImageData(dc, &readback_image, pp::Point(image_x, image_y))) | 557 ASSERT_FALSE(CompareImages(test_image, readback_image)); |
| 615 return "TC6, Couldn't read back image data."; | |
| 616 if (CompareImages(test_image, readback_image)) | |
| 617 return "TC6, Read back image is still the same as test image."; | |
| 618 pp::Rect scroll_rect(image_width - dx, image_height - dy); | 558 pp::Rect scroll_rect(image_width - dx, image_height - dy); |
| 619 if (!ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))) | 559 ASSERT_TRUE( |
| 620 return "TC6, Couldn't read back scrolled image data."; | 560 ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); |
| 621 if (!CompareImageRect(test_image, scroll_rect, readback_scroll, scroll_rect)) | 561 ASSERT_TRUE( |
| 622 return "TC6, Read back scrolled image is not the same as part test image."; | 562 CompareImageRect(test_image, scroll_rect, readback_scroll, scroll_rect)); |
| 623 | 563 |
| 624 PASS(); | 564 PASS(); |
| 625 } | 565 } |
| 626 | 566 |
| 627 std::string TestGraphics2D::TestReplace() { | 567 std::string TestGraphics2D::TestReplace() { |
| 628 const int w = 15, h = 17; | 568 const int w = 15, h = 17; |
| 629 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 569 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 630 if (dc.is_null()) | 570 ASSERT_FALSE(dc.is_null()); |
| 631 return "Failure creating a boring device"; | |
| 632 | 571 |
| 633 // Replacing with a different size image should fail. | 572 // Replacing with a different size image should fail. |
| 634 pp::ImageData weird_size(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 573 pp::ImageData weird_size(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 635 pp::Size(w - 1, h), true); | 574 pp::Size(w - 1, h), true); |
| 636 if (weird_size.is_null()) | 575 ASSERT_FALSE(weird_size.is_null()); |
| 637 return "Failure allocating the weird sized image"; | |
| 638 dc.ReplaceContents(&weird_size); | 576 dc.ReplaceContents(&weird_size); |
| 639 | 577 |
| 640 // Fill the background with blue but don't flush yet. | 578 // Fill the background with blue but don't flush yet. |
| 641 const int32_t background_color = 0xFF0000FF; | 579 const int32_t background_color = 0xFF0000FF; |
| 642 pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 580 pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 643 pp::Size(w, h), true); | 581 pp::Size(w, h), true); |
| 644 if (background.is_null()) | 582 ASSERT_FALSE(background.is_null()); |
| 645 return "Failure to allocate background image"; | |
| 646 FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color); | 583 FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color); |
| 647 dc.PaintImageData(background, pp::Point(0, 0)); | 584 dc.PaintImageData(background, pp::Point(0, 0)); |
| 648 | 585 |
| 649 // Replace with a green background but don't flush yet. | 586 // Replace with a green background but don't flush yet. |
| 650 const int32_t swapped_color = 0x00FF00FF; | 587 const int32_t swapped_color = 0x00FF00FF; |
| 651 pp::ImageData swapped(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 588 pp::ImageData swapped(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 652 pp::Size(w, h), true); | 589 pp::Size(w, h), true); |
| 653 if (swapped.is_null()) | 590 ASSERT_FALSE(swapped.is_null()); |
| 654 return "Failure to allocate swapped image"; | |
| 655 FillRectInImage(&swapped, pp::Rect(0, 0, w, h), swapped_color); | 591 FillRectInImage(&swapped, pp::Rect(0, 0, w, h), swapped_color); |
| 656 dc.ReplaceContents(&swapped); | 592 dc.ReplaceContents(&swapped); |
| 657 | 593 |
| 658 // The background should be unchanged since we didn't flush yet. | 594 // The background should be unchanged since we didn't flush yet. |
| 659 if (!IsDCUniformColor(dc, 0)) | 595 ASSERT_TRUE(IsDCUniformColor(dc, 0)); |
| 660 return "Image updated before flush (or failure in readback)."; | |
| 661 | 596 |
| 662 // Test the C++ wrapper. The size of the swapped image should be reset. | 597 // Test the C++ wrapper. The size of the swapped image should be reset. |
| 663 if (swapped.pp_resource() || swapped.size().width() || | 598 ASSERT_TRUE(!swapped.pp_resource() && !swapped.size().width() && |
| 664 swapped.size().height() || swapped.data()) | 599 !swapped.size().height() && !swapped.data()); |
| 665 return "Size of the swapped image should be reset."; | |
| 666 | 600 |
| 667 // Painting with the swapped image should fail. | 601 // Painting with the swapped image should fail. |
| 668 dc.PaintImageData(swapped, pp::Point(0, 0)); | 602 dc.PaintImageData(swapped, pp::Point(0, 0)); |
| 669 | 603 |
| 670 // Flush and make sure the result is correct. | 604 // Flush and make sure the result is correct. |
| 671 if (!FlushAndWaitForDone(&dc)) | 605 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 672 return "Couldn't flush"; | |
| 673 | 606 |
| 674 // The background should be green from the swapped image. | 607 // The background should be green from the swapped image. |
| 675 if (!IsDCUniformColor(dc, swapped_color)) | 608 ASSERT_TRUE(IsDCUniformColor(dc, swapped_color)); |
| 676 return "Flushed color incorrect (or failure in readback)."; | |
| 677 | 609 |
| 678 PASS(); | 610 PASS(); |
| 679 } | 611 } |
| 680 | 612 |
| 681 std::string TestGraphics2D::TestFlush() { | 613 std::string TestGraphics2D::TestFlush() { |
| 682 // Tests that synchronous flushes (NULL callback) fail on the main thread | 614 // Tests that synchronous flushes (NULL callback) fail on the main thread |
| 683 // (which is the current one). | 615 // (which is the current one). |
| 684 const int w = 15, h = 17; | 616 const int w = 15, h = 17; |
| 685 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 617 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 686 if (dc.is_null()) | 618 ASSERT_FALSE(dc.is_null()); |
| 687 return "Failure creating a boring device"; | |
| 688 | 619 |
| 689 // Fill the background with blue but don't flush yet. | 620 // Fill the background with blue but don't flush yet. |
| 690 pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 621 pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 691 pp::Size(w, h), true); | 622 pp::Size(w, h), true); |
| 692 if (background.is_null()) | 623 ASSERT_FALSE(background.is_null()); |
| 693 return "Failure to allocate background image"; | |
| 694 dc.PaintImageData(background, pp::Point(0, 0)); | 624 dc.PaintImageData(background, pp::Point(0, 0)); |
| 695 | 625 |
| 696 int32_t rv = dc.Flush(pp::BlockUntilComplete()); | 626 int32_t rv = dc.Flush(pp::BlockUntilComplete()); |
| 697 if (rv == PP_OK || rv == PP_OK_COMPLETIONPENDING) | 627 ASSERT_EQ(PP_ERROR_BLOCKS_MAIN_THREAD, rv); |
| 698 return "Flush succeeded from the main thread with no callback."; | |
| 699 | 628 |
| 700 // Test flushing with no operations still issues a callback. | 629 // Test flushing with no operations still issues a callback. |
| 701 // (This may also hang if the browser never issues the callback). | 630 // (This may also hang if the browser never issues the callback). |
| 702 pp::Graphics2D dc_nopaints(instance_, pp::Size(w, h), false); | 631 pp::Graphics2D dc_nopaints(instance_, pp::Size(w, h), false); |
| 703 if (dc.is_null()) | 632 ASSERT_FALSE(dc.is_null()); |
| 704 return "Failure creating the nopaint device"; | 633 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc_nopaints)); |
| 705 if (!FlushAndWaitForDone(&dc_nopaints)) | |
| 706 return "Couldn't flush the nopaint device"; | |
| 707 | 634 |
| 708 int32_t flags = (force_async_ ? 0 : PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | 635 TestCompletionCallback callback_1(instance_->pp_instance(), callback_type()); |
| 709 | 636 |
| 710 // Test that multiple flushes fail if we don't get a callback in between. | 637 // Test that multiple flushes fail if we don't get a callback in between. |
| 711 rv = dc_nopaints.Flush(pp::CompletionCallback(&FlushCallbackNOP, NULL, | 638 rv = dc_nopaints.Flush(callback_1.GetCallback()); |
| 712 flags)); | |
| 713 if (force_async_ && rv != PP_OK_COMPLETIONPENDING) | |
| 714 return "Flush must complete asynchronously."; | |
| 715 if (rv != PP_OK && rv != PP_OK_COMPLETIONPENDING) | |
| 716 return "Couldn't flush first time for multiple flush test."; | |
| 717 | |
| 718 if (rv == PP_OK_COMPLETIONPENDING) { | 639 if (rv == PP_OK_COMPLETIONPENDING) { |
| 719 // If the first flush completes asynchronously, then a second should fail. | 640 // If the first flush completes asynchronously, then a second should fail. |
| 720 rv = dc_nopaints.Flush(pp::CompletionCallback(&FlushCallbackNOP, NULL, | 641 TestCompletionCallback callback_2(instance_->pp_instance(), |
| 721 flags)); | 642 callback_type()); |
| 722 if (force_async_) { | 643 callback_2.WaitForResult(dc_nopaints.Flush(callback_2.GetCallback())); |
| 723 if (rv != PP_OK_COMPLETIONPENDING) | 644 CHECK_CALLBACK_BEHAVIOR(callback_2); |
| 724 return "Second flush must fail asynchronously."; | 645 ASSERT_EQ(PP_ERROR_INPROGRESS, callback_2.result()); |
| 725 } else { | |
| 726 if (rv == PP_OK || rv == PP_OK_COMPLETIONPENDING) | |
| 727 return "Second flush succeeded before callback ran."; | |
| 728 } | |
| 729 } | 646 } |
| 647 callback_1.WaitForResult(rv); |
| 648 ASSERT_EQ(PP_OK, callback_1.result()); |
| 730 | 649 |
| 731 PASS(); | 650 PASS(); |
| 732 } | 651 } |
| 733 | 652 |
| 734 void TestGraphics2D::DidChangeView(const pp::View& view) { | 653 void TestGraphics2D::DidChangeView(const pp::View& view) { |
| 735 if (post_quit_on_view_changed_) { | 654 if (post_quit_on_view_changed_) { |
| 736 post_quit_on_view_changed_ = false; | 655 post_quit_on_view_changed_ = false; |
| 737 is_view_changed_ = true; | 656 is_view_changed_ = true; |
| 738 testing_interface_->QuitMessageLoop(instance_->pp_instance()); | 657 testing_interface_->QuitMessageLoop(instance_->pp_instance()); |
| 739 } | 658 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 756 post_quit_on_view_changed_ = false; | 675 post_quit_on_view_changed_ = false; |
| 757 | 676 |
| 758 return is_view_changed_; | 677 return is_view_changed_; |
| 759 } | 678 } |
| 760 | 679 |
| 761 std::string TestGraphics2D::TestFlushOffscreenUpdate() { | 680 std::string TestGraphics2D::TestFlushOffscreenUpdate() { |
| 762 // Tests that callback of offscreen updates should be delayed. | 681 // Tests that callback of offscreen updates should be delayed. |
| 763 const PP_Time kFlushDelaySec = 1. / 30; // 30 fps | 682 const PP_Time kFlushDelaySec = 1. / 30; // 30 fps |
| 764 const int w = 80, h = 80; | 683 const int w = 80, h = 80; |
| 765 pp::Graphics2D dc(instance_, pp::Size(w, h), true); | 684 pp::Graphics2D dc(instance_, pp::Size(w, h), true); |
| 766 if (dc.is_null()) | 685 ASSERT_FALSE(dc.is_null()); |
| 767 return "Failure creating a boring device"; | 686 ASSERT_TRUE(instance_->BindGraphics(dc)); |
| 768 if (!instance_->BindGraphics(dc)) | |
| 769 return "Failure to bind the boring device."; | |
| 770 | 687 |
| 771 // Squeeze from top until bottom half of plugin is out of screen. | 688 // Squeeze from top until bottom half of plugin is out of screen. |
| 772 ResetViewChangedState(); | 689 ResetViewChangedState(); |
| 773 instance_->EvalScript( | 690 instance_->EvalScript( |
| 774 "var big = document.createElement('div');" | 691 "var big = document.createElement('div');" |
| 775 "var offset = " | 692 "var offset = " |
| 776 " window.innerHeight - plugin.offsetTop - plugin.offsetHeight / 2;" | 693 " window.innerHeight - plugin.offsetTop - plugin.offsetHeight / 2;" |
| 777 "big.setAttribute('id', 'big-div');" | 694 "big.setAttribute('id', 'big-div');" |
| 778 "big.setAttribute('style', 'height: ' + offset + '; width: 100%;');" | 695 "big.setAttribute('style', 'height: ' + offset + '; width: 100%;');" |
| 779 "document.body.insertBefore(big, document.body.firstChild);"); | 696 "document.body.insertBefore(big, document.body.firstChild);"); |
| 780 if (!WaitUntilViewChanged()) | 697 ASSERT_TRUE(WaitUntilViewChanged()); |
| 781 return "View didn't change as expected"; | |
| 782 | 698 |
| 783 // Allocate a red image chunk | 699 // Allocate a red image chunk |
| 784 pp::ImageData chunk(instance_, PP_IMAGEDATAFORMAT_RGBA_PREMUL, | 700 pp::ImageData chunk(instance_, PP_IMAGEDATAFORMAT_RGBA_PREMUL, |
| 785 pp::Size(w/8, h/8), true); | 701 pp::Size(w/8, h/8), true); |
| 786 if (chunk.is_null()) | 702 ASSERT_FALSE(chunk.is_null()); |
| 787 return "Failure to allocate image"; | |
| 788 const uint32_t kRed = 0xff0000ff; | 703 const uint32_t kRed = 0xff0000ff; |
| 789 FillRectInImage(&chunk, pp::Rect(chunk.size()), kRed); | 704 FillRectInImage(&chunk, pp::Rect(chunk.size()), kRed); |
| 790 | 705 |
| 791 // Paint a invisable chunk, expecting Flush to invoke callback slowly. | 706 // Paint a invisable chunk, expecting Flush to invoke callback slowly. |
| 792 dc.PaintImageData(chunk, pp::Point(0, h*0.75)); | 707 dc.PaintImageData(chunk, pp::Point(0, h*0.75)); |
| 793 | 708 |
| 794 PP_Time begin = pp::Module::Get()->core()->GetTime(); | 709 PP_Time begin = pp::Module::Get()->core()->GetTime(); |
| 795 if (!FlushAndWaitForDone(&dc)) | 710 ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); |
| 796 return "Couldn't flush an invisible paint"; | |
| 797 PP_Time actual_time_elapsed = pp::Module::Get()->core()->GetTime() - begin; | 711 PP_Time actual_time_elapsed = pp::Module::Get()->core()->GetTime() - begin; |
| 798 // Expect actual_time_elapsed >= kFlushDelaySec, but loose a bit to avoid | 712 // Expect actual_time_elapsed >= kFlushDelaySec, but loose a bit to avoid |
| 799 // precision issue. | 713 // precision issue. |
| 800 if (actual_time_elapsed < kFlushDelaySec * 0.9) | 714 ASSERT_GE(actual_time_elapsed, kFlushDelaySec * 0.9); |
| 801 return "Offscreen painting should be delayed"; | |
| 802 | 715 |
| 803 // Remove the padding on the top since test cases here isn't independent. | 716 // Remove the padding on the top since test cases here isn't independent. |
| 804 instance_->EvalScript( | 717 instance_->EvalScript( |
| 805 "var big = document.getElementById('big-div');" | 718 "var big = document.getElementById('big-div');" |
| 806 "big.parentNode.removeChild(big);"); | 719 "big.parentNode.removeChild(big);"); |
| 807 ResetViewChangedState(); | 720 ResetViewChangedState(); |
| 808 if (!WaitUntilViewChanged()) | 721 ASSERT_TRUE(WaitUntilViewChanged()); |
| 809 return "View didn't change as expected"; | |
| 810 | 722 |
| 811 PASS(); | 723 PASS(); |
| 812 } | 724 } |
| 813 | 725 |
| 814 std::string TestGraphics2D::TestDev() { | 726 std::string TestGraphics2D::TestDev() { |
| 815 // Tests GetScale/SetScale via the Graphics2D_Dev C++ wrapper | 727 // Tests GetScale/SetScale via the Graphics2D_Dev C++ wrapper |
| 816 const int w = 20, h = 16; | 728 const int w = 20, h = 16; |
| 817 const float scale = 1.0f/2.0f; | 729 const float scale = 1.0f/2.0f; |
| 818 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 730 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 819 if (dc.is_null()) | 731 ASSERT_FALSE(dc.is_null()); |
| 820 return "Failure creating a boring device"; | |
| 821 pp::Graphics2D_Dev dc_dev(dc); | 732 pp::Graphics2D_Dev dc_dev(dc); |
| 822 if (dc_dev.GetScale() != 1.0f) | 733 ASSERT_EQ(1.0f, dc_dev.GetScale()); |
| 823 return "GetScale returned unexpected value before SetScale"; | 734 ASSERT_TRUE(dc_dev.SetScale(scale)); |
| 824 if (!dc_dev.SetScale(scale)) | 735 ASSERT_EQ(scale, dc_dev.GetScale()); |
| 825 return "SetScale failed"; | |
| 826 if (dc_dev.GetScale() != scale) | |
| 827 return "GetScale mismatch with prior SetScale"; | |
| 828 // Try setting a few invalid scale factors. Ensure that we catch these errors | 736 // Try setting a few invalid scale factors. Ensure that we catch these errors |
| 829 // and don't change the actual scale | 737 // and don't change the actual scale |
| 830 if (dc_dev.SetScale(-1.0f)) | 738 ASSERT_FALSE(dc_dev.SetScale(-1.0f)); |
| 831 return "SetScale(-1f) did not fail"; | 739 ASSERT_FALSE(dc_dev.SetScale(0.0f)); |
| 832 if (dc_dev.SetScale(0.0f)) | 740 ASSERT_EQ(scale, dc_dev.GetScale()); |
| 833 return "SetScale(0.0f) did not fail"; | |
| 834 if (dc_dev.GetScale() != scale) | |
| 835 return "SetScale with invalid parameter overwrote the scale"; | |
| 836 | 741 |
| 837 // Verify that the context has the specified number of pixels, despite the | 742 // Verify that the context has the specified number of pixels, despite the |
| 838 // non-identity scale | 743 // non-identity scale |
| 839 PP_Size size; | 744 PP_Size size; |
| 840 size.width = -1; | 745 size.width = -1; |
| 841 size.height = -1; | 746 size.height = -1; |
| 842 PP_Bool is_always_opaque = PP_FALSE; | 747 PP_Bool is_always_opaque = PP_FALSE; |
| 843 if (!graphics_2d_interface_->Describe(dc_dev.pp_resource(), &size, | 748 ASSERT_TRUE(graphics_2d_interface_->Describe(dc_dev.pp_resource(), &size, |
| 844 &is_always_opaque)) | 749 &is_always_opaque)); |
| 845 return "Describe failed"; | 750 ASSERT_EQ(w, size.width); |
| 846 if (size.width != w || size.height != h || | 751 ASSERT_EQ(h, size.height); |
| 847 is_always_opaque != PP_FromBool(false)) | 752 ASSERT_EQ(PP_FALSE, is_always_opaque); |
| 848 return "Mismatch of data."; | |
| 849 | 753 |
| 850 PASS(); | 754 PASS(); |
| 851 } | 755 } |
| 852 | 756 |
| 853 // This test makes sure that the out-of-process image data caching works as | 757 // This test makes sure that the out-of-process image data caching works as |
| 854 // expected. Doing ReplaceContents quickly should re-use the image data from | 758 // expected. Doing ReplaceContents quickly should re-use the image data from |
| 855 // older ones. | 759 // older ones. |
| 856 std::string TestGraphics2D::TestReplaceContentsCaching() { | 760 std::string TestGraphics2D::TestReplaceContentsCaching() { |
| 857 // The cache is only active when running in the proxy, so skip it otherwise. | 761 // The cache is only active when running in the proxy, so skip it otherwise. |
| 858 if (!testing_interface_->IsOutOfProcess()) | 762 if (!testing_interface_->IsOutOfProcess()) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 | 798 |
| 895 std::string TestGraphics2D::TestBindNull() { | 799 std::string TestGraphics2D::TestBindNull() { |
| 896 // Binding a null resource is not an error, it should clear all bound | 800 // Binding a null resource is not an error, it should clear all bound |
| 897 // resources. We can't easily test what resource is bound, but we can test | 801 // resources. We can't easily test what resource is bound, but we can test |
| 898 // that this doesn't throw an error. | 802 // that this doesn't throw an error. |
| 899 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D())); | 803 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D())); |
| 900 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D())); | 804 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D())); |
| 901 | 805 |
| 902 const int w = 115, h = 117; | 806 const int w = 115, h = 117; |
| 903 pp::Graphics2D dc(instance_, pp::Size(w, h), false); | 807 pp::Graphics2D dc(instance_, pp::Size(w, h), false); |
| 904 if (dc.is_null()) | 808 ASSERT_FALSE(dc.is_null()); |
| 905 return "Failure creating device."; | 809 ASSERT_TRUE(instance_->BindGraphics(dc)); |
| 906 if (!instance_->BindGraphics(dc)) | |
| 907 return "Failure to bind the boring device."; | |
| 908 | 810 |
| 909 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D())); | 811 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D())); |
| 910 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D())); | 812 ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D())); |
| 911 | 813 |
| 912 PASS(); | 814 PASS(); |
| 913 } | 815 } |
| 914 | 816 |
| OLD | NEW |