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

Side by Side Diff: Source/platform/graphics/GraphicsContext.cpp

Issue 651243002: Clarify GraphicsContext::beginLayer()/endLayer() have unexpected behaviors. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: beginLayer()/endLayer() don't behave like save()/restore() Created 6 years, 2 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
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698