glamor: only use (un)pack_subimage when available
Check for GL_EXT_unpack_subimage and GL_NV_pack_subimage to
check if GL_(UN)PACK_ROW_LENGTH is available. Set the offsets
manually to prevent calls to GL_(UN)PACK_SKIP_*.
v2: Check support for GL_NV_pack_subimage as suggested by Matt Turner.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@ubuntu.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Eric Anholt <eric@anholt.net>
(cherry picked from commit 7c6f483670
)
This commit is contained in:
parent
5df6982a14
commit
1ec335ca15
|
@ -411,6 +411,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
epoxy_has_gl_extension("GL_ARB_buffer_storage");
|
||||
glamor_priv->has_nv_texture_barrier =
|
||||
epoxy_has_gl_extension("GL_NV_texture_barrier");
|
||||
glamor_priv->has_unpack_subimage =
|
||||
glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
|
||||
epoxy_gl_version() >= 30 ||
|
||||
epoxy_has_gl_extension("GL_EXT_unpack_subimage");
|
||||
glamor_priv->has_pack_subimage =
|
||||
glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
|
||||
epoxy_gl_version() >= 30 ||
|
||||
epoxy_has_gl_extension("GL_NV_pack_subimage");
|
||||
|
||||
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
|
||||
|
|
|
@ -236,6 +236,8 @@ typedef struct glamor_screen_private {
|
|||
int has_buffer_storage;
|
||||
int has_khr_debug;
|
||||
int has_nv_texture_barrier;
|
||||
int has_pack_subimage;
|
||||
int has_unpack_subimage;
|
||||
int max_fbo_size;
|
||||
int has_rw_pbo;
|
||||
|
||||
|
|
|
@ -73,7 +73,9 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
|||
glamor_make_current(glamor_priv);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
|
||||
|
||||
if (glamor_priv->has_unpack_subimage)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
|
||||
|
||||
glamor_pixmap_loop(priv, box_x, box_y) {
|
||||
BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
|
||||
|
@ -92,25 +94,34 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
|||
int y1 = MAX(boxes->y1 + dy_dst, box->y1);
|
||||
int y2 = MIN(boxes->y2 + dy_dst, box->y2);
|
||||
|
||||
size_t ofs = (y1 - dy_dst + dy_src) * byte_stride;
|
||||
ofs += (x1 - dx_dst + dx_src) * bytes_per_pixel;
|
||||
|
||||
boxes++;
|
||||
|
||||
if (x2 <= x1 || y2 <= y1)
|
||||
continue;
|
||||
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1 - dx_dst + dx_src);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
x1 - box->x1, y1 - box->y1,
|
||||
x2 - x1, y2 - y1,
|
||||
format, type,
|
||||
bits);
|
||||
if (glamor_priv->has_unpack_subimage ||
|
||||
x2 - x1 == byte_stride / bytes_per_pixel) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
x1 - box->x1, y1 - box->y1,
|
||||
x2 - x1, y2 - y1,
|
||||
format, type,
|
||||
bits + ofs);
|
||||
} else {
|
||||
for (; y1 < y2; y1++, ofs += byte_stride)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
x1 - box->x1, y1 - box->y1,
|
||||
x2 - x1, 1,
|
||||
format, type,
|
||||
bits + ofs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
if (glamor_priv->has_unpack_subimage)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -166,7 +177,8 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
|||
glamor_make_current(glamor_priv);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
|
||||
if (glamor_priv->has_pack_subimage)
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
|
||||
|
||||
glamor_pixmap_loop(priv, box_x, box_y) {
|
||||
BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
|
||||
|
@ -183,20 +195,25 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
|||
int x2 = MIN(boxes->x2 + dx_src, box->x2);
|
||||
int y1 = MAX(boxes->y1 + dy_src, box->y1);
|
||||
int y2 = MIN(boxes->y2 + dy_src, box->y2);
|
||||
size_t ofs = (y1 - dy_src + dy_dst) * byte_stride;
|
||||
ofs += (x1 - dx_src + dx_dst) * bytes_per_pixel;
|
||||
|
||||
boxes++;
|
||||
|
||||
if (x2 <= x1 || y2 <= y1)
|
||||
continue;
|
||||
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
|
||||
glPixelStorei(GL_PACK_SKIP_ROWS, y1 - dy_src + dy_dst);
|
||||
glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits);
|
||||
if (glamor_priv->has_pack_subimage ||
|
||||
x2 - x1 == byte_stride / bytes_per_pixel) {
|
||||
glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs);
|
||||
} else {
|
||||
for (; y1 < y2; y1++, ofs += byte_stride)
|
||||
glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs);
|
||||
}
|
||||
}
|
||||
}
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
|
||||
if (glamor_priv->has_pack_subimage)
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue