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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 RegionTrackingMode m_regionTrackingMode; | 81 RegionTrackingMode m_regionTrackingMode; |
82 }; | 82 }; |
83 | 83 |
84 GraphicsContext::GraphicsContext(SkCanvas* canvas, DisabledMode disableContextOr Painting) | 84 GraphicsContext::GraphicsContext(SkCanvas* canvas, DisabledMode disableContextOr Painting) |
85 : m_canvas(canvas) | 85 : m_canvas(canvas) |
86 , m_paintStateStack() | 86 , m_paintStateStack() |
87 , m_paintStateIndex(0) | 87 , m_paintStateIndex(0) |
88 , m_annotationMode(0) | 88 , m_annotationMode(0) |
89 #if ENABLE(ASSERT) | 89 #if ENABLE(ASSERT) |
90 , m_annotationCount(0) | 90 , m_annotationCount(0) |
91 , m_layerCount(0) | |
92 , m_disableDestructionChecks(false) | 91 , m_disableDestructionChecks(false) |
93 #endif | 92 #endif |
94 , m_disabledState(disableContextOrPainting) | 93 , m_disabledState(disableContextOrPainting) |
95 , m_deviceScaleFactor(1.0f) | 94 , m_deviceScaleFactor(1.0f) |
96 , m_regionTrackingMode(RegionTrackingDisabled) | 95 , m_regionTrackingMode(RegionTrackingDisabled) |
97 , m_trackTextRegion(false) | 96 , m_trackTextRegion(false) |
98 , m_accelerated(false) | 97 , m_accelerated(false) |
99 , m_isCertainlyOpaque(true) | 98 , m_isCertainlyOpaque(true) |
100 , m_printing(false) | 99 , m_printing(false) |
101 , m_antialiasHairlineImages(false) | 100 , m_antialiasHairlineImages(false) |
102 , m_shouldSmoothFonts(true) | 101 , m_shouldSmoothFonts(true) |
103 { | 102 { |
104 // FIXME: Do some tests to determine how many states are typically used, and allocate | 103 // FIXME: Do some tests to determine how many states are typically used, and allocate |
105 // several here. | 104 // several here. |
106 m_paintStateStack.append(GraphicsContextState::create()); | 105 m_paintStateStack.append(GraphicsContextState::create()); |
107 m_paintState = m_paintStateStack.last().get(); | 106 m_paintState = m_paintStateStack.last().get(); |
108 } | 107 } |
109 | 108 |
110 GraphicsContext::~GraphicsContext() | 109 GraphicsContext::~GraphicsContext() |
111 { | 110 { |
112 #if ENABLE(ASSERT) | 111 #if ENABLE(ASSERT) |
113 if (!m_disableDestructionChecks) { | 112 if (!m_disableDestructionChecks) { |
114 ASSERT(!m_paintStateIndex); | 113 ASSERT(!m_paintStateIndex); |
115 ASSERT(!m_paintState->saveCount()); | 114 ASSERT(!m_paintState->saveCount()); |
116 ASSERT(!m_annotationCount); | 115 ASSERT(!m_annotationCount); |
117 ASSERT(!m_layerCount); | 116 ASSERT(m_clipStackPointersOfLayerStack.isEmpty()); |
118 ASSERT(m_recordingStateStack.isEmpty()); | 117 ASSERT(m_recordingStateStack.isEmpty()); |
119 ASSERT(!saveCount()); | 118 ASSERT(!saveCount()); |
120 } | 119 } |
121 #endif | 120 #endif |
122 } | 121 } |
123 | 122 |
124 void GraphicsContext::resetCanvas(SkCanvas* canvas) | 123 void GraphicsContext::resetCanvas(SkCanvas* canvas) |
125 { | 124 { |
126 m_canvas = canvas; | 125 m_canvas = canvas; |
127 m_trackedRegion.reset(); | 126 m_trackedRegion.reset(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 // (on top of its own saveCount), except for the first frame. | 174 // (on top of its own saveCount), except for the first frame. |
176 unsigned count = m_paintStateIndex; | 175 unsigned count = m_paintStateIndex; |
177 ASSERT(m_paintStateStack.size() > m_paintStateIndex); | 176 ASSERT(m_paintStateStack.size() > m_paintStateIndex); |
178 for (unsigned i = 0; i <= m_paintStateIndex; ++i) | 177 for (unsigned i = 0; i <= m_paintStateIndex; ++i) |
179 count += m_paintStateStack[i]->saveCount(); | 178 count += m_paintStateStack[i]->saveCount(); |
180 | 179 |
181 return count; | 180 return count; |
182 } | 181 } |
183 #endif | 182 #endif |
184 | 183 |
184 static unsigned getClipStackPointer(const SkCanvas* canvas) | |
185 { | |
186 SkClipStack::B2TIter iter(*canvas->getClipStack()); | |
187 const SkClipStack::Element* element = iter.next(); | |
188 unsigned stackPointer = 0; | |
189 while (element) { | |
190 stackPointer++; | |
191 element = iter.next(); | |
192 } | |
193 return stackPointer; | |
194 } | |
195 | |
185 void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint) | 196 void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint) |
186 { | 197 { |
187 if (contextDisabled()) | 198 if (contextDisabled()) |
188 return; | 199 return; |
189 | 200 |
190 ASSERT(m_canvas); | 201 ASSERT(m_canvas); |
191 | 202 |
192 m_canvas->saveLayer(bounds, paint); | 203 m_canvas->saveLayer(bounds, paint); |
193 if (regionTrackingEnabled()) | 204 if (regionTrackingEnabled()) |
194 m_trackedRegion.pushCanvasLayer(paint); | 205 m_trackedRegion.pushCanvasLayer(paint); |
206 m_clipStackPointersOfLayerStack.append(getClipStackPointer(m_canvas)); | |
195 } | 207 } |
196 | 208 |
197 void GraphicsContext::restoreLayer() | 209 void GraphicsContext::restoreLayer() |
198 { | 210 { |
199 if (contextDisabled()) | 211 if (contextDisabled()) |
200 return; | 212 return; |
201 | 213 |
202 ASSERT(m_canvas); | 214 ASSERT(m_canvas); |
215 ASSERT(m_clipStackPointersOfLayerStack.size() > 0); | |
216 | |
217 // beginLayer()/endLayer() must not expose states stacking mechanism. | |
218 // Currently SkCanvas::save()/restore() in GraphicsContext affected only ctm and clip. | |
219 SkMatrix currentCTM = m_canvas->getTotalMatrix(); | |
220 SkClipStack currentSkClipStack(*m_canvas->getClipStack()); | |
Justin Novosad
2014/10/16 17:51:58
Seems unfortunate to duplicate the entire clip sta
| |
203 | 221 |
204 m_canvas->restore(); | 222 m_canvas->restore(); |
205 if (regionTrackingEnabled()) | 223 if (regionTrackingEnabled()) |
206 m_trackedRegion.popCanvasLayer(this); | 224 m_trackedRegion.popCanvasLayer(this); |
225 | |
226 // SkCanvas::clipXXX() transforms a rect/path by CTM. | |
227 m_canvas->resetMatrix(); | |
228 | |
229 static const SkRect kEmptyRect = { 0, 0, 0, 0 }; | |
230 SkClipStack::B2TIter iter(currentSkClipStack); | |
231 const SkClipStack::Element* element = nullptr; | |
232 unsigned stackPointer = m_clipStackPointersOfLayerStack.last(); | |
233 m_clipStackPointersOfLayerStack.removeLast(); | |
234 for (unsigned i = 0; i < stackPointer; i++) { | |
235 iter.next(); | |
236 } | |
237 element = iter.next(); | |
238 while (element) { | |
239 switch (element->getType()) { | |
240 case SkClipStack::Element::kPath_Type: | |
241 m_canvas->clipPath(element->getPath(), element->getOp(), element->is AA()); | |
242 break; | |
243 case SkClipStack::Element::kRRect_Type: | |
244 m_canvas->clipRRect(element->getRRect(), element->getOp(), element-> isAA()); | |
245 break; | |
246 case SkClipStack::Element::kRect_Type: | |
247 m_canvas->clipRect(element->getRect(), element->getOp(), element->is AA()); | |
248 break; | |
249 case SkClipStack::Element::kEmpty_Type: | |
250 m_canvas->clipRect(kEmptyRect, SkRegion::kIntersect_Op, false); | |
251 break; | |
252 } | |
253 element = iter.next(); | |
254 } | |
255 | |
256 m_canvas->setMatrix(currentCTM); | |
207 } | 257 } |
dshwang
2014/10/16 15:58:20
Feel like using implementation detail of skia, but
Justin Novosad
2014/10/16 17:51:58
I agree. reverse engineering the state seems unfor
| |
208 | 258 |
209 void GraphicsContext::beginAnnotation(const AnnotationList& annotations) | 259 void GraphicsContext::beginAnnotation(const AnnotationList& annotations) |
210 { | 260 { |
211 if (contextDisabled()) | 261 if (contextDisabled()) |
212 return; | 262 return; |
213 | 263 |
214 ASSERT(m_canvas); | 264 ASSERT(m_canvas); |
215 | 265 |
216 canvas()->beginCommentGroup("GraphicsContextAnnotation"); | 266 canvas()->beginCommentGroup("GraphicsContextAnnotation"); |
217 | 267 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
455 layerPaint.setXfermodeMode(WebCoreCompositeToSkiaComposite(op, m_paintState- >blendMode())); | 505 layerPaint.setXfermodeMode(WebCoreCompositeToSkiaComposite(op, m_paintState- >blendMode())); |
456 layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).g et()); | 506 layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).g et()); |
457 layerPaint.setImageFilter(imageFilter); | 507 layerPaint.setImageFilter(imageFilter); |
458 | 508 |
459 if (bounds) { | 509 if (bounds) { |
460 SkRect skBounds = WebCoreFloatRectToSKRect(*bounds); | 510 SkRect skBounds = WebCoreFloatRectToSKRect(*bounds); |
461 saveLayer(&skBounds, &layerPaint); | 511 saveLayer(&skBounds, &layerPaint); |
462 } else { | 512 } else { |
463 saveLayer(0, &layerPaint); | 513 saveLayer(0, &layerPaint); |
464 } | 514 } |
465 | |
466 #if ENABLE(ASSERT) | |
467 ++m_layerCount; | |
468 #endif | |
469 } | 515 } |
470 | 516 |
471 void GraphicsContext::endLayer() | 517 void GraphicsContext::endLayer() |
472 { | 518 { |
473 if (contextDisabled()) | 519 if (contextDisabled()) |
474 return; | 520 return; |
475 | 521 |
476 restoreLayer(); | 522 restoreLayer(); |
477 | |
478 ASSERT(m_layerCount > 0); | |
479 #if ENABLE(ASSERT) | |
480 --m_layerCount; | |
481 #endif | |
482 } | 523 } |
483 | 524 |
484 void GraphicsContext::beginRecording(const FloatRect& bounds, uint32_t recordFla gs) | 525 void GraphicsContext::beginRecording(const FloatRect& bounds, uint32_t recordFla gs) |
485 { | 526 { |
486 RefPtr<DisplayList> displayList = DisplayList::create(bounds); | 527 RefPtr<DisplayList> displayList = DisplayList::create(bounds); |
487 | 528 |
488 SkCanvas* savedCanvas = m_canvas; | 529 SkCanvas* savedCanvas = m_canvas; |
489 SkMatrix savedMatrix = getTotalMatrix(); | 530 SkMatrix savedMatrix = getTotalMatrix(); |
490 SkPictureRecorder* recorder = 0; | 531 SkPictureRecorder* recorder = 0; |
491 | 532 |
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1990 // FIXME: This is to not break tests (it results in the filter bitmap fl ag | 2031 // FIXME: This is to not break tests (it results in the filter bitmap fl ag |
1991 // being set to true). We need to decide if we respect InterpolationNone | 2032 // being set to true). We need to decide if we respect InterpolationNone |
1992 // being returned from computeInterpolationQuality. | 2033 // being returned from computeInterpolationQuality. |
1993 resampling = InterpolationLow; | 2034 resampling = InterpolationLow; |
1994 } | 2035 } |
1995 resampling = limitInterpolationQuality(this, resampling); | 2036 resampling = limitInterpolationQuality(this, resampling); |
1996 paint->setFilterLevel(static_cast<SkPaint::FilterLevel>(resampling)); | 2037 paint->setFilterLevel(static_cast<SkPaint::FilterLevel>(resampling)); |
1997 } | 2038 } |
1998 | 2039 |
1999 } // namespace blink | 2040 } // namespace blink |
OLD | NEW |