void TextureMapperLayer::flushCompositingStateForThisLayerOnly(GraphicsLayerTextureMapper* graphicsLayer) { ASSERT(graphicsLayer); int changeMask = graphicsLayer->changeMask(); if (changeMask == NoChanges && graphicsLayer->m_animations.isEmpty()) return; graphicsLayer->updateDebugIndicators(); if (changeMask & ChildrenChange) setChildren(graphicsLayer->children()); if (changeMask & MaskLayerChange) { if (TextureMapperLayer* layer = toTextureMapperLayer(graphicsLayer->maskLayer())) layer->m_effectTarget = this; } if (changeMask & ReplicaLayerChange) { if (TextureMapperLayer* layer = toTextureMapperLayer(graphicsLayer->replicaLayer())) layer->m_effectTarget = this; } if (changeMask & AnimationChange) m_animations = graphicsLayer->m_animations; m_state.maskLayer = toTextureMapperLayer(graphicsLayer->maskLayer()); m_state.replicaLayer = toTextureMapperLayer(graphicsLayer->replicaLayer()); m_state.pos = graphicsLayer->position(); m_state.anchorPoint = graphicsLayer->anchorPoint(); m_state.size = graphicsLayer->size(); m_state.transform = graphicsLayer->transform(); m_state.contentsRect = graphicsLayer->contentsRect(); m_state.preserves3D = graphicsLayer->preserves3D(); m_state.masksToBounds = graphicsLayer->masksToBounds(); m_state.drawsContent = graphicsLayer->drawsContent(); m_state.contentsVisible = graphicsLayer->contentsAreVisible(); m_state.contentsOpaque = graphicsLayer->contentsOpaque(); m_state.backfaceVisibility = graphicsLayer->backfaceVisibility(); m_state.childrenTransform = graphicsLayer->childrenTransform(); m_state.opacity = graphicsLayer->opacity(); m_state.solidColor = graphicsLayer->solidColor(); #if ENABLE(CSS_FILTERS) if (changeMask & FilterChange) m_state.filters = graphicsLayer->filters(); #endif m_fixedToViewport = graphicsLayer->fixedToViewport(); m_contentsLayer = graphicsLayer->platformLayer(); m_transform.setPosition(adjustedPosition()); m_transform.setAnchorPoint(m_state.anchorPoint); m_transform.setSize(m_state.size); m_transform.setFlattening(!m_state.preserves3D); m_transform.setChildrenTransform(m_state.childrenTransform); syncAnimations(); }
void LayerTreeHostGtk::layerFlushTimerFired() { double fireTime = monotonicallyIncreasingTime(); flushAndRenderLayers(); if (m_layerFlushTimerCallback.isScheduled() || !toTextureMapperLayer(m_rootLayer.get())->descendantsOrSelfHaveRunningAnimations()) return; static const double targetFramerate = 1 / 60.0; // When rendering layers takes more time than the target delay (0.016), we end up scheduling layer flushes // immediately. Since the layer flush timer has a higher priority than WebCore timers, these are never // fired while we keep scheduling layer flushes immediately. double current = monotonicallyIncreasingTime(); double timeToNextFlush = std::max(targetFramerate - (current - fireTime), 0.0); if (timeToNextFlush) m_lastImmediateFlushTime = 0; else if (!m_lastImmediateFlushTime) m_lastImmediateFlushTime = current; if (shouldSkipNextFrameBecauseOfContinousImmediateFlushes(current, m_lastImmediateFlushTime)) { timeToNextFlush = targetFramerate; m_lastImmediateFlushTime = 0; } // Modified by ZRL for compiling #if 0 m_layerFlushTimerCallback.scheduleAfterDelay("[WebKit] layerFlushTimer", std::bind(&LayerTreeHostGtk::layerFlushTimerFired, this), std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(timeToNextFlush)), layerFlushTimerPriority); #else std::function<void ()> fp = std::bind(&LayerTreeHostGtk::layerFlushTimerFired, this); m_layerFlushTimerCallback.scheduleAfterDelay("[WebKit] layerFlushTimer", fp, std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(timeToNextFlush)), layerFlushTimerPriority); #endif }
void TextureMapperLayer::setChildren(const Vector<GraphicsLayer*>& newChildren) { removeAllChildren(); for (size_t i = 0; i < newChildren.size(); ++i) { TextureMapperLayer* child = toTextureMapperLayer(newChildren[i]); ASSERT(child); addChild(child); } }
void LayerTreeHostGtk::layerFlushTimerFired() { ASSERT(m_layerFlushTimerCallbackId); m_layerFlushTimerCallbackId = 0; flushAndRenderLayers(); if (toTextureMapperLayer(m_rootLayer.get())->descendantsOrSelfHaveRunningAnimations() && !m_layerFlushTimerCallbackId) m_layerFlushTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 1000.0 / 60.0, reinterpret_cast<GSourceFunc>(layerFlushTimerFiredCallback), this, 0); }
void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, TextureMapper::PaintFlags PaintFlags) { if (!m_textureMapper) { m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true); } ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode); syncRemoteContent(); adjustPositionForFixedLayers(); GraphicsLayer* currentRootLayer = rootLayer(); if (!currentRootLayer) return; TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer); if (!layer) return; layer->setTextureMapper(m_textureMapper.get()); if (!m_animationsLocked) layer->applyAnimationsRecursively(); m_textureMapper->beginPainting(PaintFlags); m_textureMapper->beginClip(TransformationMatrix(), clipRect); if (m_setDrawsBackground) { RGBA32 rgba = makeRGBA32FromFloats(m_backgroundColor.red(), m_backgroundColor.green(), m_backgroundColor.blue(), m_backgroundColor.alpha() * opacity); m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), Color(rgba)); } if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) { currentRootLayer->setOpacity(opacity); currentRootLayer->setTransform(matrix); currentRootLayer->flushCompositingStateForThisLayerOnly(); } layer->paint(); m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location(), matrix); m_textureMapper->endClip(); m_textureMapper->endPainting(); if (layer->descendantsOrSelfHaveRunningAnimations()) dispatchOnMainThread(bind(&CoordinatedGraphicsScene::updateViewport, this)); #if ENABLE(REQUEST_ANIMATION_FRAME) if (m_animationFrameRequested) { m_animationFrameRequested = false; dispatchOnMainThread(bind(&CoordinatedGraphicsScene::animationFrameReady, this)); } #endif }
void CoordinatedGraphicsScene::adjustPositionForFixedLayers() { if (m_fixedLayers.isEmpty()) return; // Fixed layer positions are updated by the web process when we update the visible contents rect / scroll position. // If we want those layers to follow accurately the viewport when we move between the web process updates, we have to offset // them by the delta between the current position and the position of the viewport used for the last layout. FloatSize delta = m_scrollPosition - m_renderedContentsScrollPosition; LayerRawPtrMap::iterator end = m_fixedLayers.end(); for (LayerRawPtrMap::iterator it = m_fixedLayers.begin(); it != end; ++it) toTextureMapperLayer(it->value)->setScrollPositionDeltaIfNeeded(delta); }
void LayerTreeHostGtk::layerFlushTimerFired() { ASSERT(m_layerFlushTimerCallbackId); m_layerFlushTimerCallbackId = 0; flushAndRenderLayers(); if (toTextureMapperLayer(m_rootLayer.get())->descendantsOrSelfHaveRunningAnimations() && !m_layerFlushTimerCallbackId) { const double targetFPS = 60; double nextFlush = std::max((1 / targetFPS) - (currentTime() - m_lastFlushTime), 0.0); m_layerFlushTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, nextFlush * 1000.0, reinterpret_cast<GSourceFunc>(layerFlushTimerFiredCallback), this, 0); g_source_set_name_by_id(m_layerFlushTimerCallbackId, "[WebKit] layerFlushTimerFiredCallback"); } }
void CoordinatedGraphicsScene::ensureRootLayer() { if (m_rootLayer) return; m_rootLayer = GraphicsLayer::create(0 /* factory */, this); m_rootLayer->setMasksToBounds(false); m_rootLayer->setDrawsContent(false); m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); // The root layer should not have zero size, or it would be optimized out. m_rootLayer->setSize(FloatSize(1.0, 1.0)); ASSERT(m_textureMapper); toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); }
void LayerTreeHostGtk::initialize() { m_rootLayer = GraphicsLayer::create(graphicsLayerFactory(), this); m_rootLayer->setDrawsContent(false); m_rootLayer->setSize(m_webPage->size()); // The non-composited contents are a child of the root layer. m_nonCompositedContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this); m_nonCompositedContentLayer->setDrawsContent(true); m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); m_nonCompositedContentLayer->setSize(m_webPage->size()); if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled()) m_nonCompositedContentLayer->setAcceleratesDrawing(true); #ifndef NDEBUG m_rootLayer->setName("LayerTreeHost root layer"); m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content"); #endif m_rootLayer->addChild(m_nonCompositedContentLayer.get()); m_nonCompositedContentLayer->setNeedsDisplay(); m_layerTreeContext.windowHandle = m_webPage->nativeWindowHandle(); GLContext* context = glContext(); if (!context) { m_isValid = false; return; } // The creation of the TextureMapper needs an active OpenGL context. context->makeContextCurrent(); m_textureMapper = TextureMapperGL::create(); static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true); toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); if (m_webPage->hasPageOverlay()) { PageOverlayList& pageOverlays = m_webPage->pageOverlays(); PageOverlayList::iterator end = pageOverlays.end(); for (PageOverlayList::iterator it = pageOverlays.begin(); it != end; ++it) createPageOverlayLayer(it->get()); } scheduleLayerFlush(); }
void LayerTreeHostGtk::compositeLayersToContext() { GLContext* context = glContext(); if (!context || !context->makeContextCurrent()) return; // The window size may be out of sync with the page size at this point, and getting // the viewport parameters incorrect, means that the content will be misplaced. Thus // we set the viewport parameters directly from the window size. IntSize contextSize = m_context->defaultFrameBufferSize(); glViewport(0, 0, contextSize.width(), contextSize.height()); m_textureMapper->beginPainting(); toTextureMapperLayer(m_rootLayer.get())->paint(); m_textureMapper->endPainting(); context->swapBuffers(); }
void AcceleratedCompositingContext::attachRootGraphicsLayer(GraphicsLayer* rootLayer) { if (!rootLayer) { m_rootGraphicsLayer = nullptr; m_rootTextureMapperLayer = 0; return; } m_rootGraphicsLayer = WebCore::GraphicsLayer::create(0, 0); m_rootTextureMapperLayer = toTextureMapperLayer(m_rootGraphicsLayer.get()); m_rootGraphicsLayer->addChild(rootLayer); m_rootGraphicsLayer->setDrawsContent(false); m_rootGraphicsLayer->setMasksToBounds(false); m_rootGraphicsLayer->setSize(WebCore::IntSize(1, 1)); m_textureMapper = TextureMapperGL::create(); m_rootTextureMapperLayer->setTextureMapper(m_textureMapper.get()); m_rootGraphicsLayer->flushCompositingStateForThisLayerOnly(); }
void TextureMapperLayer::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper, int options) { if (!textureMapper) return; if (graphicsLayer && !(options & ComputationsOnly)) { syncCompositingStateSelf(graphicsLayer, textureMapper); graphicsLayer->didSynchronize(); } if (graphicsLayer && m_state.maskLayer) { m_state.maskLayer->syncCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), textureMapper); // A mask layer has its parent's size by default, in case it's not set specifically. if (m_state.maskLayer->m_size.isEmpty()) m_state.maskLayer->m_size = m_size; } if (m_state.replicaLayer) m_state.replicaLayer->syncCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), textureMapper); syncAnimations(); updateBackingStore(textureMapper, graphicsLayer); if (!(options & TraverseDescendants)) options = ComputationsOnly; if (graphicsLayer) { Vector<GraphicsLayer*> children = graphicsLayer->children(); for (int i = children.size() - 1; i >= 0; --i) { TextureMapperLayer* layer = toTextureMapperLayer(children[i]); if (!layer) continue; layer->syncCompositingState(toGraphicsLayerTextureMapper(children[i]), textureMapper, options); } } else { for (int i = m_children.size() - 1; i >= 0; --i) m_children[i]->syncCompositingState(0, textureMapper, options); } }
void LayerTreeHostGtk::initialize() { m_rootLayer = GraphicsLayer::create(graphicsLayerFactory(), *this); m_rootLayer->setDrawsContent(false); m_rootLayer->setSize(m_webPage->size()); // The non-composited contents are a child of the root layer. m_nonCompositedContentLayer = GraphicsLayer::create(graphicsLayerFactory(), *this); m_nonCompositedContentLayer->setDrawsContent(true); m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); m_nonCompositedContentLayer->setSize(m_webPage->size()); if (m_webPage->corePage()->settings().acceleratedDrawingEnabled()) m_nonCompositedContentLayer->setAcceleratesDrawing(true); #ifndef NDEBUG m_rootLayer->setName("LayerTreeHost root layer"); m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content"); #endif m_rootLayer->addChild(m_nonCompositedContentLayer.get()); m_nonCompositedContentLayer->setNeedsDisplay(); m_layerTreeContext.contextID = m_webPage->nativeWindowHandle(); GLContext* context = glContext(); if (!context) return; // The creation of the TextureMapper needs an active OpenGL context. context->makeContextCurrent(); m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true); toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); // FIXME: Cretae page olverlay layers. https://bugs.webkit.org/show_bug.cgi?id=131433. scheduleLayerFlush(); }
void CoordinatedGraphicsScene::paintToGraphicsContext(PlatformGraphicsContext* platformContext) { if (!m_textureMapper) m_textureMapper = TextureMapper::create(); ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode); syncRemoteContent(); TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); if (!layer) return; GraphicsContext graphicsContext(platformContext); m_textureMapper->setGraphicsContext(&graphicsContext); m_textureMapper->beginPainting(); IntRect clipRect = graphicsContext.clipBounds(); if (m_setDrawsBackground) m_textureMapper->drawSolidColor(clipRect, TransformationMatrix(), m_backgroundColor); layer->paint(); m_fpsCounter.updateFPSAndDisplay(m_textureMapper.get(), clipRect.location()); m_textureMapper->endPainting(); m_textureMapper->setGraphicsContext(0); }
void GraphicsLayerTextureMapper::commitLayerChanges() { if (m_changeMask == NoChanges) return; if (m_changeMask & ChildrenChange) { Vector<TextureMapperLayer*> textureMapperLayerChildren; toTextureMapperLayerVector(children(), textureMapperLayerChildren); m_layer->setChildren(textureMapperLayerChildren); } if (m_changeMask & MaskLayerChange) m_layer->setMaskLayer(toTextureMapperLayer(maskLayer())); if (m_changeMask & ReplicaLayerChange) m_layer->setReplicaLayer(toTextureMapperLayer(replicaLayer())); if (m_changeMask & PositionChange) m_layer->setPosition(position()); if (m_changeMask & AnchorPointChange) m_layer->setAnchorPoint(anchorPoint()); if (m_changeMask & SizeChange) m_layer->setSize(size()); if (m_changeMask & TransformChange) m_layer->setTransform(transform()); if (m_changeMask & ChildrenTransformChange) m_layer->setChildrenTransform(childrenTransform()); if (m_changeMask & Preserves3DChange) m_layer->setPreserves3D(preserves3D()); if (m_changeMask & ContentsRectChange) m_layer->setContentsRect(contentsRect()); if (m_changeMask & MasksToBoundsChange) m_layer->setMasksToBounds(masksToBounds()); if (m_changeMask & DrawsContentChange) m_layer->setDrawsContent(drawsContent()); if (m_changeMask & ContentsVisibleChange) m_layer->setContentsVisible(contentsAreVisible()); if (m_changeMask & ContentsOpaqueChange) m_layer->setContentsOpaque(contentsOpaque()); if (m_changeMask & BackfaceVisibilityChange) m_layer->setBackfaceVisibility(backfaceVisibility()); if (m_changeMask & OpacityChange) m_layer->setOpacity(opacity()); if (m_changeMask & BackgroundColorChange) m_layer->setSolidColor(solidColor()); #if ENABLE(CSS_FILTERS) if (m_changeMask & FilterChange) m_layer->setFilters(filters()); #endif if (m_changeMask & BackingStoreChange) m_layer->setBackingStore(m_backingStore); if (m_changeMask & DebugVisualsChange) m_layer->setDebugVisuals(isShowingDebugBorder(), debugBorderColor(), debugBorderWidth(), isShowingRepaintCounter()); if (m_changeMask & RepaintCountChange) m_layer->setRepaintCount(repaintCount()); if (m_changeMask & ContentChange) m_layer->setContentsLayer(platformLayer()); if (m_changeMask & AnimationChange) m_layer->setAnimations(m_animations); if (m_changeMask & AnimationStarted) client()->notifyAnimationStarted(this, m_animationStartTime); if (m_changeMask & FixedToViewporChange) m_layer->setFixedToViewport(fixedToViewport()); if (m_changeMask & IsScrollableChange) m_layer->setIsScrollable(isScrollable()); if (m_changeMask & CommittedScrollOffsetChange) m_layer->didCommitScrollOffset(m_committedScrollOffset); m_changeMask = NoChanges; }
static void toTextureMapperLayerVector(const Vector<GraphicsLayer*>& layers, Vector<TextureMapperLayer*>& texmapLayers) { texmapLayers.reserveCapacity(layers.size()); for (size_t i = 0; i < layers.size(); ++i) texmapLayers.append(toTextureMapperLayer(layers[i])); }
TextureMapperLayer* TextureMapperLayerClientQt::rootLayer() { return toTextureMapperLayer(m_rootGraphicsLayer.get()); }
void TextureMapperLayer::flushCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper*) { int changeMask = graphicsLayer->changeMask(); if (changeMask == NoChanges && graphicsLayer->m_animations.isEmpty()) return; graphicsLayer->updateDebugIndicators(); if (changeMask & ParentChange) { TextureMapperLayer* newParent = toTextureMapperLayer(graphicsLayer->parent()); if (newParent != m_parent) { // Remove layer from current from child list first. if (m_parent) { size_t index = m_parent->m_children.find(this); m_parent->m_children.remove(index); m_parent = 0; } // Set new layer parent and add layer to the parents child list. if (newParent) { m_parent = newParent; m_parent->m_children.append(this); } } } if (changeMask & ChildrenChange) { // Clear children parent pointer to avoid unsync and crash on layer delete. for (size_t i = 0; i < m_children.size(); i++) m_children[i]->m_parent = 0; m_children.clear(); for (size_t i = 0; i < graphicsLayer->children().size(); ++i) { TextureMapperLayer* child = toTextureMapperLayer(graphicsLayer->children()[i]); if (!child) continue; m_children.append(child); child->m_parent = this; } } m_size = graphicsLayer->size(); if (changeMask & MaskLayerChange) { if (TextureMapperLayer* layer = toTextureMapperLayer(graphicsLayer->maskLayer())) layer->m_effectTarget = this; } if (changeMask & ReplicaLayerChange) { if (TextureMapperLayer* layer = toTextureMapperLayer(graphicsLayer->replicaLayer())) layer->m_effectTarget = this; } if (changeMask & AnimationChange) m_animations = graphicsLayer->m_animations; m_state.maskLayer = toTextureMapperLayer(graphicsLayer->maskLayer()); m_state.replicaLayer = toTextureMapperLayer(graphicsLayer->replicaLayer()); m_state.pos = graphicsLayer->position(); m_state.anchorPoint = graphicsLayer->anchorPoint(); m_state.size = graphicsLayer->size(); m_state.contentsRect = graphicsLayer->contentsRect(); m_state.transform = graphicsLayer->transform(); m_state.contentsRect = graphicsLayer->contentsRect(); m_state.preserves3D = graphicsLayer->preserves3D(); m_state.masksToBounds = graphicsLayer->masksToBounds(); m_state.drawsContent = graphicsLayer->drawsContent(); m_state.contentsVisible = graphicsLayer->contentsAreVisible(); m_state.contentsOpaque = graphicsLayer->contentsOpaque(); m_state.backfaceVisibility = graphicsLayer->backfaceVisibility(); m_state.childrenTransform = graphicsLayer->childrenTransform(); m_state.opacity = graphicsLayer->opacity(); #if ENABLE(CSS_FILTERS) if (changeMask & FilterChange) m_state.filters = graphicsLayer->filters(); #endif m_fixedToViewport = graphicsLayer->fixedToViewport(); m_contentsLayer = graphicsLayer->platformLayer(); m_transform.setPosition(adjustedPosition()); m_transform.setAnchorPoint(m_state.anchorPoint); m_transform.setSize(m_state.size); m_transform.setFlattening(!m_state.preserves3D); m_transform.setChildrenTransform(m_state.childrenTransform); }
TextureMapperLayer* CoordinatedGraphicsScene::findScrollableContentsLayerAt(const FloatPoint& point) { return rootLayer() ? toTextureMapperLayer(rootLayer())->findScrollableContentsLayerAt(point) : 0; }