OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "platform/graphics/RecordingImageBufferSurface.h" | 7 #include "platform/graphics/RecordingImageBufferSurface.h" |
8 | 8 |
9 #include "platform/graphics/GraphicsContext.h" | 9 #include "platform/graphics/GraphicsContext.h" |
10 #include "platform/graphics/ImageBuffer.h" | 10 #include "platform/graphics/ImageBuffer.h" |
| 11 #include "public/platform/Platform.h" |
| 12 #include "public/platform/WebThread.h" |
11 #include "third_party/skia/include/core/SkCanvas.h" | 13 #include "third_party/skia/include/core/SkCanvas.h" |
12 #include "third_party/skia/include/core/SkPictureRecorder.h" | 14 #include "third_party/skia/include/core/SkPictureRecorder.h" |
13 #include "wtf/OwnPtr.h" | 15 #include "wtf/OwnPtr.h" |
14 #include "wtf/PassOwnPtr.h" | 16 #include "wtf/PassOwnPtr.h" |
15 #include "wtf/RefPtr.h" | 17 #include "wtf/RefPtr.h" |
16 | 18 |
17 #include <gmock/gmock.h> | 19 #include <gmock/gmock.h> |
18 #include <gtest/gtest.h> | 20 #include <gtest/gtest.h> |
19 | 21 |
20 using namespace blink; | 22 using namespace blink; |
21 using testing::Test; | 23 using testing::Test; |
22 | 24 |
23 class RecordingImageBufferSurfaceTest : public Test { | 25 class RecordingImageBufferSurfaceTest : public Test { |
24 protected: | 26 protected: |
25 RecordingImageBufferSurfaceTest() | 27 RecordingImageBufferSurfaceTest() |
26 { | 28 { |
27 OwnPtr<RecordingImageBufferSurface> testSurface = adoptPtr(new Recording
ImageBufferSurface(IntSize(10, 10))); | 29 OwnPtr<RecordingImageBufferSurface> testSurface = adoptPtr(new Recording
ImageBufferSurface(IntSize(10, 10))); |
28 m_testSurface = testSurface.get(); | 30 m_testSurface = testSurface.get(); |
29 // We create an ImageBuffer in order for the testSurface to be | 31 // We create an ImageBuffer in order for the testSurface to be |
30 // properly initialized with a GraphicsContext | 32 // properly initialized with a GraphicsContext |
31 m_imageBuffer = ImageBuffer::create(testSurface.release()); | 33 m_imageBuffer = ImageBuffer::create(testSurface.release()); |
32 } | 34 } |
33 | 35 |
| 36 public: |
34 void testEmptyPicture() | 37 void testEmptyPicture() |
35 { | 38 { |
36 m_testSurface->initializeCurrentFrame(); | 39 m_testSurface->initializeCurrentFrame(); |
37 RefPtr<SkPicture> picture = m_testSurface->getPicture(); | 40 RefPtr<SkPicture> picture = m_testSurface->getPicture(); |
38 EXPECT_TRUE((bool)picture.get()); | 41 EXPECT_TRUE((bool)picture.get()); |
39 expectDisplayListEnabled(true); | 42 expectDisplayListEnabled(true); |
40 } | 43 } |
41 | 44 |
42 void testNoFallbackWithClear() | 45 void testNoFallbackWithClear() |
43 { | 46 { |
44 m_testSurface->initializeCurrentFrame(); | 47 m_testSurface->initializeCurrentFrame(); |
45 m_testSurface->didClearCanvas(); | 48 m_testSurface->didClearCanvas(); |
46 m_testSurface->getPicture(); | 49 m_testSurface->getPicture(); |
47 expectDisplayListEnabled(true); | 50 expectDisplayListEnabled(true); |
48 } | 51 } |
49 | 52 |
50 void testNonAnimatedCanvasUpdate() | 53 void testNonAnimatedCanvasUpdate() |
51 { | 54 { |
52 m_testSurface->initializeCurrentFrame(); | 55 m_testSurface->initializeCurrentFrame(); |
53 // acquire picture twice to simulate a static canvas: nothing drawn betw
een updates | 56 // acquire picture twice to simulate a static canvas: nothing drawn betw
een updates |
54 m_testSurface->getPicture(); | 57 m_testSurface->getPicture(); |
55 m_testSurface->getPicture(); | 58 m_testSurface->getPicture(); |
56 expectDisplayListEnabled(true); | 59 expectDisplayListEnabled(true); |
57 } | 60 } |
58 | 61 |
59 void testAnimatedWithoutClear() | 62 void testAnimatedWithoutClear() |
60 { | 63 { |
61 m_testSurface->initializeCurrentFrame(); | 64 m_testSurface->initializeCurrentFrame(); |
62 m_testSurface->getPicture(); | 65 m_testSurface->getPicture(); |
63 m_testSurface->willUse(); | 66 m_testSurface->didDraw(); |
64 expectDisplayListEnabled(true); | 67 expectDisplayListEnabled(true); |
65 // This will trigger fallback | 68 // This will trigger fallback |
66 m_testSurface->getPicture(); | 69 m_testSurface->getPicture(); |
67 expectDisplayListEnabled(false); | 70 expectDisplayListEnabled(false); |
68 } | 71 } |
69 | 72 |
| 73 void testFrameFinalizedByTaskObserver1() |
| 74 { |
| 75 m_testSurface->initializeCurrentFrame(); |
| 76 expectDisplayListEnabled(true); |
| 77 m_testSurface->getPicture(); |
| 78 expectDisplayListEnabled(true); |
| 79 m_testSurface->didDraw(); |
| 80 expectDisplayListEnabled(true); |
| 81 // Display list will be disabled only after exiting the runLoop |
| 82 } |
| 83 void testFrameFinalizedByTaskObserver2() |
| 84 { |
| 85 expectDisplayListEnabled(false); |
| 86 m_testSurface->getPicture(); |
| 87 expectDisplayListEnabled(false); |
| 88 m_testSurface->didDraw(); |
| 89 expectDisplayListEnabled(false); |
| 90 } |
| 91 |
70 void testAnimatedWithClear() | 92 void testAnimatedWithClear() |
71 { | 93 { |
72 m_testSurface->initializeCurrentFrame(); | 94 m_testSurface->initializeCurrentFrame(); |
73 m_testSurface->getPicture(); | 95 m_testSurface->getPicture(); |
74 m_testSurface->didClearCanvas(); | 96 m_testSurface->didClearCanvas(); |
75 m_testSurface->willUse(); | 97 m_testSurface->didDraw(); |
76 m_testSurface->getPicture(); | 98 m_testSurface->getPicture(); |
77 expectDisplayListEnabled(true); | 99 expectDisplayListEnabled(true); |
78 // clear after use | 100 // clear after use |
79 m_testSurface->willUse(); | 101 m_testSurface->didDraw(); |
80 m_testSurface->didClearCanvas(); | 102 m_testSurface->didClearCanvas(); |
81 m_testSurface->getPicture(); | 103 m_testSurface->getPicture(); |
82 expectDisplayListEnabled(true); | 104 expectDisplayListEnabled(true); |
83 } | 105 } |
84 | 106 |
85 void testClearRect() | 107 void testClearRect() |
86 { | 108 { |
87 m_testSurface->initializeCurrentFrame(); | 109 m_testSurface->initializeCurrentFrame(); |
88 m_testSurface->getPicture(); | 110 m_testSurface->getPicture(); |
89 m_imageBuffer->context()->clearRect(FloatRect(FloatPoint(0, 0), FloatSiz
e(m_testSurface->size()))); | 111 m_imageBuffer->context()->clearRect(FloatRect(FloatPoint(0, 0), FloatSiz
e(m_testSurface->size()))); |
90 m_testSurface->willUse(); | 112 m_testSurface->didDraw(); |
91 m_testSurface->getPicture(); | 113 m_testSurface->getPicture(); |
92 expectDisplayListEnabled(true); | 114 expectDisplayListEnabled(true); |
93 } | 115 } |
94 private: | 116 |
95 void expectDisplayListEnabled(bool displayListEnabled) | 117 void expectDisplayListEnabled(bool displayListEnabled) |
96 { | 118 { |
97 EXPECT_EQ(displayListEnabled, (bool)m_testSurface->m_currentFrame.get())
; | 119 EXPECT_EQ(displayListEnabled, (bool)m_testSurface->m_currentFrame.get())
; |
98 EXPECT_EQ(!displayListEnabled, (bool)m_testSurface->m_rasterCanvas.get()
); | 120 EXPECT_EQ(!displayListEnabled, (bool)m_testSurface->m_rasterCanvas.get()
); |
99 } | 121 } |
100 | 122 |
| 123 private: |
101 RecordingImageBufferSurface* m_testSurface; | 124 RecordingImageBufferSurface* m_testSurface; |
102 OwnPtr<ImageBuffer> m_imageBuffer; | 125 OwnPtr<ImageBuffer> m_imageBuffer; |
103 }; | 126 }; |
104 | 127 |
105 namespace { | 128 namespace { |
106 | 129 |
| 130 // The following test helper class installs a mock platform that provides a mock
WebThread |
| 131 // for the current thread. The Mock thread is capable of queuing a single non-de
layed task |
| 132 // and registering a single task observer. The run loop exits immediately after
running |
| 133 // the single task. |
| 134 class AutoInstallCurrentThreadPlatformMock { |
| 135 public: |
| 136 AutoInstallCurrentThreadPlatformMock() |
| 137 { |
| 138 m_oldPlatform = blink::Platform::current(); |
| 139 blink::Platform::initialize(&m_mockPlatform); |
| 140 } |
| 141 |
| 142 ~AutoInstallCurrentThreadPlatformMock() |
| 143 { |
| 144 blink::Platform::initialize(m_oldPlatform); |
| 145 } |
| 146 |
| 147 private: |
| 148 class CurrentThreadMock : public WebThread { |
| 149 public: |
| 150 CurrentThreadMock() : m_taskObserver(0), m_task(0) { } |
| 151 |
| 152 virtual ~CurrentThreadMock() |
| 153 { |
| 154 EXPECT_EQ((Task*)0, m_task); |
| 155 } |
| 156 |
| 157 virtual void postTask(Task* task) |
| 158 { |
| 159 EXPECT_EQ((Task*)0, m_task); |
| 160 m_task = task; |
| 161 } |
| 162 |
| 163 virtual void postDelayedTask(Task*, long long delayMs) OVERRIDE { ASSERT
_NOT_REACHED(); }; |
| 164 |
| 165 virtual bool isCurrentThread() const OVERRIDE { return true; } |
| 166 |
| 167 virtual void addTaskObserver(TaskObserver* taskObserver) OVERRIDE |
| 168 { |
| 169 EXPECT_EQ((TaskObserver*)0, m_taskObserver); |
| 170 m_taskObserver = taskObserver; |
| 171 } |
| 172 |
| 173 virtual void removeTaskObserver(TaskObserver* taskObserver) OVERRIDE |
| 174 { |
| 175 EXPECT_EQ(m_taskObserver, taskObserver); |
| 176 m_taskObserver = 0; |
| 177 } |
| 178 |
| 179 virtual void enterRunLoop() OVERRIDE |
| 180 { |
| 181 if (m_taskObserver) |
| 182 m_taskObserver->willProcessTask(); |
| 183 if (m_task) { |
| 184 m_task->run(); |
| 185 delete m_task; |
| 186 m_task = 0; |
| 187 } |
| 188 if (m_taskObserver) |
| 189 m_taskObserver->didProcessTask(); |
| 190 } |
| 191 |
| 192 virtual void exitRunLoop() OVERRIDE { ASSERT_NOT_REACHED(); } |
| 193 |
| 194 private: |
| 195 TaskObserver* m_taskObserver; |
| 196 Task* m_task; |
| 197 }; |
| 198 |
| 199 class CurrentThreadPlatformMock : public blink::Platform { |
| 200 public: |
| 201 CurrentThreadPlatformMock() { } |
| 202 virtual void cryptographicallyRandomValues(unsigned char* buffer, size_t
length) { ASSERT_NOT_REACHED(); } |
| 203 virtual WebThread* currentThread() OVERRIDE { return &m_currentThread; } |
| 204 private: |
| 205 CurrentThreadMock m_currentThread; |
| 206 }; |
| 207 |
| 208 CurrentThreadPlatformMock m_mockPlatform; |
| 209 blink::Platform* m_oldPlatform; |
| 210 }; |
| 211 |
| 212 |
| 213 #define DEFINE_TEST_TASK_WRAPPER_CLASS(TEST_METHOD)
\ |
| 214 class TestWrapperTask_ ## TEST_METHOD : public blink::WebThread::Task {
\ |
| 215 public:
\ |
| 216 TestWrapperTask_ ## TEST_METHOD(RecordingImageBufferSurfaceTest* test) :
m_test(test) { } \ |
| 217 virtual void run() OVERRIDE { m_test->TEST_METHOD(); }
\ |
| 218 private:
\ |
| 219 RecordingImageBufferSurfaceTest* m_test;
\ |
| 220 }; |
| 221 |
| 222 #define CALL_TEST_TASK_WRAPPER(TEST_METHOD)
\ |
| 223 {
\ |
| 224 AutoInstallCurrentThreadPlatformMock ctpm;
\ |
| 225 blink::Platform::current()->currentThread()->postTask(new TestWrapperTas
k_ ## TEST_METHOD(this)); \ |
| 226 blink::Platform::current()->currentThread()->enterRunLoop();
\ |
| 227 } |
| 228 |
107 TEST_F(RecordingImageBufferSurfaceTest, testEmptyPicture) | 229 TEST_F(RecordingImageBufferSurfaceTest, testEmptyPicture) |
108 { | 230 { |
109 testEmptyPicture(); | 231 testEmptyPicture(); |
110 } | 232 } |
111 | 233 |
112 TEST_F(RecordingImageBufferSurfaceTest, testNoFallbackWithClear) | 234 TEST_F(RecordingImageBufferSurfaceTest, testNoFallbackWithClear) |
113 { | 235 { |
114 testNoFallbackWithClear(); | 236 testNoFallbackWithClear(); |
115 } | 237 } |
116 | 238 |
117 TEST_F(RecordingImageBufferSurfaceTest, testNonAnimatedCanvasUpdate) | 239 TEST_F(RecordingImageBufferSurfaceTest, testNonAnimatedCanvasUpdate) |
118 { | 240 { |
119 testNonAnimatedCanvasUpdate(); | 241 testNonAnimatedCanvasUpdate(); |
120 } | 242 } |
121 | 243 |
| 244 DEFINE_TEST_TASK_WRAPPER_CLASS(testAnimatedWithoutClear) |
122 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithoutClear) | 245 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithoutClear) |
123 { | 246 { |
124 testAnimatedWithoutClear(); | 247 CALL_TEST_TASK_WRAPPER(testAnimatedWithoutClear) |
| 248 expectDisplayListEnabled(false); |
125 } | 249 } |
126 | 250 |
| 251 DEFINE_TEST_TASK_WRAPPER_CLASS(testFrameFinalizedByTaskObserver1) |
| 252 DEFINE_TEST_TASK_WRAPPER_CLASS(testFrameFinalizedByTaskObserver2) |
| 253 TEST_F(RecordingImageBufferSurfaceTest, testFrameFinalizedByTaskObserver) |
| 254 { |
| 255 CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver1) |
| 256 expectDisplayListEnabled(false); |
| 257 CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver2) |
| 258 expectDisplayListEnabled(false); |
| 259 } |
| 260 |
| 261 DEFINE_TEST_TASK_WRAPPER_CLASS(testAnimatedWithClear) |
127 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithClear) | 262 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithClear) |
128 { | 263 { |
129 testAnimatedWithClear(); | 264 CALL_TEST_TASK_WRAPPER(testAnimatedWithClear) |
| 265 expectDisplayListEnabled(true); |
130 } | 266 } |
131 | 267 |
| 268 DEFINE_TEST_TASK_WRAPPER_CLASS(testClearRect) |
132 TEST_F(RecordingImageBufferSurfaceTest, testClearRect) | 269 TEST_F(RecordingImageBufferSurfaceTest, testClearRect) |
133 { | 270 { |
134 testClearRect(); | 271 CALL_TEST_TASK_WRAPPER(testClearRect); |
| 272 expectDisplayListEnabled(true); |
135 } | 273 } |
136 | 274 |
137 } // namespace | 275 } // namespace |
OLD | NEW |