void TextureMapperNode::syncCompositingStateInternal(GraphicsLayerTextureMapper* graphicsLayer, bool recurse, TextureMapper* textureMapper) { syncCompositingStateSelf(graphicsLayer, textureMapper); graphicsLayer->didSynchronize(); if (m_state.maskLayer) { m_state.maskLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), false, textureMapper); if (m_state.maskLayer->m_size.isEmpty()) m_state.maskLayer->m_size = m_size; } if (m_state.replicaLayer) m_state.replicaLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), false, textureMapper); if (m_state.dirty) uploadTextureFromContent(textureMapper, m_state.visibleRect, graphicsLayer); m_currentContent.needsDisplayRect = IntRect(); m_currentContent.needsDisplay = false; if (!recurse) return; Vector<GraphicsLayer*> children = graphicsLayer->children(); for (int i = children.size() - 1; i >= 0; --i) { TextureMapperNode* node = toTextureMapperNode(children[i]); if (!node) continue; node->syncCompositingStateInternal(toGraphicsLayerTextureMapper(children[i]), true, textureMapper); } }
void LayerTreeHostProxy::assignImageToLayer(GraphicsLayer* layer, int64_t imageID) { TextureMapperNode* node = toTextureMapperNode(layer); if (!node) return; if (!imageID) { node->clearAllDirectlyCompositedImageTiles(); return; } FloatSize size(layer->size()); FloatRect contentsRect(layer->contentsRect()); float horizontalFactor = contentsRect.width() / size.width(); float verticalFactor = contentsRect.height() / size.height(); HashMap<int64_t, TiledImage>::iterator it = m_directlyCompositedImages.find(imageID); if (it == m_directlyCompositedImages.end()) return; TiledImage::iterator endTileIterator = it->second.end(); for (TiledImage::iterator tileIt = it->second.begin(); tileIt != endTileIterator; ++tileIt) { FloatRect sourceRect(FloatPoint(tileIt->first), FloatSize(tileIt->second->size())); FloatRect targetRect(sourceRect.x() * horizontalFactor + contentsRect.x(), sourceRect.y() * verticalFactor + contentsRect.y(), sourceRect.width() * horizontalFactor, sourceRect.height() * verticalFactor); int newTileID = node->createContentsTile(1.0); node->setTileBackBufferTextureForDirectlyCompositedImage(newTileID, IntRect(sourceRect), targetRect, tileIt->second.get()); } }
void LayerTreeHostProxy::createTile(WebLayerID layerID, int tileID, float scale) { ensureLayer(layerID); TextureMapperNode* node = toTextureMapperNode(layerByID(layerID)); int nodeTileID = node->createContentsTile(scale); m_tileToNodeTile.add(tileID, nodeTileID); }
PassOwnPtr<GraphicsLayer> LayerTreeHostProxy::createLayer(WebLayerID layerID) { GraphicsLayer* newLayer = new GraphicsLayerTextureMapper(this); TextureMapperNode* node = toTextureMapperNode(newLayer); node->setID(layerID); node->setTileOwnership(TextureMapperNode::ExternallyManagedTiles); return adoptPtr(newLayer); }
void LayerTreeHostProxy::removeTile(WebLayerID layerID, int tileID) { TextureMapperNode* node = toTextureMapperNode(layerByID(layerID)); if (!node) return; int nodeTileID = remoteTileIDToNodeTileID(tileID); if (!nodeTileID) return; node->removeContentsTile(nodeTileID); m_tileToNodeTile.remove(tileID); }
void LayerTreeHostProxy::ensureRootLayer() { if (m_rootLayer) return; m_rootLayer = createLayer(InvalidWebLayerID); 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)); m_textureMapper = TextureMapperGL::create(); toTextureMapperNode(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); }
// This function needs to be reentrant. void LayerTreeHostProxy::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity) { if (!m_textureMapper) m_textureMapper = TextureMapperGL::create(); syncRemoteContent(); GraphicsLayer* currentRootLayer = rootLayer(); if (!currentRootLayer) return; TextureMapperNode* node = toTextureMapperNode(currentRootLayer); if (!node) return; GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); IntRect viewportRect(viewport[0], viewport[1], viewport[2], viewport[3]); m_textureMapper->setViewportSize(IntSize(viewport[2], viewport[3])); node->setTextureMapper(m_textureMapper.get()); m_textureMapper->beginPainting(); m_textureMapper->bindSurface(0); if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) { currentRootLayer->setOpacity(opacity); currentRootLayer->setTransform(matrix); currentRootLayer->syncCompositingStateForThisLayerOnly(); } TextureMapperNode::NodeRectMap nodeVisualContentsRectMap; if (node->collectVisibleContentsRects(nodeVisualContentsRectMap, viewportRect)) { TextureMapperNode::NodeRectMap::iterator endIterator = nodeVisualContentsRectMap.end(); for (TextureMapperNode::NodeRectMap::iterator it = nodeVisualContentsRectMap.begin(); it != endIterator; ++it) { WebLayerID layerID = it->first->id(); // avoid updating non-synced root layer if (!layerID) continue; IntRect visibleRect = IntRect(it->second); setVisibleContentsRectForLayer(layerID, visibleRect); } } node->paint(); m_textureMapper->endPainting(); if (node->descendantsOrSelfHaveRunningAnimations()) { node->syncAnimationsRecursively(); m_viewportUpdateTimer.startOneShot(0); } }
void LayerTreeHostProxy::updateTile(WebLayerID layerID, int tileID, const IntRect& sourceRect, const IntRect& targetRect, const QImage& image) { ensureLayer(layerID); TextureMapperNode* node = toTextureMapperNode(layerByID(layerID)); if (!node) return; int nodeTileID = remoteTileIDToNodeTileID(tileID); if (!nodeTileID) return; QImage imageRef(image); node->setTextureMapper(m_textureMapper.get()); node->setContentsTileBackBuffer(nodeTileID, sourceRect, targetRect, imageRef.bits(), BitmapTexture::BGRAFormat); }
TextureMapperNode* TextureMapperNodeClientQt::rootNode() { return toTextureMapperNode(m_rootGraphicsLayer.get()); }
void TextureMapperNode::syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper) { const int changeMask = graphicsLayer->changeMask(); initializeTextureMapper(textureMapper); const TextureMapperNode::ContentData& pendingContent = graphicsLayer->pendingContent(); if (changeMask == NoChanges && pendingContent.needsDisplayRect.isEmpty() && !pendingContent.needsDisplay) return; setNeedsDisplay(); if (m_parent) m_parent->m_state.dirty = true; if (m_currentContent.contentType == HTMLContentType && (changeMask & ParentChange)) { // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't // try to snatch that ownership. if (!graphicsLayer->parent()) m_parent = 0; else m_parent = toTextureMapperNode(graphicsLayer->parent()); if (!graphicsLayer->parent() && m_parent) { size_t index = m_parent->m_children.find(this); m_parent->m_children.remove(index); } } if (changeMask & ChildrenChange) { m_children.clear(); for (size_t i = 0; i < graphicsLayer->children().size(); ++i) { if (TextureMapperNode* child = toTextureMapperNode(graphicsLayer->children()[i])) { if (!child) continue; m_children.append(child); child->m_parent = this; } } m_state.dirty = true; } if (changeMask & (SizeChange | ContentsRectChange)) { IntSize wantedSize = IntSize(graphicsLayer->size().width(), graphicsLayer->size().height()); if (wantedSize.isEmpty() && pendingContent.contentType == HTMLContentType) wantedSize = IntSize(graphicsLayer->contentsRect().width(), graphicsLayer->contentsRect().height()); if (wantedSize != m_size) { m_size = IntSize(wantedSize.width(), wantedSize.height()); if (m_platformClient) m_platformClient->setSizeChanged(m_size); const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000; if (m_state.tiled != needsTiling) m_state.tiled = needsTiling; m_state.dirty = true; } } if (changeMask & MaskLayerChange) { if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->maskLayer())) layer->m_effectTarget = this; } if (changeMask & ReplicaLayerChange) { if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->replicaLayer())) layer->m_effectTarget = this; } if (changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange)) m_transforms.localDirty = true; if (changeMask & (ChildrenTransformChange | SizeChange)) m_transforms.perspectiveDirty = true; if (changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange)) { // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms, // all these elements affect the transforms of all the descendants. invalidateTransform(); } if (changeMask & DisplayChange) m_state.dirty = true; m_state.maskLayer = toTextureMapperNode(graphicsLayer->maskLayer()); m_state.replicaLayer = toTextureMapperNode(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.opacity = graphicsLayer->opacity(); m_state.contentsRect = graphicsLayer->contentsRect(); m_state.preserves3D = graphicsLayer->preserves3D(); m_state.masksToBounds = graphicsLayer->masksToBounds(); m_state.drawsContent = graphicsLayer->drawsContent(); m_state.contentsOpaque = graphicsLayer->contentsOpaque(); m_state.backfaceVisibility = graphicsLayer->backfaceVisibility(); m_state.childrenTransform = graphicsLayer->childrenTransform(); m_currentContent.contentType = pendingContent.contentType; m_currentContent.image = pendingContent.image; m_currentContent.media = pendingContent.media; m_currentContent.backgroundColor = pendingContent.backgroundColor; m_currentContent.needsDisplay = m_currentContent.needsDisplay || pendingContent.needsDisplay; m_currentContent.needsDisplayRect.unite(pendingContent.needsDisplayRect); }