Bug 1066664. Fix screenshot rotation. r=mwoodrow

This moves the screenshot (now-nonexistent) unrotation code from the opengl
compositor into ClientLayerManager.cpp
This commit is contained in:
Jeff Muizelaar 2014-09-30 16:20:48 -04:00
parent b7f16a9053
commit ef58f4304f
3 changed files with 76 additions and 0 deletions

View File

@ -443,7 +443,17 @@ ClientLayerManager::MakeSnapshotIfRequired()
}
if (mWidget) {
if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
// The compositor doesn't draw to a different sized surface
// when there's a rotation. Instead we rotate the result
// when drawing into dt
nsIntRect outerBounds;
mWidget->GetBounds(outerBounds);
nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
if (mTargetRotation) {
bounds = RotateRect(bounds, outerBounds, mTargetRotation);
}
SurfaceDescriptor inSnapshot;
if (!bounds.IsEmpty() &&
mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
@ -452,11 +462,18 @@ ClientLayerManager::MakeSnapshotIfRequired()
remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
DrawTarget* dt = mShadowTarget->GetDrawTarget();
Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
Rect srcRect(0, 0, bounds.width, bounds.height);
gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds, mTargetRotation);
gfx::Matrix oldMatrix = dt->GetTransform();
dt->SetTransform(oldMatrix * rotate);
dt->DrawSurface(surf, dstRect, srcRect,
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_OVER));
dt->SetTransform(oldMatrix);
}
mForwarder->DestroySharedSurface(&inSnapshot);
}

View File

@ -26,6 +26,13 @@ enum ScreenRotation {
gfx::Matrix ComputeTransformForRotation(const nsIntRect& aBounds,
ScreenRotation aRotation);
gfx::Matrix ComputeTransformForUnRotation(const nsIntRect& aBounds,
ScreenRotation aRotation);
nsIntRect RotateRect(nsIntRect aRect,
const nsIntRect& aBounds,
ScreenRotation aRotation);
} // namespace mozilla
#endif // mozilla_WidgetUtils_h

View File

@ -37,4 +37,56 @@ ComputeTransformForRotation(const nsIntRect& aBounds,
return transform;
}
gfx::Matrix
ComputeTransformForUnRotation(const nsIntRect& aBounds,
ScreenRotation aRotation)
{
gfx::Matrix transform;
static const gfx::Float floatPi = static_cast<gfx::Float>(M_PI);
switch (aRotation) {
case ROTATION_0:
break;
case ROTATION_90:
transform.PreTranslate(0, aBounds.height);
transform.PreRotate(floatPi * 3 / 2);
break;
case ROTATION_180:
transform.PreTranslate(aBounds.width, aBounds.height);
transform.PreRotate(floatPi);
break;
case ROTATION_270:
transform.PreTranslate(aBounds.width, 0);
transform.PreRotate(floatPi / 2);
break;
default:
MOZ_CRASH("Unknown rotation");
}
return transform;
}
nsIntRect RotateRect(nsIntRect aRect,
const nsIntRect& aBounds,
ScreenRotation aRotation)
{
switch (aRotation) {
case ROTATION_0:
return aRect;
case ROTATION_90:
return nsIntRect(aRect.y,
aBounds.width - aRect.x - aRect.width,
aRect.height, aRect.width);
case ROTATION_180:
return nsIntRect(aBounds.width - aRect.x - aRect.width,
aBounds.height - aRect.y - aRect.height,
aRect.width, aRect.height);
case ROTATION_270:
return nsIntRect(aBounds.height - aRect.y - aRect.height,
aRect.x,
aRect.height, aRect.width);
default:
MOZ_CRASH("Unknown rotation");
return aRect;
}
}
} // namespace mozilla