2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DrawingAreaImpl.h"
29 #include "DrawingAreaProxyMessages.h"
30 #include "LayerTreeContext.h"
31 #include "ShareableBitmap.h"
32 #include "UpdateInfo.h"
34 #include "WebPageCreationParameters.h"
35 #include "WebProcess.h"
36 #include <WebCore/GraphicsContext.h>
37 #include <WebCore/Page.h>
38 #include <WebCore/Settings.h>
40 using namespace WebCore;
45 PassOwnPtr<DrawingAreaImpl> DrawingAreaImpl::create(WebPage* webPage, const WebPageCreationParameters& parameters)
47 return adoptPtr(new DrawingAreaImpl(webPage, parameters));
50 DrawingAreaImpl::~DrawingAreaImpl()
53 m_layerTreeHost->invalidate();
56 DrawingAreaImpl::DrawingAreaImpl(WebPage* webPage, const WebPageCreationParameters& parameters)
57 : DrawingArea(DrawingAreaTypeImpl, webPage)
58 , m_backingStoreStateID(0)
59 , m_isPaintingEnabled(true)
60 , m_inUpdateBackingStoreState(false)
61 , m_shouldSendDidUpdateBackingStoreState(false)
62 , m_isWaitingForDidUpdate(false)
63 , m_compositingAccordingToProxyMessages(false)
64 , m_layerTreeStateIsFrozen(false)
65 , m_wantsToExitAcceleratedCompositingMode(false)
66 , m_isPaintingSuspended(!parameters.isVisible)
67 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
68 ,m_paintingSuspendCount(0)
70 , m_alwaysUseCompositing(false)
71 , m_displayTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::displayTimerFired)
72 , m_exitCompositingTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::exitAcceleratedCompositingMode)
74 if (webPage->corePage()->settings()->acceleratedDrawingEnabled() || webPage->corePage()->settings()->forceCompositingMode())
75 m_alwaysUseCompositing = true;
77 if (m_alwaysUseCompositing)
78 enterAcceleratedCompositingMode(0);
81 void DrawingAreaImpl::setNeedsDisplay(const IntRect& rect)
83 if (!m_isPaintingEnabled)
86 IntRect dirtyRect = rect;
87 dirtyRect.intersect(m_webPage->bounds());
89 if (dirtyRect.isEmpty())
92 if (m_layerTreeHost) {
93 ASSERT(m_dirtyRegion.isEmpty());
95 m_layerTreeHost->setNonCompositedContentsNeedDisplay(dirtyRect);
99 if (m_webPage->mainFrameHasCustomRepresentation())
102 m_dirtyRegion.unite(dirtyRect);
106 void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
108 if (!m_isPaintingEnabled)
111 if (m_layerTreeHost) {
112 ASSERT(m_scrollRect.isEmpty());
113 ASSERT(m_scrollOffset.isEmpty());
114 ASSERT(m_dirtyRegion.isEmpty());
116 m_layerTreeHost->scrollNonCompositedContents(scrollRect, scrollOffset);
120 if (m_webPage->mainFrameHasCustomRepresentation())
123 if (!m_scrollRect.isEmpty() && scrollRect != m_scrollRect) {
124 unsigned scrollArea = scrollRect.width() * scrollRect.height();
125 unsigned currentScrollArea = m_scrollRect.width() * m_scrollRect.height();
127 if (currentScrollArea >= scrollArea) {
128 // The rect being scrolled is at least as large as the rect we'd like to scroll.
129 // Go ahead and just invalidate the scroll rect.
130 setNeedsDisplay(scrollRect);
134 // Just repaint the entire current scroll rect, we'll scroll the new rect instead.
135 setNeedsDisplay(m_scrollRect);
136 m_scrollRect = IntRect();
137 m_scrollOffset = IntSize();
140 // Get the part of the dirty region that is in the scroll rect.
141 Region dirtyRegionInScrollRect = intersect(scrollRect, m_dirtyRegion);
142 if (!dirtyRegionInScrollRect.isEmpty()) {
143 // There are parts of the dirty region that are inside the scroll rect.
144 // We need to subtract them from the region, move them and re-add them.
145 m_dirtyRegion.subtract(scrollRect);
147 // Move the dirty parts.
148 Region movedDirtyRegionInScrollRect = intersect(translate(dirtyRegionInScrollRect, scrollOffset), scrollRect);
150 // And add them back.
151 m_dirtyRegion.unite(movedDirtyRegionInScrollRect);
154 // Compute the scroll repaint region.
155 Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollOffset));
157 m_dirtyRegion.unite(scrollRepaintRegion);
160 m_scrollRect = scrollRect;
161 m_scrollOffset += scrollOffset;
164 void DrawingAreaImpl::setLayerTreeStateIsFrozen(bool isFrozen)
166 if (m_layerTreeStateIsFrozen == isFrozen)
169 m_layerTreeStateIsFrozen = isFrozen;
172 m_layerTreeHost->setLayerFlushSchedulingEnabled(!isFrozen);
175 m_exitCompositingTimer.stop();
176 else if (m_wantsToExitAcceleratedCompositingMode)
177 exitAcceleratedCompositingModeSoon();
180 void DrawingAreaImpl::forceRepaint()
182 setNeedsDisplay(m_webPage->bounds());
184 m_webPage->layoutIfNeeded();
186 if (m_layerTreeHost) {
187 // FIXME: We need to do the same work as the layerHostDidFlushLayers function here,
188 // but clearly it doesn't make sense to call the function with that name.
189 // Consider refactoring and renaming it.
190 if (m_compositingAccordingToProxyMessages)
191 m_layerTreeHost->forceRepaint();
193 // Call setShouldNotifyAfterNextScheduledLayerFlush(false) here to
194 // prevent layerHostDidFlushLayers() from being called a second time.
195 m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
196 layerHostDidFlushLayers();
201 m_isWaitingForDidUpdate = false;
205 void DrawingAreaImpl::didInstallPageOverlay()
208 m_layerTreeHost->didInstallPageOverlay();
211 void DrawingAreaImpl::didUninstallPageOverlay()
214 m_layerTreeHost->didUninstallPageOverlay();
216 setNeedsDisplay(m_webPage->bounds());
219 void DrawingAreaImpl::setPageOverlayNeedsDisplay(const IntRect& rect)
221 if (m_layerTreeHost) {
222 m_layerTreeHost->setPageOverlayNeedsDisplay(rect);
226 setNeedsDisplay(rect);
229 void DrawingAreaImpl::setPageOverlayOpacity(float value)
232 m_layerTreeHost->setPageOverlayOpacity(value);
235 bool DrawingAreaImpl::pageOverlayShouldApplyFadeWhenPainting() const
237 if (m_layerTreeHost && !m_layerTreeHost->pageOverlayShouldApplyFadeWhenPainting())
243 void DrawingAreaImpl::pageCustomRepresentationChanged()
245 if (!m_alwaysUseCompositing)
248 if (m_webPage->mainFrameHasCustomRepresentation()) {
250 exitAcceleratedCompositingMode();
251 } else if (!m_layerTreeHost)
252 enterAcceleratedCompositingMode(0);
255 void DrawingAreaImpl::setPaintingEnabled(bool paintingEnabled)
257 m_isPaintingEnabled = paintingEnabled;
260 void DrawingAreaImpl::layerHostDidFlushLayers()
262 ASSERT(m_layerTreeHost);
264 m_layerTreeHost->forceRepaint();
266 if (m_shouldSendDidUpdateBackingStoreState && !exitAcceleratedCompositingModePending()) {
267 sendDidUpdateBackingStoreState();
271 if (!m_layerTreeHost)
274 #if USE(ACCELERATED_COMPOSITING)
275 ASSERT(!m_compositingAccordingToProxyMessages);
276 if (!exitAcceleratedCompositingModePending()) {
277 m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext()));
278 m_compositingAccordingToProxyMessages = true;
283 void DrawingAreaImpl::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
285 // FIXME: Instead of using nested if statements, we should keep a compositing state
286 // enum in the DrawingAreaImpl object and have a changeAcceleratedCompositingState function
287 // that takes the new state.
290 if (!m_layerTreeHost) {
291 // We're actually entering accelerated compositing mode.
292 enterAcceleratedCompositingMode(graphicsLayer);
294 // We're already in accelerated compositing mode, but the root compositing layer changed.
296 m_exitCompositingTimer.stop();
297 m_wantsToExitAcceleratedCompositingMode = false;
299 // If we haven't sent the EnterAcceleratedCompositingMode message, make sure that the
300 // layer tree host calls us back after the next layer flush so we can send it then.
301 if (!m_compositingAccordingToProxyMessages)
302 m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
304 m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
307 if (m_layerTreeHost) {
308 m_layerTreeHost->setRootCompositingLayer(0);
309 if (!m_alwaysUseCompositing) {
310 // We'll exit accelerated compositing mode on a timer, to avoid re-entering
311 // compositing code via display() and layout.
312 // If we're leaving compositing mode because of a setSize, it is safe to
313 // exit accelerated compositing mode right away.
314 if (m_inUpdateBackingStoreState)
315 exitAcceleratedCompositingMode();
317 exitAcceleratedCompositingModeSoon();
323 void DrawingAreaImpl::scheduleCompositingLayerSync()
325 if (!m_layerTreeHost)
327 m_layerTreeHost->scheduleLayerFlush();
330 #if ENABLE(TIZEN_ONESHOT_DRAWING_SYNCHRONIZATION)
331 void DrawingAreaImpl::setNeedsOneShotDrawingSynchronization()
333 if (!m_layerTreeHost)
335 m_layerTreeHost->setNeedsOneShotDrawingSynchronization();
339 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
340 void DrawingAreaImpl::addOrUpdateScrollingLayer(WebCore::GraphicsLayer* scrollingLayer, WebCore::GraphicsLayer* contentsLayer, const WebCore::IntSize& scrollSize)
342 if (!m_layerTreeHost)
344 m_layerTreeHost->addOrUpdateScrollingLayer(scrollingLayer, contentsLayer, scrollSize);
347 void DrawingAreaImpl::removeScrollingLayer(WebCore::GraphicsLayer* scrollingLayer, WebCore::GraphicsLayer* contentsLayer)
349 if (!m_layerTreeHost)
351 m_layerTreeHost->removeScrollingLayer(scrollingLayer, contentsLayer);
355 void DrawingAreaImpl::updateBackingStoreState(uint64_t stateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset)
357 ASSERT(!m_inUpdateBackingStoreState);
358 m_inUpdateBackingStoreState = true;
360 ASSERT_ARG(stateID, stateID >= m_backingStoreStateID);
361 if (stateID != m_backingStoreStateID) {
362 m_backingStoreStateID = stateID;
363 m_shouldSendDidUpdateBackingStoreState = true;
365 m_webPage->setDeviceScaleFactor(deviceScaleFactor);
366 m_webPage->setSize(size);
367 m_webPage->layoutIfNeeded();
368 m_webPage->scrollMainFrameIfNotAtMaxScrollPosition(scrollOffset);
370 if (m_layerTreeHost) {
371 m_layerTreeHost->deviceScaleFactorDidChange();
372 // Use the previously set page size instead of the argument.
373 // It gets adjusted properly when using the fixed layout mode.
374 m_layerTreeHost->sizeDidChange(m_webPage->size());
376 m_dirtyRegion = m_webPage->bounds();
378 ASSERT(size == m_webPage->size());
379 if (!m_shouldSendDidUpdateBackingStoreState) {
380 // We've already sent a DidUpdateBackingStoreState message for this state. We have nothing more to do.
381 m_inUpdateBackingStoreState = false;
386 // The UI process has updated to a new backing store state. Any Update messages we sent before
387 // this point will be ignored. We wait to set this to false until after updating the page's
388 // size so that any displays triggered by the relayout will be ignored. If we're supposed to
389 // respond to the UpdateBackingStoreState message immediately, we'll do a display anyway in
390 // sendDidUpdateBackingStoreState; otherwise we shouldn't do one right now.
391 m_isWaitingForDidUpdate = false;
393 if (respondImmediately) {
394 // Make sure to resume painting if we're supposed to respond immediately, otherwise we'll just
395 // send back an empty UpdateInfo struct.
396 if (m_isPaintingSuspended)
399 sendDidUpdateBackingStoreState();
402 m_inUpdateBackingStoreState = false;
405 void DrawingAreaImpl::sendDidUpdateBackingStoreState()
407 ASSERT(!m_isWaitingForDidUpdate);
408 ASSERT(m_shouldSendDidUpdateBackingStoreState);
410 m_shouldSendDidUpdateBackingStoreState = false;
412 UpdateInfo updateInfo;
414 if (!m_isPaintingSuspended && !m_layerTreeHost)
417 LayerTreeContext layerTreeContext;
419 if (m_isPaintingSuspended || m_layerTreeHost) {
420 updateInfo.viewSize = m_webPage->size();
421 updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
423 if (m_layerTreeHost) {
424 layerTreeContext = m_layerTreeHost->layerTreeContext();
426 // We don't want the layer tree host to notify after the next scheduled
427 // layer flush because that might end up sending an EnterAcceleratedCompositingMode
428 // message back to the UI process, but the updated layer tree context
429 // will be sent back in the DidUpdateBackingStoreState message.
430 m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
431 m_layerTreeHost->forceRepaint();
435 m_webPage->send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext));
436 m_compositingAccordingToProxyMessages = !layerTreeContext.isEmpty();
439 void DrawingAreaImpl::didUpdate()
441 // We might get didUpdate messages from the UI process even after we've
442 // entered accelerated compositing mode. Ignore them.
446 m_isWaitingForDidUpdate = false;
448 // Display if needed. We call displayTimerFired here since it will throttle updates to 60fps.
452 void DrawingAreaImpl::suspendPainting()
454 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
455 m_paintingSuspendCount++;
456 if (m_isPaintingSuspended)
459 ASSERT(!m_isPaintingSuspended);
462 m_layerTreeHost->pauseRendering();
464 m_isPaintingSuspended = true;
465 m_displayTimer.stop();
467 m_webPage->corePage()->suspendScriptedAnimations();
469 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
470 m_webPage->send(Messages::DrawingAreaProxy::DidSuspendPainting());
474 void DrawingAreaImpl::resumePainting()
476 if (!m_isPaintingSuspended) {
477 // FIXME: We can get a call to resumePainting when painting is not suspended.
478 // This happens when sending a synchronous message to create a new page. See <rdar://problem/8976531>.
482 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
483 if (--m_paintingSuspendCount > 0)
488 m_layerTreeHost->resumeRendering();
490 m_isPaintingSuspended = false;
492 // FIXME: We shouldn't always repaint everything here.
493 setNeedsDisplay(m_webPage->bounds());
496 if (m_webPage->windowIsVisible())
497 m_webPage->corePage()->resumeScriptedAnimations();
499 m_webPage->corePage()->resumeScriptedAnimations();
503 void DrawingAreaImpl::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLayer)
505 m_exitCompositingTimer.stop();
506 m_wantsToExitAcceleratedCompositingMode = false;
508 ASSERT(!m_layerTreeHost);
510 m_layerTreeHost = LayerTreeHost::create(m_webPage);
511 if (!m_inUpdateBackingStoreState)
512 m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
514 m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
516 // Non-composited content will now be handled exclusively by the layer tree host.
517 m_dirtyRegion = Region();
518 m_scrollRect = IntRect();
519 m_scrollOffset = IntSize();
520 m_displayTimer.stop();
521 m_isWaitingForDidUpdate = false;
524 void DrawingAreaImpl::exitAcceleratedCompositingMode()
526 if (m_alwaysUseCompositing && !m_webPage->mainFrameHasCustomRepresentation())
529 ASSERT(!m_layerTreeStateIsFrozen);
531 m_exitCompositingTimer.stop();
532 m_wantsToExitAcceleratedCompositingMode = false;
534 ASSERT(m_layerTreeHost);
536 m_layerTreeHost->invalidate();
537 m_layerTreeHost = nullptr;
538 m_dirtyRegion = m_webPage->bounds();
540 if (m_inUpdateBackingStoreState)
543 if (m_shouldSendDidUpdateBackingStoreState) {
544 sendDidUpdateBackingStoreState();
548 UpdateInfo updateInfo;
549 if (m_isPaintingSuspended) {
550 updateInfo.viewSize = m_webPage->size();
551 updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
555 #if USE(ACCELERATED_COMPOSITING)
556 // Send along a complete update of the page so we can paint the contents right after we exit the
557 // accelerated compositing mode, eliminiating flicker.
558 if (m_compositingAccordingToProxyMessages) {
559 m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo));
560 m_compositingAccordingToProxyMessages = false;
562 // If we left accelerated compositing mode before we sent an EnterAcceleratedCompositingMode message to the
563 // UI process, we still need to let it know about the new contents, so send an Update message.
564 m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
569 void DrawingAreaImpl::exitAcceleratedCompositingModeSoon()
571 if (m_layerTreeStateIsFrozen) {
572 m_wantsToExitAcceleratedCompositingMode = true;
576 if (exitAcceleratedCompositingModePending())
579 m_exitCompositingTimer.startOneShot(0);
582 void DrawingAreaImpl::scheduleDisplay()
584 ASSERT(!m_layerTreeHost);
586 if (m_isWaitingForDidUpdate)
589 if (m_isPaintingSuspended)
592 if (m_dirtyRegion.isEmpty())
595 if (m_displayTimer.isActive())
598 m_displayTimer.startOneShot(0);
601 void DrawingAreaImpl::displayTimerFired()
606 void DrawingAreaImpl::display()
608 ASSERT(!m_layerTreeHost);
609 ASSERT(!m_isWaitingForDidUpdate);
610 ASSERT(!m_inUpdateBackingStoreState);
612 if (m_isPaintingSuspended)
615 if (m_dirtyRegion.isEmpty())
618 if (m_shouldSendDidUpdateBackingStoreState) {
619 sendDidUpdateBackingStoreState();
623 UpdateInfo updateInfo;
626 if (m_layerTreeHost) {
627 // The call to update caused layout which turned on accelerated compositing.
628 // Don't send an Update message in this case.
632 m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
633 m_isWaitingForDidUpdate = true;
636 static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& rects)
638 const size_t rectThreshold = 10;
639 const double wastedSpaceThreshold = 0.75;
641 if (rects.size() <= 1 || rects.size() > rectThreshold)
644 // Attempt to guess whether or not we should use the region bounds rect or the individual rects.
645 // We do this by computing the percentage of "wasted space" in the bounds. If that wasted space
646 // is too large, then we will do individual rect painting instead.
647 unsigned boundsArea = bounds.width() * bounds.height();
648 unsigned rectsArea = 0;
649 for (size_t i = 0; i < rects.size(); ++i)
650 rectsArea += rects[i].width() * rects[i].height();
652 double wastedSpace = 1 - (static_cast<double>(rectsArea) / boundsArea);
654 return wastedSpace <= wastedSpaceThreshold;
658 PassOwnPtr<GraphicsContext> DrawingAreaImpl::createGraphicsContext(ShareableBitmap* bitmap)
660 return bitmap->createGraphicsContext();
664 void DrawingAreaImpl::display(UpdateInfo& updateInfo)
666 ASSERT(!m_isPaintingSuspended);
667 ASSERT(!m_layerTreeHost);
668 ASSERT(!m_webPage->size().isEmpty());
670 // FIXME: It would be better if we could avoid painting altogether when there is a custom representation.
671 if (m_webPage->mainFrameHasCustomRepresentation()) {
672 // ASSUMPTION: the custom representation will be painting the dirty region for us.
673 m_dirtyRegion = Region();
677 m_webPage->layoutIfNeeded();
679 // The layout may have put the page into accelerated compositing mode. If the LayerTreeHost is
680 // in charge of displaying, we have nothing more to do.
684 updateInfo.viewSize = m_webPage->size();
685 updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
687 IntRect bounds = m_dirtyRegion.bounds();
688 ASSERT(m_webPage->bounds().contains(bounds));
690 IntSize bitmapSize = bounds.size();
691 float deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
692 bitmapSize.scale(deviceScaleFactor);
693 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bitmapSize, ShareableBitmap::SupportsAlpha);
697 if (!bitmap->createHandle(updateInfo.bitmapHandle))
700 Vector<IntRect> rects = m_dirtyRegion.rects();
702 if (shouldPaintBoundsRect(bounds, rects)) {
704 rects.append(bounds);
707 updateInfo.scrollRect = m_scrollRect;
708 updateInfo.scrollOffset = m_scrollOffset;
710 m_dirtyRegion = Region();
711 m_scrollRect = IntRect();
712 m_scrollOffset = IntSize();
714 OwnPtr<GraphicsContext> graphicsContext = createGraphicsContext(bitmap.get());
715 graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
717 updateInfo.updateRectBounds = bounds;
719 graphicsContext->translate(-bounds.x(), -bounds.y());
721 for (size_t i = 0; i < rects.size(); ++i) {
722 m_webPage->drawRect(*graphicsContext, rects[i]);
723 if (m_webPage->hasPageOverlay())
724 m_webPage->drawPageOverlay(*graphicsContext, rects[i]);
725 updateInfo.updateRects.append(rects[i]);
728 // Layout can trigger more calls to setNeedsDisplay and we don't want to process them
729 // until the UI process has painted the update, so we stop the timer here.
730 m_displayTimer.stop();
733 #if USE(UI_SIDE_COMPOSITING)
734 void DrawingAreaImpl::didReceiveLayerTreeHostMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
737 m_layerTreeHost->didReceiveLayerTreeHostMessage(connection, messageID, arguments);
742 void DrawingAreaImpl::setLayerHostingMode(uint32_t opaqueLayerHostingMode)
744 LayerHostingMode layerHostingMode = static_cast<LayerHostingMode>(opaqueLayerHostingMode);
745 m_webPage->setLayerHostingMode(layerHostingMode);
747 if (!m_layerTreeHost)
750 LayerTreeContext oldLayerTreeContext = m_layerTreeHost->layerTreeContext();
751 m_layerTreeHost->setLayerHostingMode(layerHostingMode);
753 if (m_layerTreeHost->layerTreeContext() != oldLayerTreeContext)
754 m_webPage->send(Messages::DrawingAreaProxy::UpdateAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext()));
758 } // namespace WebKit