15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_graphics_2d.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_testing_dev.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_graphics_2d.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/completion_callback.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/dev/graphics_2d_dev.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/cpp/dev/graphics_2d_dev.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/graphics_2d.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/cpp/graphics_3d.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/image_data.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/rect.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/tests/test_utils.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_TEST_CASE(Graphics2D); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A NOP flush callback for use in various tests. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FlushCallbackNOP(void* data, int32_t result) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FlushCallbackQuitMessageLoop(void* data, int32_t result) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<TestGraphics2D*>(data)->QuitMessageLoop(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CanFlushContext(pp::Instance* instance, pp::Graphics2D* context) { 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestCompletionCallback callback(instance->pp_instance()); 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.WaitForResult(context->Flush(callback.GetCallback())); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (callback.result() == PP_OK); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CanFlushContextC(pp::Instance* instance, PP_Resource graphics_2d, 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const PPB_Graphics2D_1_1* graphics_2d_if) { 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestCompletionCallback callback(instance->pp_instance()); 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.WaitForResult(graphics_2d_if->Flush( 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) graphics_2d, callback.GetCallback().pp_completion_callback())); 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (callback.result() == PP_OK); 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestGraphics2D::TestGraphics2D(TestingInstance* instance) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : TestCase(instance), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_view_changed_(false), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) post_quit_on_view_changed_(false) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::Init() { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_ = static_cast<const PPB_Graphics2D*>( 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pp::Module::Get()->GetBrowserInterface(PPB_GRAPHICS_2D_INTERFACE_1_1)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_data_interface_ = static_cast<const PPB_ImageData*>( 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE_1_0)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return graphics_2d_interface_ && image_data_interface_ && 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTestingInterface(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestGraphics2D::RunTests(const std::string& filter) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(InvalidResource, filter); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(InvalidSize, filter); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(Humongous, filter); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(InitToZero, filter); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(Describe, filter); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RUN_TEST(Scale, filter); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_FORCEASYNC_AND_NOT(Paint, filter); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_FORCEASYNC_AND_NOT(Scroll, filter); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_FORCEASYNC_AND_NOT(Replace, filter); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_FORCEASYNC_AND_NOT(Flush, filter); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_FORCEASYNC_AND_NOT(FlushOffscreenUpdate, filter); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(Dev, filter); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(ReplaceContentsCaching, filter); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RUN_TEST(BindNull, filter); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestGraphics2D::QuitMessageLoop() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing_interface_->QuitMessageLoop(instance_->pp_instance()); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::ReadImageData(const pp::Graphics2D& dc, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData* image, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Point& top_left) const { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ToBool(testing_interface_->ReadImageData( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.pp_resource(), 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image->pp_resource(), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &top_left.pp_point())); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::IsDCUniformColor(const pp::Graphics2D& dc, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t color) const { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData readback(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.size(), false); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (readback.is_null()) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadImageData(dc, &readback, pp::Point(0, 0))) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsSquareInImage(readback, 0, pp::Rect(dc.size()), color); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string TestGraphics2D::FlushAndWaitForDone(pp::Graphics2D* context) { 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.WaitForResult(context->Flush(callback.GetCallback())); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PASS(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestGraphics2D::FillRectInImage(pp::ImageData* image, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& rect, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t color) const { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = rect.y(); y < rect.bottom(); y++) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* row = image->GetAddr32(pp::Point(rect.x(), y)); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int pixel = 0; pixel < rect.width(); pixel++) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) row[pixel] = color; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestGraphics2D::FillImageWithGradient(pp::ImageData* image) const { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < image->size().height(); y++) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t red = ((y * 256) / image->size().height()) & 0xFF; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < image->size().width(); x++) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t green = ((x * 256) / image->size().width()) & 0xFF; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t blue = ((red + green) / 2) & 0xFF; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t* pixel = image->GetAddr32(pp::Point(x, y)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pixel = (blue << 24) | (green << 16) | (red << 8); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::CompareImages(const pp::ImageData& image1, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::ImageData& image2) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CompareImageRect( 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image1, pp::Rect(0, 0, image1.size().width(), image1.size().height()), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image2, pp::Rect(0, 0, image2.size().width(), image2.size().height())); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::CompareImageRect(const pp::ImageData& image1, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& rc1, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::ImageData& image2, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& rc2) const { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rc1.width() != rc2.width() || rc1.height() != rc2.height()) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < rc1.height(); y++) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < rc1.width(); x++) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*(image1.GetAddr32(pp::Point(rc1.x() + x, rc1.y() + y))) != 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(image2.GetAddr32(pp::Point(rc2.x() + x, rc2.y() + y)))) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::IsSquareInImage(const pp::ImageData& image_data, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t background_color, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& square, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t square_color) const { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < image_data.size().height(); y++) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < image_data.size().width(); x++) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t pixel = *image_data.GetAddr32(pp::Point(x, y)); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t desired_color; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (square.Contains(x, y)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_color = square_color; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_color = background_color; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pixel != desired_color) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::IsSquareInDC(const pp::Graphics2D& dc, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t background_color, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Rect& square, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t square_color) const { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData readback(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.size(), false); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (readback.is_null()) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadImageData(dc, &readback, pp::Point(0, 0))) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsSquareInImage(readback, background_color, square, square_color); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource TestGraphics2D::ReplaceContentsAndReturnID( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D* dc, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Size& size) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, true); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource id = image.pp_resource(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc->ReplaceContents(&image); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string result = FlushAndWaitForDone(dc); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result.empty()) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return id; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test all the functions with an invalid handle. Most of these just check for 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a crash since the browser don't return a value. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestInvalidResource() { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D null_context; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(16, 16), true); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Describe. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Size size; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool opaque; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->Describe(image.pp_resource(), &size, &opaque); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->Describe(null_context.pp_resource(), 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &size, &opaque); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PaintImageData. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Point zero_zero; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zero_zero.x = 0; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zero_zero.y = 0; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->PaintImageData(image.pp_resource(), 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.pp_resource(), 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &zero_zero, NULL); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->PaintImageData(null_context.pp_resource(), 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.pp_resource(), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &zero_zero, NULL); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scroll. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Point zero_ten; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zero_ten.x = 0; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zero_ten.y = 10; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->Scroll(image.pp_resource(), NULL, &zero_ten); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->Scroll(null_context.pp_resource(), 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, &zero_ten); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ReplaceContents. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->ReplaceContents(image.pp_resource(), 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.pp_resource()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) graphics_2d_interface_->ReplaceContents(null_context.pp_resource(), 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.pp_resource()); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush. 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestCompletionCallback cb(instance_->pp_instance(), PP_OPTIONAL); 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cb.WaitForResult( 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) graphics_2d_interface_->Flush(image.pp_resource(), 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cb.GetCallback().pp_completion_callback())); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_ERROR_BADRESOURCE, cb.result()); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cb.WaitForResult( 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) graphics_2d_interface_->Flush(null_context.pp_resource(), 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cb.GetCallback().pp_completion_callback())); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_ERROR_BADRESOURCE, cb.result()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ReadImageData. 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(testing_interface_->ReadImageData(image.pp_resource(), 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) image.pp_resource(), 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &zero_zero)); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(testing_interface_->ReadImageData(null_context.pp_resource(), 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) image.pp_resource(), 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &zero_zero)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestInvalidSize() { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D a(instance_, pp::Size(16, 0), false); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CanFlushContext(instance_, &a)); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D b(instance_, pp::Size(0, 16), false); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CanFlushContext(instance_, &b)); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need to use the C API since pp::Size prevents negative sizes. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Size size; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.width = 16; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.height = -16; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Resource graphics = graphics_2d_interface_->Create( 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) instance_->pp_instance(), &size, PP_FALSE); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_)); 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pp::Module::Get()->core()->ReleaseResource(graphics); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.width = -16; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.height = 16; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) graphics = graphics_2d_interface_->Create( 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) instance_->pp_instance(), &size, PP_FALSE); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_)); 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pp::Module::Get()->core()->ReleaseResource(graphics); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overflow to negative size 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size.width = std::numeric_limits<int32_t>::max(); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size.height = std::numeric_limits<int32_t>::max(); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) graphics = graphics_2d_interface_->Create( 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) instance_->pp_instance(), &size, PP_FALSE); 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_)); 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pp::Module::Get()->core()->ReleaseResource(graphics); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestHumongous() { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D a(instance_, pp::Size(100000, 100000), false); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CanFlushContext(instance_, &a)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestInitToZero() { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 15, h = 17; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make an image with nonzero data in it (so we can test that zeros were 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually read versus ReadImageData being a NOP). 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w, h), true); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(image.is_null()); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(image.size().IsEmpty()); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(image.data(), 0xFF, image.stride() * image.size().height() * 4); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read out the initial data from the device & check. 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(ReadImageData(dc, &image, pp::Point(0, 0))); 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsSquareInImage(image, 0, pp::Rect(0, 0, w, h), 0)); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestDescribe() { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 15, h = 17; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool always_opaque = (::rand() % 2 == 1); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), always_opaque); 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Size size; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.width = -1; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.height = -1; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool is_always_opaque = PP_FALSE; 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(graphics_2d_interface_->Describe(dc.pp_resource(), &size, 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &is_always_opaque)); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(w, size.width); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(h, size.height); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_FromBool(always_opaque), is_always_opaque); 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PASS(); 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string TestGraphics2D::TestScale() { 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests GetScale/SetScale 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int w = 20, h = 16; 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const float scale = 1.0f/2.0f; 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(1.0, dc.GetScale()); 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(dc.SetScale(scale)); 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(scale, dc.GetScale()); 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Try setting a few invalid scale factors. Ensure that we catch these errors 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // and don't change the actual scale 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.SetScale(-1.0f)); 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.SetScale(0.0f)); 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(scale, dc.GetScale()); 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Verify that the context has the specified number of pixels, despite the 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // non-identity scale 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Size size; 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size.width = -1; 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size.height = -1; 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Bool is_always_opaque = PP_FALSE; 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(graphics_2d_interface_->Describe(dc.pp_resource(), &size, 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &is_always_opaque)); 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(w, size.width); 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(h, size.height); 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_FALSE, is_always_opaque); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestPaint() { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 15, h = 17; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the device background is 0. 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsDCUniformColor(dc, 0)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill the backing store with white. 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t background_color = 0xFFFFFFFF; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w, h), false); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(background, pp::Point(0, 0)); 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make an image to paint with that's opaque white and enqueue a paint. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int fill_w = 2, fill_h = 3; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData fill(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(fill_w, fill_h), true); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(fill.is_null()); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRectInImage(&fill, pp::Rect(fill.size()), background_color); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int paint_x = 4, paint_y = 5; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(fill, pp::Point(paint_x, paint_y)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validate that nothing has been actually painted. 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsDCUniformColor(dc, background_color)); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The paint hasn't been flushed so we can still change the bitmap. Fill with 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 50% blue. This will also verify that the backing store is replaced 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the contents rather than blended. 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t fill_color = 0x80000080; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRectInImage(&fill, pp::Rect(fill.size()), fill_color); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsSquareInDC(dc, background_color, 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pp::Rect(paint_x, paint_y, fill_w, fill_h), 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fill_color)); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset the DC to blank white & paint our image slightly off the buffer. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should succeed. We also try painting the same thing where the 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dirty rect falls outeside of the device, which should fail. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(background, pp::Point(0, 0)); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int second_paint_x = -1, second_paint_y = -2; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y)); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y), 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Rect(-second_paint_x, -second_paint_y, 1, 1)); 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we should have a little bit of the image peeking out the top left. 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1), 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fill_color)); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now repaint that top left pixel by doing a subset of the source image. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData subset(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w, h), false); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t subset_color = 0x80808080; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int subset_x = 2, subset_y = 1; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *subset.GetAddr32(pp::Point(subset_x, subset_y)) = subset_color; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(subset, pp::Point(-subset_x, -subset_y), 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Rect(subset_x, subset_y, 1, 1)); 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1), 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) subset_color)); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestScroll() { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 115, h = 117; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(instance_->BindGraphics(dc)); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the device background is 0. 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsDCUniformColor(dc, 0)); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int image_width = 15, image_height = 23; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData test_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(image_width, image_height), false); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillImageWithGradient(&test_image); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData no_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(image_width, image_height), false); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRectInImage(&no_image, pp::Rect(0, 0, image_width, image_height), 0); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData readback_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(image_width, image_height), false); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData readback_scroll(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(image_width, image_height), false); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(pp::Size(image_width, image_height), test_image.size()); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_x = 51, image_y = 72; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(test_image, pp::Point(image_x, image_y)); 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test Case 1. Incorrect usage when scrolling image to a free space. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The clip area is *not* the area to shift around within the graphics device 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by specified amount. It's the area to which the scroll is limited. So if 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the clip area is the size of the image and the amount points to free space, 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the scroll won't result in additional images. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dx = -40, dy = -48; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int scroll_x = image_x + dx, scroll_y = image_y + dy; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Rect clip(image_x, image_y, image_width, image_height); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.Scroll(clip, pp::Point(dx, dy)); 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(CompareImages(no_image, readback_scroll)); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test Case 2. 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The amount is intended to place the image in the free space outside 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the original, but the clip area extends beyond the graphics device area. 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This scroll is invalid and will be a noop. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scroll_x = 11, scroll_y = 24; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip = pp::Rect(0, 0, w, h + 1); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(CompareImages(no_image, readback_scroll)); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test Case 3. 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The amount is intended to place the image in the free space outside 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the original, but the clip area does not cover the image, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so there is nothing to scroll. 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scroll_x = 11, scroll_y = 24; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip = pp::Rect(0, 0, image_x, image_y); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(CompareImages(no_image, readback_scroll)); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test Case 4. 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as TC3, but the clip covers part of the image. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This part will be scrolled to the intended origin. 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int part_w = image_width / 2, part_h = image_height / 2; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip = pp::Rect(0, 0, image_x + part_w, image_y + part_h); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CompareImages(test_image, readback_scroll)); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Rect part_rect(part_w, part_h); 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompareImageRect(test_image, part_rect, readback_scroll, part_rect)); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test Case 5 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as TC3, but the clip area covers the entire image. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It will be scrolled to the intended origin. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip = pp::Rect(0, 0, image_x + image_width, image_y + image_height); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y)); 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(CompareImages(test_image, readback_scroll)); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the undefined area left by the scroll does not actually get 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cleared, so the original image is still there. This is not guaranteed and 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is not something for users to rely on, but we can test for this here, so 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we know when the underlying behavior changes. 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(ReadImageData(dc, &readback_image, pp::Point(image_x, image_y))); 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(CompareImages(test_image, readback_image)); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test Case 6. 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scroll image to an overlapping space. The clip area is limited 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the image, so this will just modify its area. 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dx = 6; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dy = 9; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scroll_x = image_x + dx; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scroll_y = image_y + dy; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip = pp::Rect(image_x, image_y, image_width, image_height); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.Scroll(clip, pp::Point(dx, dy)); 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(ReadImageData(dc, &readback_image, pp::Point(image_x, image_y))); 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(CompareImages(test_image, readback_image)); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Rect scroll_rect(image_width - dx, image_height - dy); 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y))); 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompareImageRect(test_image, scroll_rect, readback_scroll, scroll_rect)); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestReplace() { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 15, h = 17; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Replacing with a different size image should fail. 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData weird_size(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w - 1, h), true); 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(weird_size.is_null()); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.ReplaceContents(&weird_size); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill the background with blue but don't flush yet. 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int32_t background_color = 0xFF0000FF; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w, h), true); 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(background.is_null()); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(background, pp::Point(0, 0)); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Replace with a green background but don't flush yet. 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int32_t swapped_color = 0x00FF00FF; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData swapped(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w, h), true); 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(swapped.is_null()); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRectInImage(&swapped, pp::Rect(0, 0, w, h), swapped_color); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.ReplaceContents(&swapped); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The background should be unchanged since we didn't flush yet. 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsDCUniformColor(dc, 0)); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the C++ wrapper. The size of the swapped image should be reset. 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(!swapped.pp_resource() && !swapped.size().width() && 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !swapped.size().height() && !swapped.data()); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Painting with the swapped image should fail. 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(swapped, pp::Point(0, 0)); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush and make sure the result is correct. 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The background should be green from the swapped image. 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(IsDCUniformColor(dc, swapped_color)); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestFlush() { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tests that synchronous flushes (NULL callback) fail on the main thread 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (which is the current one). 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 15, h = 17; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill the background with blue but don't flush yet. 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w, h), true); 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(background.is_null()); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(background, pp::Point(0, 0)); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t rv = dc.Flush(pp::BlockUntilComplete()); 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_ERROR_BLOCKS_MAIN_THREAD, rv); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test flushing with no operations still issues a callback. 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (This may also hang if the browser never issues the callback). 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc_nopaints(instance_, pp::Size(w, h), false); 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc_nopaints)); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestCompletionCallback callback_1(instance_->pp_instance(), callback_type()); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that multiple flushes fail if we don't get a callback in between. 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = dc_nopaints.Flush(callback_1.GetCallback()); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == PP_OK_COMPLETIONPENDING) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the first flush completes asynchronously, then a second should fail. 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestCompletionCallback callback_2(instance_->pp_instance(), 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_type()); 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_2.WaitForResult(dc_nopaints.Flush(callback_2.GetCallback())); 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback_2); 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_ERROR_INPROGRESS, callback_2.result()); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_1.WaitForResult(rv); 649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_OK, callback_1.result()); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestGraphics2D::DidChangeView(const pp::View& view) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (post_quit_on_view_changed_) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) post_quit_on_view_changed_ = false; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_view_changed_ = true; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing_interface_->QuitMessageLoop(instance_->pp_instance()); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestGraphics2D::ResetViewChangedState() { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_view_changed_ = false; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestGraphics2D::WaitUntilViewChanged() { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run a nested message loop. It will exit either on ViewChanged or if the 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout happens. 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If view changed before we have chance to run message loop, return directly. 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_view_changed_) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) post_quit_on_view_changed_ = true; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing_interface_->RunMessageLoop(instance_->pp_instance()); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) post_quit_on_view_changed_ = false; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_view_changed_; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestFlushOffscreenUpdate() { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tests that callback of offscreen updates should be delayed. 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_Time kFlushDelaySec = 1. / 30; // 30 fps 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 80, h = 80; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), true); 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(instance_->BindGraphics(dc)); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Squeeze from top until bottom half of plugin is out of screen. 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetViewChangedState(); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->EvalScript( 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "var big = document.createElement('div');" 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "var offset = " 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " window.innerHeight - plugin.offsetTop - plugin.offsetHeight / 2;" 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "big.setAttribute('id', 'big-div');" 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "big.setAttribute('style', 'height: ' + offset + '; width: 100%;');" 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document.body.insertBefore(big, document.body.firstChild);"); 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(WaitUntilViewChanged()); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a red image chunk 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::ImageData chunk(instance_, PP_IMAGEDATAFORMAT_RGBA_PREMUL, 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size(w/8, h/8), true); 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(chunk.is_null()); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t kRed = 0xff0000ff; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRectInImage(&chunk, pp::Rect(chunk.size()), kRed); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Paint a invisable chunk, expecting Flush to invoke callback slowly. 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dc.PaintImageData(chunk, pp::Point(0, h*0.75)); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Time begin = pp::Module::Get()->core()->GetTime(); 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc)); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Time actual_time_elapsed = pp::Module::Get()->core()->GetTime() - begin; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expect actual_time_elapsed >= kFlushDelaySec, but loose a bit to avoid 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // precision issue. 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_GE(actual_time_elapsed, kFlushDelaySec * 0.9); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the padding on the top since test cases here isn't independent. 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->EvalScript( 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "var big = document.getElementById('big-div');" 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "big.parentNode.removeChild(big);"); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetViewChangedState(); 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(WaitUntilViewChanged()); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestDev() { 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tests GetScale/SetScale via the Graphics2D_Dev C++ wrapper 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int w = 20, h = 16; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float scale = 1.0f/2.0f; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D_Dev dc_dev(dc); 734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(1.0f, dc_dev.GetScale()); 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(dc_dev.SetScale(scale)); 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(scale, dc_dev.GetScale()); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try setting a few invalid scale factors. Ensure that we catch these errors 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and don't change the actual scale 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc_dev.SetScale(-1.0f)); 740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc_dev.SetScale(0.0f)); 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(scale, dc_dev.GetScale()); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the context has the specified number of pixels, despite the 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // non-identity scale 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Size size; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.width = -1; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.height = -1; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool is_always_opaque = PP_FALSE; 749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(graphics_2d_interface_->Describe(dc_dev.pp_resource(), &size, 750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &is_always_opaque)); 751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(w, size.width); 752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(h, size.height); 753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(PP_FALSE, is_always_opaque); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test makes sure that the out-of-process image data caching works as 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expected. Doing ReplaceContents quickly should re-use the image data from 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// older ones. 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestGraphics2D::TestReplaceContentsCaching() { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The cache is only active when running in the proxy, so skip it otherwise. 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!testing_interface_->IsOutOfProcess()) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Here we test resource IDs as a way to determine if the resource is being 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cached and re-used. This is non-optimal since it's entirely possible 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (and maybe better) for the proxy to return new resource IDs for the 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // re-used objects. Howevever, our current implementation does this so it is 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an easy thing to check for. 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // You could check for the shared memory pointers getting re-used, but the 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OS is very likely to use the same memory location for a newly-mapped image 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if one was deleted, meaning that it could pass even if the cache is broken. 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This would then require that we add some address-re-use-preventing code 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which would be tricky. 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<PP_Resource> resources; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Size size(16, 16); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Graphics2D dc(instance_, size, false); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do two replace contentses, adding the old resource IDs to our map. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource imageres = ReplaceContentsAndReturnID(&dc, size); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(imageres); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resources.insert(imageres); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imageres = ReplaceContentsAndReturnID(&dc, size); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(imageres); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resources.insert(imageres); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now doing more replace contents should re-use older IDs if the cache is 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // working. 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imageres = ReplaceContentsAndReturnID(&dc, size); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(resources.find(imageres) != resources.end()); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) imageres = ReplaceContentsAndReturnID(&dc, size); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(resources.find(imageres) != resources.end()); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestGraphics2D::TestBindNull() { 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Binding a null resource is not an error, it should clear all bound 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // resources. We can't easily test what resource is bound, but we can test 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that this doesn't throw an error. 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D())); 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D())); 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int w = 115, h = 117; 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pp::Graphics2D dc(instance_, pp::Size(w, h), false); 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(dc.is_null()); 810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(instance_->BindGraphics(dc)); 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D())); 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D())); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PASS(); 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 818