-    // AllocExclusive should not be needed for this internal function
-    wxASSERT(m_refData->GetRefCount() == 1);
-    wxASSERT(M_BMPDATA->m_pixbuf == NULL);
-    M_BMPDATA->m_pixbuf = pixbuf;
-    M_BMPDATA->m_width = gdk_pixbuf_get_width(pixbuf);
-    M_BMPDATA->m_height = gdk_pixbuf_get_height(pixbuf);
-    // if depth specified
-    if (depth != 0)
-        M_BMPDATA->m_bpp = depth;
-    else if (M_BMPDATA->m_bpp == 0)
-        // use something reasonable
-        M_BMPDATA->m_bpp = wxTheApp->GetGdkVisual()->depth;
-    PurgeOtherRepresentations(Pixbuf);
+GdkPixbuf *wxBitmap::GetPixbuf() const
+{
+    wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
+
+    wxBitmapRefData* bmpData = M_BMPDATA;
+#ifdef __WXGTK3__
+    if (bmpData->m_pixbufMask)
+        return bmpData->m_pixbufMask;
+
+    if (bmpData->m_pixbufNoMask == NULL)
+        GetPixbufNoMask();
+    cairo_surface_t* mask = NULL;
+    if (bmpData->m_mask)
+        mask = *bmpData->m_mask;
+    if (mask == NULL)
+        return bmpData->m_pixbufNoMask;
+
+    const int w = bmpData->m_width;
+    const int h = bmpData->m_height;
+    bmpData->m_pixbufMask = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, w, h);
+
+    guchar* dst = gdk_pixbuf_get_pixels(bmpData->m_pixbufMask);
+    const int dstStride = gdk_pixbuf_get_rowstride(bmpData->m_pixbufMask);
+    CopyImageData(dst, 4, dstStride,
+        gdk_pixbuf_get_pixels(bmpData->m_pixbufNoMask),
+        gdk_pixbuf_get_n_channels(bmpData->m_pixbufNoMask),
+        gdk_pixbuf_get_rowstride(bmpData->m_pixbufNoMask),
+        w, h);
+
+    const guchar* src = cairo_image_surface_get_data(mask);
+    const int srcStride = cairo_image_surface_get_stride(mask);
+    for (int j = 0; j < h; j++, src += srcStride, dst += dstStride)
+        for (int i = 0; i < w; i++)
+            if (src[i] == 0)
+                dst[i * 4 + 3] = 0;
+
+    return bmpData->m_pixbufMask;
+#else
+    if (bmpData->m_pixbuf)
+        return bmpData->m_pixbuf;
+
+    const int w = bmpData->m_width;
+    const int h = bmpData->m_height;
+    GdkPixmap* mask = NULL;
+    if (bmpData->m_mask)
+        mask = *bmpData->m_mask;
+    const bool useAlpha = bmpData->m_alphaRequested || mask;
+    bmpData->m_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, useAlpha, 8, w, h);
+    if (bmpData->m_pixmap)
+        PixmapToPixbuf(bmpData->m_pixmap, bmpData->m_pixbuf, w, h);
+    if (mask)
+        MaskToAlpha(mask, bmpData->m_pixbuf, w, h);
+    return bmpData->m_pixbuf;
+#endif
+}
+
+#ifndef __WXGTK3__
+bool wxBitmap::HasPixbuf() const
+{
+    wxCHECK_MSG( IsOk(), false, wxT("invalid bitmap") );
+
+    return M_BMPDATA->m_pixbuf != NULL;