TemporaryRef<CompositingRenderTarget> CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect, const CompositingRenderTarget* aSource, const gfx::IntPoint &aSourcePoint) { MOZ_ASSERT(aRect.width != 0 && aRect.height != 0); if (aRect.width * aRect.height == 0) { return nullptr; } CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aRect.width, aRect.height, 1, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET); RefPtr<ID3D11Texture2D> texture; HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(texture)); NS_ASSERTION(texture, "Could not create texture"); if (Failed(hr) || !texture) { return nullptr; } if (aSource) { const CompositingRenderTargetD3D11* sourceD3D11 = static_cast<const CompositingRenderTargetD3D11*>(aSource); D3D11_BOX srcBox; srcBox.left = aSourcePoint.x; srcBox.top = aSourcePoint.y; srcBox.front = 0; srcBox.right = aSourcePoint.x + aRect.width; srcBox.bottom = aSourcePoint.y + aRect.height; srcBox.back = 1; const IntSize& srcSize = sourceD3D11->GetSize(); MOZ_ASSERT(srcSize.width >= 0 && srcSize.height >= 0, "render targets should have nonnegative sizes"); if (srcBox.left >= 0 && srcBox.top >= 0 && srcBox.left < srcBox.right && srcBox.top < srcBox.bottom && srcBox.right <= static_cast<uint32_t>(srcSize.width) && srcBox.bottom <= static_cast<uint32_t>(srcSize.height)) { mContext->CopySubresourceRegion(texture, 0, 0, 0, 0, sourceD3D11->GetD3D11Texture(), 0, &srcBox); } else { NS_WARNING("Could not copy render target - source rect out of bounds"); } } RefPtr<CompositingRenderTargetD3D11> rt = new CompositingRenderTargetD3D11(texture, aRect.TopLeft()); rt->SetSize(aRect.Size()); return rt; }
CompositingRenderTargetD3D9::CompositingRenderTargetD3D9(IDirect3DSurface9* aSurface, SurfaceInitMode aInit, const gfx::IntRect& aRect) : CompositingRenderTarget(aRect.TopLeft()) , mSurface(aSurface) , mInitMode(aInit) , mInitialized(false) { MOZ_COUNT_CTOR(CompositingRenderTargetD3D9); MOZ_ASSERT(mSurface); TextureSourceD3D9::SetSize(aRect.Size()); }
CompositingRenderTargetD3D9::CompositingRenderTargetD3D9(IDirect3DTexture9* aTexture, SurfaceInitMode aInit, const gfx::IntRect& aRect) : CompositingRenderTarget(aRect.TopLeft()) , mInitMode(aInit) , mInitialized(false) { MOZ_COUNT_CTOR(CompositingRenderTargetD3D9); MOZ_ASSERT(aTexture); mTexture = aTexture; HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(mSurface)); NS_ASSERTION(mSurface, "Couldn't create surface for texture"); TextureSourceD3D9::SetSize(aRect.Size()); }
gfx::IntRect ComputeBackdropCopyRect(const gfx::Rect& aRect, const gfx::IntRect& aClipRect, const gfx::Matrix4x4& aTransform, const gfx::IntRect& aRenderTargetRect, gfx::Matrix4x4* aOutTransform, gfx::Rect* aOutLayerQuad) { // Compute the clip. IntPoint rtOffset = aRenderTargetRect.TopLeft(); IntSize rtSize = aRenderTargetRect.Size(); gfx::IntRect renderBounds(0, 0, rtSize.width, rtSize.height); renderBounds.IntersectRect(renderBounds, aClipRect); renderBounds.MoveBy(rtOffset); // Apply the layer transform. RectDouble dest = aTransform.TransformAndClipBounds( RectDouble(aRect.x, aRect.y, aRect.width, aRect.height), RectDouble(renderBounds.x, renderBounds.y, renderBounds.width, renderBounds.height)); dest -= rtOffset; // Ensure we don't round out to -1, which trips up Direct3D. dest.IntersectRect(dest, RectDouble(0, 0, rtSize.width, rtSize.height)); if (aOutLayerQuad) { *aOutLayerQuad = Rect(dest.x, dest.y, dest.width, dest.height); } // Round out to integer. IntRect result; dest.RoundOut(); dest.ToIntRect(&result); // Create a transform from adjusted clip space to render target space, // translate it for the backdrop rect, then transform it into the backdrop's // uv-space. Matrix4x4 transform; transform.PostScale(rtSize.width, rtSize.height, 1.0); transform.PostTranslate(-result.x, -result.y, 0.0); transform.PostScale(1 / float(result.width), 1 / float(result.height), 1.0); *aOutTransform = transform; return result; }