[byzanz] Remove the file cache
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [byzanz] Remove the file cache
- Date: Wed, 26 Aug 2009 10:21:57 +0000 (UTC)
commit e239aab0218aca1bff2bfd2865e1a35296ab7033
Author: Benjamin Otte <otte gnome org>
Date: Wed Aug 19 22:30:13 2009 +0200
Remove the file cache
The code was complicating stuff a lot and makes it complicate to
refactor. It will be reintroduced in a different way later on.
src/byzanzsession.c | 355 ++-------------------------------------------------
src/byzanzsession.h | 5 -
2 files changed, 14 insertions(+), 346 deletions(-)
---
diff --git a/src/byzanzsession.c b/src/byzanzsession.c
index 3cd1443..e28a459 100644
--- a/src/byzanzsession.c
+++ b/src/byzanzsession.c
@@ -38,14 +38,6 @@
#include "gifenc.h"
#include "i18n.h"
-/* use a maximum of 50 Mbytes to cache images */
-#define BYZANZ_SESSION_MAX_CACHE (50*1024*1024)
-/* as big as possible for 32bit ints without risking overflow
- * The current values gets overflows with pictures >= 2048x2048 */
-#define BYZANZ_SESSION_MAX_FILE_CACHE (0xFF000000)
-/* split that into ~ 16 files please */
-#define BYZANZ_SESSION_MAX_FILE_SIZE (BYZANZ_SESSION_MAX_FILE_CACHE / 16)
-
typedef enum {
SESSION_STATE_ERROR,
SESSION_STATE_CREATED,
@@ -56,7 +48,6 @@ typedef enum {
typedef enum {
SESSION_JOB_QUIT,
SESSION_JOB_ENCODE,
- SESSION_JOB_USE_FILE_CACHE,
} SessionJobType;
typedef gboolean (* DitherRegionGetDataFunc) (ByzanzSession *rec,
@@ -84,11 +75,7 @@ struct _ByzanzSession {
GdkRectangle area; /* area of the screen we record */
gboolean loop; /* wether the resulting gif should loop */
guint frame_duration; /* minimum frame duration in msecs */
- guint max_cache_size; /* maximum allowed size of cache */
- gint max_file_size; /* maximum allowed size of one cache file - ATOMIC */
- gint max_file_cache; /* maximum allowed size of all cache files together - ATOMIC */
/* state */
- guint cache_size; /* current cache size */
SessionState state; /* state the session is in */
guint timeout; /* signal id for timeout */
GdkWindow * window; /* root window we record */
@@ -102,23 +89,15 @@ struct _ByzanzSession {
GdkRectangle cursor_area; /* area occupied by cursor */
GdkRegion * region; /* the region we need to record next time */
GThread * encoder; /* encoding thread */
- gint use_file_cache :1; /* set whenever we signal using the file cache */
/* accessed ALSO by thread */
gint encoder_running;/* TRUE while the encoder is running */
GAsyncQueue * jobs; /* jobs the encoding thread has to do */
- GAsyncQueue * finished; /* store for leftover images */
- gint cur_file_cache; /* current amount of data cached in files */
/* accessed ONLY by thread */
Gifenc * gifenc; /* encoder used to encode the image */
GTimeVal current; /* timestamp of last encoded picture */
guint8 * data; /* data used to hold palettized data */
guint8 * data_full; /* palettized data of full image to compare additions to */
GdkRectangle relevant_data; /* relevant area to encode */
- GQueue * file_cache; /* queue of sorted images */
- int cur_cache_fd; /* current cache file */
- char * cur_cache_file; /* name of current cache file */
- guint8 * file_cache_data; /* data read in from file */
- guint file_cache_data_size; /* data read in from file */
};
#define IS_RECORDING_CURSOR(rec) ((rec)->cursors != NULL)
@@ -142,23 +121,15 @@ byzanz_cairo_set_source_window (cairo_t *cr, GdkWindow *window, double x, double
cairo_destroy (tmp);
}
-static guint
-compute_image_size (cairo_surface_t *image)
-{
- return cairo_image_surface_get_stride (image) * cairo_image_surface_get_height (image);
-}
-
static void
-session_job_free (ByzanzSession *rec, SessionJob *job)
+session_job_free (SessionJob *job)
{
- if (job->image) {
- rec->cache_size -= compute_image_size (job->image);
+ if (job->image)
cairo_surface_destroy (job->image);
- }
if (job->region)
gdk_region_destroy (job->region);
- g_free (job);
+ g_slice_free (SessionJob, job);
}
/* UGH: This function takes ownership of region, but only if a job could be created */
@@ -168,18 +139,7 @@ session_job_new (ByzanzSession *rec, SessionJobType type,
{
SessionJob *job;
- for (;;) {
- job = g_async_queue_try_pop (rec->finished);
- if (!job || !job->image)
- break;
- if (rec->cache_size - compute_image_size (job->image) <= rec->max_cache_size)
- break;
- session_job_free (rec, job);
- }
- if (!job)
- job = g_new0 (SessionJob, 1);
-
- g_assert (job->region == NULL);
+ job = g_slice_new0 (SessionJob);
if (tv)
job->tv = *tv;
@@ -187,35 +147,8 @@ session_job_new (ByzanzSession *rec, SessionJobType type,
job->region = region;
if (region != NULL) {
cairo_t *cr;
- if (!job->image) {
- if (rec->cache_size <= rec->max_cache_size) {
- job->image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
- rec->area.width, rec->area.height);
- rec->cache_size += compute_image_size (job->image);
- if (!rec->use_file_cache &&
- rec->cache_size >= rec->max_cache_size / 2) {
- SessionJob *tmp;
- guint count;
- rec->use_file_cache = TRUE;
- tmp = session_job_new (rec, SESSION_JOB_USE_FILE_CACHE, NULL, NULL);
- /* push job to the front */
- g_async_queue_lock (rec->jobs);
- count = g_async_queue_length_unlocked (rec->jobs);
- //g_print ("pushing USE_FILE_CACHE\n");
- g_async_queue_push_unlocked (rec->jobs, tmp);
- while (count > 0) {
- tmp = g_async_queue_pop_unlocked (rec->jobs);
- g_async_queue_push_unlocked (rec->jobs, tmp);
- count--;
- }
- g_async_queue_unlock (rec->jobs);
- }
- }
- if (!job->image) {
- g_free (job);
- return NULL;
- }
- }
+ job->image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ rec->area.width, rec->area.height);
if (type == SESSION_JOB_ENCODE) {
Display *dpy = gdk_x11_drawable_get_xdisplay (rec->window);
XDamageSubtract (dpy, rec->damage, rec->damaged, rec->damaged);
@@ -312,147 +245,6 @@ byzanz_session_add_image (ByzanzSession *rec, const GTimeVal *tv)
}
static void
-stored_image_remove_file (ByzanzSession *rec, int fd, char *filename)
-{
- guint size;
-
- size = (guint) lseek (fd, 0, SEEK_END);
- g_atomic_int_add (&rec->cur_file_cache, - (gint) size);
- close (fd);
- g_unlink (filename);
- g_free (filename);
-}
-
-/* returns FALSE if no more images can be cached */
-static gboolean
-stored_image_store (ByzanzSession *rec, cairo_surface_t *image, GdkRegion *region, const GTimeVal *tv)
-{
- off_t offset;
- StoredImage *store;
- GdkRectangle *rects;
- gint i, line, nrects;
- gboolean ret = FALSE;
- guint cache, val;
- guint stride;
- guchar *data;
-
- val = g_atomic_int_get (&rec->max_file_cache);
- cache = g_atomic_int_get (&rec->cur_file_cache);
- if (cache >= val) {
- g_print ("cache full %u/%u bytes\n", cache, val);
- return FALSE;
- }
-
- if (rec->cur_cache_fd < 0) {
- rec->cur_cache_fd = g_file_open_tmp ("byzanzcacheXXXXXX", &rec->cur_cache_file, NULL);
- if (rec->cur_cache_fd < 0) {
- g_print ("no temp file: %d\n", rec->cur_cache_fd);
- return FALSE;
- }
- offset = 0;
- } else {
- offset = lseek (rec->cur_cache_fd, 0, SEEK_END);
- }
- store = g_new (StoredImage, 1);
- store->region = region;
- store->tv = *tv;
- store->fd = rec->cur_cache_fd;
- store->filename = NULL;
- store->offset = offset;
- gdk_region_get_rectangles (store->region, &rects, &nrects);
- stride = cairo_image_surface_get_stride (image);
- data = cairo_image_surface_get_data (image);
- for (i = 0; i < nrects; i++) {
- guchar *mem;
- mem = data + rects[i].x * 4 + rects[i].y * stride;
- for (line = 0; line < rects[i].height; line++) {
- int amount = rects[i].width * 4;
- /* This can be made smarter, like retrying and catching EINTR and stuff */
- if (write (store->fd, mem, amount) != amount) {
- g_print ("couldn't write %d bytes\n", amount);
- goto out_err;
- }
- mem += stride;
- }
- }
-
- g_queue_push_tail (rec->file_cache, store);
- ret = TRUE;
-out_err:
- offset = lseek (store->fd, 0, SEEK_CUR);
- g_assert (offset > 0); /* FIXME */
- val = g_atomic_int_get (&rec->max_file_size);
- if ((guint) offset >= val) {
- rec->cur_cache_fd = -1;
- if (!ret)
- store = g_queue_peek_tail (rec->file_cache);
- if (store->filename)
- stored_image_remove_file (rec, rec->cur_cache_fd, rec->cur_cache_file);
- else
- store->filename = rec->cur_cache_file;
- rec->cur_cache_file = NULL;
- }
- //g_print ("current file is stored from %u to %u\n", (guint) store->offset, (guint) offset);
- offset -= store->offset;
- g_atomic_int_add (&rec->cur_file_cache, offset);
- //g_print ("cache size is now %u\n", g_atomic_int_get (&rec->cur_file_cache));
-
- return ret;
-}
-
-static gboolean
-stored_image_dither_get_data (ByzanzSession *rec, gpointer data, GdkRectangle *rect,
- gpointer *data_out, guint *bpl_out)
-{
- StoredImage *store = data;
- guint required_size = rect->width * rect->height * 4;
- guint8 *ptr;
-
- if (required_size > rec->file_cache_data_size) {
- rec->file_cache_data = g_realloc (rec->file_cache_data, required_size);
- rec->file_cache_data_size = required_size;
- }
-
- ptr = rec->file_cache_data;
- while (required_size > 0) {
- int ret = read (store->fd, ptr, required_size);
- if (ret < 0)
- return FALSE;
- ptr += ret;
- required_size -= ret;
- }
- *bpl_out = 4 * rect->width;
- *data_out = rec->file_cache_data;
- return TRUE;
-}
-
-static gboolean
-stored_image_process (ByzanzSession *rec)
-{
- StoredImage *store;
- gboolean ret;
-
- store = g_queue_pop_head (rec->file_cache);
- if (!store)
- return FALSE;
-
- /* FIXME: can that assertion trigger? */
- if (store->offset != lseek (store->fd, store->offset, SEEK_SET)) {
- g_printerr ("Couldn't seek to %d\n", (int) store->offset);
- g_assert_not_reached ();
- }
- byzanz_session_add_image (rec, &store->tv);
- lseek (store->fd, store->offset, SEEK_SET);
- ret = byzanz_session_dither_region (rec, store->region, stored_image_dither_get_data, store);
-
- if (store->filename)
- stored_image_remove_file (rec, store->fd, store->filename);
- gdk_region_destroy (store->region);
- g_free (store);
- return ret;
-}
-
-static void
byzanz_session_quantize (ByzanzSession *rec, cairo_surface_t *image)
{
GifencPalette *palette;
@@ -493,53 +285,18 @@ byzanz_session_run_encoder (gpointer data)
GTimeVal quit_tv;
gboolean quit = FALSE;
gboolean has_quantized = FALSE;
-#define USING_FILE_CACHE(rec) ((rec)->file_cache_data_size > 0)
-
- rec->cur_cache_fd = -1;
- rec->file_cache = g_queue_new ();
-
- while (TRUE) {
- if (USING_FILE_CACHE (rec)) {
-loop:
- job = g_async_queue_try_pop (rec->jobs);
- if (!job) {
- if (!stored_image_process (rec)) {
- if (quit)
- break;
- goto loop;
- }
- if (quit)
- goto loop;
- job = g_async_queue_pop (rec->jobs);
- }
- } else {
- if (quit)
- break;
- job = g_async_queue_pop (rec->jobs);
- }
+
+ while (!quit) {
+ job = g_async_queue_pop (rec->jobs);
+
switch (job->type) {
case SESSION_JOB_ENCODE:
if (!has_quantized) {
byzanz_session_quantize (rec, job->image);
has_quantized = TRUE;
}
- if (USING_FILE_CACHE (rec)) {
- while (!stored_image_store (rec, job->image, job->region, &job->tv)) {
- if (!stored_image_process (rec))
- /* fix this (bad error handling here) */
- g_assert_not_reached ();
- }
- job->region = NULL;
- } else {
- byzanz_session_add_image (rec, &job->tv);
- byzanz_session_encode (rec, job->image, job->region);
- }
- break;
- case SESSION_JOB_USE_FILE_CACHE:
- if (!USING_FILE_CACHE (rec)) {
- rec->file_cache_data_size = 4 * 64 * 64;
- rec->file_cache_data = g_malloc (rec->file_cache_data_size);
- }
+ byzanz_session_add_image (rec, &job->tv);
+ byzanz_session_encode (rec, job->image, job->region);
break;
case SESSION_JOB_QUIT:
quit_tv = job->tv;
@@ -549,11 +306,7 @@ loop:
g_assert_not_reached ();
return rec;
}
- if (job->region) {
- gdk_region_destroy (job->region);
- job->region = NULL;
- }
- g_async_queue_push (rec->finished, job);
+ session_job_free (job);
}
byzanz_session_add_image (rec, &quit_tv);
@@ -563,21 +316,9 @@ loop:
rec->data = NULL;
g_free (rec->data_full);
rec->data_full = NULL;
- if (USING_FILE_CACHE (rec)) {
- if (rec->cur_cache_fd) {
- stored_image_remove_file (rec, rec->cur_cache_fd, rec->cur_cache_file);
- rec->cur_cache_file = NULL;
- rec->cur_cache_fd = -1;
- }
- g_free (rec->file_cache_data);
- rec->file_cache_data = NULL;
- rec->file_cache_data_size = 0;
- }
- g_queue_free (rec->file_cache);
g_atomic_int_add (&rec->encoder_running, -1);
return rec;
-#undef USING_FILE_CACHE
}
/*** MAIN FUNCTIONS ***/
@@ -849,9 +590,6 @@ byzanz_session_new_fd (gint fd, GdkWindow *window, GdkRectangle *area,
session->area = *area;
session->loop = loop;
session->frame_duration = 1000 / 25;
- session->max_cache_size = BYZANZ_SESSION_MAX_CACHE;
- session->max_file_size = BYZANZ_SESSION_MAX_FILE_SIZE;
- session->max_file_cache = BYZANZ_SESSION_MAX_FILE_CACHE;
/* prepare thread first, so we can easily error out on failure */
session->window = window;
@@ -867,7 +605,6 @@ byzanz_session_new_fd (gint fd, GdkWindow *window, GdkRectangle *area,
return NULL;
}
session->jobs = g_async_queue_new ();
- session->finished = g_async_queue_new ();
session->encoder_running = 1;
session->encoder = g_thread_create (byzanz_session_run_encoder, session,
TRUE, NULL);
@@ -951,7 +688,6 @@ void
byzanz_session_destroy (ByzanzSession *rec)
{
Display *dpy;
- SessionJob *job;
g_return_if_fail (BYZANZ_IS_SESSION (rec));
@@ -962,8 +698,6 @@ byzanz_session_destroy (ByzanzSession *rec)
if (g_thread_join (rec->encoder) != rec)
g_assert_not_reached ();
- while ((job = g_async_queue_try_pop (rec->finished)) != NULL)
- session_job_free (rec, job);
dpy = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
XFixesDestroyRegion (dpy, rec->damaged);
XFixesDestroyRegion (dpy, rec->tmp_region);
@@ -975,73 +709,12 @@ byzanz_session_destroy (ByzanzSession *rec)
g_object_unref (rec->window);
g_assert (g_async_queue_length (rec->jobs) == 0);
- g_assert (rec->cache_size == 0);
+ g_async_queue_unref (rec->jobs);
g_free (rec);
}
/**
- * byzanz_session_set_max_cache:
- * @rec: a recording session
- * @max_cache_bytes: maximum allowed cache size in bytes
- *
- * Sets the maximum allowed cache size. Since the session uses two threads -
- * one for taking screenshots and one for encoding these screenshots into the
- * final file, on heavy screen changes a big number of screenshot images can
- * build up waiting to be encoded. This value is used to determine the maximum
- * allowed amount of memory these images may take. You can adapt this value
- * during a recording session.
- **/
-void
-byzanz_session_set_max_cache (ByzanzSession *rec,
- guint max_cache_bytes)
-{
- g_return_if_fail (BYZANZ_IS_SESSION (rec));
- g_return_if_fail (max_cache_bytes > G_MAXINT);
-
- rec->max_cache_size = max_cache_bytes;
- while (rec->cache_size > max_cache_bytes) {
- SessionJob *job = g_async_queue_try_pop (rec->finished);
- if (!job)
- break;
- session_job_free (rec, job);
- }
-}
-
-/**
- * byzanz_session_get_max_cache:
- * @rec: a recording session
- *
- * Gets the maximum allowed cache size. See byzanz_session_set_max_cache()
- * for details.
- *
- * Returns: the maximum allowed cache size in bytes
- **/
-guint
-byzanz_session_get_max_cache (ByzanzSession *rec)
-{
- g_return_val_if_fail (BYZANZ_IS_SESSION (rec), 0);
-
- return rec->max_cache_size;
-}
-
-/**
- * byzanz_session_get_cache:
- * @rec: a recording session
- *
- * Determines the current amount of image cache used.
- *
- * Returns: current cache used in bytes
- **/
-guint
-byzanz_session_get_cache (ByzanzSession *rec)
-{
- g_return_val_if_fail (BYZANZ_IS_SESSION (rec), 0);
-
- return rec->cache_size;
-}
-
-/**
* byzanz_session_is_active:
* @session: ia recording session
*
diff --git a/src/byzanzsession.h b/src/byzanzsession.h
index 97c386d..e03c4cc 100644
--- a/src/byzanzsession.h
+++ b/src/byzanzsession.h
@@ -40,11 +40,6 @@ void byzanz_session_start (ByzanzSession * session);
void byzanz_session_stop (ByzanzSession * session);
void byzanz_session_destroy (ByzanzSession * session);
gboolean byzanz_session_is_active (ByzanzSession * session);
-/* property functions */
-void byzanz_session_set_max_cache (ByzanzSession * session,
- guint max_cache_bytes);
-guint byzanz_session_get_max_cache (ByzanzSession * session);
-guint byzanz_session_get_cache (ByzanzSession * session);
#endif /* __HAVE_BYZANZ_SESSION_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]