Bug 1097464 - Part 6: Handle preserves-3d by compositor. r=roc
Remove WrapPreserve3DList() and replaced it by creating a nsDisplayTransform item for each transformed frame. - Add an additional item for each top frame extending 3D context to separate consequence contexts. - Effective transform of a layer is the accumulation of ancestors in the same 3D context. - The layers creating new context and extended by children need a temporary buffer if it's effective transform is not 2D. - Clip rects are accumulated along the context chain. - Visible rects of items are computed from dirty regions of the frame creating the context and accumulated transforms. - Bounds of items are computed from accumulated transforms and accumulated bounds of the descent frames. - Backface hidden is handled by compositor and BasicLayerManager.
This commit is contained in:
@@ -811,7 +811,15 @@ BasicLayerManager::PaintSelfOrChildren(PaintLayerContext& aPaintContext,
|
||||
nsAutoTArray<Layer*, 12> children;
|
||||
container->SortChildrenBy3DZOrder(children);
|
||||
for (uint32_t i = 0; i < children.Length(); i++) {
|
||||
PaintLayer(aGroupTarget, children.ElementAt(i), aPaintContext.mCallback,
|
||||
Layer* layer = children.ElementAt(i);
|
||||
if (layer->IsBackfaceHidden()) {
|
||||
continue;
|
||||
}
|
||||
if (!layer->AsContainerLayer() && !layer->IsVisible()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PaintLayer(aGroupTarget, layer, aPaintContext.mCallback,
|
||||
aPaintContext.mCallbackData);
|
||||
if (mTransactionIncomplete)
|
||||
break;
|
||||
@@ -845,6 +853,41 @@ BasicLayerManager::FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipT
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the clip applied to the layer on the given gfxContext. The
|
||||
* given gfxContext is the buffer that the layer will be painted to.
|
||||
*/
|
||||
static void
|
||||
InstallLayerClipPreserves3D(gfxContext* aTarget, Layer* aLayer)
|
||||
{
|
||||
const Maybe<ParentLayerIntRect> &clipRect = aLayer->GetEffectiveClipRect();
|
||||
|
||||
if (!clipRect) {
|
||||
return;
|
||||
}
|
||||
|
||||
Layer* parent = aLayer->GetParent();
|
||||
Matrix4x4 transform3d =
|
||||
parent && parent->Extend3DContext() ?
|
||||
parent->GetEffectiveTransform() :
|
||||
Matrix4x4();
|
||||
Matrix transform;
|
||||
if (!transform3d.CanDraw2D(&transform)) {
|
||||
MOZ_CRASH("We should not have a 3D transform that CanDraw2D() is false!");
|
||||
return;
|
||||
}
|
||||
gfxMatrix oldTransform = aTarget->CurrentMatrix();
|
||||
transform *= ToMatrix(oldTransform);
|
||||
aTarget->SetMatrix(ThebesMatrix(transform));
|
||||
|
||||
aTarget->NewPath();
|
||||
aTarget->SnappedRectangle(gfxRect(clipRect->x, clipRect->y,
|
||||
clipRect->width, clipRect->height));
|
||||
aTarget->Clip();
|
||||
|
||||
aTarget->SetMatrix(oldTransform);
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
Layer* aLayer,
|
||||
@@ -884,17 +927,24 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
gfxMatrix transform;
|
||||
// Will return an identity matrix for 3d transforms, and is handled separately below.
|
||||
bool is2D = paintLayerContext.Setup2DTransform();
|
||||
MOZ_ASSERT(is2D || needsGroup || !container, "Must PushGroup for 3d transforms!");
|
||||
MOZ_ASSERT(is2D || needsGroup || !container ||
|
||||
container->Extend3DContext() ||
|
||||
container->Is3DContextLeaf(),
|
||||
"Must PushGroup for 3d transforms!");
|
||||
|
||||
Layer* parent = aLayer->GetParent();
|
||||
bool inPreserves3DChain = parent && parent->Extend3DContext();
|
||||
bool needsSaveRestore =
|
||||
needsGroup || clipRect || needsClipToVisibleRegion || !is2D;
|
||||
needsGroup || clipRect || needsClipToVisibleRegion || !is2D ||
|
||||
inPreserves3DChain;
|
||||
if (needsSaveRestore) {
|
||||
contextSR.SetContext(aTarget);
|
||||
|
||||
if (clipRect) {
|
||||
aTarget->NewPath();
|
||||
aTarget->SnappedRectangle(gfxRect(clipRect->x, clipRect->y, clipRect->width, clipRect->height));
|
||||
aTarget->Clip();
|
||||
// The clips on ancestors on the preserved3d chain should be
|
||||
// installed on the aTarget before painting the layer.
|
||||
InstallLayerClipPreserves3D(aTarget, aLayer);
|
||||
for (Layer* l = parent; l && l->Extend3DContext(); l = l->GetParent()) {
|
||||
InstallLayerClipPreserves3D(aTarget, l);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,6 +979,11 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
PaintSelfOrChildren(paintLayerContext, aTarget);
|
||||
}
|
||||
} else {
|
||||
if (!needsGroup && container) {
|
||||
PaintSelfOrChildren(paintLayerContext, aTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
const IntRect& bounds = visibleRegion.GetBounds();
|
||||
RefPtr<DrawTarget> untransformedDT =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(bounds.width, bounds.height),
|
||||
|
||||
Reference in New Issue
Block a user