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
|
||||
|
||||
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
|
||||
ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
|
||||
const nsIntRegion& aUpdated,
|
||||
@ -301,26 +311,38 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
|
||||
nsIntRegion destRegion(aUpdated);
|
||||
destRegion.MoveBy(-aData.rect().TopLeft());
|
||||
|
||||
// Correct for rotation
|
||||
destRegion.MoveBy(aData.rotation());
|
||||
|
||||
IntSize size = aData.rect().Size().ToIntSize();
|
||||
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!");
|
||||
if (!aData.rect().Contains(aUpdated.GetBounds()) ||
|
||||
aData.rotation().x > aData.rect().width ||
|
||||
aData.rotation().y > aData.rect().height) {
|
||||
NS_ERROR("Invalid update data");
|
||||
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) {
|
||||
mTextureHostOnWhite->Updated(&destRegion);
|
||||
mTextureHostOnWhite->Updated(&finalRegion);
|
||||
}
|
||||
mInitialised = true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user