| 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 |