summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-24 22:11:20 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-24 22:11:20 +0000
commit5ad95d66665802bce25e127ae0d06f3e0a9b0e62 (patch)
tree97aa9ecb0268df54882e5988287c08ff783ddc97
parentaae19cbc5d0ddcf247451d06e063b2550a7ff16f (diff)
sna: Reduce number of reads required to inspect timers
By using the information provided by select at wakeup. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna.h5
-rw-r--r--src/sna/sna_accel.c13
-rw-r--r--src/sna/sna_driver.c3
3 files changed, 15 insertions, 6 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index cabf04c7..d8f96e06 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -231,7 +231,8 @@ struct sna {
#define SNA_NO_DELAYED_FLUSH 0x2
int timer[NUM_TIMERS];
- int timer_active;
+ uint16_t timer_active;
+ uint16_t timer_ready;
int vblank_interval;
@@ -581,7 +582,7 @@ static inline uint32_t pixmap_size(PixmapPtr pixmap)
Bool sna_accel_pre_init(struct sna *sna);
Bool sna_accel_init(ScreenPtr sreen, struct sna *sna);
void sna_accel_block_handler(struct sna *sna);
-void sna_accel_wakeup_handler(struct sna *sna);
+void sna_accel_wakeup_handler(struct sna *sna, fd_set *ready);
void sna_accel_close(struct sna *sna);
void sna_accel_free(struct sna *sna);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 46016e0c..1a134658 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -11276,7 +11276,7 @@ static void _sna_accel_disarm_timer(struct sna *sna, int id)
#define return_if_timer_active(id) do { \
if (sna->timer_active & (1<<(id))) \
- return read_timer(sna->timer[id]) > 0; \
+ return (sna->timer_ready & (1<<(id))) && read_timer(sna->timer[id]) > 0; \
} while (0)
static Bool sna_accel_do_flush(struct sna *sna)
@@ -11687,15 +11687,24 @@ void sna_accel_block_handler(struct sna *sna)
if (sna_accel_do_inactive(sna))
sna_accel_inactive(sna);
+
+ sna->timer_ready = 0;
}
-void sna_accel_wakeup_handler(struct sna *sna)
+void sna_accel_wakeup_handler(struct sna *sna, fd_set *ready)
{
+ int id, active;
+
if (sna->kgem.need_retire)
kgem_retire(&sna->kgem);
if (sna->kgem.need_purge)
kgem_purge_cache(&sna->kgem);
+ active = sna->timer_active & ~sna->timer_ready;
+ for (id = 0; id < NUM_TIMERS; id++)
+ if (active & (1 << id) && FD_ISSET(sna->timer[id], ready))
+ sna->timer_ready |= 1 << id;
+
sna_deferred_free(sna);
}
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 770a5bd2..bcd11915 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -606,7 +606,7 @@ sna_wakeup_handler(int i, pointer data, unsigned long result, pointer read_mask)
sna->WakeupHandler(i, sna->WakeupData, result, read_mask);
- sna_accel_wakeup_handler(sna);
+ sna_accel_wakeup_handler(sna, read_mask);
if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask))
sna_dri_wakeup(sna);
@@ -761,7 +761,6 @@ static Bool sna_close_screen(int scrnIndex, ScreenPtr screen)
#endif
/* drain the event queues */
- sna_accel_wakeup_handler(sna);
if (sna_dri_has_pending_events(sna))
sna_dri_wakeup(sna);