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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReaderTest.cpp

Issue 1812273003: Eliminate copies of encoded image data (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase 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) 2015 Google Inc. All rights reserved. 2 * Copyright (C) 2015 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 are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * 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 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 11 matching lines...) Expand all
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "platform/image-decoders/FastSharedBufferReader.h" 31 #include "platform/image-decoders/FastSharedBufferReader.h"
32 #include "platform/image-decoders/SegmentReader.h"
32 33
33 #include "testing/gtest/include/gtest/gtest.h" 34 #include "testing/gtest/include/gtest/gtest.h"
34 35
35 namespace blink { 36 namespace blink {
36 37
37 namespace { 38 namespace {
38 39
39 const unsigned kDefaultTestSize = 4 * SharedBuffer::kSegmentSize; 40 const unsigned kDefaultTestSize = 4 * SharedBuffer::kSegmentSize;
40 41
41 void prepareReferenceData(char* buffer, size_t size) 42 void prepareReferenceData(char* buffer, size_t size)
42 { 43 {
43 for (size_t i = 0; i < size; ++i) 44 for (size_t i = 0; i < size; ++i)
44 buffer[i] = static_cast<char>(i); 45 buffer[i] = static_cast<char>(i);
45 } 46 }
46 47
48 PassRefPtr<SegmentReader> copyToROBufferSegmentReader(PassRefPtr<SegmentReader> input)
49 {
50 SkRWBuffer rwBuffer;
51 const char* segment = 0;
52 size_t position = 0;
53 while (size_t length = input->getSomeData(segment, position)) {
54 rwBuffer.append(segment, length);
55 position += length;
56 }
57 return SegmentReader::createFromSkROBuffer(adoptRef(rwBuffer.newRBufferSnaps hot()));
58 }
59
60 PassRefPtr<SegmentReader> copyToDataSegmentReader(PassRefPtr<SegmentReader> inpu t)
61 {
62 return SegmentReader::createFromSkData(input->getAsSkData());
63 }
64
65 struct SegmentReaders {
66 RefPtr<SegmentReader> segmentReaders[3];
67
68 SegmentReaders(PassRefPtr<SharedBuffer> input)
69 {
70 segmentReaders[0] = SegmentReader::createFromSharedBuffer(input);
71 segmentReaders[1] = copyToROBufferSegmentReader(segmentReaders[0]);
72 segmentReaders[2] = copyToDataSegmentReader(segmentReaders[0]);
73 }
74 };
75
47 } // namespace 76 } // namespace
48 77
49 TEST(FastSharedBufferReaderTest, nonSequentialReads) 78 TEST(FastSharedBufferReaderTest, nonSequentialReads)
50 { 79 {
51 char referenceData[kDefaultTestSize]; 80 char referenceData[kDefaultTestSize];
52 prepareReferenceData(referenceData, sizeof(referenceData)); 81 prepareReferenceData(referenceData, sizeof(referenceData));
53 RefPtr<SharedBuffer> data = SharedBuffer::create(); 82 RefPtr<SharedBuffer> data = SharedBuffer::create();
54 data->append(referenceData, sizeof(referenceData)); 83 data->append(referenceData, sizeof(referenceData));
55 84
56 FastSharedBufferReader reader(data); 85 SegmentReaders readerStruct(data);
57 86 for (auto segmentReader : readerStruct.segmentReaders) {
58 // Read size is prime such there will be a segment-spanning 87 FastSharedBufferReader reader(segmentReader);
59 // read eventually. 88 // Read size is prime such there will be a segment-spanning
60 char tempBuffer[17]; 89 // read eventually.
61 for (size_t dataPosition = 0; dataPosition + sizeof(tempBuffer) < sizeof(ref erenceData); dataPosition += sizeof(tempBuffer)) { 90 char tempBuffer[17];
62 const char* block = reader.getConsecutiveData( 91 for (size_t dataPosition = 0; dataPosition + sizeof(tempBuffer) < sizeof (referenceData); dataPosition += sizeof(tempBuffer)) {
63 dataPosition, sizeof(tempBuffer), tempBuffer); 92 const char* block = reader.getConsecutiveData(
64 ASSERT_FALSE(memcmp(block, referenceData + dataPosition, sizeof(tempBuff er))); 93 dataPosition, sizeof(tempBuffer), tempBuffer);
94 ASSERT_FALSE(memcmp(block, referenceData + dataPosition, sizeof(temp Buffer)));
95 }
65 } 96 }
66 } 97 }
67 98
68 TEST(FastSharedBufferReaderTest, readBackwards) 99 TEST(FastSharedBufferReaderTest, readBackwards)
69 { 100 {
70 char referenceData[kDefaultTestSize]; 101 char referenceData[kDefaultTestSize];
71 prepareReferenceData(referenceData, sizeof(referenceData)); 102 prepareReferenceData(referenceData, sizeof(referenceData));
72 RefPtr<SharedBuffer> data = SharedBuffer::create(); 103 RefPtr<SharedBuffer> data = SharedBuffer::create();
73 data->append(referenceData, sizeof(referenceData)); 104 data->append(referenceData, sizeof(referenceData));
74 105
75 FastSharedBufferReader reader(data); 106 SegmentReaders readerStruct(data);
76 107 for (auto segmentReader : readerStruct.segmentReaders) {
77 // Read size is prime such there will be a segment-spanning 108 FastSharedBufferReader reader(segmentReader);
78 // read eventually. 109 // Read size is prime such there will be a segment-spanning
79 char tempBuffer[17]; 110 // read eventually.
80 for (size_t dataOffset = sizeof(tempBuffer); dataOffset < sizeof(referenceDa ta); dataOffset += sizeof(tempBuffer)) { 111 char tempBuffer[17];
81 const char* block = reader.getConsecutiveData( 112 for (size_t dataOffset = sizeof(tempBuffer); dataOffset < sizeof(referen ceData); dataOffset += sizeof(tempBuffer)) {
82 sizeof(referenceData) - dataOffset, sizeof(tempBuffer), tempBuffer); 113 const char* block = reader.getConsecutiveData(
83 ASSERT_FALSE(memcmp(block, referenceData + sizeof(referenceData) - dataO ffset, sizeof(tempBuffer))); 114 sizeof(referenceData) - dataOffset, sizeof(tempBuffer), tempBuff er);
115 ASSERT_FALSE(memcmp(block, referenceData + sizeof(referenceData) - d ataOffset, sizeof(tempBuffer)));
116 }
84 } 117 }
85 } 118 }
86 119
87 TEST(FastSharedBufferReaderTest, byteByByte) 120 TEST(FastSharedBufferReaderTest, byteByByte)
88 { 121 {
89 char referenceData[kDefaultTestSize]; 122 char referenceData[kDefaultTestSize];
90 prepareReferenceData(referenceData, sizeof(referenceData)); 123 prepareReferenceData(referenceData, sizeof(referenceData));
91 RefPtr<SharedBuffer> data = SharedBuffer::create(); 124 RefPtr<SharedBuffer> data = SharedBuffer::create();
92 data->append(referenceData, sizeof(referenceData)); 125 data->append(referenceData, sizeof(referenceData));
93 126
94 FastSharedBufferReader reader(data); 127 SegmentReaders readerStruct(data);
95 for (size_t i = 0; i < sizeof(referenceData); ++i) { 128 for (auto segmentReader : readerStruct.segmentReaders) {
96 ASSERT_EQ(referenceData[i], reader.getOneByte(i)); 129 FastSharedBufferReader reader(segmentReader);
130 for (size_t i = 0; i < sizeof(referenceData); ++i) {
131 ASSERT_EQ(referenceData[i], reader.getOneByte(i));
132 }
97 } 133 }
98 } 134 }
99 135
100 // Tests that a read from inside the penultimate segment to the very end of the 136 // Tests that a read from inside the penultimate segment to the very end of the
101 // buffer doesn't try to read off the end of the buffer. 137 // buffer doesn't try to read off the end of the buffer.
102 TEST(FastSharedBufferReaderTest, readAllOverlappingLastSegmentBoundary) 138 TEST(FastSharedBufferReaderTest, readAllOverlappingLastSegmentBoundary)
103 { 139 {
104 const unsigned dataSize = 2 * SharedBuffer::kSegmentSize; 140 const unsigned dataSize = 2 * SharedBuffer::kSegmentSize;
105 char referenceData[dataSize]; 141 char referenceData[dataSize];
106 prepareReferenceData(referenceData, dataSize); 142 prepareReferenceData(referenceData, dataSize);
107 RefPtr<SharedBuffer> data = SharedBuffer::create(); 143 RefPtr<SharedBuffer> data = SharedBuffer::create();
108 data->append(referenceData, dataSize); 144 data->append(referenceData, dataSize);
109 145
110 char buffer[dataSize]; 146 SegmentReaders readerStruct(data);
111 FastSharedBufferReader reader(data); 147 for (auto segmentReader : readerStruct.segmentReaders) {
112 reader.getConsecutiveData(0, dataSize, buffer); 148 FastSharedBufferReader reader(segmentReader);
149 char buffer[dataSize];
150 reader.getConsecutiveData(0, dataSize, buffer);
151 ASSERT_FALSE(memcmp(buffer, referenceData, dataSize));
152 }
153 }
113 154
114 ASSERT_FALSE(memcmp(buffer, referenceData, dataSize)); 155 // Verify that reading past the end of the buffer does not break future reads.
156 TEST(SegmentReaderTest, readPastEndThenRead)
157 {
158 const unsigned dataSize = 2 * SharedBuffer::kSegmentSize;
159 char referenceData[dataSize];
160 prepareReferenceData(referenceData, dataSize);
161 RefPtr<SharedBuffer> data = SharedBuffer::create();
162 data->append(referenceData, dataSize);
163
164 SegmentReaders readerStruct(data);
165 for (auto segmentReader : readerStruct.segmentReaders) {
166 const char* contents;
167 size_t length = segmentReader->getSomeData(contents, dataSize);
168 EXPECT_EQ(0u, length);
169
170 length = segmentReader->getSomeData(contents, 0);
171 EXPECT_LE(SharedBuffer::kSegmentSize, length);
172 }
173 }
174
175 TEST(SegmentReaderTest, getAsSkData)
176 {
177 const unsigned dataSize = 4 * SharedBuffer::kSegmentSize;
178 char referenceData[dataSize];
179 prepareReferenceData(referenceData, dataSize);
180 RefPtr<SharedBuffer> data = SharedBuffer::create();
181 data->append(referenceData, dataSize);
182
183 SegmentReaders readerStruct(data);
184 for (auto segmentReader : readerStruct.segmentReaders) {
185 RefPtr<SkData> skdata = segmentReader->getAsSkData();
186 EXPECT_EQ(data->size(), skdata->size());
187
188 const char* segment;
189 size_t position = 0;
190 for (size_t length = segmentReader->getSomeData(segment, position);
191 length; length = segmentReader->getSomeData(segment, position)) {
192 ASSERT_FALSE(memcmp(segment, skdata->bytes() + position, length));
193 position += length;
194 }
195 EXPECT_EQ(position, dataSize);
196 }
197 }
198
199 TEST(SegmentReaderTest, variableSegments)
200 {
201 const size_t dataSize = 3.5 * SharedBuffer::kSegmentSize;
202 char referenceData[dataSize];
203 prepareReferenceData(referenceData, dataSize);
204
205 RefPtr<SegmentReader> segmentReader;
206 {
207 // Create a SegmentReader with difference sized segments, to test that
208 // the SkROBuffer implementation works when two consecutive segments
209 // are not the same size. This test relies on knowledge of the
210 // internals of SkRWBuffer: it ensures that each segment is at least
211 // 4096 (though the actual data may be smaller, if it has not been
212 // written to yet), but when appending a larger amount it may create a
213 // larger segment.
214 SkRWBuffer rwBuffer;
215 rwBuffer.append(referenceData, SharedBuffer::kSegmentSize);
216 rwBuffer.append(referenceData + SharedBuffer::kSegmentSize, 2 * SharedBu ffer::kSegmentSize);
217 rwBuffer.append(referenceData + 3 * SharedBuffer::kSegmentSize, .5 * Sha redBuffer::kSegmentSize);
218
219 segmentReader = SegmentReader::createFromSkROBuffer(adoptRef(rwBuffer.ne wRBufferSnapshot()));
220 }
221
222 const char* segment;
223 size_t position = 0;
224 size_t lastLength = 0;
225 for (size_t length = segmentReader->getSomeData(segment, position);
226 length; length = segmentReader->getSomeData(segment, position)) {
227 // It is not a bug to have consecutive segments of the same length, but
228 // it does mean that the following test does not actually test what it
229 // is intended to test.
230 ASSERT_NE(length, lastLength);
231 lastLength = length;
232
233 ASSERT_FALSE(memcmp(segment, referenceData + position, length));
234 position += length;
235 }
236 EXPECT_EQ(position, dataSize);
115 } 237 }
116 238
117 } // namespace blink 239 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698