Title: [111471] trunk/Source/WebCore
Revision
111471
Author
[email protected]
Date
2012-03-20 17:04:13 -0700 (Tue, 20 Mar 2012)

Log Message

Add a per-ScrollableArea tile cache base class
https://bugs.webkit.org/show_bug.cgi?id=81694

Reviewed by Sam Weinig.

Add an abstract base class, TiledBacking, that can be used to inform tile caches about changed
state in scrollable areas (such as the currently visible rect, whether the page is active or not, etc).

Make TileCache inherit from TiledBacking and port updating the visible rect over to this new mechanism.

* WebCore.xcodeproj/project.pbxproj:
* page/FrameView.cpp:
(WebCore::FrameView::tiledBacking):
(WebCore):
* page/FrameView.h:
(FrameView):
* platform/ScrollableArea.h:
(WebCore):
(ScrollableArea):
(WebCore::ScrollableArea::tiledBacking):
* platform/graphics/GraphicsLayer.h:
(WebCore):
(WebCore::GraphicsLayer::tiledBacking):
* platform/graphics/TiledBacking.h: Added.
(WebCore):
(TiledBacking):
(WebCore::TiledBacking::~TiledBacking):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::tiledBacking):
* platform/graphics/ca/GraphicsLayerCA.h:
(GraphicsLayerCA):
* platform/graphics/ca/PlatformCALayer.h:
(PlatformCALayer):
* platform/graphics/ca/mac/PlatformCALayerMac.mm:
(PlatformCALayer::tiledBacking):
* platform/graphics/ca/mac/TileCache.h:
(TileCache):
* platform/graphics/ca/mac/WebTileCacheLayer.h:
(WebCore):
* platform/graphics/ca/mac/WebTileCacheLayer.mm:
(-[WebTileCacheLayer WebCore::]):
* platform/graphics/ca/win/PlatformCALayerWin.cpp:
(PlatformCALayer::tiledBacking):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::frameViewDidScroll):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (111470 => 111471)


--- trunk/Source/WebCore/ChangeLog	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/ChangeLog	2012-03-21 00:04:13 UTC (rev 111471)
@@ -1,3 +1,51 @@
+2012-03-20  Anders Carlsson  <[email protected]>
+
+        Add a per-ScrollableArea tile cache base class
+        https://bugs.webkit.org/show_bug.cgi?id=81694
+
+        Reviewed by Sam Weinig.
+
+        Add an abstract base class, TiledBacking, that can be used to inform tile caches about changed
+        state in scrollable areas (such as the currently visible rect, whether the page is active or not, etc).
+
+        Make TileCache inherit from TiledBacking and port updating the visible rect over to this new mechanism.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::tiledBacking):
+        (WebCore):
+        * page/FrameView.h:
+        (FrameView):
+        * platform/ScrollableArea.h:
+        (WebCore):
+        (ScrollableArea):
+        (WebCore::ScrollableArea::tiledBacking):
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore):
+        (WebCore::GraphicsLayer::tiledBacking):
+        * platform/graphics/TiledBacking.h: Added.
+        (WebCore):
+        (TiledBacking):
+        (WebCore::TiledBacking::~TiledBacking):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::tiledBacking):
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        (GraphicsLayerCA):
+        * platform/graphics/ca/PlatformCALayer.h:
+        (PlatformCALayer):
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm:
+        (PlatformCALayer::tiledBacking):
+        * platform/graphics/ca/mac/TileCache.h:
+        (TileCache):
+        * platform/graphics/ca/mac/WebTileCacheLayer.h:
+        (WebCore):
+        * platform/graphics/ca/mac/WebTileCacheLayer.mm:
+        (-[WebTileCacheLayer WebCore::]):
+        * platform/graphics/ca/win/PlatformCALayerWin.cpp:
+        (PlatformCALayer::tiledBacking):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::frameViewDidScroll):
+
 2012-03-20  Xiaomei Ji  <[email protected]>
 
         visual word movement: crashes on CSS generated content.

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (111470 => 111471)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-03-21 00:04:13 UTC (rev 111471)
@@ -598,6 +598,7 @@
 		1AF62F2414DAFE910041556C /* ScrollingThreadMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AF62F2314DAFE910041556C /* ScrollingThreadMac.mm */; };
 		1AF62F2514DAFE9E0041556C /* ScrollingThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF62F2014DAFE790041556C /* ScrollingThread.cpp */; };
 		1AF62F2614DAFEA10041556C /* ScrollingThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AF62F2114DAFE790041556C /* ScrollingThread.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		1AF89A421518FDEA00E547B5 /* TiledBacking.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AF89A411518FDEA00E547B5 /* TiledBacking.h */; };
 		1AF8E11A1256592600230FF7 /* ProxyServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AF8E1191256592600230FF7 /* ProxyServer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1AF8E13312565A4400230FF7 /* ProxyServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8E13212565A4400230FF7 /* ProxyServer.cpp */; };
 		1AF8E1C3125673E000230FF7 /* ProxyServerCFNet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8E1C1125673E000230FF7 /* ProxyServerCFNet.cpp */; };
@@ -7448,6 +7449,7 @@
 		1AF62F2014DAFE790041556C /* ScrollingThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingThread.cpp; sourceTree = "<group>"; };
 		1AF62F2114DAFE790041556C /* ScrollingThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingThread.h; sourceTree = "<group>"; };
 		1AF62F2314DAFE910041556C /* ScrollingThreadMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingThreadMac.mm; sourceTree = "<group>"; };
+		1AF89A411518FDEA00E547B5 /* TiledBacking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TiledBacking.h; sourceTree = "<group>"; };
 		1AF8E1191256592600230FF7 /* ProxyServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyServer.h; sourceTree = "<group>"; };
 		1AF8E13212565A4400230FF7 /* ProxyServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyServer.cpp; sourceTree = "<group>"; };
 		1AF8E1C1125673E000230FF7 /* ProxyServerCFNet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyServerCFNet.cpp; sourceTree = "<group>"; };
@@ -19267,6 +19269,7 @@
 				376DCCE013B4F966002EBEFC /* TextRun.cpp */,
 				A824B4640E2EF2EA0081A7B7 /* TextRun.h */,
 				37C28A6710F659CC008C7813 /* TypesettingFeatures.h */,
+				1AF89A411518FDEA00E547B5 /* TiledBacking.h */,
 				E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */,
 				939B02EC0EA2DBC400C54570 /* WidthIterator.cpp */,
 				939B02ED0EA2DBC400C54570 /* WidthIterator.h */,
@@ -24607,6 +24610,7 @@
 				FD537353137B651800008DCE /* ZeroPole.h in Headers */,
 				BCE32B9C1517C0B200F542EC /* RenderMultiColumnSet.h in Headers */,
 				BCE93F451517C567008CCF74 /* RenderRegionSet.h in Headers */,
+				1AF89A421518FDEA00E547B5 /* TiledBacking.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Source/WebCore/page/FrameView.cpp (111470 => 111471)


--- trunk/Source/WebCore/page/FrameView.cpp	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/page/FrameView.cpp	2012-03-21 00:04:13 UTC (rev 111471)
@@ -690,6 +690,19 @@
     return root->compositor()->layerForScrollCorner();
 }
 
+TiledBacking* FrameView::tiledBacking()
+{
+    RenderView* root = rootRenderer(this);
+    if (!root)
+        return 0;
+
+    RenderLayerBacking* backing = root->layer()->backing();
+    if (!backing)
+        return 0;
+
+    return backing->graphicsLayer()->tiledBacking();
+}
+
 #if ENABLE(RUBBER_BANDING)
 GraphicsLayer* FrameView::layerForOverhangAreas() const
 {

Modified: trunk/Source/WebCore/page/FrameView.h (111470 => 111471)


--- trunk/Source/WebCore/page/FrameView.h	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/page/FrameView.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -125,6 +125,8 @@
     // Called when changes to the GraphicsLayer hierarchy have to be synchronized with
     // content rendered via the normal painting path.
     void setNeedsOneShotDrawingSynchronization();
+
+    virtual TiledBacking* tiledBacking() OVERRIDE;
 #endif
 
     bool hasCompositedContent() const;

Modified: trunk/Source/WebCore/platform/ScrollableArea.h (111470 => 111471)


--- trunk/Source/WebCore/platform/ScrollableArea.h	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/ScrollableArea.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -38,6 +38,7 @@
 class ScrollAnimator;
 #if USE(ACCELERATED_COMPOSITING)
 class GraphicsLayer;
+class TiledBacking;
 #endif
 
 class ScrollableArea {
@@ -161,6 +162,10 @@
     virtual bool scheduleAnimation() { return false; }
     void serviceScrollAnimations();
 
+#if USE(ACCELERATED_COMPOSITING)
+    virtual TiledBacking* tiledBacking() { return 0; }
+#endif
+
 protected:
     ScrollableArea();
     virtual ~ScrollableArea();

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -95,6 +95,7 @@
 class GraphicsContext;
 class Image;
 class TextStream;
+class TiledBacking;
 class TimingFunction;
 
 // Base class for animation values (also used for transitions). Here to
@@ -427,8 +428,7 @@
 
     bool usingTiledLayer() const { return m_usingTiledLayer; }
 
-    // Called whenever the visible rect of the given GraphicsLayer changed.
-    virtual void visibleRectChanged(const IntRect&) { }
+    virtual TiledBacking* tiledBacking() { return 0; }
 
 #if PLATFORM(QT) || PLATFORM(GTK)
     // This allows several alternative GraphicsLayer implementations in the same port,

Added: trunk/Source/WebCore/platform/graphics/TiledBacking.h (0 => 111471)


--- trunk/Source/WebCore/platform/graphics/TiledBacking.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/TiledBacking.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TiledBacking_h
+#define TiledBacking_h
+
+namespace WebCore {
+
+class IntRect;
+
+class TiledBacking {
+public:
+    virtual ~TiledBacking() { }
+
+    virtual void visibleRectChanged(const IntRect&) = 0;
+};
+
+} // namespace WebCore
+
+#endif // TiledBacking_h

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2012-03-21 00:04:13 UTC (rev 111471)
@@ -873,9 +873,9 @@
     commitLayerChangesAfterSublayers();
 }
 
-void GraphicsLayerCA::visibleRectChanged(const IntRect& visibleRect)
+TiledBacking* GraphicsLayerCA::tiledBacking()
 {
-    m_layer->visibleRectChanged(visibleRect);
+    return m_layer->tiledBacking();
 }
 
 void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -134,7 +134,7 @@
     virtual void syncCompositingState(const FloatRect&);
     virtual void syncCompositingStateForThisLayerOnly();
 
-    virtual void visibleRectChanged(const IntRect&) OVERRIDE;
+    virtual TiledBacking* tiledBacking() OVERRIDE;
 
     bool allowTiledLayer() const { return m_allowTiledLayer; }
     virtual void setAllowTiledLayer(bool b);

Modified: trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -203,7 +203,7 @@
     float contentsScale() const;
     void setContentsScale(float);
 
-    void visibleRectChanged(const IntRect&);
+    TiledBacking* tiledBacking();
 
 #if PLATFORM(WIN)
     HashMap<String, RefPtr<PlatformCAAnimation> >& animations() { return m_animations; }

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2012-03-21 00:04:13 UTC (rev 111471)
@@ -957,13 +957,13 @@
 #endif
 }
 
-void PlatformCALayer::visibleRectChanged(const IntRect& visibleRect)
+TiledBacking* PlatformCALayer::tiledBacking()
 {
     if (m_layerType != LayerTypeTileCacheLayer)
-        return;
+        return 0;
 
     WebTileCacheLayer *tileCacheLayer = static_cast<WebTileCacheLayer *>(m_layer.get());
-    [tileCacheLayer visibleRectChanged:visibleRect];
+    return [tileCacheLayer tiledBacking];
 }
 
 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.h (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.h	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/TileCache.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -28,6 +28,7 @@
 
 #include "IntPointHash.h"
 #include "IntRect.h"
+#include "TiledBacking.h"
 #include "Timer.h"
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
@@ -44,7 +45,7 @@
 class IntPoint;
 class IntRect;
 
-class TileCache {
+class TileCache : public TiledBacking {
     WTF_MAKE_NONCOPYABLE(TileCache);
 
 public:
@@ -63,18 +64,19 @@
     void setAcceleratesDrawing(bool);
 
     CALayer *tileContainerLayer() const { return m_tileContainerLayer.get(); }
-    void visibleRectChanged(const IntRect&);
 
     void setTileDebugBorderWidth(float);
     void setTileDebugBorderColor(CGColorRef);
 
 private:
-    typedef IntPoint TileIndex;
-
     TileCache(WebTileCacheLayer*, const IntSize& tileSize);
 
+    // TiledBacking member functions.
+    virtual void visibleRectChanged(const IntRect&) OVERRIDE;
+
     IntRect bounds() const;
 
+    typedef IntPoint TileIndex;
     IntRect rectForTileIndex(const TileIndex&) const;
     void getTileIndexRangeForRect(const IntRect&, TileIndex& topLeft, TileIndex& bottomRight);
 

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.h (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.h	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.h	2012-03-21 00:04:13 UTC (rev 111471)
@@ -29,6 +29,7 @@
 namespace WebCore {
     class IntRect;
     class TileCache;
+    class TiledBacking;
 }
 
 @interface WebTileCacheLayer : CALayer {
@@ -36,6 +37,6 @@
 }
 
 - (CALayer *)tileContainerLayer;
-- (void)visibleRectChanged:(const WebCore::IntRect&)visibleRect;
+- (WebCore::TiledBacking*)tiledBacking;
 
 @end

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm	2012-03-21 00:04:13 UTC (rev 111471)
@@ -111,9 +111,9 @@
     return _tileCache->tileContainerLayer();
 }
 
-- (void)visibleRectChanged:(const IntRect&)visibleRect
+- (WebCore::TiledBacking*)tiledBacking
 {
-    _tileCache->visibleRectChanged(visibleRect);
+    return _tileCache.get();
 }
 
 - (void)setBorderColor:(CGColorRef)borderColor

Modified: trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp (111470 => 111471)


--- trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp	2012-03-21 00:04:13 UTC (rev 111471)
@@ -633,8 +633,9 @@
 {
 }
 
-void PlatformCALayer::visibleRectChanged(const IntRect&)
+TiledBacking* PlatformCALayer::tiledBacking()
 {
+    return 0;
 }
 
 #ifndef NDEBUG

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (111470 => 111471)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-03-21 00:00:07 UTC (rev 111470)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-03-21 00:04:13 UTC (rev 111471)
@@ -53,6 +53,7 @@
 #include "ScrollbarTheme.h"
 #include "ScrollingCoordinator.h"
 #include "Settings.h"
+#include "TiledBacking.h"
 
 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
 #include "HTMLMediaElement.h"
@@ -1029,8 +1030,8 @@
     FrameView* frameView = m_renderView->frameView();
     IntPoint scrollPosition = frameView->scrollPosition();
 
-    if (RenderLayerBacking* backing = rootRenderLayer()->backing())
-        backing->graphicsLayer()->visibleRectChanged(frameView->visibleContentRect(false /* exclude scrollbars */));
+    if (TiledBacking* tiledBacking = frameView->tiledBacking())
+        tiledBacking->visibleRectChanged(frameView->visibleContentRect(false /* exclude scrollbars */));
 
     if (!m_scrollLayer)
         return;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to