Bug 1328893 - Specify an ImageRendering for some WebRenderLayers r=kats
authorRyan Hunt <rhunt@eqrion.net>
Fri, 13 Jan 2017 11:59:07 -0600
changeset 342096 4328c358a7c1e7fbd9536a82a3372dc69fe10633
parent 342095 384dac8cee40d43595b757da776f524ad0241217
child 342097 66ef32af3d4154a6183ca80655a8cbae89caf4c6
push id31345
push userkwierso@gmail.com
push dateFri, 10 Feb 2017 20:35:09 +0000
treeherdermozilla-central@a288fe35e494 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1328893
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1328893 - Specify an ImageRendering for some WebRenderLayers r=kats
gfx/layers/ipc/WebRenderMessages.ipdlh
gfx/layers/wr/WebRenderAPI.cpp
gfx/layers/wr/WebRenderAPI.h
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderCanvasLayer.cpp
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderMessageUtils.h
gfx/layers/wr/WebRenderPaintedLayer.cpp
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/src/webrender.h
image/test/reftest/downscaling/reftest.list
--- a/gfx/layers/ipc/WebRenderMessages.ipdlh
+++ b/gfx/layers/ipc/WebRenderMessages.ipdlh
@@ -8,16 +8,17 @@
 include LayersSurfaces;
 include LayersMessages;
 include protocol PCompositable;
 include protocol PTexture;
 
 using WRBorderSide from "mozilla/gfx/webrender.h";
 using WRColor from "mozilla/gfx/webrender.h";
 using WRImageKey from "mozilla/gfx/webrender.h";
+using WRTextureFilter from "mozilla/gfx/webrender.h";
 using WRLayoutSize from "mozilla/gfx/webrender.h";
 using WRRect from "mozilla/gfx/webrender.h";
 using WRGlyphArray from "mozilla/gfx/webrender.h";
 using MaybeImageMask from "mozilla/layers/WebRenderTypes.h";
 using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
 using mozilla::gfx::ByteBuffer from "mozilla/layers/WebRenderTypes.h";
 
 namespace mozilla {
@@ -54,23 +55,25 @@ struct OpDPPushBorder {
   WRLayoutSize bottom_left_radius;
   WRLayoutSize bottom_right_radius;
 };
 
 struct OpDPPushImage {
   WRRect bounds;
   WRRect clip;
   MaybeImageMask mask;
+  WRTextureFilter filter;
   WRImageKey key;
 };
 
 struct OpDPPushExternalImageId {
   WRRect bounds;
   WRRect clip;
   MaybeImageMask mask;
+  WRTextureFilter filter;
   uint64_t externalImageId;
 };
 
 struct OpDPPushIframe {
   WRRect bounds;
   WRRect clip;
   uint64_t layersid;
 };
--- a/gfx/layers/wr/WebRenderAPI.cpp
+++ b/gfx/layers/wr/WebRenderAPI.cpp
@@ -190,19 +190,20 @@ DisplayListBuilder::PushRect(const WRRec
   wr_dp_push_rect(mWRState, aBounds, aClip,
                   aColor.r, aColor.g, aColor.b, aColor.a);
 }
 
 void
 DisplayListBuilder::PushImage(const WRRect& aBounds,
                               const WRRect& aClip,
                               const WRImageMask* aMask,
+                              const WRTextureFilter aFilter,
                               WRImageKey aImage)
 {
-  wr_dp_push_image(mWRState, aBounds, aClip, aMask, aImage);
+  wr_dp_push_image(mWRState, aBounds, aClip, aMask, aFilter, aImage);
 }
 
 void
 DisplayListBuilder::PushIFrame(const WRRect& aBounds,
                                const WRRect& aClip,
                                gfx::PipelineId aPipeline)
 {
   wr_dp_push_iframe(mWRState, aBounds, aClip, aPipeline.mHandle);
--- a/gfx/layers/wr/WebRenderAPI.h
+++ b/gfx/layers/wr/WebRenderAPI.h
@@ -74,16 +74,17 @@ public:
 
   void PushRect(const WRRect& aBounds,
                 const WRRect& aClip,
                 const gfx::Color& aColor);
 
   void PushImage(const WRRect& aBounds,
                  const WRRect& aClip,
                  const WRImageMask* aMask,
+                 const WRTextureFilter aFilter,
                  WRImageKey aImage);
 
   void PushIFrame(const WRRect& aBounds,
                   const WRRect& aClip,
                   gfx::PipelineId aPipeline);
 
   void PushBorder(const WRRect& bounds,
                   const WRRect& clip,
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -314,17 +314,17 @@ WebRenderBridgeParent::ProcessWebrenderC
                            op.top(), op.right(), op.bottom(), op.left(),
                            op.top_left_radius(), op.top_right_radius(),
                            op.bottom_left_radius(), op.bottom_right_radius());
         break;
       }
       case WebRenderCommand::TOpDPPushImage: {
         const OpDPPushImage& op = cmd.get_OpDPPushImage();
         builder.PushImage(op.bounds(), op.clip(),
-                          op.mask().ptrOr(nullptr), op.key());
+                          op.mask().ptrOr(nullptr), op.filter(), op.key());
         break;
       }
       case WebRenderCommand::TOpDPPushExternalImageId: {
         const OpDPPushExternalImageId& op = cmd.get_OpDPPushExternalImageId();
         MOZ_ASSERT(mExternalImageIds.Get(op.externalImageId()).get());
 
         RefPtr<CompositableHost> host = mExternalImageIds.Get(op.externalImageId());
         if (!host) {
@@ -335,17 +335,17 @@ WebRenderBridgeParent::ProcessWebrenderC
           break;
         }
         DataSourceSurface::MappedSurface map;
         if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
           break;
         }
         gfx::IntSize size = dSurf->GetSize();
         WRImageKey key = wr_add_image(mWRWindowState, size.width, size.height, map.mStride, RGBA8, map.mData, size.height * map.mStride);
-        builder.PushImage(op.bounds(), op.clip(), op.mask().ptrOr(nullptr), key);
+        builder.PushImage(op.bounds(), op.clip(), op.mask().ptrOr(nullptr), op.filter(), key);
         keysToDelete.push_back(key);
         dSurf->Unmap();
         break;
       }
       case WebRenderCommand::TOpDPPushIframe: {
         const OpDPPushIframe& op = cmd.get_OpDPPushIframe();
         wr_window_dp_push_iframe(mWRWindowState, builder.Raw(), op.bounds(), op.clip(), op.layersid());
         break;
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -64,25 +64,29 @@ WebRenderCanvasLayer::RenderLayer()
   rect = RelativeToTransformedVisible(GetTransform().TransformBounds(rect));
 
   gfx::Rect clip;
   if (GetClipRect().isSome()) {
       clip = RelativeToTransformedVisible(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
   } else {
       clip = rect;
   }
+
   if (gfxPrefs::LayersDump()) printf_stderr("CanvasLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
+
   gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
   gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
+  WRTextureFilter filter = (mFlags | TextureFlags::USE_NEAREST_FILTER) ? WRTextureFilter::Point : WRTextureFilter::Linear;
+
   WRBridge()->AddWebRenderCommand(
       OpDPPushStackingContext(ToWRRect(relBounds), ToWRRect(overflow), Nothing(), transform, FrameMetrics::NULL_SCROLL_ID));
-  WRBridge()->AddWebRenderCommand(OpDPPushExternalImageId(ToWRRect(rect), ToWRRect(clip), Nothing(), mExternalImageId));
+  WRBridge()->AddWebRenderCommand(OpDPPushExternalImageId(ToWRRect(rect), ToWRRect(clip), Nothing(), filter, mExternalImageId));
+  WRBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 
   if (gfxPrefs::LayersDump()) printf_stderr("CanvasLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
-  WRBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 }
 
 void
 WebRenderCanvasLayer::AttachCompositable()
 {
   mCanvasClient->Connect();
 }
 
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -133,26 +133,28 @@ WebRenderImageLayer::RenderLayer()
   Rect rect(0, 0, size.width, size.height);
 
   Rect clip;
   if (GetClipRect().isSome()) {
       clip = RelativeToTransformedVisible(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
   } else {
       clip = rect;
   }
+
   if (gfxPrefs::LayersDump()) printf_stderr("ImageLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
+
   Rect relBounds = TransformedVisibleBoundsRelativeToParent();
   Rect overflow(0, 0, relBounds.width, relBounds.height);
   Matrix4x4 transform;// = GetTransform();
+  WRTextureFilter filter = (mSamplingFilter == gfx::SamplingFilter::POINT) ? WRTextureFilter::Point : WRTextureFilter::Linear;
+
   WRBridge()->AddWebRenderCommand(
     OpDPPushStackingContext(ToWRRect(relBounds), ToWRRect(overflow), Nothing(), transform, FrameMetrics::NULL_SCROLL_ID));
-
-  WRBridge()->AddWebRenderCommand(OpDPPushExternalImageId(ToWRRect(rect), ToWRRect(clip), Nothing(), mExternalImageId));
-
+  WRBridge()->AddWebRenderCommand(OpDPPushExternalImageId(ToWRRect(rect), ToWRRect(clip), Nothing(), filter, mExternalImageId));
+  WRBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 
   if (gfxPrefs::LayersDump()) printf_stderr("ImageLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
-  WRBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 
   //mContainer->SetImageFactory(originalIF);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderMessageUtils.h
+++ b/gfx/layers/wr/WebRenderMessageUtils.h
@@ -228,11 +228,20 @@ struct ParamTraits<WRImageMask>
   Read(const Message* aMsg, PickleIterator* aIter, WRImageMask* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->image)
         && ReadParam(aMsg, aIter, &aResult->rect)
         && ReadParam(aMsg, aIter, &aResult->repeat);
   }
 };
 
+template<>
+struct ParamTraits<WRTextureFilter>
+  : public ContiguousEnumSerializer<
+        WRTextureFilter,
+        WRTextureFilter::Linear,
+        WRTextureFilter::Sentinel>
+{
+};
+
 } // namespace IPC
 
 #endif // GFX_WEBRENDERMESSAGEUTILS_H
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -69,17 +69,17 @@ WebRenderPaintedLayer::RenderLayer()
   if (gfxPrefs::LayersDump()) printf_stderr("PaintedLayer %p using rect:%s clip:%s\n", this, Stringify(rect).c_str(), Stringify(clip).c_str());
 
   Rect relBounds = TransformedVisibleBoundsRelativeToParent();
   Rect overflow(0, 0, relBounds.width, relBounds.height);
   Matrix4x4 transform;// = GetTransform();
 
   WRBridge()->AddWebRenderCommand(
       OpDPPushStackingContext(ToWRRect(relBounds), ToWRRect(overflow), Nothing(), transform, FrameMetrics::NULL_SCROLL_ID));
-  WRBridge()->AddWebRenderCommand(OpDPPushImage(ToWRRect(rect), ToWRRect(clip), Nothing(), key));
+  WRBridge()->AddWebRenderCommand(OpDPPushImage(ToWRRect(rect), ToWRRect(clip), Nothing(), WRTextureFilter::Linear, key));
   Manager()->AddImageKeyForDiscard(key);
 
   if (gfxPrefs::LayersDump()) printf_stderr("PaintedLayer %p using %s as bounds/overflow, %s for transform\n", this, Stringify(relBounds).c_str(), Stringify(transform).c_str());
   WRBridge()->AddWebRenderCommand(OpDPPopStackingContext());
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -786,33 +786,52 @@ pub struct WrImageMask
 impl WrImageMask
 {
     pub fn to_image_mask(&self) -> ImageMask
     {
         ImageMask { image: self.image, rect: self.rect.to_rect(), repeat: self.repeat }
     }
 }
 
+#[repr(C)]
+pub enum WrTextureFilter
+{
+    Linear,
+    Point,
+}
+impl WrTextureFilter
+{
+    pub fn to_image_rendering(self) -> ImageRendering
+    {
+        match self
+        {
+            WrTextureFilter::Linear => ImageRendering::Auto,
+            WrTextureFilter::Point => ImageRendering::Pixelated,
+        }
+    }
+}
+
 #[no_mangle]
-pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect, mask: *const WrImageMask, key: ImageKey) {
+pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect, mask: *const WrImageMask, filter: WrTextureFilter, key: ImageKey) {
     assert!( unsafe { is_in_compositor_thread() });
 
     let bounds = bounds.to_rect();
     let clip = clip.to_rect();
 
     // convert from the C type to the Rust type, mapping NULL to None
     let mask = unsafe { mask.as_ref().map(|m| m.to_image_mask()) };
+    let image_rendering = filter.to_image_rendering();
 
     let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip, Vec::new(), mask);
     state.frame_builder.dl_builder.push_image(
         bounds,
         clip_region,
         bounds.size,
         bounds.size,
-        ImageRendering::Auto,
+        image_rendering,
         key
     );
 }
 
 #[no_mangle]
 pub extern fn wr_api_add_raw_font(api: &mut RenderApi,
                                   font_buffer: *mut u8,
                                   buffer_size: usize) -> u64
--- a/gfx/webrender_bindings/src/webrender.h
+++ b/gfx/webrender_bindings/src/webrender.h
@@ -131,16 +131,23 @@ struct WRImageMask
     WRRect rect;
     bool repeat;
 
     bool operator==(const WRImageMask& aRhs) const {
       return image == aRhs.image && rect == aRhs.rect && repeat == aRhs.repeat;
     }
 };
 
+enum class WRTextureFilter
+{
+  Linear,
+  Point,
+  Sentinel,
+};
+
 typedef uint64_t WRImageIdType;
 struct WRExternalImageId {
   WRImageIdType id;
 };
 
 enum WRExternalImageType {
     TEXTURE_HANDLE, // Currently, we only support gl texture handle.
     // TODO(Jerry): handle shmem or cpu raw buffers.
@@ -335,17 +342,17 @@ WR_INLINE void
 wr_dp_push_border(WRState* wrState, WRRect bounds, WRRect clip,
                   WRBorderSide top, WRBorderSide right, WRBorderSide bottom, WRBorderSide left,
                   WRLayoutSize top_left_radius, WRLayoutSize top_right_radius,
                   WRLayoutSize bottom_left_radius, WRLayoutSize bottom_right_radius)
 WR_FUNC;
 
 WR_INLINE void
 wr_dp_push_image(WRState* wrState, WRRect bounds, WRRect clip,
-                 const WRImageMask* mask, WRImageKey key)
+                 const WRImageMask* mask, WRTextureFilter filter, WRImageKey key)
 WR_FUNC;
 
 // TODO: Remove.
 WR_INLINE void
 wr_window_dp_push_iframe(wrwindowstate* wrWindow, WRState* wrState, WRRect bounds, WRRect clip,
                    uint64_t layers_id)
 WR_FUNC;
 
--- a/image/test/reftest/downscaling/reftest.list
+++ b/image/test/reftest/downscaling/reftest.list
@@ -82,17 +82,17 @@ fuzzy(20,999) != downscale-2d.html?203,5
 fuzzy(20,999) != downscale-2e.html?203,52,bottom about:blank
 
 fuzzy(20,999) != downscale-2a.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2b.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2c.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2d.html?205,53,bottom about:blank
 fuzzy(20,999) fails-if(OSX>=1008&&!skiaContent) != downscale-2e.html?205,53,bottom about:blank
 
-fuzzy(63,3391) skip-if(/^Linux\x20i686/.test(http.oscpu)) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # linux32 timeout, bug 1328771
+fuzzy(71,3391) skip-if(/^Linux\x20i686/.test(http.oscpu)) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # linux32 timeout, bug 1328771
 
 == downscale-png.html?16,16,interlaced downscale-png.html?16,16,normal
 == downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal
 
 # Non-transparent and transparent ICO images
 == downscale-16px.html?ff-0RGB.ico downscale-16px.html?ff-0RGB.png
 fuzzy(1,1) == downscale-16px.html?ff-ARGB.ico downscale-16px.html?ff-ARGB.png
 
@@ -166,17 +166,17 @@ fuzzy(20,999) != downscale-2f.html?203,5
 fuzzy(20,999) != downscale-2a.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2b.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2c.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2d.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2e.html?205,53,bottom about:blank
 fuzzy(20,999) != downscale-2f.html?205,53,bottom about:blank
 
 # Skip on WinXP with skia content
-fuzzy(71,4439) fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) skip-if(/^Linux\x20i686/.test(http.oscpu)) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # linux32 timeout, bug 1328771
+fuzzy(77,4439) fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) skip-if(/^Linux\x20i686/.test(http.oscpu)) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # linux32 timeout, bug 1328771
 
 == downscale-png.html?16,16,interlaced downscale-png.html?16,16,normal
 == downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal
 
 # Non-transparent and transparent ICO images
 fuzzy(1,3) == downscale-16px.html?ff-0RGB.ico downscale-16px.html?ff-0RGB.png
 fuzzy(3,32) == downscale-16px.html?ff-ARGB.ico downscale-16px.html?ff-ARGB.png