diff options
| author | Drew DeVault <sir@cmpwn.com> | 2017-08-09 22:17:40 -0400 | 
|---|---|---|
| committer | Drew DeVault <sir@cmpwn.com> | 2017-08-09 22:17:40 -0400 | 
| commit | 4de930542f1a3d7322e7a7c1d2dc43dc9b4a4129 (patch) | |
| tree | 38482a217fbcb0c0527a80787725d5d77fb81e8e /render | |
| parent | b109aecff98bfed9a7ae834947ac93cb14bfc8dc (diff) | |
| download | wlroots-4de930542f1a3d7322e7a7c1d2dc43dc9b4a4129.tar.xz | |
Implement partial texture uploads
Diffstat (limited to 'render')
| -rw-r--r-- | render/gles2/texture.c | 62 | ||||
| -rw-r--r-- | render/wlr_texture.c | 13 | 
2 files changed, 74 insertions, 1 deletions
| diff --git a/render/gles2/texture.c b/render/gles2/texture.c index bd588898..ff823fc1 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -29,11 +29,36 @@ static bool gles2_texture_upload_pixels(struct wlr_texture_state *texture,  	GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride));  	GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, fmt->gl_format, width, height, 0,  			fmt->gl_format, fmt->gl_type, pixels)); -	GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0));  	texture->wlr_texture->valid = true;  	return true;  } +static bool gles2_texture_update_pixels(struct wlr_texture_state *texture, +		enum wl_shm_format format, int stride, int x, int y, +		int width, int height, const unsigned char *pixels) { +	assert(texture && texture->wlr_texture->valid); +	// TODO: Test if the unpack subimage extension is supported and adjust the +	// upload strategy if not +	if (texture->wlr_texture->format != format) { +		return gles2_texture_upload_pixels(texture, format, stride, +				width, height, pixels); +	} +	const struct pixel_format *fmt = gl_format_for_wl_format(format); +	if (!fmt || !fmt->gl_format) { +		wlr_log(L_ERROR, "No supported pixel format for this texture"); +		return false; +	} +	GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->tex_id)); +	GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, x)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, y)); +	GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, +			fmt->gl_format, fmt->gl_type, pixels)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0)); +	return true; +} +  static bool gles2_texture_upload_shm(struct wlr_texture_state *texture,  		uint32_t format, struct wl_shm_buffer *buffer) {  	const struct pixel_format *fmt = gl_format_for_wl_format(format); @@ -54,6 +79,8 @@ static bool gles2_texture_upload_shm(struct wlr_texture_state *texture,  	GL_CALL(glGenTextures(1, &texture->tex_id));  	GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->tex_id));  	GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, pitch)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0));  	GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, fmt->gl_format, width, height, 0,  				fmt->gl_format, fmt->gl_type, pixels)); @@ -62,6 +89,37 @@ static bool gles2_texture_upload_shm(struct wlr_texture_state *texture,  	return true;  } +static bool gles2_texture_update_shm(struct wlr_texture_state *texture, +		uint32_t format, int x, int y, int width, int height, +		struct wl_shm_buffer *buffer) { +	// TODO: Test if the unpack subimage extension is supported and adjust the +	// upload strategy if not +	assert(texture && texture->wlr_texture->valid); +	if (texture->wlr_texture->format != format) { +		return gles2_texture_upload_shm(texture, format, buffer); +	} +	const struct pixel_format *fmt = gl_format_for_wl_format(format); +	if (!fmt || !fmt->gl_format) { +		wlr_log(L_ERROR, "No supported pixel format for this texture"); +		return false; +	} +	wl_shm_buffer_begin_access(buffer); +	uint8_t *pixels = wl_shm_buffer_get_data(buffer); +	int pitch = wl_shm_buffer_get_stride(buffer) / (fmt->bpp / 8); + +	GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->tex_id)); +	GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, pitch)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, x)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, y)); +	GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, fmt->gl_format, width, height, 0, +				fmt->gl_format, fmt->gl_type, pixels)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0)); +	GL_CALL(glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0)); + +	wl_shm_buffer_end_access(buffer); +	return true; +} +  static void gles2_texture_get_matrix(struct wlr_texture_state *texture,  		float (*matrix)[16], const float (*projection)[16], int x, int y) {  	struct wlr_texture *_texture = texture->wlr_texture; @@ -89,7 +147,9 @@ static void gles2_texture_destroy(struct wlr_texture_state *texture) {  static struct wlr_texture_impl wlr_texture_impl = {  	.upload_pixels = gles2_texture_upload_pixels, +	.update_pixels = gles2_texture_update_pixels,  	.upload_shm = gles2_texture_upload_shm, +	.update_shm = gles2_texture_update_shm,  	.get_matrix = gles2_texture_get_matrix,  	.bind = gles2_texture_bind,  	.destroy = gles2_texture_destroy, diff --git a/render/wlr_texture.c b/render/wlr_texture.c index 926ee546..64f90990 100644 --- a/render/wlr_texture.c +++ b/render/wlr_texture.c @@ -25,11 +25,24 @@ bool wlr_texture_upload_pixels(struct wlr_texture *texture, uint32_t format,  			format, stride, width, height, pixels);  } +bool wlr_texture_update_pixels(struct wlr_texture *texture, +		enum wl_shm_format format, int stride, int x, int y, +		int width, int height, const unsigned char *pixels) { +	return texture->impl->update_pixels(texture->state, +			format, stride, x, y, width, height, pixels); +} +  bool wlr_texture_upload_shm(struct wlr_texture *texture, uint32_t format,  		struct wl_shm_buffer *shm) {  	return texture->impl->upload_shm(texture->state, format, shm);  } +bool wlr_texture_update_shm(struct wlr_texture *texture, uint32_t format, +		int x, int y, int width, int height, struct wl_shm_buffer *shm) { +	return texture->impl->update_shm(texture->state, format, +			x, y, width, height, shm); +} +  void wlr_texture_get_matrix(struct wlr_texture *texture,  		float (*matrix)[16], const float (*projection)[16], int x, int y) {  	texture->impl->get_matrix(texture->state, matrix, projection, x, y); | 
