diff options
Diffstat (limited to 'src/ui/visbuf.c')
-rw-r--r-- | src/ui/visbuf.c | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/src/ui/visbuf.c b/src/ui/visbuf.c index 0f9e1092..198ad574 100644 --- a/src/ui/visbuf.c +++ b/src/ui/visbuf.c | |||
@@ -75,12 +75,13 @@ void dealloc_VisBuf(iVisBuf *d) { | |||
75 | void reposition_VisBuf(iVisBuf *d, const iRangei vis) { | 75 | void reposition_VisBuf(iVisBuf *d, const iRangei vis) { |
76 | d->vis = vis; | 76 | d->vis = vis; |
77 | iRangei good = { 0, 0 }; | 77 | iRangei good = { 0, 0 }; |
78 | size_t avail[3], numAvail = 0; | 78 | size_t avail[iElemCount(d->buffers)], numAvail = 0; |
79 | /* Check which buffers are available for reuse. */ { | 79 | /* Check which buffers are available for reuse. */ { |
80 | iForIndices(i, d->buffers) { | 80 | iForIndices(i, d->buffers) { |
81 | iVisBufTexture *buf = d->buffers + i; | 81 | iVisBufTexture *buf = d->buffers + i; |
82 | const iRangei region = { buf->origin, buf->origin + d->texSize.y }; | 82 | const iRangei region = { buf->origin, buf->origin + d->texSize.y }; |
83 | if (region.start >= vis.end || region.end <= vis.start) { | 83 | if (isEmpty_Rangei(buf->validRange) || |
84 | buf->validRange.start >= vis.end || buf->validRange.end <= vis.start) { | ||
84 | avail[numAvail++] = i; | 85 | avail[numAvail++] = i; |
85 | iZap(buf->validRange); | 86 | iZap(buf->validRange); |
86 | } | 87 | } |
@@ -89,25 +90,50 @@ void reposition_VisBuf(iVisBuf *d, const iRangei vis) { | |||
89 | } | 90 | } |
90 | } | 91 | } |
91 | } | 92 | } |
92 | if (numAvail == iElemCount(d->buffers)) { | 93 | iBool wasChanged = iFalse; |
93 | /* All buffers are outside the visible range, do a reset. */ | 94 | iBool doReset = (numAvail == iElemCount(d->buffers)); |
94 | d->buffers[0].origin = vis.start; | 95 | /* Try to extend to cover the visible range. */ |
95 | d->buffers[1].origin = vis.start + d->texSize.y; | 96 | while (!doReset && vis.start < good.start) { |
96 | d->buffers[2].origin = vis.start + 2 * d->texSize.y; | 97 | if (numAvail == 0) { |
98 | doReset = iTrue; | ||
99 | break; | ||
100 | } | ||
101 | good.start -= d->texSize.y; | ||
102 | d->buffers[avail[--numAvail]].origin = good.start; | ||
103 | wasChanged = iTrue; | ||
97 | } | 104 | } |
98 | else { | 105 | while (!doReset && vis.end > good.end) { |
99 | /* Extend to cover the visible range. */ | 106 | if (numAvail == 0) { |
100 | while (vis.start < good.start) { | 107 | doReset = iTrue; |
101 | iAssert(numAvail > 0); | 108 | break; |
102 | d->buffers[avail[--numAvail]].origin = good.start - d->texSize.y; | ||
103 | good.start -= d->texSize.y; | ||
104 | } | 109 | } |
105 | while (vis.end > good.end) { | 110 | d->buffers[avail[--numAvail]].origin = good.end; |
106 | iAssert(numAvail > 0); | 111 | good.end += d->texSize.y; |
107 | d->buffers[avail[--numAvail]].origin = good.end; | 112 | wasChanged = iTrue; |
108 | good.end += d->texSize.y; | 113 | } |
114 | if (doReset) { | ||
115 | // puts("VisBuf reset!"); | ||
116 | // fflush(stdout); | ||
117 | wasChanged = iTrue; | ||
118 | int pos = -1; | ||
119 | iForIndices(i, d->buffers) { | ||
120 | iZap(d->buffers[i].validRange); | ||
121 | d->buffers[i].origin = vis.start + pos++ * d->texSize.y; | ||
109 | } | 122 | } |
110 | } | 123 | } |
124 | #if 0 | ||
125 | if (wasChanged) { | ||
126 | printf("\nVISIBLE RANGE: %d ... %d\n", vis.start, vis.end); | ||
127 | iForIndices(i, d->buffers) { | ||
128 | const iVisBufTexture *bt = &d->buffers[i]; | ||
129 | printf(" %zu: buf %5d ... %5d valid %5d ... %5d\n", i, bt->origin, | ||
130 | bt->origin + d->texSize.y, | ||
131 | bt->validRange.start, | ||
132 | bt->validRange.end); | ||
133 | } | ||
134 | fflush(stdout); | ||
135 | } | ||
136 | #endif | ||
111 | } | 137 | } |
112 | 138 | ||
113 | void invalidRanges_VisBuf(const iVisBuf *d, const iRangei full, iRangei *out_invalidRanges) { | 139 | void invalidRanges_VisBuf(const iVisBuf *d, const iRangei full, iRangei *out_invalidRanges) { |