2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3 Copyright (C) 2012 Company 100, Inc.
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.
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.
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.
23 #if USE(COORDINATED_GRAPHICS)
25 #include "CoordinatedGraphicsScene.h"
27 #include "CoordinatedBackingStore.h"
28 #include "GraphicsLayerTextureMapper.h"
29 #include "TextureMapper.h"
30 #include "TextureMapperBackingStore.h"
31 #include "TextureMapperGL.h"
32 #include "TextureMapperLayer.h"
33 #include <OpenGLShims.h>
34 #include <wtf/Atomics.h>
35 #include <wtf/MainThread.h>
37 #if ENABLE(CSS_SHADERS)
38 #include "CoordinatedCustomFilterOperation.h"
39 #include "CoordinatedCustomFilterProgram.h"
40 #include "CustomFilterProgram.h"
41 #include "CustomFilterProgramInfo.h"
46 void CoordinatedGraphicsScene::dispatchOnMainThread(const Function<void()>& function)
51 callOnMainThread(function);
54 static bool layerShouldHaveBackingStore(GraphicsLayer* layer)
56 return layer->drawsContent() && layer->contentsAreVisible() && !layer->size().isEmpty();
59 CoordinatedGraphicsScene::CoordinatedGraphicsScene(CoordinatedGraphicsSceneClient* client)
62 , m_rootLayerID(InvalidCoordinatedLayerID)
63 , m_animationsLocked(false)
64 #if ENABLE(REQUEST_ANIMATION_FRAME)
65 , m_animationFrameRequested(false)
67 , m_backgroundColor(Color::white)
68 , m_setDrawsBackground(false)
70 ASSERT(isMainThread());
73 CoordinatedGraphicsScene::~CoordinatedGraphicsScene()
77 void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, TextureMapper::PaintFlags PaintFlags)
79 if (!m_textureMapper) {
80 m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
81 static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
84 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
87 adjustPositionForFixedLayers();
88 GraphicsLayer* currentRootLayer = rootLayer();
89 if (!currentRootLayer)
92 TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);
97 layer->setTextureMapper(m_textureMapper.get());
98 if (!m_animationsLocked)
99 layer->applyAnimationsRecursively();
100 m_textureMapper->beginPainting(PaintFlags);
101 m_textureMapper->beginClip(TransformationMatrix(), clipRect);
103 if (m_setDrawsBackground) {
104 RGBA32 rgba = makeRGBA32FromFloats(m_backgroundColor.red(),
105 m_backgroundColor.green(), m_backgroundColor.blue(),
106 m_backgroundColor.alpha() * opacity);
107 m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba));
110 if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
111 currentRootLayer->setOpacity(opacity);
112 currentRootLayer->setTransform(matrix);
113 currentRootLayer->flushCompositingStateForThisLayerOnly();
117 m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location(), matrix);
118 m_textureMapper->endClip();
119 m_textureMapper->endPainting();
121 if (layer->descendantsOrSelfHaveRunningAnimations())
122 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::updateViewport, this));
124 #if ENABLE(REQUEST_ANIMATION_FRAME)
125 if (m_animationFrameRequested) {
126 m_animationFrameRequested = false;
127 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::animationFrameReady, this));
132 #if ENABLE(REQUEST_ANIMATION_FRAME)
133 void CoordinatedGraphicsScene::animationFrameReady()
135 ASSERT(isMainThread());
137 m_client->animationFrameReady();
140 void CoordinatedGraphicsScene::requestAnimationFrame()
142 m_animationFrameRequested = true;
146 void CoordinatedGraphicsScene::paintToGraphicsContext(PlatformGraphicsContext* platformContext)
148 if (!m_textureMapper)
149 m_textureMapper = TextureMapper::create();
150 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
152 TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
157 GraphicsContext graphicsContext(platformContext);
158 m_textureMapper->setGraphicsContext(&graphicsContext);
159 m_textureMapper->beginPainting();
161 IntRect clipRect = graphicsContext.clipBounds();
162 if (m_setDrawsBackground)
163 m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), m_backgroundColor);
166 m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location());
167 m_textureMapper->endPainting();
168 m_textureMapper->setGraphicsContext(0);
171 void CoordinatedGraphicsScene::setScrollPosition(const FloatPoint& scrollPosition)
173 m_scrollPosition = scrollPosition;
176 void CoordinatedGraphicsScene::updateViewport()
178 ASSERT(isMainThread());
180 m_client->updateViewport();
183 void CoordinatedGraphicsScene::adjustPositionForFixedLayers()
185 if (m_fixedLayers.isEmpty())
188 // Fixed layer positions are updated by the web process when we update the visible contents rect / scroll position.
189 // If we want those layers to follow accurately the viewport when we move between the web process updates, we have to offset
190 // them by the delta between the current position and the position of the viewport used for the last layout.
191 FloatSize delta = m_scrollPosition - m_renderedContentsScrollPosition;
193 LayerRawPtrMap::iterator end = m_fixedLayers.end();
194 for (LayerRawPtrMap::iterator it = m_fixedLayers.begin(); it != end; ++it)
195 toTextureMapperLayer(it->value)->setScrollPositionDeltaIfNeeded(delta);
198 #if USE(GRAPHICS_SURFACE)
199 void CoordinatedGraphicsScene::createCanvasIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
201 if (!state.canvasToken.isValid())
204 RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore(TextureMapperSurfaceBackingStore::create());
205 m_surfaceBackingStores.set(layer, canvasBackingStore);
207 GraphicsSurface::Flags surfaceFlags = GraphicsSurface::SupportsTextureTarget | GraphicsSurface::SupportsSharing;
208 canvasBackingStore->setGraphicsSurface(GraphicsSurface::create(state.canvasSize, surfaceFlags, state.canvasToken));
209 layer->setContentsToMedia(canvasBackingStore.get());
212 void CoordinatedGraphicsScene::syncCanvasIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
214 ASSERT(m_textureMapper);
216 if (state.canvasChanged) {
217 destroyCanvasIfNeeded(layer, state);
218 createCanvasIfNeeded(layer, state);
221 if (state.canvasShouldSwapBuffers) {
222 ASSERT(m_surfaceBackingStores.contains(layer));
223 SurfaceBackingStoreMap::iterator it = m_surfaceBackingStores.find(layer);
224 RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore = it->value;
225 canvasBackingStore->swapBuffersIfNeeded(state.canvasFrontBuffer);
229 void CoordinatedGraphicsScene::destroyCanvasIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
231 if (state.canvasToken.isValid())
234 m_surfaceBackingStores.remove(layer);
235 layer->setContentsToMedia(0);
239 void CoordinatedGraphicsScene::setLayerRepaintCountIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
241 if (!layer->isShowingRepaintCounter() || !state.repaintCountChanged)
244 toGraphicsLayerTextureMapper(layer)->setRepaintCount(state.repaintCount);
247 void CoordinatedGraphicsScene::setLayerChildrenIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
249 if (!state.childrenChanged)
252 Vector<GraphicsLayer*> children;
254 for (size_t i = 0; i < state.children.size(); ++i) {
255 CoordinatedLayerID childID = state.children[i];
256 GraphicsLayer* child = layerByID(childID);
257 children.append(child);
259 layer->setChildren(children);
262 #if ENABLE(CSS_FILTERS)
263 void CoordinatedGraphicsScene::setLayerFiltersIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
265 if (!state.filtersChanged)
268 #if ENABLE(CSS_SHADERS)
269 injectCachedCustomFilterPrograms(state.filters);
271 layer->setFilters(state.filters);
275 #if ENABLE(CSS_SHADERS)
276 void CoordinatedGraphicsScene::injectCachedCustomFilterPrograms(const FilterOperations& filters) const
278 for (size_t i = 0; i < filters.size(); ++i) {
279 FilterOperation* operation = filters.operations().at(i).get();
280 if (operation->getOperationType() != FilterOperation::CUSTOM)
283 CoordinatedCustomFilterOperation* customOperation = static_cast<CoordinatedCustomFilterOperation*>(operation);
284 ASSERT(!customOperation->program());
285 CustomFilterProgramMap::const_iterator iter = m_customFilterPrograms.find(customOperation->programID());
286 ASSERT(iter != m_customFilterPrograms.end());
287 customOperation->setProgram(iter->value.get());
291 void CoordinatedGraphicsScene::createCustomFilterProgram(int id, const CustomFilterProgramInfo& programInfo)
293 ASSERT(!m_customFilterPrograms.contains(id));
294 m_customFilterPrograms.set(id, CoordinatedCustomFilterProgram::create(programInfo.vertexShaderString(), programInfo.fragmentShaderString(), programInfo.programType(), programInfo.mixSettings(), programInfo.meshType()));
297 void CoordinatedGraphicsScene::removeCustomFilterProgram(int id)
299 CustomFilterProgramMap::iterator iter = m_customFilterPrograms.find(id);
300 ASSERT(iter != m_customFilterPrograms.end());
302 m_textureMapper->removeCachedCustomFilterProgram(iter->value.get());
303 m_customFilterPrograms.remove(iter);
305 #endif // ENABLE(CSS_SHADERS)
307 void CoordinatedGraphicsScene::setLayerState(CoordinatedLayerID id, const CoordinatedGraphicsLayerState& layerState)
309 ASSERT(m_rootLayerID != InvalidCoordinatedLayerID);
310 GraphicsLayer* layer = layerByID(id);
312 if (layerState.positionChanged)
313 layer->setPosition(layerState.pos);
315 if (layerState.anchorPointChanged)
316 layer->setAnchorPoint(layerState.anchorPoint);
318 if (layerState.sizeChanged)
319 layer->setSize(layerState.size);
321 if (layerState.transformChanged)
322 layer->setTransform(layerState.transform);
324 if (layerState.childrenTransformChanged)
325 layer->setChildrenTransform(layerState.childrenTransform);
327 if (layerState.contentsRectChanged)
328 layer->setContentsRect(layerState.contentsRect);
330 if (layerState.opacityChanged)
331 layer->setOpacity(layerState.opacity);
333 if (layerState.solidColorChanged)
334 layer->setContentsToSolidColor(layerState.solidColor);
336 if (layerState.debugBorderColorChanged || layerState.debugBorderWidthChanged)
337 layer->setDebugBorder(layerState.debugBorderColor, layerState.debugBorderWidth);
339 if (layerState.replicaChanged)
340 layer->setReplicatedByLayer(getLayerByIDIfExists(layerState.replica));
342 if (layerState.maskChanged)
343 layer->setMaskLayer(getLayerByIDIfExists(layerState.mask));
345 if (layerState.imageChanged)
346 assignImageBackingToLayer(layer, layerState.imageID);
348 if (layerState.flagsChanged) {
349 layer->setContentsOpaque(layerState.contentsOpaque);
350 layer->setDrawsContent(layerState.drawsContent);
351 layer->setContentsVisible(layerState.contentsVisible);
352 layer->setBackfaceVisibility(layerState.backfaceVisible);
354 // Never clip the root layer.
355 layer->setMasksToBounds(layerState.isRootLayer ? false : layerState.masksToBounds);
356 layer->setPreserves3D(layerState.preserves3D);
358 toGraphicsLayerTextureMapper(layer)->setFixedToViewport(layerState.fixedToViewport);
359 layer->setShowDebugBorder(layerState.showDebugBorders);
360 layer->setShowRepaintCounter(layerState.showRepaintCounter);
363 if (layerState.isScrollableChanged)
364 toGraphicsLayerTextureMapper(layer)->setIsScrollable(layerState.isScrollable);
366 if (layerState.committedScrollOffsetChanged)
367 toGraphicsLayerTextureMapper(layer)->didCommitScrollOffset(layerState.committedScrollOffset);
369 if (layerState.fixedToViewport)
370 m_fixedLayers.add(id, layer);
372 m_fixedLayers.remove(id);
374 prepareContentBackingStore(layer);
377 setLayerChildrenIfNeeded(layer, layerState);
378 createTilesIfNeeded(layer, layerState);
379 removeTilesIfNeeded(layer, layerState);
380 updateTilesIfNeeded(layer, layerState);
381 #if ENABLE(CSS_FILTERS)
382 setLayerFiltersIfNeeded(layer, layerState);
384 setLayerAnimationsIfNeeded(layer, layerState);
385 #if USE(GRAPHICS_SURFACE)
386 syncCanvasIfNeeded(layer, layerState);
388 setLayerRepaintCountIfNeeded(layer, layerState);
391 GraphicsLayer* CoordinatedGraphicsScene::getLayerByIDIfExists(CoordinatedLayerID id)
393 return (id != InvalidCoordinatedLayerID) ? layerByID(id) : 0;
396 void CoordinatedGraphicsScene::createLayers(const Vector<CoordinatedLayerID>& ids)
398 for (size_t index = 0; index < ids.size(); ++index)
399 createLayer(ids[index]);
402 void CoordinatedGraphicsScene::createLayer(CoordinatedLayerID id)
404 OwnPtr<GraphicsLayer> newLayer = GraphicsLayer::create(0 /* factory */, this);
405 toGraphicsLayerTextureMapper(newLayer.get())->setHasOwnBackingStore(false);
406 toGraphicsLayerTextureMapper(newLayer.get())->setID(id);
407 toGraphicsLayerTextureMapper(newLayer.get())->setScrollClient(this);
408 m_layers.add(id, newLayer.release());
411 void CoordinatedGraphicsScene::deleteLayers(const Vector<CoordinatedLayerID>& layerIDs)
413 for (size_t index = 0; index < layerIDs.size(); ++index)
414 deleteLayer(layerIDs[index]);
417 void CoordinatedGraphicsScene::deleteLayer(CoordinatedLayerID layerID)
419 OwnPtr<GraphicsLayer> layer = m_layers.take(layerID);
422 m_backingStores.remove(layer.get());
423 m_fixedLayers.remove(layerID);
424 #if USE(GRAPHICS_SURFACE)
425 m_surfaceBackingStores.remove(layer.get());
429 void CoordinatedGraphicsScene::setRootLayerID(CoordinatedLayerID layerID)
431 ASSERT(layerID != InvalidCoordinatedLayerID);
432 ASSERT(m_rootLayerID == InvalidCoordinatedLayerID);
434 m_rootLayerID = layerID;
436 GraphicsLayer* layer = layerByID(layerID);
437 ASSERT(m_rootLayer->children().isEmpty());
438 m_rootLayer->addChild(layer);
441 void CoordinatedGraphicsScene::prepareContentBackingStore(GraphicsLayer* graphicsLayer)
443 if (!layerShouldHaveBackingStore(graphicsLayer)) {
444 removeBackingStoreIfNeeded(graphicsLayer);
448 createBackingStoreIfNeeded(graphicsLayer);
449 resetBackingStoreSizeToLayerSize(graphicsLayer);
452 void CoordinatedGraphicsScene::createBackingStoreIfNeeded(GraphicsLayer* graphicsLayer)
454 if (m_backingStores.contains(graphicsLayer))
457 RefPtr<CoordinatedBackingStore> backingStore(CoordinatedBackingStore::create());
458 m_backingStores.add(graphicsLayer, backingStore);
459 toGraphicsLayerTextureMapper(graphicsLayer)->setBackingStore(backingStore);
462 void CoordinatedGraphicsScene::removeBackingStoreIfNeeded(GraphicsLayer* graphicsLayer)
464 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.take(graphicsLayer);
468 toGraphicsLayerTextureMapper(graphicsLayer)->setBackingStore(0);
471 void CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize(GraphicsLayer* graphicsLayer)
473 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(graphicsLayer);
474 ASSERT(backingStore);
475 backingStore->setSize(graphicsLayer->size());
476 m_backingStoresWithPendingBuffers.add(backingStore);
479 void CoordinatedGraphicsScene::createTilesIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
481 if (state.tilesToCreate.isEmpty())
484 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
485 ASSERT(backingStore);
487 for (size_t i = 0; i < state.tilesToCreate.size(); ++i)
488 backingStore->createTile(state.tilesToCreate[i].tileID, state.tilesToCreate[i].scale);
491 void CoordinatedGraphicsScene::removeTilesIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
493 if (state.tilesToRemove.isEmpty())
496 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
500 for (size_t i = 0; i < state.tilesToRemove.size(); ++i)
501 backingStore->removeTile(state.tilesToRemove[i]);
503 m_backingStoresWithPendingBuffers.add(backingStore);
506 void CoordinatedGraphicsScene::updateTilesIfNeeded(GraphicsLayer* layer, const CoordinatedGraphicsLayerState& state)
508 if (state.tilesToUpdate.isEmpty())
511 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
512 ASSERT(backingStore);
514 for (size_t i = 0; i < state.tilesToUpdate.size(); ++i) {
515 const TileUpdateInfo& tileInfo = state.tilesToUpdate[i];
516 const SurfaceUpdateInfo& surfaceUpdateInfo = tileInfo.updateInfo;
518 SurfaceMap::iterator surfaceIt = m_surfaces.find(surfaceUpdateInfo.atlasID);
519 ASSERT(surfaceIt != m_surfaces.end());
521 backingStore->updateTile(tileInfo.tileID, surfaceUpdateInfo.updateRect, tileInfo.tileRect, surfaceIt->value, surfaceUpdateInfo.surfaceOffset);
522 m_backingStoresWithPendingBuffers.add(backingStore);
526 void CoordinatedGraphicsScene::createUpdateAtlas(uint32_t atlasID, PassRefPtr<CoordinatedSurface> surface)
528 ASSERT(!m_surfaces.contains(atlasID));
529 m_surfaces.add(atlasID, surface);
532 void CoordinatedGraphicsScene::removeUpdateAtlas(uint32_t atlasID)
534 ASSERT(m_surfaces.contains(atlasID));
535 m_surfaces.remove(atlasID);
538 void CoordinatedGraphicsScene::createImageBacking(CoordinatedImageBackingID imageID)
540 ASSERT(!m_imageBackings.contains(imageID));
541 RefPtr<CoordinatedBackingStore> backingStore(CoordinatedBackingStore::create());
542 m_imageBackings.add(imageID, backingStore.release());
545 void CoordinatedGraphicsScene::updateImageBacking(CoordinatedImageBackingID imageID, PassRefPtr<CoordinatedSurface> surface)
547 ASSERT(m_imageBackings.contains(imageID));
548 ImageBackingMap::iterator it = m_imageBackings.find(imageID);
549 RefPtr<CoordinatedBackingStore> backingStore = it->value;
551 // CoordinatedImageBacking is realized to CoordinatedBackingStore with only one tile in UI Process.
552 backingStore->createTile(1 /* id */, 1 /* scale */);
553 IntRect rect(IntPoint::zero(), surface->size());
554 // See CoordinatedGraphicsLayer::shouldDirectlyCompositeImage()
555 ASSERT(2000 >= std::max(rect.width(), rect.height()));
556 backingStore->setSize(rect.size());
557 backingStore->updateTile(1 /* id */, rect, rect, surface, rect.location());
559 m_backingStoresWithPendingBuffers.add(backingStore);
562 void CoordinatedGraphicsScene::clearImageBackingContents(CoordinatedImageBackingID imageID)
564 ASSERT(m_imageBackings.contains(imageID));
565 ImageBackingMap::iterator it = m_imageBackings.find(imageID);
566 RefPtr<CoordinatedBackingStore> backingStore = it->value;
567 backingStore->removeAllTiles();
568 m_backingStoresWithPendingBuffers.add(backingStore);
571 void CoordinatedGraphicsScene::removeImageBacking(CoordinatedImageBackingID imageID)
573 ASSERT(m_imageBackings.contains(imageID));
575 // We don't want TextureMapperLayer refers a dangling pointer.
576 m_releasedImageBackings.append(m_imageBackings.take(imageID));
579 void CoordinatedGraphicsScene::assignImageBackingToLayer(GraphicsLayer* layer, CoordinatedImageBackingID imageID)
581 #if USE(GRAPHICS_SURFACE)
582 if (m_surfaceBackingStores.contains(layer))
586 if (imageID == InvalidCoordinatedImageBackingID) {
587 layer->setContentsToMedia(0);
590 ImageBackingMap::iterator it = m_imageBackings.find(imageID);
591 ASSERT(it != m_imageBackings.end());
592 layer->setContentsToMedia(it->value.get());
595 void CoordinatedGraphicsScene::removeReleasedImageBackingsIfNeeded()
597 m_releasedImageBackings.clear();
600 void CoordinatedGraphicsScene::commitPendingBackingStoreOperations()
602 HashSet<RefPtr<CoordinatedBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end();
603 for (HashSet<RefPtr<CoordinatedBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it)
604 (*it)->commitTileOperations(m_textureMapper.get());
606 m_backingStoresWithPendingBuffers.clear();
609 void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& state)
611 m_renderedContentsScrollPosition = state.scrollPosition;
613 // Since the frame has now been rendered, we can safely unlock the animations until the next layout.
614 setAnimationsLocked(false);
616 if (state.rootCompositingLayer != m_rootLayerID)
617 setRootLayerID(state.rootCompositingLayer);
619 if (state.backgroundColor != m_backgroundColor)
620 setBackgroundColor(state.backgroundColor);
622 for (size_t i = 0; i < state.imagesToUpdate.size(); ++i)
623 updateImageBacking(state.imagesToUpdate[i].first, state.imagesToUpdate[i].second);
625 for (size_t i = 0; i < state.layersToUpdate.size(); ++i)
626 setLayerState(state.layersToUpdate[i].first, state.layersToUpdate[i].second);
628 m_rootLayer->flushCompositingState(FloatRect());
629 commitPendingBackingStoreOperations();
630 removeReleasedImageBackingsIfNeeded();
632 // The pending tiles state is on its way for the screen, tell the web process to render the next one.
633 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::renderNextFrame, this));
636 void CoordinatedGraphicsScene::renderNextFrame()
639 m_client->renderNextFrame();
642 void CoordinatedGraphicsScene::ensureRootLayer()
647 m_rootLayer = GraphicsLayer::create(0 /* factory */, this);
648 m_rootLayer->setMasksToBounds(false);
649 m_rootLayer->setDrawsContent(false);
650 m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
652 // The root layer should not have zero size, or it would be optimized out.
653 m_rootLayer->setSize(FloatSize(1.0, 1.0));
655 ASSERT(m_textureMapper);
656 toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
659 void CoordinatedGraphicsScene::syncRemoteContent()
661 // We enqueue messages and execute them during paint, as they require an active GL context.
664 Vector<Function<void()> > renderQueue;
665 bool calledOnMainThread = WTF::isMainThread();
666 if (!calledOnMainThread)
667 m_renderQueueMutex.lock();
668 renderQueue.swap(m_renderQueue);
669 if (!calledOnMainThread)
670 m_renderQueueMutex.unlock();
672 for (size_t i = 0; i < renderQueue.size(); ++i)
676 void CoordinatedGraphicsScene::purgeGLResources()
678 m_imageBackings.clear();
679 m_releasedImageBackings.clear();
680 #if USE(GRAPHICS_SURFACE)
681 m_surfaceBackingStores.clear();
686 m_rootLayerID = InvalidCoordinatedLayerID;
688 m_fixedLayers.clear();
689 m_textureMapper.clear();
690 m_backingStores.clear();
691 m_backingStoresWithPendingBuffers.clear();
694 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::purgeBackingStores, this));
697 void CoordinatedGraphicsScene::dispatchCommitScrollOffset(uint32_t layerID, const IntSize& offset)
699 m_client->commitScrollOffset(layerID, offset);
702 void CoordinatedGraphicsScene::commitScrollOffset(uint32_t layerID, const IntSize& offset)
704 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::dispatchCommitScrollOffset, this, layerID, offset));
707 void CoordinatedGraphicsScene::purgeBackingStores()
710 m_client->purgeBackingStores();
713 void CoordinatedGraphicsScene::setLayerAnimationsIfNeeded(GraphicsLayer* graphicsLayer, const CoordinatedGraphicsLayerState& state)
715 if (!state.animationsChanged)
718 GraphicsLayerTextureMapper* layer = toGraphicsLayerTextureMapper(graphicsLayer);
720 #if ENABLE(CSS_SHADERS)
721 for (size_t i = 0; i < state.animations.animations().size(); ++i) {
722 const KeyframeValueList& keyframes = state.animations.animations().at(i).keyframes();
723 if (keyframes.property() != AnimatedPropertyWebkitFilter)
725 for (size_t j = 0; j < keyframes.size(); ++j) {
726 const FilterAnimationValue* filterValue = static_cast<const FilterAnimationValue*>(keyframes.at(i));
727 injectCachedCustomFilterPrograms(*filterValue->value());
731 layer->setAnimations(state.animations);
734 void CoordinatedGraphicsScene::setAnimationsLocked(bool locked)
736 m_animationsLocked = locked;
739 void CoordinatedGraphicsScene::detach()
741 ASSERT(isMainThread());
745 void CoordinatedGraphicsScene::appendUpdate(const Function<void()>& function)
750 ASSERT(isMainThread());
751 MutexLocker locker(m_renderQueueMutex);
752 m_renderQueue.append(function);
755 void CoordinatedGraphicsScene::setActive(bool active)
757 if (m_isActive == active)
760 // Have to clear render queue in both cases.
761 // If there are some updates in queue during activation then those updates are from previous instance of paint node
762 // and cannot be applied to the newly created instance.
763 m_renderQueue.clear();
766 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::renderNextFrame, this));
769 void CoordinatedGraphicsScene::setBackgroundColor(const Color& color)
771 m_backgroundColor = color;
774 TextureMapperLayer* CoordinatedGraphicsScene::findScrollableContentsLayerAt(const FloatPoint& point)
776 return rootLayer() ? toTextureMapperLayer(rootLayer())->findScrollableContentsLayerAt(point) : 0;
779 } // namespace WebCore
781 #endif // USE(COORDINATED_GRAPHICS)