Bug 1450814 - generic implementation of DrawTarget::Blur using LockBits. r=rhunt a=jcristau
authorLee Salzman <lsalzman@mozilla.com>
Tue, 10 Apr 2018 16:46:32 -0400
changeset 460909 2a0555131c04bffedb7a71be27ca97a3f8303d92
parent 460908 28ef3feed53a152327570e700ffa83d9dc0a5baf
child 460910 c5734a8b1d7a590e4d1c54cdbf90ea0fa348f9d6
push id9093
push userarchaeopteryx@coole-files.de
push dateThu, 19 Apr 2018 16:07:07 +0000
treeherdermozilla-beta@d84374efea51 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhunt, jcristau
bugs1450814
milestone60.0
Bug 1450814 - generic implementation of DrawTarget::Blur using LockBits. r=rhunt a=jcristau MozReview-Commit-ID: 2jROASoiPQd
gfx/2d/2D.h
gfx/2d/DrawTarget.cpp
gfx/2d/DrawTargetSkia.cpp
gfx/2d/DrawTargetSkia.h
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1254,19 +1254,17 @@ public:
    * onto the target in device space using POINT sampling and operator over.
    */
   virtual void PopLayer() { MOZ_CRASH("GFX: PopLayer"); }
 
   /**
    * Perform an in-place blur operation. This is only supported on data draw
    * targets.
    */
-  virtual void Blur(const AlphaBoxBlur& aBlur) {
-    MOZ_CRASH("GFX: DoBlur");
-  }
+  virtual void Blur(const AlphaBoxBlur& aBlur);
 
   /**
    * Create a SourceSurface optimized for use with this DrawTarget from
    * existing bitmap data in memory.
    *
    * The SourceSurface does not take ownership of aData, and may be freed at any time.
    */
   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
--- a/gfx/2d/DrawTarget.cpp
+++ b/gfx/2d/DrawTarget.cpp
@@ -263,10 +263,30 @@ DrawTarget::IntoLuminanceSource(Luminanc
   }
 
   maskSurface->Unmap();
   destMaskSurface->Unmap();
 
   return destMaskSurface.forget();
 }
 
+void
+DrawTarget::Blur(const AlphaBoxBlur& aBlur)
+{
+  uint8_t* data;
+  IntSize size;
+  int32_t stride;
+  SurfaceFormat format;
+  if (!LockBits(&data, &size, &stride, &format)) {
+    gfxWarning() << "Cannot perform in-place blur on non-data DrawTarget";
+    return;
+  }
+
+  // Sanity check that the blur size matches the draw target.
+  MOZ_ASSERT(size == aBlur.GetSize());
+  MOZ_ASSERT(stride == aBlur.GetStride());
+  aBlur.Blur(data);
+
+  ReleaseBits(data);
+}
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -2236,35 +2236,16 @@ DrawTargetSkia::PopLayer()
   mPushedLayers.pop_back();
 
 #ifdef MOZ_WIDGET_COCOA
   CGContextRelease(mCG);
   mCG = nullptr;
 #endif
 }
 
-void
-DrawTargetSkia::Blur(const AlphaBoxBlur& aBlur)
-{
-  MarkChanged();
-  Flush();
-
-  SkPixmap pixmap;
-  if (!mCanvas->peekPixels(&pixmap)) {
-    gfxWarning() << "Cannot perform in-place blur on non-raster Skia surface";
-    return;
-  }
-
-  // Sanity check that the blur size matches the draw target.
-  MOZ_ASSERT(pixmap.width() == aBlur.GetSize().width);
-  MOZ_ASSERT(pixmap.height() == aBlur.GetSize().height);
-  MOZ_ASSERT(size_t(aBlur.GetStride()) == pixmap.rowBytes());
-  aBlur.Blur(static_cast<uint8_t*>(pixmap.writable_addr()));
-}
-
 already_AddRefed<GradientStops>
 DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode) const
 {
   std::vector<GradientStop> stops;
   stops.resize(aNumStops);
   for (uint32_t i = 0; i < aNumStops; i++) {
     stops[i] = aStops[i];
   }
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -111,17 +111,16 @@ public:
                          bool aCopyBackground = false) override;
   virtual void PushLayerWithBlend(bool aOpaque, Float aOpacity,
                                   SourceSurface* aMask,
                                   const Matrix& aMaskTransform,
                                   const IntRect& aBounds = IntRect(),
                                   bool aCopyBackground = false,
                                   CompositionOp aCompositionOp = CompositionOp::OP_OVER) override;
   virtual void PopLayer() override;
-  virtual void Blur(const AlphaBoxBlur& aBlur) override;
   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
                                                             const IntSize &aSize,
                                                             int32_t aStride,
                                                             SurfaceFormat aFormat) const override;
   virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const override;
   virtual already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(SourceSurface *aSurface) const override;
   virtual already_AddRefed<SourceSurface>
     CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const override;