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

Side by Side Diff: Source/platform/geometry/Region.cpp

Issue 183663030: Reduce number of vector buffer reallocs in Regions::unite . (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased patch. Created 6 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
« no previous file with comments | « Source/platform/geometry/Region.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/platform/geometry/Region.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698