[EFL][WK2] Extract the control of page background out of color_set
[WebKit-https.git] / Source / WebCore / platform / graphics / texmap / coordinated / CoordinatedGraphicsScene.cpp
1 /*
2     Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3     Copyright (C) 2012 Company 100, Inc.
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22
23 #if USE(COORDINATED_GRAPHICS)
24
25 #include "CoordinatedGraphicsScene.h"
26
27 #include "CoordinatedBackingStore.h"
28 #include "TextureMapper.h"
29 #include "TextureMapperBackingStore.h"
30 #include "TextureMapperGL.h"
31 #include "TextureMapperLayer.h"
32 #include <wtf/Atomics.h>
33 #include <wtf/MainThread.h>
34
35 namespace WebCore {
36
37 void CoordinatedGraphicsScene::dispatchOnMainThread(std::function<void()> function)
38 {
39     if (isMainThread())
40         function();
41     else
42         callOnMainThread(std::move(function));
43 }
44
45 static bool layerShouldHaveBackingStore(TextureMapperLayer* layer)
46 {
47     return layer->drawsContent() && layer->contentsAreVisible() && !layer->size().isEmpty();
48 }
49
50 CoordinatedGraphicsScene::CoordinatedGraphicsScene(CoordinatedGraphicsSceneClient* client)
51     : m_client(client)
52     , m_isActive(false)
53     , m_rootLayerID(InvalidCoordinatedLayerID)
54     , m_backgroundColor(Color::white)
55     , m_viewBackgroundColor(Color::white)
56     , m_setDrawsBackground(false)
57 {
58     ASSERT(isMainThread());
59 }
60
61 CoordinatedGraphicsScene::~CoordinatedGraphicsScene()
62 {
63 }
64
65 void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, TextureMapper::PaintFlags PaintFlags)
66 {
67     if (!m_textureMapper) {
68         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
69         static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
70     }
71
72     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
73     syncRemoteContent();
74
75     adjustPositionForFixedLayers();
76     TextureMapperLayer* currentRootLayer = rootLayer();
77     if (!currentRootLayer)
78         return;
79
80     currentRootLayer->setTextureMapper(m_textureMapper.get());
81     currentRootLayer->applyAnimationsRecursively();
82     m_textureMapper->beginPainting(PaintFlags);
83     m_textureMapper->beginClip(TransformationMatrix(), clipRect);
84
85     if (m_setDrawsBackground) {
86         RGBA32 rgba = makeRGBA32FromFloats(m_backgroundColor.red(),
87             m_backgroundColor.green(), m_backgroundColor.blue(),
88             m_backgroundColor.alpha() * opacity);
89         m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba));
90     } else {
91         GraphicsContext3D* context = static_cast<TextureMapperGL*>(m_textureMapper.get())->graphicsContext3D();
92         context->clearColor(m_viewBackgroundColor.red() / 255.0f, m_viewBackgroundColor.green() / 255.0f, m_viewBackgroundColor.blue() / 255.0f, m_viewBackgroundColor.alpha() / 255.0f);
93         context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
94     }
95
96     if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
97         currentRootLayer->setOpacity(opacity);
98         currentRootLayer->setTransform(matrix);
99     }
100
101     currentRootLayer->paint();
102     m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location(), matrix);
103     m_textureMapper->endClip();
104     m_textureMapper->endPainting();
105
106     if (currentRootLayer->descendantsOrSelfHaveRunningAnimations()) {
107         RefPtr<CoordinatedGraphicsScene> protector(this);
108         dispatchOnMainThread([=] {
109             protector->updateViewport();
110         });
111     }
112 }
113
114 void CoordinatedGraphicsScene::paintToGraphicsContext(PlatformGraphicsContext* platformContext)
115 {
116     if (!m_textureMapper)
117         m_textureMapper = TextureMapper::create();
118     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
119     syncRemoteContent();
120     TextureMapperLayer* layer = rootLayer();
121
122     if (!layer)
123         return;
124
125     GraphicsContext graphicsContext(platformContext);
126     m_textureMapper->setGraphicsContext(&graphicsContext);
127     m_textureMapper->beginPainting();
128
129     IntRect clipRect = graphicsContext.clipBounds();
130     if (m_setDrawsBackground)
131         m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), m_backgroundColor);
132     else
133         m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), m_viewBackgroundColor);
134
135     layer->paint();
136     m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location());
137     m_textureMapper->endPainting();
138     m_textureMapper->setGraphicsContext(0);
139 }
140
141 void CoordinatedGraphicsScene::setScrollPosition(const FloatPoint& scrollPosition)
142 {
143     m_scrollPosition = scrollPosition;
144 }
145
146 void CoordinatedGraphicsScene::updateViewport()
147 {
148     ASSERT(isMainThread());
149     if (m_client)
150         m_client->updateViewport();
151 }
152
153 void CoordinatedGraphicsScene::adjustPositionForFixedLayers()
154 {
155     if (m_fixedLayers.isEmpty())
156         return;
157
158     // Fixed layer positions are updated by the web process when we update the visible contents rect / scroll position.
159     // If we want those layers to follow accurately the viewport when we move between the web process updates, we have to offset
160     // them by the delta between the current position and the position of the viewport used for the last layout.
161     FloatSize delta = m_scrollPosition - m_renderedContentsScrollPosition;
162
163     LayerRawPtrMap::iterator end = m_fixedLayers.end();
164     for (LayerRawPtrMap::iterator it = m_fixedLayers.begin(); it != end; ++it)
165         it->value->setScrollPositionDeltaIfNeeded(delta);
166 }
167
168 #if USE(GRAPHICS_SURFACE)
169 void CoordinatedGraphicsScene::createCanvasIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
170 {
171     if (!state.canvasToken.isValid())
172         return;
173
174     RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore(TextureMapperSurfaceBackingStore::create());
175     m_surfaceBackingStores.set(layer, canvasBackingStore);
176     canvasBackingStore->setGraphicsSurface(GraphicsSurface::create(state.canvasSize, state.canvasSurfaceFlags, state.canvasToken));
177     layer->setContentsLayer(canvasBackingStore.get());
178 }
179
180 void CoordinatedGraphicsScene::syncCanvasIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
181 {
182     ASSERT(m_textureMapper);
183
184     if (state.canvasChanged) {
185         destroyCanvasIfNeeded(layer, state);
186         createCanvasIfNeeded(layer, state);
187     }
188
189     if (state.canvasShouldSwapBuffers) {
190         ASSERT(m_surfaceBackingStores.contains(layer));
191         SurfaceBackingStoreMap::iterator it = m_surfaceBackingStores.find(layer);
192         RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore = it->value;
193         canvasBackingStore->swapBuffersIfNeeded(state.canvasFrontBuffer);
194     }
195 }
196
197 void CoordinatedGraphicsScene::destroyCanvasIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
198 {
199     if (state.canvasToken.isValid())
200         return;
201
202     m_surfaceBackingStores.remove(layer);
203     layer->setContentsLayer(0);
204 }
205 #endif
206
207 void CoordinatedGraphicsScene::setLayerRepaintCountIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
208 {
209     if (!layer->isShowingRepaintCounter() || !state.repaintCountChanged)
210         return;
211
212     layer->setRepaintCount(state.repaintCount);
213 }
214
215 void CoordinatedGraphicsScene::setLayerChildrenIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
216 {
217     if (!state.childrenChanged)
218         return;
219
220     Vector<TextureMapperLayer*> children;
221
222     for (size_t i = 0; i < state.children.size(); ++i) {
223         CoordinatedLayerID childID = state.children[i];
224         TextureMapperLayer* child = layerByID(childID);
225         children.append(child);
226     }
227     layer->setChildren(children);
228 }
229
230 #if ENABLE(CSS_FILTERS)
231 void CoordinatedGraphicsScene::setLayerFiltersIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
232 {
233     if (!state.filtersChanged)
234         return;
235
236     layer->setFilters(state.filters);
237 }
238 #endif
239
240 void CoordinatedGraphicsScene::setLayerState(CoordinatedLayerID id, const CoordinatedGraphicsLayerState& layerState)
241 {
242     ASSERT(m_rootLayerID != InvalidCoordinatedLayerID);
243     TextureMapperLayer* layer = layerByID(id);
244
245     if (layerState.positionChanged)
246         layer->setPosition(layerState.pos);
247
248     if (layerState.anchorPointChanged)
249         layer->setAnchorPoint(layerState.anchorPoint);
250
251     if (layerState.sizeChanged)
252         layer->setSize(layerState.size);
253
254     if (layerState.transformChanged)
255         layer->setTransform(layerState.transform);
256
257     if (layerState.childrenTransformChanged)
258         layer->setChildrenTransform(layerState.childrenTransform);
259
260     if (layerState.contentsRectChanged)
261         layer->setContentsRect(layerState.contentsRect);
262
263     if (layerState.contentsTilingChanged) {
264         layer->setContentsTilePhase(layerState.contentsTilePhase);
265         layer->setContentsTileSize(layerState.contentsTileSize);
266     }
267
268     if (layerState.opacityChanged)
269         layer->setOpacity(layerState.opacity);
270
271     if (layerState.solidColorChanged)
272         layer->setSolidColor(layerState.solidColor);
273
274     if (layerState.debugBorderColorChanged || layerState.debugBorderWidthChanged)
275         layer->setDebugVisuals(layerState.showDebugBorders, layerState.debugBorderColor, layerState.debugBorderWidth, layerState.showRepaintCounter);
276
277     if (layerState.replicaChanged)
278         layer->setReplicaLayer(getLayerByIDIfExists(layerState.replica));
279
280     if (layerState.maskChanged)
281         layer->setMaskLayer(getLayerByIDIfExists(layerState.mask));
282
283     if (layerState.imageChanged)
284         assignImageBackingToLayer(layer, layerState.imageID);
285
286     if (layerState.flagsChanged) {
287         layer->setContentsOpaque(layerState.contentsOpaque);
288         layer->setDrawsContent(layerState.drawsContent);
289         layer->setContentsVisible(layerState.contentsVisible);
290         layer->setBackfaceVisibility(layerState.backfaceVisible);
291
292         // Never clip the root layer.
293         layer->setMasksToBounds(id == m_rootLayerID ? false : layerState.masksToBounds);
294         layer->setPreserves3D(layerState.preserves3D);
295
296         bool fixedToViewportChanged = layer->fixedToViewport() != layerState.fixedToViewport;
297         layer->setFixedToViewport(layerState.fixedToViewport);
298         if (fixedToViewportChanged) {
299             if (layerState.fixedToViewport)
300                 m_fixedLayers.add(id, layer);
301             else
302                 m_fixedLayers.remove(id);
303         }
304
305         layer->setIsScrollable(layerState.isScrollable);
306     }
307
308     if (layerState.committedScrollOffsetChanged)
309         layer->didCommitScrollOffset(layerState.committedScrollOffset);
310
311     prepareContentBackingStore(layer);
312
313     // Apply Operations.
314     setLayerChildrenIfNeeded(layer, layerState);
315     createTilesIfNeeded(layer, layerState);
316     removeTilesIfNeeded(layer, layerState);
317     updateTilesIfNeeded(layer, layerState);
318 #if ENABLE(CSS_FILTERS)
319     setLayerFiltersIfNeeded(layer, layerState);
320 #endif
321     setLayerAnimationsIfNeeded(layer, layerState);
322 #if USE(GRAPHICS_SURFACE)
323     syncCanvasIfNeeded(layer, layerState);
324 #endif
325     setLayerRepaintCountIfNeeded(layer, layerState);
326 }
327
328 TextureMapperLayer* CoordinatedGraphicsScene::getLayerByIDIfExists(CoordinatedLayerID id)
329 {
330     return (id != InvalidCoordinatedLayerID) ? layerByID(id) : 0;
331 }
332
333 void CoordinatedGraphicsScene::createLayers(const Vector<CoordinatedLayerID>& ids)
334 {
335     for (size_t index = 0; index < ids.size(); ++index)
336         createLayer(ids[index]);
337 }
338
339 void CoordinatedGraphicsScene::createLayer(CoordinatedLayerID id)
340 {
341     std::unique_ptr<TextureMapperLayer> newLayer = std::make_unique<TextureMapperLayer>();
342     newLayer->setID(id);
343     newLayer->setScrollClient(this);
344     m_layers.add(id, std::move(newLayer));
345 }
346
347 void CoordinatedGraphicsScene::deleteLayers(const Vector<CoordinatedLayerID>& layerIDs)
348 {
349     for (size_t index = 0; index < layerIDs.size(); ++index)
350         deleteLayer(layerIDs[index]);
351 }
352
353 void CoordinatedGraphicsScene::deleteLayer(CoordinatedLayerID layerID)
354 {
355     std::unique_ptr<TextureMapperLayer> layer = m_layers.take(layerID);
356     ASSERT(layer);
357
358     m_backingStores.remove(layer.get());
359     m_fixedLayers.remove(layerID);
360 #if USE(GRAPHICS_SURFACE)
361     m_surfaceBackingStores.remove(layer.get());
362 #endif
363 }
364
365 void CoordinatedGraphicsScene::setRootLayerID(CoordinatedLayerID layerID)
366 {
367     ASSERT(layerID != InvalidCoordinatedLayerID);
368     ASSERT(m_rootLayerID == InvalidCoordinatedLayerID);
369
370     m_rootLayerID = layerID;
371
372     TextureMapperLayer* layer = layerByID(layerID);
373     ASSERT(m_rootLayer->children().isEmpty());
374     m_rootLayer->addChild(layer);
375 }
376
377 void CoordinatedGraphicsScene::prepareContentBackingStore(TextureMapperLayer* layer)
378 {
379     if (!layerShouldHaveBackingStore(layer)) {
380         removeBackingStoreIfNeeded(layer);
381         return;
382     }
383
384     createBackingStoreIfNeeded(layer);
385     resetBackingStoreSizeToLayerSize(layer);
386 }
387
388 void CoordinatedGraphicsScene::createBackingStoreIfNeeded(TextureMapperLayer* layer)
389 {
390     if (m_backingStores.contains(layer))
391         return;
392
393     RefPtr<CoordinatedBackingStore> backingStore(CoordinatedBackingStore::create());
394     m_backingStores.add(layer, backingStore);
395     layer->setBackingStore(backingStore);
396 }
397
398 void CoordinatedGraphicsScene::removeBackingStoreIfNeeded(TextureMapperLayer* layer)
399 {
400     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.take(layer);
401     if (!backingStore)
402         return;
403
404     layer->setBackingStore(0);
405 }
406
407 void CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize(TextureMapperLayer* layer)
408 {
409     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
410     ASSERT(backingStore);
411     backingStore->setSize(layer->size());
412     m_backingStoresWithPendingBuffers.add(backingStore);
413 }
414
415 void CoordinatedGraphicsScene::createTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
416 {
417     if (state.tilesToCreate.isEmpty())
418         return;
419
420     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
421     ASSERT(backingStore);
422
423     for (size_t i = 0; i < state.tilesToCreate.size(); ++i)
424         backingStore->createTile(state.tilesToCreate[i].tileID, state.tilesToCreate[i].scale);
425 }
426
427 void CoordinatedGraphicsScene::removeTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
428 {
429     if (state.tilesToRemove.isEmpty())
430         return;
431
432     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
433     if (!backingStore)
434         return;
435
436     for (size_t i = 0; i < state.tilesToRemove.size(); ++i)
437         backingStore->removeTile(state.tilesToRemove[i]);
438
439     m_backingStoresWithPendingBuffers.add(backingStore);
440 }
441
442 void CoordinatedGraphicsScene::updateTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
443 {
444     if (state.tilesToUpdate.isEmpty())
445         return;
446
447     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
448     ASSERT(backingStore);
449
450     for (size_t i = 0; i < state.tilesToUpdate.size(); ++i) {
451         const TileUpdateInfo& tileInfo = state.tilesToUpdate[i];
452         const SurfaceUpdateInfo& surfaceUpdateInfo = tileInfo.updateInfo;
453
454         SurfaceMap::iterator surfaceIt = m_surfaces.find(surfaceUpdateInfo.atlasID);
455         ASSERT(surfaceIt != m_surfaces.end());
456
457         backingStore->updateTile(tileInfo.tileID, surfaceUpdateInfo.updateRect, tileInfo.tileRect, surfaceIt->value, surfaceUpdateInfo.surfaceOffset);
458         m_backingStoresWithPendingBuffers.add(backingStore);
459     }
460 }
461
462 void CoordinatedGraphicsScene::syncUpdateAtlases(const CoordinatedGraphicsState& state)
463 {
464     for (size_t i = 0; i < state.updateAtlasesToCreate.size(); ++i)
465         createUpdateAtlas(state.updateAtlasesToCreate[i].first, state.updateAtlasesToCreate[i].second);
466
467     for (size_t i = 0; i < state.updateAtlasesToRemove.size(); ++i)
468         removeUpdateAtlas(state.updateAtlasesToRemove[i]);
469 }
470
471 void CoordinatedGraphicsScene::createUpdateAtlas(uint32_t atlasID, PassRefPtr<CoordinatedSurface> surface)
472 {
473     ASSERT(!m_surfaces.contains(atlasID));
474     m_surfaces.add(atlasID, surface);
475 }
476
477 void CoordinatedGraphicsScene::removeUpdateAtlas(uint32_t atlasID)
478 {
479     ASSERT(m_surfaces.contains(atlasID));
480     m_surfaces.remove(atlasID);
481 }
482
483 void CoordinatedGraphicsScene::syncImageBackings(const CoordinatedGraphicsState& state)
484 {
485     for (size_t i = 0; i < state.imagesToRemove.size(); ++i)
486         removeImageBacking(state.imagesToRemove[i]);
487
488     for (size_t i = 0; i < state.imagesToCreate.size(); ++i)
489         createImageBacking(state.imagesToCreate[i]);
490
491     for (size_t i = 0; i < state.imagesToUpdate.size(); ++i)
492         updateImageBacking(state.imagesToUpdate[i].first, state.imagesToUpdate[i].second);
493
494     for (size_t i = 0; i < state.imagesToClear.size(); ++i)
495         clearImageBackingContents(state.imagesToClear[i]);
496 }
497
498 void CoordinatedGraphicsScene::createImageBacking(CoordinatedImageBackingID imageID)
499 {
500     ASSERT(!m_imageBackings.contains(imageID));
501     RefPtr<CoordinatedBackingStore> backingStore(CoordinatedBackingStore::create());
502     m_imageBackings.add(imageID, backingStore.release());
503 }
504
505 void CoordinatedGraphicsScene::updateImageBacking(CoordinatedImageBackingID imageID, PassRefPtr<CoordinatedSurface> surface)
506 {
507     ASSERT(m_imageBackings.contains(imageID));
508     ImageBackingMap::iterator it = m_imageBackings.find(imageID);
509     RefPtr<CoordinatedBackingStore> backingStore = it->value;
510
511     // CoordinatedImageBacking is realized to CoordinatedBackingStore with only one tile in UI Process.
512     backingStore->createTile(1 /* id */, 1 /* scale */);
513     IntRect rect(IntPoint::zero(), surface->size());
514     // See CoordinatedGraphicsLayer::shouldDirectlyCompositeImage()
515     ASSERT(2000 >= std::max(rect.width(), rect.height()));
516     backingStore->setSize(rect.size());
517     backingStore->updateTile(1 /* id */, rect, rect, surface, rect.location());
518
519     m_backingStoresWithPendingBuffers.add(backingStore);
520 }
521
522 void CoordinatedGraphicsScene::clearImageBackingContents(CoordinatedImageBackingID imageID)
523 {
524     ASSERT(m_imageBackings.contains(imageID));
525     ImageBackingMap::iterator it = m_imageBackings.find(imageID);
526     RefPtr<CoordinatedBackingStore> backingStore = it->value;
527     backingStore->removeAllTiles();
528     m_backingStoresWithPendingBuffers.add(backingStore);
529 }
530
531 void CoordinatedGraphicsScene::removeImageBacking(CoordinatedImageBackingID imageID)
532 {
533     ASSERT(m_imageBackings.contains(imageID));
534
535     // We don't want TextureMapperLayer refers a dangling pointer.
536     m_releasedImageBackings.append(m_imageBackings.take(imageID));
537 }
538
539 void CoordinatedGraphicsScene::assignImageBackingToLayer(TextureMapperLayer* layer, CoordinatedImageBackingID imageID)
540 {
541 #if USE(GRAPHICS_SURFACE)
542     if (m_surfaceBackingStores.contains(layer))
543         return;
544 #endif
545
546     if (imageID == InvalidCoordinatedImageBackingID) {
547         layer->setContentsLayer(0);
548         return;
549     }
550
551     ImageBackingMap::iterator it = m_imageBackings.find(imageID);
552     ASSERT(it != m_imageBackings.end());
553     layer->setContentsLayer(it->value.get());
554 }
555
556 void CoordinatedGraphicsScene::removeReleasedImageBackingsIfNeeded()
557 {
558     m_releasedImageBackings.clear();
559 }
560
561 void CoordinatedGraphicsScene::commitPendingBackingStoreOperations()
562 {
563     HashSet<RefPtr<CoordinatedBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end();
564     for (HashSet<RefPtr<CoordinatedBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it)
565         (*it)->commitTileOperations(m_textureMapper.get());
566
567     m_backingStoresWithPendingBuffers.clear();
568 }
569
570 void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& state)
571 {
572     m_renderedContentsScrollPosition = state.scrollPosition;
573
574     createLayers(state.layersToCreate);
575     deleteLayers(state.layersToRemove);
576
577     if (state.rootCompositingLayer != m_rootLayerID)
578         setRootLayerID(state.rootCompositingLayer);
579
580     syncImageBackings(state);
581     syncUpdateAtlases(state);
582
583     for (size_t i = 0; i < state.layersToUpdate.size(); ++i)
584         setLayerState(state.layersToUpdate[i].first, state.layersToUpdate[i].second);
585
586     commitPendingBackingStoreOperations();
587     removeReleasedImageBackingsIfNeeded();
588
589     // The pending tiles state is on its way for the screen, tell the web process to render the next one.
590     RefPtr<CoordinatedGraphicsScene> protector(this);
591     dispatchOnMainThread([=] {
592         protector->renderNextFrame();
593     });
594 }
595
596 void CoordinatedGraphicsScene::renderNextFrame()
597 {
598     if (m_client)
599         m_client->renderNextFrame();
600 }
601
602 void CoordinatedGraphicsScene::ensureRootLayer()
603 {
604     if (m_rootLayer)
605         return;
606
607     m_rootLayer = std::make_unique<TextureMapperLayer>();
608     m_rootLayer->setMasksToBounds(false);
609     m_rootLayer->setDrawsContent(false);
610     m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
611
612     // The root layer should not have zero size, or it would be optimized out.
613     m_rootLayer->setSize(FloatSize(1.0, 1.0));
614
615     ASSERT(m_textureMapper);
616     m_rootLayer->setTextureMapper(m_textureMapper.get());
617 }
618
619 void CoordinatedGraphicsScene::syncRemoteContent()
620 {
621     // We enqueue messages and execute them during paint, as they require an active GL context.
622     ensureRootLayer();
623
624     Vector<std::function<void()>> renderQueue;
625     bool calledOnMainThread = WTF::isMainThread();
626     if (!calledOnMainThread)
627         m_renderQueueMutex.lock();
628     renderQueue = std::move(m_renderQueue);
629     if (!calledOnMainThread)
630         m_renderQueueMutex.unlock();
631
632     for (auto& function : renderQueue)
633         function();
634 }
635
636 void CoordinatedGraphicsScene::purgeGLResources()
637 {
638     m_imageBackings.clear();
639     m_releasedImageBackings.clear();
640 #if USE(GRAPHICS_SURFACE)
641     m_surfaceBackingStores.clear();
642 #endif
643     m_surfaces.clear();
644
645     m_rootLayer = nullptr;
646     m_rootLayerID = InvalidCoordinatedLayerID;
647     m_layers.clear();
648     m_fixedLayers.clear();
649     m_textureMapper.clear();
650     m_backingStores.clear();
651     m_backingStoresWithPendingBuffers.clear();
652
653     setActive(false);
654
655     RefPtr<CoordinatedGraphicsScene> protector(this);
656     dispatchOnMainThread([=] {
657         protector->purgeBackingStores();
658     });
659 }
660
661 void CoordinatedGraphicsScene::dispatchCommitScrollOffset(uint32_t layerID, const IntSize& offset)
662 {
663     m_client->commitScrollOffset(layerID, offset);
664 }
665
666 void CoordinatedGraphicsScene::commitScrollOffset(uint32_t layerID, const IntSize& offset)
667 {
668     RefPtr<CoordinatedGraphicsScene> protector(this);
669     dispatchOnMainThread([=] {
670         protector->dispatchCommitScrollOffset(layerID, offset);
671     });
672 }
673
674 void CoordinatedGraphicsScene::purgeBackingStores()
675 {
676     if (m_client)
677         m_client->purgeBackingStores();
678 }
679
680 void CoordinatedGraphicsScene::setLayerAnimationsIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
681 {
682     if (!state.animationsChanged)
683         return;
684
685     layer->setAnimations(state.animations);
686 }
687
688 void CoordinatedGraphicsScene::detach()
689 {
690     ASSERT(isMainThread());
691     m_renderQueue.clear();
692     m_client = 0;
693 }
694
695 void CoordinatedGraphicsScene::appendUpdate(std::function<void()> function)
696 {
697     if (!m_isActive)
698         return;
699
700     ASSERT(isMainThread());
701     MutexLocker locker(m_renderQueueMutex);
702     m_renderQueue.append(std::move(function));
703 }
704
705 void CoordinatedGraphicsScene::setActive(bool active)
706 {
707     if (m_isActive == active)
708         return;
709
710     // Have to clear render queue in both cases.
711     // If there are some updates in queue during activation then those updates are from previous instance of paint node
712     // and cannot be applied to the newly created instance.
713     m_renderQueue.clear();
714     m_isActive = active;
715     if (m_isActive) {
716         RefPtr<CoordinatedGraphicsScene> protector(this);
717         dispatchOnMainThread([=] {
718             protector->renderNextFrame();
719         });
720     }
721 }
722
723 void CoordinatedGraphicsScene::setBackgroundColor(const Color& color)
724 {
725     m_backgroundColor = color;
726 }
727
728 TextureMapperLayer* CoordinatedGraphicsScene::findScrollableContentsLayerAt(const FloatPoint& point)
729 {
730     return rootLayer() ? rootLayer()->findScrollableContentsLayerAt(point) : 0;
731 }
732
733 } // namespace WebCore
734
735 #endif // USE(COORDINATED_GRAPHICS)