bool DeprecatedContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) { aUpdatedRegionBack->SetEmpty(); if (!mDeprecatedTextureHost && !mNewFrontHost) { mInitialised = false; return true; } if (mNewFrontHost) { DestroyFrontHost(); mDeprecatedTextureHost = mNewFrontHost; mNewFrontHost = nullptr; if (mNewFrontHostOnWhite) { mDeprecatedTextureHostOnWhite = mNewFrontHostOnWhite; mNewFrontHostOnWhite = nullptr; } } MOZ_ASSERT(mDeprecatedTextureHost); MOZ_ASSERT(!mNewFrontHostOnWhite, "New white host without a new black?"); // updated is in screen coordinates. Convert it to buffer coordinates. 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!"); return false; } mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->LockSurfaceDescriptor(), &destRegion); if (mDeprecatedTextureHostOnWhite) { mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->LockSurfaceDescriptor(), &destRegion); } mInitialised = true; mBufferRect = aData.rect(); mBufferRotation = aData.rotation(); return true; }
void DeprecatedContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) { aUpdatedRegionBack->SetEmpty(); if (!mDeprecatedTextureHost && !mNewFrontHost) { mInitialised = false; return; } if (mNewFrontHost) { DestroyFrontHost(); mDeprecatedTextureHost = mNewFrontHost; mNewFrontHost = nullptr; if (mNewFrontHostOnWhite) { mDeprecatedTextureHostOnWhite = mNewFrontHostOnWhite; mNewFrontHostOnWhite = nullptr; } } MOZ_ASSERT(mDeprecatedTextureHost); MOZ_ASSERT(!mNewFrontHostOnWhite, "New white host without a new black?"); // updated is in screen coordinates. Convert it to buffer coordinates. nsIntRegion destRegion(aUpdated); destRegion.MoveBy(-aData.rect().TopLeft()); // Correct for rotation destRegion.MoveBy(aData.rotation()); gfxIntSize size = aData.rect().Size(); nsIntRect destBounds = destRegion.GetBounds(); destRegion.MoveBy((destBounds.x >= size.width) ? -size.width : 0, (destBounds.y >= size.height) ? -size.height : 0); // There's code to make sure that updated regions don't cross rotation // boundaries, so assert here that this is the case MOZ_ASSERT((destBounds.x % size.width) + destBounds.width <= size.width, "updated region lies across rotation boundaries!"); MOZ_ASSERT((destBounds.y % size.height) + destBounds.height <= size.height, "updated region lies across rotation boundaries!"); mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->LockSurfaceDescriptor(), &destRegion); if (mDeprecatedTextureHostOnWhite) { mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->LockSurfaceDescriptor(), &destRegion); } mInitialised = true; mBufferRect = aData.rect(); mBufferRotation = aData.rotation(); }
bool ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) { aUpdatedRegionBack->SetEmpty(); if (!mTextureHost) { mInitialised = false; return true; // FIXME should we return false? Returning true for now } // to preserve existing behavior of NOT causing IPC errors. // updated is in screen coordinates. Convert it to buffer coordinates. nsIntRegion destRegion(aUpdated); destRegion.MoveBy(-aData.rect().TopLeft()); 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; } // 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(&finalRegion); } mInitialised = true; mBufferRect = aData.rect(); mBufferRotation = aData.rotation(); return true; }
bool ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) { aUpdatedRegionBack->SetEmpty(); if (!mTextureHost) { mInitialised = false; return true; // FIXME should we return false? Returning true for now } // to preserve existing behavior of NOT causing IPC errors. // updated is in screen coordinates. Convert it to buffer coordinates. 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!"); return false; } mTextureHost->Updated(&destRegion); if (mTextureHostOnWhite) { mTextureHostOnWhite->Updated(&destRegion); } mInitialised = true; mBufferRect = aData.rect(); mBufferRotation = aData.rotation(); return true; }
bool DeprecatedContentHostDoubleBuffered::UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) { if (!mDeprecatedTextureHost && !mNewFrontHost) { mInitialised = false; *aUpdatedRegionBack = aUpdated; return true; } if (mNewFrontHost) { DestroyFrontHost(); mDeprecatedTextureHost = mNewFrontHost; mNewFrontHost = nullptr; if (mNewFrontHostOnWhite) { mDeprecatedTextureHostOnWhite = mNewFrontHostOnWhite; mNewFrontHostOnWhite = nullptr; } } MOZ_ASSERT(mDeprecatedTextureHost); MOZ_ASSERT(!mNewFrontHostOnWhite, "New white host without a new black?"); MOZ_ASSERT(mBackHost); RefPtr<DeprecatedTextureHost> oldFront = mDeprecatedTextureHost; mDeprecatedTextureHost = mBackHost; mBackHost = oldFront; oldFront = mDeprecatedTextureHostOnWhite; mDeprecatedTextureHostOnWhite = mBackHostOnWhite; mBackHostOnWhite = oldFront; mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->LockSurfaceDescriptor()); if (mDeprecatedTextureHostOnWhite) { mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->LockSurfaceDescriptor()); } mInitialised = true; mBufferRect = aData.rect(); mBufferRotation = aData.rotation(); *aUpdatedRegionBack = aUpdated; // Save the current valid region of our front buffer, because if // we're double buffering, it's going to be the valid region for the // next back buffer sent back to the renderer. // // NB: we rely here on the fact that mValidRegion is initialized to // empty, and that the first time Swap() is called we don't have a // valid front buffer that we're going to return to content. mValidRegionForNextBackBuffer = aOldValidRegionBack; return true; }
void ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) { aUpdatedRegionBack->SetEmpty(); if (!mTextureHost) { mInitialised = false; return; } // updated is in screen coordinates. Convert it to buffer coordinates. nsIntRegion destRegion(aUpdated); destRegion.MoveBy(-aData.rect().TopLeft()); // Correct for rotation destRegion.MoveBy(aData.rotation()); gfxIntSize size = aData.rect().Size(); nsIntRect destBounds = destRegion.GetBounds(); destRegion.MoveBy((destBounds.x >= size.width) ? -size.width : 0, (destBounds.y >= size.height) ? -size.height : 0); // There's code to make sure that updated regions don't cross rotation // boundaries, so assert here that this is the case MOZ_ASSERT((destBounds.x % size.width) + destBounds.width <= size.width, "updated region lies across rotation boundaries!"); MOZ_ASSERT((destBounds.y % size.height) + destBounds.height <= size.height, "updated region lies across rotation boundaries!"); mTextureHost->Updated(&destRegion); if (mTextureHostOnWhite) { mTextureHostOnWhite->Updated(&destRegion); } mInitialised = true; mBufferRect = aData.rect(); mBufferRotation = aData.rotation(); }
bool ContentHostDoubleBuffered::UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) { if (!mTextureHost) { mInitialised = false; *aUpdatedRegionBack = aUpdated; return true; } // We don't need to calculate an update region because we assume that if we // are using double buffering then we have render-to-texture and thus no // upload to do. mTextureHost->Updated(); if (mTextureHostOnWhite) { mTextureHostOnWhite->Updated(); } mInitialised = true; mBufferRect = aData.rect(); mBufferRotation = aData.rotation(); *aUpdatedRegionBack = aUpdated; // Save the current valid region of our front buffer, because if // we're double buffering, it's going to be the valid region for the // next back buffer sent back to the renderer. // // NB: we rely here on the fact that mValidRegion is initialized to // empty, and that the first time Swap() is called we don't have a // valid front buffer that we're going to return to content. mValidRegionForNextBackBuffer = aOldValidRegionBack; return true; }