2b94cea9c4a5d1a079cdf757dd43db87d79ef1c3
[WebKit-https.git] / Source / WebKit2 / UIProcess / PageViewportController.h
1 /*
2  * Copyright (C) 2011, 2012 Nokia Corporation and/or its subsidiary(-ies)
3  * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this program; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef PageViewportController_h
23 #define PageViewportController_h
24
25 #include <WebCore/FloatPoint.h>
26 #include <WebCore/FloatRect.h>
27 #include <WebCore/FloatSize.h>
28 #include <WebCore/ViewportArguments.h>
29
30 namespace WebCore {
31 class IntPoint;
32 class IntSize;
33 }
34
35 namespace WebKit {
36
37 class WebPageProxy;
38 class PageViewportController;
39 class PageViewportControllerClient;
40
41 // When interacting with the content, either by animating or by the hand of the user,
42 // it is important to ensure smooth animations of at least 60fps in order to give a
43 // good user experience.
44 //
45 // In order to do this we need to get rid of unknown factors. These include device
46 // sensors (geolocation, orientation updates etc), CSS3 animations, JavaScript
47 // exectution, sub resource loads etc.
48 // We do this by sending suspend and resume notifications to the web process.
49 //
50 // For this purpose the ViewportUpdateDeferrer guard can be used when interacting
51 // with or animating the content to scope suspend / resume and defer update
52 // notifications.
53 //
54 // If something should only be executed when the content is suspended, it is possible
55 // to check for that using ASSERT(hasSuspendedContent()).
56
57 class ViewportUpdateDeferrer {
58 public:
59     enum SuspendContentFlag { DeferUpdate, DeferUpdateAndSuspendContent };
60     ViewportUpdateDeferrer(PageViewportController*, SuspendContentFlag = DeferUpdate);
61     ~ViewportUpdateDeferrer();
62
63 private:
64     PageViewportController* const m_controller;
65 };
66
67 class PageViewportController {
68     WTF_MAKE_NONCOPYABLE(PageViewportController);
69
70 public:
71     PageViewportController(WebKit::WebPageProxy*, PageViewportControllerClient*);
72     virtual ~PageViewportController() { }
73
74     void suspendContent();
75     void resumeContent();
76
77     float innerBoundedViewportScale(float) const;
78     float outerBoundedViewportScale(float) const;
79     WebCore::FloatPoint clampViewportToContents(const WebCore::FloatPoint& viewportPos, float viewportScale);
80
81     bool hasSuspendedContent() const { return m_hasSuspendedContent; }
82     bool hadUserInteraction() const { return m_hadUserInteraction; }
83     bool allowsUserScaling() const { return m_allowsUserScaling; }
84
85     WebCore::FloatSize contentsLayoutSize() const { return m_rawAttributes.layoutSize; }
86     float devicePixelRatio() const;
87     float minimumContentsScale() const { return m_minimumScaleToFit; }
88     float maximumContentsScale() const { return m_rawAttributes.maximumScale; }
89     float currentContentsScale() const { return fromViewportScale(m_effectiveScale); }
90
91     void setHadUserInteraction(bool didUserInteract) { m_hadUserInteraction = didUserInteract; }
92
93     // Notifications from the viewport.
94     void didChangeViewportSize(const WebCore::FloatSize& newSize);
95     void didChangeContentsVisibility(const WebCore::FloatPoint& viewportPos, float viewportScale, const WebCore::FloatPoint& trajectoryVector = WebCore::FloatPoint::zero());
96
97     // Notifications from the WebProcess.
98     void didCommitLoad();
99     void didChangeContentsSize(const WebCore::IntSize& newSize);
100     void didChangeViewportAttributes(const WebCore::ViewportAttributes&);
101     void didRenderFrame(const WebCore::IntSize& contentsSize);
102     void pageTransitionViewportReady();
103     void pageDidRequestScroll(const WebCore::IntPoint& cssPosition);
104
105 private:
106     float fromViewportScale(float scale) const { return scale / devicePixelRatio(); }
107     float toViewportScale(float scale) const { return scale * devicePixelRatio(); }
108     void syncVisibleContents(const WebCore::FloatPoint &trajectoryVector = WebCore::FloatPoint::zero());
109     void applyScaleAfterRenderingContents(float scale);
110     void applyPositionAfterRenderingContents(const WebCore::FloatPoint& pos);
111     void updateMinimumScaleToFit();
112
113     WebPageProxy* const m_webPageProxy;
114     PageViewportControllerClient* m_client;
115
116     WebCore::ViewportAttributes m_rawAttributes;
117
118     bool m_allowsUserScaling;
119     float m_minimumScaleToFit;
120
121     int m_activeDeferrerCount;
122     bool m_hasSuspendedContent;
123     bool m_hadUserInteraction;
124
125     WebCore::FloatPoint m_viewportPos;
126     WebCore::FloatSize m_viewportSize;
127     WebCore::FloatSize m_contentsSize;
128     float m_effectiveScale; // Should always be cssScale * devicePixelRatio.
129
130     bool m_viewportPosIsLocked;
131     bool m_effectiveScaleIsLocked;
132
133     friend class ViewportUpdateDeferrer;
134 };
135
136 bool fuzzyCompare(float, float, float epsilon);
137
138 } // namespace WebKit
139
140 #endif // PageViewportController_h