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; }
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; }
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()); // 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; }
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(); }
void RenderTargetFBO::blit( const RenderTargetFBSharedPtr & destination, const BlitMask & mask, const BlitFilter & filter ) { GLint binding; TmpCurrent current = TmpCurrent(this); glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &binding ); m_bindingStack.push_back( binding ); glBindFramebuffer( GL_FRAMEBUFFER_EXT, m_framebuffer ); resizeAttachments( m_stereoTarget ); bindAttachments( m_stereoTarget ); // restore old binding glBindFramebuffer( GL_FRAMEBUFFER_EXT, binding ); m_bindingStack.pop_back(); BlitRegion destRegion(0,0, destination->getWidth(), destination->getHeight()); BlitRegion srcRegion(0,0, this->getWidth(), this->getHeight()); blit(0, mask, filter, destRegion, srcRegion); }
void RenderTargetFBO::blit( const RenderTargetFBOSharedPtr & destination, const BlitMask & mask, const BlitFilter & filter ) { BlitRegion destRegion(0,0, destination->getWidth(), destination->getHeight()); BlitRegion srcRegion(0,0, this->getWidth(), this->getHeight()); blit(destination->getFramebufferId(), mask, filter, destRegion, srcRegion); }