OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2010, 2011 Apple 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 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 } | 226 } |
227 | 227 |
228 Region::Shape::Shape(const IntRect& rect) | 228 Region::Shape::Shape(const IntRect& rect) |
229 { | 229 { |
230 appendSpan(rect.y()); | 230 appendSpan(rect.y()); |
231 appendSegment(rect.x()); | 231 appendSegment(rect.x()); |
232 appendSegment(rect.maxX()); | 232 appendSegment(rect.maxX()); |
233 appendSpan(rect.maxY()); | 233 appendSpan(rect.maxY()); |
234 } | 234 } |
235 | 235 |
236 Region::Shape::Shape(size_t segmentsCapacity, size_t spansCapacity) | |
237 { | |
238 if (segmentsCapacity > m_segments.capacity()) { | |
239 segmentsCapacity = (segmentsCapacity + segmentsMask) & ~segmentsMask; | |
240 m_segments.reserveCapacity(segmentsCapacity); | |
241 } | |
242 | |
243 if (spansCapacity > m_spans.capacity()) { | |
244 spansCapacity = (spansCapacity + spansMask) & ~spansMask; | |
245 m_spans.reserveCapacity(spansCapacity); | |
246 } | |
247 } | |
248 | |
249 void Region::Shape::trimCapacities() | |
danakj
2014/04/09 18:39:51
Methods in the same order as their declarations in
ostap
2014/04/09 22:45:43
It seems that all other methods are not in the sam
| |
250 { | |
251 if (m_segments.size() > segmentsDefaultCapacity && m_segments.capacity() > m _segments.size() * 2) | |
252 m_segments.shrinkToFit(); | |
danakj
2014/04/09 18:39:51
I feel like this is kinda unfortunate, in that you
ostap
2014/04/09 22:45:43
Region always allocate new buffers for operation.
danakj
2014/04/15 20:15:43
Wanna add that to the CL and we'll see what OWNERs
| |
253 | |
254 if (m_spans.size() > spansDefaultCapacity && m_spans.capacity() > m_spans.si ze() * 2) | |
255 m_spans.shrinkToFit(); | |
256 } | |
257 | |
236 void Region::Shape::appendSpan(int y) | 258 void Region::Shape::appendSpan(int y) |
237 { | 259 { |
238 m_spans.append(Span(y, m_segments.size())); | 260 m_spans.append(Span(y, m_segments.size())); |
239 } | 261 } |
240 | 262 |
241 bool Region::Shape::canCoalesce(SegmentIterator begin, SegmentIterator end) | 263 bool Region::Shape::canCoalesce(SegmentIterator begin, SegmentIterator end) |
242 { | 264 { |
243 if (m_spans.isEmpty()) | 265 if (m_spans.isEmpty()) |
244 return false; | 266 return false; |
245 | 267 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 Shape1, | 408 Shape1, |
387 Shape2, | 409 Shape2, |
388 }; | 410 }; |
389 | 411 |
390 template<typename Operation> | 412 template<typename Operation> |
391 Region::Shape Region::Shape::shapeOperation(const Shape& shape1, const Shape& sh ape2) | 413 Region::Shape Region::Shape::shapeOperation(const Shape& shape1, const Shape& sh ape2) |
392 { | 414 { |
393 COMPILE_ASSERT(!(!Operation::shouldAddRemainingSegmentsFromSpan1 && Operatio n::shouldAddRemainingSegmentsFromSpan2), invalid_segment_combination); | 415 COMPILE_ASSERT(!(!Operation::shouldAddRemainingSegmentsFromSpan1 && Operatio n::shouldAddRemainingSegmentsFromSpan2), invalid_segment_combination); |
394 COMPILE_ASSERT(!(!Operation::shouldAddRemainingSpansFromShape1 && Operation: :shouldAddRemainingSpansFromShape2), invalid_span_combination); | 416 COMPILE_ASSERT(!(!Operation::shouldAddRemainingSpansFromShape1 && Operation: :shouldAddRemainingSpansFromShape2), invalid_span_combination); |
395 | 417 |
396 Shape result; | 418 size_t segmentsCapacity = shape1.segmentsSize() + shape2.segmentsSize(); |
419 size_t spansCapacity = shape1.spansSize() + shape2.spansSize(); | |
420 Shape result(segmentsCapacity, spansCapacity); | |
397 if (Operation::trySimpleOperation(shape1, shape2, result)) | 421 if (Operation::trySimpleOperation(shape1, shape2, result)) |
398 return result; | 422 return result; |
399 | 423 |
400 SpanIterator spans1 = shape1.spansBegin(); | 424 SpanIterator spans1 = shape1.spansBegin(); |
401 SpanIterator spans1End = shape1.spansEnd(); | 425 SpanIterator spans1End = shape1.spansEnd(); |
402 | 426 |
403 SpanIterator spans2 = shape2.spansBegin(); | 427 SpanIterator spans2 = shape2.spansBegin(); |
404 SpanIterator spans2End = shape2.spansEnd(); | 428 SpanIterator spans2End = shape2.spansEnd(); |
405 | 429 |
406 SegmentIterator segments1 = 0; | 430 SegmentIterator segments1 = 0; |
407 SegmentIterator segments1End = 0; | 431 SegmentIterator segments1End = 0; |
408 | 432 |
409 SegmentIterator segments2 = 0; | 433 SegmentIterator segments2 = 0; |
410 SegmentIterator segments2End = 0; | 434 SegmentIterator segments2End = 0; |
411 | 435 |
436 Vector<int, segmentsDefaultCapacity> segments; | |
danakj
2014/04/09 18:39:51
would it improve anything further in your benchmar
ostap
2014/04/09 22:45:43
No, no change at all.
But this benchmark is very s
| |
437 | |
412 // Iterate over all spans. | 438 // Iterate over all spans. |
413 while (spans1 != spans1End && spans2 != spans2End) { | 439 while (spans1 != spans1End && spans2 != spans2End) { |
414 int y = 0; | 440 int y = 0; |
415 int test = spans1->y - spans2->y; | 441 int test = spans1->y - spans2->y; |
416 | 442 |
417 if (test <= 0) { | 443 if (test <= 0) { |
418 y = spans1->y; | 444 y = spans1->y; |
419 | 445 |
420 segments1 = shape1.segmentsBegin(spans1); | 446 segments1 = shape1.segmentsBegin(spans1); |
421 segments1End = shape1.segmentsEnd(spans1); | 447 segments1End = shape1.segmentsEnd(spans1); |
422 ++spans1; | 448 ++spans1; |
423 } | 449 } |
424 if (test >= 0) { | 450 if (test >= 0) { |
425 y = spans2->y; | 451 y = spans2->y; |
426 | 452 |
427 segments2 = shape2.segmentsBegin(spans2); | 453 segments2 = shape2.segmentsBegin(spans2); |
428 segments2End = shape2.segmentsEnd(spans2); | 454 segments2End = shape2.segmentsEnd(spans2); |
429 ++spans2; | 455 ++spans2; |
430 } | 456 } |
431 | 457 |
432 int flag = 0; | 458 int flag = 0; |
433 int oldFlag = 0; | 459 int oldFlag = 0; |
434 | 460 |
461 // clear vector without dropping capacity | |
danakj
2014/04/09 18:39:51
nit: proper sentence (capitalized, with period at
ostap
2014/04/09 22:45:43
Done.
| |
462 segments.resize(0); | |
danakj
2014/04/09 18:39:51
keep this in the same position? (below s1,s2 assig
ostap
2014/04/09 22:45:43
Done.
| |
463 | |
435 SegmentIterator s1 = segments1; | 464 SegmentIterator s1 = segments1; |
436 SegmentIterator s2 = segments2; | 465 SegmentIterator s2 = segments2; |
437 | 466 |
438 Vector<int, 32> segments; | |
439 | |
440 // Now iterate over the segments in each span and construct a new vector of segments. | 467 // Now iterate over the segments in each span and construct a new vector of segments. |
441 while (s1 != segments1End && s2 != segments2End) { | 468 while (s1 != segments1End && s2 != segments2End) { |
442 int test = *s1 - *s2; | 469 int test = *s1 - *s2; |
443 int x; | 470 int x; |
444 | 471 |
445 if (test <= 0) { | 472 if (test <= 0) { |
446 x = *s1; | 473 x = *s1; |
447 flag = flag ^ 1; | 474 flag = flag ^ 1; |
448 ++s1; | 475 ++s1; |
449 } | 476 } |
(...skipping 19 matching lines...) Expand all Loading... | |
469 if (!segments.isEmpty() || !result.isEmpty()) | 496 if (!segments.isEmpty() || !result.isEmpty()) |
470 result.appendSpan(y, segments.data(), segments.data() + segments.siz e()); | 497 result.appendSpan(y, segments.data(), segments.data() + segments.siz e()); |
471 } | 498 } |
472 | 499 |
473 // Add any remaining spans. | 500 // Add any remaining spans. |
474 if (Operation::shouldAddRemainingSpansFromShape1 && spans1 != spans1End) | 501 if (Operation::shouldAddRemainingSpansFromShape1 && spans1 != spans1End) |
475 result.appendSpans(shape1, spans1, spans1End); | 502 result.appendSpans(shape1, spans1, spans1End); |
476 else if (Operation::shouldAddRemainingSpansFromShape2 && spans2 != spans2End ) | 503 else if (Operation::shouldAddRemainingSpansFromShape2 && spans2 != spans2End ) |
477 result.appendSpans(shape2, spans2, spans2End); | 504 result.appendSpans(shape2, spans2, spans2End); |
478 | 505 |
506 // Trim excess capacities if necessary. | |
danakj
2014/04/09 18:39:51
Prefer not to add comments that just repeat the na
ostap
2014/04/09 22:45:43
Done.
| |
507 result.trimCapacities(); | |
508 | |
479 return result; | 509 return result; |
480 } | 510 } |
481 | 511 |
482 struct Region::Shape::UnionOperation { | 512 struct Region::Shape::UnionOperation { |
483 static bool trySimpleOperation(const Shape& shape1, const Shape& shape2, Sha pe& result) | 513 static bool trySimpleOperation(const Shape& shape1, const Shape& shape2, Sha pe& result) |
484 { | 514 { |
485 if (shape1.isEmpty()) { | 515 if (shape1.isEmpty()) { |
486 result = shape2; | 516 result = shape2; |
487 return true; | 517 return true; |
488 } | 518 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
601 m_bounds = m_shape.bounds(); | 631 m_bounds = m_shape.bounds(); |
602 } | 632 } |
603 | 633 |
604 void Region::translate(const IntSize& offset) | 634 void Region::translate(const IntSize& offset) |
605 { | 635 { |
606 m_bounds.move(offset); | 636 m_bounds.move(offset); |
607 m_shape.translate(offset); | 637 m_shape.translate(offset); |
608 } | 638 } |
609 | 639 |
610 } // namespace WebCore | 640 } // namespace WebCore |
OLD | NEW |