From ef17357a9745e05e301b724d13a341067ddb3d5b Mon Sep 17 00:00:00 2001 From: root Date: Mon, 11 Mar 2013 00:04:02 -0700 Subject: Mon Mar 11 00:04:02 PDT 2013 --- extra/glamor-egl/PKGBUILD | 55 + extra/glamor-egl/compat-api.h | 107 ++ extra/glamor-egl/compiler.h | 59 + extra/glamor-egl/git-fixes.patch | 177 ++ extra/glamor-egl/glamor_debug.h | 116 ++ extra/glamor-egl/glamor_gl_dispatch.h | 137 ++ extra/glamor-egl/glamor_glext.h | 64 + extra/glamor-egl/glamor_priv.h | 1016 +++++++++++ extra/glamor-egl/glamor_utils.h | 1836 ++++++++++++++++++++ extra/glamor-egl/glapi.h | 121 ++ extra/gnome-shell/PKGBUILD | 12 +- extra/gnome-shell/nm-libexecdir.patch | 12 + extra/gparted/PKGBUILD | 12 +- extra/kwebkitpart/PKGBUILD | 12 +- extra/libkdcraw/PKGBUILD | 9 +- extra/xfdesktop/PKGBUILD | 16 +- ...images-are-no-longer-pixilated-when-scale.patch | 108 -- 17 files changed, 3729 insertions(+), 140 deletions(-) create mode 100644 extra/glamor-egl/PKGBUILD create mode 100644 extra/glamor-egl/compat-api.h create mode 100644 extra/glamor-egl/compiler.h create mode 100644 extra/glamor-egl/git-fixes.patch create mode 100644 extra/glamor-egl/glamor_debug.h create mode 100644 extra/glamor-egl/glamor_gl_dispatch.h create mode 100644 extra/glamor-egl/glamor_glext.h create mode 100644 extra/glamor-egl/glamor_priv.h create mode 100644 extra/glamor-egl/glamor_utils.h create mode 100644 extra/glamor-egl/glapi.h create mode 100644 extra/gnome-shell/nm-libexecdir.patch delete mode 100644 extra/xfdesktop/revert-SVG-images-are-no-longer-pixilated-when-scale.patch (limited to 'extra') diff --git a/extra/glamor-egl/PKGBUILD b/extra/glamor-egl/PKGBUILD new file mode 100644 index 000000000..32ea75b3d --- /dev/null +++ b/extra/glamor-egl/PKGBUILD @@ -0,0 +1,55 @@ +# $Id: PKGBUILD 179700 2013-03-09 11:48:07Z andyrtr $ +# Maintainer: Jan de Groot +# Contributor: Eugeni Dodonov + +pkgname=glamor-egl +pkgver=0.5.0 +pkgrel=1 +pkgdesc='OpenGL based 2D rendering acceleration library ' +arch=('i686' 'x86_64') +url="http://xorg.freedesktop.org/" +license=('custom') +depends=('mesa-libgl') +makedepends=('xorg-server-devel') +source=(${url}/releases/individual/driver/${pkgname}-${pkgver}.tar.bz2 + glamor_utils.h glamor_priv.h glapi.h + compat-api.h compiler.h glamor_debug.h glamor_gl_dispatch.h glamor_glext.h + git-fixes.patch) +conflicts=('glamir-git') +options=('!libtool') +sha256sums=('5dc8679ccb3e42bf431b6316c7907b9df2db89745d523e04721f34aee6c84991' + 'fb7db610451d8bb0baaabe3ac618794f535924ac08f62159b08a82ac90a1ed4a' + '6ad1b6349325be84aa9fe6f0b3224128f11bcf00a91a7080e40cd7b58a83137c' + '5c148a18607f94fcdfebe2838aa77d190cb913e05579a9676c2520219a5e2a6a' + '1a5c1059a3757047de064ccd952ab637b73e7e2d55cbccd6dafc60b57aaed1d0' + 'f883c329e7ec94afafa646b866eaab8a5616761b5ffe2b2837c75d403917944a' + 'fc3d937f2cb996586d3a9cc7427050d04d2d19d3f745055cc9d3556428a7cf93' + 'a7fac65474af636995d0181dbf7f8f091d8657260162eb172ae816b75ad98b54' + 'dcf38a7ac303c1636a3b1b7810dcb6ee65ba7e81b6e590840e164ce0e28010dc' + '5c0d1dd79a8b50f6720ba2d4dbe288dca11cc19131bb502c6ad2920298ccf843') + +build() { + cd ${srcdir}/${pkgname}-${pkgver} + + # add missing headers - tarball creation buggy + cp $srcdir/*.h src/ + + patch -Np1 -i ${srcdir}/git-fixes.patch + + autoreconf -vfi + + ./configure --prefix=/usr \ + --disable-static \ + --enable-glamor-gles2 \ + --enable-glx-tls \ + #--help + + make +} + +package() { + cd "${srcdir}/${pkgname}-${pkgver}" + make "DESTDIR=${pkgdir}" install + install -m755 -d "${pkgdir}/usr/share/licenses/${pkgname}" + install -m644 COPYING "${pkgdir}/usr/share/licenses/${pkgname}/" +} diff --git a/extra/glamor-egl/compat-api.h b/extra/glamor-egl/compat-api.h new file mode 100644 index 000000000..1608478f8 --- /dev/null +++ b/extra/glamor-egl/compat-api.h @@ -0,0 +1,107 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Dave Airlie + */ + +/* this file provides API compat between server post 1.13 and pre it, + it should be reused inside as many drivers as possible */ +#ifndef COMPAT_API_H +#define COMPAT_API_H + +#ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR +#define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum] +#define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p +#endif + +#ifndef XF86_HAS_SCRN_CONV +#define xf86ScreenToScrn(s) xf86Screens[(s)->myNum] +#define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex] +#endif + +#ifndef XF86_SCRN_INTERFACE + +#define SCRN_ARG_TYPE int +#define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = xf86Screens[(arg1)] + +#define SCREEN_ARG_TYPE int +#define SCREEN_PTR(arg1) ScreenPtr screen = screenInfo.screens[(arg1)] + +#define SCREEN_INIT_ARGS_DECL int scrnIndex, ScreenPtr screen, int argc, char **argv + +#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer timeout, pointer read_mask +#define BLOCKHANDLER_ARGS arg, blockData, timeout, read_mask + +#define WAKEUPHANDLER_ARGS_DECL int arg, pointer wakeupData, unsigned long result, pointer read_mask +#define WAKEUPHANDLER_ARGS arg, wakeupData, result, read_mask + +#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr screen +#define CLOSE_SCREEN_ARGS scrnIndex, screen + +#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags +#define ADJUST_FRAME_ARGS(arg, x, y) (arg)->scrnIndex, x, y, 0 + +#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags +#define SWITCH_MODE_ARGS(arg, m) (arg)->scrnIndex, m, 0 + +#define FREE_SCREEN_ARGS_DECL int arg, int flags +#define FREE_SCREEN_ARGS arg, flags + +#define VT_FUNC_ARGS_DECL int arg, int flags +#define VT_FUNC_ARGS(flags) scrn->scrnIndex, (flags) + +#define XF86_ENABLEDISABLEFB_ARG(x) ((x)->scrnIndex) + +#else +#define SCRN_ARG_TYPE ScrnInfoPtr +#define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = (arg1) + +#define SCREEN_ARG_TYPE ScreenPtr +#define SCREEN_PTR(arg1) ScreenPtr screen = (arg1) + +#define SCREEN_INIT_ARGS_DECL ScreenPtr screen, int argc, char **argv + +#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer timeout, pointer read_mask +#define BLOCKHANDLER_ARGS arg, timeout, read_mask + +#define WAKEUPHANDLER_ARGS_DECL ScreenPtr arg, unsigned long result, pointer read_mask +#define WAKEUPHANDLER_ARGS arg, result, read_mask + +#define CLOSE_SCREEN_ARGS_DECL ScreenPtr screen +#define CLOSE_SCREEN_ARGS screen + +#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y +#define ADJUST_FRAME_ARGS(arg, x, y) arg, x, y + +#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode +#define SWITCH_MODE_ARGS(arg, m) arg, m + +#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg +#define FREE_SCREEN_ARGS arg + +#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg +#define VT_FUNC_ARGS(flags) scrn + +#define XF86_ENABLEDISABLEFB_ARG(x) (x) + +#endif +#endif diff --git a/extra/glamor-egl/compiler.h b/extra/glamor-egl/compiler.h new file mode 100644 index 000000000..fa2895976 --- /dev/null +++ b/extra/glamor-egl/compiler.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Chris Wilson + * + * Copied from sna + * + */ + +#ifndef _GLAMOR_COMPILER_H_ +#define _GLAMOR_COMPILER_H_ + +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +#define likely(expr) (__builtin_expect (!!(expr), 1)) +#define unlikely(expr) (__builtin_expect (!!(expr), 0)) +#define noinline __attribute__((noinline)) +#define fastcall __attribute__((regparm(3))) +#define must_check __attribute__((warn_unused_result)) +#define constant __attribute__((const)) +#else +#define likely(expr) (expr) +#define unlikely(expr) (expr) +#define noinline +#define fastcall +#define must_check +#define constant +#endif + +#ifdef HAVE_VALGRIND +#define VG(x) x +#else +#define VG(x) +#endif + +#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s))) + +#define COMPILE_TIME_ASSERT(E) ((void)sizeof(char[1 - 2*!(E)])) + +#endif /* _SNA_COMPILER_H_ */ diff --git a/extra/glamor-egl/git-fixes.patch b/extra/glamor-egl/git-fixes.patch new file mode 100644 index 000000000..4cf1b9fa0 --- /dev/null +++ b/extra/glamor-egl/git-fixes.patch @@ -0,0 +1,177 @@ +From beeddaae1da253d1a442228a75f80ef40a0204ac Mon Sep 17 00:00:00 2001 +From: Michel Dänzer +Date: Wed, 31 Oct 2012 15:56:00 +0000 +Subject: Don't use glBlitFramebufferEXT for overlapping copies. + +According to the GL_EXT_framebuffer_blit spec, the result of doing so is +undefined. But we need well-defined results. :) + +Signed-off-by: Michel Dänzer +--- +diff --git a/src/glamor_copyarea.c b/src/glamor_copyarea.c +index 7d06833..4e6f953 100644 +--- a/src/glamor_copyarea.c ++++ b/src/glamor_copyarea.c +@@ -318,7 +318,8 @@ __glamor_copy_n_to_n(DrawablePtr src, + dx, dy, + src_pixmap, dst_pixmap); + #ifndef GLAMOR_GLES2 +- if ((overlaped || glamor_priv->state != RENDER_STATE ++ if (!overlaped && ++ (glamor_priv->state != RENDER_STATE + || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex) + && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, + dy)) { +-- +cgit v0.9.0.2-2-gbebe +From f1457c1c59efdadbad25f01dce9433643d688844 Mon Sep 17 00:00:00 2001 +From: Zhigang Gong +Date: Tue, 13 Nov 2012 02:08:02 +0000 +Subject: glamor_compositerects: Need to initialize region before fallback. + +As we need to call DamageRegionAppend even for fallback path, +we must initialize the region before do that. Pointed by +Igor Vagulin. + +https://bugs.freedesktop.org/show_bug.cgi?id=56940 + +Signed-off-by: Zhigang Gong +--- +diff --git a/src/glamor_compositerects.c b/src/glamor_compositerects.c +index 5fe1bbf..f1564a2 100644 +--- a/src/glamor_compositerects.c ++++ b/src/glamor_compositerects.c +@@ -131,16 +131,6 @@ glamor_composite_rectangles(CARD8 op, + return; + } + +- pixmap = glamor_get_drawable_pixmap(dst->pDrawable); +- priv = glamor_get_pixmap_private(pixmap); +- +- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) +- goto fallback; +- if (dst->alphaMap) { +- DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__); +- goto fallback; +- } +- + if ((color->red|color->green|color->blue|color->alpha) <= 0x00ff) { + switch (op) { + case PictOpOver: +@@ -204,6 +194,16 @@ glamor_composite_rectangles(CARD8 op, + return; + } + ++ pixmap = glamor_get_drawable_pixmap(dst->pDrawable); ++ priv = glamor_get_pixmap_private(pixmap); ++ ++ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) ++ goto fallback; ++ if (dst->alphaMap) { ++ DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__); ++ goto fallback; ++ } ++ + need_free_region = TRUE; + + DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n", +-- +cgit v0.9.0.2-2-gbebe +From 4a0ac3ff00d70b13e8483d50657187c7abdfc110 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Sat, 29 Dec 2012 06:28:17 +0000 +Subject: glamor: fix make distcheck part 1 + +This just adds the headers, then it falls over on the sdk_HEADERS +as it overrides proper install paths by the looks of it. + +Signed-off-by: Dave Airlie +--- +diff --git a/src/Makefile.am b/src/Makefile.am +index 766aac7..e1ee86d 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -20,10 +20,13 @@ AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS) + libglamor_la_LDFLAGS = -avoid-version + + libglamor_la_SOURCES = \ ++ compat-api.h \ + glamor.c \ + glamor_copyarea.c \ + glamor_copywindow.c \ + glamor_core.c \ ++ glamor_debug.h \ ++ glamor_gl_dispatch.h \ + glamor_fill.c \ + glamor_fillspans.c \ + glamor_getspans.c \ +@@ -42,6 +45,7 @@ libglamor_la_SOURCES = \ + glamor_copyplane.c\ + glamor_glyphblt.c\ + glamor_polyops.c\ ++ glamor_priv.h\ + glamor_pixmap.c\ + glamor_largepixmap.c\ + glamor_picture.c\ +@@ -49,7 +53,9 @@ libglamor_la_SOURCES = \ + glamor_gl_dispatch.c\ + glamor_fbo.c\ + glamor_compositerects.c\ +- glamor.h ++ glamor_utils.h\ ++ glamor.h\ ++ glapi.h + + sdk_HEADERS = glamor.h + +-- +cgit v0.9.0.2-2-gbebe +From c6d9cb1eb4962a15f8bbc869e9fef6d1464165af Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Sat, 29 Dec 2012 06:42:10 +0000 +Subject: glamor: add compiler.h + +This is also required for distchecking. + +Signed-off-by: Dave Airlie +--- +diff --git a/src/Makefile.am b/src/Makefile.am +index e1ee86d..55721f6 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -21,6 +21,7 @@ libglamor_la_LDFLAGS = -avoid-version + + libglamor_la_SOURCES = \ + compat-api.h \ ++ compiler.h \ + glamor.c \ + glamor_copyarea.c \ + glamor_copywindow.c \ +-- +cgit v0.9.0.2-2-gbebe +From c0729336ae35dcc7e46bcf840d6e9a056d5cdd26 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Sat, 29 Dec 2012 06:42:30 +0000 +Subject: glamor_utils: fix unlikely define use + +using a define across a split line expression is failure, compiling +with warnings shows this up. + +Signed-off-by: Dave Airlie +--- +diff --git a/src/glamor_utils.h b/src/glamor_utils.h +index 36beb49..d307838 100644 +--- a/src/glamor_utils.h ++++ b/src/glamor_utils.h +@@ -80,8 +80,7 @@ + + #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_) \ + do { \ +- if (unlikely(_priv_ && (_priv_)->type \ +- == GLAMOR_TEXTURE_LARGE)) { \ ++ if (unlikely(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) { \ + *(_xoff_) = - (_priv_)->large.box.x1; \ + *(_yoff_) = - (_priv_)->large.box.y1; \ + } else { \ +-- +cgit v0.9.0.2-2-gbebe diff --git a/extra/glamor-egl/glamor_debug.h b/extra/glamor-egl/glamor_debug.h new file mode 100644 index 000000000..f0c969b11 --- /dev/null +++ b/extra/glamor-egl/glamor_debug.h @@ -0,0 +1,116 @@ +/* + * Copyright © 2009 Intel Corporation + * Copyright © 1998 Keith Packard + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Zhigang Gong + * + */ + +#ifndef __GLAMOR_DEBUG_H__ +#define __GLAMOR_DEBUG_H__ + + +#define GLAMOR_DELAYED_STRING_MAX 64 + +#define GLAMOR_DEBUG_NONE 0 +#define GLAMOR_DEBUG_UNIMPL 0 +#define GLAMOR_DEBUG_FALLBACK 1 +#define GLAMOR_DEBUG_TEXTURE_DOWNLOAD 2 +#define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD 3 + +extern void +AbortServer(void) + _X_NORETURN; + +#define GLAMOR_PANIC(_format_, ...) \ + do { \ + LogMessageVerb(X_NONE, 0, "Glamor Fatal Error" \ + " at %32s line %d: " _format_ "\n", \ + __FUNCTION__, __LINE__, \ + ##__VA_ARGS__ ); \ + exit(1); \ + } while(0) + + + + +#define __debug_output_message(_format_, _prefix_, ...) \ + LogMessageVerb(X_NONE, 0, \ + "%32s:\t" _format_ , \ + /*_prefix_,*/ \ + __FUNCTION__, \ + ##__VA_ARGS__) + +#define glamor_debug_output(_level_, _format_,...) \ + do { \ + if (glamor_debug_level >= _level_) \ + __debug_output_message(_format_, \ + "Glamor debug", \ + ##__VA_ARGS__); \ + } while(0) + + +#define glamor_fallback(_format_,...) \ + do { \ + if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) \ + __debug_output_message(_format_, \ + "Glamor fallback", \ + ##__VA_ARGS__);} while(0) + + + +#define glamor_delayed_fallback(_screen_, _format_,...) \ + do { \ + if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) { \ + glamor_screen_private *_glamor_priv_; \ + _glamor_priv_ = glamor_get_screen_private(_screen_); \ + _glamor_priv_->delayed_fallback_pending = 1; \ + snprintf(_glamor_priv_->delayed_fallback_string, \ + GLAMOR_DELAYED_STRING_MAX, \ + "glamor delayed fallback: \t%s " _format_ , \ + __FUNCTION__, ##__VA_ARGS__); } } while(0) + + +#define glamor_clear_delayed_fallbacks(_screen_) \ + do { \ + if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) { \ + glamor_screen_private *_glamor_priv_; \ + _glamor_priv_ = glamor_get_screen_private(_screen_); \ + _glamor_priv_->delayed_fallback_pending = 0; } } while(0) + +#define glamor_report_delayed_fallbacks(_screen_) \ + do { \ + if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) { \ + glamor_screen_private *_glamor_priv_; \ + _glamor_priv_ = glamor_get_screen_private(_screen_); \ + LogMessageVerb(X_INFO, 0, "%s", \ + _glamor_priv_->delayed_fallback_string); \ + _glamor_priv_->delayed_fallback_pending = 0; } } while(0) + +#define DEBUGF(str, ...) do {} while(0) +//#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__) +#define DEBUGRegionPrint(x) do {} while (0) +//#define DEBUGRegionPrint RegionPrint + + +#endif diff --git a/extra/glamor-egl/glamor_gl_dispatch.h b/extra/glamor-egl/glamor_gl_dispatch.h new file mode 100644 index 000000000..b3fc3a629 --- /dev/null +++ b/extra/glamor-egl/glamor_gl_dispatch.h @@ -0,0 +1,137 @@ +typedef struct glamor_gl_dispatch { + /* Transformation functions */ + void (*glMatrixMode) (GLenum mode); + void (*glLoadIdentity) (void); + void (*glViewport) (GLint x, GLint y, GLsizei width, + GLsizei height); + /* Drawing functions */ + void (*glRasterPos2i) (GLint x, GLint y); + + /* Vertex Array */ + void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count); + + /* Elements Array*/ + void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices); + + /* Raster functions */ + void (*glReadPixels) (GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid * pixels); + + void (*glDrawPixels) (GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels); + void (*glPixelStorei) (GLenum pname, GLint param); + /* Texture Mapping */ + + void (*glTexParameteri) (GLenum target, GLenum pname, GLint param); + void (*glTexImage2D) (GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid * pixels); + /* 1.1 */ + void (*glGenTextures) (GLsizei n, GLuint * textures); + void (*glDeleteTextures) (GLsizei n, const GLuint * textures); + void (*glBindTexture) (GLenum target, GLuint texture); + void (*glTexSubImage2D) (GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels); + /* MISC */ + void (*glFlush) (void); + void (*glFinish) (void); + void (*glGetIntegerv) (GLenum pname, GLint * params); + const GLubyte *(*glGetString) (GLenum name); + void (*glScissor) (GLint x, GLint y, GLsizei width, + GLsizei height); + void (*glEnable) (GLenum cap); + void (*glDisable) (GLenum cap); + void (*glBlendFunc) (GLenum sfactor, GLenum dfactor); + void (*glLogicOp) (GLenum opcode); + + /* 1.3 */ + void (*glActiveTexture) (GLenum texture); + + /* GL Extentions */ + void (*glGenBuffers) (GLsizei n, GLuint * buffers); + void (*glBufferData) (GLenum target, GLsizeiptr size, + const GLvoid * data, GLenum usage); + GLvoid *(*glMapBuffer) (GLenum target, GLenum access); + GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + GLboolean (*glUnmapBuffer) (GLenum target); + void (*glBindBuffer) (GLenum target, GLuint buffer); + void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers); + + void (*glFramebufferTexture2D) (GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level); + void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); + void (*glDeleteFramebuffers) (GLsizei n, + const GLuint * framebuffers); + void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers); + GLenum (*glCheckFramebufferStatus) (GLenum target); + void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, + GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + + void (*glVertexAttribPointer) (GLuint index, GLint size, + GLenum type, GLboolean normalized, + GLsizei stride, + const GLvoid * pointer); + void (*glDisableVertexAttribArray) (GLuint index); + void (*glEnableVertexAttribArray) (GLuint index); + void (*glBindAttribLocation) (GLuint program, GLuint index, + const GLchar * name); + + void (*glLinkProgram) (GLuint program); + void (*glShaderSource) (GLuint shader, GLsizei count, + const GLchar * *string, + const GLint * length); + void (*glUseProgram) (GLuint program); + void (*glUniform1i) (GLint location, GLint v0); + void (*glUniform1f) (GLint location, GLfloat v0); + void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, + GLfloat v2, GLfloat v3); + void (*glUniform1fv) (GLint location, GLsizei count, + const GLfloat * value); + void (*glUniform2fv) (GLint location, GLsizei count, + const GLfloat * value); + void (*glUniform4fv) (GLint location, GLsizei count, + const GLfloat * value); + void (*glUniformMatrix3fv) (GLint location, GLsizei count, + GLboolean transpose, const GLfloat* value); + GLuint (*glCreateProgram) (void); + GLuint (*glDeleteProgram) (GLuint); + GLuint (*glCreateShader) (GLenum type); + void (*glCompileShader) (GLuint shader); + void (*glAttachShader) (GLuint program, GLuint shader); + void (*glDeleteShader) (GLuint shader); + void (*glGetShaderiv) (GLuint shader, GLenum pname, + GLint * params); + void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize, + GLsizei * length, GLchar * infoLog); + void (*glGetProgramiv) (GLuint program, GLenum pname, + GLint * params); + void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize, + GLsizei * length, GLchar * infoLog); + GLint (*glGetUniformLocation) (GLuint program, + const GLchar * name); + +} glamor_gl_dispatch; + + +typedef void *(*get_proc_address_t) (const char *); + +_X_EXPORT Bool +glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, + int gl_version, + get_proc_address_t get_proc_address); + + +_X_EXPORT Bool +glamor_gl_dispatch_init(ScreenPtr screen, + struct glamor_gl_dispatch *dispatch, + int gl_version); diff --git a/extra/glamor-egl/glamor_glext.h b/extra/glamor-egl/glamor_glext.h new file mode 100644 index 000000000..1f7206b99 --- /dev/null +++ b/extra/glamor-egl/glamor_glext.h @@ -0,0 +1,64 @@ +/* + * Copyright © 2001 Keith Packard + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Zhigang Gong + * + */ + + +#ifdef GLAMOR_GLES2 + +#define GL_BGRA GL_BGRA_EXT +#define GL_COLOR_INDEX 0x1900 +#define GL_BITMAP 0x1A00 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 + +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_CLAMP_TO_BORDER 0x812D + +#define GL_READ_WRITE 0x88BA +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 + +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 + +#define GL_PACK_INVERT_MESA 0x8758 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 + +#endif diff --git a/extra/glamor-egl/glamor_priv.h b/extra/glamor-egl/glamor_priv.h new file mode 100644 index 000000000..6e80ebdf9 --- /dev/null +++ b/extra/glamor-egl/glamor_priv.h @@ -0,0 +1,1016 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ +#ifndef GLAMOR_PRIV_H +#define GLAMOR_PRIV_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "compiler.h" + +#include +#ifndef DEBUG +#define NDEBUG +#endif +#include "glamor.h" +#include "compat-api.h" + +#define GL_GLEXT_PROTOTYPES + +#ifdef GLAMOR_GLES2 +#include +#include + +#define GLAMOR_DEFAULT_PRECISION "precision mediump float;\n" +#include "glamor_glext.h" +#else +#include +#include +#define GLAMOR_DEFAULT_PRECISION +#endif + +#ifdef RENDER +#include "glyphstr.h" +#endif + +#include "glamor_debug.h" + +#include +/* The list.h rename all the function to add xorg_ prefix. + We add hack here to avoid the compile error when using + old version xserver header file. + These will be removed in future. */ +#ifndef xorg_list_entry +#define xorg_list list +#define xorg_list_for_each_entry list_for_each_entry +#define xorg_list_for_each_entry_safe list_for_each_entry_safe +#define xorg_list_del list_del +#define xorg_list_add list_add +#define xorg_list_append list_append +#define xorg_list_init list_init +#endif + +struct glamor_pixmap_private; + +typedef struct glamor_composite_shader { + GLuint prog; + GLint dest_to_dest_uniform_location; + GLint dest_to_source_uniform_location; + GLint dest_to_mask_uniform_location; + GLint source_uniform_location; + GLint mask_uniform_location; + GLint source_wh; + GLint mask_wh; + GLint source_repeat_mode; + GLint mask_repeat_mode; + union { + float source_solid_color[4]; + struct { + struct glamor_pixmap_private *source_priv; + PicturePtr source; + }; + }; + + union { + float mask_solid_color[4]; + struct { + struct glamor_pixmap_private *mask_priv; + PicturePtr mask; + }; + }; +} glamor_composite_shader; + +enum shader_source { + SHADER_SOURCE_SOLID, + SHADER_SOURCE_TEXTURE, + SHADER_SOURCE_TEXTURE_ALPHA, + SHADER_SOURCE_COUNT, +}; + +enum shader_mask { + SHADER_MASK_NONE, + SHADER_MASK_SOLID, + SHADER_MASK_TEXTURE, + SHADER_MASK_TEXTURE_ALPHA, + SHADER_MASK_COUNT, +}; + +enum shader_in { + SHADER_IN_SOURCE_ONLY, + SHADER_IN_NORMAL, + SHADER_IN_CA_SOURCE, + SHADER_IN_CA_ALPHA, + SHADER_IN_COUNT, +}; + +struct shader_key { + enum shader_source source; + enum shader_mask mask; + enum shader_in in; +}; + +struct blendinfo { + Bool dest_alpha; + Bool source_alpha; + GLenum source_blend; + GLenum dest_blend; +}; + +typedef struct { + INT16 x_src; + INT16 y_src; + INT16 x_mask; + INT16 y_mask; + INT16 x_dst; + INT16 y_dst; + INT16 width; + INT16 height; +} glamor_composite_rect_t; + + +enum glamor_vertex_type { + GLAMOR_VERTEX_POS, + GLAMOR_VERTEX_SOURCE, + GLAMOR_VERTEX_MASK +}; + + +enum gradient_shader { + SHADER_GRADIENT_LINEAR, + SHADER_GRADIENT_RADIAL, + SHADER_GRADIENT_CONICAL, + SHADER_GRADIENT_COUNT, +}; + +enum gradient_shader_prog { + SHADER_GRADIENT_VS_PROG, + SHADER_GRADIENT_FS_MAIN_PROG, + SHADER_GRADIENT_FS_GETCOLOR_PROG, + SHADER_GRADIENT_PROG_COUNT, +}; + +struct glamor_screen_private; +struct glamor_pixmap_private; + +enum glamor_gl_flavor { + GLAMOR_GL_DESKTOP, // OPENGL API + GLAMOR_GL_ES2 // OPENGL ES2.0 API +}; + +#define GLAMOR_CREATE_PIXMAP_CPU 0x100 +#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101 +#define GLAMOR_CREATE_FBO_NO_FBO 0x103 +#define GLAMOR_CREATE_PIXMAP_MAP 0x104 + +#define GLAMOR_CREATE_TEXTURE_EXACT_SIZE 0x104 + +#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 + +#define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024) + +typedef struct { + PicturePtr picture; /* Where the glyphs of the cache are stored */ + GlyphPtr *glyphs; + uint16_t count; + uint16_t evict; +} glamor_glyph_cache_t; + +#include "glamor_gl_dispatch.h" + +struct glamor_saved_procs { + CloseScreenProcPtr close_screen; + CreateGCProcPtr create_gc; + CreatePixmapProcPtr create_pixmap; + DestroyPixmapProcPtr destroy_pixmap; + GetSpansProcPtr get_spans; + GetImageProcPtr get_image; + CompositeProcPtr composite; + CompositeRectsProcPtr composite_rects; + TrapezoidsProcPtr trapezoids; + GlyphsProcPtr glyphs; + ChangeWindowAttributesProcPtr change_window_attributes; + CopyWindowProcPtr copy_window; + BitmapToRegionProcPtr bitmap_to_region; + TrianglesProcPtr triangles; + AddTrapsProcPtr addtraps; + CreatePictureProcPtr create_picture; + DestroyPictureProcPtr destroy_picture; + UnrealizeGlyphProcPtr unrealize_glyph; +}; + +#ifdef GLAMOR_GLES2 +#define CACHE_FORMAT_COUNT 3 +#else +#define CACHE_FORMAT_COUNT 2 +#endif + +#define CACHE_BUCKET_WCOUNT 4 +#define CACHE_BUCKET_HCOUNT 4 + +#define GLAMOR_TICK_AFTER(t0, t1) \ + (((int)(t1) - (int)(t0)) < 0) + +#define IDLE_STATE 0 +#define RENDER_STATE 1 +#define BLIT_STATE 2 +#define RENDER_IDEL_MAX 32 + +typedef struct glamor_screen_private { + struct glamor_gl_dispatch _dispatch; + int yInverted; + unsigned int tick; + enum glamor_gl_flavor gl_flavor; + int has_pack_invert; + int has_fbo_blit; + int max_fbo_size; + + struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; + unsigned long fbo_cache_watermark; + + /* glamor_solid */ + GLint solid_prog; + GLint solid_color_uniform_location; + + /* vertext/elment_index buffer object for render */ + GLuint vbo, ebo; + int vbo_offset; + int vbo_size; + char *vb; + int vb_stride; + Bool has_source_coords, has_mask_coords; + int render_nr_verts; + glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] + [SHADER_MASK_COUNT] + [SHADER_IN_COUNT]; + glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; + Bool glyph_cache_initialized; + + /* shaders to restore a texture to another texture.*/ + GLint finish_access_prog[2]; + GLint finish_access_revert[2]; + GLint finish_access_swap_rb[2]; + + /* glamor_tile */ + GLint tile_prog; + GLint tile_wh; + + /* glamor gradient, 0 for small nstops, 1 for + large nstops and 2 for dynamic generate. */ + GLint gradient_prog[SHADER_GRADIENT_COUNT][3]; + GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3]; + int linear_max_nstops; + GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3]; + int radial_max_nstops; + + /* glamor trapezoid shader. */ + GLint trapezoid_prog; + + /* glamor_putimage */ + GLint put_image_xybitmap_prog; + GLint put_image_xybitmap_fg_uniform_location; + GLint put_image_xybitmap_bg_uniform_location; + + PixmapPtr *back_pixmap; + int screen_fbo; + struct glamor_saved_procs saved_procs; + char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; + int delayed_fallback_pending; + int flags; + int state; + unsigned int render_idle_cnt; + ScreenPtr screen; +} glamor_screen_private; + +typedef enum glamor_access { + GLAMOR_ACCESS_RO, + GLAMOR_ACCESS_RW, + GLAMOR_ACCESS_WO, +} glamor_access_t; + +#define GLAMOR_FBO_NORMAL 1 +#define GLAMOR_FBO_DOWNLOADED 2 +/* glamor_pixmap_fbo: + * @list: to be used to link to the cache pool list. + * @expire: when push to cache pool list, set a expire count. + * will be freed when glamor_priv->tick is equal or + * larger than this expire count in block handler. + * @pbo_valid: The pbo has a valid copy of the pixmap's data. + * @tex: attached texture. + * @fb: attached fbo. + * @pbo: attached pbo. + * @width: width of this fbo. + * @height: height of this fbo. + * @format: internal format of this fbo's texture. + * @type: internal type of this fbo's texture. + * @glamor_priv: point to glamor private data. + */ +typedef struct glamor_pixmap_fbo { + struct xorg_list list; + unsigned int expire; + unsigned char pbo_valid; + GLuint tex; + GLuint fb; + GLuint pbo; + int width; + int height; + GLenum format; + GLenum type; + glamor_screen_private *glamor_priv; +} glamor_pixmap_fbo; + +/* + * glamor_pixmap_private - glamor pixmap's private structure. + * @gl_fbo: + * 0 - The pixmap doesn't has a fbo attached to it. + * GLAMOR_FBO_NORMAL - The pixmap has a fbo and can be accessed normally. + * GLAMOR_FBO_DOWNLOADED - The pixmap has a fbo and already downloaded to + * CPU, so it can only be treated as a in-memory pixmap + * if this bit is set. + * @gl_tex: The pixmap is in a gl texture originally. + * @is_picture: The drawable is attached to a picture. + * @pict_format: the corresponding picture's format. + * @pixmap: The corresponding pixmap's pointer. + * + * For GLAMOR_TEXTURE_LARGE, nbox should larger than 1. + * And the box and fbo will both have nbox elements. + * and box[i] store the relatively coords in this pixmap + * of the fbo[i]. The reason why use boxes not region to + * represent this structure is we may need to use overlapped + * boxes for one pixmap for some special reason. + * + * pixmap + * ****************** + * * fbo0 * fbo1 * + * * * * + * ****************** + * * fbo2 * fbo3 * + * * * * + * ****************** + * + * Let's assume the texture has size of 1024x1024 + * box[0] = {0,0,1024,1024} + * box[1] = {1024,0,2048,2048} + * ... + * + * For GLAMOR_TEXTURE_ATLAS nbox should be 1. And box + * and fbo both has one elements, and the box store + * the relatively coords in the fbo of this pixmap: + * + * fbo + * ****************** + * * pixmap * + * * ********* * + * * * * * + * * ********* * + * * * + * ****************** + * + * Assume the pixmap is at the (100,100) relatively to + * the fbo's origin. + * box[0]={100, 100, 1124, 1124}; + * + * Considering large pixmap is not a normal case, to keep + * it simple, I designe it as the following way. + * When deal with a large pixmap, it split the working + * rectangle into serval boxes, and each box fit into a + * corresponding fbo. And then the rendering function will + * loop from the left-top box to the right-bottom box, + * each time, we will set current box and current fbo + * to the box and fbo elements. Thus the inner routines + * can handle it as normal, only the coords calculation need + * to aware of it's large pixmap. + * + * Currently, we haven't implemented the atlas pixmap. + * + **/ + +typedef struct glamor_pixmap_clipped_regions{ + int block_idx; + RegionPtr region; +} glamor_pixmap_clipped_regions; + +#define SET_PIXMAP_FBO_CURRENT(priv, idx) \ + do { \ + if (priv->type == GLAMOR_TEXTURE_LARGE) { \ + (priv)->large.base.fbo = priv->large.fbo_array[idx]; \ + (priv)->large.box = priv->large.box_array[idx]; \ + } \ + } while(0) + +typedef struct glamor_pixmap_private_base { + glamor_pixmap_type_t type; + unsigned char gl_fbo:2; + unsigned char is_picture:1; + unsigned char gl_tex:1; + glamor_pixmap_fbo *fbo; + PixmapPtr pixmap; + int drm_stride; + glamor_screen_private *glamor_priv; + PicturePtr picture; +}glamor_pixmap_private_base_t; + +/* + * @base.fbo: current fbo. + * @box: current fbo's coords in the whole pixmap. + * @block_w: block width of this large pixmap. + * @block_h: block height of this large pixmap. + * @block_wcnt: block count in one block row. + * @block_hcnt: block count in one block column. + * @nbox: total block count. + * @box_array: contains each block's corresponding box. + * @fbo_array: contains each block's fbo pointer. + * + **/ +typedef struct glamor_pixmap_private_large { + union { + glamor_pixmap_type_t type; + glamor_pixmap_private_base_t base; + }; + BoxRec box; + int block_w; + int block_h; + int block_wcnt; + int block_hcnt; + int nbox; + BoxPtr box_array; + glamor_pixmap_fbo **fbo_array; +}glamor_pixmap_private_large_t; + +/* + * @box: the relative coords in the corresponding fbo. + */ +typedef struct glamor_pixmap_private_atlas { + union { + glamor_pixmap_type_t type; + glamor_pixmap_private_base_t base; + }; + BoxRec box; +}glamor_pixmap_private_atlas_t; + +typedef struct glamor_pixmap_private { + union { + glamor_pixmap_type_t type; + glamor_pixmap_private_base_t base; + glamor_pixmap_private_large_t large; + glamor_pixmap_private_atlas_t atlas; + }; +}glamor_pixmap_private; + +/* + * Pixmap dynamic status, used by dynamic upload feature. + * + * GLAMOR_NONE: initial status, don't need to do anything. + * GLAMOR_UPLOAD_PENDING: marked as need to be uploaded to gl texture. + * GLAMOR_UPLOAD_DONE: the pixmap has been uploaded successfully. + * GLAMOR_UPLOAD_FAILED: fail to upload the pixmap. + * + * */ +typedef enum glamor_pixmap_status { + GLAMOR_NONE, + GLAMOR_UPLOAD_PENDING, + GLAMOR_UPLOAD_DONE, + GLAMOR_UPLOAD_FAILED +} glamor_pixmap_status_t; + +extern DevPrivateKey glamor_screen_private_key; +extern DevPrivateKey glamor_pixmap_private_key; +static inline glamor_screen_private * +glamor_get_screen_private(ScreenPtr screen) +{ + return (glamor_screen_private *) + dixLookupPrivate(&screen->devPrivates, + glamor_screen_private_key); +} + +static inline void +glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv) +{ + dixSetPrivate(&screen->devPrivates, + glamor_screen_private_key, + priv); +} + + + +static inline glamor_pixmap_private * +glamor_get_pixmap_private(PixmapPtr pixmap) +{ + glamor_pixmap_private *priv; + priv = dixLookupPrivate(&pixmap->devPrivates, + glamor_pixmap_private_key); + if (!priv) { + glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY); + priv = dixLookupPrivate(&pixmap->devPrivates, + glamor_pixmap_private_key); + } + return priv; +} + +void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv); + +/** + * Returns TRUE if the given planemask covers all the significant bits in the + * pixel values for pDrawable. + */ +static inline Bool +glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) +{ + return (planemask & FbFullMask(drawable->depth)) == + FbFullMask(drawable->depth); +} + +extern int glamor_debug_level; + +/* glamor.c */ +PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); + +Bool glamor_destroy_pixmap(PixmapPtr pixmap); + +glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv); +void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo); +glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, + int w, int h, GLenum format, GLint tex, int flag); +glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv, + int w, int h, GLenum format, int flag); +void glamor_destroy_fbo(glamor_pixmap_fbo *fbo); +void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv); +void glamor_purge_fbo(glamor_pixmap_fbo *fbo); + +void glamor_init_pixmap_fbo(ScreenPtr screen); +void glamor_fini_pixmap_fbo(ScreenPtr screen); +Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap); +void glamor_fbo_expire(glamor_screen_private *glamor_priv); + +glamor_pixmap_fbo * +glamor_create_fbo_array(glamor_screen_private *glamor_priv, + int w, int h, GLenum format, int flag, + int block_w, int block_h, glamor_pixmap_private *); + +/* glamor_copyarea.c */ +RegionPtr +glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, + int dsty); +void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, + BoxPtr box, int nbox, int dx, int dy, Bool reverse, + Bool upsidedown, Pixel bitplane, void *closure); + +/* glamor_copywindow.c */ +void glamor_copy_window(WindowPtr win, DDXPointRec old_origin, + RegionPtr src_region); + +/* glamor_core.c */ +Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); +void glamor_finish_access(DrawablePtr drawable, glamor_access_t access); +Bool glamor_prepare_access_window(WindowPtr window); +void glamor_finish_access_window(WindowPtr window); +Bool glamor_prepare_access_gc(GCPtr gc); +void glamor_finish_access_gc(GCPtr gc); +void glamor_init_finish_access_shaders(ScreenPtr screen); +void glamor_fini_finish_access_shaders(ScreenPtr screen); +const Bool glamor_get_drawable_location(const DrawablePtr drawable); +void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, + int *x, int *y); +Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, + int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, + unsigned long fg_pixel, unsigned long bg_pixel, + int stipple_x, int stipple_y); +GLint glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type, + const char *source); +void glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog); +void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, + unsigned long fg_pixel, + GLfloat * color); + +int glamor_set_destination_pixmap(PixmapPtr pixmap); +int glamor_set_destination_pixmap_priv(glamor_pixmap_private * + pixmap_priv); +void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int); + +/* nc means no check. caller must ensure this pixmap has valid fbo. + * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. + * */ +void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * + pixmap_priv); + +glamor_pixmap_fbo * +glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format, + GLenum type, int no_alpha, int revert, int swap_rb); + +Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch, + unsigned char alu); +Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); +Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); +RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); +Bool glamor_gl_has_extension(const char *extension); +int glamor_gl_get_version(void); + +#define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \ + ((major) * 256) \ + + ((minor) * 1)) + + + + +/* glamor_fill.c */ +Bool glamor_fill(DrawablePtr drawable, + GCPtr gc, int x, int y, int width, int height, Bool fallback); +Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, + unsigned long fg_pixel); +Bool +glamor_solid_boxes(PixmapPtr pixmap, + BoxPtr box, int nbox, + unsigned long fg_pixel); + +/* glamor_fillspans.c */ +void glamor_fill_spans(DrawablePtr drawable, + GCPtr gc, + int n, DDXPointPtr points, int *widths, int sorted); + +void glamor_init_solid_shader(ScreenPtr screen); +void glamor_fini_solid_shader(ScreenPtr screen); + +/* glamor_getspans.c */ +void + +glamor_get_spans(DrawablePtr drawable, + int wmax, + DDXPointPtr points, + int *widths, int nspans, char *dst_start); + +/* glamor_glyphs.c */ +void glamor_glyphs_fini(ScreenPtr screen); +void glamor_glyphs(CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, int nlist, GlyphListPtr list, + GlyphPtr * glyphs); + +/* glamor_setspans.c */ +void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, + DDXPointPtr points, int *widths, int n, int sorted); + +/* glamor_polyfillrect.c */ +void +glamor_poly_fill_rect(DrawablePtr drawable, + GCPtr gc, int nrect, xRectangle * prect); + +/* glamor_polylines.c */ +void + +glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, + DDXPointPtr points); + +/* glamor_putimage.c */ +void + +glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits); +void glamor_init_putimage_shaders(ScreenPtr screen); +void glamor_fini_putimage_shaders(ScreenPtr screen); + +/* glamor_render.c */ +Bool +glamor_composite_clipped_region(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private *soruce_pixmap_priv, + glamor_pixmap_private *mask_pixmap_priv, + glamor_pixmap_private *dest_pixmap_priv, + RegionPtr region, + int x_source, + int y_source, + int x_mask, + int y_mask, + int x_dest, + int y_dest); + +void glamor_composite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); + +void glamor_init_composite_shaders(ScreenPtr screen); +void glamor_fini_composite_shaders(ScreenPtr screen); +void glamor_composite_glyph_rects(CARD8 op, + PicturePtr src, PicturePtr mask, + PicturePtr dst, int nrect, + glamor_composite_rect_t * rects); +void glamor_composite_rects (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects); +void glamor_init_trapezoid_shader(ScreenPtr screen); +void glamor_fini_trapezoid_shader(ScreenPtr screen); +PicturePtr glamor_convert_gradient_picture(ScreenPtr screen, + PicturePtr source, + int x_source, + int y_source, int width, int height); + +Bool glamor_composite_choose_shader(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private *source_pixmap_priv, + glamor_pixmap_private *mask_pixmap_priv, + glamor_pixmap_private *dest_pixmap_priv, + struct shader_key *s_key, + glamor_composite_shader **shader, + struct blendinfo *op_info, + PictFormatShort *psaved_source_format); + +void +glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv, + struct shader_key *key, + glamor_composite_shader *shader, + struct blendinfo *op_info); + +void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts); +void glamor_emit_composite_vert(ScreenPtr screen, + const float *src_coords, + const float *mask_coords, + const float *dst_coords, int i); + +/* glamor_trapezoid.c */ +void glamor_trapezoids(CARD8 op, + PicturePtr src, PicturePtr dst, + PictFormatPtr mask_format, INT16 x_src, INT16 y_src, + int ntrap, xTrapezoid * traps); + +/* glamor_tile.c */ +Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, + int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, + int tile_x, int tile_y); +void glamor_init_tile_shader(ScreenPtr screen); +void glamor_fini_tile_shader(ScreenPtr screen); + +/* glamor_gradient.c */ +void glamor_init_gradient_shader(ScreenPtr screen); +void glamor_fini_gradient_shader(ScreenPtr screen); +PicturePtr glamor_generate_linear_gradient_picture(ScreenPtr screen, + PicturePtr src_picture, + int x_source, int y_source, + int width, int height, + PictFormatShort format); +PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen, + PicturePtr src_picture, + int x_source, int y_source, + int width, int height, + PictFormatShort format); + +/* glamor_triangles.c */ +void + +glamor_triangles(CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris); + +/* glamor_pixmap.c */ + +void glamor_pixmap_init(ScreenPtr screen); +void glamor_pixmap_fini(ScreenPtr screen); +/** + * Download a pixmap's texture to cpu memory. If success, + * One copy of current pixmap's texture will be put into + * the pixmap->devPrivate.ptr. Will use pbo to map to + * the pointer if possible. + * The pixmap must be a gl texture pixmap. gl_fbo and + * gl_tex must be 1. Used by glamor_prepare_access. + * + */ +Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap, + glamor_access_t access); + +void * +glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h, + int stride, void *bits, int pbo, glamor_access_t access); + + +/** + * Restore a pixmap's data which is downloaded by + * glamor_download_pixmap_to_cpu to its original + * gl texture. Used by glamor_finish_access. + * + * The pixmap must be + * in texture originally. In other word, the gl_fbo + * must be 1. + **/ +void glamor_restore_pixmap_to_texture(PixmapPtr pixmap); + +/** + * According to the flag, + * if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure + * the fbo has a valid texture. Otherwise, it will ensure + * the fbo has valid texture and attach to a valid fb. + * If the fbo already has a valid glfbo then do nothing. + */ +Bool +glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag); + +/** + * Upload a pixmap to gl texture. Used by dynamic pixmap + * uploading feature. The pixmap must be a software pixmap. + * This function will change current FBO and current shaders. + */ +enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr + pixmap); + +Bool +glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, + int stride, void *bits, int pbo); + +PixmapPtr +glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, + int w, int h, glamor_access_t access); +void +glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, + int w, int h, glamor_access_t access); + +glamor_pixmap_clipped_regions * +glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, + int *clipped_nbox, int repeat_type, + int reverse, int upsidedown); + +glamor_pixmap_clipped_regions * +glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv, + RegionPtr region, + int *n_region, + int inner_block_w, int inner_block_h, + int reverse, int upsidedown); + +glamor_pixmap_clipped_regions * +glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform, + RegionPtr region, int *n_region, int dx, int dy, int repeat_type, + int reverse, int upsidedown); + +Bool +glamor_composite_largepixmap_region(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private * source_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, + RegionPtr region, Bool force_clip, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, + CARD16 width, CARD16 height); + +Bool +glamor_get_transform_block_size(struct pixman_transform *transform, + int block_w, int block_h, + int *transformed_block_w, + int *transformed_block_h); + +void +glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box, + struct pixman_transform *transform); + +/** + * Upload a picture to gl texture. Similar to the + * glamor_upload_pixmap_to_texture. Used in rendering. + **/ +enum glamor_pixmap_status + glamor_upload_picture_to_texture(PicturePtr picture); + +/** + * Upload bits to a pixmap's texture. This function will + * convert the bits to the specified format/type format + * if the conversion is unavoidable. + **/ +Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type, + int no_alpha, int revert, int swap_rb, void *bits); + +/** + * Destroy all the resources allocated on the uploading + * phase, includs the tex and fbo. + **/ +void glamor_destroy_upload_pixmap(PixmapPtr pixmap); + +int glamor_create_picture(PicturePtr picture); + +Bool +glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); + +void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access); + +void glamor_destroy_picture(PicturePtr picture); + +/* fixup a fbo to the exact size as the pixmap. */ +Bool +glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv); + +void +glamor_picture_format_fixup(PicturePtr picture, + glamor_pixmap_private * pixmap_priv); + +void +glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, char *d); + +void +glamor_add_traps(PicturePtr pPicture, + INT16 x_off, + INT16 y_off, int ntrap, xTrap * traps); + +RegionPtr +glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty, + unsigned long bitPlane); + +void +glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase); + +void +glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase); + +void +glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, + DrawablePtr pDrawable, int w, int h, int x, int y); + +void +glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr ppt); + +void +glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, + xSegment *pSeg); + +void +glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr ppt); + +void +glamor_composite_rectangles(CARD8 op, + PicturePtr dst, + xRenderColor *color, + int num_rects, + xRectangle *rects); + +#include"glamor_utils.h" + +/* Dynamic pixmap upload to texture if needed. + * Sometimes, the target is a gl texture pixmap/picture, + * but the source or mask is in cpu memory. In that case, + * upload the source/mask to gl texture and then avoid + * fallback the whole process to cpu. Most of the time, + * this will increase performance obviously. */ + +#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD +#define GLAMOR_GRADIENT_SHADER +#define GLAMOR_TRAPEZOID_SHADER +#define GLAMOR_TEXTURED_LARGE_PIXMAP 1 +#define WALKAROUND_LARGE_TEXTURE_MAP +#if 0 +#define MAX_FBO_SIZE 32 /* For test purpose only. */ +#endif +//#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK +#define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK + +#endif /* GLAMOR_PRIV_H */ diff --git a/extra/glamor-egl/glamor_utils.h b/extra/glamor-egl/glamor_utils.h new file mode 100644 index 000000000..36beb49ed --- /dev/null +++ b/extra/glamor-egl/glamor_utils.h @@ -0,0 +1,1836 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Zhigang Gong + * + */ + +#ifndef GLAMOR_PRIV_H +#error This file can only be included by glamor_priv.h +#endif + +#ifndef __GLAMOR_UTILS_H__ +#define __GLAMOR_UTILS_H__ + +#define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0) +#define v_from_x_coord_y(_yscale_, _y_) (-2 * (_y_) * (_yscale_) + 1.0) +#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) +#define t_from_x_coord_x(_xscale_, _x_) ((_x_) * (_xscale_)) +#define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_)) +#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_)) + +#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \ + do { \ + int _w_,_h_; \ + PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, _w_, _h_); \ + *(_pxscale_) = 1.0 / _w_; \ + *(_pyscale_) = 1.0 / _h_; \ + } while(0) + +#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \ + do { \ + *(_pxscale_) = 1.0 / (_pixmap_priv_)->base.fbo->width; \ + *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height; \ + } while(0) + +#define GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(priv) \ + (priv->base.fbo->width != priv->base.pixmap->drawable.width \ + || priv->base.fbo->height != priv->base.pixmap->drawable.height) \ + +#define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h) \ + do { \ + if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) { \ + w = priv->large.box.x2 - priv->large.box.x1; \ + h = priv->large.box.y2 - priv->large.box.y1; \ + } else { \ + w = priv->base.pixmap->drawable.width; \ + h = priv->base.pixmap->drawable.height; \ + } \ + } while(0) + +#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv) \ + do { \ + int actual_w, actual_h; \ + PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, actual_w, actual_h); \ + wh[0] = (float)priv->base.fbo->width / actual_w; \ + wh[1] = (float)priv->base.fbo->height / actual_h; \ + wh[2] = 1.0 / priv->base.fbo->width; \ + wh[3] = 1.0 / priv->base.fbo->height; \ + } while(0) + +#define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_) \ + do { \ + if (unlikely(_priv_ && (_priv_)->type \ + == GLAMOR_TEXTURE_LARGE)) { \ + *(_xoff_) = - (_priv_)->large.box.x1; \ + *(_yoff_) = - (_priv_)->large.box.y1; \ + } else { \ + *(_xoff_) = 0; \ + *(_yoff_) = 0; \ + } \ + } while(0) + +#define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \ + + ((float)xFixedFrac(_val_) / 65536.0)) + +#define glamor_picture_get_matrixf(_picture_, _matrix_) \ + do { \ + int _i_; \ + if ((_picture_)->transform) \ + { \ + for(_i_ = 0; _i_ < 3; _i_++) \ + { \ + (_matrix_)[_i_ * 3 + 0] = \ + xFixedToFloat((_picture_)->transform->matrix[_i_][0]); \ + (_matrix_)[_i_ * 3 + 1] = \ + xFixedToFloat((_picture_)->transform->matrix[_i_][1]); \ + (_matrix_)[_i_ * 3 + 2] = \ + xFixedToFloat((_picture_)->transform->matrix[_i_][2]); \ + } \ + } \ + } while(0) + +#define fmod(x, w) (x - w * floor((float)x/w)) + +#define fmodulus(x, w, c) do {c = fmod(x, w); \ + c = c >= 0 ? c : c + w;} \ + while(0) +/* @x: is current coord + * @x2: is the right/bottom edge + * @w: is current width or height + * @odd: is output value, 0 means we are in an even region, 1 means we are in a + * odd region. + * @c: is output value, equal to x mod w. */ +#define fodd_repeat_mod(x, x2, w, odd, c) \ + do { \ + float shift; \ + fmodulus((x), w, c); \ + shift = fabs((x) - (c)); \ + shift = floor(fabs(round(shift)) / w); \ + odd = (int)shift & 1; \ + if (odd && (((x2 % w) == 0) && \ + round(fabs(x)) == x2)) \ + odd = 0; \ + } while(0) + +/* @txy: output value, is the corrected coords. + * @xy: input coords to be fixed up. + * @cd: xy mod wh, is a input value. + * @wh: current width or height. + * @bxy1,bxy2: current box edge's x1/x2 or y1/y2 + * + * case 1: + * ---------- + * | * | + * | | + * ---------- + * tx = (c - x1) mod w + * + * case 2: + * --------- + * * | | + * | | + * --------- + * tx = - (c - (x1 mod w)) + * + * case 3: + * + * ---------- + * | | * + * | | + * ---------- + * tx = ((x2 mod x) - c) + (x2 - x1) + **/ +#define __glamor_repeat_reflect_fixup(txy, xy, \ + cd, wh, bxy1, bxy2) \ + do { \ + cd = wh - cd; \ + if ( xy >= bxy1 && xy < bxy2) { \ + cd = cd - bxy1; \ + fmodulus(cd, wh, txy); \ + } else if (xy < bxy1) { \ + float bxy1_mod; \ + fmodulus(bxy1, wh, bxy1_mod); \ + txy = -(cd - bxy1_mod); \ + } \ + else if (xy >= bxy2) { \ + float bxy2_mod; \ + fmodulus(bxy2, wh, bxy2_mod); \ + if (bxy2_mod == 0) \ + bxy2_mod = wh; \ + txy = (bxy2_mod - cd) + bxy2 - bxy1; \ + } else {assert(0); txy = 0;} \ + } while(0) + +#define _glamor_repeat_reflect_fixup(txy, xy, cd, odd, \ + wh, bxy1, bxy2) \ + do { \ + if (odd) { \ + __glamor_repeat_reflect_fixup(txy, xy, \ + cd, wh, bxy1, bxy2); \ + } else \ + txy = xy - bxy1; \ + } while(0) + +#define _glamor_get_reflect_transform_coords(priv, repeat_type, \ + tx1, ty1, \ + _x1_, _y1_) \ + do { \ + int odd_x, odd_y; \ + float c, d; \ + fodd_repeat_mod(_x1_,priv->box.x2, \ + priv->base.pixmap->drawable.width, \ + odd_x, c); \ + fodd_repeat_mod(_y1_, priv->box.y2, \ + priv->base.pixmap->drawable.height, \ + odd_y, d); \ + DEBUGF("c %f d %f oddx %d oddy %d \n", \ + c, d, odd_x, odd_y); \ + DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2, \ + priv->box.x1, priv->base.fbo->width); \ + DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, \ + priv->box.y1, priv->base.fbo->height); \ + _glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x, \ + priv->base.pixmap->drawable.width, \ + priv->box.x1, priv->box.x2); \ + _glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y, \ + priv->base.pixmap->drawable.height, \ + priv->box.y1, priv->box.y2); \ + } while(0) + +#define _glamor_get_repeat_coords(priv, repeat_type, tx1, \ + ty1, tx2, ty2, \ + _x1_, _y1_, _x2_, \ + _y2_, c, d, odd_x, odd_y) \ + do { \ + if (repeat_type == RepeatReflect) { \ + DEBUGF("x1 y1 %d %d\n", \ + _x1_, _y1_ ); \ + DEBUGF("width %d box.x1 %d \n", \ + (priv)->base.pixmap->drawable.width, \ + priv->box.x1); \ + if (odd_x) { \ + c = (priv)->base.pixmap->drawable.width \ + - c; \ + tx1 = c - priv->box.x1; \ + tx2 = tx1 - ((_x2_) - (_x1_)); \ + } else { \ + tx1 = c - priv->box.x1; \ + tx2 = tx1 + ((_x2_) - (_x1_)); \ + } \ + if (odd_y){ \ + d = (priv)->base.pixmap->drawable.height\ + - d; \ + ty1 = d - priv->box.y1; \ + ty2 = ty1 - ((_y2_) - (_y1_)); \ + } else { \ + ty1 = d - priv->box.y1; \ + ty2 = ty1 + ((_y2_) - (_y1_)); \ + } \ + } else { /* RepeatNormal*/ \ + tx1 = (c - priv->box.x1); \ + ty1 = (d - priv->box.y1); \ + tx2 = tx1 + ((_x2_) - (_x1_)); \ + ty2 = ty1 + ((_y2_) - (_y1_)); \ + } \ + } while(0) + + +/* _x1_ ... _y2_ may has fractional. */ +#define glamor_get_repeat_transform_coords(priv, repeat_type, tx1, \ + ty1, _x1_, _y1_) \ + do { \ + DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \ + (priv)->base.pixmap->drawable.width, \ + priv->box.x1, priv->box.x2, priv->box.y1, \ + priv->box.y2); \ + DEBUGF("x1 %f y1 %f \n", _x1_, _y1_); \ + if (repeat_type != RepeatReflect) { \ + tx1 = _x1_ - priv->box.x1; \ + ty1 = _y1_ - priv->box.y1; \ + } else \ + _glamor_get_reflect_transform_coords(priv, repeat_type, \ + tx1, ty1, \ + _x1_, _y1_); \ + DEBUGF("tx1 %f ty1 %f \n", tx1, ty1); \ + } while(0) + +/* _x1_ ... _y2_ must be integer. */ +#define glamor_get_repeat_coords(priv, repeat_type, tx1, \ + ty1, tx2, ty2, _x1_, _y1_, _x2_, \ + _y2_) \ + do { \ + int c, d; \ + int odd_x = 0, odd_y = 0; \ + DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \ + (priv)->base.pixmap->drawable.width, \ + priv->box.x1, priv->box.x2, \ + priv->box.y1, priv->box.y2); \ + modulus((_x1_), (priv)->base.pixmap->drawable.width, c); \ + modulus((_y1_), (priv)->base.pixmap->drawable.height, d); \ + DEBUGF("c %d d %d \n", c, d); \ + if (repeat_type == RepeatReflect) { \ + odd_x = abs((_x1_ - c) \ + / (priv->base.pixmap->drawable.width)) & 1; \ + odd_y = abs((_y1_ - d) \ + / (priv->base.pixmap->drawable.height)) & 1; \ + } \ + _glamor_get_repeat_coords(priv, repeat_type, tx1, ty1, tx2, ty2,\ + _x1_, _y1_, _x2_, _y2_, c, d, \ + odd_x, odd_y); \ + } while(0) + +#define glamor_transform_point(matrix, tx, ty, x, y) \ + do { \ + int _i_; \ + float _result_[4]; \ + for (_i_ = 0; _i_ < 3; _i_++) { \ + _result_[_i_] = (matrix)[_i_ * 3] * (x) + (matrix)[_i_ * 3 + 1] * (y) \ + + (matrix)[_i_ * 3 + 2]; \ + } \ + tx = _result_[0] / _result_[2]; \ + ty = _result_[1] / _result_[2]; \ + } while(0) + +#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \ + texcoord, yInverted) \ + do { \ + (texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \ + if (likely(yInverted)) \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\ + else \ + (texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \ + DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \ + (texcoord)[1]); \ + } while(0) + +#define glamor_set_transformed_point(priv, matrix, xscale, \ + yscale, texcoord, \ + x, y, \ + yInverted) \ + do { \ + float tx, ty; \ + int fbo_x_off, fbo_y_off; \ + pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ + glamor_transform_point(matrix, tx, ty, x, y); \ + DEBUGF("tx %f ty %f fbooff %d %d \n", \ + tx, ty, fbo_x_off, fbo_y_off); \ + \ + tx += fbo_x_off; \ + ty += fbo_y_off; \ + (texcoord)[0] = t_from_x_coord_x(xscale, tx); \ + if (likely(yInverted)) \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ + else \ + (texcoord)[1] = t_from_x_coord_y(yscale, ty); \ + DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \ + } while(0) + +#define glamor_set_transformed_normalize_tri_tcoords(priv, \ + matrix, \ + xscale, \ + yscale, \ + vtx, \ + yInverted, \ + texcoords) \ + do { \ + glamor_set_transformed_point(priv, matrix, xscale, yscale, \ + texcoords, (vtx)[0], (vtx)[1], \ + yInverted); \ + glamor_set_transformed_point(priv, matrix, xscale, yscale, \ + texcoords+2, (vtx)[2], (vtx)[3], \ + yInverted); \ + glamor_set_transformed_point(priv, matrix, xscale, yscale, \ + texcoords+4, (vtx)[4], (vtx)[5], \ + yInverted); \ + } while (0) + +#define glamor_set_transformed_normalize_tcoords_ext( priv, \ + matrix, \ + xscale, \ + yscale, \ + tx1, ty1, tx2, ty2, \ + yInverted, texcoords, \ + stride) \ + do { \ + glamor_set_transformed_point(priv, matrix, xscale, yscale, \ + texcoords, tx1, ty1, \ + yInverted); \ + glamor_set_transformed_point(priv, matrix, xscale, yscale, \ + texcoords + 1 * stride, tx2, ty1, \ + yInverted); \ + glamor_set_transformed_point(priv, matrix, xscale, yscale, \ + texcoords + 2 * stride, tx2, ty2, \ + yInverted); \ + glamor_set_transformed_point(priv, matrix, xscale, yscale, \ + texcoords + 3 * stride, tx1, ty2, \ + yInverted); \ + } while (0) + +#define glamor_set_transformed_normalize_tcoords( priv, \ + matrix, \ + xscale, \ + yscale, \ + tx1, ty1, tx2, ty2, \ + yInverted, texcoords) \ + do { \ + glamor_set_transformed_normalize_tcoords_ext( priv, \ + matrix, \ + xscale, \ + yscale, \ + tx1, ty1, tx2, ty2, \ + yInverted, texcoords, \ + 2); \ + } while (0) + + + +#define glamor_set_normalize_tri_tcoords(xscale, \ + yscale, \ + vtx, \ + yInverted, \ + texcoords) \ + do { \ + _glamor_set_normalize_tpoint(xscale, yscale, \ + (vtx)[0], (vtx)[1], \ + texcoords, \ + yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, \ + (vtx)[2], (vtx)[3], \ + texcoords+2, \ + yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, \ + (vtx)[4], (vtx)[5], \ + texcoords+4, \ + yInverted); \ + } while (0) + +#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \ + repeat_type, \ + matrix, \ + xscale, \ + yscale, \ + _x1_, _y1_, \ + _x2_, _y2_, \ + yInverted, \ + texcoords, \ + stride) \ + do { \ + if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) { \ + glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \ + yscale, _x1_, _y1_, \ + _x2_, _y2_, yInverted, \ + texcoords, stride); \ + } else { \ + float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \ + float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4; \ + DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_); \ + glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_); \ + glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_); \ + glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_); \ + glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \ + DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \ + tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx1, tty1, \ + tx1, ty1); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx2, tty2, \ + tx2, ty2); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx3, tty3, \ + tx3, ty3); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx4, tty4, \ + tx4, ty4); \ + DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \ + ttx2, tty2, ttx3, tty3, ttx4, tty4); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \ + texcoords, yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \ + texcoords + 1 * stride, yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \ + texcoords + 2 * stride, yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \ + texcoords + 3 * stride, yInverted); \ + } \ + } while (0) + + +#define glamor_set_repeat_transformed_normalize_tcoords( priv, \ + repeat_type, \ + matrix, \ + xscale, \ + yscale, \ + _x1_, _y1_, \ + _x2_, _y2_, \ + yInverted, \ + texcoords) \ + do { \ + glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \ + repeat_type, \ + matrix, \ + xscale, \ + yscale, \ + _x1_, _y1_, \ + _x2_, _y2_, \ + yInverted, \ + texcoords, \ + 2); \ + } while (0) + +#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \ + ty1, tx2, ty2, \ + yInverted, vertices, stride) \ + do { \ + /* vertices may be write-only, so we use following \ + * temporary variable. */ \ + float _t0_, _t1_, _t2_, _t5_; \ + (vertices)[0] = _t0_ = t_from_x_coord_x(xscale, tx1); \ + (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \ + (vertices)[2 * stride] = _t2_; \ + (vertices)[3 * stride] = _t0_; \ + if (likely(yInverted)) { \ + (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \ + (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\ + } \ + else { \ + (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \ + (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);\ + } \ + (vertices)[1 * stride + 1] = _t1_; \ + (vertices)[3 * stride + 1] = _t5_; \ + } while(0) + +#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices, stride) \ + do { \ + if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) { \ + float tx1, tx2, ty1, ty2; \ + int fbo_x_off, fbo_y_off; \ + pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ + tx1 = x1 + fbo_x_off; \ + tx2 = x2 + fbo_x_off; \ + ty1 = y1 + fbo_y_off; \ + ty2 = y2 + fbo_y_off; \ + _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ + tx2, ty2, yInverted, vertices, \ + stride); \ + } else \ + _glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \ + x2, y2, yInverted, vertices, stride);\ + } while(0) + + +#define glamor_set_normalize_tcoords(priv, xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices, 2); \ + } while(0) + +#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \ + xscale, yscale, \ + _x1_, _y1_, _x2_, _y2_, \ + yInverted, vertices, stride)\ + do { \ + if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) { \ + float tx1, tx2, ty1, ty2; \ + if (repeat_type == RepeatPad) { \ + tx1 = _x1_ - priv->large.box.x1; \ + ty1 = _y1_ - priv->large.box.y1; \ + tx2 = tx1 + ((_x2_) - (_x1_)); \ + ty2 = ty1 + ((_y2_) - (_y1_)); \ + } else { \ + glamor_get_repeat_coords((&priv->large), repeat_type, \ + tx1, ty1, tx2, ty2, \ + _x1_, _y1_, _x2_, _y2_); \ + } \ + _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ + tx2, ty2, yInverted, vertices, \ + stride); \ + } else \ + _glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \ + _x2_, _y2_, yInverted, vertices, \ + stride); \ + } while(0) + + +#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \ + xscale, yscale, \ + _x1_, _y1_, _x2_, _y2_, \ + yInverted, vertices) \ + do { \ + glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \ + xscale, yscale, \ + _x1_, _y1_, _x2_, _y2_, \ + yInverted, vertices, 2); \ + } while(0) + +#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + (vertices)[0] = t_from_x_coord_x(xscale, x1); \ + (vertices)[2] = t_from_x_coord_x(xscale, x2); \ + (vertices)[6] = (vertices)[2]; \ + (vertices)[4] = (vertices)[0]; \ + if (likely(yInverted)) { \ + (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \ + } \ + else { \ + (vertices)[1] = t_from_x_coord_y(yscale, y1); \ + (vertices)[7] = t_from_x_coord_y(yscale, y2); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[5] = (vertices)[7]; \ + } while(0) + +#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + (vertices)[0] = (x1); \ + (vertices)[2] = (x2); \ + (vertices)[4] = (vertices)[2]; \ + (vertices)[6] = (vertices)[0]; \ + if (likely(yInverted)) { \ + (vertices)[1] = (y1); \ + (vertices)[5] = (y2); \ + } \ + else { \ + (vertices)[1] = height - (y2); \ + (vertices)[5] = height - (y1); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[7] = (vertices)[5]; \ + } while(0) + +#define glamor_set_tcoords_ext(width, height, x1, y1, x2, y2, \ + yInverted, vertices, stride) \ + do { \ + (vertices)[0] = (x1); \ + (vertices)[1*stride] = (x2); \ + (vertices)[2*stride] = (vertices)[1*stride]; \ + (vertices)[3*stride] = (vertices)[0]; \ + if (likely(yInverted)) { \ + (vertices)[1] = (y1); \ + (vertices)[2*stride + 1] = (y2); \ + } \ + else { \ + (vertices)[1] = height - (y2); \ + (vertices)[2*stride + 1] = height - (y1); \ + } \ + (vertices)[1*stride + 1] = (vertices)[1]; \ + (vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \ + } while(0) + +#define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \ + yInverted, vertices) \ + do { \ + (vertices)[0] = v_from_x_coord_x(xscale, x); \ + if (likely(yInverted)) { \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \ + } else { \ + (vertices)[1] = v_from_x_coord_y(yscale, y); \ + } \ + } while(0) + +#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \ + yInverted, vertices) \ + do { \ + glamor_set_normalize_one_vcoord(xscale, yscale, \ + (vtx)[0], (vtx)[1], \ + yInverted, vertices); \ + glamor_set_normalize_one_vcoord(xscale, yscale, \ + (vtx)[2], (vtx)[3], \ + yInverted, vertices+2); \ + glamor_set_normalize_one_vcoord(xscale, yscale, \ + (vtx)[4], (vtx)[5], \ + yInverted, vertices+4); \ + } while(0) + +#define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + (vertices)[0] = (x1); \ + (vertices)[2] = (x2); \ + (vertices)[6] = (vertices)[2]; \ + (vertices)[4] = (vertices)[0]; \ + if (likely(yInverted)) { \ + (vertices)[1] = (y1); \ + (vertices)[7] = (y2); \ + } \ + else { \ + (vertices)[1] = height - (y2); \ + (vertices)[7] = height - (y1); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[5] = (vertices)[7]; \ + } while(0) + +#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices, stride) \ + do { \ + int fbo_x_off, fbo_y_off; \ + /* vertices may be write-only, so we use following \ + * temporary variable. */ \ + float _t0_, _t1_, _t2_, _t5_; \ + pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ + (vertices)[0] = _t0_ = v_from_x_coord_x(xscale, x1 + fbo_x_off); \ + (vertices)[1 * stride] = _t2_ = v_from_x_coord_x(xscale, \ + x2 + fbo_x_off); \ + (vertices)[2 * stride] = _t2_; \ + (vertices)[3 * stride] = _t0_; \ + if (likely(yInverted)) { \ + (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \ + y1 + fbo_y_off); \ + (vertices)[2 * stride + 1] = _t5_ = \ + v_from_x_coord_y_inverted(yscale, \ + y2 + fbo_y_off); \ + } \ + else { \ + (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \ + (vertices)[2 * stride + 1] = _t5_ = v_from_x_coord_y(yscale, \ + y2 + fbo_y_off); \ + } \ + (vertices)[1 * stride + 1] = _t1_; \ + (vertices)[3 * stride + 1] = _t5_; \ + } while(0) + + +#define glamor_set_normalize_vcoords(priv, xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices, 2); \ + } while(0) + +#define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \ + do { \ + int _i_ = 0, _j_ = 0; \ + for(; _i_ < nverts; _i_++) { \ + for(_j_ = 0; _j_ < nparam; _j_++) { \ + vertices[stride*_i_ + _j_] = params[_j_]; \ + } \ + } \ + } while(0) + +#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \ + x1, y1, x2, y2, \ + yInverted, vertices) \ + do { \ + (vertices)[0] = v_from_x_coord_x(xscale, x1); \ + (vertices)[2] = v_from_x_coord_x(xscale, x2); \ + (vertices)[6] = (vertices)[2]; \ + (vertices)[4] = (vertices)[0]; \ + if (likely(yInverted)) { \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \ + } \ + else { \ + (vertices)[1] = v_from_x_coord_y(yscale, y1); \ + (vertices)[7] = v_from_x_coord_y(yscale, y2); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[5] = (vertices)[7]; \ + } while(0) + +#define glamor_set_normalize_pt(xscale, yscale, x, y, \ + yInverted, pt) \ + do { \ + (pt)[0] = t_from_x_coord_x(xscale, x); \ + if (likely(yInverted)) { \ + (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \ + } else { \ + (pt)[1] = t_from_x_coord_y(yscale, y); \ + } \ + } while(0) + +#define glamor_set_circle_centre(width, height, x, y, \ + yInverted, c) \ + do { \ + (c)[0] = (float)x; \ + if (likely(yInverted)) { \ + (c)[1] = (float)y; \ + } else { \ + (c)[1] = (float)height - (float)y; \ + } \ + } while(0) + +inline static void +glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox) +{ + int x_min, y_min; + int x_max, y_max; + int i; + x_min = y_min = MAXSHORT; + x_max = y_max = MINSHORT; + for (i = 0; i < nbox; i++) { + if (x_min > boxes[i].x1) + x_min = boxes[i].x1; + if (y_min > boxes[i].y1) + y_min = boxes[i].y1; + + if (x_max < boxes[i].x2) + x_max = boxes[i].x2; + if (y_max < boxes[i].y2) + y_max = boxes[i].y2; + } + bound->x1 = x_min; + bound->y1 = y_min; + bound->x2 = x_max; + bound->y2 = y_max; +} + +inline static void +glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy) +{ + int i; + for (i = 0; i < nbox; i++) { + boxes[i].x1 += dx; + boxes[i].y1 += dy; + boxes[i].x2 += dx; + boxes[i].y2 += dy; + } +} + +static inline Bool +region_is_empty(pixman_region16_t *region) +{ + return region->data && region->data->numRects == 0; +} + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define glamor_check_fbo_size(_glamor_,_w_, _h_) ((_w_) > 0 && (_h_) > 0 \ + && (_w_) <= _glamor_->max_fbo_size \ + && (_h_) <= _glamor_->max_fbo_size) + +/* For 1bpp pixmap, we don't store it as texture. */ +#define glamor_check_pixmap_fbo_depth(_depth_) ( \ + _depth_ == 8 \ + || _depth_ == 15 \ + || _depth_ == 16 \ + || _depth_ == 24 \ + || _depth_ == 30 \ + || _depth_ == 32) + +#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->base.is_picture == 1) +#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv && pixmap_priv->base.gl_fbo == GLAMOR_FBO_NORMAL) +#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv) (pixmap_priv && (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)) + +/** + * Borrow from uxa. + */ +static inline CARD32 +format_for_depth(int depth) +{ + switch (depth) { + case 1: + return PICT_a1; + case 4: + return PICT_a4; + case 8: + return PICT_a8; + case 15: + return PICT_x1r5g5b5; + case 16: + return PICT_r5g6b5; + default: + case 24: + return PICT_x8r8g8b8; +#if XORG_VERSION_CURRENT >= 10699900 + case 30: + return PICT_x2r10g10b10; +#endif + case 32: + return PICT_a8r8g8b8; + } +} + +static inline void +gl_iformat_for_depth(int depth, GLenum * format) +{ + switch (depth) { +#ifndef GLAMOR_GLES2 + case 1: + case 8: + *format = GL_ALPHA; + break; +#endif + default: + *format = GL_RGBA; + break; + } +} + +static inline CARD32 +format_for_pixmap(PixmapPtr pixmap) +{ + glamor_pixmap_private *pixmap_priv; + PictFormatShort pict_format; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) + pict_format = pixmap_priv->base.picture->format; + else + pict_format = format_for_depth(pixmap->drawable.depth); + + return pict_format; +} + +#define REVERT_NONE 0 +#define REVERT_NORMAL 1 +#define REVERT_DOWNLOADING_A1 2 +#define REVERT_UPLOADING_A1 3 +#define REVERT_DOWNLOADING_2_10_10_10 4 +#define REVERT_UPLOADING_2_10_10_10 5 +#define REVERT_DOWNLOADING_1_5_5_5 7 +#define REVERT_UPLOADING_1_5_5_5 8 +#define REVERT_DOWNLOADING_10_10_10_2 9 +#define REVERT_UPLOADING_10_10_10_2 10 + +#define SWAP_NONE_DOWNLOADING 0 +#define SWAP_DOWNLOADING 1 +#define SWAP_UPLOADING 2 +#define SWAP_NONE_UPLOADING 3 + +/* + * Map picture's format to the correct gl texture format and type. + * no_alpha is used to indicate whehter we need to wire alpha to 1. + * + * Although opengl support A1/GL_BITMAP, we still don't use it + * here, it seems that mesa has bugs when uploading a A1 bitmap. + * + * Return 0 if find a matched texture type. Otherwise return -1. + **/ +#ifndef GLAMOR_GLES2 +static inline int +glamor_get_tex_format_type_from_pictformat(PictFormatShort format, + GLenum * tex_format, + GLenum * tex_type, + int *no_alpha, + int *revert, + int *swap_rb, + int is_upload) + +{ + *no_alpha = 0; + *revert = REVERT_NONE; + *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; + switch (format) { + case PICT_a1: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; + break; + case PICT_b8g8r8x8: + *no_alpha = 1; + case PICT_b8g8r8a8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8; + break; + + case PICT_x8r8g8b8: + *no_alpha = 1; + case PICT_a8r8g8b8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case PICT_x8b8g8r8: + *no_alpha = 1; + case PICT_a8b8g8r8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case PICT_x2r10g10b10: + *no_alpha = 1; + case PICT_a2r10g10b10: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; + break; + case PICT_x2b10g10r10: + *no_alpha = 1; + case PICT_a2b10g10r10: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; + break; + + case PICT_r5g6b5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + break; + case PICT_b5g6r5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV; + break; + case PICT_x1b5g5r5: + *no_alpha = 1; + case PICT_a1b5g5r5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + + case PICT_x1r5g5b5: + *no_alpha = 1; + case PICT_a1r5g5b5: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case PICT_a8: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + break; + case PICT_x4r4g4b4: + *no_alpha = 1; + case PICT_a4r4g4b4: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + + case PICT_x4b4g4r4: + *no_alpha = 1; + case PICT_a4b4g4r4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + + default: + LogMessageVerb(X_INFO, 0, + "fail to get matched format for %x \n", + format); + return -1; + } + return 0; +} + +/* Currently, we use RGBA to represent all formats. */ +inline static int cache_format(GLenum format) +{ + switch (format) { + case GL_ALPHA: + return 1; + case GL_RGBA: + return 0; + default: + return -1; + } +} + +#else +#define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst) + +static inline int +glamor_get_tex_format_type_from_pictformat(PictFormatShort format, + GLenum * tex_format, + GLenum * tex_type, + int *no_alpha, + int *revert, + int *swap_rb, + int is_upload) +{ + int need_swap_rb = 0; + + *no_alpha = 0; + *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL; + + switch (format) { + case PICT_b8g8r8x8: + *no_alpha = 1; + case PICT_b8g8r8a8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + need_swap_rb = 1; + *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; + break; + + case PICT_x8r8g8b8: + *no_alpha = 1; + case PICT_a8r8g8b8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + need_swap_rb = 1; + break; + + case PICT_x8b8g8r8: + *no_alpha = 1; + case PICT_a8b8g8r8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + break; + + case PICT_x2r10g10b10: + *no_alpha = 1; + case PICT_a2r10g10b10: + *tex_format = GL_RGBA; + /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2. + * we have to use GL_UNSIGNED_BYTE and do the conversion in + * shader latter.*/ + *tex_type = GL_UNSIGNED_BYTE; + if (is_upload == 1) { + if (!IS_LITTLE_ENDIAN) + *revert = REVERT_UPLOADING_10_10_10_2; + else + *revert = REVERT_UPLOADING_2_10_10_10; + } + else { + if (!IS_LITTLE_ENDIAN) { + *revert = REVERT_DOWNLOADING_10_10_10_2; + } + else { + *revert = REVERT_DOWNLOADING_2_10_10_10; + } + } + need_swap_rb = 1; + + break; + + case PICT_x2b10g10r10: + *no_alpha = 1; + case PICT_a2b10g10r10: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + if (is_upload == 1) { + if (!IS_LITTLE_ENDIAN) + *revert = REVERT_UPLOADING_10_10_10_2; + else + *revert = REVERT_UPLOADING_2_10_10_10; + } + else { + if (!IS_LITTLE_ENDIAN) { + *revert = REVERT_DOWNLOADING_10_10_10_2; + } + else { + *revert = REVERT_DOWNLOADING_2_10_10_10; + } + } + break; + + case PICT_r5g6b5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL; + + break; + + case PICT_b5g6r5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;; + break; + + case PICT_x1b5g5r5: + *no_alpha = 1; + case PICT_a1b5g5r5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_5_5_5_1; + if (IS_LITTLE_ENDIAN) { + *revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5; + } else + *revert = REVERT_NONE; + break; + + case PICT_x1r5g5b5: + *no_alpha = 1; + case PICT_a1r5g5b5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_5_5_5_1; + if (IS_LITTLE_ENDIAN) { + *revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5; + } else + *revert = REVERT_NONE; + need_swap_rb = 1; + break; + + case PICT_a1: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; + break; + + case PICT_a8: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *revert = REVERT_NONE; + break; + + case PICT_x4r4g4b4: + *no_alpha = 1; + case PICT_a4r4g4b4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; + *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; + need_swap_rb = 1; + break; + + case PICT_x4b4g4r4: + *no_alpha = 1; + case PICT_a4b4g4r4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; + *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; + break; + + default: + LogMessageVerb(X_INFO, 0, + "fail to get matched format for %x \n", + format); + return -1; + } + + if (need_swap_rb) + *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING; + else + *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; + return 0; +} + +inline static int cache_format(GLenum format) +{ + switch (format) { + case GL_ALPHA: + return 2; + case GL_RGB: + return 1; + case GL_RGBA: + return 0; + default: + return -1; + } +} + +#endif + + +static inline int +glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, + GLenum * format, + GLenum * type, + int *no_alpha, + int *revert, + int *swap_rb, + int is_upload) +{ + glamor_pixmap_private *pixmap_priv; + PictFormatShort pict_format; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) + pict_format = pixmap_priv->base.picture->format; + else + pict_format = format_for_depth(pixmap->drawable.depth); + + return glamor_get_tex_format_type_from_pictformat(pict_format, + format, type, + no_alpha, + revert, + swap_rb, + is_upload); +} + + +/* borrowed from uxa */ +static inline Bool +glamor_get_rgba_from_pixel(CARD32 pixel, + float *red, + float *green, + float *blue, float *alpha, CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { + rshift = gshift = bshift = ashift = 0; + } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; +#if XORG_VERSION_CURRENT >= 10699900 + } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { + ashift = 0; + rshift = abits; + if (abits == 0) + rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + + bbits); + gshift = rshift + rbits; + bshift = gshift + gbits; +#endif + } else { + return FALSE; + } +#define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \ + *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \ + / (float)((1<<(_bits_)) - 1) + + if (rbits) + COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits); + else + *red = 0; + + if (gbits) + COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits); + else + *green = 0; + + if (bbits) + COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits); + else + *blue = 0; + + if (abits) + COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits); + else + *alpha = 1; + + return TRUE; +} + +inline static Bool glamor_pict_format_is_compatible(PictFormatShort pict_format, int depth) +{ + GLenum iformat; + + gl_iformat_for_depth(depth, &iformat); + switch (iformat) { + case GL_RGBA: + return (pict_format == PICT_a8r8g8b8 || pict_format == PICT_x8r8g8b8); + case GL_ALPHA: + return (pict_format == PICT_a8); + default: + return FALSE; + } +} + +/* return TRUE if we can access this pixmap at DDX driver. */ +inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + return (!pixmap_priv + || (pixmap_priv->type == GLAMOR_TEXTURE_DRM + || pixmap_priv->type == GLAMOR_MEMORY + || pixmap_priv->type == GLAMOR_DRM_ONLY)); +} + +inline static Bool glamor_ddx_fallback_check_gc(GCPtr gc) +{ + PixmapPtr pixmap; + if (!gc) + return TRUE; + switch (gc->fillStyle) { + case FillStippled: + case FillOpaqueStippled: + pixmap = gc->stipple; + break; + case FillTiled: + pixmap = gc->tile.pixmap; + break; + default: + pixmap = NULL; + } + return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable)); +} +inline static Bool glamor_is_large_pixmap(PixmapPtr pixmap) +{ + glamor_pixmap_private *priv; + + priv = glamor_get_pixmap_private(pixmap); + return (priv->type == GLAMOR_TEXTURE_LARGE); +} + +inline static Bool glamor_is_large_picture(PicturePtr picture) +{ + PixmapPtr pixmap; + + if (picture->pDrawable) { + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + return glamor_is_large_pixmap(pixmap); + } + return FALSE; +} + +inline static Bool glamor_tex_format_is_readable(GLenum format) +{ + return ((format == GL_RGBA || format == GL_RGB || format == GL_ALPHA)); + +} + +static inline void _glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h) +{ + int i,j; + unsigned char * p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) + { + ErrorF("line %3d: ", i); + for(j = 0; j < w; j++) + ErrorF("%2d ", (p[j/8] & (1 << (j%8)))>>(j%8)); + p += stride; + ErrorF("\n"); + } +} + +static inline void _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h) +{ + int i,j; + unsigned char * p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) + { + ErrorF("line %3d: ", i); + for(j = 0; j < w; j++) + ErrorF("%2x ", p[j]); + p += stride; + ErrorF("\n"); + } +} + +static inline void _glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h) +{ + int i,j; + unsigned short * p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind / 2; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) + { + ErrorF("line %3d: ", i); + for(j = 0; j < w; j++) + ErrorF("%2x ", p[j]); + p += stride; + ErrorF("\n"); + } +} + +static inline void _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h) +{ + int i,j; + unsigned int * p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind / 4; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) + { + ErrorF("line %3d: ", i); + for(j = 0; j < w; j++) + ErrorF("%2x ", p[j]); + p += stride; + ErrorF("\n"); + } +} + +static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h) +{ + w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w; + h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h; + + glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO); + switch (pixmap->drawable.depth) { + case 8: + _glamor_dump_pixmap_byte(pixmap, x, y, w, h); + break; + case 15: + case 16: + _glamor_dump_pixmap_sword(pixmap, x, y, w, h); + break; + + case 24: + case 32: + _glamor_dump_pixmap_word(pixmap, x, y, w, h); + break; + case 1: + _glamor_dump_pixmap_bits(pixmap, x, y, w, h); + break; + default: + ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth); + } + glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); +} + +static inline void _glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, + int x, int y, int w, int h, + PictFormatShort short_format, + int all, int diffs) +{ + int i, j; + unsigned char * p1 = pixmap1->devPrivate.ptr; + unsigned char * p2 = pixmap2->devPrivate.ptr; + int line_need_printed = 0; + int test_code = 0xAABBCCDD; + int little_endian = 0; + unsigned char *p_test; + int bpp = pixmap1->drawable.depth == 8 ? 1 : 4; + int stride = pixmap1->devKind; + + assert(pixmap1->devKind == pixmap2->devKind); + + ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h); + + p1 = p1 + y * stride + x; + p2 = p2 + y * stride + x; + + if (all) { + for (i = 0; i < h; i++) { + ErrorF("line %3d: ", i); + + for (j = 0; j < stride; j++) { + if (j % bpp == 0) + ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); + else + ErrorF("%2x:%2x ", p1[j], p2[j]); + } + + p1 += stride; + p2 += stride; + ErrorF("\n"); + } + } else { + if (short_format == PICT_a8r8g8b8) { + p_test = (unsigned char *) & test_code; + little_endian = (*p_test == 0xDD); + bpp = 4; + + for (i = 0; i < h; i++) { + line_need_printed = 0; + + for (j = 0; j < stride; j++) { + if (p1[j] != p2[j] && (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) { + if (line_need_printed) { + if (little_endian) { + switch (j % 4) { + case 2: + ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + case 1: + ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + case 0: + ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + case 3: + ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + } + } else { + switch (j % 4) { + case 1: + ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + case 2: + ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + case 3: + ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + case 0: + ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]); + break; + } + } + } else { + line_need_printed = 1; + j = -1; + ErrorF("line %3d: ", i); + continue; + } + } + } + + p1 += stride; + p2 += stride; + ErrorF("\n"); + } + } //more format can be added here. + else { // the default format, just print. + for (i = 0; i < h; i++) { + line_need_printed = 0; + + for (j = 0; j < stride; j++) { + if (p1[j] != p2[j]) { + if (line_need_printed) { + ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); + } else { + line_need_printed = 1; + j = -1; + ErrorF("line %3d: ", i); + continue; + } + } + } + + p1 += stride; + p2 += stride; + ErrorF("\n"); + } + } + } +} + +static inline void glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, + int x, int y, int w, int h, int all, int diffs) +{ + assert(pixmap1->drawable.depth == pixmap2->drawable.depth); + + glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); + glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); + + _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs); + + glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); +} + +/* This function is used to compare two pictures. + If the picture has no drawable, we use fb functions to generate it. */ +static inline void glamor_compare_pictures( ScreenPtr screen, + PicturePtr fst_picture, + PicturePtr snd_picture, + int x_source, int y_source, + int width, int height, + int all, int diffs) +{ + PixmapPtr fst_pixmap; + PixmapPtr snd_pixmap; + int fst_generated, snd_generated; + int error; + int fst_type = -1; + int snd_type = -1; // -1 represent has drawable. + + if (fst_picture->format != snd_picture->format) { + ErrorF("Different picture format can not compare!\n"); + return; + } + + if (!fst_picture->pDrawable) { + fst_type = fst_picture->pSourcePict->type; + } + + if (!snd_picture->pDrawable) { + snd_type = snd_picture->pSourcePict->type; + } + + if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) { + ErrorF("Different picture type will never be same!\n"); + return; + } + + fst_generated = snd_generated = 0; + + if (!fst_picture->pDrawable) { + PicturePtr pixman_pic; + PixmapPtr pixmap = NULL; + PictFormatShort format; + + format = fst_picture->format; + + pixmap = glamor_create_pixmap(screen, + width, height, + PIXMAN_FORMAT_DEPTH(format), + GLAMOR_CREATE_PIXMAP_CPU); + + pixman_pic = CreatePicture(0, + &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH(format), format), + 0, 0, serverClient, &error); + + fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic, + x_source, y_source, + 0, 0, + 0, 0, + width, height); + + glamor_destroy_pixmap(pixmap); + + fst_picture = pixman_pic; + fst_generated = 1; + } + + if (!snd_picture->pDrawable) { + PicturePtr pixman_pic; + PixmapPtr pixmap = NULL; + PictFormatShort format; + + format = snd_picture->format; + + pixmap = glamor_create_pixmap(screen, + width, height, + PIXMAN_FORMAT_DEPTH(format), + GLAMOR_CREATE_PIXMAP_CPU); + + pixman_pic = CreatePicture(0, + &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH(format), format), + 0, 0, serverClient, &error); + + fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic, + x_source, y_source, + 0, 0, + 0, 0, + width, height); + + glamor_destroy_pixmap(pixmap); + + snd_picture = pixman_pic; + snd_generated = 1; + } + + fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable); + snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable); + + if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) { + if (fst_generated) + glamor_destroy_picture(fst_picture); + if (snd_generated) + glamor_destroy_picture(snd_picture); + + ErrorF("Different pixmap depth can not compare!\n"); + return; + } + + glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); + glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); + + if ((fst_type == SourcePictTypeLinear) || + (fst_type == SourcePictTypeRadial) || + (fst_type == SourcePictTypeConical) || + (snd_type == SourcePictTypeLinear) || + (snd_type == SourcePictTypeRadial) || + (snd_type == SourcePictTypeConical)) { + x_source = y_source = 0; + } + + _glamor_compare_pixmaps(fst_pixmap, snd_pixmap, + x_source, y_source, + width, height, + fst_picture->format, all, diffs); + + glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); + + if (fst_generated) + glamor_destroy_picture(fst_picture); + if (snd_generated) + glamor_destroy_picture(snd_picture); + + return; +} + +#ifdef __i386__ +static inline unsigned long __fls(unsigned long x) +{ + asm("bsr %1,%0" + : "=r" (x) + : "rm" (x)); + return x; +} +#else +static inline unsigned long __fls(unsigned long x) +{ + int n; + + if (x == 0) return(0); + n = 0; + if (x <= 0x0000FFFF) {n = n +16; x = x <<16;} + if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;} + if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;} + if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;} + if (x <= 0x7FFFFFFF) {n = n + 1;} + return 31 - n; +} +#endif + +static inline void glamor_make_current(ScreenPtr screen) +{ + glamor_egl_make_current(screen); +} + +static inline void glamor_restore_current(ScreenPtr screen) +{ + glamor_egl_restore_context(screen); +} + +#ifdef GLX_USE_SHARED_DISPATCH +static inline glamor_gl_dispatch * +glamor_get_dispatch(glamor_screen_private *glamor_priv) +{ + if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) + glamor_make_current(glamor_priv->screen); + + return &glamor_priv->_dispatch; +} + +static inline void +glamor_put_dispatch(glamor_screen_private *glamor_priv) +{ + if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) + glamor_restore_current(glamor_priv->screen); +} +#else +#warning "Indirect GLX may be broken, need to implement context switch." +static inline glamor_gl_dispatch * +glamor_get_dispatch(glamor_screen_private *glamor_priv) +{ + return &glamor_priv->_dispatch; +} + +static inline void +glamor_put_dispatch(glamor_screen_private *glamor_priv) +{ +} + +#endif + +#endif diff --git a/extra/glamor-egl/glapi.h b/extra/glamor-egl/glapi.h new file mode 100644 index 000000000..d510dac1d --- /dev/null +++ b/extra/glamor-egl/glapi.h @@ -0,0 +1,121 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * \mainpage Mesa GL API Module + * + * \section GLAPIIntroduction Introduction + * + * The Mesa GL API module is responsible for dispatching all the + * gl*() functions. All GL functions are dispatched by jumping through + * the current dispatch table (basically a struct full of function + * pointers.) + * + * A per-thread current dispatch table and per-thread current context + * pointer are managed by this module too. + * + * This module is intended to be non-Mesa-specific so it can be used + * with the X/DRI libGL also. + */ + +#ifndef _GLAPI_H +#define _GLAPI_H + +#define GL_GLEXT_PROTOTYPES + +#if GLAMOR_GLES2 +#include +#include +#else +#include +#include "GL/glext.h" +#endif + +/* Is this needed? It is incomplete anyway. */ +#ifdef USE_MGL_NAMESPACE +#define _glapi_set_dispatch _mglapi_set_dispatch +#define _glapi_get_dispatch _mglapi_get_dispatch +#define _glapi_set_context _mglapi_set_context +#define _glapi_get_context _mglapi_get_context +#define _glapi_Dispatch _mglapi_Dispatch +#define _glapi_Context _mglapi_Context +#endif + +typedef void (*_glapi_proc)(void); +struct _glapi_table; + + +#if defined (GLX_USE_TLS) + +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); + +extern __thread void * _glapi_tls_Context + __attribute__((tls_model("initial-exec"))); + +extern const struct _glapi_table *_glapi_Dispatch; +extern const void *_glapi_Context; + +# define GET_DISPATCH() _glapi_tls_Dispatch +# define GET_CURRENT_CONTEXT(C) C = (typeof(C)) _glapi_tls_Context +# define SET_CURRENT_CONTEXT(C) _glapi_tls_Context = (void*)C + +#else + +extern struct _glapi_table *_glapi_Dispatch; +extern void *_glapi_Context; + +# ifdef THREADS + +# define GET_DISPATCH() \ + (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch()) + +# define GET_CURRENT_CONTEXT(C) C = (typeof(C)) \ + (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context()) + + +# define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context)) \ + _glapi_Context = (void*)C; \ + else \ + _glapi_set_context(C); } while(0) + +# else + +# define GET_DISPATCH() _glapi_Dispatch +# define GET_CURRENT_CONTEXT(C) C = (typeof(C)) _glapi_Context +# define SET_CURRENT_CONTEXT(C) _glapi_Context = (void*)C + +# endif + +#endif /* defined (GLX_USE_TLS) */ + + +extern void +_glapi_set_context(void *context); + +extern void * +_glapi_get_context(void); + +#endif diff --git a/extra/gnome-shell/PKGBUILD b/extra/gnome-shell/PKGBUILD index 4c04ddf49..8ecc52e2e 100644 --- a/extra/gnome-shell/PKGBUILD +++ b/extra/gnome-shell/PKGBUILD @@ -1,10 +1,10 @@ -# $Id: PKGBUILD 178416 2013-02-21 17:18:12Z heftig $ +# $Id: PKGBUILD 179858 2013-03-10 16:33:19Z heftig $ # Maintainer: Ionut Biru # Contributor: Flamelab # Contributor: Andrew Simmons # Contributor: György Balló pkgname=gparted pkgver=0.14.1 -pkgrel=4 +pkgrel=5 pkgdesc="A Partition Magic clone, frontend to GNU Parted" arch=('i686' 'x86_64') url="http://gparted.sourceforge.net" license=('GPL') -depends=('parted' 'gtkmm' 'hicolor-icon-theme' 'polkit-gnome') +depends=('parted' 'gtkmm' 'hicolor-icon-theme' 'polkit') makedepends=('intltool' 'pkg-config' 'gnome-doc-utils') optdepends=('dosfstools: for FAT16 and FAT32 partitions' 'jfsutils: for jfs partitions' @@ -18,6 +18,7 @@ optdepends=('dosfstools: for FAT16 and FAT32 partitions' 'reiserfsprogs: for reiser partitions' 'xfsprogs: for xfs partitions' 'nilfs-utils: for nilfs2 support' + 'polkit-gnome: to run gparted directly from menu' 'gpart: for recovering corrupt partition tables' 'mtools: utilities to access MS-DOS disks') install=gparted.install @@ -46,9 +47,6 @@ package() { # Install launcher script echo '#!/bin/sh' > ${pkgdir}/usr/sbin/gparted - echo 'pkexec "/usr/sbin/gparted.elf" "$@"' >> ${pkgdir}/usr/sbin/gparted + echo 'pkexec --disable-internal-agent "/usr/sbin/gparted.elf" "$@"' >> ${pkgdir}/usr/sbin/gparted chmod 755 ${pkgdir}/usr/sbin/gparted - - # Modify desktop file - sed -i -e "s|^Exec=.*|Exec=pkexec --disable-internal-agent /usr/sbin/gparted.elf|" "${pkgdir}/usr/share/applications/gparted.desktop" } diff --git a/extra/kwebkitpart/PKGBUILD b/extra/kwebkitpart/PKGBUILD index 72cf6349a..1ca34bd46 100644 --- a/extra/kwebkitpart/PKGBUILD +++ b/extra/kwebkitpart/PKGBUILD @@ -1,20 +1,22 @@ -# $Id: PKGBUILD 178216 2013-02-18 09:51:49Z andrea $ +# $Id: PKGBUILD 179888 2013-03-10 21:31:07Z andrea $ # Maintainer: Andrea Scarpino pkgname=kwebkitpart pkgver=1.3.2 -pkgrel=1 +pkgrel=2 pkgdesc="A WebKit browser component for KDE" url="https://projects.kde.org/projects/extragear/base/kwebkitpart/" arch=('i686' 'x86_64') license=('LGPL') -depends=('kdebase-runtime') +depends=('kdelibs') makedepends=('cmake' 'automoc4') install=${pkgname}.install -source=("ftp://ftp.archlinux.org/other/${pkgname}/${pkgname}-${pkgver}.tar.xz") -md5sums=('c8bfcf46b4b01594d328804b6f55dcc6') +source=("ftp://ftp.archlinux.org/other/packages/${pkgname}/${pkgname}-${pkgver}.tar.bz2") +md5sums=('2df1c70371b99e5f638fff702f789ba1') build() { + sed -i '/add_subdirectory(kdelauncher)/d' ${pkgname}-${pkgver}/CMakeLists.txt + mkdir build cd build cmake ../${pkgname}-${pkgver} \ diff --git a/extra/libkdcraw/PKGBUILD b/extra/libkdcraw/PKGBUILD index 1593231e8..aa87080be 100644 --- a/extra/libkdcraw/PKGBUILD +++ b/extra/libkdcraw/PKGBUILD @@ -1,14 +1,14 @@ -# $Id: PKGBUILD 179346 2013-03-05 15:25:06Z andrea $ +# $Id: PKGBUILD 179854 2013-03-10 15:00:56Z andrea $ # Maintainer: Andrea Scarpino pkgname=libkdcraw pkgver=4.10.1 -pkgrel=1 +pkgrel=2 pkgdesc="A C++ interface used to decode RAW picture" url="https://projects.kde.org/projects/kde/kdegraphics/libs/libkdcraw" arch=('i686' 'x86_64') license=('GPL' 'LGPL' 'FDL') -depends=('kdelibs' 'lcms') +depends=('kdelibs' 'lcms2') makedepends=('cmake' 'automoc4') replaces=('kdegraphics-libs') conflicts=('kdegraphics-libs') @@ -17,7 +17,6 @@ source=("http://download.kde.org/stable/${pkgver}/src/${pkgname}-${pkgver}.tar.x sha1sums=('75d1f52d02137b275b545a5390e1857a580a1128') build() { - cd "${srcdir}" mkdir build cd build cmake ../${pkgname}-${pkgver} \ @@ -28,6 +27,6 @@ build() { } package() { - cd "${srcdir}"/build + cd build make DESTDIR="${pkgdir}" install } diff --git a/extra/xfdesktop/PKGBUILD b/extra/xfdesktop/PKGBUILD index c72c40d06..39e171b28 100644 --- a/extra/xfdesktop/PKGBUILD +++ b/extra/xfdesktop/PKGBUILD @@ -1,10 +1,10 @@ -# $Id: PKGBUILD 179526 2013-03-06 02:34:29Z foutrelis $ +# $Id: PKGBUILD 179856 2013-03-10 16:22:07Z foutrelis $ # Maintainer: Evangelos Foutras # Contributor: tobias pkgname=xfdesktop -pkgver=4.10.1 -pkgrel=2 +pkgver=4.10.2 +pkgrel=1 pkgdesc="A desktop manager for Xfce" arch=('i686' 'x86_64') url="http://www.xfce.org/" @@ -16,18 +16,12 @@ conflicts=('xfce4-menueditor') replaces=('xfce4-menueditor') options=('!libtool') install=xfdesktop.install -source=(http://archive.xfce.org/src/xfce/$pkgname/4.10/$pkgname-$pkgver.tar.bz2 - revert-SVG-images-are-no-longer-pixilated-when-scale.patch) -sha256sums=('2883fe381e1b967d179fdf5ece5ac2566a3ffdb94f4cf139c7fb44567f17d4ad' - '94274832eede98a7d99652ff90ecabd932b46b0f002c25297ddd6f0c346aa3d0') +source=(http://archive.xfce.org/src/xfce/$pkgname/4.10/$pkgname-$pkgver.tar.bz2) +sha256sums=('49a6e0be513e307e896f7e5929825babec9bbcd4b2e73552f9d27647a4db797d') build() { cd "$srcdir/$pkgname-$pkgver" - # Fix hang when solid color is selected - # https://bugzilla.xfce.org/show_bug.cgi?id=9892 - patch -Np1 -i "$srcdir/revert-SVG-images-are-no-longer-pixilated-when-scale.patch" - ./configure \ --prefix=/usr \ --sysconfdir=/etc \ diff --git a/extra/xfdesktop/revert-SVG-images-are-no-longer-pixilated-when-scale.patch b/extra/xfdesktop/revert-SVG-images-are-no-longer-pixilated-when-scale.patch deleted file mode 100644 index 020888a2b..000000000 --- a/extra/xfdesktop/revert-SVG-images-are-no-longer-pixilated-when-scale.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 8c868b20f3e19871f3f09e972cd20dbe3640084a Mon Sep 17 00:00:00 2001 -From: Evangelos Foutras -Date: Wed, 6 Mar 2013 04:27:07 +0200 -Subject: [PATCH] Revert "SVG images are no longer pixilated when scaled up" - -This reverts commit ebad377e5cd067cec9f2b402dff4991ddc4cc3b5. ---- - src/xfce-backdrop.c | 38 +++++++++++++++++--------------------- - 1 file changed, 17 insertions(+), 21 deletions(-) - -diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c -index 9a4d7db..b07492f 100644 ---- a/src/xfce-backdrop.c -+++ b/src/xfce-backdrop.c -@@ -933,10 +933,17 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) - - g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), NULL); - -- if(backdrop->priv->show_image && backdrop->priv->image_path) -- gdk_pixbuf_get_file_info(backdrop->priv->image_path, &iw, &ih); -- -+ if(backdrop->priv->show_image && backdrop->priv->image_path) { -+ image = gdk_pixbuf_new_from_file(backdrop->priv->image_path, NULL); -+ if(image) { -+ iw = gdk_pixbuf_get_width(image); -+ ih = gdk_pixbuf_get_height(image); -+ } -+ } -+ - if(backdrop->priv->width == 0 || backdrop->priv->height == 0) { -+ if(!image) -+ return NULL; - w = iw; - h = ih; - } else { -@@ -956,9 +963,7 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) - final_image = create_solid(&backdrop->priv->color1, w, h, FALSE, 0xff); - } - -- /*check if the file exists, -- *and if it doesn't then make the background the single colour*/ -- if(!g_file_test(backdrop->priv->image_path, G_FILE_TEST_EXISTS)) { -+ if(!image) { - if(backdrop->priv->brightness != 0) - final_image = adjust_brightness(final_image, backdrop->priv->brightness); - -@@ -996,7 +1001,6 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) - - switch(istyle) { - case XFCE_BACKDROP_IMAGE_CENTERED: -- image = gdk_pixbuf_new_from_file(backdrop->priv->image_path, NULL); - dx = MAX((w - iw) / 2, 0); - dy = MAX((h - ih) / 2, 0); - xo = MIN((w - iw) / 2, dx); -@@ -1007,7 +1011,6 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) - break; - - case XFCE_BACKDROP_IMAGE_TILED: -- image = gdk_pixbuf_new_from_file(backdrop->priv->image_path, NULL); - tmp = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h); - for(i = 0; (i * iw) < w; i++) { - for(j = 0; (j * ih) < h; j++) { -@@ -1030,10 +1033,10 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) - break; - - case XFCE_BACKDROP_IMAGE_STRETCHED: -- image = gdk_pixbuf_new_from_file_at_scale( -- backdrop->priv->image_path, w, h, FALSE, NULL); -+ xscale = (gdouble)w / iw; -+ yscale = (gdouble)h / ih; - gdk_pixbuf_composite(image, final_image, 0, 0, w, h, -- 0, 0, 1, 1, interp, 255); -+ 0, 0, xscale, yscale, interp, 255); - break; - - case XFCE_BACKDROP_IMAGE_SCALED: -@@ -1050,12 +1053,9 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) - } - dx = xo; - dy = yo; -- -- image = gdk_pixbuf_new_from_file_at_scale( -- backdrop->priv->image_path, iw * xscale, -- ih * yscale, TRUE, NULL); -+ - gdk_pixbuf_composite(image, final_image, dx, dy, -- iw * xscale, ih * yscale, xo, yo, 1, 1, -+ iw * xscale, ih * yscale, xo, yo, xscale, yscale, - interp, 255); - break; - -@@ -1071,12 +1071,8 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) - xo = 0; - yo = (h - (ih * yscale)) * 0.5; - } -- -- image = gdk_pixbuf_new_from_file_at_scale( -- backdrop->priv->image_path, iw * xscale, -- ih * yscale, TRUE, NULL); - gdk_pixbuf_composite(image, final_image, 0, 0, -- w, h, xo, yo, 1, 1, interp, 255); -+ w, h, xo, yo, xscale, yscale, interp, 255); - break; - - default: --- -1.8.1.5 - -- cgit v1.2.3-54-g00ecf