[Mac] Remove backing store for layers that are outside the viewport
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Jun 2017 05:04:14 +0000 (05:04 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Jun 2017 05:04:14 +0000 (05:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170082
<rdar://problem/31245009>

Reviewed by Simon Fraser.

Source/WebCore:

Implement the backingStoreAttached flag in PlatformCALayerCocoa. This means that
compositing layers outside the tiling coverage rect will no longer have backing
stores, saving large amounts of memory.

Also added a canDetachBackingStore flag that is set to false for scroll control
layers, to avoid complicating coverage rect computations.

Test: compositing/backing-store-attachment-1.html

* page/Frame.h:
* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::GraphicsLayer):
(WebCore::GraphicsLayer::dumpProperties):
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::backingStoreAttached):
(WebCore::GraphicsLayer::setCanDetachBackingStore):
(WebCore::GraphicsLayer::canDetachBackingStore):
* platform/graphics/GraphicsLayerClient.h:
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::backingStoreAttached):
(WebCore::GraphicsLayerCA::setNeedsDisplay):
(WebCore::GraphicsLayerCA::updateCoverage):
* platform/graphics/ca/GraphicsLayerCA.h:
* platform/graphics/ca/PlatformCALayer.h:
* platform/graphics/ca/cocoa/PlatformCALayerCocoa.h:
* platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
(PlatformCALayerCocoa::setBackingStoreAttached):
(PlatformCALayerCocoa::backingStoreAttached):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateOverflowControlsLayers):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::layerTreeAsText):
(WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
* testing/Internals.cpp:
(WebCore::toLayerTreeFlags):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit2:

* WebProcess/WebPage/mac/PlatformCALayerRemote.h:

LayoutTests:

Add a simple test with two compositing layers far apart vertically. Only one of them
should have its backing store attached.

* compositing/backing-store-attachment-1-expected.txt: Added.
* compositing/backing-store-attachment-1.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@217696 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/backing-store-attachment-1-expected.txt [new file with mode: 0644]
LayoutTests/compositing/backing-store-attachment-1.html [new file with mode: 0644]
LayoutTests/platform/ios/compositing/backing-store-attachment-1-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/Frame.h
Source/WebCore/platform/graphics/GraphicsLayer.cpp
Source/WebCore/platform/graphics/GraphicsLayer.h
Source/WebCore/platform/graphics/GraphicsLayerClient.h
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
Source/WebCore/platform/graphics/ca/PlatformCALayer.h
Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.h
Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h

index f478891..f0079f4 100644 (file)
@@ -1,3 +1,17 @@
+2017-06-01  Andreas Kling  <akling@apple.com>
+
+        [Mac] Remove backing store for layers that are outside the viewport
+        https://bugs.webkit.org/show_bug.cgi?id=170082
+        <rdar://problem/31245009>
+
+        Reviewed by Simon Fraser.
+
+        Add a simple test with two compositing layers far apart vertically. Only one of them
+        should have its backing store attached.
+
+        * compositing/backing-store-attachment-1-expected.txt: Added.
+        * compositing/backing-store-attachment-1.html: Added.
+
 2017-06-01  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r217691.
diff --git a/LayoutTests/compositing/backing-store-attachment-1-expected.txt b/LayoutTests/compositing/backing-store-attachment-1-expected.txt
new file mode 100644 (file)
index 0000000..654f495
--- /dev/null
@@ -0,0 +1,28 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 2221.00)
+  (backingStoreAttached 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2221.00)
+      (contentsOpaque 1)
+      (backingStoreAttached 1)
+      (children 2
+        (GraphicsLayer
+          (position 8.00 13.00)
+          (bounds 600.00 600.00)
+          (drawsContent 1)
+          (backingStoreAttached 1)
+        )
+        (GraphicsLayer
+          (position 8.00 1613.00)
+          (bounds 600.00 600.00)
+          (drawsContent 1)
+          (backingStoreAttached 0)
+        )
+      )
+    )
+  )
+)
+I'm attached.
+I'm detached.
diff --git a/LayoutTests/compositing/backing-store-attachment-1.html b/LayoutTests/compositing/backing-store-attachment-1.html
new file mode 100644 (file)
index 0000000..eef8e10
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.layerized {
+    transform: translateZ(0);
+    width: 600px;
+    height: 600px;
+}
+.vspace {
+    height: 1000px;
+}
+</style>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+window.onload = function() {
+    if (window.testRunner) {
+        var out = document.getElementById('out');
+        out.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED);
+        testRunner.notifyDone();
+    }
+};
+</script>
+</head>
+<body>
+<pre id="out"></pre>
+<div class="layerized">I'm attached.</div>
+<div class="vspace"></div>
+<div class="layerized">I'm detached.</div>
+</body>
+</html>
diff --git a/LayoutTests/platform/ios/compositing/backing-store-attachment-1-expected.txt b/LayoutTests/platform/ios/compositing/backing-store-attachment-1-expected.txt
new file mode 100644 (file)
index 0000000..f244e38
--- /dev/null
@@ -0,0 +1,28 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 2221.00)
+  (backingStoreAttached 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 2221.00)
+      (contentsOpaque 1)
+      (backingStoreAttached 1)
+      (children 2
+        (GraphicsLayer
+          (position 8.00 13.00)
+          (bounds 600.00 600.00)
+          (drawsContent 1)
+          (backingStoreAttached 1)
+        )
+        (GraphicsLayer
+          (position 8.00 1613.00)
+          (bounds 600.00 600.00)
+          (drawsContent 1)
+          (backingStoreAttached 0)
+        )
+      )
+    )
+  )
+)
+I'm attached.
+I'm detached.
index d5c3166..e23bb7f 100644 (file)
@@ -1,3 +1,49 @@
+2017-06-01  Andreas Kling  <akling@apple.com>
+
+        [Mac] Remove backing store for layers that are outside the viewport
+        https://bugs.webkit.org/show_bug.cgi?id=170082
+        <rdar://problem/31245009>
+
+        Reviewed by Simon Fraser.
+
+        Implement the backingStoreAttached flag in PlatformCALayerCocoa. This means that
+        compositing layers outside the tiling coverage rect will no longer have backing
+        stores, saving large amounts of memory.
+
+        Also added a canDetachBackingStore flag that is set to false for scroll control
+        layers, to avoid complicating coverage rect computations.
+
+        Test: compositing/backing-store-attachment-1.html
+
+        * page/Frame.h:
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::GraphicsLayer):
+        (WebCore::GraphicsLayer::dumpProperties):
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::backingStoreAttached):
+        (WebCore::GraphicsLayer::setCanDetachBackingStore):
+        (WebCore::GraphicsLayer::canDetachBackingStore):
+        * platform/graphics/GraphicsLayerClient.h:
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::backingStoreAttached):
+        (WebCore::GraphicsLayerCA::setNeedsDisplay):
+        (WebCore::GraphicsLayerCA::updateCoverage):
+        * platform/graphics/ca/GraphicsLayerCA.h:
+        * platform/graphics/ca/PlatformCALayer.h:
+        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.h:
+        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
+        (PlatformCALayerCocoa::setBackingStoreAttached):
+        (PlatformCALayerCocoa::backingStoreAttached):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateOverflowControlsLayers):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::layerTreeAsText):
+        (WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
+        * testing/Internals.cpp:
+        (WebCore::toLayerTreeFlags):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2017-06-01  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r217691.
index d0292d7..65999c3 100644 (file)
@@ -107,6 +107,7 @@ enum {
     LayerTreeFlagsIncludePaintingPhases = 1 << 4,
     LayerTreeFlagsIncludeContentLayers = 1 << 5,
     LayerTreeFlagsIncludeAcceleratesDrawing = 1 << 6,
+    LayerTreeFlagsIncludeBackingStoreAttached = 1 << 7,
 };
 typedef unsigned LayerTreeFlags;
 
index 698f758..64a8fa2 100644 (file)
@@ -134,6 +134,7 @@ GraphicsLayer::GraphicsLayer(Type type, GraphicsLayerClient& client)
     , m_isMaskLayer(false)
     , m_isTrackingDisplayListReplay(false)
     , m_userInteractionEnabled(true)
+    , m_canDetachBackingStore(true)
     , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
     , m_contentsOrientation(CompositingCoordinatesTopDown)
     , m_parent(nullptr)
@@ -810,6 +811,11 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe
         ts << "(acceleratesDrawing " << m_acceleratesDrawing << ")\n";
     }
 
+    if (behavior & LayerTreeAsTextIncludeBackingStoreAttached) {
+        writeIndent(ts, indent + 1);
+        ts << "(backingStoreAttached " << backingStoreAttached() << ")\n";
+    }
+
     if (!m_transform.isIdentity()) {
         writeIndent(ts, indent + 1);
         ts << "(transform ";
index 95fa7c8..ecfe39c 100644 (file)
@@ -546,6 +546,11 @@ public:
     // Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers.
     WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const;
 
+    virtual bool backingStoreAttached() const { return true; }
+
+    void setCanDetachBackingStore(bool b) { m_canDetachBackingStore = b; }
+    bool canDetachBackingStore() const { return m_canDetachBackingStore; }
+
     virtual TiledBacking* tiledBacking() const { return 0; }
 
     void resetTrackedRepaints();
@@ -649,6 +654,7 @@ protected:
     bool m_isMaskLayer : 1;
     bool m_isTrackingDisplayListReplay : 1;
     bool m_userInteractionEnabled : 1;
+    bool m_canDetachBackingStore : 1;
     
     GraphicsLayerPaintingPhase m_paintingPhase;
     CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents
index 45f6512..db16756 100644 (file)
@@ -72,6 +72,7 @@ enum LayerTreeAsTextBehaviorFlags {
     LayerTreeAsTextIncludeContentLayers         = 1 << 5,
     LayerTreeAsTextIncludePageOverlayLayers     = 1 << 6,
     LayerTreeAsTextIncludeAcceleratesDrawing    = 1 << 7,
+    LayerTreeAsTextIncludeBackingStoreAttached  = 1 << 8,
 };
 typedef unsigned LayerTreeAsTextBehavior;
 
index be0877c..b8d4ed5 100644 (file)
@@ -863,11 +863,19 @@ void GraphicsLayerCA::setBlendMode(BlendMode blendMode)
 }
 #endif
 
+bool GraphicsLayerCA::backingStoreAttached() const
+{
+    return m_layer->backingStoreAttached();
+}
+
 void GraphicsLayerCA::setNeedsDisplay()
 {
     if (!drawsContent())
         return;
 
+    if (!backingStoreAttached())
+        return;
+
     m_needsFullRepaint = true;
     m_dirtyRects.clear();
     noteLayerPropertyChanged(DirtyRectsChanged);
@@ -2277,11 +2285,12 @@ void GraphicsLayerCA::updateCoverage()
         backing->setCoverageRect(m_coverageRect);
     }
 
-    m_layer->setBackingStoreAttached(m_intersectsCoverageRect);
-    if (m_layerClones) {
-        LayerMap::const_iterator end = m_layerClones->end();
-        for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it)
-            it->value->setBackingStoreAttached(m_intersectsCoverageRect);
+    if (canDetachBackingStore()) {
+        m_layer->setBackingStoreAttached(m_intersectsCoverageRect);
+        if (m_layerClones) {
+            for (auto& it : *m_layerClones)
+                it.value->setBackingStoreAttached(m_intersectsCoverageRect);
+        }
     }
 
     m_sizeAtLastCoverageRectUpdate = m_size;
@@ -4123,7 +4132,7 @@ double GraphicsLayerCA::backingStoreMemoryEstimate() const
     if (TiledBacking* tiledBacking = this->tiledBacking())
         return tiledBacking->retainedTileBackingStoreMemory();
 
-    if (!m_layer->backingContributesToMemoryEstimate())
+    if (!backingStoreAttached())
         return 0;
 
     return m_layer->backingStoreBytesPerPixel() * size().width() * m_layer->contentsScale() * size().height() * m_layer->contentsScale();
index 9ae1834..91bfc44 100644 (file)
@@ -258,6 +258,8 @@ private:
 
     bool isRunningTransformAnimation() const;
 
+    WEBCORE_EXPORT bool backingStoreAttached() const override;
+
     bool animationIsRunning(const String& animationName) const
     {
         return m_runningAnimations.find(animationName) != m_runningAnimations.end();
index f94c07e..88a29a0 100644 (file)
@@ -188,7 +188,6 @@ public:
 
     virtual void setBackingStoreAttached(bool) = 0;
     virtual bool backingStoreAttached() const = 0;
-    virtual bool backingContributesToMemoryEstimate() const { return true; }
 
     virtual void setMinificationFilter(FilterType) = 0;
     virtual void setMagnificationFilter(FilterType) = 0;
index 57467a0..ec77b52 100644 (file)
@@ -197,6 +197,7 @@ private:
     std::unique_ptr<FloatRoundedRect> m_shapeRoundedRect;
     bool m_wantsDeepColorBackingStore { false };
     bool m_supportsSubpixelAntialiasedText { false };
+    bool m_backingStoreAttached { true };
 };
 
 } // namespace WebCore
index 1658144..04e705f 100644 (file)
@@ -635,14 +635,21 @@ void PlatformCALayerCocoa::setUserInteractionEnabled(bool)
 {
 }
 
-void PlatformCALayerCocoa::setBackingStoreAttached(bool)
+void PlatformCALayerCocoa::setBackingStoreAttached(bool attached)
 {
-    // We could throw away backing store here with setContents:nil.
+    if (attached == m_backingStoreAttached)
+        return;
+    m_backingStoreAttached = attached;
+
+    if (attached)
+        setNeedsDisplay();
+    else
+        setContents(nullptr);
 }
 
 bool PlatformCALayerCocoa::backingStoreAttached() const
 {
-    return true;
+    return m_backingStoreAttached;
 }
 
 bool PlatformCALayerCocoa::geometryFlipped() const
index 93607e2..a460362 100644 (file)
@@ -1479,6 +1479,7 @@ bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScroll
     if (needsHorizontalScrollbarLayer) {
         if (!m_layerForHorizontalScrollbar) {
             m_layerForHorizontalScrollbar = createGraphicsLayer("horizontal scrollbar");
+            m_layerForHorizontalScrollbar->setCanDetachBackingStore(false);
             horizontalScrollbarLayerChanged = true;
         }
     } else if (m_layerForHorizontalScrollbar) {
@@ -1491,6 +1492,7 @@ bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScroll
     if (needsVerticalScrollbarLayer) {
         if (!m_layerForVerticalScrollbar) {
             m_layerForVerticalScrollbar = createGraphicsLayer("vertical scrollbar");
+            m_layerForVerticalScrollbar->setCanDetachBackingStore(false);
             verticalScrollbarLayerChanged = true;
         }
     } else if (m_layerForVerticalScrollbar) {
@@ -1503,6 +1505,7 @@ bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScroll
     if (needsScrollCornerLayer) {
         if (!m_layerForScrollCorner) {
             m_layerForScrollCorner = createGraphicsLayer("scroll corner");
+            m_layerForScrollCorner->setCanDetachBackingStore(false);
             scrollCornerLayerChanged = true;
         }
     } else if (m_layerForScrollCorner) {
index a57a0b1..1ff136a 100644 (file)
@@ -1828,6 +1828,8 @@ String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
         layerTreeBehavior |= LayerTreeAsTextIncludeContentLayers;
     if (flags & LayerTreeFlagsIncludeAcceleratesDrawing)
         layerTreeBehavior |= LayerTreeAsTextIncludeAcceleratesDrawing;
+    if (flags & LayerTreeFlagsIncludeBackingStoreAttached)
+        layerTreeBehavior |= LayerTreeAsTextIncludeBackingStoreAttached;
 
     // We skip dumping the scroll and clip layers to keep layerTreeAsText output
     // similar between platforms.
@@ -3313,6 +3315,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers()
     if (requiresHorizontalScrollbarLayer()) {
         if (!m_layerForHorizontalScrollbar) {
             m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), *this);
+            m_layerForHorizontalScrollbar->setCanDetachBackingStore(false);
             m_layerForHorizontalScrollbar->setShowDebugBorder(m_showDebugBorders);
             m_layerForHorizontalScrollbar->setName("horizontal scrollbar container");
 #if PLATFORM(COCOA) && USE(CA)
@@ -3334,6 +3337,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers()
     if (requiresVerticalScrollbarLayer()) {
         if (!m_layerForVerticalScrollbar) {
             m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), *this);
+            m_layerForVerticalScrollbar->setCanDetachBackingStore(false);
             m_layerForVerticalScrollbar->setShowDebugBorder(m_showDebugBorders);
             m_layerForVerticalScrollbar->setName("vertical scrollbar container");
 #if PLATFORM(COCOA) && USE(CA)
@@ -3355,6 +3359,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers()
     if (requiresScrollCornerLayer()) {
         if (!m_layerForScrollCorner) {
             m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), *this);
+            m_layerForScrollCorner->setCanDetachBackingStore(false);
             m_layerForScrollCorner->setShowDebugBorder(m_showDebugBorders);
             m_layerForScrollCorner->setName("scroll corner");
 #if PLATFORM(COCOA) && USE(CA)
index 3bbbb33..cc18925 100644 (file)
@@ -2270,6 +2270,8 @@ static LayerTreeFlags toLayerTreeFlags(unsigned short flags)
         layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
     if (flags & Internals::LAYER_TREE_INCLUDES_ACCELERATES_DRAWING)
         layerTreeFlags |= LayerTreeFlagsIncludeAcceleratesDrawing;
+    if (flags & Internals::LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED)
+        layerTreeFlags |= LayerTreeFlagsIncludeBackingStoreAttached;
 
     return layerTreeFlags;
 }
index d1b4f34..ab10d84 100644 (file)
@@ -294,6 +294,7 @@ public:
         LAYER_TREE_INCLUDES_PAINTING_PHASES = 8,
         LAYER_TREE_INCLUDES_CONTENT_LAYERS = 16,
         LAYER_TREE_INCLUDES_ACCELERATES_DRAWING = 32,
+        LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED = 64,
     };
     ExceptionOr<String> layerTreeAsText(Document&, unsigned short flags) const;
     ExceptionOr<uint64_t> layerIDForElement(Element&);
index 99eeb1e..f41de7c 100644 (file)
@@ -268,6 +268,7 @@ enum EventThrottlingBehavior {
     const unsigned short LAYER_TREE_INCLUDES_PAINTING_PHASES = 8;
     const unsigned short LAYER_TREE_INCLUDES_CONTENT_LAYERS = 16;
     const unsigned short LAYER_TREE_INCLUDES_ACCELERATES_DRAWING = 32;
+    const unsigned short LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED = 64;
     [MayThrowException] DOMString layerTreeAsText(Document document, optional unsigned short flags = 0);
 
     [MayThrowException] unsigned long long layerIDForElement(Element element);
index 3391c32..8c27e59 100644 (file)
@@ -1,3 +1,13 @@
+2017-06-01  Andreas Kling  <akling@apple.com>
+
+        [Mac] Remove backing store for layers that are outside the viewport
+        https://bugs.webkit.org/show_bug.cgi?id=170082
+        <rdar://problem/31245009>
+
+        Reviewed by Simon Fraser.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+
 2017-06-01  Chris Dumez  <cdumez@apple.com>
 
         REGRESSION (r206386): Xactimate Website Crashes @ com.apple.WebKit: WebKit::NPRuntimeObjectMap::convertJSValueToNPVariant + 255
index 5267682..a9635ef 100644 (file)
@@ -101,7 +101,6 @@ public:
 
     void setBackingStoreAttached(bool) override;
     bool backingStoreAttached() const override;
-    bool backingContributesToMemoryEstimate() const override { return backingStoreAttached(); }
 
     bool geometryFlipped() const override;
     void setGeometryFlipped(bool) override;