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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: Source/platform/graphics/GraphicsContext.cpp
diff --git a/Source/platform/graphics/GraphicsContext.cpp b/Source/platform/graphics/GraphicsContext.cpp
index c75c0cf53327cf7d8f54e8286c2eb75ceeb637f3..d40eff4a59e3c033a37fbb437f088f6032dae257 100644
--- a/Source/platform/graphics/GraphicsContext.cpp
+++ b/Source/platform/graphics/GraphicsContext.cpp
@@ -88,7 +88,6 @@ GraphicsContext::GraphicsContext(SkCanvas* canvas, DisabledMode disableContextOr
, m_annotationMode(0)
#if ENABLE(ASSERT)
, m_annotationCount(0)
- , m_layerCount(0)
, m_disableDestructionChecks(false)
#endif
, m_disabledState(disableContextOrPainting)
@@ -114,7 +113,7 @@ GraphicsContext::~GraphicsContext()
ASSERT(!m_paintStateIndex);
ASSERT(!m_paintState->saveCount());
ASSERT(!m_annotationCount);
- ASSERT(!m_layerCount);
+ ASSERT(m_clipStackPointersOfLayerStack.isEmpty());
ASSERT(m_recordingStateStack.isEmpty());
ASSERT(!saveCount());
}
@@ -182,6 +181,18 @@ unsigned GraphicsContext::saveCount() const
}
#endif
+static unsigned getClipStackPointer(const SkCanvas* canvas)
+{
+ SkClipStack::B2TIter iter(*canvas->getClipStack());
+ const SkClipStack::Element* element = iter.next();
+ unsigned stackPointer = 0;
+ while (element) {
+ stackPointer++;
+ element = iter.next();
+ }
+ return stackPointer;
+}
+
void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint)
{
if (contextDisabled())
@@ -192,6 +203,7 @@ void GraphicsContext::saveLayer(const SkRect* bounds, const SkPaint* paint)
m_canvas->saveLayer(bounds, paint);
if (regionTrackingEnabled())
m_trackedRegion.pushCanvasLayer(paint);
+ m_clipStackPointersOfLayerStack.append(getClipStackPointer(m_canvas));
}
void GraphicsContext::restoreLayer()
@@ -200,10 +212,48 @@ void GraphicsContext::restoreLayer()
return;
ASSERT(m_canvas);
+ ASSERT(m_clipStackPointersOfLayerStack.size() > 0);
+
+ // beginLayer()/endLayer() must not expose states stacking mechanism.
+ // Currently SkCanvas::save()/restore() in GraphicsContext affected only ctm and clip.
+ SkMatrix currentCTM = m_canvas->getTotalMatrix();
+ SkClipStack currentSkClipStack(*m_canvas->getClipStack());
Justin Novosad 2014/10/16 17:51:58 Seems unfortunate to duplicate the entire clip sta
m_canvas->restore();
if (regionTrackingEnabled())
m_trackedRegion.popCanvasLayer(this);
+
+ // SkCanvas::clipXXX() transforms a rect/path by CTM.
+ m_canvas->resetMatrix();
+
+ static const SkRect kEmptyRect = { 0, 0, 0, 0 };
+ SkClipStack::B2TIter iter(currentSkClipStack);
+ const SkClipStack::Element* element = nullptr;
+ unsigned stackPointer = m_clipStackPointersOfLayerStack.last();
+ m_clipStackPointersOfLayerStack.removeLast();
+ for (unsigned i = 0; i < stackPointer; i++) {
+ iter.next();
+ }
+ element = iter.next();
+ while (element) {
+ switch (element->getType()) {
+ case SkClipStack::Element::kPath_Type:
+ m_canvas->clipPath(element->getPath(), element->getOp(), element->isAA());
+ break;
+ case SkClipStack::Element::kRRect_Type:
+ m_canvas->clipRRect(element->getRRect(), element->getOp(), element->isAA());
+ break;
+ case SkClipStack::Element::kRect_Type:
+ m_canvas->clipRect(element->getRect(), element->getOp(), element->isAA());
+ break;
+ case SkClipStack::Element::kEmpty_Type:
+ m_canvas->clipRect(kEmptyRect, SkRegion::kIntersect_Op, false);
+ break;
+ }
+ element = iter.next();
+ }
+
+ m_canvas->setMatrix(currentCTM);
}
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
void GraphicsContext::beginAnnotation(const AnnotationList& annotations)
@@ -462,10 +512,6 @@ void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const Floa
} else {
saveLayer(0, &layerPaint);
}
-
-#if ENABLE(ASSERT)
- ++m_layerCount;
-#endif
}
void GraphicsContext::endLayer()
@@ -474,11 +520,6 @@ void GraphicsContext::endLayer()
return;
restoreLayer();
-
- ASSERT(m_layerCount > 0);
-#if ENABLE(ASSERT)
- --m_layerCount;
-#endif
}
void GraphicsContext::beginRecording(const FloatRect& bounds, uint32_t recordFlags)

Powered by Google App Engine
This is Rietveld 408576698