24c47c4e17452fa7f57b672c01bd9d5e3227ac62
[WebKit-https.git] / WebKit2 / UIProcess / ChunkedUpdateDrawingAreaProxy.cpp
1 /*
2  * Copyright (C) 2010 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 "ChunkedUpdateDrawingAreaProxy.h"
27
28 #include "DrawingAreaMessageKinds.h"
29 #include "DrawingAreaProxyMessageKinds.h"
30 #include "MessageID.h"
31 #include "UpdateChunk.h"
32 #include "WebCoreArgumentCoders.h"
33 #include "WebPageProxy.h"
34 #include "WebProcessProxy.h"
35
36 using namespace WebCore;
37
38 namespace WebKit {
39
40 PassOwnPtr<ChunkedUpdateDrawingAreaProxy> ChunkedUpdateDrawingAreaProxy::create(PlatformWebView* webView, WebPageProxy* webPageProxy)
41 {
42     return adoptPtr(new ChunkedUpdateDrawingAreaProxy(webView, webPageProxy));
43 }
44
45 ChunkedUpdateDrawingAreaProxy::ChunkedUpdateDrawingAreaProxy(PlatformWebView* webView, WebPageProxy* webPageProxy)
46     : DrawingAreaProxy(DrawingAreaInfo::ChunkedUpdate, webPageProxy)
47     , m_isWaitingForDidSetFrameNotification(false)
48     , m_isVisible(true)
49     , m_forceRepaintWhenResumingPainting(false)
50     , m_webView(webView)
51 {
52 }
53
54 ChunkedUpdateDrawingAreaProxy::~ChunkedUpdateDrawingAreaProxy()
55 {
56 }
57
58 void ChunkedUpdateDrawingAreaProxy::paint(const IntRect& rect, PlatformDrawingContext context)
59 {
60     if (m_isWaitingForDidSetFrameNotification) {
61         WebPageProxy* page = this->page();
62         if (!page->isValid())
63             return;
64         
65         if (page->process()->isLaunching())
66             return;
67
68         OwnPtr<CoreIPC::ArgumentDecoder> arguments = page->process()->connection()->waitFor(DrawingAreaProxyMessage::DidSetSize, page->pageID(), 0.04);
69         if (arguments)
70             didReceiveMessage(page->process()->connection(), CoreIPC::MessageID(DrawingAreaProxyMessage::DidSetSize), arguments.get());
71     }
72
73     platformPaint(rect, context);
74 }
75
76 void ChunkedUpdateDrawingAreaProxy::sizeDidChange()
77 {
78     WebPageProxy* page = this->page();
79     if (!page->isValid())
80         return;
81
82     if (m_size.isEmpty())
83         return;
84
85     m_lastSetViewSize = m_size;
86
87     if (m_isWaitingForDidSetFrameNotification)
88         return;
89     m_isWaitingForDidSetFrameNotification = true;
90
91     page->process()->responsivenessTimer()->start();
92     page->process()->send(DrawingAreaMessage::SetSize, page->pageID(), CoreIPC::In(info().identifier, m_size));
93 }
94
95 void ChunkedUpdateDrawingAreaProxy::setPageIsVisible(bool isVisible)
96 {
97     WebPageProxy* page = this->page();
98
99     if (isVisible == m_isVisible)
100         return;
101     
102     m_isVisible = isVisible;
103     if (!page->isValid())
104         return;
105
106     if (!m_isVisible) {
107         // Tell the web process that it doesn't need to paint anything for now.
108         page->process()->send(DrawingAreaMessage::SuspendPainting, page->pageID(), CoreIPC::In(info().identifier));
109         return;
110     }
111     
112     // The page is now visible, resume painting.
113     page->process()->send(DrawingAreaMessage::ResumePainting, page->pageID(), CoreIPC::In(info().identifier, m_forceRepaintWhenResumingPainting));
114     m_forceRepaintWhenResumingPainting = false;
115 }
116     
117 void ChunkedUpdateDrawingAreaProxy::didSetSize(UpdateChunk* updateChunk)
118 {
119     ASSERT(m_isWaitingForDidSetFrameNotification);
120     m_isWaitingForDidSetFrameNotification = false;
121
122     IntSize viewSize = updateChunk->rect().size();
123
124     if (viewSize != m_lastSetViewSize)
125         setSize(m_lastSetViewSize);
126
127     invalidateBackingStore();
128     if (!updateChunk->isEmpty())
129         drawUpdateChunkIntoBackingStore(updateChunk);
130
131     WebPageProxy* page = this->page();
132     page->process()->responsivenessTimer()->stop();
133 }
134
135 void ChunkedUpdateDrawingAreaProxy::update(UpdateChunk* updateChunk)
136 {
137     if (!m_isVisible) {
138         // We got an update request that must have been sent before we told the web process to suspend painting.
139         // Don't paint this into the backing store, because that could leave the backing store in an inconsistent state.
140         // Instead, we will just tell the drawing area to repaint everything when we resume painting.
141         m_forceRepaintWhenResumingPainting = true;
142     } else {
143         // Just paint into backing store.
144         drawUpdateChunkIntoBackingStore(updateChunk);
145     }
146
147     WebPageProxy* page = this->page();
148     page->process()->send(DrawingAreaMessage::DidUpdate, page->pageID(), CoreIPC::In(info().identifier));
149 }
150
151 void ChunkedUpdateDrawingAreaProxy::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
152 {
153     switch (messageID.get<DrawingAreaProxyMessage::Kind>()) {
154         case DrawingAreaProxyMessage::Update: {
155             UpdateChunk updateChunk;
156             if (!arguments->decode(updateChunk))
157                 return;
158
159             update(&updateChunk);
160             break;
161         }
162         case DrawingAreaProxyMessage::DidSetSize: {
163             UpdateChunk updateChunk;
164             if (!arguments->decode(CoreIPC::Out(updateChunk)))
165                 return;
166
167             didSetSize(&updateChunk);
168             break;
169         }
170         default:
171             ASSERT_NOT_REACHED();
172     }
173 }
174
175 } // namespace WebKit