e47de04332cc29ac08b35cc942ca254348bdc819
[WebKit-https.git] / Source / WebKit2 / UIProcess / DrawingAreaProxyImpl.cpp
1 /*
2  * Copyright (C) 2011 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "DrawingAreaProxyImpl.h"
28
29 #include "DrawingAreaMessages.h"
30 #include "DrawingAreaProxyMessages.h"
31 #include "LayerTreeContext.h"
32 #include "Region.h"
33 #include "UpdateInfo.h"
34 #include "WebPageProxy.h"
35 #include "WebProcessProxy.h"
36
37 #ifndef __APPLE__
38 #error "This drawing area is not ready for use by other ports yet."
39 #endif
40
41 using namespace WebCore;
42
43 namespace WebKit {
44
45 PassOwnPtr<DrawingAreaProxyImpl> DrawingAreaProxyImpl::create(WebPageProxy* webPageProxy)
46 {
47     return adoptPtr(new DrawingAreaProxyImpl(webPageProxy));
48 }
49
50 DrawingAreaProxyImpl::DrawingAreaProxyImpl(WebPageProxy* webPageProxy)
51     : DrawingAreaProxy(DrawingAreaInfo::Impl, webPageProxy)
52     , m_isWaitingForDidSetSize(false)
53     , m_isInAcceleratedCompositingMode(false)
54 {
55 }
56
57 DrawingAreaProxyImpl::~DrawingAreaProxyImpl()
58 {
59 }
60
61 void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, const IntRect& rect, Region& unpaintedRegion)
62 {
63     unpaintedRegion = rect;
64
65     if (!m_backingStore)
66         return;
67
68     ASSERT(!m_isInAcceleratedCompositingMode);
69
70     if (m_isWaitingForDidSetSize) {
71         if (!m_webPageProxy->isValid())
72             return;
73         if (m_webPageProxy->process()->isLaunching())
74             return;
75
76         // The timeout, in seconds, we use when waiting for a DidSetSize message when we're asked to paint.
77         static const double didSetSizeTimeout = 0.5;
78         m_webPageProxy->process()->connection()->waitForAndDispatchImmediately<Messages::DrawingAreaProxy::DidSetSize>(m_webPageProxy->pageID(), didSetSizeTimeout);
79     }
80
81     m_backingStore->paint(context, rect);
82     unpaintedRegion.subtract(IntRect(IntPoint(), m_backingStore->size()));
83 }
84
85 void DrawingAreaProxyImpl::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*)
86 {
87     ASSERT_NOT_REACHED();
88 }
89
90 void DrawingAreaProxyImpl::didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*)
91 {
92     ASSERT_NOT_REACHED();
93 }
94
95 bool DrawingAreaProxyImpl::paint(const WebCore::IntRect&, PlatformDrawingContext)
96 {
97     ASSERT_NOT_REACHED();
98     return false;
99 }
100
101 void DrawingAreaProxyImpl::sizeDidChange()
102 {
103     sendSetSize();
104 }
105
106 void DrawingAreaProxyImpl::visibilityDidChange()
107 {
108     if (!m_webPageProxy->isViewVisible()) {
109         // Suspend painting.
110         m_webPageProxy->process()->send(Messages::DrawingArea::SuspendPainting(), m_webPageProxy->pageID());
111         return;
112     }
113
114     // Resume painting.
115     m_webPageProxy->process()->send(Messages::DrawingArea::ResumePainting(), m_webPageProxy->pageID());
116 }
117
118 void DrawingAreaProxyImpl::setPageIsVisible(bool)
119 {
120 }
121
122 void DrawingAreaProxyImpl::attachCompositingContext(uint32_t contextID)
123 {
124     ASSERT_NOT_REACHED();
125 }
126
127 void DrawingAreaProxyImpl::detachCompositingContext()
128 {
129     ASSERT_NOT_REACHED();
130 }
131
132 void DrawingAreaProxyImpl::update(const UpdateInfo& updateInfo)
133 {
134     // FIXME: Handle the case where the view is hidden.
135
136     incorporateUpdate(updateInfo);
137     m_webPageProxy->process()->send(Messages::DrawingArea::DidUpdate(), m_webPageProxy->pageID());
138 }
139
140 void DrawingAreaProxyImpl::didSetSize(const UpdateInfo& updateInfo)
141 {
142     ASSERT(m_isWaitingForDidSetSize);
143     m_isWaitingForDidSetSize = false;
144
145     if (m_size != updateInfo.viewSize)
146         sendSetSize();
147
148     if (m_isInAcceleratedCompositingMode)
149         return;
150
151     m_backingStore = nullptr;
152     incorporateUpdate(updateInfo);
153 }
154
155 void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
156 {
157     ASSERT(!m_isInAcceleratedCompositingMode);
158     m_isInAcceleratedCompositingMode = true;
159
160     m_backingStore = nullptr;
161     m_webPageProxy->enterAcceleratedCompositingMode(layerTreeContext);
162 }
163
164 void DrawingAreaProxyImpl::exitAcceleratedCompositingMode()
165 {
166     ASSERT(m_isInAcceleratedCompositingMode);
167     m_isInAcceleratedCompositingMode = false;
168
169     m_webPageProxy->exitAcceleratedCompositingMode();
170 }
171
172 void DrawingAreaProxyImpl::incorporateUpdate(const UpdateInfo& updateInfo)
173 {
174     ASSERT(!m_isInAcceleratedCompositingMode);
175
176     if (updateInfo.updateRectBounds.isEmpty())
177         return;
178
179     if (!m_backingStore)
180         m_backingStore = BackingStore::create(updateInfo.viewSize, m_webPageProxy);
181
182     m_backingStore->incorporateUpdate(updateInfo);
183
184     bool shouldScroll = !updateInfo.scrollRect.isEmpty();
185
186     if (shouldScroll)
187         m_webPageProxy->scrollView(updateInfo.scrollRect, updateInfo.scrollOffset);
188     
189     for (size_t i = 0; i < updateInfo.updateRects.size(); ++i)
190         m_webPageProxy->setViewNeedsDisplay(updateInfo.updateRects[i]);
191
192     if (shouldScroll)
193         m_webPageProxy->displayView();
194 }
195
196 void DrawingAreaProxyImpl::sendSetSize()
197 {
198     if (!m_webPageProxy->isValid())
199         return;
200
201     if (m_isWaitingForDidSetSize)
202         return;
203
204     m_isWaitingForDidSetSize = true;
205     m_webPageProxy->process()->send(Messages::DrawingArea::SetSize(m_size), m_webPageProxy->pageID());
206 }
207
208 } // namespace WebKit