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/CurrentTime.h>
36 #include <wtf/MainThread.h>
38 #if ENABLE(CSS_SHADERS)
39 #include "CoordinatedCustomFilterOperation.h"
40 #include "CoordinatedCustomFilterProgram.h"
41 #include "CustomFilterProgram.h"
42 #include "CustomFilterProgramInfo.h"
47 void CoordinatedGraphicsScene::dispatchOnMainThread(const Function<void()>& function)
52 callOnMainThread(function);
55 static FloatPoint boundedScrollPosition(const FloatPoint& scrollPosition, const FloatRect& visibleContentRect, const FloatSize& contentSize)
57 float scrollPositionX = std::max(scrollPosition.x(), 0.0f);
58 scrollPositionX = std::min(scrollPositionX, contentSize.width() - visibleContentRect.width());
60 float scrollPositionY = std::max(scrollPosition.y(), 0.0f);
61 scrollPositionY = std::min(scrollPositionY, contentSize.height() - visibleContentRect.height());
62 return FloatPoint(scrollPositionX, scrollPositionY);
65 static bool layerShouldHaveBackingStore(GraphicsLayer* layer)
67 return layer->drawsContent() && layer->contentsAreVisible() && !layer->size().isEmpty();
70 CoordinatedGraphicsScene::CoordinatedGraphicsScene(CoordinatedGraphicsSceneClient* client)
73 , m_rootLayerID(InvalidCoordinatedLayerID)
74 , m_animationsLocked(false)
75 #if ENABLE(REQUEST_ANIMATION_FRAME)
76 , m_animationFrameRequested(false)
78 , m_backgroundColor(Color::white)
79 , m_setDrawsBackground(false)
80 , m_isShowingFPS(false)
86 ASSERT(isMainThread());
88 String showFPSEnvironment = getenv("WEBKIT_SHOW_FPS");
90 m_fpsInterval = showFPSEnvironment.toDouble(&ok);
91 if (ok && m_fpsInterval) {
92 m_isShowingFPS = true;
93 m_fpsTimestamp = WTF::currentTime();
97 CoordinatedGraphicsScene::~CoordinatedGraphicsScene()
101 void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, TextureMapper::PaintFlags PaintFlags)
103 if (!m_textureMapper) {
104 m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
105 static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
108 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
111 adjustPositionForFixedLayers();
112 GraphicsLayer* currentRootLayer = rootLayer();
113 if (!currentRootLayer)
116 TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer);
121 layer->setTextureMapper(m_textureMapper.get());
122 if (!m_animationsLocked)
123 layer->applyAnimationsRecursively();
124 m_textureMapper->beginPainting(PaintFlags);
125 m_textureMapper->beginClip(TransformationMatrix(), clipRect);
127 if (m_setDrawsBackground) {
128 RGBA32 rgba = makeRGBA32FromFloats(m_backgroundColor.red(),
129 m_backgroundColor.green(), m_backgroundColor.blue(),
130 m_backgroundColor.alpha() * opacity);
131 m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba));
134 if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) {
135 currentRootLayer->setOpacity(opacity);
136 currentRootLayer->setTransform(matrix);
137 currentRootLayer->flushCompositingStateForThisLayerOnly();
142 updateFPS(clipRect.location(), matrix);
143 m_textureMapper->endClip();
144 m_textureMapper->endPainting();
146 if (layer->descendantsOrSelfHaveRunningAnimations())
147 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::updateViewport, this));
149 #if ENABLE(REQUEST_ANIMATION_FRAME)
150 if (m_animationFrameRequested) {
151 m_animationFrameRequested = false;
152 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::animationFrameReady, this));
157 #if ENABLE(REQUEST_ANIMATION_FRAME)
158 void CoordinatedGraphicsScene::animationFrameReady()
160 ASSERT(isMainThread());
162 m_client->animationFrameReady();
165 void CoordinatedGraphicsScene::requestAnimationFrame()
167 m_animationFrameRequested = true;
172 void CoordinatedGraphicsScene::paintToGraphicsContext(QPainter* painter)
174 void CoordinatedGraphicsScene::paintToGraphicsContext(cairo_t* painter)
177 if (!m_textureMapper)
178 m_textureMapper = TextureMapper::create();
179 ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode);
181 TextureMapperLayer* layer = toTextureMapperLayer(rootLayer());
186 GraphicsContext graphicsContext(painter);
187 m_textureMapper->setGraphicsContext(&graphicsContext);
188 m_textureMapper->beginPainting();
190 IntRect clipRect = graphicsContext.clipBounds();
191 if (m_setDrawsBackground)
192 m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), m_backgroundColor);
196 updateFPS(clipRect.location());
197 m_textureMapper->endPainting();
198 m_textureMapper->setGraphicsContext(0);
201 void CoordinatedGraphicsScene::setContentsSize(const FloatSize& contentsSize)
203 m_contentsSize = contentsSize;
206 void CoordinatedGraphicsScene::setVisibleContentsRect(const FloatRect& rect)
208 m_visibleContentsRect = rect;
211 void CoordinatedGraphicsScene::updateViewport()
213 ASSERT(isMainThread());
215 m_client->updateViewport();
218 void CoordinatedGraphicsScene::adjustPositionForFixedLayers()
220 if (m_fixedLayers.isEmpty())
223 // Fixed layer positions are updated by the web process when we update the visible contents rect / scroll position.
224 // If we want those layers to follow accurately the viewport when we move between the web process updates, we have to offset
225 // them by the delta between the current position and the position of the viewport used for the last layout.
226 FloatPoint scrollPosition = boundedScrollPosition(m_visibleContentsRect.location(), m_visibleContentsRect, m_contentsSize);
227 FloatPoint renderedScrollPosition = boundedScrollPosition(m_renderedContentsScrollPosition, m_visibleContentsRect, m_contentsSize);
228 FloatSize delta = scrollPosition - renderedScrollPosition;
230 LayerRawPtrMap::iterator end = m_fixedLayers.end();
231 for (LayerRawPtrMap::iterator it = m_fixedLayers.begin(); it != end; ++it)
232 toTextureMapperLayer(it->value)->setScrollPositionDeltaIfNeeded(delta);
235 #if USE(GRAPHICS_SURFACE)
236 void CoordinatedGraphicsScene::createCanvas(CoordinatedLayerID id, const IntSize&, PassRefPtr<GraphicsSurface> surface)
238 ASSERT(m_textureMapper);
239 GraphicsLayer* layer = layerByID(id);
240 ASSERT(!m_surfaceBackingStores.contains(id));
242 RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore(TextureMapperSurfaceBackingStore::create());
243 m_surfaceBackingStores.set(id, canvasBackingStore);
245 canvasBackingStore->setGraphicsSurface(surface);
246 layer->setContentsToMedia(canvasBackingStore.get());
249 void CoordinatedGraphicsScene::syncCanvas(CoordinatedLayerID id, uint32_t frontBuffer)
251 ASSERT(m_textureMapper);
252 ASSERT(m_surfaceBackingStores.contains(id));
254 SurfaceBackingStoreMap::iterator it = m_surfaceBackingStores.find(id);
255 RefPtr<TextureMapperSurfaceBackingStore> canvasBackingStore = it->value;
257 canvasBackingStore->swapBuffersIfNeeded(frontBuffer);
260 void CoordinatedGraphicsScene::destroyCanvas(CoordinatedLayerID id)
262 ASSERT(m_textureMapper);
263 GraphicsLayer* layer = layerByID(id);
264 ASSERT(m_surfaceBackingStores.contains(id));
266 m_surfaceBackingStores.remove(id);
267 layer->setContentsToMedia(0);
271 void CoordinatedGraphicsScene::setLayerRepaintCount(CoordinatedLayerID id, int value)
273 GraphicsLayer* layer = layerByID(id);
274 toGraphicsLayerTextureMapper(layer)->setRepaintCount(value);
277 void CoordinatedGraphicsScene::setLayerChildren(CoordinatedLayerID id, const Vector<CoordinatedLayerID>& childIDs)
279 GraphicsLayer* layer = layerByID(id);
280 Vector<GraphicsLayer*> children;
282 for (size_t i = 0; i < childIDs.size(); ++i) {
283 CoordinatedLayerID childID = childIDs[i];
284 GraphicsLayer* child = layerByID(childID);
285 children.append(child);
287 layer->setChildren(children);
290 #if ENABLE(CSS_FILTERS)
291 void CoordinatedGraphicsScene::setLayerFilters(CoordinatedLayerID id, const FilterOperations& filters)
293 GraphicsLayer* layer = layerByID(id);
295 #if ENABLE(CSS_SHADERS)
296 injectCachedCustomFilterPrograms(filters);
298 layer->setFilters(filters);
302 #if ENABLE(CSS_SHADERS)
303 void CoordinatedGraphicsScene::injectCachedCustomFilterPrograms(const FilterOperations& filters) const
305 for (size_t i = 0; i < filters.size(); ++i) {
306 FilterOperation* operation = filters.operations().at(i).get();
307 if (operation->getOperationType() != FilterOperation::CUSTOM)
310 CoordinatedCustomFilterOperation* customOperation = static_cast<CoordinatedCustomFilterOperation*>(operation);
311 ASSERT(!customOperation->program());
312 CustomFilterProgramMap::const_iterator iter = m_customFilterPrograms.find(customOperation->programID());
313 ASSERT(iter != m_customFilterPrograms.end());
314 customOperation->setProgram(iter->value.get());
318 void CoordinatedGraphicsScene::createCustomFilterProgram(int id, const CustomFilterProgramInfo& programInfo)
320 ASSERT(!m_customFilterPrograms.contains(id));
321 m_customFilterPrograms.set(id, CoordinatedCustomFilterProgram::create(programInfo.vertexShaderString(), programInfo.fragmentShaderString(), programInfo.programType(), programInfo.mixSettings(), programInfo.meshType()));
324 void CoordinatedGraphicsScene::removeCustomFilterProgram(int id)
326 CustomFilterProgramMap::iterator iter = m_customFilterPrograms.find(id);
327 ASSERT(iter != m_customFilterPrograms.end());
329 m_textureMapper->removeCachedCustomFilterProgram(iter->value.get());
330 m_customFilterPrograms.remove(iter);
332 #endif // ENABLE(CSS_SHADERS)
334 void CoordinatedGraphicsScene::setLayerState(CoordinatedLayerID id, const CoordinatedLayerInfo& layerInfo)
336 ASSERT(m_rootLayerID != InvalidCoordinatedLayerID);
337 GraphicsLayer* layer = layerByID(id);
339 layer->setReplicatedByLayer(getLayerByIDIfExists(layerInfo.replica));
340 layer->setMaskLayer(getLayerByIDIfExists(layerInfo.mask));
342 layer->setAnchorPoint(layerInfo.anchorPoint);
343 layer->setPosition(layerInfo.pos);
344 layer->setSize(layerInfo.size);
346 layer->setTransform(layerInfo.transform);
347 layer->setChildrenTransform(layerInfo.childrenTransform);
348 layer->setBackfaceVisibility(layerInfo.backfaceVisible);
349 layer->setContentsOpaque(layerInfo.contentsOpaque);
350 layer->setContentsRect(layerInfo.contentsRect);
351 layer->setContentsToSolidColor(layerInfo.solidColor);
352 layer->setDrawsContent(layerInfo.drawsContent);
353 layer->setContentsVisible(layerInfo.contentsVisible);
354 toGraphicsLayerTextureMapper(layer)->setFixedToViewport(layerInfo.fixedToViewport);
355 layer->setShowDebugBorder(layerInfo.showDebugBorders);
356 layer->setDebugBorder(layerInfo.debugBorderColor, layerInfo.debugBorderWidth);
357 layer->setShowRepaintCounter(layerInfo.showRepaintCounter);
359 if (layerInfo.fixedToViewport)
360 m_fixedLayers.add(id, layer);
362 m_fixedLayers.remove(id);
364 assignImageBackingToLayer(layer, layerInfo.imageID);
365 prepareContentBackingStore(layer);
367 // Never make the root layer clip.
368 layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds);
369 layer->setOpacity(layerInfo.opacity);
370 layer->setPreserves3D(layerInfo.preserves3D);
373 GraphicsLayer* CoordinatedGraphicsScene::getLayerByIDIfExists(CoordinatedLayerID id)
375 return (id != InvalidCoordinatedLayerID) ? layerByID(id) : 0;
378 void CoordinatedGraphicsScene::createLayers(const Vector<CoordinatedLayerID>& ids)
380 for (size_t index = 0; index < ids.size(); ++index)
381 createLayer(ids[index]);
384 void CoordinatedGraphicsScene::createLayer(CoordinatedLayerID id)
386 OwnPtr<GraphicsLayer> newLayer = GraphicsLayer::create(0 /* factory */, this);
387 toGraphicsLayerTextureMapper(newLayer.get())->setHasOwnBackingStore(false);
388 m_layers.add(id, newLayer.release());
391 void CoordinatedGraphicsScene::deleteLayers(const Vector<CoordinatedLayerID>& layerIDs)
393 for (size_t index = 0; index < layerIDs.size(); ++index)
394 deleteLayer(layerIDs[index]);
397 void CoordinatedGraphicsScene::deleteLayer(CoordinatedLayerID layerID)
399 OwnPtr<GraphicsLayer> layer = m_layers.take(layerID);
402 m_backingStores.remove(layer.get());
403 m_fixedLayers.remove(layerID);
404 #if USE(GRAPHICS_SURFACE)
405 m_surfaceBackingStores.remove(layerID);
409 void CoordinatedGraphicsScene::setRootLayerID(CoordinatedLayerID layerID)
411 ASSERT(layerID != InvalidCoordinatedLayerID);
412 ASSERT(m_rootLayerID == InvalidCoordinatedLayerID);
414 m_rootLayerID = layerID;
416 GraphicsLayer* layer = layerByID(layerID);
417 ASSERT(m_rootLayer->children().isEmpty());
418 m_rootLayer->addChild(layer);
421 void CoordinatedGraphicsScene::prepareContentBackingStore(GraphicsLayer* graphicsLayer)
423 if (!layerShouldHaveBackingStore(graphicsLayer)) {
424 removeBackingStoreIfNeeded(graphicsLayer);
428 createBackingStoreIfNeeded(graphicsLayer);
431 void CoordinatedGraphicsScene::createBackingStoreIfNeeded(GraphicsLayer* graphicsLayer)
433 if (m_backingStores.contains(graphicsLayer))
436 RefPtr<CoordinatedBackingStore> backingStore(CoordinatedBackingStore::create());
437 backingStore->setSize(graphicsLayer->size());
438 m_backingStores.add(graphicsLayer, backingStore);
439 toGraphicsLayerTextureMapper(graphicsLayer)->setBackingStore(backingStore);
442 void CoordinatedGraphicsScene::removeBackingStoreIfNeeded(GraphicsLayer* graphicsLayer)
444 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.take(graphicsLayer);
448 toGraphicsLayerTextureMapper(graphicsLayer)->setBackingStore(0);
451 void CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize(GraphicsLayer* graphicsLayer)
453 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(graphicsLayer);
454 ASSERT(backingStore);
455 backingStore->setSize(graphicsLayer->size());
458 void CoordinatedGraphicsScene::createTile(CoordinatedLayerID layerID, uint32_t tileID, float scale)
460 GraphicsLayer* layer = layerByID(layerID);
461 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
462 ASSERT(backingStore);
463 backingStore->createTile(tileID, scale);
464 resetBackingStoreSizeToLayerSize(layer);
467 void CoordinatedGraphicsScene::removeTile(CoordinatedLayerID layerID, uint32_t tileID)
469 GraphicsLayer* layer = layerByID(layerID);
470 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
474 backingStore->removeTile(tileID);
475 resetBackingStoreSizeToLayerSize(layer);
476 m_backingStoresWithPendingBuffers.add(backingStore);
479 void CoordinatedGraphicsScene::updateTile(CoordinatedLayerID layerID, uint32_t tileID, const TileUpdate& update)
481 GraphicsLayer* layer = layerByID(layerID);
482 RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
483 ASSERT(backingStore);
485 SurfaceMap::iterator it = m_surfaces.find(update.atlasID);
486 ASSERT(it != m_surfaces.end());
488 backingStore->updateTile(tileID, update.sourceRect, update.tileRect, it->value, update.offset);
489 resetBackingStoreSizeToLayerSize(layer);
490 m_backingStoresWithPendingBuffers.add(backingStore);
493 void CoordinatedGraphicsScene::createUpdateAtlas(uint32_t atlasID, PassRefPtr<CoordinatedSurface> surface)
495 ASSERT(!m_surfaces.contains(atlasID));
496 m_surfaces.add(atlasID, surface);
499 void CoordinatedGraphicsScene::removeUpdateAtlas(uint32_t atlasID)
501 ASSERT(m_surfaces.contains(atlasID));
502 m_surfaces.remove(atlasID);
505 void CoordinatedGraphicsScene::createImageBacking(CoordinatedImageBackingID imageID)
507 ASSERT(!m_imageBackings.contains(imageID));
508 RefPtr<CoordinatedBackingStore> backingStore(CoordinatedBackingStore::create());
509 m_imageBackings.add(imageID, backingStore.release());
512 void CoordinatedGraphicsScene::updateImageBacking(CoordinatedImageBackingID imageID, PassRefPtr<CoordinatedSurface> surface)
514 ASSERT(m_imageBackings.contains(imageID));
515 ImageBackingMap::iterator it = m_imageBackings.find(imageID);
516 RefPtr<CoordinatedBackingStore> backingStore = it->value;
518 // CoordinatedImageBacking is realized to CoordinatedBackingStore with only one tile in UI Process.
519 backingStore->createTile(1 /* id */, 1 /* scale */);
520 IntRect rect(IntPoint::zero(), surface->size());
521 // See CoordinatedGraphicsLayer::shouldDirectlyCompositeImage()
522 ASSERT(2000 >= std::max(rect.width(), rect.height()));
523 backingStore->setSize(rect.size());
524 backingStore->updateTile(1 /* id */, rect, rect, surface, rect.location());
526 m_backingStoresWithPendingBuffers.add(backingStore);
529 void CoordinatedGraphicsScene::clearImageBackingContents(CoordinatedImageBackingID imageID)
531 ASSERT(m_imageBackings.contains(imageID));
532 ImageBackingMap::iterator it = m_imageBackings.find(imageID);
533 RefPtr<CoordinatedBackingStore> backingStore = it->value;
534 backingStore->removeAllTiles();
535 m_backingStoresWithPendingBuffers.add(backingStore);
538 void CoordinatedGraphicsScene::removeImageBacking(CoordinatedImageBackingID imageID)
540 ASSERT(m_imageBackings.contains(imageID));
542 // We don't want TextureMapperLayer refers a dangling pointer.
543 m_releasedImageBackings.append(m_imageBackings.take(imageID));
546 void CoordinatedGraphicsScene::assignImageBackingToLayer(GraphicsLayer* layer, CoordinatedImageBackingID imageID)
548 if (imageID == InvalidCoordinatedImageBackingID) {
549 layer->setContentsToMedia(0);
552 ImageBackingMap::iterator it = m_imageBackings.find(imageID);
553 ASSERT(it != m_imageBackings.end());
554 layer->setContentsToMedia(it->value.get());
557 void CoordinatedGraphicsScene::removeReleasedImageBackingsIfNeeded()
559 m_releasedImageBackings.clear();
562 void CoordinatedGraphicsScene::commitPendingBackingStoreOperations()
564 HashSet<RefPtr<CoordinatedBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end();
565 for (HashSet<RefPtr<CoordinatedBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it)
566 (*it)->commitTileOperations(m_textureMapper.get());
568 m_backingStoresWithPendingBuffers.clear();
571 void CoordinatedGraphicsScene::flushLayerChanges(const FloatPoint& scrollPosition)
573 m_renderedContentsScrollPosition = scrollPosition;
575 // Since the frame has now been rendered, we can safely unlock the animations until the next layout.
576 setAnimationsLocked(false);
578 m_rootLayer->flushCompositingState(FloatRect());
579 commitPendingBackingStoreOperations();
580 removeReleasedImageBackingsIfNeeded();
582 // The pending tiles state is on its way for the screen, tell the web process to render the next one.
583 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::renderNextFrame, this));
586 void CoordinatedGraphicsScene::renderNextFrame()
589 m_client->renderNextFrame();
592 void CoordinatedGraphicsScene::ensureRootLayer()
597 m_rootLayer = GraphicsLayer::create(0 /* factory */, this);
598 m_rootLayer->setMasksToBounds(false);
599 m_rootLayer->setDrawsContent(false);
600 m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
602 // The root layer should not have zero size, or it would be optimized out.
603 m_rootLayer->setSize(FloatSize(1.0, 1.0));
605 ASSERT(m_textureMapper);
606 toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
609 void CoordinatedGraphicsScene::syncRemoteContent()
611 // We enqueue messages and execute them during paint, as they require an active GL context.
614 Vector<Function<void()> > renderQueue;
615 bool calledOnMainThread = WTF::isMainThread();
616 if (!calledOnMainThread)
617 m_renderQueueMutex.lock();
618 renderQueue.swap(m_renderQueue);
619 if (!calledOnMainThread)
620 m_renderQueueMutex.unlock();
622 for (size_t i = 0; i < renderQueue.size(); ++i)
626 void CoordinatedGraphicsScene::purgeGLResources()
628 m_imageBackings.clear();
629 m_releasedImageBackings.clear();
630 #if USE(GRAPHICS_SURFACE)
631 m_surfaceBackingStores.clear();
636 m_rootLayerID = InvalidCoordinatedLayerID;
638 m_fixedLayers.clear();
639 m_textureMapper.clear();
640 m_backingStores.clear();
641 m_backingStoresWithPendingBuffers.clear();
644 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::purgeBackingStores, this));
647 void CoordinatedGraphicsScene::purgeBackingStores()
650 m_client->purgeBackingStores();
653 void CoordinatedGraphicsScene::setLayerAnimations(CoordinatedLayerID id, const GraphicsLayerAnimations& animations)
655 GraphicsLayerTextureMapper* layer = toGraphicsLayerTextureMapper(layerByID(id));
656 #if ENABLE(CSS_SHADERS)
657 for (size_t i = 0; i < animations.animations().size(); ++i) {
658 const KeyframeValueList& keyframes = animations.animations().at(i).keyframes();
659 if (keyframes.property() != AnimatedPropertyWebkitFilter)
661 for (size_t j = 0; j < keyframes.size(); ++j) {
662 const FilterAnimationValue* filterValue = static_cast<const FilterAnimationValue*>(keyframes.at(i));
663 injectCachedCustomFilterPrograms(*filterValue->value());
667 layer->setAnimations(animations);
670 void CoordinatedGraphicsScene::setAnimationsLocked(bool locked)
672 m_animationsLocked = locked;
675 void CoordinatedGraphicsScene::detach()
677 ASSERT(isMainThread());
681 void CoordinatedGraphicsScene::appendUpdate(const Function<void()>& function)
686 ASSERT(isMainThread());
687 MutexLocker locker(m_renderQueueMutex);
688 m_renderQueue.append(function);
691 void CoordinatedGraphicsScene::setActive(bool active)
693 if (m_isActive == active)
696 // Have to clear render queue in both cases.
697 // If there are some updates in queue during activation then those updates are from previous instance of paint node
698 // and cannot be applied to the newly created instance.
699 m_renderQueue.clear();
702 dispatchOnMainThread(bind(&CoordinatedGraphicsScene::renderNextFrame, this));
705 void CoordinatedGraphicsScene::setBackgroundColor(const Color& color)
707 m_backgroundColor = color;
710 void CoordinatedGraphicsScene::updateFPS(const FloatPoint& location, const TransformationMatrix& matrix)
713 double delta = WTF::currentTime() - m_fpsTimestamp;
714 if (delta >= m_fpsInterval) {
715 m_lastFPS = int(m_frameCount / delta);
717 m_fpsTimestamp += delta;
720 // FIXME: drawRepaintCounter() should save a texture and re-use whenever possible.
721 m_textureMapper->drawRepaintCounter(m_lastFPS, Color::black, location, matrix);
724 } // namespace WebCore
726 #endif // USE(COORDINATED_GRAPHICS)