📄 renderlayerbacking.cpp
字号:
FloatPoint dirtyOrigin = contentsToGraphicsLayerCoordinates(m_graphicsLayer, FloatPoint(r.x(), r.y())); FloatRect dirtyRect(dirtyOrigin, r.size()); FloatRect bounds(FloatPoint(), m_graphicsLayer->size()); if (bounds.intersects(dirtyRect)) m_graphicsLayer->setNeedsDisplayInRect(dirtyRect); } if (m_contentsLayer) { // FIXME: do incremental repaint m_contentsLayer->setNeedsDisplay(); }}static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect){ if (paintDirtyRect == clipRect) return; p->save(); p->clip(clipRect);}static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect){ if (paintDirtyRect == clipRect) return; p->restore();}// Share this with RenderLayer::paintLayer, which would have to be educated about GraphicsLayerPaintingPhase?void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context, const IntRect& paintDirtyRect, // in the coords of rootLayer bool haveTransparency, PaintRestriction paintRestriction, GraphicsLayerPaintingPhase paintingPhase, RenderObject* paintingRoot){ if (paintingGoesToWindow()) { ASSERT_NOT_REACHED(); return; } m_owningLayer->updateLayerListsIfNeeded(); // Calculate the clip rects we should use. IntRect layerBounds, damageRect, clipRectToApply, outlineRect; m_owningLayer->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect); int x = layerBounds.x(); // layerBounds is computed relative to rootLayer int y = layerBounds.y(); int tx = x - m_owningLayer->renderBoxX(); int ty = y - m_owningLayer->renderBoxY(); // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set). // Else, our renderer tree may or may not contain the painting root, so we pass that root along // so it will be tested against as we decend through the renderers. RenderObject *paintingRootForRenderer = 0; if (paintingRoot && !renderer()->isDescendantOf(paintingRoot)) paintingRootForRenderer = paintingRoot; if (paintingPhase & GraphicsLayerPaintBackgroundMask) { // If this is the root then we need to send in a bigger bounding box // because we'll be painting the background as well (see RenderBox::paintRootBoxDecorations()). IntRect paintBox = clipRectToApply; // FIXME: do we need this code? if (renderer()->node()->isDocumentNode() && renderer()->document()->isHTMLDocument()) { RenderBox* box = toRenderBox(renderer()); int w = box->width(); int h = box->height(); int rw; int rh; if (box->view()->frameView()) { rw = box->view()->frameView()->contentsWidth(); rh = box->view()->frameView()->contentsHeight(); } else { rw = box->view()->width(); rh = box->view()->height(); } int bx = tx - box->marginLeft(); int by = ty - box->marginTop(); int bw = max(w + box->marginLeft() + box->marginRight() + box->borderLeft() + box->borderRight(), rw); int bh = max(h + box->marginTop() + box->marginBottom() + box->borderTop() + box->borderBottom(), rh); paintBox = IntRect(bx, by, bw, bh); } // Paint our background first, before painting any child layers. // Establish the clip used to paint our background. setClip(context, paintDirtyRect, damageRect); RenderObject::PaintInfo info(context, paintBox, PaintPhaseBlockBackground, false, paintingRootForRenderer, 0); renderer()->paint(info, tx, ty); // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with // z-index. We paint after we painted the background/border, so that the scrollbars will // sit above the background/border. m_owningLayer->paintOverflowControls(context, x, y, damageRect); // Restore the clip. restoreClip(context, paintDirtyRect, damageRect); } if (paintingPhase & GraphicsLayerPaintForegroundMask) { // Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint. // FIXME: should these be painted as background? Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList(); if (negZOrderList) { for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) it[0]->paintLayer(rootLayer, context, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot); } bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText; bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText; // Set up the clip used when painting our children. setClip(context, paintDirtyRect, clipRectToApply); RenderObject::PaintInfo paintInfo(context, clipRectToApply, selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, forceBlackText, paintingRootForRenderer, 0); renderer()->paint(paintInfo, tx, ty); if (!selectionOnly) { paintInfo.phase = PaintPhaseFloat; renderer()->paint(paintInfo, tx, ty); paintInfo.phase = PaintPhaseForeground; renderer()->paint(paintInfo, tx, ty); paintInfo.phase = PaintPhaseChildOutlines; renderer()->paint(paintInfo, tx, ty); } // Now restore our clip. restoreClip(context, paintDirtyRect, clipRectToApply); if (!outlineRect.isEmpty()) { // Paint our own outline RenderObject::PaintInfo paintInfo(context, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0); setClip(context, paintDirtyRect, outlineRect); renderer()->paint(paintInfo, tx, ty); restoreClip(context, paintDirtyRect, outlineRect); } // Paint any child layers that have overflow. Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList(); if (normalFlowList) { for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) it[0]->paintLayer(rootLayer, context, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot); } // Now walk the sorted list of children with positive z-indices. Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList(); if (posZOrderList) { for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) it[0]->paintLayer(rootLayer, context, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot); } if (renderer()->hasMask() && !selectionOnly && !damageRect.isEmpty()) { setClip(context, paintDirtyRect, damageRect); // Paint the mask. RenderObject::PaintInfo paintInfo(context, damageRect, PaintPhaseMask, false, paintingRootForRenderer, 0); renderer()->paint(paintInfo, tx, ty); // Restore the clip. restoreClip(context, paintDirtyRect, damageRect); } } ASSERT(!m_owningLayer->m_usedTransparency);}// Up-call from compositing layer drawing callback.void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase drawingPhase, const IntRect& clip){ // We have to use the same root as for hit testing, because both methods // can compute and cache clipRects. IntRect enclosingBBox = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); IntRect clipRect(clip); // Set up the coordinate space to be in the layer's rendering coordinates. context.translate(-enclosingBBox.x(), -enclosingBBox.y()); // Offset the clip. clipRect.move(enclosingBBox.x(), enclosingBBox.y()); // The dirtyRect is in the coords of the painting root. IntRect dirtyRect = enclosingBBox; dirtyRect.intersect(clipRect); paintIntoLayer(m_owningLayer, &context, dirtyRect, false, PaintRestrictionNone, drawingPhase, renderer());}bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes){ bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity); bool hasTransform = keyframes.containsProperty(CSSPropertyWebkitTransform); if (!hasOpacity && !hasTransform) return false; GraphicsLayer::TransformValueList transformVector; GraphicsLayer::FloatValueList opacityVector; for (Vector<KeyframeValue>::const_iterator it = keyframes.beginKeyframes(); it != keyframes.endKeyframes(); ++it) { const RenderStyle* keyframeStyle = it->style(); float key = it->key(); if (!keyframeStyle) continue; // get timing function const TimingFunction* tf = keyframeStyle->hasAnimations() ? &((*keyframeStyle->animations()).animation(0)->timingFunction()) : 0; if (hasTransform) transformVector.insert(key, &(keyframeStyle->transform()), tf); if (hasOpacity) opacityVector.insert(key, keyframeStyle->opacity(), tf); } bool didAnimateTransform = !hasTransform; bool didAnimateOpacity = !hasOpacity; if (hasTransform && m_graphicsLayer->animateTransform(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, beginTime, false)) didAnimateTransform = true; if (hasOpacity && m_graphicsLayer->animateFloat(AnimatedPropertyOpacity, opacityVector, anim, beginTime)) didAnimateOpacity = true; return didAnimateTransform && didAnimateOpacity;}bool RenderLayerBacking::startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle){ bool didAnimate = false; ASSERT(property != cAnimateAll); if (property == (int)CSSPropertyOpacity) { const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity); if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) { // If beginTime is not 0, we are restarting this transition, so first set the from value // in case it was smashed by a previous animation. if (beginTime > 0) m_graphicsLayer->setOpacity(compositingOpacity(fromStyle->opacity()), 0, 0); if (m_graphicsLayer->setOpacity(compositingOpacity(toStyle->opacity()), opacityAnim, beginTime)) didAnimate = true; } } if (property == (int)CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) { // We get a TransformOperation, which is a linked list of primitive operations and their arguments. // Arguments can be floats or Length values, which need to be converted to numbers using // val.calcFloatValue(renderer()->width()) (or height()). const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform); if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) { GraphicsLayer::TransformValueList transformVector; transformVector.insert(0, &fromStyle->transform(), 0); transformVector.insert(1, &toStyle->transform(), 0); if (m_graphicsLayer->animateTransform(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, beginTime, true)) didAnimate = true; } } return didAnimate;}void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time){ renderer()->animation()->notifyAnimationStarted(renderer(), time);}void RenderLayerBacking::animationFinished(const String& name, int index, bool reset){ m_graphicsLayer->removeFinishedAnimations(name, index, reset);}void RenderLayerBacking::transitionFinished(int property){ AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property); if (animatedProperty != AnimatedPropertyInvalid) m_graphicsLayer->removeFinishedTransitions(animatedProperty);}void RenderLayerBacking::suspendAnimations(){ m_graphicsLayer->suspendAnimations();}void RenderLayerBacking::resumeAnimations(){ m_graphicsLayer->resumeAnimations();}int RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property){ int cssProperty = CSSPropertyInvalid; switch (property) { case AnimatedPropertyWebkitTransform: cssProperty = CSSPropertyWebkitTransform; break; case AnimatedPropertyOpacity: cssProperty = CSSPropertyOpacity; break; case AnimatedPropertyBackgroundColor: cssProperty = CSSPropertyBackgroundColor; break; case AnimatedPropertyInvalid: ASSERT_NOT_REACHED(); } return cssProperty;}AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(int cssProperty){ switch (cssProperty) { case CSSPropertyWebkitTransform: return AnimatedPropertyWebkitTransform; case CSSPropertyOpacity: return AnimatedPropertyOpacity; case CSSPropertyBackgroundColor: return AnimatedPropertyBackgroundColor; // It's fine if we see other css properties here; they are just not accelerated. } return AnimatedPropertyInvalid;}} // namespace WebCore#endif // USE(ACCELERATED_COMPOSITING)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -