Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp

Issue 2653933003: Make stream captures work on canvases that are not in the DOM. (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "platform/graphics/RecordingImageBufferSurface.h" 5 #include "platform/graphics/RecordingImageBufferSurface.h"
6 6
7 #include "platform/WebTaskRunner.h" 7 #include "platform/WebTaskRunner.h"
8 #include "platform/graphics/GraphicsContext.h" 8 #include "platform/graphics/GraphicsContext.h"
9 #include "platform/graphics/ImageBuffer.h" 9 #include "platform/graphics/ImageBuffer.h"
10 #include "platform/graphics/ImageBufferClient.h" 10 #include "platform/graphics/ImageBufferClient.h"
11 #include "platform/graphics/UnacceleratedImageBufferSurface.h" 11 #include "platform/graphics/UnacceleratedImageBufferSurface.h"
12 #include "platform/graphics/paint/PaintCanvas.h" 12 #include "platform/graphics/paint/PaintCanvas.h"
13 #include "platform/graphics/paint/PaintRecord.h" 13 #include "platform/graphics/paint/PaintRecord.h"
14 #include "platform/testing/TestingPlatformSupport.h" 14 #include "platform/testing/TestingPlatformSupport.h"
15 #include "public/platform/Platform.h" 15 #include "public/platform/Platform.h"
16 #include "public/platform/WebThread.h" 16 #include "public/platform/WebThread.h"
17 #include "public/platform/WebTraceLocation.h" 17 #include "public/platform/WebTraceLocation.h"
18 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "wtf/PtrUtil.h" 20 #include "wtf/PtrUtil.h"
21 #include "wtf/RefPtr.h" 21 #include "wtf/RefPtr.h"
22 #include <memory> 22 #include <memory>
23 23
24 using testing::Test; 24 using testing::Test;
25 25
26 namespace blink { 26 namespace blink {
27 27
28 class FakeImageBufferClient : public ImageBufferClient,
29 public WebThread::TaskObserver {
30 public:
31 FakeImageBufferClient(ImageBuffer* imageBuffer)
32 : m_isDirty(false), m_imageBuffer(imageBuffer), m_frameCount(0) {}
33
34 ~FakeImageBufferClient() override {}
35
36 // ImageBufferClient implementation
37 void notifySurfaceInvalid() override {}
38 bool isDirty() override { return m_isDirty; }
39 void didDisableAcceleration() override {}
40 void didFinalizeFrame() override {
41 if (m_isDirty) {
42 Platform::current()->currentThread()->removeTaskObserver(this);
43 m_isDirty = false;
44 }
45 ++m_frameCount;
46 }
47
48 // TaskObserver implementation
49 void willProcessTask() override { NOTREACHED(); }
50 void didProcessTask() override {
51 ASSERT_TRUE(m_isDirty);
52 FloatRect dirtyRect(0, 0, 1, 1);
53 m_imageBuffer->finalizeFrame(dirtyRect);
54 ASSERT_FALSE(m_isDirty);
55 }
56 void restoreCanvasMatrixClipStack(PaintCanvas*) const override {}
57
58 void fakeDraw() {
59 if (m_isDirty)
60 return;
61 m_isDirty = true;
62 Platform::current()->currentThread()->addTaskObserver(this);
63 }
64
65 int frameCount() { return m_frameCount; }
66
67 private:
68 bool m_isDirty;
69 ImageBuffer* m_imageBuffer;
70 int m_frameCount;
71 };
72
73 class MockSurfaceFactory : public RecordingImageBufferFallbackSurfaceFactory { 28 class MockSurfaceFactory : public RecordingImageBufferFallbackSurfaceFactory {
74 public: 29 public:
75 MockSurfaceFactory() : m_createSurfaceCount(0) {} 30 MockSurfaceFactory() : m_createSurfaceCount(0) {}
76 31
77 virtual std::unique_ptr<ImageBufferSurface> createSurface( 32 virtual std::unique_ptr<ImageBufferSurface> createSurface(
78 const IntSize& size, 33 const IntSize& size,
79 OpacityMode opacityMode, 34 OpacityMode opacityMode,
80 sk_sp<SkColorSpace> colorSpace, 35 sk_sp<SkColorSpace> colorSpace,
81 SkColorType colorType) { 36 SkColorType colorType) {
82 m_createSurfaceCount++; 37 m_createSurfaceCount++;
(...skipping 17 matching lines...) Expand all
100 WTF::makeUnique<MockSurfaceFactory>(); 55 WTF::makeUnique<MockSurfaceFactory>();
101 m_surfaceFactory = surfaceFactory.get(); 56 m_surfaceFactory = surfaceFactory.get();
102 std::unique_ptr<RecordingImageBufferSurface> testSurface = 57 std::unique_ptr<RecordingImageBufferSurface> testSurface =
103 WTF::wrapUnique(new RecordingImageBufferSurface( 58 WTF::wrapUnique(new RecordingImageBufferSurface(
104 IntSize(10, 10), std::move(surfaceFactory), NonOpaque, nullptr)); 59 IntSize(10, 10), std::move(surfaceFactory), NonOpaque, nullptr));
105 m_testSurface = testSurface.get(); 60 m_testSurface = testSurface.get();
106 // We create an ImageBuffer in order for the testSurface to be 61 // We create an ImageBuffer in order for the testSurface to be
107 // properly initialized with a GraphicsContext 62 // properly initialized with a GraphicsContext
108 m_imageBuffer = ImageBuffer::create(std::move(testSurface)); 63 m_imageBuffer = ImageBuffer::create(std::move(testSurface));
109 EXPECT_FALSE(!m_imageBuffer); 64 EXPECT_FALSE(!m_imageBuffer);
110 m_fakeImageBufferClient = 65 m_testSurface->initializeCurrentFrame();
111 WTF::wrapUnique(new FakeImageBufferClient(m_imageBuffer.get()));
112 m_imageBuffer->setClient(m_fakeImageBufferClient.get());
113 } 66 }
114 67
115 public: 68 public:
116 void testEmptyRecord() { 69 RecordingImageBufferSurface* testSurface() { return m_testSurface; }
117 m_testSurface->initializeCurrentFrame(); 70 int createSurfaceCount() { return m_surfaceFactory->createSurfaceCount(); }
118 sk_sp<PaintRecord> record = m_testSurface->getRecord(); 71 SkCanvas* canvas() { return m_imageBuffer->canvas(); }
119 EXPECT_TRUE((bool)record.get());
120 EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
121 expectDisplayListEnabled(true);
122 }
123
124 void testNoFallbackWithClear() {
125 m_testSurface->initializeCurrentFrame();
126 m_testSurface->willOverwriteCanvas();
127 m_testSurface->getRecord();
128 EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
129 expectDisplayListEnabled(true);
130 }
131
132 void testNonAnimatedCanvasUpdate() {
133 m_testSurface->initializeCurrentFrame();
134 // Acquire record twice to simulate a static canvas: nothing drawn between
135 // updates.
136 m_fakeImageBufferClient->fakeDraw();
137 m_testSurface->getRecord();
138 m_testSurface->getRecord();
139 EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
140 expectDisplayListEnabled(true);
141 }
142
143 void testAnimatedWithoutClear() {
144 m_testSurface->initializeCurrentFrame();
145 m_fakeImageBufferClient->fakeDraw();
146 m_testSurface->getRecord();
147 EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
148 EXPECT_EQ(0, m_surfaceFactory->createSurfaceCount());
149 expectDisplayListEnabled(true); // first frame has an implicit clear
150 m_fakeImageBufferClient->fakeDraw();
151 m_testSurface->getRecord();
152 EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
153 expectDisplayListEnabled(false);
154 }
155
156 void testFrameFinalizedByTaskObserver1() {
157 m_testSurface->initializeCurrentFrame();
158 expectDisplayListEnabled(true);
159 m_testSurface->getRecord();
160 EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
161 expectDisplayListEnabled(true);
162 m_fakeImageBufferClient->fakeDraw();
163 EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
164 expectDisplayListEnabled(true);
165 m_testSurface->getRecord();
166 EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
167 expectDisplayListEnabled(true);
168 m_fakeImageBufferClient->fakeDraw();
169 EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
170 expectDisplayListEnabled(true);
171 // Display list will be disabled only after exiting the runLoop
172 }
173 void testFrameFinalizedByTaskObserver2() {
174 EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
175 expectDisplayListEnabled(false);
176 m_testSurface->getRecord();
177 EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
178 expectDisplayListEnabled(false);
179 m_fakeImageBufferClient->fakeDraw();
180 EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
181 expectDisplayListEnabled(false);
182 }
183
184 void testAnimatedWithClear() {
185 m_testSurface->initializeCurrentFrame();
186 m_testSurface->getRecord();
187 m_testSurface->willOverwriteCanvas();
188 m_fakeImageBufferClient->fakeDraw();
189 EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
190 m_testSurface->getRecord();
191 EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
192 expectDisplayListEnabled(true);
193 // clear after use
194 m_fakeImageBufferClient->fakeDraw();
195 m_testSurface->willOverwriteCanvas();
196 EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
197 m_testSurface->getRecord();
198 EXPECT_EQ(3, m_fakeImageBufferClient->frameCount());
199 expectDisplayListEnabled(true);
200 }
201
202 void testClearRect() {
203 m_testSurface->initializeCurrentFrame();
204 m_testSurface->getRecord();
205 PaintFlags clearPaint;
206 clearPaint.setBlendMode(SkBlendMode::kClear);
207 m_imageBuffer->canvas()->drawRect(
208 SkRect::MakeWH(m_testSurface->size().width(),
209 m_testSurface->size().height()),
210 clearPaint);
211 m_fakeImageBufferClient->fakeDraw();
212 EXPECT_EQ(1, m_fakeImageBufferClient->frameCount());
213 m_testSurface->getRecord();
214 EXPECT_EQ(2, m_fakeImageBufferClient->frameCount());
215 expectDisplayListEnabled(true);
216 }
217 72
218 void expectDisplayListEnabled(bool displayListEnabled) { 73 void expectDisplayListEnabled(bool displayListEnabled) {
219 EXPECT_EQ(displayListEnabled, (bool)m_testSurface->m_currentFrame.get()); 74 EXPECT_EQ(displayListEnabled, (bool)m_testSurface->m_currentFrame.get());
220 EXPECT_EQ(!displayListEnabled, 75 EXPECT_EQ(!displayListEnabled,
221 (bool)m_testSurface->m_fallbackSurface.get()); 76 (bool)m_testSurface->m_fallbackSurface.get());
222 int expectedSurfaceCreationCount = displayListEnabled ? 0 : 1; 77 int expectedSurfaceCreationCount = displayListEnabled ? 0 : 1;
223 EXPECT_EQ(expectedSurfaceCreationCount, 78 EXPECT_EQ(expectedSurfaceCreationCount,
224 m_surfaceFactory->createSurfaceCount()); 79 m_surfaceFactory->createSurfaceCount());
225 } 80 }
226 81
227 private: 82 private:
228 MockSurfaceFactory* m_surfaceFactory; 83 MockSurfaceFactory* m_surfaceFactory;
229 RecordingImageBufferSurface* m_testSurface; 84 RecordingImageBufferSurface* m_testSurface;
230 std::unique_ptr<FakeImageBufferClient> m_fakeImageBufferClient;
231 std::unique_ptr<ImageBuffer> m_imageBuffer; 85 std::unique_ptr<ImageBuffer> m_imageBuffer;
232 }; 86 };
233 87
234 #define CALL_TEST_TASK_WRAPPER(TEST_METHOD) \ 88 TEST_F(RecordingImageBufferSurfaceTest, testEmptyPicture) {
235 { \ 89 sk_sp<SkPicture> picture = testSurface()->getRecord();
236 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> \ 90 EXPECT_TRUE((bool)picture.get());
237 platform; \ 91 expectDisplayListEnabled(true);
238 Platform::current()->currentThread()->getWebTaskRunner()->postTask( \
239 BLINK_FROM_HERE, \
240 WTF::bind(&RecordingImageBufferSurfaceTest::TEST_METHOD, \
241 WTF::unretained(this))); \
242 platform->runUntilIdle(); \
243 }
244
245 TEST_F(RecordingImageBufferSurfaceTest, testEmptyRecord) {
246 testEmptyRecord();
247 } 92 }
248 93
249 TEST_F(RecordingImageBufferSurfaceTest, testNoFallbackWithClear) { 94 TEST_F(RecordingImageBufferSurfaceTest, testNoFallbackWithClear) {
250 testNoFallbackWithClear(); 95 testSurface()->willOverwriteCanvas();
96 testSurface()->getRecord();
97 expectDisplayListEnabled(true);
251 } 98 }
252 99
253 TEST_F(RecordingImageBufferSurfaceTest, testNonAnimatedCanvasUpdate) { 100 TEST_F(RecordingImageBufferSurfaceTest, testNonAnimatedCanvasUpdate) {
254 CALL_TEST_TASK_WRAPPER(testNonAnimatedCanvasUpdate) 101 // Acquire picture twice to simulate a static canvas: nothing drawn between
102 // updates.
103 testSurface()->didDraw(FloatRect(0, 0, 1, 1));
104 testSurface()->getRecord();
105 testSurface()->getRecord();
255 expectDisplayListEnabled(true); 106 expectDisplayListEnabled(true);
256 } 107 }
257 108
258 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithoutClear) { 109 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithoutClear) {
259 CALL_TEST_TASK_WRAPPER(testAnimatedWithoutClear) 110 testSurface()->didDraw(FloatRect(0, 0, 1, 1));
260 expectDisplayListEnabled(false); 111 testSurface()->getRecord();
261 } 112 EXPECT_EQ(0, createSurfaceCount());
262 113 expectDisplayListEnabled(true); // first frame has an implicit clear
263 TEST_F(RecordingImageBufferSurfaceTest, testFrameFinalizedByTaskObserver) { 114 testSurface()->didDraw(FloatRect(0, 0, 1, 1));
264 CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver1) 115 testSurface()->getRecord();
265 expectDisplayListEnabled(false);
266 CALL_TEST_TASK_WRAPPER(testFrameFinalizedByTaskObserver2)
267 expectDisplayListEnabled(false); 116 expectDisplayListEnabled(false);
268 } 117 }
269 118
270 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithClear) { 119 TEST_F(RecordingImageBufferSurfaceTest, testAnimatedWithClear) {
271 CALL_TEST_TASK_WRAPPER(testAnimatedWithClear) 120 testSurface()->getRecord();
121 testSurface()->willOverwriteCanvas();
122 testSurface()->didDraw(FloatRect(0, 0, 1, 1));
123 testSurface()->getRecord();
124 expectDisplayListEnabled(true);
125 // clear after use
126 testSurface()->didDraw(FloatRect(0, 0, 1, 1));
127 testSurface()->willOverwriteCanvas();
128 testSurface()->getRecord();
272 expectDisplayListEnabled(true); 129 expectDisplayListEnabled(true);
273 } 130 }
274 131
275 TEST_F(RecordingImageBufferSurfaceTest, testClearRect) { 132 TEST_F(RecordingImageBufferSurfaceTest, testClearRect) {
276 CALL_TEST_TASK_WRAPPER(testClearRect); 133 testSurface()->getRecord();
134 SkPaint clearPaint;
135 clearPaint.setBlendMode(SkBlendMode::kClear);
136 canvas()->drawRect(SkRect::MakeWH(testSurface()->size().width(),
137 testSurface()->size().height()),
138 clearPaint);
139 testSurface()->didDraw(FloatRect(0, 0, 1, 1));
140 testSurface()->getRecord();
277 expectDisplayListEnabled(true); 141 expectDisplayListEnabled(true);
278 } 142 }
279 143
280 } // namespace blink 144 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698