Clean up ChunkedUpdateDrawingAreaProxy
[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     sendSetSize();
79 }
80
81 void ChunkedUpdateDrawingAreaProxy::setPageIsVisible(bool isVisible)
82 {
83     WebPageProxy* page = this->page();
84
85     if (isVisible == m_isVisible)
86         return;
87     
88     m_isVisible = isVisible;
89     if (!page->isValid())
90         return;
91
92     if (!m_isVisible) {
93         // Tell the web process that it doesn't need to paint anything for now.
94         page->process()->send(DrawingAreaMessage::SuspendPainting, page->pageID(), CoreIPC::In(info().identifier));
95         return;
96     }
97     
98     // The page is now visible, resume painting.
99     page->process()->send(DrawingAreaMessage::ResumePainting, page->pageID(), CoreIPC::In(info().identifier, m_forceRepaintWhenResumingPainting));
100     m_forceRepaintWhenResumingPainting = false;
101 }
102     
103 void ChunkedUpdateDrawingAreaProxy::didSetSize(UpdateChunk* updateChunk)
104 {
105     ASSERT(m_isWaitingForDidSetFrameNotification);
106     m_isWaitingForDidSetFrameNotification = false;
107
108     IntSize viewSize = updateChunk->rect().size();
109
110     if (viewSize != m_size)
111         sendSetSize();
112
113     invalidateBackingStore();
114     if (!updateChunk->isEmpty())
115         drawUpdateChunkIntoBackingStore(updateChunk);
116
117     WebPageProxy* page = this->page();
118     page->process()->responsivenessTimer()->stop();
119 }
120
121 void ChunkedUpdateDrawingAreaProxy::update(UpdateChunk* updateChunk)
122 {
123     if (!m_isVisible) {
124         // We got an update request that must have been sent before we told the web process to suspend painting.
125         // Don't paint this into the backing store, because that could leave the backing store in an inconsistent state.
126         // Instead, we will just tell the drawing area to repaint everything when we resume painting.
127         m_forceRepaintWhenResumingPainting = true;
128     } else {
129         // Just paint into backing store.
130         drawUpdateChunkIntoBackingStore(updateChunk);
131     }
132
133     WebPageProxy* page = this->page();
134     page->process()->send(DrawingAreaMessage::DidUpdate, page->pageID(), CoreIPC::In(info().identifier));
135 }
136
137 void ChunkedUpdateDrawingAreaProxy::sendSetSize()
138 {
139     if (!m_webPageProxy->isValid())
140         return;
141     
142     if (m_isWaitingForDidSetFrameNotification)
143         return;
144     m_isWaitingForDidSetFrameNotification = true;
145     
146     m_webPageProxy->process()->responsivenessTimer()->start();
147     m_webPageProxy->process()->send(DrawingAreaMessage::SetSize, m_webPageProxy->pageID(), CoreIPC::In(info().identifier, m_size));
148 }
149     
150 void ChunkedUpdateDrawingAreaProxy::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
151 {
152     switch (messageID.get<DrawingAreaProxyMessage::Kind>()) {
153         case DrawingAreaProxyMessage::Update: {
154             UpdateChunk updateChunk;
155             if (!arguments->decode(updateChunk))
156                 return;
157
158             update(&updateChunk);
159             break;
160         }
161         case DrawingAreaProxyMessage::DidSetSize: {
162             UpdateChunk updateChunk;
163             if (!arguments->decode(CoreIPC::Out(updateChunk)))
164                 return;
165
166             didSetSize(&updateChunk);
167             break;
168         }
169         default:
170             ASSERT_NOT_REACHED();
171     }
172 }
173
174 } // namespace WebKit