Fix cairo surface flushing and marking in create_surface
This commit is contained in:
parent
94176c8d7c
commit
96087d17a1
1 changed files with 24 additions and 9 deletions
33
visor.c
33
visor.c
|
@ -355,8 +355,7 @@ void plane_resize(GtkWidget *widget)
|
||||||
|
|
||||||
void create_surface(GtkWidget *widget)
|
void create_surface(GtkWidget *widget)
|
||||||
{
|
{
|
||||||
cairo_t *cr;
|
// Stop all current drawers
|
||||||
|
|
||||||
pthread_mutex_lock(&pixmapMutex);
|
pthread_mutex_lock(&pixmapMutex);
|
||||||
pixmapAvailable = false; // Mark drawing area as unavailable
|
pixmapAvailable = false; // Mark drawing area as unavailable
|
||||||
pthread_mutex_unlock(&pixmapMutex);
|
pthread_mutex_unlock(&pixmapMutex);
|
||||||
|
@ -367,9 +366,24 @@ void create_surface(GtkWidget *widget)
|
||||||
for (int32_t i = 0; i < thread_count; i++) {
|
for (int32_t i = 0; i < thread_count; i++) {
|
||||||
if (threads[i].drawing) {
|
if (threads[i].drawing) {
|
||||||
allWritersStopped = false;
|
allWritersStopped = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!allWritersStopped);
|
} while (!allWritersStopped);
|
||||||
|
|
||||||
|
// If all drawers hadn't completed, we need to call
|
||||||
|
// cairo_surface_mark_dirty in the main thread
|
||||||
|
bool allWritersHadCompleted = true;
|
||||||
|
for (int32_t i = 0; i < thread_count; i++) {
|
||||||
|
if (!threads[i].complete) {
|
||||||
|
allWritersHadCompleted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!allWritersHadCompleted && surface != NULL) {
|
||||||
|
cairo_surface_mark_dirty(surface);
|
||||||
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < thread_count; i++) {
|
for (int32_t i = 0; i < thread_count; i++) {
|
||||||
threads[i].complete = false;
|
threads[i].complete = false;
|
||||||
}
|
}
|
||||||
|
@ -382,20 +396,21 @@ void create_surface(GtkWidget *widget)
|
||||||
gtk_widget_get_width(widget),
|
gtk_widget_get_width(widget),
|
||||||
gtk_widget_get_height(widget));
|
gtk_widget_get_height(widget));
|
||||||
|
|
||||||
cr = cairo_create(surface);
|
|
||||||
|
|
||||||
cairo_surface_flush(surface);
|
|
||||||
int h = cairo_image_surface_get_height(surface);
|
int h = cairo_image_surface_get_height(surface);
|
||||||
int w = cairo_image_surface_get_width(surface);
|
int w = cairo_image_surface_get_width(surface);
|
||||||
mandelbrot.height = h;
|
mandelbrot.height = h;
|
||||||
mandelbrot.width = w;
|
mandelbrot.width = w;
|
||||||
pixmap = cairo_image_surface_get_data(surface);
|
|
||||||
cairo_surface_mark_dirty(surface);
|
|
||||||
|
|
||||||
|
// Mark the surface as ready to be drawn by memory access
|
||||||
|
// Then notify other threads to start drawing
|
||||||
|
// One of these threads will make the corresponding call using
|
||||||
|
// cairo_surface_mark_dirty, to notify they are all done drawing
|
||||||
|
cairo_surface_flush(surface);
|
||||||
|
pixmap = cairo_image_surface_get_data(surface);
|
||||||
|
|
||||||
|
// This lock is unnecessary since all other threads are stopped already
|
||||||
pthread_mutex_lock(&pixmapMutex);
|
pthread_mutex_lock(&pixmapMutex);
|
||||||
pixmapAvailable = true;
|
pixmapAvailable = true;
|
||||||
pthread_mutex_unlock(&pixmapMutex);
|
pthread_mutex_unlock(&pixmapMutex);
|
||||||
pthread_cond_broadcast(&pixmapCond);
|
pthread_cond_broadcast(&pixmapCond);
|
||||||
|
|
||||||
cairo_destroy(cr);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue