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