This source file includes following definitions.
- m_repaintStatus
- repaintAfterLayout
- clearRepaintRects
- computeRepaintRects
- computeRepaintRectsIncludingDescendants
- shouldRepaintLayer
- repaintIncludingNonCompositingDescendants
- repaintRectIncludingNonCompositingDescendants
- setBackingNeedsRepaint
- setBackingNeedsRepaintInRect
- repaintIncludingDescendants
- setFilterBackendNeedsRepaintingInRect
- enclosingFilterRepaintLayer
#include "config.h"
#include "core/rendering/RenderLayerRepainter.h"
#include "core/rendering/FilterEffectRenderer.h"
#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/compositing/CompositedLayerMapping.h"
namespace WebCore {
RenderLayerRepainter::RenderLayerRepainter(RenderLayerModelObject* renderer)
: m_renderer(renderer)
, m_repaintStatus(NeedsNormalRepaint)
{
}
void RenderLayerRepainter::repaintAfterLayout(RenderGeometryMap* geometryMap, bool shouldCheckForRepaint)
{
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
return;
DisableCompositingQueryAsserts disabler;
if (m_renderer->layer()->hasVisibleContent()) {
RenderView* view = m_renderer->view();
ASSERT(view);
ASSERT(!view->layoutStateEnabled());
RenderLayerModelObject* repaintContainer = m_renderer->containerForRepaint();
LayoutRect oldRepaintRect = m_repaintRect;
computeRepaintRects(repaintContainer, geometryMap);
shouldCheckForRepaint &= shouldRepaintLayer();
if (shouldCheckForRepaint) {
if (view && !view->document().printing()) {
if (m_repaintStatus & NeedsFullRepaint) {
m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldRepaintRect), InvalidationLayer);
if (m_repaintRect != oldRepaintRect)
m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect), InvalidationLayer);
} else {
m_renderer->repaintAfterLayoutIfNeeded(repaintContainer, m_renderer->selfNeedsLayout(), oldRepaintRect, &m_repaintRect);
}
}
}
} else {
clearRepaintRects();
}
m_repaintStatus = NeedsNormalRepaint;
}
void RenderLayerRepainter::clearRepaintRects()
{
ASSERT(!m_renderer->layer()->hasVisibleContent());
m_repaintRect = IntRect();
}
void RenderLayerRepainter::computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
{
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
return;
m_repaintRect = m_renderer->clippedOverflowRectForRepaint(repaintContainer);
}
void RenderLayerRepainter::computeRepaintRectsIncludingDescendants()
{
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
LayoutRectRecorder recorder(*m_renderer);
} else {
computeRepaintRects(m_renderer->containerForRepaint());
}
for (RenderLayer* layer = m_renderer->layer()->firstChild(); layer; layer = layer->nextSibling())
layer->repainter().computeRepaintRectsIncludingDescendants();
}
inline bool RenderLayerRepainter::shouldRepaintLayer() const
{
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
return false;
if (m_repaintStatus != NeedsFullRepaintForPositionedMovementLayout)
return true;
return m_renderer->compositingState() != PaintsIntoOwnBacking;
}
void RenderLayerRepainter::repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer)
{
m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_renderer->clippedOverflowRectForRepaint(repaintContainer)), InvalidationLayer);
for (RenderLayer* curr = m_renderer->layer()->firstChild(); curr; curr = curr->nextSibling()) {
if (!curr->hasCompositedLayerMapping())
curr->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
}
}
LayoutRect RenderLayerRepainter::repaintRectIncludingNonCompositingDescendants() const
{
LayoutRect repaintRect;
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
repaintRect = m_renderer->newRepaintRect();
else
repaintRect = m_repaintRect;
for (RenderLayer* child = m_renderer->layer()->firstChild(); child; child = child->nextSibling()) {
if (child->hasCompositedLayerMapping())
continue;
repaintRect.unite(child->repainter().repaintRectIncludingNonCompositingDescendants());
}
return repaintRect;
}
void RenderLayerRepainter::setBackingNeedsRepaint()
{
ASSERT(m_renderer->compositingState() != NotComposited);
if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplay();
} else {
m_renderer->compositedLayerMapping()->setContentsNeedDisplay();
}
}
void RenderLayerRepainter::setBackingNeedsRepaintInRect(const LayoutRect& r)
{
ASSERT(m_renderer->compositingState() != NotComposited);
if (m_renderer->compositingState() == NotComposited) {
LayoutRect absRect(r);
LayoutPoint delta;
m_renderer->layer()->convertToLayerCoords(m_renderer->layer()->root(), delta);
absRect.moveBy(delta);
RenderView* view = m_renderer->view();
if (view)
view->repaintViewRectangle(absRect);
} else {
if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
IntRect offsetRect = pixelSnappedIntRect(r);
if (m_renderer->hasTransform())
offsetRect = m_renderer->layer()->transform()->mapRect(pixelSnappedIntRect(r));
offsetRect.move(-m_renderer->layer()->offsetFromSquashingLayerOrigin());
m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(offsetRect);
} else {
IntRect repaintRect = pixelSnappedIntRect(r.location() + m_renderer->layer()->subpixelAccumulation(), r.size());
m_renderer->compositedLayerMapping()->setContentsNeedDisplayInRect(repaintRect);
}
}
}
void RenderLayerRepainter::repaintIncludingDescendants()
{
m_renderer->repaint();
for (RenderLayer* curr = m_renderer->layer()->firstChild(); curr; curr = curr->nextSibling())
curr->repainter().repaintIncludingDescendants();
}
void RenderLayerRepainter::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
{
if (rect.isEmpty())
return;
LayoutRect rectForRepaint = rect;
m_renderer->style()->filterOutsets().expandRect(rectForRepaint);
RenderLayerFilterInfo* filterInfo = m_renderer->layer()->filterInfo();
ASSERT(filterInfo);
filterInfo->expandDirtySourceRect(rectForRepaint);
ASSERT(filterInfo->renderer());
if (filterInfo->renderer()->hasCustomShaderFilter()) {
rectForRepaint.unite(m_renderer->layer()->calculateLayerBounds(m_renderer->layer()));
}
RenderLayer* parentLayer = enclosingFilterRepaintLayer();
ASSERT(parentLayer);
FloatQuad repaintQuad(rectForRepaint);
LayoutRect parentLayerRect = m_renderer->localToContainerQuad(repaintQuad, parentLayer->renderer()).enclosingBoundingBox();
if (parentLayer->hasCompositedLayerMapping()) {
parentLayer->repainter().setBackingNeedsRepaintInRect(parentLayerRect);
return;
}
if (parentLayer->paintsWithFilters()) {
parentLayer->repainter().setFilterBackendNeedsRepaintingInRect(parentLayerRect);
return;
}
if (parentLayer->isRootLayer()) {
RenderView* view = toRenderView(parentLayer->renderer());
view->repaintViewRectangle(parentLayerRect);
return;
}
ASSERT_NOT_REACHED();
}
RenderLayer* RenderLayerRepainter::enclosingFilterRepaintLayer() const
{
for (const RenderLayer* curr = m_renderer->layer(); curr; curr = curr->parent()) {
if ((curr != m_renderer->layer() && curr->requiresFullLayerImageForFilters()) || curr->compositingState() == PaintsIntoOwnBacking || curr->isRootLayer())
return const_cast<RenderLayer*>(curr);
}
return 0;
}
}