1 /*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "config.h"
28 #include "ChunkedUpdateDrawingAreaProxy.h"
29
30 #include "DrawingAreaMessageKinds.h"
31 #include "DrawingAreaProxyMessageKinds.h"
32 #include "MessageID.h"
33 #include "UpdateChunk.h"
34 #include "WebCoreArgumentCoders.h"
35 #include "WebPageProxy.h"
36 #include "WebProcessProxy.h"
37
38 using namespace WebCore;
39
40 namespace WebKit {
41
create(PlatformWebView * webView,WebPageProxy * webPageProxy)42 PassOwnPtr<ChunkedUpdateDrawingAreaProxy> ChunkedUpdateDrawingAreaProxy::create(PlatformWebView* webView, WebPageProxy* webPageProxy)
43 {
44 return adoptPtr(new ChunkedUpdateDrawingAreaProxy(webView, webPageProxy));
45 }
46
ChunkedUpdateDrawingAreaProxy(PlatformWebView * webView,WebPageProxy * webPageProxy)47 ChunkedUpdateDrawingAreaProxy::ChunkedUpdateDrawingAreaProxy(PlatformWebView* webView, WebPageProxy* webPageProxy)
48 : DrawingAreaProxy(DrawingAreaTypeChunkedUpdate, webPageProxy)
49 , m_isWaitingForDidSetFrameNotification(false)
50 , m_isVisible(true)
51 , m_forceRepaintWhenResumingPainting(false)
52 #if PLATFORM(GTK)
53 , m_backingStoreImage(0)
54 #endif
55 , m_webView(webView)
56 {
57 }
58
~ChunkedUpdateDrawingAreaProxy()59 ChunkedUpdateDrawingAreaProxy::~ChunkedUpdateDrawingAreaProxy()
60 {
61 }
62
paint(const IntRect & rect,PlatformDrawingContext context)63 bool ChunkedUpdateDrawingAreaProxy::paint(const IntRect& rect, PlatformDrawingContext context)
64 {
65 if (m_isWaitingForDidSetFrameNotification) {
66 WebPageProxy* page = this->page();
67 if (!page->isValid())
68 return false;
69
70 if (page->process()->isLaunching())
71 return false;
72
73 OwnPtr<CoreIPC::ArgumentDecoder> arguments = page->process()->connection()->deprecatedWaitFor(DrawingAreaProxyLegacyMessage::DidSetSize, page->pageID(), 0.04);
74 if (arguments)
75 didReceiveMessage(page->process()->connection(), CoreIPC::MessageID(DrawingAreaProxyLegacyMessage::DidSetSize), arguments.get());
76 }
77
78 return platformPaint(rect, context);
79 }
80
sizeDidChange()81 void ChunkedUpdateDrawingAreaProxy::sizeDidChange()
82 {
83 sendSetSize();
84 }
85
setPageIsVisible(bool isVisible)86 void ChunkedUpdateDrawingAreaProxy::setPageIsVisible(bool isVisible)
87 {
88 WebPageProxy* page = this->page();
89
90 if (isVisible == m_isVisible)
91 return;
92
93 m_isVisible = isVisible;
94 if (!page->isValid())
95 return;
96
97 if (!m_isVisible) {
98 // Tell the web process that it doesn't need to paint anything for now.
99 page->process()->deprecatedSend(DrawingAreaLegacyMessage::SuspendPainting, page->pageID(), CoreIPC::In());
100 return;
101 }
102
103 // The page is now visible, resume painting.
104 page->process()->deprecatedSend(DrawingAreaLegacyMessage::ResumePainting, page->pageID(), CoreIPC::In(m_forceRepaintWhenResumingPainting));
105 m_forceRepaintWhenResumingPainting = false;
106 }
107
didSetSize(UpdateChunk * updateChunk)108 void ChunkedUpdateDrawingAreaProxy::didSetSize(UpdateChunk* updateChunk)
109 {
110 ASSERT(m_isWaitingForDidSetFrameNotification);
111 m_isWaitingForDidSetFrameNotification = false;
112
113 IntSize viewSize = updateChunk->rect().size();
114
115 if (viewSize != m_size)
116 sendSetSize();
117
118 invalidateBackingStore();
119 if (!updateChunk->isEmpty())
120 drawUpdateChunkIntoBackingStore(updateChunk);
121 }
122
deprecatedUpdate(UpdateChunk * updateChunk)123 void ChunkedUpdateDrawingAreaProxy::deprecatedUpdate(UpdateChunk* updateChunk)
124 {
125 if (!m_isVisible) {
126 // We got an update request that must have been sent before we told the web process to suspend painting.
127 // Don't paint this into the backing store, because that could leave the backing store in an inconsistent state.
128 // Instead, we will just tell the drawing area to repaint everything when we resume painting.
129 m_forceRepaintWhenResumingPainting = true;
130 } else {
131 // Just paint into backing store.
132 drawUpdateChunkIntoBackingStore(updateChunk);
133 }
134
135 WebPageProxy* page = this->page();
136 page->process()->deprecatedSend(DrawingAreaLegacyMessage::DidUpdate, page->pageID(), CoreIPC::In());
137 }
138
sendSetSize()139 void ChunkedUpdateDrawingAreaProxy::sendSetSize()
140 {
141 if (!m_webPageProxy->isValid())
142 return;
143
144 if (m_isWaitingForDidSetFrameNotification)
145 return;
146 m_isWaitingForDidSetFrameNotification = true;
147
148 m_webPageProxy->process()->deprecatedSend(DrawingAreaLegacyMessage::SetSize, m_webPageProxy->pageID(), CoreIPC::In(m_size));
149 }
150
didReceiveMessage(CoreIPC::Connection *,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments)151 void ChunkedUpdateDrawingAreaProxy::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
152 {
153 switch (messageID.get<DrawingAreaProxyLegacyMessage::Kind>()) {
154 case DrawingAreaProxyLegacyMessage::Update: {
155 UpdateChunk updateChunk;
156 if (!arguments->decode(updateChunk))
157 return;
158
159 deprecatedUpdate(&updateChunk);
160 break;
161 }
162 case DrawingAreaProxyLegacyMessage::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
176