mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 992486 - Part 2: Make ContentHostSingleBuffered able to handle updates that cross the rotation boundary. r=nical
This commit is contained in:
parent
031f178fa9
commit
0a23f9d8f6
@ -284,6 +284,16 @@ ContentHostTexture::Dump(FILE* aFile,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
AddWrappedRegion(const nsIntRegion& aInput, nsIntRegion& aOutput,
|
||||||
|
const nsIntSize& aSize, const nsIntPoint& aShift)
|
||||||
|
{
|
||||||
|
nsIntRegion tempRegion;
|
||||||
|
tempRegion.And(nsIntRect(aShift, aSize), aInput);
|
||||||
|
tempRegion.MoveBy(-aShift);
|
||||||
|
aOutput.Or(aOutput, tempRegion);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
|
ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
|
||||||
const nsIntRegion& aUpdated,
|
const nsIntRegion& aUpdated,
|
||||||
@ -301,26 +311,38 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
|
|||||||
nsIntRegion destRegion(aUpdated);
|
nsIntRegion destRegion(aUpdated);
|
||||||
destRegion.MoveBy(-aData.rect().TopLeft());
|
destRegion.MoveBy(-aData.rect().TopLeft());
|
||||||
|
|
||||||
// Correct for rotation
|
if (!aData.rect().Contains(aUpdated.GetBounds()) ||
|
||||||
destRegion.MoveBy(aData.rotation());
|
aData.rotation().x > aData.rect().width ||
|
||||||
|
aData.rotation().y > aData.rect().height) {
|
||||||
IntSize size = aData.rect().Size().ToIntSize();
|
NS_ERROR("Invalid update data");
|
||||||
nsIntRect destBounds = destRegion.GetBounds();
|
|
||||||
destRegion.MoveBy((destBounds.x >= size.width) ? -size.width : 0,
|
|
||||||
(destBounds.y >= size.height) ? -size.height : 0);
|
|
||||||
|
|
||||||
// We can get arbitrary bad regions from an untrusted client,
|
|
||||||
// which we need to be resilient to. See bug 967330.
|
|
||||||
if((destBounds.x % size.width) + destBounds.width > size.width ||
|
|
||||||
(destBounds.y % size.height) + destBounds.height > size.height)
|
|
||||||
{
|
|
||||||
NS_ERROR("updated region lies across rotation boundaries!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTextureHost->Updated(&destRegion);
|
// destRegion is now in logical coordinates relative to the buffer, but we
|
||||||
|
// need to account for rotation. We do that by moving the region to the
|
||||||
|
// rotation offset and then wrapping any pixels that extend off the
|
||||||
|
// bottom/right edges.
|
||||||
|
|
||||||
|
// Shift to the rotation point
|
||||||
|
destRegion.MoveBy(aData.rotation());
|
||||||
|
|
||||||
|
nsIntSize bufferSize = aData.rect().Size();
|
||||||
|
|
||||||
|
// Select only the pixels that are still within the buffer.
|
||||||
|
nsIntRegion finalRegion;
|
||||||
|
finalRegion.And(nsIntRect(nsIntPoint(), bufferSize), destRegion);
|
||||||
|
|
||||||
|
// For each of the overlap areas (right, bottom-right, bottom), select those
|
||||||
|
// pixels and wrap them around to the opposite edge of the buffer rect.
|
||||||
|
AddWrappedRegion(destRegion, finalRegion, bufferSize, nsIntPoint(aData.rect().width, 0));
|
||||||
|
AddWrappedRegion(destRegion, finalRegion, bufferSize, nsIntPoint(aData.rect().width, aData.rect().height));
|
||||||
|
AddWrappedRegion(destRegion, finalRegion, bufferSize, nsIntPoint(0, aData.rect().height));
|
||||||
|
|
||||||
|
MOZ_ASSERT(nsIntRect(0, 0, aData.rect().width, aData.rect().height).Contains(finalRegion.GetBounds()));
|
||||||
|
|
||||||
|
mTextureHost->Updated(&finalRegion);
|
||||||
if (mTextureHostOnWhite) {
|
if (mTextureHostOnWhite) {
|
||||||
mTextureHostOnWhite->Updated(&destRegion);
|
mTextureHostOnWhite->Updated(&finalRegion);
|
||||||
}
|
}
|
||||||
mInitialised = true;
|
mInitialised = true;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user