summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Waters <awaters1@gmail.com>2014-01-29 11:21:14 -0500
committerAlex Deucher <alexander.deucher@amd.com>2014-01-31 10:05:39 -0500
commit6ffa4b88be5ac1580d29193b6cd3d216415d9be2 (patch)
tree24446203d51ea7a34fef9a8489a38609fd58bbce
parent654e1536a6d6539dcc30d9151122536c1807f34a (diff)
glamor: Added in an optimization to copy area that uploads the data directly to the destination similar to what EXA did
For instances where the destination has a FBO but the source doesn't, the code now just puts the data that was in source directly into destination through glamor_upload_sub_pixmap_to_texture. This is the same way that EXA works in this case as well. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=71813 Signed-off-by: Anthony Waters <awaters1@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--src/glamor_copyarea.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/src/glamor_copyarea.c b/src/glamor_copyarea.c
index bde6b4f..accf0d1 100644
--- a/src/glamor_copyarea.c
+++ b/src/glamor_copyarea.c
@@ -157,31 +157,56 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glamor_pixmap_private *src_pixmap_priv;
glamor_pixmap_private *dst_pixmap_priv;
int src_x_off, src_y_off, dst_x_off, dst_y_off;
- enum glamor_pixmap_status src_status = GLAMOR_NONE;
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+ glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
+ &src_y_off);
+ glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
+ &dst_y_off);
+
if (!src_pixmap_priv->base.gl_fbo) {
-#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
- glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
- return FALSE;
-#else
- src_status = glamor_upload_pixmap_to_texture(src_pixmap);
- if (src_status != GLAMOR_UPLOAD_DONE)
+ /* Optimize when the source doesn't have an FBO, just upload
+ the data directly to the dest FBO */
+ int src_stride = src_pixmap->devKind;
+ int bpp = src_pixmap->drawable.bitsPerPixel;
+ void *src_data = NULL;
+ if (src->bitsPerPixel != dst->bitsPerPixel) {
+ DEBUGF("Non-matching bpp\n");
return FALSE;
-
- src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-#endif
+ }
+ if (src->bitsPerPixel < 8) {
+ DEBUGF("bpp < 8\n");
+ return FALSE;
+ }
+ if (gc && !(gc->alu == GXcopy && glamor_pm_is_solid(src, gc->planemask))) {
+ DEBUGF("non gxcopy and solid\n");
+ return FALSE;
+ }
+ for (i = 0; i < nbox; i++) {
+ int x = box[i].x1 + dst_x_off;
+ int y = box[i].y1 + dst_y_off;
+ int w = box[i].x2 - box[i].x1;
+ int h = box[i].y2 - box[i].y1;
+ src_data = (char *)src_pixmap->devPrivate.ptr + (box[i].y1 + dy +
+ src_y_off) * src_stride +
+ (box[i].x1 + dx + src_x_off) * (bpp / 8);
+ if (!glamor_upload_sub_pixmap_to_texture(dst_pixmap,
+ x, y, w, h,
+ src_stride, src_data, 0)) {
+ ErrorF("Failed to upload the sub pixmap to dst\n");
+ return FALSE;
+ }
+ }
+ return TRUE;
}
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
- glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
- &dst_y_off);
dispatch = glamor_get_dispatch(glamor_priv);
@@ -192,11 +217,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
- &src_y_off);
+
dx += src_x_off;
dy += src_y_off;
+
dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D,
src_pixmap_priv->base.fbo->tex);
@@ -335,7 +360,7 @@ __glamor_copy_n_to_n(DrawablePtr src,
* 4 >
src_pixmap->drawable.width *
src_pixmap->drawable.height)
- || !(glamor_check_fbo_size(glamor_priv,
+ || !(glamor_check_fbo_size(glamor_priv,
src_pixmap->drawable.width,
src_pixmap->drawable.height))))) {