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

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

Issue 1866243003: Revert of Eliminate copies of encoded image data (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 11 matching lines...) Expand all
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
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/ThreadSafeFunctional.h" 29 #include "platform/ThreadSafeFunctional.h"
30 #include "platform/graphics/ImageDecodingStore.h" 30 #include "platform/graphics/ImageDecodingStore.h"
31 #include "platform/graphics/test/MockImageDecoder.h" 31 #include "platform/graphics/test/MockImageDecoder.h"
32 #include "platform/image-decoders/SegmentReader.h"
33 #include "public/platform/Platform.h" 32 #include "public/platform/Platform.h"
34 #include "public/platform/WebTaskRunner.h" 33 #include "public/platform/WebTaskRunner.h"
35 #include "public/platform/WebThread.h" 34 #include "public/platform/WebThread.h"
36 #include "public/platform/WebTraceLocation.h" 35 #include "public/platform/WebTraceLocation.h"
37 #include "testing/gtest/include/gtest/gtest.h" 36 #include "testing/gtest/include/gtest/gtest.h"
38 37
39 namespace blink { 38 namespace blink {
40 39
41 namespace { 40 namespace {
42 41
43 // Helper methods to generate standard sizes. 42 // Helper methods to generate standard sizes.
44 SkISize fullSize() { return SkISize::Make(100, 100); } 43 SkISize fullSize() { return SkISize::Make(100, 100); }
45 44
46 SkImageInfo imageInfo() 45 SkImageInfo imageInfo()
47 { 46 {
48 return SkImageInfo::Make(100, 100, kBGRA_8888_SkColorType, kOpaque_SkAlphaTy pe); 47 return SkImageInfo::Make(100, 100, kBGRA_8888_SkColorType, kOpaque_SkAlphaTy pe);
49 } 48 }
50 49
51 } // namespace 50 } // namespace
52 51
53 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderC lient { 52 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderC lient {
54 public: 53 public:
55 void SetUp() override 54 void SetUp() override
56 { 55 {
57 ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024); 56 ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024);
58 m_generator = ImageFrameGenerator::create(fullSize(), false);
59 m_data = SharedBuffer::create(); 57 m_data = SharedBuffer::create();
60 m_segmentReader = SegmentReader::createFromSharedBuffer(m_data); 58 m_generator = ImageFrameGenerator::create(fullSize(), m_data, false);
61 useMockImageDecoderFactory(); 59 useMockImageDecoderFactory();
62 m_decodersDestroyed = 0; 60 m_decodersDestroyed = 0;
63 m_decodeRequestCount = 0; 61 m_decodeRequestCount = 0;
64 m_status = ImageFrame::FrameEmpty; 62 m_status = ImageFrame::FrameEmpty;
65 m_frameCount = 1; 63 m_frameCount = 1;
66 m_requestedClearExceptFrame = kNotFound; 64 m_requestedClearExceptFrame = kNotFound;
67 } 65 }
68 66
69 void TearDown() override 67 void TearDown() override
70 { 68 {
(...skipping 25 matching lines...) Expand all
96 size_t frameCount() override { return m_frameCount; } 94 size_t frameCount() override { return m_frameCount; }
97 int repetitionCount() const override { return m_frameCount == 1 ? cAnimation None:cAnimationLoopOnce; } 95 int repetitionCount() const override { return m_frameCount == 1 ? cAnimation None:cAnimationLoopOnce; }
98 float frameDuration() const override { return 0; } 96 float frameDuration() const override { return 0; }
99 97
100 protected: 98 protected:
101 void useMockImageDecoderFactory() 99 void useMockImageDecoderFactory()
102 { 100 {
103 m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this , fullSize())); 101 m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this , fullSize()));
104 } 102 }
105 103
106 void addNewData() 104 void addNewData(bool allDataReceived = false)
107 { 105 {
108 m_data->append("g", 1u); 106 m_data->append("g", 1u);
107 m_generator->setData(m_data, allDataReceived);
109 } 108 }
110 109
111 void setFrameStatus(ImageFrame::Status status) { m_status = m_nextFrameStat us = status; } 110 void setFrameStatus(ImageFrame::Status status) { m_status = m_nextFrameStat us = status; }
112 void setNextFrameStatus(ImageFrame::Status status) { m_nextFrameStatus = st atus; } 111 void setNextFrameStatus(ImageFrame::Status status) { m_nextFrameStatus = st atus; }
113 void setFrameCount(size_t count) 112 void setFrameCount(size_t count)
114 { 113 {
115 m_frameCount = count; 114 m_frameCount = count;
116 if (count > 1) { 115 if (count > 1) {
117 m_generator.clear(); 116 m_generator.clear();
118 m_generator = ImageFrameGenerator::create(fullSize(), true); 117 m_generator = ImageFrameGenerator::create(fullSize(), m_data, true, true);
119 useMockImageDecoderFactory(); 118 useMockImageDecoderFactory();
120 } 119 }
121 } 120 }
122 121
123 RefPtr<SharedBuffer> m_data; 122 RefPtr<SharedBuffer> m_data;
124 RefPtr<SegmentReader> m_segmentReader;
125 RefPtr<ImageFrameGenerator> m_generator; 123 RefPtr<ImageFrameGenerator> m_generator;
126 int m_decodersDestroyed; 124 int m_decodersDestroyed;
127 int m_decodeRequestCount; 125 int m_decodeRequestCount;
128 ImageFrame::Status m_status; 126 ImageFrame::Status m_status;
129 ImageFrame::Status m_nextFrameStatus; 127 ImageFrame::Status m_nextFrameStatus;
130 size_t m_frameCount; 128 size_t m_frameCount;
131 size_t m_requestedClearExceptFrame; 129 size_t m_requestedClearExceptFrame;
132 }; 130 };
133 131
134 TEST_F(ImageFrameGeneratorTest, incompleteDecode) 132 TEST_F(ImageFrameGeneratorTest, incompleteDecode)
135 { 133 {
136 setFrameStatus(ImageFrame::FramePartial); 134 setFrameStatus(ImageFrame::FramePartial);
137 135
138 char buffer[100 * 100 * 4]; 136 char buffer[100 * 100 * 4];
139 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 137 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
140 EXPECT_EQ(1, m_decodeRequestCount); 138 EXPECT_EQ(1, m_decodeRequestCount);
141 139
142 addNewData(); 140 addNewData();
143 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 141 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
144 EXPECT_EQ(2, m_decodeRequestCount); 142 EXPECT_EQ(2, m_decodeRequestCount);
145 EXPECT_EQ(0, m_decodersDestroyed); 143 EXPECT_EQ(0, m_decodersDestroyed);
146 } 144 }
147 145
148 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete) 146 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete)
149 { 147 {
150 setFrameStatus(ImageFrame::FramePartial); 148 setFrameStatus(ImageFrame::FramePartial);
151 149
152 char buffer[100 * 100 * 4]; 150 char buffer[100 * 100 * 4];
153 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 151 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
154 EXPECT_EQ(1, m_decodeRequestCount); 152 EXPECT_EQ(1, m_decodeRequestCount);
155 EXPECT_EQ(0, m_decodersDestroyed); 153 EXPECT_EQ(0, m_decodersDestroyed);
156 154
157 setFrameStatus(ImageFrame::FrameComplete); 155 setFrameStatus(ImageFrame::FrameComplete);
158 addNewData(); 156 addNewData();
159 157
160 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 158 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
161 EXPECT_EQ(2, m_decodeRequestCount); 159 EXPECT_EQ(2, m_decodeRequestCount);
162 EXPECT_EQ(1, m_decodersDestroyed); 160 EXPECT_EQ(1, m_decodersDestroyed);
163 161
164 // Decoder created again. 162 // Decoder created again.
165 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 163 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
166 EXPECT_EQ(3, m_decodeRequestCount); 164 EXPECT_EQ(3, m_decodeRequestCount);
167 } 165 }
168 166
169 static void decodeThreadMain(ImageFrameGenerator* generator, SegmentReader* segm entReader) 167 static void decodeThreadMain(ImageFrameGenerator* generator)
170 { 168 {
171 char buffer[100 * 100 * 4]; 169 char buffer[100 * 100 * 4];
172 generator->decodeAndScale(segmentReader, false, 0, imageInfo(), buffer, 100 * 4); 170 generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
171 }
172
173 static void decodeThreadWithRefEncodedMain(ImageFrameGenerator* generator)
174 {
175 // Image must be complete - refEncodedData otherwise returns null.
176 char buffer[100 * 100 * 4];
177 SkData* data = generator->refEncodedData();
178 generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
179 data->unref();
173 } 180 }
174 181
175 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded) 182 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
176 { 183 {
177 setFrameStatus(ImageFrame::FramePartial); 184 setFrameStatus(ImageFrame::FramePartial);
178 185
179 char buffer[100 * 100 * 4]; 186 char buffer[100 * 100 * 4];
180 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 187 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
181 EXPECT_EQ(1, m_decodeRequestCount); 188 EXPECT_EQ(1, m_decodeRequestCount);
182 EXPECT_EQ(0, m_decodersDestroyed); 189 EXPECT_EQ(0, m_decodersDestroyed);
190 SkData* data = m_generator->refEncodedData();
191 EXPECT_EQ(nullptr, data);
183 192
184 // LocalFrame can now be decoded completely. 193 // LocalFrame can now be decoded completely.
185 setFrameStatus(ImageFrame::FrameComplete); 194 setFrameStatus(ImageFrame::FrameComplete);
186 addNewData(); 195 addNewData();
196 // addNewData is calling m_generator->setData with allDataReceived == false, which means that
197 // refEncodedData should return null.
198 data = m_generator->refEncodedData();
199 EXPECT_EQ(nullptr, data);
187 OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("Decod eThread")); 200 OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("Decod eThread"));
188 thread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(&decode ThreadMain, AllowCrossThreadAccess(m_generator.get()), AllowCrossThreadAccess(m_ segmentReader.get()))); 201 thread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(&decode ThreadMain, AllowCrossThreadAccess(m_generator.get())));
189 thread.clear(); 202 thread.clear();
190 EXPECT_EQ(2, m_decodeRequestCount); 203 EXPECT_EQ(2, m_decodeRequestCount);
191 EXPECT_EQ(1, m_decodersDestroyed); 204 EXPECT_EQ(1, m_decodersDestroyed);
192 205
193 // Decoder created again. 206 // Decoder created again.
194 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 207 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
195 EXPECT_EQ(3, m_decodeRequestCount); 208 EXPECT_EQ(3, m_decodeRequestCount);
196 209
197 addNewData(); 210 addNewData(true);
211 data = m_generator->refEncodedData();
212 ASSERT_TRUE(data);
213 // To prevent data writting, SkData::unique() should be false.
214 ASSERT_TRUE(!data->unique());
198 215
199 // Delete generator. 216 // Thread will also ref and unref the data.
217 thread = adoptPtr(Platform::current()->createThread("RefEncodedDataThread")) ;
218 thread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(&decode ThreadWithRefEncodedMain, AllowCrossThreadAccess(m_generator.get())));
219 thread.clear();
220 EXPECT_EQ(4, m_decodeRequestCount);
221
222 data->unref();
223 // m_generator is holding the only reference to SkData now.
224 ASSERT_TRUE(data->unique());
225
226 data = m_generator->refEncodedData();
227 ASSERT_TRUE(data && !data->unique());
228
229 // Delete generator, and SkData should have the only reference.
200 m_generator = nullptr; 230 m_generator = nullptr;
231 ASSERT_TRUE(data->unique());
232 data->unref();
201 } 233 }
202 234
203 TEST_F(ImageFrameGeneratorTest, frameHasAlpha) 235 TEST_F(ImageFrameGeneratorTest, frameHasAlpha)
204 { 236 {
205 setFrameStatus(ImageFrame::FramePartial); 237 setFrameStatus(ImageFrame::FramePartial);
206 238
207 char buffer[100 * 100 * 4]; 239 char buffer[100 * 100 * 4];
208 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 240 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
209 EXPECT_TRUE(m_generator->hasAlpha(0)); 241 EXPECT_TRUE(m_generator->hasAlpha(0));
210 EXPECT_EQ(1, m_decodeRequestCount); 242 EXPECT_EQ(1, m_decodeRequestCount);
211 243
212 ImageDecoder* tempDecoder = 0; 244 ImageDecoder* tempDecoder = 0;
213 EXPECT_TRUE(ImageDecodingStore::instance().lockDecoder(m_generator.get(), fu llSize(), &tempDecoder)); 245 EXPECT_TRUE(ImageDecodingStore::instance().lockDecoder(m_generator.get(), fu llSize(), &tempDecoder));
214 ASSERT_TRUE(tempDecoder); 246 ASSERT_TRUE(tempDecoder);
215 tempDecoder->frameBufferAtIndex(0)->setHasAlpha(false); 247 tempDecoder->frameBufferAtIndex(0)->setHasAlpha(false);
216 ImageDecodingStore::instance().unlockDecoder(m_generator.get(), tempDecoder) ; 248 ImageDecodingStore::instance().unlockDecoder(m_generator.get(), tempDecoder) ;
217 EXPECT_EQ(2, m_decodeRequestCount); 249 EXPECT_EQ(2, m_decodeRequestCount);
218 250
219 setFrameStatus(ImageFrame::FrameComplete); 251 setFrameStatus(ImageFrame::FrameComplete);
220 m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), bu ffer, 100 * 4); 252 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
221 EXPECT_EQ(3, m_decodeRequestCount); 253 EXPECT_EQ(3, m_decodeRequestCount);
222 EXPECT_FALSE(m_generator->hasAlpha(0)); 254 EXPECT_FALSE(m_generator->hasAlpha(0));
223 } 255 }
224 256
225 TEST_F(ImageFrameGeneratorTest, clearMultiFrameDecoder) 257 TEST_F(ImageFrameGeneratorTest, clearMultiFrameDecoder)
226 { 258 {
227 setFrameCount(3); 259 setFrameCount(3);
228 setFrameStatus(ImageFrame::FrameComplete); 260 setFrameStatus(ImageFrame::FrameComplete);
229 261
230 char buffer[100 * 100 * 4]; 262 char buffer[100 * 100 * 4];
231 m_generator->decodeAndScale(m_segmentReader.get(), true, 0, imageInfo(), buf fer, 100 * 4); 263 m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
232 EXPECT_EQ(1, m_decodeRequestCount); 264 EXPECT_EQ(1, m_decodeRequestCount);
233 EXPECT_EQ(0, m_decodersDestroyed); 265 EXPECT_EQ(0, m_decodersDestroyed);
234 EXPECT_EQ(0U, m_requestedClearExceptFrame); 266 EXPECT_EQ(0U, m_requestedClearExceptFrame);
235 267
236 setFrameStatus(ImageFrame::FrameComplete); 268 setFrameStatus(ImageFrame::FrameComplete);
237 269
238 m_generator->decodeAndScale(m_segmentReader.get(), true, 1, imageInfo(), buf fer, 100 * 4); 270 m_generator->decodeAndScale(1, imageInfo(), buffer, 100 * 4);
239 EXPECT_EQ(2, m_decodeRequestCount); 271 EXPECT_EQ(2, m_decodeRequestCount);
240 EXPECT_EQ(0, m_decodersDestroyed); 272 EXPECT_EQ(0, m_decodersDestroyed);
241 EXPECT_EQ(1U, m_requestedClearExceptFrame); 273 EXPECT_EQ(1U, m_requestedClearExceptFrame);
242 274
243 setFrameStatus(ImageFrame::FrameComplete); 275 setFrameStatus(ImageFrame::FrameComplete);
244 276
245 // Decoding the last frame of a multi-frame images should trigger clearing 277 // Decoding the last frame of a multi-frame images should trigger clearing
246 // all the frame data, but not destroying the decoder. See comments in 278 // all the frame data, but not destroying the decoder. See comments in
247 // ImageFrameGenerator::tryToResumeDecode(). 279 // ImageFrameGenerator::tryToResumeDecode().
248 m_generator->decodeAndScale(m_segmentReader.get(), true, 2, imageInfo(), buf fer, 100 * 4); 280 m_generator->decodeAndScale(2, imageInfo(), buffer, 100 * 4);
249 EXPECT_EQ(3, m_decodeRequestCount); 281 EXPECT_EQ(3, m_decodeRequestCount);
250 EXPECT_EQ(0, m_decodersDestroyed); 282 EXPECT_EQ(0, m_decodersDestroyed);
251 EXPECT_EQ(kNotFound, m_requestedClearExceptFrame); 283 EXPECT_EQ(kNotFound, m_requestedClearExceptFrame);
252 } 284 }
253 285
254 } // namespace blink 286 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698