Bug 924679. Part 6: Remove gfxXlibNativeRender::DrawOutput and convert tmpXlibSurface from gfxXlibSurface to cairo_surface_t. r=karlt
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 25 Oct 2013 23:25:40 +0200
changeset 152584 f3b1b03a815546b8968a6e8f655cf2be396b2f53
parent 152583 e6057ba50267120f87da1e8b3eaf2244b8d97150
child 152585 f31b00b83f666c1f6ec46872912b8c77b8f9e35f
push id25552
push usercbook@mozilla.com
push dateTue, 29 Oct 2013 12:21:45 +0000
treeherdermozilla-central@cd94525c17a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs924679
milestone28.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 924679. Part 6: Remove gfxXlibNativeRender::DrawOutput and convert tmpXlibSurface from gfxXlibSurface to cairo_surface_t. r=karlt
dom/plugins/base/nsPluginInstanceOwner.cpp
gfx/thebes/gfxGdkNativeRenderer.cpp
gfx/thebes/gfxQtNativeRenderer.cpp
gfx/thebes/gfxQtNativeRenderer.h
gfx/thebes/gfxXlibNativeRenderer.cpp
gfx/thebes/gfxXlibNativeRenderer.h
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -2790,17 +2790,17 @@ void nsPluginInstanceOwner::Paint(gfxCon
 
   Renderer renderer(window, this, pluginSize, pluginDirtyRect);
 
   Display* dpy = mozilla::DefaultXDisplay();
   Screen* screen = DefaultScreenOfDisplay(dpy);
   Visual* visual = DefaultVisualOfScreen(screen);
 
   renderer.Draw(aContext, nsIntSize(window->width, window->height),
-                rendererFlags, screen, visual, nullptr);
+                rendererFlags, screen, visual);
 }
 nsresult
 nsPluginInstanceOwner::Renderer::DrawWithXlib(cairo_surface_t* xsurface,
                                               nsIntPoint offset,
                                               nsIntRect *clipRects, 
                                               uint32_t numClipRects)
 {
   Screen *screen = cairo_xlib_surface_get_screen(xsurface);
--- a/gfx/thebes/gfxGdkNativeRenderer.cpp
+++ b/gfx/thebes/gfxGdkNativeRenderer.cpp
@@ -54,16 +54,16 @@ gfxGdkNativeRenderer::Draw(gfxContext* c
 {
     mColormap = colormap;
 
     Visual* visual =
         gdk_x11_visual_get_xvisual(gdk_colormap_get_visual(colormap));
     Screen* screen =
         gdk_x11_screen_get_xscreen(gdk_colormap_get_screen(colormap));
 
-    gfxXlibNativeRenderer::Draw(ctx, size, flags, screen, visual, nullptr);
+    gfxXlibNativeRenderer::Draw(ctx, size, flags, screen, visual);
 }
 
 #else
 // TODO GTK3
 #endif
 
 #endif
--- a/gfx/thebes/gfxQtNativeRenderer.cpp
+++ b/gfx/thebes/gfxQtNativeRenderer.cpp
@@ -4,18 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxQtNativeRenderer.h"
 #include "gfxContext.h"
 #include "gfxXlibSurface.h"
 
 nsresult
 gfxQtNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
-                          uint32_t flags, Screen* screen, Visual* visual,
-                          DrawOutput* output)
+                          uint32_t flags, Screen* screen, Visual* visual)
 {
     Display *dpy = DisplayOfScreen(screen);
     bool isOpaque = (flags & DRAW_IS_OPAQUE) ? true : false;
     int screenNumber = screen - ScreenOfDisplay(dpy, 0);
 
     if (!isOpaque) {
         int depth = 32;
         XVisualInfo vinfo;
--- a/gfx/thebes/gfxQtNativeRenderer.h
+++ b/gfx/thebes/gfxQtNativeRenderer.h
@@ -49,31 +49,23 @@ public:
         // visual passed in must be the default visual for dpy's default screen
         DRAW_SUPPORTS_ALTERNATE_VISUAL = 0x10,
         // If set, then the Screen 'screen' in the callback can be different
         // from the default Screen of the display passed to 'Draw' and can be
         // on a different display.
         DRAW_SUPPORTS_ALTERNATE_SCREEN = 0x20
     };
 
-    struct DrawOutput {
-        nsRefPtr<gfxASurface> mSurface;
-        bool mUniformAlpha;
-        bool mUniformColor;
-        gfxRGBA      mColor;
-    };
-
     /**
      * @param flags see above
      * @param size Draw()'s drawing is guaranteed to be restricted to
      * the rectangle (offset.x,offset.y,size.width,size.height)
      * @param dpy a display to use for the drawing if ctx doesn't have one
      * @param resultSurface if non-null, we will try to capture a copy of the
      * rendered image into a surface similar to the surface of ctx; if
      * successful, a pointer to the new gfxASurface is stored in *resultSurface,
      * otherwise *resultSurface is set to nullptr.
      */
     nsresult Draw(gfxContext* ctx, nsIntSize size,
-                  uint32_t flags, Screen* screen, Visual* visual,
-                  DrawOutput* output);
+                  uint32_t flags, Screen* screen, Visual* visual);
 };
 
 #endif /*GFXQTNATIVERENDER_H_*/
--- a/gfx/thebes/gfxXlibNativeRenderer.cpp
+++ b/gfx/thebes/gfxXlibNativeRenderer.cpp
@@ -8,16 +8,17 @@
 #include "gfxXlibSurface.h"
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxAlphaRecovery.h"
 #include "cairo-xlib.h"
 #include "cairo-xlib-xrender.h"
 #include "mozilla/gfx/BorrowedContext.h"
+#include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 #if 0
 #include <stdio.h>
 #define NATIVE_DRAWING_NOTE(m) fprintf(stderr, m)
 #else
@@ -303,74 +304,72 @@ FormatConversionIsExact(Screen *screen, 
 // The 3 non-direct strategies described above.
 // The surface format and strategy are inter-dependent.
 enum DrawingMethod {
     eSimple,
     eCopyBackground,
     eAlphaExtraction
 };
 
-static already_AddRefed<gfxXlibSurface>
-CreateTempXlibSurface (gfxASurface *destination, nsIntSize size,
+static cairo_surface_t*
+CreateTempXlibSurface (cairo_surface_t* cairoTarget,
+                       DrawTarget* drawTarget,
+                       nsIntSize size,
                        bool canDrawOverBackground,
                        uint32_t flags, Screen *screen, Visual *visual,
                        DrawingMethod *method)
 {
+    NS_ASSERTION(cairoTarget || drawTarget, "Must have some type");
+
     bool drawIsOpaque = (flags & gfxXlibNativeRenderer::DRAW_IS_OPAQUE) != 0;
     bool supportsAlternateVisual =
         (flags & gfxXlibNativeRenderer::DRAW_SUPPORTS_ALTERNATE_VISUAL) != 0;
     bool supportsAlternateScreen = supportsAlternateVisual &&
         (flags & gfxXlibNativeRenderer::DRAW_SUPPORTS_ALTERNATE_SCREEN);
 
-    cairo_surface_t *target = destination->CairoSurface();
-    cairo_surface_type_t target_type = cairo_surface_get_type (target);
-    cairo_content_t target_content = cairo_surface_get_content (target);
+    cairo_surface_type_t cairoTargetType =
+        cairoTarget ? cairo_surface_get_type (cairoTarget) : (cairo_surface_type_t)0xFF;
 
-    Screen *target_screen = target_type == CAIRO_SURFACE_TYPE_XLIB ?
-        cairo_xlib_surface_get_screen (target) : screen;
+    Screen *target_screen = cairoTargetType == CAIRO_SURFACE_TYPE_XLIB ?
+        cairo_xlib_surface_get_screen (cairoTarget) : screen;
 
     // When the background has an alpha channel, we need to draw with an alpha
     // channel anyway, so there is no need to copy the background.  If
     // doCopyBackground is set here, we'll also need to check below that the
     // background can copied without any loss in format conversions.
     bool doCopyBackground = !drawIsOpaque && canDrawOverBackground &&
-        target_content == CAIRO_CONTENT_COLOR;
+        cairoTarget && cairo_surface_get_content (cairoTarget) == CAIRO_CONTENT_COLOR;
 
     if (supportsAlternateScreen && screen != target_screen && drawIsOpaque) {
         // Prefer a visual on the target screen.
         // (If !drawIsOpaque, we'll need doCopyBackground or an alpha channel.)
         visual = DefaultVisualOfScreen(target_screen);
         screen = target_screen;
 
     } else if (doCopyBackground || (supportsAlternateVisual && drawIsOpaque)) {
         // Analyse the pixel formats either to check whether we can
         // doCopyBackground or to see if we can find a better visual for
         // opaque drawing.
         Visual *target_visual = nullptr;
         XRenderPictFormat *target_format = nullptr;
-        switch (target_type) {
-        case CAIRO_SURFACE_TYPE_XLIB:
-            target_visual = cairo_xlib_surface_get_visual (target);
-            target_format = cairo_xlib_surface_get_xrender_format (target);
-            break;
-        case CAIRO_SURFACE_TYPE_IMAGE: {
+        if (cairoTargetType == CAIRO_SURFACE_TYPE_XLIB) {
+            target_visual = cairo_xlib_surface_get_visual (cairoTarget);
+            target_format = cairo_xlib_surface_get_xrender_format (cairoTarget);
+        } else if (cairoTargetType == CAIRO_SURFACE_TYPE_IMAGE || drawTarget) {
             gfxImageFormat imageFormat =
-                static_cast<gfxImageSurface*>(destination)->Format();
+                drawTarget ? SurfaceFormatToImageFormat(drawTarget->GetFormat()) :
+                    (gfxImageFormat)cairo_image_surface_get_format(cairoTarget);
             target_visual = gfxXlibSurface::FindVisual(screen, imageFormat);
             Display *dpy = DisplayOfScreen(screen);
             if (target_visual) {
                 target_format = XRenderFindVisualFormat(dpy, target_visual);
             } else {
                 target_format =
                     gfxXlibSurface::FindRenderFormat(dpy, imageFormat);
             }                
-            break;
-        }
-        default:
-            break;
         }
 
         if (supportsAlternateVisual &&
             (supportsAlternateScreen || screen == target_screen)) {
             if (target_visual) {
                 visual = target_visual;
                 screen = target_screen;
             }
@@ -407,78 +406,75 @@ CreateTempXlibSurface (gfxASurface *dest
                                            gfxImageFormatRGB24);
             if (rgb24Visual) {
                 visual = rgb24Visual;
             }
         }
     }
 
     Drawable drawable =
-        (screen == target_screen && target_type == CAIRO_SURFACE_TYPE_XLIB) ?
-        cairo_xlib_surface_get_drawable (target) : RootWindowOfScreen(screen);
+        (screen == target_screen && cairoTargetType == CAIRO_SURFACE_TYPE_XLIB) ?
+        cairo_xlib_surface_get_drawable (cairoTarget) : RootWindowOfScreen(screen);
 
-    nsRefPtr<gfxXlibSurface> surface =
-        gfxXlibSurface::Create(screen, visual,
-                               gfxIntSize(size.width, size.height),
-                               drawable);
+    cairo_surface_t *surface =
+        gfxXlibSurface::CreateCairoSurface(screen, visual,
+                                           gfxIntSize(size.width, size.height),
+                                           drawable);
+    if (!surface) {
+        return nullptr;
+    }
 
     if (drawIsOpaque ||
-        surface->GetContentType() == GFX_CONTENT_COLOR_ALPHA) {
+        cairo_surface_get_content(surface) == CAIRO_CONTENT_COLOR_ALPHA) {
         NATIVE_DRAWING_NOTE(drawIsOpaque ?
                             ", SIMPLE OPAQUE\n" : ", SIMPLE WITH ALPHA");
         *method = eSimple;
     } else if (doCopyBackground) {
         NATIVE_DRAWING_NOTE(", COPY BACKGROUND\n");
         *method = eCopyBackground;
     } else {
         NATIVE_DRAWING_NOTE(", SLOW ALPHA EXTRACTION\n");
         *method = eAlphaExtraction;
     }
 
-    return surface.forget();
+    return surface;
 }
 
 bool
-gfxXlibNativeRenderer::DrawOntoTempSurface(gfxXlibSurface *tempXlibSurface,
+gfxXlibNativeRenderer::DrawOntoTempSurface(cairo_surface_t *tempXlibSurface,
                                            nsIntPoint offset)
 {
-    tempXlibSurface->Flush();
+    cairo_surface_flush(tempXlibSurface);
     /* no clipping is needed because the callback can't draw outside the native
        surface anyway */
-    nsresult rv = DrawWithXlib(tempXlibSurface->CairoSurface(), offset, nullptr, 0);
-    tempXlibSurface->MarkDirty();
+    nsresult rv = DrawWithXlib(tempXlibSurface, offset, nullptr, 0);
+    cairo_surface_mark_dirty(tempXlibSurface);
     return NS_SUCCEEDED(rv);
 }
 
 static already_AddRefed<gfxImageSurface>
-CopyXlibSurfaceToImage(gfxXlibSurface *tempXlibSurface,
+CopyXlibSurfaceToImage(cairo_surface_t *tempXlibSurface,
+                       gfxIntSize size,
                        gfxImageFormat format)
 {
-    nsRefPtr<gfxImageSurface> result =
-        new gfxImageSurface(tempXlibSurface->GetSize(), format);
+    nsRefPtr<gfxImageSurface> result = new gfxImageSurface(size, format);
 
-    gfxContext copyCtx(result);
-    copyCtx.SetSource(tempXlibSurface);
-    copyCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
-    copyCtx.Paint();
+    cairo_t* copyCtx = cairo_create(result->CairoSurface());
+    cairo_set_source_surface(copyCtx, tempXlibSurface, 0, 0);
+    cairo_set_operator(copyCtx, CAIRO_OPERATOR_SOURCE);
+    cairo_paint(copyCtx);
+    cairo_destroy(copyCtx);
 
     return result.forget();
 }
 
 void
 gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
-                            uint32_t flags, Screen *screen, Visual *visual,
-                            DrawOutput* result)
+                            uint32_t flags, Screen *screen, Visual *visual)
 {
-    if (result) {
-        result->mSurface = nullptr;
-        result->mUniformAlpha = false;
-        result->mUniformColor = false;
-    }
-
     gfxMatrix matrix = ctx->CurrentMatrix();
 
     // We can only draw direct or onto a copied background if pixels align and
     // native drawing is compatible with the current operator.  (The matrix is
     // actually also pixel-exact for flips and right-angle rotations, which
     // would permit copying the background but not drawing direct.)
     bool matrixIsIntegerTranslation = !matrix.HasNonIntegerTranslation();
     bool canDrawOverBackground = matrixIsIntegerTranslation &&
@@ -525,154 +521,115 @@ gfxXlibNativeRenderer::Draw(gfxContext* 
     clipExtents.RoundOut();
 
     nsIntRect intExtents(int32_t(clipExtents.X()),
                          int32_t(clipExtents.Y()),
                          int32_t(clipExtents.Width()),
                          int32_t(clipExtents.Height()));
     drawingRect.IntersectRect(drawingRect, intExtents);
 
-    if (ctx->IsCairo()) {
-        nsRefPtr<gfxASurface> target(ctx->CurrentSurface());
-        DrawFallback(nullptr, ctx, target, size, drawingRect, canDrawOverBackground,
-                     flags, screen, visual, result);
-    } else {
-        DrawTarget* drawTarget = ctx->GetDrawTarget();
-        if (!drawTarget) {
-            return;
-        }
-
-        nsRefPtr<gfxASurface> target = gfxPlatform::GetPlatform()->
-            GetThebesSurfaceForDrawTarget(drawTarget);
-        if (!target) {
-            return;
-        }
-        DrawFallback(drawTarget, ctx, target, size, drawingRect, canDrawOverBackground,
-                     flags, screen, visual, result);
-    }
-}
-
-void
-gfxXlibNativeRenderer::DrawFallback(DrawTarget* drawTarget, gfxContext* ctx, gfxASurface* target,
-                                    nsIntSize& size, nsIntRect& drawingRect,
-                                    bool canDrawOverBackground, uint32_t flags,
-                                    Screen* screen, Visual* visual, DrawOutput* result)
-{
     gfxPoint offset(drawingRect.x, drawingRect.y);
 
     DrawingMethod method;
-    nsRefPtr<gfxXlibSurface> tempXlibSurface = 
-        CreateTempXlibSurface(target, drawingRect.Size(),
+    cairo_surface_t* cairoTarget = nullptr;
+    DrawTarget* drawTarget = nullptr;
+    if (ctx->IsCairo()) {
+        cairoTarget = cairo_get_group_target(ctx->GetCairo());
+    } else {
+        drawTarget = ctx->GetDrawTarget();
+        cairoTarget = static_cast<cairo_surface_t*>
+            (drawTarget->GetNativeSurface(NATIVE_SURFACE_CAIRO_SURFACE));
+    }
+
+    cairo_surface_t* tempXlibSurface =
+        CreateTempXlibSurface(cairoTarget, drawTarget, size,
                               canDrawOverBackground, flags, screen, visual,
                               &method);
     if (!tempXlibSurface)
         return;
 
-    if (drawingRect.Size() != size || method == eCopyBackground) {
-        // Only drawing a portion, or copying background,
-        // so won't return a result.
-        result = nullptr;
-    }
-  
-    nsRefPtr<gfxContext> tmpCtx;
     bool drawIsOpaque = (flags & DRAW_IS_OPAQUE) != 0;
     if (!drawIsOpaque) {
-        tmpCtx = new gfxContext(tempXlibSurface);
+        cairo_t* tmpCtx = cairo_create(tempXlibSurface);
         if (method == eCopyBackground) {
-            tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
-            tmpCtx->SetSource(target, -(offset + ctx->CurrentMatrix().GetTranslation()));
+            NS_ASSERTION(cairoTarget, "eCopyBackground only used when there's a cairoTarget");
+            cairo_set_operator(tmpCtx, CAIRO_OPERATOR_SOURCE);
+            gfxPoint pt = -(offset + ctx->CurrentMatrix().GetTranslation());
+            cairo_set_source_surface(tmpCtx, cairoTarget, pt.x, pt.y);
             // The copy from the tempXlibSurface to the target context should
             // use operator SOURCE, but that would need a mask to bound the
             // operation.  Here we only copy opaque backgrounds so operator
             // OVER will behave like SOURCE masked by the surface.
-            NS_ASSERTION(tempXlibSurface->GetContentType()
-                         == GFX_CONTENT_COLOR,
+            NS_ASSERTION(cairo_surface_get_content(tempXlibSurface) == CAIRO_CONTENT_COLOR,
                          "Don't copy background with a transparent surface");
         } else {
-            tmpCtx->SetOperator(gfxContext::OPERATOR_CLEAR);
+            cairo_set_operator(tmpCtx, CAIRO_OPERATOR_CLEAR);
         }
-        tmpCtx->Paint();
+        cairo_paint(tmpCtx);
+        cairo_destroy(tmpCtx);
     }
 
     if (!DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft())) {
+        cairo_surface_destroy(tempXlibSurface);
         return;
     }
   
+    SurfaceFormat moz2DFormat =
+        cairo_surface_get_content(tempXlibSurface) == CAIRO_CONTENT_COLOR ?
+            FORMAT_B8G8R8A8 : FORMAT_B8G8R8X8;
     if (method != eAlphaExtraction) {
         if (drawTarget) {
-            RefPtr<SourceSurface> sourceSurface = gfxPlatform::GetPlatform()->
-                GetSourceSurfaceForSurface(drawTarget, tempXlibSurface);
-            drawTarget->DrawSurface(sourceSurface,
-                Rect(offset.x, offset.y, size.width, size.height),
-                Rect(0, 0, size.width, size.height));
+            // It doesn't matter if moz2DFormat doesn't exactly match the format
+            // of tempXlibSurface, since this DrawTarget just wraps the cairo
+            // drawing.
+            RefPtr<SourceSurface> sourceSurface =
+                Factory::CreateSourceSurfaceForCairoSurface(tempXlibSurface,
+                                                            moz2DFormat);
+            if (sourceSurface) {
+                drawTarget->DrawSurface(sourceSurface,
+                    Rect(offset.x, offset.y, size.width, size.height),
+                    Rect(0, 0, size.width, size.height));
+            }
         } else {
-            ctx->SetSource(tempXlibSurface, offset);
+            nsRefPtr<gfxASurface> tmpSurf = gfxASurface::Wrap(tempXlibSurface);
+            ctx->SetSource(tmpSurf, offset);
             ctx->Paint();
         }
-        if (result) {
-            result->mSurface = tempXlibSurface;
-            /* fill in the result with what we know, which is really just what our
-               assumption was */
-            result->mUniformAlpha = true;
-            result->mColor.a = 1.0;
-        }
+        cairo_surface_destroy(tempXlibSurface);
         return;
     }
     
     nsRefPtr<gfxImageSurface> blackImage =
-        CopyXlibSurfaceToImage(tempXlibSurface, gfxImageFormatARGB32);
+        CopyXlibSurfaceToImage(tempXlibSurface, size, gfxImageFormatARGB32);
     
-    tmpCtx->SetDeviceColor(gfxRGBA(1.0, 1.0, 1.0));
-    tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
-    tmpCtx->Paint();
+    cairo_t* tmpCtx = cairo_create(tempXlibSurface);
+    cairo_set_source_rgba(tmpCtx, 1.0, 1.0, 1.0, 1.0);
+    cairo_set_operator(tmpCtx, CAIRO_OPERATOR_SOURCE);
+    cairo_paint(tmpCtx);
+    cairo_destroy(tmpCtx);
     DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft());
     nsRefPtr<gfxImageSurface> whiteImage =
-        CopyXlibSurfaceToImage(tempXlibSurface, gfxImageFormatRGB24);
+        CopyXlibSurfaceToImage(tempXlibSurface, size, gfxImageFormatRGB24);
   
     if (blackImage->CairoStatus() == CAIRO_STATUS_SUCCESS &&
         whiteImage->CairoStatus() == CAIRO_STATUS_SUCCESS) {
-        gfxAlphaRecovery::Analysis analysis;
-        if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage,
-                                            result ? &analysis : nullptr))
+        if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage, nullptr)) {
+            cairo_surface_destroy(tempXlibSurface);
             return;
+        }
 
         gfxASurface* paintSurface = blackImage;
-        /* if the caller wants to retrieve the rendered image, put it into
-           a 'similar' surface, and use that as the source for the drawing right
-           now. This means we always return a surface similar to the surface
-           used for 'cr', which is ideal if it's going to be cached and reused.
-           We do not return an image if the result has uniform color (including
-           alpha). */
-        if (result) {
-            if (analysis.uniformAlpha) {
-                result->mUniformAlpha = true;
-                result->mColor.a = analysis.alpha;
+        if (drawTarget) {
+            RefPtr<SourceSurface> sourceSurface =
+                Factory::CreateSourceSurfaceForCairoSurface(paintSurface->CairoSurface(),
+                                                            moz2DFormat);
+            if (sourceSurface) {
+                drawTarget->DrawSurface(sourceSurface,
+                    Rect(offset.x, offset.y, size.width, size.height),
+                    Rect(0, 0, size.width, size.height));
             }
-            if (analysis.uniformColor) {
-                result->mUniformColor = true;
-                result->mColor.r = analysis.r;
-                result->mColor.g = analysis.g;
-                result->mColor.b = analysis.b;
-            } else {
-                result->mSurface = target->
-                    CreateSimilarSurface(GFX_CONTENT_COLOR_ALPHA,
-                                         gfxIntSize(size.width, size.height));
-
-                gfxContext copyCtx(result->mSurface);
-                copyCtx.SetSource(blackImage);
-                copyCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
-                copyCtx.Paint();
-
-                paintSurface = result->mSurface;
-            }
-        }
-        if (drawTarget) {
-            RefPtr<SourceSurface> sourceSurface = gfxPlatform::GetPlatform()->
-                GetSourceSurfaceForSurface(drawTarget, paintSurface);
-            drawTarget->DrawSurface(sourceSurface,
-                Rect(offset.x, offset.y, size.width, size.height),
-                Rect(0, 0, size.width, size.height));
         } else {
             ctx->SetSource(paintSurface, offset);
             ctx->Paint();
         }
     }
+    cairo_surface_destroy(tempXlibSurface);
 }
--- a/gfx/thebes/gfxXlibNativeRenderer.h
+++ b/gfx/thebes/gfxXlibNativeRenderer.h
@@ -1,33 +1,33 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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/. */
 
 #ifndef GFXXLIBNATIVERENDER_H_
 #define GFXXLIBNATIVERENDER_H_
 
-#include "gfxColor.h"
-#include "nsAutoPtr.h"
+#include "nsPoint.h"
+#include "nsRect.h"
 #include <X11/Xlib.h>
 
 namespace mozilla {
 namespace gfx {
   class DrawTarget;
 }
 }
 
 class gfxASurface;
-class gfxXlibSurface;
 class gfxContext;
 struct nsIntRect;
 struct nsIntPoint;
 struct nsIntSize;
 typedef struct _cairo cairo_t;
+typedef struct _cairo_surface cairo_surface_t;
 
 /**
  * This class lets us take code that draws into an X drawable and lets us
  * use it to draw into any Thebes context. The user should subclass this class,
  * override DrawWithXib, and then call Draw(). The drawing will be subjected
  * to all Thebes transformations, clipping etc.
  */
 class gfxXlibNativeRenderer {
@@ -65,50 +65,41 @@ public:
         // passed to 'Draw'.
         DRAW_SUPPORTS_ALTERNATE_VISUAL = 0x10,
         // If set, then the Screen 'screen' in the callback can be different
         // from the default Screen of the display passed to 'Draw' and can be
         // on a different display.
         DRAW_SUPPORTS_ALTERNATE_SCREEN = 0x20
     };
 
-    struct DrawOutput {
-        nsRefPtr<gfxASurface> mSurface;
-        bool mUniformAlpha;
-        bool mUniformColor;
-        gfxRGBA      mColor;
-    };
-
     /**
      * @param flags see above
      * @param size the size of the rectangle being drawn;
      * the caller guarantees that drawing will not extend beyond the rectangle
      * (0,0,size.width,size.height).
      * @param screen a Screen to use for the drawing if ctx doesn't have one.
      * @param visual a Visual to use for the drawing if ctx doesn't have one.
      * @param result if non-null, we will try to capture a copy of the
      * rendered image into a surface similar to the surface of ctx; if
      * successful, a pointer to the new gfxASurface is stored in *resultSurface,
      * otherwise *resultSurface is set to nullptr.
      */
     void Draw(gfxContext* ctx, nsIntSize size,
-              uint32_t flags, Screen *screen, Visual *visual,
-              DrawOutput* result);
+              uint32_t flags, Screen *screen, Visual *visual);
 
 private:
     bool DrawDirect(gfxContext *ctx, nsIntSize bounds,
                     uint32_t flags, Screen *screen, Visual *visual);
 
     bool DrawCairo(cairo_t* cr, nsIntSize size,
                    uint32_t flags, Screen *screen, Visual *visual);
 
     void DrawFallback(mozilla::gfx::DrawTarget* dt, gfxContext* ctx,
                       gfxASurface* aSurface, nsIntSize& size,
                       nsIntRect& drawingRect, bool canDrawOverBackground,
-                      uint32_t flags, Screen* screen, Visual* visual,
-                      DrawOutput* result);
+                      uint32_t flags, Screen* screen, Visual* visual);
 
-    bool DrawOntoTempSurface(gfxXlibSurface *tempXlibSurface,
+    bool DrawOntoTempSurface(cairo_surface_t *tempXlibSurface,
                              nsIntPoint offset);
 
 };
 
 #endif /*GFXXLIBNATIVERENDER_H_*/