diff --git a/gfx/webrender_bindings/DCLayerTree.cpp b/gfx/webrender_bindings/DCLayerTree.cpp index 7168a703e972..1af4900822e8 100644 --- a/gfx/webrender_bindings/DCLayerTree.cpp +++ b/gfx/webrender_bindings/DCLayerTree.cpp @@ -621,7 +621,7 @@ void DCLayerTree::CompositorEndFrame() { surface->UpdateAllocatedRect(); if (!same) { // Add surfaces in z-order they were added to the scene. - const auto visual = surface->GetVisual(); + const auto visual = surface->GetRootVisual(); mRootVisual->AddVisual(visual, false, nullptr); } } @@ -824,7 +824,7 @@ void DCLayerTree::DestroySurface(NativeSurfaceId aId) { MOZ_RELEASE_ASSERT(surface_it != mDCSurfaces.end()); auto surface = surface_it->second.get(); - mRootVisual->RemoveVisual(surface->GetVisual()); + mRootVisual->RemoveVisual(surface->GetRootVisual()); mDCSurfaces.erase(surface_it); } @@ -893,8 +893,8 @@ DCSurface* DCExternalSurfaceWrapper::EnsureSurfaceForExternalImage( } // Add surface's visual which will contain video data to our root visual. - const auto surfaceVisual = mSurface->GetVisual(); - mVisual->AddVisual(surfaceVisual, true, nullptr); + const auto surfaceVisual = mSurface->GetRootVisual(); + mContentVisual->AddVisual(surfaceVisual, true, nullptr); // - // Apply color management. @@ -1024,11 +1024,13 @@ static inline D2D1_MATRIX_3X2_F D2DMatrix(const gfx::Matrix& aTransform) { void DCLayerTree::AddSurface(wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, wr::DeviceIntRect aClipRect, - wr::ImageRendering aImageRendering) { + wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, + wr::ClipRadius aClipRadius) { auto it = mDCSurfaces.find(aId); MOZ_RELEASE_ASSERT(it != mDCSurfaces.end()); const auto surface = it->second.get(); - const auto visual = surface->GetVisual(); + const auto visual = surface->GetContentVisual(); wr::DeviceIntPoint virtualOffset = surface->GetVirtualOffset(); @@ -1071,6 +1073,8 @@ void DCLayerTree::AddSurface(wr::NativeSurfaceId aId, DCOMPOSITION_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR); } + surface->SetClip(aRoundedClipRect, aClipRadius); + mCurrentLayers.push_back(aId); } @@ -1275,11 +1279,22 @@ bool DCSurface::Initialize() { // Create a visual for tiles to attach to, whether virtual or not. HRESULT hr; const auto dCompDevice = mDCLayerTree->GetCompositionDevice(); - hr = dCompDevice->CreateVisual(getter_AddRefs(mVisual)); + hr = dCompDevice->CreateVisual(getter_AddRefs(mRootVisual)); if (FAILED(hr)) { gfxCriticalNote << "Failed to create DCompositionVisual: " << gfx::hexa(hr); return false; } + hr = dCompDevice->CreateVisual(getter_AddRefs(mContentVisual)); + if (FAILED(hr)) { + gfxCriticalNote << "Failed to create DCompositionVisual: " << gfx::hexa(hr); + return false; + } + mRootVisual->AddVisual(mContentVisual, false, nullptr); + hr = dCompDevice->CreateRectangleClip(getter_AddRefs(mClip)); + if (FAILED(hr)) { + gfxCriticalNote << "Failed to create RectangleClip: " << gfx::hexa(hr); + return false; + } // If virtual surface is enabled, create and attach to visual, in this case // the tiles won't own visuals or surfaces. @@ -1293,20 +1308,50 @@ bool DCSurface::Initialize() { MOZ_ASSERT(SUCCEEDED(hr)); // Bind the surface memory to this visual - hr = mVisual->SetContent(mVirtualSurface); + hr = mContentVisual->SetContent(mVirtualSurface); MOZ_ASSERT(SUCCEEDED(hr)); } return true; } +void DCSurface::SetClip(wr::DeviceIntRect aClipRect, + wr::ClipRadius aClipRadius) { + bool needsClip = + aClipRadius.top_left > 0.0f || aClipRadius.top_right > 0.0f || + aClipRadius.bottom_left > 0.0f || aClipRadius.bottom_right > 0.0f; + + if (needsClip) { + mClip->SetLeft(aClipRect.min.x); + mClip->SetRight(aClipRect.max.x); + mClip->SetTop(aClipRect.min.y); + mClip->SetBottom(aClipRect.max.y); + + mClip->SetTopLeftRadiusX(aClipRadius.top_left); + mClip->SetTopLeftRadiusY(aClipRadius.top_left); + + mClip->SetTopRightRadiusX(aClipRadius.top_right); + mClip->SetTopRightRadiusY(aClipRadius.top_right); + + mClip->SetBottomLeftRadiusX(aClipRadius.bottom_left); + mClip->SetBottomLeftRadiusY(aClipRadius.bottom_left); + + mClip->SetBottomRightRadiusX(aClipRadius.bottom_right); + mClip->SetBottomRightRadiusY(aClipRadius.bottom_right); + + mRootVisual->SetClip(mClip); + } else { + mRootVisual->SetClip(nullptr); + } +} + void DCSurface::CreateTile(int32_t aX, int32_t aY) { TileKey key(aX, aY); MOZ_RELEASE_ASSERT(mDCTiles.find(key) == mDCTiles.end()); auto tile = MakeUnique(mDCLayerTree); if (!tile->Initialize(aX, aY, mTileSize, mIsVirtualSurface, mIsOpaque, - mVisual)) { + mContentVisual)) { gfxCriticalNote << "Failed to initialize DCTile: " << aX << aY; return; } @@ -1314,7 +1359,7 @@ void DCSurface::CreateTile(int32_t aX, int32_t aY) { if (mIsVirtualSurface) { mAllocatedRectDirty = true; } else { - mVisual->AddVisual(tile->GetVisual(), false, nullptr); + mContentVisual->AddVisual(tile->GetVisual(), false, nullptr); } mDCTiles[key] = std::move(tile); @@ -1326,7 +1371,7 @@ void DCSurface::DestroyTile(int32_t aX, int32_t aY) { mAllocatedRectDirty = true; } else { auto tile = GetTile(aX, aY); - mVisual->RemoveVisual(tile->GetVisual()); + mContentVisual->RemoveVisual(tile->GetVisual()); } mDCTiles.erase(key); } @@ -1419,7 +1464,7 @@ bool DCSwapChain::Initialize() { hr = dxgiFactory->CreateSwapChainForComposition(device, &desc, nullptr, getter_AddRefs(mSwapChain)); MOZ_RELEASE_ASSERT(SUCCEEDED(hr)); - mVisual->SetContent(mSwapChain); + mContentVisual->SetContent(mSwapChain); ID3D11Texture2D* backBuffer; hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer); @@ -1610,7 +1655,7 @@ bool DCLayerCompositionSurface::Resize(wr::DeviceIntSize aSize) { return false; } - hr = mVisual->SetContent(surface); + hr = mContentVisual->SetContent(surface); if (FAILED(hr)) { gfxCriticalNote << "Failed to SetContent: " << gfx::hexa(hr); return false; @@ -1814,7 +1859,7 @@ void DCSurfaceVideo::PresentVideo() { return; } - mVisual->SetContent(mVideoSwapChain); + mContentVisual->SetContent(mVideoSwapChain); if (!CallVideoProcessorBlt()) { bool useYUVSwapChain = IsYUVSwapChainFormat(mSwapChainFormat); @@ -2290,9 +2335,9 @@ void DCSurfaceHandle::PresentSurfaceHandle() { LOG_H("PresentSurfaceHandle"); if (IDCompositionSurface* surface = EnsureSurface()) { LOG_H("Set surface %p to visual", surface); - mVisual->SetContent(surface); + mContentVisual->SetContent(surface); } else { - mVisual->SetContent(nullptr); + mContentVisual->SetContent(nullptr); } } diff --git a/gfx/webrender_bindings/DCLayerTree.h b/gfx/webrender_bindings/DCLayerTree.h index 1b8074726084..7a4cda4306f6 100644 --- a/gfx/webrender_bindings/DCLayerTree.h +++ b/gfx/webrender_bindings/DCLayerTree.h @@ -41,6 +41,7 @@ struct IDXGIDecodeSwapChain; struct IDXGIResource; struct IDXGISwapChain1; struct IDCompositionVirtualSurface; +struct IDCompositionRectangleClip; namespace mozilla { @@ -152,7 +153,9 @@ class DCLayerTree { void AddSurface(wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, wr::DeviceIntRect aClipRect, - wr::ImageRendering aImageRendering); + wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, + wr::ClipRadius aClipRadius); void BindSwapChain(wr::NativeSurfaceId aId); void PresentSwapChain(wr::NativeSurfaceId aId); @@ -300,8 +303,10 @@ class DCSurface { virtual bool Initialize(); void CreateTile(int32_t aX, int32_t aY); void DestroyTile(int32_t aX, int32_t aY); + void SetClip(wr::DeviceIntRect aClipRect, wr::ClipRadius aClipRadius); - IDCompositionVisual2* GetVisual() const { return mVisual; } + IDCompositionVisual2* GetContentVisual() const { return mContentVisual; } + IDCompositionVisual2* GetRootVisual() const { return mRootVisual; } DCTile* GetTile(int32_t aX, int32_t aY) const; struct TileKey { @@ -343,17 +348,22 @@ class DCSurface { } }; - // The visual for this surface. No content is attached to here, but tiles - // that belong to this surface are added as children. In this way, we can - // set the clip and scroll offset once, on this visual, to affect all - // children. + // Each surface creates two visuals. The root is where it gets attached + // to parent visuals, the content is where surface (or child visuals) + // get attached. Most of the time, the root visual does nothing, but + // in the case of a complex clip, we attach the clip here. This allows + // us to implement the simple rectangle clip on the content, and apply + // the complex clip, if present, in a way that it's not affected by + // the transform of the content visual. // - // However when using a virtual surface, it is directly attached to this - // visual and the tiles do not own visuals. + // When using a virtual surface, it is directly attached to this + // child visual and the tiles do not own visuals. // // Whether mIsVirtualSurface is enabled is decided at DCSurface creation // time based on the pref gfx.webrender.dcomp-use-virtual-surfaces - RefPtr mVisual; + RefPtr mRootVisual; + RefPtr mContentVisual; + RefPtr mClip; wr::DeviceIntSize mTileSize; bool mIsOpaque; diff --git a/gfx/webrender_bindings/RenderCompositor.cpp b/gfx/webrender_bindings/RenderCompositor.cpp index 92432f03763f..62e408ede084 100644 --- a/gfx/webrender_bindings/RenderCompositor.cpp +++ b/gfx/webrender_bindings/RenderCompositor.cpp @@ -40,9 +40,12 @@ namespace mozilla::wr { void wr_compositor_add_surface(void* aCompositor, wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform* aTransform, wr::DeviceIntRect aClipRect, - wr::ImageRendering aImageRendering) { + wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, + wr::ClipRadius aRoundedClipRadius) { RenderCompositor* compositor = static_cast(aCompositor); - compositor->AddSurface(aId, *aTransform, aClipRect, aImageRendering); + compositor->AddSurface(aId, *aTransform, aClipRect, aImageRendering, + aRoundedClipRect, aRoundedClipRadius); } void wr_compositor_begin_frame(void* aCompositor) { diff --git a/gfx/webrender_bindings/RenderCompositor.h b/gfx/webrender_bindings/RenderCompositor.h index 863b58542975..bf82f5821a38 100644 --- a/gfx/webrender_bindings/RenderCompositor.h +++ b/gfx/webrender_bindings/RenderCompositor.h @@ -149,7 +149,9 @@ class RenderCompositor { virtual void AddSurface(wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, wr::DeviceIntRect aClipRect, - wr::ImageRendering aImageRendering) {} + wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, + wr::ClipRadius aClipRadius) {} // Called in the middle of a frame after all surfaces have been added but // before tiles are updated to signal that early compositing can start virtual void StartCompositing(wr::ColorF aClearColor, diff --git a/gfx/webrender_bindings/RenderCompositorANGLE.cpp b/gfx/webrender_bindings/RenderCompositorANGLE.cpp index 3c5b693abcfd..bd8de8782057 100644 --- a/gfx/webrender_bindings/RenderCompositorANGLE.cpp +++ b/gfx/webrender_bindings/RenderCompositorANGLE.cpp @@ -913,8 +913,10 @@ void RenderCompositorANGLE::AttachExternalImage( void RenderCompositorANGLE::AddSurface( wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, - wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering) { - mDCLayerTree->AddSurface(aId, aTransform, aClipRect, aImageRendering); + wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, wr::ClipRadius aClipRadius) { + mDCLayerTree->AddSurface(aId, aTransform, aClipRect, aImageRendering, + aRoundedClipRect, aClipRadius); } void RenderCompositorANGLE::GetCompositorCapabilities( diff --git a/gfx/webrender_bindings/RenderCompositorANGLE.h b/gfx/webrender_bindings/RenderCompositorANGLE.h index 6c577c786ad2..1c4f0339b14a 100644 --- a/gfx/webrender_bindings/RenderCompositorANGLE.h +++ b/gfx/webrender_bindings/RenderCompositorANGLE.h @@ -107,7 +107,9 @@ class RenderCompositorANGLE final : public RenderCompositor { void AddSurface(wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, wr::DeviceIntRect aClipRect, - wr::ImageRendering aImageRendering) override; + wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, + wr::ClipRadius aClipRadius) override; void EnableNativeCompositor(bool aEnable) override; void GetCompositorCapabilities(CompositorCapabilities* aCaps) override; void GetWindowProperties(WindowProperties* aProperties) override; diff --git a/gfx/webrender_bindings/RenderCompositorLayersSWGL.cpp b/gfx/webrender_bindings/RenderCompositorLayersSWGL.cpp index 505e07d59f94..a4baef69ba31 100644 --- a/gfx/webrender_bindings/RenderCompositorLayersSWGL.cpp +++ b/gfx/webrender_bindings/RenderCompositorLayersSWGL.cpp @@ -307,7 +307,8 @@ gfx::SamplingFilter RenderCompositorLayersSWGL::ToSamplingFilter( void RenderCompositorLayersSWGL::AddSurface( wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, - wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering) { + wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, wr::ClipRadius aClipRadius) { float sx = aTransform.scale.x; float sy = aTransform.scale.y; float tx = aTransform.offset.x; diff --git a/gfx/webrender_bindings/RenderCompositorLayersSWGL.h b/gfx/webrender_bindings/RenderCompositorLayersSWGL.h index 3cf6bb44f5c6..26bb4a55fe8f 100644 --- a/gfx/webrender_bindings/RenderCompositorLayersSWGL.h +++ b/gfx/webrender_bindings/RenderCompositorLayersSWGL.h @@ -79,7 +79,9 @@ class RenderCompositorLayersSWGL : public RenderCompositor { void AddSurface(wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, wr::DeviceIntRect aClipRect, - wr::ImageRendering aImageRendering) override; + wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, + wr::ClipRadius aClipRadius) override; void EnableNativeCompositor(bool aEnable) override {} void DeInit() override {} diff --git a/gfx/webrender_bindings/RenderCompositorNative.cpp b/gfx/webrender_bindings/RenderCompositorNative.cpp index ee07970b41ca..f1f11b282d58 100644 --- a/gfx/webrender_bindings/RenderCompositorNative.cpp +++ b/gfx/webrender_bindings/RenderCompositorNative.cpp @@ -408,7 +408,8 @@ gfx::SamplingFilter ToSamplingFilter(wr::ImageRendering aImageRendering) { void RenderCompositorNative::AddSurface( wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, - wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering) { + wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, wr::ClipRadius aClipRadius) { MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer); auto surfaceCursor = mSurfaces.find(aId); diff --git a/gfx/webrender_bindings/RenderCompositorNative.h b/gfx/webrender_bindings/RenderCompositorNative.h index 7f4f180ae418..fed55a05fe43 100644 --- a/gfx/webrender_bindings/RenderCompositorNative.h +++ b/gfx/webrender_bindings/RenderCompositorNative.h @@ -75,7 +75,9 @@ class RenderCompositorNative : public RenderCompositor { void AddSurface(wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, wr::DeviceIntRect aClipRect, - wr::ImageRendering aImageRendering) override; + wr::ImageRendering aImageRendering, + wr::DeviceIntRect aRoundedClipRect, + wr::ClipRadius aClipRadius) override; struct TileKey { TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {} diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 23cb521b40d4..0b0bc51232e9 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -41,7 +41,7 @@ use webrender::{ AsyncScreenshotHandle, Compositor, LayerCompositor, CompositorCapabilities, CompositorConfig, CompositorSurfaceTransform, Device, MappableCompositor, MappedTileInfo, NativeSurfaceId, NativeSurfaceInfo, NativeTileId, PartialPresentCompositor, PendingShadersToPrecache, PipelineInfo, ProfilerHooks, RecordedFrameHandle, RenderBackendHooks, Renderer, RendererStats, - SWGLCompositeSurfaceInfo, SceneBuilderHooks, ShaderPrecacheFlags, Shaders, SharedShaders, TextureCacheConfig, + ClipRadius, SWGLCompositeSurfaceInfo, SceneBuilderHooks, ShaderPrecacheFlags, Shaders, SharedShaders, TextureCacheConfig, UploadMethod, WebRenderOptions, WindowVisibility, WindowProperties, ONE_TIME_USAGE_HINT, CompositorInputConfig, CompositorSurfaceUsage, }; use wr_malloc_size_of::MallocSizeOfOps; @@ -1311,6 +1311,8 @@ extern "C" { transform: &CompositorSurfaceTransform, clip_rect: DeviceIntRect, image_rendering: ImageRendering, + rounded_clip_rect: DeviceIntRect, + rounded_clip_radii: ClipRadius, ); fn wr_compositor_start_compositing( compositor: *mut c_void, @@ -1442,9 +1444,19 @@ impl Compositor for WrCompositor { transform: CompositorSurfaceTransform, clip_rect: DeviceIntRect, image_rendering: ImageRendering, + rounded_clip_rect: DeviceIntRect, + rounded_clip_radii: ClipRadius, ) { unsafe { - wr_compositor_add_surface(self.0, id, &transform, clip_rect, image_rendering); + wr_compositor_add_surface( + self.0, + id, + &transform, + clip_rect, + image_rendering, + rounded_clip_rect, + rounded_clip_radii, + ); } } @@ -1665,6 +1677,8 @@ impl LayerCompositor for WrLayerCompositor { &transform, clip_rect, image_rendering, + clip_rect, + ClipRadius::EMPTY, ); } } diff --git a/gfx/wr/webrender/src/composite.rs b/gfx/wr/webrender/src/composite.rs index 526c13a24dd1..16f86c890f7f 100644 --- a/gfx/wr/webrender/src/composite.rs +++ b/gfx/wr/webrender/src/composite.rs @@ -524,6 +524,8 @@ pub struct CompositeSurfaceDescriptor { pub image_rendering: ImageRendering, // List of the surface information for each tile added to this virtual surface pub tile_descriptors: Vec, + pub rounded_clip_rect: DeviceRect, + pub rounded_clip_radii: ClipRadius, } /// Describes surface properties used to composite a frame. This @@ -683,6 +685,31 @@ impl CompositeState { } } + fn compositor_clip_params( + &self, + clip_index: Option, + default_rect: DeviceRect, + ) -> (DeviceRect, ClipRadius) { + match clip_index { + Some(clip_index) => { + let clip = self.get_compositor_clip(clip_index); + + ( + clip.rect.cast_unit(), + ClipRadius { + top_left: clip.radius.top_left.width, + top_right: clip.radius.top_right.width, + bottom_left: clip.radius.bottom_left.width, + bottom_right: clip.radius.bottom_right.width, + } + ) + } + None => { + (default_rect, ClipRadius::EMPTY) + } + } + } + /// Register use of a transform for a picture cache tile or external surface pub fn register_transform( &mut self, @@ -894,6 +921,11 @@ impl CompositeState { clip_index, }; + let (rounded_clip_rect, rounded_clip_radii) = self.compositor_clip_params( + clip_index, + clip_rect, + ); + // Add a surface descriptor for each compositor surface. For the Draw // compositor, this is used to avoid composites being skipped by adding // a dependency on the compositor surface external image keys / generations. @@ -905,6 +937,8 @@ impl CompositeState { image_dependencies: image_dependencies, image_rendering: external_surface.image_rendering, tile_descriptors: Vec::new(), + rounded_clip_rect, + rounded_clip_radii, } ); @@ -934,6 +968,11 @@ impl CompositeState { }; if let Some(backdrop_surface) = &tile_cache.backdrop_surface { + let (rounded_clip_rect, rounded_clip_radii) = self.compositor_clip_params( + tile_cache.compositor_clip, + backdrop_surface.device_rect, + ); + // Use the backdrop native surface we created and add that to the composite state. self.descriptor.surfaces.push( CompositeSurfaceDescriptor { @@ -943,6 +982,8 @@ impl CompositeState { image_dependencies: [ImageDependency::INVALID; 3], image_rendering, tile_descriptors: Vec::new(), + rounded_clip_rect, + rounded_clip_radii, } ); } @@ -994,6 +1035,11 @@ impl CompositeState { // Only push tiles if they have valid clip rects. if !surface_clip_rect.is_empty() { + let (rounded_clip_rect, rounded_clip_radii) = self.compositor_clip_params( + tile_cache.compositor_clip, + surface_clip_rect, + ); + // Add opaque surface before any compositor surfaces if !sub_slice.opaque_tile_descriptors.is_empty() { self.descriptor.surfaces.push( @@ -1004,6 +1050,8 @@ impl CompositeState { image_dependencies: [ImageDependency::INVALID; 3], image_rendering, tile_descriptors: sub_slice.opaque_tile_descriptors.clone(), + rounded_clip_rect, + rounded_clip_radii, } ); } @@ -1018,6 +1066,8 @@ impl CompositeState { image_dependencies: [ImageDependency::INVALID; 3], image_rendering, tile_descriptors: sub_slice.alpha_tile_descriptors.clone(), + rounded_clip_rect, + rounded_clip_radii, } ); } @@ -1296,6 +1346,21 @@ impl Default for WindowVisibility { // pub struct CompositorSurfacePixel; pub type CompositorSurfaceTransform = ScaleOffset; +#[repr(C)] +#[cfg_attr(feature = "capture", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +#[derive(PartialEq, Copy, Clone, Debug)] +pub struct ClipRadius { + top_left: f32, + top_right: f32, + bottom_left: f32, + bottom_right: f32, +} + +impl ClipRadius { + pub const EMPTY: ClipRadius = ClipRadius { top_left: 0.0, top_right: 0.0, bottom_left: 0.0, bottom_right: 0.0 }; +} + /// Defines an interface to a native (OS level) compositor. If supplied /// by the client application, then picture cache slices will be /// composited by the OS compositor, rather than drawn via WR batches. @@ -1422,6 +1487,8 @@ pub trait Compositor { transform: CompositorSurfaceTransform, clip_rect: DeviceIntRect, image_rendering: ImageRendering, + rounded_clip_rect: DeviceIntRect, + rounded_clip_radii: ClipRadius, ); /// Notify the compositor that all tiles have been invalidated and all diff --git a/gfx/wr/webrender/src/compositor/sw_compositor.rs b/gfx/wr/webrender/src/compositor/sw_compositor.rs index 62c2027be23d..1cff6178db60 100644 --- a/gfx/wr/webrender/src/compositor/sw_compositor.rs +++ b/gfx/wr/webrender/src/compositor/sw_compositor.rs @@ -14,7 +14,7 @@ use crate::{ api::units::*, api::ColorDepth, api::ColorF, api::ExternalImageId, api::ImageRendering, api::YuvRangedColorSpace, Compositor, CompositorCapabilities, CompositorSurfaceTransform, NativeSurfaceId, NativeSurfaceInfo, NativeTileId, profiler, MappableCompositor, SWGLCompositeSurfaceInfo, WindowVisibility, - device::Device, + device::Device, ClipRadius, }; pub struct SwTile { @@ -1424,9 +1424,19 @@ impl Compositor for SwCompositor { transform: CompositorSurfaceTransform, clip_rect: DeviceIntRect, filter: ImageRendering, + _rounded_clip_rect: DeviceIntRect, + _rounded_clip_radii: ClipRadius, ) { if self.use_native_compositor { - self.compositor.add_surface(device, id, transform, clip_rect, filter); + self.compositor.add_surface( + device, + id, + transform, + clip_rect, + filter, + _rounded_clip_rect, + _rounded_clip_radii, + ); } if self.composite_thread.is_some() { diff --git a/gfx/wr/webrender/src/lib.rs b/gfx/wr/webrender/src/lib.rs index 8c01d6650c64..04a1ba50e604 100644 --- a/gfx/wr/webrender/src/lib.rs +++ b/gfx/wr/webrender/src/lib.rs @@ -166,7 +166,7 @@ pub extern crate api; extern crate webrender_build; #[doc(hidden)] -pub use crate::composite::{LayerCompositor, CompositorInputConfig, CompositorSurfaceUsage}; +pub use crate::composite::{LayerCompositor, CompositorInputConfig, CompositorSurfaceUsage, ClipRadius}; pub use crate::composite::{CompositorConfig, Compositor, CompositorCapabilities, CompositorSurfaceTransform}; pub use crate::composite::{NativeSurfaceId, NativeTileId, NativeSurfaceInfo, PartialPresentCompositor}; pub use crate::composite::{MappableCompositor, MappedTileInfo, SWGLCompositeSurfaceInfo, WindowVisibility, WindowProperties}; diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs index 69c426e3f77a..4e6a4a88591b 100644 --- a/gfx/wr/webrender/src/renderer/mod.rs +++ b/gfx/wr/webrender/src/renderer/mod.rs @@ -56,7 +56,7 @@ use crate::batch::ClipMaskInstanceList; use crate::capture::{CaptureConfig, ExternalCaptureImage, PlainExternalImage}; use crate::composite::{CompositeState, CompositeTileSurface, CompositorInputLayer, CompositorSurfaceTransform, ResolvedExternalSurface}; use crate::composite::{CompositorKind, Compositor, NativeTileId, CompositeFeatures, CompositeSurfaceFormat, ResolvedExternalSurfaceColorData}; -use crate::composite::{CompositorConfig, NativeSurfaceOperationDetails, NativeSurfaceId, NativeSurfaceOperation}; +use crate::composite::{CompositorConfig, NativeSurfaceOperationDetails, NativeSurfaceId, NativeSurfaceOperation, ClipRadius}; use crate::composite::TileKind; use crate::segment::SegmentBuilder; use crate::{debug_colors, CompositorInputConfig, CompositorSurfaceUsage}; @@ -1451,14 +1451,18 @@ impl Renderer { // Unbind the draw target and add it to the visual tree to be composited compositor.unbind(&mut self.device); + let clip_rect = DeviceIntRect::from_size( + self.debug_overlay_state.current_size.unwrap(), + ); + compositor.add_surface( &mut self.device, NativeSurfaceId::DEBUG_OVERLAY, CompositorSurfaceTransform::identity(), - DeviceIntRect::from_size( - self.debug_overlay_state.current_size.unwrap(), - ), + clip_rect, ImageRendering::Auto, + clip_rect, + ClipRadius::EMPTY, ); } CompositorKind::Draw { .. } => {} @@ -6247,6 +6251,8 @@ impl CompositeState { surface.transform, surface.clip_rect.to_i32(), surface.image_rendering, + surface.rounded_clip_rect.to_i32(), + surface.rounded_clip_radii, ); } compositor.start_compositing(device, clear_color, dirty_rects, &[]);