int
TestNewSurface () {
    int failures = 0;
    int destroyed = 0;

    nsRefPtr<gfxASurface> s = new gfxImageSurface (gfxIntSize(10, 10), gfxImageFormat::ARGB32);
    cairo_surface_t *cs = s->CairoSurface();

    cairo_surface_set_user_data (cs, &destruction_key, &destroyed, SurfaceDestroyNotifier);

    failures += CheckInt (GetASurfaceRefCount(s.get()), 1);
    failures += CheckInt (cairo_surface_get_reference_count(cs), 1);
    failures += CheckInt (destroyed, 0);

    cairo_surface_reference(cs);

    failures += CheckInt (GetASurfaceRefCount(s.get()), 2);
    failures += CheckInt (cairo_surface_get_reference_count(cs), 2);
    failures += CheckInt (destroyed, 0);

    gfxASurface *savedWrapper = s.get();

    s = nullptr;

    failures += CheckInt (cairo_surface_get_reference_count(cs), 1);
    failures += CheckInt (destroyed, 0);

    s = gfxASurface::Wrap(cs);

    failures += CheckPointer (s.get(), savedWrapper);
    failures += CheckInt (GetASurfaceRefCount(s.get()), 2);
    failures += CheckInt (cairo_surface_get_reference_count(cs), 2);
    failures += CheckInt (destroyed, 0);

    cairo_surface_destroy(cs);

    failures += CheckInt (GetASurfaceRefCount(s.get()), 1);
    failures += CheckInt (cairo_surface_get_reference_count(cs), 1);
    failures += CheckInt (destroyed, 0);

    s = nullptr;

    failures += CheckInt (destroyed, 1);

    return failures;
}
static cairo_test_status_t
test_cairo_surface_get_reference_count (cairo_surface_t *surface)
{
    unsigned int refcount = cairo_surface_get_reference_count (surface);
    if (refcount > 0)
        return CAIRO_TEST_SUCCESS;
    /* inert error surfaces have a refcount of 0 */
    return cairo_surface_status (surface) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
}
ImageGStreamer::~ImageGStreamer()
{
    if (m_image)
        m_image.clear();

    m_image = 0;

    if (m_surface && cairo_surface_get_reference_count(m_surface))
        cairo_surface_destroy(m_surface);

    m_surface = 0;
}
int
TestExistingSurface () {
    int failures = 0;
    int destroyed = 0;

    cairo_surface_t *cs = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);

    cairo_surface_set_user_data (cs, &destruction_key, &destroyed, SurfaceDestroyNotifier);

    failures += CheckInt (cairo_surface_get_reference_count(cs), 1);
    failures += CheckInt (destroyed, 0);

    nsRefPtr<gfxASurface> s = gfxASurface::Wrap(cs);

    failures += CheckInt (GetASurfaceRefCount(s.get()), 2);

    cairo_surface_reference(cs);

    failures += CheckInt (GetASurfaceRefCount(s.get()), 3);
    failures += CheckInt (cairo_surface_get_reference_count(cs), 3);
    failures += CheckInt (destroyed, 0);

    gfxASurface *savedWrapper = s.get();

    s = nullptr;

    failures += CheckInt (cairo_surface_get_reference_count(cs), 2);
    failures += CheckInt (destroyed, 0);

    s = gfxASurface::Wrap(cs);

    failures += CheckPointer (s.get(), savedWrapper);
    failures += CheckInt (GetASurfaceRefCount(s.get()), 3);
    failures += CheckInt (cairo_surface_get_reference_count(cs), 3);
    failures += CheckInt (destroyed, 0);

    cairo_surface_destroy(cs);

    failures += CheckInt (GetASurfaceRefCount(s.get()), 2);
    failures += CheckInt (cairo_surface_get_reference_count(cs), 2);
    failures += CheckInt (destroyed, 0);

    s = nullptr;

    failures += CheckInt (cairo_surface_get_reference_count(cs), 1);
    failures += CheckInt (destroyed, 0);

    cairo_surface_destroy(cs);

    failures += CheckInt (destroyed, 1);

    return failures;
}
Example #5
0
// Surfaces use refcounting that's tied to the cairo surface refcnt, to avoid
// refcount mismatch issues.
nsrefcnt
gfxASurface::AddRef(void)
{
    if (mSurfaceValid) {
        if (mFloatingRefs) {
            // eat a floating ref
            mFloatingRefs--;
        } else {
            cairo_surface_reference(mSurface);
        }

        return (nsrefcnt) cairo_surface_get_reference_count(mSurface);
    } else {
        // the surface isn't valid, but we still need to refcount
        // the gfxASurface
        return ++mFloatingRefs;
    }
}
Example #6
0
nsrefcnt
gfxASurface::Release(void)
{
    if (mSurfaceValid) {
        NS_ASSERTION(mFloatingRefs == 0, "gfxASurface::Release with floating refs still hanging around!");

        // Note that there is a destructor set on user data for mSurface,
        // which will delete this gfxASurface wrapper when the surface's refcount goes
        // out of scope.
        nsrefcnt refcnt = (nsrefcnt) cairo_surface_get_reference_count(mSurface);
        cairo_surface_destroy(mSurface);

        // |this| may not be valid any more, don't use it!

        return --refcnt;
    } else {
        if (--mFloatingRefs == 0) {
            delete this;
            return 0;
        }

        return mFloatingRefs;
    }
}
Example #7
0
static void
byzanz_encoder_gstreamer_need_data (GstAppSrc *src, guint length, gpointer data)
{
  ByzanzEncoder *encoder = data;
  ByzanzEncoderGStreamer *gst = data;
  GstBuffer *buffer;
  cairo_t *cr;
  cairo_surface_t *surface;
  cairo_region_t *region;
  GError *error = NULL;
  guint64 msecs;
  int i, num_rects;

  if (!byzanz_deserialize (encoder->input_stream, &msecs, &surface, &region, encoder->cancellable, &error)) {
    gst_element_message_full (GST_ELEMENT (src), GST_MESSAGE_ERROR,
        error->domain, error->code, g_strdup (error->message), NULL, __FILE__, GST_FUNCTION, __LINE__);
    g_error_free (error);
    return;
  }

  if (surface == NULL) {
    gst_app_src_end_of_stream (gst->src);
    if (gst->audiosrc)
      gst_element_send_event (gst->audiosrc, gst_event_new_eos ());
    return;
  }

  if (cairo_surface_get_reference_count (gst->surface) > 1) {
    cairo_surface_t *copy = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
        cairo_image_surface_get_width (gst->surface), cairo_image_surface_get_height (gst->surface));
    
    cr = cairo_create (copy);
    cairo_set_source_surface (cr, gst->surface, 0, 0);
    cairo_paint (cr);
    cairo_destroy (cr);

    cairo_surface_destroy (gst->surface);
    gst->surface = copy;
  }
  cr = cairo_create (gst->surface);
  cairo_set_source_surface (cr, surface, 0, 0);

  num_rects = cairo_region_num_rectangles (region);
  for (i = 0; i < num_rects; i++) {
    cairo_rectangle_int_t rect;
    cairo_region_get_rectangle (region, i, &rect);
    cairo_rectangle (cr, rect.x, rect.y,
                     rect.width, rect.height);
  }

  cairo_fill (cr);
  cairo_destroy (cr);

  /* create a buffer and send it */
  /* FIXME: stride just works? */
  cairo_surface_reference (gst->surface);
  buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
                                        cairo_image_surface_get_data (gst->surface),
                                        cairo_image_surface_get_stride (gst->surface) * cairo_image_surface_get_height (gst->surface),
                                        0,
                                        cairo_image_surface_get_stride (gst->surface) * cairo_image_surface_get_height (gst->surface),
                                        gst->surface,
                                        (GDestroyNotify) cairo_surface_destroy);
  GST_BUFFER_TIMESTAMP (buffer) = msecs * GST_MSECOND;
  gst_app_src_push_buffer (gst->src, buffer);
}