void BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity, Layer* aMaskLayer) { aTarget->Save(); // If the entire buffer is valid, we can just draw the whole thing, // no need to clip. But we'll still clip if clipping is cheap --- // that might let us copy a smaller region of the buffer. // Also clip to the visible region if we're told to. if (!aLayer->GetValidRegion().Contains(BufferRect()) || (ToData(aLayer)->GetClipToVisibleRegion() && !aLayer->GetVisibleRegion().Contains(BufferRect())) || IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) { // We don't want to draw invalid stuff, so we need to clip. Might as // well clip to the smallest area possible --- the visible region. // Bug 599189 if there is a non-integer-translation transform in aTarget, // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong // and may cause gray lines. gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion()); } // Pull out the mask surface and transform here, because the mask // is internal to basic layers gfxMatrix maskTransform; if (nsRefPtr<gfxASurface> maskSurface = GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) { DrawBufferWithRotation(aTarget, aOpacity, maskSurface, &maskTransform); } else { DrawBufferWithRotation(aTarget, aOpacity); } aTarget->Restore(); }
void ContentClientRemote::SetBackingBuffer(gfxASurface* aBuffer, const nsIntRect& aRect, const nsIntPoint& aRotation) { #ifdef DEBUG gfxIntSize prevSize = gfxIntSize(BufferRect().width, BufferRect().height); gfxIntSize newSize = aBuffer->GetSize(); NS_ABORT_IF_FALSE(newSize == prevSize, "Swapped-in buffer size doesn't match old buffer's!"); #endif nsRefPtr<gfxASurface> oldBuffer; oldBuffer = SetBuffer(aBuffer, aRect, aRotation); }
void RotatedContentBuffer::DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity, gfxASurface* aMask, const gfxMatrix* aMaskTransform) { if (!EnsureBuffer()) { return; } RefPtr<DrawTarget> dt = aTarget->GetDrawTarget(); MOZ_ASSERT(dt, "Did you pass a non-Azure gfxContext?"); bool clipped = false; // If the entire buffer is valid, we can just draw the whole thing, // no need to clip. But we'll still clip if clipping is cheap --- // that might let us copy a smaller region of the buffer. // Also clip to the visible region if we're told to. if (!aLayer->GetValidRegion().Contains(BufferRect()) || (ToData(aLayer)->GetClipToVisibleRegion() && !aLayer->GetVisibleRegion().Contains(BufferRect())) || IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) { // We don't want to draw invalid stuff, so we need to clip. Might as // well clip to the smallest area possible --- the visible region. // Bug 599189 if there is a non-integer-translation transform in aTarget, // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong // and may cause gray lines. gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion()); clipped = true; } RefPtr<gfx::SourceSurface> mask; if (aMask) { mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask); } Matrix maskTransform; if (aMaskTransform) { maskTransform = ToMatrix(*aMaskTransform); } CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator()); DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform); if (clipped) { dt->PopClip(); } }
void ContentClientRemoteBuffer::Updated(const nsIntRegion& aRegionToDraw, const nsIntRegion& aVisibleRegion, bool aDidSelfCopy) { nsIntRegion updatedRegion = GetUpdatedRegion(aRegionToDraw, aVisibleRegion, aDidSelfCopy); MOZ_ASSERT(mTextureClient); if (mTextureClientOnWhite) { mForwarder->UseComponentAlphaTextures(this, mTextureClient, mTextureClientOnWhite); } else { nsAutoTArray<CompositableForwarder::TimedTextureClient,1> textures; CompositableForwarder::TimedTextureClient* t = textures.AppendElement(); t->mTextureClient = mTextureClient; IntSize size = mTextureClient->GetSize(); t->mPictureRect = nsIntRect(0, 0, size.width, size.height); GetForwarder()->UseTextures(this, textures); } mForwarder->UpdateTextureRegion(this, ThebesBufferData(BufferRect(), BufferRotation()), updatedRegion); }
nsIntRegion ContentClientRemoteBuffer::GetUpdatedRegion(const nsIntRegion& aRegionToDraw, const nsIntRegion& aVisibleRegion, bool aDidSelfCopy) { nsIntRegion updatedRegion; if (mIsNewBuffer || aDidSelfCopy) { // A buffer reallocation clears both buffers. The front buffer has all the // content by now, but the back buffer is still clear. Here, in effect, we // are saying to copy all of the pixels of the front buffer to the back. // Also when we self-copied in the buffer, the buffer space // changes and some changed buffer content isn't reflected in the // draw or invalidate region (on purpose!). When this happens, we // need to read back the entire buffer too. updatedRegion = aVisibleRegion; mIsNewBuffer = false; } else { updatedRegion = aRegionToDraw; } NS_ASSERTION(BufferRect().Contains(aRegionToDraw.GetBounds()), "Update outside of buffer rect!"); MOZ_ASSERT(mTextureClient, "should have a back buffer by now"); return updatedRegion; }
/** * Swap in the old "virtual buffer" (see above) attributes in aNew* * and return the old ones in aOld*. * * Swap() must only be called when the buffer is in its "unmapped" * state, that is the underlying gfxASurface is not available. It * is expected that the owner of this buffer holds an unmapped * SurfaceDescriptor as the backing storage for this buffer. That's * why no gfxASurface or SurfaceDescriptor parameters appear here. */ void Swap(const nsIntRect& aNewRect, const nsIntPoint& aNewRotation, nsIntRect* aOldRect, nsIntPoint* aOldRotation) { *aOldRect = BufferRect(); *aOldRotation = BufferRotation(); nsRefPtr<gfxASurface> oldBuffer; oldBuffer = SetBuffer(nullptr, aNewRect, aNewRotation); MOZ_ASSERT(!oldBuffer); }
void ContentClientRemote::Updated(const nsIntRegion& aRegionToDraw, const nsIntRegion& aVisibleRegion, bool aDidSelfCopy) { nsIntRegion updatedRegion = GetUpdatedRegion(aRegionToDraw, aVisibleRegion, aDidSelfCopy); MOZ_ASSERT(mTextureClient); mTextureClient->SetAccessMode(TextureClient::ACCESS_NONE); LockFrontBuffer(); mForwarder->UpdateTextureRegion(this, ThebesBufferData(BufferRect(), BufferRotation()), updatedRegion); }
void ContentClientRemoteBuffer::Updated(const nsIntRegion& aRegionToDraw, const nsIntRegion& aVisibleRegion, bool aDidSelfCopy) { nsIntRegion updatedRegion = GetUpdatedRegion(aRegionToDraw, aVisibleRegion, aDidSelfCopy); MOZ_ASSERT(mTextureClient); if (mTextureClientOnWhite) { mForwarder->UseComponentAlphaTextures(this, mTextureClient, mTextureClientOnWhite); } else { mForwarder->UseTexture(this, mTextureClient); } mForwarder->UpdateTextureRegion(this, ThebesBufferData(BufferRect(), BufferRotation()), updatedRegion); }