diff options
Diffstat (limited to 'xorg-server/glamor')
-rw-r--r-- | xorg-server/glamor/glamor_copy.c | 55 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_font.c | 7 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_xv.c | 13 |
3 files changed, 72 insertions, 3 deletions
diff --git a/xorg-server/glamor/glamor_copy.c b/xorg-server/glamor/glamor_copy.c index bfcde43db..6f422d419 100644 --- a/xorg-server/glamor/glamor_copy.c +++ b/xorg-server/glamor/glamor_copy.c @@ -233,6 +233,56 @@ bail: return FALSE; } +/** + * Implements CopyArea from the GPU to the CPU using glReadPixels from the + * source FBO. + */ +static Bool +glamor_copy_fbo_cpu(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + FbBits *dst_bits; + FbStride dst_stride; + int dst_bpp; + int src_xoff, src_yoff; + int dst_xoff, dst_yoff; + + if (gc && gc->alu != GXcopy) + goto bail; + + if (gc && !glamor_pm_is_solid(dst, gc->planemask)) + goto bail; + + glamor_make_current(glamor_priv); + glamor_prepare_access(dst, GLAMOR_ACCESS_RW); + + glamor_get_drawable_deltas(src, src_pixmap, &src_xoff, &src_yoff); + + fbGetDrawable(dst, dst_bits, dst_stride, dst_bpp, dst_xoff, dst_yoff); + + glamor_download_boxes(src_pixmap, box, nbox, src_xoff + dx, src_yoff + dy, + dst_xoff, dst_yoff, + (uint8_t *) dst_bits, dst_stride * sizeof (FbBits)); + glamor_finish_access(dst); + + return TRUE; + +bail: + return FALSE; +} + /* * Copy from GPU to GPU by using the source * as a texture and painting that into the destination @@ -584,6 +634,11 @@ glamor_copy_gl(DrawablePtr src, if (bitplane == 0) return glamor_copy_cpu_fbo(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); + } else if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv) && + dst_priv->type != GLAMOR_DRM_ONLY && + bitplane == 0) { + return glamor_copy_fbo_cpu(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); } return FALSE; } diff --git a/xorg-server/glamor/glamor_font.c b/xorg-server/glamor/glamor_font.c index 57c607dc2..0ca91fa2e 100644 --- a/xorg-server/glamor/glamor_font.c +++ b/xorg-server/glamor/glamor_font.c @@ -46,6 +46,8 @@ glamor_font_get(ScreenPtr screen, FontPtr font) CharInfoPtr glyph; unsigned long count; + if (glamor_priv->glsl_version < 130) + return NULL; privates = FontGetPrivate(font, glamor_font_private_index); if (!privates) { @@ -167,6 +169,11 @@ glamor_unrealize_font(ScreenPtr screen, FontPtr font) Bool glamor_font_init(ScreenPtr screen) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + if (glamor_priv->glsl_version < 130) + return TRUE; + if (glamor_font_generation != serverGeneration) { glamor_font_private_index = AllocateFontPrivateIndex(); if (glamor_font_private_index == -1) diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c index 3f3e064d5..26bdef66b 100644 --- a/xorg-server/glamor/glamor_xv.c +++ b/xorg-server/glamor/glamor_xv.c @@ -136,6 +136,11 @@ glamor_init_xv_shader(ScreenPtr screen) void glamor_xv_stop_video(glamor_port_private *port_priv) { +} + +static void +glamor_xv_free_port_data(glamor_port_private *port_priv) +{ int i; for (i = 0; i < 3; i++) { @@ -144,6 +149,8 @@ glamor_xv_stop_video(glamor_port_private *port_priv) port_priv->src_pix[i] = NULL; } } + RegionUninit(&port_priv->clip); + RegionNull(&port_priv->clip); } int @@ -381,6 +388,8 @@ glamor_xv_render(glamor_port_private *port_priv) glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); DamageDamageRegion(port_priv->pDraw, &port_priv->clip); + + glamor_xv_free_port_data(port_priv); } int @@ -468,9 +477,7 @@ glamor_xv_put_image(glamor_port_private *port_priv, else port_priv->pPixmap = (PixmapPtr) pDrawable; - if (!RegionEqual(&port_priv->clip, clipBoxes)) { - RegionCopy(&port_priv->clip, clipBoxes); - } + RegionCopy(&port_priv->clip, clipBoxes); port_priv->src_x = src_x; port_priv->src_y = src_y; |