Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / pepper_graphics_2d_host_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/pepper/pepper_graphics_2d_host.h"
6
7 #include "base/basictypes.h"
8 #include "base/message_loop/message_loop.h"
9 #include "content/renderer/pepper/gfx_conversion.h"
10 #include "content/renderer/pepper/mock_renderer_ppapi_host.h"
11 #include "content/renderer/pepper/ppb_image_data_impl.h"
12 #include "ppapi/shared_impl/ppb_view_shared.h"
13 #include "ppapi/shared_impl/proxy_lock.h"
14 #include "ppapi/shared_impl/test_globals.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/platform/WebCanvas.h"
17 #include "third_party/skia/include/core/SkCanvas.h"
18 #include "ui/gfx/point.h"
19 #include "ui/gfx/rect.h"
20
21 using blink::WebCanvas;
22
23 namespace content {
24
25 class PepperGraphics2DHostTest : public testing::Test {
26  public:
27   static bool ConvertToLogicalPixels(float scale,
28                                      gfx::Rect* op_rect,
29                                      gfx::Point* delta) {
30     return PepperGraphics2DHost::ConvertToLogicalPixels(scale, op_rect, delta);
31   }
32
33   PepperGraphics2DHostTest() : renderer_ppapi_host_(NULL, 12345) {}
34
35   virtual ~PepperGraphics2DHostTest() {
36     ppapi::ProxyAutoLock proxy_lock;
37     host_.reset();
38   }
39
40   void Init(PP_Instance instance,
41             const PP_Size& backing_store_size,
42             const PP_Rect& plugin_rect) {
43     renderer_view_data_.rect = plugin_rect;
44     PluginViewUpdated();
45     test_globals_.GetResourceTracker()->DidCreateInstance(instance);
46     scoped_refptr<PPB_ImageData_Impl> backing_store(
47         new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest()));
48     host_.reset(PepperGraphics2DHost::Create(
49         &renderer_ppapi_host_, instance, 12345, backing_store_size, PP_FALSE,
50         backing_store));
51     DCHECK(host_.get());
52   }
53
54   void PaintImageData(PPB_ImageData_Impl* image_data) {
55     ppapi::HostResource image_data_resource;
56     image_data_resource.SetHostResource(image_data->pp_instance(),
57                                         image_data->pp_resource());
58     host_->OnHostMsgPaintImageData(NULL, image_data_resource,
59                                    PP_Point(), false, PP_Rect());
60   }
61
62   void SetOffset(const PP_Point& point) {
63     host_->OnHostMsgSetOffset(NULL, point);
64   }
65
66   void Flush() {
67     ppapi::host::HostMessageContext context(
68         ppapi::proxy::ResourceMessageCallParams(host_->pp_resource(), 0));
69     host_->OnHostMsgFlush(&context, plugin_view_data_);
70     host_->ViewFlushedPaint();
71     host_->SendOffscreenFlushAck();
72   }
73
74   void PaintToWebCanvas(SkBitmap* bitmap) {
75     scoped_ptr<WebCanvas> canvas(new WebCanvas(*bitmap));
76     gfx::Rect plugin_rect(PP_ToGfxRect(renderer_view_data_.rect));
77     host_->Paint(canvas.get(), plugin_rect,
78                  gfx::Rect(0, 0, plugin_rect.width(), plugin_rect.height()));
79   }
80
81   void DidChangeView(const PP_Rect& plugin_rect) {
82     renderer_view_data_.rect = plugin_rect;
83     host_->DidChangeView(renderer_view_data_);
84   }
85
86   void PluginViewUpdated() {
87     plugin_view_data_ = renderer_view_data_;
88   }
89
90   void SetResizeMode(PP_Graphics2D_Dev_ResizeMode resize_mode) {
91     host_->OnHostMsgSetResizeMode(NULL, resize_mode);
92   }
93
94   void ResetPageBitmap(SkBitmap* bitmap) {
95     PP_Rect plugin_rect = renderer_view_data_.rect;
96     int width = plugin_rect.point.x + plugin_rect.size.width;
97     int height = plugin_rect.point.y + plugin_rect.size.height;
98     if (bitmap->isNull() || bitmap->width() != width ||
99         bitmap->height() != height) {
100       bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
101       bitmap->allocPixels();
102     }
103     bitmap->eraseColor(0);
104   }
105
106  private:
107   ppapi::ViewData renderer_view_data_;
108   ppapi::ViewData plugin_view_data_;
109   scoped_ptr<PepperGraphics2DHost> host_;
110   base::MessageLoop message_loop_;
111   MockRendererPpapiHost renderer_ppapi_host_;
112   ppapi::TestGlobals test_globals_;
113 };
114
115 TEST_F(PepperGraphics2DHostTest, ConvertToLogicalPixels) {
116   static const struct {
117     int x1;
118     int y1;
119     int w1;
120     int h1;
121     int x2;
122     int y2;
123     int w2;
124     int h2;
125     int dx1;
126     int dy1;
127     int dx2;
128     int dy2;
129     float scale;
130     bool result;
131   } tests[] = {
132     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, true },
133     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.0, true },
134     { 0, 0, 4, 4, 0, 0, 2, 2, 0, 0, 0, 0, 0.5, true },
135     { 1, 1, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0.5, false },
136     { 53, 75, 100, 100, 53, 75, 100, 100, 0, 0, 0, 0, 1.0, true },
137     { 53, 75, 100, 100, 106, 150, 200, 200, 0, 0, 0, 0, 2.0, true },
138     { 53, 75, 100, 100, 26, 37, 51, 51, 0, 0, 0, 0, 0.5, false },
139     { 53, 74, 100, 100, 26, 37, 51, 50, 0, 0, 0, 0, 0.5, false },
140     { -1, -1, 100, 100, -1, -1, 51, 51, 0, 0, 0, 0, 0.5, false },
141     { -2, -2, 100, 100, -1, -1, 50, 50, 4, -4, 2, -2, 0.5, true },
142     { -101, -100, 50, 50, -51, -50, 26, 25, 0, 0, 0, 0, 0.5, false },
143     { 10, 10, 20, 20, 5, 5, 10, 10, 0, 0, 0, 0, 0.5, true },
144       // Cannot scroll due to partial coverage on sides
145     { 11, 10, 20, 20, 5, 5, 11, 10, 0, 0, 0, 0, 0.5, false },
146       // Can scroll since backing store is actually smaller/scaling up
147     { 11, 20, 100, 100, 22, 40, 200, 200, 7, 3, 14, 6, 2.0, true },
148       // Can scroll due to delta and bounds being aligned
149     { 10, 10, 20, 20, 5, 5, 10, 10, 6, 4, 3, 2, 0.5, true },
150       // Cannot scroll due to dx
151     { 10, 10, 20, 20, 5, 5, 10, 10, 5, 4, 2, 2, 0.5, false },
152       // Cannot scroll due to dy
153     { 10, 10, 20, 20, 5, 5, 10, 10, 6, 3, 3, 1, 0.5, false },
154       // Cannot scroll due to top
155     { 10, 11, 20, 20, 5, 5, 10, 11, 6, 4, 3, 2, 0.5, false },
156       // Cannot scroll due to left
157     { 7, 10, 20, 20, 3, 5, 11, 10, 6, 4, 3, 2, 0.5, false },
158       // Cannot scroll due to width
159     { 10, 10, 21, 20, 5, 5, 11, 10, 6, 4, 3, 2, 0.5, false },
160       // Cannot scroll due to height
161     { 10, 10, 20, 51, 5, 5, 10, 26, 6, 4, 3, 2, 0.5, false },
162       // Check negative scroll deltas
163     { 10, 10, 20, 20, 5, 5, 10, 10, -6, -4, -3, -2, 0.5, true },
164     { 10, 10, 20, 20, 5, 5, 10, 10, -6, -3, -3, -1, 0.5, false },
165   };
166   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
167     gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
168     gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
169     gfx::Rect orig = r1;
170     gfx::Point delta(tests[i].dx1, tests[i].dy1);
171     bool res = ConvertToLogicalPixels(tests[i].scale, &r1, &delta);
172     EXPECT_EQ(r2.ToString(), r1.ToString());
173     EXPECT_EQ(res, tests[i].result);
174     if (res) {
175       EXPECT_EQ(delta, gfx::Point(tests[i].dx2, tests[i].dy2));
176     }
177     // Reverse the scale and ensure all the original pixels are still inside
178     // the result.
179     ConvertToLogicalPixels(1.0f / tests[i].scale, &r1, NULL);
180     EXPECT_TRUE(r1.Contains(orig));
181   }
182 }
183
184 TEST_F(PepperGraphics2DHostTest, SetOffset) {
185   ppapi::ProxyAutoLock proxy_lock;
186
187   // Initialize the backing store.
188   PP_Instance instance = 12345;
189   PP_Size backing_store_size = { 300, 300 };
190   PP_Rect plugin_rect = PP_MakeRectFromXYWH(0, 0, 500, 500);
191   Init(instance, backing_store_size, plugin_rect);
192
193   // Paint the entire backing store red.
194   scoped_refptr<PPB_ImageData_Impl> image_data(
195       new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest()));
196   image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(),
197                    backing_store_size.width,
198                    backing_store_size.height,
199                    true);
200   {
201     ImageDataAutoMapper auto_mapper(image_data.get());
202     image_data->GetMappedBitmap()->eraseColor(
203         SkColorSetARGBMacro(255, 255, 0, 0));
204   }
205   PaintImageData(image_data.get());
206   Flush();
207
208   // Set up the actual and expected bitmaps/canvas.
209   SkBitmap actual_bitmap;
210   ResetPageBitmap(&actual_bitmap);
211   SkBitmap expected_bitmap;
212   ResetPageBitmap(&expected_bitmap);
213
214   // Paint the backing store to the canvas.
215   PaintToWebCanvas(&actual_bitmap);
216   expected_bitmap.eraseArea(
217       SkIRect::MakeWH(backing_store_size.width, backing_store_size.height),
218       SkColorSetARGBMacro(255, 255, 0, 0));
219   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
220                    actual_bitmap.getAddr(0, 0),
221                    expected_bitmap.getSize()), 0);
222
223   // Set the offset.
224   PP_Point offset = { 20, 20 };
225   SetOffset(offset);
226   ResetPageBitmap(&actual_bitmap);
227   PaintToWebCanvas(&actual_bitmap);
228   // No flush has occurred so the result should be the same.
229   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
230                    actual_bitmap.getAddr(0, 0),
231                    expected_bitmap.getSize()), 0);
232
233   // Flush the offset and the location of the rectangle should have shifted.
234   Flush();
235   ResetPageBitmap(&actual_bitmap);
236   PaintToWebCanvas(&actual_bitmap);
237   ResetPageBitmap(&expected_bitmap);
238   expected_bitmap.eraseArea(
239       SkIRect::MakeXYWH(offset.x, offset.y,
240                         backing_store_size.width, backing_store_size.height),
241       SkColorSetARGBMacro(255, 255, 0, 0));
242   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
243                    actual_bitmap.getAddr(0, 0),
244                    expected_bitmap.getSize()), 0);
245 }
246
247 TEST_F(PepperGraphics2DHostTest, ResizeModeDefault) {
248   ppapi::ProxyAutoLock proxy_lock;
249
250   // Initialize the backing store.
251   PP_Instance instance = 12345;
252   PP_Size backing_store_size = { 300, 300 };
253   PP_Rect plugin_rect = PP_MakeRectFromXYWH(0, 0, 300, 300);
254   Init(instance, backing_store_size, plugin_rect);
255
256   // Paint the entire backing store red.
257   scoped_refptr<PPB_ImageData_Impl> image_data(
258       new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest()));
259   image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(),
260                    backing_store_size.width,
261                    backing_store_size.height,
262                    true);
263   {
264     ImageDataAutoMapper auto_mapper(image_data.get());
265     image_data->GetMappedBitmap()->eraseColor(
266         SkColorSetARGBMacro(255, 255, 0, 0));
267   }
268   PaintImageData(image_data.get());
269   Flush();
270
271   // Set up the actual and expected bitmaps/canvas.
272   SkBitmap actual_bitmap;
273   ResetPageBitmap(&actual_bitmap);
274   SkBitmap expected_bitmap;
275   ResetPageBitmap(&expected_bitmap);
276
277   // Paint the backing store to the canvas.
278   PaintToWebCanvas(&actual_bitmap);
279   expected_bitmap.eraseArea(
280       SkIRect::MakeWH(backing_store_size.width, backing_store_size.height),
281       SkColorSetARGBMacro(255, 255, 0, 0));
282   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
283                    actual_bitmap.getAddr(0, 0),
284                    expected_bitmap.getSize()), 0);
285
286   // Resize the plugin.
287   DidChangeView(PP_MakeRectFromXYWH(0, 0, 500, 500));
288   // Paint the backing store again, it shouldn't have changed.
289   ResetPageBitmap(&actual_bitmap);
290   PaintToWebCanvas(&actual_bitmap);
291   ResetPageBitmap(&expected_bitmap);
292   expected_bitmap.eraseArea(
293       SkIRect::MakeWH(backing_store_size.width, backing_store_size.height),
294       SkColorSetARGBMacro(255, 255, 0, 0));
295   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
296                    actual_bitmap.getAddr(0, 0),
297                    expected_bitmap.getSize()), 0);
298
299   // Let the plugin know about the updated view and reflush the original image.
300   PluginViewUpdated();
301   PaintImageData(image_data.get());
302   Flush();
303   // Paint the backing store again, it shouldn't have changed.
304   ResetPageBitmap(&actual_bitmap);
305   PaintToWebCanvas(&actual_bitmap);
306   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
307                    actual_bitmap.getAddr(0, 0),
308                    expected_bitmap.getSize()), 0);
309 }
310
311 TEST_F(PepperGraphics2DHostTest, ResizeModeStretch) {
312   ppapi::ProxyAutoLock proxy_lock;
313
314   // Initialize the backing store.
315   PP_Instance instance = 12345;
316   PP_Size backing_store_size = { 300, 300 };
317   PP_Rect plugin_rect = PP_MakeRectFromXYWH(0, 0, 300, 300);
318   Init(instance, backing_store_size, plugin_rect);
319   SetResizeMode(PP_GRAPHICS2D_DEV_RESIZEMODE_STRETCH);
320
321   // Paint the entire backing store red.
322   scoped_refptr<PPB_ImageData_Impl> image_data(
323       new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest()));
324   image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(),
325                    backing_store_size.width,
326                    backing_store_size.height,
327                    true);
328   {
329     ImageDataAutoMapper auto_mapper(image_data.get());
330     image_data->GetMappedBitmap()->eraseColor(
331         SkColorSetARGBMacro(255, 255, 0, 0));
332   }
333   PaintImageData(image_data.get());
334   Flush();
335
336   // Set up the actual and expected bitmaps/canvas.
337   SkBitmap actual_bitmap;
338   ResetPageBitmap(&actual_bitmap);
339   SkBitmap expected_bitmap;
340   ResetPageBitmap(&expected_bitmap);
341
342   // Paint the backing store to the canvas.
343   PaintToWebCanvas(&actual_bitmap);
344   expected_bitmap.eraseArea(
345       SkIRect::MakeWH(backing_store_size.width, backing_store_size.height),
346       SkColorSetARGBMacro(255, 255, 0, 0));
347   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
348                    actual_bitmap.getAddr(0, 0),
349                    expected_bitmap.getSize()), 0);
350
351   // Resize the plugin.
352   plugin_rect = PP_MakeRectFromXYWH(0, 0, 500, 500);
353   DidChangeView(plugin_rect);
354   ResetPageBitmap(&actual_bitmap);
355   ResetPageBitmap(&expected_bitmap);
356
357   // Paint the backing store again, it should be stretched even though no new
358   // image has been flushed.
359   PaintToWebCanvas(&actual_bitmap);
360   expected_bitmap.eraseColor(SkColorSetARGBMacro(255, 255, 0, 0));
361   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
362                    actual_bitmap.getAddr(0, 0),
363                    expected_bitmap.getSize()), 0);
364
365   // Re-flush the original image data and paint it, it should be stretched as
366   // well.
367   PaintImageData(image_data.get());
368   Flush();
369   ResetPageBitmap(&actual_bitmap);
370   PaintToWebCanvas(&actual_bitmap);
371   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
372                    actual_bitmap.getAddr(0, 0),
373                    expected_bitmap.getSize()), 0);
374
375   // Let the plugin know about the updated view.
376   PluginViewUpdated();
377
378   // Now flush the image data again, it should be at the original size.
379   PaintImageData(image_data.get());
380   Flush();
381   ResetPageBitmap(&actual_bitmap);
382   PaintToWebCanvas(&actual_bitmap);
383   ResetPageBitmap(&expected_bitmap);
384   expected_bitmap.eraseArea(
385       SkIRect::MakeWH(backing_store_size.width, backing_store_size.height),
386       SkColorSetARGBMacro(255, 255, 0, 0));
387   EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0),
388                    actual_bitmap.getAddr(0, 0),
389                    expected_bitmap.getSize()), 0);
390 }
391
392 }  // namespace content