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_RECORDING_SURFACE_SET)
103 , m_compositedContentLayersCount(0)
105 #if ENABLE(TIZEN_ONESHOT_DRAWING_SYNCHRONIZATION)
106 , m_needsOneShotDrawingSynchronization(false)
108 , m_animationsLocked(false)
109 #if ENABLE(TIZEN_RUNTIME_BACKEND_SELECTION)
110 , m_isGLAccelerationMode(true)
113 // Create a root layer.
114 m_rootLayer = GraphicsLayer::create(this);
115 WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get());
116 webRootLayer->setRootLayer(true);
118 m_rootLayer->setName("LayerTreeCoordinator root layer");
120 m_rootLayer->setDrawsContent(false);
121 m_rootLayer->setSize(m_webPage->size());
122 m_layerTreeContext.webLayerID = toWebGraphicsLayer(webRootLayer)->id();
124 m_nonCompositedContentLayer = GraphicsLayer::create(this);
125 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
126 WebGraphicsLayer* webNonCompositedLayer = toWebGraphicsLayer(m_nonCompositedContentLayer.get());
127 webNonCompositedLayer->setNonCompositedLayer(true);
130 toWebGraphicsLayer(m_rootLayer.get())->setWebGraphicsLayerClient(this);
132 m_nonCompositedContentLayer->setName("LayerTreeCoordinator non-composited content");
134 m_nonCompositedContentLayer->setDrawsContent(true);
135 m_nonCompositedContentLayer->setSize(m_webPage->size());
137 m_rootLayer->addChild(m_nonCompositedContentLayer.get());
139 if (m_webPage->hasPageOverlay())
140 createPageOverlayLayer();
142 scheduleLayerFlush();
145 void LayerTreeCoordinator::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
147 if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
150 m_layerFlushSchedulingEnabled = layerFlushingEnabled;
152 if (m_layerFlushSchedulingEnabled) {
153 scheduleLayerFlush();
157 cancelPendingLayerFlush();
160 void LayerTreeCoordinator::scheduleLayerFlush()
162 if (!m_layerFlushSchedulingEnabled)
165 if (!m_layerFlushTimer.isActive()) {
166 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
167 m_layerFlushTimerDelay = deferredLayerFlushDelay();
168 m_layerFlushTimer.startOneShot(m_layerFlushTimerDelay);
170 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
171 if (m_layerFlushTimerDelay > 0.0)
172 m_webPage->suspendAnimationController();
175 m_layerFlushTimer.startOneShot(0.0);
179 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
180 if (!m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply)
181 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply = m_webPage->connection()->dispatchWorkItemWhileWaitingForSyncReply(WTF::bind(&LayerTreeCoordinator::performScheduledLayerFlushForcely, this));
185 void LayerTreeCoordinator::cancelPendingLayerFlush()
187 m_layerFlushTimer.stop();
188 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
189 m_webPage->connection()->clearWorkItemWhileWaitingForSyncReply(m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply);
190 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply.clear();
194 void LayerTreeCoordinator::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
196 m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
199 void LayerTreeCoordinator::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer)
201 m_nonCompositedContentLayer->removeAllChildren();
202 m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
204 // Add the accelerated layer tree hierarchy.
206 m_nonCompositedContentLayer->addChild(graphicsLayer);
208 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
209 m_compositedContentLayersCount = compositedContentLayersCount(m_nonCompositedContentLayer.get());
213 void LayerTreeCoordinator::invalidate()
215 cancelPendingLayerFlush();
218 m_rootLayer = nullptr;
222 void LayerTreeCoordinator::setNonCompositedContentsNeedDisplay(const WebCore::IntRect& rect)
224 m_nonCompositedContentLayer->setNeedsDisplayInRect(rect);
225 if (m_pageOverlayLayer)
226 m_pageOverlayLayer->setNeedsDisplayInRect(rect);
228 scheduleLayerFlush();
231 void LayerTreeCoordinator::scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
233 setNonCompositedContentsNeedDisplay(scrollRect);
236 void LayerTreeCoordinator::forceRepaint()
238 // We need to schedule another flush, otherwise the forced paint might cancel a later expected flush.
239 // This is aligned with LayerTreeHostCA.
240 scheduleLayerFlush();
241 flushPendingLayerChanges();
244 void LayerTreeCoordinator::sizeDidChange(const WebCore::IntSize& newSize)
246 if (m_rootLayer->size() == newSize)
249 m_rootLayer->setSize(newSize);
251 // If the newSize exposes new areas of the non-composited content a setNeedsDisplay is needed
252 // for those newly exposed areas.
253 FloatSize oldSize = m_nonCompositedContentLayer->size();
254 m_nonCompositedContentLayer->setSize(newSize);
256 if (newSize.width() > oldSize.width()) {
257 float height = std::min(static_cast<float>(newSize.height()), oldSize.height());
258 m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(oldSize.width(), 0, newSize.width() - oldSize.width(), height));
261 if (newSize.height() > oldSize.height())
262 m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height()));
264 if (m_pageOverlayLayer)
265 m_pageOverlayLayer->setSize(newSize);
267 scheduleLayerFlush();
270 void LayerTreeCoordinator::didInstallPageOverlay()
272 createPageOverlayLayer();
273 scheduleLayerFlush();
276 void LayerTreeCoordinator::didUninstallPageOverlay()
278 destroyPageOverlayLayer();
279 scheduleLayerFlush();
282 void LayerTreeCoordinator::setPageOverlayNeedsDisplay(const WebCore::IntRect& rect)
284 ASSERT(m_pageOverlayLayer);
285 m_pageOverlayLayer->setNeedsDisplayInRect(rect);
286 scheduleLayerFlush();
289 void LayerTreeCoordinator::setPageOverlayOpacity(float value)
291 ASSERT(m_pageOverlayLayer);
292 m_pageOverlayLayer->setOpacity(value);
293 scheduleLayerFlush();
296 bool LayerTreeCoordinator::flushPendingLayerChanges()
298 if (m_waitingForUIProcess)
301 bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
302 m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly();
303 if (m_pageOverlayLayer)
304 m_pageOverlayLayer->syncCompositingStateForThisLayerOnly();
306 m_rootLayer->syncCompositingStateForThisLayerOnly();
308 if (m_shouldSyncRootLayer) {
309 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetRootCompositingLayer(toWebGraphicsLayer(m_rootLayer.get())->id()));
310 m_shouldSyncRootLayer = false;
313 if (!m_shouldSyncFrame)
316 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
317 if (!m_compositedContentLayers.isEmpty()) {
318 Vector<uint32_t> weblayerIDsCopy;
319 copyToVector(m_compositedContentLayers, weblayerIDsCopy);
320 m_compositedContentLayers.clear();
321 bool pauseJavaScript = false;
322 for (size_t i = 0; i < weblayerIDsCopy.size(); ++i) {
323 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(weblayerIDsCopy[i]);
324 if (layer && !layer->swapPlatformSurfaces())
325 pauseJavaScript = true;
327 if (pauseJavaScript) {
328 m_webPage->suspendJavaScriptAndResources();
329 m_suspendedJavaScript = true;
334 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
335 m_webPage->suspendAnimationController();
337 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DidRenderFrame());
338 m_waitingForUIProcess = true;
339 m_shouldSyncFrame = false;
344 void LayerTreeCoordinator::syncLayerState(WebLayerID id, const WebLayerInfo& info)
346 if (m_shouldSendScrollPositionUpdate) {
347 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DidChangeScrollPosition(m_visibleContentsRect.location()));
348 m_shouldSendScrollPositionUpdate = false;
351 m_shouldSyncFrame = true;
352 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetCompositingLayerState(id, info));
355 void LayerTreeCoordinator::syncLayerChildren(WebLayerID id, const Vector<WebLayerID>& children)
357 m_shouldSyncFrame = true;
358 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetCompositingLayerChildren(id, children));
361 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
362 void LayerTreeCoordinator::syncCanvas(WebLayerID id, const IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer, int flags)
364 void LayerTreeCoordinator::syncCanvas(WebLayerID id, const IntSize& canvasSize, uint64_t graphicsSurfaceToken, uint32_t frontBuffer)
367 m_shouldSyncFrame = true;
368 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
369 m_compositedContentLayers.add(id);
370 #if ENABLE(TIZEN_ACCELERATED_2D_CANVAS_EFL)
371 m_compositedContentCanvas2DLayers.add(id);
373 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SyncCanvas(id, canvasSize, graphicsSurfaceToken, frontBuffer, flags));
375 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SyncCanvas(id, canvasSize, graphicsSurfaceToken, frontBuffer));
379 #if ENABLE(CSS_FILTERS)
380 void LayerTreeCoordinator::syncLayerFilters(WebLayerID id, const FilterOperations& filters)
382 m_shouldSyncFrame = true;
383 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetCompositingLayerFilters(id, filters));
387 void LayerTreeCoordinator::attachLayer(WebGraphicsLayer* layer)
389 ASSERT(!m_registeredLayers.contains(layer));
390 m_registeredLayers.add(layer);
392 layer->setContentsScale(m_contentsScale);
393 layer->adjustVisibleRect();
395 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
396 m_compositedContentLayersCount = compositedContentLayersCount(m_nonCompositedContentLayer.get());
400 void LayerTreeCoordinator::detachLayer(WebGraphicsLayer* layer)
402 m_registeredLayers.remove(layer);
403 m_shouldSyncFrame = true;
404 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DeleteCompositingLayer(layer->id()));
406 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
407 m_compositedContentLayersCount = compositedContentLayersCount(m_nonCompositedContentLayer.get());
410 #if ENABLE(TIZEN_WEBKIT2_TILED_AC)
411 m_compositedContentLayers.remove(layer->id());
413 #if ENABLE(TIZEN_ACCELERATED_2D_CANVAS_EFL)
414 m_compositedContentCanvas2DLayers.remove(layer->id());
418 static void updateOffsetFromViewportForSelf(RenderLayer* renderLayer)
420 // These conditions must match the conditions in RenderLayerCompositor::requiresCompositingForPosition.
421 RenderLayerBacking* backing = renderLayer->backing();
425 RenderStyle* style = renderLayer->renderer()->style();
429 if (!renderLayer->renderer()->isOutOfFlowPositioned() || renderLayer->renderer()->style()->position() != FixedPosition)
432 if (!renderLayer->renderer()->container()->isRenderView())
435 if (!renderLayer->isStackingContext())
438 WebGraphicsLayer* graphicsLayer = toWebGraphicsLayer(backing->graphicsLayer());
439 graphicsLayer->setFixedToViewport(true);
442 static void updateOffsetFromViewportForLayer(RenderLayer* renderLayer)
444 updateOffsetFromViewportForSelf(renderLayer);
446 if (renderLayer->firstChild())
447 updateOffsetFromViewportForLayer(renderLayer->firstChild());
448 if (renderLayer->nextSibling())
449 updateOffsetFromViewportForLayer(renderLayer->nextSibling());
452 void LayerTreeCoordinator::syncFixedLayers()
454 if (!m_webPage->corePage()->settings() || !m_webPage->corePage()->settings()->acceleratedCompositingForFixedPositionEnabled())
457 if (!m_webPage->mainFrame()->view()->hasFixedObjects())
460 RenderLayer* rootRenderLayer = m_webPage->mainFrame()->contentRenderer()->compositor()->rootRenderLayer();
461 ASSERT(rootRenderLayer);
462 if (rootRenderLayer->firstChild())
463 updateOffsetFromViewportForLayer(rootRenderLayer->firstChild());
466 void LayerTreeCoordinator::lockAnimations()
468 m_animationsLocked = true;
469 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetAnimationsLocked(true));
472 void LayerTreeCoordinator::unlockAnimations()
474 if (!m_animationsLocked)
477 m_animationsLocked = false;
478 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetAnimationsLocked(false));
481 void LayerTreeCoordinator::performScheduledLayerFlush()
483 #if ENABLE(TIZEN_ACCELERATED_2D_CANVAS_EFL)
484 if (m_waitingForUIProcess && !m_compositedContentCanvas2DLayers.isEmpty()) {
485 Vector<uint32_t> weblayerIDsCopy;
486 copyToVector(m_compositedContentCanvas2DLayers, weblayerIDsCopy);
487 m_compositedContentCanvas2DLayers.clear();
488 for (size_t i = 0; i < weblayerIDsCopy.size(); ++i) {
489 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(weblayerIDsCopy[i]);
491 layer->flushPlatformSurfaces();
497 if (m_isSuspended || m_waitingForUIProcess)
500 #if ENABLE(TIZEN_CUTOFF_TILES_OVER_MEMORY_LIMIT)
501 calculateCutOffThreshold();
504 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER) && !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
505 // Make sure that any previously registered animation callbacks are being executed before we flush the layers.
506 m_webPage->corePage()->mainFrame()->view()->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime()));
509 // We lock the animations while performing layout, to avoid flickers caused by animations continuing in the UI process while
510 // the web process layout wants to cancel them.
513 m_webPage->layoutIfNeeded();
515 // We can unlock the animations before flushing if there are no visible changes, for example if there are content updates
516 // in a layer with opacity 0.
517 bool canUnlockBeforeFlush = !m_isValid || !toWebGraphicsLayer(m_rootLayer.get())->hasPendingVisibleChanges();
518 if (canUnlockBeforeFlush)
524 #if ENABLE(TIZEN_ONESHOT_DRAWING_SYNCHRONIZATION)
525 if (m_needsOneShotDrawingSynchronization) {
526 scheduleLayerFlush();
527 toWebGraphicsLayer(m_nonCompositedContentLayer.get())->adjustVisibleRect();
528 m_needsOneShotDrawingSynchronization = false;
533 if (flushPendingLayerChanges())
534 didPerformScheduledLayerFlush();
537 void LayerTreeCoordinator::didPerformScheduledLayerFlush()
539 if (m_notifyAfterScheduledLayerFlush) {
540 static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
541 m_notifyAfterScheduledLayerFlush = false;
545 void LayerTreeCoordinator::layerFlushTimerFired(Timer<LayerTreeCoordinator>*)
547 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
548 m_webPage->connection()->clearWorkItemWhileWaitingForSyncReply(m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply);
549 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply.clear();
551 performScheduledLayerFlush();
554 void LayerTreeCoordinator::createPageOverlayLayer()
556 ASSERT(!m_pageOverlayLayer);
558 m_pageOverlayLayer = GraphicsLayer::create(this);
560 m_pageOverlayLayer->setName("LayerTreeCoordinator page overlay content");
563 m_pageOverlayLayer->setDrawsContent(true);
564 m_pageOverlayLayer->setSize(m_webPage->size());
566 m_rootLayer->addChild(m_pageOverlayLayer.get());
569 void LayerTreeCoordinator::destroyPageOverlayLayer()
571 ASSERT(m_pageOverlayLayer);
572 m_pageOverlayLayer->removeFromParent();
573 m_pageOverlayLayer = nullptr;
576 int64_t LayerTreeCoordinator::adoptImageBackingStore(Image* image)
579 return InvalidWebLayerID;
584 QImage* nativeImage = image->nativeImageForCurrentFrame();
587 return InvalidWebLayerID;
589 key = nativeImage->cacheKey();
590 #elif ENABLE(TIZEN_WEBKIT2_TILED_AC)
591 key = (int64_t)(image);
594 HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
596 if (it != m_directlyCompositedImageRefCounts.end()) {
601 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), (image->currentFrameHasAlpha() ? ShareableBitmap::SupportsAlpha : 0));
603 OwnPtr<WebCore::GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
604 graphicsContext->drawImage(image, ColorSpaceDeviceRGB, IntPoint::zero());
607 ShareableBitmap::Handle handle;
608 bitmap->createHandle(handle);
609 m_webPage->send(Messages::LayerTreeCoordinatorProxy::CreateDirectlyCompositedImage(key, handle));
610 m_directlyCompositedImageRefCounts.add(key, 1);
614 void LayerTreeCoordinator::releaseImageBackingStore(int64_t key)
618 HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
619 if (it == m_directlyCompositedImageRefCounts.end())
627 m_directlyCompositedImageRefCounts.remove(it);
628 m_webPage->send(Messages::LayerTreeCoordinatorProxy::DestroyDirectlyCompositedImage(key));
632 void LayerTreeCoordinator::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
636 void LayerTreeCoordinator::notifySyncRequired(const WebCore::GraphicsLayer*)
640 void LayerTreeCoordinator::paintContents(const WebCore::GraphicsLayer* graphicsLayer, WebCore::GraphicsContext& graphicsContext, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect)
642 if (graphicsLayer == m_nonCompositedContentLayer) {
643 m_webPage->drawRect(graphicsContext, clipRect);
647 if (graphicsLayer == m_pageOverlayLayer) {
648 // Overlays contain transparent contents and won't clear the context as part of their rendering, so we do it here.
649 graphicsContext.clearRect(clipRect);
650 m_webPage->drawPageOverlay(graphicsContext, clipRect);
655 bool LayerTreeCoordinator::showDebugBorders(const WebCore::GraphicsLayer*) const
657 return m_webPage->corePage()->settings()->showDebugBorders();
660 bool LayerTreeCoordinator::showRepaintCounter(const WebCore::GraphicsLayer*) const
662 return m_webPage->corePage()->settings()->showRepaintCounter();
665 bool LayerTreeHost::supportsAcceleratedCompositing()
670 void LayerTreeCoordinator::createTile(WebLayerID layerID, int tileID, const SurfaceUpdateInfo& updateInfo, const WebCore::IntRect& targetRect)
672 m_shouldSyncFrame = true;
673 m_webPage->send(Messages::LayerTreeCoordinatorProxy::CreateTileForLayer(layerID, tileID, targetRect, updateInfo));
676 void LayerTreeCoordinator::updateTile(WebLayerID layerID, int tileID, const SurfaceUpdateInfo& updateInfo, const WebCore::IntRect& targetRect)
678 m_shouldSyncFrame = true;
679 m_webPage->send(Messages::LayerTreeCoordinatorProxy::UpdateTileForLayer(layerID, tileID, targetRect, updateInfo));
682 void LayerTreeCoordinator::removeTile(WebLayerID layerID, int tileID)
684 m_shouldSyncFrame = true;
685 m_webPage->send(Messages::LayerTreeCoordinatorProxy::RemoveTileForLayer(layerID, tileID));
688 WebCore::IntRect LayerTreeCoordinator::visibleContentsRect() const
690 return m_visibleContentsRect;
693 void LayerTreeCoordinator::setLayerAnimations(WebLayerID layerID, const GraphicsLayerAnimations& animations)
695 m_shouldSyncFrame = true;
696 m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetLayerAnimations(layerID, animations.getActiveAnimations()));
699 void LayerTreeCoordinator::setVisibleContentsRect(const IntRect& rect, float scale, const FloatPoint& trajectoryVector)
701 bool contentsRectDidChange = rect != m_visibleContentsRect;
702 bool contentsScaleDidChange = scale != m_contentsScale;
704 if (trajectoryVector != FloatPoint::zero())
705 toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRectTrajectoryVector(trajectoryVector);
707 if (contentsRectDidChange || contentsScaleDidChange) {
708 m_visibleContentsRect = rect;
709 m_contentsScale = scale;
711 HashSet<WebCore::WebGraphicsLayer*>::iterator end = m_registeredLayers.end();
712 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it) {
713 if (contentsScaleDidChange)
714 (*it)->setContentsScale(scale);
715 if (contentsRectDidChange)
716 #if ENABLE(TIZEN_WEBKIT2_PRE_RENDERING_WITH_DIRECTIVITY)
717 (*it)->setVisibleContentRectTrajectoryVector(trajectoryVector);
719 (*it)->adjustVisibleRect();
724 scheduleLayerFlush();
725 if (m_webPage->useFixedLayout())
726 m_webPage->setFixedVisibleContentRect(rect);
727 if (contentsRectDidChange)
728 m_shouldSendScrollPositionUpdate = true;
731 #if USE(UI_SIDE_COMPOSITING)
732 void LayerTreeCoordinator::scheduleAnimation()
734 scheduleLayerFlush();
738 void LayerTreeCoordinator::renderNextFrame()
740 m_waitingForUIProcess = false;
741 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
742 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
743 if (m_layerFlushTimerDelay <= 0.0)
745 m_webPage->resumeAnimationController();
747 scheduleLayerFlush();
748 for (int i = 0; i < m_updateAtlases.size(); ++i)
749 m_updateAtlases[i]->didSwapBuffers();
751 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
752 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
753 if (m_layerFlushTimerDelay > 0.0)
754 m_webPage->resumeAnimationController();
759 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
760 void LayerTreeCoordinator::performScheduledLayerFlushForcely()
762 if (!WebProcess::shared().isWaitingForJavaScriptPopupFinished())
765 m_layerFlushTimer.stop();
766 m_webPage->connection()->clearWorkItemWhileWaitingForSyncReply(m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply);
767 m_layerFlushWorkItemToDispatchWhileWaitingForSyncReply.clear();
769 m_waitingForUIProcess = false;
771 performScheduledLayerFlush();
775 bool LayerTreeCoordinator::layerTreeTileUpdatesAllowed() const
777 return !m_isSuspended && !m_waitingForUIProcess;
780 void LayerTreeCoordinator::purgeBackingStores()
782 HashSet<WebCore::WebGraphicsLayer*>::iterator end = m_registeredLayers.end();
783 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it)
784 (*it)->purgeBackingStores();
786 ASSERT(!m_directlyCompositedImageRefCounts.size());
787 m_updateAtlases.clear();
790 PassOwnPtr<WebCore::GraphicsContext> LayerTreeCoordinator::beginContentUpdate(const WebCore::IntSize& size, ShareableBitmap::Flags flags, ShareableSurface::Handle& handle, WebCore::IntPoint& offset)
792 OwnPtr<WebCore::GraphicsContext> graphicsContext;
793 for (int i = 0; i < m_updateAtlases.size(); ++i) {
794 UpdateAtlas* atlas = m_updateAtlases[i].get();
795 if (atlas->flags() == flags) {
796 // This will return null if there is no available buffer space.
797 graphicsContext = atlas->beginPaintingOnAvailableBuffer(handle, size, offset);
799 return graphicsContext.release();
803 static const int ScratchBufferDimension = 1024;
804 m_updateAtlases.append(adoptPtr(new UpdateAtlas(ScratchBufferDimension, flags)));
805 scheduleReleaseInactiveAtlases();
806 return m_updateAtlases.last()->beginPaintingOnAvailableBuffer(handle, size, offset);
809 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
810 void LayerTreeCoordinator::freePlatformSurface(int layerID, int platformSurfaceId)
812 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(layerID);
813 if (layer && (layer->contentType() == WebLayerInfo::Canvas3DContentType || layer->contentType() == WebLayerInfo::MediaContentType || layer->contentType() == WebLayerInfo::Canvas2DContentType)) {
814 layer->freePlatformSurface(platformSurfaceId);
816 if (m_suspendedJavaScript && layer->swapPlatformSurfaces()) {
817 m_webPage->resumeJavaScriptAndResources();
818 m_suspendedJavaScript = false;
822 // Even after a graphics layer just destroyed in WebProcess side,
823 // freePlatformSurface messages that destroyed layer can surely come.
824 // Therefore, below code should be run always before layer validity check.
825 WebProcess::shared().platformSurfacePool()->freePlatformSurface(platformSurfaceId);
828 void LayerTreeCoordinator::freePlatformSurfaceByTileID(int tileID)
830 WebProcess::shared().platformSurfacePool()->freePlatformSurfaceByTileID(tileID);
833 void LayerTreeCoordinator::removePlatformSurface(int layerID, int platformSurfaceId)
835 WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(layerID);
836 if (layer && (layer->contentType() == WebLayerInfo::Canvas3DContentType || layer->contentType() == WebLayerInfo::MediaContentType || layer->contentType() == WebLayerInfo::Canvas2DContentType))
837 layer->removePlatformSurface(platformSurfaceId);
841 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
842 bool LayerTreeCoordinator::recordingSurfaceSetEnableGet()
844 return recordingSurfaceAllowed() && m_webPage->recordingSurfaceEnabled();
847 bool LayerTreeCoordinator::recordingSurfaceSetLoadStartGet()
849 if (m_webPage->recordingSurfaceLoadStart()) {
850 m_webPage->setRecordingSurfaceLoadStart(false);
856 bool LayerTreeCoordinator::recordingSurfaceSetLoadFinishedGet()
858 if (m_webPage->recordingSurfaceLoadFinish()) {
859 m_webPage->setRecordingSurfaceLoadFinish(false);
865 bool LayerTreeCoordinator::recordingSurfaceAllowed()
867 if (m_compositedContentLayersCount > 0)
873 int LayerTreeCoordinator::compositedContentLayersCount(GraphicsLayer* layer)
876 int contentType = toWebGraphicsLayer(layer)->contentType();
878 if (contentType == WebLayerInfo::Canvas3DContentType || contentType == WebLayerInfo::MediaContentType || contentType == WebLayerInfo::Canvas2DContentType)
881 const Vector<GraphicsLayer*>& childLayers = layer->children();
882 for (int i = 0; i < childLayers.size(); ++i)
883 count += compositedContentLayersCount(childLayers[i]);
889 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
890 void LayerTreeCoordinator::setVisibleContentsRectAndTrajectoryVectorForLayer(int layerID, const WebCore::IntRect& visibleRect, const WebCore::FloatPoint& trajectoryVector)
892 GraphicsLayer* contentsLayer = WebGraphicsLayer::layerByID(layerID);
896 toWebGraphicsLayer(contentsLayer)->setVisibleRect(visibleRect);
897 if (trajectoryVector != FloatPoint::zero()) {
898 m_webPage->scrollOverflowWithTrajectoryVector(trajectoryVector);
899 toWebGraphicsLayer(contentsLayer)->setVisibleContentRectTrajectoryVector(trajectoryVector);
901 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_SCROLLBAR)
902 const Vector<GraphicsLayer*>& childLayers = contentsLayer->children();
903 for (int i = 0; i < childLayers.size(); ++i)
904 if (childLayers[i]->isScrollbar())
905 toWebGraphicsLayer(childLayers[i])->startAnimation();
909 toWebGraphicsLayer(contentsLayer)->adjustVisibleRect();
911 scheduleLayerFlush();
915 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
916 void LayerTreeCoordinator::addOrUpdateScrollingLayer(WebCore::GraphicsLayer* scrollingLayer, WebCore::GraphicsLayer* contentsLayer, const WebCore::IntSize& scrollSize)
918 if (!scrollingLayer || !contentsLayer)
921 toWebGraphicsLayer(contentsLayer)->setIsOverflow(true);
922 #if !ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
923 // FIXME: We might need to consider paddingBox margin for overflow scroll layer
924 // FloatPoint offset(-scrollingLayer->offsetFromRenderer().width() - scrollingLayer->boundsOrigin().x()
925 // , -scrollingLayer->offsetFromRenderer().height() - scrollingLayer->boundsOrigin().y());
926 FloatPoint offset(scrollingLayer->boundsOrigin());
927 contentsLayer->setPosition(-offset);
929 IntRect visibleRect(FloatRect(offset, scrollingLayer->size()));
930 toWebGraphicsLayer(contentsLayer)->setVisibleRect(visibleRect);
932 // FIXME: Need to set trajectoryVector?
933 // FloatPoint trajectoryVector(scrollingLayer->trajectoryVector());
934 // if (trajectoryVector != FloatPoint::zero())
935 //toWebGraphicsLayer(contentsLayer)->setVisibleContentRectTrajectoryVector(-trajectoryVector);
937 // FIXME: Scale factor might be changed.
938 // toWebGraphicsLayer(contentsLayer)->setContentsScale(m_contentsScale);
940 setNeedsOneShotDrawingSynchronization();
942 toWebGraphicsLayer(contentsLayer)->adjustVisibleRect();
945 void LayerTreeCoordinator::removeScrollingLayer(WebCore::GraphicsLayer* scrollingLayer, WebCore::GraphicsLayer* contentsLayer)
947 if (!scrollingLayer || !contentsLayer)
950 toWebGraphicsLayer(contentsLayer)->setIsOverflow(false);
951 toWebGraphicsLayer(contentsLayer)->syncLayerState();
953 #endif // ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
955 #if ENABLE(TIZEN_ONESHOT_DRAWING_SYNCHRONIZATION)
956 void LayerTreeCoordinator::setNeedsOneShotDrawingSynchronization()
958 m_needsOneShotDrawingSynchronization = true;
962 #if ENABLE(TIZEN_LAYER_FLUSH_THROTTLING)
963 void LayerTreeCoordinator::setDeferLayerFlush(bool deferLayerFlushEnabled)
965 m_deferLayerFlushEnabled = deferLayerFlushEnabled;
966 m_layerFlushTimerDelayLevel = 0;
967 double newDelay = deferredLayerFlushDelay();
969 // If the m_layerFlushTimer is already activated, we stop the old timer and then begin the timer with a new delay
970 if (m_layerFlushTimerDelay != newDelay && m_layerFlushTimer.isActive()) {
971 m_layerFlushTimer.stop();
972 m_layerFlushTimer.startOneShot(newDelay);
974 m_layerFlushTimerDelay = newDelay;
976 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
977 if (m_layerFlushTimerDelay == 0.0)
978 m_webPage->resumeAnimationController();
982 float LayerTreeCoordinator::deferredLayerFlushDelay()
984 if (!m_deferLayerFlushEnabled)
987 if (m_layerFlushTimerDelayLevel >= s_layerFlushTimerDelayMaxLevel)
988 m_layerFlushTimerDelayLevel = s_layerFlushTimerDelayMaxLevel - 1;
990 return s_layerFlushTimerDelayTable[m_layerFlushTimerDelayLevel++];
994 #if ENABLE(TIZEN_CUTOFF_TILES_OVER_MEMORY_LIMIT)
995 static bool AscendingTileSortByDistance(TileCutOffInfo first, TileCutOffInfo second)
997 if (first.m_distance < second.m_distance)
1003 void LayerTreeCoordinator::calculateCutOffThreshold()
1005 Vector<WebCore::TileCutOffInfo> tilesCutOffInfo;
1006 HashSet<WebCore::WebGraphicsLayer*>::iterator end = m_registeredLayers.end();
1007 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it)
1008 tilesCutOffInfo.append((*it)->getCutOffInfoList());
1009 tilesCutOffInfo.append(toWebGraphicsLayer(m_nonCompositedContentLayer.get())->getCutOffInfoList());
1011 std::sort(tilesCutOffInfo.begin(), tilesCutOffInfo.end(), AscendingTileSortByDistance);
1013 size_t allocatedMemory = 0;
1014 // FIXME: This patch will be considered in future.
1015 // Need to correct offscreen-to-onscreen animation layer's tile cutoff computation
1016 const size_t memoryLimit = 30 * 1024 * 1024; // 30 MB
1017 double cutOffDistance = std::numeric_limits<double>::max();
1018 for (size_t i = 0; i < tilesCutOffInfo.size(); ++i) {
1019 TileCutOffInfo cutOffInfo = tilesCutOffInfo[i];
1020 allocatedMemory += cutOffInfo.m_allocatedMemoryByte;
1021 if (memoryLimit < allocatedMemory) {
1022 cutOffDistance = cutOffInfo.m_distance;
1027 for (HashSet<WebCore::WebGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it)
1028 (*it)->setCutOffDistance(cutOffDistance);
1030 toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setCutOffDistance(cutOffDistance);
1034 const double ReleaseInactiveAtlasesTimerInterval = 0.5;
1036 void LayerTreeCoordinator::scheduleReleaseInactiveAtlases()
1038 if (!m_releaseInactiveAtlasesTimer.isActive())
1039 m_releaseInactiveAtlasesTimer.startRepeating(ReleaseInactiveAtlasesTimerInterval);
1042 void LayerTreeCoordinator::releaseInactiveAtlasesTimerFired(Timer<LayerTreeCoordinator>*)
1044 // We always want to keep one atlas for non-composited content.
1045 OwnPtr<UpdateAtlas> atlasToKeepAnyway;
1046 bool foundActiveAtlasForNonCompositedContent = false;
1047 for (int i = m_updateAtlases.size() - 1; i >= 0; --i) {
1048 UpdateAtlas* atlas = m_updateAtlases[i].get();
1049 if (!atlas->isInUse())
1050 atlas->addTimeInactive(ReleaseInactiveAtlasesTimerInterval);
1051 bool usableForNonCompositedContent = !atlas->supportsAlpha();
1052 if (atlas->isInactive()) {
1053 if (!foundActiveAtlasForNonCompositedContent && !atlasToKeepAnyway && usableForNonCompositedContent)
1054 atlasToKeepAnyway = m_updateAtlases[i].release();
1055 m_updateAtlases.remove(i);
1056 } else if (usableForNonCompositedContent)
1057 foundActiveAtlasForNonCompositedContent = true;
1060 if (!foundActiveAtlasForNonCompositedContent && atlasToKeepAnyway)
1061 m_updateAtlases.append(atlasToKeepAnyway.release());
1063 if (m_updateAtlases.size() <= 1)
1064 m_releaseInactiveAtlasesTimer.stop();
1067 } // namespace WebKit