Backed out changeset d727d297aeee for wrong bug number (bug 1319544)
authorLee Salzman <lsalzman@mozilla.com>
Thu, 01 Dec 2016 12:14:50 -0500
changeset 325031 87e3edcefc5bc35b707dc9df00190fbf203b5c8d
parent 325030 d727d297aeeee2e9e490b4285d365d35f9323c8e
child 325032 47e2650093d575c5042b43feb0575ef9678352b1
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
bugs1319544
milestone53.0a1
backs outd727d297aeeee2e9e490b4285d365d35f9323c8e
Backed out changeset d727d297aeee for wrong bug number (bug 1319544)
widget/WindowSurface.h
widget/gtk/WindowSurfaceProvider.cpp
widget/gtk/WindowSurfaceX11.cpp
widget/gtk/WindowSurfaceX11.h
widget/gtk/WindowSurfaceX11Image.cpp
widget/gtk/WindowSurfaceX11Image.h
widget/gtk/WindowSurfaceXRender.cpp
widget/gtk/WindowSurfaceXRender.h
--- a/widget/WindowSurface.h
+++ b/widget/WindowSurface.h
@@ -21,17 +21,14 @@ public:
   // Locks a region of the window for drawing, returning a draw target
   // capturing the bounds of the provided region.
   // Implementations must permit invocation from any thread.
   virtual already_AddRefed<gfx::DrawTarget> Lock(const LayoutDeviceIntRegion& aRegion) = 0;
 
   // Swaps the provided invalid region from the back buffer to the window.
   // Implementations must permit invocation from any thread.
   virtual void Commit(const LayoutDeviceIntRegion& aInvalidRegion) = 0;
-
-  // Whether the window surface represents a fallback method.
-  virtual bool IsFallback() const { return false; }
 };
 
 }  // namespace widget
 }  // namespace mozilla
 
 #endif // _MOZILLA_WIDGET_WINDOW_SURFACE_H
--- a/widget/gtk/WindowSurfaceProvider.cpp
+++ b/widget/gtk/WindowSurfaceProvider.cpp
@@ -88,21 +88,19 @@ WindowSurfaceProvider::StartRemoteDrawin
   if (!mWindowSurface) {
     mWindowSurface = CreateWindowSurface();
     if (!mWindowSurface)
       return nullptr;
   }
 
   *aBufferMode = BufferMode::BUFFER_NONE;
   RefPtr<DrawTarget> dt = nullptr;
-  if (!(dt = mWindowSurface->Lock(aInvalidRegion)) &&
-      !mWindowSurface->IsFallback()) {
+  if (!(dt = mWindowSurface->Lock(aInvalidRegion))) {
     gfxWarningOnce() << "Failed to lock WindowSurface, falling back to XPutImage backend.";
     mWindowSurface = MakeUnique<WindowSurfaceX11Image>(mXDisplay, mXWindow, mXVisual, mXDepth);
-    dt = mWindowSurface->Lock(aInvalidRegion);
   }
   return dt.forget();
 }
 
 void
 WindowSurfaceProvider::EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
                                               LayoutDeviceIntRegion& aInvalidRegion)
 {
--- a/widget/gtk/WindowSurfaceX11.cpp
+++ b/widget/gtk/WindowSurfaceX11.cpp
@@ -15,17 +15,50 @@ WindowSurfaceX11::WindowSurfaceX11(Displ
                                    Window aWindow,
                                    Visual* aVisual,
                                    unsigned int aDepth)
   : mDisplay(aDisplay)
   , mWindow(aWindow)
   , mVisual(aVisual)
   , mDepth(aDepth)
   , mFormat(GetVisualFormat(aVisual, aDepth))
+  , mGC(X11None)
 {
+  MOZ_ASSERT(mFormat != gfx::SurfaceFormat::UNKNOWN,
+             "Could not find SurfaceFormat for visual!");
+}
+
+WindowSurfaceX11::~WindowSurfaceX11()
+{
+  if (mGC != X11None)
+    XFreeGC(mDisplay, mGC);
+}
+
+void
+WindowSurfaceX11::Commit(const LayoutDeviceIntRegion& aInvalidRegion)
+{
+  AutoTArray<XRectangle, 32> xrects;
+  xrects.SetCapacity(aInvalidRegion.GetNumRects());
+
+  for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
+    const mozilla::LayoutDeviceIntRect &r = iter.Get();
+    XRectangle xrect = { (short)r.x, (short)r.y, (unsigned short)r.width, (unsigned short)r.height };
+    xrects.AppendElement(xrect);
+  }
+
+  if (!mGC) {
+    mGC = XCreateGC(mDisplay, mWindow, 0, nullptr);
+    if (!mGC) {
+      NS_WARNING("Couldn't create X11 graphics context for window!");
+      return;
+    }
+  }
+
+  XSetClipRectangles(mDisplay, mGC, 0, 0, xrects.Elements(), xrects.Length(), YXBanded);
+  CommitToDrawable(mWindow, mGC, aInvalidRegion);
 }
 
 /* static */
 gfx::SurfaceFormat
 WindowSurfaceX11::GetVisualFormat(const Visual* aVisual, unsigned int aDepth)
 {
   switch (aDepth) {
   case 32:
--- a/widget/gtk/WindowSurfaceX11.h
+++ b/widget/gtk/WindowSurfaceX11.h
@@ -16,24 +16,36 @@
 
 namespace mozilla {
 namespace widget {
 
 class WindowSurfaceX11 : public WindowSurface {
 public:
   WindowSurfaceX11(Display* aDisplay, Window aWindow, Visual* aVisual,
                    unsigned int aDepth);
+  ~WindowSurfaceX11();
+
+  void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;
+
+  virtual already_AddRefed<gfx::DrawTarget> Lock(const LayoutDeviceIntRegion& aRegion) override = 0;
+
+  // Draws the buffered image onto aDest using the given GC.
+  // The GC provided has been clipped to aInvalidRegion.
+  virtual void CommitToDrawable(Drawable aDest, GC aGC,
+                                const LayoutDeviceIntRegion& aInvalidRegion) = 0;
 
 protected:
   static gfx::SurfaceFormat GetVisualFormat(const Visual* aVisual, unsigned int aDepth);
 
   Display* const mDisplay;
   const Window mWindow;
   Visual* const mVisual;
   const unsigned int mDepth;
   const gfx::SurfaceFormat mFormat;
+
+  GC mGC;
 };
 
 }  // namespace widget
 }  // namespace mozilla
 
 #endif // MOZ_X11
 #endif // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_X11_H
--- a/widget/gtk/WindowSurfaceX11Image.cpp
+++ b/widget/gtk/WindowSurfaceX11Image.cpp
@@ -3,117 +3,75 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WindowSurfaceX11Image.h"
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Tools.h"
-#include "mozilla/gfx/gfxVars.h"
 #include "gfxPlatform.h"
-#include "gfx2DGlue.h"
 
 namespace mozilla {
 namespace widget {
 
 WindowSurfaceX11Image::WindowSurfaceX11Image(Display* aDisplay,
                                              Window aWindow,
                                              Visual* aVisual,
                                              unsigned int aDepth)
   : WindowSurfaceX11(aDisplay, aWindow, aVisual, aDepth)
+  , mImage(nullptr)
 {
 }
 
 WindowSurfaceX11Image::~WindowSurfaceX11Image()
 {
+  if (mImage)
+    XDestroyImage(mImage);
 }
 
 already_AddRefed<gfx::DrawTarget>
 WindowSurfaceX11Image::Lock(const LayoutDeviceIntRegion& aRegion)
 {
   gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
   gfx::IntSize size(bounds.XMost(), bounds.YMost());
 
-  if (!mWindowSurface || mWindowSurface->CairoStatus() ||
-      !(size <= mWindowSurface->GetSize())) {
-    mWindowSurface = new gfxXlibSurface(mDisplay, mWindow, mVisual, size);
-  }
-  if (mWindowSurface->CairoStatus()) {
-    return nullptr;
+  if (!mImage || mImage->width < size.width || mImage->height < size.height) {
+    if (mImage)
+      XDestroyImage(mImage);
+
+    int stride = gfx::GetAlignedStride<16>(size.width, gfx::BytesPerPixel(mFormat));
+    if (stride == 0) {
+        return nullptr;
+    }
+    char* data = static_cast<char*>(malloc(stride * size.height));
+    if (!data)
+      return nullptr;
+
+    mImage = XCreateImage(mDisplay, mVisual, mDepth, ZPixmap, 0,
+                          data, size.width, size.height,
+                          8 * gfx::BytesPerPixel(mFormat), stride);
   }
 
-  if (!mImageSurface || mImageSurface->CairoStatus() ||
-      !(size <= mImageSurface->GetSize())) {
-    gfxImageFormat format = SurfaceFormatToImageFormat(mFormat);
-    if (format == gfx::SurfaceFormat::UNKNOWN) {
-      format = mDepth == 32 ?
-                 gfx::SurfaceFormat::A8R8G8B8_UINT32 :
-                 gfx::SurfaceFormat::X8R8G8B8_UINT32;
-    }
-
-    mImageSurface = new gfxImageSurface(size, format);
-    if (mImageSurface->CairoStatus()) {
-      return nullptr;
-    }
-  }
+  if (!mImage)
+    return nullptr;
 
-  gfxImageFormat format = mImageSurface->Format();
-  // Cairo prefers compositing to BGRX instead of BGRA where possible.
-  if (format == gfx::SurfaceFormat::X8R8G8B8_UINT32) {
-    gfx::BackendType backend = gfxVars::ContentBackend();
-    if (!gfx::Factory::DoesBackendSupportDataDrawtarget(backend)) {
-#ifdef USE_SKIA
-      backend = gfx::BackendType::SKIA;
-#else
-      backend = gfx::BackendType::CAIRO;
-#endif
-    }
-    if (backend != gfx::BackendType::CAIRO) {
-      format = gfx::SurfaceFormat::A8R8G8B8_UINT32;
-    }
-  }
-
-  return gfxPlatform::CreateDrawTargetForData(mImageSurface->Data(),
-                                              mImageSurface->GetSize(),
-                                              mImageSurface->Stride(),
-                                              ImageFormatToSurfaceFormat(format));
+  unsigned char* data = (unsigned char*) mImage->data;
+  return gfxPlatform::CreateDrawTargetForData(data,
+                                              size,
+                                              mImage->bytes_per_line,
+                                              mFormat);
 }
 
 void
-WindowSurfaceX11Image::Commit(const LayoutDeviceIntRegion& aInvalidRegion)
+WindowSurfaceX11Image::CommitToDrawable(Drawable aDest, GC aGC,
+                                        const LayoutDeviceIntRegion& aInvalidRegion)
 {
-  RefPtr<gfx::DrawTarget> dt =
-    gfx::Factory::CreateDrawTargetForCairoSurface(mWindowSurface->CairoSurface(),
-                                                  mWindowSurface->GetSize());
-  RefPtr<gfx::SourceSurface> surf =
-    gfx::Factory::CreateSourceSurfaceForCairoSurface(mImageSurface->CairoSurface(),
-                                                     mImageSurface->GetSize(),
-                                                     mImageSurface->Format());
-  if (!dt || !surf) {
-    return;
-  }
+  MOZ_ASSERT(mImage, "Attempted to commit invalid surface!");
 
   gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect();
-  gfx::Rect rect(0, 0, bounds.XMost(), bounds.YMost());
-  if (rect.IsEmpty()) {
-    return;
-  }
-
-  uint32_t numRects = aInvalidRegion.GetNumRects();
-  if (numRects != 1) {
-    AutoTArray<IntRect, 32> rects;
-    rects.SetCapacity(numRects);
-    for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
-      rects.AppendElement(iter.Get().ToUnknownRect());
-    }
-    dt->PushDeviceSpaceClipRects(rects.Elements(), rects.Length());
-  }
-
-  dt->DrawSurface(surf, rect, rect);
-
-  if (numRects != 1) {
-    dt->PopClip();
-  }
+  gfx::IntSize size(bounds.XMost(), bounds.YMost());
+  XPutImage(mDisplay, aDest, aGC, mImage, bounds.x, bounds.y,
+            bounds.x, bounds.y, size.width, size.height);
 }
 
 }  // namespace widget
 }  // namespace mozilla
--- a/widget/gtk/WindowSurfaceX11Image.h
+++ b/widget/gtk/WindowSurfaceX11Image.h
@@ -5,34 +5,31 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_X11_IMAGE_H
 #define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_X11_IMAGE_H
 
 #ifdef MOZ_X11
 
 #include "WindowSurfaceX11.h"
-#include "gfxXlibSurface.h"
-#include "gfxImageSurface.h"
 
 namespace mozilla {
 namespace widget {
 
 class WindowSurfaceX11Image : public WindowSurfaceX11 {
 public:
   WindowSurfaceX11Image(Display* aDisplay, Window aWindow, Visual* aVisual,
                         unsigned int aDepth);
   ~WindowSurfaceX11Image();
 
   already_AddRefed<gfx::DrawTarget> Lock(const LayoutDeviceIntRegion& aRegion) override;
-  void Commit(const LayoutDeviceIntRegion& aInvalidRegion) override;
-  bool IsFallback() const override { return true; }
+  void CommitToDrawable(Drawable aDest, GC aGC,
+                        const LayoutDeviceIntRegion& aInvalidRegion) override;
 
 private:
-  RefPtr<gfxXlibSurface> mWindowSurface;
-  RefPtr<gfxImageSurface> mImageSurface;
+  XImage* mImage;
 };
 
 }  // namespace widget
 }  // namespace mozilla
 
 #endif // MOZ_X11
 #endif // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_X11_IMAGE_H
--- a/widget/gtk/WindowSurfaceXRender.cpp
+++ b/widget/gtk/WindowSurfaceXRender.cpp
@@ -14,70 +14,46 @@ namespace mozilla {
 namespace widget {
 
 WindowSurfaceXRender::WindowSurfaceXRender(Display* aDisplay,
                                            Window aWindow,
                                            Visual* aVisual,
                                            unsigned int aDepth)
   : WindowSurfaceX11(aDisplay, aWindow, aVisual, aDepth)
   , mXlibSurface(nullptr)
-  , mGC(X11None)
 {
 }
 
-WindowSurfaceXRender::~WindowSurfaceXRender()
-{
-  if (mGC != X11None) {
-    XFreeGC(mDisplay, mGC);
-  }
-}
-
 already_AddRefed<gfx::DrawTarget>
 WindowSurfaceXRender::Lock(const LayoutDeviceIntRegion& aRegion)
 {
   gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
   gfx::IntSize size(bounds.XMost(), bounds.YMost());
-  if (!mXlibSurface || mXlibSurface->CairoStatus() ||
-      !(size <= mXlibSurface->GetSize())) {
+  if (!mXlibSurface || mXlibSurface->CairoStatus() != 0 ||
+      mXlibSurface->GetSize().width < size.width ||
+      mXlibSurface->GetSize().height < size.height)
+  {
     mXlibSurface = gfxXlibSurface::Create(DefaultScreenOfDisplay(mDisplay),
                                           mVisual,
                                           size,
                                           mWindow);
   }
-  if (!mXlibSurface || mXlibSurface->CairoStatus()) {
-    return nullptr;
+
+  if (mXlibSurface && mXlibSurface->CairoStatus() == 0) {
+    return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mXlibSurface.get(), size);
   }
-
-  return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mXlibSurface, size);
+  return nullptr;
 }
 
 void
-WindowSurfaceXRender::Commit(const LayoutDeviceIntRegion& aInvalidRegion)
+WindowSurfaceXRender::CommitToDrawable(Drawable aDest, GC aGC,
+                                       const LayoutDeviceIntRegion& aInvalidRegion)
 {
-  AutoTArray<XRectangle, 32> xrects;
-  xrects.SetCapacity(aInvalidRegion.GetNumRects());
-
-  for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
-    const LayoutDeviceIntRect &r = iter.Get();
-    XRectangle xrect = { (short)r.x, (short)r.y, (unsigned short)r.width, (unsigned short)r.height };
-    xrects.AppendElement(xrect);
-  }
-
-  if (!mGC) {
-    mGC = XCreateGC(mDisplay, mWindow, 0, nullptr);
-    if (!mGC) {
-      NS_WARNING("Couldn't create X11 graphics context for window!");
-      return;
-    }
-  }
-
-  XSetClipRectangles(mDisplay, mGC, 0, 0, xrects.Elements(), xrects.Length(), YXBanded);
-
   MOZ_ASSERT(mXlibSurface && mXlibSurface->CairoStatus() == 0,
              "Attempted to commit invalid surface!");
   gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect();
   gfx::IntSize size(bounds.XMost(), bounds.YMost());
-  XCopyArea(mDisplay, mXlibSurface->XDrawable(), mWindow, mGC, bounds.x, bounds.y,
+  XCopyArea(mDisplay, mXlibSurface->XDrawable(), aDest, aGC, bounds.x, bounds.y,
             size.width, size.height, bounds.x, bounds.y);
 }
 
 }  // namespace widget
 }  // namespace mozilla
--- a/widget/gtk/WindowSurfaceXRender.h
+++ b/widget/gtk/WindowSurfaceXRender.h
@@ -14,23 +14,22 @@
 
 namespace mozilla {
 namespace widget {
 
 class WindowSurfaceXRender : public WindowSurfaceX11 {
 public:
   WindowSurfaceXRender(Display* aDisplay, Window aWindow, Visual* aVisual,
                        unsigned int aDepth);
-  ~WindowSurfaceXRender();
 
   already_AddRefed<gfx::DrawTarget> Lock(const LayoutDeviceIntRegion& aRegion) override;
-  void Commit(const LayoutDeviceIntRegion& aInvalidRegion) override;
+  void CommitToDrawable(Drawable aDest, GC aGC,
+                        const LayoutDeviceIntRegion& aInvalidRegion) override;
 
 private:
   RefPtr<gfxXlibSurface> mXlibSurface;
-  GC mGC;
 };
 
 }  // namespace widget
 }  // namespace mozilla
 
 #endif // MOZ_X11
 #endif // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_XRENDER_H