win-capture: Cache cursor textures to prevent reallocation

Whenever a cursor is captured and the cursor icon changes, it creates a
new texture.  This isn't particularly optimal, so instead just store a
cache of cursor textures (based on size), and make the textures dynamic.
Doing this will prevent unnecessary texture reallocation.
This commit is contained in:
jp9000
2016-11-03 08:10:21 -07:00
parent 8e8834f109
commit 81ab13a2a4
2 changed files with 41 additions and 6 deletions

View File

@@ -131,6 +131,25 @@ static inline uint8_t *cursor_capture_icon_bitmap(ICONINFO *ii,
return output;
}
static gs_texture_t *get_cached_texture(struct cursor_data *data,
uint32_t cx, uint32_t cy)
{
struct cached_cursor cc;
for (size_t i = 0; i < data->cached_textures.num; i++) {
struct cached_cursor *pcc = &data->cached_textures.array[i];
if (pcc->cx == cx && pcc->cy == cy)
return pcc->texture;
}
cc.texture = gs_texture_create(cx, cy, GS_BGRA, 1, NULL, GS_DYNAMIC);
cc.cx = cx;
cc.cy = cy;
da_push_back(data->cached_textures, &cc);
return cc.texture;
}
static inline bool cursor_capture_icon(struct cursor_data *data, HICON icon)
{
uint8_t *bitmap;
@@ -138,9 +157,6 @@ static inline bool cursor_capture_icon(struct cursor_data *data, HICON icon)
uint32_t width;
ICONINFO ii;
gs_texture_destroy(data->texture);
data->texture = NULL;
if (!icon) {
return false;
}
@@ -150,8 +166,12 @@ static inline bool cursor_capture_icon(struct cursor_data *data, HICON icon)
bitmap = cursor_capture_icon_bitmap(&ii, &width, &height);
if (bitmap) {
data->texture = gs_texture_create(width, height, GS_BGRA,
1, (const uint8_t**)&bitmap, 0);
if (data->last_cx != width && data->last_cy != height) {
data->texture = get_cached_texture(data, width, height);
data->last_cx = width;
data->last_cy = height;
}
gs_texture_set_image(data->texture, bitmap, width * 4, false);
bfree(bitmap);
data->x_hotspot = ii.xHotspot;
@@ -217,6 +237,10 @@ void cursor_draw(struct cursor_data *data, long x_offset, long y_offset,
void cursor_data_free(struct cursor_data *data)
{
gs_texture_destroy(data->texture);
for (size_t i = 0; i < data->cached_textures.num; i++) {
struct cached_cursor *pcc = &data->cached_textures.array[i];
gs_texture_destroy(pcc->texture);
}
da_free(data->cached_textures);
memset(data, 0, sizeof(*data));
}

View File

@@ -2,6 +2,12 @@
#include <stdint.h>
struct cached_cursor {
gs_texture_t *texture;
uint32_t cx;
uint32_t cy;
};
struct cursor_data {
gs_texture_t *texture;
HCURSOR current_cursor;
@@ -9,6 +15,11 @@ struct cursor_data {
long x_hotspot;
long y_hotspot;
bool visible;
uint32_t last_cx;
uint32_t last_cy;
DARRAY(struct cached_cursor) cached_textures;
};
extern void cursor_capture(struct cursor_data *data);