WebKit Bugzilla
Attachment 369836 Details for
Bug 197836
: Event region computation should respect transforms
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch
event-region-transform-4.patch (text/plain), 15.67 KB, created by
Antti Koivisto
on 2019-05-14 05:18:39 PDT
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Antti Koivisto
Created:
2019-05-14 05:18:39 PDT
Size:
15.67 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 245274) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,48 @@ >+2019-05-14 Antti Koivisto <antti@apple.com> >+ >+ Event region computation should respect transforms >+ https://bugs.webkit.org/show_bug.cgi?id=197836 >+ <rdar://problem/50762971> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * platform/graphics/transforms/AffineTransform.cpp: >+ (WebCore::AffineTransform::mapRegion const): >+ >+ Add support for transforming regions. Non-rectlinear results use enclosing rects. >+ >+ * platform/graphics/transforms/AffineTransform.h: >+ * rendering/EventRegion.cpp: >+ (WebCore::EventRegionContext::EventRegionContext): >+ (WebCore::EventRegionContext::pushTransform): >+ (WebCore::EventRegionContext::popTransform): >+ (WebCore::EventRegionContext::unite): >+ (WebCore::EventRegionContext::contains const): >+ >+ Add a context object that holds the current transform. >+ >+ * rendering/EventRegion.h: >+ (WebCore::EventRegion::makeContext): >+ * rendering/InlineTextBox.cpp: >+ (WebCore::InlineTextBox::paint): >+ * rendering/PaintInfo.h: >+ >+ Replace the region object with the context. >+ >+ * rendering/RenderBlock.cpp: >+ (WebCore::RenderBlock::paintObject): >+ * rendering/RenderLayer.cpp: >+ (WebCore::RenderLayer::paintLayerByApplyingTransform): >+ >+ Apply transforms to regions if needed. >+ >+ (WebCore::RenderLayer::collectEventRegionForFragments): >+ * rendering/RenderLayer.h: >+ * rendering/RenderLayerBacking.cpp: >+ (WebCore::RenderLayerBacking::updateEventRegion): >+ * rendering/SimpleLineLayoutFunctions.cpp: >+ (WebCore::SimpleLineLayout::paintFlow): >+ > 2019-05-13 Yusuke Suzuki <ysuzuki@apple.com> > > Unreviewed, build fix after 245258, missing ThreadSpecific.h include >Index: Source/WebCore/platform/graphics/transforms/AffineTransform.cpp >=================================================================== >--- Source/WebCore/platform/graphics/transforms/AffineTransform.cpp (revision 245274) >+++ Source/WebCore/platform/graphics/transforms/AffineTransform.cpp (working copy) >@@ -31,6 +31,7 @@ > #include "FloatQuad.h" > #include "FloatRect.h" > #include "IntRect.h" >+#include "Region.h" > #include "TransformationMatrix.h" > #include <wtf/MathExtras.h> > #include <wtf/Optional.h> >@@ -334,6 +335,21 @@ FloatQuad AffineTransform::mapQuad(const > return result; > } > >+Region AffineTransform::mapRegion(const Region& region) const >+{ >+ if (isIdentityOrTranslation()) { >+ Region mappedRegion(region); >+ mappedRegion.translate(roundedIntSize(FloatSize(narrowPrecisionToFloat(m_transform[4]), narrowPrecisionToFloat(m_transform[5])))); >+ return mappedRegion; >+ } >+ >+ Region mappedRegion; >+ for (auto& rect : region.rects()) >+ mappedRegion.unite(mapRect(rect)); >+ >+ return mappedRegion; >+} >+ > void AffineTransform::blend(const AffineTransform& from, double progress) > { > DecomposedType srA, srB; >Index: Source/WebCore/platform/graphics/transforms/AffineTransform.h >=================================================================== >--- Source/WebCore/platform/graphics/transforms/AffineTransform.h (revision 245274) >+++ Source/WebCore/platform/graphics/transforms/AffineTransform.h (working copy) >@@ -53,6 +53,7 @@ class FloatSize; > class IntPoint; > class IntSize; > class IntRect; >+class Region; > class TransformationMatrix; > > class AffineTransform { >@@ -89,6 +90,8 @@ public: > WEBCORE_EXPORT FloatRect mapRect(const FloatRect&) const; > WEBCORE_EXPORT FloatQuad mapQuad(const FloatQuad&) const; > >+ WEBCORE_EXPORT Region mapRegion(const Region&) const; >+ > WEBCORE_EXPORT bool isIdentity() const; > > double a() const { return m_transform[0]; } >Index: Source/WebCore/rendering/EventRegion.cpp >=================================================================== >--- Source/WebCore/rendering/EventRegion.cpp (revision 245274) >+++ Source/WebCore/rendering/EventRegion.cpp (working copy) >@@ -30,6 +30,40 @@ > > namespace WebCore { > >+EventRegionContext::EventRegionContext(EventRegion& eventRegion) >+ : m_eventRegion(eventRegion) >+{ >+} >+ >+void EventRegionContext::pushTransform(const AffineTransform& transform) >+{ >+ if (m_transformStack.isEmpty()) >+ m_transformStack.append(transform); >+ else >+ m_transformStack.append(m_transformStack.last() * transform); >+} >+ >+void EventRegionContext::popTransform() >+{ >+ m_transformStack.removeLast(); >+} >+ >+void EventRegionContext::unite(const Region& region, const RenderStyle& style) >+{ >+ if (m_transformStack.isEmpty()) >+ m_eventRegion.unite(region, style); >+ else >+ m_eventRegion.unite(m_transformStack.last().mapRegion(region), style); >+} >+ >+bool EventRegionContext::contains(const IntRect& rect) const >+{ >+ if (m_transformStack.isEmpty()) >+ return m_eventRegion.contains(rect); >+ >+ return m_eventRegion.contains(m_transformStack.last().mapRect(rect)); >+} >+ > EventRegion::EventRegion() = default; > > bool EventRegion::operator==(const EventRegion& other) const >Index: Source/WebCore/rendering/EventRegion.h >=================================================================== >--- Source/WebCore/rendering/EventRegion.h (revision 245274) >+++ Source/WebCore/rendering/EventRegion.h (working copy) >@@ -25,6 +25,7 @@ > > #pragma once > >+#include "AffineTransform.h" > #include "Region.h" > #include "TouchAction.h" > #include <wtf/OptionSet.h> >@@ -32,12 +33,30 @@ > > namespace WebCore { > >+class EventRegion; > class RenderStyle; > >+class EventRegionContext { >+public: >+ EventRegionContext(EventRegion&); >+ >+ void pushTransform(const AffineTransform&); >+ void popTransform(); >+ >+ void unite(const Region&, const RenderStyle&); >+ bool contains(const IntRect&) const; >+ >+private: >+ EventRegion& m_eventRegion; >+ Vector<AffineTransform> m_transformStack; >+}; >+ > class EventRegion { > public: > WEBCORE_EXPORT EventRegion(); > >+ EventRegionContext makeContext() { return { *this }; } >+ > bool isEmpty() const { return m_region.isEmpty(); } > > WEBCORE_EXPORT bool operator==(const EventRegion&) const; >Index: Source/WebCore/rendering/InlineTextBox.cpp >=================================================================== >--- Source/WebCore/rendering/InlineTextBox.cpp (revision 245274) >+++ Source/WebCore/rendering/InlineTextBox.cpp (working copy) >@@ -505,7 +505,7 @@ void InlineTextBox::paint(PaintInfo& pai > > if (paintInfo.phase == PaintPhase::EventRegion) { > if (visibleToHitTesting()) >- paintInfo.eventRegion->unite(enclosingIntRect(boxRect), renderer().style()); >+ paintInfo.eventRegionContext->unite(enclosingIntRect(boxRect), renderer().style()); > return; > } > >Index: Source/WebCore/rendering/PaintInfo.h >=================================================================== >--- Source/WebCore/rendering/PaintInfo.h (revision 245274) >+++ Source/WebCore/rendering/PaintInfo.h (working copy) >@@ -37,7 +37,7 @@ > > namespace WebCore { > >-class EventRegion; >+class EventRegionContext; > class OverlapTestRequestClient; > class RenderInline; > class RenderLayer; >@@ -130,7 +130,8 @@ struct PaintInfo { > const RenderLayerModelObject* paintContainer; // the layer object that originates the current painting > bool requireSecurityOriginAccessForWidgets { false }; > const RenderLayer* m_enclosingSelfPaintingLayer { nullptr }; >- EventRegion* eventRegion { nullptr }; // For PaintPhase::EventRegion. >+ EventRegionContext* eventRegionContext { nullptr }; // For PaintPhase::EventRegion. >+ > private: > GraphicsContext* m_context; > }; >Index: Source/WebCore/rendering/RenderBlock.cpp >=================================================================== >--- Source/WebCore/rendering/RenderBlock.cpp (revision 245274) >+++ Source/WebCore/rendering/RenderBlock.cpp (working copy) >@@ -1246,11 +1246,11 @@ void RenderBlock::paintObject(PaintInfo& > > if (visibleToHitTesting()) { > auto borderRegion = approximateAsRegion(style().getRoundedBorderFor(borderRect)); >- paintInfo.eventRegion->unite(borderRegion, style()); >+ paintInfo.eventRegionContext->unite(borderRegion, style()); > } > > // No need to check descendants if we don't have overflow and the area is already covered. >- bool needsTraverseDescendants = hasVisualOverflow() || !paintInfo.eventRegion->contains(enclosingIntRect(borderRect)); >+ bool needsTraverseDescendants = hasVisualOverflow() || !paintInfo.eventRegionContext->contains(enclosingIntRect(borderRect)); > #if PLATFORM(IOS_FAMILY) && ENABLE(POINTER_EVENTS) > needsTraverseDescendants = needsTraverseDescendants || document().touchActionElements(); > #endif >Index: Source/WebCore/rendering/RenderLayer.cpp >=================================================================== >--- Source/WebCore/rendering/RenderLayer.cpp (revision 245274) >+++ Source/WebCore/rendering/RenderLayer.cpp (working copy) >@@ -4600,8 +4600,12 @@ void RenderLayer::paintLayerByApplyingTr > // Translate the graphics context to the snapping position to avoid off-device-pixel positing. > transform.translateRight(devicePixelSnappedOffsetForThisLayer.width(), devicePixelSnappedOffsetForThisLayer.height()); > // Apply the transform. >- AffineTransform oldTransfrom = context.getCTM(); >- context.concatCTM(transform.toAffineTransform()); >+ auto oldTransfrom = context.getCTM(); >+ auto affineTransform = transform.toAffineTransform(); >+ context.concatCTM(affineTransform); >+ >+ if (paintingInfo.eventRegionContext) >+ paintingInfo.eventRegionContext->pushTransform(affineTransform); > > // Now do a paint with the root layer shifted to be us. > LayoutSize adjustedSubpixelOffset = offsetForThisLayer - LayoutSize(devicePixelSnappedOffsetForThisLayer); >@@ -4610,6 +4614,10 @@ void RenderLayer::paintLayerByApplyingTr > transformedPaintingInfo.paintDirtyRect = LayoutRect(encloseRectToDevicePixels(transform.inverse().valueOr(AffineTransform()).mapRect(paintingInfo.paintDirtyRect), deviceScaleFactor)); > transformedPaintingInfo.subpixelOffset = adjustedSubpixelOffset; > paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags); >+ >+ if (paintingInfo.eventRegionContext) >+ paintingInfo.eventRegionContext->popTransform(); >+ > context.setCTM(oldTransfrom); > } > >@@ -4998,11 +5006,11 @@ void RenderLayer::paintOverflowControlsF > > void RenderLayer::collectEventRegionForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo) > { >- ASSERT(localPaintingInfo.eventRegion); >+ ASSERT(localPaintingInfo.eventRegionContext); > > for (const auto& fragment : layerFragments) { > PaintInfo paintInfo(context, fragment.foregroundRect.rect(), PaintPhase::EventRegion, { }); >- paintInfo.eventRegion = localPaintingInfo.eventRegion; >+ paintInfo.eventRegionContext = localPaintingInfo.eventRegionContext; > renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)); > } > } >Index: Source/WebCore/rendering/RenderLayer.h >=================================================================== >--- Source/WebCore/rendering/RenderLayer.h (revision 245274) >+++ Source/WebCore/rendering/RenderLayer.h (working copy) >@@ -63,7 +63,7 @@ namespace WebCore { > class CSSFilter; > class ClipRects; > class ClipRectsCache; >-class EventRegion; >+class EventRegionContext; > class HitTestRequest; > class HitTestResult; > class HitTestingTransformState; >@@ -941,7 +941,7 @@ private: > OptionSet<PaintBehavior> paintBehavior; > bool requireSecurityOriginAccessForWidgets; > bool clipToDirtyRect { true }; >- EventRegion* eventRegion { nullptr }; >+ EventRegionContext* eventRegionContext { nullptr }; > }; > > // Compute, cache and return clip rects computed with the given layer as the root. >Index: Source/WebCore/rendering/RenderLayerBacking.cpp >=================================================================== >--- Source/WebCore/rendering/RenderLayerBacking.cpp (revision 245274) >+++ Source/WebCore/rendering/RenderLayerBacking.cpp (working copy) >@@ -1484,7 +1484,8 @@ void RenderLayerBacking::updateEventRegi > RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, compositedBounds(), { }, LayoutSize()); > > EventRegion eventRegion; >- paintingInfo.eventRegion = &eventRegion; >+ auto eventRegionContext = eventRegion.makeContext(); >+ paintingInfo.eventRegionContext = &eventRegionContext; > > auto paintFlags = RenderLayer::paintLayerPaintingCompositingAllPhasesFlags() | RenderLayer::PaintLayerCollectingEventRegion; > m_owningLayer.paintLayerContents(nullContext, paintingInfo, paintFlags); >Index: Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp >=================================================================== >--- Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp (revision 245274) >+++ Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp (working copy) >@@ -84,7 +84,7 @@ void paintFlow(const RenderBlockFlow& fl > paintRect.moveBy(-paintOffset); > for (auto run : layout.runResolver().rangeForRect(paintRect)) { > FloatRect visualOverflowRect = computeOverflow(flow, run.rect()); >- paintInfo.eventRegion->unite(enclosingIntRect(visualOverflowRect), flow.style()); >+ paintInfo.eventRegionContext->unite(enclosingIntRect(visualOverflowRect), flow.style()); > } > return; > } >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 245274) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,14 @@ >+2019-05-14 Antti Koivisto <antti@apple.com> >+ >+ Event region computation should respect transforms >+ https://bugs.webkit.org/show_bug.cgi?id=197836 >+ <rdar://problem/50762971> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/scrolling/ios/event-region-scale-transform-shared-expected.txt: >+ * fast/scrolling/ios/event-region-translate-transform-shared-expected.txt: >+ > 2019-05-13 Wenson Hsieh <wenson_hsieh@apple.com> > > [iOS] When running layout tests that tap in the same location, subsequent tests fail to fire click handlers >Index: LayoutTests/fast/scrolling/ios/event-region-scale-transform-shared-expected.txt >=================================================================== >--- LayoutTests/fast/scrolling/ios/event-region-scale-transform-shared-expected.txt (revision 245274) >+++ LayoutTests/fast/scrolling/ios/event-region-scale-transform-shared-expected.txt (working copy) >@@ -19,8 +19,9 @@ > (bounds 201.00 201.00) > (drawsContent 1) > (event region >- (rect (0,0) width=200 height=200) >- (rect (200,200) width=100 height=100) >+ (rect (0,0) width=12 height=12) >+ (rect (51,51) width=100 height=100) >+ (rect (151,151) width=50 height=50) > ) > ) > ) >Index: LayoutTests/fast/scrolling/ios/event-region-translate-transform-shared-expected.txt >=================================================================== >--- LayoutTests/fast/scrolling/ios/event-region-translate-transform-shared-expected.txt (revision 245274) >+++ LayoutTests/fast/scrolling/ios/event-region-translate-transform-shared-expected.txt (working copy) >@@ -19,8 +19,9 @@ > (bounds 451.00 451.00) > (drawsContent 1) > (event region >- (rect (0,0) width=200 height=200) >- (rect (200,200) width=100 height=100) >+ (rect (0,0) width=12 height=12) >+ (rect (151,151) width=200 height=200) >+ (rect (351,351) width=100 height=100) > ) > ) > )
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
darin
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197836
:
369836
|
369867