Home | History | Annotate | Download | only in web
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "PinchViewports.h"
     33 
     34 #include "WebSettingsImpl.h"
     35 #include "WebViewImpl.h"
     36 #include "core/page/FrameView.h"
     37 #include "core/platform/graphics/FloatSize.h"
     38 #include "core/platform/graphics/GraphicsLayer.h"
     39 #include "core/rendering/RenderLayerCompositor.h"
     40 #include "public/platform/Platform.h"
     41 #include "public/platform/WebCompositorSupport.h"
     42 #include "public/platform/WebLayerTreeView.h"
     43 #include "public/platform/WebScrollbarLayer.h"
     44 
     45 using WebCore::GraphicsLayer;
     46 
     47 namespace WebKit {
     48 
     49 PassOwnPtr<PinchViewports> PinchViewports::create(WebViewImpl* owner)
     50 {
     51     return adoptPtr(new PinchViewports(owner));
     52 }
     53 
     54 PinchViewports::PinchViewports(WebViewImpl* owner)
     55     : m_owner(owner)
     56     , m_innerViewportContainerLayer(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this))
     57     , m_pageScaleLayer(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this))
     58     , m_innerViewportScrollLayer(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this))
     59     , m_overlayScrollbarHorizontal(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this))
     60     , m_overlayScrollbarVertical(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this))
     61 {
     62     m_innerViewportContainerLayer->platformLayer()->setIsContainerForFixedPositionLayers(true);
     63     // No need for the inner viewport to clip, since the compositing
     64     // surface takes care of it -- and clipping here would interfere with
     65     // dynamically-sized viewports on Android.
     66     m_innerViewportContainerLayer->setMasksToBounds(false);
     67 
     68     m_innerViewportScrollLayer->platformLayer()->setScrollable(true);
     69 
     70 #ifndef NDEBUG
     71     m_innerViewportContainerLayer->setName("inner viewport container layer");
     72     m_pageScaleLayer->setName("page scale layer");
     73     m_innerViewportScrollLayer->setName("inner viewport scroll layer");
     74     m_overlayScrollbarHorizontal->setName("overlay scrollbar horizontal");
     75     m_overlayScrollbarVertical->setName("overlay scrollbar vertical");
     76 #endif
     77 
     78     m_innerViewportContainerLayer->addChild(m_pageScaleLayer.get());
     79     m_pageScaleLayer->addChild(m_innerViewportScrollLayer.get());
     80     m_innerViewportContainerLayer->addChild(m_overlayScrollbarHorizontal.get());
     81     m_innerViewportContainerLayer->addChild(m_overlayScrollbarVertical.get());
     82 
     83     // Setup the inner viewport overlay scrollbars.
     84     setupScrollbar(WebScrollbar::Horizontal);
     85     setupScrollbar(WebScrollbar::Vertical);
     86 }
     87 
     88 PinchViewports::~PinchViewports() { }
     89 
     90 void PinchViewports::setViewportSize(const WebCore::IntSize& newSize)
     91 {
     92     m_innerViewportContainerLayer->setSize(newSize);
     93 
     94     // Need to re-compute sizes for the overlay scrollbars.
     95     setupScrollbar(WebScrollbar::Horizontal);
     96     setupScrollbar(WebScrollbar::Vertical);
     97 }
     98 
     99 // Modifies the top of the graphics layer tree to add layers needed to support
    100 // the inner/outer viewport fixed-position model for pinch zoom. When finished,
    101 // the tree will look like this (with * denoting added layers):
    102 //
    103 // *innerViewportContainerLayer (fixed pos container)
    104 //  +- *pageScaleLayer
    105 //  |   +- *innerViewportScrollLayer
    106 //  |       +-- overflowControlsHostLayer (root layer)
    107 //  |           +-- outerViewportContainerLayer (fixed pos container) [frame container layer in RenderLayerCompositor]
    108 //  |           |   +-- outerViewportScrollLayer [frame scroll layer in RenderLayerCompositor]
    109 //  |           |       +-- content layers ...
    110 //  |           +-- horizontal ScrollbarLayer (non-overlay)
    111 //  |           +-- verticalScrollbarLayer (non-overlay)
    112 //  |           +-- scroll corner (non-overlay)
    113 //  +- *horizontalScrollbarLayer (overlay)
    114 //  +- *verticalScrollbarLayer (overlay)
    115 //
    116 void PinchViewports::setOverflowControlsHostLayer(GraphicsLayer* layer)
    117 {
    118     if (layer) {
    119         ASSERT(!m_innerViewportScrollLayer->children().size());
    120         m_innerViewportScrollLayer->addChild(layer);
    121     } else {
    122         m_innerViewportScrollLayer->removeAllChildren();
    123         return;
    124     }
    125 
    126     WebCore::Page* page = m_owner->page();
    127     if (!page)
    128         return;
    129 
    130     // We only need to disable the existing (outer viewport) scrollbars
    131     // if the existing ones are already overlay.
    132     // FIXME: If we knew in advance before the overflowControlsHostLayer goes
    133     // away, we would re-enable the drawing of these scrollbars.
    134     if (GraphicsLayer* scrollbar = m_owner->compositor()->layerForHorizontalScrollbar())
    135         scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars());
    136     if (GraphicsLayer* scrollbar = m_owner->compositor()->layerForVerticalScrollbar())
    137         scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars());
    138 }
    139 
    140 void PinchViewports::setupScrollbar(WebScrollbar::Orientation orientation)
    141 {
    142     bool isHorizontal = orientation == WebScrollbar::Horizontal;
    143     GraphicsLayer* scrollbarGraphicsLayer = isHorizontal ?
    144         m_overlayScrollbarHorizontal.get() : m_overlayScrollbarVertical.get();
    145 
    146     const int overlayScrollbarThickness = m_owner->settingsImpl()->pinchOverlayScrollbarThickness();
    147 
    148     int xPosition = isHorizontal ? 0 : m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness;
    149     int yPosition = isHorizontal ? m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness : 0;
    150     int width = isHorizontal ? m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness : overlayScrollbarThickness;
    151     int height = isHorizontal ? overlayScrollbarThickness : m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness;
    152 
    153     scrollbarGraphicsLayer->setPosition(WebCore::IntPoint(xPosition, yPosition));
    154     scrollbarGraphicsLayer->setSize(WebCore::IntSize(width, height));
    155 }
    156 
    157 void PinchViewports::registerViewportLayersWithTreeView(WebLayerTreeView* layerTreeView) const
    158 {
    159     if (!layerTreeView)
    160         return;
    161 
    162     WebCore::RenderLayerCompositor* compositor = m_owner->compositor();
    163     ASSERT(compositor);
    164     layerTreeView->registerPinchViewportLayers(
    165         m_innerViewportContainerLayer->platformLayer(),
    166         m_pageScaleLayer->platformLayer(),
    167         m_innerViewportScrollLayer->platformLayer(),
    168         compositor->scrollLayer()->platformLayer(),
    169         m_overlayScrollbarHorizontal->platformLayer(),
    170         m_overlayScrollbarVertical->platformLayer());
    171 }
    172 
    173 void PinchViewports::clearViewportLayersForTreeView(WebLayerTreeView* layerTreeView) const
    174 {
    175     if (!layerTreeView)
    176         return;
    177 
    178     layerTreeView->clearPinchViewportLayers();
    179 }
    180 
    181 void PinchViewports::notifyAnimationStarted(const GraphicsLayer*, double time)
    182 {
    183 }
    184 
    185 void PinchViewports::paintContents(const GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& inClip)
    186 {
    187 }
    188 
    189 } // namespace WebKit
    190