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

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

Issue 1812273003: Eliminate copies of encoded image data (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 12 matching lines...) Expand all
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "platform/graphics/ImageFrameGenerator.h" 26 #include "platform/graphics/ImageFrameGenerator.h"
27 27
28 #include "platform/SharedBuffer.h" 28 #include "platform/SharedBuffer.h"
29 #include "platform/Task.h" 29 #include "platform/Task.h"
30 #include "platform/ThreadSafeFunctional.h" 30 #include "platform/ThreadSafeFunctional.h"
31 #include "platform/graphics/ImageDecodingStore.h" 31 #include "platform/graphics/ImageDecodingStore.h"
32 #include "platform/graphics/test/MockImageDecoder.h" 32 #include "platform/graphics/test/MockImageDecoder.h"
33 #include "platform/image-decoders/SharedBufferSegmentReader.h"
33 #include "public/platform/Platform.h" 34 #include "public/platform/Platform.h"
34 #include "public/platform/WebThread.h" 35 #include "public/platform/WebThread.h"
35 #include "public/platform/WebTraceLocation.h" 36 #include "public/platform/WebTraceLocation.h"
36 #include "testing/gtest/include/gtest/gtest.h" 37 #include "testing/gtest/include/gtest/gtest.h"
37 38
38 namespace blink { 39 namespace blink {
39 40
40 namespace { 41 namespace {
41 42
42 // Helper methods to generate standard sizes. 43 // Helper methods to generate standard sizes.
43 SkISize fullSize() { return SkISize::Make(100, 100); } 44 SkISize fullSize() { return SkISize::Make(100, 100); }
44 45
45 SkImageInfo imageInfo() 46 SkImageInfo imageInfo()
46 { 47 {
47 return SkImageInfo::Make(100, 100, kBGRA_8888_SkColorType, kOpaque_SkAlphaTy pe); 48 return SkImageInfo::Make(100, 100, kBGRA_8888_SkColorType, kOpaque_SkAlphaTy pe);
48 } 49 }
49 50
50 } // namespace 51 } // namespace
51 52
52 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderC lient { 53 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderC lient {
53 public: 54 public:
54 void SetUp() override 55 void SetUp() override
55 { 56 {
56 ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024); 57 ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024);
58 m_generator = ImageFrameGenerator::create(fullSize(), false);
57 m_data = SharedBuffer::create(); 59 m_data = SharedBuffer::create();
58 m_generator = ImageFrameGenerator::create(fullSize(), m_data, false); 60 m_segmentReader = adoptRef(new SharedBufferSegmentReader(m_data));
59 useMockImageDecoderFactory(); 61 useMockImageDecoderFactory();
60 m_decodersDestroyed = 0; 62 m_decodersDestroyed = 0;
61 m_decodeRequestCount = 0; 63 m_decodeRequestCount = 0;
62 m_status = ImageFrame::FrameEmpty; 64 m_status = ImageFrame::FrameEmpty;
63 m_frameCount = 1; 65 m_frameCount = 1;
64 } 66 }
65 67
66 void TearDown() override 68 void TearDown() override
67 { 69 {
68 ImageDecodingStore::instance().clear(); 70 ImageDecodingStore::instance().clear();
(...skipping 19 matching lines...) Expand all
88 size_t frameCount() override { return m_frameCount; } 90 size_t frameCount() override { return m_frameCount; }
89 int repetitionCount() const override { return m_frameCount == 1 ? cAnimation None:cAnimationLoopOnce; } 91 int repetitionCount() const override { return m_frameCount == 1 ? cAnimation None:cAnimationLoopOnce; }
90 float frameDuration() const override { return 0; } 92 float frameDuration() const override { return 0; }
91 93
92 protected: 94 protected:
93 void useMockImageDecoderFactory() 95 void useMockImageDecoderFactory()
94 { 96 {
95 m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this , fullSize())); 97 m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this , fullSize()));
96 } 98 }
97 99
98 void addNewData(bool allDataReceived = false) 100 void addNewData()
99 { 101 {
100 m_data->append("g", 1); 102 m_data->append("g", 1);
101 m_generator->setData(m_data, allDataReceived);
102 } 103 }
103 104
104 void setFrameStatus(ImageFrame::Status status) { m_status = m_nextFrameStat us = status; } 105 void setFrameStatus(ImageFrame::Status status) { m_status = m_nextFrameStat us = status; }
105 void setNextFrameStatus(ImageFrame::Status status) { m_nextFrameStatus = st atus; } 106 void setNextFrameStatus(ImageFrame::Status status) { m_nextFrameStatus = st atus; }
106 void setFrameCount(size_t count) 107 void setFrameCount(size_t count)
107 { 108 {
108 m_frameCount = count; 109 m_frameCount = count;
109 if (count > 1) { 110 if (count > 1) {
110 m_generator.clear(); 111 m_generator.clear();
111 m_generator = ImageFrameGenerator::create(fullSize(), m_data, true, true); 112 m_generator = ImageFrameGenerator::create(fullSize(), true);
112 useMockImageDecoderFactory(); 113 useMockImageDecoderFactory();
113 } 114 }
114 } 115 }
115 116
116 RefPtr<SharedBuffer> m_data; 117 RefPtr<SharedBuffer> m_data;
118 RefPtr<SegmentReader> m_segmentReader;
117 RefPtr<ImageFrameGenerator> m_generator; 119 RefPtr<ImageFrameGenerator> m_generator;
118 int m_decodersDestroyed; 120 int m_decodersDestroyed;
119 int m_decodeRequestCount; 121 int m_decodeRequestCount;
120 ImageFrame::Status m_status; 122 ImageFrame::Status m_status;
121 ImageFrame::Status m_nextFrameStatus; 123 ImageFrame::Status m_nextFrameStatus;
122 size_t m_frameCount; 124 size_t m_frameCount;
123 }; 125 };
124 126
125 TEST_F(ImageFrameGeneratorTest, incompleteDecode) 127 TEST_F(ImageFrameGeneratorTest, incompleteDecode)
126 { 128 {
127 setFrameStatus(ImageFrame::FramePartial); 129 setFrameStatus(ImageFrame::FramePartial);
128 130
129 char buffer[100 * 100 * 4]; 131 char buffer[100 * 100 * 4];
130 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 132 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
131 EXPECT_EQ(1, m_decodeRequestCount); 133 EXPECT_EQ(1, m_decodeRequestCount);
132 134
133 addNewData(); 135 addNewData();
134 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 136 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
135 EXPECT_EQ(2, m_decodeRequestCount); 137 EXPECT_EQ(2, m_decodeRequestCount);
136 EXPECT_EQ(0, m_decodersDestroyed); 138 EXPECT_EQ(0, m_decodersDestroyed);
137 } 139 }
138 140
139 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete) 141 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete)
140 { 142 {
141 setFrameStatus(ImageFrame::FramePartial); 143 setFrameStatus(ImageFrame::FramePartial);
142 144
143 char buffer[100 * 100 * 4]; 145 char buffer[100 * 100 * 4];
144 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 146 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
145 EXPECT_EQ(1, m_decodeRequestCount); 147 EXPECT_EQ(1, m_decodeRequestCount);
146 EXPECT_EQ(0, m_decodersDestroyed); 148 EXPECT_EQ(0, m_decodersDestroyed);
147 149
148 setFrameStatus(ImageFrame::FrameComplete); 150 setFrameStatus(ImageFrame::FrameComplete);
149 addNewData(); 151 addNewData();
150 152
151 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 153 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
152 EXPECT_EQ(2, m_decodeRequestCount); 154 EXPECT_EQ(2, m_decodeRequestCount);
153 EXPECT_EQ(1, m_decodersDestroyed); 155 EXPECT_EQ(1, m_decodersDestroyed);
154 156
155 // Decoder created again. 157 // Decoder created again.
156 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 158 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
157 EXPECT_EQ(3, m_decodeRequestCount); 159 EXPECT_EQ(3, m_decodeRequestCount);
158 } 160 }
159 161
160 static void decodeThreadMain(ImageFrameGenerator* generator) 162 static void decodeThreadMain(ImageFrameGenerator* generator, SegmentReader* segm entReader)
161 { 163 {
162 char buffer[100 * 100 * 4]; 164 char buffer[100 * 100 * 4];
163 generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 165 generator->decodeAndScale(segmentReader, false, 0, imageInfo(), buffer, 100 * 4);
164 }
165
166 static void decodeThreadWithRefEncodedMain(ImageFrameGenerator* generator)
167 {
168 // Image must be complete - refEncodedData otherwise returns null.
169 char buffer[100 * 100 * 4];
170 SkData* data = generator->refEncodedData();
171 generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
172 data->unref();
173 } 166 }
174 167
175 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded) 168 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
176 { 169 {
177 setFrameStatus(ImageFrame::FramePartial); 170 setFrameStatus(ImageFrame::FramePartial);
178 171
179 char buffer[100 * 100 * 4]; 172 char buffer[100 * 100 * 4];
180 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 173 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
181 EXPECT_EQ(1, m_decodeRequestCount); 174 EXPECT_EQ(1, m_decodeRequestCount);
182 EXPECT_EQ(0, m_decodersDestroyed); 175 EXPECT_EQ(0, m_decodersDestroyed);
183 SkData* data = m_generator->refEncodedData();
184 EXPECT_EQ(nullptr, data);
185 176
186 // LocalFrame can now be decoded completely. 177 // LocalFrame can now be decoded completely.
187 setFrameStatus(ImageFrame::FrameComplete); 178 setFrameStatus(ImageFrame::FrameComplete);
188 addNewData(); 179 addNewData();
189 // addNewData is calling m_generator->setData with allDataReceived == false, which means that
190 // refEncodedData should return null.
191 data = m_generator->refEncodedData();
192 EXPECT_EQ(nullptr, data);
193 OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("Decod eThread")); 180 OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("Decod eThread"));
194 thread->taskRunner()->postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&dec odeThreadMain, AllowCrossThreadAccess(m_generator.get())))); 181 thread->taskRunner()->postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&dec odeThreadMain, AllowCrossThreadAccess(m_generator.get()), AllowCrossThreadAccess (m_segmentReader.get()))));
195 thread.clear(); 182 thread.clear();
196 EXPECT_EQ(2, m_decodeRequestCount); 183 EXPECT_EQ(2, m_decodeRequestCount);
197 EXPECT_EQ(1, m_decodersDestroyed); 184 EXPECT_EQ(1, m_decodersDestroyed);
198 185
199 // Decoder created again. 186 // Decoder created again.
200 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 187 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
201 EXPECT_EQ(3, m_decodeRequestCount); 188 EXPECT_EQ(3, m_decodeRequestCount);
202 189
203 addNewData(true); 190 addNewData();
204 data = m_generator->refEncodedData();
205 ASSERT_TRUE(data);
206 // To prevent data writting, SkData::unique() should be false.
207 ASSERT_TRUE(!data->unique());
208 191
209 // Thread will also ref and unref the data. 192 // Delete generator
Peter Kasting 2016/03/23 02:42:58 Nit: Period
scroggo_chromium 2016/03/24 13:59:45 Done.
210 thread = adoptPtr(Platform::current()->createThread("RefEncodedDataThread")) ;
211 thread->taskRunner()->postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&dec odeThreadWithRefEncodedMain, AllowCrossThreadAccess(m_generator.get()))));
212 thread.clear();
213 EXPECT_EQ(4, m_decodeRequestCount);
214
215 data->unref();
216 // m_generator is holding the only reference to SkData now.
217 ASSERT_TRUE(data->unique());
218
219 data = m_generator->refEncodedData();
220 ASSERT_TRUE(data && !data->unique());
221
222 // Delete generator, and SkData should have the only reference.
223 m_generator = nullptr; 193 m_generator = nullptr;
224 ASSERT_TRUE(data->unique());
225 data->unref();
226 } 194 }
227 195
228 TEST_F(ImageFrameGeneratorTest, frameHasAlpha) 196 TEST_F(ImageFrameGeneratorTest, frameHasAlpha)
229 { 197 {
230 setFrameStatus(ImageFrame::FramePartial); 198 setFrameStatus(ImageFrame::FramePartial);
231 199
232 char buffer[100 * 100 * 4]; 200 char buffer[100 * 100 * 4];
233 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 201 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
234 EXPECT_TRUE(m_generator->hasAlpha(0)); 202 EXPECT_TRUE(m_generator->hasAlpha(0));
235 EXPECT_EQ(1, m_decodeRequestCount); 203 EXPECT_EQ(1, m_decodeRequestCount);
236 204
237 ImageDecoder* tempDecoder = 0; 205 ImageDecoder* tempDecoder = 0;
238 EXPECT_TRUE(ImageDecodingStore::instance().lockDecoder(m_generator.get(), fu llSize(), &tempDecoder)); 206 EXPECT_TRUE(ImageDecodingStore::instance().lockDecoder(m_generator.get(), fu llSize(), &tempDecoder));
239 ASSERT_TRUE(tempDecoder); 207 ASSERT_TRUE(tempDecoder);
240 tempDecoder->frameBufferAtIndex(0)->setHasAlpha(false); 208 tempDecoder->frameBufferAtIndex(0)->setHasAlpha(false);
241 ImageDecodingStore::instance().unlockDecoder(m_generator.get(), tempDecoder) ; 209 ImageDecodingStore::instance().unlockDecoder(m_generator.get(), tempDecoder) ;
242 EXPECT_EQ(2, m_decodeRequestCount); 210 EXPECT_EQ(2, m_decodeRequestCount);
243 211
244 setFrameStatus(ImageFrame::FrameComplete); 212 setFrameStatus(ImageFrame::FrameComplete);
245 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 213 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4);
246 EXPECT_EQ(3, m_decodeRequestCount); 214 EXPECT_EQ(3, m_decodeRequestCount);
247 EXPECT_FALSE(m_generator->hasAlpha(0)); 215 EXPECT_FALSE(m_generator->hasAlpha(0));
248 } 216 }
249 217
250 TEST_F(ImageFrameGeneratorTest, removeMultiFrameDecoder) 218 TEST_F(ImageFrameGeneratorTest, removeMultiFrameDecoder)
251 { 219 {
252 setFrameCount(3); 220 setFrameCount(3);
253 setFrameStatus(ImageFrame::FrameComplete); 221 setFrameStatus(ImageFrame::FrameComplete);
254 222
255 char buffer[100 * 100 * 4]; 223 char buffer[100 * 100 * 4];
256 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4); 224 m_generator->decodeAndScale(m_segmentReader.get(), true, 0, imageInfo(), buf fer, 100 * 4);
257 EXPECT_EQ(1, m_decodeRequestCount); 225 EXPECT_EQ(1, m_decodeRequestCount);
258 EXPECT_EQ(0, m_decodersDestroyed); 226 EXPECT_EQ(0, m_decodersDestroyed);
259 227
260 setFrameStatus(ImageFrame::FrameComplete); 228 setFrameStatus(ImageFrame::FrameComplete);
261 229
262 m_generator->decodeAndScale(1, imageInfo(), buffer, 100 * 4); 230 m_generator->decodeAndScale(m_segmentReader.get(), true, 1, imageInfo(), buf fer, 100 * 4);
263 EXPECT_EQ(2, m_decodeRequestCount); 231 EXPECT_EQ(2, m_decodeRequestCount);
264 EXPECT_EQ(0, m_decodersDestroyed); 232 EXPECT_EQ(0, m_decodersDestroyed);
265 233
266 setFrameStatus(ImageFrame::FrameComplete); 234 setFrameStatus(ImageFrame::FrameComplete);
267 235
268 // Multi frame decoder should be removed. 236 // Multi frame decoder should be removed.
269 m_generator->decodeAndScale(2, imageInfo(), buffer, 100 * 4); 237 m_generator->decodeAndScale(m_segmentReader.get(), true, 2, imageInfo(), buf fer, 100 * 4);
270 EXPECT_EQ(3, m_decodeRequestCount); 238 EXPECT_EQ(3, m_decodeRequestCount);
271 EXPECT_EQ(1, m_decodersDestroyed); 239 EXPECT_EQ(1, m_decodersDestroyed);
272 } 240 }
273 241
274 } // namespace blink 242 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698