Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / RecordingImageBufferSurfaceTest.cpp
1 // Copyright 2014 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 "config.h"
6
7 #include "platform/graphics/RecordingImageBufferSurface.h"
8
9 #include "platform/graphics/GraphicsContext.h"
10 #include "platform/graphics/ImageBuffer.h"
11 #include "platform/graphics/ImageBufferClient.h"
12 #include "public/platform/Platform.h"
13 #include "public/platform/WebThread.h"
14 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "third_party/skia/include/core/SkPictureRecorder.h"
16 #include "wtf/OwnPtr.h"
17 #include "wtf/PassOwnPtr.h"
18 #include "wtf/RefPtr.h"
19
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 using namespace blink;
24 using testing::Test;
25
26 namespace {
27
28 class FakeImageBufferClient : public ImageBufferClient, public WebThread::TaskObserver {
29 public:
30     FakeImageBufferClient(ImageBuffer* imageBuffer)
31         : m_isDirty(false)
32         , m_imageBuffer(imageBuffer)
33         , m_frameCount(0)
34     { }
35
36     virtual ~FakeImageBufferClient() { }
37
38     // ImageBufferClient implementation
39     virtual void notifySurfaceInvalid() { }
40     virtual bool isDirty() { return m_isDirty; };
41     virtual void didFinalizeFrame()
42     {
43         if (m_isDirty) {
44             Platform::current()->currentThread()->removeTaskObserver(this);
45             m_isDirty = false;
46         }
47         ++m_frameCount;
48     }
49
50     // TaskObserver implementation
51     virtual void willProcessTask() OVERRIDE { ASSERT_NOT_REACHED(); }
52     virtual void didProcessTask() OVERRIDE
53     {
54         ASSERT_TRUE(m_isDirty);
55         FloatRect dirtyRect(0, 0, 1, 1);
56         m_imageBuffer->finalizeFrame(dirtyRect);
57         ASSERT_FALSE(m_isDirty);
58     }
59
60     void fakeDraw()
61     {
62         if (m_isDirty)
63             return;
64         m_isDirty = true;
65         Platform::current()->currentThread()->addTaskObserver(this);
66     }
67
68     int frameCount() { return m_frameCount; }
69
70 private:
71     bool m_isDirty;
72     ImageBuffer* m_imageBuffer;
73     int m_frameCount;
74 };
75
76 } // unnamed namespace
77
78 class RecordingImageBufferSurfaceTest : public Test {
79 protected:
80     RecordingImageBufferSurfaceTest()
81     {
82         OwnPtr<RecordingImageBufferSurface> testSurface = adoptPtr(new RecordingImageBufferSurface(IntSize(10, 10)));
83         m_testSurface = testSurface.get();
84         // We create an ImageBuffer in order for the testSurface to be
85         // properly initialized with a GraphicsContext
86         m_imageBuffer = ImageBuffer::create(testSurface.release());
87         m_fakeImageBufferClient = adoptPtr(new FakeImageBufferClient(m_imageBuffer.get()));
88         m_imageBuffer->setClient(m_fakeImageBufferClient.get());
89     }
90
91 public:
92     void testEmptyPicture()
93     {
94         m_testSurface->initializeCurrentFrame();
95         RefPtr<SkPicture> picture = m_testSurface->getPicture();
96         EXPECT_TRUE((bool)picture.get());
97         EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
98         expectDisplayListEnabled(true);
99     }
100
101     void testNoFallbackWithClear()
102     {
103         m_testSurface->initializeCurrentFrame();
104         m_testSurface->didClearCanvas();
105         m_testSurface->getPicture();
106         EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
107         expectDisplayListEnabled(true);
108     }
109
110     void testNonAnimatedCanvasUpdate()
111     {
112         m_testSurface->initializeCurrentFrame();
113         // acquire picture twice to simulate a static canvas: nothing drawn between updates
114         m_fakeImageBufferClient->fakeDraw();
115         m_testSurface->getPicture();
116         m_testSurface->getPicture();
117         EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
118         expectDisplayListEnabled(true);
119     }
120
121     void testAnimatedWithoutClear()
122     {
123         m_testSurface->initializeCurrentFrame();
124         m_fakeImageBufferClient->fakeDraw();
125         m_testSurface->getPicture();
126         EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
127         expectDisplayListEnabled(true); // first frame has an implicit clear
128         m_fakeImageBufferClient->fakeDraw();
129         m_testSurface->getPicture();
130         EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
131         expectDisplayListEnabled(false);
132     }
133
134     void testFrameFinalizedByTaskObserver1()
135     {
136         m_testSurface->initializeCurrentFrame();
137         expectDisplayListEnabled(true);
138         m_testSurface->getPicture();
139         EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
140         expectDisplayListEnabled(true);
141         m_fakeImageBufferClient->fakeDraw();
142         EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
143         expectDisplayListEnabled(true);
144         m_testSurface->getPicture();
145         EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
146         expectDisplayListEnabled(true);
147         m_fakeImageBufferClient->fakeDraw();
148         EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
149         expectDisplayListEnabled(true);
150         // Display list will be disabled only after exiting the runLoop
151     }
152     void testFrameFinalizedByTaskObserver2()
153     {
154         EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
155         expectDisplayListEnabled(false);
156         m_testSurface->getPicture();
157         EXPECT_EQ(4, m_fakeImageBufferClient->frameCount());
158         expectDisplayListEnabled(false);
159         m_fakeImageBufferClient->fakeDraw();
160         EXPECT_EQ(4, m_fakeImageBufferClient->frameCount());
161         expectDisplayListEnabled(false);
162     }
163
164     void testAnimatedWithClear()
165     {
166         m_testSurface->initializeCurrentFrame();
167         m_testSurface->getPicture();
168         m_testSurface->didClearCanvas();
169         m_fakeImageBufferClient->fakeDraw();
170         EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
171         m_testSurface->getPicture();
172         EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
173         expectDisplayListEnabled(true);
174         // clear after use
175         m_fakeImageBufferClient->fakeDraw();
176         m_testSurface->didClearCanvas();
177         EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
178         m_testSurface->getPicture();
179         EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
180         expectDisplayListEnabled(true);
181     }
182
183     void testClearRect()
184     {
185         m_testSurface->initializeCurrentFrame();
186         m_testSurface->getPicture();
187         m_imageBuffer->context()->clearRect(FloatRect(FloatPoint(0, 0), FloatSize(m_testSurface->size())));
188         m_fakeImageBufferClient->fakeDraw();
189         EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
190         m_testSurface->getPicture();
191         EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
192         expectDisplayListEnabled(true);
193     }
194
195     void expectDisplayListEnabled(bool displayListEnabled)
196     {
197         EXPECT_EQ(displayListEnabled, (bool)m_testSurface->m_currentFrame.get());
198         EXPECT_EQ(!displayListEnabled, (bool)m_testSurface->m_rasterCanvas.get());
199     }
200
201 private:
202     RecordingImageBufferSurface* m_testSurface;
203     OwnPtr<FakeImageBufferClient> m_fakeImageBufferClient;
204     OwnPtr<ImageBuffer> m_imageBuffer;
205 };
206
207 namespace {
208
209 // The following test helper class installs a mock platform that provides a mock WebThread
210 // for the current thread. The Mock thread is capable of queuing a single non-delayed task
211 // and registering a single task observer. The run loop exits immediately after running
212 // the single task.
213 class AutoInstallCurrentThreadPlatformMock {
214 public:
215     AutoInstallCurrentThreadPlatformMock()
216     {
217         m_oldPlatform = Platform::current();
218         Platform::initialize(&m_mockPlatform);
219     }
220
221     ~AutoInstallCurrentThreadPlatformMock()
222     {
223         Platform::initialize(m_oldPlatform);
224     }
225
226 private:
227     class CurrentThreadMock : public WebThread {
228     public:
229         CurrentThreadMock() : m_taskObserver(0), m_task(0) { }
230
231         virtual ~CurrentThreadMock()
232         {
233             EXPECT_EQ((Task*)0, m_task);
234         }
235
236         virtual void postTask(Task* task)
237         {
238             EXPECT_EQ((Task*)0, m_task);
239             m_task = task;
240         }
241
242         virtual void postDelayedTask(Task*, long long delayMs) OVERRIDE { ASSERT_NOT_REACHED(); };
243
244         virtual bool isCurrentThread() const OVERRIDE { return true; }
245
246         virtual void addTaskObserver(TaskObserver* taskObserver) OVERRIDE
247         {
248             EXPECT_EQ((TaskObserver*)0, m_taskObserver);
249             m_taskObserver = taskObserver;
250         }
251
252         virtual void removeTaskObserver(TaskObserver* taskObserver) OVERRIDE
253         {
254             EXPECT_EQ(m_taskObserver, taskObserver);
255             m_taskObserver = 0;
256         }
257
258         virtual void enterRunLoop() OVERRIDE
259         {
260             if (m_taskObserver)
261                 m_taskObserver->willProcessTask();
262             if (m_task) {
263                 m_task->run();
264                 delete m_task;
265                 m_task = 0;
266             }
267             if (m_taskObserver)
268                 m_taskObserver->didProcessTask();
269         }
270
271         virtual void exitRunLoop() OVERRIDE { ASSERT_NOT_REACHED(); }
272
273     private:
274         TaskObserver* m_taskObserver;
275         Task* m_task;
276     };
277
278     class CurrentThreadPlatformMock : public Platform {
279     public:
280         CurrentThreadPlatformMock() { }
281         virtual void cryptographicallyRandomValues(unsigned char* buffer, size_t length) { ASSERT_NOT_REACHED(); }
282         virtual WebThread* currentThread() OVERRIDE { return &m_currentThread; }
283     private:
284         CurrentThreadMock m_currentThread;
285     };
286
287     CurrentThreadPlatformMock m_mockPlatform;
288     Platform* m_oldPlatform;
289 };
290
291
292 #define DEFINE_TEST_TASK_WRAPPER_CLASS(TEST_METHOD)                                               \
293 class TestWrapperTask_ ## TEST_METHOD : public WebThread::Task {                           \
294     public:                                                                                       \
295         TestWrapperTask_ ## TEST_METHOD(RecordingImageBufferSurfaceTest* test) : m_test(test) { } \
296         virtual void run() OVERRIDE { m_test->TEST_METHOD(); }                                    \
297     private:                                                                                      \
298         RecordingImageBufferSurfaceTest* m_test;                                                  \
299 };
300
301 #define CALL_TEST_TASK_WRAPPER(TEST_METHOD)                                                               \
302     {                                                                                                     \
303         AutoInstallCurrentThreadPlatformMock ctpm;                                                        \
304         Platform::current()->currentThread()->postTask(new TestWrapperTask_ ## TEST_METHOD(this)); \
305         Platform::current()->currentThread()->enterRunLoop();                                      \
306     }
307
308 TEST_F(RecordingImageBufferSurfaceTest, testEmptyPicture)
309 {
310     testEmptyPicture();
311 }
312
313 TEST_F(RecordingImageBufferSurfaceTest, testNoFallbackWithClear)
314 {
315     testNoFallbackWithClear();
316 }
317
318 DEFINE_TEST_TASK_WRAPPER_CLASS(testNonAnimatedCanvasUpdate)
319 TEST_F(RecordingImageBufferSurfaceTest, testNonAnimatedCanvasUpdate)
320 {
321     CALL_TEST_TASK_WRAPPER(testNonAnimatedCanvasUpdate)
322     expectDisplayListEnabled(true);
323 }
324
325 DEFINE_TEST_TASK_WRAPPER_CLASS(testAnimatedWithoutClear)
326 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithoutClear)
327 {
328     CALL_TEST_TASK_WRAPPER(testAnimatedWithoutClear)
329     expectDisplayListEnabled(false);
330 }
331
332 DEFINE_TEST_TASK_WRAPPER_CLASS(testFrameFinalizedByTaskObserver1)
333 DEFINE_TEST_TASK_WRAPPER_CLASS(testFrameFinalizedByTaskObserver2)
334 TEST_F(RecordingImageBufferSurfaceTest, testFrameFinalizedByTaskObserver)
335 {
336     CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver1)
337     expectDisplayListEnabled(false);
338     CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver2)
339     expectDisplayListEnabled(false);
340 }
341
342 DEFINE_TEST_TASK_WRAPPER_CLASS(testAnimatedWithClear)
343 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithClear)
344 {
345     CALL_TEST_TASK_WRAPPER(testAnimatedWithClear)
346     expectDisplayListEnabled(true);
347 }
348
349 DEFINE_TEST_TASK_WRAPPER_CLASS(testClearRect)
350 TEST_F(RecordingImageBufferSurfaceTest, testClearRect)
351 {
352     CALL_TEST_TASK_WRAPPER(testClearRect);
353     expectDisplayListEnabled(true);
354 }
355
356 } // namespace