Changeset 117106 in webkit
- Timestamp:
- May 15, 2012 11:43:21 AM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r117102 r117106 1 2012-05-15 Darin Adler <darin@apple.com> 2 3 Optimize save/restore with no drawing operations between them (shows up on some canvas benchmarks) 4 https://bugs.webkit.org/show_bug.cgi?id=86448 5 6 Reviewed by Simon Fraser. 7 8 Since canvas programmers sometimes end up doing extra save/restore pairs with no actual drawing 9 in between, optimize that case by not realizing saves until we have to. This is doubly important 10 because saves are costly. 11 12 * html/canvas/CanvasRenderingContext2D.cpp: 13 (WebCore::CanvasRenderingContext2D::CanvasRenderingContext2D): Initialize m_unrealizedSaveCount. 14 (WebCore::CanvasRenderingContext2D::isAccelerated): Improve performance by calling the 15 drawingContext function only once. 16 (WebCore::CanvasRenderingContext2D::reset): Set m_unrealizedSaveCount to 0. 17 (WebCore::CanvasRenderingContext2D::realizeSavesLoop): Added. Replaces the save function as the 18 function that actually pushes context onto the state stack. 19 (WebCore::CanvasRenderingContext2D::restore): Added code to do an early return if we can do the 20 restore just by decrementing the unrealized save count. 21 (WebCore::CanvasRenderingContext2D::setStrokeStyle): Added calls to realizeSaves and replaced 22 calls to state with calls to modifiableState. 23 (WebCore::CanvasRenderingContext2D::setFillStyle): Ditto. 24 (WebCore::CanvasRenderingContext2D::setLineWidth): Ditto. Also added an early out for cases where 25 the line width is not changing. 26 (WebCore::CanvasRenderingContext2D::setLineCap): Ditto. 27 (WebCore::CanvasRenderingContext2D::setLineJoin): Ditto. 28 (WebCore::CanvasRenderingContext2D::setMiterLimit): Ditto. 29 (WebCore::CanvasRenderingContext2D::setShadowOffsetX): Ditto. 30 (WebCore::CanvasRenderingContext2D::setShadowOffsetY): Ditto. 31 (WebCore::CanvasRenderingContext2D::setShadowBlur): Ditto. 32 (WebCore::CanvasRenderingContext2D::setShadowColor): Ditto. 33 (WebCore::CanvasRenderingContext2D::setWebkitLineDash): Ditto. 34 (WebCore::CanvasRenderingContext2D::setWebkitLineDashOffset): Ditto. 35 (WebCore::CanvasRenderingContext2D::setGlobalAlpha): Ditto. 36 (WebCore::CanvasRenderingContext2D::setGlobalCompositeOperation): Ditto. 37 (WebCore::CanvasRenderingContext2D::scale): Ditto. 38 (WebCore::CanvasRenderingContext2D::rotate): Ditto. 39 (WebCore::CanvasRenderingContext2D::translate): Ditto. 40 (WebCore::CanvasRenderingContext2D::transform): Ditto. 41 (WebCore::CanvasRenderingContext2D::setTransform): Ditto. 42 (WebCore::CanvasRenderingContext2D::setStrokeColor): Ditto. 43 (WebCore::CanvasRenderingContext2D::setFillColor): Ditto. 44 (WebCore::CanvasRenderingContext2D::clip): Ditto. 45 (WebCore::CanvasRenderingContext2D::clearRect): Changed implementation so it does not save 46 the graphics context in the common case where shadows, global alpha, and global compositing 47 operators do not interfer with the function's operation. This allowed us to get rid of the 48 setAllAttributesToDefault function, which was used nowhere else. 49 (WebCore::CanvasRenderingContext2D::setShadow): Added a new common bottleneck and made all 50 the setShadow functions call it. 51 (WebCore::CanvasRenderingContext2D::clearShadow): Changed to call the new setShadow. 52 (WebCore::CanvasRenderingContext2D::setFont): Renamed tempDecl to the more friendly 53 parsedStyle. Changed code structure so the CSS parser is deleted right after parsing is 54 done. Used string concatenation instead of more expensive string append. Added calls to 55 realizeSaves and modifiableState. 56 (WebCore::CanvasRenderingContext2D::setTextAlign): Added calls to realizeSaves and replaced 57 calls to state with calls to modifiableState. Also added an early out for cases where the 58 alignment is not changing. 59 (WebCore::CanvasRenderingContext2D::setTextBaseline): Ditto. 60 61 * html/canvas/CanvasRenderingContext2D.h: Made save an inline function that bumps 62 m_unrealizedSaveCount. Removed setAllAttributesToDefault. Added OVERRIDE for all the 63 virtual function overrides, and made them all private. Moved m_path down with the other data 64 members. Renamed the non-const state function to modifiableState. Added a realizeSaves 65 function and the realizeSavesLoop for the unusual case where there is work to do. 66 Added m_unrealizedSaveCount. 67 1 68 2012-05-15 Tommy Widenflycht <tommyw@google.com> 2 69 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
r116723 r117106 1 1 /* 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) 4 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> … … 116 116 : CanvasRenderingContext(canvas) 117 117 , m_stateStack(1) 118 , m_unrealizedSaveCount(0) 118 119 , m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode) 119 120 #if ENABLE(DASHBOARD_SUPPORT) … … 149 150 { 150 151 #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS) 151 return canvas()->hasCreatedImageBuffer() && drawingContext() && drawingContext()->isAcceleratedContext(); 152 if (!canvas()->hasCreatedImageBuffer()) 153 return false; 154 GraphicsContext* context = drawingContext(); 155 return context && context->isAcceleratedContext(); 152 156 #else 153 157 return false; … … 161 165 m_stateStack.first() = State(); 162 166 m_path.clear(); 167 m_unrealizedSaveCount = 0; 163 168 } 164 169 … … 260 265 } 261 266 262 void CanvasRenderingContext2D::save() 263 { 267 void CanvasRenderingContext2D::realizeSavesLoop() 268 { 269 ASSERT(m_unrealizedSaveCount); 264 270 ASSERT(m_stateStack.size() >= 1); 265 m_stateStack.append(state()); 266 GraphicsContext* c = drawingContext(); 267 if (!c) 268 return; 269 c->save(); 271 GraphicsContext* context = drawingContext(); 272 do { 273 m_stateStack.append(state()); 274 if (context) 275 context->save(); 276 } while (--m_unrealizedSaveCount); 270 277 } 271 278 272 279 void CanvasRenderingContext2D::restore() 273 280 { 281 if (m_unrealizedSaveCount) { 282 --m_unrealizedSaveCount; 283 return; 284 } 274 285 ASSERT(m_stateStack.size() >= 1); 275 286 if (m_stateStack.size() <= 1) … … 282 293 return; 283 294 c->restore(); 284 }285 286 void CanvasRenderingContext2D::setAllAttributesToDefault()287 {288 state().m_globalAlpha = 1;289 state().m_shadowOffset = FloatSize();290 state().m_shadowBlur = 0;291 state().m_shadowColor = Color::transparent;292 state().m_globalComposite = CompositeSourceOver;293 294 GraphicsContext* context = drawingContext();295 if (!context)296 return;297 298 applyShadow();299 context->setAlpha(1);300 context->setCompositeOperation(CompositeSourceOver);301 295 } 302 296 … … 324 318 checkOrigin(style->canvasPattern()); 325 319 326 state().m_strokeStyle = style.release(); 320 realizeSaves(); 321 modifiableState().m_strokeStyle = style.release(); 327 322 GraphicsContext* c = drawingContext(); 328 323 if (!c) 329 324 return; 330 325 state().m_strokeStyle->applyStrokeColor(c); 331 state().m_unparsedStrokeColor = String();326 modifiableState().m_unparsedStrokeColor = String(); 332 327 } 333 328 … … 355 350 checkOrigin(style->canvasPattern()); 356 351 357 state().m_fillStyle = style.release(); 352 realizeSaves(); 353 modifiableState().m_fillStyle = style.release(); 358 354 GraphicsContext* c = drawingContext(); 359 355 if (!c) 360 356 return; 361 357 state().m_fillStyle->applyFillColor(c); 362 state().m_unparsedFillColor = String();358 modifiableState().m_unparsedFillColor = String(); 363 359 } 364 360 … … 372 368 if (!(isfinite(width) && width > 0)) 373 369 return; 374 state().m_lineWidth = width; 370 if (state().m_lineWidth == width) 371 return; 372 realizeSaves(); 373 modifiableState().m_lineWidth = width; 375 374 GraphicsContext* c = drawingContext(); 376 375 if (!c) … … 389 388 if (!parseLineCap(s, cap)) 390 389 return; 391 state().m_lineCap = cap; 390 if (state().m_lineCap == cap) 391 return; 392 realizeSaves(); 393 modifiableState().m_lineCap = cap; 392 394 GraphicsContext* c = drawingContext(); 393 395 if (!c) … … 406 408 if (!parseLineJoin(s, join)) 407 409 return; 408 state().m_lineJoin = join; 410 if (state().m_lineJoin == join) 411 return; 412 realizeSaves(); 413 modifiableState().m_lineJoin = join; 409 414 GraphicsContext* c = drawingContext(); 410 415 if (!c) … … 422 427 if (!(isfinite(limit) && limit > 0)) 423 428 return; 424 state().m_miterLimit = limit; 429 if (state().m_miterLimit == limit) 430 return; 431 realizeSaves(); 432 modifiableState().m_miterLimit = limit; 425 433 GraphicsContext* c = drawingContext(); 426 434 if (!c) … … 438 446 if (!isfinite(x)) 439 447 return; 440 state().m_shadowOffset.setWidth(x); 448 if (state().m_shadowOffset.width() == x) 449 return; 450 realizeSaves(); 451 modifiableState().m_shadowOffset.setWidth(x); 441 452 applyShadow(); 442 453 } … … 451 462 if (!isfinite(y)) 452 463 return; 453 state().m_shadowOffset.setHeight(y); 464 if (state().m_shadowOffset.height() == y) 465 return; 466 realizeSaves(); 467 modifiableState().m_shadowOffset.setHeight(y); 454 468 applyShadow(); 455 469 } … … 464 478 if (!(isfinite(blur) && blur >= 0)) 465 479 return; 466 state().m_shadowBlur = blur; 480 if (state().m_shadowBlur == blur) 481 return; 482 realizeSaves(); 483 modifiableState().m_shadowBlur = blur; 467 484 applyShadow(); 468 485 } … … 475 492 void CanvasRenderingContext2D::setShadowColor(const String& color) 476 493 { 477 if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas())) 478 return; 494 RGBA32 rgba; 495 if (!parseColorOrCurrentColor(rgba, color, canvas())) 496 return; 497 if (state().m_shadowColor == rgba) 498 return; 499 realizeSaves(); 500 modifiableState().m_shadowColor = rgba; 479 501 applyShadow(); 480 502 } … … 487 509 void CanvasRenderingContext2D::setWebkitLineDash(const DashArray& dash) 488 510 { 489 state().m_lineDash = dash; 490 511 if (state().m_lineDash == dash) 512 return; 513 realizeSaves(); 514 modifiableState().m_lineDash = dash; 491 515 GraphicsContext* c = drawingContext(); 492 516 if (!c) … … 504 528 if (!isfinite(offset)) 505 529 return; 506 507 state().m_lineDashOffset = offset; 508 530 if (state().m_lineDashOffset == offset) 531 return; 532 realizeSaves(); 533 modifiableState().m_lineDashOffset = offset; 509 534 GraphicsContext* c = drawingContext(); 510 535 if (!c) … … 522 547 if (!(alpha >= 0 && alpha <= 1)) 523 548 return; 524 state().m_globalAlpha = alpha; 549 if (state().m_globalAlpha == alpha) 550 return; 551 realizeSaves(); 552 modifiableState().m_globalAlpha = alpha; 525 553 GraphicsContext* c = drawingContext(); 526 554 if (!c) … … 539 567 if (!parseCompositeOperator(operation, op)) 540 568 return; 541 state().m_globalComposite = op; 569 if (state().m_globalComposite == op) 570 return; 571 realizeSaves(); 572 modifiableState().m_globalComposite = op; 542 573 GraphicsContext* c = drawingContext(); 543 574 if (!c) … … 559 590 AffineTransform newTransform = state().m_transform; 560 591 newTransform.scaleNonUniform(sx, sy); 592 if (state().m_transform == newTransform) 593 return; 594 595 realizeSaves(); 596 561 597 if (!newTransform.isInvertible()) { 562 state().m_invertibleCTM = false;563 return; 564 } 565 566 state().m_transform = newTransform;598 modifiableState().m_invertibleCTM = false; 599 return; 600 } 601 602 modifiableState().m_transform = newTransform; 567 603 c->scale(FloatSize(sx, sy)); 568 604 m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy)); … … 582 618 AffineTransform newTransform = state().m_transform; 583 619 newTransform.rotate(angleInRadians / piDouble * 180.0); 620 if (state().m_transform == newTransform) 621 return; 622 623 realizeSaves(); 624 584 625 if (!newTransform.isInvertible()) { 585 state().m_invertibleCTM = false;586 return; 587 } 588 589 state().m_transform = newTransform;626 modifiableState().m_invertibleCTM = false; 627 return; 628 } 629 630 modifiableState().m_transform = newTransform; 590 631 c->rotate(angleInRadians); 591 632 m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0)); … … 605 646 AffineTransform newTransform = state().m_transform; 606 647 newTransform.translate(tx, ty); 648 if (state().m_transform == newTransform) 649 return; 650 651 realizeSaves(); 652 607 653 if (!newTransform.isInvertible()) { 608 state().m_invertibleCTM = false;609 return; 610 } 611 612 state().m_transform = newTransform;654 modifiableState().m_invertibleCTM = false; 655 return; 656 } 657 658 modifiableState().m_transform = newTransform; 613 659 c->translate(tx, ty); 614 660 m_path.transform(AffineTransform().translate(-tx, -ty)); … … 628 674 AffineTransform transform(m11, m12, m21, m22, dx, dy); 629 675 AffineTransform newTransform = state().m_transform * transform; 676 if (state().m_transform == newTransform) 677 return; 678 679 realizeSaves(); 680 630 681 if (!newTransform.isInvertible()) { 631 state().m_invertibleCTM = false;632 return; 633 } 634 635 state().m_transform = newTransform;682 modifiableState().m_invertibleCTM = false; 683 return; 684 } 685 686 modifiableState().m_transform = newTransform; 636 687 c->concatCTM(transform); 637 688 m_path.transform(transform.inverse()); … … 650 701 if (!ctm.isInvertible()) 651 702 return; 703 704 realizeSaves(); 705 652 706 c->setCTM(canvas()->baseTransform()); 653 state().m_transform = AffineTransform();707 modifiableState().m_transform = AffineTransform(); 654 708 m_path.transform(ctm); 655 709 656 state().m_invertibleCTM = true;710 modifiableState().m_invertibleCTM = true; 657 711 transform(m11, m12, m21, m22, dx, dy); 658 712 } … … 662 716 if (color == state().m_unparsedStrokeColor) 663 717 return; 718 realizeSaves(); 664 719 setStrokeStyle(CanvasStyle::createFromString(color, canvas()->document())); 665 state().m_unparsedStrokeColor = color;720 modifiableState().m_unparsedStrokeColor = color; 666 721 } 667 722 … … 703 758 if (color == state().m_unparsedFillColor) 704 759 return; 760 realizeSaves(); 705 761 setFillStyle(CanvasStyle::createFromString(color, canvas()->document())); 706 state().m_unparsedFillColor = color;762 modifiableState().m_unparsedFillColor = color; 707 763 } 708 764 … … 972 1028 if (!state().m_invertibleCTM) 973 1029 return; 1030 realizeSaves(); 974 1031 c->canvasClip(m_path); 975 1032 #if ENABLE(DASHBOARD_SUPPORT) … … 1005 1062 FloatRect rect(x, y, width, height); 1006 1063 1007 save(); 1008 setAllAttributesToDefault(); 1064 bool saved = false; 1065 if (shouldDrawShadows()) { 1066 context->save(); 1067 saved = true; 1068 context->setLegacyShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB); 1069 } 1070 if (state().m_globalAlpha != 1) { 1071 if (!saved) { 1072 context->save(); 1073 saved = true; 1074 } 1075 context->setAlpha(1); 1076 } 1077 if (state().m_globalComposite != CompositeSourceOver) { 1078 if (!saved) { 1079 context->save(); 1080 saved = true; 1081 } 1082 context->setCompositeOperation(CompositeSourceOver); 1083 } 1009 1084 context->clearRect(rect); 1085 if (saved) 1086 context->restore(); 1010 1087 didDraw(rect); 1011 restore();1012 1088 } 1013 1089 … … 1080 1156 void CanvasRenderingContext2D::setShadow(float width, float height, float blur) 1081 1157 { 1082 state().m_shadowOffset = FloatSize(width, height); 1083 state().m_shadowBlur = blur; 1084 state().m_shadowColor = Color::transparent; 1085 applyShadow(); 1158 setShadow(FloatSize(width, height), blur, Color::transparent); 1086 1159 } 1087 1160 1088 1161 void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color) 1089 1162 { 1090 if (!parseColorOrCurrentColor(state().m_shadowColor, color, canvas())) 1091 return; 1092 1093 state().m_shadowOffset = FloatSize(width, height); 1094 state().m_shadowBlur = blur; 1095 applyShadow(); 1163 RGBA32 rgba; 1164 if (!parseColorOrCurrentColor(rgba, color, canvas())) 1165 return; 1166 setShadow(FloatSize(width, height), blur, rgba); 1096 1167 } 1097 1168 1098 1169 void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel) 1099 1170 { 1100 state().m_shadowOffset = FloatSize(width, height); 1101 state().m_shadowBlur = blur; 1102 state().m_shadowColor = makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, 1.0f); 1103 applyShadow(); 1171 setShadow(FloatSize(width, height), blur, makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, 1)); 1104 1172 } 1105 1173 … … 1107 1175 { 1108 1176 RGBA32 rgba; 1109 1110 1177 if (!parseColorOrCurrentColor(rgba, color, canvas())) 1111 1178 return; 1112 1113 state().m_shadowColor = colorWithOverrideAlpha(rgba, alpha); 1114 state().m_shadowOffset = FloatSize(width, height); 1115 state().m_shadowBlur = blur; 1116 applyShadow(); 1179 setShadow(FloatSize(width, height), blur, colorWithOverrideAlpha(rgba, alpha)); 1117 1180 } 1118 1181 1119 1182 void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel, float alpha) 1120 1183 { 1121 state().m_shadowOffset = FloatSize(width, height); 1122 state().m_shadowBlur = blur; 1123 state().m_shadowColor = makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha); 1124 applyShadow(); 1184 setShadow(FloatSize(width, height), blur, makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha)); 1125 1185 } 1126 1186 1127 1187 void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float r, float g, float b, float a) 1128 1188 { 1129 state().m_shadowOffset = FloatSize(width, height); 1130 state().m_shadowBlur = blur; 1131 state().m_shadowColor = makeRGBA32FromFloats(r, g, b, a); 1132 applyShadow(); 1189 setShadow(FloatSize(width, height), blur, makeRGBA32FromFloats(r, g, b, a)); 1133 1190 } 1134 1191 1135 1192 void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float c, float m, float y, float k, float a) 1136 1193 { 1137 state().m_shadowOffset = FloatSize(width, height); 1138 state().m_shadowBlur = blur; 1139 state().m_shadowColor = makeRGBAFromCMYKA(c, m, y, k, a); 1140 applyShadow(); 1194 setShadow(FloatSize(width, height), blur, makeRGBAFromCMYKA(c, m, y, k, a)); 1141 1195 } 1142 1196 1143 1197 void CanvasRenderingContext2D::clearShadow() 1144 1198 { 1145 state().m_shadowOffset = FloatSize(); 1146 state().m_shadowBlur = 0; 1147 state().m_shadowColor = Color::transparent; 1199 setShadow(FloatSize(), 0, Color::transparent); 1200 } 1201 1202 void CanvasRenderingContext2D::setShadow(const FloatSize& offset, float blur, RGBA32 color) 1203 { 1204 if (state().m_shadowOffset == offset && state().m_shadowBlur == blur && state().m_shadowColor == color) 1205 return; 1206 bool wasDrawingShadows = shouldDrawShadows(); 1207 realizeSaves(); 1208 modifiableState().m_shadowOffset = offset; 1209 modifiableState().m_shadowBlur = blur; 1210 modifiableState().m_shadowColor = color; 1211 if (!wasDrawingShadows && !shouldDrawShadows()) 1212 return; 1148 1213 applyShadow(); 1149 1214 } … … 1924 1989 void CanvasRenderingContext2D::setFont(const String& newFont) 1925 1990 { 1926 RefPtr<StylePropertySet> tempDecl = StylePropertySet::create(); 1927 CSSParser parser(strictToCSSParserMode(!m_usesCSSCompatibilityParseMode)); 1928 1929 String declarationText("font: "); 1930 declarationText += newFont; 1931 parser.parseDeclaration(tempDecl.get(), declarationText, 0, 0); 1932 if (tempDecl->isEmpty()) 1991 RefPtr<StylePropertySet> parsedStyle = StylePropertySet::create(); 1992 CSSParser(strictToCSSParserMode(!m_usesCSSCompatibilityParseMode)).parseDeclaration(parsedStyle.get(), "font:" + newFont, 0, 0); 1993 if (parsedStyle->isEmpty()) 1933 1994 return; 1934 1995 1935 1996 // The parse succeeded. 1936 state().m_unparsedFont = newFont; 1997 realizeSaves(); 1998 modifiableState().m_unparsedFont = newFont; 1937 1999 1938 2000 // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work … … 1945 2007 // Now map the font property longhands into the style. 1946 2008 StyleResolver* styleResolver = canvas()->styleResolver(); 1947 styleResolver->applyPropertyToStyle(CSSPropertyFontFamily, tempDecl->getPropertyCSSValue(CSSPropertyFontFamily).get(), newStyle.get());1948 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontStyle, tempDecl->getPropertyCSSValue(CSSPropertyFontStyle).get());1949 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontVariant, tempDecl->getPropertyCSSValue(CSSPropertyFontVariant).get());1950 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontWeight, tempDecl->getPropertyCSSValue(CSSPropertyFontWeight).get());2009 styleResolver->applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), newStyle.get()); 2010 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get()); 2011 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontVariant, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariant).get()); 2012 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get()); 1951 2013 1952 2014 // As described in BUG66291, setting font-size on a font may entail a CSSPrimitiveValue::computeLengthDouble call, … … 1954 2016 // The updateFont() call below updates the fontMetrics and ensures the proper setting of font-size. 1955 2017 styleResolver->updateFont(); 1956 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontSize, tempDecl->getPropertyCSSValue(CSSPropertyFontSize).get());1957 styleResolver->applyPropertyToCurrentStyle(CSSPropertyLineHeight, tempDecl->getPropertyCSSValue(CSSPropertyLineHeight).get());1958 1959 state().m_font = newStyle->font();1960 state().m_font.update(styleResolver->fontSelector());1961 state().m_realizedFont = true;1962 styleResolver->fontSelector()->registerForInvalidationCallbacks(& state());2018 styleResolver->applyPropertyToCurrentStyle(CSSPropertyFontSize, parsedStyle->getPropertyCSSValue(CSSPropertyFontSize).get()); 2019 styleResolver->applyPropertyToCurrentStyle(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get()); 2020 2021 modifiableState().m_font = newStyle->font(); 2022 modifiableState().m_font.update(styleResolver->fontSelector()); 2023 modifiableState().m_realizedFont = true; 2024 styleResolver->fontSelector()->registerForInvalidationCallbacks(&modifiableState()); 1963 2025 } 1964 2026 … … 1973 2035 if (!parseTextAlign(s, align)) 1974 2036 return; 1975 state().m_textAlign = align; 2037 if (state().m_textAlign == align) 2038 return; 2039 realizeSaves(); 2040 modifiableState().m_textAlign = align; 1976 2041 } 1977 2042 … … 1986 2051 if (!parseTextBaseline(s, baseline)) 1987 2052 return; 1988 state().m_textBaseline = baseline; 2053 if (state().m_textBaseline == baseline) 2054 return; 2055 realizeSaves(); 2056 modifiableState().m_textBaseline = baseline; 1989 2057 } 1990 2058 -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
r114679 r117106 1 1 /* 2 * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 67 67 virtual ~CanvasRenderingContext2D(); 68 68 69 virtual bool is2d() const { return true; }70 virtual bool isAccelerated() const;71 72 69 CanvasStyle* strokeStyle() const; 73 70 void setStrokeStyle(PassRefPtr<CanvasStyle>); … … 112 109 void setGlobalCompositeOperation(const String&); 113 110 114 void save() ;111 void save() { ++m_unrealizedSaveCount; } 115 112 void restore(); 116 void setAllAttributesToDefault();117 113 118 114 void scale(float sx, float sy); … … 227 223 LineJoin getLineJoin() const { return state().m_lineJoin; } 228 224 229 #if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)230 virtual PlatformLayer* platformLayer() const;231 #endif232 233 225 private: 234 226 struct State : FontSelectorClient { … … 239 231 State& operator=(const State&); 240 232 241 virtual void fontsNeedUpdate(FontSelector*) ;233 virtual void fontsNeedUpdate(FontSelector*) OVERRIDE; 242 234 243 235 String m_unparsedStrokeColor; … … 278 270 CanvasRenderingContext2D(HTMLCanvasElement*, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode); 279 271 280 Path m_path; 281 282 State& state() { return m_stateStack.last(); } 272 State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); } 283 273 const State& state() const { return m_stateStack.last(); } 284 274 275 void setShadow(const FloatSize& offset, float blur, RGBA32 color); 285 276 void applyShadow(); 286 277 bool shouldDrawShadows() const; … … 292 283 293 284 void unwindStateStack(); 285 void realizeSaves() 286 { 287 if (m_unrealizedSaveCount) 288 realizeSavesLoop(); 289 } 290 void realizeSavesLoop(); 294 291 295 292 void applyStrokePattern(); … … 323 320 void putImageData(ImageData*, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode&); 324 321 322 virtual bool is2d() const OVERRIDE { return true; } 323 virtual bool isAccelerated() const OVERRIDE; 324 325 #if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING) 326 virtual PlatformLayer* platformLayer() const OVERRIDE; 327 #endif 328 329 Path m_path; 325 330 Vector<State, 1> m_stateStack; 331 unsigned m_unrealizedSaveCount; 326 332 bool m_usesCSSCompatibilityParseMode; 327 333 #if ENABLE(DASHBOARD_SUPPORT)
Note: See TracChangeset
for help on using the changeset viewer.