2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 #include "LayerTreeCoordinator.h"
31 #include "CoordinatedGraphicsArgumentCoders.h"
32 #include "DrawingAreaImpl.h"
33 #include "GraphicsContext.h"
34 #include "LayerTreeCoordinatorProxyMessages.h"
35 #include "MessageID.h"
36 #include "SurfaceUpdateInfo.h"
37 #include "WebCoreArgumentCoders.h"
38 #include "WebGraphicsLayer.h"
40 #include <WebCore/Frame.h>
41 #include <WebCore/FrameView.h>
42 #include <WebCore/Page.h>
43 #include <WebCore/RenderLayer.h>
44 #include <WebCore/RenderLayerBacking.h>
45 #include <WebCore/RenderLayerCompositor.h>
46 #include <WebCore/RenderView.h>
47 #include <WebCore/Settings.h>
49 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
50 #include "WebProcess.h"
53 using namespace WebCore;
57 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
58 const float LayerTreeCoordinator::s_layerFlushTimerDelayTable[s_layerFlushTimerDelayMaxLevel] = {0, 0.1, 0.2, 0.6, 1.3};
61 PassRefPtr<LayerTreeCoordinator> LayerTreeCoordinator::create(WebPage* webPage)
63 return adoptRef(new LayerTreeCoordinator(webPage));
66 LayerTreeCoordinator::~LayerTreeCoordinator()
68 // Prevent setWebGraphicsLayerClient(0) -> detachLayer() from modifying the set while we iterate it.
69 HashSet<WebCore::WebGraphicsLayer*> registeredLayers;
70 registeredLayers.swap(m_registeredLayers);
72 HashSet<WebCore::WebGraphicsLayer*>::iterator end = registeredLayers.end();
73 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = registeredLayers.begin(); it != end; ++it)
74 (*it)->setWebGraphicsLayerClient(0);
77 LayerTreeCoordinator::LayerTreeCoordinator(WebPage* webPage)
78 : LayerTreeHost(webPage)
79 , m_notifyAfterScheduledLayerFlush(false)
82 , m_waitingForUIProcess(false)
84 , m_waitingForUIProcess(true)
86 , m_isSuspended(false)
88 , m_shouldSendScrollPositionUpdate(true)
89 , m_shouldSyncFrame(false)
90 , m_shouldSyncRootLayer(true)
91 , m_layerFlushTimer(this, &LayerTreeCoordinator::layerFlushTimerFired)
92 , m_releaseInactiveAtlasesTimer(this, &LayerTreeCoordinator::releaseInactiveAtlasesTimerFired)
93 , m_layerFlushSchedulingEnabled(true)
94 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
95 , m_layerFlushTimerDelay(0.0)
96 , m_deferLayerFlushEnabled(false)
97 , m_layerFlushTimerDelayLevel(0)
99 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
100 , m_suspendedJavaScript(false)
102 #if ENABLE(TIZEN_ONESHOT_DRAWING_SYNCHRONIZATION)
103 , m_needsOneShotDrawingSynchronization(false)
105 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
106 , m_isGLAccelerationMode(true)
108 , m_animationsLocked(false)
110 // Create a root layer.
111 m_rootLayer = GraphicsLayer::create(this);
112 WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get());
113 webRootLayer->setRootLayer(true);
115 m_rootLayer->setName("LayerTreeCoordinator root layer");
117 m_rootLayer->setDrawsContent(false);
118 m_rootLayer->setSize(m_webPage->size());
119 m_layerTreeContext.webLayerID = toWebGraphicsLayer(webRootLayer)->id();
121 m_nonCompositedContentLayer = GraphicsLayer::create(this);
122 toWebGraphicsLayer(m_rootLayer.get())->setWebGraphicsLayerClient(this);
124 m_nonCompositedContentLayer->setName("LayerTreeCoordinator non-composited content");
126 m_nonCompositedContentLayer->setDrawsContent(true);
127 m_nonCompositedContentLayer->setSize(m_webPage->size());
129 m_rootLayer->addChild(m_nonCompositedContentLayer.get());
131 if (m_webPage->hasPageOverlay())
132 createPageOverlayLayer();
134 scheduleLayerFlush();
137 void LayerTreeCoordinator::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
139 if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
142 m_layerFlushSchedulingEnabled = layerFlushingEnabled;
144 if (m_layerFlushSchedulingEnabled) {
145 scheduleLayerFlush();
149 cancelPendingLayerFlush();
152 void LayerTreeCoordinator::scheduleLayerFlush()
154 if (!m_layerFlushSchedulingEnabled)
157 if (!m_layerFlushTimer.isActive()) {
158 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
159 m_layerFlushTimerDelay = deferredLayerFlushDelay();
160 m_layerFlushTimer.startOneShot(m_layerFlushTimerDelay);
162 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
163 if (m_layerFlushTimerDelay > 0.0)
164 m_webPage->suspendAnimationController();
167 m_layerFlushTimer.startOneShot(0.0);
171 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
172 if (!m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply)
173 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply = m_webPage->connection()->dispatchWorkItemWhileWaitingForSyncReply(WTF::bind(&LayerTreeCoordinator::performScheduledLayerFlushForcely, this));
177 void LayerTreeCoordinator::cancelPendingLayerFlush()
179 m_layerFlushTimer.stop();
180 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
181 m_webPage->connection()->clearWorkItemWhileWaitingForSyncReply(m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply);
182 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply.clear();
186 void LayerTreeCoordinator::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
188 m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
191 void LayerTreeCoordinator::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer)
193 m_nonCompositedContentLayer->removeAllChildren();
194 m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
196 // Add the accelerated layer tree hierarchy.
198 m_nonCompositedContentLayer->addChild(graphicsLayer);
201 void LayerTreeCoordinator::invalidate()
203 cancelPendingLayerFlush();
206 m_rootLayer = nullptr;
210 void LayerTreeCoordinator::setNonCompositedContentsNeedDisplay(const WebCore::IntRect& rect)
212 m_nonCompositedContentLayer->setNeedsDisplayInRect(rect);
213 if (m_pageOverlayLayer)
214 m_pageOverlayLayer->setNeedsDisplayInRect(rect);
216 scheduleLayerFlush();
219 void LayerTreeCoordinator::scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
221 setNonCompositedContentsNeedDisplay(scrollRect);
224 void LayerTreeCoordinator::forceRepaint()
226 // We need to schedule another flush, otherwise the forced paint might cancel a later expected flush.
227 // This is aligned with LayerTreeHostCA.
228 scheduleLayerFlush();
229 flushPendingLayerChanges();
232 void LayerTreeCoordinator::sizeDidChange(const WebCore::IntSize& newSize)
234 if (m_rootLayer->size() == newSize)
237 m_rootLayer->setSize(newSize);
239 // If the newSize exposes new areas of the non-composited content a setNeedsDisplay is needed
240 // for those newly exposed areas.
241 FloatSize oldSize = m_nonCompositedContentLayer->size();
242 m_nonCompositedContentLayer->setSize(newSize);
244 if (newSize.width() > oldSize.width()) {
245 float height = std::min(static_cast<float>(newSize.height()), oldSize.height());
246 m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(oldSize.width(), 0, newSize.width() - oldSize.width(), height));
249 if (newSize.height() > oldSize.height())
250 m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height()));
252 if (m_pageOverlayLayer)
253 m_pageOverlayLayer->setSize(newSize);
255 scheduleLayerFlush();
258 void LayerTreeCoordinator::didInstallPageOverlay()
260 createPageOverlayLayer();
261 scheduleLayerFlush();
264 void LayerTreeCoordinator::didUninstallPageOverlay()
266 destroyPageOverlayLayer();
267 scheduleLayerFlush();
270 void LayerTreeCoordinator::setPageOverlayNeedsDisplay(const WebCore::IntRect& rect)
272 ASSERT(m_pageOverlayLayer);
273 m_pageOverlayLayer->setNeedsDisplayInRect(rect);
274 scheduleLayerFlush();
277 void LayerTreeCoordinator::setPageOverlayOpacity(float value)
279 ASSERT(m_pageOverlayLayer);
280 m_pageOverlayLayer->setOpacity(value);
281 scheduleLayerFlush();
284 bool LayerTreeCoordinator::flushPendingLayerChanges()
286 if (m_waitingForUIProcess)
289 bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
290 m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly();
291 if (m_pageOverlayLayer)
292 m_pageOverlayLayer->syncCompositingStateForThisLayerOnly();
294 m_rootLayer->syncCompositingStateForThisLayerOnly();
296 if (m_shouldSyncRootLayer) {
297 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetRootCompositingLayer(toWebGraphicsLayer(m_rootLayer.get())->id()));
298 m_shouldSyncRootLayer = false;
301 if (!m_shouldSyncFrame)
304 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
305 if (!m_compositedContentLayers.isEmpty()) {
306 Vector<uint32_t> weblayerIDsCopy;
307 copyToVector(m_compositedContentLayers, weblayerIDsCopy);
308 m_compositedContentLayers.clear();
309 bool pauseJavaScript = false;
310 for (size_t i = 0; i < weblayerIDsCopy.size(); ++i) {
311 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(weblayerIDsCopy[i]);
312 if (layer && !layer->swapPlatformSurfaces())
313 pauseJavaScript = true;
315 if (pauseJavaScript) {
316 m_webPage->suspendJavaScriptAndResources();
317 m_suspendedJavaScript = true;
322 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
323 m_webPage->suspendAnimationController();
325 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DidRenderFrame());
326 m_waitingForUIProcess = true;
327 m_shouldSyncFrame = false;
332 void LayerTreeCoordinator::syncLayerState(WebLayerID id, const WebLayerInfo& info)
334 if (m_shouldSendScrollPositionUpdate) {
335 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DidChangeScrollPosition(m_visibleContentsRect.location()));
336 m_shouldSendScrollPositionUpdate = false;
339 m_shouldSyncFrame = true;
340 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetCompositingLayerState(id, info));
343 void LayerTreeCoordinator::syncLayerChildren(WebLayerID id, const Vector<WebLayerID>& children)
345 m_shouldSyncFrame = true;
346 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetCompositingLayerChildren(id, children));
349 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
350 void LayerTreeCoordinator::syncCanvas(WebLayerID id, const IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer, int flags)
352 void LayerTreeCoordinator::syncCanvas(WebLayerID id, const IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer)
355 m_shouldSyncFrame = true;
356 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
357 m_compositedContentLayers.add(id);
358 #if ENABLE(TIZEN_ACCELERATED_2D_CANVAS_EFL)
359 m_compositedContentCanvas2DLayers.add(id);
361 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SyncCanvas(id, canvasSize, graphicsSurfaceToken, frontBuffer, flags));
363 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SyncCanvas(id, canvasSize, graphicsSurfaceToken, frontBuffer));
367 #if ENABLE(CSS_FILTERS)
368 void LayerTreeCoordinator::syncLayerFilters(WebLayerID id, const FilterOperations& filters)
370 m_shouldSyncFrame = true;
371 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetCompositingLayerFilters(id, filters));
375 void LayerTreeCoordinator::attachLayer(WebGraphicsLayer* layer)
377 ASSERT(!m_registeredLayers.contains(layer));
378 m_registeredLayers.add(layer);
380 layer->setContentsScale(m_contentsScale);
381 layer->adjustVisibleRect();
384 void LayerTreeCoordinator::detachLayer(WebGraphicsLayer* layer)
386 m_registeredLayers.remove(layer);
387 m_shouldSyncFrame = true;
388 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DeleteCompositingLayer(layer->id()));
390 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
391 m_compositedContentLayers.remove(layer->id());
393 #if ENABLE(TIZEN_ACCELERATED_2D_CANVAS_EFL)
394 m_compositedContentCanvas2DLayers.remove(layer->id());
398 static void updateOffsetFromViewportForSelf(RenderLayer* renderLayer)
400 // These conditions must match the conditions in RenderLayerCompositor::requiresCompositingForPosition.
401 RenderLayerBacking* backing = renderLayer->backing();
405 RenderStyle* style = renderLayer->renderer()->style();
409 if (!renderLayer->renderer()->isOutOfFlowPositioned() || renderLayer->renderer()->style()->position() != FixedPosition)
412 if (!renderLayer->renderer()->container()->isRenderView())
415 if (!renderLayer->isStackingContext())
418 WebGraphicsLayer* graphicsLayer = toWebGraphicsLayer(backing->graphicsLayer());
419 graphicsLayer->setFixedToViewport(true);
422 static void updateOffsetFromViewportForLayer(RenderLayer* renderLayer)
424 updateOffsetFromViewportForSelf(renderLayer);
426 if (renderLayer->firstChild())
427 updateOffsetFromViewportForLayer(renderLayer->firstChild());
428 if (renderLayer->nextSibling())
429 updateOffsetFromViewportForLayer(renderLayer->nextSibling());
432 void LayerTreeCoordinator::syncFixedLayers()
434 if (!m_webPage->corePage()->settings() || !m_webPage->corePage()->settings()->acceleratedCompositingForFixedPositionEnabled())
437 if (!m_webPage->mainFrame()->view()->hasFixedObjects())
440 RenderLayer* rootRenderLayer = m_webPage->mainFrame()->contentRenderer()->compositor()->rootRenderLayer();
441 ASSERT(rootRenderLayer);
442 if (rootRenderLayer->firstChild())
443 updateOffsetFromViewportForLayer(rootRenderLayer->firstChild());
446 void LayerTreeCoordinator::lockAnimations()
448 m_animationsLocked = true;
449 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetAnimationsLocked(true));
452 void LayerTreeCoordinator::unlockAnimations()
454 if (!m_animationsLocked)
457 m_animationsLocked = false;
458 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetAnimationsLocked(false));
461 void LayerTreeCoordinator::performScheduledLayerFlush()
463 #if ENABLE(TIZEN_ACCELERATED_2D_CANVAS_EFL)
464 if (m_waitingForUIProcess && !m_compositedContentCanvas2DLayers.isEmpty()) {
465 Vector<uint32_t> weblayerIDsCopy;
466 copyToVector(m_compositedContentCanvas2DLayers, weblayerIDsCopy);
467 m_compositedContentCanvas2DLayers.clear();
468 for (size_t i = 0; i < weblayerIDsCopy.size(); ++i) {
469 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(weblayerIDsCopy[i]);
471 layer->flushPlatformSurfaces();
477 if (m_isSuspended || m_waitingForUIProcess)
480 #if ENABLE(TIZEN_CUTOFF_TILES_OVER_MEMORY_LIMIT)
481 calculateCutOffThreshold();
484 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER) && !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
485 // Make sure that any previously registered animation callbacks are being executed before we flush the layers.
486 m_webPage->corePage()->mainFrame()->view()->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime()));
489 // We lock the animations while performing layout, to avoid flickers caused by animations continuing in the UI process while
490 // the web process layout wants to cancel them.
493 m_webPage->layoutIfNeeded();
495 // We can unlock the animations before flushing if there are no visible changes, for example if there are content updates
496 // in a layer with opacity 0.
497 bool canUnlockBeforeFlush = !m_isValid || !toWebGraphicsLayer(m_rootLayer.get())->hasPendingVisibleChanges();
498 if (canUnlockBeforeFlush)
504 #if ENABLE(TIZEN_ONESHOT_DRAWING_SYNCHRONIZATION)
505 if (m_needsOneShotDrawingSynchronization) {
506 scheduleLayerFlush();
507 toWebGraphicsLayer(m_nonCompositedContentLayer.get())->adjustVisibleRect();
508 m_needsOneShotDrawingSynchronization = false;
513 if (flushPendingLayerChanges())
514 didPerformScheduledLayerFlush();
517 void LayerTreeCoordinator::didPerformScheduledLayerFlush()
519 if (m_notifyAfterScheduledLayerFlush) {
520 static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
521 m_notifyAfterScheduledLayerFlush = false;
525 void LayerTreeCoordinator::layerFlushTimerFired(Timer<LayerTreeCoordinator>*)
527 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
528 m_webPage->connection()->clearWorkItemWhileWaitingForSyncReply(m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply);
529 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply.clear();
531 performScheduledLayerFlush();
534 void LayerTreeCoordinator::createPageOverlayLayer()
536 ASSERT(!m_pageOverlayLayer);
538 m_pageOverlayLayer = GraphicsLayer::create(this);
540 m_pageOverlayLayer->setName("LayerTreeCoordinator page overlay content");
543 m_pageOverlayLayer->setDrawsContent(true);
544 m_pageOverlayLayer->setSize(m_webPage->size());
546 m_rootLayer->addChild(m_pageOverlayLayer.get());
549 void LayerTreeCoordinator::destroyPageOverlayLayer()
551 ASSERT(m_pageOverlayLayer);
552 m_pageOverlayLayer->removeFromParent();
553 m_pageOverlayLayer = nullptr;
556 int64_t LayerTreeCoordinator::adoptImageBackingStore(Image* image)
559 return InvalidWebLayerID;
564 QImage* nativeImage = image->nativeImageForCurrentFrame();
567 return InvalidWebLayerID;
569 key = nativeImage->cacheKey();
570 #elif ENABLE(TIZEN_WEBKIT2_TILED_AC)
571 key = (int64_t)(image);
574 HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
576 if (it != m_directlyCompositedImageRefCounts.end()) {
581 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), (image->currentFrameHasAlpha() ? ShareableBitmap::SupportsAlpha : 0));
583 OwnPtr<WebCore::GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
584 graphicsContext->drawImage(image, ColorSpaceDeviceRGB, IntPoint::zero());
587 ShareableBitmap::Handle handle;
588 bitmap->createHandle(handle);
589 m_webPage->send(Messages::LayerTreeCoordinatorProxy::CreateDirectlyCompositedImage(key, handle));
590 m_directlyCompositedImageRefCounts.add(key, 1);
594 void LayerTreeCoordinator::releaseImageBackingStore(int64_t key)
598 HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
599 if (it == m_directlyCompositedImageRefCounts.end())
607 m_directlyCompositedImageRefCounts.remove(it);
608 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DestroyDirectlyCompositedImage(key));
612 void LayerTreeCoordinator::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
616 void LayerTreeCoordinator::notifySyncRequired(const WebCore::GraphicsLayer*)
620 void LayerTreeCoordinator::paintContents(const WebCore::GraphicsLayer* graphicsLayer, WebCore::GraphicsContext& graphicsContext, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect)
622 if (graphicsLayer == m_nonCompositedContentLayer) {
623 m_webPage->drawRect(graphicsContext, clipRect);
627 if (graphicsLayer == m_pageOverlayLayer) {
628 // Overlays contain transparent contents and won't clear the context as part of their rendering, so we do it here.
629 graphicsContext.clearRect(clipRect);
630 m_webPage->drawPageOverlay(graphicsContext, clipRect);
635 bool LayerTreeCoordinator::showDebugBorders(const WebCore::GraphicsLayer*) const
637 return m_webPage->corePage()->settings()->showDebugBorders();
640 bool LayerTreeCoordinator::showRepaintCounter(const WebCore::GraphicsLayer*) const
642 return m_webPage->corePage()->settings()->showRepaintCounter();
645 bool LayerTreeHost::supportsAcceleratedCompositing()
650 void LayerTreeCoordinator::createTile(WebLayerID layerID, int tileID, const SurfaceUpdateInfo& updateInfo, const WebCore::IntRect& targetRect)
652 m_shouldSyncFrame = true;
653 m_webPage->send(Messages::LayerTreeCoordinatorProxy::CreateTileForLayer(layerID, tileID, targetRect, updateInfo));
656 void LayerTreeCoordinator::updateTile(WebLayerID layerID, int tileID, const SurfaceUpdateInfo& updateInfo, const WebCore::IntRect& targetRect)
658 m_shouldSyncFrame = true;
659 m_webPage->send(Messages::LayerTreeCoordinatorProxy::UpdateTileForLayer(layerID, tileID, targetRect, updateInfo));
662 void LayerTreeCoordinator::removeTile(WebLayerID layerID, int tileID)
664 m_shouldSyncFrame = true;
665 m_webPage->send(Messages::LayerTreeCoordinatorProxy::RemoveTileForLayer(layerID, tileID));
668 WebCore::IntRect LayerTreeCoordinator::visibleContentsRect() const
670 return m_visibleContentsRect;
673 void LayerTreeCoordinator::setLayerAnimations(WebLayerID layerID, const GraphicsLayerAnimations& animations)
675 m_shouldSyncFrame = true;
676 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetLayerAnimations(layerID, animations.getActiveAnimations()));
679 void LayerTreeCoordinator::setVisibleContentsRect(const IntRect& rect, float scale, const FloatPoint& trajectoryVector)
681 bool contentsRectDidChange = rect != m_visibleContentsRect;
682 bool contentsScaleDidChange = scale != m_contentsScale;
684 if (trajectoryVector != FloatPoint::zero())
685 toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRectTrajectoryVector(trajectoryVector);
687 if (contentsRectDidChange || contentsScaleDidChange) {
688 m_visibleContentsRect = rect;
689 m_contentsScale = scale;
691 HashSet<WebCore::WebGraphicsLayer*>::iterator end = m_registeredLayers.end();
692 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it) {
693 if (contentsScaleDidChange)
694 (*it)->setContentsScale(scale);
695 if (contentsRectDidChange)
696 #if ENABLE(TIZEN_WEBKIT2_PRE_RENDERING_WITH_DIRECTIVITY)
697 (*it)->setVisibleContentRectTrajectoryVector(trajectoryVector);
699 (*it)->adjustVisibleRect();
704 scheduleLayerFlush();
705 if (m_webPage->useFixedLayout())
706 m_webPage->setFixedVisibleContentRect(rect);
707 if (contentsRectDidChange)
708 m_shouldSendScrollPositionUpdate = true;
711 #if USE(UI_SIDE_COMPOSITING)
712 void LayerTreeCoordinator::scheduleAnimation()
714 scheduleLayerFlush();
718 void LayerTreeCoordinator::renderNextFrame()
720 m_waitingForUIProcess = false;
721 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
722 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
723 if (m_layerFlushTimerDelay <= 0.0)
725 m_webPage->resumeAnimationController();
727 scheduleLayerFlush();
728 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
729 for (size_t i = 0; i < m_updateAtlases.size(); ++i)
731 for (int i = 0; i < m_updateAtlases.size(); ++i)
733 m_updateAtlases[i]->didSwapBuffers();
735 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
736 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
737 if (m_layerFlushTimerDelay > 0.0)
738 m_webPage->resumeAnimationController();
743 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
744 void LayerTreeCoordinator::performScheduledLayerFlushForcely()
746 if (!WebProcess::shared().isWaitingForJavaScriptPopupFinished())
749 m_layerFlushTimer.stop();
750 m_webPage->connection()->clearWorkItemWhileWaitingForSyncReply(m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply);
751 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply.clear();
753 m_waitingForUIProcess = false;
755 performScheduledLayerFlush();
759 bool LayerTreeCoordinator::layerTreeTileUpdatesAllowed() const
761 return !m_isSuspended && !m_waitingForUIProcess;
764 void LayerTreeCoordinator::purgeBackingStores()
766 HashSet<WebCore::WebGraphicsLayer*>::iterator end = m_registeredLayers.end();
767 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it)
768 (*it)->purgeBackingStores();
770 ASSERT(!m_directlyCompositedImageRefCounts.size());
771 m_updateAtlases.clear();
774 PassOwnPtr<WebCore::GraphicsContext> LayerTreeCoordinator::beginContentUpdate(const WebCore::IntSize& size, ShareableBitmap::Flags flags, ShareableSurface::Handle& handle, WebCore::IntPoint& offset)
776 OwnPtr<WebCore::GraphicsContext> graphicsContext;
777 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
778 for (size_t i = 0; i < m_updateAtlases.size(); ++i) {
780 for (int i = 0; i < m_updateAtlases.size(); ++i) {
782 UpdateAtlas* atlas = m_updateAtlases[i].get();
783 if (atlas->flags() == flags) {
784 // This will return null if there is no available buffer space.
785 graphicsContext = atlas->beginPaintingOnAvailableBuffer(handle, size, offset);
787 return graphicsContext.release();
791 static const int ScratchBufferDimension = 1024;
792 m_updateAtlases.append(adoptPtr(new UpdateAtlas(ScratchBufferDimension, flags)));
793 scheduleReleaseInactiveAtlases();
794 return m_updateAtlases.last()->beginPaintingOnAvailableBuffer(handle, size, offset);
797 #if ENABLE(TIZEN_WEBKIT2_TILED_AC) && !ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
798 void LayerTreeCoordinator::pauseRendering()
800 m_isSuspended = true;
802 // Make sure compositing webgl layer after returning from home screen.
803 HashSet<WebCore::WebGraphicsLayer*>::iterator end = m_registeredLayers.end();
804 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it) {
805 if ((*it)->contentType() == WebLayerInfo::Canvas3DContentType)
806 (*it)->markCanvasPlatformLayerNeedsUpdate();
812 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
813 void LayerTreeCoordinator::freePlatformSurface(int layerID, int platformSurfaceId)
815 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(layerID);
816 if (layer && (layer->contentType() == WebLayerInfo::Canvas3DContentType || layer->contentType() == WebLayerInfo::MediaContentType || layer->contentType() == WebLayerInfo::Canvas2DContentType)) {
817 layer->freePlatformSurface(platformSurfaceId);
819 if (m_suspendedJavaScript && layer->swapPlatformSurfaces()) {
820 m_webPage->resumeJavaScriptAndResources();
821 m_suspendedJavaScript = false;
825 // Even after a graphics layer just destroyed in WebProcess side,
826 // freePlatformSurface messages that destroyed layer can surely come.
827 // Therefore, below code should be run always before layer validity check.
828 WebProcess::shared().platformSurfacePool()->freePlatformSurface(platformSurfaceId);
831 void LayerTreeCoordinator::freePlatformSurfaceByTileID(int tileID)
833 WebProcess::shared().platformSurfacePool()->freePlatformSurfaceByTileID(tileID);
836 void LayerTreeCoordinator::removePlatformSurface(int layerID, int platformSurfaceId)
838 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(layerID);
839 if (layer && (layer->contentType() == WebLayerInfo::Canvas3DContentType || layer->contentType() == WebLayerInfo::MediaContentType || layer->contentType() == WebLayerInfo::Canvas2DContentType))
840 layer->removePlatformSurface(platformSurfaceId);
844 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
845 void LayerTreeCoordinator::setVisibleContentsRectAndTrajectoryVectorForLayer(int layerID, const WebCore::IntRect& visibleRect, const WebCore::FloatPoint& trajectoryVector)
847 GraphicsLayer* contentsLayer = WebGraphicsLayer::layerByID(layerID);
851 toWebGraphicsLayer(contentsLayer)->setVisibleRect(visibleRect);
852 if (trajectoryVector != FloatPoint::zero()) {
853 m_webPage->scrollOverflowWithTrajectoryVector(trajectoryVector);
854 toWebGraphicsLayer(contentsLayer)->setVisibleContentRectTrajectoryVector(trajectoryVector);
856 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_SCROLLBAR)
857 const Vector<GraphicsLayer*>& childLayers = contentsLayer->children();
858 for (size_t i = 0; i < childLayers.size(); ++i)
859 if (childLayers[i]->isScrollbar())
860 toWebGraphicsLayer(childLayers[i])->startAnimation();
864 toWebGraphicsLayer(contentsLayer)->adjustVisibleRect();
866 scheduleLayerFlush();
870 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
871 void LayerTreeCoordinator::addOrUpdateScrollingLayer(WebCore::GraphicsLayer* scrollingLayer, WebCore::GraphicsLayer* contentsLayer, const WebCore::IntSize& scrollSize)
873 if (!scrollingLayer || !contentsLayer)
876 toWebGraphicsLayer(contentsLayer)->setIsOverflow(true);
877 #if !ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
878 // FIXME: We might need to consider paddingBox margin for overflow scroll layer
879 // FloatPoint offset(-scrollingLayer->offsetFromRenderer().width() - scrollingLayer->boundsOrigin().x()
880 // , -scrollingLayer->offsetFromRenderer().height() - scrollingLayer->boundsOrigin().y());
881 FloatPoint offset(scrollingLayer->boundsOrigin());
882 contentsLayer->setPosition(-offset);
884 IntRect visibleRect(FloatRect(offset, scrollingLayer->size()));
885 toWebGraphicsLayer(contentsLayer)->setVisibleRect(visibleRect);
887 // FIXME: Need to set trajectoryVector?
888 // FloatPoint trajectoryVector(scrollingLayer->trajectoryVector());
889 // if (trajectoryVector != FloatPoint::zero())
890 //toWebGraphicsLayer(contentsLayer)->setVisibleContentRectTrajectoryVector(-trajectoryVector);
892 // FIXME: Scale factor might be changed.
893 // toWebGraphicsLayer(contentsLayer)->setContentsScale(m_contentsScale);
895 setNeedsOneShotDrawingSynchronization();
897 toWebGraphicsLayer(contentsLayer)->adjustVisibleRect();
900 void LayerTreeCoordinator::removeScrollingLayer(WebCore::GraphicsLayer* scrollingLayer, WebCore::GraphicsLayer* contentsLayer)
902 if (!scrollingLayer || !contentsLayer)
905 toWebGraphicsLayer(contentsLayer)->setIsOverflow(false);
906 toWebGraphicsLayer(contentsLayer)->syncLayerState();
908 #endif // ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
910 #if ENABLE(TIZEN_ONESHOT_DRAWING_SYNCHRONIZATION)
911 void LayerTreeCoordinator::setNeedsOneShotDrawingSynchronization()
913 m_needsOneShotDrawingSynchronization = true;
917 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
918 void LayerTreeCoordinator::setDeferLayerFlush(bool deferLayerFlushEnabled)
920 m_deferLayerFlushEnabled = deferLayerFlushEnabled;
921 m_layerFlushTimerDelayLevel = 0;
922 double newDelay = deferredLayerFlushDelay();
924 // If the m_layerFlushTimer is already activated, we stop the old timer and then begin the timer with a new delay
925 if (m_layerFlushTimerDelay != newDelay && m_layerFlushTimer.isActive()) {
926 m_layerFlushTimer.stop();
927 m_layerFlushTimer.startOneShot(newDelay);
929 m_layerFlushTimerDelay = newDelay;
931 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
932 if (m_layerFlushTimerDelay == 0.0)
933 m_webPage->resumeAnimationController();
937 float LayerTreeCoordinator::deferredLayerFlushDelay()
939 if (!m_deferLayerFlushEnabled)
942 if (m_layerFlushTimerDelayLevel >= s_layerFlushTimerDelayMaxLevel)
943 m_layerFlushTimerDelayLevel = s_layerFlushTimerDelayMaxLevel - 1;
945 return s_layerFlushTimerDelayTable[m_layerFlushTimerDelayLevel++];
949 #if ENABLE(TIZEN_CUTOFF_TILES_OVER_MEMORY_LIMIT)
950 static bool AscendingTileSortByDistance(TileCutOffInfo first, TileCutOffInfo second)
952 if (first.m_distance < second.m_distance)
958 void LayerTreeCoordinator::calculateCutOffThreshold()
960 Vector<WebCore::TileCutOffInfo> tilesCutOffInfo;
961 HashSet<WebCore::WebGraphicsLayer*>::iterator end = m_registeredLayers.end();
962 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it)
963 tilesCutOffInfo.append((*it)->getCutOffInfoList());
964 tilesCutOffInfo.append(toWebGraphicsLayer(m_nonCompositedContentLayer.get())->getCutOffInfoList());
966 std::sort(tilesCutOffInfo.begin(), tilesCutOffInfo.end(), AscendingTileSortByDistance);
968 size_t allocatedMemory = 0;
969 // FIXME: This patch will be considered in future.
970 // Need to correct offscreen-to-onscreen animation layer's tile cutoff computation
971 const size_t memoryLimit = 30 * 1024 * 1024; // 30 MB
972 double cutOffDistance = std::numeric_limits<double>::max();
973 for (size_t i = 0; i < tilesCutOffInfo.size(); ++i) {
974 TileCutOffInfo cutOffInfo = tilesCutOffInfo[i];
975 allocatedMemory += cutOffInfo.m_allocatedMemoryByte;
976 if (memoryLimit < allocatedMemory) {
977 cutOffDistance = cutOffInfo.m_distance;
982 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it)
983 (*it)->setCutOffDistance(cutOffDistance);
985 toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setCutOffDistance(cutOffDistance);
989 const double ReleaseInactiveAtlasesTimerInterval = 0.5;
991 void LayerTreeCoordinator::scheduleReleaseInactiveAtlases()
993 if (!m_releaseInactiveAtlasesTimer.isActive())
994 m_releaseInactiveAtlasesTimer.startRepeating(ReleaseInactiveAtlasesTimerInterval);
997 void LayerTreeCoordinator::releaseInactiveAtlasesTimerFired(Timer<LayerTreeCoordinator>*)
999 // We always want to keep one atlas for non-composited content.
1000 OwnPtr<UpdateAtlas> atlasToKeepAnyway;
1001 bool foundActiveAtlasForNonCompositedContent = false;
1002 for (int i = m_updateAtlases.size() - 1; i >= 0; --i) {
1003 UpdateAtlas* atlas = m_updateAtlases[i].get();
1004 if (!atlas->isInUse())
1005 atlas->addTimeInactive(ReleaseInactiveAtlasesTimerInterval);
1006 bool usableForNonCompositedContent = !atlas->supportsAlpha();
1007 if (atlas->isInactive()) {
1008 if (!foundActiveAtlasForNonCompositedContent && !atlasToKeepAnyway && usableForNonCompositedContent)
1009 atlasToKeepAnyway = m_updateAtlases[i].release();
1010 m_updateAtlases.remove(i);
1011 } else if (usableForNonCompositedContent)
1012 foundActiveAtlasForNonCompositedContent = true;
1015 if (!foundActiveAtlasForNonCompositedContent && atlasToKeepAnyway)
1016 m_updateAtlases.append(atlasToKeepAnyway.release());
1018 if (m_updateAtlases.size() <= 1)
1019 m_releaseInactiveAtlasesTimer.stop();
1022 } // namespace WebKit