OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. |
3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 #include "third_party/skia/include/effects/SkLumaColorFilter.h" | 54 #include "third_party/skia/include/effects/SkLumaColorFilter.h" |
55 #include "third_party/skia/include/effects/SkMatrixImageFilter.h" | 55 #include "third_party/skia/include/effects/SkMatrixImageFilter.h" |
56 #include "third_party/skia/include/effects/SkPictureImageFilter.h" | 56 #include "third_party/skia/include/effects/SkPictureImageFilter.h" |
57 #include "third_party/skia/include/gpu/GrRenderTarget.h" | 57 #include "third_party/skia/include/gpu/GrRenderTarget.h" |
58 #include "third_party/skia/include/gpu/GrTexture.h" | 58 #include "third_party/skia/include/gpu/GrTexture.h" |
59 #include "wtf/Assertions.h" | 59 #include "wtf/Assertions.h" |
60 #include "wtf/MathExtras.h" | 60 #include "wtf/MathExtras.h" |
61 | 61 |
62 namespace blink { | 62 namespace blink { |
63 | 63 |
64 struct GraphicsContext::CanvasSaveState { | |
65 CanvasSaveState(bool pendingSave, int count) | |
66 : m_pendingSave(pendingSave), m_restoreCount(count) { } | |
67 | |
68 bool m_pendingSave; | |
69 int m_restoreCount; | |
70 }; | |
71 | |
72 struct GraphicsContext::RecordingState { | 64 struct GraphicsContext::RecordingState { |
73 RecordingState(SkPictureRecorder* recorder, SkCanvas* currentCanvas, const S
kMatrix& currentMatrix, bool currentShouldSmoothFonts, | 65 RecordingState(SkPictureRecorder* recorder, SkCanvas* currentCanvas, const S
kMatrix& currentMatrix, bool currentShouldSmoothFonts, |
74 PassRefPtr<DisplayList> displayList, RegionTrackingMode trackingMode) | 66 PassRefPtr<DisplayList> displayList, RegionTrackingMode trackingMode) |
75 : m_displayList(displayList) | 67 : m_displayList(displayList) |
76 , m_recorder(recorder) | 68 , m_recorder(recorder) |
77 , m_savedCanvas(currentCanvas) | 69 , m_savedCanvas(currentCanvas) |
78 , m_savedMatrix(currentMatrix) | 70 , m_savedMatrix(currentMatrix) |
79 , m_savedShouldSmoothFonts(currentShouldSmoothFonts) | 71 , m_savedShouldSmoothFonts(currentShouldSmoothFonts) |
80 , m_regionTrackingMode(trackingMode) { } | 72 , m_regionTrackingMode(trackingMode) { } |
81 | 73 |
82 ~RecordingState() { } | 74 ~RecordingState() { } |
83 | 75 |
84 RefPtr<DisplayList> m_displayList; | 76 RefPtr<DisplayList> m_displayList; |
85 SkPictureRecorder* m_recorder; | 77 SkPictureRecorder* m_recorder; |
86 SkCanvas* m_savedCanvas; | 78 SkCanvas* m_savedCanvas; |
87 const SkMatrix m_savedMatrix; | 79 const SkMatrix m_savedMatrix; |
88 bool m_savedShouldSmoothFonts; | 80 bool m_savedShouldSmoothFonts; |
89 RegionTrackingMode m_regionTrackingMode; | 81 RegionTrackingMode m_regionTrackingMode; |
90 }; | 82 }; |
91 | 83 |
92 GraphicsContext::GraphicsContext(SkCanvas* canvas, DisabledMode disableContextOr
Painting) | 84 GraphicsContext::GraphicsContext(SkCanvas* canvas, DisabledMode disableContextOr
Painting) |
93 : m_canvas(canvas) | 85 : m_canvas(canvas) |
94 , m_paintStateStack() | 86 , m_paintStateStack() |
95 , m_paintStateIndex(0) | 87 , m_paintStateIndex(0) |
96 , m_pendingCanvasSave(false) | |
97 , m_annotationMode(0) | 88 , m_annotationMode(0) |
98 #if ENABLE(ASSERT) | 89 #if ENABLE(ASSERT) |
99 , m_annotationCount(0) | 90 , m_annotationCount(0) |
100 , m_layerCount(0) | 91 , m_layerCount(0) |
101 , m_disableDestructionChecks(false) | 92 , m_disableDestructionChecks(false) |
102 #endif | 93 #endif |
103 , m_disabledState(disableContextOrPainting) | 94 , m_disabledState(disableContextOrPainting) |
104 , m_deviceScaleFactor(1.0f) | 95 , m_deviceScaleFactor(1.0f) |
105 , m_regionTrackingMode(RegionTrackingDisabled) | 96 , m_regionTrackingMode(RegionTrackingDisabled) |
106 , m_trackTextRegion(false) | 97 , m_trackTextRegion(false) |
(...skipping 11 matching lines...) Expand all Loading... |
118 | 109 |
119 GraphicsContext::~GraphicsContext() | 110 GraphicsContext::~GraphicsContext() |
120 { | 111 { |
121 #if ENABLE(ASSERT) | 112 #if ENABLE(ASSERT) |
122 if (!m_disableDestructionChecks) { | 113 if (!m_disableDestructionChecks) { |
123 ASSERT(!m_paintStateIndex); | 114 ASSERT(!m_paintStateIndex); |
124 ASSERT(!m_paintState->saveCount()); | 115 ASSERT(!m_paintState->saveCount()); |
125 ASSERT(!m_annotationCount); | 116 ASSERT(!m_annotationCount); |
126 ASSERT(!m_layerCount); | 117 ASSERT(!m_layerCount); |
127 ASSERT(m_recordingStateStack.isEmpty()); | 118 ASSERT(m_recordingStateStack.isEmpty()); |
128 ASSERT(m_canvasStateStack.isEmpty()); | 119 ASSERT(!saveCount()); |
129 } | 120 } |
130 #endif | 121 #endif |
131 } | 122 } |
132 | 123 |
133 void GraphicsContext::resetCanvas(SkCanvas* canvas) | 124 void GraphicsContext::resetCanvas(SkCanvas* canvas) |
134 { | 125 { |
135 m_canvas = canvas; | 126 m_canvas = canvas; |
136 m_trackedRegion.reset(); | 127 m_trackedRegion.reset(); |
137 } | 128 } |
138 | 129 |
139 void GraphicsContext::setRegionTrackingMode(RegionTrackingMode mode) | 130 void GraphicsContext::setRegionTrackingMode(RegionTrackingMode mode) |
140 { | 131 { |
141 m_regionTrackingMode = mode; | 132 m_regionTrackingMode = mode; |
142 if (mode == RegionTrackingOpaque) | 133 if (mode == RegionTrackingOpaque) |
143 m_trackedRegion.setTrackedRegionType(RegionTracker::Opaque); | 134 m_trackedRegion.setTrackedRegionType(RegionTracker::Opaque); |
144 else if (mode == RegionTrackingOverwrite) | 135 else if (mode == RegionTrackingOverwrite) |
145 m_trackedRegion.setTrackedRegionType(RegionTracker::Overwrite); | 136 m_trackedRegion.setTrackedRegionType(RegionTracker::Overwrite); |
146 } | 137 } |
147 | 138 |
148 void GraphicsContext::save() | 139 void GraphicsContext::save() |
149 { | 140 { |
150 if (contextDisabled()) | 141 if (contextDisabled()) |
151 return; | 142 return; |
152 | 143 |
153 m_paintState->incrementSaveCount(); | 144 m_paintState->incrementSaveCount(); |
154 | 145 |
155 if (m_canvas) { | 146 ASSERT(m_canvas); |
156 m_canvasStateStack.append(CanvasSaveState(m_pendingCanvasSave, m_canvas-
>getSaveCount())); | 147 m_canvas->save(); |
157 m_pendingCanvasSave = true; | |
158 } | |
159 } | 148 } |
160 | 149 |
161 void GraphicsContext::restore() | 150 void GraphicsContext::restore() |
162 { | 151 { |
163 if (contextDisabled()) | 152 if (contextDisabled()) |
164 return; | 153 return; |
165 | 154 |
166 if (!m_paintStateIndex && !m_paintState->saveCount()) { | 155 if (!m_paintStateIndex && !m_paintState->saveCount()) { |
167 WTF_LOG_ERROR("ERROR void GraphicsContext::restore() stack is empty"); | 156 WTF_LOG_ERROR("ERROR void GraphicsContext::restore() stack is empty"); |
168 return; | 157 return; |
169 } | 158 } |
170 | 159 |
171 if (m_paintState->saveCount()) { | 160 if (m_paintState->saveCount()) { |
172 m_paintState->decrementSaveCount(); | 161 m_paintState->decrementSaveCount(); |
173 } else { | 162 } else { |
174 m_paintStateIndex--; | 163 m_paintStateIndex--; |
175 m_paintState = m_paintStateStack[m_paintStateIndex].get(); | 164 m_paintState = m_paintStateStack[m_paintStateIndex].get(); |
176 } | 165 } |
177 | 166 |
178 if (m_canvas) { | 167 ASSERT(m_canvas); |
179 ASSERT(m_canvasStateStack.size() > 0); | 168 m_canvas->restore(); |
180 CanvasSaveState savedState = m_canvasStateStack.last(); | |
181 m_canvasStateStack.removeLast(); | |
182 m_pendingCanvasSave = savedState.m_pendingSave; | |
183 m_canvas->restoreToCount(savedState.m_restoreCount); | |
184 } | |
185 } | 169 } |
186 | 170 |
| 171 #if ENABLE(ASSERT) |
| 172 unsigned GraphicsContext::saveCount() const |
| 173 { |
| 174 // Each m_paintStateStack entry implies an additional save op |
| 175 // (on top of its own saveCount), except for the first frame. |
| 176 unsigned count = m_paintStateIndex; |
| 177 ASSERT(m_paintStateStack.size() > m_paintStateIndex); |
| 178 for (unsigned i = 0; i <= m_paintStateIndex; ++i) |
| 179 count += m_paintStateStack[i]->saveCount(); |
| 180 |
| 181 return count; |
| 182 } |
| 183 #endif |
| 184 |
187 void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint) | 185 void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint) |
188 { | 186 { |
189 if (contextDisabled()) | 187 if (contextDisabled()) |
190 return; | 188 return; |
191 | 189 |
192 ASSERT(m_canvas); | 190 ASSERT(m_canvas); |
193 | 191 |
194 realizeCanvasSave(); | |
195 | |
196 m_canvas->saveLayer(bounds, paint); | 192 m_canvas->saveLayer(bounds, paint); |
197 if (regionTrackingEnabled()) | 193 if (regionTrackingEnabled()) |
198 m_trackedRegion.pushCanvasLayer(paint); | 194 m_trackedRegion.pushCanvasLayer(paint); |
199 } | 195 } |
200 | 196 |
201 void GraphicsContext::restoreLayer() | 197 void GraphicsContext::restoreLayer() |
202 { | 198 { |
203 if (contextDisabled()) | 199 if (contextDisabled()) |
204 return; | 200 return; |
205 | 201 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 ASSERT(m_canvas); | 416 ASSERT(m_canvas); |
421 return m_canvas->readPixels(info, pixels, rowBytes, x, y); | 417 return m_canvas->readPixels(info, pixels, rowBytes, x, y); |
422 } | 418 } |
423 | 419 |
424 void GraphicsContext::setMatrix(const SkMatrix& matrix) | 420 void GraphicsContext::setMatrix(const SkMatrix& matrix) |
425 { | 421 { |
426 if (contextDisabled()) | 422 if (contextDisabled()) |
427 return; | 423 return; |
428 | 424 |
429 ASSERT(m_canvas); | 425 ASSERT(m_canvas); |
430 realizeCanvasSave(); | |
431 | 426 |
432 m_canvas->setMatrix(matrix); | 427 m_canvas->setMatrix(matrix); |
433 } | 428 } |
434 | 429 |
435 void GraphicsContext::concat(const SkMatrix& matrix) | 430 void GraphicsContext::concat(const SkMatrix& matrix) |
436 { | 431 { |
437 if (contextDisabled()) | 432 if (contextDisabled()) |
438 return; | 433 return; |
439 | 434 |
440 if (matrix.isIdentity()) | 435 if (matrix.isIdentity()) |
441 return; | 436 return; |
442 | 437 |
443 ASSERT(m_canvas); | 438 ASSERT(m_canvas); |
444 realizeCanvasSave(); | |
445 | 439 |
446 m_canvas->concat(matrix); | 440 m_canvas->concat(matrix); |
447 } | 441 } |
448 | 442 |
449 void GraphicsContext::beginTransparencyLayer(float opacity, const FloatRect* bou
nds) | 443 void GraphicsContext::beginTransparencyLayer(float opacity, const FloatRect* bou
nds) |
450 { | 444 { |
451 beginLayer(opacity, immutableState()->compositeOperator(), bounds); | 445 beginLayer(opacity, immutableState()->compositeOperator(), bounds); |
452 } | 446 } |
453 | 447 |
454 void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const Floa
tRect* bounds, ColorFilter colorFilter, ImageFilter* imageFilter) | 448 void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const Floa
tRect* bounds, ColorFilter colorFilter, ImageFilter* imageFilter) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 bool performClip = !displayList->clip().isEmpty(); | 544 bool performClip = !displayList->clip().isEmpty(); |
551 bool performTransform = !displayList->transform().isIdentity(); | 545 bool performTransform = !displayList->transform().isIdentity(); |
552 if (performClip || performTransform) { | 546 if (performClip || performTransform) { |
553 save(); | 547 save(); |
554 if (performTransform) | 548 if (performTransform) |
555 concat(displayList->transform()); | 549 concat(displayList->transform()); |
556 if (performClip) | 550 if (performClip) |
557 clipRect(displayList->clip()); | 551 clipRect(displayList->clip()); |
558 } | 552 } |
559 | 553 |
560 realizeCanvasSave(); | |
561 | |
562 const FloatPoint& location = displayList->bounds().location(); | 554 const FloatPoint& location = displayList->bounds().location(); |
563 if (location.x() || location.y()) { | 555 if (location.x() || location.y()) { |
564 SkMatrix m; | 556 SkMatrix m; |
565 m.setTranslate(location.x(), location.y()); | 557 m.setTranslate(location.x(), location.y()); |
566 m_canvas->drawPicture(displayList->picture(), &m, 0); | 558 m_canvas->drawPicture(displayList->picture(), &m, 0); |
567 } else { | 559 } else { |
568 m_canvas->drawPicture(displayList->picture()); | 560 m_canvas->drawPicture(displayList->picture()); |
569 } | 561 } |
570 | 562 |
571 if (regionTrackingEnabled()) { | 563 if (regionTrackingEnabled()) { |
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 | 1568 |
1577 path.setFillType(previousFillType); | 1569 path.setFillType(previousFillType); |
1578 } | 1570 } |
1579 | 1571 |
1580 void GraphicsContext::clipRect(const SkRect& rect, AntiAliasingMode aa, SkRegion
::Op op) | 1572 void GraphicsContext::clipRect(const SkRect& rect, AntiAliasingMode aa, SkRegion
::Op op) |
1581 { | 1573 { |
1582 ASSERT(m_canvas); | 1574 ASSERT(m_canvas); |
1583 if (contextDisabled()) | 1575 if (contextDisabled()) |
1584 return; | 1576 return; |
1585 | 1577 |
1586 realizeCanvasSave(); | |
1587 | |
1588 m_canvas->clipRect(rect, op, aa == AntiAliased); | 1578 m_canvas->clipRect(rect, op, aa == AntiAliased); |
1589 } | 1579 } |
1590 | 1580 |
1591 void GraphicsContext::clipPath(const SkPath& path, AntiAliasingMode aa, SkRegion
::Op op) | 1581 void GraphicsContext::clipPath(const SkPath& path, AntiAliasingMode aa, SkRegion
::Op op) |
1592 { | 1582 { |
1593 ASSERT(m_canvas); | 1583 ASSERT(m_canvas); |
1594 if (contextDisabled()) | 1584 if (contextDisabled()) |
1595 return; | 1585 return; |
1596 | 1586 |
1597 realizeCanvasSave(); | |
1598 | |
1599 m_canvas->clipPath(path, op, aa == AntiAliased); | 1587 m_canvas->clipPath(path, op, aa == AntiAliased); |
1600 } | 1588 } |
1601 | 1589 |
1602 void GraphicsContext::clipRRect(const SkRRect& rect, AntiAliasingMode aa, SkRegi
on::Op op) | 1590 void GraphicsContext::clipRRect(const SkRRect& rect, AntiAliasingMode aa, SkRegi
on::Op op) |
1603 { | 1591 { |
1604 ASSERT(m_canvas); | 1592 ASSERT(m_canvas); |
1605 if (contextDisabled()) | 1593 if (contextDisabled()) |
1606 return; | 1594 return; |
1607 | 1595 |
1608 realizeCanvasSave(); | |
1609 | |
1610 m_canvas->clipRRect(rect, op, aa == AntiAliased); | 1596 m_canvas->clipRRect(rect, op, aa == AntiAliased); |
1611 } | 1597 } |
1612 | 1598 |
1613 void GraphicsContext::beginCull(const FloatRect& rect) | 1599 void GraphicsContext::beginCull(const FloatRect& rect) |
1614 { | 1600 { |
1615 ASSERT(m_canvas); | 1601 ASSERT(m_canvas); |
1616 if (contextDisabled()) | 1602 if (contextDisabled()) |
1617 return; | 1603 return; |
1618 | 1604 |
1619 realizeCanvasSave(); | |
1620 m_canvas->pushCull(rect); | 1605 m_canvas->pushCull(rect); |
1621 } | 1606 } |
1622 | 1607 |
1623 void GraphicsContext::endCull() | 1608 void GraphicsContext::endCull() |
1624 { | 1609 { |
1625 ASSERT(m_canvas); | 1610 ASSERT(m_canvas); |
1626 if (contextDisabled()) | 1611 if (contextDisabled()) |
1627 return; | 1612 return; |
1628 | 1613 |
1629 realizeCanvasSave(); | |
1630 | |
1631 m_canvas->popCull(); | 1614 m_canvas->popCull(); |
1632 } | 1615 } |
1633 | 1616 |
1634 void GraphicsContext::rotate(float angleInRadians) | 1617 void GraphicsContext::rotate(float angleInRadians) |
1635 { | 1618 { |
1636 ASSERT(m_canvas); | 1619 ASSERT(m_canvas); |
1637 if (contextDisabled()) | 1620 if (contextDisabled()) |
1638 return; | 1621 return; |
1639 | 1622 |
1640 realizeCanvasSave(); | |
1641 | |
1642 m_canvas->rotate(WebCoreFloatToSkScalar(angleInRadians * (180.0f / 3.1415926
5f))); | 1623 m_canvas->rotate(WebCoreFloatToSkScalar(angleInRadians * (180.0f / 3.1415926
5f))); |
1643 } | 1624 } |
1644 | 1625 |
1645 void GraphicsContext::translate(float x, float y) | 1626 void GraphicsContext::translate(float x, float y) |
1646 { | 1627 { |
1647 ASSERT(m_canvas); | 1628 ASSERT(m_canvas); |
1648 if (contextDisabled()) | 1629 if (contextDisabled()) |
1649 return; | 1630 return; |
1650 | 1631 |
1651 if (!x && !y) | 1632 if (!x && !y) |
1652 return; | 1633 return; |
1653 | 1634 |
1654 realizeCanvasSave(); | |
1655 | |
1656 m_canvas->translate(WebCoreFloatToSkScalar(x), WebCoreFloatToSkScalar(y)); | 1635 m_canvas->translate(WebCoreFloatToSkScalar(x), WebCoreFloatToSkScalar(y)); |
1657 } | 1636 } |
1658 | 1637 |
1659 void GraphicsContext::scale(float x, float y) | 1638 void GraphicsContext::scale(float x, float y) |
1660 { | 1639 { |
1661 ASSERT(m_canvas); | 1640 ASSERT(m_canvas); |
1662 if (contextDisabled()) | 1641 if (contextDisabled()) |
1663 return; | 1642 return; |
1664 | 1643 |
1665 if (x == 1.0f && y == 1.0f) | 1644 if (x == 1.0f && y == 1.0f) |
1666 return; | 1645 return; |
1667 | 1646 |
1668 realizeCanvasSave(); | |
1669 | |
1670 m_canvas->scale(WebCoreFloatToSkScalar(x), WebCoreFloatToSkScalar(y)); | 1647 m_canvas->scale(WebCoreFloatToSkScalar(x), WebCoreFloatToSkScalar(y)); |
1671 } | 1648 } |
1672 | 1649 |
1673 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) | 1650 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) |
1674 { | 1651 { |
1675 ASSERT(m_canvas); | 1652 ASSERT(m_canvas); |
1676 if (contextDisabled()) | 1653 if (contextDisabled()) |
1677 return; | 1654 return; |
1678 | 1655 |
1679 SkAutoDataUnref url(SkData::NewWithCString(link.string().utf8().data())); | 1656 SkAutoDataUnref url(SkData::NewWithCString(link.string().utf8().data())); |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2013 // FIXME: This is to not break tests (it results in the filter bitmap fl
ag | 1990 // FIXME: This is to not break tests (it results in the filter bitmap fl
ag |
2014 // being set to true). We need to decide if we respect InterpolationNone | 1991 // being set to true). We need to decide if we respect InterpolationNone |
2015 // being returned from computeInterpolationQuality. | 1992 // being returned from computeInterpolationQuality. |
2016 resampling = InterpolationLow; | 1993 resampling = InterpolationLow; |
2017 } | 1994 } |
2018 resampling = limitInterpolationQuality(this, resampling); | 1995 resampling = limitInterpolationQuality(this, resampling); |
2019 paint->setFilterLevel(static_cast<SkPaint::FilterLevel>(resampling)); | 1996 paint->setFilterLevel(static_cast<SkPaint::FilterLevel>(resampling)); |
2020 } | 1997 } |
2021 | 1998 |
2022 } // namespace blink | 1999 } // namespace blink |
OLD | NEW |