summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2010-01-16 21:12:10 +0000
committerKeith Whitwell <[email protected]>2010-01-17 00:30:23 +0000
commit591401ff05f878ff1607a1a34db1319103025d8f (patch)
tree408330ff784a9ae92aec1a0ddae53e9cee9be6dd
parentba5d600c90f7075cf2c33a0c5c679ef822e8746e (diff)
llvmpipe: use new u_ringbuffer for scene queue
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene_queue.c114
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene_queue.h8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c11
4 files changed, 46 insertions, 89 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index d03ba1752d6..2e2ebee45de 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -844,7 +844,7 @@ thread_func( void *init_data )
const struct pipe_framebuffer_state *fb;
boolean write_depth;
- rast->curr_scene = lp_scene_dequeue( rast->full_scenes );
+ rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE );
lp_scene_bin_iter_begin( rast->curr_scene );
diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c
index 8d65a6a6fa2..43d74e4d89d 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene_queue.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c
@@ -32,8 +32,7 @@
* which are produced by the "rast" code when it finishes rendering a scene.
*/
-
-#include "pipe/p_thread.h"
+#include "util/u_ringbuffer.h"
#include "util/u_memory.h"
#include "lp_scene_queue.h"
@@ -41,20 +40,17 @@
#define MAX_SCENE_QUEUE 4
+struct scene_packet {
+ struct util_packet header;
+ struct lp_scene *scene;
+};
/**
* A queue of scenes
*/
struct lp_scene_queue
{
- /** XXX might use a linked list here somedone, but the list will
- * probably always be pretty short.
- */
- struct lp_scene *scenes[MAX_SCENE_QUEUE];
- unsigned count;
-
- pipe_condvar count_change;
- pipe_mutex mutex;
+ struct util_ringbuffer *ring;
};
@@ -64,11 +60,19 @@ struct lp_scene_queue *
lp_scene_queue_create(void)
{
struct lp_scene_queue *queue = CALLOC_STRUCT(lp_scene_queue);
- if (queue) {
- pipe_condvar_init(queue->count_change);
- pipe_mutex_init(queue->mutex);
- }
+ if (queue == NULL)
+ return NULL;
+
+ queue->ring = util_ringbuffer_create( MAX_SCENE_QUEUE *
+ sizeof( struct scene_packet ) / 4);
+ if (queue->ring == NULL)
+ goto fail;
+
return queue;
+
+fail:
+ FREE(queue);
+ return NULL;
}
@@ -76,41 +80,26 @@ lp_scene_queue_create(void)
void
lp_scene_queue_destroy(struct lp_scene_queue *queue)
{
- pipe_condvar_destroy(queue->count_change);
- pipe_mutex_destroy(queue->mutex);
+ util_ringbuffer_destroy(queue->ring);
+ FREE(queue);
}
/** Remove first lp_scene from head of queue */
struct lp_scene *
-lp_scene_dequeue(struct lp_scene_queue *queue)
+lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait)
{
- struct lp_scene *scene;
- unsigned i;
-
- pipe_mutex_lock(queue->mutex);
- while (queue->count == 0) {
- pipe_condvar_wait(queue->count_change, queue->mutex);
- }
-
- assert(queue->count >= 1);
-
- /* get head */
- scene = queue->scenes[0];
-
- /* shift entries */
- for (i = 0; i < queue->count - 1; i++) {
- queue->scenes[i] = queue->scenes[i + 1];
- }
+ struct scene_packet packet;
+ enum pipe_error ret;
- queue->count--;
+ ret = util_ringbuffer_dequeue(queue->ring,
+ &packet.header,
+ sizeof packet / 4,
+ wait );
+ if (ret != PIPE_OK)
+ return NULL;
- /* signal size change */
- pipe_condvar_signal(queue->count_change);
-
- pipe_mutex_unlock(queue->mutex);
-
- return scene;
+ return packet.scene;
}
@@ -118,47 +107,16 @@ lp_scene_dequeue(struct lp_scene_queue *queue)
void
lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene)
{
- pipe_mutex_lock(queue->mutex);
-
- assert(queue->count < MAX_SCENE_QUEUE);
+ struct scene_packet packet;
- /* debug: check that scene is not already in the queue */
- if (0) {
- unsigned i;
- for (i = 0; i < queue->count; i++) {
- assert(queue->scenes[i] != scene);
- }
- }
+ packet.header.dwords = sizeof packet / 4;
+ packet.header.data24 = 0;
+ packet.scene = scene;
- /* add to end */
- queue->scenes[queue->count++] = scene;
-
- /* signal size change */
- pipe_condvar_signal(queue->count_change);
-
- pipe_mutex_unlock(queue->mutex);
+ util_ringbuffer_enqueue(queue->ring, &packet.header);
}
-/** Return number of entries in the queue */
-unsigned
-lp_scene_queue_count(struct lp_scene_queue *queue)
-{
- unsigned count;
- pipe_mutex_lock(queue->mutex);
- count = queue->count;
- pipe_mutex_unlock(queue->mutex);
- return count;
-}
-/** Wait until the queue has exactly 'count' entries */
-void
-lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned count)
-{
- pipe_mutex_lock(queue->mutex);
- while (queue->count != count) {
- pipe_condvar_wait(queue->count_change, queue->mutex);
- }
- pipe_mutex_unlock(queue->mutex);
-}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.h b/src/gallium/drivers/llvmpipe/lp_scene_queue.h
index 1bd475fa504..fd7c65a2c8b 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene_queue.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.h
@@ -40,16 +40,12 @@ void
lp_scene_queue_destroy(struct lp_scene_queue *queue);
struct lp_scene *
-lp_scene_dequeue(struct lp_scene_queue *queue);
+lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait);
void
-lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *bins);
+lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene);
-unsigned
-lp_scene_queue_count(struct lp_scene_queue *queue);
-void
-lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned size);
#endif /* LP_BIN_QUEUE */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index f52dce65d74..d4a4724ad1b 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -57,8 +57,11 @@ struct lp_scene *
lp_setup_get_current_scene(struct setup_context *setup)
{
if (!setup->scene) {
- /* wait for a free/empty bin */
- setup->scene = lp_scene_dequeue(setup->empty_scenes);
+
+ /* wait for a free/empty scene
+ */
+ setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE);
+
if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */
lp_scene_set_framebuffer_size(setup->scene,
@@ -651,8 +654,8 @@ lp_setup_destroy( struct setup_context *setup )
pipe_buffer_reference(&setup->constants.current, NULL);
/* free the scenes in the 'empty' queue */
- while (lp_scene_queue_count(setup->empty_scenes) > 0) {
- struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes);
+ while (1) {
+ struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes, FALSE);
if (!scene)
break;
lp_scene_destroy(scene);