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) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/pepper/pepper_graphics_2d_host.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/renderer/pepper/gfx_conversion.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/renderer/pepper/mock_renderer_ppapi_host.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/renderer/pepper/ppb_image_data_impl.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/ppb_view_shared.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/test_globals.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebCanvas.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/latency_info.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCanvas; 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PepperGraphics2DHostTest : public testing::Test { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool ConvertToLogicalPixels(float scale, 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect* op_rect, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point* delta) { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PepperGraphics2DHost::ConvertToLogicalPixels(scale, op_rect, delta); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PepperGraphics2DHostTest() : renderer_ppapi_host_(NULL, 12345) {} 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~PepperGraphics2DHostTest() { 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ppapi::ProxyAutoLock proxy_lock; 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) host_.reset(); 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Init(PP_Instance instance, 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PP_Size& backing_store_size, 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PP_Rect& plugin_rect) { 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) renderer_view_data_.rect = plugin_rect; 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) test_globals_.GetResourceTracker()->DidCreateInstance(instance); 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<PPB_ImageData_Impl> backing_store( 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest())); 48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host_.reset(PepperGraphics2DHost::Create(&renderer_ppapi_host_, 49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch instance, 50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 12345, 51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch backing_store_size, 52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PP_FALSE, 53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch backing_store)); 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(host_.get()); 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void PaintImageData(PPB_ImageData_Impl* image_data) { 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ppapi::HostResource image_data_resource; 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) image_data_resource.SetHostResource(image_data->pp_instance(), 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) image_data->pp_resource()); 61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host_->OnHostMsgPaintImageData( 62a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NULL, image_data_resource, PP_Point(), false, PP_Rect()); 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Flush() { 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ppapi::host::HostMessageContext context( 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ppapi::proxy::ResourceMessageCallParams(host_->pp_resource(), 0)); 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<ui::LatencyInfo> latency; 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) host_->OnHostMsgFlush(&context, latency); 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) host_->ViewFlushedPaint(); 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) host_->SendOffscreenFlushAck(); 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void PaintToWebCanvas(SkBitmap* bitmap) { 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<WebCanvas> canvas(new WebCanvas(*bitmap)); 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect plugin_rect(PP_ToGfxRect(renderer_view_data_.rect)); 77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host_->Paint(canvas.get(), 78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch plugin_rect, 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect(0, 0, plugin_rect.width(), plugin_rect.height())); 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void ResetPageBitmap(SkBitmap* bitmap) { 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PP_Rect plugin_rect = renderer_view_data_.rect; 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int width = plugin_rect.point.x + plugin_rect.size.width; 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int height = plugin_rect.point.y + plugin_rect.size.height; 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (bitmap->isNull() || bitmap->width() != width || 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bitmap->height() != height) { 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bitmap->allocN32Pixels(width, height); 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bitmap->eraseColor(0); 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ppapi::ViewData renderer_view_data_; 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<PepperGraphics2DHost> host_; 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop message_loop_; 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MockRendererPpapiHost renderer_ppapi_host_; 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ppapi::TestGlobals test_globals_; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PepperGraphics2DHostTest, ConvertToLogicalPixels) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const struct { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x1; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y1; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int w1; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h1; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x2; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y2; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int w2; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int h2; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dx1; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dy1; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dx2; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dy2; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float scale; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result; 117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } tests[] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, true}, 118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.0, true}, 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {0, 0, 4, 4, 0, 0, 2, 2, 0, 0, 0, 0, 0.5, true}, 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {1, 1, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0.5, false}, 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {53, 75, 100, 100, 53, 75, 100, 100, 0, 0, 0, 0, 1.0, true}, 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {53, 75, 100, 100, 106, 150, 200, 200, 0, 0, 0, 0, 2.0, true}, 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {53, 75, 100, 100, 26, 37, 51, 51, 0, 0, 0, 0, 0.5, false}, 124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {53, 74, 100, 100, 26, 37, 51, 50, 0, 0, 0, 0, 0.5, false}, 125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {-1, -1, 100, 100, -1, -1, 51, 51, 0, 0, 0, 0, 0.5, false}, 126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {-2, -2, 100, 100, -1, -1, 50, 50, 4, -4, 2, -2, 0.5, true}, 127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {-101, -100, 50, 50, -51, -50, 26, 25, 0, 0, 0, 0, 0.5, false}, 128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 20, 20, 5, 5, 10, 10, 0, 0, 0, 0, 0.5, true}, 129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Cannot scroll due to partial coverage on sides 130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {11, 10, 20, 20, 5, 5, 11, 10, 0, 0, 0, 0, 0.5, false}, 131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Can scroll since backing store is actually smaller/scaling up 132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {11, 20, 100, 100, 22, 40, 200, 200, 7, 3, 14, 6, 2.0, true}, 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Can scroll due to delta and bounds being aligned 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 20, 20, 5, 5, 10, 10, 6, 4, 3, 2, 0.5, true}, 135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Cannot scroll due to dx 136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 20, 20, 5, 5, 10, 10, 5, 4, 2, 2, 0.5, false}, 137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Cannot scroll due to dy 138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 20, 20, 5, 5, 10, 10, 6, 3, 3, 1, 0.5, false}, 139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Cannot scroll due to top 140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 11, 20, 20, 5, 5, 10, 11, 6, 4, 3, 2, 0.5, false}, 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Cannot scroll due to left 142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {7, 10, 20, 20, 3, 5, 11, 10, 6, 4, 3, 2, 0.5, false}, 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Cannot scroll due to width 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 21, 20, 5, 5, 11, 10, 6, 4, 3, 2, 0.5, false}, 145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Cannot scroll due to height 146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 20, 51, 5, 5, 10, 26, 6, 4, 3, 2, 0.5, false}, 147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Check negative scroll deltas 148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 20, 20, 5, 5, 10, 10, -6, -4, -3, -2, 0.5, true}, 149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch {10, 10, 20, 20, 5, 5, 10, 10, -6, -3, -3, -1, 0.5, false}, }; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect orig = r1; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point delta(tests[i].dx1, tests[i].dy1); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool res = ConvertToLogicalPixels(tests[i].scale, &r1, &delta); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(r2.ToString(), r1.ToString()); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(res, tests[i].result); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(delta, gfx::Point(tests[i].dx2, tests[i].dy2)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reverse the scale and ensure all the original pixels are still inside 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the result. 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConvertToLogicalPixels(1.0f / tests[i].scale, &r1, NULL); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(r1.Contains(orig)); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 169