TemporaryRef<TextureClient> CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat, TextureFlags aTextureFlags) { RefPtr<TextureClient> result; #ifdef XP_WIN LayersBackend parentBackend = GetForwarder()->GetCompositorBackendType(); if (parentBackend == LAYERS_D3D11 && gfxWindowsPlatform::GetPlatform()->GetD2DDevice() && !(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) { result = new TextureClientD3D11(aFormat, aTextureFlags); } if (parentBackend == LAYERS_D3D9 && !GetForwarder()->ForwardsToDifferentProcess() && !(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) { // non-DIB textures don't work with alpha, see notes in TextureD3D9. if (ContentForFormat(aFormat) != GFX_CONTENT_COLOR) { result = new DIBTextureClientD3D9(aFormat, aTextureFlags); } else { result = new CairoTextureClientD3D9(aFormat, aTextureFlags); } } #endif // Can't do any better than a buffer texture client. if (!result) { result = CreateBufferTextureClient(aFormat, aTextureFlags); } MOZ_ASSERT(!result || result->AsTextureClientDrawTarget(), "Not a TextureClientDrawTarget?"); return result; }
gfxContentType RotatedContentBuffer::BufferContentType() { if (mDeprecatedBufferProvider) { return mDeprecatedBufferProvider->GetContentType(); } if (mBufferProvider || mDTBuffer) { SurfaceFormat format; if (mBufferProvider) { format = mBufferProvider->AsTextureClientDrawTarget()->GetFormat(); } else if (mDTBuffer) { format = mDTBuffer->GetFormat(); } return ContentForFormat(format); } return GFX_CONTENT_SENTINEL; }
void ContentHostIncremental::TextureCreationRequest::Execute(ContentHostIncremental* aHost) { RefPtr<DeprecatedTextureHost> newHost = DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptor::TShmem, mTextureInfo.mDeprecatedTextureHostFlags, mTextureInfo.mTextureFlags, nullptr); Compositor* compositor = aHost->GetCompositor(); if (compositor) { newHost->SetCompositor(compositor); } RefPtr<DeprecatedTextureHost> newHostOnWhite; if (mTextureInfo.mTextureFlags & TEXTURE_COMPONENT_ALPHA) { newHostOnWhite = DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptor::TShmem, mTextureInfo.mDeprecatedTextureHostFlags, mTextureInfo.mTextureFlags, nullptr); Compositor* compositor = aHost->GetCompositor(); if (compositor) { newHostOnWhite->SetCompositor(compositor); } } if (mTextureInfo.mDeprecatedTextureHostFlags & TEXTURE_HOST_COPY_PREVIOUS) { nsIntRect bufferRect = aHost->mBufferRect; nsIntPoint bufferRotation = aHost->mBufferRotation; nsIntRect overlap; // The buffer looks like: // ______ // |1 |2 | Where the center point is offset by mBufferRotation from the top-left corner. // |___|__| // |3 |4 | // |___|__| // // This is drawn to the screen as: // ______ // |4 |3 | Where the center point is { width - mBufferRotation.x, height - mBufferRotation.y } from // |___|__| from the top left corner - rotationPoint. // |2 |1 | // |___|__| // // The basic idea below is to take all quadrant rectangles from the src and transform them into rectangles // in the destination. Unfortunately, it seems it is overly complex and could perhaps be simplified. nsIntRect srcBufferSpaceBottomRight(bufferRotation.x, bufferRotation.y, bufferRect.width - bufferRotation.x, bufferRect.height - bufferRotation.y); nsIntRect srcBufferSpaceTopRight(bufferRotation.x, 0, bufferRect.width - bufferRotation.x, bufferRotation.y); nsIntRect srcBufferSpaceTopLeft(0, 0, bufferRotation.x, bufferRotation.y); nsIntRect srcBufferSpaceBottomLeft(0, bufferRotation.y, bufferRotation.x, bufferRect.height - bufferRotation.y); overlap.IntersectRect(bufferRect, mBufferRect); nsIntRect srcRect(overlap), dstRect(overlap); srcRect.MoveBy(- bufferRect.TopLeft() + bufferRotation); nsIntRect srcRectDrawTopRight(srcRect); nsIntRect srcRectDrawTopLeft(srcRect); nsIntRect srcRectDrawBottomLeft(srcRect); // transform into the different quadrants srcRectDrawTopRight .MoveBy(-nsIntPoint(0, bufferRect.height)); srcRectDrawTopLeft .MoveBy(-nsIntPoint(bufferRect.width, bufferRect.height)); srcRectDrawBottomLeft.MoveBy(-nsIntPoint(bufferRect.width, 0)); // Intersect with the quadrant srcRect = srcRect .Intersect(srcBufferSpaceBottomRight); srcRectDrawTopRight = srcRectDrawTopRight .Intersect(srcBufferSpaceTopRight); srcRectDrawTopLeft = srcRectDrawTopLeft .Intersect(srcBufferSpaceTopLeft); srcRectDrawBottomLeft = srcRectDrawBottomLeft.Intersect(srcBufferSpaceBottomLeft); dstRect = srcRect; nsIntRect dstRectDrawTopRight(srcRectDrawTopRight); nsIntRect dstRectDrawTopLeft(srcRectDrawTopLeft); nsIntRect dstRectDrawBottomLeft(srcRectDrawBottomLeft); // transform back to src buffer space dstRect .MoveBy(-bufferRotation); dstRectDrawTopRight .MoveBy(-bufferRotation + nsIntPoint(0, bufferRect.height)); dstRectDrawTopLeft .MoveBy(-bufferRotation + nsIntPoint(bufferRect.width, bufferRect.height)); dstRectDrawBottomLeft.MoveBy(-bufferRotation + nsIntPoint(bufferRect.width, 0)); // transform back to draw coordinates dstRect .MoveBy(bufferRect.TopLeft()); dstRectDrawTopRight .MoveBy(bufferRect.TopLeft()); dstRectDrawTopLeft .MoveBy(bufferRect.TopLeft()); dstRectDrawBottomLeft.MoveBy(bufferRect.TopLeft()); // transform to destBuffer space dstRect .MoveBy(-mBufferRect.TopLeft()); dstRectDrawTopRight .MoveBy(-mBufferRect.TopLeft()); dstRectDrawTopLeft .MoveBy(-mBufferRect.TopLeft()); dstRectDrawBottomLeft.MoveBy(-mBufferRect.TopLeft()); newHost->EnsureBuffer(mBufferRect.Size(), ContentForFormat(aHost->mDeprecatedTextureHost->GetFormat())); aHost->mDeprecatedTextureHost->CopyTo(srcRect, newHost, dstRect); if (bufferRotation != nsIntPoint(0, 0)) { // Draw the remaining quadrants. We call BlitTextureImage 3 extra // times instead of doing a single draw call because supporting that // with a tiled source is quite tricky. if (!srcRectDrawTopRight.IsEmpty()) aHost->mDeprecatedTextureHost->CopyTo(srcRectDrawTopRight, newHost, dstRectDrawTopRight); if (!srcRectDrawTopLeft.IsEmpty()) aHost->mDeprecatedTextureHost->CopyTo(srcRectDrawTopLeft, newHost, dstRectDrawTopLeft); if (!srcRectDrawBottomLeft.IsEmpty()) aHost->mDeprecatedTextureHost->CopyTo(srcRectDrawBottomLeft, newHost, dstRectDrawBottomLeft); } if (newHostOnWhite) { newHostOnWhite->EnsureBuffer(mBufferRect.Size(), ContentForFormat(aHost->mDeprecatedTextureHostOnWhite->GetFormat())); aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRect, newHostOnWhite, dstRect); if (bufferRotation != nsIntPoint(0, 0)) { // draw the remaining quadrants if (!srcRectDrawTopRight.IsEmpty()) aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRectDrawTopRight, newHostOnWhite, dstRectDrawTopRight); if (!srcRectDrawTopLeft.IsEmpty()) aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRectDrawTopLeft, newHostOnWhite, dstRectDrawTopLeft); if (!srcRectDrawBottomLeft.IsEmpty()) aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRectDrawBottomLeft, newHostOnWhite, dstRectDrawBottomLeft); } } } aHost->mDeprecatedTextureHost = newHost; aHost->mDeprecatedTextureHostOnWhite = newHostOnWhite; aHost->mBufferRect = mBufferRect; aHost->mBufferRotation = nsIntPoint(); }