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; }
// 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; } }
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; } }
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, ®ion, 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); }