From 0ec823ce5b72bcf3be3923f2f23e5386feb0107b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 Dec 2008 12:30:14 -0800 Subject: [PATCH 001/225] Add build infrastructure for glamor. --- Makefile.am | 2 ++ configure.ac | 1 + glamor/Makefile.am | 18 +++++++++++ glamor/glamor.c | 37 +++++++++++++++++++++ glamor/glamor.h | 26 +++++++++++++++ hw/kdrive/ephyr/Makefile.am | 5 ++- hw/kdrive/ephyr/ephyr.h | 6 ++++ hw/kdrive/ephyr/ephyr_glamor.c | 59 ++++++++++++++++++++++++++++++++++ hw/kdrive/ephyr/ephyrinit.c | 9 ++++++ 9 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 glamor/Makefile.am create mode 100644 glamor/glamor.c create mode 100644 glamor/glamor.h create mode 100644 hw/kdrive/ephyr/ephyr_glamor.c diff --git a/Makefile.am b/Makefile.am index cea140bea..0c701633d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,6 +38,7 @@ SUBDIRS = \ $(COMPOSITE_DIR) \ $(GLX_DIR) \ exa \ + glamor \ config \ hw \ test @@ -88,6 +89,7 @@ DIST_SUBDIRS = \ composite \ glx \ exa \ + glamor \ config \ hw \ test diff --git a/configure.ac b/configure.ac index b0d26435a..85d5b706f 100644 --- a/configure.ac +++ b/configure.ac @@ -2133,6 +2133,7 @@ Xext/Makefile Xi/Makefile xfixes/Makefile exa/Makefile +glamor/Makefile hw/Makefile hw/xfree86/Makefile hw/xfree86/common/Makefile diff --git a/glamor/Makefile.am b/glamor/Makefile.am new file mode 100644 index 000000000..8f4c60758 --- /dev/null +++ b/glamor/Makefile.am @@ -0,0 +1,18 @@ +noinst_LTLIBRARIES = libglamor.la + +# Override these since glamor doesn't need them and the needed files aren't +# built (in hw/xfree86/os-support/solaris) until after glamor is built +SOLARIS_ASM_CFLAGS="" + +if XORG +sdk_HEADERS = glamor.h +endif + +INCLUDES = \ + $(XORG_INCS) + +AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) + +libglamor_la_SOURCES = \ + glamor.c \ + glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c new file mode 100644 index 000000000..718cce3cf --- /dev/null +++ b/glamor/glamor.c @@ -0,0 +1,37 @@ +/* + * 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 + * + */ + +/** @file + * This file covers the initialization and teardown of glamor, and has various + * functions not responsible for performing rendering. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include diff --git a/glamor/glamor.h b/glamor/glamor.h new file mode 100644 index 000000000..7aa4a73dc --- /dev/null +++ b/glamor/glamor.h @@ -0,0 +1,26 @@ +/* + * 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 + * + */ diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 9d9b64ee5..79e950bb5 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -7,7 +7,8 @@ INCLUDES = \ @XEPHYR_CFLAGS@ \ @DRIPROTO_CFLAGS@ \ -I$(top_srcdir) \ - -I$(top_srcdir)/exa + -I$(top_srcdir)/exa \ + -I$(top_srcdir)/glamor if XV LIBXEPHYR_HOSTXV=libxephyr-hostxv.la @@ -47,6 +48,7 @@ XEPHYR_SRCS = \ ephyr.h \ ephyrlog.h \ ephyr_draw.c \ + ephyr_glamor.c \ os.c libxephyr_hostx_la_SOURCES = $(HOSTX_SRCS) @@ -70,6 +72,7 @@ Xephyr_LDADD = \ $(LIBXEPHYR_HOSTXV) \ $(LIBXEPHYR_HOSTDRI) \ $(top_builddir)/exa/libexa.la \ + $(top_builddir)/glamor/libglamor.la \ @KDRIVE_LIBS@ \ @XEPHYR_LIBS@ diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index 23848004c..cd1521209 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -196,6 +196,12 @@ ephyrDrawDisable(ScreenPtr pScreen); void ephyrDrawFini(ScreenPtr pScreen); +/* ephyr_glamor.c */ +Bool ephyr_glamor_init(ScreenPtr pScreen); +void ephyr_glamor_enable(ScreenPtr pScreen); +void ephyr_glamor_disable(ScreenPtr pScreen); +void ephyr_glamor_fini(ScreenPtr pScreen); + /*ephyvideo.c*/ Bool ephyrInitVideo(ScreenPtr pScreen) ; diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c new file mode 100644 index 000000000..f4fb3df05 --- /dev/null +++ b/hw/kdrive/ephyr/ephyr_glamor.c @@ -0,0 +1,59 @@ +/* + * Copyright © 2006 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ephyr.h" +/*#include "glamor.h"*/ + +/** + * This function initializes EXA to use the fake acceleration implementation + * which just falls through to software. The purpose is to have a reliable, + * correct driver with which to test changes to the EXA core. + */ +Bool +ephyr_glamor_init(ScreenPtr pScreen) +{ + return TRUE; +} + +void +ephyr_glamor_enable(ScreenPtr pScreen) +{ +} + +void +ephyr_glamor_disable(ScreenPtr pScreen) +{ +} + +void +ephyr_glamor_fini(ScreenPtr pScreen) +{ +} diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index b674bb8d0..4b291813a 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -117,6 +117,7 @@ ddxUseMsg (void) ErrorF("-host-cursor Re-use exisiting X host server cursor\n"); ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); ErrorF("-grayscale Simulate 8bit grayscale\n"); + ErrorF("-glamor Enable 2D acceleration using glamor\n"); ErrorF("-fakexa Simulate acceleration using software rendering\n"); ErrorF("-verbosity Set log verbosity level\n"); #ifdef GLXEXT @@ -220,6 +221,14 @@ ddxProcessArgument (int argc, char **argv, int i) EphyrWantGrayScale = 1; return 1; } + else if (!strcmp (argv[i], "-glamor")) + { + ephyrFuncs.initAccel = ephyr_glamor_init; + ephyrFuncs.enableAccel = ephyr_glamor_enable; + ephyrFuncs.disableAccel = ephyr_glamor_disable; + ephyrFuncs.finiAccel = ephyr_glamor_fini; + return 1; + } else if (!strcmp (argv[i], "-fakexa")) { ephyrFuncs.initAccel = ephyrDrawInit; From da6e0ffad2173d65f27feff36291f94e6aa06f88 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 Dec 2008 14:00:05 -0800 Subject: [PATCH 002/225] More ephyr/glamor glue. --- glamor/glamor.c | 12 +++++++++++- glamor/glamor.h | 14 ++++++++++++++ hw/kdrive/ephyr/Makefile.am | 3 ++- hw/kdrive/ephyr/ephyr_glamor.c | 19 +++++++++++++------ hw/kdrive/ephyr/hostx.h | 3 +++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 718cce3cf..49771ce9d 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -25,7 +25,7 @@ * */ -/** @file +/** @file glamor.c * This file covers the initialization and teardown of glamor, and has various * functions not responsible for performing rendering. */ @@ -35,3 +35,13 @@ #endif #include + +#include "glamor.h" + +/** Set up glamor for an already-configured GL context. */ +Bool +glamor_init(ScreenPtr screen) +{ + return Success; +} + diff --git a/glamor/glamor.h b/glamor/glamor.h index 7aa4a73dc..e6f303845 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -24,3 +24,17 @@ * Eric Anholt * */ + +#ifndef GLAMOR_H +#define GLAMOR_H + +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "gcstruct.h" +#include "picturestr.h" +#include "fb.h" + +#endif /* GLAMOR_H */ + +Bool glamor_init(ScreenPtr screen); diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 79e950bb5..027db1364 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -24,7 +24,8 @@ bin_PROGRAMS = Xephyr HOSTX_SRCS = \ hostx.c \ - hostx.h + hostx.h \ + ephyr_host_glamor.c HOSTVIDEO_SRCS = \ ephyrvideo.c \ diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c index f4fb3df05..2e2d946a9 100644 --- a/hw/kdrive/ephyr/ephyr_glamor.c +++ b/hw/kdrive/ephyr/ephyr_glamor.c @@ -1,5 +1,5 @@ /* - * Copyright © 2006 Intel Corporation + * 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"), @@ -30,7 +30,7 @@ #endif #include "ephyr.h" -/*#include "glamor.h"*/ +#include "glamor.h" /** * This function initializes EXA to use the fake acceleration implementation @@ -38,22 +38,29 @@ * correct driver with which to test changes to the EXA core. */ Bool -ephyr_glamor_init(ScreenPtr pScreen) +ephyr_glamor_init(ScreenPtr screen) { + KdScreenPriv(screen); + KdScreenInfo *kd_screen = pScreenPriv->screen; + + ephyr_glamor_host_create_context(kd_screen); + + glamor_init(screen); + return TRUE; } void -ephyr_glamor_enable(ScreenPtr pScreen) +ephyr_glamor_enable(ScreenPtr screen) { } void -ephyr_glamor_disable(ScreenPtr pScreen) +ephyr_glamor_disable(ScreenPtr screen) { } void -ephyr_glamor_fini(ScreenPtr pScreen) +ephyr_glamor_fini(ScreenPtr screen) { } diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h index 42578576a..d5cb0faa6 100644 --- a/hw/kdrive/ephyr/hostx.h +++ b/hw/kdrive/ephyr/hostx.h @@ -261,4 +261,7 @@ int hostx_has_dri (void) ; int hostx_has_glx (void) ; #endif /* XF86DRI */ +/* ephyr_glamor_host.c */ +void ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen); + #endif /*_XLIBS_STUFF_H_*/ From 8885b3b1ffb45ae16484151ce533683af526f509 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 Dec 2008 15:08:21 -0800 Subject: [PATCH 003/225] Add exa/glamor to _DEPENDENCIES so the bin gets rebuilt with the libs. --- hw/kdrive/ephyr/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 027db1364..349e86dca 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -80,6 +80,8 @@ Xephyr_LDADD = \ Xephyr_DEPENDENCIES = \ libxephyr.la \ libxephyr-hostx.la \ + $(top_builddir)/exa/libexa.la \ + $(top_builddir)/glamor/libglamor.la \ $(LIBXEPHYR_HOSTXV) \ $(LIBXEPHYR_HOSTDRI) \ @KDRIVE_LOCAL_LIBS@ From 41e3e580de95fca3095d015ec8febe1a5f47cca3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 10:49:41 -0700 Subject: [PATCH 004/225] glamor: Use -lgl for Xephyr if GLX is unset. I'm experimenting with that because of conflicts with GL dispatch tables. --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index 85d5b706f..10069be66 100644 --- a/configure.ac +++ b/configure.ac @@ -1998,6 +1998,10 @@ if test "$KDRIVE" = yes; then if test "x$DRI" = xyes && test "x$GLX" = xyes; then XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm" fi + # The glamor stuff requires libGL, but that conflicts with GLX currently. + if test "x$GLX" = xno; then + XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS gl" + fi PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"]) if test "x$XEPHYR" = xauto; then From 4d52ae7f2dca78d493e11375d764c978db5567ed Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 Dec 2008 15:14:31 -0800 Subject: [PATCH 005/225] glamor: Start trying to hook up the rendering bits --- glamor/Makefile.am | 1 + glamor/glamor.c | 66 ++++++++- glamor/glamor.h | 1 + glamor/glamor_core.c | 216 ++++++++++++++++++++++++++++ glamor/glamor_priv.h | 53 +++++++ hw/kdrive/ephyr/ephyr_glamor.c | 1 + hw/kdrive/ephyr/ephyr_host_glamor.c | 60 ++++++++ 7 files changed, 396 insertions(+), 2 deletions(-) create mode 100644 glamor/glamor_core.c create mode 100644 glamor/glamor_priv.h create mode 100644 hw/kdrive/ephyr/ephyr_host_glamor.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 8f4c60758..9ed40420f 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -15,4 +15,5 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ + glamor_core.c \ glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c index 49771ce9d..ba2701415 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -36,12 +36,74 @@ #include -#include "glamor.h" +#include "glamor_priv.h" + +static int glamor_screen_private_key_index; +DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index; + +/** + * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable. + * + * @param drawable the drawable being requested. + * + * This function returns the backing pixmap for a drawable, whether it is a + * redirected window, unredirected window, or already a pixmap. Note that + * coordinate translation is needed when drawing to the backing pixmap of a + * redirected window, and the translation coordinates are provided by calling + * exaGetOffscreenPixmap() on the drawable. + */ +PixmapPtr +glamor_get_drawable_pixmap(DrawablePtr drawable) +{ + if (drawable->type == DRAWABLE_WINDOW) + return drawable->pScreen->GetWindowPixmap((WindowPtr)drawable); + else + return (PixmapPtr)drawable; +} + +static PixmapPtr +glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, + unsigned int usage_hint) +{ + return fbCreatePixmap(screen, w, h, depth, usage_hint); +} + +static Bool +glamor_destroy_pixmap(PixmapPtr pixmap) +{ + return fbDestroyPixmap(pixmap); +} /** Set up glamor for an already-configured GL context. */ Bool glamor_init(ScreenPtr screen) { - return Success; + glamor_screen_private *glamor_priv; + + glamor_priv = xcalloc(1, sizeof(*glamor_priv)); + if (glamor_priv == NULL) + return FALSE; + + dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); + + glamor_priv->saved_create_gc = screen->CreateGC; + screen->CreateGC = glamor_create_gc; + + glamor_priv->saved_create_pixmap = screen->CreatePixmap; + screen->CreatePixmap = glamor_create_pixmap; + + glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap; + screen->DestroyPixmap = glamor_destroy_pixmap; + + return TRUE; } +void +glamor_fini(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + screen->CreateGC = glamor_priv->saved_create_gc; + screen->CreatePixmap = glamor_priv->saved_create_pixmap; + screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; +} diff --git a/glamor/glamor.h b/glamor/glamor.h index e6f303845..50617b857 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -38,3 +38,4 @@ #endif /* GLAMOR_H */ Bool glamor_init(ScreenPtr screen); +void glamor_fini(ScreenPtr screen); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c new file mode 100644 index 000000000..a894e9869 --- /dev/null +++ b/glamor/glamor_core.c @@ -0,0 +1,216 @@ +/* + * 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: + * Eric Anholt + * + */ + +/** @file glamor_core.c + * + * This file covers core X rendering in glamor. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "glamor_priv.h" + +static void +glamor_fill_spans(DrawablePtr drawable, GCPtr gc, int n, + DDXPointPtr points, int *width, int sorted) +{ + ScreenPtr screen = drawable->pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + + if (1 || screen_pixmap != dest_pixmap) { + fbFillSpans(drawable, gc, n, points, width, sorted); + } else { + ErrorF("stub fill_spans\n"); + } +} + +static void +glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ + ScreenPtr screen = drawable->pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + + if (1 || screen_pixmap != dest_pixmap) { + fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); + } else { + ErrorF("stub put_image\n"); + } +} + +static void +glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, + DDXPointPtr points, int *width, int n, int sorted) +{ + ScreenPtr screen = drawable->pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + + if (1 || screen_pixmap != dest_pixmap) { + fbSetSpans(drawable, gc, src, points, width, n, sorted); + } else { + ErrorF("stub set_spans\n"); + } +} + + +/** + * glamor_poly_line() checks if it can accelerate the lines as a group of + * horizontal or vertical lines (rectangles), and uses existing rectangle fill + * acceleration if so. + */ +static void +glamor_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n, + DDXPointPtr points) +{ + ScreenPtr screen = drawable->pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + xRectangle *rects; + int x1, x2, y1, y2; + int i; + + /* Don't try to do wide lines or non-solid fill style. */ + if (gc->lineWidth != 0 || gc->lineStyle != LineSolid || + gc->fillStyle != FillSolid) { + if (1 || dest_pixmap != screen_pixmap) + fbPolyLine(drawable, gc, mode, n, points); + else + ErrorF("stub poly_line\n"); + return; + } + + rects = xalloc(sizeof(xRectangle) * (n - 1)); + x1 = points[0].x; + y1 = points[0].y; + /* If we have any non-horizontal/vertical, fall back. */ + for (i = 0; i < n - 1; i++) { + if (mode == CoordModePrevious) { + x2 = x1 + points[i + 1].x; + y2 = y1 + points[i + 1].y; + } else { + x2 = points[i + 1].x; + y2 = points[i + 1].y; + } + + if (x1 != x2 && y1 != y2) { + xfree(rects); + if (1 || dest_pixmap != screen_pixmap) + fbPolyLine(drawable, gc, mode, n, points); + else + ErrorF("stub poly_line\n"); + return; + } + + if (x1 < x2) { + rects[i].x = x1; + rects[i].width = x2 - x1 + 1; + } else { + rects[i].x = x2; + rects[i].width = x1 - x2 + 1; + } + if (y1 < y2) { + rects[i].y = y1; + rects[i].height = y2 - y1 + 1; + } else { + rects[i].y = y2; + rects[i].height = y1 - y2 + 1; + } + + x1 = x2; + y1 = y2; + } + gc->ops->PolyFillRect(drawable, gc, n - 1, rects); + xfree(rects); +} + +GCOps glamor_gc_ops = { + glamor_fill_spans, + glamor_set_spans, + glamor_put_image, + miCopyArea, + miCopyPlane, + miPolyPoint, + glamor_poly_line, + miPolySegment, + miPolyRectangle, + miPolyArc, + miFillPolygon, + miPolyFillRect, + miPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + miImageGlyphBlt, + miPolyGlyphBlt, + miPushPixels, +}; + +/** + * exaValidateGC() sets the ops to EXA's implementations, which may be + * accelerated or may sync the card and fall back to fb. + */ +static void +glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) +{ + fbValidateGC(gc, changes, drawable); + + gc->ops = &glamor_gc_ops; +} + +static GCFuncs glamor_gc_funcs = { + glamor_validate_gc, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip +}; + +/** + * exaCreateGC makes a new GC and hooks up its funcs handler, so that + * exaValidateGC() will get called. + */ +int +glamor_create_gc(GCPtr gc) +{ + if (!fbCreateGC(gc)) + return FALSE; + + gc->funcs = &glamor_gc_funcs; + + return TRUE; +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h new file mode 100644 index 000000000..fe597c230 --- /dev/null +++ b/glamor/glamor_priv.h @@ -0,0 +1,53 @@ +/* + * 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 + +#include "glamor.h" + +typedef struct glamor_screen_private { + CreateGCProcPtr saved_create_gc; + CreatePixmapProcPtr saved_create_pixmap; + DestroyPixmapProcPtr saved_destroy_pixmap; +} glamor_screen_private; + +extern DevPrivateKey glamor_screen_private_key; +static inline glamor_screen_private * +glamor_get_screen_private(ScreenPtr screen) +{ + return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates, + glamor_screen_private_key); +} + +/* glamor.c */ +PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); + +/* glamor_core.c */ +Bool glamor_create_gc(GCPtr gc); + +#endif /* GLAMOR_PRIV_H */ diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c index 2e2d946a9..70b466388 100644 --- a/hw/kdrive/ephyr/ephyr_glamor.c +++ b/hw/kdrive/ephyr/ephyr_glamor.c @@ -63,4 +63,5 @@ ephyr_glamor_disable(ScreenPtr screen) void ephyr_glamor_fini(ScreenPtr screen) { + glamor_fini(screen); } diff --git a/hw/kdrive/ephyr/ephyr_host_glamor.c b/hw/kdrive/ephyr/ephyr_host_glamor.c new file mode 100644 index 000000000..f652bd00e --- /dev/null +++ b/hw/kdrive/ephyr/ephyr_host_glamor.c @@ -0,0 +1,60 @@ +/* + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "GL/glx.h" + +#include "hostx.h" + +void +ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) +{ + Display *dpy = hostx_get_display(); + int attribs[] = {GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None}; + XVisualInfo *visual_info; + GLXContext ctx; + + visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs); + if (visual_info == NULL) + errx(1, "Couldn't get RGB visual\n"); + + ctx = glXCreateContext(dpy, visual_info, NULL, True); + if (ctx == NULL) + errx(1, "glXCreateContext failed\n"); + + glXMakeCurrent(dpy, hostx_get_window(DefaultScreen(dpy)), ctx); + + XFree(visual_info); +} From b530cdea4a8e05b1f487765b8dde42cde1a6fc98 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 Dec 2008 15:20:49 -0800 Subject: [PATCH 006/225] glamor: Use a nicer struct initializer for gcops. --- glamor/glamor_core.c | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index a894e9869..e49e9b5ed 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -86,13 +86,13 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, /** - * glamor_poly_line() checks if it can accelerate the lines as a group of + * glamor_poly_lines() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill * acceleration if so. */ static void -glamor_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) +glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, + DDXPointPtr points) { ScreenPtr screen = drawable->pScreen; PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); @@ -156,26 +156,26 @@ glamor_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n, } GCOps glamor_gc_ops = { - glamor_fill_spans, - glamor_set_spans, - glamor_put_image, - miCopyArea, - miCopyPlane, - miPolyPoint, - glamor_poly_line, - miPolySegment, - miPolyRectangle, - miPolyArc, - miFillPolygon, - miPolyFillRect, - miPolyFillArc, - miPolyText8, - miPolyText16, - miImageText8, - miImageText16, - miImageGlyphBlt, - miPolyGlyphBlt, - miPushPixels, + .FillSpans = glamor_fill_spans, + .SetSpans = glamor_set_spans, + .PutImage = glamor_put_image, + .CopyArea = miCopyArea, + .CopyPlane = miCopyPlane, + .PolyPoint = miPolyPoint, + .Polylines = glamor_poly_lines, + .PolySegment = miPolySegment, + .PolyRectangle = miPolyRectangle, + .PolyArc = miPolyArc, + .FillPolygon = miFillPolygon, + .PolyFillRect = miPolyFillRect, + .PolyFillArc = miPolyFillArc, + .PolyText8 = miPolyText8, + .PolyText16 = miPolyText16, + .ImageText8 = miImageText8, + .ImageText16 = miImageText16, + .ImageGlyphBlt = miImageGlyphBlt, + .PolyGlyphBlt = miPolyGlyphBlt, + .PushPixels = miPushPixels, }; /** From 1b151f2e6aa581400b09220b87ae2d34a39aeb17 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Dec 2008 13:48:39 -0800 Subject: [PATCH 007/225] glamor: glFlush from the blockhandler so rendering happens. --- glamor/glamor.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index ba2701415..a45745985 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -74,6 +74,18 @@ glamor_destroy_pixmap(PixmapPtr pixmap) return fbDestroyPixmap(pixmap); } +static void +glamor_block_handler(void *data, OSTimePtr wt, void *last_select_mask) +{ + glFlush(); +} + +static void +glamor_wakeup_handler(void *data, OSTimePtr wt, void *last_select_mask) +{ + glFlush(); +} + /** Set up glamor for an already-configured GL context. */ Bool glamor_init(ScreenPtr screen) @@ -86,6 +98,14 @@ glamor_init(ScreenPtr screen) dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); + if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, + glamor_wakeup_handler, + NULL)) { + dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL); + xfree(glamor_priv); + return FALSE; + } + glamor_priv->saved_create_gc = screen->CreateGC; screen->CreateGC = glamor_create_gc; From df083fab84cf57fc1a2e3cd98572039bc9fe20de Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Dec 2008 13:43:52 -0800 Subject: [PATCH 008/225] glamor: first real attempt at rendering. --- glamor/Makefile.am | 2 + glamor/glamor_core.c | 108 +++++++++++++++++++++++++++++++++------- glamor/glamor_priv.h | 28 +++++++++++ hw/kdrive/ephyr/ephyr.c | 5 +- 4 files changed, 125 insertions(+), 18 deletions(-) diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 9ed40420f..b6a64fbe2 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -16,4 +16,6 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ glamor_core.c \ + glamor_fill.c \ + glamor_fillspans.c \ glamor.h diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index e49e9b5ed..eaa6b2d1e 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -36,22 +36,86 @@ #endif #include +#include "GL/gl.h" #include "glamor_priv.h" static void -glamor_fill_spans(DrawablePtr drawable, GCPtr gc, int n, - DDXPointPtr points, int *width, int sorted) +glamor_set_color_from_fgpixel(PixmapPtr pixmap, unsigned long fg_pixel) { - ScreenPtr screen = drawable->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + glColor4ub((fg_pixel >> 16) & 0xff, + (fg_pixel >> 8) & 0xff, + (fg_pixel) & 0xff, + (fg_pixel >> 24) & 0xff); +} - if (1 || screen_pixmap != dest_pixmap) { - fbFillSpans(drawable, gc, n, points, width, sorted); - } else { - ErrorF("stub fill_spans\n"); +static Bool +glamor_set_destination_pixmap(PixmapPtr pixmap) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap != screen_pixmap) { + ErrorF("stubbed drawing to non-screen pixmap\n"); + return FALSE; } + + glViewport(0, 0, + screen_pixmap->drawable.width, + screen_pixmap->drawable.height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, screen_pixmap->drawable.width, + 0, screen_pixmap->drawable.height, + -1.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + return TRUE; +} + +void +glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, unsigned long fg_pixel) +{ + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + + if (!glamor_set_destination_pixmap(pixmap)) + return; + glamor_set_color_from_fgpixel(pixmap, fg_pixel); + + glBegin(GL_TRIANGLE_FAN); + glVertex2f(x1, y1); + glVertex2f(x1, y2); + glVertex2f(x2, y2); + glVertex2f(x2, y1); + glEnd(); + + glFlush(); +} + +void +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) +{ + ErrorF("stubbed out stipple\n"); +} + +void +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) +{ + ErrorF("stubbed out tile\n"); } static void @@ -62,7 +126,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); - if (1 || screen_pixmap != dest_pixmap) { + if (screen_pixmap != dest_pixmap) { fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); } else { ErrorF("stub put_image\n"); @@ -71,20 +135,30 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, static void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, - DDXPointPtr points, int *width, int n, int sorted) + DDXPointPtr points, int *widths, int n, int sorted) { ScreenPtr screen = drawable->pScreen; PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); - if (1 || screen_pixmap != dest_pixmap) { - fbSetSpans(drawable, gc, src, points, width, n, sorted); + if (screen_pixmap != dest_pixmap) { + fbSetSpans(drawable, gc, src, points, widths, n, sorted); } else { - ErrorF("stub set_spans\n"); + int i; + + if (!glamor_set_destination_pixmap(dest_pixmap)) + return; + for (i = 0; i < n; i++) { + glDrawPixels(points[i].x - dest_pixmap->screen_x, + points[i].y - dest_pixmap->screen_y, + widths[i], + 1, + src); + src += PixmapBytePad(widths[i], drawable->depth); + } } } - /** * glamor_poly_lines() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill @@ -104,7 +178,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0 || gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) { - if (1 || dest_pixmap != screen_pixmap) + if (dest_pixmap != screen_pixmap) fbPolyLine(drawable, gc, mode, n, points); else ErrorF("stub poly_line\n"); @@ -126,7 +200,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, if (x1 != x2 && y1 != y2) { xfree(rects); - if (1 || dest_pixmap != screen_pixmap) + if (dest_pixmap != screen_pixmap) fbPolyLine(drawable, gc, mode, n, points); else ErrorF("stub poly_line\n"); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index fe597c230..ef043d035 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -49,5 +49,33 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); /* glamor_core.c */ Bool glamor_create_gc(GCPtr gc); +void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, + unsigned long fg_pixel); +void 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); +void 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); + +/* glamor_fill.c */ +void glamor_fill(DrawablePtr drawable, + GCPtr gc, + int x, + int y, + int width, + int height); + +/* glamor_fillspans.c */ +void glamor_fill_spans(DrawablePtr drawable, + GCPtr gc, + int n, + DDXPointPtr points, + int *widths, + int sorted); #endif /* GLAMOR_PRIV_H */ diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 7ebf1c253..16959d74b 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -394,7 +394,10 @@ ephyrSetInternalDamage (ScreenPtr pScreen) KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; PixmapPtr pPixmap = NULL; - + + if (ephyrFuncs.initAccel == ephyr_glamor_init) + return TRUE; + scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0, (DamageDestroyFunc) 0, DamageReportNone, From e32efb02e5dff9124e8680f9a15d9d2b01db84c7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Dec 2008 14:48:18 -0800 Subject: [PATCH 009/225] ephyr: merge the host glamor bits into hostx. --- hw/kdrive/ephyr/Makefile.am | 3 +- hw/kdrive/ephyr/ephyr_host_glamor.c | 60 ----------------------------- hw/kdrive/ephyr/hostx.c | 35 +++++++++++++++++ 3 files changed, 36 insertions(+), 62 deletions(-) delete mode 100644 hw/kdrive/ephyr/ephyr_host_glamor.c diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 349e86dca..7e10d6b79 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -24,8 +24,7 @@ bin_PROGRAMS = Xephyr HOSTX_SRCS = \ hostx.c \ - hostx.h \ - ephyr_host_glamor.c + hostx.h HOSTVIDEO_SRCS = \ ephyrvideo.c \ diff --git a/hw/kdrive/ephyr/ephyr_host_glamor.c b/hw/kdrive/ephyr/ephyr_host_glamor.c deleted file mode 100644 index f652bd00e..000000000 --- a/hw/kdrive/ephyr/ephyr_host_glamor.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "GL/glx.h" - -#include "hostx.h" - -void -ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) -{ - Display *dpy = hostx_get_display(); - int attribs[] = {GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - None}; - XVisualInfo *visual_info; - GLXContext ctx; - - visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs); - if (visual_info == NULL) - errx(1, "Couldn't get RGB visual\n"); - - ctx = glXCreateContext(dpy, visual_info, NULL, True); - if (ctx == NULL) - errx(1, "glXCreateContext failed\n"); - - glXMakeCurrent(dpy, hostx_get_window(DefaultScreen(dpy)), ctx); - - XFree(visual_info); -} diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 4caf4516d..a854c881d 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -46,6 +46,7 @@ #include #include /* for memset */ #include +#include #include #include @@ -61,6 +62,7 @@ #include #endif /* XF86DRI */ #include "ephyrlog.h" +#include "GL/glx.h" #ifdef XF86DRI extern Bool XF86DRIQueryExtension (Display *dpy, @@ -1445,3 +1447,36 @@ hostx_has_glx (void) } #endif /* XF86DRI */ + +void +ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) +{ + Display *dpy = hostx_get_display(); + int attribs[] = {GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None}; + XVisualInfo *visual_info; + GLXContext ctx; + struct EphyrHostScreen *host_screen; + int event_base = 0, error_base = 0; + + host_screen = host_screen_from_screen_info(ephyr_screen); + + if (!glXQueryExtension (dpy, &event_base, &error_base)) + errx(1, "Couldn't find GLX extension\n"); + + visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs); + if (visual_info == NULL) + errx(1, "Couldn't get RGB visual\n"); + + ctx = glXCreateContext(dpy, visual_info, NULL, True); + if (ctx == NULL) + errx(1, "glXCreateContext failed\n"); + + if (!glXMakeCurrent(dpy, host_screen->win, ctx)) + errx(1, "glXMakeCurrent failed\n"); + + XFree(visual_info); +} From 08097434ecc6479dc69a408523f398284168697e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 09:10:12 -0700 Subject: [PATCH 010/225] add fill files, merge with first real attempt at rendering. --- glamor/glamor_fill.c | 84 +++++++++++++++++++++++++++++ glamor/glamor_fillspans.c | 108 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 glamor/glamor_fill.c create mode 100644 glamor/glamor_fillspans.c diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c new file mode 100644 index 000000000..36e7badfb --- /dev/null +++ b/glamor/glamor_fill.c @@ -0,0 +1,84 @@ +/* + * Copyright © 2008 Intel Corporation + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +/** @file glamor_fillspans.c + * + * GC fill implementation, based loosely on fb_fill.c + */ + +void +glamor_fill(DrawablePtr drawable, + GCPtr gc, + int x, + int y, + int width, + int height) +{ + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); + + switch (gc->fillStyle) { + case FillSolid: + glamor_solid(dst_pixmap, + x - dst_pixmap->screen_x, + y - dst_pixmap->screen_y, + width, + height, + gc->alu, + gc->planemask, + gc->fgPixel); + break; + case FillStippled: + case FillOpaqueStippled: + glamor_stipple(dst_pixmap, + gc->stipple, + x - dst_pixmap->screen_x, + y - dst_pixmap->screen_y, + width, + height, + gc->alu, + gc->planemask, + gc->fgPixel, + gc->bgPixel, + gc->patOrg.x - dst_pixmap->screen_x, + gc->patOrg.y - dst_pixmap->screen_y); + break; + case FillTiled: + glamor_tile(dst_pixmap, + gc->tile.pixmap, + x - dst_pixmap->screen_x, + y - dst_pixmap->screen_y, + width, + height, + gc->alu, + gc->planemask, + gc->patOrg.x - dst_pixmap->screen_y, + gc->patOrg.y - dst_pixmap->screen_y); + break; + } +} diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c new file mode 100644 index 000000000..b0b704fd9 --- /dev/null +++ b/glamor/glamor_fillspans.c @@ -0,0 +1,108 @@ +/* + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +/** @file glamor_fillspans.c + * + * FillSpans implementation, taken from fb_fillsp.c + */ +#include "glamor_priv.h" + +void +glamor_fill_spans(DrawablePtr drawable, + GCPtr gc, + int n, + DDXPointPtr points, + int *widths, + int sorted) +{ + RegionPtr clip = gc->pCompositeClip; + BoxPtr extents, boxes; + int nbox; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1; + int partX1, partX2; + ScreenPtr screen = drawable->pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + + if (dest_pixmap != screen_pixmap) { + fbFillSpans(drawable, gc, n, points, widths, sorted); + return; + } + + extents = REGION_EXTENTS(gc->pScreen, clip); + extentX1 = extents->x1; + extentY1 = extents->y1; + extentX2 = extents->x2; + extentY2 = extents->y2; + while (n--) { + fullX1 = points->x; + fullY1 = points->y; + fullX2 = fullX1 + *widths; + points++; + widths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + nbox = REGION_NUM_RECTS (clip); + if (nbox == 1) { + glamor_fill(drawable, + gc, + fullX1, fullY1, fullX2-fullX1, 1); + } else { + boxes = REGION_RECTS(clip); + while(nbox--) + { + if (boxes->y1 <= fullY1 && fullY1 < boxes->y2) + { + partX1 = boxes->x1; + if (partX1 < fullX1) + partX1 = fullX1; + partX2 = boxes->x2; + if (partX2 > fullX2) + partX2 = fullX2; + if (partX2 > partX1) + { + glamor_fill(drawable, gc, + partX1, fullY1, + partX2 - partX1, 1); + } + } + boxes++; + } + } + } +} From 370df817ac0b346f1c7aa0b6e823c77797caaa9f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 09:35:24 -0700 Subject: [PATCH 011/225] ephyr: Make sure a glamor-using window is created with a glx visual. --- hw/kdrive/ephyr/ephyrinit.c | 2 ++ hw/kdrive/ephyr/hostx.c | 39 +++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index 4b291813a..9155d0861 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -31,6 +31,7 @@ extern Window EphyrPreExistingHostWin; extern Bool EphyrWantGrayScale; +extern Bool ephyr_glamor; extern Bool kdHasPointer; extern Bool kdHasKbd; @@ -223,6 +224,7 @@ ddxProcessArgument (int argc, char **argv, int i) } else if (!strcmp (argv[i], "-glamor")) { + ephyr_glamor = TRUE; ephyrFuncs.initAccel = ephyr_glamor_init; ephyrFuncs.enableAccel = ephyr_glamor_enable; ephyrFuncs.disableAccel = ephyr_glamor_disable; diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index a854c881d..c7c792984 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -97,6 +97,7 @@ struct EphyrHostXVars Display *dpy; int screen; Visual *visual; + XVisualInfo *visual_info; Window winroot; GC gc; int depth; @@ -125,10 +126,14 @@ extern int monitorResolution; char *ephyrResName = NULL; int ephyrResNameFromCmd = 0; char *ephyrTitle = NULL; +Bool ephyr_glamor = FALSE; static void hostx_set_fullscreen_hint(void); +static void +ephyr_glamor_get_visual(void); + /* X Error traps */ static int trapped_error_code = 0; @@ -364,8 +369,11 @@ hostx_init (void) HostX.winroot = RootWindow(HostX.dpy, HostX.screen); HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL); HostX.depth = DefaultDepth(HostX.dpy, HostX.screen); - HostX.visual = DefaultVisual(HostX.dpy, HostX.screen); - + if (ephyr_glamor) { + ephyr_glamor_get_visual(); + } else { + HostX.visual = DefaultVisual(HostX.dpy, HostX.screen); + } class_hint = XAllocClassHint(); for (index = 0 ; index < HostX.n_screens ; index++) @@ -1448,22 +1456,18 @@ hostx_has_glx (void) #endif /* XF86DRI */ -void -ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) +static void +ephyr_glamor_get_visual(void) { - Display *dpy = hostx_get_display(); + Display *dpy = HostX.dpy; int attribs[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None}; XVisualInfo *visual_info; - GLXContext ctx; - struct EphyrHostScreen *host_screen; int event_base = 0, error_base = 0; - host_screen = host_screen_from_screen_info(ephyr_screen); - if (!glXQueryExtension (dpy, &event_base, &error_base)) errx(1, "Couldn't find GLX extension\n"); @@ -1471,12 +1475,23 @@ ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) if (visual_info == NULL) errx(1, "Couldn't get RGB visual\n"); - ctx = glXCreateContext(dpy, visual_info, NULL, True); + HostX.visual_info = visual_info; + HostX.visual = visual_info->visual; +} + +void +ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) +{ + Display *dpy = HostX.dpy; + GLXContext ctx; + struct EphyrHostScreen *host_screen; + + host_screen = host_screen_from_screen_info(ephyr_screen); + + ctx = glXCreateContext(dpy, HostX.visual_info, NULL, True); if (ctx == NULL) errx(1, "glXCreateContext failed\n"); if (!glXMakeCurrent(dpy, host_screen->win, ctx)) errx(1, "glXMakeCurrent failed\n"); - - XFree(visual_info); } From 2e35ceca65bbebf07c15ea2cff932a8749955c2b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 11:19:43 -0700 Subject: [PATCH 012/225] ephyr: Use GLEW. This will hide all sorts of extension stuff from us. --- configure.ac | 9 +++++++++ glamor/glamor.c | 2 ++ glamor/glamor_core.c | 1 - glamor/glamor_priv.h | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 10069be66..3954ecc06 100644 --- a/configure.ac +++ b/configure.ac @@ -2011,6 +2011,15 @@ if test "$KDRIVE" = yes; then AC_MSG_ERROR([Xephyr dependencies missing]) fi + AC_CHECK_LIB(GLEW, glewInit, [ + AC_CHECK_HEADER(GL/glew.h, [], [ + AC_MSG_ERROR([requires glew http://glew.sourceforge.net/]) + ]) + ], [ + AC_MSG_ERROR([requires glew http://glew.sourceforge.net/]) + ]) + XEPHYR_LIBS="$XEPHYR_LIBS -lGLEW" + # Xephyr needs nanosleep() which is in librt on Solaris AC_CHECK_FUNC([nanosleep], [], AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt")) diff --git a/glamor/glamor.c b/glamor/glamor.c index a45745985..08e7ff966 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -115,6 +115,8 @@ glamor_init(ScreenPtr screen) glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_destroy_pixmap; + glewInit(); + return TRUE; } diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index eaa6b2d1e..651414b6e 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -36,7 +36,6 @@ #endif #include -#include "GL/gl.h" #include "glamor_priv.h" diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index ef043d035..285799da5 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -29,6 +29,7 @@ #define GLAMOR_PRIV_H #include "glamor.h" +#include typedef struct glamor_screen_private { CreateGCProcPtr saved_create_gc; From 399e00698976dd2e503b3a092bfe54ab24ea26d9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 11:37:37 -0700 Subject: [PATCH 013/225] glamor: Fix up block/wakeup handler. Prototypes are fixed, and we don't need to flush on wakeup. --- glamor/glamor.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 08e7ff966..86a76940e 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -75,15 +75,14 @@ glamor_destroy_pixmap(PixmapPtr pixmap) } static void -glamor_block_handler(void *data, OSTimePtr wt, void *last_select_mask) +glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask) { glFlush(); } static void -glamor_wakeup_handler(void *data, OSTimePtr wt, void *last_select_mask) +glamor_wakeup_handler(void *data, int result, void *last_select_mask) { - glFlush(); } /** Set up glamor for an already-configured GL context. */ From 74f262bcdb3d8ae769ef8975cf4a4b2ebaeb6b39 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 11:39:05 -0700 Subject: [PATCH 014/225] glamor: remove gratuitous flush. --- glamor/glamor_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 651414b6e..39f36cd9b 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -94,8 +94,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glVertex2f(x2, y2); glVertex2f(x2, y1); glEnd(); - - glFlush(); } void From fbbdd788cbc822fc8a2d2726435bfa39e69a0e85 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 12:36:33 -0700 Subject: [PATCH 015/225] glamor: Fix up DrawPixels arguments to bear some relation to reality. --- glamor/glamor_core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 39f36cd9b..7f97190cc 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -146,10 +146,11 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, if (!glamor_set_destination_pixmap(dest_pixmap)) return; for (i = 0; i < n; i++) { - glDrawPixels(points[i].x - dest_pixmap->screen_x, - points[i].y - dest_pixmap->screen_y, - widths[i], + glRasterPos2i(points[i].x - dest_pixmap->screen_x, + points[i].y - dest_pixmap->screen_y); + glDrawPixels(widths[i], 1, + GL_RGBA, GL_UNSIGNED_BYTE, src); src += PixmapBytePad(widths[i], drawable->depth); } From f1dbed5456e5a608425530e0dde2dc617a7c6115 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 12:32:53 -0700 Subject: [PATCH 016/225] glamor: Move to using shader objects. --- glamor/glamor.c | 22 ++++++-- glamor/glamor_core.c | 125 +++++++++++++++++++++++++++++++------------ glamor/glamor_fill.c | 86 +++++++++++++++++++++++++++++ glamor/glamor_priv.h | 29 ++++++++-- 4 files changed, 221 insertions(+), 41 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 86a76940e..050dd3d66 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -97,12 +97,21 @@ glamor_init(ScreenPtr screen) dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); + glewInit(); + + if (!GLEW_ARB_shader_objects) { + ErrorF("GL_ARB_shader_objects required\n"); + goto fail; + } + if (!GLEW_ARB_vertex_shader) { + ErrorF("GL_ARB_vertex_shader required\n"); + goto fail; + } + if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, NULL)) { - dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL); - xfree(glamor_priv); - return FALSE; + goto fail; } glamor_priv->saved_create_gc = screen->CreateGC; @@ -114,9 +123,14 @@ glamor_init(ScreenPtr screen) glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_destroy_pixmap; - glewInit(); + glamor_init_solid_shader(screen); return TRUE; + +fail: + xfree(glamor_priv); + dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL); + return FALSE; } void diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 7f97190cc..9c892ead9 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -39,16 +39,7 @@ #include "glamor_priv.h" -static void -glamor_set_color_from_fgpixel(PixmapPtr pixmap, unsigned long fg_pixel) -{ - glColor4ub((fg_pixel >> 16) & 0xff, - (fg_pixel >> 8) & 0xff, - (fg_pixel) & 0xff, - (fg_pixel >> 24) & 0xff); -} - -static Bool +Bool glamor_set_destination_pixmap(PixmapPtr pixmap) { ScreenPtr screen = pixmap->drawable.pScreen; @@ -63,37 +54,103 @@ glamor_set_destination_pixmap(PixmapPtr pixmap) screen_pixmap->drawable.width, screen_pixmap->drawable.height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, screen_pixmap->drawable.width, - 0, screen_pixmap->drawable.height, - -1.0, 1.0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - return TRUE; } void -glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, unsigned long fg_pixel) +glamor_get_transform_uniform_locations(GLint prog, + glamor_transform_uniforms *uniform_locations) { - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; + uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias"); + uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale"); + uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias"); + uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale"); +} - if (!glamor_set_destination_pixmap(pixmap)) - return; - glamor_set_color_from_fgpixel(pixmap, fg_pixel); +/* We don't use a full matrix for our transformations because it's + * wasteful when all we want is to rescale to NDC and possibly do a flip + * if it's the front buffer. + */ +void +glamor_set_transform_for_pixmap(PixmapPtr pixmap, + glamor_transform_uniforms *uniform_locations) +{ + glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); + glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); + glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); + glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); +} - glBegin(GL_TRIANGLE_FAN); - glVertex2f(x1, y1); - glVertex2f(x1, y2); - glVertex2f(x2, y2); - glVertex2f(x2, y1); - glEnd(); +GLint +glamor_compile_glsl_prog(GLenum type, const char *source) +{ + GLint ok; + GLint prog; + + prog = glCreateShaderObjectARB(type); + glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL); + glCompileShaderARB(prog); + glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok); + if (!ok) { + GLchar *info; + GLint size; + + glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); + info = malloc(size); + + glGetInfoLogARB(prog, size, NULL, info); + ErrorF("Failed to compile %s: %s\n", + type == GL_FRAGMENT_SHADER ? "FS" : "VS", + info); + ErrorF("Program source:\n%s", source); + FatalError("GLSL compile failure\n"); + } + + return prog; +} + +void +glamor_link_glsl_prog(GLint prog) +{ + GLint ok; + + glLinkProgram(prog); + glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok); + if (!ok) { + GLchar *info; + GLint size; + + glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); + info = malloc(size); + + glGetInfoLogARB(prog, size, NULL, info); + ErrorF("Failed to link: %s\n", + info); + FatalError("GLSL link failure\n"); + } +} + +static float ubyte_to_float(uint8_t b) +{ + return b / 255.0f; +} + +void +glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, + GLfloat *color) +{ + if (pixmap->drawable.depth < 24) { + ErrorF("pixmap with bad depth\n"); + color[0] = 1.0; + color[1] = 0.0; + color[2] = 1.0; + color[3] = 1.0; + } else { + color[0] = ubyte_to_float(fg_pixel >> 16); + color[1] = ubyte_to_float(fg_pixel >> 8); + color[2] = ubyte_to_float(fg_pixel >> 0); + color[3] = ubyte_to_float(fg_pixel >> 24); + } } void diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 36e7badfb..0d87bd037 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -82,3 +82,89 @@ glamor_fill(DrawablePtr drawable, break; } } + +void +glamor_init_solid_shader(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + const char *solid_vs_only = + "uniform vec4 color;\n" + "uniform float x_bias;\n" + "uniform float x_scale;\n" + "uniform float y_bias;\n" + "uniform float y_scale;\n" + "void main()\n" + "{\n" + " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" + " (gl_Vertex.y + y_bias) * y_scale,\n" + " 0,\n" + " 1);\n" + " gl_Color = color;\n" + "}\n"; + const char *solid_vs = + "uniform float x_bias;\n" + "uniform float x_scale;\n" + "uniform float y_bias;\n" + "uniform float y_scale;\n" + "void main()\n" + "{\n" + " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" + " (gl_Vertex.y + y_bias) * y_scale,\n" + " 0,\n" + " 1);\n" + "}\n"; + const char *solid_fs = + "uniform vec4 color;\n" + "void main()\n" + "{\n" + " gl_FragColor = color;\n" + "}\n"; + GLint fs_prog, vs_prog; + + glamor_priv->solid_prog = glCreateProgramObjectARB(); + if (GLEW_ARB_fragment_shader) { + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, solid_fs); + glAttachObjectARB(glamor_priv->solid_prog, vs_prog); + glAttachObjectARB(glamor_priv->solid_prog, fs_prog); + } else { + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs_only); + glAttachObjectARB(glamor_priv->solid_prog, vs_prog); + } + glamor_link_glsl_prog(glamor_priv->solid_prog); + + glamor_priv->solid_color_uniform_location = + glGetUniformLocationARB(glamor_priv->solid_prog, "color"); + glamor_get_transform_uniform_locations(glamor_priv->solid_prog, + &glamor_priv->solid_transform); +} + +void +glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, unsigned long fg_pixel) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + GLfloat color[4]; + + if (!glamor_set_destination_pixmap(pixmap)) + return; + + glUseProgramObjectARB(glamor_priv->solid_prog); + glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color); + glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color); + glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform); + + glBegin(GL_TRIANGLE_FAN); + glVertex2f(x1, y1); + glVertex2f(x1, y2); + glVertex2f(x2, y2); + glVertex2f(x2, y1); + glEnd(); + + glUseProgramObjectARB(0); +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 285799da5..3216a7a4a 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -31,10 +31,22 @@ #include "glamor.h" #include +typedef struct glamor_transform_uniforms { + GLint x_bias; + GLint x_scale; + GLint y_bias; + GLint y_scale; +} glamor_transform_uniforms; + typedef struct glamor_screen_private { CreateGCProcPtr saved_create_gc; CreatePixmapProcPtr saved_create_pixmap; DestroyPixmapProcPtr saved_destroy_pixmap; + + /* glamor_solid */ + GLint solid_prog; + GLint solid_color_uniform_location; + glamor_transform_uniforms solid_transform; } glamor_screen_private; extern DevPrivateKey glamor_screen_private_key; @@ -50,9 +62,6 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); /* glamor_core.c */ Bool glamor_create_gc(GCPtr gc); -void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - unsigned long fg_pixel); void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, @@ -62,6 +71,15 @@ void 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); +GLint glamor_compile_glsl_prog(GLenum type, const char *source); +void glamor_link_glsl_prog(GLint prog); +void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, + GLfloat *color); +Bool glamor_set_destination_pixmap(PixmapPtr pixmap); +void glamor_get_transform_uniform_locations(GLint prog, + glamor_transform_uniforms *uniform_locations); +void glamor_set_transform_for_pixmap(PixmapPtr pixmap, + glamor_transform_uniforms *uniform_locations); /* glamor_fill.c */ void glamor_fill(DrawablePtr drawable, @@ -70,6 +88,9 @@ void glamor_fill(DrawablePtr drawable, int y, int width, int height); +void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, + unsigned long fg_pixel); /* glamor_fillspans.c */ void glamor_fill_spans(DrawablePtr drawable, @@ -79,4 +100,6 @@ void glamor_fill_spans(DrawablePtr drawable, int *widths, int sorted); +void glamor_init_solid_shader(ScreenPtr screen); + #endif /* GLAMOR_PRIV_H */ From 4f139db92fb283792adae8d39a49a083e4382fb5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 14:43:43 -0700 Subject: [PATCH 017/225] glamor: Add getspans implementation. --- glamor/Makefile.am | 1 + glamor/glamor.c | 4 +++ glamor/glamor_getspans.c | 74 ++++++++++++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 10 ++++++ 4 files changed, 89 insertions(+) create mode 100644 glamor/glamor_getspans.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index b6a64fbe2..2d9fdf57c 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -18,4 +18,5 @@ libglamor_la_SOURCES = \ glamor_core.c \ glamor_fill.c \ glamor_fillspans.c \ + glamor_getspans.c \ glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c index 050dd3d66..0aa9db83b 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -123,6 +123,9 @@ glamor_init(ScreenPtr screen) glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_destroy_pixmap; + glamor_priv->saved_get_spans = screen->GetSpans; + screen->GetSpans = glamor_get_spans; + glamor_init_solid_shader(screen); return TRUE; @@ -141,4 +144,5 @@ glamor_fini(ScreenPtr screen) screen->CreateGC = glamor_priv->saved_create_gc; screen->CreatePixmap = glamor_priv->saved_create_pixmap; screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; + screen->GetSpans = glamor_priv->saved_get_spans; } diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c new file mode 100644 index 000000000..b10a29dcd --- /dev/null +++ b/glamor/glamor_getspans.c @@ -0,0 +1,74 @@ +/* + * 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: + * Eric Anholt + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +void +glamor_get_spans(DrawablePtr drawable, + int wmax, + DDXPointPtr points, + int *widths, + int count, + char *dst) +{ + ScreenPtr screen = drawable->pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + + if (screen_pixmap != pixmap) { + fbGetSpans(drawable, wmax, points, widths, count, dst); + return; + } else { + GLenum format, type; + int i; + switch (drawable->depth) { + case 24: + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown getspans depth %d\n", drawable->depth); + return; + } + if (!glamor_set_destination_pixmap(pixmap)) + return; + for (i = 0; i < count; i++) { + glReadPixels(points[i].x - pixmap->screen_x, + points[i].y - pixmap->screen_y, + widths[i], + 1, + format, type, + dst); + dst += PixmapBytePad(widths[i], drawable->depth); + } + } +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 3216a7a4a..016a404bc 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -42,6 +42,7 @@ typedef struct glamor_screen_private { CreateGCProcPtr saved_create_gc; CreatePixmapProcPtr saved_create_pixmap; DestroyPixmapProcPtr saved_destroy_pixmap; + GetSpansProcPtr saved_get_spans; /* glamor_solid */ GLint solid_prog; @@ -102,4 +103,13 @@ void glamor_fill_spans(DrawablePtr drawable, void glamor_init_solid_shader(ScreenPtr screen); +/* glamor_getspans.c */ +void +glamor_get_spans(DrawablePtr drawable, + int wmax, + DDXPointPtr points, + int *widths, + int nspans, + char *dst_start); + #endif /* GLAMOR_PRIV_H */ From f92d1478e984d57806731886820f47e1258b5115 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 14:45:47 -0700 Subject: [PATCH 018/225] glamor: Maybe fix up the format/type for setspans. --- glamor/glamor_core.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 9c892ead9..c8b331a18 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -198,8 +198,20 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, if (screen_pixmap != dest_pixmap) { fbSetSpans(drawable, gc, src, points, widths, n, sorted); } else { + GLenum format, type; int i; + switch (drawable->depth) { + case 24: + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown setspans depth %d\n", drawable->depth); + return; + } + if (!glamor_set_destination_pixmap(dest_pixmap)) return; for (i = 0; i < n; i++) { @@ -207,7 +219,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, points[i].y - dest_pixmap->screen_y); glDrawPixels(widths[i], 1, - GL_RGBA, GL_UNSIGNED_BYTE, + format, type, src); src += PixmapBytePad(widths[i], drawable->depth); } From 519103565c1b182014dea93c58917bf7e5a35fcb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 15:28:13 -0700 Subject: [PATCH 019/225] glamor: Create FBOs for pixmaps. --- glamor/glamor.c | 64 ++++++++++++++++++++++- glamor/glamor_core.c | 107 ++++++++++++++++++-------------------- glamor/glamor_fillspans.c | 8 --- glamor/glamor_getspans.c | 51 +++++++++--------- glamor/glamor_priv.h | 11 ++++ 5 files changed, 148 insertions(+), 93 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 0aa9db83b..7b81abab2 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -40,6 +40,8 @@ static int glamor_screen_private_key_index; DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index; +static int glamor_pixmap_private_key_index; +DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index; /** * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable. @@ -63,9 +65,57 @@ glamor_get_drawable_pixmap(DrawablePtr drawable) static PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, - unsigned int usage_hint) + unsigned int usage) { - return fbCreatePixmap(screen, w, h, depth, usage_hint); + PixmapPtr pixmap; + glamor_pixmap_private *pixmap_priv; + GLenum format; + + if (w > 32767 || h > 32767) + return NullPixmap; + + pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); + pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (w == 0 || h == 0) + return pixmap; + + /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA. + * FBOs, which EXT_fbo forgot to do. + */ + switch (depth) { + case 24: + format = GL_RGB; + break; + default: + format = GL_RGBA; + break; + } + + /* Create the texture used to store the pixmap's data. */ + glGenTextures(1, &pixmap_priv->tex); + glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, + format, GL_UNSIGNED_BYTE, NULL); + + /* Create a framebuffer object wrapping the texture so that we can render + * to it. + */ + glGenFramebuffersEXT(1, &pixmap_priv->fb); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + pixmap_priv->tex, + 0); + + screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, + (w * pixmap->drawable.bitsPerPixel + 7) / 8, + NULL); + + return pixmap; } static Bool @@ -96,9 +146,19 @@ glamor_init(ScreenPtr screen) return FALSE; dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); + if (!dixRequestPrivate(glamor_pixmap_private_key, + sizeof(glamor_pixmap_private))) { + LogMessage(X_WARNING, + "glamor%d: Failed to allocate pixmap private\n", + screen->myNum); + } glewInit(); + if (!GLEW_EXT_framebuffer_object) { + ErrorF("GL_EXT_framebuffer_object required\n"); + goto fail; + } if (!GLEW_ARB_shader_objects) { ErrorF("GL_ARB_shader_objects required\n"); goto fail; diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index c8b331a18..ffccd3e12 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -42,17 +42,28 @@ Bool glamor_set_destination_pixmap(PixmapPtr pixmap) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - if (pixmap != screen_pixmap) { - ErrorF("stubbed drawing to non-screen pixmap\n"); + if (pixmap_priv == NULL) { + ErrorF("no pixmap priv?"); return FALSE; } + if (pixmap_priv->fb == 0) { + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap != screen_pixmap) { + ErrorF("No FBO\n"); + return FALSE; + } + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glViewport(0, 0, - screen_pixmap->drawable.width, - screen_pixmap->drawable.height); + pixmap->drawable.width, + pixmap->drawable.height); return TRUE; } @@ -75,10 +86,18 @@ void glamor_set_transform_for_pixmap(PixmapPtr pixmap, glamor_transform_uniforms *uniform_locations) { + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); - glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); + if (pixmap == screen_pixmap) + glUniform1fARB(uniform_locations->y_scale, + -2.0f / pixmap->drawable.height); + else + glUniform1fARB(uniform_locations->y_scale, + 2.0f / pixmap->drawable.height); } GLint @@ -176,53 +195,38 @@ static void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { - ScreenPtr screen = drawable->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); - - if (screen_pixmap != dest_pixmap) { - fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); - } else { - ErrorF("stub put_image\n"); - } + ErrorF("stub put_image\n"); } static void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int n, int sorted) { - ScreenPtr screen = drawable->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + GLenum format, type; + int i; - if (screen_pixmap != dest_pixmap) { - fbSetSpans(drawable, gc, src, points, widths, n, sorted); - } else { - GLenum format, type; - int i; + switch (drawable->depth) { + case 24: + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown setspans depth %d\n", drawable->depth); + return; + } - switch (drawable->depth) { - case 24: - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - ErrorF("Unknown setspans depth %d\n", drawable->depth); - return; - } - - if (!glamor_set_destination_pixmap(dest_pixmap)) - return; - for (i = 0; i < n; i++) { - glRasterPos2i(points[i].x - dest_pixmap->screen_x, - points[i].y - dest_pixmap->screen_y); - glDrawPixels(widths[i], - 1, - format, type, - src); - src += PixmapBytePad(widths[i], drawable->depth); - } + if (!glamor_set_destination_pixmap(dest_pixmap)) + return; + for (i = 0; i < n; i++) { + glRasterPos2i(points[i].x - dest_pixmap->screen_x, + points[i].y - dest_pixmap->screen_y); + glDrawPixels(widths[i], + 1, + format, type, + src); + src += PixmapBytePad(widths[i], drawable->depth); } } @@ -235,9 +239,6 @@ static void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points) { - ScreenPtr screen = drawable->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); xRectangle *rects; int x1, x2, y1, y2; int i; @@ -245,10 +246,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0 || gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) { - if (dest_pixmap != screen_pixmap) - fbPolyLine(drawable, gc, mode, n, points); - else - ErrorF("stub poly_line\n"); + ErrorF("stub poly_line\n"); return; } @@ -267,10 +265,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, if (x1 != x2 && y1 != y2) { xfree(rects); - if (dest_pixmap != screen_pixmap) - fbPolyLine(drawable, gc, mode, n, points); - else - ErrorF("stub poly_line\n"); + ErrorF("stub poly_line\n"); return; } diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index b0b704fd9..120e3467d 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -44,14 +44,6 @@ glamor_fill_spans(DrawablePtr drawable, int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1; int partX1, partX2; - ScreenPtr screen = drawable->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); - - if (dest_pixmap != screen_pixmap) { - fbFillSpans(drawable, gc, n, points, widths, sorted); - return; - } extents = REGION_EXTENTS(gc->pScreen, clip); extentX1 = extents->x1; diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index b10a29dcd..8466208d7 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -39,36 +39,33 @@ glamor_get_spans(DrawablePtr drawable, int count, char *dst) { - ScreenPtr screen = drawable->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + GLenum format, type; + int i; - if (screen_pixmap != pixmap) { + switch (drawable->depth) { + case 24: + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown getspans depth %d\n", drawable->depth); + return; + } + + if (!glamor_set_destination_pixmap(pixmap)) { fbGetSpans(drawable, wmax, points, widths, count, dst); return; - } else { - GLenum format, type; - int i; - switch (drawable->depth) { - case 24: - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - ErrorF("Unknown getspans depth %d\n", drawable->depth); - return; - } - if (!glamor_set_destination_pixmap(pixmap)) - return; - for (i = 0; i < count; i++) { - glReadPixels(points[i].x - pixmap->screen_x, - points[i].y - pixmap->screen_y, - widths[i], - 1, - format, type, - dst); - dst += PixmapBytePad(widths[i], drawable->depth); - } + } + + for (i = 0; i < count; i++) { + glReadPixels(points[i].x - pixmap->screen_x, + points[i].y - pixmap->screen_y, + widths[i], + 1, + format, type, + dst); + dst += PixmapBytePad(widths[i], drawable->depth); } } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 016a404bc..6d08b00c6 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -50,13 +50,24 @@ typedef struct glamor_screen_private { glamor_transform_uniforms solid_transform; } glamor_screen_private; +typedef struct glamor_pixmap_private { + GLuint tex; + GLuint fb; +} glamor_pixmap_private; + 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 glamor_pixmap_private * +glamor_get_pixmap_private(PixmapPtr pixmap) +{ + return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); +} /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); From 8016135ec7616530e64d0019ce0401e62b25e483 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 15:37:22 -0700 Subject: [PATCH 020/225] glamor: Fill out glamor_get_color_4f_from_pixel() a bit. --- glamor/glamor_core.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index ffccd3e12..e4aa95dbc 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -158,17 +158,33 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, GLfloat *color) { - if (pixmap->drawable.depth < 24) { - ErrorF("pixmap with bad depth\n"); - color[0] = 1.0; + switch (pixmap->drawable.depth) { + case 1: + color[0] = 0.0; color[1] = 0.0; - color[2] = 1.0; - color[3] = 1.0; - } else { + color[2] = 0.0; + color[3] = fg_pixel & 0x01; + break; + case 8: + color[0] = 0.0; + color[1] = 0.0; + color[2] = 0.0; + color[3] = (fg_pixel & 0xff) / 255.0; + break; + case 24: + case 32: color[0] = ubyte_to_float(fg_pixel >> 16); color[1] = ubyte_to_float(fg_pixel >> 8); color[2] = ubyte_to_float(fg_pixel >> 0); color[3] = ubyte_to_float(fg_pixel >> 24); + break; + default: + ErrorF("pixmap with bad depth: %d\n", pixmap->drawable.depth); + color[0] = 1.0; + color[1] = 0.0; + color[2] = 1.0; + color[3] = 1.0; + break; } } From 16c3b929dd4cae6b40e847256db6ff32e63e9029 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 16:06:42 -0700 Subject: [PATCH 021/225] glamor: Add untested support for tile filling. --- glamor/Makefile.am | 1 + glamor/glamor.c | 1 + glamor/glamor_core.c | 9 --- glamor/glamor_fill.c | 20 ++++++ glamor/glamor_priv.h | 27 ++++++-- glamor/glamor_tile.c | 151 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 196 insertions(+), 13 deletions(-) create mode 100644 glamor/glamor_tile.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 2d9fdf57c..2453566fc 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -19,4 +19,5 @@ libglamor_la_SOURCES = \ glamor_fill.c \ glamor_fillspans.c \ glamor_getspans.c \ + glamor_tile.c \ glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c index 7b81abab2..c3e4eb9f8 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -187,6 +187,7 @@ glamor_init(ScreenPtr screen) screen->GetSpans = glamor_get_spans; glamor_init_solid_shader(screen); + glamor_init_tile_shader(screen); return TRUE; diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index e4aa95dbc..549a5f313 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -198,15 +198,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, ErrorF("stubbed out stipple\n"); } -void -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) -{ - ErrorF("stubbed out tile\n"); -} - static void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 0d87bd037..11d5f9841 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -168,3 +168,23 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glUseProgramObjectARB(0); } + +/* Highlight places where we're doing it wrong. */ +void +glamor_solid_fail_region(PixmapPtr pixmap, int x, int y, int width, int height) +{ + unsigned long pixel; + + switch (pixmap->drawable.depth) { + case 24: + case 32: + pixel = 0x00ff00ff; /* our favorite color */ + break; + default: + case 8: + pixel = 0xd0d0d0d0; + break; + } + + glamor_solid(pixmap, x, y, width, height, GXcopy, ~0, pixel); +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 6d08b00c6..9bae8144b 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -48,6 +48,9 @@ typedef struct glamor_screen_private { GLint solid_prog; GLint solid_color_uniform_location; glamor_transform_uniforms solid_transform; + + GLint tile_prog; + glamor_transform_uniforms tile_transform; } glamor_screen_private; typedef struct glamor_pixmap_private { @@ -69,6 +72,17 @@ glamor_get_pixmap_private(PixmapPtr pixmap) return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); } +/** + * 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); +} + /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); @@ -79,10 +93,6 @@ void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, unsigned char alu, unsigned long planemask, unsigned long fg_pixel, unsigned long bg_pixel, int stipple_x, int stipple_y); -void 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); GLint glamor_compile_glsl_prog(GLenum type, const char *source); void glamor_link_glsl_prog(GLint prog); void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, @@ -103,6 +113,8 @@ void glamor_fill(DrawablePtr drawable, void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, unsigned long fg_pixel); +void glamor_solid_fail_region(PixmapPtr pixmap, + int x, int y, int width, int height); /* glamor_fillspans.c */ void glamor_fill_spans(DrawablePtr drawable, @@ -123,4 +135,11 @@ glamor_get_spans(DrawablePtr drawable, int nspans, char *dst_start); +/* glamor_tile.c */ +void 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); + #endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c new file mode 100644 index 000000000..d47644297 --- /dev/null +++ b/glamor/glamor_tile.c @@ -0,0 +1,151 @@ +/* + * 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: + * Eric Anholt + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +/** @file glamor_tile.c + * + * Implements the basic fill-with-a-tile support used by multiple GC ops. + */ + +void +glamor_init_tile_shader(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + const char *tile_vs = + "uniform float x_bias;\n" + "uniform float x_scale;\n" + "uniform float y_bias;\n" + "uniform float y_scale;\n" + "void main()\n" + "{\n" + " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" + " (gl_Vertex.y + y_bias) * y_scale,\n" + " 0,\n" + " 1);\n" + " gl_TexCoord[0] = vec4(gl_MultiTexCoord0.xy, 0, 1);\n" + "}\n"; + const char *tile_fs = + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" + "}\n"; + GLint fs_prog, vs_prog; + GLint sampler_uniform_location; + + if (!GLEW_ARB_fragment_shader) + return; + + glamor_priv->tile_prog = glCreateProgramObjectARB(); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, tile_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, tile_fs); + glAttachObjectARB(glamor_priv->tile_prog, vs_prog); + glAttachObjectARB(glamor_priv->tile_prog, fs_prog); + glamor_link_glsl_prog(glamor_priv->tile_prog); + + sampler_uniform_location = + glGetUniformLocationARB(glamor_priv->tile_prog, "sampler"); + glUseProgramObjectARB(glamor_priv->tile_prog); + glUniform1iARB(sampler_uniform_location, 0); + glamor_get_transform_uniform_locations(glamor_priv->tile_prog, + &glamor_priv->tile_transform); +} + +void +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) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + int tile_x1 = tile_x + tile->screen_x; + int tile_x2 = tile_x + tile->screen_x + width; + int tile_y1 = tile_y + tile->screen_y; + int tile_y2 = tile_y + tile->screen_y + height; + glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile); + + if (glamor_priv->tile_prog == 0) { + ErrorF("Tiling unsupported\n"); + goto fail; + } + + if (!glamor_set_destination_pixmap(pixmap)) + goto fail; + if (tile_priv->fb == 0) { + ErrorF("Non-FBO tile pixmap\n"); + goto fail; + } + if (alu != GXcopy) { + ErrorF("tile alu\n"); + goto fail; + } + if (!glamor_pm_is_solid(&pixmap->drawable, planemask)) { + ErrorF("tile pm\n"); + goto fail; + } + + glUseProgramObjectARB(glamor_priv->tile_prog); + glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tile_priv->tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEnable(GL_TEXTURE_2D); + + tile_x += tile->screen_x; + tile_y += tile->screen_y; + + glBegin(GL_TRIANGLE_FAN); + glMultiTexCoord2f(0, tile_x1, tile_y1); + glVertex2f(x1, y1); + glMultiTexCoord2f(0, tile_x1, tile_y2); + glVertex2f(x1, y2); + glMultiTexCoord2f(0, tile_x2, tile_y2); + glVertex2f(x2, y2); + glMultiTexCoord2f(0, tile_x2, tile_y1); + glVertex2f(x2, y1); + glEnd(); + + glUseProgramObjectARB(0); + glDisable(GL_TEXTURE_2D); + return; + +fail: + glamor_solid_fail_region(pixmap, x, y, width, height); + return; +} From 2fa26c4958168064da95361db78ccc518c8f3ed8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 16:43:03 -0700 Subject: [PATCH 022/225] glamor: Free resources when destroying pixmaps. --- glamor/glamor.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index c3e4eb9f8..03886ad65 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -121,6 +121,13 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, static Bool glamor_destroy_pixmap(PixmapPtr pixmap) { + if (pixmap->refcnt == 1) { + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + glDeleteFramebuffersEXT(1, &pixmap_priv->fb); + glDeleteTextures(1, &pixmap_priv->tex); + } + return fbDestroyPixmap(pixmap); } From f6cffbb2ba66948ad5cc1cbe20e12de204de175d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 16:43:22 -0700 Subject: [PATCH 023/225] glamor: Add stub Composite support. --- glamor/Makefile.am | 1 + glamor/glamor.c | 14 ++++++++++++++ glamor/glamor_priv.h | 15 +++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 2453566fc..3f5a2002b 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -19,5 +19,6 @@ libglamor_la_SOURCES = \ glamor_fill.c \ glamor_fillspans.c \ glamor_getspans.c \ + glamor_render.c \ glamor_tile.c \ glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c index 03886ad65..ff31f5dba 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -147,6 +147,9 @@ Bool glamor_init(ScreenPtr screen) { glamor_screen_private *glamor_priv; +#ifdef RENDER + PictureScreenPtr ps = GetPictureScreenIfSet(screen); +#endif glamor_priv = xcalloc(1, sizeof(*glamor_priv)); if (glamor_priv == NULL) @@ -193,6 +196,11 @@ glamor_init(ScreenPtr screen) glamor_priv->saved_get_spans = screen->GetSpans; screen->GetSpans = glamor_get_spans; +#ifdef RENDER + glamor_priv->saved_composite = ps->Composite; + ps->Composite = glamor_composite; +#endif + glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); @@ -208,9 +216,15 @@ void glamor_fini(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); +#ifdef RENDER + PictureScreenPtr ps = GetPictureScreenIfSet(screen); +#endif screen->CreateGC = glamor_priv->saved_create_gc; screen->CreatePixmap = glamor_priv->saved_create_pixmap; screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; screen->GetSpans = glamor_priv->saved_get_spans; +#ifdef RENDER + ps->Composite = glamor_priv->saved_composite; +#endif } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 9bae8144b..aee8e2d3e 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -43,6 +43,7 @@ typedef struct glamor_screen_private { CreatePixmapProcPtr saved_create_pixmap; DestroyPixmapProcPtr saved_destroy_pixmap; GetSpansProcPtr saved_get_spans; + CompositeProcPtr saved_composite; /* glamor_solid */ GLint solid_prog; @@ -135,6 +136,20 @@ glamor_get_spans(DrawablePtr drawable, int nspans, char *dst_start); +/* glamor_render.c */ +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); + /* glamor_tile.c */ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int x, int y, int width, int height, From 7500ee2b0215932ecb6688f301fb4e6f080f8a66 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 17:05:00 -0700 Subject: [PATCH 024/225] glamor: Fill in 1 and 24-bit getspans. --- glamor/glamor_getspans.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 8466208d7..5853f9450 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -31,6 +31,18 @@ #include "glamor_priv.h" +static void +set_bit(uint8_t *bitfield, unsigned int index, unsigned int val) +{ + int i = index / 8; + int mask = 1 << (index % 8); + + if (val) + bitfield[i] |= mask; + else + bitfield[i] &= ~mask; +} + void glamor_get_spans(DrawablePtr drawable, int wmax, @@ -41,10 +53,20 @@ glamor_get_spans(DrawablePtr drawable, { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; - int i; + int i, j; + uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst; switch (drawable->depth) { + case 1: + temp_dst = xalloc(4 * wmax); + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + readpixels_dst = temp_dst; + break; case 24: + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -65,7 +87,14 @@ glamor_get_spans(DrawablePtr drawable, widths[i], 1, format, type, - dst); - dst += PixmapBytePad(widths[i], drawable->depth); + readpixels_dst); + if (temp_dst) { + for (j = 0; j < widths[i]; j++) { + set_bit((uint8_t *)dst, j, temp_dst[j] & 0x1); + } + dst += PixmapBytePad(widths[i], drawable->depth); + } else { + readpixels_dst += PixmapBytePad(widths[i], drawable->depth); + } } } From 60ca0260f23cac6577aa85aacb0e5644d5f1b349 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Aug 2009 17:17:43 -0700 Subject: [PATCH 025/225] glamor: Add more solid_fail_regions for software fallbacks. --- glamor/glamor_core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 549a5f313..5ecc894bb 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -195,14 +195,18 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, unsigned long fg_pixel, unsigned long bg_pixel, int stipple_x, int stipple_y) { - ErrorF("stubbed out stipple\n"); + ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth); + glamor_solid_fail_region(pixmap, x, y, width, height); } static void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { - ErrorF("stub put_image\n"); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + + ErrorF("stub put_image depth %d\n", drawable->depth); + glamor_solid_fail_region(pixmap, x, y, w, h); } static void @@ -253,7 +257,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0 || gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) { - ErrorF("stub poly_line\n"); + ErrorF("stub poly_line depth %d\n", drawable->depth); return; } @@ -271,8 +275,12 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, } if (x1 != x2 && y1 != y2) { + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + xfree(rects); - ErrorF("stub poly_line\n"); + + ErrorF("stub diagonal poly_line\n"); + glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1); return; } From 93ad09144213fe6b9ce8bea7ebfcc2d60887810b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 21 Aug 2009 10:02:02 -0700 Subject: [PATCH 026/225] glamor: Add trapezoids code. This fixes segfaults on starting gnome-terminal. --- glamor/glamor.c | 2 ++ glamor/glamor_priv.h | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index ff31f5dba..05e05511b 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -199,6 +199,8 @@ glamor_init(ScreenPtr screen) #ifdef RENDER glamor_priv->saved_composite = ps->Composite; ps->Composite = glamor_composite; + glamor_priv->saved_trapezoids = ps->Trapezoids; + ps->Trapezoids = glamor_trapezoids; #endif glamor_init_solid_shader(screen); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index aee8e2d3e..e8f486f27 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -44,6 +44,7 @@ typedef struct glamor_screen_private { DestroyPixmapProcPtr saved_destroy_pixmap; GetSpansProcPtr saved_get_spans; CompositeProcPtr saved_composite; + TrapezoidsProcPtr saved_trapezoids; /* glamor_solid */ GLint solid_prog; @@ -149,6 +150,10 @@ void glamor_composite(CARD8 op, INT16 yDst, CARD16 width, CARD16 height); +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 */ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile, From f66e5c4145d003247447ac1bf93f9737c6eaa27c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 21 Aug 2009 10:05:32 -0700 Subject: [PATCH 027/225] glamor: Add 8bpp to get/setspans. --- glamor/glamor_core.c | 3 +++ glamor/glamor_getspans.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 5ecc894bb..ed6663e5c 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -218,6 +218,9 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, int i; switch (drawable->depth) { + case 8: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; case 24: case 32: format = GL_BGRA; diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 5853f9450..9a7066cb9 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -63,6 +63,9 @@ glamor_get_spans(DrawablePtr drawable, type = GL_UNSIGNED_BYTE; readpixels_dst = temp_dst; break; + case 8: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; case 24: format = GL_RGB; type = GL_UNSIGNED_BYTE; From 2b657d91d80a0a4d9fa2e390255ff87f51426b7c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 22 Aug 2009 15:54:24 -0700 Subject: [PATCH 028/225] glamor: Add untested putimage support. --- glamor/Makefile.am | 1 + glamor/glamor_core.c | 10 --- glamor/glamor_priv.h | 5 ++ glamor/glamor_putimage.c | 129 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 glamor/glamor_putimage.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 3f5a2002b..43512f720 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -19,6 +19,7 @@ libglamor_la_SOURCES = \ glamor_fill.c \ glamor_fillspans.c \ glamor_getspans.c \ + glamor_putimage.c \ glamor_render.c \ glamor_tile.c \ glamor.h diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index ed6663e5c..ba73c0bd2 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -199,16 +199,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, glamor_solid_fail_region(pixmap, x, y, width, height); } -static void -glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int leftPad, int format, char *bits) -{ - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - - ErrorF("stub put_image depth %d\n", drawable->depth); - glamor_solid_fail_region(pixmap, x, y, w, h); -} - static void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int n, int sorted) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index e8f486f27..74c1aea68 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -137,6 +137,11 @@ glamor_get_spans(DrawablePtr drawable, int nspans, char *dst_start); +/* 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); + /* glamor_render.c */ void glamor_composite(CARD8 op, PicturePtr pSrc, diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c new file mode 100644 index 000000000..2795d837e --- /dev/null +++ b/glamor/glamor_putimage.c @@ -0,0 +1,129 @@ +/* + * 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: + * Eric Anholt + * + */ + + +/** @file glamor_putaimge.c + * + * XPutImage implementation + */ +#include "glamor_priv.h" + +void +glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int left_pad, int image_format, char *bits) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + GLenum type, format; + RegionPtr clip; + BoxPtr pbox; + int nbox; + int bpp = drawable->bitsPerPixel; + int src_stride = PixmapBytePad(w, drawable->depth); + + if (gc->alu != GXcopy) { + ErrorF("putimage: non-copy alu\n"); + goto fail; + } + if (!glamor_pm_is_solid(drawable, gc->planemask)) { + ErrorF("putimage: non-solid planemask\n"); + goto fail; + } + if (image_format != ZPixmap) { + ErrorF("putimage: non-ZPixmap\n"); + goto fail; + } + if (bpp < 8) { + ErrorF("putimage: bad bpp: %d\n", bpp); + return; + } + + switch (drawable->depth) { + case 8: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + break; + case 24: + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("stub put_image depth %d\n", drawable->depth); + goto fail; + break; + } + + if (!glamor_set_destination_pixmap(pixmap)) { + fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, + image_format, bits); + goto fail; + } + + x += drawable->x; + y += drawable->y; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride / (bpp / 8)); + clip = fbGetCompositeClip(gc); + for (nbox = REGION_NUM_RECTS(clip), + pbox = REGION_RECTS(clip); + nbox--; + pbox++) + { + int x1 = x; + int y1 = y; + int x2 = x + w; + int y2 = y + h; + char *src; + + if (x1 < pbox->x1) + x1 = pbox->x1; + if (y1 < pbox->y1) + y1 = pbox->y1; + if (x2 > pbox->x2) + x2 = pbox->x2; + if (y2 > pbox->y2) + y2 = pbox->y2; + if (x1 >= x2 || y1 >= y2) + continue; + + src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); + glRasterPos2i(x1 + pixmap->screen_x, y1 + pixmap->screen_y); + glDrawPixels(x2 - x1, + y2 - y1, + format, type, + src); + } + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + return; + +fail: + glamor_solid_fail_region(pixmap, x, y, w, h); +} From e3c02c09c125bb5def1a70a1264ef34b18182afa Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 07:00:32 -0700 Subject: [PATCH 029/225] glamor: Add ALU support to solid, tile, and putimage. --- glamor/glamor_core.c | 61 ++++++++++++++++++++++++++++++++++++++++ glamor/glamor_fill.c | 2 ++ glamor/glamor_priv.h | 1 + glamor/glamor_putimage.c | 15 +++++----- glamor/glamor_tile.c | 6 ++-- 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index ba73c0bd2..055df399a 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -68,6 +68,67 @@ glamor_set_destination_pixmap(PixmapPtr pixmap) return TRUE; } +void +glamor_set_alu(unsigned char alu) +{ + if (alu == GXcopy) { + glDisable(GL_LOGIC_OP); + return; + } + + glEnable(GL_LOGIC_OP); + + switch (alu) { + case GXclear: + glLogicOp(GL_CLEAR); + break; + case GXand: + glLogicOp(GL_AND); + break; + case GXandReverse: + glLogicOp(GL_AND_REVERSE); + break; + case GXandInverted: + glLogicOp(GL_AND_INVERTED); + break; + case GXnoop: + glLogicOp(GL_NOOP); + break; + case GXxor: + glLogicOp(GL_XOR); + break; + case GXor: + glLogicOp(GL_OR); + break; + case GXnor: + glLogicOp(GL_NOR); + break; + case GXequiv: + glLogicOp(GL_EQUIV); + break; + case GXinvert: + glLogicOp(GL_INVERT); + break; + case GXorReverse: + glLogicOp(GL_OR_REVERSE); + break; + case GXcopyInverted: + glLogicOp(GL_COPY_INVERTED); + break; + case GXorInverted: + glLogicOp(GL_OR_INVERTED); + break; + case GXnand: + glLogicOp(GL_NAND); + break; + case GXset: + glLogicOp(GL_SET); + break; + default: + FatalError("unknown logic op\n"); + } +} + void glamor_get_transform_uniform_locations(GLint prog, glamor_transform_uniforms *uniform_locations) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 11d5f9841..f387dab62 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -153,6 +153,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, if (!glamor_set_destination_pixmap(pixmap)) return; + glamor_set_alu(alu); glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color); @@ -167,6 +168,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glEnd(); glUseProgramObjectARB(0); + glamor_set_alu(GXcopy); } /* Highlight places where we're doing it wrong. */ diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 74c1aea68..6484c9495 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -100,6 +100,7 @@ void glamor_link_glsl_prog(GLint prog); void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, GLfloat *color); Bool glamor_set_destination_pixmap(PixmapPtr pixmap); +void glamor_set_alu(unsigned char alu); void glamor_get_transform_uniform_locations(GLint prog, glamor_transform_uniforms *uniform_locations); void glamor_set_transform_for_pixmap(PixmapPtr pixmap, diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 2795d837e..f1a4e947a 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -44,10 +44,12 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int bpp = drawable->bitsPerPixel; int src_stride = PixmapBytePad(w, drawable->depth); - if (gc->alu != GXcopy) { - ErrorF("putimage: non-copy alu\n"); - goto fail; + if (!glamor_set_destination_pixmap(pixmap)) { + fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, + image_format, bits); + return; } + if (!glamor_pm_is_solid(drawable, gc->planemask)) { ErrorF("putimage: non-solid planemask\n"); goto fail; @@ -80,11 +82,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, break; } - if (!glamor_set_destination_pixmap(pixmap)) { - fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, - image_format, bits); - goto fail; - } + glamor_set_alu(gc->alu); x += drawable->x; y += drawable->y; @@ -122,6 +120,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, src); } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glamor_set_alu(GXcopy); return; fail: diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index d47644297..c33b3c1a6 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -109,15 +109,12 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, ErrorF("Non-FBO tile pixmap\n"); goto fail; } - if (alu != GXcopy) { - ErrorF("tile alu\n"); - goto fail; - } if (!glamor_pm_is_solid(&pixmap->drawable, planemask)) { ErrorF("tile pm\n"); goto fail; } + glamor_set_alu(alu); glUseProgramObjectARB(glamor_priv->tile_prog); glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform); @@ -143,6 +140,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glUseProgramObjectARB(0); glDisable(GL_TEXTURE_2D); + glamor_set_alu(GXcopy); return; fail: From cfb8dea815086b9aafd27bd314e02739e04dfc7d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 07:22:14 -0700 Subject: [PATCH 030/225] glamor: Hook up miGetImage to fix some invalid accesses. --- glamor/glamor.c | 3 +++ glamor/glamor_priv.h | 1 + 2 files changed, 4 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index 05e05511b..a03274a54 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -196,6 +196,9 @@ glamor_init(ScreenPtr screen) glamor_priv->saved_get_spans = screen->GetSpans; screen->GetSpans = glamor_get_spans; + glamor_priv->saved_get_image = screen->GetImage; + screen->GetImage = miGetImage; + #ifdef RENDER glamor_priv->saved_composite = ps->Composite; ps->Composite = glamor_composite; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 6484c9495..5d47c2590 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -43,6 +43,7 @@ typedef struct glamor_screen_private { CreatePixmapProcPtr saved_create_pixmap; DestroyPixmapProcPtr saved_destroy_pixmap; GetSpansProcPtr saved_get_spans; + GetImageProcPtr saved_get_image; CompositeProcPtr saved_composite; TrapezoidsProcPtr saved_trapezoids; From cdb1fe6d9682616b1def52fa38b2dae623e2503f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 08:03:17 -0700 Subject: [PATCH 031/225] glamor: Move setspans to a separate file. --- glamor/Makefile.am | 1 + glamor/glamor_core.c | 35 --------------------- glamor/glamor_priv.h | 4 +++ glamor/glamor_setspans.c | 67 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 35 deletions(-) create mode 100644 glamor/glamor_setspans.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 43512f720..098aa37c0 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -20,6 +20,7 @@ libglamor_la_SOURCES = \ glamor_fillspans.c \ glamor_getspans.c \ glamor_putimage.c \ + glamor_setspans.c \ glamor_render.c \ glamor_tile.c \ glamor.h diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 055df399a..38829de99 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -260,41 +260,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, glamor_solid_fail_region(pixmap, x, y, width, height); } -static void -glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, - DDXPointPtr points, int *widths, int n, int sorted) -{ - PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); - GLenum format, type; - int i; - - switch (drawable->depth) { - case 8: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - case 24: - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - ErrorF("Unknown setspans depth %d\n", drawable->depth); - return; - } - - if (!glamor_set_destination_pixmap(dest_pixmap)) - return; - for (i = 0; i < n; i++) { - glRasterPos2i(points[i].x - dest_pixmap->screen_x, - points[i].y - dest_pixmap->screen_y); - glDrawPixels(widths[i], - 1, - format, type, - src); - src += PixmapBytePad(widths[i], drawable->depth); - } -} - /** * glamor_poly_lines() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 5d47c2590..3929819e8 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -139,6 +139,10 @@ glamor_get_spans(DrawablePtr drawable, int nspans, char *dst_start); +/* glamor_setspans.c */ +void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, + DDXPointPtr points, int *widths, int n, int sorted); + /* glamor_putimage.c */ void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c new file mode 100644 index 000000000..bf9c50818 --- /dev/null +++ b/glamor/glamor_setspans.c @@ -0,0 +1,67 @@ +/* + * 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: + * Eric Anholt + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +void +glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, + DDXPointPtr points, int *widths, int n, int sorted) +{ + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + GLenum format, type; + int i; + + switch (drawable->depth) { + case 8: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + case 24: + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown setspans depth %d\n", drawable->depth); + return; + } + + if (!glamor_set_destination_pixmap(dest_pixmap)) + return; + for (i = 0; i < n; i++) { + glRasterPos2i(points[i].x - dest_pixmap->screen_x, + points[i].y - dest_pixmap->screen_y); + glDrawPixels(widths[i], + 1, + format, type, + src); + src += PixmapBytePad(widths[i], drawable->depth); + } +} From 0360ba361a67f6cfa5c9c65590ed8440a153c16e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 08:06:57 -0700 Subject: [PATCH 032/225] glamor: Fix memory leak in getspans. --- glamor/glamor_getspans.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 9a7066cb9..21ba9f095 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -58,7 +58,7 @@ glamor_get_spans(DrawablePtr drawable, switch (drawable->depth) { case 1: - temp_dst = xalloc(4 * wmax); + temp_dst = xalloc(wmax); format = GL_ALPHA; type = GL_UNSIGNED_BYTE; readpixels_dst = temp_dst; @@ -100,4 +100,5 @@ glamor_get_spans(DrawablePtr drawable, readpixels_dst += PixmapBytePad(widths[i], drawable->depth); } } + xfree(temp_dst); } From d9eef95c74b7b04a3398b4cfc1a81b480838b25e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 08:17:06 -0700 Subject: [PATCH 033/225] glamor: Fix bad fallthrough in getspans (accessing invalid memory). --- glamor/glamor_getspans.c | 1 + 1 file changed, 1 insertion(+) diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 21ba9f095..76c6cceef 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -66,6 +66,7 @@ glamor_get_spans(DrawablePtr drawable, case 8: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; + break; case 24: format = GL_RGB; type = GL_UNSIGNED_BYTE; From c70ce72fd74354a0b9731dc8d4451f6aaf951117 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 08:24:54 -0700 Subject: [PATCH 034/225] glamor: Give setspans the same format support as getspans. --- glamor/glamor_setspans.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index bf9c50818..48168a937 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -37,13 +37,30 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, { PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; - int i; + uint8_t *temp_src = NULL, *drawpixels_src = (uint8_t *)src; + int i, j; + int wmax = 0; + + for (i = 0 ; i < n; i++) { + if (wmax < widths[i]) + wmax = widths[i]; + } switch (drawable->depth) { + case 1: + temp_src = xalloc(wmax); + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + drawpixels_src = temp_src; + break; case 8: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; + break; case 24: + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -56,12 +73,26 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, if (!glamor_set_destination_pixmap(dest_pixmap)) return; for (i = 0; i < n; i++) { + if (temp_src) { + for (j = 0; j < widths[i]; j++) { + if (src[j / 8] & (1 << (j % 8))) + temp_src[j] = 0xff; + else + temp_src[j] = 0; + } + } + glRasterPos2i(points[i].x - dest_pixmap->screen_x, points[i].y - dest_pixmap->screen_y); glDrawPixels(widths[i], 1, format, type, - src); - src += PixmapBytePad(widths[i], drawable->depth); + drawpixels_src); + if (temp_src) { + src += PixmapBytePad(widths[i], drawable->depth); + } else { + drawpixels_src += PixmapBytePad(widths[i], drawable->depth); + } } + xfree(temp_src); } From 882411bef1091f97f61ae27a549970d87eef9cab Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 08:29:30 -0700 Subject: [PATCH 035/225] glamor: add alu support to setspans. --- glamor/glamor_setspans.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 48168a937..f81551ad0 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -72,6 +72,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, if (!glamor_set_destination_pixmap(dest_pixmap)) return; + glamor_set_alu(gc->alu); for (i = 0; i < n; i++) { if (temp_src) { for (j = 0; j < widths[i]; j++) { @@ -94,5 +95,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, drawpixels_src += PixmapBytePad(widths[i], drawable->depth); } } + glamor_set_alu(GXcopy); xfree(temp_src); } From 44e4599b83cc330a7c9edd7e18266f222a69418a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 08:59:52 -0700 Subject: [PATCH 036/225] glamor: Move planemask to a function in case I decide to fill it in. --- glamor/glamor_core.c | 11 +++++++++++ glamor/glamor_fill.c | 3 +++ glamor/glamor_priv.h | 1 + glamor/glamor_putimage.c | 8 ++++---- glamor/glamor_setspans.c | 8 +++++++- glamor/glamor_tile.c | 6 ++---- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 38829de99..58cb35716 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -68,6 +68,17 @@ glamor_set_destination_pixmap(PixmapPtr pixmap) return TRUE; } +Bool +glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask) +{ + if (glamor_pm_is_solid(&pixmap->drawable, planemask)) { + return GL_TRUE; + } + + ErrorF("unsupported planemask\n"); + return GL_FALSE; +} + void glamor_set_alu(unsigned char alu) { diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index f387dab62..6290f1210 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -154,6 +154,8 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, if (!glamor_set_destination_pixmap(pixmap)) return; glamor_set_alu(alu); + if (!glamor_set_planemask(pixmap, planemask)) + goto fail; glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color); @@ -168,6 +170,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glEnd(); glUseProgramObjectARB(0); +fail: glamor_set_alu(GXcopy); } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 3929819e8..d054372b4 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -102,6 +102,7 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, GLfloat *color); Bool glamor_set_destination_pixmap(PixmapPtr pixmap); void glamor_set_alu(unsigned char alu); +Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); void glamor_get_transform_uniform_locations(GLint prog, glamor_transform_uniforms *uniform_locations); void glamor_set_transform_for_pixmap(PixmapPtr pixmap, diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index f1a4e947a..36f5c85d7 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -50,17 +50,15 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, return; } - if (!glamor_pm_is_solid(drawable, gc->planemask)) { - ErrorF("putimage: non-solid planemask\n"); + if (!glamor_set_planemask(pixmap, gc->planemask)) goto fail; - } if (image_format != ZPixmap) { ErrorF("putimage: non-ZPixmap\n"); goto fail; } if (bpp < 8) { ErrorF("putimage: bad bpp: %d\n", bpp); - return; + goto fail; } switch (drawable->depth) { @@ -121,8 +119,10 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glamor_set_alu(GXcopy); + glamor_set_planemask(pixmap, ~0); return; fail: + glamor_set_planemask(pixmap, ~0); glamor_solid_fail_region(pixmap, x, y, w, h); } diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index f81551ad0..65471e916 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -71,8 +71,12 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, } if (!glamor_set_destination_pixmap(dest_pixmap)) - return; + goto fail; + if (!glamor_set_planemask(dest_pixmap, gc->planemask)) + goto fail; glamor_set_alu(gc->alu); + if (!glamor_set_planemask(dest_pixmap, gc->planemask)) + goto fail; for (i = 0; i < n; i++) { if (temp_src) { for (j = 0; j < widths[i]; j++) { @@ -95,6 +99,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, drawpixels_src += PixmapBytePad(widths[i], drawable->depth); } } +fail: + glamor_set_planemask(dest_pixmap, ~0); glamor_set_alu(GXcopy); xfree(temp_src); } diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index c33b3c1a6..cb1fe2d68 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -109,11 +109,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, ErrorF("Non-FBO tile pixmap\n"); goto fail; } - if (!glamor_pm_is_solid(&pixmap->drawable, planemask)) { - ErrorF("tile pm\n"); + if (!glamor_set_planemask(pixmap, planemask)) goto fail; - } - glamor_set_alu(alu); glUseProgramObjectARB(glamor_priv->tile_prog); glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform); @@ -141,6 +138,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glUseProgramObjectARB(0); glDisable(GL_TEXTURE_2D); glamor_set_alu(GXcopy); + glamor_set_planemask(pixmap, ~0); return; fail: From 5fadea5d9c02670c35ddf3e0f12f9d355b412103 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 09:10:14 -0700 Subject: [PATCH 037/225] glamor: Fix some screen_xy offsets to be the right way around. --- glamor/glamor_putimage.c | 2 +- glamor/glamor_tile.c | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 36f5c85d7..a0b8635dd 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -111,7 +111,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, continue; src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); - glRasterPos2i(x1 + pixmap->screen_x, y1 + pixmap->screen_y); + glRasterPos2i(x1 - pixmap->screen_x, y1 - pixmap->screen_y); glDrawPixels(x2 - x1, y2 - y1, format, type, diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index cb1fe2d68..517dbd3ea 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -92,10 +92,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int x2 = x + width; int y1 = y; int y2 = y + height; - int tile_x1 = tile_x + tile->screen_x; - int tile_x2 = tile_x + tile->screen_x + width; - int tile_y1 = tile_y + tile->screen_y; - int tile_y2 = tile_y + tile->screen_y + height; + int tile_x1 = tile_x - tile->screen_x; + int tile_x2 = tile_x - tile->screen_x + width; + int tile_y1 = tile_y - tile->screen_y; + int tile_y2 = tile_y - tile->screen_y + height; glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile); if (glamor_priv->tile_prog == 0) { @@ -121,9 +121,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); - tile_x += tile->screen_x; - tile_y += tile->screen_y; - glBegin(GL_TRIANGLE_FAN); glMultiTexCoord2f(0, tile_x1, tile_y1); glVertex2f(x1, y1); From 4a51cc0440c8d026fd8c82b40cfb188c6ea4a9f0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Aug 2009 09:14:20 -0700 Subject: [PATCH 038/225] glamor: Add clipping to setspans. --- glamor/glamor_setspans.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 65471e916..66ec3dafd 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -40,6 +40,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, uint8_t *temp_src = NULL, *drawpixels_src = (uint8_t *)src; int i, j; int wmax = 0; + RegionPtr clip = fbGetCompositeClip(gc); + BoxRec *pbox; for (i = 0 ; i < n; i++) { if (wmax < widths[i]) @@ -87,12 +89,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, } } - glRasterPos2i(points[i].x - dest_pixmap->screen_x, - points[i].y - dest_pixmap->screen_y); - glDrawPixels(widths[i], - 1, - format, type, - drawpixels_src); + n = REGION_NUM_RECTS(clip); + pbox = REGION_RECTS(clip); + while (n--) { + if (pbox->y1 > points[i].y) + break; + glScissor(pbox->x1, + points[i].y - dest_pixmap->screen_y, + pbox->x2 - pbox->x1, + 1); + glEnable(GL_SCISSOR_TEST); + glRasterPos2i(points[i].x - dest_pixmap->screen_x, + points[i].y - dest_pixmap->screen_y); + glDrawPixels(widths[i], + 1, + format, type, + drawpixels_src); + } if (temp_src) { src += PixmapBytePad(widths[i], drawable->depth); } else { @@ -100,6 +113,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, } } fail: + glDisable(GL_SCISSOR_TEST); glamor_set_planemask(dest_pixmap, ~0); glamor_set_alu(GXcopy); xfree(temp_src); From aa133069745fc59bb2f212b0816add9bae40c376 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 25 Aug 2009 12:10:32 -0700 Subject: [PATCH 039/225] glamor: Start adding render acceleration support. This brings in idr's glu3 code. We'll probably want to move to linking to it as a library, once an ABI-stable release is out. --- configure.ac | 1 + glamor/Makefile.am | 4 + glamor/glamor.c | 1 + glamor/glamor_priv.h | 16 + glamor/glamor_render.c | 620 ++++++++++++++++++++++++++++++++++++++ glamor/glu3/Makefile.am | 15 + glamor/glu3/glu3.h | 192 ++++++++++++ glamor/glu3/glu3_scalar.h | 388 ++++++++++++++++++++++++ glamor/glu3/matrix.c | 217 +++++++++++++ 9 files changed, 1454 insertions(+) create mode 100644 glamor/glamor_render.c create mode 100644 glamor/glu3/Makefile.am create mode 100644 glamor/glu3/glu3.h create mode 100644 glamor/glu3/glu3_scalar.h create mode 100644 glamor/glu3/matrix.c diff --git a/configure.ac b/configure.ac index 3954ecc06..7a8e507e7 100644 --- a/configure.ac +++ b/configure.ac @@ -2147,6 +2147,7 @@ Xi/Makefile xfixes/Makefile exa/Makefile glamor/Makefile +glamor/glu3/Makefile hw/Makefile hw/xfree86/Makefile hw/xfree86/common/Makefile diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 098aa37c0..4d307fe7a 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -4,6 +4,8 @@ noinst_LTLIBRARIES = libglamor.la # built (in hw/xfree86/os-support/solaris) until after glamor is built SOLARIS_ASM_CFLAGS="" +SUBDIRS = glu3 + if XORG sdk_HEADERS = glamor.h endif @@ -24,3 +26,5 @@ libglamor_la_SOURCES = \ glamor_render.c \ glamor_tile.c \ glamor.h +libglamor_la_LIBADD = \ + glu3/libglu3.la diff --git a/glamor/glamor.c b/glamor/glamor.c index a03274a54..43e1c7d3a 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -208,6 +208,7 @@ glamor_init(ScreenPtr screen) glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); + glamor_init_composite_shaders(screen); return TRUE; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index d054372b4..864be51ab 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -38,6 +38,13 @@ typedef struct glamor_transform_uniforms { GLint y_scale; } glamor_transform_uniforms; +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; +} glamor_composite_shader; + typedef struct glamor_screen_private { CreateGCProcPtr saved_create_gc; CreatePixmapProcPtr saved_create_pixmap; @@ -52,8 +59,12 @@ typedef struct glamor_screen_private { GLint solid_color_uniform_location; glamor_transform_uniforms solid_transform; + /* glamor_tile */ GLint tile_prog; glamor_transform_uniforms tile_transform; + + /* glamor_composite */ + glamor_composite_shader composite_shader[2]; } glamor_screen_private; typedef struct glamor_pixmap_private { @@ -75,6 +86,10 @@ glamor_get_pixmap_private(PixmapPtr pixmap) return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); } +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + /** * Returns TRUE if the given planemask covers all the significant bits in the * pixel values for pDrawable. @@ -166,6 +181,7 @@ void glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps); +void glamor_init_composite_shaders(ScreenPtr screen); /* glamor_tile.c */ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile, diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c new file mode 100644 index 000000000..d0c955792 --- /dev/null +++ b/glamor/glamor_render.c @@ -0,0 +1,620 @@ +/* + * 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: + * Eric Anholt + * + */ + + +/** @file glamor_render.c + * + * Render acceleration implementation + */ + +#include "glamor_priv.h" + +#ifdef RENDER +#include "mipict.h" + +#include "glu3/glu3.h" + +struct shader_key { + Bool has_mask; +}; + +struct blendinfo { + Bool dest_alpha; + Bool source_alpha; + GLenum source_blend; + GLenum dest_blend; +}; + +static struct blendinfo composite_op_info[] = { + [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, + [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, + [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, + [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, + [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, + [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, + [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, + [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, + [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, +}; + +#define HAS_MASK_INDEX 1 + +static glamor_composite_shader * +glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + int index = 0; + + if (key->has_mask) + index += HAS_MASK_INDEX; + + assert(index < ARRAY_SIZE(glamor_priv->composite_shader)); + + return &glamor_priv->composite_shader[index]; +} + +static GLuint +glamor_create_composite_fs(struct shader_key *key) +{ + const char *header = + "uniform sampler2D source_sampler;\n" + "varying vec4 source_coords;\n"; + const char *mask_header = + "uniform sampler2D mask_sampler;\n" + "varying vec4 mask_coords;\n"; + const char *main_opening = + "void main()\n" + "{\n" + " vec4 result;\n" + " result = texture2DProj(source_sampler, source_coords.xyw);\n"; + const char *source_in_mask = + " vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n" + " result = result * mask.w;\n"; + const char *main_closing = + " gl_FragColor = result;\n" + "}\n"; + char *source; + GLuint prog; + + source = XNFprintf("%s%s%s%s%s", + header, + key->has_mask ? mask_header : "", + main_opening, + key->has_mask ? source_in_mask : "", + main_closing); + + prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); + xfree(source); + + return prog; +} + +static GLuint +glamor_create_composite_vs(struct shader_key *key) +{ + const char *header = + "uniform mat4 dest_to_dest;\n" + "uniform mat4 dest_to_source;\n" + "varying vec4 source_coords;\n"; + const char *mask_header = + "uniform mat4 dest_to_mask;\n" + "varying vec4 mask_coords;\n"; + const char *main_opening = + "void main()\n" + "{\n" + " vec4 incoming_dest_coords = vec4(gl_Vertex.xy, 0, 1);\n" + " gl_Position = dest_to_dest * incoming_dest_coords;\n" + " source_coords = dest_to_source * incoming_dest_coords;\n"; + const char *mask_coords = + " mask_coords = dest_to_mask * incoming_dest_coords;\n"; + const char *main_closing = + "}\n"; + char *source; + GLuint prog; + + source = XNFprintf("%s%s%s%s%s", + header, + key->has_mask ? mask_header : "", + main_opening, + key->has_mask ? mask_coords : "", + main_closing); + + prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source); + xfree(source); + + return prog; +} + +static void +glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) +{ + GLuint vs, fs, prog; + GLint source_sampler_uniform_location, mask_sampler_uniform_location; + glamor_composite_shader *shader; + + shader = glamor_lookup_composite_shader(screen, key); + + vs = glamor_create_composite_vs(key); + if (vs == 0) + return; + fs = glamor_create_composite_fs(key); + if (fs == 0) + return; + + prog = glCreateProgramObjectARB(); + glAttachObjectARB(prog, vs); + glAttachObjectARB(prog, fs); + glamor_link_glsl_prog(prog); + + shader->prog = prog; + + glUseProgramObjectARB(prog); + source_sampler_uniform_location = glGetUniformLocationARB(prog, + "source_sampler"); + shader->dest_to_dest_uniform_location = + glGetUniformLocationARB(prog, "dest_to_dest"); + shader->dest_to_source_uniform_location = + glGetUniformLocationARB(prog, "dest_to_source"); + glUniform1i(source_sampler_uniform_location, 0); + + if (key->has_mask) { + mask_sampler_uniform_location = glGetUniformLocationARB(prog, + "mask_sampler"); + glUniform1i(mask_sampler_uniform_location, 1); + shader->dest_to_mask_uniform_location = + glGetUniformLocationARB(prog, "dest_to_mask"); + } +} + +void +glamor_init_composite_shaders(ScreenPtr screen) +{ + struct shader_key key; + + key.has_mask = FALSE; + glamor_create_composite_shader(screen, &key); + key.has_mask = TRUE; + glamor_create_composite_shader(screen, &key); +} + +static void +glamor_set_composite_transform_matrix(GLUmat4 *m, + PicturePtr picture, + float x_source, + float y_source) +{ + GLUmat4 temp; + DrawablePtr drawable = picture->pDrawable; + GLUvec4 scale = {{1.0f / drawable->width, + 1.0f / drawable->height, + 1.0, + 1.0}}; + + gluTranslate3f(m, -x_source, -y_source, 0.0); + gluScale4v(&temp, &scale); + gluMult4m_4m(m, &temp, m); +} + +static Bool +glamor_set_composite_op(ScreenPtr screen, + CARD8 op, PicturePtr dest, PicturePtr mask) +{ + GLenum source_blend, dest_blend; + struct blendinfo *op_info; + + if (op >= ARRAY_SIZE(composite_op_info)) { + ErrorF("unsupported render op\n"); + return GL_FALSE; + } + op_info = &composite_op_info[op]; + + source_blend = op_info->source_blend; + dest_blend = op_info->dest_blend; + + if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 && + op_info->source_alpha && source_blend != GL_ZERO) { + } + + /* If there's no dst alpha channel, adjust the blend op so that we'll treat + * it as always 1. + */ + if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) { + if (source_blend == GL_DST_ALPHA) + source_blend = GL_ONE; + else if (source_blend == GL_ONE_MINUS_DST_ALPHA) + source_blend = GL_ZERO; + } + + /* Set up the source alpha value for blending in component alpha mode. */ + if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 && + op_info->source_alpha) { + if (source_blend != GL_ZERO) { + ErrorF("Dual-source composite blending not supported\n"); + return GL_FALSE; + } + if (dest_blend == GL_SRC_ALPHA) + dest_blend = GL_SRC_COLOR; + else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA) + dest_blend = GL_ONE_MINUS_SRC_COLOR; + } + + if (source_blend == GL_ONE && dest_blend == GL_ZERO) { + glDisable(GL_BLEND); + } else { + glEnable(GL_BLEND); + glBlendFunc(source_blend, dest_blend); + } + return TRUE; +} + +static void +glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, + glamor_pixmap_private *pixmap_priv) +{ + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + switch (picture->repeatType) { + case RepeatNone: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + break; + case RepeatNormal: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case RepeatPad: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + break; + case RepeatReflect: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + break; + } + + switch (picture->filter) { + case PictFilterNearest: + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case PictFilterBilinear: + default: + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + } + + glEnable(GL_TEXTURE_2D); +} + +void +glamor_composite(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, + INT16 y_dest, + CARD16 width, + CARD16 height) +{ + ScreenPtr screen = dest->pDrawable->pScreen; + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); + PixmapPtr source_pixmap, mask_pixmap = NULL; + glamor_pixmap_private *source_pixmap_priv, *mask_pixmap_priv = NULL; + struct shader_key key; + glamor_composite_shader *shader; + GLUmat4 dest_to_dest, dest_to_source, dest_to_mask; + RegionRec region; + int i; + + /* Do two-pass PictOpOver componentAlpha, until we enable + * dual source color blending. + */ + if (mask && mask->componentAlpha && op == PictOpOver) { + glamor_composite(PictOpOutReverse, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + glamor_composite(PictOpAdd, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + return; + } + + key.has_mask = (mask != NULL); + if (!source->pDrawable) { + ErrorF("source-only source\n"); + goto fail; + } + if (mask && !mask->pDrawable) { + ErrorF("source-only mask\n"); + goto fail; + } + if (source->alphaMap) { + ErrorF("source alphaMap\n"); + goto fail; + } + if (mask && mask->alphaMap) { + ErrorF("mask alphaMap\n"); + goto fail; + } + + source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + if (source_pixmap == dest_pixmap) { + ErrorF("source == dest\n"); + goto fail; + } + if (!source_pixmap_priv || source_pixmap_priv->tex == 0) { + ErrorF("no FBO in source\n"); + goto fail; + } + if (mask) { + mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); + mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); + if (mask_pixmap == dest_pixmap) { + ErrorF("mask == dest\n"); + goto fail; + } + if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) { + ErrorF("no FBO in mask\n"); + goto fail; + } + } + + shader = glamor_lookup_composite_shader(screen, &key); + if (shader->prog == 0) { + ErrorF("No program compiled for this render accel mode\n"); + goto fail; + } + + glUseProgramObjectARB(shader->prog); + + if (!glamor_set_destination_pixmap(dest_pixmap)) + goto fail; + + if (!glamor_set_composite_op(screen, op, dest, mask)) { + goto fail; + } + + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + if (source->pDrawable) { + x_source += source->pDrawable->x; + y_source += source->pDrawable->y; + } + if (mask && mask->pDrawable) { + x_mask += mask->pDrawable->x; + y_mask += mask->pDrawable->y; + } + + gluOrtho6f(&dest_to_dest, + dest_pixmap->screen_x, dest_pixmap->screen_x + width, + dest_pixmap->screen_y, dest_pixmap->screen_y + height, + -1, 1); + glUniformMatrix4fvARB(shader->dest_to_dest_uniform_location, 1, 0, + (float *)&dest_to_dest); + glamor_set_composite_transform_matrix(&dest_to_source, + source, + x_source - x_dest, + y_source - x_dest); + glUniformMatrix4fvARB(shader->dest_to_source_uniform_location, 1, 0, + (float *)&dest_to_source); + + if (mask) { + glamor_set_composite_transform_matrix(&dest_to_mask, + mask, + x_mask - x_dest, + y_mask - x_dest); + glUniformMatrix4fvARB(shader->dest_to_mask_uniform_location, 1, 0, + (float *)&dest_to_mask); + } + + glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); + if (mask) + glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); + + if (!miComputeCompositeRegion(®ion, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height)) + return; + + glBegin(GL_QUADS); + for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { + BoxPtr box = ®ION_RECTS(®ion)[i]; + glVertex2i(box->x1, box->y1); + glVertex2i(box->x2, box->y1); + glVertex2i(box->x2, box->y2); + glVertex2i(box->x1, box->y2); + } + glEnd(); + + glamor_set_composite_op(screen, PictOpSrc, dest, mask); + glUseProgramObjectARB(0); + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + + return; + +fail: + glamor_set_composite_op(screen, PictOpSrc, dest, mask); + glUseProgramObjectARB(0); + glamor_solid_fail_region(dest_pixmap, x_dest, y_dest, width, height); +} + + +/** + * Creates an appropriate picture to upload our alpha mask into (which + * we calculated in system memory) + */ +static PicturePtr +glamor_create_mask_picture(ScreenPtr screen, + PicturePtr dst, + PictFormatPtr pict_format, + CARD16 width, + CARD16 height) +{ + PixmapPtr pixmap; + PicturePtr picture; + int error; + + if (!pict_format) { + if (dst->polyEdge == PolyEdgeSharp) + pict_format = PictureMatchFormat(screen, 1, PICT_a1); + else + pict_format = PictureMatchFormat(screen, 8, PICT_a8); + if (!pict_format) + return 0; + } + + pixmap = screen->CreatePixmap(screen, width, height, + pict_format->depth, + 0); + if (!pixmap) + return 0; + picture = CreatePicture(0, &pixmap->drawable, pict_format, + 0, 0, serverClient, &error); + screen->DestroyPixmap(pixmap); + return picture; +} + +/** + * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid + * accumulation in system memory. + */ +void +glamor_trapezoids(CARD8 op, + PicturePtr src, PicturePtr dst, + PictFormatPtr mask_format, INT16 x_src, INT16 y_src, + int ntrap, xTrapezoid *traps) +{ + ScreenPtr screen = dst->pDrawable->pScreen; + BoxRec bounds; + PicturePtr picture; + INT16 x_dst, y_dst; + INT16 x_rel, y_rel; + int width, height, stride; + PixmapPtr pixmap; + GCPtr gc; + pixman_image_t *image; + + /* If a mask format wasn't provided, we get to choose, but behavior should + * be as if there was no temporary mask the traps were accumulated into. + */ + if (!mask_format) { + if (dst->polyEdge == PolyEdgeSharp) + mask_format = PictureMatchFormat(screen, 1, PICT_a1); + else + mask_format = PictureMatchFormat(screen, 8, PICT_a8); + for (; ntrap; ntrap--, traps++) + glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, + 1, traps); + return; + } + + miTrapezoidBounds(ntrap, traps, &bounds); + + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return; + + x_dst = traps[0].left.p1.x >> 16; + y_dst = traps[0].left.p1.y >> 16; + + width = bounds.x2 - bounds.x1; + height = bounds.y2 - bounds.y1; + stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8; + + picture = glamor_create_mask_picture(screen, dst, mask_format, + width, height); + if (!picture) + return; + + image = pixman_image_create_bits(picture->format, + width, height, + NULL, stride); + if (!image) { + FreePicture(picture, 0); + return; + } + + for (; ntrap; ntrap--, traps++) + pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, + -bounds.x1, -bounds.y1); + + pixmap = GetScratchPixmapHeader(screen, width, height, + mask_format->depth, + BitsPerPixel(mask_format->depth), + PixmapBytePad(width, mask_format->depth), + pixman_image_get_data(image)); + if (!pixmap) { + FreePicture(picture, 0); + pixman_image_unref(image); + return; + } + + gc = GetScratchGC(picture->pDrawable->depth, screen); + if (!gc) { + FreeScratchPixmapHeader(pixmap); + pixman_image_unref (image); + FreePicture(picture, 0); + return; + } + ValidateGC(picture->pDrawable, gc); + + gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable, + gc, 0, 0, width, height, 0, 0); + + FreeScratchGC(gc); + FreeScratchPixmapHeader(pixmap); + pixman_image_unref(image); + + x_rel = bounds.x1 + x_src - x_dst; + y_rel = bounds.y1 + y_src - y_dst; + CompositePicture(op, src, picture, dst, + x_rel, y_rel, + 0, 0, + bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + FreePicture(picture, 0); +} + +#endif /* RENDER */ diff --git a/glamor/glu3/Makefile.am b/glamor/glu3/Makefile.am new file mode 100644 index 000000000..7d141a7fc --- /dev/null +++ b/glamor/glu3/Makefile.am @@ -0,0 +1,15 @@ +noinst_LTLIBRARIES = libglu3.la + +# Override these since glu3 doesn't need them and the needed files aren't +# built (in hw/xfree86/os-support/solaris) until after glu3 is built +SOLARIS_ASM_CFLAGS="" + +INCLUDES = \ + $(XORG_INCS) + +AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) + +libglu3_la_SOURCES = \ + matrix.c \ + glu3.h \ + glu3_scalar.h diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h new file mode 100644 index 000000000..29dba380a --- /dev/null +++ b/glamor/glu3/glu3.h @@ -0,0 +1,192 @@ +/* + * Copyright © 2009 Ian D. Romanick + * + * 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. + */ + +#ifndef __glu3_h__ +#define __glu3_h__ + +#include + +#define GLU_VERSION_3_0 + +struct GLUmat4; + +struct GLUvec4 { + GLfloat values[4]; + +#ifdef __cplusplus + inline GLUvec4(void) + { + } + + inline GLUvec4(GLfloat x , GLfloat y, GLfloat z, GLfloat w) + { + values[0] = x; + values[1] = y; + values[2] = z; + values[3] = w; + } + + inline GLUvec4(const GLUvec4 &v) + { + values[0] = v.values[0]; + values[1] = v.values[1]; + values[2] = v.values[2]; + values[3] = v.values[3]; + } + + GLUvec4 operator *(const GLUmat4 &) const; + GLUvec4 operator *(const GLUvec4 &) const; + GLUvec4 operator *(GLfloat) const; + + GLUvec4 operator +(const GLUvec4 &) const; + GLUvec4 operator -(const GLUvec4 &) const; +#endif /* __cplusplus */ +}; + + +struct GLUmat4 { + struct GLUvec4 col[4]; + +#ifdef __cplusplus + inline GLUmat4(void) + { + } + + inline GLUmat4(const GLUvec4 & c0, const GLUvec4 & c1, + const GLUvec4 & c2, const GLUvec4 & c3) + { + col[0] = c0; + col[1] = c1; + col[2] = c2; + col[3] = c3; + } + + inline GLUmat4(const GLUmat4 &m) + { + col[0] = m.col[0]; + col[1] = m.col[1]; + col[2] = m.col[2]; + col[3] = m.col[3]; + } + + + GLUvec4 operator *(const GLUvec4 &) const; + GLUmat4 operator *(const GLUmat4 &) const; + GLUmat4 operator *(GLfloat) const; + + GLUmat4 operator +(const GLUmat4 &) const; + GLUmat4 operator -(const GLUmat4 &) const; +#endif /* __cplusplus */ +}; + +#define GLU_MAX_STACK_DEPTH 32 + +struct GLUmat4Stack { + struct GLUmat4 stack[GLU_MAX_STACK_DEPTH]; + unsigned top; + +#ifdef __cplusplus + GLUmat4Stack() : top(0) + { + /* empty */ + } +#endif /* __cplusplus */ +}; + +#ifndef __cplusplus +typedef struct GLUvec4 GLUvec4; +typedef struct GLUmat4 GLUmat4; +typedef struct GLUmat4Stack GLUmat4Stack; +#endif /* __cplusplus */ + + +#ifdef __cplusplus +extern "C" { +#endif + +GLfloat gluDot4_4v(const GLUvec4 *, const GLUvec4 *); +GLfloat gluDot3_4v(const GLUvec4 *, const GLUvec4 *); +GLfloat gluDot2_4v(const GLUvec4 *, const GLUvec4 *); + +void gluCross4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); +void gluNormalize4v(GLUvec4 *result, const GLUvec4 *); +GLfloat gluLength4v(const GLUvec4 *); +GLfloat gluLengthSqr4v(const GLUvec4 *); +void gluOuter4v(GLUmat4 *result, const GLUvec4 *, const GLUvec4 *); + + +void gluMult4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); +void gluDiv4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); +void gluAdd4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); +void gluSub4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); + +void gluMult4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); +void gluDiv4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); +void gluAdd4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); +void gluSub4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); + +void gluMult4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *); +void gluAdd4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *); +void gluSub4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *); +void gluMult4m_4v(GLUvec4 *result, const GLUmat4 *m, const GLUvec4 *v); + +void gluMult4m_f(GLUmat4 *result, const GLUmat4 *, GLfloat); + +void gluScale4v(GLUmat4 *result, const GLUvec4 *); +void gluTranslate3f(GLUmat4 *result, GLfloat x, GLfloat y, GLfloat z); +void gluTranslate4v(GLUmat4 *result, const GLUvec4 *); +void gluRotate4v(GLUmat4 *result, const GLUvec4 *axis, GLfloat angle); +void gluLookAt4v(GLUmat4 *result, const GLUvec4 *eye, const GLUvec4 *center, + const GLUvec4 *up); +void gluPerspective4f(GLUmat4 *result, GLfloat fovy, GLfloat aspect, + GLfloat near, GLfloat far); +void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m); +void gluFrustum6f(GLUmat4 *result, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat near, GLfloat far); +void gluOrtho6f(GLUmat4 *result, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat near, GLfloat far); + +extern const GLUmat4 gluIdentityMatrix; + +#ifdef __cplusplus +}; +#endif + +#ifdef __cplusplus +GLfloat gluDot4(const GLUvec4 &, const GLUvec4 &); +GLfloat gluDot3(const GLUvec4 &, const GLUvec4 &); +GLfloat gluDot2(const GLUvec4 &, const GLUvec4 &); + +GLUvec4 gluCross(const GLUvec4 &, const GLUvec4 &); +GLUvec4 gluNormalize(const GLUvec4 &); +GLfloat gluLength(const GLUvec4 &); +GLfloat gluLengthSqr(const GLUvec4 &); +#endif /* __cplusplus */ + +#include "glu3_scalar.h" + +#endif /* __glu3_h__ */ diff --git a/glamor/glu3/glu3_scalar.h b/glamor/glu3/glu3_scalar.h new file mode 100644 index 000000000..3e87b8cce --- /dev/null +++ b/glamor/glu3/glu3_scalar.h @@ -0,0 +1,388 @@ +/* + * Copyright © 2009 Ian D. Romanick + * + * 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. + */ + +#include +#include + +extern inline void gluMult4v_4v(GLUvec4 *result, + const GLUvec4 *v1, const GLUvec4 *v2) +{ + result->values[0] = v1->values[0] * v2->values[0]; + result->values[1] = v1->values[1] * v2->values[1]; + result->values[2] = v1->values[2] * v2->values[2]; + result->values[3] = v1->values[3] * v2->values[3]; +} + + +extern inline void gluDiv4v_4v(GLUvec4 *result, + const GLUvec4 *v1, const GLUvec4 *v2) +{ + result->values[0] = v1->values[0] / v2->values[0]; + result->values[1] = v1->values[1] / v2->values[1]; + result->values[2] = v1->values[2] / v2->values[2]; + result->values[3] = v1->values[3] / v2->values[3]; +} + + +extern inline void gluAdd4v_4v(GLUvec4 *result, + const GLUvec4 *v1, const GLUvec4 *v2) +{ + result->values[0] = v1->values[0] + v2->values[0]; + result->values[1] = v1->values[1] + v2->values[1]; + result->values[2] = v1->values[2] + v2->values[2]; + result->values[3] = v1->values[3] + v2->values[3]; +} + + +extern inline void gluSub4v_4v(GLUvec4 *result, + const GLUvec4 *v1, const GLUvec4 *v2) +{ + result->values[0] = v1->values[0] - v2->values[0]; + result->values[1] = v1->values[1] - v2->values[1]; + result->values[2] = v1->values[2] - v2->values[2]; + result->values[3] = v1->values[3] - v2->values[3]; +} + + +extern inline void gluMult4v_f(GLUvec4 *result, + const GLUvec4 *v1, GLfloat f) +{ + result->values[0] = v1->values[0] * f; + result->values[1] = v1->values[1] * f; + result->values[2] = v1->values[2] * f; + result->values[3] = v1->values[3] * f; +} + + +extern inline void gluDiv4v_f(GLUvec4 *result, + const GLUvec4 *v1, GLfloat f) +{ + result->values[0] = v1->values[0] / f; + result->values[1] = v1->values[1] / f; + result->values[2] = v1->values[2] / f; + result->values[3] = v1->values[3] / f; +} + + +extern inline void gluAdd4v_f(GLUvec4 *result, + const GLUvec4 *v1, GLfloat f) +{ + result->values[0] = v1->values[0] + f; + result->values[1] = v1->values[1] + f; + result->values[2] = v1->values[2] + f; + result->values[3] = v1->values[3] + f; +} + + +extern inline void gluSub4v_f(GLUvec4 *result, + const GLUvec4 *v1, GLfloat f) +{ + result->values[0] = v1->values[0] - f; + result->values[1] = v1->values[1] - f; + result->values[2] = v1->values[2] - f; + result->values[3] = v1->values[3] - f; +} + + +extern inline void gluMult4m_f(GLUmat4 *result, + const GLUmat4 *m, GLfloat f) +{ + GLUmat4 temp; + + gluMult4v_f(& temp.col[0], & m->col[0], f); + gluMult4v_f(& temp.col[1], & m->col[1], f); + gluMult4v_f(& temp.col[2], & m->col[2], f); + gluMult4v_f(& temp.col[3], & m->col[3], f); + *result = temp; +} + + +extern inline void gluMult4m_4v(GLUvec4 *result, + const GLUmat4 *m, const GLUvec4 *v) +{ + GLUvec4 temp[6]; + unsigned i; + + for (i = 0; i < 4; i++) { + gluMult4v_f(& temp[i], & m->col[i], v->values[i]); + } + + gluAdd4v_4v(& temp[4], & temp[0], & temp[1]); + gluAdd4v_4v(& temp[5], & temp[2], & temp[3]); + gluAdd4v_4v(result, & temp[4], & temp[5]); +} + + +extern inline void gluAdd4m_4m(GLUmat4 *result, + const GLUmat4 *m1, const GLUmat4 *m2) +{ + GLUmat4 temp; + + gluAdd4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]); + gluAdd4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]); + gluAdd4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]); + gluAdd4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]); + *result = temp; +} + +extern inline void gluSub4m_4m(GLUmat4 *result, + const GLUmat4 *m1, const GLUmat4 *m2) +{ + GLUmat4 temp; + + gluSub4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]); + gluSub4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]); + gluSub4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]); + gluSub4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]); + *result = temp; +} + +extern inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2) +{ + return v1->values[0] * v2->values[0] + + v1->values[1] * v2->values[1] + + v1->values[2] * v2->values[2] + + v1->values[3] * v2->values[3]; +} + + +extern inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2) +{ + return v1->values[0] * v2->values[0] + + v1->values[1] * v2->values[1] + + v1->values[2] * v2->values[2]; +} + + +extern inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2) +{ + return v1->values[0] * v2->values[0] + + v1->values[1] * v2->values[1]; +} + + +extern inline void gluCross4v(GLUvec4 *result, + const GLUvec4 *v1, const GLUvec4 *v2) +{ + GLUvec4 temp; + + temp.values[0] = (v1->values[1] * v2->values[2]) + - (v1->values[2] * v2->values[1]); + temp.values[1] = (v1->values[2] * v2->values[0]) + - (v1->values[0] * v2->values[2]); + temp.values[2] = (v1->values[0] * v2->values[1]) + - (v1->values[1] * v2->values[0]); + temp.values[3] = 0.0; + *result = temp; +} + + +extern inline void gluOuter4v(GLUmat4 *result, + const GLUvec4 *v1, const GLUvec4 *v2) +{ + GLUmat4 temp; + + gluMult4v_f(& temp.col[0], v1, v2->values[0]); + gluMult4v_f(& temp.col[1], v1, v2->values[1]); + gluMult4v_f(& temp.col[2], v1, v2->values[2]); + gluMult4v_f(& temp.col[3], v1, v2->values[3]); + *result = temp; +} + + +extern inline GLfloat gluLengthSqr4v(const GLUvec4 *v) +{ + return gluDot4_4v(v, v); +} + + +extern inline GLfloat gluLength4v(const GLUvec4 *v) +{ + return sqrt(gluLengthSqr4v(v)); +} + + +extern inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v) +{ + gluDiv4v_f(result, v, gluLength4v(v)); +} + + + +extern inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m) +{ + unsigned i; + unsigned j; + GLUmat4 temp; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + temp.col[i].values[j] = m->col[j].values[i]; + } + } + + *result = temp; +} + + +extern inline void gluMult4m_4m(GLUmat4 *result, + const GLUmat4 *m1, const GLUmat4 *m2) +{ + GLUmat4 temp; + unsigned i; + + for (i = 0; i < 4; i++) { + gluMult4m_4v(& temp.col[i], m1, & m2->col[i]); + } + + *result = temp; +} + + + +extern inline void gluTranslate3f(GLUmat4 *result, + GLfloat x, GLfloat y, GLfloat z) +{ + memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix)); + result->col[3].values[0] = x; + result->col[3].values[1] = y; + result->col[3].values[2] = z; +} + + +#ifdef __cplusplus +extern inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2) +{ + return v1.values[0] * v2.values[0] + + v1.values[1] * v2.values[1] + + v1.values[2] * v2.values[2] + + v1.values[3] * v2.values[3]; +} + + +extern inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2) +{ + return v1.values[0] * v2.values[0] + + v1.values[1] * v2.values[1] + + v1.values[2] * v2.values[2]; +} + + +extern inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2) +{ + return v1.values[0] * v2.values[0] + + v1.values[1] * v2.values[1]; +} + + +inline GLUvec4 GLUvec4::operator+(const GLUvec4 &v) const +{ + return GLUvec4(values[0] + v.values[0], + values[1] + v.values[1], + values[2] + v.values[2], + values[3] + v.values[3]); +} + + +inline GLUvec4 GLUvec4::operator-(const GLUvec4 &v) const +{ + return GLUvec4(values[0] - v.values[0], + values[1] - v.values[1], + values[2] - v.values[2], + values[3] - v.values[3]); +} + + +inline GLUvec4 GLUvec4::operator*(const GLUvec4 &v) const +{ + return GLUvec4(values[0] * v.values[0], + values[1] * v.values[1], + values[2] * v.values[2], + values[3] * v.values[3]); +} + + +inline GLUvec4 GLUvec4::operator*(GLfloat f) const +{ + return GLUvec4(values[0] * f, + values[1] * f, + values[2] * f, + values[3] * f); +} + + +inline GLUvec4 GLUvec4::operator*(const GLUmat4 &m) const +{ + return GLUvec4(gluDot4(*this, m.col[0]), + gluDot4(*this, m.col[1]), + gluDot4(*this, m.col[2]), + gluDot4(*this, m.col[3])); +} + + +inline GLUmat4 GLUmat4::operator+(const GLUmat4 &m) const +{ + GLUmat4 temp; + + gluAdd4m_4m(& temp, this, &m); + return temp; +} + + +inline GLUmat4 GLUmat4::operator-(const GLUmat4 &m) const +{ + return GLUmat4(col[0] - m.col[0], + col[1] - m.col[1], + col[2] - m.col[2], + col[3] - m.col[3]); +} + + +inline GLUmat4 GLUmat4::operator*(GLfloat f) const +{ + GLUmat4 temp; + + gluMult4m_f(& temp, this, f); + return temp; +} + + +inline GLUvec4 GLUmat4::operator*(const GLUvec4 &v) const +{ + return (col[0] * v.values[0]) + + (col[1] * v.values[1]) + + (col[2] * v.values[2]) + + (col[3] * v.values[3]); +} + + +inline GLUmat4 GLUmat4::operator*(const GLUmat4 &m) const +{ + GLUmat4 temp; + + gluMult4m_4m(& temp, this, &m); + return temp; +} + + +#endif /* __cplusplus */ diff --git a/glamor/glu3/matrix.c b/glamor/glu3/matrix.c new file mode 100644 index 000000000..b3d5819f7 --- /dev/null +++ b/glamor/glu3/matrix.c @@ -0,0 +1,217 @@ +/* + * Copyright © 2009 Ian D. Romanick + * + * 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. + */ + +#include +#include "glu3.h" + +#define DEG2RAD(d) ((d) * M_PI / 180.0) + +const GLUmat4 gluIdentityMatrix = { + { + { { 1.0f, 0.0f, 0.0f, 0.0f } }, + { { 0.0f, 1.0f, 0.0f, 0.0f } }, + { { 0.0f, 0.0f, 1.0f, 0.0f } }, + { { 0.0f, 0.0f, 0.0f, 1.0f } } + } +}; + + +void gluTranslate4v(GLUmat4 *result, const GLUvec4 *t) +{ + memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix)); + result->col[3] = *t; + result->col[3].values[3] = 1.0f; +} + + +void gluScale4v(GLUmat4 *result, const GLUvec4 *t) +{ + memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix)); + result->col[0].values[0] = t->values[0]; + result->col[1].values[1] = t->values[1]; + result->col[2].values[2] = t->values[2]; +} + + +void gluLookAt4v(GLUmat4 *result, + const GLUvec4 *_eye, + const GLUvec4 *_center, + const GLUvec4 *_up) +{ + static const GLUvec4 col3 = { { 0.0f, 0.0f, 0.0f, 1.0f } }; + const GLUvec4 e = { + { -_eye->values[0], -_eye->values[1], -_eye->values[2], 0.0f } + }; + GLUmat4 translate; + GLUmat4 rotate; + GLUmat4 rotateT; + GLUvec4 f; + GLUvec4 s; + GLUvec4 u; + GLUvec4 center, up; + + center = *_center; + center.values[3] = 0; + up = *_up; + up.values[3] = 0; + + gluAdd4v_4v(& f, ¢er, &e); + gluNormalize4v(& f, & f); + + gluNormalize4v(& u, &up); + + gluCross4v(& s, & f, & u); + gluCross4v(& u, & s, & f); + + rotate.col[0] = s; + rotate.col[1] = u; + rotate.col[2].values[0] = -f.values[0]; + rotate.col[2].values[1] = -f.values[1]; + rotate.col[2].values[2] = -f.values[2]; + rotate.col[2].values[3] = 0.0f; + rotate.col[3] = col3; + gluTranspose4m(& rotateT, & rotate); + + gluTranslate4v(& translate, & e); + gluMult4m_4m(result, & rotateT, & translate); +} + + +void gluRotate4v(GLUmat4 *result, const GLUvec4 *_axis, GLfloat angle) +{ + GLUvec4 axis; + const float c = cos(angle); + const float s = sin(angle); + const float one_c = 1.0 - c; + + float xx; + float yy; + float zz; + + float xs; + float ys; + float zs; + + float xy; + float xz; + float yz; + + /* Only normalize the 3-component axis. A gluNormalize3v might be + * appropriate to save us some computation. + */ + axis = *_axis; + axis.values[3] = 0; + gluNormalize4v(&axis, &axis); + + xx = axis.values[0] * axis.values[0]; + yy = axis.values[1] * axis.values[1]; + zz = axis.values[2] * axis.values[2]; + + xs = axis.values[0] * s; + ys = axis.values[1] * s; + zs = axis.values[2] * s; + + xy = axis.values[0] * axis.values[1]; + xz = axis.values[0] * axis.values[2]; + yz = axis.values[1] * axis.values[2]; + + + result->col[0].values[0] = (one_c * xx) + c; + result->col[0].values[1] = (one_c * xy) + zs; + result->col[0].values[2] = (one_c * xz) - ys; + result->col[0].values[3] = 0.0; + + result->col[1].values[0] = (one_c * xy) - zs; + result->col[1].values[1] = (one_c * yy) + c; + result->col[1].values[2] = (one_c * yz) + xs; + result->col[1].values[3] = 0.0; + + + result->col[2].values[0] = (one_c * xz) + ys; + result->col[2].values[1] = (one_c * yz) - xs; + result->col[2].values[2] = (one_c * zz) + c; + result->col[2].values[3] = 0.0; + + result->col[3].values[0] = 0.0; + result->col[3].values[1] = 0.0; + result->col[3].values[2] = 0.0; + result->col[3].values[3] = 1.0; +} + + +void +gluPerspective4f(GLUmat4 *result, + GLfloat fovy, GLfloat aspect, GLfloat near, GLfloat far) +{ + const double sine = sin(DEG2RAD(fovy / 2.0)); + const double cosine = cos(DEG2RAD(fovy / 2.0)); + const double sine_aspect = sine * aspect; + const double dz = far - near; + + + memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix)); + if ((sine == 0.0) || (dz == 0.0) || (sine_aspect == 0.0)) { + return; + } + + result->col[0].values[0] = cosine / sine_aspect; + result->col[1].values[1] = cosine / sine; + result->col[2].values[2] = -(far + near) / dz; + result->col[2].values[3] = -1.0; + result->col[3].values[2] = -2.0 * near * far / dz; + result->col[3].values[3] = 0.0; +} + +void gluFrustum6f(GLUmat4 *result, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat near, GLfloat far) +{ + memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix)); + + result->col[0].values[0] = (2.0 * near) / (right - left); + result->col[1].values[1] = (2.0 * near) / (top - bottom); + result->col[2].values[0] = (right + left) / (right - left); + result->col[2].values[1] = (top + bottom) / (top - bottom); + result->col[2].values[2] = -(far + near) / (far - near); + result->col[2].values[3] = -1.0; + result->col[3].values[2] = -2.0 * near * far / (far - near); + result->col[3].values[3] = 0.0; +} + +void gluOrtho6f(GLUmat4 *result, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat near, GLfloat far) +{ + memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix)); + + result->col[0].values[0] = 2.0f / (right - left); + result->col[3].values[0] = -(right + left) / (right - left); + + result->col[1].values[1] = 2.0f / (top - bottom); + result->col[3].values[1] = -(top + bottom) / (top - bottom); + + result->col[2].values[2] = -2.0f / (far - near); + result->col[3].values[2] = -(far + near) / (far - near); +} From 8a53566acb5870816807425dc805df888fa42792 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 25 Aug 2009 13:06:11 -0700 Subject: [PATCH 040/225] glamor: make the polylines complaint a little more useful. --- glamor/glamor_core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 58cb35716..addff1ac7 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -285,9 +285,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, int i; /* Don't try to do wide lines or non-solid fill style. */ - if (gc->lineWidth != 0 || gc->lineStyle != LineSolid || + if (gc->lineWidth != 0) { + ErrorF("stub wide polylines\n"); + return; + } + if (gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) { - ErrorF("stub poly_line depth %d\n", drawable->depth); + ErrorF("stub poly_line non-solid fill\n"); return; } From 854e9bd20a2d0f8ed636d4fba0ddfa4c71d54667 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 25 Aug 2009 16:56:50 -0700 Subject: [PATCH 041/225] glamor: Add untested PutImage XYBitmap support. --- glamor/glamor.c | 1 + glamor/glamor_priv.h | 7 ++ glamor/glamor_putimage.c | 202 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index 43e1c7d3a..71c8ab20f 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -208,6 +208,7 @@ glamor_init(ScreenPtr screen) glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); + glamor_init_putimage_shaders(screen); glamor_init_composite_shaders(screen); return TRUE; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 864be51ab..b5ba82d12 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -63,6 +63,12 @@ typedef struct glamor_screen_private { GLint tile_prog; glamor_transform_uniforms tile_transform; + /* glamor_putimage */ + GLint put_image_xybitmap_prog; + glamor_transform_uniforms put_image_xybitmap_transform; + GLint put_image_xybitmap_fg_uniform_location; + GLint put_image_xybitmap_bg_uniform_location; + /* glamor_composite */ glamor_composite_shader composite_shader[2]; } glamor_screen_private; @@ -163,6 +169,7 @@ void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, 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); /* glamor_render.c */ void glamor_composite(CARD8 op, diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index a0b8635dd..07052358c 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -32,6 +32,201 @@ */ #include "glamor_priv.h" +void +glamor_init_putimage_shaders(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + const char *xybitmap_vs = + "uniform float x_bias;\n" + "uniform float x_scale;\n" + "uniform float y_bias;\n" + "uniform float y_scale;\n" + "varying vec2 bitmap_coords;\n" + "void main()\n" + "{\n" + " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" + " (gl_Vertex.y + y_bias) * y_scale,\n" + " 0,\n" + " 1);\n" + " bitmap_coords = gl_MultiTexCoord0.xy;\n" + "}\n"; + const char *xybitmap_fs = + "uniform vec4 fg, bg;\n" + "varying vec2 bitmap_coords;\n" + "uniform sampler2D bitmap_sampler;\n" + "void main()\n" + "{\n" + " float bitmap_value = texture2D(bitmap_sampler,\n" + " bitmap_coords).x;\n" + " gl_FragColor = mix(bg, fg, bitmap_value);\n" + "}\n"; + GLint fs_prog, vs_prog, prog; + GLint sampler_uniform_location; + + if (!GLEW_ARB_fragment_shader) + return; + + prog = glCreateProgramObjectARB(); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, xybitmap_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, xybitmap_fs); + glAttachObjectARB(prog, vs_prog); + glAttachObjectARB(prog, fs_prog); + glamor_link_glsl_prog(prog); + + glUseProgramObjectARB(prog); + sampler_uniform_location = glGetUniformLocationARB(prog, "bitmap_sampler"); + glUniform1iARB(sampler_uniform_location, 0); + + glamor_priv->put_image_xybitmap_fg_uniform_location = + glGetUniformLocationARB(prog, "fg"); + glamor_priv->put_image_xybitmap_bg_uniform_location = + glGetUniformLocationARB(prog, "bg"); + glamor_get_transform_uniform_locations(prog, + &glamor_priv->put_image_xybitmap_transform); + glamor_priv->put_image_xybitmap_prog = prog; + glUseProgramObjectARB(0); +} + +static int +y_flip(PixmapPtr pixmap, int y) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap == screen_pixmap) + return (pixmap->drawable.height - 1) - y; + else + return y; +} + +/* Do an XYBitmap putimage. The bits are byte-aligned rows of bitmap + * data (where each row starts at a bit index of left_pad), and the + * destination gets filled with the gc's fg color where the bitmap is set + * and the bg color where the bitmap is unset. + * + * Implement this by passing the bitmap right through to GL, and sampling + * it to choose between fg and bg in the fragment shader. The driver may + * be exploding the bitmap up to be an 8-bit alpha texture, in which + * case we might be better off just doing the fg/bg choosing in the CPU + * and just draw the resulting texture to the destination. + */ +static void +glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, + int x, int y, int w, int h, int left_pad, + int image_format, char *bits) +{ + ScreenPtr screen = drawable->pScreen; + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + float fg[4], bg[4]; + GLuint tex; + unsigned int stride = PixmapBytePad(1, w + left_pad); + RegionPtr clip; + BoxPtr box; + int nbox; + float dest_coords[8] = { + x, y, + x + w, y, + x + w, y + h, + x, y + h, + }; + const float bitmap_coords[8] = { + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + }; + + if (glamor_priv->put_image_xybitmap_prog == 0) { + ErrorF("no program for xybitmap putimage\n"); + goto fail; + } + + glamor_set_alu(gc->alu); + if (!glamor_set_planemask(pixmap, gc->planemask)) + goto fail; + + glUseProgramObjectARB(glamor_priv->put_image_xybitmap_prog); + + glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); + glUniform4fvARB(glamor_priv->put_image_xybitmap_fg_uniform_location, + 1, fg); + glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); + glUniform4fvARB(glamor_priv->put_image_xybitmap_bg_uniform_location, + 1, bg); + + glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform); + + glGenTextures(1, &tex); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, + w, h, 0, + GL_COLOR_INDEX, GL_BITMAP, bits); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glEnable(GL_TEXTURE_2D); + + /* Now that we've set up our bitmap texture and the shader, shove + * the destination rectangle through the cliprects and run the + * shader on the resulting fragments. + */ + glVertexPointer(2, GL_FLOAT, 0, dest_coords); + glEnableClientState(GL_VERTEX_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnable(GL_SCISSOR_TEST); + clip = fbGetCompositeClip(gc); + for (nbox = REGION_NUM_RECTS(clip), + box = REGION_RECTS(clip); + nbox--; + box++) + { + int x1 = x; + int y1 = y; + int x2 = x + w; + int y2 = y + h; + + if (x1 < box->x1) + x1 = box->x1; + if (y1 < box->y1) + y1 = box->y1; + if (x2 > box->x2) + x2 = box->x2; + if (y2 > box->y2) + y2 = box->y2; + if (x1 >= x2 || y1 >= y2) + continue; + + glScissor(box->x1, + y_flip(pixmap, box->y1), + box->x2 - box->x1, + box->y2 - box->y1); + glDrawArrays(GL_QUADS, 0, 4); + } + + glDisable(GL_SCISSOR_TEST); + glamor_set_alu(GXcopy); + glamor_set_planemask(pixmap, ~0); + glDeleteTextures(1, &tex); + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + return; + +fail: + glamor_set_alu(GXcopy); + glamor_set_planemask(pixmap, ~0); + glamor_solid_fail_region(pixmap, x, y, w, h); +} + void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int left_pad, int image_format, char *bits) @@ -50,6 +245,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, return; } + if (image_format == XYBitmap) { + assert(depth == 1); + glamor_put_image_xybitmap(drawable, gc, x, y, w, h, + left_pad, image_format, bits); + return; + } + if (!glamor_set_planemask(pixmap, gc->planemask)) goto fail; if (image_format != ZPixmap) { From 6dacc9b08c2af51c1826c20ccf12bb2c73856f25 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 25 Aug 2009 17:01:43 -0700 Subject: [PATCH 042/225] glamor: Add untested PutImage 1bpp XYPixmap support. --- glamor/glamor_putimage.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 07052358c..55854daae 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -252,18 +252,21 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, return; } + if (bpp == 1 && image_format == XYPixmap) + image_format = ZPixmap; + if (!glamor_set_planemask(pixmap, gc->planemask)) goto fail; if (image_format != ZPixmap) { ErrorF("putimage: non-ZPixmap\n"); goto fail; } - if (bpp < 8) { - ErrorF("putimage: bad bpp: %d\n", bpp); - goto fail; - } switch (drawable->depth) { + case 1: + format = GL_COLOR_INDEX; + type = GL_BITMAP; + break; case 8: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; @@ -279,7 +282,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, default: ErrorF("stub put_image depth %d\n", drawable->depth); goto fail; - break; } glamor_set_alu(gc->alu); @@ -288,7 +290,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, y += drawable->y; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride / (bpp / 8)); + glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / bpp); + if (bpp == 1) + glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); clip = fbGetCompositeClip(gc); for (nbox = REGION_NUM_RECTS(clip), pbox = REGION_RECTS(clip); @@ -320,6 +324,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, src); } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); return; From 936385142c12d074dcb603490517ac095840fa3f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 25 Aug 2009 17:24:30 -0700 Subject: [PATCH 043/225] glamor: Accelerate PolyFillRect using glamor_fill instead of spans. --- glamor/Makefile.am | 1 + glamor/glamor_core.c | 2 +- glamor/glamor_polyfillrect.c | 118 +++++++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 7 +++ 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 glamor/glamor_polyfillrect.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 4d307fe7a..3035f6323 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -21,6 +21,7 @@ libglamor_la_SOURCES = \ glamor_fill.c \ glamor_fillspans.c \ glamor_getspans.c \ + glamor_polyfillrect.c \ glamor_putimage.c \ glamor_setspans.c \ glamor_render.c \ diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index addff1ac7..7b96d674a 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -352,7 +352,7 @@ GCOps glamor_gc_ops = { .PolyRectangle = miPolyRectangle, .PolyArc = miPolyArc, .FillPolygon = miFillPolygon, - .PolyFillRect = miPolyFillRect, + .PolyFillRect = glamor_poly_fill_rect, .PolyFillArc = miPolyFillArc, .PolyText8 = miPolyText8, .PolyText16 = miPolyText16, diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c new file mode 100644 index 000000000..ae8963dac --- /dev/null +++ b/glamor/glamor_polyfillrect.c @@ -0,0 +1,118 @@ +/* + * 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: + * Eric Anholt + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +/** @file glamor_fillspans.c + * + * GC PolyFillRect implementation, taken straight from fb_fill.c + */ + +void +glamor_poly_fill_rect(DrawablePtr drawable, + GCPtr gc, + int nrect, + xRectangle *prect) +{ + RegionPtr clip = fbGetCompositeClip(gc); + register BoxPtr box; + BoxPtr pextent; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1, fullY2; + int partX1, partX2, partY1, partY2; + int xorg, yorg; + int n; + + xorg = drawable->x; + yorg = drawable->y; + + pextent = REGION_EXTENTS(gc->pScreen, clip); + extentX1 = pextent->x1; + extentY1 = pextent->y1; + extentX2 = pextent->x2; + extentY2 = pextent->y2; + while (nrect--) + { + fullX1 = prect->x + xorg; + fullY1 = prect->y + yorg; + fullX2 = fullX1 + (int)prect->width; + fullY2 = fullY1 + (int)prect->height; + prect++; + + if (fullX1 < extentX1) + fullX1 = extentX1; + + if (fullY1 < extentY1) + fullY1 = extentY1; + + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullY2 > extentY2) + fullY2 = extentY2; + + if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) + continue; + n = REGION_NUM_RECTS(clip); + if (n == 1) { + glamor_fill(drawable, + gc, + fullX1, fullY1, fullX2-fullX1, fullY2-fullY1); + } else { + box = REGION_RECTS(clip); + /* clip the rectangle to each box in the clip region + * this is logically equivalent to calling Intersect() + */ + while (n--) { + partX1 = box->x1; + if (partX1 < fullX1) + partX1 = fullX1; + partY1 = box->y1; + if (partY1 < fullY1) + partY1 = fullY1; + partX2 = box->x2; + if (partX2 > fullX2) + partX2 = fullX2; + partY2 = box->y2; + if (partY2 > fullY2) + partY2 = fullY2; + + box++; + + if (partX1 < partX2 && partY1 < partY2) + glamor_fill(drawable, gc, + partX1, partY1, + partX2 - partX1, partY2 - partY1); + } + } + } +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index b5ba82d12..3ad18b5f5 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -165,6 +165,13 @@ glamor_get_spans(DrawablePtr drawable, 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_putimage.c */ void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, From 1159ebb30b7530c2f4612109306cf85a594dd530 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 4 Sep 2009 18:43:02 -0700 Subject: [PATCH 044/225] glamor: Add untested copyarea implementation --- glamor/Makefile.am | 1 + glamor/glamor_copyarea.c | 116 +++++++++++++++++++++++++++++++++++++++ glamor/glamor_core.c | 2 +- glamor/glamor_priv.h | 4 ++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 glamor/glamor_copyarea.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 3035f6323..838aedcd6 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -17,6 +17,7 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ + glamor_copyarea.c \ glamor_core.c \ glamor_fill.c \ glamor_fillspans.c \ diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c new file mode 100644 index 000000000..876892213 --- /dev/null +++ b/glamor/glamor_copyarea.c @@ -0,0 +1,116 @@ +/* + * Copyright © 2008 Intel Corporation + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +/** @file glamor_copyarea.c + * + * GC CopyArea implementation + */ + +static 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) +{ + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + int i; + + glamor_set_alu(gc->alu); + if (!glamor_set_planemask(dst_pixmap, gc->planemask)) + goto fail; + + for (i = 0; i < nbox; i++) { + glRasterPos2i(box[i].x1 - dst_pixmap->screen_x, + box[i].y1 - dst_pixmap->screen_y); + glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x, + box[i].y1 + dy - src_pixmap->screen_y, + box[i].x2 - box[i].x1, + box[i].y2 - box[i].y1, + GL_RGBA); + } + +fail: + glamor_set_alu(GXcopy); + glamor_set_planemask(dst_pixmap, ~0); +} + +RegionPtr +glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty) +{ + ScreenPtr screen = dst->pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src); + RegionPtr region; + + if (!GLEW_EXT_framebuffer_blit) { + ErrorF("EXT_framebuffer_blit unsupported\n"); + goto fail; + } + + if (!glamor_set_destination_pixmap(dst_pixmap)) { + /* + return miDoCopy(pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, + dstx, dsty, fbCopyNtoN, 0, NULL); + */ + return NULL; + } + + if (src_priv == NULL) { + ErrorF("glamor_copy_area: no src pixmap priv?"); + goto fail; + } + + if (src_priv->fb == 0 && src_pixmap != screen_pixmap) { + ErrorF("glamor_copy_area: No src FBO\n"); + return NULL; + } + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_priv->fb); + + region = miDoCopy(src, dst, gc, + srcx, srcy, width, height, + dstx, dsty, glamor_copy_n_to_n, 0, NULL); + + return region; + +fail: + return NULL; +} diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 7b96d674a..c31e23ced 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -344,7 +344,7 @@ GCOps glamor_gc_ops = { .FillSpans = glamor_fill_spans, .SetSpans = glamor_set_spans, .PutImage = glamor_put_image, - .CopyArea = miCopyArea, + .CopyArea = glamor_copy_area, .CopyPlane = miCopyPlane, .PolyPoint = miPolyPoint, .Polylines = glamor_poly_lines, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 3ad18b5f5..1e2a17357 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -110,6 +110,10 @@ glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); +/* 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); /* glamor_core.c */ Bool glamor_create_gc(GCPtr gc); void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, From 5915b4c0cfcfb25a68b77b29a4d7b39b7f6b4822 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 4 Sep 2009 18:43:52 -0700 Subject: [PATCH 045/225] glamor: Add support for solid source pictures. --- glamor/glamor_priv.h | 4 +- glamor/glamor_render.c | 218 +++++++++++++++++++++++++++++------------ 2 files changed, 159 insertions(+), 63 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 1e2a17357..93a0115e1 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -43,6 +43,8 @@ typedef struct glamor_composite_shader { 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; } glamor_composite_shader; typedef struct glamor_screen_private { @@ -70,7 +72,7 @@ typedef struct glamor_screen_private { GLint put_image_xybitmap_bg_uniform_location; /* glamor_composite */ - glamor_composite_shader composite_shader[2]; + glamor_composite_shader composite_shader[8]; } glamor_screen_private; typedef struct glamor_pixmap_private { diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index d0c955792..2ebb4c5c9 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -39,7 +39,9 @@ #include "glu3/glu3.h" struct shader_key { + Bool solid_source; Bool has_mask; + Bool solid_mask; }; struct blendinfo { @@ -65,7 +67,9 @@ static struct blendinfo composite_op_info[] = { [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, }; -#define HAS_MASK_INDEX 1 +#define SOLID_SOURCE_INDEX 1 +#define HAS_MASK_INDEX 2 +#define SOLID_MASK_INDEX 3 static glamor_composite_shader * glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) @@ -73,8 +77,13 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int index = 0; - if (key->has_mask) + if (key->solid_source) + index += SOLID_SOURCE_INDEX; + if (key->has_mask) { index += HAS_MASK_INDEX; + if (key->solid_mask) + index += SOLID_MASK_INDEX; + } assert(index < ARRAY_SIZE(glamor_priv->composite_shader)); @@ -84,31 +93,58 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) static GLuint glamor_create_composite_fs(struct shader_key *key) { - const char *header = + const char *source_pixmap_header = "uniform sampler2D source_sampler;\n" "varying vec4 source_coords;\n"; - const char *mask_header = + const char *source_solid_header = + "uniform vec4 source;\n"; + const char *mask_pixmap_header = "uniform sampler2D mask_sampler;\n" "varying vec4 mask_coords;\n"; + const char *mask_solid_header = + "uniform vec4 mask;\n"; const char *main_opening = "void main()\n" - "{\n" - " vec4 result;\n" - " result = texture2DProj(source_sampler, source_coords.xyw);\n"; + "{\n"; + const char *source_pixmap_fetch = + " vec4 source = texture2DProj(source_sampler, " + " source_coords.xyw);\n"; + const char *mask_pixmap_fetch = + " vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n"; const char *source_in_mask = - " vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n" - " result = result * mask.w;\n"; + " gl_FragColor = source * mask.w;\n"; + const char *source_only = + " gl_FragColor = source;\n"; const char *main_closing = - " gl_FragColor = result;\n" "}\n"; char *source; + const char *source_setup = ""; + const char *source_fetch = ""; + const char *mask_setup = ""; + const char *mask_fetch = ""; GLuint prog; - source = XNFprintf("%s%s%s%s%s", - header, - key->has_mask ? mask_header : "", + if (key->solid_source) { + source_setup = source_solid_header; + } else { + source_setup = source_pixmap_header; + source_fetch = source_pixmap_fetch; + } + if (key->has_mask) { + if (key->solid_mask) { + mask_setup = mask_solid_header; + } else { + mask_setup = mask_pixmap_header; + mask_fetch = mask_pixmap_fetch; + } + } + source = XNFprintf("%s%s%s%s%s%s%s", + source_setup, + mask_setup, main_opening, - key->has_mask ? source_in_mask : "", + source_fetch, + mask_fetch, + key->has_mask ? source_in_mask : source_only, main_closing); prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); @@ -139,12 +175,13 @@ glamor_create_composite_vs(struct shader_key *key) "}\n"; char *source; GLuint prog; + Bool compute_mask_coords = key->has_mask && !key->solid_mask; source = XNFprintf("%s%s%s%s%s", header, - key->has_mask ? mask_header : "", + compute_mask_coords ? mask_header : "", main_opening, - key->has_mask ? mask_coords : "", + compute_mask_coords ? mask_coords : "", main_closing); prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source); @@ -177,20 +214,31 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) shader->prog = prog; glUseProgramObjectARB(prog); - source_sampler_uniform_location = glGetUniformLocationARB(prog, - "source_sampler"); shader->dest_to_dest_uniform_location = glGetUniformLocationARB(prog, "dest_to_dest"); - shader->dest_to_source_uniform_location = - glGetUniformLocationARB(prog, "dest_to_source"); - glUniform1i(source_sampler_uniform_location, 0); + + if (key->solid_source) { + shader->source_uniform_location = glGetUniformLocationARB(prog, + "source"); + } else { + source_sampler_uniform_location = glGetUniformLocationARB(prog, + "source_sampler"); + shader->dest_to_source_uniform_location = + glGetUniformLocationARB(prog, "dest_to_source"); + glUniform1i(source_sampler_uniform_location, 0); + } if (key->has_mask) { - mask_sampler_uniform_location = glGetUniformLocationARB(prog, - "mask_sampler"); - glUniform1i(mask_sampler_uniform_location, 1); - shader->dest_to_mask_uniform_location = - glGetUniformLocationARB(prog, "dest_to_mask"); + if (key->solid_mask) { + shader->mask_uniform_location = glGetUniformLocationARB(prog, + "mask"); + } else { + mask_sampler_uniform_location = glGetUniformLocationARB(prog, + "mask_sampler"); + glUniform1i(mask_sampler_uniform_location, 1); + shader->dest_to_mask_uniform_location = + glGetUniformLocationARB(prog, "dest_to_mask"); + } } } @@ -199,10 +247,21 @@ glamor_init_composite_shaders(ScreenPtr screen) { struct shader_key key; + memset(&key, 0, sizeof(key)); key.has_mask = FALSE; glamor_create_composite_shader(screen, &key); key.has_mask = TRUE; glamor_create_composite_shader(screen, &key); + key.solid_mask = TRUE; + glamor_create_composite_shader(screen, &key); + + key.solid_source = TRUE; + key.has_mask = FALSE; + glamor_create_composite_shader(screen, &key); + key.has_mask = TRUE; + glamor_create_composite_shader(screen, &key); + key.solid_mask = TRUE; + glamor_create_composite_shader(screen, &key); } static void @@ -277,8 +336,12 @@ glamor_set_composite_op(ScreenPtr screen, static void glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, - glamor_pixmap_private *pixmap_priv) + glamor_pixmap_private *pixmap_priv, + GLint transform_uniform_location, + int x_translate, int y_translate) { + GLUmat4 transform; + glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); switch (picture->repeatType) { @@ -313,6 +376,27 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, } glEnable(GL_TEXTURE_2D); + + glamor_set_composite_transform_matrix(&transform, + picture, + x_translate, + y_translate); + glUniformMatrix4fvARB(transform_uniform_location, 1, 0, + (float *)&transform); +} + +static void +glamor_set_composite_solid(PicturePtr picture, GLint uniform_location) +{ + CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */ + float color[4]; /* rgba */ + + color[0] = ((c >> 16) & 0xff) / 255.0; + color[1] = ((c >> 8) & 0xff) / 255.0; + color[2] = ((c >> 0) & 0xff) / 255.0; + color[3] = ((c >> 24) & 0xff) / 255.0; + + glUniform4fvARB(uniform_location, 1, color); } void @@ -332,10 +416,11 @@ glamor_composite(CARD8 op, ScreenPtr screen = dest->pDrawable->pScreen; PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); PixmapPtr source_pixmap, mask_pixmap = NULL; - glamor_pixmap_private *source_pixmap_priv, *mask_pixmap_priv = NULL; + glamor_pixmap_private *source_pixmap_priv = NULL; + glamor_pixmap_private *mask_pixmap_priv = NULL; struct shader_key key; glamor_composite_shader *shader; - GLUmat4 dest_to_dest, dest_to_source, dest_to_mask; + GLUmat4 dest_to_dest; RegionRec region; int i; @@ -358,14 +443,23 @@ glamor_composite(CARD8 op, return; } + memset(&key, 0, sizeof(key)); key.has_mask = (mask != NULL); if (!source->pDrawable) { - ErrorF("source-only source\n"); - goto fail; + if (source->pSourcePict->type == SourcePictTypeSolidFill) { + key.solid_source = TRUE; + } else { + ErrorF("gradient source\n"); + goto fail; + } } if (mask && !mask->pDrawable) { - ErrorF("source-only mask\n"); - goto fail; + if (mask->pSourcePict->type == SourcePictTypeSolidFill) { + key.solid_mask = TRUE; + } else { + ErrorF("gradient mask\n"); + goto fail; + } } if (source->alphaMap) { ErrorF("source alphaMap\n"); @@ -376,17 +470,19 @@ glamor_composite(CARD8 op, goto fail; } - source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); - source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); - if (source_pixmap == dest_pixmap) { - ErrorF("source == dest\n"); - goto fail; + if (!key.solid_source) { + source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + if (source_pixmap == dest_pixmap) { + ErrorF("source == dest\n"); + goto fail; + } + if (!source_pixmap_priv || source_pixmap_priv->tex == 0) { + ErrorF("no FBO in source\n"); + goto fail; + } } - if (!source_pixmap_priv || source_pixmap_priv->tex == 0) { - ErrorF("no FBO in source\n"); - goto fail; - } - if (mask) { + if (mask && !key.solid_mask) { mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); if (mask_pixmap == dest_pixmap) { @@ -431,25 +527,23 @@ glamor_composite(CARD8 op, -1, 1); glUniformMatrix4fvARB(shader->dest_to_dest_uniform_location, 1, 0, (float *)&dest_to_dest); - glamor_set_composite_transform_matrix(&dest_to_source, - source, - x_source - x_dest, - y_source - x_dest); - glUniformMatrix4fvARB(shader->dest_to_source_uniform_location, 1, 0, - (float *)&dest_to_source); - if (mask) { - glamor_set_composite_transform_matrix(&dest_to_mask, - mask, - x_mask - x_dest, - y_mask - x_dest); - glUniformMatrix4fvARB(shader->dest_to_mask_uniform_location, 1, 0, - (float *)&dest_to_mask); + if (key.solid_source) { + glamor_set_composite_solid(source, shader->source_uniform_location); + } else { + glamor_set_composite_texture(screen, 0, source, source_pixmap_priv, + shader->dest_to_source_uniform_location, + x_source - x_dest, y_source - y_dest); + } + if (key.has_mask) { + if (key.solid_mask) { + glamor_set_composite_solid(mask, shader->mask_uniform_location); + } else { + glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv, + shader->dest_to_mask_uniform_location, + x_mask - x_dest, y_mask - y_dest); + } } - - glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); - if (mask) - glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); if (!miComputeCompositeRegion(®ion, source, mask, dest, @@ -469,9 +563,9 @@ glamor_composite(CARD8 op, } glEnd(); - glamor_set_composite_op(screen, PictOpSrc, dest, mask); + glDisable(GL_BLEND); glUseProgramObjectARB(0); - REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); return; From f17473cdd5f93a2bf3a7b6a14bd5acd965e8e9f0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 22 Sep 2009 10:55:04 -0700 Subject: [PATCH 046/225] glamor: Fix pixmap private getter in copyarea. --- glamor/glamor_copyarea.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 876892213..6f2911a1c 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -76,7 +76,7 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); - glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src); + glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); RegionPtr region; if (!GLEW_EXT_framebuffer_blit) { From c4343dfa0a2b40d46d3feb14f1df9fae0fd4a214 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 22 Sep 2009 12:08:19 -0700 Subject: [PATCH 047/225] glamor: Add prepare/finishaccess code based on UXA. --- glamor/glamor.c | 12 +++ glamor/glamor_core.c | 245 ++++++++++++++++++++++++++++++++++++++++++- glamor/glamor_priv.h | 14 +++ 3 files changed, 269 insertions(+), 2 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 71c8ab20f..507a19be4 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -177,6 +177,10 @@ glamor_init(ScreenPtr screen) ErrorF("GL_ARB_vertex_shader required\n"); goto fail; } + if (!GLEW_ARB_pixel_buffer_object) { + ErrorF("GL_ARB_pixel_buffer_object required\n"); + goto fail; + } if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, @@ -199,6 +203,12 @@ glamor_init(ScreenPtr screen) glamor_priv->saved_get_image = screen->GetImage; screen->GetImage = miGetImage; + glamor_priv->saved_change_window_attributes = screen->ChangeWindowAttributes; + screen->ChangeWindowAttributes = glamor_change_window_attributes; + + glamor_priv->saved_bitmap_to_region = screen->BitmapToRegion; + screen->BitmapToRegion = glamor_bitmap_to_region; + #ifdef RENDER glamor_priv->saved_composite = ps->Composite; ps->Composite = glamor_composite; @@ -231,6 +241,8 @@ glamor_fini(ScreenPtr screen) screen->CreatePixmap = glamor_priv->saved_create_pixmap; screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; screen->GetSpans = glamor_priv->saved_get_spans; + screen->ChangeWindowAttributes = glamor_priv->saved_change_window_attributes; + screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region; #ifdef RENDER ps->Composite = glamor_priv->saved_composite; #endif diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index c31e23ced..3c98b5cb0 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -260,6 +260,129 @@ glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, } } +Bool +glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + unsigned int stride; + GLenum format, type; + + if (pixmap_priv == NULL) + return TRUE; + + if (pixmap_priv->fb == 0) { + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap != screen_pixmap) + return TRUE; + } + + stride = PixmapBytePad(drawable->width, drawable->depth); + + switch (drawable->depth) { + case 1: + format = GL_COLOR_INDEX; + type = GL_BITMAP; + break; + case 8: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + break; + case 24: + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown prepareaccess depth %d\n", drawable->depth); + return FALSE; + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glGenBuffersARB(1, &pixmap_priv->pbo); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, stride * drawable->height, + NULL, GL_DYNAMIC_DRAW_ARB); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ROW_LENGTH, stride * 8 / + pixmap->drawable.bitsPerPixel); + + glReadPixels(0, 0, + pixmap->drawable.width, pixmap->drawable.height, + format, type, 0); + + pixmap->devPrivate.ptr = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, + GL_READ_WRITE_ARB); + + return TRUE; +} + +void +glamor_finish_access(DrawablePtr drawable) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + unsigned int stride; + GLenum format, type; + + if (pixmap_priv == NULL) + return; + + if (pixmap_priv->fb == 0) { + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap != screen_pixmap) + return; + } + + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + pixmap->devPrivate.ptr = NULL; + + stride = PixmapBytePad(drawable->width, drawable->depth); + + switch (drawable->depth) { + case 1: + format = GL_COLOR_INDEX; + type = GL_BITMAP; + break; + case 8: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + break; + case 24: + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown finishaccess depth %d\n", drawable->depth); + return; + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 / + pixmap->drawable.bitsPerPixel); + + glRasterPos2i(0, 0); + glDrawPixels(pixmap->drawable.width, pixmap->drawable.height, + format, type, 0); + glDeleteBuffersARB(1, &pixmap_priv->pbo); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); +} + void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, int x, int y, int width, int height, @@ -364,13 +487,78 @@ GCOps glamor_gc_ops = { }; /** - * exaValidateGC() sets the ops to EXA's implementations, which may be + * uxa_validate_gc() sets the ops to glamor's implementations, which may be * accelerated or may sync the card and fall back to fb. */ static void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) { - fbValidateGC(gc, changes, drawable); + /* fbValidateGC will do direct access to pixmaps if the tiling has changed. + * Preempt fbValidateGC by doing its work and masking the change out, so + * that we can do the Prepare/finish_access. + */ +#ifdef FB_24_32BIT + if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { + gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); + fbGetRotatedPixmap(gc) = 0; + } + + if (gc->fillStyle == FillTiled) { + PixmapPtr old_tile, new_tile; + + old_tile = gc->tile.pixmap; + if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { + new_tile = fbGetRotatedPixmap(gc); + if (!new_tile || + new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel) + { + if (new_tile) + gc->pScreen->DestroyPixmap(new_tile); + /* fb24_32ReformatTile will do direct access of a newly- + * allocated pixmap. + */ + if (glamor_prepare_access(&old_tile->drawable, + GLAMOR_ACCESS_RO)) { + new_tile = fb24_32ReformatTile(old_tile, + drawable->bitsPerPixel); + glamor_finish_access(&old_tile->drawable); + } + } + if (new_tile) { + fbGetRotatedPixmap(gc) = old_tile; + gc->tile.pixmap = new_tile; + changes |= GCTile; + } + } + } +#endif + if (changes & GCTile) { + if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width * + drawable->bitsPerPixel)) + { + if (glamor_prepare_access(&gc->tile.pixmap->drawable, + GLAMOR_ACCESS_RW)) { + fbPadPixmap(gc->tile.pixmap); + glamor_finish_access(&gc->tile.pixmap->drawable); + } + } + /* Mask out the GCTile change notification, now that we've done FB's + * job for it. + */ + changes &= ~GCTile; + } + + if (changes & GCStipple && gc->stipple) { + /* We can't inline stipple handling like we do for GCTile because + * it sets fbgc privates. + */ + if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { + fbValidateGC(gc, changes, drawable); + glamor_finish_access(&gc->stipple->drawable); + } + } else { + fbValidateGC(gc, changes, drawable); + } gc->ops = &glamor_gc_ops; } @@ -399,3 +587,56 @@ glamor_create_gc(GCPtr gc) return TRUE; } + +Bool +glamor_prepare_access_window(WindowPtr window) +{ + if (window->backgroundState == BackgroundPixmap) { + if (!glamor_prepare_access(&window->background.pixmap->drawable, + GLAMOR_ACCESS_RO)) + return FALSE; + } + + if (window->borderIsPixel == FALSE) { + if (!glamor_prepare_access(&window->border.pixmap->drawable, + GLAMOR_ACCESS_RO)) { + if (window->backgroundState == BackgroundPixmap) + glamor_finish_access(&window->background.pixmap->drawable); + return FALSE; + } + } + return TRUE; +} + +void +glamor_finish_access_window(WindowPtr window) +{ + if (window->backgroundState == BackgroundPixmap) + glamor_finish_access(&window->background.pixmap->drawable); + + if (window->borderIsPixel == FALSE) + glamor_finish_access(&window->border.pixmap->drawable); +} + +Bool +glamor_change_window_attributes(WindowPtr window, unsigned long mask) +{ + Bool ret; + + if (!glamor_prepare_access_window(window)) + return FALSE; + ret = fbChangeWindowAttributes(window, mask); + glamor_finish_access_window(window); + return ret; +} + +RegionPtr +glamor_bitmap_to_region(PixmapPtr pixmap) +{ + RegionPtr ret; + if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) + return NULL; + ret = fbPixmapToRegion(pixmap); + glamor_finish_access(&pixmap->drawable); + return ret; +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 93a0115e1..81bb035f5 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -31,6 +31,11 @@ #include "glamor.h" #include +typedef enum glamor_access { + GLAMOR_ACCESS_RO, + GLAMOR_ACCESS_RW, +} glamor_access_t; + typedef struct glamor_transform_uniforms { GLint x_bias; GLint x_scale; @@ -55,6 +60,8 @@ typedef struct glamor_screen_private { GetImageProcPtr saved_get_image; CompositeProcPtr saved_composite; TrapezoidsProcPtr saved_trapezoids; + ChangeWindowAttributesProcPtr saved_change_window_attributes; + BitmapToRegionProcPtr saved_bitmap_to_region; /* glamor_solid */ GLint solid_prog; @@ -78,6 +85,7 @@ typedef struct glamor_screen_private { typedef struct glamor_pixmap_private { GLuint tex; GLuint fb; + GLuint pbo; } glamor_pixmap_private; extern DevPrivateKey glamor_screen_private_key; @@ -117,6 +125,10 @@ RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty); /* glamor_core.c */ +Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); +void glamor_finish_access(DrawablePtr drawable); +Bool glamor_prepare_access_window(WindowPtr window); +void glamor_finish_access_window(WindowPtr window); Bool glamor_create_gc(GCPtr gc); void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, int x, int y, int width, int height, @@ -134,6 +146,8 @@ void glamor_get_transform_uniform_locations(GLint prog, glamor_transform_uniforms *uniform_locations); void glamor_set_transform_for_pixmap(PixmapPtr pixmap, glamor_transform_uniforms *uniform_locations); +Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); +RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); /* glamor_fill.c */ void glamor_fill(DrawablePtr drawable, From 800fd4f8494ad6f0984073406b3dec584ba63648 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 22 Sep 2009 15:41:18 -0700 Subject: [PATCH 048/225] glamor: Fix the type for copyarea. --- glamor/glamor_copyarea.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 6f2911a1c..c89dffcba 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -60,7 +60,7 @@ glamor_copy_n_to_n(DrawablePtr src, box[i].y1 + dy - src_pixmap->screen_y, box[i].x2 - box[i].x1, box[i].y2 - box[i].y1, - GL_RGBA); + GL_COLOR); } fail: From ca58607a44c310ef369a097a06be83aa2a9e1c5b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 09:58:55 +0100 Subject: [PATCH 049/225] glamor: Move glamor_poly_lines to a separate file. --- glamor/Makefile.am | 1 + glamor/glamor_core.c | 133 +++++++++++++------------------------- glamor/glamor_polylines.c | 107 ++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 5 ++ 4 files changed, 159 insertions(+), 87 deletions(-) create mode 100644 glamor/glamor_polylines.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 838aedcd6..ce7869244 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -23,6 +23,7 @@ libglamor_la_SOURCES = \ glamor_fillspans.c \ glamor_getspans.c \ glamor_polyfillrect.c \ + glamor_polylines.c \ glamor_putimage.c \ glamor_setspans.c \ glamor_render.c \ diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 3c98b5cb0..4ae0d6c78 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -265,8 +265,9 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride; + unsigned int stride, read_stride, x, y; GLenum format, type; + uint8_t *data, *read; if (pixmap_priv == NULL) return TRUE; @@ -280,11 +281,15 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) } stride = PixmapBytePad(drawable->width, drawable->depth); + read_stride = stride; + + data = xalloc(stride * drawable->height); switch (drawable->depth) { case 1: - format = GL_COLOR_INDEX; - type = GL_BITMAP; + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + read_stride = drawable->width; break; case 8: format = GL_ALPHA; @@ -300,24 +305,52 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) break; default: ErrorF("Unknown prepareaccess depth %d\n", drawable->depth); + xfree(data); return FALSE; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glGenBuffersARB(1, &pixmap_priv->pbo); glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, stride * drawable->height, + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + read_stride * pixmap->drawable.height, NULL, GL_DYNAMIC_DRAW_ARB); glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ROW_LENGTH, stride * 8 / + glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 / pixmap->drawable.bitsPerPixel); glReadPixels(0, 0, pixmap->drawable.width, pixmap->drawable.height, format, type, 0); - pixmap->devPrivate.ptr = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, - GL_READ_WRITE_ARB); + read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB); + + if (pixmap->drawable.depth == 1) { + for (y = 0; y < pixmap->drawable.height; y++) { + uint8_t *read_row = read + read_stride * (pixmap->drawable.height - + y - 1); + + for (x = 0; x < pixmap->drawable.width; x++) { + int index = x / 8; + int bit = 1 << (x % 8); + + if (read_row[x]) + data[index] |= bit; + else + data[index] &= ~bit; + } + } + } else { + for (y = 0; y < pixmap->drawable.height; y++) + memcpy(data + y * stride, + read + (pixmap->drawable.height - y - 1) * stride, stride); + } + pixmap->devPrivate.ptr = data; + + glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, &pixmap_priv->pbo); + pixmap_priv->pbo = 0; return TRUE; } @@ -341,13 +374,6 @@ glamor_finish_access(DrawablePtr drawable) return; } - glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); - glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); - pixmap->devPrivate.ptr = NULL; - - stride = PixmapBytePad(drawable->width, drawable->depth); - switch (drawable->depth) { case 1: format = GL_COLOR_INDEX; @@ -370,17 +396,19 @@ glamor_finish_access(DrawablePtr drawable) return; } + stride = PixmapBytePad(drawable->width, drawable->depth); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 / pixmap->drawable.bitsPerPixel); glRasterPos2i(0, 0); glDrawPixels(pixmap->drawable.width, pixmap->drawable.height, - format, type, 0); - glDeleteBuffersARB(1, &pixmap_priv->pbo); - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + format, type, pixmap->devPrivate.ptr); + + xfree(pixmap->devPrivate.ptr); + pixmap->devPrivate.ptr = NULL; } void @@ -394,75 +422,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, glamor_solid_fail_region(pixmap, x, y, width, height); } -/** - * glamor_poly_lines() checks if it can accelerate the lines as a group of - * horizontal or vertical lines (rectangles), and uses existing rectangle fill - * acceleration if so. - */ -static void -glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) -{ - xRectangle *rects; - int x1, x2, y1, y2; - int i; - - /* Don't try to do wide lines or non-solid fill style. */ - if (gc->lineWidth != 0) { - ErrorF("stub wide polylines\n"); - return; - } - if (gc->lineStyle != LineSolid || - gc->fillStyle != FillSolid) { - ErrorF("stub poly_line non-solid fill\n"); - return; - } - - rects = xalloc(sizeof(xRectangle) * (n - 1)); - x1 = points[0].x; - y1 = points[0].y; - /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < n - 1; i++) { - if (mode == CoordModePrevious) { - x2 = x1 + points[i + 1].x; - y2 = y1 + points[i + 1].y; - } else { - x2 = points[i + 1].x; - y2 = points[i + 1].y; - } - - if (x1 != x2 && y1 != y2) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - - xfree(rects); - - ErrorF("stub diagonal poly_line\n"); - glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1); - return; - } - - if (x1 < x2) { - rects[i].x = x1; - rects[i].width = x2 - x1 + 1; - } else { - rects[i].x = x2; - rects[i].width = x1 - x2 + 1; - } - if (y1 < y2) { - rects[i].y = y1; - rects[i].height = y2 - y1 + 1; - } else { - rects[i].y = y2; - rects[i].height = y1 - y2 + 1; - } - - x1 = x2; - y1 = y2; - } - gc->ops->PolyFillRect(drawable, gc, n - 1, rects); - xfree(rects); -} - GCOps glamor_gc_ops = { .FillSpans = glamor_fill_spans, .SetSpans = glamor_set_spans, diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c new file mode 100644 index 000000000..48e62f454 --- /dev/null +++ b/glamor/glamor_polylines.c @@ -0,0 +1,107 @@ +/* + * 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: + * Eric Anholt + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +/** @file glamor_polylines.c + * + * GC PolyFillRect implementation, taken straight from fb_fill.c + */ + +/** + * glamor_poly_lines() checks if it can accelerate the lines as a group of + * horizontal or vertical lines (rectangles), and uses existing rectangle fill + * acceleration if so. + */ +void +glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, + DDXPointPtr points) +{ + xRectangle *rects; + int x1, x2, y1, y2; + int i; + + /* Don't try to do wide lines or non-solid fill style. */ + if (gc->lineWidth != 0) { + ErrorF("stub wide polylines\n"); + return; + } + if (gc->lineStyle != LineSolid || + gc->fillStyle != FillSolid) { + ErrorF("stub poly_line non-solid fill\n"); + return; + } + + rects = xalloc(sizeof(xRectangle) * (n - 1)); + x1 = points[0].x; + y1 = points[0].y; + /* If we have any non-horizontal/vertical, fall back. */ + for (i = 0; i < n - 1; i++) { + if (mode == CoordModePrevious) { + x2 = x1 + points[i + 1].x; + y2 = y1 + points[i + 1].y; + } else { + x2 = points[i + 1].x; + y2 = points[i + 1].y; + } + + if (x1 != x2 && y1 != y2) { + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + + xfree(rects); + + ErrorF("stub diagonal poly_line\n"); + glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1); + return; + } + + if (x1 < x2) { + rects[i].x = x1; + rects[i].width = x2 - x1 + 1; + } else { + rects[i].x = x2; + rects[i].width = x1 - x2 + 1; + } + if (y1 < y2) { + rects[i].y = y1; + rects[i].height = y2 - y1 + 1; + } else { + rects[i].y = y2; + rects[i].height = y1 - y2 + 1; + } + + x1 = x2; + y1 = y2; + } + gc->ops->PolyFillRect(drawable, gc, n - 1, rects); + xfree(rects); +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 81bb035f5..ad68c12f1 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -192,6 +192,11 @@ glamor_poly_fill_rect(DrawablePtr drawable, 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, From de675893b7ce2880289cce13be6190d55f4fc29c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 10:16:21 +0100 Subject: [PATCH 050/225] glamor: Add fallbacks for glamor_copy_area(). --- glamor/glamor_copyarea.c | 33 ++++++++++++++++++++------------- glamor/glamor_core.c | 17 +++++++++++++++-- glamor/glamor_priv.h | 12 ++++++++++++ 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index c89dffcba..077c44ffd 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -80,27 +80,22 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, RegionPtr region; if (!GLEW_EXT_framebuffer_blit) { - ErrorF("EXT_framebuffer_blit unsupported\n"); + glamor_fallback("glamor_copy_area(): " + "EXT_framebuffer_blit unsupported\n"); goto fail; } - if (!glamor_set_destination_pixmap(dst_pixmap)) { - /* - return miDoCopy(pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, - dstx, dsty, fbCopyNtoN, 0, NULL); - */ - return NULL; - } + if (!glamor_set_destination_pixmap(dst_pixmap)) + goto fail; if (src_priv == NULL) { - ErrorF("glamor_copy_area: no src pixmap priv?"); + glamor_fallback("glamor_copy_area(): no src pixmap priv"); goto fail; } if (src_priv->fb == 0 && src_pixmap != screen_pixmap) { - ErrorF("glamor_copy_area: No src FBO\n"); - return NULL; + glamor_fallback("glamor_copy_area(): no src fbo"); + goto fail; } glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_priv->fb); @@ -112,5 +107,17 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, return region; fail: - return NULL; + glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst, + glamor_get_drawable_location(src), + glamor_get_drawable_location(dst)); + region = NULL; + if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + region = fbCopyArea(src, dst, gc, srcx, srcy, width, height, + dstx, dsty); + glamor_finish_access(src); + } + glamor_finish_access(dst); + } + return region; } diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 4ae0d6c78..32a09b625 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -39,13 +39,26 @@ #include "glamor_priv.h" +const Bool +glamor_get_drawable_location(const DrawablePtr drawable) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + if (pixmap_priv == NULL) + return 'm'; + if (pixmap_priv->fb == 0) + return 's'; + else + return 'f'; +} + Bool glamor_set_destination_pixmap(PixmapPtr pixmap) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv == NULL) { - ErrorF("no pixmap priv?"); + glamor_fallback("glamor_set_destination_pixmap(): no pixmap priv"); return FALSE; } @@ -54,7 +67,7 @@ glamor_set_destination_pixmap(PixmapPtr pixmap) PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); if (pixmap != screen_pixmap) { - ErrorF("No FBO\n"); + glamor_fallback("glamor_set_destination_pixmap(): no fbo"); return FALSE; } } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index ad68c12f1..2ee16ef56 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -117,6 +117,17 @@ glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) FbFullMask(drawable->depth); } +static inline void +glamor_fallback(char *format, ...) +{ + va_list ap; + + va_start(ap, format); + LogMessageVerb(X_INFO, 1, "glamor fallback: "); + LogVMessageVerb(X_INFO, 1, format, ap); + va_end(ap); +} + /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); @@ -129,6 +140,7 @@ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); void glamor_finish_access(DrawablePtr drawable); Bool glamor_prepare_access_window(WindowPtr window); void glamor_finish_access_window(WindowPtr window); +const Bool glamor_get_drawable_location(const DrawablePtr drawable); Bool glamor_create_gc(GCPtr gc); void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, int x, int y, int width, int height, From e9d4794cd0bc6c8790204405fe09f968edfa409d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 11:23:14 +0100 Subject: [PATCH 051/225] glamor: Add fallbacks for Render. --- glamor/glamor_priv.h | 4 ++-- glamor/glamor_render.c | 39 +++++++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 2ee16ef56..b470be5a4 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -123,8 +123,8 @@ glamor_fallback(char *format, ...) va_list ap; va_start(ap, format); - LogMessageVerb(X_INFO, 1, "glamor fallback: "); - LogVMessageVerb(X_INFO, 1, format, ap); + LogMessageVerb(X_INFO, 0, "fallback: "); + LogVMessageVerb(X_NONE, 0, format, ap); va_end(ap); } diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 2ebb4c5c9..b6f6b86cb 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -25,7 +25,6 @@ * */ - /** @file glamor_render.c * * Render acceleration implementation @@ -35,6 +34,7 @@ #ifdef RENDER #include "mipict.h" +#include "fbpict.h" #include "glu3/glu3.h" @@ -474,11 +474,11 @@ glamor_composite(CARD8 op, source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); if (source_pixmap == dest_pixmap) { - ErrorF("source == dest\n"); + glamor_fallback("glamor_composite(): source == dest\n"); goto fail; } if (!source_pixmap_priv || source_pixmap_priv->tex == 0) { - ErrorF("no FBO in source\n"); + glamor_fallback("glamor_composite(): no FBO in source\n"); goto fail; } } @@ -486,18 +486,19 @@ glamor_composite(CARD8 op, mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); if (mask_pixmap == dest_pixmap) { - ErrorF("mask == dest\n"); + glamor_fallback("glamor_composite(): mask == dest\n"); goto fail; } if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) { - ErrorF("no FBO in mask\n"); + glamor_fallback("glamor_composite(): no FBO in mask\n"); goto fail; } } shader = glamor_lookup_composite_shader(screen, &key); if (shader->prog == 0) { - ErrorF("No program compiled for this render accel mode\n"); + glamor_fallback("glamor_composite(): " + "no shader program for this render acccel mode\n"); goto fail; } @@ -570,9 +571,31 @@ glamor_composite(CARD8 op, return; fail: - glamor_set_composite_op(screen, PictOpSrc, dest, mask); + glamor_fallback("glamor_composite(): " + "from picts %p/%p to pict %p\n", source, mask, dest); + glUseProgramObjectARB(0); - glamor_solid_fail_region(dest_pixmap, x_dest, y_dest, width, height); + if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) { + if (source->pDrawable == NULL || + glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO)) + { + if (!mask || mask->pDrawable == NULL || + glamor_prepare_access(mask->pDrawable, GLAMOR_ACCESS_RO)) + { + fbComposite(op, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + if (mask && mask->pDrawable != NULL) + glamor_finish_access(mask->pDrawable); + } + if (source->pDrawable != NULL) + glamor_finish_access(source->pDrawable); + } + glamor_finish_access(dest->pDrawable); + } } From 72a757ba00232fe8b42b977f5210fa119495b05e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 11:58:52 +0100 Subject: [PATCH 052/225] glamor: Use GL_MESA_pack_invert to avoid complexity in prepare_access. --- glamor/glamor_core.c | 96 +++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 32a09b625..5afbf3969 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -293,25 +293,24 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) return TRUE; } - stride = PixmapBytePad(drawable->width, drawable->depth); + stride = PixmapBytePad(pixmap->drawable.width, drawable->depth); read_stride = stride; - data = xalloc(stride * drawable->height); + data = xalloc(stride * pixmap->drawable.height); switch (drawable->depth) { case 1: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; - read_stride = drawable->width; + read_stride = pixmap->drawable.width; break; case 8: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; break; case 24: - format = GL_RGB; - type = GL_UNSIGNED_BYTE; - break; + assert(drawable->bitsPerPixel == 32); + /* FALLTHROUGH */ case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -323,47 +322,55 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glGenBuffersARB(1, &pixmap_priv->pbo); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, - read_stride * pixmap->drawable.height, - NULL, GL_DYNAMIC_DRAW_ARB); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 / pixmap->drawable.bitsPerPixel); - glReadPixels(0, 0, - pixmap->drawable.width, pixmap->drawable.height, - format, type, 0); - - read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB); - - if (pixmap->drawable.depth == 1) { - for (y = 0; y < pixmap->drawable.height; y++) { - uint8_t *read_row = read + read_stride * (pixmap->drawable.height - - y - 1); - - for (x = 0; x < pixmap->drawable.width; x++) { - int index = x / 8; - int bit = 1 << (x % 8); - - if (read_row[x]) - data[index] |= bit; - else - data[index] &= ~bit; - } - } + if (GLEW_MESA_pack_invert && drawable->depth != 1) { + glPixelStorei(GL_PACK_INVERT_MESA, 1); + glReadPixels(0, 0, + pixmap->drawable.width, pixmap->drawable.height, + format, type, data); + glPixelStorei(GL_PACK_INVERT_MESA, 0); } else { - for (y = 0; y < pixmap->drawable.height; y++) - memcpy(data + y * stride, - read + (pixmap->drawable.height - y - 1) * stride, stride); - } - pixmap->devPrivate.ptr = data; + glGenBuffersARB(1, &pixmap_priv->pbo); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + read_stride * pixmap->drawable.height, + NULL, GL_DYNAMIC_DRAW_ARB); + glReadPixels(0, 0, + pixmap->drawable.width, pixmap->drawable.height, + format, type, 0); - glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); - glDeleteBuffersARB(1, &pixmap_priv->pbo); - pixmap_priv->pbo = 0; + read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB); + + if (pixmap->drawable.depth == 1) { + for (y = 0; y < pixmap->drawable.height; y++) { + uint8_t *read_row = read + + read_stride * (pixmap->drawable.height - y - 1); + + for (x = 0; x < pixmap->drawable.width; x++) { + int index = x / 8; + int bit = 1 << (x % 8); + + if (read_row[x]) + data[index] |= bit; + else + data[index] &= ~bit; + } + } + } else { + for (y = 0; y < pixmap->drawable.height; y++) + memcpy(data + y * stride, + read + (pixmap->drawable.height - y - 1) * stride, stride); + } + glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, &pixmap_priv->pbo); + pixmap_priv->pbo = 0; + } + + pixmap->devPrivate.ptr = data; return TRUE; } @@ -397,9 +404,8 @@ glamor_finish_access(DrawablePtr drawable) type = GL_UNSIGNED_BYTE; break; case 24: - format = GL_RGB; - type = GL_UNSIGNED_BYTE; - break; + assert(drawable->bitsPerPixel == 32); + /* FALLTHROUGH */ case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -409,7 +415,7 @@ glamor_finish_access(DrawablePtr drawable) return; } - stride = PixmapBytePad(drawable->width, drawable->depth); + stride = PixmapBytePad(pixmap->drawable.width, drawable->depth); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); From 55dac9b42e18dcc1586770d31ee265178e68b744 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 12:09:52 +0100 Subject: [PATCH 053/225] glamor: Add glamor_prepare_access_gc() from UXA. --- glamor/glamor_core.c | 36 ++++++++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 5afbf3969..431cb4139 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -429,6 +429,42 @@ glamor_finish_access(DrawablePtr drawable) xfree(pixmap->devPrivate.ptr); pixmap->devPrivate.ptr = NULL; } +/** + * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the + * current fill style. + * + * Solid doesn't use an extra pixmap source, so we don't worry about them. + * Stippled/OpaqueStippled are 1bpp and can be in fb, so we should worry + * about them. + */ +Bool +glamor_prepare_access_gc(GCPtr gc) +{ + if (gc->stipple) + if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO)) + return FALSE; + if (gc->fillStyle == FillTiled) { + if (!glamor_prepare_access (&gc->tile.pixmap->drawable, + GLAMOR_ACCESS_RO)) { + if (gc->stipple) + glamor_finish_access(&gc->stipple->drawable); + return FALSE; + } + } + return TRUE; +} + +/** + * Finishes access to the tile in the GC, if used. + */ +void +glamor_finish_access_gc(GCPtr gc) +{ + if (gc->fillStyle == FillTiled) + glamor_finish_access(&gc->tile.pixmap->drawable); + if (gc->stipple) + glamor_finish_access(&gc->stipple->drawable); +} void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index b470be5a4..2045ed691 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -140,6 +140,8 @@ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); void glamor_finish_access(DrawablePtr drawable); 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); const Bool glamor_get_drawable_location(const DrawablePtr drawable); Bool glamor_create_gc(GCPtr gc); void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, From 22cad98975091ed724a37ec940946cd2899ebcbf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 12:13:15 +0100 Subject: [PATCH 054/225] glamor: Add fallback support to glamor_set_spans(). --- glamor/glamor_setspans.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 66ec3dafd..0bd0ac1c2 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -68,8 +68,9 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, type = GL_UNSIGNED_INT_8_8_8_8_REV; break; default: - ErrorF("Unknown setspans depth %d\n", drawable->depth); - return; + glamor_fallback("glamor_set_spans()Unknown depth %d\n", + drawable->depth); + goto fail; } if (!glamor_set_destination_pixmap(dest_pixmap)) @@ -117,4 +118,11 @@ fail: glamor_set_planemask(dest_pixmap, ~0); glamor_set_alu(GXcopy); xfree(temp_src); + + glamor_fallback("glamor_set_spans(): to %p (%c)\n", + drawable, glamor_get_drawable_location(drawable)); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + fbSetSpans(drawable, gc, src, points, widths, n, sorted); + glamor_finish_access(drawable); + } } From 0e56c182c3b06f5b02d357e2b8e930a580bd0274 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 12:16:30 +0100 Subject: [PATCH 055/225] glamor: Add fallback support to glamor_put_image(). --- glamor/glamor_putimage.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 55854daae..39f120eca 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -224,7 +224,13 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, fail: glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); - glamor_solid_fail_region(pixmap, x, y, w, h); + + glamor_fallback("glamor_put_image(): to %p (%c)\n", + drawable, glamor_get_drawable_location(drawable)); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); + glamor_finish_access(drawable); + } } void @@ -331,5 +337,11 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, fail: glamor_set_planemask(pixmap, ~0); - glamor_solid_fail_region(pixmap, x, y, w, h); + glamor_fallback("glamor_put_image(): to %p (%c)\n", + drawable, glamor_get_drawable_location(drawable)); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format, + bits); + glamor_finish_access(drawable); + } } From e93070affdf64c47be02684e7902a61e7ae9fa33 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 12:44:03 +0100 Subject: [PATCH 056/225] glamor: Fix up the access flags for glamor_prepare_access(). --- glamor/glamor_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 431cb4139..b0653d8cb 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -337,12 +337,12 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, read_stride * pixmap->drawable.height, - NULL, GL_DYNAMIC_DRAW_ARB); + NULL, GL_STREAM_READ_ARB); glReadPixels(0, 0, pixmap->drawable.width, pixmap->drawable.height, format, type, 0); - read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB); + read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB); if (pixmap->drawable.depth == 1) { for (y = 0; y < pixmap->drawable.height; y++) { From b5087ff9b1e5495c742e581f586c055de878dd4b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 12:47:59 +0100 Subject: [PATCH 057/225] glamor: Fix the row length of 1bpp prepare_access. --- glamor/glamor_core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index b0653d8cb..9d0e40f44 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -323,9 +323,12 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 / - pixmap->drawable.bitsPerPixel); - + if (drawable->depth != 1) { + glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 / + pixmap->drawable.bitsPerPixel); + } else { + glPixelStorei(GL_PACK_ROW_LENGTH, read_stride); + } if (GLEW_MESA_pack_invert && drawable->depth != 1) { glPixelStorei(GL_PACK_INVERT_MESA, 1); glReadPixels(0, 0, From ec526eab8f02e0bcce859a1b7ebaf6c5bccc5e87 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 13:05:13 +0100 Subject: [PATCH 058/225] ephyr: Hook the glamor into damage and draw into the backbuffer. This should avoid a bunch of absurdity with GLX front buffer handling, fix exposes, and improve performance. For now we're copying the whole buffer while glamor is developed. --- hw/kdrive/ephyr/ephyr.c | 3 --- hw/kdrive/ephyr/ephyr.h | 1 + hw/kdrive/ephyr/hostx.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 16959d74b..1aacc5fe8 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -395,9 +395,6 @@ ephyrSetInternalDamage (ScreenPtr pScreen) EphyrScrPriv *scrpriv = screen->driver; PixmapPtr pPixmap = NULL; - if (ephyrFuncs.initAccel == ephyr_glamor_init) - return TRUE; - scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0, (DamageDestroyFunc) 0, DamageReportNone, diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index cd1521209..9dcde8d56 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -201,6 +201,7 @@ Bool ephyr_glamor_init(ScreenPtr pScreen); void ephyr_glamor_enable(ScreenPtr pScreen); void ephyr_glamor_disable(ScreenPtr pScreen); void ephyr_glamor_fini(ScreenPtr pScreen); +void ephyr_glamor_host_paint_rect(ScreenPtr pScreen); /*ephyvideo.c*/ diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index c7c792984..15dfc70ae 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -767,6 +767,11 @@ hostx_screen_init (EphyrScreenInfo screen, static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen, int x, int y, int width, int height); +static void +ephyr_glamor_paint_rect (EphyrScreenInfo screen, + int sx, int sy, + int dx, int dy, + int width, int height); void hostx_paint_rect (EphyrScreenInfo screen, @@ -778,6 +783,11 @@ hostx_paint_rect (EphyrScreenInfo screen, EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ; + if (ephyr_glamor) { + ephyr_glamor_paint_rect(screen, sx, sy, dx, dy, width, height); + return; + } + /* * Copy the image data updated by the shadow layer * on to the window @@ -1464,6 +1474,7 @@ ephyr_glamor_get_visual(void) GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, 1, None}; XVisualInfo *visual_info; int event_base = 0, error_base = 0; @@ -1495,3 +1506,29 @@ ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) if (!glXMakeCurrent(dpy, host_screen->win, ctx)) errx(1, "glXMakeCurrent failed\n"); } + +static void +ephyr_glamor_paint_rect (EphyrScreenInfo screen, + int sx, int sy, + int dx, int dy, + int width, int height) +{ + struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen); + static PFNGLXCOPYSUBBUFFERMESAPROC pglXCopySubBufferMESA = NULL; + + if (!pglXCopySubBufferMESA) { + pglXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC) + glXGetProcAddressARB((const GLubyte*)"glXCopySubBufferMESA"); + assert(pglXCopySubBufferMESA); + } + + /* Always copy the full screen until we get things rendering correctly. */ +#if 0 + pglXCopySubBufferMESA(HostX.dpy, host_screen->win, + sx, sy, width, height); +#else + pglXCopySubBufferMESA(HostX.dpy, host_screen->win, + 0, 0, + host_screen->win_width, host_screen->win_height); +#endif +} From 6ce378f11ff396f350cbaa280086f6f9600da29e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 13:15:38 +0100 Subject: [PATCH 059/225] glamor: Add fallback support for glamor_get_spans(). --- glamor/glamor_getspans.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 76c6cceef..8339eb130 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -76,14 +76,13 @@ glamor_get_spans(DrawablePtr drawable, type = GL_UNSIGNED_INT_8_8_8_8_REV; break; default: - ErrorF("Unknown getspans depth %d\n", drawable->depth); - return; + glamor_fallback("glamor_get_spans(): " + "Unknown getspans depth %d\n", drawable->depth); + goto fail; } - if (!glamor_set_destination_pixmap(pixmap)) { - fbGetSpans(drawable, wmax, points, widths, count, dst); - return; - } + if (!glamor_set_destination_pixmap(pixmap)) + goto fail; for (i = 0; i < count; i++) { glReadPixels(points[i].x - pixmap->screen_x, @@ -102,4 +101,14 @@ glamor_get_spans(DrawablePtr drawable, } } xfree(temp_dst); + return; + +fail: + free(temp_dst); + glamor_fallback("glamor_get_spans() from %p (%c)\n", drawable, + glamor_get_drawable_location(drawable)); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) { + fbGetSpans(drawable, wmax, points, widths, count, dst); + glamor_finish_access(drawable); + } } From 745502af962a2bb475c0c667c3091c2c080771dc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 13:27:47 +0100 Subject: [PATCH 060/225] glamor: Add check for EXT_bgra which we rely on. --- glamor/glamor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index 507a19be4..a2cd02a6a 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -181,6 +181,10 @@ glamor_init(ScreenPtr screen) ErrorF("GL_ARB_pixel_buffer_object required\n"); goto fail; } + if (!GLEW_EXT_bgra) { + ErrorF("GL_EXT_bgra required\n"); + goto fail; + } if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, From d8d3fa10346302384b8e62967c5a67893ed1c67b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 14:53:41 +0100 Subject: [PATCH 061/225] glamor: All the fallbacks in the world. Bringup is really not flying when I can't see anything. So dump back to all software so I can turn on a bit at a time. --- glamor/glamor_copyarea.c | 2 ++ glamor/glamor_fill.c | 2 ++ glamor/glamor_fillspans.c | 13 +++++++++++++ glamor/glamor_getspans.c | 2 ++ glamor/glamor_polyfillrect.c | 15 +++++++++++++++ glamor/glamor_putimage.c | 2 ++ glamor/glamor_render.c | 2 ++ glamor/glamor_setspans.c | 2 ++ 8 files changed, 40 insertions(+) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 077c44ffd..b0f6a7e2f 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -79,6 +79,8 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); RegionPtr region; + goto fail; + if (!GLEW_EXT_framebuffer_blit) { glamor_fallback("glamor_copy_area(): " "EXT_framebuffer_blit unsupported\n"); diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 6290f1210..b3418a91d 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -42,6 +42,8 @@ glamor_fill(DrawablePtr drawable, { PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); + assert(0); + switch (gc->fillStyle) { case FillSolid: glamor_solid(dst_pixmap, diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index 120e3467d..9b070eced 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -45,6 +45,8 @@ glamor_fill_spans(DrawablePtr drawable, int fullX1, fullX2, fullY1; int partX1, partX2; + goto fail; + extents = REGION_EXTENTS(gc->pScreen, clip); extentX1 = extents->x1; extentY1 = extents->y1; @@ -97,4 +99,15 @@ glamor_fill_spans(DrawablePtr drawable, } } } + return; +fail: + glamor_fallback("to %p (%c)\n", drawable, + glamor_get_drawable_location(drawable)); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_gc(gc)) { + fbFillSpans(drawable, gc, n, points, widths, sorted); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable); + } } diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 8339eb130..6e92b4d0b 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -56,6 +56,8 @@ glamor_get_spans(DrawablePtr drawable, int i, j; uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst; + goto fail; + switch (drawable->depth) { case 1: temp_dst = xalloc(wmax); diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index ae8963dac..dc3c0e69a 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -52,6 +52,8 @@ glamor_poly_fill_rect(DrawablePtr drawable, int xorg, yorg; int n; + goto fail; + xorg = drawable->x; yorg = drawable->y; @@ -115,4 +117,17 @@ glamor_poly_fill_rect(DrawablePtr drawable, } } } + return; + +fail: + glamor_fallback("glamor_poly_fill_rect() to %p (%c)\n", + drawable, glamor_get_drawable_location(drawable)); + + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_gc(gc)) { + fbPolyFillRect(drawable, gc, nrect, prect ); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable); + } } diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 39f120eca..537992101 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -245,6 +245,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int bpp = drawable->bitsPerPixel; int src_stride = PixmapBytePad(w, drawable->depth); + goto fail; + if (!glamor_set_destination_pixmap(pixmap)) { fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format, bits); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index b6f6b86cb..f9e7341c1 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -424,6 +424,8 @@ glamor_composite(CARD8 op, RegionRec region; int i; + goto fail; + /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. */ diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 0bd0ac1c2..32f7bc515 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -43,6 +43,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, RegionPtr clip = fbGetCompositeClip(gc); BoxRec *pbox; + goto fail; + for (i = 0 ; i < n; i++) { if (wmax < widths[i]) wmax = widths[i]; From 45de3d24b44aa3feabdda0e377d637f498e03eb0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 14:40:06 +0100 Subject: [PATCH 062/225] glamor: Replace the glDrawPixels in glamor_finish_access with GLSL. Root weave displays. \o/ --- glamor/glamor.c | 1 + glamor/glamor_core.c | 88 +++++++++++++++++++++++++++++++++++++++++++- glamor/glamor_priv.h | 4 ++ 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index a2cd02a6a..ba16d63fc 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -224,6 +224,7 @@ glamor_init(ScreenPtr screen) glamor_init_tile_shader(screen); glamor_init_putimage_shaders(screen); glamor_init_composite_shaders(screen); + glamor_init_finish_access_shaders(screen); return TRUE; diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 9d0e40f44..f35baafa0 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -378,13 +378,67 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) return TRUE; } +void +glamor_init_finish_access_shaders(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + const char *vs_source = + "void main()\n" + "{\n" + " gl_Position = gl_Vertex;\n" + " gl_TexCoord[0] = gl_MultiTexCoord0;\n" + "}\n"; + const char *fs_source = + "varying vec2 texcoords;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" + "}\n"; + GLint fs_prog, vs_prog; + + glamor_priv->finish_access_prog = glCreateProgramObjectARB(); + if (GLEW_ARB_fragment_shader) { + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source); + glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); + glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog); + } else { + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); + glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); + } + + glamor_link_glsl_prog(glamor_priv->finish_access_prog); + + if (GLEW_ARB_fragment_shader) { + GLint sampler_uniform_location; + + sampler_uniform_location = + glGetUniformLocationARB(glamor_priv->finish_access_prog, "sampler"); + glUseProgramObjectARB(glamor_priv->finish_access_prog); + glUniform1iARB(sampler_uniform_location, 0); + glUseProgramObjectARB(0); + } +} + void glamor_finish_access(DrawablePtr drawable) { + glamor_screen_private *glamor_priv = + glamor_get_screen_private(drawable->pScreen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); unsigned int stride; GLenum format, type; + static float vertices[4][2] = {{-1, -1}, + { 1, -1}, + { 1, 1}, + {-1, 1}}; + static float texcoords[4][2] = {{0, 1}, + {1, 1}, + {1, 0}, + {0, 0}}; + GLuint tex; if (pixmap_priv == NULL) return; @@ -397,6 +451,10 @@ glamor_finish_access(DrawablePtr drawable) return; } + /* Check if finish_access was already called once on this */ + if (pixmap->devPrivate.ptr == NULL) + return; + switch (drawable->depth) { case 1: format = GL_COLOR_INDEX; @@ -420,18 +478,44 @@ glamor_finish_access(DrawablePtr drawable) stride = PixmapBytePad(pixmap->drawable.width, drawable->depth); + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 / pixmap->drawable.bitsPerPixel); - glRasterPos2i(0, 0); - glDrawPixels(pixmap->drawable.width, pixmap->drawable.height, + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + pixmap->drawable.width, pixmap->drawable.height, 0, format, type, pixmap->devPrivate.ptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEnable(GL_TEXTURE_2D); + + assert(GLEW_ARB_fragment_shader); + glUseProgramObjectARB(glamor_priv->finish_access_prog); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisable(GL_TEXTURE_2D); + glUseProgramObjectARB(0); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDeleteTextures(1, &tex); xfree(pixmap->devPrivate.ptr); pixmap->devPrivate.ptr = NULL; } + /** * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the * current fill style. diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 2045ed691..dc3b77860 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -63,6 +63,9 @@ typedef struct glamor_screen_private { ChangeWindowAttributesProcPtr saved_change_window_attributes; BitmapToRegionProcPtr saved_bitmap_to_region; + /* glamor_finishaccess */ + GLint finish_access_prog; + /* glamor_solid */ GLint solid_prog; GLint solid_color_uniform_location; @@ -142,6 +145,7 @@ 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); const Bool glamor_get_drawable_location(const DrawablePtr drawable); Bool glamor_create_gc(GCPtr gc); void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, From c3c3a6349766b4fdee080ff203fb548725e42e50 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 15:34:45 +0100 Subject: [PATCH 063/225] glamor: Use the pixmap stride in fallbacks instead of trying to guess it. Mostly fixes gnome-terminal text. --- glamor/glamor_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index f35baafa0..4d03bd718 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -293,7 +293,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) return TRUE; } - stride = PixmapBytePad(pixmap->drawable.width, drawable->depth); + stride = pixmap->devKind; read_stride = stride; data = xalloc(stride * pixmap->drawable.height); @@ -476,7 +476,7 @@ glamor_finish_access(DrawablePtr drawable) return; } - stride = PixmapBytePad(pixmap->drawable.width, drawable->depth); + stride = pixmap->devKind; glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); From 5332547a0ac6ae6b9f1a6c6428e6fdbdf303108f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 17:14:34 +0100 Subject: [PATCH 064/225] glamor: Fix prepare_access on 1bpp data. Apparently I don't have anything hitting this path, so I'm not sure if it's good or not. --- glamor/glamor_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 4d03bd718..4ec8540f0 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -351,15 +351,16 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) for (y = 0; y < pixmap->drawable.height; y++) { uint8_t *read_row = read + read_stride * (pixmap->drawable.height - y - 1); + uint8_t *write_row = data + y * stride; for (x = 0; x < pixmap->drawable.width; x++) { int index = x / 8; int bit = 1 << (x % 8); if (read_row[x]) - data[index] |= bit; + write_row[index] |= bit; else - data[index] &= ~bit; + write_row[index] &= ~bit; } } } else { From 95d4a5a6ab58625d8205461157263bfb635ccd1a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 19:38:00 +0100 Subject: [PATCH 065/225] glamor: Enable fill acceleration and flip opposite for pixmaps too. Here's my theory for the flipping: It doesn't really matter which orientation we store the pixmaps if we don't scan them out. We have to flip coordinates for the window system framebuffer. Doing so for everything else makes things consistent. I'm not sure how this will interact with future GLX integration, though. --- glamor/glamor_core.c | 7 +------ glamor/glamor_fill.c | 2 -- glamor/glamor_polyfillrect.c | 3 ++- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 4ec8540f0..ca7add4ac 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -177,12 +177,7 @@ glamor_set_transform_for_pixmap(PixmapPtr pixmap, glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); - if (pixmap == screen_pixmap) - glUniform1fARB(uniform_locations->y_scale, - -2.0f / pixmap->drawable.height); - else - glUniform1fARB(uniform_locations->y_scale, - 2.0f / pixmap->drawable.height); + glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); } GLint diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index b3418a91d..6290f1210 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -42,8 +42,6 @@ glamor_fill(DrawablePtr drawable, { PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); - assert(0); - switch (gc->fillStyle) { case FillSolid: glamor_solid(dst_pixmap, diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index dc3c0e69a..62e0a0fe4 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -52,7 +52,8 @@ glamor_poly_fill_rect(DrawablePtr drawable, int xorg, yorg; int n; - goto fail; + if (gc->fillStyle != FillSolid) + goto fail; xorg = drawable->x; yorg = drawable->y; From 647b9fb49a5bb636c9b0da6b708083328238543a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 20:12:44 +0100 Subject: [PATCH 066/225] glamor: Add CopyWindow implementation so it doesn't crash. --- glamor/Makefile.am | 1 + glamor/glamor.c | 4 +++ glamor/glamor_copyarea.c | 18 ++++++++++-- glamor/glamor_copywindow.c | 60 ++++++++++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 18 ++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 glamor/glamor_copywindow.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index ce7869244..17139c09f 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -18,6 +18,7 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ glamor_copyarea.c \ + glamor_copywindow.c \ glamor_core.c \ glamor_fill.c \ glamor_fillspans.c \ diff --git a/glamor/glamor.c b/glamor/glamor.c index ba16d63fc..7bb093474 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -210,6 +210,9 @@ glamor_init(ScreenPtr screen) glamor_priv->saved_change_window_attributes = screen->ChangeWindowAttributes; screen->ChangeWindowAttributes = glamor_change_window_attributes; + glamor_priv->saved_copy_window = screen->CopyWindow; + screen->CopyWindow = glamor_copy_window; + glamor_priv->saved_bitmap_to_region = screen->BitmapToRegion; screen->BitmapToRegion = glamor_bitmap_to_region; @@ -247,6 +250,7 @@ glamor_fini(ScreenPtr screen) screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; screen->GetSpans = glamor_priv->saved_get_spans; screen->ChangeWindowAttributes = glamor_priv->saved_change_window_attributes; + screen->CopyWindow = glamor_priv->saved_copy_window; screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region; #ifdef RENDER ps->Composite = glamor_priv->saved_composite; diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index b0f6a7e2f..7f14f2a4c 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -32,7 +32,7 @@ * GC CopyArea implementation */ -static void +void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, @@ -49,6 +49,8 @@ glamor_copy_n_to_n(DrawablePtr src, PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int i; + goto fail; + glamor_set_alu(gc->alu); if (!glamor_set_planemask(dst_pixmap, gc->planemask)) goto fail; @@ -64,6 +66,18 @@ glamor_copy_n_to_n(DrawablePtr src, } fail: + glamor_fallback("from %p to %p (%c,%c)\n", src, dst, + glamor_get_drawable_location(src), + glamor_get_drawable_location(dst)); + if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + fbCopyNtoN(src, dst, gc, box, nbox, + dx, dy, reverse, upsidedown, bitplane, + closure); + glamor_finish_access(src); + } + glamor_finish_access(dst); + } glamor_set_alu(GXcopy); glamor_set_planemask(dst_pixmap, ~0); } @@ -79,8 +93,6 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); RegionPtr region; - goto fail; - if (!GLEW_EXT_framebuffer_blit) { glamor_fallback("glamor_copy_area(): " "EXT_framebuffer_blit unsupported\n"); diff --git a/glamor/glamor_copywindow.c b/glamor/glamor_copywindow.c new file mode 100644 index 000000000..1e840a934 --- /dev/null +++ b/glamor/glamor_copywindow.c @@ -0,0 +1,60 @@ +/* + * Copyright © 2008 Intel Corporation + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +/** @file glamor_copywindow.c + * + * Screen CopyWindow implementation. + */ + +void glamor_copy_window(WindowPtr win, DDXPointRec old_origin, + RegionPtr src_region) +{ + RegionRec dst_region; + int dx, dy; + PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win); + + dx = old_origin.x - win->drawable.x; + dy = old_origin.y - win->drawable.y; + REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy); + + REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0); + + REGION_INTERSECT(win->drawable.pScreen, &dst_region, &win->borderClip, + src_region); +#ifdef COMPOSITE + if (pixmap->screen_x || pixmap->screen_y) + REGION_TRANSLATE(win->drawable.pScreen, &dst_region, + -pixmap->screen_x, -pixmap->screen_y); +#endif + + miCopyRegion(&pixmap->drawable, &pixmap->drawable, + NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL); + + REGION_UNINIT(win->drawable.pScreen, &dst_region); +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index dc3b77860..adc6997cc 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -61,6 +61,7 @@ typedef struct glamor_screen_private { CompositeProcPtr saved_composite; TrapezoidsProcPtr saved_trapezoids; ChangeWindowAttributesProcPtr saved_change_window_attributes; + CopyWindowProcPtr saved_copy_window; BitmapToRegionProcPtr saved_bitmap_to_region; /* glamor_finishaccess */ @@ -138,6 +139,23 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); 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); From 35847c578e9c35a3c90da792c34c1cb0cc536261 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 21:24:15 +0100 Subject: [PATCH 067/225] glamor: Add acceleration for copyarea not from the screen. --- glamor/glamor_copyarea.c | 119 ++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 26 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 7f14f2a4c..e07cf6224 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -32,6 +32,30 @@ * GC CopyArea implementation */ +static float +v_from_x_coord_x(PixmapPtr pixmap, int x) +{ + return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0; +} + +static float +v_from_x_coord_y(PixmapPtr pixmap, int y) +{ + return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0; +} + +static float +t_from_x_coord_x(PixmapPtr pixmap, int x) +{ + return (float)(x - pixmap->screen_x) / pixmap->drawable.width; +} + +static float +t_from_x_coord_y(PixmapPtr pixmap, int y) +{ + return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height; +} + void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, @@ -45,16 +69,78 @@ glamor_copy_n_to_n(DrawablePtr src, Pixel bitplane, void *closure) { + glamor_screen_private *glamor_priv = + glamor_get_screen_private(dst->pScreen); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int i; + float vertices[4][2], texcoords[4][2]; + glamor_pixmap_private *src_pixmap_priv; - goto fail; + src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - glamor_set_alu(gc->alu); - if (!glamor_set_planemask(dst_pixmap, gc->planemask)) + if (src == dst) { + glamor_fallback("glamor_copy_n_to_n with same src/dst\n"); + goto fail; + } + + if (!src_pixmap_priv || !src_pixmap_priv->tex) { + glamor_fallback("glamor_copy_n_to_n with non-texture src\n"); + goto fail; + } + + if (!glamor_set_destination_pixmap(dst_pixmap)) goto fail; + if (gc) { + glamor_set_alu(gc->alu); + if (!glamor_set_planemask(dst_pixmap, gc->planemask)) + goto fail; + } + + glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); + glEnable(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + assert(GLEW_ARB_fragment_shader); + glUseProgramObjectARB(glamor_priv->finish_access_prog); + + for (i = 0; i < nbox; i++) { + vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1); + vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1); + vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2); + vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1); + vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2); + vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2); + vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1); + vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2); + + texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); + texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); + texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); + texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); + texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); + texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); + texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); + texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + + glUseProgramObjectARB(0); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); + +#if 0 for (i = 0; i < nbox; i++) { glRasterPos2i(box[i].x1 - dst_pixmap->screen_x, box[i].y1 - dst_pixmap->screen_y); @@ -64,9 +150,12 @@ glamor_copy_n_to_n(DrawablePtr src, box[i].y2 - box[i].y1, GL_COLOR); } +#endif + + return; fail: - glamor_fallback("from %p to %p (%c,%c)\n", src, dst, + glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { @@ -89,31 +178,9 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, ScreenPtr screen = dst->pScreen; PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); RegionPtr region; - if (!GLEW_EXT_framebuffer_blit) { - glamor_fallback("glamor_copy_area(): " - "EXT_framebuffer_blit unsupported\n"); - goto fail; - } - - if (!glamor_set_destination_pixmap(dst_pixmap)) - goto fail; - - if (src_priv == NULL) { - glamor_fallback("glamor_copy_area(): no src pixmap priv"); - goto fail; - } - - if (src_priv->fb == 0 && src_pixmap != screen_pixmap) { - glamor_fallback("glamor_copy_area(): no src fbo"); - goto fail; - } - - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_priv->fb); - region = miDoCopy(src, dst, gc, srcx, srcy, width, height, dstx, dsty, glamor_copy_n_to_n, 0, NULL); From 4811e428a9206ef59487fb0d3fab160a19845d46 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 21:46:49 +0100 Subject: [PATCH 068/225] glamor: Pull in UXA code for dumping some composites down to copy_n_to_n. Window dragging with metacity+gnome-terminal+xcompmgr is almost credible. --- glamor/glamor_render.c | 57 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index f9e7341c1..a7777fbad 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -399,6 +399,32 @@ glamor_set_composite_solid(PicturePtr picture, GLint uniform_location) glUniform4fvARB(uniform_location, 1, color); } +static int +compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src) +{ + if (op == PictOpSrc) { + if (src->format == dst->format) + return 1; + + if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8) + return 1; + + if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8) + return 1; + } else if (op == PictOpOver) { + if (src->alphaMap || dst->alphaMap) + return 0; + + if (src->format != dst->format) + return 0; + + if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8) + return 1; + } + + return 0; +} + void glamor_composite(CARD8 op, PicturePtr source, @@ -424,8 +450,6 @@ glamor_composite(CARD8 op, RegionRec region; int i; - goto fail; - /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. */ @@ -445,6 +469,35 @@ glamor_composite(CARD8 op, return; } + if (!mask) { + if (compatible_formats (op, dest, source)) { + if (!source->repeat && !source->transform) { + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + x_source += source->pDrawable->x; + y_source += source->pDrawable->y; + + if (!miComputeCompositeRegion + (®ion, + source, NULL, dest, + x_source, y_source, 0, 0, x_dest, y_dest, width, height)) + return; + + glamor_copy_n_to_n(source->pDrawable, + dest->pDrawable, NULL, + REGION_RECTS(®ion), + REGION_NUM_RECTS(®ion), + x_source - x_dest, y_source - y_dest, + FALSE, FALSE, 0, NULL); + REGION_UNINIT(dest->pDrawable->pScreen, + ®ion); + return; + } + } + } + + goto fail; + memset(&key, 0, sizeof(key)); key.has_mask = (mask != NULL); if (!source->pDrawable) { From ad67299fa2afc8b42432d71d14163a36e013fef7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 21:52:35 +0100 Subject: [PATCH 069/225] glamor: Provide more information about the operands to fallback composites. --- glamor/glamor_render.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index a7777fbad..495f5683f 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -425,6 +425,27 @@ compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src) return 0; } +static char +glamor_get_picture_location(PicturePtr picture) +{ + if (picture == NULL) + return ' '; + + if (picture->pDrawable == NULL) { + switch (picture->pSourcePict->type) { + case SourcePictTypeSolidFill: + return 'c'; + case SourcePictTypeLinear: + return 'l'; + case SourcePictTypeRadial: + return 'r'; + default: + return '?'; + } + } + return glamor_get_drawable_location(picture->pDrawable); +} + void glamor_composite(CARD8 op, PicturePtr source, @@ -627,7 +648,12 @@ glamor_composite(CARD8 op, fail: glamor_fallback("glamor_composite(): " - "from picts %p/%p to pict %p\n", source, mask, dest); + "from picts %p/%p(%c,%c) to pict %p (%c)\n", + source, mask, + glamor_get_picture_location(source), + glamor_get_picture_location(mask), + dest, + glamor_get_picture_location(dest)); glUseProgramObjectARB(0); if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) { From 15e58b5ffb427c6c6f5172ccd72758047b98024a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Feb 2010 22:05:51 +0100 Subject: [PATCH 070/225] glamor: Split the copy path out into its own function. --- glamor/glamor_render.c | 72 ++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 495f5683f..ba67d7381 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -446,6 +446,49 @@ glamor_get_picture_location(PicturePtr picture) return glamor_get_drawable_location(picture->pDrawable); } +static Bool +glamor_composite_copy(CARD8 op, + PicturePtr source, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_dest, + INT16 y_dest, + CARD16 width, + CARD16 height) +{ + RegionRec region; + + if (!compatible_formats(op, dest, source)) + return FALSE; + + if (source->repeat || source->transform) + return FALSE; + + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + x_source += source->pDrawable->x; + y_source += source->pDrawable->y; + + if (!miComputeCompositeRegion(®ion, + source, NULL, dest, + x_source, y_source, + 0, 0, + x_dest, y_dest, + width, height)) + return TRUE; + + glamor_copy_n_to_n(source->pDrawable, + dest->pDrawable, NULL, + REGION_RECTS(®ion), + REGION_NUM_RECTS(®ion), + x_source - x_dest, y_source - y_dest, + FALSE, FALSE, 0, NULL); + REGION_UNINIT(dest->pDrawable->pScreen, + ®ion); + return TRUE; +} + void glamor_composite(CARD8 op, PicturePtr source, @@ -491,30 +534,11 @@ glamor_composite(CARD8 op, } if (!mask) { - if (compatible_formats (op, dest, source)) { - if (!source->repeat && !source->transform) { - x_dest += dest->pDrawable->x; - y_dest += dest->pDrawable->y; - x_source += source->pDrawable->x; - y_source += source->pDrawable->y; - - if (!miComputeCompositeRegion - (®ion, - source, NULL, dest, - x_source, y_source, 0, 0, x_dest, y_dest, width, height)) - return; - - glamor_copy_n_to_n(source->pDrawable, - dest->pDrawable, NULL, - REGION_RECTS(®ion), - REGION_NUM_RECTS(®ion), - x_source - x_dest, y_source - y_dest, - FALSE, FALSE, 0, NULL); - REGION_UNINIT(dest->pDrawable->pScreen, - ®ion); - return; - } - } + if (glamor_composite_copy(op, source, dest, + x_source, y_source, + x_dest, y_dest, + width, height)) + return; } goto fail; From 4f398b29dd42260d2c02e8e795546fd0623397b1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Feb 2010 21:56:39 -0600 Subject: [PATCH 071/225] glamor: Align stride of fallback pixmap data to 32 bits. fb/pixman demand this alignment, and all sorts of things go badly otherwise. Fixes piglit x11-8bpp-7x8-draw. --- glamor/glamor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 7bb093474..7bc75aa13 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -112,7 +112,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, 0); screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, - (w * pixmap->drawable.bitsPerPixel + 7) / 8, + (((w * pixmap->drawable.bitsPerPixel + + 7) / 8) + 3) & ~3, NULL); return pixmap; From d8c2662bf452a82c8fcbdd1c95a40ee34d2c32ca Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Feb 2010 22:48:28 -0600 Subject: [PATCH 072/225] glamor: Set active texture in finishaccess drawing. --- glamor/glamor_core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index ca7add4ac..b0a64f2ef 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -171,9 +171,6 @@ void glamor_set_transform_for_pixmap(PixmapPtr pixmap, glamor_transform_uniforms *uniform_locations) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); @@ -489,6 +486,7 @@ glamor_finish_access(DrawablePtr drawable) pixmap->drawable.bitsPerPixel); glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, pixmap->drawable.height, 0, From a0b589e90a885cf20b349b95df31bb0823a1514b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Feb 2010 22:49:27 -0600 Subject: [PATCH 073/225] glamor: Restore planemask to all-on when finishing a fill. --- glamor/glamor_fill.c | 1 + 1 file changed, 1 insertion(+) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 6290f1210..1b601ee5d 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -172,6 +172,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glUseProgramObjectARB(0); fail: glamor_set_alu(GXcopy); + glamor_set_planemask(pixmap, ~0); } /* Highlight places where we're doing it wrong. */ From 7e6432e7b94f7f99b257da8de53573108d30ae22 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Feb 2010 22:54:40 -0600 Subject: [PATCH 074/225] glamor: Fix up and enable accelerated composite. --- glamor/glamor_copyarea.c | 28 +-- glamor/glamor_priv.h | 24 +++ glamor/glamor_render.c | 360 ++++++++++++++++++++++++--------------- 3 files changed, 249 insertions(+), 163 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index e07cf6224..695edc3e9 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -32,30 +32,6 @@ * GC CopyArea implementation */ -static float -v_from_x_coord_x(PixmapPtr pixmap, int x) -{ - return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0; -} - -static float -v_from_x_coord_y(PixmapPtr pixmap, int y) -{ - return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0; -} - -static float -t_from_x_coord_x(PixmapPtr pixmap, int x) -{ - return (float)(x - pixmap->screen_x) / pixmap->drawable.width; -} - -static float -t_from_x_coord_y(PixmapPtr pixmap, int y) -{ - return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height; -} - void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, @@ -175,10 +151,12 @@ RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty) { +#if 0 ScreenPtr screen = dst->pScreen; PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); +#endif RegionPtr region; region = miDoCopy(src, dst, gc, @@ -187,6 +165,7 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, return region; +#if 0 fail: glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), @@ -201,4 +180,5 @@ fail: glamor_finish_access(dst); } return region; +#endif } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index adc6997cc..526b2cf3a 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -132,6 +132,30 @@ glamor_fallback(char *format, ...) va_end(ap); } +static inline float +v_from_x_coord_x(PixmapPtr pixmap, int x) +{ + return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0; +} + +static inline float +v_from_x_coord_y(PixmapPtr pixmap, int y) +{ + return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0; +} + +static inline float +t_from_x_coord_x(PixmapPtr pixmap, int x) +{ + return (float)(x - pixmap->screen_x) / pixmap->drawable.width; +} + +static inline float +t_from_x_coord_y(PixmapPtr pixmap, int y) +{ + return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height; +} + /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index ba67d7381..be28bd4e0 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -94,23 +94,20 @@ static GLuint glamor_create_composite_fs(struct shader_key *key) { const char *source_pixmap_header = - "uniform sampler2D source_sampler;\n" - "varying vec4 source_coords;\n"; + "uniform sampler2D source_sampler;\n"; const char *source_solid_header = "uniform vec4 source;\n"; const char *mask_pixmap_header = - "uniform sampler2D mask_sampler;\n" - "varying vec4 mask_coords;\n"; + "uniform sampler2D mask_sampler;\n"; const char *mask_solid_header = "uniform vec4 mask;\n"; const char *main_opening = "void main()\n" "{\n"; const char *source_pixmap_fetch = - " vec4 source = texture2DProj(source_sampler, " - " source_coords.xyw);\n"; + " vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n"; const char *mask_pixmap_fetch = - " vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n"; + " vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n"; const char *source_in_mask = " gl_FragColor = source * mask.w;\n"; const char *source_only = @@ -156,30 +153,20 @@ glamor_create_composite_fs(struct shader_key *key) static GLuint glamor_create_composite_vs(struct shader_key *key) { - const char *header = - "uniform mat4 dest_to_dest;\n" - "uniform mat4 dest_to_source;\n" - "varying vec4 source_coords;\n"; - const char *mask_header = - "uniform mat4 dest_to_mask;\n" - "varying vec4 mask_coords;\n"; const char *main_opening = "void main()\n" "{\n" - " vec4 incoming_dest_coords = vec4(gl_Vertex.xy, 0, 1);\n" - " gl_Position = dest_to_dest * incoming_dest_coords;\n" - " source_coords = dest_to_source * incoming_dest_coords;\n"; + " gl_Position = gl_Vertex;\n" + " gl_TexCoord[0] = gl_MultiTexCoord0;\n"; const char *mask_coords = - " mask_coords = dest_to_mask * incoming_dest_coords;\n"; + " gl_TexCoord[1] = gl_MultiTexCoord1;\n"; const char *main_closing = "}\n"; char *source; GLuint prog; Bool compute_mask_coords = key->has_mask && !key->solid_mask; - source = XNFprintf("%s%s%s%s%s", - header, - compute_mask_coords ? mask_header : "", + source = XNFprintf("%s%s%s", main_opening, compute_mask_coords ? mask_coords : "", main_closing); @@ -214,8 +201,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) shader->prog = prog; glUseProgramObjectARB(prog); - shader->dest_to_dest_uniform_location = - glGetUniformLocationARB(prog, "dest_to_dest"); if (key->solid_source) { shader->source_uniform_location = glGetUniformLocationARB(prog, @@ -223,8 +208,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) } else { source_sampler_uniform_location = glGetUniformLocationARB(prog, "source_sampler"); - shader->dest_to_source_uniform_location = - glGetUniformLocationARB(prog, "dest_to_source"); glUniform1i(source_sampler_uniform_location, 0); } @@ -236,8 +219,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) mask_sampler_uniform_location = glGetUniformLocationARB(prog, "mask_sampler"); glUniform1i(mask_sampler_uniform_location, 1); - shader->dest_to_mask_uniform_location = - glGetUniformLocationARB(prog, "dest_to_mask"); } } } @@ -255,6 +236,7 @@ glamor_init_composite_shaders(ScreenPtr screen) key.solid_mask = TRUE; glamor_create_composite_shader(screen, &key); + memset(&key, 0, sizeof(key)); key.solid_source = TRUE; key.has_mask = FALSE; glamor_create_composite_shader(screen, &key); @@ -264,24 +246,6 @@ glamor_init_composite_shaders(ScreenPtr screen) glamor_create_composite_shader(screen, &key); } -static void -glamor_set_composite_transform_matrix(GLUmat4 *m, - PicturePtr picture, - float x_source, - float y_source) -{ - GLUmat4 temp; - DrawablePtr drawable = picture->pDrawable; - GLUvec4 scale = {{1.0f / drawable->width, - 1.0f / drawable->height, - 1.0, - 1.0}}; - - gluTranslate3f(m, -x_source, -y_source, 0.0); - gluScale4v(&temp, &scale); - gluMult4m_4m(m, &temp, m); -} - static Bool glamor_set_composite_op(ScreenPtr screen, CARD8 op, PicturePtr dest, PicturePtr mask) @@ -298,10 +262,6 @@ glamor_set_composite_op(ScreenPtr screen, source_blend = op_info->source_blend; dest_blend = op_info->dest_blend; - if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 && - op_info->source_alpha && source_blend != GL_ZERO) { - } - /* If there's no dst alpha channel, adjust the blend op so that we'll treat * it as always 1. */ @@ -336,12 +296,8 @@ glamor_set_composite_op(ScreenPtr screen, static void glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, - glamor_pixmap_private *pixmap_priv, - GLint transform_uniform_location, - int x_translate, int y_translate) + glamor_pixmap_private *pixmap_priv) { - GLUmat4 transform; - glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); switch (picture->repeatType) { @@ -376,13 +332,6 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, } glEnable(GL_TEXTURE_2D); - - glamor_set_composite_transform_matrix(&transform, - picture, - x_translate, - y_translate); - glUniformMatrix4fvARB(transform_uniform_location, 1, 0, - (float *)&transform); } static void @@ -447,15 +396,15 @@ glamor_get_picture_location(PicturePtr picture) } static Bool -glamor_composite_copy(CARD8 op, - PicturePtr source, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_dest, - INT16 y_dest, - CARD16 width, - CARD16 height) +glamor_composite_with_copy(CARD8 op, + PicturePtr source, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_dest, + INT16 y_dest, + CARD16 width, + CARD16 height) { RegionRec region; @@ -489,19 +438,59 @@ glamor_composite_copy(CARD8 op, return TRUE; } -void -glamor_composite(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, - INT16 y_dest, - CARD16 width, - CARD16 height) +static Bool +good_source_format(PicturePtr picture) +{ + switch (picture->format) { + case PICT_a8: + case PICT_a8r8g8b8: + return TRUE; + default: + glamor_fallback("Bad source format 0x%08x\n", picture->format); + return FALSE; + } +} + +static Bool +good_mask_format(PicturePtr picture) +{ + switch (picture->format) { + case PICT_a8: + case PICT_a8r8g8b8: + return TRUE; + default: + glamor_fallback("Bad mask format 0x%08x\n", picture->format); + return FALSE; + } +} + +static Bool +good_dest_format(PicturePtr picture) +{ + switch (picture->format) { + case PICT_a8: + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + return TRUE; + default: + glamor_fallback("Bad dest format 0x%08x\n", picture->format); + return FALSE; + } +} + +static Bool +glamor_composite_with_shader(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, + INT16 y_dest, + CARD16 width, + CARD16 height) { ScreenPtr screen = dest->pDrawable->pScreen; PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); @@ -510,38 +499,10 @@ glamor_composite(CARD8 op, glamor_pixmap_private *mask_pixmap_priv = NULL; struct shader_key key; glamor_composite_shader *shader; - GLUmat4 dest_to_dest; RegionRec region; + float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2]; int i; - - /* Do two-pass PictOpOver componentAlpha, until we enable - * dual source color blending. - */ - if (mask && mask->componentAlpha && op == PictOpOver) { - glamor_composite(PictOpOutReverse, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - glamor_composite(PictOpAdd, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - return; - } - - if (!mask) { - if (glamor_composite_copy(op, source, dest, - x_source, y_source, - x_dest, y_dest, - width, height)) - return; - } - - goto fail; + BoxPtr box; memset(&key, 0, sizeof(key)); key.has_mask = (mask != NULL); @@ -581,6 +542,8 @@ glamor_composite(CARD8 op, glamor_fallback("glamor_composite(): no FBO in source\n"); goto fail; } + if (!good_source_format(source)) + goto fail; } if (mask && !key.solid_mask) { mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); @@ -593,7 +556,11 @@ glamor_composite(CARD8 op, glamor_fallback("glamor_composite(): no FBO in mask\n"); goto fail; } + if (!good_mask_format(mask)) + goto fail; } + if (!good_dest_format(dest)) + goto fail; shader = glamor_lookup_composite_shader(screen, &key); if (shader->prog == 0) { @@ -622,27 +589,16 @@ glamor_composite(CARD8 op, y_mask += mask->pDrawable->y; } - gluOrtho6f(&dest_to_dest, - dest_pixmap->screen_x, dest_pixmap->screen_x + width, - dest_pixmap->screen_y, dest_pixmap->screen_y + height, - -1, 1); - glUniformMatrix4fvARB(shader->dest_to_dest_uniform_location, 1, 0, - (float *)&dest_to_dest); - if (key.solid_source) { glamor_set_composite_solid(source, shader->source_uniform_location); } else { - glamor_set_composite_texture(screen, 0, source, source_pixmap_priv, - shader->dest_to_source_uniform_location, - x_source - x_dest, y_source - y_dest); + glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); } if (key.has_mask) { if (key.solid_mask) { glamor_set_composite_solid(mask, shader->mask_uniform_location); } else { - glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv, - shader->dest_to_mask_uniform_location, - x_mask - x_dest, y_mask - y_dest); + glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); } } @@ -652,25 +608,150 @@ glamor_composite(CARD8 op, x_mask, y_mask, x_dest, y_dest, width, height)) - return; + goto done; - glBegin(GL_QUADS); - for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { - BoxPtr box = ®ION_RECTS(®ion)[i]; - glVertex2i(box->x1, box->y1); - glVertex2i(box->x2, box->y1); - glVertex2i(box->x2, box->y2); - glVertex2i(box->x1, box->y2); + + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + + if (!key.solid_source) { + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); } - glEnd(); + if (key.has_mask && !key.solid_mask) { + glClientActiveTexture(GL_TEXTURE1); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + box = REGION_RECTS(®ion); + for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { + vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1); + vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1); + vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2); + vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1); + vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2); + vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2); + vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1); + vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2); + + if (!key.solid_source) { + int tx1 = box[i].x1 + x_source - x_dest; + int ty1 = box[i].y1 + y_source - y_dest; + int tx2 = box[i].x2 + x_source - x_dest; + int ty2 = box[i].y2 + y_source - y_dest; + source_texcoords[0][0] = t_from_x_coord_x(source_pixmap, tx1); + source_texcoords[0][1] = t_from_x_coord_y(source_pixmap, ty1); + source_texcoords[1][0] = t_from_x_coord_x(source_pixmap, tx2); + source_texcoords[1][1] = t_from_x_coord_y(source_pixmap, ty1); + source_texcoords[2][0] = t_from_x_coord_x(source_pixmap, tx2); + source_texcoords[2][1] = t_from_x_coord_y(source_pixmap, ty2); + source_texcoords[3][0] = t_from_x_coord_x(source_pixmap, tx1); + source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2); + } + + if (key.has_mask && !key.solid_mask) { + int tx1 = box[i].x1 + x_mask - x_dest; + int ty1 = box[i].y1 + y_mask - y_dest; + int tx2 = box[i].x2 + x_mask - x_dest; + int ty2 = box[i].y2 + y_mask - y_dest; + mask_texcoords[0][0] = t_from_x_coord_x(mask_pixmap, tx1); + mask_texcoords[0][1] = t_from_x_coord_y(mask_pixmap, ty1); + mask_texcoords[1][0] = t_from_x_coord_x(mask_pixmap, tx2); + mask_texcoords[1][1] = t_from_x_coord_y(mask_pixmap, ty1); + mask_texcoords[2][0] = t_from_x_coord_x(mask_pixmap, tx2); + mask_texcoords[2][1] = t_from_x_coord_y(mask_pixmap, ty2); + mask_texcoords[3][0] = t_from_x_coord_x(mask_pixmap, tx1); + mask_texcoords[3][1] = t_from_x_coord_y(mask_pixmap, ty2); + } +#if 0 + else memset(mask_texcoords, 0, sizeof(mask_texcoords)); + for (i = 0; i < 4; i++) { + ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) (%04.4f, %04.4f)\n", + i, + source_texcoords[i][0], source_texcoords[i][1], + mask_texcoords[i][0], mask_texcoords[i][1], + vertices[i][0], vertices[i][1]); + } +#endif + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + +done: + REGION_UNINIT(dst->pDrawable->pScreen, ®ion); glDisable(GL_BLEND); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); glUseProgramObjectARB(0); - REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); - - return; + return TRUE; fail: + glDisable(GL_BLEND); + glUseProgramObjectARB(0); + return FALSE; +} + +void +glamor_composite(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, + INT16 y_dest, + CARD16 width, + CARD16 height) +{ + /* Do two-pass PictOpOver componentAlpha, until we enable + * dual source color blending. + */ + if (mask && mask->componentAlpha) + goto fail; + if (mask && mask->componentAlpha && op == PictOpOver) { + glamor_composite(PictOpOutReverse, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + glamor_composite(PictOpAdd, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + return; + } + + if (!mask) { + if (glamor_composite_with_copy(op, source, dest, + x_source, y_source, + x_dest, y_dest, + width, height)) + return; + } + + if (glamor_composite_with_shader(op, source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height)) + return; + glamor_fallback("glamor_composite(): " "from picts %p/%p(%c,%c) to pict %p (%c)\n", source, mask, @@ -678,8 +759,9 @@ fail: glamor_get_picture_location(mask), dest, glamor_get_picture_location(dest)); - +fail: glUseProgramObjectARB(0); + glDisable(GL_BLEND); if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) { if (source->pDrawable == NULL || glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO)) From f4a3194837e640997c0c3a775f48a49800e213c6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Feb 2010 23:17:09 -0600 Subject: [PATCH 075/225] glamor: Add the glyph cache from UXA (de-camelCased). This doesn't yet have an optimized glamor_composite_rects() implementation, but it does triple the speed of x11perf -aa10text. --- glamor/Makefile.am | 1 + glamor/glamor.c | 8 + glamor/glamor_glyphs.c | 877 +++++++++++++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 62 +++ glamor/glamor_render.c | 27 ++ 5 files changed, 975 insertions(+) create mode 100644 glamor/glamor_glyphs.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 17139c09f..e823234ae 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -23,6 +23,7 @@ libglamor_la_SOURCES = \ glamor_fill.c \ glamor_fillspans.c \ glamor_getspans.c \ + glamor_glyphs.c \ glamor_polyfillrect.c \ glamor_polylines.c \ glamor_putimage.c \ diff --git a/glamor/glamor.c b/glamor/glamor.c index 7bc75aa13..03db7ecec 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -222,6 +222,8 @@ glamor_init(ScreenPtr screen) ps->Composite = glamor_composite; glamor_priv->saved_trapezoids = ps->Trapezoids; ps->Trapezoids = glamor_trapezoids; + glamor_priv->saved_glyphs = ps->Glyphs; + ps->Glyphs = glamor_glyphs; #endif glamor_init_solid_shader(screen); @@ -230,6 +232,8 @@ glamor_init(ScreenPtr screen) glamor_init_composite_shaders(screen); glamor_init_finish_access_shaders(screen); + glamor_glyphs_init(screen); + return TRUE; fail: @@ -246,6 +250,8 @@ glamor_fini(ScreenPtr screen) PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif + glamor_glyphs_fini(screen); + screen->CreateGC = glamor_priv->saved_create_gc; screen->CreatePixmap = glamor_priv->saved_create_pixmap; screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; @@ -255,5 +261,7 @@ glamor_fini(ScreenPtr screen) screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region; #ifdef RENDER ps->Composite = glamor_priv->saved_composite; + ps->Trapezoids = glamor_priv->saved_trapezoids; + ps->Glyphs = glamor_priv->saved_glyphs; #endif } diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c new file mode 100644 index 000000000..7b2d13d0f --- /dev/null +++ b/glamor/glamor_glyphs.c @@ -0,0 +1,877 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * Partly based on code Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor + * Based on code by: Keith Packard + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "glamor_priv.h" + +#include "mipict.h" + +#if DEBUG_GLYPH_CACHE +#define DBG_GLYPH_CACHE(a) ErrorF a +#else +#define DBG_GLYPH_CACHE(a) +#endif + +/* Width of the pixmaps we use for the caches; this should be less than + * max texture size of the driver; this may need to actually come from + * the driver. + */ +#define CACHE_PICTURE_WIDTH 1024 + +/* Maximum number of glyphs we buffer on the stack before flushing + * rendering to the mask or destination surface. + */ +#define GLYPH_BUFFER_SIZE 256 + +typedef struct { + PicturePtr source; + glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE]; + int count; +} glamor_glyph_buffer_t; + +typedef enum { + GLAMOR_GLYPH_SUCCESS, /* Glyph added to render buffer */ + GLAMOR_GLYPH_FAIL, /* out of memory, etc */ + GLAMOR_GLYPH_NEED_FLUSH, /* would evict a glyph already in the buffer */ +} glamor_glyph_cache_result_t; + +void glamor_glyphs_init(ScreenPtr screen) +{ + glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); + int i = 0; + + memset(glamor_screen->glyph_caches, 0, sizeof(glamor_screen->glyph_caches)); + + glamor_screen->glyph_caches[i].format = PICT_a8; + glamor_screen->glyph_caches[i].glyph_width = + glamor_screen->glyph_caches[i].glyph_height = 16; + i++; + glamor_screen->glyph_caches[i].format = PICT_a8; + glamor_screen->glyph_caches[i].glyph_width = + glamor_screen->glyph_caches[i].glyph_height = 32; + i++; + glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8; + glamor_screen->glyph_caches[i].glyph_width = + glamor_screen->glyph_caches[i].glyph_height = 16; + i++; + glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8; + glamor_screen->glyph_caches[i].glyph_width = + glamor_screen->glyph_caches[i].glyph_height = 32; + i++; + + assert(i == GLAMOR_NUM_GLYPH_CACHES); + + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { + glamor_screen->glyph_caches[i].columns = + CACHE_PICTURE_WIDTH / glamor_screen->glyph_caches[i].glyph_width; + glamor_screen->glyph_caches[i].size = 256; + glamor_screen->glyph_caches[i].hash_size = 557; + } +} + +static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format) +{ + glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); + int i; + + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { + glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; + + if (cache->format != format) + continue; + + if (cache->picture) { + FreePicture((pointer) cache->picture, (XID) 0); + cache->picture = NULL; + } + + if (cache->hash_entries) { + xfree(cache->hash_entries); + cache->hash_entries = NULL; + } + + if (cache->glyphs) { + xfree(cache->glyphs); + cache->glyphs = NULL; + } + cache->glyph_count = 0; + } +} + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +/* All caches for a single format share a single pixmap for glyph storage, + * allowing mixing glyphs of different sizes without paying a penalty + * for switching between source pixmaps. (Note that for a size of font + * right at the border between two sizes, we might be switching for almost + * every glyph.) + * + * This function allocates the storage pixmap, and then fills in the + * rest of the allocated structures for all caches with the given format. + */ +static Bool glamor_realize_glyph_caches(ScreenPtr screen, unsigned int format) +{ + glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); + int depth = PIXMAN_FORMAT_DEPTH(format); + PictFormatPtr pict_format; + PixmapPtr pixmap; + PicturePtr picture; + CARD32 component_alpha; + int height; + int i; + int error; + + pict_format = PictureMatchFormat(screen, depth, format); + if (!pict_format) + return FALSE; + + /* Compute the total vertical size needed for the format */ + + height = 0; + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { + glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; + int rows; + + if (cache->format != format) + continue; + + cache->y_offset = height; + + rows = (cache->size + cache->columns - 1) / cache->columns; + height += rows * cache->glyph_height; + } + + /* Now allocate the pixmap and picture */ + + pixmap = screen->CreatePixmap(screen, + CACHE_PICTURE_WIDTH, + height, depth, + 0); + if (!pixmap) + return FALSE; + + component_alpha = NeedsComponent(pict_format->format); + picture = CreatePicture(0, &pixmap->drawable, pict_format, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + screen->DestroyPixmap(pixmap); /* picture holds a refcount */ + + if (!picture) + return FALSE; + + /* And store the picture in all the caches for the format */ + + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { + glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; + int j; + + if (cache->format != format) + continue; + + cache->picture = picture; + cache->picture->refcnt++; + cache->hash_entries = xalloc(sizeof(int) * cache->hash_size); + cache->glyphs = + xalloc(sizeof(glamor_cached_glyph_t) * cache->size); + cache->glyph_count = 0; + + if (!cache->hash_entries || !cache->glyphs) + goto bail; + + for (j = 0; j < cache->hash_size; j++) + cache->hash_entries[j] = -1; + + cache->eviction_position = rand() % cache->size; + } + + /* Each cache references the picture individually */ + FreePicture(picture, 0); + return TRUE; + + bail: + glamor_unrealize_glyph_caches(screen, format); + return FALSE; +} + +void glamor_glyphs_fini(ScreenPtr screen) +{ + glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); + int i; + + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { + glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; + + if (cache->picture) + glamor_unrealize_glyph_caches(screen, cache->format); + } +} + +static int +glamor_glyph_cache_hash_lookup(glamor_glyph_cache_t * cache, GlyphPtr glyph) +{ + int slot; + + slot = (*(CARD32 *) glyph->sha1) % cache->hash_size; + + while (TRUE) { /* hash table can never be full */ + int entryPos = cache->hash_entries[slot]; + if (entryPos == -1) + return -1; + + if (memcmp(glyph->sha1, cache->glyphs[entryPos].sha1, + sizeof(glyph->sha1)) == 0) { + return entryPos; + } + + slot--; + if (slot < 0) + slot = cache->hash_size - 1; + } +} + +static void +glamor_glyph_cache_hash_insert(glamor_glyph_cache_t * cache, GlyphPtr glyph, int pos) +{ + int slot; + + memcpy(cache->glyphs[pos].sha1, glyph->sha1, sizeof(glyph->sha1)); + + slot = (*(CARD32 *) glyph->sha1) % cache->hash_size; + + while (TRUE) { /* hash table can never be full */ + if (cache->hash_entries[slot] == -1) { + cache->hash_entries[slot] = pos; + return; + } + + slot--; + if (slot < 0) + slot = cache->hash_size - 1; + } +} + +static void glamor_glyph_cache_hash_remove(glamor_glyph_cache_t * cache, int pos) +{ + int slot; + int emptied_slot = -1; + + slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hash_size; + + while (TRUE) { /* hash table can never be full */ + int entryPos = cache->hash_entries[slot]; + + if (entryPos == -1) + return; + + if (entryPos == pos) { + cache->hash_entries[slot] = -1; + emptied_slot = slot; + } else if (emptied_slot != -1) { + /* See if we can move this entry into the emptied slot, + * we can't do that if if entry would have hashed + * between the current position and the emptied slot. + * (taking wrapping into account). Bad positions + * are: + * + * | XXXXXXXXXX | + * i j + * + * |XXX XXXX| + * j i + * + * i - slot, j - emptied_slot + * + * (Knuth 6.4R) + */ + + int entry_slot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % + cache->hash_size; + + if (!((entry_slot >= slot && entry_slot < emptied_slot) || + (emptied_slot < slot + && (entry_slot < emptied_slot + || entry_slot >= slot)))) { + cache->hash_entries[emptied_slot] = entryPos; + cache->hash_entries[slot] = -1; + emptied_slot = slot; + } + } + + slot--; + if (slot < 0) + slot = cache->hash_size - 1; + } +} + +#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyph_width) +#define CACHE_Y(pos) (cache->y_offset + ((pos) / cache->columns) * cache->glyph_height) + +/* The most efficient thing to way to upload the glyph to the screen + * is to use CopyArea; glamor pixmaps are always offscreen. + */ +static Bool +glamor_glyph_cache_upload_glyph(ScreenPtr screen, + glamor_glyph_cache_t * cache, + int pos, GlyphPtr glyph) +{ + PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum]; + PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable; + PixmapPtr cache_pixmap = (PixmapPtr) cache->picture->pDrawable; + PixmapPtr scratch; + GCPtr gc; + + /* UploadToScreen only works if bpp match */ + if (glyph_pixmap->drawable.bitsPerPixel != + cache_pixmap->drawable.bitsPerPixel) + return FALSE; + + gc = GetScratchGC(cache_pixmap->drawable.depth, screen); + ValidateGC(&cache_pixmap->drawable, gc); + + /* Create a temporary bo to stream the updates to the cache */ + scratch = screen->CreatePixmap(screen, + glyph->info.width, + glyph->info.height, + glyph_pixmap->drawable.depth, + 0); + if (scratch) { + (void)glamor_copy_area(&glyph_pixmap->drawable, + &scratch->drawable, + gc, + 0, 0, + glyph->info.width, glyph->info.height, + 0, 0); + } else { + scratch = glyph_pixmap; + } + + (void)glamor_copy_area(&scratch->drawable, + &cache_pixmap->drawable, + gc, + 0, 0, glyph->info.width, glyph->info.height, + CACHE_X(pos), CACHE_Y(pos)); + + if (scratch != glyph_pixmap) + screen->DestroyPixmap(scratch); + + FreeScratchGC(gc); + + return TRUE; +} + +static glamor_glyph_cache_result_t +glamor_glyph_cache_buffer_glyph(ScreenPtr screen, + glamor_glyph_cache_t * cache, + glamor_glyph_buffer_t * buffer, + GlyphPtr glyph, int x_glyph, int y_glyph) +{ + glamor_composite_rect_t *rect; + int pos; + + if (buffer->source && buffer->source != cache->picture) + return GLAMOR_GLYPH_NEED_FLUSH; + + if (!cache->picture) { + if (!glamor_realize_glyph_caches(screen, cache->format)) + return GLAMOR_GLYPH_FAIL; + } + + DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n", + cache->glyph_width, cache->glyph_height, + cache->format == PICT_a8 ? "A" : "ARGB", + (long)*(CARD32 *) glyph->sha1)); + + pos = glamor_glyph_cache_hash_lookup(cache, glyph); + if (pos != -1) { + DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos)); + } else { + if (cache->glyph_count < cache->size) { + /* Space remaining; we fill from the start */ + pos = cache->glyph_count; + cache->glyph_count++; + DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos)); + + glamor_glyph_cache_hash_insert(cache, glyph, pos); + + } else { + /* Need to evict an entry. We have to see if any glyphs + * already in the output buffer were at this position in + * the cache + */ + + pos = cache->eviction_position; + DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos)); + if (buffer->count) { + int x, y; + int i; + + x = CACHE_X(pos); + y = CACHE_Y(pos); + + for (i = 0; i < buffer->count; i++) { + if (buffer->rects[i].x_src == x + && buffer->rects[i].y_src == y) { + DBG_GLYPH_CACHE((" must flush buffer\n")); + return GLAMOR_GLYPH_NEED_FLUSH; + } + } + } + + /* OK, we're all set, swap in the new glyph */ + glamor_glyph_cache_hash_remove(cache, pos); + glamor_glyph_cache_hash_insert(cache, glyph, pos); + + /* And pick a new eviction position */ + cache->eviction_position = rand() % cache->size; + } + + /* Now actually upload the glyph into the cache picture; if + * we can't do it with UploadToScreen (because the glyph is + * offscreen, etc), we fall back to CompositePicture. + */ + if (!glamor_glyph_cache_upload_glyph(screen, cache, pos, glyph)) { + CompositePicture(PictOpSrc, + GlyphPicture(glyph)[screen->myNum], + None, + cache->picture, + 0, 0, + 0, 0, + CACHE_X(pos), + CACHE_Y(pos), + glyph->info.width, + glyph->info.height); + } + + } + + buffer->source = cache->picture; + + rect = &buffer->rects[buffer->count]; + rect->x_src = CACHE_X(pos); + rect->y_src = CACHE_Y(pos); + rect->x_dst = x_glyph - glyph->info.x; + rect->y_dst = y_glyph - glyph->info.y; + rect->width = glyph->info.width; + rect->height = glyph->info.height; + + buffer->count++; + + return GLAMOR_GLYPH_SUCCESS; +} + +#undef CACHE_X +#undef CACHE_Y + +static glamor_glyph_cache_result_t +glamor_buffer_glyph(ScreenPtr screen, + glamor_glyph_buffer_t *buffer, + GlyphPtr glyph, int x_glyph, int y_glyph) +{ + glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); + unsigned int format = (GlyphPicture(glyph)[screen->myNum])->format; + int width = glyph->info.width; + int height = glyph->info.height; + glamor_composite_rect_t *rect; + PicturePtr source; + int i; + + if (buffer->count == GLYPH_BUFFER_SIZE) + return GLAMOR_GLYPH_NEED_FLUSH; + + if (PICT_FORMAT_BPP(format) == 1) + format = PICT_a8; + + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { + glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; + + if (format == cache->format && + width <= cache->glyph_width && + height <= cache->glyph_height) { + glamor_glyph_cache_result_t result = + glamor_glyph_cache_buffer_glyph(screen, + &glamor_screen->glyph_caches[i], + buffer, + glyph, x_glyph, + y_glyph); + switch (result) { + case GLAMOR_GLYPH_FAIL: + break; + case GLAMOR_GLYPH_SUCCESS: + case GLAMOR_GLYPH_NEED_FLUSH: + return result; + } + } + } + + /* Couldn't find the glyph in the cache, use the glyph picture directly */ + + source = GlyphPicture(glyph)[screen->myNum]; + if (buffer->source && buffer->source != source) + return GLAMOR_GLYPH_NEED_FLUSH; + + buffer->source = source; + + rect = &buffer->rects[buffer->count]; + rect->x_src = 0; + rect->y_src = 0; + rect->x_dst = x_glyph - glyph->info.x; + rect->y_dst = y_glyph - glyph->info.y; + rect->width = glyph->info.width; + rect->height = glyph->info.height; + + buffer->count++; + + return GLAMOR_GLYPH_SUCCESS; +} + +static void glamor_glyphs_to_mask(PicturePtr mask, + glamor_glyph_buffer_t *buffer) +{ + glamor_composite_rects(PictOpAdd, buffer->source, mask, + buffer->count, buffer->rects); + + buffer->count = 0; + buffer->source = NULL; +} + +static void +glamor_glyphs_to_dst(CARD8 op, + PicturePtr src, + PicturePtr dst, + glamor_glyph_buffer_t *buffer, + INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst) +{ + int i; + + for (i = 0; i < buffer->count; i++) { + glamor_composite_rect_t *rect = &buffer->rects[i]; + + CompositePicture(op, + src, + buffer->source, + dst, + x_src + rect->x_dst - x_dst, + y_src + rect->y_dst - y_dst, + rect->x_src, + rect->y_src, + rect->x_dst, + rect->y_dst, rect->width, rect->height); + } + + buffer->count = 0; + buffer->source = NULL; +} + +/* Cut and paste from render/glyph.c - probably should export it instead */ +static void +glamor_glyph_extents(int nlist, + GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents) +{ + int x1, x2, y1, y2; + int n; + GlyphPtr glyph; + int x, y; + + x = 0; + y = 0; + extents->x1 = MAXSHORT; + extents->x2 = MINSHORT; + extents->y1 = MAXSHORT; + extents->y2 = MINSHORT; + while (nlist--) { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) { + glyph = *glyphs++; + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + if (x1 < extents->x1) + extents->x1 = x1; + if (x2 > extents->x2) + extents->x2 = x2; + if (y1 < extents->y1) + extents->y1 = y1; + if (y2 > extents->y2) + extents->y2 = y2; + x += glyph->info.xOff; + y += glyph->info.yOff; + } + } +} + +/** + * Returns TRUE if the glyphs in the lists intersect. Only checks based on + * bounding box, which appears to be good enough to catch most cases at least. + */ +static Bool +glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) +{ + int x1, x2, y1, y2; + int n; + GlyphPtr glyph; + int x, y; + BoxRec extents; + Bool first = TRUE; + + x = 0; + y = 0; + extents.x1 = 0; + extents.y1 = 0; + extents.x2 = 0; + extents.y2 = 0; + while (nlist--) { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) { + glyph = *glyphs++; + + if (glyph->info.width == 0 || glyph->info.height == 0) { + x += glyph->info.xOff; + y += glyph->info.yOff; + continue; + } + + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + + if (first) { + extents.x1 = x1; + extents.y1 = y1; + extents.x2 = x2; + extents.y2 = y2; + first = FALSE; + } else { + if (x1 < extents.x2 && x2 > extents.x1 && + y1 < extents.y2 && y2 > extents.y1) { + return TRUE; + } + + if (x1 < extents.x1) + extents.x1 = x1; + if (x2 > extents.x2) + extents.x2 = x2; + if (y1 < extents.y1) + extents.y1 = y1; + if (y2 > extents.y2) + extents.y2 = y2; + } + x += glyph->info.xOff; + y += glyph->info.yOff; + } + } + + return FALSE; +} + +void +glamor_glyphs(CARD8 op, + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs) +{ + PicturePtr picture; + PixmapPtr mask_pixmap = 0; + PicturePtr mask; + ScreenPtr screen = dst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int x_dst = list->xOff, y_dst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = { 0, 0, 0, 0 }; + CARD32 component_alpha; + glamor_glyph_buffer_t buffer; + + /* If we don't have a mask format but all the glyphs have the same format + * and don't intersect, use the glyph format as mask format for the full + * benefits of the glyph cache. + */ + if (!mask_format) { + Bool same_format = TRUE; + int i; + + mask_format = list[0].format; + + for (i = 0; i < nlist; i++) { + if (mask_format->format != list[i].format->format) { + same_format = FALSE; + break; + } + } + + if (!same_format || (mask_format->depth != 1 && + glamor_glyphs_intersect(nlist, list, + glyphs))) { + mask_format = NULL; + } + } + + if (mask_format) { + GCPtr gc; + xRectangle rect; + + glamor_glyph_extents(nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + + if (mask_format->depth == 1) { + PictFormatPtr a8Format = + PictureMatchFormat(screen, 8, PICT_a8); + + if (a8Format) + mask_format = a8Format; + } + + mask_pixmap = screen->CreatePixmap(screen, width, height, + mask_format->depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!mask_pixmap) + return; + component_alpha = NeedsComponent(mask_format->format); + mask = CreatePicture(0, &mask_pixmap->drawable, + mask_format, CPComponentAlpha, + &component_alpha, serverClient, &error); + if (!mask) { + screen->DestroyPixmap(mask_pixmap); + return; + } + gc = GetScratchGC(mask_pixmap->drawable.depth, screen); + ValidateGC(&mask_pixmap->drawable, gc); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + gc->ops->PolyFillRect(&mask_pixmap->drawable, gc, 1, &rect); + FreeScratchGC(gc); + x = -extents.x1; + y = -extents.y1; + } else { + mask = dst; + x = 0; + y = 0; + } + buffer.count = 0; + buffer.source = NULL; + while (nlist--) { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) { + glyph = *glyphs++; + picture = GlyphPicture(glyph)[screen->myNum]; + + if (glyph->info.width > 0 && glyph->info.height > 0 && + glamor_buffer_glyph(screen, &buffer, glyph, x, + y) == GLAMOR_GLYPH_NEED_FLUSH) { + if (mask_format) + glamor_glyphs_to_mask(mask, &buffer); + else + glamor_glyphs_to_dst(op, src, dst, + &buffer, x_src, y_src, + x_dst, y_dst); + + glamor_buffer_glyph(screen, &buffer, glyph, x, y); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + + if (buffer.count) { + if (mask_format) + glamor_glyphs_to_mask(mask, &buffer); + else + glamor_glyphs_to_dst(op, src, dst, &buffer, + x_src, y_src, x_dst, y_dst); + } + + if (mask_format) { + x = extents.x1; + y = extents.y1; + CompositePicture(op, + src, + mask, + dst, + x_src + x - x_dst, + y_src + y - y_dst, 0, 0, x, y, width, height); + FreePicture(mask, 0); + screen->DestroyPixmap(mask_pixmap); + } +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 526b2cf3a..dc1a5ca87 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -31,6 +31,10 @@ #include "glamor.h" #include +#ifdef RENDER +#include "glyphstr.h" +#endif + typedef enum glamor_access { GLAMOR_ACCESS_RO, GLAMOR_ACCESS_RW, @@ -52,6 +56,48 @@ typedef struct glamor_composite_shader { GLint mask_uniform_location; } glamor_composite_shader; +typedef struct { + INT16 x_src; + INT16 y_src; + INT16 x_dst; + INT16 y_dst; + INT16 width; + INT16 height; +} glamor_composite_rect_t; + +typedef struct { + unsigned char sha1[20]; +} glamor_cached_glyph_t; + +typedef struct { + /* The identity of the cache, statically configured at initialization */ + unsigned int format; + int glyph_width; + int glyph_height; + + /* Size of cache; eventually this should be dynamically determined */ + int size; + + /* Hash table mapping from glyph sha1 to position in the glyph; we use + * open addressing with a hash table size determined based on size and large + * enough so that we always have a good amount of free space, so we can + * use linear probing. (Linear probing is preferrable to double hashing + * here because it allows us to easily remove entries.) + */ + int *hash_entries; + int hash_size; + + glamor_cached_glyph_t *glyphs; + int glyph_count; /* Current number of glyphs */ + + PicturePtr picture; /* Where the glyphs of the cache are stored */ + int y_offset; /* y location within the picture where the cache starts */ + int columns; /* Number of columns the glyphs are layed out in */ + int eviction_position; /* Next random position to evict a glyph */ +} glamor_glyph_cache_t; + +#define GLAMOR_NUM_GLYPH_CACHES 4 + typedef struct glamor_screen_private { CreateGCProcPtr saved_create_gc; CreatePixmapProcPtr saved_create_pixmap; @@ -60,6 +106,7 @@ typedef struct glamor_screen_private { GetImageProcPtr saved_get_image; CompositeProcPtr saved_composite; TrapezoidsProcPtr saved_trapezoids; + GlyphsProcPtr saved_glyphs; ChangeWindowAttributesProcPtr saved_change_window_attributes; CopyWindowProcPtr saved_copy_window; BitmapToRegionProcPtr saved_bitmap_to_region; @@ -84,6 +131,8 @@ typedef struct glamor_screen_private { /* glamor_composite */ glamor_composite_shader composite_shader[8]; + + glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; } glamor_screen_private; typedef struct glamor_pixmap_private { @@ -241,6 +290,16 @@ glamor_get_spans(DrawablePtr drawable, int nspans, char *dst_start); +/* glamor_glyphs.c */ +void glamor_glyphs_init(ScreenPtr screen); +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); @@ -281,6 +340,9 @@ void glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps); void glamor_init_composite_shaders(ScreenPtr screen); +void glamor_composite_rects(CARD8 op, + PicturePtr src, PicturePtr dst, + int nrect, glamor_composite_rect_t *rects); /* glamor_tile.c */ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile, diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index be28bd4e0..e4a9441a4 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -921,4 +921,31 @@ glamor_trapezoids(CARD8 op, FreePicture(picture, 0); } +void +glamor_composite_rects(CARD8 op, + PicturePtr src, PicturePtr dst, + int nrect, glamor_composite_rect_t *rects) +{ + int n; + glamor_composite_rect_t *r; + + ValidatePicture(src); + ValidatePicture(dst); + + n = nrect; + r = rects; + + while (n--) { + CompositePicture(op, + src, + NULL, + dst, + r->x_src, r->y_src, + 0, 0, + r->x_dst, r->y_dst, + r->width, r->height); + r++; + } +} + #endif /* RENDER */ From 126fc09cb5bf8c38b73f1c2cd2a0ef588c3265e8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Feb 2010 22:35:04 -0800 Subject: [PATCH 076/225] glamor: Rework the Render shader setup to be easily modified, like cairo-gl. --- glamor/glamor_priv.h | 16 +++- glamor/glamor_render.c | 181 +++++++++++++++++++++-------------------- 2 files changed, 108 insertions(+), 89 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index dc1a5ca87..95aad7da1 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -98,6 +98,19 @@ typedef struct { #define GLAMOR_NUM_GLYPH_CACHES 4 +enum shader_source { + SHADER_SOURCE_SOLID, + SHADER_SOURCE_TEXTURE_ALPHA, + SHADER_SOURCE_COUNT, +}; + +enum shader_mask { + SHADER_MASK_NONE, + SHADER_MASK_SOLID, + SHADER_MASK_TEXTURE_ALPHA, + SHADER_MASK_COUNT, +}; + typedef struct glamor_screen_private { CreateGCProcPtr saved_create_gc; CreatePixmapProcPtr saved_create_pixmap; @@ -130,7 +143,8 @@ typedef struct glamor_screen_private { GLint put_image_xybitmap_bg_uniform_location; /* glamor_composite */ - glamor_composite_shader composite_shader[8]; + glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] + [SHADER_MASK_COUNT]; glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; } glamor_screen_private; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index e4a9441a4..f432b5f29 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -39,9 +39,8 @@ #include "glu3/glu3.h" struct shader_key { - Bool solid_source; - Bool has_mask; - Bool solid_mask; + enum shader_source source; + enum shader_mask mask; }; struct blendinfo { @@ -67,29 +66,6 @@ static struct blendinfo composite_op_info[] = { [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, }; -#define SOLID_SOURCE_INDEX 1 -#define HAS_MASK_INDEX 2 -#define SOLID_MASK_INDEX 3 - -static glamor_composite_shader * -glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) -{ - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - int index = 0; - - if (key->solid_source) - index += SOLID_SOURCE_INDEX; - if (key->has_mask) { - index += HAS_MASK_INDEX; - if (key->solid_mask) - index += SOLID_MASK_INDEX; - } - - assert(index < ARRAY_SIZE(glamor_priv->composite_shader)); - - return &glamor_priv->composite_shader[index]; -} - static GLuint glamor_create_composite_fs(struct shader_key *key) { @@ -104,12 +80,12 @@ glamor_create_composite_fs(struct shader_key *key) const char *main_opening = "void main()\n" "{\n"; - const char *source_pixmap_fetch = + const char *source_alpha_pixmap_fetch = " vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n"; - const char *mask_pixmap_fetch = + const char *mask_alpha_pixmap_fetch = " vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n"; const char *source_in_mask = - " gl_FragColor = source * mask.w;\n"; + " gl_FragColor = source * mask.a;\n"; const char *source_only = " gl_FragColor = source;\n"; const char *main_closing = @@ -119,29 +95,49 @@ glamor_create_composite_fs(struct shader_key *key) const char *source_fetch = ""; const char *mask_setup = ""; const char *mask_fetch = ""; + const char *in; GLuint prog; - if (key->solid_source) { + switch (key->source) { + case SHADER_SOURCE_SOLID: source_setup = source_solid_header; - } else { + break; + case SHADER_SOURCE_TEXTURE_ALPHA: source_setup = source_pixmap_header; - source_fetch = source_pixmap_fetch; + source_fetch = source_alpha_pixmap_fetch; + break; + FatalError("Bad composite shader source"); + default: + FatalError("Bad composite source mask"); } - if (key->has_mask) { - if (key->solid_mask) { - mask_setup = mask_solid_header; - } else { - mask_setup = mask_pixmap_header; - mask_fetch = mask_pixmap_fetch; - } + + switch (key->mask) { + case SHADER_MASK_NONE: + break; + case SHADER_MASK_SOLID: + mask_setup = mask_solid_header; + break; + case SHADER_MASK_TEXTURE_ALPHA: + mask_setup = mask_pixmap_header; + mask_fetch = mask_alpha_pixmap_fetch; + break; + default: + FatalError("Bad composite shader mask"); } + + if (key->mask == SHADER_MASK_NONE) { + in = source_only; + } else { + in = source_in_mask; + } + source = XNFprintf("%s%s%s%s%s%s%s", source_setup, mask_setup, main_opening, source_fetch, mask_fetch, - key->has_mask ? source_in_mask : source_only, + in, main_closing); prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); @@ -156,19 +152,28 @@ glamor_create_composite_vs(struct shader_key *key) const char *main_opening = "void main()\n" "{\n" - " gl_Position = gl_Vertex;\n" + " gl_Position = gl_Vertex;\n"; + const char *source_coords = " gl_TexCoord[0] = gl_MultiTexCoord0;\n"; const char *mask_coords = " gl_TexCoord[1] = gl_MultiTexCoord1;\n"; const char *main_closing = "}\n"; + const char *source_coords_setup = ""; + const char *mask_coords_setup = ""; char *source; GLuint prog; - Bool compute_mask_coords = key->has_mask && !key->solid_mask; - source = XNFprintf("%s%s%s", + if (key->source != SHADER_SOURCE_SOLID) + source_coords_setup = source_coords; + + if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID) + mask_coords_setup = mask_coords; + + source = XNFprintf("%s%s%s%s", main_opening, - compute_mask_coords ? mask_coords : "", + source_coords_setup, + mask_coords_setup, main_closing); prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source); @@ -178,13 +183,11 @@ glamor_create_composite_vs(struct shader_key *key) } static void -glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) +glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, + glamor_composite_shader *shader) { GLuint vs, fs, prog; GLint source_sampler_uniform_location, mask_sampler_uniform_location; - glamor_composite_shader *shader; - - shader = glamor_lookup_composite_shader(screen, key); vs = glamor_create_composite_vs(key); if (vs == 0) @@ -202,7 +205,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) glUseProgramObjectARB(prog); - if (key->solid_source) { + if (key->source == SHADER_SOURCE_SOLID) { shader->source_uniform_location = glGetUniformLocationARB(prog, "source"); } else { @@ -211,8 +214,8 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) glUniform1i(source_sampler_uniform_location, 0); } - if (key->has_mask) { - if (key->solid_mask) { + if (key->mask != SHADER_MASK_NONE) { + if (key->mask == SHADER_MASK_SOLID) { shader->mask_uniform_location = glGetUniformLocationARB(prog, "mask"); } else { @@ -223,27 +226,22 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key) } } +static glamor_composite_shader * +glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_composite_shader *shader; + + shader = &glamor_priv->composite_shader[key->source][key->mask]; + if (shader->prog == 0) + glamor_create_composite_shader(screen, key, shader); + + return shader; +} + void glamor_init_composite_shaders(ScreenPtr screen) { - struct shader_key key; - - memset(&key, 0, sizeof(key)); - key.has_mask = FALSE; - glamor_create_composite_shader(screen, &key); - key.has_mask = TRUE; - glamor_create_composite_shader(screen, &key); - key.solid_mask = TRUE; - glamor_create_composite_shader(screen, &key); - - memset(&key, 0, sizeof(key)); - key.solid_source = TRUE; - key.has_mask = FALSE; - glamor_create_composite_shader(screen, &key); - key.has_mask = TRUE; - glamor_create_composite_shader(screen, &key); - key.solid_mask = TRUE; - glamor_create_composite_shader(screen, &key); } static Bool @@ -505,33 +503,40 @@ glamor_composite_with_shader(CARD8 op, BoxPtr box; memset(&key, 0, sizeof(key)); - key.has_mask = (mask != NULL); if (!source->pDrawable) { if (source->pSourcePict->type == SourcePictTypeSolidFill) { - key.solid_source = TRUE; + key.source = SHADER_SOURCE_SOLID; } else { - ErrorF("gradient source\n"); + glamor_fallback("gradient source\n"); goto fail; } + } else { + key.source = SHADER_SOURCE_TEXTURE_ALPHA; } - if (mask && !mask->pDrawable) { - if (mask->pSourcePict->type == SourcePictTypeSolidFill) { - key.solid_mask = TRUE; + if (mask) { + if (!mask->pDrawable) { + if (mask->pSourcePict->type == SourcePictTypeSolidFill) { + key.mask = SHADER_MASK_SOLID; + } else { + glamor_fallback("gradient mask\n"); + goto fail; + } } else { - ErrorF("gradient mask\n"); - goto fail; + key.mask = SHADER_MASK_TEXTURE_ALPHA; } + } else { + key.mask = SHADER_MASK_NONE; } if (source->alphaMap) { - ErrorF("source alphaMap\n"); + glamor_fallback("source alphaMap\n"); goto fail; } if (mask && mask->alphaMap) { - ErrorF("mask alphaMap\n"); + glamor_fallback("mask alphaMap\n"); goto fail; } - if (!key.solid_source) { + if (key.source == SHADER_SOURCE_TEXTURE_ALPHA) { source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); if (source_pixmap == dest_pixmap) { @@ -545,7 +550,7 @@ glamor_composite_with_shader(CARD8 op, if (!good_source_format(source)) goto fail; } - if (mask && !key.solid_mask) { + if (key.mask == SHADER_MASK_TEXTURE_ALPHA) { mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); if (mask_pixmap == dest_pixmap) { @@ -589,13 +594,13 @@ glamor_composite_with_shader(CARD8 op, y_mask += mask->pDrawable->y; } - if (key.solid_source) { + if (key.source == SHADER_SOURCE_SOLID) { glamor_set_composite_solid(source, shader->source_uniform_location); } else { glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); } - if (key.has_mask) { - if (key.solid_mask) { + if (key.mask != SHADER_MASK_NONE) { + if (key.mask == SHADER_MASK_SOLID) { glamor_set_composite_solid(mask, shader->mask_uniform_location); } else { glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); @@ -614,13 +619,13 @@ glamor_composite_with_shader(CARD8 op, glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - if (!key.solid_source) { + if (key.source != SHADER_SOURCE_SOLID) { glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } - if (key.has_mask && !key.solid_mask) { + if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { glClientActiveTexture(GL_TEXTURE1); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -637,7 +642,7 @@ glamor_composite_with_shader(CARD8 op, vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1); vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2); - if (!key.solid_source) { + if (key.source != SHADER_SOURCE_SOLID) { int tx1 = box[i].x1 + x_source - x_dest; int ty1 = box[i].y1 + y_source - y_dest; int tx2 = box[i].x2 + x_source - x_dest; @@ -652,7 +657,7 @@ glamor_composite_with_shader(CARD8 op, source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2); } - if (key.has_mask && !key.solid_mask) { + if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { int tx1 = box[i].x1 + x_mask - x_dest; int ty1 = box[i].y1 + y_mask - y_dest; int tx2 = box[i].x2 + x_mask - x_dest; From be64167fea3c74447ed3c5116b97473676c25b29 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 09:20:50 -0800 Subject: [PATCH 077/225] glamor: Don't try to CopyArea from a Solid source picture. Fixes failure with rendercheck. --- glamor/glamor_render.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index f432b5f29..0f4f4c0af 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -406,6 +406,9 @@ glamor_composite_with_copy(CARD8 op, { RegionRec region; + if (!source->pDrawable) + return FALSE; + if (!compatible_formats(op, dest, source)) return FALSE; From e6bf50573650f03c8130b7783485b24e98e15c79 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 09:23:09 -0800 Subject: [PATCH 078/225] glamor: Set active texture on glamor_copy_n_to_n setup. Fixes failure in rendercheck -t blend -o src --- glamor/glamor_copyarea.c | 1 + 1 file changed, 1 insertion(+) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 695edc3e9..f21752b42 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -74,6 +74,7 @@ glamor_copy_n_to_n(DrawablePtr src, goto fail; } + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); From 0565c1d789ed82c533f860713d66b4941c299f9c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 9 Feb 2010 22:35:04 -0800 Subject: [PATCH 079/225] glamor: Add support for accel of x8r8g8b8 source pictures. There's a limitation still for RepeatNone, but this fixes a bunch of fallbacks for gnome-terminal. --- glamor/glamor_priv.h | 2 ++ glamor/glamor_render.c | 51 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 95aad7da1..283f7ea12 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -100,6 +100,7 @@ typedef struct { enum shader_source { SHADER_SOURCE_SOLID, + SHADER_SOURCE_TEXTURE, SHADER_SOURCE_TEXTURE_ALPHA, SHADER_SOURCE_COUNT, }; @@ -107,6 +108,7 @@ enum shader_source { enum shader_mask { SHADER_MASK_NONE, SHADER_MASK_SOLID, + SHADER_MASK_TEXTURE, SHADER_MASK_TEXTURE_ALPHA, SHADER_MASK_COUNT, }; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 0f4f4c0af..cb9da1e1a 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -82,8 +82,14 @@ glamor_create_composite_fs(struct shader_key *key) "{\n"; const char *source_alpha_pixmap_fetch = " vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n"; + const char *source_pixmap_fetch = + " vec4 source = vec4(texture2D(source_sampler, " + " gl_TexCoord[0].xy).rgb, 1.0);\n"; const char *mask_alpha_pixmap_fetch = " vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n"; + const char *mask_pixmap_fetch = + " vec4 mask = vec4(texture2D(mask_sampler, " + " gl_TexCoord[1].xy).rgb, 1.0);\n"; const char *source_in_mask = " gl_FragColor = source * mask.a;\n"; const char *source_only = @@ -106,9 +112,12 @@ glamor_create_composite_fs(struct shader_key *key) source_setup = source_pixmap_header; source_fetch = source_alpha_pixmap_fetch; break; - FatalError("Bad composite shader source"); + case SHADER_SOURCE_TEXTURE: + source_setup = source_pixmap_header; + source_fetch = source_pixmap_fetch; + break; default: - FatalError("Bad composite source mask"); + FatalError("Bad composite shader source"); } switch (key->mask) { @@ -121,6 +130,10 @@ glamor_create_composite_fs(struct shader_key *key) mask_setup = mask_pixmap_header; mask_fetch = mask_alpha_pixmap_fetch; break; + case SHADER_MASK_TEXTURE: + mask_setup = mask_pixmap_header; + mask_fetch = mask_pixmap_fetch; + break; default: FatalError("Bad composite shader mask"); } @@ -446,6 +459,14 @@ good_source_format(PicturePtr picture) case PICT_a8: case PICT_a8r8g8b8: return TRUE; + case PICT_x8r8g8b8: + /* In order to support formats with no alpha, we have to wire the + * alpha to 1 in the shader, which conflicts with + * GL_CLAMP_TO_BORDERing to transparent. We could possibly compute + * coverage of the texels in the sampling area if we need to, but + * that isn't implemented today. + */ + return (picture->repeatType != RepeatNone); default: glamor_fallback("Bad source format 0x%08x\n", picture->format); return FALSE; @@ -459,6 +480,14 @@ good_mask_format(PicturePtr picture) case PICT_a8: case PICT_a8r8g8b8: return TRUE; + case PICT_x8r8g8b8: + /* In order to support formats with no alpha, we have to wire the + * alpha to 1 in the shader, which conflicts with + * GL_CLAMP_TO_BORDERing to transparent. We could possibly compute + * coverage of the texels in the sampling area if we need to, but + * that isn't implemented today. + */ + return (picture->repeatType != RepeatNone); default: glamor_fallback("Bad mask format 0x%08x\n", picture->format); return FALSE; @@ -514,7 +543,11 @@ glamor_composite_with_shader(CARD8 op, goto fail; } } else { - key.source = SHADER_SOURCE_TEXTURE_ALPHA; + if (PICT_FORMAT_A(source->format) != 0) { + key.source = SHADER_SOURCE_TEXTURE_ALPHA; + } else { + key.source = SHADER_SOURCE_TEXTURE; + } } if (mask) { if (!mask->pDrawable) { @@ -525,7 +558,11 @@ glamor_composite_with_shader(CARD8 op, goto fail; } } else { - key.mask = SHADER_MASK_TEXTURE_ALPHA; + if (PICT_FORMAT_A(mask->format) != 0) { + key.mask = SHADER_MASK_TEXTURE_ALPHA; + } else { + key.mask = SHADER_MASK_TEXTURE; + } } } else { key.mask = SHADER_MASK_NONE; @@ -539,7 +576,8 @@ glamor_composite_with_shader(CARD8 op, goto fail; } - if (key.source == SHADER_SOURCE_TEXTURE_ALPHA) { + if (key.source == SHADER_SOURCE_TEXTURE || + key.source == SHADER_SOURCE_TEXTURE_ALPHA) { source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); if (source_pixmap == dest_pixmap) { @@ -553,7 +591,8 @@ glamor_composite_with_shader(CARD8 op, if (!good_source_format(source)) goto fail; } - if (key.mask == SHADER_MASK_TEXTURE_ALPHA) { + if (key.mask == SHADER_MASK_TEXTURE || + key.mask == SHADER_MASK_TEXTURE_ALPHA) { mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); if (mask_pixmap == dest_pixmap) { From 5360b1e8bbae571b120999e7eec7cd2826601497 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 09:47:38 -0800 Subject: [PATCH 080/225] glamor: Implement glCopyPixels based src == dest CopyArea acceleration --- glamor/glamor_copyarea.c | 117 +++++++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 28 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index f21752b42..578ad3087 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -32,18 +32,70 @@ * GC CopyArea implementation */ -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) +static Bool +glamor_copy_n_to_n_copypixels(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy) +{ + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + int i; + + if (src != dst) { + glamor_fallback("glamor_copy_n_to_n_copypixels(): src != dest\n"); + return FALSE; + } + + if (gc) { + if (gc->alu != GXcopy) { + glamor_fallback("glamor_copy_n_to_n_copypixels(): non-copy ALU\n"); + return FALSE; + } + if (!glamor_pm_is_solid(dst, gc->planemask)) { + glamor_fallback("glamor_copy_n_to_n_copypixels(): " + "non-solid planemask\n"); + return FALSE; + } + } + + if (!glamor_set_destination_pixmap(dst_pixmap)) + return FALSE; + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glOrtho(0, dst_pixmap->drawable.width, + 0, dst_pixmap->drawable.height, + -1, 1); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + for (i = 0; i < nbox; i++) { + int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2; + glRasterPos2i(box[i].x1 - dst_pixmap->screen_x, + flip_y1 - dst_pixmap->screen_x); + glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x, + flip_y1 - dy - src_pixmap->screen_y, + box[i].x2 - box[i].x1, + box[i].y2 - box[i].y1, + GL_COLOR); + } + + return TRUE; +} + +static Bool +glamor_copy_n_to_n_textured(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy) { glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pScreen); @@ -116,22 +168,33 @@ glamor_copy_n_to_n(DrawablePtr src, glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); - -#if 0 - for (i = 0; i < nbox; i++) { - glRasterPos2i(box[i].x1 - dst_pixmap->screen_x, - box[i].y1 - dst_pixmap->screen_y); - glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x, - box[i].y1 + dy - src_pixmap->screen_y, - box[i].x2 - box[i].x1, - box[i].y2 - box[i].y1, - GL_COLOR); - } -#endif - - return; + return TRUE; fail: + glamor_set_alu(GXcopy); + glamor_set_planemask(dst_pixmap, ~0); + return FALSE; +} + +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) +{ + if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) + return; + + if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) + return; + glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); @@ -144,8 +207,6 @@ fail: } glamor_finish_access(dst); } - glamor_set_alu(GXcopy); - glamor_set_planemask(dst_pixmap, ~0); } RegionPtr From be82a0624207b5f367b97c25ac7d7dbd8a518597 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 13:21:47 -0800 Subject: [PATCH 081/225] glamor: Fix screen_x/screen_y handling for compositing. It's not an offset from pixmap coords to composited pixmap coords, it's an offset from screen-relative window drawable coords to composited pixmap coords. --- glamor/glamor_copyarea.c | 37 ++++++++++++++++++++++--------------- glamor/glamor_core.c | 21 +++++++++++++++++++++ glamor/glamor_fill.c | 23 +++++++++++++---------- glamor/glamor_getspans.c | 7 +++++-- glamor/glamor_priv.h | 10 ++++++---- glamor/glamor_putimage.c | 5 ++++- glamor/glamor_render.c | 34 ++++++++++++++++++++++++++-------- glamor/glamor_setspans.c | 10 +++++++--- glamor/glamor_tile.c | 8 ++++---- 9 files changed, 108 insertions(+), 47 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 578ad3087..94e987ca2 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -41,9 +41,8 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, int dx, int dy) { - PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); - int i; + int x_off, y_off, i; if (src != dst) { glamor_fallback("glamor_copy_n_to_n_copypixels(): src != dest\n"); @@ -74,12 +73,14 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, glMatrixMode(GL_PROJECTION); glLoadIdentity(); + glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off); + for (i = 0; i < nbox; i++) { - int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2; - glRasterPos2i(box[i].x1 - dst_pixmap->screen_x, - flip_y1 - dst_pixmap->screen_x); - glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x, - flip_y1 - dy - src_pixmap->screen_y, + int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2 + y_off; + glRasterPos2i(box[i].x1 + x_off, + flip_y1); + glCopyPixels(box[i].x1 + dx + x_off, + flip_y1 - dy, box[i].x2 - box[i].x1, box[i].y2 - box[i].y1, GL_COLOR); @@ -104,6 +105,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, int i; float vertices[4][2], texcoords[4][2]; glamor_pixmap_private *src_pixmap_priv; + int src_x_off, src_y_off, dst_x_off, dst_y_off; src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); @@ -126,6 +128,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src, goto fail; } + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); + glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); + dx += src_x_off; + dy += src_y_off; + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); glEnable(GL_TEXTURE_2D); @@ -143,14 +150,14 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glUseProgramObjectARB(glamor_priv->finish_access_prog); for (i = 0; i < nbox; i++) { - vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1); - vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1); - vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2); - vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1); - vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2); - vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2); - vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1); - vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2); + vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off); + vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); + vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off); + vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); + vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off); + vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off); + vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off); + vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off); texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index b0a64f2ef..a4036c89e 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -52,6 +52,27 @@ glamor_get_drawable_location(const DrawablePtr drawable) return 'f'; } +/** + * Sets the offsets to add to coordinates to make them address the same bits in + * the backing drawable. These coordinates are nonzero only for redirected + * windows. + */ +void +glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, + int *x, int *y) +{ +#ifdef COMPOSITE + if (drawable->type == DRAWABLE_WINDOW) { + *x = -pixmap->screen_x; + *y = -pixmap->screen_y; + return; + } +#endif + + *x = 0; + *y = 0; +} + Bool glamor_set_destination_pixmap(PixmapPtr pixmap) { diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 1b601ee5d..d2e8e8826 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -41,12 +41,15 @@ glamor_fill(DrawablePtr drawable, int height) { PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); + int x_off, y_off; + + glamor_get_drawable_deltas(drawable, dst_pixmap, &x_off, &y_off); switch (gc->fillStyle) { case FillSolid: glamor_solid(dst_pixmap, - x - dst_pixmap->screen_x, - y - dst_pixmap->screen_y, + x + x_off, + y + y_off, width, height, gc->alu, @@ -57,28 +60,28 @@ glamor_fill(DrawablePtr drawable, case FillOpaqueStippled: glamor_stipple(dst_pixmap, gc->stipple, - x - dst_pixmap->screen_x, - y - dst_pixmap->screen_y, + x+ x_off, + y + y_off, width, height, gc->alu, gc->planemask, gc->fgPixel, gc->bgPixel, - gc->patOrg.x - dst_pixmap->screen_x, - gc->patOrg.y - dst_pixmap->screen_y); + gc->patOrg.x + x_off, + gc->patOrg.y + y_off); break; case FillTiled: glamor_tile(dst_pixmap, gc->tile.pixmap, - x - dst_pixmap->screen_x, - y - dst_pixmap->screen_y, + x + x_off, + y + y_off, width, height, gc->alu, gc->planemask, - gc->patOrg.x - dst_pixmap->screen_y, - gc->patOrg.y - dst_pixmap->screen_y); + gc->patOrg.x, + gc->patOrg.y); break; } } diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 6e92b4d0b..92ffba5cc 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -55,6 +55,7 @@ glamor_get_spans(DrawablePtr drawable, GLenum format, type; int i, j; uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst; + int x_off, y_off; goto fail; @@ -86,9 +87,11 @@ glamor_get_spans(DrawablePtr drawable, if (!glamor_set_destination_pixmap(pixmap)) goto fail; + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); + for (i = 0; i < count; i++) { - glReadPixels(points[i].x - pixmap->screen_x, - points[i].y - pixmap->screen_y, + glReadPixels(points[i].x + x_off, + points[i].y + y_off, widths[i], 1, format, type, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 283f7ea12..c69ff98ec 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -200,25 +200,25 @@ glamor_fallback(char *format, ...) static inline float v_from_x_coord_x(PixmapPtr pixmap, int x) { - return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0; + return (float)x / pixmap->drawable.width * 2.0 - 1.0; } static inline float v_from_x_coord_y(PixmapPtr pixmap, int y) { - return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0; + return (float)y / pixmap->drawable.height * -2.0 + 1.0; } static inline float t_from_x_coord_x(PixmapPtr pixmap, int x) { - return (float)(x - pixmap->screen_x) / pixmap->drawable.width; + return (float)x / pixmap->drawable.width; } static inline float t_from_x_coord_y(PixmapPtr pixmap, int y) { - return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height; + return 1.0 - (float)y / pixmap->drawable.height; } /* glamor.c */ @@ -254,6 +254,8 @@ Bool glamor_prepare_access_gc(GCPtr gc); void glamor_finish_access_gc(GCPtr gc); void glamor_init_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_create_gc(GCPtr gc); void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, int x, int y, int width, int height, diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 537992101..b71644f02 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -244,6 +244,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int nbox; int bpp = drawable->bitsPerPixel; int src_stride = PixmapBytePad(w, drawable->depth); + int x_off, y_off; goto fail; @@ -297,6 +298,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, x += drawable->x; y += drawable->y; + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / bpp); if (bpp == 1) @@ -325,7 +328,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, continue; src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); - glRasterPos2i(x1 - pixmap->screen_x, y1 - pixmap->screen_y); + glRasterPos2i(x1 + x_off, y1 + y_off); glDrawPixels(x2 - x1, y2 - y1, format, type, diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index cb9da1e1a..35e3e0a2b 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -533,6 +533,7 @@ glamor_composite_with_shader(CARD8 op, float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2]; int i; BoxPtr box; + int dst_x_off, dst_y_off; memset(&key, 0, sizeof(key)); if (!source->pDrawable) { @@ -673,16 +674,33 @@ glamor_composite_with_shader(CARD8 op, glEnableClientState(GL_TEXTURE_COORD_ARRAY); } + glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, + &dst_x_off, &dst_y_off); + if (source_pixmap) { + int dx, dy; + + glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &dx, &dy); + x_source += dx; + y_source += dy; + } + if (mask_pixmap) { + int dx, dy; + + glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &dx, &dy); + x_mask += dx; + y_mask += dy; + } + box = REGION_RECTS(®ion); for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { - vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1); - vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1); - vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2); - vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1); - vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2); - vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2); - vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1); - vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2); + vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off); + vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off); + vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off); + vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off); + vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off); + vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off); + vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off); + vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off); if (key.source != SHADER_SOURCE_SOLID) { int tx1 = box[i].x1 + x_source - x_dest; diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 32f7bc515..54aa26635 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -42,6 +42,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, int wmax = 0; RegionPtr clip = fbGetCompositeClip(gc); BoxRec *pbox; + int x_off, y_off; goto fail; @@ -82,6 +83,9 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, glamor_set_alu(gc->alu); if (!glamor_set_planemask(dest_pixmap, gc->planemask)) goto fail; + + glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off); + for (i = 0; i < n; i++) { if (temp_src) { for (j = 0; j < widths[i]; j++) { @@ -98,12 +102,12 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, if (pbox->y1 > points[i].y) break; glScissor(pbox->x1, - points[i].y - dest_pixmap->screen_y, + points[i].y + y_off, pbox->x2 - pbox->x1, 1); glEnable(GL_SCISSOR_TEST); - glRasterPos2i(points[i].x - dest_pixmap->screen_x, - points[i].y - dest_pixmap->screen_y); + glRasterPos2i(points[i].x + x_off, + points[i].y + y_off); glDrawPixels(widths[i], 1, format, type, diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 517dbd3ea..01c4b7ab4 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -92,10 +92,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int x2 = x + width; int y1 = y; int y2 = y + height; - int tile_x1 = tile_x - tile->screen_x; - int tile_x2 = tile_x - tile->screen_x + width; - int tile_y1 = tile_y - tile->screen_y; - int tile_y2 = tile_y - tile->screen_y + height; + int tile_x1 = tile_x; + int tile_x2 = tile_x + width; + int tile_y1 = tile_y; + int tile_y2 = tile_y + height; glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile); if (glamor_priv->tile_prog == 0) { From 86a206525350b7e82ab0e432ad0fb8858960857d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 13:40:28 -0800 Subject: [PATCH 082/225] glamor: Fix off-by-one in CopyPixels CopyArea path. Fixes window dragging in uncomposited metacity. --- glamor/glamor_copyarea.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 94e987ca2..b7762cc22 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -76,7 +76,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off); for (i = 0; i < nbox; i++) { - int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2 + y_off; + int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off; glRasterPos2i(box[i].x1 + x_off, flip_y1); glCopyPixels(box[i].x1 + dx + x_off, From d61a13cf3f0a3028fbcf41310a4f5ecaa8546961 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 14:52:04 -0800 Subject: [PATCH 083/225] glamor: Fix and enable tile fill acceleration (aka the root weave). --- glamor/glamor_fill.c | 4 +-- glamor/glamor_polyfillrect.c | 2 +- glamor/glamor_priv.h | 1 - glamor/glamor_tile.c | 66 +++++++++++++++++++++++------------- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index d2e8e8826..8e269e22e 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -80,8 +80,8 @@ glamor_fill(DrawablePtr drawable, height, gc->alu, gc->planemask, - gc->patOrg.x, - gc->patOrg.y); + drawable->x + x - gc->patOrg.x, + drawable->y + y - gc->patOrg.y); break; } } diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index 62e0a0fe4..29e9db537 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -52,7 +52,7 @@ glamor_poly_fill_rect(DrawablePtr drawable, int xorg, yorg; int n; - if (gc->fillStyle != FillSolid) + if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) goto fail; xorg = drawable->x; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index c69ff98ec..91fa6e1fe 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -136,7 +136,6 @@ typedef struct glamor_screen_private { /* glamor_tile */ GLint tile_prog; - glamor_transform_uniforms tile_transform; /* glamor_putimage */ GLint put_image_xybitmap_prog; diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 01c4b7ab4..60a1a1e8f 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -41,17 +41,10 @@ glamor_init_tile_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); const char *tile_vs = - "uniform float x_bias;\n" - "uniform float x_scale;\n" - "uniform float y_bias;\n" - "uniform float y_scale;\n" "void main()\n" "{\n" - " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" - " (gl_Vertex.y + y_bias) * y_scale,\n" - " 0,\n" - " 1);\n" - " gl_TexCoord[0] = vec4(gl_MultiTexCoord0.xy, 0, 1);\n" + " gl_Position = gl_Vertex;\n" + " gl_TexCoord[0] = gl_MultiTexCoord0;\n" "}\n"; const char *tile_fs = "uniform sampler2D sampler;\n" @@ -76,8 +69,7 @@ glamor_init_tile_shader(ScreenPtr screen) glGetUniformLocationARB(glamor_priv->tile_prog, "sampler"); glUseProgramObjectARB(glamor_priv->tile_prog); glUniform1iARB(sampler_uniform_location, 0); - glamor_get_transform_uniform_locations(glamor_priv->tile_prog, - &glamor_priv->tile_transform); + glUseProgramObjectARB(0); } void @@ -97,6 +89,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int tile_y1 = tile_y; int tile_y2 = tile_y + height; glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile); + float vertices[4][2]; + float source_texcoords[4][2]; if (glamor_priv->tile_prog == 0) { ErrorF("Tiling unsupported\n"); @@ -105,32 +99,56 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, if (!glamor_set_destination_pixmap(pixmap)) goto fail; - if (tile_priv->fb == 0) { - ErrorF("Non-FBO tile pixmap\n"); + + if (tile_priv->tex == 0) { + ErrorF("Non-texture tile pixmap\n"); goto fail; } + if (!glamor_set_planemask(pixmap, planemask)) goto fail; glamor_set_alu(alu); + glUseProgramObjectARB(glamor_priv->tile_prog); - glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tile_priv->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glEnable(GL_TEXTURE_2D); - glBegin(GL_TRIANGLE_FAN); - glMultiTexCoord2f(0, tile_x1, tile_y1); - glVertex2f(x1, y1); - glMultiTexCoord2f(0, tile_x1, tile_y2); - glVertex2f(x1, y2); - glMultiTexCoord2f(0, tile_x2, tile_y2); - glVertex2f(x2, y2); - glMultiTexCoord2f(0, tile_x2, tile_y1); - glVertex2f(x2, y1); - glEnd(); + vertices[0][0] = v_from_x_coord_x(pixmap, x1); + vertices[0][1] = v_from_x_coord_y(pixmap, y1); + vertices[1][0] = v_from_x_coord_x(pixmap, x2); + vertices[1][1] = v_from_x_coord_y(pixmap, y1); + vertices[2][0] = v_from_x_coord_x(pixmap, x2); + vertices[2][1] = v_from_x_coord_y(pixmap, y2); + vertices[3][0] = v_from_x_coord_x(pixmap, x1); + vertices[3][1] = v_from_x_coord_y(pixmap, y2); + + source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1); + source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1); + source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2); + source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1); + source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2); + source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2); + source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1); + source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2); + + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); glUseProgramObjectARB(0); glDisable(GL_TEXTURE_2D); From a63df0c504be3be0e969f5080a6593a55cb87246 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 15:00:32 -0800 Subject: [PATCH 084/225] glamor: Fix up the wide/non-solid lines fallback. --- glamor/glamor_polylines.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index 48e62f454..5a7204b5e 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -52,13 +52,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0) { - ErrorF("stub wide polylines\n"); - return; + glamor_fallback("glamor_poly_lines(): wide lines\n"); + goto fail; } if (gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) { - ErrorF("stub poly_line non-solid fill\n"); - return; + glamor_fallback("glamor_poly_lines(): non-solid fill\n"); + goto fail; } rects = xalloc(sizeof(xRectangle) * (n - 1)); @@ -104,4 +104,19 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, } gc->ops->PolyFillRect(drawable, gc, n - 1, rects); xfree(rects); + return; + +fail: + if (gc->lineWidth == 0) { + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_gc(gc)) { + fbPolyLine(drawable, gc, mode, n, points); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable); + } + return; + } + /* fb calls mi functions in the lineWidth != 0 case. */ + fbPolyLine(drawable, gc, mode, n, points); } From f88d76cf7e05cf885d80c0b91f37f1b30675e928 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 16:51:13 -0800 Subject: [PATCH 085/225] glamor: Enable glamor_fill_spans(). x11perf -wline100 performance goes from 8.8/sec to 111/sec. --- glamor/glamor_fillspans.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index 9b070eced..a633b3066 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -45,7 +45,8 @@ glamor_fill_spans(DrawablePtr drawable, int fullX1, fullX2, fullY1; int partX1, partX2; - goto fail; + if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) + goto fail; extents = REGION_EXTENTS(gc->pScreen, clip); extentX1 = extents->x1; @@ -101,7 +102,7 @@ glamor_fill_spans(DrawablePtr drawable, } return; fail: - glamor_fallback("to %p (%c)\n", drawable, + glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_gc(gc)) { From b1f67a5082420bbff141733833905f8ac95fe983 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 17:15:05 -0800 Subject: [PATCH 086/225] glamor: Fix and enable glamor_get_spans(). This makes running the cairo test suite almost tolerable. --- glamor/glamor_getspans.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 92ffba5cc..9b77f28db 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -57,8 +57,6 @@ glamor_get_spans(DrawablePtr drawable, uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst; int x_off, y_off; - goto fail; - switch (drawable->depth) { case 1: temp_dst = xalloc(wmax); @@ -71,9 +69,6 @@ glamor_get_spans(DrawablePtr drawable, type = GL_UNSIGNED_BYTE; break; case 24: - format = GL_RGB; - type = GL_UNSIGNED_BYTE; - break; case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -91,7 +86,7 @@ glamor_get_spans(DrawablePtr drawable, for (i = 0; i < count; i++) { glReadPixels(points[i].x + x_off, - points[i].y + y_off, + pixmap->drawable.height - 1 - (points[i].y + y_off), widths[i], 1, format, type, From 2ba634fab9b03995629497efdbf5305394011e4a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Feb 2010 17:32:27 -0800 Subject: [PATCH 087/225] glamor: Fix render source transforms. Fixes (except for small bit differences) cairo source-pattern. --- glamor/glamor_render.c | 72 ++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 35e3e0a2b..6e281c910 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -508,6 +508,36 @@ good_dest_format(PicturePtr picture) } } +static inline float +xFixedToFloat(pixman_fixed_t val) +{ + return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)); +} + +static void +glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap, + float *texcoord, int x, int y) +{ + float result[3]; + int i; + float tx, ty; + + if (picture->transform) { + for (i = 0; i < 3; i++) { + result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x + + xFixedToFloat(picture->transform->matrix[i][1]) * y + + xFixedToFloat(picture->transform->matrix[i][2])); + } + tx = result[0] / result[2]; + ty = result[1] / result[2]; + } else { + tx = x; + ty = y; + } + texcoord[0] = t_from_x_coord_x(pixmap, tx); + texcoord[1] = t_from_x_coord_y(pixmap, ty); +} + static Bool glamor_composite_with_shader(CARD8 op, PicturePtr source, @@ -707,29 +737,31 @@ glamor_composite_with_shader(CARD8 op, int ty1 = box[i].y1 + y_source - y_dest; int tx2 = box[i].x2 + x_source - x_dest; int ty2 = box[i].y2 + y_source - y_dest; - source_texcoords[0][0] = t_from_x_coord_x(source_pixmap, tx1); - source_texcoords[0][1] = t_from_x_coord_y(source_pixmap, ty1); - source_texcoords[1][0] = t_from_x_coord_x(source_pixmap, tx2); - source_texcoords[1][1] = t_from_x_coord_y(source_pixmap, ty1); - source_texcoords[2][0] = t_from_x_coord_x(source_pixmap, tx2); - source_texcoords[2][1] = t_from_x_coord_y(source_pixmap, ty2); - source_texcoords[3][0] = t_from_x_coord_x(source_pixmap, tx1); - source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2); + + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[0], tx1, ty1); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[1], tx2, ty1); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[2], tx2, ty2); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[3], tx1, ty2); } if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { - int tx1 = box[i].x1 + x_mask - x_dest; - int ty1 = box[i].y1 + y_mask - y_dest; - int tx2 = box[i].x2 + x_mask - x_dest; - int ty2 = box[i].y2 + y_mask - y_dest; - mask_texcoords[0][0] = t_from_x_coord_x(mask_pixmap, tx1); - mask_texcoords[0][1] = t_from_x_coord_y(mask_pixmap, ty1); - mask_texcoords[1][0] = t_from_x_coord_x(mask_pixmap, tx2); - mask_texcoords[1][1] = t_from_x_coord_y(mask_pixmap, ty1); - mask_texcoords[2][0] = t_from_x_coord_x(mask_pixmap, tx2); - mask_texcoords[2][1] = t_from_x_coord_y(mask_pixmap, ty2); - mask_texcoords[3][0] = t_from_x_coord_x(mask_pixmap, tx1); - mask_texcoords[3][1] = t_from_x_coord_y(mask_pixmap, ty2); + float tx1 = box[i].x1 + x_mask - x_dest; + float ty1 = box[i].y1 + y_mask - y_dest; + float tx2 = box[i].x2 + x_mask - x_dest; + float ty2 = box[i].y2 + y_mask - y_dest; + + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[0], tx1, ty1); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[1], tx2, ty1); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[2], tx2, ty2); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[3], tx1, ty2); } #if 0 else memset(mask_texcoords, 0, sizeof(mask_texcoords)); From 9bcbcbf8c28e945fa5c4f4ad1a772b787618455f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Feb 2010 13:30:20 -0800 Subject: [PATCH 088/225] glamor: Fix and enable ZPixmap PutImage acceleration. --- glamor/glamor_putimage.c | 118 ++++++++++++++++++++++++++++++--------- 1 file changed, 92 insertions(+), 26 deletions(-) diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index b71644f02..74910fa67 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -137,6 +137,9 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, 0.0, 1.0, }; + glamor_fallback("glamor_put_image_xybitmap: disabled\n"); + goto fail; + if (glamor_priv->put_image_xybitmap_prog == 0) { ErrorF("no program for xybitmap putimage\n"); goto fail; @@ -158,6 +161,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform); glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -237,7 +241,10 @@ void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int left_pad, int image_format, char *bits) { + glamor_screen_private *glamor_priv = + glamor_get_screen_private(drawable->pScreen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); GLenum type, format; RegionPtr clip; BoxPtr pbox; @@ -245,14 +252,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int bpp = drawable->bitsPerPixel; int src_stride = PixmapBytePad(w, drawable->depth); int x_off, y_off; - - goto fail; - - if (!glamor_set_destination_pixmap(pixmap)) { - fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, - image_format, bits); - return; - } + float vertices[4][2], texcoords[4][2]; + GLuint tex; if (image_format == XYBitmap) { assert(depth == 1); @@ -261,13 +262,26 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, return; } + if (pixmap_priv == NULL) { + glamor_fallback("glamor_put_image: system memory pixmap\n"); + goto fail; + } + + if (pixmap_priv->fb == 0) { + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap != screen_pixmap) { + glamor_fallback("glamor_put_image: no fbo\n"); + goto fail; + } + } + if (bpp == 1 && image_format == XYPixmap) image_format = ZPixmap; - if (!glamor_set_planemask(pixmap, gc->planemask)) - goto fail; if (image_format != ZPixmap) { - ErrorF("putimage: non-ZPixmap\n"); + glamor_fallback("glamor_put_image: non-ZPixmap\n"); goto fail; } @@ -281,29 +295,57 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, type = GL_UNSIGNED_BYTE; break; case 24: - format = GL_RGB; - type = GL_UNSIGNED_BYTE; - break; + assert(drawable->bitsPerPixel == 32); + /* FALLTHROUGH */ case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; break; default: - ErrorF("stub put_image depth %d\n", drawable->depth); + glamor_fallback("glamor_putimage: bad depth %d\n", drawable->depth); goto fail; } + if (!glamor_set_planemask(pixmap, gc->planemask)) + goto fail; + glamor_set_alu(gc->alu); + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / + pixmap->drawable.bitsPerPixel); + if (bpp == 1) + glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); + + glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + w, h, 0, + format, type, bits); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEnable(GL_TEXTURE_2D); + + assert(GLEW_ARB_fragment_shader); + glUseProgramObjectARB(glamor_priv->finish_access_prog); + + x += drawable->x; y += drawable->y; glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / bpp); - if (bpp == 1) - glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); clip = fbGetCompositeClip(gc); for (nbox = REGION_NUM_RECTS(clip), pbox = REGION_RECTS(clip); @@ -314,7 +356,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int y1 = y; int x2 = x + w; int y2 = y + h; - char *src; + float src_x1, src_x2, src_y1, src_y2; if (x1 < pbox->x1) x1 = pbox->x1; @@ -327,13 +369,37 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (x1 >= x2 || y1 >= y2) continue; - src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); - glRasterPos2i(x1 + x_off, y1 + y_off); - glDrawPixels(x2 - x1, - y2 - y1, - format, type, - src); + src_x1 = (float)(x1 - x) / w; + src_y1 = (float)(y1 - y) / h; + src_x2 = (float)(x2 - x) / w; + src_y2 = (float)(y2 - y) / h; + + vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off); + vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off); + vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off); + vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off); + vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off); + vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off); + vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off); + vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off); + + texcoords[0][0] = src_x1; + texcoords[0][1] = src_y1; + texcoords[1][0] = src_x2; + texcoords[1][1] = src_y1; + texcoords[2][0] = src_x2; + texcoords[2][1] = src_y2; + texcoords[3][0] = src_x1; + texcoords[3][1] = src_y2; + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } + + glDisable(GL_TEXTURE_2D); + glUseProgramObjectARB(0); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDeleteTextures(1, &tex); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glamor_set_alu(GXcopy); From 2fa95725d845e5bf8a41ac776267be0d55d58004 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Feb 2010 13:33:48 -0800 Subject: [PATCH 089/225] glamor: Add support for a1 composite sources. They're stored just like a8, but the values are set to either 0.0 or 1.0. Because they're a8 with only two legal values, we can't use them as destinations, but nobody's rendering to a1 dests anyway (we hope). --- glamor/glamor_render.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6e281c910..6d8dd9797 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -456,6 +456,7 @@ static Bool good_source_format(PicturePtr picture) { switch (picture->format) { + case PICT_a1: case PICT_a8: case PICT_a8r8g8b8: return TRUE; @@ -477,6 +478,7 @@ static Bool good_mask_format(PicturePtr picture) { switch (picture->format) { + case PICT_a1: case PICT_a8: case PICT_a8r8g8b8: return TRUE; From 5f5c35b56d3568f72e2305e74ed8457e0a787a3b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Feb 2010 15:02:17 -0800 Subject: [PATCH 090/225] glamor: Fix up the fallback message for no texture present on compositing. --- glamor/glamor_render.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6d8dd9797..421aa3530 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -618,7 +618,7 @@ glamor_composite_with_shader(CARD8 op, goto fail; } if (!source_pixmap_priv || source_pixmap_priv->tex == 0) { - glamor_fallback("glamor_composite(): no FBO in source\n"); + glamor_fallback("glamor_composite(): no texture in source\n"); goto fail; } if (!good_source_format(source)) @@ -633,7 +633,7 @@ glamor_composite_with_shader(CARD8 op, goto fail; } if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) { - glamor_fallback("glamor_composite(): no FBO in mask\n"); + glamor_fallback("glamor_composite(): no texture in mask\n"); goto fail; } if (!good_mask_format(mask)) From 8cefa287ddb4ed4ad178e751b35bb93b4a44e0ab Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Feb 2010 16:00:22 -0800 Subject: [PATCH 091/225] glamor: Add a little mechanism for only printing fallbacks when they happen. Sometimes we want to try a couple of different methods for accelerating. If one of them says "no" and the other says "yes", don't spam the log about the "no." --- glamor/glamor_copyarea.c | 21 +++++++++++++++------ glamor/glamor_priv.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index b7762cc22..172b9593c 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -41,22 +41,25 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, int dx, int dy) { + ScreenPtr screen = dst->pScreen; PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int x_off, y_off, i; if (src != dst) { - glamor_fallback("glamor_copy_n_to_n_copypixels(): src != dest\n"); + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " + "src != dest\n"); return FALSE; } if (gc) { if (gc->alu != GXcopy) { - glamor_fallback("glamor_copy_n_to_n_copypixels(): non-copy ALU\n"); + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " + "non-copy ALU\n"); return FALSE; } if (!glamor_pm_is_solid(dst, gc->planemask)) { - glamor_fallback("glamor_copy_n_to_n_copypixels(): " - "non-solid planemask\n"); + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " + "non-solid planemask\n"); return FALSE; } } @@ -196,11 +199,17 @@ glamor_copy_n_to_n(DrawablePtr src, Pixel bitplane, void *closure) { - if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) + if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) { + glamor_clear_delayed_fallbacks(dst->pScreen); return; + } - if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) + if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) { + glamor_clear_delayed_fallbacks(dst->pScreen); return; + } + + glamor_report_delayed_fallbacks(dst->pScreen); glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 91fa6e1fe..cd7ca1528 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -126,6 +126,8 @@ typedef struct glamor_screen_private { CopyWindowProcPtr saved_copy_window; BitmapToRegionProcPtr saved_bitmap_to_region; + char *delayed_fallback_string; + /* glamor_finishaccess */ GLint finish_access_prog; @@ -196,6 +198,41 @@ glamor_fallback(char *format, ...) va_end(ap); } +static inline void +glamor_delayed_fallback(ScreenPtr screen, char *format, ...) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + va_list ap; + + if (glamor_priv->delayed_fallback_string != NULL) + return; + + va_start(ap, format); + glamor_priv->delayed_fallback_string = XNFvprintf(format, ap); + va_end(ap); +} + +static inline void +glamor_clear_delayed_fallbacks(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + xfree(glamor_priv->delayed_fallback_string); + glamor_priv->delayed_fallback_string = NULL; +} + +static inline void +glamor_report_delayed_fallbacks(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + if (glamor_priv->delayed_fallback_string) { + LogMessageVerb(X_INFO, 0, "fallback: %s", + glamor_priv->delayed_fallback_string); + glamor_clear_delayed_fallbacks(screen); + } +} + static inline float v_from_x_coord_x(PixmapPtr pixmap, int x) { From d07fc66a056dd4eab2dac82b3784c482071d1915 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Feb 2010 09:23:22 -0800 Subject: [PATCH 092/225] glamor: Rework shader setup to make extending the IN types easier. --- glamor/glamor_priv.h | 9 +++- glamor/glamor_render.c | 107 ++++++++++++++++++++++++----------------- 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index cd7ca1528..5ce74890b 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -113,6 +113,12 @@ enum shader_mask { SHADER_MASK_COUNT, }; +enum shader_in { + SHADER_IN_SOURCE_ONLY, + SHADER_IN_NORMAL, + SHADER_IN_COUNT, +}; + typedef struct glamor_screen_private { CreateGCProcPtr saved_create_gc; CreatePixmapProcPtr saved_create_pixmap; @@ -147,7 +153,8 @@ typedef struct glamor_screen_private { /* glamor_composite */ glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] - [SHADER_MASK_COUNT]; + [SHADER_MASK_COUNT] + [SHADER_IN_COUNT]; glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; } glamor_screen_private; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 421aa3530..f4840dc0c 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -41,6 +41,7 @@ struct shader_key { enum shader_source source; enum shader_mask mask; + enum shader_in in; }; struct blendinfo { @@ -69,51 +70,68 @@ static struct blendinfo composite_op_info[] = { static GLuint glamor_create_composite_fs(struct shader_key *key) { - const char *source_pixmap_header = - "uniform sampler2D source_sampler;\n"; - const char *source_solid_header = - "uniform vec4 source;\n"; - const char *mask_pixmap_header = - "uniform sampler2D mask_sampler;\n"; - const char *mask_solid_header = - "uniform vec4 mask;\n"; - const char *main_opening = - "void main()\n" - "{\n"; + const char *source_solid_fetch = + "uniform vec4 source;\n" + "vec4 get_source()\n" + "{\n" + " return source;\n" + "}\n"; const char *source_alpha_pixmap_fetch = - " vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n"; + "uniform sampler2D source_sampler;\n" + "vec4 get_source()\n" + "{\n" + " return texture2D(source_sampler, gl_TexCoord[0].xy);\n" + "}\n"; const char *source_pixmap_fetch = - " vec4 source = vec4(texture2D(source_sampler, " - " gl_TexCoord[0].xy).rgb, 1.0);\n"; + "uniform sampler2D source_sampler;\n" + "vec4 get_source()\n" + "{\n" + " return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb,\n" + " 1.0);\n" + "}\n"; + const char *mask_solid_fetch = + "uniform vec4 mask;\n" + "vec4 get_mask()\n" + "{\n" + " return mask;\n" + "}\n"; const char *mask_alpha_pixmap_fetch = - " vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n"; + "uniform sampler2D mask_sampler;\n" + "vec4 get_mask()\n" + "{\n" + " return texture2D(mask_sampler, gl_TexCoord[1].xy);\n" + "}\n"; const char *mask_pixmap_fetch = - " vec4 mask = vec4(texture2D(mask_sampler, " - " gl_TexCoord[1].xy).rgb, 1.0);\n"; - const char *source_in_mask = - " gl_FragColor = source * mask.a;\n"; - const char *source_only = - " gl_FragColor = source;\n"; - const char *main_closing = + "uniform sampler2D mask_sampler;\n" + "vec4 get_mask()\n" + "{\n" + " return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, \n" + " 1.0);\n" + "}\n"; + const char *in_source_only = + "void main()\n" + "{\n" + " gl_FragColor = get_source();\n" + "}\n"; + const char *in_normal = + "void main()\n" + "{\n" + " gl_FragColor = get_source() * get_mask().a;\n" "}\n"; char *source; - const char *source_setup = ""; - const char *source_fetch = ""; - const char *mask_setup = ""; + const char *source_fetch; const char *mask_fetch = ""; const char *in; GLuint prog; switch (key->source) { case SHADER_SOURCE_SOLID: - source_setup = source_solid_header; + source_fetch = source_solid_fetch; break; case SHADER_SOURCE_TEXTURE_ALPHA: - source_setup = source_pixmap_header; source_fetch = source_alpha_pixmap_fetch; break; case SHADER_SOURCE_TEXTURE: - source_setup = source_pixmap_header; source_fetch = source_pixmap_fetch; break; default: @@ -124,34 +142,33 @@ glamor_create_composite_fs(struct shader_key *key) case SHADER_MASK_NONE: break; case SHADER_MASK_SOLID: - mask_setup = mask_solid_header; + mask_fetch = mask_solid_fetch; break; case SHADER_MASK_TEXTURE_ALPHA: - mask_setup = mask_pixmap_header; mask_fetch = mask_alpha_pixmap_fetch; break; case SHADER_MASK_TEXTURE: - mask_setup = mask_pixmap_header; mask_fetch = mask_pixmap_fetch; break; default: FatalError("Bad composite shader mask"); } - if (key->mask == SHADER_MASK_NONE) { - in = source_only; - } else { - in = source_in_mask; + switch (key->in) { + case SHADER_IN_SOURCE_ONLY: + in = in_source_only; + break; + case SHADER_IN_NORMAL: + in = in_normal; + break; + default: + FatalError("Bad composite IN type"); } - source = XNFprintf("%s%s%s%s%s%s%s", - source_setup, - mask_setup, - main_opening, + source = XNFprintf("%s%s%s", source_fetch, mask_fetch, - in, - main_closing); + in); prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); xfree(source); @@ -245,7 +262,7 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_composite_shader *shader; - shader = &glamor_priv->composite_shader[key->source][key->mask]; + shader = &glamor_priv->composite_shader[key->source][key->mask][key->in]; if (shader->prog == 0) glamor_create_composite_shader(screen, key, shader); @@ -597,8 +614,11 @@ glamor_composite_with_shader(CARD8 op, key.mask = SHADER_MASK_TEXTURE; } } + + key.in = SHADER_IN_NORMAL; } else { key.mask = SHADER_MASK_NONE; + key.in = SHADER_IN_SOURCE_ONLY; } if (source->alphaMap) { glamor_fallback("source alphaMap\n"); @@ -851,6 +871,7 @@ glamor_composite(CARD8 op, width, height)) return; +fail: glamor_fallback("glamor_composite(): " "from picts %p/%p(%c,%c) to pict %p (%c)\n", source, mask, @@ -858,7 +879,7 @@ glamor_composite(CARD8 op, glamor_get_picture_location(mask), dest, glamor_get_picture_location(dest)); -fail: + glUseProgramObjectARB(0); glDisable(GL_BLEND); if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) { From 858ce0c1928c199435c9c2627f84c37c7ca7a38a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Feb 2010 14:02:48 -0800 Subject: [PATCH 093/225] glamor: Add support for component alpha rendering. Brings x11perf -rgb24text from 230/sec to 18400/sec --- glamor/glamor_priv.h | 2 ++ glamor/glamor_render.c | 64 +++++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 5ce74890b..1b9740fa3 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -116,6 +116,8 @@ enum shader_mask { enum shader_in { SHADER_IN_SOURCE_ONLY, SHADER_IN_NORMAL, + SHADER_IN_CA_SOURCE, + SHADER_IN_CA_ALPHA, SHADER_IN_COUNT, }; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index f4840dc0c..55d533856 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -118,6 +118,16 @@ glamor_create_composite_fs(struct shader_key *key) "{\n" " gl_FragColor = get_source() * get_mask().a;\n" "}\n"; + const char *in_ca_source = + "void main()\n" + "{\n" + " gl_FragColor = get_source() * get_mask();\n" + "}\n"; + const char *in_ca_alpha = + "void main()\n" + "{\n" + " gl_FragColor = get_source().a * get_mask();\n" + "}\n"; char *source; const char *source_fetch; const char *mask_fetch = ""; @@ -161,6 +171,12 @@ glamor_create_composite_fs(struct shader_key *key) case SHADER_IN_NORMAL: in = in_normal; break; + case SHADER_IN_CA_SOURCE: + in = in_ca_source; + break; + case SHADER_IN_CA_ALPHA: + in = in_ca_alpha; + break; default: FatalError("Bad composite IN type"); } @@ -615,11 +631,22 @@ glamor_composite_with_shader(CARD8 op, } } - key.in = SHADER_IN_NORMAL; + if (!mask->componentAlpha) { + key.in = SHADER_IN_NORMAL; + } else { + /* We only handle two CA modes. */ + if (op == PictOpAdd) + key.in = SHADER_IN_CA_SOURCE; + else { + assert(op == PictOpOutReverse); + key.in = SHADER_IN_CA_ALPHA; + } + } } else { key.mask = SHADER_MASK_NONE; key.in = SHADER_IN_SOURCE_ONLY; } + if (source->alphaMap) { glamor_fallback("source alphaMap\n"); goto fail; @@ -838,22 +865,25 @@ glamor_composite(CARD8 op, /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. */ - if (mask && mask->componentAlpha) - goto fail; - if (mask && mask->componentAlpha && op == PictOpOver) { - glamor_composite(PictOpOutReverse, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - glamor_composite(PictOpAdd, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - return; + if (mask && mask->componentAlpha) { + if (op == PictOpOver) { + glamor_composite(PictOpOutReverse, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + glamor_composite(PictOpAdd, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + return; + } else if (op != PictOpAdd && op != PictOpOutReverse) { + glamor_fallback("glamor_composite(): component alpha\n"); + goto fail; + } } if (!mask) { From 6ce05e0b28052e5206694228218322f0dd3a6b00 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Feb 2010 14:44:20 -0800 Subject: [PATCH 094/225] glamor: Convert the shaders path to handling glamor_composite_rect_t. --- glamor/glamor_priv.h | 2 + glamor/glamor_render.c | 219 +++++++++++++++++++++++------------------ 2 files changed, 127 insertions(+), 94 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 1b9740fa3..9a1640419 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -59,6 +59,8 @@ typedef struct glamor_composite_shader { typedef struct { INT16 x_src; INT16 y_src; + INT16 x_mask; + INT16 y_mask; INT16 x_dst; INT16 y_dst; INT16 width; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 55d533856..45c7d9c69 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -578,18 +578,12 @@ glamor_composite_with_shader(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, - INT16 y_dest, - CARD16 width, - CARD16 height) + int nrect, + glamor_composite_rect_t *rects) { ScreenPtr screen = dest->pDrawable->pScreen; PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); - PixmapPtr source_pixmap, mask_pixmap = NULL; + PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; glamor_pixmap_private *source_pixmap_priv = NULL; glamor_pixmap_private *mask_pixmap_priv = NULL; struct shader_key key; @@ -598,7 +592,9 @@ glamor_composite_with_shader(CARD8 op, float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2]; int i; BoxPtr box; - int dst_x_off, dst_y_off; + int dest_x_off, dest_y_off; + int source_x_off, source_y_off; + int mask_x_off, mask_y_off; memset(&key, 0, sizeof(key)); if (!source->pDrawable) { @@ -637,9 +633,11 @@ glamor_composite_with_shader(CARD8 op, /* We only handle two CA modes. */ if (op == PictOpAdd) key.in = SHADER_IN_CA_SOURCE; - else { - assert(op == PictOpOutReverse); + else if (op == PictOpOutReverse) { key.in = SHADER_IN_CA_ALPHA; + } else { + glamor_fallback("Unsupported component alpha op: %d\n", op); + goto fail; } } } else { @@ -705,17 +703,6 @@ glamor_composite_with_shader(CARD8 op, goto fail; } - x_dest += dest->pDrawable->x; - y_dest += dest->pDrawable->y; - if (source->pDrawable) { - x_source += source->pDrawable->x; - y_source += source->pDrawable->y; - } - if (mask && mask->pDrawable) { - x_mask += mask->pDrawable->x; - y_mask += mask->pDrawable->y; - } - if (key.source == SHADER_SOURCE_SOLID) { glamor_set_composite_solid(source, shader->source_uniform_location); } else { @@ -729,15 +716,6 @@ glamor_composite_with_shader(CARD8 op, } } - if (!miComputeCompositeRegion(®ion, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height)) - goto done; - - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); @@ -754,76 +732,124 @@ glamor_composite_with_shader(CARD8 op, } glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, - &dst_x_off, &dst_y_off); + &dest_x_off, &dest_y_off); if (source_pixmap) { - int dx, dy; - - glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &dx, &dy); - x_source += dx; - y_source += dy; + glamor_get_drawable_deltas(source->pDrawable, source_pixmap, + &source_x_off, &source_y_off); } if (mask_pixmap) { - int dx, dy; - - glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &dx, &dy); - x_mask += dx; - y_mask += dy; + glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, + &mask_x_off, &mask_y_off); } - box = REGION_RECTS(®ion); - for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { - vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off); - vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off); - vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off); - vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off); - vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off); - vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off); - vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off); - vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off); + while (nrect--) { + INT16 x_source; + INT16 y_source; + INT16 x_mask; + INT16 y_mask; + INT16 x_dest; + INT16 y_dest; + CARD16 width; + CARD16 height; - if (key.source != SHADER_SOURCE_SOLID) { - int tx1 = box[i].x1 + x_source - x_dest; - int ty1 = box[i].y1 + y_source - y_dest; - int tx2 = box[i].x2 + x_source - x_dest; - int ty2 = box[i].y2 + y_source - y_dest; + x_dest = rects->x_dst; + y_dest = rects->y_dst; + x_source = rects->x_src; + y_source = rects->y_src; + x_mask = rects->x_mask; + y_mask = rects->y_mask; + width = rects->width; + height = rects->height; - glamor_set_transformed_point(source, source_pixmap, - source_texcoords[0], tx1, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords[1], tx2, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords[2], tx2, ty2); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords[3], tx1, ty2); + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + if (source->pDrawable) { + x_source += source->pDrawable->x; + y_source += source->pDrawable->y; + } + if (mask && mask->pDrawable) { + x_mask += mask->pDrawable->x; + y_mask += mask->pDrawable->y; } - if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { - float tx1 = box[i].x1 + x_mask - x_dest; - float ty1 = box[i].y1 + y_mask - y_dest; - float tx2 = box[i].x2 + x_mask - x_dest; - float ty2 = box[i].y2 + y_mask - y_dest; + if (!miComputeCompositeRegion(®ion, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height)) + continue; - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[0], tx1, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[1], tx2, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[2], tx2, ty2); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[3], tx1, ty2); - } + x_source += source_x_off; + y_source += source_y_off; + x_mask += mask_x_off; + y_mask += mask_y_off; + + box = REGION_RECTS(®ion); + for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { + vertices[0][0] = v_from_x_coord_x(dest_pixmap, + box[i].x1 + dest_x_off); + vertices[0][1] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[1][0] = v_from_x_coord_x(dest_pixmap, + box[i].x2 + dest_x_off); + vertices[1][1] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[2][0] = v_from_x_coord_x(dest_pixmap, + box[i].x2 + dest_x_off); + vertices[2][1] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); + vertices[3][0] = v_from_x_coord_x(dest_pixmap, + box[i].x1 + dest_x_off); + vertices[3][1] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); + + if (key.source != SHADER_SOURCE_SOLID) { + int tx1 = box[i].x1 + x_source - x_dest; + int ty1 = box[i].y1 + y_source - y_dest; + int tx2 = box[i].x2 + x_source - x_dest; + int ty2 = box[i].y2 + y_source - y_dest; + + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[0], tx1, ty1); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[1], tx2, ty1); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[2], tx2, ty2); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords[3], tx1, ty2); + } + + if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { + float tx1 = box[i].x1 + x_mask - x_dest; + float ty1 = box[i].y1 + y_mask - y_dest; + float tx2 = box[i].x2 + x_mask - x_dest; + float ty2 = box[i].y2 + y_mask - y_dest; + + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[0], tx1, ty1); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[1], tx2, ty1); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[2], tx2, ty2); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords[3], tx1, ty2); + } #if 0 else memset(mask_texcoords, 0, sizeof(mask_texcoords)); - for (i = 0; i < 4; i++) { - ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) (%04.4f, %04.4f)\n", - i, - source_texcoords[i][0], source_texcoords[i][1], - mask_texcoords[i][0], mask_texcoords[i][1], - vertices[i][0], vertices[i][1]); - } + for (i = 0; i < 4; i++) { + ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) " + "(%04.4f, %04.4f)\n", + i, + source_texcoords[i][0], source_texcoords[i][1], + mask_texcoords[i][0], mask_texcoords[i][1], + vertices[i][0], vertices[i][1]); + } #endif - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + rects++; } glClientActiveTexture(GL_TEXTURE0); @@ -832,7 +858,6 @@ glamor_composite_with_shader(CARD8 op, glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); -done: REGION_UNINIT(dst->pDrawable->pScreen, ®ion); glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE0); @@ -862,6 +887,8 @@ glamor_composite(CARD8 op, CARD16 width, CARD16 height) { + glamor_composite_rect_t rect; + /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. */ @@ -894,11 +921,15 @@ glamor_composite(CARD8 op, return; } - if (glamor_composite_with_shader(op, source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height)) + rect.x_src = x_source; + rect.y_src = y_source; + rect.x_mask = x_mask; + rect.y_mask = y_mask; + rect.x_dst = x_dest; + rect.y_dst = y_dest; + rect.width = width; + rect.height = height; + if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect)) return; fail: From 8ce312e61952e9f2193c28ac6124eff30f3a122c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Feb 2010 14:49:06 -0800 Subject: [PATCH 095/225] glamor: Use glamor_composite_with_shader once per group of glyphs. This shaves CPU time in GL setup. Performance of rgb24text went from 18400/sec to 23500/sec. --- glamor/glamor_render.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 45c7d9c69..e78886c56 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1113,6 +1113,9 @@ glamor_composite_rects(CARD8 op, ValidatePicture(src); ValidatePicture(dst); + if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects)) + return; + n = nrect; r = rects; From 60775e21e3532452891e1b52589f7d5d7ef04b40 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Feb 2010 18:11:54 -0800 Subject: [PATCH 096/225] glamor: Use a VBO to accumulate multiple glyph quads at once. This increases us from 23000 to 27000/sec on rgb24text. --- glamor/glamor_priv.h | 8 ++ glamor/glamor_render.c | 182 ++++++++++++++++++++++++++++++++--------- 2 files changed, 150 insertions(+), 40 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 9a1640419..0db9b28c4 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -138,6 +138,12 @@ typedef struct glamor_screen_private { char *delayed_fallback_string; + GLuint vbo; + int vbo_offset; + int vbo_size; + char *vb; + int vb_stride; + /* glamor_finishaccess */ GLint finish_access_prog; @@ -159,6 +165,8 @@ typedef struct glamor_screen_private { glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] [SHADER_MASK_COUNT] [SHADER_IN_COUNT]; + Bool has_source_coords, has_mask_coords; + int render_nr_verts; glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; } glamor_screen_private; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index e78886c56..de57f5219 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -573,6 +573,114 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap, texcoord[1] = t_from_x_coord_y(pixmap, ty); } +static void +glamor_setup_composite_vbo(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + glamor_priv->vb_stride = 2 * sizeof(float); + if (glamor_priv->has_source_coords) + glamor_priv->vb_stride += 2 * sizeof(float); + if (glamor_priv->has_mask_coords) + glamor_priv->vb_stride += 2 * sizeof(float); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); + glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride, + (void *)(glamor_priv->vbo_offset)); + glEnableClientState(GL_VERTEX_ARRAY); + + if (glamor_priv->has_source_coords) { + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, + (void *)(glamor_priv->vbo_offset + 2 * sizeof(float))); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + if (glamor_priv->has_mask_coords) { + glClientActiveTexture(GL_TEXTURE1); + glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, + (void *)(glamor_priv->vbo_offset + + (glamor_priv->has_source_coords ? 4 : 2) * + sizeof(float))); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } +} + +static void +glamor_emit_composite_vert(ScreenPtr screen, + const float *src_coords, + const float *mask_coords, + const float *dst_coords, + int i) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + float *vb = (float *)(glamor_priv->vb + glamor_priv->vbo_offset); + int j = 0; + + vb[j++] = dst_coords[i * 2 + 0]; + vb[j++] = dst_coords[i * 2 + 1]; + if (glamor_priv->has_source_coords) { + vb[j++] = src_coords[i * 2 + 0]; + vb[j++] = src_coords[i * 2 + 1]; + } + if (glamor_priv->has_mask_coords) { + vb[j++] = mask_coords[i * 2 + 0]; + vb[j++] = mask_coords[i * 2 + 1]; + } + + glamor_priv->render_nr_verts++; + glamor_priv->vbo_offset += glamor_priv->vb_stride; +} + +static void +glamor_flush_composite_rects(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + if (!glamor_priv->render_nr_verts) + return; + + glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + glamor_priv->vb = NULL; + + glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts); + glamor_priv->render_nr_verts = 0; + glamor_priv->vbo_size = 0; +} + +static void +glamor_emit_composite_rect(ScreenPtr screen, + const float *src_coords, + const float *mask_coords, + const float *dst_coords) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride > + glamor_priv->vbo_size) + { + glamor_flush_composite_rects(screen); + } + + if (glamor_priv->vbo_size == 0) { + if (glamor_priv->vbo == 0) + glGenBuffersARB(1, &glamor_priv->vbo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); + + glamor_priv->vbo_size = 4096; + glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL, + GL_STREAM_DRAW_ARB); + glamor_priv->vbo_offset = 0; + glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + glamor_setup_composite_vbo(screen); + } + + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3); +} + static Bool glamor_composite_with_shader(CARD8 op, PicturePtr source, @@ -582,6 +690,7 @@ glamor_composite_with_shader(CARD8 op, glamor_composite_rect_t *rects) { ScreenPtr screen = dest->pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; glamor_pixmap_private *source_pixmap_priv = NULL; @@ -589,7 +698,7 @@ glamor_composite_with_shader(CARD8 op, struct shader_key key; glamor_composite_shader *shader; RegionRec region; - float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2]; + float vertices[8], source_texcoords[8], mask_texcoords[8]; int i; BoxPtr box; int dest_x_off, dest_y_off; @@ -716,20 +825,9 @@ glamor_composite_with_shader(CARD8 op, } } - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); - - if (key.source != SHADER_SOURCE_SOLID) { - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { - glClientActiveTexture(GL_TEXTURE1); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; + glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && + key.mask != SHADER_MASK_SOLID); glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, &dest_x_off, &dest_y_off); @@ -787,22 +885,22 @@ glamor_composite_with_shader(CARD8 op, box = REGION_RECTS(®ion); for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { - vertices[0][0] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); - vertices[0][1] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[1][0] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[1][1] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[2][0] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[2][1] = v_from_x_coord_y(dest_pixmap, - box[i].y2 + dest_y_off); - vertices[3][0] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); - vertices[3][1] = v_from_x_coord_y(dest_pixmap, - box[i].y2 + dest_y_off); + vertices[0] = v_from_x_coord_x(dest_pixmap, + box[i].x1 + dest_x_off); + vertices[1] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[2] = v_from_x_coord_x(dest_pixmap, + box[i].x2 + dest_x_off); + vertices[3] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[4] = v_from_x_coord_x(dest_pixmap, + box[i].x2 + dest_x_off); + vertices[5] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); + vertices[6] = v_from_x_coord_x(dest_pixmap, + box[i].x1 + dest_x_off); + vertices[7] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); if (key.source != SHADER_SOURCE_SOLID) { int tx1 = box[i].x1 + x_source - x_dest; @@ -811,13 +909,13 @@ glamor_composite_with_shader(CARD8 op, int ty2 = box[i].y2 + y_source - y_dest; glamor_set_transformed_point(source, source_pixmap, - source_texcoords[0], tx1, ty1); + source_texcoords + 0, tx1, ty1); glamor_set_transformed_point(source, source_pixmap, - source_texcoords[1], tx2, ty1); + source_texcoords + 2, tx2, ty1); glamor_set_transformed_point(source, source_pixmap, - source_texcoords[2], tx2, ty2); + source_texcoords + 4, tx2, ty2); glamor_set_transformed_point(source, source_pixmap, - source_texcoords[3], tx1, ty2); + source_texcoords + 6, tx1, ty2); } if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { @@ -827,13 +925,13 @@ glamor_composite_with_shader(CARD8 op, float ty2 = box[i].y2 + y_mask - y_dest; glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[0], tx1, ty1); + mask_texcoords + 0, tx1, ty1); glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[1], tx2, ty1); + mask_texcoords + 2, tx2, ty1); glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[2], tx2, ty2); + mask_texcoords + 4, tx2, ty2); glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords[3], tx1, ty2); + mask_texcoords + 6, tx1, ty2); } #if 0 else memset(mask_texcoords, 0, sizeof(mask_texcoords)); @@ -847,11 +945,15 @@ glamor_composite_with_shader(CARD8 op, } #endif - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glamor_emit_composite_rect(screen, source_texcoords, + mask_texcoords, vertices); } rects++; } + glamor_flush_composite_rects(screen); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE1); From 003dee4c82f8af9e7749876c736018410f347440 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Feb 2010 06:10:11 -0800 Subject: [PATCH 097/225] glamor: Replace the immediate mode in glamor_fill() with glDrawArrays(). --- glamor/glamor_fill.c | 42 ++++++++++++++++------------------------ glamor/glamor_priv.h | 1 - glamor/glamor_putimage.c | 20 ++++++++++--------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 8e269e22e..c3e0528bf 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -92,29 +92,15 @@ glamor_init_solid_shader(ScreenPtr screen) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); const char *solid_vs_only = "uniform vec4 color;\n" - "uniform float x_bias;\n" - "uniform float x_scale;\n" - "uniform float y_bias;\n" - "uniform float y_scale;\n" "void main()\n" "{\n" - " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" - " (gl_Vertex.y + y_bias) * y_scale,\n" - " 0,\n" - " 1);\n" + " gl_Position = gl_Vertex;\n" " gl_Color = color;\n" "}\n"; const char *solid_vs = - "uniform float x_bias;\n" - "uniform float x_scale;\n" - "uniform float y_bias;\n" - "uniform float y_scale;\n" "void main()\n" "{\n" - " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" - " (gl_Vertex.y + y_bias) * y_scale,\n" - " 0,\n" - " 1);\n" + " gl_Position = gl_Vertex;\n" "}\n"; const char *solid_fs = "uniform vec4 color;\n" @@ -138,8 +124,6 @@ glamor_init_solid_shader(ScreenPtr screen) glamor_priv->solid_color_uniform_location = glGetUniformLocationARB(glamor_priv->solid_prog, "color"); - glamor_get_transform_uniform_locations(glamor_priv->solid_prog, - &glamor_priv->solid_transform); } void @@ -153,6 +137,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, int y1 = y; int y2 = y + height; GLfloat color[4]; + float vertices[4][2]; if (!glamor_set_destination_pixmap(pixmap)) return; @@ -163,15 +148,22 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color); glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color); - glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform); - glBegin(GL_TRIANGLE_FAN); - glVertex2f(x1, y1); - glVertex2f(x1, y2); - glVertex2f(x2, y2); - glVertex2f(x2, y1); - glEnd(); + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + vertices[0][0] = v_from_x_coord_x(pixmap, x1); + vertices[0][1] = v_from_x_coord_y(pixmap, y1); + vertices[1][0] = v_from_x_coord_x(pixmap, x2); + vertices[1][1] = v_from_x_coord_y(pixmap, y1); + vertices[2][0] = v_from_x_coord_x(pixmap, x2); + vertices[2][1] = v_from_x_coord_y(pixmap, y2); + vertices[3][0] = v_from_x_coord_x(pixmap, x1); + vertices[3][1] = v_from_x_coord_y(pixmap, y2); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); glUseProgramObjectARB(0); fail: glamor_set_alu(GXcopy); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 0db9b28c4..3dc3a5389 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -150,7 +150,6 @@ typedef struct glamor_screen_private { /* glamor_solid */ GLint solid_prog; GLint solid_color_uniform_location; - glamor_transform_uniforms solid_transform; /* glamor_tile */ GLint tile_prog; diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 74910fa67..ead5b692e 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -124,12 +124,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, RegionPtr clip; BoxPtr box; int nbox; - float dest_coords[8] = { - x, y, - x + w, y, - x + w, y + h, - x, y + h, - }; + float dest_coords[4][2]; const float bitmap_coords[8] = { 0.0, 0.0, 1.0, 0.0, @@ -137,7 +132,16 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, 0.0, 1.0, }; - glamor_fallback("glamor_put_image_xybitmap: disabled\n"); + dest_coords[0][0] = v_from_x_coord_x(pixmap, x); + dest_coords[0][1] = v_from_x_coord_y(pixmap, y); + dest_coords[1][0] = v_from_x_coord_x(pixmap, x + w); + dest_coords[1][1] = v_from_x_coord_y(pixmap, y); + dest_coords[2][0] = v_from_x_coord_x(pixmap, x + w); + dest_coords[2][1] = v_from_x_coord_y(pixmap, y + h); + dest_coords[3][0] = v_from_x_coord_x(pixmap, x); + dest_coords[3][1] = v_from_x_coord_y(pixmap, y + h); + + glamor_fallback("glamor_put_image_xybitmap: disabled\n"); goto fail; if (glamor_priv->put_image_xybitmap_prog == 0) { @@ -158,8 +162,6 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, glUniform4fvARB(glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); - glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform); - glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); From 955ccfbc34f370c80f7189ac5b0240e859e00b5f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Feb 2010 07:52:50 -0800 Subject: [PATCH 098/225] glamor: Fix the segfault at screen fini. --- glamor/glamor.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 03db7ecec..b7259afa4 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -260,8 +260,10 @@ glamor_fini(ScreenPtr screen) screen->CopyWindow = glamor_priv->saved_copy_window; screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region; #ifdef RENDER - ps->Composite = glamor_priv->saved_composite; - ps->Trapezoids = glamor_priv->saved_trapezoids; - ps->Glyphs = glamor_priv->saved_glyphs; + if (ps) { + ps->Composite = glamor_priv->saved_composite; + ps->Trapezoids = glamor_priv->saved_trapezoids; + ps->Glyphs = glamor_priv->saved_glyphs; + } #endif } From d2da9d1c22d25d1f86ecd83c15ca9909fab8610a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Feb 2010 07:36:28 -0800 Subject: [PATCH 099/225] glamor: Reduce the noise from wide lines "fallback". --- glamor/glamor_polylines.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index 5a7204b5e..acf6bf673 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -52,7 +52,10 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0) { - glamor_fallback("glamor_poly_lines(): wide lines\n"); + /* This ends up in miSetSpans, which is accelerated as well as we + * can hope X wide lines will be. + */ + /*glamor_fallback("glamor_poly_lines(): wide lines\n");*/ goto fail; } if (gc->lineStyle != LineSolid || From 8cfcc614032320bb6a2eca2c61baeebf388d22ea Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Feb 2010 07:14:13 -0800 Subject: [PATCH 100/225] glamor: Add support for using EXT_framebuffer_blit to do CopyArea. --- glamor/glamor_copyarea.c | 87 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 172b9593c..297a1fbc5 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -32,6 +32,88 @@ * GC CopyArea implementation */ +static Bool +glamor_copy_n_to_n_fbo_blit(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy) +{ + ScreenPtr screen = dst->pScreen; + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + glamor_pixmap_private *src_pixmap_priv; + int dst_x_off, dst_y_off, src_x_off, src_y_off, i; + + if (src == dst) { + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " + "src == dest\n"); + return FALSE; + } + + if (!GLEW_EXT_framebuffer_blit) { + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " + "no EXT_framebuffer_blit\n"); + return FALSE; + } + + src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); + + if (src_pixmap_priv->fb == 0) { + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (src_pixmap != screen_pixmap) { + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " + "no src fbo\n"); + return FALSE; + } + } + + if (gc) { + if (gc->alu != GXcopy) { + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " + "non-copy ALU\n"); + return FALSE; + } + if (!glamor_pm_is_solid(dst, gc->planemask)) { + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " + "non-solid planemask\n"); + return FALSE; + } + } + + if (!glamor_set_destination_pixmap(dst_pixmap)) + return FALSE; + + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); + + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); + glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); + src_y_off += dy; + + for (i = 0; i < nbox; i++) { + int flip_dst_y1 = dst_pixmap->drawable.height - (box[i].y2 + dst_y_off); + int flip_dst_y2 = dst_pixmap->drawable.height - (box[i].y1 + dst_y_off); + int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off); + int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off); + + glBlitFramebufferEXT(box[i].x1 + dx + src_x_off, + flip_src_y1, + box[i].x2 + dx + src_x_off, + flip_src_y2, + box[i].x1 + dst_x_off, + flip_dst_y1, + box[i].x2 + dst_x_off, + flip_dst_y2, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + } + + return TRUE; +} + static Bool glamor_copy_n_to_n_copypixels(DrawablePtr src, DrawablePtr dst, @@ -199,6 +281,11 @@ glamor_copy_n_to_n(DrawablePtr src, Pixel bitplane, void *closure) { + if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { + glamor_clear_delayed_fallbacks(dst->pScreen); + return; + } + if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) { glamor_clear_delayed_fallbacks(dst->pScreen); return; From e194740c9413bbfefee6506a734e0c82c091dfa3 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 8 Apr 2011 14:49:57 +0800 Subject: [PATCH 101/225] glamor: Fixed some compiling and linking errors. Change the inline functions to static type, otherwise when linking it complains multiple definitions of those functions. --- glamor/glu3/glu3.h | 4 +-- glamor/glu3/glu3_scalar.h | 52 +++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h index 29dba380a..27bcebc80 100644 --- a/glamor/glu3/glu3.h +++ b/glamor/glu3/glu3.h @@ -123,7 +123,7 @@ typedef struct GLUmat4Stack GLUmat4Stack; #ifdef __cplusplus extern "C" { #endif - +#if 0 GLfloat gluDot4_4v(const GLUvec4 *, const GLUvec4 *); GLfloat gluDot3_4v(const GLUvec4 *, const GLUvec4 *); GLfloat gluDot2_4v(const GLUvec4 *, const GLUvec4 *); @@ -169,7 +169,7 @@ void gluOrtho6f(GLUmat4 *result, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far); - +#endif extern const GLUmat4 gluIdentityMatrix; #ifdef __cplusplus diff --git a/glamor/glu3/glu3_scalar.h b/glamor/glu3/glu3_scalar.h index 3e87b8cce..00592f0dc 100644 --- a/glamor/glu3/glu3_scalar.h +++ b/glamor/glu3/glu3_scalar.h @@ -24,7 +24,7 @@ #include #include -extern inline void gluMult4v_4v(GLUvec4 *result, +static inline void gluMult4v_4v(GLUvec4 *result, const GLUvec4 *v1, const GLUvec4 *v2) { result->values[0] = v1->values[0] * v2->values[0]; @@ -34,7 +34,7 @@ extern inline void gluMult4v_4v(GLUvec4 *result, } -extern inline void gluDiv4v_4v(GLUvec4 *result, +static inline void gluDiv4v_4v(GLUvec4 *result, const GLUvec4 *v1, const GLUvec4 *v2) { result->values[0] = v1->values[0] / v2->values[0]; @@ -44,7 +44,7 @@ extern inline void gluDiv4v_4v(GLUvec4 *result, } -extern inline void gluAdd4v_4v(GLUvec4 *result, +static inline void gluAdd4v_4v(GLUvec4 *result, const GLUvec4 *v1, const GLUvec4 *v2) { result->values[0] = v1->values[0] + v2->values[0]; @@ -54,7 +54,7 @@ extern inline void gluAdd4v_4v(GLUvec4 *result, } -extern inline void gluSub4v_4v(GLUvec4 *result, +static inline void gluSub4v_4v(GLUvec4 *result, const GLUvec4 *v1, const GLUvec4 *v2) { result->values[0] = v1->values[0] - v2->values[0]; @@ -64,7 +64,7 @@ extern inline void gluSub4v_4v(GLUvec4 *result, } -extern inline void gluMult4v_f(GLUvec4 *result, +static inline void gluMult4v_f(GLUvec4 *result, const GLUvec4 *v1, GLfloat f) { result->values[0] = v1->values[0] * f; @@ -74,7 +74,7 @@ extern inline void gluMult4v_f(GLUvec4 *result, } -extern inline void gluDiv4v_f(GLUvec4 *result, +static inline void gluDiv4v_f(GLUvec4 *result, const GLUvec4 *v1, GLfloat f) { result->values[0] = v1->values[0] / f; @@ -84,7 +84,7 @@ extern inline void gluDiv4v_f(GLUvec4 *result, } -extern inline void gluAdd4v_f(GLUvec4 *result, +static inline void gluAdd4v_f(GLUvec4 *result, const GLUvec4 *v1, GLfloat f) { result->values[0] = v1->values[0] + f; @@ -94,7 +94,7 @@ extern inline void gluAdd4v_f(GLUvec4 *result, } -extern inline void gluSub4v_f(GLUvec4 *result, +static inline void gluSub4v_f(GLUvec4 *result, const GLUvec4 *v1, GLfloat f) { result->values[0] = v1->values[0] - f; @@ -104,7 +104,7 @@ extern inline void gluSub4v_f(GLUvec4 *result, } -extern inline void gluMult4m_f(GLUmat4 *result, +static inline void gluMult4m_f(GLUmat4 *result, const GLUmat4 *m, GLfloat f) { GLUmat4 temp; @@ -117,7 +117,7 @@ extern inline void gluMult4m_f(GLUmat4 *result, } -extern inline void gluMult4m_4v(GLUvec4 *result, +static inline void gluMult4m_4v(GLUvec4 *result, const GLUmat4 *m, const GLUvec4 *v) { GLUvec4 temp[6]; @@ -133,7 +133,7 @@ extern inline void gluMult4m_4v(GLUvec4 *result, } -extern inline void gluAdd4m_4m(GLUmat4 *result, +static inline void gluAdd4m_4m(GLUmat4 *result, const GLUmat4 *m1, const GLUmat4 *m2) { GLUmat4 temp; @@ -145,7 +145,7 @@ extern inline void gluAdd4m_4m(GLUmat4 *result, *result = temp; } -extern inline void gluSub4m_4m(GLUmat4 *result, +static inline void gluSub4m_4m(GLUmat4 *result, const GLUmat4 *m1, const GLUmat4 *m2) { GLUmat4 temp; @@ -157,7 +157,7 @@ extern inline void gluSub4m_4m(GLUmat4 *result, *result = temp; } -extern inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2) +static inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2) { return v1->values[0] * v2->values[0] + v1->values[1] * v2->values[1] @@ -166,7 +166,7 @@ extern inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2) } -extern inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2) +static inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2) { return v1->values[0] * v2->values[0] + v1->values[1] * v2->values[1] @@ -174,14 +174,14 @@ extern inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2) } -extern inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2) +static inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2) { return v1->values[0] * v2->values[0] + v1->values[1] * v2->values[1]; } -extern inline void gluCross4v(GLUvec4 *result, +static inline void gluCross4v(GLUvec4 *result, const GLUvec4 *v1, const GLUvec4 *v2) { GLUvec4 temp; @@ -197,7 +197,7 @@ extern inline void gluCross4v(GLUvec4 *result, } -extern inline void gluOuter4v(GLUmat4 *result, +static inline void gluOuter4v(GLUmat4 *result, const GLUvec4 *v1, const GLUvec4 *v2) { GLUmat4 temp; @@ -210,26 +210,26 @@ extern inline void gluOuter4v(GLUmat4 *result, } -extern inline GLfloat gluLengthSqr4v(const GLUvec4 *v) +static inline GLfloat gluLengthSqr4v(const GLUvec4 *v) { return gluDot4_4v(v, v); } -extern inline GLfloat gluLength4v(const GLUvec4 *v) +static inline GLfloat gluLength4v(const GLUvec4 *v) { return sqrt(gluLengthSqr4v(v)); } -extern inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v) +static inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v) { gluDiv4v_f(result, v, gluLength4v(v)); } -extern inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m) +static inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m) { unsigned i; unsigned j; @@ -245,7 +245,7 @@ extern inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m) } -extern inline void gluMult4m_4m(GLUmat4 *result, +static inline void gluMult4m_4m(GLUmat4 *result, const GLUmat4 *m1, const GLUmat4 *m2) { GLUmat4 temp; @@ -260,7 +260,7 @@ extern inline void gluMult4m_4m(GLUmat4 *result, -extern inline void gluTranslate3f(GLUmat4 *result, +static inline void gluTranslate3f(GLUmat4 *result, GLfloat x, GLfloat y, GLfloat z) { memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix)); @@ -271,7 +271,7 @@ extern inline void gluTranslate3f(GLUmat4 *result, #ifdef __cplusplus -extern inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2) +static inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2) { return v1.values[0] * v2.values[0] + v1.values[1] * v2.values[1] @@ -280,7 +280,7 @@ extern inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2) } -extern inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2) +static inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2) { return v1.values[0] * v2.values[0] + v1.values[1] * v2.values[1] @@ -288,7 +288,7 @@ extern inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2) } -extern inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2) +static inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2) { return v1.values[0] * v2.values[0] + v1.values[1] * v2.values[1]; From f9843c7a35975b178eec9812d21e1f02a2120928 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 8 Apr 2011 14:53:15 +0800 Subject: [PATCH 102/225] glamor: Fixed one conflict data type(XID) bug. We should include the dix-config.h for all the glamor files. Otherwise the XID type maybe inconsisitent in different files in 64bit machine. The root cause is this macro "#define _XSERVER64 1" should be included in all files refer to the data type "XID" which is originally defined in X.h. If _XSERVER64 is defined as 1, then XID is defined as CARD32 which is a 32bit integer. If _XSERVER64 is not defined as 1 then XID is "unsigned long". In a 32bit machine, "unsigned long" should be identical to CARD32. But in a 64bit machine, they are different. --- glamor/glamor_priv.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 3dc3a5389..18bd76b12 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -24,10 +24,14 @@ * Eric Anholt * */ - #ifndef GLAMOR_PRIV_H #define GLAMOR_PRIV_H +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + + #include "glamor.h" #include From 3105fe9f6491f37a1f82a9e6f03f4efaed6c7e92 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 8 Apr 2011 15:22:52 +0800 Subject: [PATCH 103/225] glamor: Call glamor_composite_rects only when enable RENDER. --- glamor/glamor_glyphs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index 7b2d13d0f..6e5595e68 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -572,8 +572,10 @@ glamor_buffer_glyph(ScreenPtr screen, static void glamor_glyphs_to_mask(PicturePtr mask, glamor_glyph_buffer_t *buffer) { +#ifdef RENDER glamor_composite_rects(PictOpAdd, buffer->source, mask, buffer->count, buffer->rects); +#endif buffer->count = 0; buffer->source = NULL; From b3577a1c853d870f4d583a35d27012acb9099ef4 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 8 Apr 2011 15:24:55 +0800 Subject: [PATCH 104/225] glamor: Merged with latest xserver. Merged with latest xserver, the major change is due to the API change of the management of devPrivates. --- glamor/glamor.c | 67 ++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index b7259afa4..29cefa8ec 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -30,17 +30,13 @@ * functions not responsible for performing rendering. */ -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - #include #include "glamor_priv.h" -static int glamor_screen_private_key_index; +static DevPrivateKeyRec glamor_screen_private_key_index; DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index; -static int glamor_pixmap_private_key_index; +static DevPrivateKeyRec glamor_pixmap_private_key_index; DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index; /** @@ -68,54 +64,59 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) { PixmapPtr pixmap; - glamor_pixmap_private *pixmap_priv; + glamor_pixmap_private *pixmap_priv, *newpixmap_priv; GLenum format; if (w > 32767 || h > 32767) return NullPixmap; pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); + if (dixAllocatePrivates(pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { + fbDestroyPixmap(pixmap); + ErrorF("Fail to allocate privates for PIXMAP.\n"); + return NullPixmap; + } pixmap_priv = glamor_get_pixmap_private(pixmap); + assert(pixmap_priv != NULL); if (w == 0 || h == 0) return pixmap; - /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA. * FBOs, which EXT_fbo forgot to do. */ switch (depth) { case 24: - format = GL_RGB; - break; + format = GL_RGB; + break; default: - format = GL_RGBA; - break; + format = GL_RGBA; + break; } + /* Create the texture used to store the pixmap's data. */ glGenTextures(1, &pixmap_priv->tex); glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, - format, GL_UNSIGNED_BYTE, NULL); + format, GL_UNSIGNED_BYTE, NULL); - /* Create a framebuffer object wrapping the texture so that we can render - * to it. - */ + /* Create a framebuffer object wrapping the texture so that we can render + ** to it. + **/ glGenFramebuffersEXT(1, &pixmap_priv->fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, - pixmap_priv->tex, - 0); + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + pixmap_priv->tex, + 0); - screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, + screen->ModifyPixmapHeader(pixmap, w, h, depth, 0, (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3, NULL); - return pixmap; } @@ -156,13 +157,22 @@ glamor_init(ScreenPtr screen) if (glamor_priv == NULL) return FALSE; - dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); - if (!dixRequestPrivate(glamor_pixmap_private_key, - sizeof(glamor_pixmap_private))) { + + if (!dixRegisterPrivateKey(glamor_screen_private_key,PRIVATE_SCREEN, + 0)) { LogMessage(X_WARNING, - "glamor%d: Failed to allocate pixmap private\n", + "glamor%d: Failed to allocate screen private\n", screen->myNum); } + dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); + + if (!dixRegisterPrivateKey(glamor_pixmap_private_key,PRIVATE_PIXMAP, + sizeof(glamor_pixmap_private))) { + LogMessage(X_WARNING, + "glamor%d: Failed to allocate pixmap private\n", + screen->myNum); + } + glewInit(); @@ -224,16 +234,15 @@ glamor_init(ScreenPtr screen) ps->Trapezoids = glamor_trapezoids; glamor_priv->saved_glyphs = ps->Glyphs; ps->Glyphs = glamor_glyphs; + glamor_init_composite_shaders(screen); #endif - glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); glamor_init_putimage_shaders(screen); - glamor_init_composite_shaders(screen); glamor_init_finish_access_shaders(screen); - glamor_glyphs_init(screen); + return TRUE; fail: From 0d9e8db8d031d22b02df2c9b226287b1ca489f5a Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 8 Apr 2011 15:30:45 +0800 Subject: [PATCH 105/225] glamor: Fixed one linking error. As current glamor implementation depends on the glx library in the mesa package which is conflict with the version in xorg. We have to --disable-glx when build Xephyr. But this leads to the linking error here. We comment out the calling to ephyrHijackGLXExtension() now. Need revisit latter. --- hw/kdrive/ephyr/ephyr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 1aacc5fe8..4bead1f36 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -669,7 +669,9 @@ ephyrInitScreen (ScreenPtr pScreen) } if (!ephyrNoDRI) { ephyrDRIExtensionInit (pScreen) ; +#if 0 ephyrHijackGLXExtension () ; +#endif } #endif From 47b6531273e3052b653194099a49ca11d80b12df Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 13 Apr 2011 15:50:26 +0800 Subject: [PATCH 106/225] glamor: Fixed one segfault bug when close screen. move the original glamor_fini to glamor_close_screen. And wrap the CloseScreen with glamor_close_screen, Then we can do some thing before call the underlying CloseScreen(). The root cause is that glamor_fini will be called after the ->CloseScreen(). This may trigger a segmentation fault at glamor_unrealize_glyph_caches() at calling into FreePicture(). --- glamor/glamor.c | 18 +++++++++++++++--- glamor/glamor_priv.h | 4 ++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 29cefa8ec..537fb685c 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -203,6 +203,9 @@ glamor_init(ScreenPtr screen) goto fail; } + glamor_priv->saved_close_screen = screen->CloseScreen; + screen->CloseScreen = glamor_close_screen; + glamor_priv->saved_create_gc = screen->CreateGC; screen->CreateGC = glamor_create_gc; @@ -251,8 +254,8 @@ fail: return FALSE; } -void -glamor_fini(ScreenPtr screen) +Bool +glamor_close_screen(int idx, ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); #ifdef RENDER @@ -260,7 +263,7 @@ glamor_fini(ScreenPtr screen) #endif glamor_glyphs_fini(screen); - + screen->CloseScreen = glamor_priv->saved_close_screen; screen->CreateGC = glamor_priv->saved_create_gc; screen->CreatePixmap = glamor_priv->saved_create_pixmap; screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; @@ -275,4 +278,13 @@ glamor_fini(ScreenPtr screen) ps->Glyphs = glamor_priv->saved_glyphs; } #endif + free(glamor_priv); + return screen->CloseScreen(idx, screen); + +} + +void +glamor_fini(ScreenPtr screen) +{ +/* Do nothing currently. */ } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 18bd76b12..c2f516d9c 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -128,6 +128,7 @@ enum shader_in { }; typedef struct glamor_screen_private { + CloseScreenProcPtr saved_close_screen; CreateGCProcPtr saved_create_gc; CreatePixmapProcPtr saved_create_pixmap; DestroyPixmapProcPtr saved_destroy_pixmap; @@ -282,6 +283,9 @@ t_from_x_coord_y(PixmapPtr pixmap, int y) /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); +Bool glamor_close_screen(int idx, ScreenPtr screen); + + /* glamor_copyarea.c */ RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, From 49bf0e301e7317a02e8b34ec2e290fcfda520e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 5 Mar 2010 14:53:35 -0500 Subject: [PATCH 107/225] glamor ddx driver using EGL on KMS --- hw/xfree86/glamor/Makefile.am | 21 + hw/xfree86/glamor/glamor.c | 530 +++++++++++ hw/xfree86/glamor/glamor_crtc.c | 1493 +++++++++++++++++++++++++++++++ hw/xfree86/glamor/glamor_ddx.h | 15 + 4 files changed, 2059 insertions(+) create mode 100644 hw/xfree86/glamor/Makefile.am create mode 100644 hw/xfree86/glamor/glamor.c create mode 100644 hw/xfree86/glamor/glamor_crtc.c create mode 100644 hw/xfree86/glamor/glamor_ddx.h diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am new file mode 100644 index 000000000..4c82b42b8 --- /dev/null +++ b/hw/xfree86/glamor/Makefile.am @@ -0,0 +1,21 @@ +glamor_la_LTLIBRARIES = glamor.la +glamor_la_CFLAGS = \ + -DHAVE_XORG_CONFIG_H \ + @DIX_CFLAGS@ @XORG_CFLAGS@ \ + -I$(top_srcdir)/hw/xfree86/common \ + -I$(top_srcdir)/hw/xfree86/os-support/bus \ + -I$(top_srcdir)/hw/xfree86/parser \ + -I$(top_srcdir)/hw/xfree86/modes \ + -I$(top_srcdir)/hw/xfree86/ddc \ + -I$(top_srcdir)/hw/xfree86/ramdac \ + -I$(top_srcdir)/hw/xfree86/i2c \ + -I$(top_srcdir)/glamor \ + -I/usr/include/drm + +glamor_la_LDFLAGS = \ + -module -avoid-version -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW +glamor_ladir = $(moduledir)/drivers +glamor_la_SOURCES = \ + glamor.c \ + glamor_crtc.c \ + glamor_ddx.h diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c new file mode 100644 index 000000000..b80d58758 --- /dev/null +++ b/hw/xfree86/glamor/glamor.c @@ -0,0 +1,530 @@ +/* + * Copyright © 2010 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: + * Kristian Høgsberg + * + */ + +#include +#include +#include +#include + +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#define EGL_DISPLAY_NO_X_MESA +#include +#include +#include + +#include "../../../mi/micmap.h" +#include +#include +#include + +#include "glamor_ddx.h" + +#define GLAMOR_VERSION_MAJOR 0 +#define GLAMOR_VERSION_MINOR 1 +#define GLAMOR_VERSION_PATCH 0 + +static const char glamor_name[] = "glamor"; + +static void +glamor_identify(int flags) +{ + xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver\n", glamor_name); +} + +struct glamor_screen_private { + EGLDisplay display; + EGLContext context; + EGLImageKHR root, cursor; + EGLint major, minor; + GLuint cursor_tex; + + CreateScreenResourcesProcPtr CreateScreenResources; + CloseScreenProcPtr CloseScreen; + int fd; + int cpp; +}; + +static inline struct glamor_screen_private * +glamor_get_screen_private(ScrnInfoPtr scrn) +{ + return (struct glamor_screen_private *) (scrn->driverPrivate); +} + +Bool +glamor_resize(ScrnInfoPtr scrn, int width, int height) +{ + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + EGLImageKHR image; + GLuint texture; + EGLint attribs[] = { + EGL_IMAGE_WIDTH_INTEL, 0, + EGL_IMAGE_HEIGHT_INTEL, 0, + EGL_IMAGE_FORMAT_INTEL, EGL_FORMAT_RGBA_8888_KHR, + EGL_IMAGE_USE_INTEL, EGL_IMAGE_USE_SHARE_INTEL | + EGL_IMAGE_USE_SCANOUT_INTEL, + EGL_NONE + }; + + if (glamor->root != EGL_NO_IMAGE_KHR && + scrn->virtualX == width && scrn->virtualY == height) + return TRUE; + + attribs[1] = width; + attribs[3] = height; + image = eglCreateImageKHR(glamor->display, glamor->context, + EGL_SYSTEM_IMAGE_INTEL, + NULL, attribs); + if (image == EGL_NO_IMAGE_KHR) + return FALSE; + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + + glamor_set_pixmap_texture(screen->GetScreenPixmap(screen), + width, height, texture); + glamor->root = image; + scrn->virtualX = width; + scrn->virtualY = height; + + return TRUE; +} + +void +glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) +{ + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + EGLint name; + + eglShareImageINTEL (glamor->display, glamor->context, glamor->root, 0, + &name, (EGLint *) handle, (EGLint *) pitch); +} + +Bool +glamor_load_cursor(ScrnInfoPtr scrn, CARD32 *image, int width, int height) +{ + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + + if (glamor->cursor == NULL) { + EGLint attribs[] = { + EGL_IMAGE_WIDTH_INTEL, 0, + EGL_IMAGE_HEIGHT_INTEL, 0, + EGL_IMAGE_FORMAT_INTEL, EGL_FORMAT_RGBA_8888_KHR, + EGL_IMAGE_USE_INTEL, EGL_IMAGE_USE_SHARE_INTEL | + EGL_IMAGE_USE_SCANOUT_INTEL, + EGL_NONE + }; + + attribs[1] = width; + attribs[3] = height; + glamor->cursor = + eglCreateImageKHR(glamor->display, glamor->context, + EGL_SYSTEM_IMAGE_INTEL, + NULL, attribs); + if (image == EGL_NO_IMAGE_KHR) + return FALSE; + + glGenTextures(1, &glamor->cursor_tex); + glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, glamor->cursor); + } + + glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + + return TRUE; +} + +void +glamor_cursor_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) +{ + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + EGLint name; + + eglShareImageINTEL (glamor->display, glamor->context, glamor->cursor, + 0, &name, (EGLint *) handle, (EGLint *) pitch); + ErrorF("cursor stride: %d\n", *pitch); +} + +static Bool +glamor_pre_init(ScrnInfoPtr scrn, int flags) +{ + struct glamor_screen_private *glamor; + rgb defaultWeight = { 0, 0, 0 }; + + glamor = xnfcalloc(sizeof *glamor, 1); + + scrn->driverPrivate = glamor; + + glamor->fd = open("/dev/dri/card0", O_RDWR); + glamor->cpp = 4; + + scrn->monitor = scrn->confScreen->monitor; + scrn->progClock = TRUE; + scrn->rgbBits = 8; + + if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb)) + return FALSE; + + xf86PrintDepthBpp(scrn); + + if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) + return FALSE; + if (!xf86SetDefaultVisual(scrn, -1)) + return FALSE; + + glamor->cpp = scrn->bitsPerPixel / 8; + + if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Kernel modesetting setup failed\n"); + xfree(glamor); + return FALSE; + } + + scrn->currentMode = scrn->modes; + xf86SetDpi(scrn, 0, 0); + + /* Load the required sub modules */ + if (!xf86LoadSubModule(scrn, "fb")) + return FALSE; + + return TRUE; +} + +static void +glamor_adjust_frame(int scrnIndex, int x, int y, int flags) +{ +} + +static Bool +glamor_enter_vt(int scrnIndex, int flags) +{ + ScrnInfoPtr scrn = xf86Screens[scrnIndex]; + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + + if (drmSetMaster(glamor->fd)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "drmSetMaster failed: %s\n", strerror(errno)); + return FALSE; + } + + return TRUE; +} + +static void +glamor_leave_vt(int scrnIndex, int flags) +{ + ScrnInfoPtr scrn = xf86Screens[scrnIndex]; + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + + drmDropMaster(glamor->fd); +} + +static Bool +glamor_create_screen_resources(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + + screen->CreateScreenResources = glamor->CreateScreenResources; + if (!(*screen->CreateScreenResources) (screen)) + return FALSE; + + if (!xf86SetDesiredModes(scrn)) + return FALSE; + + return TRUE; +} + +static Bool +glamor_close_screen(int scrnIndex, ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[scrnIndex]; + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + + if (scrn->vtSema == TRUE) + glamor_leave_vt(scrnIndex, 0); + + glamor_fini(screen); + + eglMakeCurrent(glamor->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglTerminate(glamor->display); + + drmmode_closefb(scrn); + + screen->CloseScreen = glamor->CloseScreen; + (*screen->CloseScreen) (scrnIndex, screen); + + return TRUE; +} + +static Bool +glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + EGLDisplayTypeDRMMESA display; + const char *version; + + display.type = EGL_DISPLAY_TYPE_DRM_MESA; + display.device = NULL; + display.fd = glamor->fd; + + glamor->display = eglGetDisplay((EGLNativeDisplayType) &display); + + if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "eglInitialize() failed\n"); + return FALSE; + } + + version = eglQueryString(glamor->display, EGL_VERSION); + xf86Msg(X_INFO, "%s: EGL version %s:", glamor_name, version); + + glamor->context = eglCreateContext(glamor->display, + NULL, EGL_NO_CONTEXT, NULL); + if (glamor->context == EGL_NO_CONTEXT) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to create EGL context\n"); + return FALSE; + } + if (!eglMakeCurrent(glamor->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to make EGL context current\n"); + return FALSE; + } + + miClearVisualTypes(); + if (!miSetVisualTypes(scrn->depth, + miGetDefaultVisualMask(scrn->depth), + scrn->rgbBits, scrn->defaultVisual)) + return FALSE; + if (!miSetPixmapDepths()) + return FALSE; + + if (!fbScreenInit(screen, NULL, + scrn->virtualX, scrn->virtualY, + scrn->xDpi, scrn->yDpi, + 1, scrn->bitsPerPixel)) + return FALSE; + + fbPictureInit(screen, NULL, 0); + + xf86SetBlackWhitePixels(screen); + + if (!glamor_init(screen)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to initialize glamor\n"); + return FALSE; + } + + miInitializeBackingStore(screen); + xf86SetBackingStore(screen); + xf86SetSilkenMouse(screen); + miDCInitialize(screen, xf86GetPointerScreenFuncs()); + + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n"); + + if (!xf86_cursors_init(screen, 64, 64, + (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_UPDATE_UNHIDDEN | + HARDWARE_CURSOR_ARGB))) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + } + + /* Must force it before EnterVT, so we are in control of VT and + * later memory should be bound when allocating, e.g rotate_mem */ + scrn->vtSema = TRUE; + + if (!glamor_enter_vt(scrnIndex, 0)) + return FALSE; + + screen->SaveScreen = xf86SaveScreen; + glamor->CreateScreenResources = screen->CreateScreenResources; + screen->CreateScreenResources = glamor_create_screen_resources; + glamor->CloseScreen = screen->CloseScreen; + screen->CloseScreen = glamor_close_screen; + + return TRUE; +} + +static void +glamor_free_screen(int scrnIndex, int flags) +{ + ScrnInfoPtr scrn = xf86Screens[scrnIndex]; + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + + close(glamor->fd); + xfree(scrn->driverPrivate); + scrn->driverPrivate = NULL; +} + +static ModeStatus +glamor_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + if (mode->Flags & V_INTERLACE) { + if (verbose) { + xf86DrvMsg(scrnIndex, X_PROBED, + "Removing interlaced mode \"%s\"\n", + mode->name); + } + return MODE_BAD; + } + return MODE_OK; +} + +static Bool +glamor_probe(struct _DriverRec *drv, int flags) +{ + ScrnInfoPtr scrn = NULL; + GDevPtr *sections; + int entity, n; + + n = xf86MatchDevice(glamor_name, §ions); + if (n <= 0) + return FALSE; + + entity = xf86ClaimFbSlot(drv, 0, sections[0], TRUE); + + scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL); + if (scrn == NULL) { + xf86Msg(X_ERROR, "Failed to add fb entity\n"); + return FALSE; + } + + scrn->driverVersion = 1; + scrn->driverName = (char *) glamor_name; + scrn->name = (char *) glamor_name; + scrn->Probe = NULL; + + scrn->PreInit = glamor_pre_init; + scrn->ScreenInit = glamor_screen_init; + scrn->AdjustFrame = glamor_adjust_frame; + scrn->EnterVT = glamor_enter_vt; + scrn->LeaveVT = glamor_leave_vt; + scrn->FreeScreen = glamor_free_screen; + scrn->ValidMode = glamor_valid_mode; + + return TRUE; +} + +static const OptionInfoRec * +glamor_available_options(int chipid, int busid) +{ + return NULL; +} + +static Bool +glamor_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) +{ + xorgHWFlags *flag; + + switch (op) { + case GET_REQUIRED_HW_INTERFACES: + flag = (CARD32*)ptr; + (*flag) = 0; + return TRUE; + default: + /* Unknown or deprecated function */ + return FALSE; + } +} + +_X_EXPORT DriverRec glamor = { + 1, + "glamor", + glamor_identify, + glamor_probe, + glamor_available_options, + NULL, + 0, + glamor_driver_func, +}; + +static pointer +glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = 0; + + /* This module should be loaded only once, but check to be sure. + */ + if (!setupDone) { + setupDone = 1; + xf86AddDriver(&glamor, module, HaveDriverFuncs); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer) 1; + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +static XF86ModuleVersionInfo glamor_version_info = { + glamor_name, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + GLAMOR_VERSION_MAJOR, + GLAMOR_VERSION_MINOR, + GLAMOR_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +_X_EXPORT XF86ModuleData glamorModuleData = { + &glamor_version_info, + glamor_setup, + NULL +}; diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c new file mode 100644 index 000000000..4c9181922 --- /dev/null +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -0,0 +1,1493 @@ +/* + * Copyright © 2007 Red Hat, Inc. + * Copyright © 2010 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: + * Dave Airlie + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "glamor_ddx.h" + +typedef struct { + int fd; + uint32_t fb_id; + drmModeResPtr mode_res; + int cpp; + + drmEventContext event_context; + void *event_data; + int old_fb_id; + int flip_count; +} drmmode_rec, *drmmode_ptr; + +typedef struct { + drmmode_ptr drmmode; + drmModeCrtcPtr mode_crtc; + uint32_t rotate_fb_id; + unsigned int cursor_tex; +} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; + +typedef struct { + drmModePropertyPtr mode_prop; + uint64_t value; + int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ + Atom *atoms; +} drmmode_prop_rec, *drmmode_prop_ptr; + +struct fixed_panel_lvds { + int hdisplay; + int vdisplay; +}; +typedef struct { + drmmode_ptr drmmode; + int output_id; + drmModeConnectorPtr mode_output; + drmModeEncoderPtr mode_encoder; + drmModePropertyBlobPtr edid_blob; + int num_props; + drmmode_prop_ptr props; + void *private_data; + int dpms_mode; + char *backlight_iface; + int backlight_active_level; + int backlight_max; +} drmmode_output_private_rec, *drmmode_output_private_ptr; + +static void +drmmode_output_dpms(xf86OutputPtr output, int mode); +static Bool +drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height); + +#define BACKLIGHT_CLASS "/sys/class/backlight" + +/* + * List of available kernel interfaces in priority order + */ +static char *backlight_interfaces[] = { + "asus-laptop", + "eeepc", + "thinkpad_screen", + "acpi_video1", + "acpi_video0", + "fujitsu-laptop", + "sony", + "samsung", + NULL, +}; +/* + * Must be long enough for BACKLIGHT_CLASS + '/' + longest in above table + + * '/' + "max_backlight" + */ +#define BACKLIGHT_PATH_LEN 80 +/* Enough for 10 digits of backlight + '\n' + '\0' */ +#define BACKLIGHT_VALUE_LEN 12 + +static void +drmmode_backlight_set(xf86OutputPtr output, int level) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; + int fd, len, ret; + + if (level > drmmode_output->backlight_max) + level = drmmode_output->backlight_max; + if (! drmmode_output->backlight_iface || level < 0) + return; + + len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level); + sprintf(path, "%s/%s/brightness", + BACKLIGHT_CLASS, drmmode_output->backlight_iface); + fd = open(path, O_RDWR); + if (fd == -1) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s for backlight " + "control: %s\n", path, strerror(errno)); + return; + } + + ret = write(fd, val, len); + if (ret == -1) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "write to %s for backlight " + "control failed: %s\n", path, strerror(errno)); + } + + close(fd); +} + +static int +drmmode_backlight_get(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; + int fd, level; + + if (! drmmode_output->backlight_iface) + return -1; + + sprintf(path, "%s/%s/actual_brightness", + BACKLIGHT_CLASS, drmmode_output->backlight_iface); + fd = open(path, O_RDONLY); + if (fd == -1) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s " + "for backlight control: %s\n", path, strerror(errno)); + return -1; + } + + memset(val, 0, sizeof(val)); + if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) { + close(fd); + return -1; + } + + close(fd); + + level = atoi(val); + if (level > drmmode_output->backlight_max) + level = drmmode_output->backlight_max; + if (level < 0) + level = -1; + return level; +} + +static int +drmmode_backlight_get_max(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; + int fd, max = 0; + + sprintf(path, "%s/%s/max_brightness", + BACKLIGHT_CLASS, drmmode_output->backlight_iface); + fd = open(path, O_RDONLY); + if (fd == -1) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s " + "for backlight control: %s\n", path, strerror(errno)); + return 0; + } + + memset(val, 0, sizeof(val)); + if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) { + close(fd); + return -1; + } + + close(fd); + + max = atoi(val); + if (max <= 0) + max = -1; + return max; +} + +static void +drmmode_backlight_init(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + char path[BACKLIGHT_PATH_LEN]; + struct stat buf; + int i; + + for (i = 0; backlight_interfaces[i] != NULL; i++) { + sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]); + if (!stat(path, &buf)) { + drmmode_output->backlight_iface = backlight_interfaces[i]; + xf86DrvMsg(output->scrn->scrnIndex, X_INFO, + "found backlight control interface %s\n", path); + drmmode_output->backlight_max = drmmode_backlight_get_max(output); + drmmode_output->backlight_active_level = drmmode_backlight_get(output); + return; + } + } + drmmode_output->backlight_iface = NULL; +} + + +static void +drmmode_ConvertFromKMode(ScrnInfoPtr scrn, + drmModeModeInfoPtr kmode, + DisplayModePtr mode) +{ + memset(mode, 0, sizeof(DisplayModeRec)); + mode->status = MODE_OK; + + mode->Clock = kmode->clock; + + mode->HDisplay = kmode->hdisplay; + mode->HSyncStart = kmode->hsync_start; + mode->HSyncEnd = kmode->hsync_end; + mode->HTotal = kmode->htotal; + mode->HSkew = kmode->hskew; + + mode->VDisplay = kmode->vdisplay; + mode->VSyncStart = kmode->vsync_start; + mode->VSyncEnd = kmode->vsync_end; + mode->VTotal = kmode->vtotal; + mode->VScan = kmode->vscan; + + mode->Flags = kmode->flags; //& FLAG_BITS; + mode->name = strdup(kmode->name); + + if (kmode->type & DRM_MODE_TYPE_DRIVER) + mode->type = M_T_DRIVER; + if (kmode->type & DRM_MODE_TYPE_PREFERRED) + mode->type |= M_T_PREFERRED; + xf86SetModeCrtc (mode, scrn->adjustFlags); +} + +static void +drmmode_ConvertToKMode(ScrnInfoPtr scrn, + drmModeModeInfoPtr kmode, + DisplayModePtr mode) +{ + memset(kmode, 0, sizeof(*kmode)); + + kmode->clock = mode->Clock; + kmode->hdisplay = mode->HDisplay; + kmode->hsync_start = mode->HSyncStart; + kmode->hsync_end = mode->HSyncEnd; + kmode->htotal = mode->HTotal; + kmode->hskew = mode->HSkew; + + kmode->vdisplay = mode->VDisplay; + kmode->vsync_start = mode->VSyncStart; + kmode->vsync_end = mode->VSyncEnd; + kmode->vtotal = mode->VTotal; + kmode->vscan = mode->VScan; + + kmode->flags = mode->Flags; //& FLAG_BITS; + if (mode->name) + strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); + kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; + +} + +static void +drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode) +{ + +} + +static Bool +drmmode_update_fb (ScrnInfoPtr scrn, int width, int height) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + drmmode_crtc_private_ptr + drmmode_crtc = xf86_config->crtc[0]->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + uint32_t handle, pitch; + int ret; + + if (drmmode->fb_id != 0 && + scrn->virtualX == width && scrn->virtualY == height) + return TRUE; + if (!glamor_resize(scrn, width, height)) + return FALSE; + if (drmmode->fb_id != 0) + drmModeRmFB(drmmode->fd, drmmode->fb_id); + glamor_frontbuffer_handle(scrn, &handle, &pitch); + ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, + scrn->bitsPerPixel, pitch * drmmode->cpp, + handle, &drmmode->fb_id); + if (ret) + /* FIXME: Undo glamor_resize() */ + return FALSE; + + return TRUE; +} + +static Bool +drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int saved_x, saved_y; + Rotation saved_rotation; + DisplayModeRec saved_mode; + uint32_t *output_ids; + int output_count = 0; + int ret = TRUE; + int i; + int fb_id; + drmModeModeInfo kmode; + + if (!drmmode_update_fb(scrn, scrn->virtualX, scrn->virtualY)) + return FALSE; + + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; + + output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output); + if (!output_ids) { + ret = FALSE; + goto done; + } + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output; + + if (output->crtc != crtc) + continue; + + drmmode_output = output->driver_private; + output_ids[output_count] = + drmmode_output->mode_output->connector_id; + output_count++; + } + +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0) + if (!xf86CrtcRotate(crtc, mode, rotation)) + goto done; +#else + if (!xf86CrtcRotate(crtc)) + goto done; +#endif + +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); +#endif + + drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); + + + fb_id = drmmode->fb_id; + if (drmmode_crtc->rotate_fb_id) { + fb_id = drmmode_crtc->rotate_fb_id; + x = 0; + y = 0; + } + ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + fb_id, x, y, output_ids, output_count, &kmode); + if (ret) + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "failed to set mode: %s", strerror(-ret)); + else + ret = TRUE; + + /* Turn on any outputs on this crtc that may have been disabled */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if (output->crtc != crtc) + continue; + + drmmode_output_dpms(output, DPMSModeOn); + } + + if (scrn->pScreen) + xf86_reload_cursors(scrn->pScreen); +done: + if (!ret) { + crtc->x = saved_x; + crtc->y = saved_y; + crtc->rotation = saved_rotation; + crtc->mode = saved_mode; + } + return ret; +} + +static void +drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) +{ + +} + +static void +drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + ErrorF("move cursor\n"); + + drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); +} + +static void +drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) +{ + ScrnInfoPtr scrn = crtc->scrn; + + glamor_load_cursor(scrn, image, 64, 64); +} + + +static void +drmmode_hide_cursor (xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + 0, 64, 64); +} + +static void +drmmode_show_cursor (xf86CrtcPtr crtc) +{ + ScrnInfoPtr scrn = crtc->scrn; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + uint32_t handle, stride; + + ErrorF("show cursor\n"); + glamor_cursor_handle(scrn, &handle, &stride); + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + handle, 64, 64); +} + +#if 0 +static void * +drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + ScrnInfoPtr scrn = crtc->scrn; + intel_screen_private *intel = intel_get_screen_private(scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int size, ret; + unsigned long rotate_pitch; + + width = i830_pad_drawable_width(width, drmmode->cpp); + rotate_pitch = width * drmmode->cpp; + size = rotate_pitch * height; + + drmmode_crtc->rotate_bo = + drm_intel_bo_alloc(intel->bufmgr, "rotate", size, 4096); + + if (!drmmode_crtc->rotate_bo) { + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow memory for rotated CRTC\n"); + return NULL; + } + + drm_intel_bo_disable_reuse(drmmode_crtc->rotate_bo); + + ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, + crtc->scrn->bitsPerPixel, rotate_pitch, + drmmode_crtc->rotate_bo->handle, + &drmmode_crtc->rotate_fb_id); + if (ret) { + ErrorF("failed to add rotate fb\n"); + drm_intel_bo_unreference(drmmode_crtc->rotate_bo); + return NULL; + } + + return drmmode_crtc->rotate_bo; +} + +static PixmapPtr +drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr scrn = crtc->scrn; + intel_screen_private *intel = intel_get_screen_private(scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + unsigned long rotate_pitch; + PixmapPtr rotate_pixmap; + + if (!data) { + data = drmmode_crtc_shadow_allocate (crtc, width, height); + if (!data) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + return NULL; + } + } + + rotate_pitch = + i830_pad_drawable_width(width, drmmode->cpp) * drmmode->cpp; + rotate_pixmap = GetScratchPixmapHeader(scrn->pScreen, + width, height, + scrn->depth, + scrn->bitsPerPixel, + rotate_pitch, + NULL); + + if (rotate_pixmap == NULL) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + return NULL; + } + + if (drmmode_crtc->rotate_bo) + i830_set_pixmap_bo(rotate_pixmap, drmmode_crtc->rotate_bo); + + intel->shadow_present = TRUE; + + return rotate_pixmap; +} + +static void +drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ +} +#endif + +static void +drmmode_crtc_gamma_set(xf86CrtcPtr crtc, + CARD16 *red, CARD16 *green, CARD16 *blue, int size) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + size, red, green, blue); +} + +static const xf86CrtcFuncsRec drmmode_crtc_funcs = { + .dpms = drmmode_crtc_dpms, + .set_mode_major = drmmode_set_mode_major, + .set_cursor_colors = drmmode_set_cursor_colors, + .set_cursor_position = drmmode_set_cursor_position, + .show_cursor = drmmode_show_cursor, + .hide_cursor = drmmode_hide_cursor, + .load_cursor_argb = drmmode_load_cursor_argb, +#if 0 + .shadow_create = drmmode_crtc_shadow_create, + .shadow_allocate = drmmode_crtc_shadow_allocate, + .shadow_destroy = drmmode_crtc_shadow_destroy, +#endif + .gamma_set = drmmode_crtc_gamma_set, + .destroy = NULL, /* XXX */ +}; + + +static void +drmmode_crtc_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) +{ + xf86CrtcPtr crtc; + drmmode_crtc_private_ptr drmmode_crtc; + + crtc = xf86CrtcCreate(scrn, &drmmode_crtc_funcs); + if (crtc == NULL) + return; + + drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); + drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, + drmmode->mode_res->crtcs[num]); + drmmode_crtc->drmmode = drmmode; + crtc->driver_private = drmmode_crtc; + + return; +} + +static xf86OutputStatus +drmmode_output_detect(xf86OutputPtr output) +{ + /* go to the hw and retrieve a new output struct */ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmmode_ptr drmmode = drmmode_output->drmmode; + xf86OutputStatus status; + drmModeFreeConnector(drmmode_output->mode_output); + + drmmode_output->mode_output = + drmModeGetConnector(drmmode->fd, drmmode_output->output_id); + + switch (drmmode_output->mode_output->connection) { + case DRM_MODE_CONNECTED: + status = XF86OutputStatusConnected; + break; + case DRM_MODE_DISCONNECTED: + status = XF86OutputStatusDisconnected; + break; + default: + case DRM_MODE_UNKNOWNCONNECTION: + status = XF86OutputStatusUnknown; + break; + } + return status; +} + +static Bool +drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + struct fixed_panel_lvds *p_lvds = drmmode_output->private_data; + + /* + * If the connector type is LVDS, we will use the panel limit to + * verfiy whether the mode is valid. + */ + if ((koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) && p_lvds) { + if (pModes->HDisplay > p_lvds->hdisplay || + pModes->VDisplay > p_lvds->vdisplay) + return MODE_PANEL; + else + return MODE_OK; + } + return MODE_OK; +} + +static void fill_detailed_lvds_block(struct detailed_monitor_section *det_mon, + DisplayModePtr mode) +{ + struct detailed_timings *timing = &det_mon->section.d_timings; + + det_mon->type = DT; + timing->clock = mode->Clock * 1000; + timing->h_active = mode->HDisplay; + timing->h_blanking = mode->HTotal - mode->HDisplay; + timing->v_active = mode->VDisplay; + timing->v_blanking = mode->VTotal - mode->VDisplay; + timing->h_sync_off = mode->HSyncStart - mode->HDisplay; + timing->h_sync_width = mode->HSyncEnd - mode->HSyncStart; + timing->v_sync_off = mode->VSyncStart - mode->VDisplay; + timing->v_sync_width = mode->VSyncEnd - mode->VSyncStart; + + if (mode->Flags & V_PVSYNC) + timing->misc |= 0x02; + + if (mode->Flags & V_PHSYNC) + timing->misc |= 0x01; +} + +static int drmmode_output_lvds_edid(xf86OutputPtr output, + struct fixed_panel_lvds *p_lvds) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + int i, j; + DisplayModePtr pmode; + xf86MonPtr edid_mon; + drmModeModeInfo *mode_ptr; + struct detailed_monitor_section *det_mon; + + if (output->MonInfo) { + /* + * If there exists the EDID, we will either find a DS_RANGES + * or replace a DS_VENDOR block, smashing it into a DS_RANGES + * block with opern refresh to match all the default modes. + */ + int edid_det_block_num; + edid_mon = output->MonInfo; + edid_mon->features.msc |= 0x01; + j = -1; + edid_det_block_num = sizeof(edid_mon->det_mon) / + sizeof(edid_mon->det_mon[0]); + for (i = 0; i < edid_det_block_num; i++) { + if (edid_mon->det_mon[i].type >= DS_VENDOR && j == -1) + j = i; + if (edid_mon->det_mon[i].type == DS_RANGES) { + j = i; + break; + } + } + if (j != -1) { + struct monitor_ranges *ranges = + &edid_mon->det_mon[j].section.ranges; + edid_mon->det_mon[j].type = DS_RANGES; + ranges->min_v = 0; + ranges->max_v = 200; + ranges->min_h = 0; + ranges->max_h = 200; + } + return 0; + } + /* + * If there is no EDID, we will construct a bogus EDID for LVDS output + * device. This is similar to what we have done in i830_lvds.c + */ + edid_mon = NULL; + edid_mon = xcalloc(1, sizeof(xf86Monitor)); + if (!edid_mon) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "Can't allocate memory for edid_mon.\n"); + return 0; + } + /* Find the fixed panel mode. + * In theory when there is no EDID, KMS kernel will return only one + * mode. And this can be regarded as fixed lvds panel mode. + * But it will be better to traverse the mode list to get the fixed + * lvds panel mode again as we don't know whether some new modes + * are added for the LVDS output device + */ + j = 0; + for (i = 0; i < koutput->count_modes; i++) { + mode_ptr = &koutput->modes[i]; + if ((mode_ptr->hdisplay == p_lvds->hdisplay) && + (mode_ptr->vdisplay == p_lvds->vdisplay)) { + /* find the fixed panel mode */ + j = i; + break; + } + } + pmode = xnfalloc(sizeof(DisplayModeRec)); + drmmode_ConvertFromKMode(output->scrn, &koutput->modes[j], pmode); + /*support DPM, instead of DPMS*/ + edid_mon->features.dpms |= 0x1; + /*defaultly support RGB color display*/ + edid_mon->features.display_type |= 0x1; + /*defaultly display support continuous-freqencey*/ + edid_mon->features.msc |= 0x1; + /*defaultly the EDID version is 1.4 */ + edid_mon->ver.version = 1; + edid_mon->ver.revision = 4; + det_mon = edid_mon->det_mon; + if (pmode) { + /* now we construct new EDID monitor, + * so filled one detailed timing block + */ + fill_detailed_lvds_block(det_mon, pmode); + /* the filed timing block should be set preferred*/ + edid_mon->features.msc |= 0x2; + det_mon = det_mon + 1; + } + /* Set wide sync ranges so we get all modes + * handed to valid_mode for checking + */ + det_mon->type = DS_RANGES; + det_mon->section.ranges.min_v = 0; + det_mon->section.ranges.max_v = 200; + det_mon->section.ranges.min_h = 0; + det_mon->section.ranges.max_h = 200; + output->MonInfo = edid_mon; + return 0; +} + +static DisplayModePtr +drmmode_output_get_modes(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + DisplayModePtr Modes = NULL, Mode; + drmModePropertyPtr props; + struct fixed_panel_lvds *p_lvds; + drmModeModeInfo *mode_ptr; + + /* look for an EDID property */ + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (!props) + continue; + if (!(props->flags & DRM_MODE_PROP_BLOB)) { + drmModeFreeProperty(props); + continue; + } + + if (!strcmp(props->name, "EDID")) { + drmModeFreePropertyBlob(drmmode_output->edid_blob); + drmmode_output->edid_blob = + drmModeGetPropertyBlob(drmmode->fd, + koutput->prop_values[i]); + } + drmModeFreeProperty(props); + } + + if (drmmode_output->edid_blob) + xf86OutputSetEDID(output, + xf86InterpretEDID(output->scrn->scrnIndex, + drmmode_output->edid_blob->data)); + else + xf86OutputSetEDID(output, + xf86InterpretEDID(output->scrn->scrnIndex, + NULL)); + + /* modes should already be available */ + for (i = 0; i < koutput->count_modes; i++) { + Mode = xnfalloc(sizeof(DisplayModeRec)); + + drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], + Mode); + Modes = xf86ModesAdd(Modes, Mode); + + } + p_lvds = drmmode_output->private_data; + /* + * If the connector type is LVDS, we will traverse the kernel mode to + * get the panel limit. + * If it is incorrect, please fix me. + */ + if ((koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) && p_lvds) { + p_lvds->hdisplay = 0; + p_lvds->vdisplay = 0; + for (i = 0; i < koutput->count_modes; i++) { + mode_ptr = &koutput->modes[i]; + if ((mode_ptr->hdisplay >= p_lvds->hdisplay) && + (mode_ptr->vdisplay >= p_lvds->vdisplay)) { + p_lvds->hdisplay = mode_ptr->hdisplay; + p_lvds->vdisplay = mode_ptr->vdisplay; + } + } + if (!p_lvds->hdisplay || !p_lvds->vdisplay) + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "Incorrect KMS mode.\n"); + drmmode_output_lvds_edid(output, p_lvds); + } + return Modes; +} + +static void +drmmode_output_destroy(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + int i; + + if (drmmode_output->edid_blob) + drmModeFreePropertyBlob(drmmode_output->edid_blob); + for (i = 0; i < drmmode_output->num_props; i++) { + drmModeFreeProperty(drmmode_output->props[i].mode_prop); + xfree(drmmode_output->props[i].atoms); + } + xfree(drmmode_output->props); + drmModeFreeConnector(drmmode_output->mode_output); + if (drmmode_output->private_data) { + xfree(drmmode_output->private_data); + drmmode_output->private_data = NULL; + } + if (drmmode_output->backlight_iface) + drmmode_backlight_set(output, drmmode_output->backlight_active_level); + xfree(drmmode_output); + output->driver_private = NULL; +} + +static void +drmmode_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + + if (!drmmode_output->backlight_iface) + return; + + if (mode == DPMSModeOn) { + /* If we're going from off->on we may need to turn on the backlight. */ + if (oldmode != DPMSModeOn) + drmmode_backlight_set(output, drmmode_output->backlight_active_level); + } else { + /* Only save the current backlight value if we're going from on to off. */ + if (oldmode == DPMSModeOn) + drmmode_output->backlight_active_level = drmmode_backlight_get(output); + drmmode_backlight_set(output, 0); + } +} + +static void +drmmode_output_dpms(xf86OutputPtr output, int mode) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + drmModePropertyPtr props; + + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (!props) + continue; + + if (!strcmp(props->name, "DPMS")) { + drmModeConnectorSetProperty(drmmode->fd, + drmmode_output->output_id, + props->prop_id, + mode); + drmmode_output_dpms_backlight(output, + drmmode_output->dpms_mode, + mode); + drmmode_output->dpms_mode = mode; + drmModeFreeProperty(props); + return; + } + drmModeFreeProperty(props); + } +} + +static Bool +drmmode_property_ignore(drmModePropertyPtr prop) +{ + if (!prop) + return TRUE; + /* ignore blob prop */ + if (prop->flags & DRM_MODE_PROP_BLOB) + return TRUE; + /* ignore standard property */ + if (!strcmp(prop->name, "EDID") || + !strcmp(prop->name, "DPMS")) + return TRUE; + + return FALSE; +} + +#define BACKLIGHT_NAME "Backlight" +#define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT" +static Atom backlight_atom, backlight_deprecated_atom; + +static void +drmmode_output_create_resources(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr mode_output = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + drmModePropertyPtr drmmode_prop; + int i, j, err; + + drmmode_output->props = xcalloc(mode_output->count_props, sizeof(drmmode_prop_rec)); + if (!drmmode_output->props) + return; + + drmmode_output->num_props = 0; + for (i = 0, j = 0; i < mode_output->count_props; i++) { + drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); + if (drmmode_property_ignore(drmmode_prop)) { + drmModeFreeProperty(drmmode_prop); + continue; + } + drmmode_output->props[j].mode_prop = drmmode_prop; + drmmode_output->props[j].value = mode_output->prop_values[i]; + drmmode_output->num_props++; + j++; + } + + for (i = 0; i < drmmode_output->num_props; i++) { + drmmode_prop_ptr p = &drmmode_output->props[i]; + drmmode_prop = p->mode_prop; + + if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { + INT32 range[2]; + + p->num_atoms = 1; + p->atoms = xcalloc(p->num_atoms, sizeof(Atom)); + if (!p->atoms) + continue; + p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); + range[0] = drmmode_prop->values[0]; + range[1] = drmmode_prop->values[1]; + err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], + FALSE, TRUE, + drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, + 2, range); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + err = RRChangeOutputProperty(output->randr_output, p->atoms[0], + XA_INTEGER, 32, PropModeReplace, 1, &p->value, FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { + p->num_atoms = drmmode_prop->count_enums + 1; + p->atoms = xcalloc(p->num_atoms, sizeof(Atom)); + if (!p->atoms) + continue; + p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); + for (j = 1; j <= drmmode_prop->count_enums; j++) { + struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1]; + p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); + } + err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], + FALSE, FALSE, + drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, + p->num_atoms - 1, (INT32 *)&p->atoms[1]); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + for (j = 0; j < drmmode_prop->count_enums; j++) + if (drmmode_prop->enums[j].value == p->value) + break; + /* there's always a matching value */ + err = RRChangeOutputProperty(output->randr_output, p->atoms[0], + XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } + } + + if (drmmode_output->backlight_iface) { + INT32 data, backlight_range[2]; + /* Set up the backlight property, which takes effect immediately + * and accepts values only within the backlight_range. */ + backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1, TRUE); + backlight_deprecated_atom = MakeAtom(BACKLIGHT_DEPRECATED_NAME, + sizeof(BACKLIGHT_DEPRECATED_NAME) - 1, TRUE); + + backlight_range[0] = 0; + backlight_range[1] = drmmode_output->backlight_max; + err = RRConfigureOutputProperty(output->randr_output, backlight_atom, + FALSE, TRUE, FALSE, 2, backlight_range); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + err = RRConfigureOutputProperty(output->randr_output, backlight_deprecated_atom, + FALSE, TRUE, FALSE, 2, backlight_range); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + /* Set the current value of the backlight property */ + data = drmmode_output->backlight_active_level; + err = RRChangeOutputProperty(output->randr_output, backlight_atom, + XA_INTEGER, 32, PropModeReplace, 1, &data, + FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + err = RRChangeOutputProperty(output->randr_output, backlight_deprecated_atom, + XA_INTEGER, 32, PropModeReplace, 1, &data, + FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } +} + +static Bool +drmmode_output_set_property(xf86OutputPtr output, Atom property, + RRPropertyValuePtr value) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + + if (property == backlight_atom || property == backlight_deprecated_atom) { + INT32 val; + + if (value->type != XA_INTEGER || value->format != 32 || + value->size != 1) + { + return FALSE; + } + + val = *(INT32 *)value->data; + if (val < 0 || val > drmmode_output->backlight_max) + return FALSE; + + if (drmmode_output->dpms_mode == DPMSModeOn) + drmmode_backlight_set(output, val); + drmmode_output->backlight_active_level = val; + return TRUE; + } + + for (i = 0; i < drmmode_output->num_props; i++) { + drmmode_prop_ptr p = &drmmode_output->props[i]; + + if (p->atoms[0] != property) + continue; + + if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { + uint32_t val; + + if (value->type != XA_INTEGER || value->format != 32 || + value->size != 1) + return FALSE; + val = *(uint32_t *)value->data; + + drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, + p->mode_prop->prop_id, (uint64_t)val); + return TRUE; + } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { + Atom atom; + const char *name; + int j; + + if (value->type != XA_ATOM || value->format != 32 || value->size != 1) + return FALSE; + memcpy(&atom, value->data, 4); + name = NameForAtom(atom); + + /* search for matching name string, then set its value down */ + for (j = 0; j < p->mode_prop->count_enums; j++) { + if (!strcmp(p->mode_prop->enums[j].name, name)) { + drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, + p->mode_prop->prop_id, p->mode_prop->enums[j].value); + return TRUE; + } + } + return FALSE; + } + } + + return TRUE; +} + +static Bool +drmmode_output_get_property(xf86OutputPtr output, Atom property) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + int err; + + if (property == backlight_atom || property == backlight_deprecated_atom) { + INT32 val; + + if (! drmmode_output->backlight_iface) + return FALSE; + + val = drmmode_backlight_get(output); + if (val < 0) + return FALSE; + err = RRChangeOutputProperty(output->randr_output, property, + XA_INTEGER, 32, PropModeReplace, 1, &val, + FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + return FALSE; + } + + return TRUE; + } + + return TRUE; +} + +static const xf86OutputFuncsRec drmmode_output_funcs = { + .create_resources = drmmode_output_create_resources, +#ifdef RANDR_12_INTERFACE + .set_property = drmmode_output_set_property, + .get_property = drmmode_output_get_property, +#endif + .dpms = drmmode_output_dpms, + .detect = drmmode_output_detect, + .mode_valid = drmmode_output_mode_valid, + + .get_modes = drmmode_output_get_modes, + .destroy = drmmode_output_destroy +}; + +static int subpixel_conv_table[7] = { 0, SubPixelUnknown, + SubPixelHorizontalRGB, + SubPixelHorizontalBGR, + SubPixelVerticalRGB, + SubPixelVerticalBGR, + SubPixelNone }; + +static const char *output_names[] = { "None", + "VGA", + "DVI", + "DVI", + "DVI", + "Composite", + "TV", + "LVDS", + "CTV", + "DIN", + "DP", + "HDMI", + "HDMI", +}; + + +static void +drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) +{ + xf86OutputPtr output; + drmModeConnectorPtr koutput; + drmModeEncoderPtr kencoder; + drmmode_output_private_ptr drmmode_output; + char name[32]; + + koutput = drmModeGetConnector(drmmode->fd, + drmmode->mode_res->connectors[num]); + if (!koutput) + return; + + kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]); + if (!kencoder) { + drmModeFreeConnector(koutput); + return; + } + + snprintf(name, 32, "%s%d", output_names[koutput->connector_type], + koutput->connector_type_id); + + output = xf86OutputCreate (scrn, &drmmode_output_funcs, name); + if (!output) { + drmModeFreeEncoder(kencoder); + drmModeFreeConnector(koutput); + return; + } + + drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1); + if (!drmmode_output) { + xf86OutputDestroy(output); + drmModeFreeConnector(koutput); + drmModeFreeEncoder(kencoder); + return; + } + /* + * If the connector type of the output device is LVDS, we will + * allocate the private_data to store the panel limit. + * For example: hdisplay, vdisplay + */ + drmmode_output->private_data = NULL; + if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) { + drmmode_output->private_data = xcalloc( + sizeof(struct fixed_panel_lvds), 1); + if (!drmmode_output->private_data) + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Can't allocate private memory for LVDS.\n"); + } + drmmode_output->output_id = drmmode->mode_res->connectors[num]; + drmmode_output->mode_output = koutput; + drmmode_output->mode_encoder = kencoder; + drmmode_output->drmmode = drmmode; + output->mm_width = koutput->mmWidth; + output->mm_height = koutput->mmHeight; + + output->subpixel_order = subpixel_conv_table[koutput->subpixel]; + output->driver_private = drmmode_output; + + if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) + drmmode_backlight_init(output); + + output->possible_crtcs = kencoder->possible_crtcs; + output->possible_clones = kencoder->possible_clones; + return; +} + + +static Bool +drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int i; + + if (!drmmode_update_fb(scrn, width, height)) + return FALSE; + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + if (!crtc->enabled) + continue; + + drmmode_set_mode_major(crtc, &crtc->mode, + crtc->rotation, crtc->x, crtc->y); + } + + return TRUE; +} + +static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { + drmmode_xf86crtc_resize +}; + +#if 0 +Bool +drmmode_do_pageflip(ScreenPtr screen, dri_bo *new_front, dri_bo *old_front, + void *data) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + intel_screen_private *intel = intel_get_screen_private(scrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + unsigned int pitch = scrn->displayWidth * intel->cpp; + int i, old_fb_id; + unsigned int crtc_id; + + /* + * Create a new handle for the back buffer + */ + old_fb_id = drmmode->fb_id; + if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY, + scrn->depth, scrn->bitsPerPixel, pitch, + new_front->handle, &drmmode->fb_id)) + goto error_out; + + /* + * Queue flips on all enabled CRTCs + * Note that if/when we get per-CRTC buffers, we'll have to update this. + * Right now it assumes a single shared fb across all CRTCs, with the + * kernel fixing up the offset of each CRTC as necessary. + * + * Also, flips queued on disabled or incorrectly configured displays + * may never complete; this is a configuration error. + */ + for (i = 0; i < config->num_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; + + if (!crtc->enabled) + continue; + + drmmode_crtc = crtc->driver_private; + crtc_id = drmmode_crtc->mode_crtc->crtc_id; + drmmode->event_data = data; + drmmode->flip_count++; + if (drmModePageFlip(drmmode->fd, crtc_id, drmmode->fb_id, + DRM_MODE_PAGE_FLIP_EVENT, drmmode)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue failed: %s\n", strerror(errno)); + goto error_undo; + } + } + + dri_bo_pin(new_front, 0); + dri_bo_unpin(new_front); + + scrn->fbOffset = new_front->offset; + intel->front_buffer->bo = new_front; + intel->front_buffer->offset = new_front->offset; + drmmode->old_fb_id = old_fb_id; + + return TRUE; + +error_undo: + drmModeRmFB(drmmode->fd, drmmode->fb_id); + drmmode->fb_id = old_fb_id; + +error_out: + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", + strerror(errno)); + return FALSE; +} + +static void +drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec, + unsigned int tv_usec, void *event_data) +{ + I830DRI2FrameEventHandler(frame, tv_sec, tv_usec, event_data); +} + +static void +drmmode_page_flip_handler(int fd, unsigned int frame, unsigned int tv_sec, + unsigned int tv_usec, void *event_data) +{ + drmmode_ptr drmmode = event_data; + + drmmode->flip_count--; + if (drmmode->flip_count > 0) + return; + + drmModeRmFB(drmmode->fd, drmmode->old_fb_id); + + I830DRI2FlipEventHandler(frame, tv_sec, tv_usec, drmmode->event_data); +} + +static void +drm_wakeup_handler(pointer data, int err, pointer p) +{ + drmmode_ptr drmmode = data; + fd_set *read_mask = p; + + if (err >= 0 && FD_ISSET(drmmode->fd, read_mask)) + drmHandleEvent(drmmode->fd, &drmmode->event_context); +} +#endif + +Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) +{ + drmmode_ptr drmmode; + unsigned int i; + + drmmode = xnfalloc(sizeof *drmmode); + drmmode->fd = fd; + drmmode->fb_id = 0; + + xf86CrtcConfigInit(scrn, &drmmode_xf86crtc_config_funcs); + + drmmode->cpp = cpp; + drmmode->mode_res = drmModeGetResources(drmmode->fd); + if (!drmmode->mode_res) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "failed to get resources: %s\n", strerror(errno)); + return FALSE; + } + + xf86CrtcSetSizeRange(scrn, 320, 200, drmmode->mode_res->max_width, + drmmode->mode_res->max_height); + for (i = 0; i < drmmode->mode_res->count_crtcs; i++) + drmmode_crtc_init(scrn, drmmode, i); + + for (i = 0; i < drmmode->mode_res->count_connectors; i++) + drmmode_output_init(scrn, drmmode, i); + + xf86InitialConfiguration(scrn, TRUE); + +#if 0 + gp.param = I915_PARAM_HAS_PAGEFLIPPING; + gp.value = &has_flipping; + (void)drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp, + sizeof(gp)); + if (has_flipping) { + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "Kernel page flipping support detected, enabling\n"); + intel->use_pageflipping = TRUE; + drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; + drmmode->event_context.vblank_handler = drmmode_vblank_handler; + drmmode->event_context.page_flip_handler = + drmmode_page_flip_handler; + AddGeneralSocket(fd); + RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, + drm_wakeup_handler, drmmode); + } +#endif + + return TRUE; +} + +void drmmode_closefb(ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr xf86_config; + drmmode_crtc_private_ptr drmmode_crtc; + drmmode_ptr drmmode; + + xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + + drmmode_crtc = xf86_config->crtc[0]->driver_private; + drmmode = drmmode_crtc->drmmode; + + drmModeRmFB(drmmode->fd, drmmode->fb_id); + drmmode->fb_id = 0; +} diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h new file mode 100644 index 000000000..0968f013f --- /dev/null +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -0,0 +1,15 @@ +#ifndef GLAMOR_DDX_H +#define GLAMOR_DDX_H + +Bool glamor_resize(ScrnInfoPtr scrn, int width, int height); +void glamor_frontbuffer_handle(ScrnInfoPtr scrn, + uint32_t *handle, uint32_t *pitch); +Bool glamor_load_cursor(ScrnInfoPtr scrn, + CARD32 *image, int width, int height); +void glamor_cursor_handle(ScrnInfoPtr scrn, + uint32_t *handle, uint32_t *pitch); + +Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp); +void drmmode_closefb(ScrnInfoPtr scrn); + +#endif From 26ff612171d53baef08078a852875d5ddf1804ed Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 11 May 2011 15:54:50 +0800 Subject: [PATCH 108/225] glamor: Resolved merge conflictions with Kristian's glamor-ddx patch. --- configure.ac | 1 + glamor/glamor.c | 58 ++++++++++++++++++++++------------ glamor/glamor.h | 2 ++ hw/xfree86/common/xf86pciBus.c | 2 +- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 7a8e507e7..caefc4674 100644 --- a/configure.ac +++ b/configure.ac @@ -2185,6 +2185,7 @@ hw/xfree86/utils/Makefile hw/xfree86/utils/man/Makefile hw/xfree86/utils/cvt/Makefile hw/xfree86/utils/gtf/Makefile +hw/xfree86/glamor/Makefile hw/dmx/config/Makefile hw/dmx/config/man/Makefile hw/dmx/doc/Makefile diff --git a/glamor/glamor.c b/glamor/glamor.c index 537fb685c..b5252aacf 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -59,25 +59,54 @@ glamor_get_drawable_pixmap(DrawablePtr drawable) return (PixmapPtr)drawable; } + +void +glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_pixmap_private *pixmap_priv; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + pixmap_priv->tex = tex; + + /* Create a framebuffer object wrapping the texture so that we can render + * to it. + */ + glGenFramebuffersEXT(1, &pixmap_priv->fb); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + pixmap_priv->tex, + 0); + + screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, + (((w * pixmap->drawable.bitsPerPixel + + 7) / 8) + 3) & ~3, + NULL); +} + + + static PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) { PixmapPtr pixmap; - glamor_pixmap_private *pixmap_priv, *newpixmap_priv; GLenum format; + GLuint tex; + if (w > 32767 || h > 32767) return NullPixmap; pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); + if (dixAllocatePrivates(pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { fbDestroyPixmap(pixmap); ErrorF("Fail to allocate privates for PIXMAP.\n"); return NullPixmap; } - pixmap_priv = glamor_get_pixmap_private(pixmap); - assert(pixmap_priv != NULL); if (w == 0 || h == 0) return pixmap; @@ -95,28 +124,15 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, /* Create the texture used to store the pixmap's data. */ - glGenTextures(1, &pixmap_priv->tex); - glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, NULL); - /* Create a framebuffer object wrapping the texture so that we can render - ** to it. - **/ - glGenFramebuffersEXT(1, &pixmap_priv->fb); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, - pixmap_priv->tex, - 0); + glamor_set_pixmap_texture(pixmap, w, h, tex); - screen->ModifyPixmapHeader(pixmap, w, h, depth, 0, - (((w * pixmap->drawable.bitsPerPixel + - 7) / 8) + 3) & ~3, - NULL); return pixmap; } @@ -149,6 +165,7 @@ Bool glamor_init(ScreenPtr screen) { glamor_screen_private *glamor_priv; + #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif @@ -173,7 +190,6 @@ glamor_init(ScreenPtr screen) screen->myNum); } - glewInit(); if (!GLEW_EXT_framebuffer_object) { @@ -196,13 +212,13 @@ glamor_init(ScreenPtr screen) ErrorF("GL_EXT_bgra required\n"); goto fail; } - if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, NULL)) { goto fail; } + glamor_priv->saved_close_screen = screen->CloseScreen; screen->CloseScreen = glamor_close_screen; diff --git a/glamor/glamor.h b/glamor/glamor.h index 50617b857..546a50c42 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -37,5 +37,7 @@ #endif /* GLAMOR_H */ + Bool glamor_init(ScreenPtr screen); void glamor_fini(ScreenPtr screen); +void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex); diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 447b19229..56fb62f64 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -1118,7 +1118,7 @@ videoPtrToDriverList(struct pci_device *dev, } else if (dev->device_id == 0x8108) { break; /* "hooray" for poulsbo */ } else { - driverList[0] = "intel"; + driverList[0] = "glamor"; } break; case 0x102b: driverList[0] = "mga"; break; From 6dae8dc7ea6e7add3c6fda30773f264904ef8df5 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 11 May 2011 15:57:05 +0800 Subject: [PATCH 109/225] glamor: Add glamor-ddx driver to the build tree. Correct the linking parameters and add dependency to the libglamor.a. --- hw/xfree86/Makefile.am | 4 ++-- hw/xfree86/glamor/Makefile.am | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index e3ef14fc1..830f17ac9 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -27,12 +27,12 @@ if INT10MODULE INT10_SUBDIR = int10 endif -SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \ +SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw glamor os-support parser \ ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ loader dixmods exa modes \ $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man -DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ +DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw glamor os-support \ parser ramdac shadowfb vbe vgahw xaa \ loader dixmods dri dri2 exa modes \ utils doc man diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index 4c82b42b8..d691009eb 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -13,9 +13,12 @@ glamor_la_CFLAGS = \ -I/usr/include/drm glamor_la_LDFLAGS = \ - -module -avoid-version -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW + -module -avoid-version -L$(libdir) -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW glamor_ladir = $(moduledir)/drivers glamor_la_SOURCES = \ glamor.c \ glamor_crtc.c \ glamor_ddx.h + +glamor_la_DEPENDENCIES = \ + $(top_builddir)/glamor/libglamor.la From eb3487a448ff0efa46079323821d65d7c3e4d872 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 12 May 2011 01:08:38 +0800 Subject: [PATCH 110/225] glamor: Add new feature which is to flip output on y axis. Due to the coordinate system on EGL is different from FBO object. To support EGL surface well, we add this new feature. When calling glamor_init from EGL ddx driver, it should use the new flag GLAMOR_INVERTED_Y_AXIS. --- glamor/glamor.c | 11 ++++++- glamor/glamor.h | 5 ++- glamor/glamor_copyarea.c | 56 +++++++++++++++++++++++++++++----- glamor/glamor_core.c | 34 +++++++++++++++++---- glamor/glamor_fill.c | 17 ++++++++--- glamor/glamor_getspans.c | 11 +++++++ glamor/glamor_priv.h | 16 +++++++++- glamor/glamor_putimage.c | 20 +++++++++--- glamor/glamor_render.c | 33 +++++++++++++++----- glamor/glamor_tile.c | 31 +++++++++++++------ hw/kdrive/ephyr/ephyr_glamor.c | 2 +- 11 files changed, 193 insertions(+), 43 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index b5252aacf..026f1bf52 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -162,10 +162,15 @@ glamor_wakeup_handler(void *data, int result, void *last_select_mask) /** Set up glamor for an already-configured GL context. */ Bool -glamor_init(ScreenPtr screen) +glamor_init(ScreenPtr screen, unsigned int flags) { glamor_screen_private *glamor_priv; + if (flags & ~GLAMOR_VALID_FLAGS) { + ErrorF("glamor_init: Invalid flags %x\n", flags); + return FALSE; + } + #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif @@ -174,6 +179,10 @@ glamor_init(ScreenPtr screen) if (glamor_priv == NULL) return FALSE; + if (flags & GLAMOR_INVERTED_Y_AXIS) { + glamor_priv->yInverted = 1; + } else + glamor_priv->yInverted = 0; if (!dixRegisterPrivateKey(glamor_screen_private_key,PRIVATE_SCREEN, 0)) { diff --git a/glamor/glamor.h b/glamor/glamor.h index 546a50c42..33610a668 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -38,6 +38,9 @@ #endif /* GLAMOR_H */ -Bool glamor_init(ScreenPtr screen); +#define GLAMOR_INVERTED_Y_AXIS 0x1 +#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS) + +Bool glamor_init(ScreenPtr screen, unsigned int flags); void glamor_fini(ScreenPtr screen); void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex); diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 297a1fbc5..07d8b1456 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -45,6 +45,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); glamor_pixmap_private *src_pixmap_priv; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int dst_x_off, dst_y_off, src_x_off, src_y_off, i; if (src == dst) { @@ -94,6 +95,18 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, src_y_off += dy; for (i = 0; i < nbox; i++) { + if(glamor_priv->yInverted) { + glBlitFramebufferEXT((box[i].x1 + dx + src_x_off), + (box[i].y1 + src_y_off), + (box[i].x2 + dx + src_x_off), + (box[i].y2 + src_y_off), + (box[i].x1 + dst_x_off), + (box[i].y1 + dst_y_off), + (box[i].x2 + dst_x_off), + (box[i].y2 + dst_y_off), + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + } else { int flip_dst_y1 = dst_pixmap->drawable.height - (box[i].y2 + dst_y_off); int flip_dst_y2 = dst_pixmap->drawable.height - (box[i].y1 + dst_y_off); int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off); @@ -109,6 +122,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, flip_dst_y2, GL_COLOR_BUFFER_BIT, GL_NEAREST); + } } return TRUE; @@ -125,6 +139,8 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, { ScreenPtr screen = dst->pScreen; PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(screen); int x_off, y_off, i; if (src != dst) { @@ -161,6 +177,15 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off); for (i = 0; i < nbox; i++) { + if(glamor_priv->yInverted) { + glRasterPos2i(box[i].x1 + x_off, + box[i].y1 + y_off); + glCopyPixels(box[i].x1 + dx + x_off, + box[i].y1 + dy + y_off, + box[i].x2 - box[i].x1, + box[i].y2 - box[i].y1, + GL_COLOR); + } else { int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off; glRasterPos2i(box[i].x1 + x_off, flip_y1); @@ -169,6 +194,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, box[i].x2 - box[i].x1, box[i].y2 - box[i].y1, GL_COLOR); + } } return TRUE; @@ -235,23 +261,39 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glUseProgramObjectARB(glamor_priv->finish_access_prog); for (i = 0; i < nbox; i++) { + vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off); - vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off); - vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off); - vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off); vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off); + texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); + texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); + texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); + texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); + + if(glamor_priv->yInverted) { + + vertices[0][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off); + vertices[1][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off); + vertices[2][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off); + vertices[3][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off); + + texcoords[0][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy); + texcoords[1][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy); + texcoords[2][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy); + texcoords[3][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy); + } else { + + vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); + vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); + vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off); vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off); - texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); - texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); - texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); - texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); + } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index a4036c89e..3d1d3f842 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -294,12 +294,14 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) unsigned int stride, read_stride, x, y; GLenum format, type; uint8_t *data, *read; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(drawable->pScreen); if (pixmap_priv == NULL) return TRUE; if (pixmap_priv->fb == 0) { - ScreenPtr screen = pixmap->drawable.pScreen; + ScreenPtr screen = pixmap->drawable.pScreen; PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); if (pixmap != screen_pixmap) @@ -343,11 +345,13 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) glPixelStorei(GL_PACK_ROW_LENGTH, read_stride); } if (GLEW_MESA_pack_invert && drawable->depth != 1) { - glPixelStorei(GL_PACK_INVERT_MESA, 1); + if (!glamor_priv->yInverted) + glPixelStorei(GL_PACK_INVERT_MESA, 1); glReadPixels(0, 0, pixmap->drawable.width, pixmap->drawable.height, format, type, data); - glPixelStorei(GL_PACK_INVERT_MESA, 0); + if (!glamor_priv->yInverted) + glPixelStorei(GL_PACK_INVERT_MESA, 0); } else { glGenBuffersARB(1, &pixmap_priv->pbo); glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); @@ -362,10 +366,15 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) if (pixmap->drawable.depth == 1) { for (y = 0; y < pixmap->drawable.height; y++) { - uint8_t *read_row = read + - read_stride * (pixmap->drawable.height - y - 1); + uint8_t *read_row; uint8_t *write_row = data + y * stride; + if (glamor_priv->yInverted) + read_row = read + read_stride * y; + else + read_row = read + + read_stride * (pixmap->drawable.height - y - 1); + for (x = 0; x < pixmap->drawable.width; x++) { int index = x / 8; int bit = 1 << (x % 8); @@ -378,6 +387,9 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) } } else { for (y = 0; y < pixmap->drawable.height; y++) + if (glamor_priv->yInverted) + memcpy(data + y * stride, read + y * stride, stride); + else memcpy(data + y * stride, read + (pixmap->drawable.height - y - 1) * stride, stride); } @@ -452,10 +464,20 @@ glamor_finish_access(DrawablePtr drawable) {1, 1}, {1, 0}, {0, 0}}; + GLuint tex; + static float texcoords_inverted[4][2] = {{0, 0}, + {1, 0}, + {1, 1}, + {0, 1}}; + static float *ptexcoords; if (pixmap_priv == NULL) return; + if (glamor_priv->yInverted) + ptexcoords = texcoords_inverted; + else + ptexcoords = texcoords; if (pixmap_priv->fb == 0) { ScreenPtr screen = pixmap->drawable.pScreen; @@ -496,7 +518,7 @@ glamor_finish_access(DrawablePtr drawable) glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index c3e0528bf..1a982054a 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -153,14 +153,21 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glEnableClientState(GL_VERTEX_ARRAY); vertices[0][0] = v_from_x_coord_x(pixmap, x1); - vertices[0][1] = v_from_x_coord_y(pixmap, y1); vertices[1][0] = v_from_x_coord_x(pixmap, x2); - vertices[1][1] = v_from_x_coord_y(pixmap, y1); vertices[2][0] = v_from_x_coord_x(pixmap, x2); - vertices[2][1] = v_from_x_coord_y(pixmap, y2); vertices[3][0] = v_from_x_coord_x(pixmap, x1); - vertices[3][1] = v_from_x_coord_y(pixmap, y2); - + + if (glamor_priv->yInverted) { + vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1); + vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1); + vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2); + vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2); + } else { + vertices[0][1] = v_from_x_coord_y(pixmap, y1); + vertices[1][1] = v_from_x_coord_y(pixmap, y1); + vertices[2][1] = v_from_x_coord_y(pixmap, y2); + vertices[3][1] = v_from_x_coord_y(pixmap, y2); + } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 9b77f28db..e35c4168a 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -53,6 +53,8 @@ glamor_get_spans(DrawablePtr drawable, { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(drawable->pScreen); int i, j; uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst; int x_off, y_off; @@ -85,12 +87,21 @@ glamor_get_spans(DrawablePtr drawable, glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); for (i = 0; i < count; i++) { + if (glamor_priv->yInverted) { + glReadPixels(points[i].x + x_off, + (points[i].y + y_off), + widths[i], + 1, + format, type, + readpixels_dst); + } else { glReadPixels(points[i].x + x_off, pixmap->drawable.height - 1 - (points[i].y + y_off), widths[i], 1, format, type, readpixels_dst); + } if (temp_dst) { for (j = 0; j < widths[i]; j++) { set_bit((uint8_t *)dst, j, temp_dst[j] & 0x1); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index c2f516d9c..f12016d33 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -142,7 +142,7 @@ typedef struct glamor_screen_private { BitmapToRegionProcPtr saved_bitmap_to_region; char *delayed_fallback_string; - + int yInverted; GLuint vbo; int vbo_offset; int vbo_size; @@ -268,6 +268,13 @@ v_from_x_coord_y(PixmapPtr pixmap, int y) return (float)y / pixmap->drawable.height * -2.0 + 1.0; } +static inline float +v_from_x_coord_y_inverted(PixmapPtr pixmap, int y) +{ + return (float)y / pixmap->drawable.height * 2.0 - 1.0; +} + + static inline float t_from_x_coord_x(PixmapPtr pixmap, int x) { @@ -280,6 +287,13 @@ t_from_x_coord_y(PixmapPtr pixmap, int y) return 1.0 - (float)y / pixmap->drawable.height; } +static inline float +t_from_x_coord_y_inverted(PixmapPtr pixmap, int y) +{ + return (float)y / pixmap->drawable.height; +} + + /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index ead5b692e..6a9c1aa60 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -377,13 +377,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, src_y2 = (float)(y2 - y) / h; vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off); - vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off); vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off); - vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off); vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off); - vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off); vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off); - vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off); texcoords[0][0] = src_x1; texcoords[0][1] = src_y1; @@ -393,7 +389,23 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, texcoords[2][1] = src_y2; texcoords[3][0] = src_x1; texcoords[3][1] = src_y2; + + if (glamor_priv->yInverted) { + + vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off); + vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off); + vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off); + vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off); + + } else { + + vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off); + vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off); + vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off); + vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off); + + } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index de57f5219..2ec811f6e 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -556,6 +556,8 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap, float result[3]; int i; float tx, ty; + ScreenPtr screen = picture->pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (picture->transform) { for (i = 0; i < 3; i++) { @@ -570,7 +572,10 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap, ty = y; } texcoord[0] = t_from_x_coord_x(pixmap, tx); - texcoord[1] = t_from_x_coord_y(pixmap, ty); + if (glamor_priv->yInverted) + texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty); + else + texcoord[1] = t_from_x_coord_y(pixmap, ty); } static void @@ -887,21 +892,33 @@ glamor_composite_with_shader(CARD8 op, for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { vertices[0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dest_x_off); - vertices[1] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); vertices[2] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dest_x_off); - vertices[3] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); vertices[4] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dest_x_off); - vertices[5] = v_from_x_coord_y(dest_pixmap, - box[i].y2 + dest_y_off); vertices[6] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dest_x_off); - vertices[7] = v_from_x_coord_y(dest_pixmap, + + if (glamor_priv->yInverted) { + vertices[1] = v_from_x_coord_y_inverted(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[3] = v_from_x_coord_y_inverted(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[5] = v_from_x_coord_y_inverted(dest_pixmap, + box[i].y2 + dest_y_off); + vertices[7] = v_from_x_coord_y_inverted(dest_pixmap, box[i].y2 + dest_y_off); + } else { + vertices[1] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[3] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[5] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); + vertices[7] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); + } if (key.source != SHADER_SOURCE_SOLID) { int tx1 = box[i].x1 + x_source - x_dest; int ty1 = box[i].y1 + y_source - y_dest; diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 60a1a1e8f..58923701e 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -120,23 +120,36 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glEnable(GL_TEXTURE_2D); vertices[0][0] = v_from_x_coord_x(pixmap, x1); - vertices[0][1] = v_from_x_coord_y(pixmap, y1); vertices[1][0] = v_from_x_coord_x(pixmap, x2); - vertices[1][1] = v_from_x_coord_y(pixmap, y1); vertices[2][0] = v_from_x_coord_x(pixmap, x2); - vertices[2][1] = v_from_x_coord_y(pixmap, y2); vertices[3][0] = v_from_x_coord_x(pixmap, x1); - vertices[3][1] = v_from_x_coord_y(pixmap, y2); - source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1); - source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1); source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2); - source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1); source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2); - source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2); source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1); - source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2); + + if (glamor_priv->yInverted) { + vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1); + vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1); + vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2); + vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2); + source_texcoords[0][1] = t_from_x_coord_y_inverted(tile, tile_y1); + source_texcoords[1][1] = t_from_x_coord_y_inverted(tile, tile_y1); + source_texcoords[2][1] = t_from_x_coord_y_inverted(tile, tile_y2); + source_texcoords[3][1] = t_from_x_coord_y_inverted(tile, tile_y2); + } else { + + vertices[0][1] = v_from_x_coord_y(pixmap, y1); + vertices[1][1] = v_from_x_coord_y(pixmap, y1); + vertices[2][1] = v_from_x_coord_y(pixmap, y2); + vertices[3][1] = v_from_x_coord_y(pixmap, y2); + + source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1); + source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1); + source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2); + source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2); + } glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c index 70b466388..027cfc52f 100644 --- a/hw/kdrive/ephyr/ephyr_glamor.c +++ b/hw/kdrive/ephyr/ephyr_glamor.c @@ -45,7 +45,7 @@ ephyr_glamor_init(ScreenPtr screen) ephyr_glamor_host_create_context(kd_screen); - glamor_init(screen); + glamor_init(screen, 0); return TRUE; } From 18a52e23882e4664fdb2de4958c4f9c97e16068c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 12 May 2011 01:37:52 +0800 Subject: [PATCH 111/225] glamor-ddx: Migrate the code to latest mesa library. Use eglCreateDRMImageMESA to create surfaceless image. And then export the drm buffer back which can be used to create the frame buffer. --- hw/xfree86/glamor/glamor.c | 129 ++++++++++++++++---------------- hw/xfree86/glamor/glamor_crtc.c | 4 +- 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index b80d58758..61db4ad78 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -27,6 +27,9 @@ * */ +#ifdef HAVE_DIX_CONFIG_H +#include +#endif #include #include #include @@ -85,11 +88,11 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) EGLImageKHR image; GLuint texture; EGLint attribs[] = { - EGL_IMAGE_WIDTH_INTEL, 0, - EGL_IMAGE_HEIGHT_INTEL, 0, - EGL_IMAGE_FORMAT_INTEL, EGL_FORMAT_RGBA_8888_KHR, - EGL_IMAGE_USE_INTEL, EGL_IMAGE_USE_SHARE_INTEL | - EGL_IMAGE_USE_SCANOUT_INTEL, + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA | + EGL_DRM_BUFFER_USE_SCANOUT_MESA, EGL_NONE }; @@ -99,9 +102,8 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) attribs[1] = width; attribs[3] = height; - image = eglCreateImageKHR(glamor->display, glamor->context, - EGL_SYSTEM_IMAGE_INTEL, - NULL, attribs); + EGLint name, handle, stride, i; + image = eglCreateDRMImageMESA(glamor->display, attribs); if (image == EGL_NO_IMAGE_KHR) return FALSE; @@ -109,14 +111,13 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); glamor_set_pixmap_texture(screen->GetScreenPixmap(screen), width, height, texture); glamor->root = image; scrn->virtualX = width; scrn->virtualY = height; - return TRUE; } @@ -125,49 +126,24 @@ glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) { struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); EGLint name; - - eglShareImageINTEL (glamor->display, glamor->context, glamor->root, 0, - &name, (EGLint *) handle, (EGLint *) pitch); + eglExportDRMImageMESA (glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch); } -Bool -glamor_load_cursor(ScrnInfoPtr scrn, CARD32 *image, int width, int height) +EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) { struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + EGLint attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA | + EGL_DRM_BUFFER_USE_SCANOUT_MESA | EGL_DRM_BUFFER_USE_CURSOR_MESA, + EGL_NONE + }; - if (glamor->cursor == NULL) { - EGLint attribs[] = { - EGL_IMAGE_WIDTH_INTEL, 0, - EGL_IMAGE_HEIGHT_INTEL, 0, - EGL_IMAGE_FORMAT_INTEL, EGL_FORMAT_RGBA_8888_KHR, - EGL_IMAGE_USE_INTEL, EGL_IMAGE_USE_SHARE_INTEL | - EGL_IMAGE_USE_SCANOUT_INTEL, - EGL_NONE - }; - - attribs[1] = width; - attribs[3] = height; - glamor->cursor = - eglCreateImageKHR(glamor->display, glamor->context, - EGL_SYSTEM_IMAGE_INTEL, - NULL, attribs); - if (image == EGL_NO_IMAGE_KHR) - return FALSE; - - glGenTextures(1, &glamor->cursor_tex); - glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, glamor->cursor); - } - - glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); - - return TRUE; + attribs[1] = width; + attribs[3] = height; + return eglCreateDRMImageMESA(glamor->display, attribs); } void @@ -175,9 +151,7 @@ glamor_cursor_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) { struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); EGLint name; - - eglShareImageINTEL (glamor->display, glamor->context, glamor->cursor, - 0, &name, (EGLint *) handle, (EGLint *) pitch); + eglExportDRMImageMESA (glamor->display, glamor->cursor, &name, (EGLint*) handle, (EGLint*) pitch); ErrorF("cursor stride: %d\n", *pitch); } @@ -190,8 +164,7 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags) glamor = xnfcalloc(sizeof *glamor, 1); scrn->driverPrivate = glamor; - - glamor->fd = open("/dev/dri/card0", O_RDWR); + glamor->fd = open("/dev/dri/card1", O_RDWR); glamor->cpp = 4; scrn->monitor = scrn->confScreen->monitor; @@ -243,7 +216,10 @@ glamor_enter_vt(int scrnIndex, int flags) "drmSetMaster failed: %s\n", strerror(errno)); return FALSE; } - +#if 0 + if (!xf86SetDesiredModes(scrn)) + return FALSE; +#endif return TRUE; } @@ -266,6 +242,7 @@ glamor_create_screen_resources(ScreenPtr screen) if (!(*screen->CreateScreenResources) (screen)) return FALSE; + if (!xf86SetDesiredModes(scrn)) return FALSE; @@ -300,15 +277,12 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); - EGLDisplayTypeDRMMESA display; const char *version; + VisualPtr visual; - display.type = EGL_DISPLAY_TYPE_DRM_MESA; - display.device = NULL; - display.fd = glamor->fd; - - glamor->display = eglGetDisplay((EGLNativeDisplayType) &display); - + glamor->display = eglGetDRMDisplayMESA(glamor->fd); + eglBindAPI(EGL_OPENGL_API); + LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB)); if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n"); @@ -325,6 +299,7 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) "Failed to create EGL context\n"); return FALSE; } + if (!eglMakeCurrent(glamor->display, EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, @@ -346,16 +321,29 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) 1, scrn->bitsPerPixel)) return FALSE; - fbPictureInit(screen, NULL, 0); + if (scrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = screen->visuals + screen->numVisuals; + while(--visual >= screen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = scrn->offset.red; + visual->offsetGreen = scrn->offset.green; + visual->offsetBlue = scrn->offset.blue; + visual->redMask = scrn->mask.red; + visual->blueMask = scrn->mask.blue; + } + } + } + fbPictureInit(screen, NULL, 0); xf86SetBlackWhitePixels(screen); - if (!glamor_init(screen)) { + if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to initialize glamor\n"); return FALSE; } - + miInitializeBackingStore(screen); xf86SetBackingStore(screen); xf86SetSilkenMouse(screen); @@ -369,7 +357,7 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) HARDWARE_CURSOR_INVERT_MASK | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED | HARDWARE_CURSOR_UPDATE_UNHIDDEN | HARDWARE_CURSOR_ARGB))) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, @@ -389,6 +377,15 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) glamor->CloseScreen = screen->CloseScreen; screen->CloseScreen = glamor_close_screen; + /* Fixme should we init crtc screen here? */ + if (!xf86CrtcScreenInit(screen)) + return FALSE; + if (!miCreateDefColormap(screen)) + return FALSE; + /* Fixme should we add handle colormap here? */ + + xf86DPMSInit(screen, xf86DPMSSet, 0); + return TRUE; } @@ -423,6 +420,8 @@ glamor_probe(struct _DriverRec *drv, int flags) ScrnInfoPtr scrn = NULL; GDevPtr *sections; int entity, n; + LogMessageVerb(X_INFO, 0 , "%s : %d \n", __FUNCTION__, __LINE__); + n = xf86MatchDevice(glamor_name, §ions); if (n <= 0) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 4c9181922..352f79f79 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -328,7 +328,7 @@ drmmode_update_fb (ScrnInfoPtr scrn, int width, int height) drmModeRmFB(drmmode->fd, drmmode->fb_id); glamor_frontbuffer_handle(scrn, &handle, &pitch); ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, - scrn->bitsPerPixel, pitch * drmmode->cpp, + scrn->bitsPerPixel, pitch, handle, &drmmode->fb_id); if (ret) /* FIXME: Undo glamor_resize() */ @@ -461,7 +461,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { ScrnInfoPtr scrn = crtc->scrn; - glamor_load_cursor(scrn, image, 64, 64); + //glamor_load_cursor(scrn, image, 64, 64); } From 43280372686177603111b175e92e1c88ad4ccdee Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 12 May 2011 01:42:05 +0800 Subject: [PATCH 112/225] glamor-ddx: Fix a compiling error. Need revisit. GC is redefined in the X11/Xlib.h and include/gcstruct.h which is a xorg header file. Just use a macro to simply avoid the conflict. Need revisit latter to find a correct way to fix this problem. --- hw/xfree86/glamor/glamor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 61db4ad78..59475288f 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -45,7 +45,9 @@ #include "../../../mi/micmap.h" #include #include +#define GC XORG_GC #include +#undef GC #include "glamor_ddx.h" From e3295d4106ac5b62f63e32dcb24a6094194cb1a8 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 12 May 2011 10:22:07 +0800 Subject: [PATCH 113/225] glamor-ddx: Move the cursor EGL image to crtc strcture. Cursor is a per crtc resource. And this commit also fix the cursor initialization regard to the latest mesa EGL code. Now hardware cursor works fine. --- hw/xfree86/glamor/glamor.c | 42 ++++++++++++++++++++------------- hw/xfree86/glamor/glamor_crtc.c | 41 ++++++++++++++++++++++++++++---- hw/xfree86/glamor/glamor_ddx.h | 4 ++-- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 59475288f..bf05a0b2f 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -66,9 +66,8 @@ glamor_identify(int flags) struct glamor_screen_private { EGLDisplay display; EGLContext context; - EGLImageKHR root, cursor; + EGLImageKHR root; EGLint major, minor; - GLuint cursor_tex; CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; @@ -149,14 +148,15 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) } void -glamor_cursor_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) +glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch) { struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); EGLint name; - eglExportDRMImageMESA (glamor->display, glamor->cursor, &name, (EGLint*) handle, (EGLint*) pitch); + eglExportDRMImageMESA (glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch); ErrorF("cursor stride: %d\n", *pitch); } +char * dri_device_name = "/dev/dri/card0"; static Bool glamor_pre_init(ScrnInfoPtr scrn, int flags) { @@ -166,7 +166,12 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags) glamor = xnfcalloc(sizeof *glamor, 1); scrn->driverPrivate = glamor; - glamor->fd = open("/dev/dri/card1", O_RDWR); + glamor->fd = open(dri_device_name, O_RDWR); + if (glamor->fd == -1 ) { + ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno)); + goto fail; + } + glamor->cpp = 4; scrn->monitor = scrn->confScreen->monitor; @@ -174,22 +179,21 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags) scrn->rgbBits = 8; if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb)) - return FALSE; + goto fail; xf86PrintDepthBpp(scrn); if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) - return FALSE; + goto fail; if (!xf86SetDefaultVisual(scrn, -1)) - return FALSE; + goto fail; glamor->cpp = scrn->bitsPerPixel / 8; if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); - xfree(glamor); - return FALSE; + goto fail; } scrn->currentMode = scrn->modes; @@ -197,9 +201,13 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags) /* Load the required sub modules */ if (!xf86LoadSubModule(scrn, "fb")) - return FALSE; + goto fail; return TRUE; + +fail: + scrn->driverPrivate = NULL; + xfree(glamor); } static void @@ -396,10 +404,12 @@ glamor_free_screen(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); - - close(glamor->fd); - xfree(scrn->driverPrivate); - scrn->driverPrivate = NULL; + if (glamor != NULL) + { + close(glamor->fd); + xfree(glamor); + scrn->driverPrivate = NULL; + } } static ModeStatus @@ -422,8 +432,6 @@ glamor_probe(struct _DriverRec *drv, int flags) ScrnInfoPtr scrn = NULL; GDevPtr *sections; int entity, n; - LogMessageVerb(X_INFO, 0 , "%s : %d \n", __FUNCTION__, __LINE__); - n = xf86MatchDevice(glamor_name, §ions); if (n <= 0) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 352f79f79..9425b6970 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -48,6 +48,14 @@ #include #include #include +#include + +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#define EGL_DISPLAY_NO_X_MESA +#include +#include +#include #include "glamor_ddx.h" @@ -67,6 +75,7 @@ typedef struct { drmmode_ptr drmmode; drmModeCrtcPtr mode_crtc; uint32_t rotate_fb_id; + EGLImageKHR cursor; unsigned int cursor_tex; } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; @@ -328,7 +337,7 @@ drmmode_update_fb (ScrnInfoPtr scrn, int width, int height) drmModeRmFB(drmmode->fd, drmmode->fb_id); glamor_frontbuffer_handle(scrn, &handle, &pitch); ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, - scrn->bitsPerPixel, pitch, + scrn->bitsPerPixel, pitch /** drmmode->cpp*/, handle, &drmmode->fb_id); if (ret) /* FIXME: Undo glamor_resize() */ @@ -459,9 +468,31 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) static void drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; ScrnInfoPtr scrn = crtc->scrn; - //glamor_load_cursor(scrn, image, 64, 64); + + if (drmmode_crtc->cursor == NULL) + { + drmmode_crtc->cursor = glamor_create_cursor_argb(scrn, 64, 64); + if (drmmode_crtc->cursor == EGL_NO_IMAGE_KHR) + return; + glGenTextures(1, &drmmode_crtc->cursor_tex); + glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor); + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 64); + glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); + // memset(image, 0xff, 64*64*4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image); + } @@ -484,7 +515,7 @@ drmmode_show_cursor (xf86CrtcPtr crtc) uint32_t handle, stride; ErrorF("show cursor\n"); - glamor_cursor_handle(scrn, &handle, &stride); + glamor_cursor_handle(scrn, drmmode_crtc->cursor, &handle, &stride); drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64); @@ -596,6 +627,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { .show_cursor = drmmode_show_cursor, .hide_cursor = drmmode_hide_cursor, .load_cursor_argb = drmmode_load_cursor_argb, + .load_cursor_image = NULL, #if 0 .shadow_create = drmmode_crtc_shadow_create, .shadow_allocate = drmmode_crtc_shadow_allocate, @@ -1311,9 +1343,10 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) if (!crtc->enabled) continue; - +#if 0 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); +#endif } return TRUE; diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index 0968f013f..0f7cbe47e 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -6,8 +6,8 @@ void glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch); Bool glamor_load_cursor(ScrnInfoPtr scrn, CARD32 *image, int width, int height); -void glamor_cursor_handle(ScrnInfoPtr scrn, - uint32_t *handle, uint32_t *pitch); + +void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch); Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp); void drmmode_closefb(ScrnInfoPtr scrn); From c97d4533f29e77d80c076deff9ad0f218eb2e8f4 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 12 May 2011 14:49:08 +0800 Subject: [PATCH 114/225] glamor: Silent compilation warnings due to some deprecated APIs. those xcalloc/xfree/xalloc/XNFprintf/... are deprecated. Replace then with the new one. And fix some other minor problems. --- glamor/glamor.c | 15 +++++++-------- glamor/glamor_core.c | 10 +++++----- glamor/glamor_getspans.c | 4 ++-- glamor/glamor_glyphs.c | 8 ++++---- glamor/glamor_polylines.c | 6 +++--- glamor/glamor_priv.h | 4 ++-- glamor/glamor_render.c | 27 +++++++++++++++------------ glamor/glamor_setspans.c | 4 ++-- glamor/glu3/glu3.h | 31 ------------------------------- hw/xfree86/glamor/glamor.c | 8 ++++---- hw/xfree86/glamor/glamor_crtc.c | 25 +++++++++++-------------- hw/xfree86/glamor/glamor_ddx.h | 1 + 12 files changed, 56 insertions(+), 87 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 026f1bf52..66a694ec9 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -102,7 +102,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); - if (dixAllocatePrivates(pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { + if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { fbDestroyPixmap(pixmap); ErrorF("Fail to allocate privates for PIXMAP.\n"); return NullPixmap; @@ -166,16 +166,15 @@ glamor_init(ScreenPtr screen, unsigned int flags) { glamor_screen_private *glamor_priv; - if (flags & ~GLAMOR_VALID_FLAGS) { - ErrorF("glamor_init: Invalid flags %x\n", flags); - return FALSE; - } - #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif - glamor_priv = xcalloc(1, sizeof(*glamor_priv)); + if (flags & ~GLAMOR_VALID_FLAGS) { + ErrorF("glamor_init: Invalid flags %x\n", flags); + return FALSE; + } + glamor_priv = calloc(1, sizeof(*glamor_priv)); if (glamor_priv == NULL) return FALSE; @@ -274,7 +273,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) return TRUE; fail: - xfree(glamor_priv); + free(glamor_priv); dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL); return FALSE; } diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 3d1d3f842..09605e222 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -311,7 +311,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) stride = pixmap->devKind; read_stride = stride; - data = xalloc(stride * pixmap->drawable.height); + data = malloc(stride * pixmap->drawable.height); switch (drawable->depth) { case 1: @@ -332,7 +332,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) break; default: ErrorF("Unknown prepareaccess depth %d\n", drawable->depth); - xfree(data); + free(data); return FALSE; } @@ -475,9 +475,9 @@ glamor_finish_access(DrawablePtr drawable) if (pixmap_priv == NULL) return; if (glamor_priv->yInverted) - ptexcoords = texcoords_inverted; + ptexcoords = &texcoords_inverted[0][0]; else - ptexcoords = texcoords; + ptexcoords = &texcoords[0][0]; if (pixmap_priv->fb == 0) { ScreenPtr screen = pixmap->drawable.pScreen; @@ -549,7 +549,7 @@ glamor_finish_access(DrawablePtr drawable) glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); - xfree(pixmap->devPrivate.ptr); + free(pixmap->devPrivate.ptr); pixmap->devPrivate.ptr = NULL; } diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index e35c4168a..dba23a89d 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -61,7 +61,7 @@ glamor_get_spans(DrawablePtr drawable, switch (drawable->depth) { case 1: - temp_dst = xalloc(wmax); + temp_dst = malloc(wmax); format = GL_ALPHA; type = GL_UNSIGNED_BYTE; readpixels_dst = temp_dst; @@ -111,7 +111,7 @@ glamor_get_spans(DrawablePtr drawable, readpixels_dst += PixmapBytePad(widths[i], drawable->depth); } } - xfree(temp_dst); + free(temp_dst); return; fail: diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index 6e5595e68..e24b222f4 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -130,12 +130,12 @@ static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format) } if (cache->hash_entries) { - xfree(cache->hash_entries); + free(cache->hash_entries); cache->hash_entries = NULL; } if (cache->glyphs) { - xfree(cache->glyphs); + free(cache->glyphs); cache->glyphs = NULL; } cache->glyph_count = 0; @@ -215,9 +215,9 @@ static Bool glamor_realize_glyph_caches(ScreenPtr screen, unsigned int format) cache->picture = picture; cache->picture->refcnt++; - cache->hash_entries = xalloc(sizeof(int) * cache->hash_size); + cache->hash_entries = malloc(sizeof(int) * cache->hash_size); cache->glyphs = - xalloc(sizeof(glamor_cached_glyph_t) * cache->size); + malloc(sizeof(glamor_cached_glyph_t) * cache->size); cache->glyph_count = 0; if (!cache->hash_entries || !cache->glyphs) diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index acf6bf673..c9752685f 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -64,7 +64,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, goto fail; } - rects = xalloc(sizeof(xRectangle) * (n - 1)); + rects = malloc(sizeof(xRectangle) * (n - 1)); x1 = points[0].x; y1 = points[0].y; /* If we have any non-horizontal/vertical, fall back. */ @@ -80,7 +80,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, if (x1 != x2 && y1 != y2) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - xfree(rects); + free(rects); ErrorF("stub diagonal poly_line\n"); glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1); @@ -106,7 +106,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, y1 = y2; } gc->ops->PolyFillRect(drawable, gc, n - 1, rects); - xfree(rects); + free(rects); return; fail: diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index f12016d33..b98907837 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -231,7 +231,7 @@ glamor_delayed_fallback(ScreenPtr screen, char *format, ...) return; va_start(ap, format); - glamor_priv->delayed_fallback_string = XNFvprintf(format, ap); + XNFvasprintf(&glamor_priv->delayed_fallback_string, format, ap); va_end(ap); } @@ -240,7 +240,7 @@ glamor_clear_delayed_fallbacks(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - xfree(glamor_priv->delayed_fallback_string); + free(glamor_priv->delayed_fallback_string); glamor_priv->delayed_fallback_string = NULL; } diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 2ec811f6e..6139b0d02 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -181,13 +181,15 @@ glamor_create_composite_fs(struct shader_key *key) FatalError("Bad composite IN type"); } - source = XNFprintf("%s%s%s", - source_fetch, - mask_fetch, - in); + XNFasprintf(&source, + "%s%s%s", + source_fetch, + mask_fetch, + in); + prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); - xfree(source); + free(source); return prog; } @@ -216,14 +218,15 @@ glamor_create_composite_vs(struct shader_key *key) if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID) mask_coords_setup = mask_coords; - source = XNFprintf("%s%s%s%s", - main_opening, - source_coords_setup, - mask_coords_setup, - main_closing); + XNFasprintf(&source, + "%s%s%s%s", + main_opening, + source_coords_setup, + mask_coords_setup, + main_closing); prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source); - xfree(source); + free(source); return prog; } @@ -591,7 +594,7 @@ glamor_setup_composite_vbo(ScreenPtr screen) glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride, - (void *)(glamor_priv->vbo_offset)); + (void *)((long)glamor_priv->vbo_offset)); glEnableClientState(GL_VERTEX_ARRAY); if (glamor_priv->has_source_coords) { diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 54aa26635..6c1c2ff3f 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -53,7 +53,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, switch (drawable->depth) { case 1: - temp_src = xalloc(wmax); + temp_src = malloc(wmax); format = GL_ALPHA; type = GL_UNSIGNED_BYTE; drawpixels_src = temp_src; @@ -123,7 +123,7 @@ fail: glDisable(GL_SCISSOR_TEST); glamor_set_planemask(dest_pixmap, ~0); glamor_set_alu(GXcopy); - xfree(temp_src); + free(temp_src); glamor_fallback("glamor_set_spans(): to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h index 27bcebc80..0a698cc02 100644 --- a/glamor/glu3/glu3.h +++ b/glamor/glu3/glu3.h @@ -123,44 +123,14 @@ typedef struct GLUmat4Stack GLUmat4Stack; #ifdef __cplusplus extern "C" { #endif -#if 0 -GLfloat gluDot4_4v(const GLUvec4 *, const GLUvec4 *); -GLfloat gluDot3_4v(const GLUvec4 *, const GLUvec4 *); -GLfloat gluDot2_4v(const GLUvec4 *, const GLUvec4 *); - -void gluCross4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); -void gluNormalize4v(GLUvec4 *result, const GLUvec4 *); -GLfloat gluLength4v(const GLUvec4 *); -GLfloat gluLengthSqr4v(const GLUvec4 *); -void gluOuter4v(GLUmat4 *result, const GLUvec4 *, const GLUvec4 *); - - -void gluMult4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); -void gluDiv4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); -void gluAdd4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); -void gluSub4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *); - -void gluMult4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); -void gluDiv4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); -void gluAdd4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); -void gluSub4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat); - -void gluMult4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *); -void gluAdd4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *); -void gluSub4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *); -void gluMult4m_4v(GLUvec4 *result, const GLUmat4 *m, const GLUvec4 *v); - -void gluMult4m_f(GLUmat4 *result, const GLUmat4 *, GLfloat); void gluScale4v(GLUmat4 *result, const GLUvec4 *); -void gluTranslate3f(GLUmat4 *result, GLfloat x, GLfloat y, GLfloat z); void gluTranslate4v(GLUmat4 *result, const GLUvec4 *); void gluRotate4v(GLUmat4 *result, const GLUvec4 *axis, GLfloat angle); void gluLookAt4v(GLUmat4 *result, const GLUvec4 *eye, const GLUvec4 *center, const GLUvec4 *up); void gluPerspective4f(GLUmat4 *result, GLfloat fovy, GLfloat aspect, GLfloat near, GLfloat far); -void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m); void gluFrustum6f(GLUmat4 *result, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, @@ -169,7 +139,6 @@ void gluOrtho6f(GLUmat4 *result, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far); -#endif extern const GLUmat4 gluIdentityMatrix; #ifdef __cplusplus diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index bf05a0b2f..255661d62 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -103,7 +103,6 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) attribs[1] = width; attribs[3] = height; - EGLint name, handle, stride, i; image = eglCreateDRMImageMESA(glamor->display, attribs); if (image == EGL_NO_IMAGE_KHR) return FALSE; @@ -206,8 +205,9 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags) return TRUE; fail: - scrn->driverPrivate = NULL; - xfree(glamor); + scrn->driverPrivate = NULL; + free(glamor); + return FALSE; } static void @@ -407,7 +407,7 @@ glamor_free_screen(int scrnIndex, int flags) if (glamor != NULL) { close(glamor->fd); - xfree(glamor); + free(glamor); scrn->driverPrivate = NULL; } } diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 9425b6970..fd4ee8671 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -377,7 +377,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, crtc->y = y; crtc->rotation = rotation; - output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output); + output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); if (!output_ids) { ret = FALSE; goto done; @@ -469,10 +469,8 @@ static void drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; ScrnInfoPtr scrn = crtc->scrn; - if (drmmode_crtc->cursor == NULL) { drmmode_crtc->cursor = glamor_create_cursor_argb(scrn, 64, 64); @@ -489,7 +487,6 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) glPixelStorei(GL_UNPACK_ROW_LENGTH, 64); glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); - // memset(image, 0xff, 64*64*4); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image); @@ -775,7 +772,7 @@ static int drmmode_output_lvds_edid(xf86OutputPtr output, * device. This is similar to what we have done in i830_lvds.c */ edid_mon = NULL; - edid_mon = xcalloc(1, sizeof(xf86Monitor)); + edid_mon = calloc(1, sizeof(xf86Monitor)); if (!edid_mon) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "Can't allocate memory for edid_mon.\n"); @@ -915,17 +912,17 @@ drmmode_output_destroy(xf86OutputPtr output) drmModeFreePropertyBlob(drmmode_output->edid_blob); for (i = 0; i < drmmode_output->num_props; i++) { drmModeFreeProperty(drmmode_output->props[i].mode_prop); - xfree(drmmode_output->props[i].atoms); + free(drmmode_output->props[i].atoms); } - xfree(drmmode_output->props); + free(drmmode_output->props); drmModeFreeConnector(drmmode_output->mode_output); if (drmmode_output->private_data) { - xfree(drmmode_output->private_data); + free(drmmode_output->private_data); drmmode_output->private_data = NULL; } if (drmmode_output->backlight_iface) drmmode_backlight_set(output, drmmode_output->backlight_active_level); - xfree(drmmode_output); + free(drmmode_output); output->driver_private = NULL; } @@ -1008,7 +1005,7 @@ drmmode_output_create_resources(xf86OutputPtr output) drmModePropertyPtr drmmode_prop; int i, j, err; - drmmode_output->props = xcalloc(mode_output->count_props, sizeof(drmmode_prop_rec)); + drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); if (!drmmode_output->props) return; @@ -1033,7 +1030,7 @@ drmmode_output_create_resources(xf86OutputPtr output) INT32 range[2]; p->num_atoms = 1; - p->atoms = xcalloc(p->num_atoms, sizeof(Atom)); + p->atoms = calloc(p->num_atoms, sizeof(Atom)); if (!p->atoms) continue; p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); @@ -1055,7 +1052,7 @@ drmmode_output_create_resources(xf86OutputPtr output) } } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { p->num_atoms = drmmode_prop->count_enums + 1; - p->atoms = xcalloc(p->num_atoms, sizeof(Atom)); + p->atoms = calloc(p->num_atoms, sizeof(Atom)); if (!p->atoms) continue; p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); @@ -1291,7 +1288,7 @@ drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) return; } - drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1); + drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); if (!drmmode_output) { xf86OutputDestroy(output); drmModeFreeConnector(koutput); @@ -1305,7 +1302,7 @@ drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) */ drmmode_output->private_data = NULL; if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) { - drmmode_output->private_data = xcalloc( + drmmode_output->private_data = calloc( sizeof(struct fixed_panel_lvds), 1); if (!drmmode_output->private_data) xf86DrvMsg(scrn->scrnIndex, X_ERROR, diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index 0f7cbe47e..6f8de11ac 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -8,6 +8,7 @@ Bool glamor_load_cursor(ScrnInfoPtr scrn, CARD32 *image, int width, int height); void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch); +EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height); Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp); void drmmode_closefb(ScrnInfoPtr scrn); From 74ca45e7d0ed6654204189793261ef65f213bb2e Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 18 May 2011 16:48:06 +0800 Subject: [PATCH 115/225] glamor-ddx: Fixed one bug when a client reset the connection. This commit fixed two bugs when one client reset the connection. The first is that we should reopen the graphic device when the previous node was closed during the screen closing. The second one is we should call glamor_close_screen (not the ddx version) prior to call eglTerminate(). As eglTerminate will release the share library. And the glamor_close_screen may still need to call openGL APIs and thus will hit segfault. And renamed the ddx functions to avoid naming conflications with the glamor functions. --- hw/xfree86/glamor/glamor.c | 61 +++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 255661d62..665cd0aea 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -157,7 +157,7 @@ glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uin char * dri_device_name = "/dev/dri/card0"; static Bool -glamor_pre_init(ScrnInfoPtr scrn, int flags) +glamor_pre_init_ddx(ScrnInfoPtr scrn, int flags) { struct glamor_screen_private *glamor; rgb defaultWeight = { 0, 0, 0 }; @@ -211,12 +211,12 @@ fail: } static void -glamor_adjust_frame(int scrnIndex, int x, int y, int flags) +glamor_adjust_frame_ddx(int scrnIndex, int x, int y, int flags) { } static Bool -glamor_enter_vt(int scrnIndex, int flags) +glamor_enter_vt_ddx(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); @@ -234,7 +234,7 @@ glamor_enter_vt(int scrnIndex, int flags) } static void -glamor_leave_vt(int scrnIndex, int flags) +glamor_leave_vt_ddx(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); @@ -243,7 +243,7 @@ glamor_leave_vt(int scrnIndex, int flags) } static Bool -glamor_create_screen_resources(ScreenPtr screen) +glamor_create_screen_resources_ddx(ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); @@ -260,13 +260,16 @@ glamor_create_screen_resources(ScreenPtr screen) } static Bool -glamor_close_screen(int scrnIndex, ScreenPtr screen) +glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + screen->CloseScreen = glamor->CloseScreen; + (*screen->CloseScreen) (scrnIndex, screen); + if (scrn->vtSema == TRUE) - glamor_leave_vt(scrnIndex, 0); + glamor_leave_vt_ddx(scrnIndex, 0); glamor_fini(screen); @@ -275,21 +278,32 @@ glamor_close_screen(int scrnIndex, ScreenPtr screen) eglTerminate(glamor->display); drmmode_closefb(scrn); - - screen->CloseScreen = glamor->CloseScreen; - (*screen->CloseScreen) (scrnIndex, screen); + + glamor->fd = -1; + glamor->root = EGL_NO_IMAGE_KHR; return TRUE; } static Bool -glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) +glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); const char *version; VisualPtr visual; + /* If serverGeneration != 1 then fd was closed during the last + time closing screen, actually in eglTerminate(). */ + + if (glamor->fd == -1 && serverGeneration != 1) { + glamor->fd = open(dri_device_name, O_RDWR); + if (glamor->fd == -1 ) { + ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno)); + return FALSE; + } + } + glamor->display = eglGetDRMDisplayMESA(glamor->fd); eglBindAPI(EGL_OPENGL_API); LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB)); @@ -378,15 +392,14 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) * later memory should be bound when allocating, e.g rotate_mem */ scrn->vtSema = TRUE; - if (!glamor_enter_vt(scrnIndex, 0)) + if (!glamor_enter_vt_ddx(scrnIndex, 0)) return FALSE; screen->SaveScreen = xf86SaveScreen; glamor->CreateScreenResources = screen->CreateScreenResources; - screen->CreateScreenResources = glamor_create_screen_resources; + screen->CreateScreenResources = glamor_create_screen_resources_ddx; glamor->CloseScreen = screen->CloseScreen; - screen->CloseScreen = glamor_close_screen; - + screen->CloseScreen = glamor_close_screen_ddx; /* Fixme should we init crtc screen here? */ if (!xf86CrtcScreenInit(screen)) return FALSE; @@ -400,7 +413,7 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) } static void -glamor_free_screen(int scrnIndex, int flags) +glamor_free_screen_ddx(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); @@ -413,7 +426,7 @@ glamor_free_screen(int scrnIndex, int flags) } static ModeStatus -glamor_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +glamor_valid_mode_ddx(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { if (mode->Flags & V_INTERLACE) { if (verbose) { @@ -450,13 +463,13 @@ glamor_probe(struct _DriverRec *drv, int flags) scrn->name = (char *) glamor_name; scrn->Probe = NULL; - scrn->PreInit = glamor_pre_init; - scrn->ScreenInit = glamor_screen_init; - scrn->AdjustFrame = glamor_adjust_frame; - scrn->EnterVT = glamor_enter_vt; - scrn->LeaveVT = glamor_leave_vt; - scrn->FreeScreen = glamor_free_screen; - scrn->ValidMode = glamor_valid_mode; + scrn->PreInit = glamor_pre_init_ddx; + scrn->ScreenInit = glamor_screen_init_ddx; + scrn->AdjustFrame = glamor_adjust_frame_ddx; + scrn->EnterVT = glamor_enter_vt_ddx; + scrn->LeaveVT = glamor_leave_vt_ddx; + scrn->FreeScreen = glamor_free_screen_ddx; + scrn->ValidMode = glamor_valid_mode_ddx; return TRUE; } From f871d174a861e7c3d2b8f4d9a3f10c38a5120606 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 19 May 2011 11:40:38 +0800 Subject: [PATCH 116/225] glamor: Switch to software fb for too large pixmap. If pixmap's size exceeds the limitation of the MESA library, the rendering will fail. So we switch to software fb if it is the case. Add one new element for pixmap private structure to indicate whehter we are a software fb type or a opengl type. --- glamor/glamor.c | 26 +++++++++++++++++++------- glamor/glamor_priv.h | 18 ++++++++++++++++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 66a694ec9..4594f145c 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -95,12 +95,24 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, PixmapPtr pixmap; GLenum format; GLuint tex; - + glamor_pixmap_private *pixmap_priv; + int type = GLAMOR_GL; if (w > 32767 || h > 32767) return NullPixmap; - pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); + if (w > MAX_WIDTH || h > MAX_HEIGHT) { + /* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo. + If we exceed such limitation, we have to use framebuffer.*/ + type = GLAMOR_FB; + pixmap = fbCreatePixmap (screen, w, h, depth, usage); + screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, + (((w * pixmap->drawable.bitsPerPixel + + 7) / 8) + 3) & ~3, + NULL); + ErrorF("fallback to software fb for pixmap %p , %d x %d \n", pixmap, w, h); + } else + pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { fbDestroyPixmap(pixmap); @@ -108,8 +120,12 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, return NullPixmap; } - if (w == 0 || h == 0) + if (w == 0 || h == 0 || type != GLAMOR_GL) return pixmap; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + pixmap_priv->type = type; + /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA. * FBOs, which EXT_fbo forgot to do. */ @@ -122,7 +138,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, break; } - /* Create the texture used to store the pixmap's data. */ glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); @@ -132,7 +147,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, format, GL_UNSIGNED_BYTE, NULL); glamor_set_pixmap_texture(pixmap, w, h, tex); - return pixmap; } @@ -141,7 +155,6 @@ glamor_destroy_pixmap(PixmapPtr pixmap) { if (pixmap->refcnt == 1) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - glDeleteFramebuffersEXT(1, &pixmap_priv->fb); glDeleteTextures(1, &pixmap_priv->tex); } @@ -285,7 +298,6 @@ glamor_close_screen(int idx, ScreenPtr screen) #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif - glamor_glyphs_fini(screen); screen->CloseScreen = glamor_priv->saved_close_screen; screen->CreateGC = glamor_priv->saved_create_gc; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index b98907837..93837e0b7 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -39,6 +39,14 @@ #include "glyphstr.h" #endif +#ifndef MAX_WIDTH +#define MAX_WIDTH 4096 +#endif + +#ifndef MAX_HEIGHT +#define MAX_HEIGHT 4096 +#endif + typedef enum glamor_access { GLAMOR_ACCESS_RO, GLAMOR_ACCESS_RW, @@ -175,10 +183,16 @@ typedef struct glamor_screen_private { glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; } glamor_screen_private; +enum glamor_pixmap_type { + GLAMOR_GL, + GLAMOR_FB +}; + typedef struct glamor_pixmap_private { GLuint tex; GLuint fb; GLuint pbo; + enum glamor_pixmap_type type; } glamor_pixmap_private; extern DevPrivateKey glamor_screen_private_key; @@ -250,8 +264,8 @@ glamor_report_delayed_fallbacks(ScreenPtr screen) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (glamor_priv->delayed_fallback_string) { - LogMessageVerb(X_INFO, 0, "fallback: %s", - glamor_priv->delayed_fallback_string); + // LogMessageVerb(X_INFO, 0, "fallback: %s", + // glamor_priv->delayed_fallback_string); glamor_clear_delayed_fallbacks(screen); } } From 8593f22fb8fc5e0d0f406d9c94cca22347505fd6 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 19 May 2011 17:59:19 +0800 Subject: [PATCH 117/225] glamor: glamor_set_alu should enable GL_COLOR_LOGIC_OP. GL_COLOR_OP seems not supported in current MESA. --- glamor/glamor_core.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 09605e222..5f13b56d2 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -117,12 +117,10 @@ void glamor_set_alu(unsigned char alu) { if (alu == GXcopy) { - glDisable(GL_LOGIC_OP); + glDisable(GL_COLOR_LOGIC_OP); return; } - - glEnable(GL_LOGIC_OP); - + glEnable(GL_COLOR_LOGIC_OP); switch (alu) { case GXclear: glLogicOp(GL_CLEAR); @@ -271,10 +269,10 @@ glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, break; case 24: case 32: - color[0] = ubyte_to_float(fg_pixel >> 16); - color[1] = ubyte_to_float(fg_pixel >> 8); - color[2] = ubyte_to_float(fg_pixel >> 0); - color[3] = ubyte_to_float(fg_pixel >> 24); + color[0] = ubyte_to_float((fg_pixel >> 16) & 0xFF); + color[1] = ubyte_to_float((fg_pixel >> 8) & 0xFF); + color[2] = ubyte_to_float((fg_pixel >> 0) & 0xFF); + color[3] = ubyte_to_float((fg_pixel >> 24) & 0xFF); break; default: ErrorF("pixmap with bad depth: %d\n", pixmap->drawable.depth); From cd43b1ea831eac11bc6ad0c3b1e040bb968b9861 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 19 May 2011 18:02:19 +0800 Subject: [PATCH 118/225] glamor: Add fallback code path for glamor_fill. --- glamor/glamor_fill.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 1a982054a..8ea70d0cf 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -84,6 +84,20 @@ glamor_fill(DrawablePtr drawable, drawable->y + y - gc->patOrg.y); break; } + return; +#if 0 + fail: + glamor_fallback("glamor_fill()"); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_gc(gc)) { + fbFill(drawable, gc, x, y, width, height); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable); + } +#endif +return; + } void @@ -142,8 +156,10 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, if (!glamor_set_destination_pixmap(pixmap)) return; glamor_set_alu(alu); - if (!glamor_set_planemask(pixmap, planemask)) + if (!glamor_set_planemask(pixmap, planemask)) { + ErrorF("Failedto set planemask in glamor_solid.\n"); goto fail; + } glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color); From 529c38a4601e8f0712773bf29a48cddfa7a5edc4 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 19 May 2011 18:03:12 +0800 Subject: [PATCH 119/225] glamor-ddx: Remove debug message when moving cursor. --- hw/xfree86/glamor/glamor_crtc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index fd4ee8671..aba9b2c29 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -460,8 +460,6 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - ErrorF("move cursor\n"); - drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); } From 1495ba9e64633476508febb01ec2e9594a7b466b Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sun, 22 May 2011 17:51:27 +0800 Subject: [PATCH 120/225] glamor: Use buffer object as much as possible. Change the row length of 1bit color depth pixmap to the actual stride. The previous implementation use the width as its stride which is not good. As it will waste 8 times of space and also bring some non-unify code path. With this commit, we can merge those 1bit or other color depth to almost one code path. And we will use pixel buffer object as much as possible due to performance issue. By default, some mesa hardware driver will fallback to software rasterization when use glReadPixels on a non-buffer-object frame buffer. This change will get about 4x times performance improvemention when we use y-inverted glamor or the driver support hardware y-flipped blitting. --- glamor/glamor_core.c | 111 +++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 62 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 5f13b56d2..635b72641 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -289,7 +289,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride, read_stride, x, y; + unsigned int stride, row_length, x, y; GLenum format, type; uint8_t *data, *read; glamor_screen_private *glamor_priv = @@ -307,15 +307,14 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) } stride = pixmap->devKind; - read_stride = stride; - - data = malloc(stride * pixmap->drawable.height); + row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; + switch (drawable->depth) { case 1: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; - read_stride = pixmap->drawable.width; + row_length = stride; break; case 8: format = GL_ALPHA; @@ -330,67 +329,47 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) break; default: ErrorF("Unknown prepareaccess depth %d\n", drawable->depth); - free(data); return FALSE; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glPixelStorei(GL_PACK_ALIGNMENT, 1); - if (drawable->depth != 1) { - glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 / - pixmap->drawable.bitsPerPixel); + glPixelStorei(GL_PACK_ROW_LENGTH, row_length); + + if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { + + if (!glamor_priv->yInverted) + glPixelStorei(GL_PACK_INVERT_MESA, 1); + + glGenBuffersARB (1, &pixmap_priv->pbo); + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT, + stride * pixmap->drawable.height, + NULL, GL_DYNAMIC_DRAW_ARB); + glReadPixels (0, 0, + row_length, pixmap->drawable.height, + format, type, 0); + + data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB); + + if (!glamor_priv->yInverted) + glPixelStorei(GL_PACK_INVERT_MESA, 0); + } else { - glPixelStorei(GL_PACK_ROW_LENGTH, read_stride); - } - if (GLEW_MESA_pack_invert && drawable->depth != 1) { - if (!glamor_priv->yInverted) - glPixelStorei(GL_PACK_INVERT_MESA, 1); - glReadPixels(0, 0, - pixmap->drawable.width, pixmap->drawable.height, - format, type, data); - if (!glamor_priv->yInverted) - glPixelStorei(GL_PACK_INVERT_MESA, 0); - } else { - glGenBuffersARB(1, &pixmap_priv->pbo); + data = malloc(stride * pixmap->drawable.height); + + glGenBuffersARB(1, &pixmap_priv->pbo); glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, - read_stride * pixmap->drawable.height, - NULL, GL_STREAM_READ_ARB); - glReadPixels(0, 0, - pixmap->drawable.width, pixmap->drawable.height, - format, type, 0); - + stride * pixmap->drawable.height, + NULL, GL_STREAM_READ_ARB); + glReadPixels (0, 0, row_length, pixmap->drawable.height, + format, type, 0); read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB); - if (pixmap->drawable.depth == 1) { - for (y = 0; y < pixmap->drawable.height; y++) { - uint8_t *read_row; - uint8_t *write_row = data + y * stride; - - if (glamor_priv->yInverted) - read_row = read + read_stride * y; - else - read_row = read + - read_stride * (pixmap->drawable.height - y - 1); - - for (x = 0; x < pixmap->drawable.width; x++) { - int index = x / 8; - int bit = 1 << (x % 8); - - if (read_row[x]) - write_row[index] |= bit; - else - write_row[index] &= ~bit; - } - } - } else { - for (y = 0; y < pixmap->drawable.height; y++) - if (glamor_priv->yInverted) - memcpy(data + y * stride, read + y * stride, stride); - else - memcpy(data + y * stride, - read + (pixmap->drawable.height - y - 1) * stride, stride); - } + for (y = 0; y < pixmap->drawable.height; y++) + memcpy(data + y * stride, + read + (pixmap->drawable.height - y - 1) * stride, stride); glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); glDeleteBuffersARB(1, &pixmap_priv->pbo); @@ -452,7 +431,7 @@ glamor_finish_access(DrawablePtr drawable) glamor_get_screen_private(drawable->pScreen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride; + unsigned int stride, row_length; GLenum format, type; static float vertices[4][2] = {{-1, -1}, { 1, -1}, @@ -489,10 +468,13 @@ glamor_finish_access(DrawablePtr drawable) if (pixmap->devPrivate.ptr == NULL) return; + stride = pixmap->devKind; + row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; switch (drawable->depth) { case 1: format = GL_COLOR_INDEX; type = GL_BITMAP; + row_length = stride; break; case 8: format = GL_ALPHA; @@ -510,7 +492,6 @@ glamor_finish_access(DrawablePtr drawable) return; } - stride = pixmap->devKind; glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); @@ -523,8 +504,7 @@ glamor_finish_access(DrawablePtr drawable) glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 / - pixmap->drawable.bitsPerPixel); + glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0); @@ -540,14 +520,21 @@ glamor_finish_access(DrawablePtr drawable) glUseProgramObjectARB(glamor_priv->finish_access_prog); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisable(GL_TEXTURE_2D); glUseProgramObjectARB(0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); - free(pixmap->devPrivate.ptr); + if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT); + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB (1, &pixmap_priv->pbo); + pixmap_priv->pbo = 0; + } else + free(pixmap->devPrivate.ptr); + pixmap->devPrivate.ptr = NULL; } From 1edf0cc6ab340c98fde201328631ca61e9d871a1 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sun, 22 May 2011 23:45:51 +0800 Subject: [PATCH 121/225] glamor: Don't write back read only pixmap to fbo. For those pixmap which has valid fbo and opened as GLAMOR_ACCESS_RO mode, we don't need to upload the texture back when calling the glamor_finish_access(). This will get about 10% performance gain. --- glamor/glamor_core.c | 5 +++++ glamor/glamor_priv.h | 1 + 2 files changed, 6 insertions(+) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 635b72641..f5fc1a3eb 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -332,6 +332,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) return FALSE; } + pixmap_priv->access_mode = access; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, row_length); @@ -468,6 +469,9 @@ glamor_finish_access(DrawablePtr drawable) if (pixmap->devPrivate.ptr == NULL) return; + if (pixmap_priv->access_mode == GLAMOR_ACCESS_RO) + goto read_only; + stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; switch (drawable->depth) { @@ -526,6 +530,7 @@ glamor_finish_access(DrawablePtr drawable) glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); +read_only: if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 93837e0b7..8ded91a5e 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -193,6 +193,7 @@ typedef struct glamor_pixmap_private { GLuint fb; GLuint pbo; enum glamor_pixmap_type type; + glamor_access_t access_mode; } glamor_pixmap_private; extern DevPrivateKey glamor_screen_private_key; From 28835be1b8a05e510aa7fcc2f331771e3cf7dfec Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 24 May 2011 22:01:49 +0800 Subject: [PATCH 122/225] glamor: improve glamor_finish_access. When the platform's coordinate system is the same as X11's . We can load the texture to the fbo directly without one extra texture transformation. --- glamor/glamor_core.c | 148 +++++++++++++++++++++++++++++-------------- 1 file changed, 100 insertions(+), 48 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index f5fc1a3eb..d41b26db7 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -425,56 +425,21 @@ glamor_init_finish_access_shaders(ScreenPtr screen) } } -void -glamor_finish_access(DrawablePtr drawable) +/* Load the pixmap's data to the fbo's texutre directly. + * Only useful when the platform enable yInverted, for + * example MESA/EGL. + * */ +void glamor_load_texture_pixmap_direct(PixmapPtr pixmap) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(drawable->pScreen); - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); unsigned int stride, row_length; GLenum format, type; - static float vertices[4][2] = {{-1, -1}, - { 1, -1}, - { 1, 1}, - {-1, 1}}; - static float texcoords[4][2] = {{0, 1}, - {1, 1}, - {1, 0}, - {0, 0}}; - - GLuint tex; - static float texcoords_inverted[4][2] = {{0, 0}, - {1, 0}, - {1, 1}, - {0, 1}}; - static float *ptexcoords; - - if (pixmap_priv == NULL) - return; - if (glamor_priv->yInverted) - ptexcoords = &texcoords_inverted[0][0]; - else - ptexcoords = &texcoords[0][0]; - - if (pixmap_priv->fb == 0) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (pixmap != screen_pixmap) - return; - } - - /* Check if finish_access was already called once on this */ - if (pixmap->devPrivate.ptr == NULL) - return; - - if (pixmap_priv->access_mode == GLAMOR_ACCESS_RO) - goto read_only; stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - switch (drawable->depth) { + switch (pixmap->drawable.depth) { case 1: format = GL_COLOR_INDEX; type = GL_BITMAP; @@ -485,23 +450,80 @@ glamor_finish_access(DrawablePtr drawable) type = GL_UNSIGNED_BYTE; break; case 24: - assert(drawable->bitsPerPixel == 32); + assert(pixmap->drawable.bitsPerPixel == 32); /* FALLTHROUGH */ case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; break; default: - ErrorF("Unknown finishaccess depth %d\n", drawable->depth); + ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth); return; } + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + pixmap->drawable.width, pixmap->drawable.height, 0, + format, type, pixmap->devPrivate.ptr); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +} + + +/* + * Load texture from the pixmap's data pointer and then + * draw the texture to the fbo, and flip the y axis. + * */ +void +glamor_load_texture_pixmap(PixmapPtr pixmap) +{ + + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + unsigned int stride, row_length; + GLenum format, type; + static float vertices[8] = {-1, -1, + 1, -1, + 1, 1, + -1, 1}; + static float texcoords[8] = {0, 1, + 1, 1, + 1, 0, + 0, 0}; + GLuint tex; + + stride = pixmap->devKind; + row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; + switch (pixmap->drawable.depth) { + case 1: + format = GL_COLOR_INDEX; + type = GL_BITMAP; + row_length = stride; + break; + case 8: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + break; + case 24: + assert(pixmap->drawable.bitsPerPixel == 32); + /* FALLTHROUGH */ + case 32: + format = GL_BGRA; + type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth); + return; + } glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); @@ -529,8 +551,39 @@ glamor_finish_access(DrawablePtr drawable) glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); +} + +void +glamor_finish_access(DrawablePtr drawable) +{ + glamor_screen_private *glamor_priv = + glamor_get_screen_private(drawable->pScreen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + unsigned int stride, row_length; + GLenum format, type; + /* Check if finish_access was already called once on this */ + if (pixmap->devPrivate.ptr == NULL) + return; + + if (pixmap_priv == NULL) + return; + + if (pixmap_priv->fb == 0) { + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap != screen_pixmap) + return; + } + + if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { + if (glamor_priv->yInverted) + glamor_load_texture_pixmap_direct(pixmap); + else + glamor_load_texture_pixmap(pixmap); + } -read_only: if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT); @@ -542,7 +595,6 @@ read_only: pixmap->devPrivate.ptr = NULL; } - /** * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the * current fill style. From b8ce483f58112f200dec9853fcd7ff455479990f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 1 Jun 2011 17:54:01 +0800 Subject: [PATCH 123/225] glamor: Don't use glamor_pixmap_type currently. Added comments to glamor_pixmap_create. To be refined in the future. We need to identify whether a pixmap is a CPU memory pixmap or a GPU pixmap. Current implementation is not correct. There are three cases: 1. Too large pixmap, we direct it to CPU memory pixmap. 2. w ==0 || h == 0 pixmap, this case has two possibilities: 2.1 It will become a screen pixmap latter, then it should be GPU type. 2.2 It's a scratch pixmap or created from a share memory, then it should belong to CPU memory. XXX, need to be refined latter. --- glamor/glamor.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 4594f145c..42e398646 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -67,6 +67,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) glamor_pixmap_private *pixmap_priv; pixmap_priv = glamor_get_pixmap_private(pixmap); + assert(pixmap_priv); pixmap_priv->tex = tex; /* Create a framebuffer object wrapping the texture so that we can render @@ -87,6 +88,12 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) } +/* XXX For the screen pixmap, the w and h maybe 0,0 too, but it should + * be GLAMOR_GL pixmap. Now, all the pixmap will have a valid pixmap_priv. + * This is not good enough. After we can identify which is the screen + * pixmap and which is not, then we can split the pixmap to exclusive + * two types GLAMOR_GL and GLAMOR_FB, and for those GLAMOR_FB pixmaps, + * we don't need to allocate pixmap_priv. */ static PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, @@ -96,7 +103,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, GLenum format; GLuint tex; glamor_pixmap_private *pixmap_priv; - int type = GLAMOR_GL; + enum glamor_pixmap_type type = GLAMOR_GL; if (w > 32767 || h > 32767) return NullPixmap; @@ -111,7 +118,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, 7) / 8) + 3) & ~3, NULL); ErrorF("fallback to software fb for pixmap %p , %d x %d \n", pixmap, w, h); - } else + } else pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { @@ -120,12 +127,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, return NullPixmap; } - if (w == 0 || h == 0 || type != GLAMOR_GL) + if (w == 0 || h == 0 || type == GLAMOR_FB) return pixmap; - pixmap_priv = glamor_get_pixmap_private(pixmap); - pixmap_priv->type = type; - /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA. * FBOs, which EXT_fbo forgot to do. */ From 925fc9724ff72d9e2a4940d7a1e39c23fb3ec9f0 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 1 Jun 2011 18:02:03 +0800 Subject: [PATCH 124/225] glamor: Optimize glamor_finish_access. use pbo if possible when we load texture to a temporary tex. And for the previous direct texture load function, it's not correct and get removed in this commit. Signed-off-by: Zhigang Gong --- glamor/glamor_core.c | 103 +++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 67 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index d41b26db7..f9e43c50c 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -295,7 +295,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); - if (pixmap_priv == NULL) + if (!pixmap_priv) return TRUE; if (pixmap_priv->fb == 0) { @@ -425,53 +425,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen) } } -/* Load the pixmap's data to the fbo's texutre directly. - * Only useful when the platform enable yInverted, for - * example MESA/EGL. - * */ -void glamor_load_texture_pixmap_direct(PixmapPtr pixmap) -{ - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - unsigned int stride, row_length; - GLenum format, type; - - stride = pixmap->devKind; - row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - switch (pixmap->drawable.depth) { - case 1: - format = GL_COLOR_INDEX; - type = GL_BITMAP; - row_length = stride; - break; - case 8: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - break; - case 24: - assert(pixmap->drawable.bitsPerPixel == 32); - /* FALLTHROUGH */ - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth); - return; - } - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - pixmap->drawable.width, pixmap->drawable.height, 0, - format, type, pixmap->devPrivate.ptr); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -} - - /* * Load texture from the pixmap's data pointer and then * draw the texture to the fbo, and flip the y axis. @@ -493,8 +446,18 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) 1, 1, 1, 0, 0, 0}; + static float texcoords_inverted[8] = {0, 0, + 1, 0, + 1, 1, + 0, 1}; + float *ptexcoords; + + void * texel; GLuint tex; + if (glamor_priv->yInverted) + ptexcoords = texcoords_inverted; + stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; switch (pixmap->drawable.depth) { @@ -523,7 +486,7 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); @@ -535,9 +498,18 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); + + if (glamor_priv->yInverted || GLEW_MESA_pack_invert) { + texel = NULL; + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); + } + else + texel = pixmap->devPrivate.ptr; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, pixmap->drawable.height, 0, - format, type, pixmap->devPrivate.ptr); + format, type, texel); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); @@ -560,13 +532,11 @@ glamor_finish_access(DrawablePtr drawable) glamor_get_screen_private(drawable->pScreen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride, row_length; - GLenum format, type; /* Check if finish_access was already called once on this */ if (pixmap->devPrivate.ptr == NULL) return; - if (pixmap_priv == NULL) + if (!pixmap_priv) return; if (pixmap_priv->fb == 0) { @@ -577,21 +547,20 @@ glamor_finish_access(DrawablePtr drawable) return; } - if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { - if (glamor_priv->yInverted) - glamor_load_texture_pixmap_direct(pixmap); - else - glamor_load_texture_pixmap(pixmap); - } - if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT); - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); - glDeleteBuffersARB (1, &pixmap_priv->pbo); - pixmap_priv->pbo = 0; - } else - free(pixmap->devPrivate.ptr); + if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { + glamor_load_texture_pixmap(pixmap); + } + + if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT); + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); + glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glDeleteBuffersARB (1, &pixmap_priv->pbo); + pixmap_priv->pbo = 0; + } else + free(pixmap->devPrivate.ptr); pixmap->devPrivate.ptr = NULL; } From 0e2af4d0c942405dd0869f1e6a1effee943de139 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 1 Jun 2011 18:14:01 +0800 Subject: [PATCH 125/225] glamor: Don't print those fallback messages by default. Signed-off-by: Zhigang Gong --- glamor/glamor_priv.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 8ded91a5e..d88626f51 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -231,8 +231,8 @@ glamor_fallback(char *format, ...) va_list ap; va_start(ap, format); - LogMessageVerb(X_INFO, 0, "fallback: "); - LogVMessageVerb(X_NONE, 0, format, ap); + LogMessageVerb(X_INFO, 3, "fallback: "); + LogMessageVerb(X_NONE, 3, format, ap); va_end(ap); } @@ -265,8 +265,8 @@ glamor_report_delayed_fallbacks(ScreenPtr screen) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (glamor_priv->delayed_fallback_string) { - // LogMessageVerb(X_INFO, 0, "fallback: %s", - // glamor_priv->delayed_fallback_string); + LogMessageVerb(X_INFO, 3, "fallback: %s", + glamor_priv->delayed_fallback_string); glamor_clear_delayed_fallbacks(screen); } } From 3c44e3e0ce1e286e0540298d5db547c43903629f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 1 Jun 2011 19:35:15 +0800 Subject: [PATCH 126/225] glamor: Optimize composite when soure/mask is xrgb. Added a new shader aswizlle_prog to wired the alpha to 1 when the image color depth is 24 (xrgb). Then we don't need to fallback the xrgb source/mask to software composite in render phase. Also don't wire the alpha bit to 1 in the render phase. This can get about 2x performance gain with the cairo performance trace's firefox-planet case. Signed-off-by: Zhigang Gong --- glamor/glamor_core.c | 41 ++++++++++++++++++++++++++++++++++------ glamor/glamor_priv.h | 1 + glamor/glamor_putimage.c | 9 ++++++--- glamor/glamor_render.c | 24 ++++------------------- 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index f9e43c50c..0bfa7600a 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -289,7 +289,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride, row_length, x, y; + unsigned int stride, row_length, y; GLenum format, type; uint8_t *data, *read; glamor_screen_private *glamor_priv = @@ -399,20 +399,38 @@ glamor_init_finish_access_shaders(ScreenPtr screen) "{\n" " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" "}\n"; - GLint fs_prog, vs_prog; + + const char *aswizzle_source = + "varying vec2 texcoords;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n" + "}\n"; + + GLint fs_prog, vs_prog, avs_prog, aswizzle_prog; glamor_priv->finish_access_prog = glCreateProgramObjectARB(); + glamor_priv->aswizzle_prog = glCreateProgramObjectARB(); + if (GLEW_ARB_fragment_shader) { vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source); glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog); + + avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); + aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source); + glAttachObjectARB(glamor_priv->aswizzle_prog, avs_prog); + glAttachObjectARB(glamor_priv->aswizzle_prog, aswizzle_prog); } else { vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); + ErrorF("Lack of framgment shader support.\n"); } glamor_link_glsl_prog(glamor_priv->finish_access_prog); + glamor_link_glsl_prog(glamor_priv->aswizzle_prog); if (GLEW_ARB_fragment_shader) { GLint sampler_uniform_location; @@ -422,6 +440,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glUseProgramObjectARB(glamor_priv->finish_access_prog); glUniform1iARB(sampler_uniform_location, 0); glUseProgramObjectARB(0); + + sampler_uniform_location = + glGetUniformLocationARB(glamor_priv->aswizzle_prog, "sampler"); + glUseProgramObjectARB(glamor_priv->aswizzle_prog); + glUniform1iARB(sampler_uniform_location, 0); + glUseProgramObjectARB(0); } } @@ -429,7 +453,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) * Load texture from the pixmap's data pointer and then * draw the texture to the fbo, and flip the y axis. * */ -void +static void glamor_load_texture_pixmap(PixmapPtr pixmap) { @@ -454,9 +478,12 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) void * texel; GLuint tex; + int alfa_mode = 0; if (glamor_priv->yInverted) ptexcoords = texcoords_inverted; + else + ptexcoords = texcoords; stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; @@ -473,6 +500,7 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) case 24: assert(pixmap->drawable.bitsPerPixel == 32); /* FALLTHROUGH */ + alfa_mode = 1; case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -515,7 +543,10 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) glEnable(GL_TEXTURE_2D); assert(GLEW_ARB_fragment_shader); - glUseProgramObjectARB(glamor_priv->finish_access_prog); + if (alfa_mode == 0) + glUseProgramObjectARB(glamor_priv->finish_access_prog); + else + glUseProgramObjectARB(glamor_priv->aswizzle_prog); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisable(GL_TEXTURE_2D); @@ -547,14 +578,12 @@ glamor_finish_access(DrawablePtr drawable) return; } - if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { glamor_load_texture_pixmap(pixmap); } if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT); glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0); glDeleteBuffersARB (1, &pixmap_priv->pbo); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index d88626f51..8c9ff857c 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -159,6 +159,7 @@ typedef struct glamor_screen_private { /* glamor_finishaccess */ GLint finish_access_prog; + GLint aswizzle_prog; /* glamor_solid */ GLint solid_prog; diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 6a9c1aa60..f1081b055 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -256,7 +256,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int x_off, y_off; float vertices[4][2], texcoords[4][2]; GLuint tex; - + int alfa_mode = 0; if (image_format == XYBitmap) { assert(depth == 1); glamor_put_image_xybitmap(drawable, gc, x, y, w, h, @@ -299,6 +299,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, case 24: assert(drawable->bitsPerPixel == 32); /* FALLTHROUGH */ + alfa_mode = 1; case 32: format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -340,8 +341,10 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glEnable(GL_TEXTURE_2D); assert(GLEW_ARB_fragment_shader); - glUseProgramObjectARB(glamor_priv->finish_access_prog); - + if (alfa_mode == 0) + glUseProgramObjectARB(glamor_priv->finish_access_prog); + else + glUseProgramObjectARB(glamor_priv->aswizzle_prog); x += drawable->x; y += drawable->y; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6139b0d02..e69d370d9 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -86,8 +86,7 @@ glamor_create_composite_fs(struct shader_key *key) "uniform sampler2D source_sampler;\n" "vec4 get_source()\n" "{\n" - " return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb,\n" - " 1.0);\n" + " return texture2D(source_sampler, gl_TexCoord[0].xy);\n" "}\n"; const char *mask_solid_fetch = "uniform vec4 mask;\n" @@ -105,8 +104,7 @@ glamor_create_composite_fs(struct shader_key *key) "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n" - " return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, \n" - " 1.0);\n" + " return texture2D(mask_sampler, gl_TexCoord[1].xy);\n" "}\n"; const char *in_source_only = "void main()\n" @@ -495,15 +493,8 @@ good_source_format(PicturePtr picture) case PICT_a1: case PICT_a8: case PICT_a8r8g8b8: - return TRUE; case PICT_x8r8g8b8: - /* In order to support formats with no alpha, we have to wire the - * alpha to 1 in the shader, which conflicts with - * GL_CLAMP_TO_BORDERing to transparent. We could possibly compute - * coverage of the texels in the sampling area if we need to, but - * that isn't implemented today. - */ - return (picture->repeatType != RepeatNone); + return TRUE; default: glamor_fallback("Bad source format 0x%08x\n", picture->format); return FALSE; @@ -517,15 +508,8 @@ good_mask_format(PicturePtr picture) case PICT_a1: case PICT_a8: case PICT_a8r8g8b8: - return TRUE; case PICT_x8r8g8b8: - /* In order to support formats with no alpha, we have to wire the - * alpha to 1 in the shader, which conflicts with - * GL_CLAMP_TO_BORDERing to transparent. We could possibly compute - * coverage of the texels in the sampling area if we need to, but - * that isn't implemented today. - */ - return (picture->repeatType != RepeatNone); + return TRUE; default: glamor_fallback("Bad mask format 0x%08x\n", picture->format); return FALSE; From ac0589c91699433bc9dbc25b7edff456dff742a4 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 10 Jun 2011 14:02:19 +0800 Subject: [PATCH 127/225] glamor: Use software fb for 1bpp pixmap. For 1bpp pixmap, software fb get better performance than GL surface. The main reason is that fbo doesn't support 1bpp texture as internal format, so we have to translate a 1bpp bitmap to a 8bit alpha format each time which is very inefficient. And the previous implementation is not supported by the latest OpenGL 4.0, the GL_BITMAP was deprecated. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 5 +++-- glamor/glamor_core.c | 13 ++----------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 42e398646..be5999a0c 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -108,7 +108,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, if (w > 32767 || h > 32767) return NullPixmap; - if (w > MAX_WIDTH || h > MAX_HEIGHT) { + if (w > MAX_WIDTH || h > MAX_HEIGHT || ( depth == 1 && w != 0 && h != 0)) { /* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo. If we exceed such limitation, we have to use framebuffer.*/ type = GLAMOR_FB; @@ -117,7 +117,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3, NULL); - ErrorF("fallback to software fb for pixmap %p , %d x %d \n", pixmap, w, h); + + glamor_fallback("fallback to software fb for pixmap %p , %d x %d depth %d\n", pixmap, w, h, depth); } else pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 0bfa7600a..14031d276 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -309,13 +309,8 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - + assert(drawable->depth != 1); switch (drawable->depth) { - case 1: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - row_length = stride; - break; case 8: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; @@ -485,14 +480,10 @@ glamor_load_texture_pixmap(PixmapPtr pixmap) else ptexcoords = texcoords; + assert(pixmap->drawable.depth != 1); stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; switch (pixmap->drawable.depth) { - case 1: - format = GL_COLOR_INDEX; - type = GL_BITMAP; - row_length = stride; - break; case 8: format = GL_ALPHA; type = GL_UNSIGNED_BYTE; From 229240e565f976de8e7b82dd606c2e862152b2b5 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 10 Jun 2011 14:07:54 +0800 Subject: [PATCH 128/225] glamor: Add render triangles support. By default, fallback to frame buffer currently. This commit makes us pass the rendercheck's triangles testing. Signed-off-by: Zhigang Gong --- glamor/Makefile.am | 1 + glamor/glamor.c | 3 ++ glamor/glamor_priv.h | 20 ++++++++++--- glamor/glamor_triangles.c | 61 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 glamor/glamor_triangles.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index e823234ae..8f6292020 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -30,6 +30,7 @@ libglamor_la_SOURCES = \ glamor_setspans.c \ glamor_render.c \ glamor_tile.c \ + glamor_triangles.c\ glamor.h libglamor_la_LIBADD = \ glu3/libglu3.la diff --git a/glamor/glamor.c b/glamor/glamor.c index be5999a0c..7eebba39a 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -279,6 +279,8 @@ glamor_init(ScreenPtr screen, unsigned int flags) ps->Trapezoids = glamor_trapezoids; glamor_priv->saved_glyphs = ps->Glyphs; ps->Glyphs = glamor_glyphs; + glamor_priv->saved_triangles = ps->Triangles; + ps->Triangles = glamor_triangles; glamor_init_composite_shaders(screen); #endif glamor_init_solid_shader(screen); @@ -317,6 +319,7 @@ glamor_close_screen(int idx, ScreenPtr screen) ps->Composite = glamor_priv->saved_composite; ps->Trapezoids = glamor_priv->saved_trapezoids; ps->Glyphs = glamor_priv->saved_glyphs; + ps->Triangles = glamor_priv->saved_triangles; } #endif free(glamor_priv); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 8c9ff857c..9f1679269 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -148,6 +148,7 @@ typedef struct glamor_screen_private { ChangeWindowAttributesProcPtr saved_change_window_attributes; CopyWindowProcPtr saved_copy_window; BitmapToRegionProcPtr saved_bitmap_to_region; + TrianglesProcPtr saved_triangles; char *delayed_fallback_string; int yInverted; @@ -232,8 +233,8 @@ glamor_fallback(char *format, ...) va_list ap; va_start(ap, format); - LogMessageVerb(X_INFO, 3, "fallback: "); - LogMessageVerb(X_NONE, 3, format, ap); + //LogMessageVerb(X_INFO, 3, "fallback: "); + //LogMessageVerb(X_NONE, 3, format, ap); va_end(ap); } @@ -266,8 +267,8 @@ glamor_report_delayed_fallbacks(ScreenPtr screen) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (glamor_priv->delayed_fallback_string) { - LogMessageVerb(X_INFO, 3, "fallback: %s", - glamor_priv->delayed_fallback_string); + //LogMessageVerb(X_INFO, 3, "fallback: %s", + // glamor_priv->delayed_fallback_string); glamor_clear_delayed_fallbacks(screen); } } @@ -461,4 +462,15 @@ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int tile_x, int tile_y); void glamor_init_tile_shader(ScreenPtr screen); +/* glamor_triangles */ +void +glamor_triangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntris, + xTriangle *tris); + #endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c new file mode 100644 index 000000000..168d485f0 --- /dev/null +++ b/glamor/glamor_triangles.c @@ -0,0 +1,61 @@ +/* + * 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 + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +void +glamor_triangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntris, + xTriangle *tris) +{ + + if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) { + if (pSrc->pDrawable == NULL || + glamor_prepare_access(pSrc->pDrawable, GLAMOR_ACCESS_RO)) + { + + fbTriangles(op, + pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris); + } + if (pSrc->pDrawable != NULL) + glamor_finish_access(pSrc->pDrawable); + + glamor_finish_access(pDst->pDrawable); + } +} + + From b60e6cb66d3fba43d5403b2b5027537d09ee7c98 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 10 Jun 2011 15:46:23 +0800 Subject: [PATCH 129/225] glamor: Silence compilation warnings. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 1 - glamor/glamor.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 7eebba39a..d6d6d950a 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -102,7 +102,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, PixmapPtr pixmap; GLenum format; GLuint tex; - glamor_pixmap_private *pixmap_priv; enum glamor_pixmap_type type = GLAMOR_GL; if (w > 32767 || h > 32767) diff --git a/glamor/glamor.h b/glamor/glamor.h index 33610a668..c49662e89 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -34,6 +34,7 @@ #include "gcstruct.h" #include "picturestr.h" #include "fb.h" +#include "fbpict.h" #endif /* GLAMOR_H */ From d7f8b888d0961af8d0ec6ad5c920ce758529b620 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 10 Jun 2011 16:01:40 +0800 Subject: [PATCH 130/225] glamor: For non-supported fill style fallback to fbFill. The previous implementation will just skip the rendering which is not good. Signed-off-by: Zhigang Gong --- glamor/glamor_core.c | 8 +++++--- glamor/glamor_fill.c | 45 +++++++++++++++++++++++--------------------- glamor/glamor_priv.h | 6 +++--- glamor/glamor_tile.c | 11 +++++------ 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 14031d276..a517045a5 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -621,15 +621,17 @@ glamor_finish_access_gc(GCPtr gc) glamor_finish_access(&gc->stipple->drawable); } -void +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) { - ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth); - glamor_solid_fail_region(pixmap, x, y, width, height); + glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth); + return FALSE; +// ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth); +// glamor_solid_fail_region(pixmap, x, y, width, height); } GCOps glamor_gc_ops = { diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 8ea70d0cf..2b94934b6 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -42,23 +42,23 @@ glamor_fill(DrawablePtr drawable, { PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); int x_off, y_off; - glamor_get_drawable_deltas(drawable, dst_pixmap, &x_off, &y_off); switch (gc->fillStyle) { case FillSolid: - glamor_solid(dst_pixmap, - x + x_off, - y + y_off, - width, - height, - gc->alu, - gc->planemask, - gc->fgPixel); + if (!glamor_solid(dst_pixmap, + x + x_off, + y + y_off, + width, + height, + gc->alu, + gc->planemask, + gc->fgPixel)) + goto fail; break; case FillStippled: case FillOpaqueStippled: - glamor_stipple(dst_pixmap, + if (!glamor_stipple(dst_pixmap, gc->stipple, x+ x_off, y + y_off, @@ -69,10 +69,12 @@ glamor_fill(DrawablePtr drawable, gc->fgPixel, gc->bgPixel, gc->patOrg.x + x_off, - gc->patOrg.y + y_off); + gc->patOrg.y + y_off)) + goto fail; + return; break; case FillTiled: - glamor_tile(dst_pixmap, + if (!glamor_tile(dst_pixmap, gc->tile.pixmap, x + x_off, y + y_off, @@ -81,12 +83,12 @@ glamor_fill(DrawablePtr drawable, gc->alu, gc->planemask, drawable->x + x - gc->patOrg.x, - drawable->y + y - gc->patOrg.y); + drawable->y + y - gc->patOrg.y)) + goto fail; break; } return; -#if 0 - fail: +fail: glamor_fallback("glamor_fill()"); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_gc(gc)) { @@ -95,7 +97,6 @@ glamor_fill(DrawablePtr drawable, } glamor_finish_access(drawable); } -#endif return; } @@ -140,7 +141,7 @@ glamor_init_solid_shader(ScreenPtr screen) glGetUniformLocationARB(glamor_priv->solid_prog, "color"); } -void +Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, unsigned long fg_pixel) { @@ -154,12 +155,12 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, float vertices[4][2]; if (!glamor_set_destination_pixmap(pixmap)) - return; + goto fail; glamor_set_alu(alu); if (!glamor_set_planemask(pixmap, planemask)) { - ErrorF("Failedto set planemask in glamor_solid.\n"); - goto fail; - } + ErrorF("Failedto set planemask in glamor_solid.\n"); + goto fail; + } glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color); @@ -188,9 +189,11 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glDisableClientState(GL_VERTEX_ARRAY); glUseProgramObjectARB(0); + return TRUE; fail: glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); + return FALSE; } /* Highlight places where we're doing it wrong. */ diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 9f1679269..1dc2c42c5 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -350,7 +350,7 @@ const Bool glamor_get_drawable_location(const DrawablePtr drawable); void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y); Bool glamor_create_gc(GCPtr gc); -void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, +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, @@ -376,7 +376,7 @@ void glamor_fill(DrawablePtr drawable, int y, int width, int height); -void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, +Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, unsigned long fg_pixel); void glamor_solid_fail_region(PixmapPtr pixmap, @@ -456,7 +456,7 @@ void glamor_composite_rects(CARD8 op, int nrect, glamor_composite_rect_t *rects); /* glamor_tile.c */ -void glamor_tile(PixmapPtr pixmap, PixmapPtr tile, +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); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 58923701e..5b1e73d5a 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -72,7 +72,7 @@ glamor_init_tile_shader(ScreenPtr screen) glUseProgramObjectARB(0); } -void +Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, @@ -93,7 +93,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, float source_texcoords[4][2]; if (glamor_priv->tile_prog == 0) { - ErrorF("Tiling unsupported\n"); + glamor_fallback("Tiling unsupported\n"); goto fail; } @@ -101,7 +101,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, goto fail; if (tile_priv->tex == 0) { - ErrorF("Non-texture tile pixmap\n"); + glamor_fallback("Non-texture tile pixmap\n"); goto fail; } @@ -167,9 +167,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glDisable(GL_TEXTURE_2D); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); - return; + return TRUE; fail: - glamor_solid_fail_region(pixmap, x, y, width, height); - return; + return FALSE; } From a0a52be73994c93521e94f1f10152ce851485ea3 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 10 Jun 2011 16:51:27 +0800 Subject: [PATCH 131/225] glamor: Fallback to fbPolylines for diagonal poly_line. It's better to give a correct output when we haven't implement all the code path. Signed-off-by: Zhigang Gong --- glamor/glamor_polylines.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index c9752685f..75bc9bf9a 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -76,17 +76,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, x2 = points[i + 1].x; y2 = points[i + 1].y; } - if (x1 != x2 && y1 != y2) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - free(rects); - - ErrorF("stub diagonal poly_line\n"); - glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1); + glamor_fallback("stub diagonal poly_line\n"); + goto fail; return; } - if (x1 < x2) { rects[i].x = x1; rects[i].width = x2 - x1 + 1; From ba6dd8aa492d9d555d8b175bcf350e5db1821597 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 10 Jun 2011 18:32:15 +0800 Subject: [PATCH 132/225] glamor: Simplify fill acceleration for spans/polyfillrect by only clipping once. This commit was borrowed from uxa driver contributed by Eric. commit number is e0066e77e026b0dd0daa0c3765473c7d63aa6753. commit log paste as below: We were clipping each span against the bounds of the clip, throwing out the span early if it was all clipped, and then walked the clip box clipping against each of the cliprects. We would expect spans to typically be clipped against one box, and not thrown out, so we were not saving any work there. For multiple cliprects, we were adding work. Only for many spans clipped entirely out of a complicated clip region would it have saved work, and it clearly didn't save bugs as evidenced by the many fix attempts here. Signed-off-by: Zhigang Gong --- glamor/glamor_fillspans.c | 84 +++++++++++------------------ glamor/glamor_polyfillrect.c | 102 ++++++++++++++--------------------- 2 files changed, 73 insertions(+), 113 deletions(-) diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index a633b3066..c6976c376 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -38,68 +38,48 @@ glamor_fill_spans(DrawablePtr drawable, int *widths, int sorted) { - RegionPtr clip = gc->pCompositeClip; - BoxPtr extents, boxes; + DDXPointPtr ppt; int nbox; - int extentX1, extentX2, extentY1, extentY2; - int fullX1, fullX2, fullY1; - int partX1, partX2; + BoxPtr pbox; + int x1, x2, y; + int off_x, off_y; + RegionPtr pClip = fbGetCompositeClip(gc); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) goto fail; - extents = REGION_EXTENTS(gc->pScreen, clip); - extentX1 = extents->x1; - extentY1 = extents->y1; - extentX2 = extents->x2; - extentY2 = extents->y2; - while (n--) { - fullX1 = points->x; - fullY1 = points->y; - fullX2 = fullX1 + *widths; - points++; - widths++; - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + ppt = points; + while (n--) { + x1 = ppt->x; + y = ppt->y; + x2 = x1 + (int)*widths; + ppt++; + widths++; - if (fullX1 < extentX1) - fullX1 = extentX1; + nbox = REGION_NUM_RECTS(pClip); + pbox = REGION_RECTS(pClip); + while (nbox--) { + if (pbox->y1 > y || pbox->y2 <= y) + continue; - if (fullX2 > extentX2) - fullX2 = extentX2; + if (x1 < pbox->x1) + x1 = pbox->x1; - if (fullX1 >= fullX2) - continue; + if (x2 > pbox->x2) + x2 = pbox->x2; - nbox = REGION_NUM_RECTS (clip); - if (nbox == 1) { - glamor_fill(drawable, - gc, - fullX1, fullY1, fullX2-fullX1, 1); - } else { - boxes = REGION_RECTS(clip); - while(nbox--) - { - if (boxes->y1 <= fullY1 && fullY1 < boxes->y2) - { - partX1 = boxes->x1; - if (partX1 < fullX1) - partX1 = fullX1; - partX2 = boxes->x2; - if (partX2 > fullX2) - partX2 = fullX2; - if (partX2 > partX1) - { - glamor_fill(drawable, gc, - partX1, fullY1, - partX2 - partX1, 1); - } - } - boxes++; - } - } - } + if (x2 <= x1) + continue; + glamor_fill (drawable,gc, + x1 + off_x, y + off_y, + x2 - x1 , 1); + pbox++; + } + } return; fail: glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable, diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index 29e9db537..660dc4a5b 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -43,80 +43,60 @@ glamor_poly_fill_rect(DrawablePtr drawable, int nrect, xRectangle *prect) { - RegionPtr clip = fbGetCompositeClip(gc); - register BoxPtr box; - BoxPtr pextent; - int extentX1, extentX2, extentY1, extentY2; int fullX1, fullX2, fullY1, fullY2; - int partX1, partX2, partY1, partY2; int xorg, yorg; int n; + register BoxPtr pbox; + int off_x, off_y; + RegionPtr pClip = fbGetCompositeClip(gc); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) goto fail; xorg = drawable->x; yorg = drawable->y; + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); - pextent = REGION_EXTENTS(gc->pScreen, clip); - extentX1 = pextent->x1; - extentY1 = pextent->y1; - extentX2 = pextent->x2; - extentY2 = pextent->y2; - while (nrect--) - { - fullX1 = prect->x + xorg; - fullY1 = prect->y + yorg; - fullX2 = fullX1 + (int)prect->width; - fullY2 = fullY1 + (int)prect->height; - prect++; + while (nrect--) { + fullX1 = prect->x + xorg; + fullY1 = prect->y + yorg; + fullX2 = fullX1 + (int)prect->width; + fullY2 = fullY1 + (int)prect->height; + prect++; - if (fullX1 < extentX1) - fullX1 = extentX1; + n = REGION_NUM_RECTS(pClip); + pbox = REGION_RECTS(pClip); + /* + * clip the rectangle to each box in the clip region + * this is logically equivalent to calling Intersect(), + * but rectangles may overlap each other here. + */ + while (n--) { + int x1 = fullX1; + int x2 = fullX2; + int y1 = fullY1; + int y2 = fullY2; - if (fullY1 < extentY1) - fullY1 = extentY1; + if (pbox->x1 > x1) + x1 = pbox->x1; + if (pbox->x2 < x2) + x2 = pbox->x2; + if (pbox->y1 > y1) + y1 = pbox->y1; + if (pbox->y2 < y2) + y2 = pbox->y2; + pbox++; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullY2 > extentY2) - fullY2 = extentY2; - - if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) - continue; - n = REGION_NUM_RECTS(clip); - if (n == 1) { - glamor_fill(drawable, - gc, - fullX1, fullY1, fullX2-fullX1, fullY2-fullY1); - } else { - box = REGION_RECTS(clip); - /* clip the rectangle to each box in the clip region - * this is logically equivalent to calling Intersect() - */ - while (n--) { - partX1 = box->x1; - if (partX1 < fullX1) - partX1 = fullX1; - partY1 = box->y1; - if (partY1 < fullY1) - partY1 = fullY1; - partX2 = box->x2; - if (partX2 > fullX2) - partX2 = fullX2; - partY2 = box->y2; - if (partY2 > fullY2) - partY2 = fullY2; - - box++; - - if (partX1 < partX2 && partY1 < partY2) - glamor_fill(drawable, gc, - partX1, partY1, - partX2 - partX1, partY2 - partY1); - } - } + if (x1 >= x2 || y1 >= y2) + continue; + glamor_fill(drawable, + gc, + x1 + off_x, + y1 + off_y, + x2 - x1, + y2 - y1); + } } return; From 355334fcd99e4dce62e2be1e27290c9a74ea944f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 21 Jun 2011 18:31:11 +0800 Subject: [PATCH 133/225] glamor : Add dynamic texture uploading feature. Major refactoring. 1. Rewrite the pixmap texture uploading and downloading functions. Add some new functions for both the prepare/finish access and the new performance feature dynamic texture uploading, which could download and upload the current image to/from a private texture/fbo. In the uploading or downloading phase, we need to handle two things: The first is the yInverted option, If it set, then we don't need to flip y. If not set, if it is from a dynamic texture uploading then we don't need to flip either if the current drawing process will flip it latter. If it is from finish_access, then we must flip the y axis. The second thing is the alpha channel hanlding, if the pixmap's format is something like x8a8r8g8, x1r5g5b5 which means it doesn't has alpha channel, but it do has those extra bits. Then we need to wire those bits to 1. 2. Add almost all the required picture format support. This is not as trivial as it looks like. The previous implementation only support GL_a8,GL_a8r8g8b8,GL_x8r8g8b8. All the other format, we have to fallback to cpu. The reason why we can't simply add those other color format is because the exists of picture. one drawable pixmap may has one or even more container pictures. The drawable pixmap's depth can't map to a specified color format, for example depth 16 can mapped to r5g6b5, x1r5g5b5, a1r5g5b5, or even b5g6r5. So we can't get get the color format just from the depth value. But the pixmap do not has a pict_format element. We have to make a new one in the pixmap private data structure. Reroute the CreatePicture to glamor_create_picture and then store the picture's format to the pixmap's private structure. This is not an ideal solution, as there may be more than one pictures refer to the same pixmap. Then we will have trouble. There is an example in glamor_composite_with_shader. The source and mask often share the same pixmap, but use different picture format. Our current solution is to combine those two different picture formats to one which will not lose any data. Then change the source's format to this new format and then upload the pixmap to texture once. It works. If we fail to find a matched new format then we fallback. There still is a potential problem, if two pictures refer to the same pixmap, and one of them destroy the picture, but the other still remained to be used latter. We don't handle that situation currently. To be fixed. 3. Dynamic texture uploading. This is a performance feature. Although we don't like the client to hold a pixmap data to shared memory and we can't accelerate it. And even worse, we may need to fallback all the required pixmaps to cpu memory and then process them on CPU. This feature is to mitigate this penalty. When the target pixmap has a valid gl fbo attached to it. But the other pixmaps are not. Then it will be more efficient to upload the other pixmaps to GPU and then do the blitting or rendering on GPU than fallback all the pixmaps to CPU. To enable this feature, I experienced a significant performance improvement in the Game "Mines" :). 4. Debug facility. Modify the debug output mechanism. Now add a new macro: glamor_debug_output(_level_, _format_,...) to conditional output some messages according to the environment variable GLAMOR_DEBUG. We have the following levels currently. exports GLAMOR_DEBUG to 3 will enable all the above messages. 5. Changes in pixmap private data structure. Add some for the full color format supports and relate it to the pictures which already described. Also Add the following new elements: gl_fbo - to indicates whether this pixmap is on gpu only. gl_tex - to indicates whether the tex is valid and is containing the pixmap's image originally. As we bring the dynamic pixmap uploading feature, so a cpu memory pixmap may also has a valid fbo or tex attached to it. So we will have to use the above new element to check it true type. After this commit, we can pass the rendercheck testing for all the picture formats. And is much much fater than fallback to cpu when doing rendercheck testing. Signed-off-by: Zhigang Gong --- glamor/Makefile.am | 2 + glamor/glamor.c | 117 +- glamor/glamor.h | 7 +- glamor/glamor_copyarea.c | 98 +- glamor/glamor_core.c | 866 +++++--------- glamor/glamor_debug.h | 67 ++ glamor/glamor_fill.c | 33 +- glamor/glamor_fillspans.c | 5 +- glamor/glamor_getspans.c | 65 +- glamor/glamor_glyphs.c | 2 + glamor/glamor_picture.c | 93 ++ glamor/glamor_pixmap.c | 483 ++++++++ glamor/glamor_polyfillrect.c | 7 +- glamor/glamor_polylines.c | 7 +- glamor/glamor_priv.h | 660 ++++++++--- glamor/glamor_putimage.c | 79 +- glamor/glamor_render.c | 1972 +++++++++++++++++--------------- glamor/glamor_setspans.c | 60 +- glamor/glamor_tile.c | 12 +- hw/kdrive/ephyr/ephyr_glamor.c | 2 +- hw/xfree86/glamor/glamor.c | 3 +- 21 files changed, 2676 insertions(+), 1964 deletions(-) create mode 100644 glamor/glamor_debug.h create mode 100644 glamor/glamor_picture.c create mode 100644 glamor/glamor_pixmap.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 8f6292020..53877dcbe 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -31,6 +31,8 @@ libglamor_la_SOURCES = \ glamor_render.c \ glamor_tile.c \ glamor_triangles.c\ + glamor_pixmap.c\ + glamor_picture.c\ glamor.h libglamor_la_LIBADD = \ glu3/libglu3.la diff --git a/glamor/glamor.c b/glamor/glamor.c index d6d6d950a..c10ff4021 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -59,8 +59,7 @@ glamor_get_drawable_pixmap(DrawablePtr drawable) return (PixmapPtr)drawable; } - -void +static void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) { ScreenPtr screen = pixmap->drawable.pScreen; @@ -73,6 +72,8 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) /* Create a framebuffer object wrapping the texture so that we can render * to it. */ + pixmap_priv->gl_fbo = 1; + pixmap_priv->gl_tex = 1; glGenFramebuffersEXT(1, &pixmap_priv->fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, @@ -87,13 +88,24 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) NULL); } +/* Set screen pixmap. If tex equal to 0, means it is called from ephyr. */ +void +glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex) +{ + PixmapPtr pixmap = screen->GetScreenPixmap(screen); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + glamor_set_pixmap_texture(pixmap, w, h, tex); + glamor_priv->screen_fbo = pixmap_priv->fb; +} + + + +#define GLAMOR_PIXMAP_MEMORY 0 +#define GLAMOR_PIXMAP_TEXTURE 1 + -/* XXX For the screen pixmap, the w and h maybe 0,0 too, but it should - * be GLAMOR_GL pixmap. Now, all the pixmap will have a valid pixmap_priv. - * This is not good enough. After we can identify which is the screen - * pixmap and which is not, then we can split the pixmap to exclusive - * two types GLAMOR_GL and GLAMOR_FB, and for those GLAMOR_FB pixmaps, - * we don't need to allocate pixmap_priv. */ static PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, @@ -102,22 +114,24 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, PixmapPtr pixmap; GLenum format; GLuint tex; - enum glamor_pixmap_type type = GLAMOR_GL; + int type = GLAMOR_PIXMAP_TEXTURE; + glamor_pixmap_private *pixmap_priv; if (w > 32767 || h > 32767) return NullPixmap; - if (w > MAX_WIDTH || h > MAX_HEIGHT || ( depth == 1 && w != 0 && h != 0)) { + if (!glamor_check_fbo_width_height(w,h) || !glamor_check_fbo_depth(depth)) { /* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo. If we exceed such limitation, we have to use framebuffer.*/ - type = GLAMOR_FB; + type = GLAMOR_PIXMAP_MEMORY; pixmap = fbCreatePixmap (screen, w, h, depth, usage); screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3, NULL); - glamor_fallback("fallback to software fb for pixmap %p , %d x %d depth %d\n", pixmap, w, h, depth); + glamor_fallback("choose cpu memory for pixmap %p ," + " %d x %d depth %d\n", pixmap, w, h, depth); } else pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); @@ -127,7 +141,10 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, return NullPixmap; } - if (w == 0 || h == 0 || type == GLAMOR_FB) + pixmap_priv = glamor_get_pixmap_private(pixmap); + pixmap_priv->container = pixmap; + + if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY) return pixmap; /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA. @@ -136,7 +153,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, switch (depth) { case 24: format = GL_RGB; - break; + break; default: format = GL_RGBA; break; @@ -154,13 +171,51 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, return pixmap; } + +/** + * For Xephyr use only. set up the screen pixmap to correct state. + **/ +static PixmapPtr +glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth, + unsigned int usage) +{ + PixmapPtr pixmap; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + assert(w ==0 && h == 0); + + glamor_priv->screen_fbo = 0; + pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); + + if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { + fbDestroyPixmap(pixmap); + ErrorF("Fail to allocate privates for PIXMAP.\n"); + return NullPixmap; + } + + pixmap_priv = glamor_get_pixmap_private(pixmap); + pixmap_priv->tex = 0; + pixmap_priv->gl_fbo = 1; + pixmap_priv->gl_tex = 1; + + screen->CreatePixmap = glamor_create_pixmap; + return pixmap; +} + + + + static Bool glamor_destroy_pixmap(PixmapPtr pixmap) { if (pixmap->refcnt == 1) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - glDeleteFramebuffersEXT(1, &pixmap_priv->fb); - glDeleteTextures(1, &pixmap_priv->tex); + if (pixmap_priv->fb) + glDeleteFramebuffersEXT(1, &pixmap_priv->fb); + if (pixmap_priv->tex) + glDeleteTextures(1, &pixmap_priv->tex); + if (pixmap_priv->pbo) + glDeleteBuffersARB(1, &pixmap_priv->pbo); } return fbDestroyPixmap(pixmap); @@ -177,6 +232,18 @@ glamor_wakeup_handler(void *data, int result, void *last_select_mask) { } +static void +glamor_set_debug_level(int *debug_level) +{ + char *debug_level_string; + debug_level_string = getenv("GLAMOR_DEBUG"); + if (debug_level_string && sscanf(debug_level_string, "%d", debug_level) == 1) + return; + *debug_level = 0; +} + +int glamor_debug_level; + /** Set up glamor for an already-configured GL context. */ Bool glamor_init(ScreenPtr screen, unsigned int flags) @@ -186,7 +253,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif - if (flags & ~GLAMOR_VALID_FLAGS) { ErrorF("glamor_init: Invalid flags %x\n", flags); return FALSE; @@ -205,7 +271,9 @@ glamor_init(ScreenPtr screen, unsigned int flags) LogMessage(X_WARNING, "glamor%d: Failed to allocate screen private\n", screen->myNum); + return FALSE; } + dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); if (!dixRegisterPrivateKey(glamor_pixmap_private_key,PRIVATE_PIXMAP, @@ -213,6 +281,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) LogMessage(X_WARNING, "glamor%d: Failed to allocate pixmap private\n", screen->myNum); + return FALSE; } glewInit(); @@ -243,7 +312,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) goto fail; } - + glamor_set_debug_level(&glamor_debug_level); glamor_priv->saved_close_screen = screen->CloseScreen; screen->CloseScreen = glamor_close_screen; @@ -251,7 +320,11 @@ glamor_init(ScreenPtr screen, unsigned int flags) screen->CreateGC = glamor_create_gc; glamor_priv->saved_create_pixmap = screen->CreatePixmap; - screen->CreatePixmap = glamor_create_pixmap; + + if (flags & GLAMOR_HOSTX) + screen->CreatePixmap = glamor_create_screen_pixmap; + else + screen->CreatePixmap = glamor_create_pixmap; glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_destroy_pixmap; @@ -281,6 +354,10 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->saved_triangles = ps->Triangles; ps->Triangles = glamor_triangles; glamor_init_composite_shaders(screen); + glamor_priv->saved_create_picture = ps->CreatePicture; + ps->CreatePicture = glamor_create_picture; + glamor_priv->saved_destroy_picture = ps->DestroyPicture; + ps->DestroyPicture = glamor_destroy_picture; #endif glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); @@ -288,7 +365,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_init_finish_access_shaders(screen); glamor_glyphs_init(screen); - return TRUE; fail: @@ -319,6 +395,7 @@ glamor_close_screen(int idx, ScreenPtr screen) ps->Trapezoids = glamor_priv->saved_trapezoids; ps->Glyphs = glamor_priv->saved_glyphs; ps->Triangles = glamor_priv->saved_triangles; + ps->CreatePicture = glamor_priv->saved_create_picture; } #endif free(glamor_priv); diff --git a/glamor/glamor.h b/glamor/glamor.h index c49662e89..2c1b241ba 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -39,9 +39,10 @@ #endif /* GLAMOR_H */ -#define GLAMOR_INVERTED_Y_AXIS 0x1 -#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS) +#define GLAMOR_INVERTED_Y_AXIS 1 +#define GLAMOR_HOSTX 2 +#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX) Bool glamor_init(ScreenPtr screen, unsigned int flags); void glamor_fini(ScreenPtr screen); -void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex); +void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 07d8b1456..766c9e2b3 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -31,7 +31,6 @@ * * GC CopyArea implementation */ - static Bool glamor_copy_n_to_n_fbo_blit(DrawablePtr src, DrawablePtr dst, @@ -49,45 +48,36 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, int dst_x_off, dst_y_off, src_x_off, src_y_off, i; if (src == dst) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " - "src == dest\n"); + glamor_delayed_fallback(screen,"src == dest\n"); return FALSE; } if (!GLEW_EXT_framebuffer_blit) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " - "no EXT_framebuffer_blit\n"); + glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n"); return FALSE; } src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - if (src_pixmap_priv->fb == 0) { - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (src_pixmap != screen_pixmap) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " - "no src fbo\n"); - return FALSE; - } - } - if (gc) { if (gc->alu != GXcopy) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " - "non-copy ALU\n"); + glamor_delayed_fallback(screen, "non-copy ALU\n"); return FALSE; } if (!glamor_pm_is_solid(dst, gc->planemask)) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): " - "non-solid planemask\n"); + glamor_delayed_fallback(screen, "non-solid planemask\n"); return FALSE; } } - if (!glamor_set_destination_pixmap(dst_pixmap)) - return FALSE; + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { + glamor_delayed_fallback(screen, "no src fbo\n"); + return FALSE; + } + if (glamor_set_destination_pixmap(dst_pixmap)) { + return FALSE; + } glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); @@ -124,7 +114,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, GL_NEAREST); } } - return TRUE; } @@ -142,29 +131,26 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int x_off, y_off, i; - if (src != dst) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " - "src != dest\n"); + glamor_delayed_fallback(screen, "src != dest\n"); return FALSE; } if (gc) { if (gc->alu != GXcopy) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " - "non-copy ALU\n"); + glamor_delayed_fallback(screen,"non-copy ALU\n"); return FALSE; } if (!glamor_pm_is_solid(dst, gc->planemask)) { - glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " - "non-solid planemask\n"); + glamor_delayed_fallback(screen,"non-solid planemask\n"); return FALSE; } } - if (!glamor_set_destination_pixmap(dst_pixmap)) + if (glamor_set_destination_pixmap(dst_pixmap)) { + glamor_delayed_fallback(screen, "dst has no fbo.\n"); return FALSE; - + } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glOrtho(0, dst_pixmap->drawable.width, @@ -196,7 +182,6 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, GL_COLOR); } } - return TRUE; } @@ -216,29 +201,43 @@ glamor_copy_n_to_n_textured(DrawablePtr src, int i; float vertices[4][2], texcoords[4][2]; glamor_pixmap_private *src_pixmap_priv; + glamor_pixmap_private *dst_pixmap_priv; int src_x_off, src_y_off, dst_x_off, dst_y_off; - + enum glamor_pixmap_status src_status = GLAMOR_NONE; src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); + dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); if (src == dst) { - glamor_fallback("glamor_copy_n_to_n with same src/dst\n"); + glamor_delayed_fallback(dst->pScreen, "same src/dst\n"); goto fail; } - if (!src_pixmap_priv || !src_pixmap_priv->tex) { - glamor_fallback("glamor_copy_n_to_n with non-texture src\n"); - goto fail; + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { + glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n"); + goto fail; } - if (!glamor_set_destination_pixmap(dst_pixmap)) + if (!src_pixmap_priv->gl_tex) { +#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD + glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); goto fail; +#else + /* XXX in yInverted mode we have bug here.*/ + if (!glamor_priv->yInverted) goto fail; + src_status = glamor_upload_pixmap_to_texture(src_pixmap); + if (src_status != GLAMOR_UPLOAD_DONE) + goto fail; +#endif + } if (gc) { glamor_set_alu(gc->alu); if (!glamor_set_planemask(dst_pixmap, gc->planemask)) - goto fail; + goto fail; } + glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); dx += src_x_off; @@ -258,7 +257,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glEnableClientState(GL_TEXTURE_COORD_ARRAY); assert(GLEW_ARB_fragment_shader); - glUseProgramObjectARB(glamor_priv->finish_access_prog); + glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); for (i = 0; i < nbox; i++) { @@ -324,23 +323,23 @@ glamor_copy_n_to_n(DrawablePtr src, void *closure) { if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { - glamor_clear_delayed_fallbacks(dst->pScreen); + goto done; return; } - if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) { - glamor_clear_delayed_fallbacks(dst->pScreen); + if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)){ + goto done; return; - } + } if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) { - glamor_clear_delayed_fallbacks(dst->pScreen); + goto done; return; } - + glamor_report_delayed_fallbacks(src->pScreen); glamor_report_delayed_fallbacks(dst->pScreen); - glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst, + glamor_fallback("from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { @@ -352,6 +351,11 @@ glamor_copy_n_to_n(DrawablePtr src, } glamor_finish_access(dst); } + return; + +done: + glamor_clear_delayed_fallbacks(src->pScreen); + glamor_clear_delayed_fallbacks(dst->pScreen); } RegionPtr diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index a517045a5..a61b8ae53 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -42,144 +42,27 @@ const Bool glamor_get_drawable_location(const DrawablePtr drawable) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - if (pixmap_priv == NULL) - return 'm'; - if (pixmap_priv->fb == 0) - return 's'; - else - return 'f'; + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(drawable->pScreen); + if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0) + return 'm'; + if (pixmap_priv->fb == glamor_priv->screen_fbo) + return 's'; + else + return 'f'; } -/** - * Sets the offsets to add to coordinates to make them address the same bits in - * the backing drawable. These coordinates are nonzero only for redirected - * windows. - */ -void -glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, - int *x, int *y) -{ -#ifdef COMPOSITE - if (drawable->type == DRAWABLE_WINDOW) { - *x = -pixmap->screen_x; - *y = -pixmap->screen_y; - return; - } -#endif - - *x = 0; - *y = 0; -} - -Bool -glamor_set_destination_pixmap(PixmapPtr pixmap) -{ - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (pixmap_priv == NULL) { - glamor_fallback("glamor_set_destination_pixmap(): no pixmap priv"); - return FALSE; - } - - if (pixmap_priv->fb == 0) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (pixmap != screen_pixmap) { - glamor_fallback("glamor_set_destination_pixmap(): no fbo"); - return FALSE; - } - } - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - - glViewport(0, 0, - pixmap->drawable.width, - pixmap->drawable.height); - - return TRUE; -} - -Bool -glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask) -{ - if (glamor_pm_is_solid(&pixmap->drawable, planemask)) { - return GL_TRUE; - } - - ErrorF("unsupported planemask\n"); - return GL_FALSE; -} - -void -glamor_set_alu(unsigned char alu) -{ - if (alu == GXcopy) { - glDisable(GL_COLOR_LOGIC_OP); - return; - } - glEnable(GL_COLOR_LOGIC_OP); - switch (alu) { - case GXclear: - glLogicOp(GL_CLEAR); - break; - case GXand: - glLogicOp(GL_AND); - break; - case GXandReverse: - glLogicOp(GL_AND_REVERSE); - break; - case GXandInverted: - glLogicOp(GL_AND_INVERTED); - break; - case GXnoop: - glLogicOp(GL_NOOP); - break; - case GXxor: - glLogicOp(GL_XOR); - break; - case GXor: - glLogicOp(GL_OR); - break; - case GXnor: - glLogicOp(GL_NOR); - break; - case GXequiv: - glLogicOp(GL_EQUIV); - break; - case GXinvert: - glLogicOp(GL_INVERT); - break; - case GXorReverse: - glLogicOp(GL_OR_REVERSE); - break; - case GXcopyInverted: - glLogicOp(GL_COPY_INVERTED); - break; - case GXorInverted: - glLogicOp(GL_OR_INVERTED); - break; - case GXnand: - glLogicOp(GL_NAND); - break; - case GXset: - glLogicOp(GL_SET); - break; - default: - FatalError("unknown logic op\n"); - } -} void glamor_get_transform_uniform_locations(GLint prog, glamor_transform_uniforms *uniform_locations) { - uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias"); - uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale"); - uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias"); - uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale"); + uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias"); + uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale"); + uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias"); + uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale"); } /* We don't use a full matrix for our transformations because it's @@ -190,400 +73,163 @@ void glamor_set_transform_for_pixmap(PixmapPtr pixmap, glamor_transform_uniforms *uniform_locations) { - glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); - glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); - glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); - glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); + glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); + glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); + glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); + glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); } GLint glamor_compile_glsl_prog(GLenum type, const char *source) { - GLint ok; - GLint prog; + GLint ok; + GLint prog; - prog = glCreateShaderObjectARB(type); - glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL); - glCompileShaderARB(prog); - glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok); - if (!ok) { - GLchar *info; - GLint size; + prog = glCreateShaderObjectARB(type); + glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL); + glCompileShaderARB(prog); + glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok); + if (!ok) { + GLchar *info; + GLint size; - glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); - info = malloc(size); + glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); + info = malloc(size); - glGetInfoLogARB(prog, size, NULL, info); - ErrorF("Failed to compile %s: %s\n", - type == GL_FRAGMENT_SHADER ? "FS" : "VS", - info); - ErrorF("Program source:\n%s", source); - FatalError("GLSL compile failure\n"); - } + glGetInfoLogARB(prog, size, NULL, info); + ErrorF("Failed to compile %s: %s\n", + type == GL_FRAGMENT_SHADER ? "FS" : "VS", + info); + ErrorF("Program source:\n%s", source); + FatalError("GLSL compile failure\n"); + } - return prog; + return prog; } void glamor_link_glsl_prog(GLint prog) { - GLint ok; + GLint ok; - glLinkProgram(prog); - glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok); - if (!ok) { - GLchar *info; - GLint size; + glLinkProgram(prog); + glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok); + if (!ok) { + GLchar *info; + GLint size; - glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); - info = malloc(size); + glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); + info = malloc(size); - glGetInfoLogARB(prog, size, NULL, info); - ErrorF("Failed to link: %s\n", - info); - FatalError("GLSL link failure\n"); - } + glGetInfoLogARB(prog, size, NULL, info); + ErrorF("Failed to link: %s\n", + info); + FatalError("GLSL link failure\n"); + } } -static float ubyte_to_float(uint8_t b) -{ - return b / 255.0f; -} - -void -glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, - GLfloat *color) -{ - switch (pixmap->drawable.depth) { - case 1: - color[0] = 0.0; - color[1] = 0.0; - color[2] = 0.0; - color[3] = fg_pixel & 0x01; - break; - case 8: - color[0] = 0.0; - color[1] = 0.0; - color[2] = 0.0; - color[3] = (fg_pixel & 0xff) / 255.0; - break; - case 24: - case 32: - color[0] = ubyte_to_float((fg_pixel >> 16) & 0xFF); - color[1] = ubyte_to_float((fg_pixel >> 8) & 0xFF); - color[2] = ubyte_to_float((fg_pixel >> 0) & 0xFF); - color[3] = ubyte_to_float((fg_pixel >> 24) & 0xFF); - break; - default: - ErrorF("pixmap with bad depth: %d\n", pixmap->drawable.depth); - color[0] = 1.0; - color[1] = 0.0; - color[2] = 1.0; - color[3] = 1.0; - break; - } -} Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - unsigned int stride, row_length, y; - GLenum format, type; - uint8_t *data, *read; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(drawable->pScreen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - if (!pixmap_priv) - return TRUE; - - if (pixmap_priv->fb == 0) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (pixmap != screen_pixmap) - return TRUE; - } - - stride = pixmap->devKind; - row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - - assert(drawable->depth != 1); - switch (drawable->depth) { - case 8: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - break; - case 24: - assert(drawable->bitsPerPixel == 32); - /* FALLTHROUGH */ - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - ErrorF("Unknown prepareaccess depth %d\n", drawable->depth); - return FALSE; - } - - pixmap_priv->access_mode = access; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ROW_LENGTH, row_length); - - if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { - - if (!glamor_priv->yInverted) - glPixelStorei(GL_PACK_INVERT_MESA, 1); - - glGenBuffersARB (1, &pixmap_priv->pbo); - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT, - stride * pixmap->drawable.height, - NULL, GL_DYNAMIC_DRAW_ARB); - glReadPixels (0, 0, - row_length, pixmap->drawable.height, - format, type, 0); - - data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB); - - if (!glamor_priv->yInverted) - glPixelStorei(GL_PACK_INVERT_MESA, 0); - - } else { - data = malloc(stride * pixmap->drawable.height); - - glGenBuffersARB(1, &pixmap_priv->pbo); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, - stride * pixmap->drawable.height, - NULL, GL_STREAM_READ_ARB); - glReadPixels (0, 0, row_length, pixmap->drawable.height, - format, type, 0); - read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB); - - for (y = 0; y < pixmap->drawable.height; y++) - memcpy(data + y * stride, - read + (pixmap->drawable.height - y - 1) * stride, stride); - glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); - glDeleteBuffersARB(1, &pixmap_priv->pbo); - pixmap_priv->pbo = 0; - } - - pixmap->devPrivate.ptr = data; - - return TRUE; + return glamor_download_pixmap_to_cpu(pixmap, access); } void glamor_init_finish_access_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - const char *vs_source = - "void main()\n" - "{\n" - " gl_Position = gl_Vertex;\n" - " gl_TexCoord[0] = gl_MultiTexCoord0;\n" - "}\n"; - const char *fs_source = - "varying vec2 texcoords;\n" - "uniform sampler2D sampler;\n" - "void main()\n" - "{\n" - " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" - "}\n"; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + const char *vs_source = + "void main()\n" + "{\n" + " gl_Position = gl_Vertex;\n" + " gl_TexCoord[0] = gl_MultiTexCoord0;\n" + "}\n"; + const char *fs_source = + "varying vec2 texcoords;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" + "}\n"; - const char *aswizzle_source = - "varying vec2 texcoords;\n" - "uniform sampler2D sampler;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n" - "}\n"; + const char *aswizzle_source = + "varying vec2 texcoords;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n" + "}\n"; - GLint fs_prog, vs_prog, avs_prog, aswizzle_prog; + GLint fs_prog, vs_prog, avs_prog, aswizzle_prog; - glamor_priv->finish_access_prog = glCreateProgramObjectARB(); - glamor_priv->aswizzle_prog = glCreateProgramObjectARB(); + glamor_priv->finish_access_prog[0] = glCreateProgramObjectARB(); + glamor_priv->finish_access_prog[1] = glCreateProgramObjectARB(); - if (GLEW_ARB_fragment_shader) { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source); - glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); - glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog); + if (GLEW_ARB_fragment_shader) { + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source); + glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog); + glAttachObjectARB(glamor_priv->finish_access_prog[0], fs_prog); - avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); - aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source); - glAttachObjectARB(glamor_priv->aswizzle_prog, avs_prog); - glAttachObjectARB(glamor_priv->aswizzle_prog, aswizzle_prog); - } else { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); - glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog); - ErrorF("Lack of framgment shader support.\n"); - } + avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); + aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source); + glAttachObjectARB(glamor_priv->finish_access_prog[1], avs_prog); + glAttachObjectARB(glamor_priv->finish_access_prog[1], aswizzle_prog); + } else { + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); + glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog); + ErrorF("Lack of framgment shader support.\n"); + } - glamor_link_glsl_prog(glamor_priv->finish_access_prog); - glamor_link_glsl_prog(glamor_priv->aswizzle_prog); + glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]); + glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); - if (GLEW_ARB_fragment_shader) { - GLint sampler_uniform_location; + if (GLEW_ARB_fragment_shader) { + GLint sampler_uniform_location; - sampler_uniform_location = - glGetUniformLocationARB(glamor_priv->finish_access_prog, "sampler"); - glUseProgramObjectARB(glamor_priv->finish_access_prog); - glUniform1iARB(sampler_uniform_location, 0); - glUseProgramObjectARB(0); - - sampler_uniform_location = - glGetUniformLocationARB(glamor_priv->aswizzle_prog, "sampler"); - glUseProgramObjectARB(glamor_priv->aswizzle_prog); - glUniform1iARB(sampler_uniform_location, 0); - glUseProgramObjectARB(0); - } -} - -/* - * Load texture from the pixmap's data pointer and then - * draw the texture to the fbo, and flip the y axis. - * */ -static void -glamor_load_texture_pixmap(PixmapPtr pixmap) -{ - - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - unsigned int stride, row_length; - GLenum format, type; - static float vertices[8] = {-1, -1, - 1, -1, - 1, 1, - -1, 1}; - static float texcoords[8] = {0, 1, - 1, 1, - 1, 0, - 0, 0}; - static float texcoords_inverted[8] = {0, 0, - 1, 0, - 1, 1, - 0, 1}; - float *ptexcoords; - - void * texel; - GLuint tex; - int alfa_mode = 0; - - if (glamor_priv->yInverted) - ptexcoords = texcoords_inverted; - else - ptexcoords = texcoords; - - assert(pixmap->drawable.depth != 1); - stride = pixmap->devKind; - row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - switch (pixmap->drawable.depth) { - case 8: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - break; - case 24: - assert(pixmap->drawable.bitsPerPixel == 32); - /* FALLTHROUGH */ - alfa_mode = 1; - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth); - return; - } - - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); - - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); - - glGenTextures(1, &tex); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); - - if (glamor_priv->yInverted || GLEW_MESA_pack_invert) { - texel = NULL; - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); - } - else - texel = pixmap->devPrivate.ptr; - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - pixmap->drawable.width, pixmap->drawable.height, 0, - format, type, texel); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glEnable(GL_TEXTURE_2D); - - assert(GLEW_ARB_fragment_shader); - if (alfa_mode == 0) - glUseProgramObjectARB(glamor_priv->finish_access_prog); - else - glUseProgramObjectARB(glamor_priv->aswizzle_prog); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisable(GL_TEXTURE_2D); + sampler_uniform_location = + glGetUniformLocationARB(glamor_priv->finish_access_prog[0], "sampler"); + glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); + glUniform1iARB(sampler_uniform_location, 0); glUseProgramObjectARB(0); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDeleteTextures(1, &tex); + + sampler_uniform_location = + glGetUniformLocationARB(glamor_priv->finish_access_prog[1], "sampler"); + glUseProgramObjectARB(glamor_priv->finish_access_prog[1]); + glUniform1iARB(sampler_uniform_location, 0); + glUseProgramObjectARB(0); + } } void glamor_finish_access(DrawablePtr drawable) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(drawable->pScreen); - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - /* Check if finish_access was already called once on this */ - if (pixmap->devPrivate.ptr == NULL) - return; + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return; - if (!pixmap_priv) - return; + if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { + glamor_restore_pixmap_to_texture(pixmap); + } - if (pixmap_priv->fb == 0) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) { + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); + glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0); + pixmap_priv->pbo_valid = FALSE; + glDeleteBuffersARB(1, &pixmap_priv->pbo); + pixmap_priv->pbo = 0; + } else + free(pixmap->devPrivate.ptr); - if (pixmap != screen_pixmap) - return; - } - - if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { - glamor_load_texture_pixmap(pixmap); - } - - if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); - glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0); - glDeleteBuffersARB (1, &pixmap_priv->pbo); - pixmap_priv->pbo = 0; - } else - free(pixmap->devPrivate.ptr); - - pixmap->devPrivate.ptr = NULL; + pixmap->devPrivate.ptr = NULL; } + + /** * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the * current fill style. @@ -595,18 +241,18 @@ glamor_finish_access(DrawablePtr drawable) Bool glamor_prepare_access_gc(GCPtr gc) { - if (gc->stipple) - if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO)) - return FALSE; - if (gc->fillStyle == FillTiled) { - if (!glamor_prepare_access (&gc->tile.pixmap->drawable, - GLAMOR_ACCESS_RO)) { - if (gc->stipple) - glamor_finish_access(&gc->stipple->drawable); - return FALSE; - } + if (gc->stipple) + if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO)) + return FALSE; + if (gc->fillStyle == FillTiled) { + if (!glamor_prepare_access (&gc->tile.pixmap->drawable, + GLAMOR_ACCESS_RO)) { + if (gc->stipple) + glamor_finish_access(&gc->stipple->drawable); + return FALSE; } - return TRUE; + } + return TRUE; } /** @@ -615,10 +261,10 @@ glamor_prepare_access_gc(GCPtr gc) void glamor_finish_access_gc(GCPtr gc) { - if (gc->fillStyle == FillTiled) - glamor_finish_access(&gc->tile.pixmap->drawable); - if (gc->stipple) - glamor_finish_access(&gc->stipple->drawable); + if (gc->fillStyle == FillTiled) + glamor_finish_access(&gc->tile.pixmap->drawable); + if (gc->stipple) + glamor_finish_access(&gc->stipple->drawable); } Bool @@ -628,33 +274,31 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, unsigned long fg_pixel, unsigned long bg_pixel, int stipple_x, int stipple_y) { - glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth); - return FALSE; -// ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth); -// glamor_solid_fail_region(pixmap, x, y, width, height); + glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth); + return FALSE; } GCOps glamor_gc_ops = { - .FillSpans = glamor_fill_spans, - .SetSpans = glamor_set_spans, - .PutImage = glamor_put_image, - .CopyArea = glamor_copy_area, - .CopyPlane = miCopyPlane, - .PolyPoint = miPolyPoint, - .Polylines = glamor_poly_lines, - .PolySegment = miPolySegment, - .PolyRectangle = miPolyRectangle, - .PolyArc = miPolyArc, - .FillPolygon = miFillPolygon, - .PolyFillRect = glamor_poly_fill_rect, - .PolyFillArc = miPolyFillArc, - .PolyText8 = miPolyText8, - .PolyText16 = miPolyText16, - .ImageText8 = miImageText8, - .ImageText16 = miImageText16, - .ImageGlyphBlt = miImageGlyphBlt, - .PolyGlyphBlt = miPolyGlyphBlt, - .PushPixels = miPushPixels, + .FillSpans = glamor_fill_spans, + .SetSpans = glamor_set_spans, + .PutImage = glamor_put_image, + .CopyArea = glamor_copy_area, + .CopyPlane = miCopyPlane, + .PolyPoint = miPolyPoint, + .Polylines = glamor_poly_lines, + .PolySegment = miPolySegment, + .PolyRectangle = miPolyRectangle, + .PolyArc = miPolyArc, + .FillPolygon = miFillPolygon, + .PolyFillRect = glamor_poly_fill_rect, + .PolyFillArc = miPolyFillArc, + .PolyText8 = miPolyText8, + .PolyText16 = miPolyText16, + .ImageText8 = miImageText8, + .ImageText16 = miImageText16, + .ImageGlyphBlt = miImageGlyphBlt, + .PolyGlyphBlt = miPolyGlyphBlt, + .PushPixels = miPushPixels, }; /** @@ -664,84 +308,84 @@ GCOps glamor_gc_ops = { static void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) { - /* fbValidateGC will do direct access to pixmaps if the tiling has changed. - * Preempt fbValidateGC by doing its work and masking the change out, so - * that we can do the Prepare/finish_access. - */ + /* fbValidateGC will do direct access to pixmaps if the tiling has changed. + * Preempt fbValidateGC by doing its work and masking the change out, so + * that we can do the Prepare/finish_access. + */ #ifdef FB_24_32BIT - if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { - gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); - fbGetRotatedPixmap(gc) = 0; - } + if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { + gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); + fbGetRotatedPixmap(gc) = 0; + } - if (gc->fillStyle == FillTiled) { - PixmapPtr old_tile, new_tile; + if (gc->fillStyle == FillTiled) { + PixmapPtr old_tile, new_tile; - old_tile = gc->tile.pixmap; - if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { - new_tile = fbGetRotatedPixmap(gc); - if (!new_tile || - new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel) - { - if (new_tile) - gc->pScreen->DestroyPixmap(new_tile); - /* fb24_32ReformatTile will do direct access of a newly- - * allocated pixmap. - */ - if (glamor_prepare_access(&old_tile->drawable, - GLAMOR_ACCESS_RO)) { - new_tile = fb24_32ReformatTile(old_tile, - drawable->bitsPerPixel); - glamor_finish_access(&old_tile->drawable); - } - } - if (new_tile) { - fbGetRotatedPixmap(gc) = old_tile; - gc->tile.pixmap = new_tile; - changes |= GCTile; - } - } - } -#endif - if (changes & GCTile) { - if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width * - drawable->bitsPerPixel)) + old_tile = gc->tile.pixmap; + if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { + new_tile = fbGetRotatedPixmap(gc); + if (!new_tile || + new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel) { - if (glamor_prepare_access(&gc->tile.pixmap->drawable, - GLAMOR_ACCESS_RW)) { - fbPadPixmap(gc->tile.pixmap); - glamor_finish_access(&gc->tile.pixmap->drawable); - } + if (new_tile) + gc->pScreen->DestroyPixmap(new_tile); + /* fb24_32ReformatTile will do direct access of a newly- + * allocated pixmap. + */ + if (glamor_prepare_access(&old_tile->drawable, + GLAMOR_ACCESS_RO)) { + new_tile = fb24_32ReformatTile(old_tile, + drawable->bitsPerPixel); + glamor_finish_access(&old_tile->drawable); + } } - /* Mask out the GCTile change notification, now that we've done FB's - * job for it. - */ - changes &= ~GCTile; + if (new_tile) { + fbGetRotatedPixmap(gc) = old_tile; + gc->tile.pixmap = new_tile; + changes |= GCTile; + } } - - if (changes & GCStipple && gc->stipple) { - /* We can't inline stipple handling like we do for GCTile because - * it sets fbgc privates. - */ - if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { - fbValidateGC(gc, changes, drawable); - glamor_finish_access(&gc->stipple->drawable); + } +#endif + if (changes & GCTile) { + if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width * + drawable->bitsPerPixel)) + { + if (glamor_prepare_access(&gc->tile.pixmap->drawable, + GLAMOR_ACCESS_RW)) { + fbPadPixmap(gc->tile.pixmap); + glamor_finish_access(&gc->tile.pixmap->drawable); } - } else { - fbValidateGC(gc, changes, drawable); - } + } + /* Mask out the GCTile change notification, now that we've done FB's + * job for it. + */ + changes &= ~GCTile; + } - gc->ops = &glamor_gc_ops; + if (changes & GCStipple && gc->stipple) { + /* We can't inline stipple handling like we do for GCTile because + * it sets fbgc privates. + */ + if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { + fbValidateGC(gc, changes, drawable); + glamor_finish_access(&gc->stipple->drawable); + } + } else { + fbValidateGC(gc, changes, drawable); + } + + gc->ops = &glamor_gc_ops; } static GCFuncs glamor_gc_funcs = { - glamor_validate_gc, - miChangeGC, - miCopyGC, - miDestroyGC, - miChangeClip, - miDestroyClip, - miCopyClip + glamor_validate_gc, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip }; /** @@ -751,54 +395,54 @@ static GCFuncs glamor_gc_funcs = { int glamor_create_gc(GCPtr gc) { - if (!fbCreateGC(gc)) - return FALSE; + if (!fbCreateGC(gc)) + return FALSE; - gc->funcs = &glamor_gc_funcs; + gc->funcs = &glamor_gc_funcs; - return TRUE; + return TRUE; } Bool glamor_prepare_access_window(WindowPtr window) { - if (window->backgroundState == BackgroundPixmap) { - if (!glamor_prepare_access(&window->background.pixmap->drawable, - GLAMOR_ACCESS_RO)) - return FALSE; - } + if (window->backgroundState == BackgroundPixmap) { + if (!glamor_prepare_access(&window->background.pixmap->drawable, + GLAMOR_ACCESS_RO)) + return FALSE; + } - if (window->borderIsPixel == FALSE) { - if (!glamor_prepare_access(&window->border.pixmap->drawable, - GLAMOR_ACCESS_RO)) { - if (window->backgroundState == BackgroundPixmap) - glamor_finish_access(&window->background.pixmap->drawable); - return FALSE; - } + if (window->borderIsPixel == FALSE) { + if (!glamor_prepare_access(&window->border.pixmap->drawable, + GLAMOR_ACCESS_RO)) { + if (window->backgroundState == BackgroundPixmap) + glamor_finish_access(&window->background.pixmap->drawable); + return FALSE; } - return TRUE; + } + return TRUE; } void glamor_finish_access_window(WindowPtr window) { - if (window->backgroundState == BackgroundPixmap) - glamor_finish_access(&window->background.pixmap->drawable); + if (window->backgroundState == BackgroundPixmap) + glamor_finish_access(&window->background.pixmap->drawable); - if (window->borderIsPixel == FALSE) - glamor_finish_access(&window->border.pixmap->drawable); + if (window->borderIsPixel == FALSE) + glamor_finish_access(&window->border.pixmap->drawable); } Bool glamor_change_window_attributes(WindowPtr window, unsigned long mask) { - Bool ret; + Bool ret; - if (!glamor_prepare_access_window(window)) - return FALSE; - ret = fbChangeWindowAttributes(window, mask); - glamor_finish_access_window(window); - return ret; + if (!glamor_prepare_access_window(window)) + return FALSE; + ret = fbChangeWindowAttributes(window, mask); + glamor_finish_access_window(window); + return ret; } RegionPtr diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h new file mode 100644 index 000000000..aad4b3ca6 --- /dev/null +++ b/glamor/glamor_debug.h @@ -0,0 +1,67 @@ +#ifndef __GLAMOR_DEBUG_H__ +#define __GLAMOR_DEBUG_H__ + + +#define GLAMOR_DELAYED_STRING_MAX 64 + +#define GLAMOR_DEBUG_NONE 0 +#define GLAMOR_DEBUG_FALLBACK 1 +#define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD 2 +#define GLAMOR_DEBUG_TEXTURE_DOWNLOAD 3 + + +#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) + + +#endif diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 2b94934b6..fade2b3cd 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -89,7 +89,6 @@ glamor_fill(DrawablePtr drawable, } return; fail: - glamor_fallback("glamor_fill()"); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_gc(gc)) { fbFill(drawable, gc, x, y, width, height); @@ -154,16 +153,22 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, GLfloat color[4]; float vertices[4][2]; - if (!glamor_set_destination_pixmap(pixmap)) + if (glamor_set_destination_pixmap(pixmap)) { + glamor_fallback("dest has no fbo.\n"); goto fail; + } glamor_set_alu(alu); if (!glamor_set_planemask(pixmap, planemask)) { - ErrorF("Failedto set planemask in glamor_solid.\n"); + glamor_fallback("Failedto set planemask in glamor_solid.\n"); goto fail; } - glUseProgramObjectARB(glamor_priv->solid_prog); - glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color); + glamor_get_rgba_from_pixel(fg_pixel, + &color[0], + &color[1], + &color[2], + &color[3], + format_for_pixmap(pixmap)); glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color); glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); @@ -196,22 +201,4 @@ fail: return FALSE; } -/* Highlight places where we're doing it wrong. */ -void -glamor_solid_fail_region(PixmapPtr pixmap, int x, int y, int width, int height) -{ - unsigned long pixel; - switch (pixmap->drawable.depth) { - case 24: - case 32: - pixel = 0x00ff00ff; /* our favorite color */ - break; - default: - case 8: - pixel = 0xd0d0d0d0; - break; - } - - glamor_solid(pixmap, x, y, width, height, GXcopy, ~0, pixel); -} diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index c6976c376..b1f79a9d8 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -47,10 +47,9 @@ glamor_fill_spans(DrawablePtr drawable, PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) + if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) goto fail; - glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); ppt = points; while (n--) { @@ -82,7 +81,7 @@ glamor_fill_spans(DrawablePtr drawable, } return; fail: - glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable, + glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_gc(gc)) { diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index dba23a89d..10fa2a2c3 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -31,18 +31,6 @@ #include "glamor_priv.h" -static void -set_bit(uint8_t *bitfield, unsigned int index, unsigned int val) -{ - int i = index / 8; - int mask = 1 << (index % 8); - - if (val) - bitfield[i] |= mask; - else - bitfield[i] &= ~mask; -} - void glamor_get_spans(DrawablePtr drawable, int wmax, @@ -53,39 +41,27 @@ glamor_get_spans(DrawablePtr drawable, { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; + int ax; glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); - int i, j; - uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst; + int i; + uint8_t *readpixels_dst = (uint8_t *)dst; int x_off, y_off; - - switch (drawable->depth) { - case 1: - temp_dst = malloc(wmax); - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - readpixels_dst = temp_dst; - break; - case 8: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - break; - case 24: - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - glamor_fallback("glamor_get_spans(): " - "Unknown getspans depth %d\n", drawable->depth); - goto fail; + if (glamor_get_tex_format_type_from_pixmap(pixmap, + &format, + &type, + &ax + )) { + glamor_fallback("unknown depth. %d \n", + drawable->depth); + goto fail; } - if (!glamor_set_destination_pixmap(pixmap)) + if (glamor_set_destination_pixmap(pixmap)) { + glamor_fallback("pixmap has no fbo.\n"); goto fail; - + } glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - for (i = 0; i < count; i++) { if (glamor_priv->yInverted) { glReadPixels(points[i].x + x_off, @@ -102,21 +78,12 @@ glamor_get_spans(DrawablePtr drawable, format, type, readpixels_dst); } - if (temp_dst) { - for (j = 0; j < widths[i]; j++) { - set_bit((uint8_t *)dst, j, temp_dst[j] & 0x1); - } - dst += PixmapBytePad(widths[i], drawable->depth); - } else { - readpixels_dst += PixmapBytePad(widths[i], drawable->depth); - } + readpixels_dst += PixmapBytePad(widths[i], drawable->depth); } - free(temp_dst); return; fail: - free(temp_dst); - glamor_fallback("glamor_get_spans() from %p (%c)\n", drawable, + glamor_fallback("from %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) { fbGetSpans(drawable, wmax, points, widths, count, dst); diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index e24b222f4..26e08470a 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -67,6 +67,7 @@ */ #define GLYPH_BUFFER_SIZE 256 + typedef struct { PicturePtr source; glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE]; @@ -573,6 +574,7 @@ static void glamor_glyphs_to_mask(PicturePtr mask, glamor_glyph_buffer_t *buffer) { #ifdef RENDER + glamor_composite_rects(PictOpAdd, buffer->source, mask, buffer->count, buffer->rects); #endif diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c new file mode 100644 index 000000000..c94c07cd7 --- /dev/null +++ b/glamor/glamor_picture.c @@ -0,0 +1,93 @@ +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "glamor_priv.h" + +/* Upload picture to texture. We may need to flip the y axis or + * wire alpha to 1. So we may conditional create fbo for the picture. + * */ +enum glamor_pixmap_status +glamor_upload_picture_to_texture(PicturePtr picture) +{ + PixmapPtr pixmap; + glamor_pixmap_private *pixmap_priv; + assert(picture->pDrawable); + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + pixmap_priv = glamor_get_pixmap_private(pixmap); + + assert(GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) == 1); + return glamor_upload_pixmap_to_texture(pixmap); +} + + +Bool +glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) +{ + if (!picture || !picture->pDrawable) + return TRUE; + + return glamor_prepare_access(picture->pDrawable, access); +} + +void +glamor_finish_access_picture(PicturePtr picture) +{ + if (!picture || !picture->pDrawable) + return; + + glamor_finish_access(picture->pDrawable); +} + +/* + * We should already has drawable attached to it, if it has one. + * Then set the attached pixmap to is_picture format, and set + * the pict format. + * */ +int +glamor_create_picture(PicturePtr picture) +{ + PixmapPtr pixmap; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv; + + if (!picture || !picture->pDrawable) + return 0; + + glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen); + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + pixmap_priv = glamor_get_pixmap_private(pixmap); + assert(pixmap_priv); + + pixmap_priv->is_picture = 1; + pixmap_priv->pict_format = picture->format; + return glamor_priv->saved_create_picture(picture); +} + +void +glamor_destroy_picture(PicturePtr picture) +{ + PixmapPtr pixmap; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv; + + if (!picture || !picture->pDrawable) + return; + + glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen); + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + pixmap_priv = glamor_get_pixmap_private(pixmap); + assert(pixmap_priv); + + pixmap_priv->is_picture = 0; + pixmap_priv->pict_format = 0; + glamor_priv->saved_destroy_picture(picture); +} + +void glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv) +{ + pixmap_priv->pict_format = picture->format; +} + diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c new file mode 100644 index 000000000..6e2d9d576 --- /dev/null +++ b/glamor/glamor_pixmap.c @@ -0,0 +1,483 @@ +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "glamor_priv.h" +/** + * Sets the offsets to add to coordinates to make them address the same bits in + * the backing drawable. These coordinates are nonzero only for redirected + * windows. + */ +void +glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, + int *x, int *y) +{ +#ifdef COMPOSITE + if (drawable->type == DRAWABLE_WINDOW) { + *x = -pixmap->screen_x; + *y = -pixmap->screen_y; + return; + } +#endif + + *x = 0; + *y = 0; +} + +void +glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) +{ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + + glViewport(0, 0, + pixmap_priv->container->drawable.width, + pixmap_priv->container->drawable.height); +} + +int +glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv) +{ + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return -1; + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + return 0; +} + +int +glamor_set_destination_pixmap(PixmapPtr pixmap) +{ + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + return glamor_set_destination_pixmap_priv(pixmap_priv); +} + +Bool +glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask) +{ + if (glamor_pm_is_solid(&pixmap->drawable, planemask)) { + return GL_TRUE; + } + + glamor_fallback("unsupported planemask %lx\n", planemask); + return GL_FALSE; +} + + + +void +glamor_set_alu(unsigned char alu) +{ + if (alu == GXcopy) { + glDisable(GL_COLOR_LOGIC_OP); + return; + } + glEnable(GL_COLOR_LOGIC_OP); + switch (alu) { + case GXclear: + glLogicOp(GL_CLEAR); + break; + case GXand: + glLogicOp(GL_AND); + break; + case GXandReverse: + glLogicOp(GL_AND_REVERSE); + break; + case GXandInverted: + glLogicOp(GL_AND_INVERTED); + break; + case GXnoop: + glLogicOp(GL_NOOP); + break; + case GXxor: + glLogicOp(GL_XOR); + break; + case GXor: + glLogicOp(GL_OR); + break; + case GXnor: + glLogicOp(GL_NOR); + break; + case GXequiv: + glLogicOp(GL_EQUIV); + break; + case GXinvert: + glLogicOp(GL_INVERT); + break; + case GXorReverse: + glLogicOp(GL_OR_REVERSE); + break; + case GXcopyInverted: + glLogicOp(GL_COPY_INVERTED); + break; + case GXorInverted: + glLogicOp(GL_OR_INVERTED); + break; + case GXnand: + glLogicOp(GL_NAND); + break; + case GXset: + glLogicOp(GL_SET); + break; + default: + FatalError("unknown logic op\n"); + } +} + + + + +/** + * Upload pixmap to a specified texture. + * This texture may not be the one attached to it. + **/ + +static void +__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex) +{ + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + unsigned int stride, row_length; + void *texels; + GLenum iformat = GL_RGBA; + + stride = pixmap->devKind; + row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; + + glBindTexture(GL_TEXTURE_2D, tex); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); + + if (pixmap_priv->pbo && pixmap_priv->pbo_valid) { + texels = NULL; + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); + } + else + texels = pixmap->devPrivate.ptr; + + glTexImage2D(GL_TEXTURE_2D, + 0, + iformat, + pixmap->drawable.width, + pixmap->drawable.height, 0, + format, type, texels); +} + + +/* + * Load texture from the pixmap's data pointer and then + * draw the texture to the fbo, and flip the y axis. + * */ + +static void +_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, int ax, int flip) +{ + + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + static float vertices[8] = {-1, -1, + 1, -1, + 1, 1, + -1, 1}; + static float texcoords[8] = {0, 1, + 1, 1, + 1, 0, + 0, 0}; + static float texcoords_inv[8] = {0, 0, + 1, 0, + 1, 1, + 0, 1}; + float *ptexcoords; + + GLuint tex; + int need_flip; + need_flip = (flip && !glamor_priv->yInverted); + + /* Try fast path firstly, upload the pixmap to the texture attached + * to the fbo directly. */ + + if (ax == 0 && !need_flip) { + __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex); + return; + } + + + if (need_flip) + ptexcoords = texcoords; + else + ptexcoords = texcoords_inv; + + /* Slow path, we need to flip y or wire alpha to 1. */ + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); + + glGenTextures(1, &tex); + + __glamor_upload_pixmap_to_texture(pixmap, format, type, tex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEnable(GL_TEXTURE_2D); + glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisable(GL_TEXTURE_2D); + glUseProgramObjectARB(0); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDeleteTextures(1, &tex); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +} + + +/* */ +static int +glamor_pixmap_upload_prepare(PixmapPtr pixmap, int need_fbo) +{ + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (!glamor_check_fbo_width_height(pixmap->drawable.width , pixmap->drawable.height) + || !glamor_check_fbo_depth(pixmap->drawable.depth)) { + glamor_fallback("upload failed reason: bad size or depth %d x %d @depth %d \n", + pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth); + return -1; + } + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return 0; + if (pixmap_priv->tex == 0) { + /* Create a framebuffer object wrapping the texture so that we can render + * to it. + */ + glGenTextures(1, &pixmap_priv->tex); + glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + } + + if (need_fbo && pixmap_priv->fb == 0) { + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, + pixmap->drawable.height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glGenFramebuffersEXT(1, &pixmap_priv->fb); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + pixmap_priv->tex, + 0); + } + + return 0; +} + +enum glamor_pixmap_status +glamor_upload_pixmap_to_texture(PixmapPtr pixmap) +{ + GLenum format, type; + int ax; + + if (glamor_get_tex_format_type_from_pixmap(pixmap, + &format, + &type, + &ax)) { + glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); + return GLAMOR_UPLOAD_FAILED; + } + if (glamor_pixmap_upload_prepare(pixmap, ax)) + return GLAMOR_UPLOAD_FAILED; + glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD, + "Uploading pixmap %p %dx%d depth%d.\n", + pixmap, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.depth); + _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 0); + return GLAMOR_UPLOAD_DONE; +} + +#if 0 +enum glamor_pixmap_status +glamor_upload_pixmap_to_texure_from_data(PixmapPtr pixmap, void *data) +{ + enum glamor_pixmap_status upload_status; + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + assert(pixmap_priv->pbo_valid == 0); + assert(pixmap->devPrivate.ptr == NULL); + pixmap->devPrivate.ptr = data; + upload_status = glamor_upload_pixmap_to_texture(pixmap); + pixmap->devPrivate.ptr = NULL; + return upload_status; +} +#endif + +void +glamor_restore_pixmap_to_texture(PixmapPtr pixmap) +{ + GLenum format, type; + int ax; + + if (glamor_get_tex_format_type_from_pixmap(pixmap, + &format, + &type, + &ax)) { + ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); + assert(0); + } + _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1); +} + + +/** + * Move a pixmap to CPU memory. + * The input data is the pixmap's fbo. + * The output data is at pixmap->devPrivate.ptr. We always use pbo + * to read the fbo and then map it to va. If possible, we will use + * it directly as devPrivate.ptr. + * If successfully download a fbo to cpu then return TRUE. + * Otherwise return FALSE. + **/ + +Bool +glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) +{ + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + unsigned int stride, row_length, y; + GLenum format, type, gl_access, gl_usage; + int ax; + uint8_t *data, *read; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return TRUE; + + if (glamor_get_tex_format_type_from_pixmap(pixmap, + &format, + &type, + &ax)) { + ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); + assert(0); // Should never happen. + return FALSE; + } + + pixmap_priv->access_mode = access; + + switch (access) { + case GLAMOR_ACCESS_RO: + gl_access = GL_READ_ONLY_ARB; + gl_usage = GL_STREAM_READ_ARB; + break; + case GLAMOR_ACCESS_WO: + gl_access = GL_WRITE_ONLY_ARB; + gl_usage = GL_STREAM_DRAW_ARB; + break; + case GLAMOR_ACCESS_RW: + gl_access = GL_READ_WRITE_ARB; + gl_usage = GL_DYNAMIC_DRAW_ARB; + break; + default: + ErrorF("Glamor: Invalid access code. %d\n", access); + assert(0); + } + + glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD, + "Downloading pixmap %p %dx%d depth%d\n", + pixmap, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.depth); + + stride = pixmap->devKind; + row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ROW_LENGTH, row_length); + + if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { + + if (!glamor_priv->yInverted) + glPixelStorei(GL_PACK_INVERT_MESA, 1); + if (pixmap_priv->pbo == 0) + glGenBuffersARB (1, &pixmap_priv->pbo); + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT, + stride * pixmap->drawable.height, + NULL, gl_usage); + if (access != GLAMOR_ACCESS_WO) + glReadPixels (0, 0, + row_length, pixmap->drawable.height, + format, type, 0); + data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, gl_access); + pixmap_priv->pbo_valid = TRUE; + + if (!glamor_priv->yInverted) + glPixelStorei(GL_PACK_INVERT_MESA, 0); + + } else { + data = malloc(stride * pixmap->drawable.height); + assert(data); + if (access != GLAMOR_ACCESS_WO) { + if (pixmap_priv->pbo == 0) + glGenBuffersARB(1, &pixmap_priv->pbo); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + stride * pixmap->drawable.height, + NULL, GL_STREAM_READ_ARB); + glReadPixels (0, 0, row_length, pixmap->drawable.height, + format, type, 0); + read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB); + + for (y = 0; y < pixmap->drawable.height; y++) + memcpy(data + y * stride, + read + (pixmap->drawable.height - y - 1) * stride, stride); + glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + pixmap_priv->pbo_valid = FALSE; + glDeleteBuffersARB(1, &pixmap_priv->pbo); + pixmap_priv->pbo = 0; + } + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + pixmap->devPrivate.ptr = data; + return TRUE; +} + + + +static void +_glamor_destroy_upload_pixmap(PixmapPtr pixmap) +{ + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + assert(pixmap_priv->gl_fbo == 0); + if (pixmap_priv->fb) + glDeleteFramebuffersEXT(1, &pixmap_priv->fb); + if (pixmap_priv->tex) + glDeleteTextures(1, &pixmap_priv->tex); + if (pixmap_priv->pbo) + glDeleteBuffersARB(1, &pixmap_priv->pbo); + pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0; + +} + +void glamor_destroy_upload_pixmap(PixmapPtr pixmap) +{ + _glamor_destroy_upload_pixmap(pixmap); +} + diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index 660dc4a5b..218c308dd 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -50,9 +50,9 @@ glamor_poly_fill_rect(DrawablePtr drawable, int off_x, off_y; RegionPtr pClip = fbGetCompositeClip(gc); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - - if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) + if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) { goto fail; + } xorg = drawable->x; yorg = drawable->y; @@ -101,9 +101,8 @@ glamor_poly_fill_rect(DrawablePtr drawable, return; fail: - glamor_fallback("glamor_poly_fill_rect() to %p (%c)\n", + glamor_fallback(" to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_gc(gc)) { fbPolyFillRect(drawable, gc, nrect, prect ); diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index 75bc9bf9a..914961161 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -49,18 +49,17 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, xRectangle *rects; int x1, x2, y1, y2; int i; - /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0) { /* This ends up in miSetSpans, which is accelerated as well as we * can hope X wide lines will be. */ - /*glamor_fallback("glamor_poly_lines(): wide lines\n");*/ goto fail; } if (gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) { - glamor_fallback("glamor_poly_lines(): non-solid fill\n"); + glamor_fallback("non-solid fill line style %d, fill style %d\n", + gc->lineStyle, gc->fillStyle); goto fail; } @@ -77,11 +76,9 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, y2 = points[i + 1].y; } if (x1 != x2 && y1 != y2) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); free(rects); glamor_fallback("stub diagonal poly_line\n"); goto fail; - return; } if (x1 < x2) { rects[i].x = x1; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 1dc2c42c5..cf293b5dc 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -39,6 +39,7 @@ #include "glyphstr.h" #endif + #ifndef MAX_WIDTH #define MAX_WIDTH 4096 #endif @@ -47,175 +48,450 @@ #define MAX_HEIGHT 4096 #endif -typedef enum glamor_access { - GLAMOR_ACCESS_RO, - GLAMOR_ACCESS_RW, -} glamor_access_t; +#include "glamor_debug.h" + +#define glamor_check_fbo_width_height(_w_, _h_) (_w_ > 0 && _h_ > 0 \ + && _w_ < MAX_WIDTH \ + && _h_ < MAX_HEIGHT) + +#define glamor_check_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->is_picture == 1) +#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == 1) typedef struct glamor_transform_uniforms { - GLint x_bias; - GLint x_scale; - GLint y_bias; - GLint y_scale; + GLint x_bias; + GLint x_scale; + GLint y_bias; + GLint y_scale; } glamor_transform_uniforms; 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; + 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; } glamor_composite_shader; typedef struct { - INT16 x_src; - INT16 y_src; - INT16 x_mask; - INT16 y_mask; - INT16 x_dst; - INT16 y_dst; - INT16 width; - INT16 height; + 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; typedef struct { - unsigned char sha1[20]; + unsigned char sha1[20]; } glamor_cached_glyph_t; typedef struct { - /* The identity of the cache, statically configured at initialization */ - unsigned int format; - int glyph_width; - int glyph_height; + /* The identity of the cache, statically configured at initialization */ + unsigned int format; + int glyph_width; + int glyph_height; - /* Size of cache; eventually this should be dynamically determined */ - int size; + /* Size of cache; eventually this should be dynamically determined */ + int size; - /* Hash table mapping from glyph sha1 to position in the glyph; we use - * open addressing with a hash table size determined based on size and large - * enough so that we always have a good amount of free space, so we can - * use linear probing. (Linear probing is preferrable to double hashing - * here because it allows us to easily remove entries.) - */ - int *hash_entries; - int hash_size; + /* Hash table mapping from glyph sha1 to position in the glyph; we use + * open addressing with a hash table size determined based on size and large + * enough so that we always have a good amount of free space, so we can + * use linear probing. (Linear probing is preferrable to double hashing + * here because it allows us to easily remove entries.) + */ + int *hash_entries; + int hash_size; - glamor_cached_glyph_t *glyphs; - int glyph_count; /* Current number of glyphs */ + glamor_cached_glyph_t *glyphs; + int glyph_count; /* Current number of glyphs */ - PicturePtr picture; /* Where the glyphs of the cache are stored */ - int y_offset; /* y location within the picture where the cache starts */ - int columns; /* Number of columns the glyphs are layed out in */ - int eviction_position; /* Next random position to evict a glyph */ + PicturePtr picture; /* Where the glyphs of the cache are stored */ + int y_offset; /* y location within the picture where the cache starts */ + int columns; /* Number of columns the glyphs are layed out in */ + int eviction_position; /* Next random position to evict a glyph */ } glamor_glyph_cache_t; #define GLAMOR_NUM_GLYPH_CACHES 4 enum shader_source { - SHADER_SOURCE_SOLID, - SHADER_SOURCE_TEXTURE, - SHADER_SOURCE_TEXTURE_ALPHA, - SHADER_SOURCE_COUNT, + 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, + 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, + SHADER_IN_SOURCE_ONLY, + SHADER_IN_NORMAL, + SHADER_IN_CA_SOURCE, + SHADER_IN_CA_ALPHA, + SHADER_IN_COUNT, }; typedef struct glamor_screen_private { - CloseScreenProcPtr saved_close_screen; - CreateGCProcPtr saved_create_gc; - CreatePixmapProcPtr saved_create_pixmap; - DestroyPixmapProcPtr saved_destroy_pixmap; - GetSpansProcPtr saved_get_spans; - GetImageProcPtr saved_get_image; - CompositeProcPtr saved_composite; - TrapezoidsProcPtr saved_trapezoids; - GlyphsProcPtr saved_glyphs; - ChangeWindowAttributesProcPtr saved_change_window_attributes; - CopyWindowProcPtr saved_copy_window; - BitmapToRegionProcPtr saved_bitmap_to_region; - TrianglesProcPtr saved_triangles; + CloseScreenProcPtr saved_close_screen; + CreateGCProcPtr saved_create_gc; + CreatePixmapProcPtr saved_create_pixmap; + DestroyPixmapProcPtr saved_destroy_pixmap; + GetSpansProcPtr saved_get_spans; + GetImageProcPtr saved_get_image; + CompositeProcPtr saved_composite; + TrapezoidsProcPtr saved_trapezoids; + GlyphsProcPtr saved_glyphs; + ChangeWindowAttributesProcPtr saved_change_window_attributes; + CopyWindowProcPtr saved_copy_window; + BitmapToRegionProcPtr saved_bitmap_to_region; + TrianglesProcPtr saved_triangles; + CreatePictureProcPtr saved_create_picture; + DestroyPictureProcPtr saved_destroy_picture; - char *delayed_fallback_string; - int yInverted; - GLuint vbo; - int vbo_offset; - int vbo_size; - char *vb; - int vb_stride; + int yInverted; + int screen_fbo; + GLuint vbo; + int vbo_offset; + int vbo_size; + char *vb; + int vb_stride; - /* glamor_finishaccess */ - GLint finish_access_prog; - GLint aswizzle_prog; + /* glamor_finishaccess */ + GLint finish_access_prog[2]; - /* glamor_solid */ - GLint solid_prog; - GLint solid_color_uniform_location; + /* glamor_solid */ + GLint solid_prog; + GLint solid_color_uniform_location; - /* glamor_tile */ - GLint tile_prog; + /* glamor_tile */ + GLint tile_prog; - /* glamor_putimage */ - GLint put_image_xybitmap_prog; - glamor_transform_uniforms put_image_xybitmap_transform; - GLint put_image_xybitmap_fg_uniform_location; - GLint put_image_xybitmap_bg_uniform_location; + /* glamor_putimage */ + GLint put_image_xybitmap_prog; + glamor_transform_uniforms put_image_xybitmap_transform; + GLint put_image_xybitmap_fg_uniform_location; + GLint put_image_xybitmap_bg_uniform_location; - /* glamor_composite */ - glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] - [SHADER_MASK_COUNT] - [SHADER_IN_COUNT]; - Bool has_source_coords, has_mask_coords; - int render_nr_verts; + /* glamor_composite */ + glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] + [SHADER_MASK_COUNT] + [SHADER_IN_COUNT]; + Bool has_source_coords, has_mask_coords; + int render_nr_verts; - glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; + glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; + char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; + int delayed_fallback_pending; } glamor_screen_private; -enum glamor_pixmap_type { - GLAMOR_GL, - GLAMOR_FB -}; +typedef enum glamor_access { + GLAMOR_ACCESS_RO, + GLAMOR_ACCESS_RW, + GLAMOR_ACCESS_WO, +} glamor_access_t; + +/* + * glamor_pixmap_private - glamor pixmap's private structure. + * @gl_fbo: The pixmap is attached to a fbo originally. + * @gl_tex: The pixmap is in a gl texture originally. + * @pbo_valid: The pbo has a valid copy of the pixmap's data. + * @is_picture: The drawable is attached to a picture. + * @tex: attached texture. + * @fb: attached fbo. + * @pbo: attached pbo. + * @access_mode: access mode during the prepare/finish pair. + * @pict_format: the corresponding picture's format. + * @container: The corresponding pixmap's pointer. + **/ typedef struct glamor_pixmap_private { - GLuint tex; - GLuint fb; - GLuint pbo; - enum glamor_pixmap_type type; - glamor_access_t access_mode; + unsigned char gl_fbo:1; + unsigned char gl_tex:1; + unsigned char pbo_valid:1; + unsigned char is_picture:1; + GLuint tex; + GLuint fb; + GLuint pbo; + glamor_access_t access_mode; + PictFormatShort pict_format; + PixmapPtr container; } 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); + return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates, + glamor_screen_private_key); } static inline glamor_pixmap_private * glamor_get_pixmap_private(PixmapPtr pixmap) { - return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); + return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); } #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) +/** + * 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 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->pict_format; + else + pict_format = format_for_depth(pixmap->drawable.depth); + + return pict_format; +} + +/* + * Map picture's format to the correct gl texture format and type. + * xa is used to indicate whehter we need to wire alpha to 1. + * + * Return 0 if find a matched texture type. Otherwise return -1. + **/ +static inline int +glamor_get_tex_format_type_from_pictformat(PictFormatShort format, + GLenum *tex_format, + GLenum *tex_type, + int *xa) +{ + *xa = 0; + switch (format) { + case PICT_a1: + *tex_format = GL_COLOR_INDEX; + *tex_type = GL_BITMAP; + break; + case PICT_b8g8r8x8: + *xa = 1; + case PICT_b8g8r8a8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8; + break; + + case PICT_x8r8g8b8: + *xa = 1; + case PICT_a8r8g8b8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case PICT_x8b8g8r8: + *xa = 1; + case PICT_a8b8g8r8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case PICT_x2r10g10b10: + *xa = 1; + case PICT_a2r10g10b10: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; + break; + case PICT_x2b10g10r10: + *xa = 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: + *xa = 1; + case PICT_a1b5g5r5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + + case PICT_x1r5g5b5: + *xa = 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: + *xa = 1; + case PICT_a4r4g4b4: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + + case PICT_x4b4g4r4: + *xa = 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; +} + + +static inline int +glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, + GLenum *format, + GLenum *type, + int *ax) +{ + 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->pict_format; + else + pict_format = format_for_depth(pixmap->drawable.depth); + + return glamor_get_tex_format_type_from_pictformat(pict_format, + format, type, ax); +} + + +/* 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; +} + + /** * Returns TRUE if the given planemask covers all the significant bits in the * pixel values for pDrawable. @@ -223,91 +499,47 @@ glamor_get_pixmap_private(PixmapPtr pixmap) static inline Bool glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) { - return (planemask & FbFullMask(drawable->depth)) == - FbFullMask(drawable->depth); + return (planemask & FbFullMask(drawable->depth)) == + FbFullMask(drawable->depth); } -static inline void -glamor_fallback(char *format, ...) -{ - va_list ap; - - va_start(ap, format); - //LogMessageVerb(X_INFO, 3, "fallback: "); - //LogMessageVerb(X_NONE, 3, format, ap); - va_end(ap); -} - -static inline void -glamor_delayed_fallback(ScreenPtr screen, char *format, ...) -{ - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - va_list ap; - - if (glamor_priv->delayed_fallback_string != NULL) - return; - - va_start(ap, format); - XNFvasprintf(&glamor_priv->delayed_fallback_string, format, ap); - va_end(ap); -} - -static inline void -glamor_clear_delayed_fallbacks(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - - free(glamor_priv->delayed_fallback_string); - glamor_priv->delayed_fallback_string = NULL; -} - -static inline void -glamor_report_delayed_fallbacks(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - - if (glamor_priv->delayed_fallback_string) { - //LogMessageVerb(X_INFO, 3, "fallback: %s", - // glamor_priv->delayed_fallback_string); - glamor_clear_delayed_fallbacks(screen); - } -} +extern int glamor_debug_level; static inline float v_from_x_coord_x(PixmapPtr pixmap, int x) { - return (float)x / pixmap->drawable.width * 2.0 - 1.0; + return (float)x / pixmap->drawable.width * 2.0 - 1.0; } static inline float v_from_x_coord_y(PixmapPtr pixmap, int y) { - return (float)y / pixmap->drawable.height * -2.0 + 1.0; + return (float)y / pixmap->drawable.height * -2.0 + 1.0; } static inline float v_from_x_coord_y_inverted(PixmapPtr pixmap, int y) { - return (float)y / pixmap->drawable.height * 2.0 - 1.0; + return (float)y / pixmap->drawable.height * 2.0 - 1.0; } static inline float t_from_x_coord_x(PixmapPtr pixmap, int x) { - return (float)x / pixmap->drawable.width; + return (float)x / pixmap->drawable.width; } static inline float t_from_x_coord_y(PixmapPtr pixmap, int y) { - return 1.0 - (float)y / pixmap->drawable.height; + return 1.0 - (float)y / pixmap->drawable.height; } static inline float t_from_x_coord_y_inverted(PixmapPtr pixmap, int y) { - return (float)y / pixmap->drawable.height; + return (float)y / pixmap->drawable.height; } @@ -359,7 +591,15 @@ GLint glamor_compile_glsl_prog(GLenum type, const char *source); void glamor_link_glsl_prog(GLint prog); void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, GLfloat *color); -Bool glamor_set_destination_pixmap(PixmapPtr pixmap); + +int glamor_set_destination_pixmap(PixmapPtr pixmap); +int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv); + +/* 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); + void glamor_set_alu(unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); void glamor_get_transform_uniform_locations(GLint prog, @@ -462,15 +702,93 @@ Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int tile_x, int tile_y); void glamor_init_tile_shader(ScreenPtr screen); -/* glamor_triangles */ +/* glamor_triangles.c */ void glamor_triangles (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int ntris, - xTriangle *tris); + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntris, + xTriangle *tris); + +/* glamor_pixmap.c */ + +/** + * 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); + +/** + * 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); + +/** + * 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); + +/** + * 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); + +/** + * 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); + +void +glamor_destroy_picture(PicturePtr picture); + +enum glamor_pixmap_status +glamor_upload_picture_to_texture(PicturePtr picture); + +void +glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv); + +/* 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 #endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index f1081b055..d056576a0 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -132,6 +132,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, 0.0, 1.0, }; + dest_coords[0][0] = v_from_x_coord_x(pixmap, x); dest_coords[0][1] = v_from_x_coord_y(pixmap, y); dest_coords[1][0] = v_from_x_coord_x(pixmap, x + w); @@ -226,13 +227,11 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); return; - -fail: glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); - - glamor_fallback("glamor_put_image(): to %p (%c)\n", + glamor_fallback(": to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); +fail: if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); glamor_finish_access(drawable); @@ -251,12 +250,11 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, RegionPtr clip; BoxPtr pbox; int nbox; - int bpp = drawable->bitsPerPixel; int src_stride = PixmapBytePad(w, drawable->depth); int x_off, y_off; float vertices[4][2], texcoords[4][2]; GLuint tex; - int alfa_mode = 0; + int ax = 0; if (image_format == XYBitmap) { assert(depth == 1); glamor_put_image_xybitmap(drawable, gc, x, y, w, h, @@ -264,56 +262,32 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, return; } - if (pixmap_priv == NULL) { - glamor_fallback("glamor_put_image: system memory pixmap\n"); - goto fail; + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { + glamor_fallback("has no fbo.\n"); + goto fail; } - if (pixmap_priv->fb == 0) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (pixmap != screen_pixmap) { - glamor_fallback("glamor_put_image: no fbo\n"); - goto fail; - } - } - - if (bpp == 1 && image_format == XYPixmap) - image_format = ZPixmap; - if (image_format != ZPixmap) { - glamor_fallback("glamor_put_image: non-ZPixmap\n"); + glamor_fallback("non-ZPixmap\n"); goto fail; } - switch (drawable->depth) { - case 1: - format = GL_COLOR_INDEX; - type = GL_BITMAP; - break; - case 8: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - break; - case 24: - assert(drawable->bitsPerPixel == 32); - /* FALLTHROUGH */ - alfa_mode = 1; - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - glamor_fallback("glamor_putimage: bad depth %d\n", drawable->depth); + if (!glamor_set_planemask(pixmap, gc->planemask)) { goto fail; } - - if (!glamor_set_planemask(pixmap, gc->planemask)) - goto fail; - glamor_set_alu(gc->alu); + if (glamor_get_tex_format_type_from_pixmap(pixmap, + &format, + &type, + &ax + )) { + glamor_fallback("unknown depth. %d \n", + drawable->depth); + goto fail; + } + + /* XXX consider to reuse a function to do the following work. */ glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); @@ -321,15 +295,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); + glamor_set_destination_pixmap_priv_nc(pixmap_priv); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / pixmap->drawable.bitsPerPixel); - if (bpp == 1) - glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); + glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); @@ -341,10 +313,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glEnable(GL_TEXTURE_2D); assert(GLEW_ARB_fragment_shader); - if (alfa_mode == 0) - glUseProgramObjectARB(glamor_priv->finish_access_prog); - else - glUseProgramObjectARB(glamor_priv->aswizzle_prog); + glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]); x += drawable->x; y += drawable->y; @@ -425,7 +394,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, fail: glamor_set_planemask(pixmap, ~0); - glamor_fallback("glamor_put_image(): to %p (%c)\n", + glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format, diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index e69d370d9..ca27b4d59 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -39,251 +39,251 @@ #include "glu3/glu3.h" struct shader_key { - enum shader_source source; - enum shader_mask mask; - enum shader_in in; + 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; + Bool dest_alpha; + Bool source_alpha; + GLenum source_blend; + GLenum dest_blend; }; static struct blendinfo composite_op_info[] = { - [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, - [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, - [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, - [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, - [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, - [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, - [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, - [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, - [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, + [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, + [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, + [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, + [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, + [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, + [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, + [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, + [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, + [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, }; static GLuint glamor_create_composite_fs(struct shader_key *key) { - const char *source_solid_fetch = - "uniform vec4 source;\n" - "vec4 get_source()\n" - "{\n" - " return source;\n" - "}\n"; - const char *source_alpha_pixmap_fetch = - "uniform sampler2D source_sampler;\n" - "vec4 get_source()\n" - "{\n" - " return texture2D(source_sampler, gl_TexCoord[0].xy);\n" - "}\n"; - const char *source_pixmap_fetch = - "uniform sampler2D source_sampler;\n" - "vec4 get_source()\n" - "{\n" - " return texture2D(source_sampler, gl_TexCoord[0].xy);\n" - "}\n"; - const char *mask_solid_fetch = - "uniform vec4 mask;\n" - "vec4 get_mask()\n" - "{\n" - " return mask;\n" - "}\n"; - const char *mask_alpha_pixmap_fetch = - "uniform sampler2D mask_sampler;\n" - "vec4 get_mask()\n" - "{\n" - " return texture2D(mask_sampler, gl_TexCoord[1].xy);\n" - "}\n"; - const char *mask_pixmap_fetch = - "uniform sampler2D mask_sampler;\n" - "vec4 get_mask()\n" - "{\n" - " return texture2D(mask_sampler, gl_TexCoord[1].xy);\n" - "}\n"; - const char *in_source_only = - "void main()\n" - "{\n" - " gl_FragColor = get_source();\n" - "}\n"; - const char *in_normal = - "void main()\n" - "{\n" - " gl_FragColor = get_source() * get_mask().a;\n" - "}\n"; - const char *in_ca_source = - "void main()\n" - "{\n" - " gl_FragColor = get_source() * get_mask();\n" - "}\n"; - const char *in_ca_alpha = - "void main()\n" - "{\n" - " gl_FragColor = get_source().a * get_mask();\n" - "}\n"; - char *source; - const char *source_fetch; - const char *mask_fetch = ""; - const char *in; - GLuint prog; + const char *source_solid_fetch = + "uniform vec4 source;\n" + "vec4 get_source()\n" + "{\n" + " return source;\n" + "}\n"; + const char *source_alpha_pixmap_fetch = + "uniform sampler2D source_sampler;\n" + "vec4 get_source()\n" + "{\n" + " return texture2D(source_sampler, gl_TexCoord[0].xy);\n" + "}\n"; + const char *source_pixmap_fetch = + "uniform sampler2D source_sampler;\n" + "vec4 get_source()\n" + "{\n" + " return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb, 1);\n" + "}\n"; + const char *mask_solid_fetch = + "uniform vec4 mask;\n" + "vec4 get_mask()\n" + "{\n" + " return mask;\n" + "}\n"; + const char *mask_alpha_pixmap_fetch = + "uniform sampler2D mask_sampler;\n" + "vec4 get_mask()\n" + "{\n" + " return texture2D(mask_sampler, gl_TexCoord[1].xy);\n" + "}\n"; + const char *mask_pixmap_fetch = + "uniform sampler2D mask_sampler;\n" + "vec4 get_mask()\n" + "{\n" + " return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, 1);\n" + "}\n"; + const char *in_source_only = + "void main()\n" + "{\n" + " gl_FragColor = get_source();\n" + "}\n"; + const char *in_normal = + "void main()\n" + "{\n" + " gl_FragColor = get_source() * get_mask().a;\n" + "}\n"; + const char *in_ca_source = + "void main()\n" + "{\n" + " gl_FragColor = get_source() * get_mask();\n" + "}\n"; + const char *in_ca_alpha = + "void main()\n" + "{\n" + " gl_FragColor = get_source().a * get_mask();\n" + "}\n"; + char *source; + const char *source_fetch; + const char *mask_fetch = ""; + const char *in; + GLuint prog; - switch (key->source) { - case SHADER_SOURCE_SOLID: - source_fetch = source_solid_fetch; - break; - case SHADER_SOURCE_TEXTURE_ALPHA: - source_fetch = source_alpha_pixmap_fetch; - break; - case SHADER_SOURCE_TEXTURE: - source_fetch = source_pixmap_fetch; - break; - default: - FatalError("Bad composite shader source"); - } + switch (key->source) { + case SHADER_SOURCE_SOLID: + source_fetch = source_solid_fetch; + break; + case SHADER_SOURCE_TEXTURE_ALPHA: + source_fetch = source_alpha_pixmap_fetch; + break; + case SHADER_SOURCE_TEXTURE: + source_fetch = source_pixmap_fetch; + break; + default: + FatalError("Bad composite shader source"); + } - switch (key->mask) { - case SHADER_MASK_NONE: - break; - case SHADER_MASK_SOLID: - mask_fetch = mask_solid_fetch; - break; - case SHADER_MASK_TEXTURE_ALPHA: - mask_fetch = mask_alpha_pixmap_fetch; - break; - case SHADER_MASK_TEXTURE: - mask_fetch = mask_pixmap_fetch; - break; - default: - FatalError("Bad composite shader mask"); - } + switch (key->mask) { + case SHADER_MASK_NONE: + break; + case SHADER_MASK_SOLID: + mask_fetch = mask_solid_fetch; + break; + case SHADER_MASK_TEXTURE_ALPHA: + mask_fetch = mask_alpha_pixmap_fetch; + break; + case SHADER_MASK_TEXTURE: + mask_fetch = mask_pixmap_fetch; + break; + default: + FatalError("Bad composite shader mask"); + } - switch (key->in) { - case SHADER_IN_SOURCE_ONLY: - in = in_source_only; - break; - case SHADER_IN_NORMAL: - in = in_normal; - break; - case SHADER_IN_CA_SOURCE: - in = in_ca_source; - break; - case SHADER_IN_CA_ALPHA: - in = in_ca_alpha; - break; - default: - FatalError("Bad composite IN type"); - } + switch (key->in) { + case SHADER_IN_SOURCE_ONLY: + in = in_source_only; + break; + case SHADER_IN_NORMAL: + in = in_normal; + break; + case SHADER_IN_CA_SOURCE: + in = in_ca_source; + break; + case SHADER_IN_CA_ALPHA: + in = in_ca_alpha; + break; + default: + FatalError("Bad composite IN type"); + } - XNFasprintf(&source, - "%s%s%s", - source_fetch, - mask_fetch, - in); + XNFasprintf(&source, + "%s%s%s", + source_fetch, + mask_fetch, + in); - prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); - free(source); + prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); + free(source); - return prog; + return prog; } static GLuint glamor_create_composite_vs(struct shader_key *key) { - const char *main_opening = - "void main()\n" - "{\n" - " gl_Position = gl_Vertex;\n"; - const char *source_coords = - " gl_TexCoord[0] = gl_MultiTexCoord0;\n"; - const char *mask_coords = - " gl_TexCoord[1] = gl_MultiTexCoord1;\n"; - const char *main_closing = - "}\n"; - const char *source_coords_setup = ""; - const char *mask_coords_setup = ""; - char *source; - GLuint prog; + const char *main_opening = + "void main()\n" + "{\n" + " gl_Position = gl_Vertex;\n"; + const char *source_coords = + " gl_TexCoord[0] = gl_MultiTexCoord0;\n"; + const char *mask_coords = + " gl_TexCoord[1] = gl_MultiTexCoord1;\n"; + const char *main_closing = + "}\n"; + const char *source_coords_setup = ""; + const char *mask_coords_setup = ""; + char *source; + GLuint prog; - if (key->source != SHADER_SOURCE_SOLID) - source_coords_setup = source_coords; + if (key->source != SHADER_SOURCE_SOLID) + source_coords_setup = source_coords; - if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID) - mask_coords_setup = mask_coords; + if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID) + mask_coords_setup = mask_coords; - XNFasprintf(&source, - "%s%s%s%s", - main_opening, - source_coords_setup, - mask_coords_setup, - main_closing); + XNFasprintf(&source, + "%s%s%s%s", + main_opening, + source_coords_setup, + mask_coords_setup, + main_closing); - prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source); - free(source); + prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source); + free(source); - return prog; + return prog; } static void glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, glamor_composite_shader *shader) { - GLuint vs, fs, prog; - GLint source_sampler_uniform_location, mask_sampler_uniform_location; + GLuint vs, fs, prog; + GLint source_sampler_uniform_location, mask_sampler_uniform_location; - vs = glamor_create_composite_vs(key); - if (vs == 0) - return; - fs = glamor_create_composite_fs(key); - if (fs == 0) - return; + vs = glamor_create_composite_vs(key); + if (vs == 0) + return; + fs = glamor_create_composite_fs(key); + if (fs == 0) + return; - prog = glCreateProgramObjectARB(); - glAttachObjectARB(prog, vs); - glAttachObjectARB(prog, fs); - glamor_link_glsl_prog(prog); + prog = glCreateProgramObjectARB(); + glAttachObjectARB(prog, vs); + glAttachObjectARB(prog, fs); + glamor_link_glsl_prog(prog); - shader->prog = prog; + shader->prog = prog; - glUseProgramObjectARB(prog); + glUseProgramObjectARB(prog); - if (key->source == SHADER_SOURCE_SOLID) { - shader->source_uniform_location = glGetUniformLocationARB(prog, - "source"); + if (key->source == SHADER_SOURCE_SOLID) { + shader->source_uniform_location = glGetUniformLocationARB(prog, + "source"); + } else { + source_sampler_uniform_location = glGetUniformLocationARB(prog, + "source_sampler"); + glUniform1i(source_sampler_uniform_location, 0); + } + + if (key->mask != SHADER_MASK_NONE) { + if (key->mask == SHADER_MASK_SOLID) { + shader->mask_uniform_location = glGetUniformLocationARB(prog, + "mask"); } else { - source_sampler_uniform_location = glGetUniformLocationARB(prog, - "source_sampler"); - glUniform1i(source_sampler_uniform_location, 0); - } - - if (key->mask != SHADER_MASK_NONE) { - if (key->mask == SHADER_MASK_SOLID) { - shader->mask_uniform_location = glGetUniformLocationARB(prog, - "mask"); - } else { - mask_sampler_uniform_location = glGetUniformLocationARB(prog, - "mask_sampler"); - glUniform1i(mask_sampler_uniform_location, 1); - } + mask_sampler_uniform_location = glGetUniformLocationARB(prog, + "mask_sampler"); + glUniform1i(mask_sampler_uniform_location, 1); } + } } static glamor_composite_shader * glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) { - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_composite_shader *shader; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_composite_shader *shader; - shader = &glamor_priv->composite_shader[key->source][key->mask][key->in]; - if (shader->prog == 0) - glamor_create_composite_shader(screen, key, shader); + shader = &glamor_priv->composite_shader[key->source][key->mask][key->in]; + if (shader->prog == 0) + glamor_create_composite_shader(screen, key, shader); - return shader; + return shader; } void @@ -295,149 +295,149 @@ static Bool glamor_set_composite_op(ScreenPtr screen, CARD8 op, PicturePtr dest, PicturePtr mask) { - GLenum source_blend, dest_blend; - struct blendinfo *op_info; + GLenum source_blend, dest_blend; + struct blendinfo *op_info; - if (op >= ARRAY_SIZE(composite_op_info)) { - ErrorF("unsupported render op\n"); - return GL_FALSE; + if (op >= ARRAY_SIZE(composite_op_info)) { + glamor_fallback("unsupported render op %d \n", op); + return GL_FALSE; + } + op_info = &composite_op_info[op]; + + source_blend = op_info->source_blend; + dest_blend = op_info->dest_blend; + + /* If there's no dst alpha channel, adjust the blend op so that we'll treat + * it as always 1. + */ + if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) { + if (source_blend == GL_DST_ALPHA) + source_blend = GL_ONE; + else if (source_blend == GL_ONE_MINUS_DST_ALPHA) + source_blend = GL_ZERO; + } + + /* Set up the source alpha value for blending in component alpha mode. */ + if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 && + op_info->source_alpha) { + if (source_blend != GL_ZERO) { + glamor_fallback("Dual-source composite blending not supported\n"); + return GL_FALSE; } - op_info = &composite_op_info[op]; + if (dest_blend == GL_SRC_ALPHA) + dest_blend = GL_SRC_COLOR; + else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA) + dest_blend = GL_ONE_MINUS_SRC_COLOR; + } - source_blend = op_info->source_blend; - dest_blend = op_info->dest_blend; - - /* If there's no dst alpha channel, adjust the blend op so that we'll treat - * it as always 1. - */ - if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) { - if (source_blend == GL_DST_ALPHA) - source_blend = GL_ONE; - else if (source_blend == GL_ONE_MINUS_DST_ALPHA) - source_blend = GL_ZERO; - } - - /* Set up the source alpha value for blending in component alpha mode. */ - if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 && - op_info->source_alpha) { - if (source_blend != GL_ZERO) { - ErrorF("Dual-source composite blending not supported\n"); - return GL_FALSE; - } - if (dest_blend == GL_SRC_ALPHA) - dest_blend = GL_SRC_COLOR; - else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA) - dest_blend = GL_ONE_MINUS_SRC_COLOR; - } - - if (source_blend == GL_ONE && dest_blend == GL_ZERO) { - glDisable(GL_BLEND); - } else { - glEnable(GL_BLEND); - glBlendFunc(source_blend, dest_blend); - } - return TRUE; + if (source_blend == GL_ONE && dest_blend == GL_ZERO) { + glDisable(GL_BLEND); + } else { + glEnable(GL_BLEND); + glBlendFunc(source_blend, dest_blend); + } + return TRUE; } static void glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glamor_pixmap_private *pixmap_priv) { - glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); - switch (picture->repeatType) { - case RepeatNone: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - break; - case RepeatNormal: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - break; - case RepeatPad: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - break; - case RepeatReflect: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); - break; - } + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + switch (picture->repeatType) { + case RepeatNone: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + break; + case RepeatNormal: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case RepeatPad: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + break; + case RepeatReflect: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + break; + } - switch (picture->filter) { - case PictFilterNearest: - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case PictFilterBilinear: - default: - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - } + switch (picture->filter) { + case PictFilterNearest: + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case PictFilterBilinear: + default: + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + } - glEnable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); } static void glamor_set_composite_solid(PicturePtr picture, GLint uniform_location) { - CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */ - float color[4]; /* rgba */ + CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */ + float color[4]; /* rgba */ - color[0] = ((c >> 16) & 0xff) / 255.0; - color[1] = ((c >> 8) & 0xff) / 255.0; - color[2] = ((c >> 0) & 0xff) / 255.0; - color[3] = ((c >> 24) & 0xff) / 255.0; + color[0] = ((c >> 16) & 0xff) / 255.0; + color[1] = ((c >> 8) & 0xff) / 255.0; + color[2] = ((c >> 0) & 0xff) / 255.0; + color[3] = ((c >> 24) & 0xff) / 255.0; - glUniform4fvARB(uniform_location, 1, color); + glUniform4fvARB(uniform_location, 1, color); } static int compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src) { - if (op == PictOpSrc) { - if (src->format == dst->format) - return 1; + if (op == PictOpSrc) { + if (src->format == dst->format) + return 1; - if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8) - return 1; + if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8) + return 1; - if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8) - return 1; - } else if (op == PictOpOver) { - if (src->alphaMap || dst->alphaMap) - return 0; + if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8) + return 1; + } else if (op == PictOpOver) { + if (src->alphaMap || dst->alphaMap) + return 0; - if (src->format != dst->format) - return 0; + if (src->format != dst->format) + return 0; - if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8) - return 1; - } + if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8) + return 1; + } - return 0; + return 0; } static char glamor_get_picture_location(PicturePtr picture) { - if (picture == NULL) - return ' '; + if (picture == NULL) + return ' '; - if (picture->pDrawable == NULL) { - switch (picture->pSourcePict->type) { - case SourcePictTypeSolidFill: - return 'c'; - case SourcePictTypeLinear: - return 'l'; - case SourcePictTypeRadial: - return 'r'; - default: - return '?'; - } + if (picture->pDrawable == NULL) { + switch (picture->pSourcePict->type) { + case SourcePictTypeSolidFill: + return 'c'; + case SourcePictTypeLinear: + return 'l'; + case SourcePictTypeRadial: + return 'r'; + default: + return '?'; } - return glamor_get_drawable_location(picture->pDrawable); + } + return glamor_get_drawable_location(picture->pDrawable); } static Bool @@ -451,151 +451,154 @@ glamor_composite_with_copy(CARD8 op, CARD16 width, CARD16 height) { - RegionRec region; + RegionRec region; - if (!source->pDrawable) - return FALSE; + if (!source->pDrawable) + return FALSE; - if (!compatible_formats(op, dest, source)) - return FALSE; + if (!compatible_formats(op, dest, source)) + return FALSE; - if (source->repeat || source->transform) - return FALSE; + if (source->repeat || source->transform) + return FALSE; - x_dest += dest->pDrawable->x; - y_dest += dest->pDrawable->y; - x_source += source->pDrawable->x; - y_source += source->pDrawable->y; + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + x_source += source->pDrawable->x; + y_source += source->pDrawable->y; - if (!miComputeCompositeRegion(®ion, - source, NULL, dest, - x_source, y_source, - 0, 0, - x_dest, y_dest, - width, height)) - return TRUE; - - glamor_copy_n_to_n(source->pDrawable, - dest->pDrawable, NULL, - REGION_RECTS(®ion), - REGION_NUM_RECTS(®ion), - x_source - x_dest, y_source - y_dest, - FALSE, FALSE, 0, NULL); - REGION_UNINIT(dest->pDrawable->pScreen, - ®ion); + if (!miComputeCompositeRegion(®ion, + source, NULL, dest, + x_source, y_source, + 0, 0, + x_dest, y_dest, + width, height)) return TRUE; + + glamor_copy_n_to_n(source->pDrawable, + dest->pDrawable, NULL, + REGION_RECTS(®ion), + REGION_NUM_RECTS(®ion), + x_source - x_dest, y_source - y_dest, + FALSE, FALSE, 0, NULL); + REGION_UNINIT(dest->pDrawable->pScreen, + ®ion); + return TRUE; } static Bool good_source_format(PicturePtr picture) { - switch (picture->format) { - case PICT_a1: - case PICT_a8: - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - return TRUE; - default: - glamor_fallback("Bad source format 0x%08x\n", picture->format); - return FALSE; - } + switch (picture->format) { + case PICT_a1: + case PICT_a8: + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + return TRUE; + default: + return TRUE; + glamor_fallback("Bad source format 0x%08x\n", picture->format); + return FALSE; + } } static Bool good_mask_format(PicturePtr picture) { - switch (picture->format) { - case PICT_a1: - case PICT_a8: - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - return TRUE; - default: - glamor_fallback("Bad mask format 0x%08x\n", picture->format); - return FALSE; - } + switch (picture->format) { + case PICT_a1: + case PICT_a8: + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + return TRUE; + default: + return TRUE; + glamor_fallback("Bad mask format 0x%08x\n", picture->format); + return FALSE; + } } static Bool good_dest_format(PicturePtr picture) { - switch (picture->format) { - case PICT_a8: - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - return TRUE; - default: - glamor_fallback("Bad dest format 0x%08x\n", picture->format); - return FALSE; - } + switch (picture->format) { + case PICT_a8: + case PICT_a8r8g8b8: + case PICT_x8r8g8b8: + return TRUE; + default: + return TRUE; + glamor_fallback("Bad dest format 0x%08x\n", picture->format); + return FALSE; + } } static inline float xFixedToFloat(pixman_fixed_t val) { - return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)); + return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)); } static void glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap, float *texcoord, int x, int y) { - float result[3]; - int i; - float tx, ty; - ScreenPtr screen = picture->pDrawable->pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + float result[3]; + int i; + float tx, ty; + ScreenPtr screen = picture->pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - if (picture->transform) { - for (i = 0; i < 3; i++) { - result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x + - xFixedToFloat(picture->transform->matrix[i][1]) * y + - xFixedToFloat(picture->transform->matrix[i][2])); - } - tx = result[0] / result[2]; - ty = result[1] / result[2]; - } else { - tx = x; - ty = y; + if (picture->transform) { + for (i = 0; i < 3; i++) { + result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x + + xFixedToFloat(picture->transform->matrix[i][1]) * y + + xFixedToFloat(picture->transform->matrix[i][2])); } - texcoord[0] = t_from_x_coord_x(pixmap, tx); - if (glamor_priv->yInverted) - texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty); - else - texcoord[1] = t_from_x_coord_y(pixmap, ty); + tx = result[0] / result[2]; + ty = result[1] / result[2]; + } else { + tx = x; + ty = y; + } + texcoord[0] = t_from_x_coord_x(pixmap, tx); + if (glamor_priv->yInverted) + texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty); + else + texcoord[1] = t_from_x_coord_y(pixmap, ty); } static void glamor_setup_composite_vbo(ScreenPtr screen) { - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_priv->vb_stride = 2 * sizeof(float); - if (glamor_priv->has_source_coords) - glamor_priv->vb_stride += 2 * sizeof(float); - if (glamor_priv->has_mask_coords) - glamor_priv->vb_stride += 2 * sizeof(float); + glamor_priv->vb_stride = 2 * sizeof(float); + if (glamor_priv->has_source_coords) + glamor_priv->vb_stride += 2 * sizeof(float); + if (glamor_priv->has_mask_coords) + glamor_priv->vb_stride += 2 * sizeof(float); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); - glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride, - (void *)((long)glamor_priv->vbo_offset)); - glEnableClientState(GL_VERTEX_ARRAY); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); + glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride, + (void *)((long)glamor_priv->vbo_offset)); + glEnableClientState(GL_VERTEX_ARRAY); - if (glamor_priv->has_source_coords) { - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, - (void *)(glamor_priv->vbo_offset + 2 * sizeof(float))); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + if (glamor_priv->has_source_coords) { + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, + (void *)(glamor_priv->vbo_offset + 2 * sizeof(float))); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } - if (glamor_priv->has_mask_coords) { - glClientActiveTexture(GL_TEXTURE1); - glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, - (void *)(glamor_priv->vbo_offset + - (glamor_priv->has_source_coords ? 4 : 2) * - sizeof(float))); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } + if (glamor_priv->has_mask_coords) { + glClientActiveTexture(GL_TEXTURE1); + glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, + (void *)(glamor_priv->vbo_offset + + (glamor_priv->has_source_coords ? 4 : 2) * + sizeof(float))); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } } static void @@ -605,39 +608,39 @@ glamor_emit_composite_vert(ScreenPtr screen, const float *dst_coords, int i) { - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - float *vb = (float *)(glamor_priv->vb + glamor_priv->vbo_offset); - int j = 0; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + float *vb = (float *)(glamor_priv->vb + glamor_priv->vbo_offset); + int j = 0; - vb[j++] = dst_coords[i * 2 + 0]; - vb[j++] = dst_coords[i * 2 + 1]; - if (glamor_priv->has_source_coords) { - vb[j++] = src_coords[i * 2 + 0]; - vb[j++] = src_coords[i * 2 + 1]; - } - if (glamor_priv->has_mask_coords) { - vb[j++] = mask_coords[i * 2 + 0]; - vb[j++] = mask_coords[i * 2 + 1]; - } + vb[j++] = dst_coords[i * 2 + 0]; + vb[j++] = dst_coords[i * 2 + 1]; + if (glamor_priv->has_source_coords) { + vb[j++] = src_coords[i * 2 + 0]; + vb[j++] = src_coords[i * 2 + 1]; + } + if (glamor_priv->has_mask_coords) { + vb[j++] = mask_coords[i * 2 + 0]; + vb[j++] = mask_coords[i * 2 + 1]; + } - glamor_priv->render_nr_verts++; - glamor_priv->vbo_offset += glamor_priv->vb_stride; + glamor_priv->render_nr_verts++; + glamor_priv->vbo_offset += glamor_priv->vb_stride; } static void glamor_flush_composite_rects(ScreenPtr screen) { - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - if (!glamor_priv->render_nr_verts) - return; + if (!glamor_priv->render_nr_verts) + return; - glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); - glamor_priv->vb = NULL; + glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + glamor_priv->vb = NULL; - glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts); - glamor_priv->render_nr_verts = 0; - glamor_priv->vbo_size = 0; + glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts); + glamor_priv->render_nr_verts = 0; + glamor_priv->vbo_size = 0; } static void @@ -646,31 +649,96 @@ glamor_emit_composite_rect(ScreenPtr screen, const float *mask_coords, const float *dst_coords) { - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride > - glamor_priv->vbo_size) + if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride > + glamor_priv->vbo_size) { - glamor_flush_composite_rects(screen); + glamor_flush_composite_rects(screen); } - if (glamor_priv->vbo_size == 0) { - if (glamor_priv->vbo == 0) - glGenBuffersARB(1, &glamor_priv->vbo); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); + if (glamor_priv->vbo_size == 0) { + if (glamor_priv->vbo == 0) + glGenBuffersARB(1, &glamor_priv->vbo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); - glamor_priv->vbo_size = 4096; - glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL, - GL_STREAM_DRAW_ARB); - glamor_priv->vbo_offset = 0; - glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - glamor_setup_composite_vbo(screen); - } + glamor_priv->vbo_size = 4096; + glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL, + GL_STREAM_DRAW_ARB); + glamor_priv->vbo_offset = 0; + glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + glamor_setup_composite_vbo(screen); + } - glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0); - glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1); - glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2); - glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3); +} + + +int pict_format_combine_tab[][3] = + { + {PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB}, + {PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR}, + }; + +static Bool +combine_pict_format(PictFormatShort *des, const PictFormatShort src, + const PictFormatShort mask, enum shader_in in_ca) +{ + PictFormatShort new_vis; + int src_type, mask_type, src_bpp, mask_bpp; + int i; + if (src == mask) { + *des = src; + return TRUE; + } + src_bpp = PICT_FORMAT_BPP(src); + mask_bpp = PICT_FORMAT_BPP(mask); + + assert(src_bpp == mask_bpp); + + new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask); + + switch(in_ca) { + case SHADER_IN_SOURCE_ONLY: + return TRUE; + case SHADER_IN_NORMAL: + src_type = PICT_FORMAT_TYPE(src); + mask_type = PICT_TYPE_A; + break; + case SHADER_IN_CA_SOURCE: + src_type = PICT_FORMAT_TYPE(src); + mask_type = PICT_FORMAT_TYPE(mask); + break; + case SHADER_IN_CA_ALPHA: + src_type = PICT_TYPE_A; + mask_type = PICT_FORMAT_TYPE(mask); + break; + default: + return FALSE; + } + + + if (src_type == mask_type) { + *des = PICT_VISFORMAT(src_bpp, src_type, new_vis); + return TRUE; + } + + for(i = 0; + i < sizeof(pict_format_combine_tab)/sizeof(pict_format_combine_tab[0]); + i++) + { + if ((src_type == pict_format_combine_tab[i][0] + && mask_type == pict_format_combine_tab[i][1]) + ||(src_type == pict_format_combine_tab[i][1] + && mask_type == pict_format_combine_tab[i][0])) { + *des = PICT_VISFORMAT(src_bpp, pict_format_combine_tab[i][2], new_vis); + return TRUE; + } + } + return FALSE; } static Bool @@ -681,302 +749,374 @@ glamor_composite_with_shader(CARD8 op, int nrect, glamor_composite_rect_t *rects) { - ScreenPtr screen = dest->pDrawable->pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); - PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; - glamor_pixmap_private *source_pixmap_priv = NULL; - glamor_pixmap_private *mask_pixmap_priv = NULL; - struct shader_key key; - glamor_composite_shader *shader; - RegionRec region; - float vertices[8], source_texcoords[8], mask_texcoords[8]; - int i; - BoxPtr box; - int dest_x_off, dest_y_off; - int source_x_off, source_y_off; - int mask_x_off, mask_y_off; + ScreenPtr screen = dest->pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); + PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; + glamor_pixmap_private *source_pixmap_priv = NULL; + glamor_pixmap_private *mask_pixmap_priv = NULL; + glamor_pixmap_private *dest_pixmap_priv = NULL; + struct shader_key key; + glamor_composite_shader *shader; + RegionRec region; + float vertices[8], source_texcoords[8], mask_texcoords[8]; + int i; + BoxPtr box; + int dest_x_off, dest_y_off; + int source_x_off, source_y_off; + int mask_x_off, mask_y_off; + enum glamor_pixmap_status source_status = GLAMOR_NONE; + enum glamor_pixmap_status mask_status = GLAMOR_NONE; + PictFormatShort saved_source_format = 0; + dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); - memset(&key, 0, sizeof(key)); - if (!source->pDrawable) { - if (source->pSourcePict->type == SourcePictTypeSolidFill) { - key.source = SHADER_SOURCE_SOLID; - } else { - glamor_fallback("gradient source\n"); - goto fail; - } + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { + glamor_fallback("dest has no fbo.\n"); + goto fail; + } + memset(&key, 0, sizeof(key)); + if (!source->pDrawable) { + if (source->pSourcePict->type == SourcePictTypeSolidFill) { + key.source = SHADER_SOURCE_SOLID; } else { - if (PICT_FORMAT_A(source->format) != 0) { - key.source = SHADER_SOURCE_TEXTURE_ALPHA; - } else { - key.source = SHADER_SOURCE_TEXTURE; - } + glamor_fallback("gradient source\n"); + goto fail; } - if (mask) { - if (!mask->pDrawable) { - if (mask->pSourcePict->type == SourcePictTypeSolidFill) { - key.mask = SHADER_MASK_SOLID; - } else { - glamor_fallback("gradient mask\n"); - goto fail; - } - } else { - if (PICT_FORMAT_A(mask->format) != 0) { - key.mask = SHADER_MASK_TEXTURE_ALPHA; - } else { - key.mask = SHADER_MASK_TEXTURE; - } - } - - if (!mask->componentAlpha) { - key.in = SHADER_IN_NORMAL; - } else { - /* We only handle two CA modes. */ - if (op == PictOpAdd) - key.in = SHADER_IN_CA_SOURCE; - else if (op == PictOpOutReverse) { - key.in = SHADER_IN_CA_ALPHA; - } else { - glamor_fallback("Unsupported component alpha op: %d\n", op); - goto fail; - } - } + } else { + key.source = SHADER_SOURCE_TEXTURE_ALPHA; + } + if (mask) { + if (!mask->pDrawable) { + if (mask->pSourcePict->type == SourcePictTypeSolidFill) { + key.mask = SHADER_MASK_SOLID; + } else { + glamor_fallback("gradient mask\n"); + goto fail; + } } else { - key.mask = SHADER_MASK_NONE; - key.in = SHADER_IN_SOURCE_ONLY; + key.mask = SHADER_MASK_TEXTURE_ALPHA; } - if (source->alphaMap) { - glamor_fallback("source alphaMap\n"); - goto fail; - } - if (mask && mask->alphaMap) { - glamor_fallback("mask alphaMap\n"); - goto fail; - } - - if (key.source == SHADER_SOURCE_TEXTURE || - key.source == SHADER_SOURCE_TEXTURE_ALPHA) { - source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); - source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); - if (source_pixmap == dest_pixmap) { - glamor_fallback("glamor_composite(): source == dest\n"); - goto fail; - } - if (!source_pixmap_priv || source_pixmap_priv->tex == 0) { - glamor_fallback("glamor_composite(): no texture in source\n"); - goto fail; - } - if (!good_source_format(source)) - goto fail; - } - if (key.mask == SHADER_MASK_TEXTURE || - key.mask == SHADER_MASK_TEXTURE_ALPHA) { - mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); - mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); - if (mask_pixmap == dest_pixmap) { - glamor_fallback("glamor_composite(): mask == dest\n"); - goto fail; - } - if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) { - glamor_fallback("glamor_composite(): no texture in mask\n"); - goto fail; - } - if (!good_mask_format(mask)) - goto fail; - } - if (!good_dest_format(dest)) - goto fail; - - shader = glamor_lookup_composite_shader(screen, &key); - if (shader->prog == 0) { - glamor_fallback("glamor_composite(): " - "no shader program for this render acccel mode\n"); - goto fail; - } - - glUseProgramObjectARB(shader->prog); - - if (!glamor_set_destination_pixmap(dest_pixmap)) - goto fail; - - if (!glamor_set_composite_op(screen, op, dest, mask)) { - goto fail; - } - - if (key.source == SHADER_SOURCE_SOLID) { - glamor_set_composite_solid(source, shader->source_uniform_location); + if (!mask->componentAlpha) { + key.in = SHADER_IN_NORMAL; } else { - glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); + /* We only handle two CA modes. */ + if (op == PictOpAdd) + key.in = SHADER_IN_CA_SOURCE; + else if (op == PictOpOutReverse) { + key.in = SHADER_IN_CA_ALPHA; + } else { + glamor_fallback("Unsupported component alpha op: %d\n", op); + goto fail; + } } - if (key.mask != SHADER_MASK_NONE) { - if (key.mask == SHADER_MASK_SOLID) { - glamor_set_composite_solid(mask, shader->mask_uniform_location); - } else { - glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); - } + } else { + key.mask = SHADER_MASK_NONE; + key.in = SHADER_IN_SOURCE_ONLY; + } + + if (source->alphaMap) { + glamor_fallback("source alphaMap\n"); + goto fail; + } + if (mask && mask->alphaMap) { + glamor_fallback("mask alphaMap\n"); + goto fail; + } + if (key.source == SHADER_SOURCE_TEXTURE || + key.source == SHADER_SOURCE_TEXTURE_ALPHA) { + source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + if (source_pixmap == dest_pixmap) { + glamor_fallback("source == dest\n"); + goto fail; + } + if (!source_pixmap_priv || source_pixmap_priv->gl_tex == 0) { +#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD + source_status = GLAMOR_UPLOAD_PENDING; +#else + glamor_fallback("no texture in source\n"); + goto fail; +#endif + } + if ((source_status != GLAMOR_UPLOAD_PENDING) + && !good_source_format(source)) { + goto fail; + } + } + if (key.mask == SHADER_MASK_TEXTURE || + key.mask == SHADER_MASK_TEXTURE_ALPHA) { + mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); + mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); + if (mask_pixmap == dest_pixmap) { + glamor_fallback("mask == dest\n"); + goto fail; + } + if (!mask_pixmap_priv || mask_pixmap_priv->gl_tex == 0) { +#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD + mask_status = GLAMOR_UPLOAD_PENDING; +#else + glamor_fallback("no texture in mask\n"); + goto fail; +#endif + } + if ((mask_status != GLAMOR_UPLOAD_PENDING) + && !good_mask_format(mask)) { + goto fail; + } + } + if (!good_dest_format(dest)) { + goto fail; + } + if (!glamor_set_composite_op(screen, op, dest, mask)) { + goto fail; + } + +#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD + if (source_status == GLAMOR_UPLOAD_PENDING + && mask_status == GLAMOR_UPLOAD_PENDING + && source_pixmap == mask_pixmap) { + + if (source->format != mask->format) { + saved_source_format = source->format; + /* XXX + * when need to flip the texture and mask and source share the same pixmap, + * there is a bug, need to be fixed. * + */ + if (!glamor_priv->yInverted) + goto fail; + if (!combine_pict_format(&source->format, source->format, mask->format, key.in)) { + glamor_fallback("combine source %x mask %x failed.\n", + source->format, mask->format); + goto fail; + } + if (source->format != saved_source_format) { + glamor_picture_format_fixup(source, source_pixmap_priv); + } + /* XXX + * By default, glamor_upload_picture_to_texture will wire alpha to 1 + * if one picture doesn't have alpha. So we don't do that again in + * rendering function. But here is a special case, as source and + * mask share the same texture but may have different formats. For + * example, source doesn't have alpha, but mask has alpha. Then the + * texture will have the alpha value for the mask. And will not wire + * to 1 for the source. In this case, we have to use different shader + * to wire the source's alpha to 1. + * + * But this may cause a potential problem if the source's repeat mode + * is REPEAT_NONE, and if the source is smaller than the dest, then + * for the region not covered by the source may be painted incorrectly. + * because we wire the alpha to 1. + * + **/ + if (!PICT_FORMAT_A(saved_source_format) && PICT_FORMAT_A(mask->format)) + key.source = SHADER_SOURCE_TEXTURE; + + if (!PICT_FORMAT_A(mask->format) && PICT_FORMAT_A(saved_source_format)) + key.mask = SHADER_MASK_TEXTURE; + + mask_status = GLAMOR_NONE; + } + source_status = glamor_upload_picture_to_texture(source); + + if (source_status != GLAMOR_UPLOAD_DONE) { + glamor_fallback("Failed to upload source texture.\n"); + goto fail; + } + } + else { + + if (source_status == GLAMOR_UPLOAD_PENDING) { + source_status = glamor_upload_picture_to_texture(source); + if (source_status != GLAMOR_UPLOAD_DONE) { + glamor_fallback("Failed to upload source texture.\n"); + goto fail; + } } - glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; - glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && - key.mask != SHADER_MASK_SOLID); - - glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, - &dest_x_off, &dest_y_off); - if (source_pixmap) { - glamor_get_drawable_deltas(source->pDrawable, source_pixmap, - &source_x_off, &source_y_off); + if (mask_status == GLAMOR_UPLOAD_PENDING) { + mask_status = glamor_upload_picture_to_texture(mask); + if (mask_status != GLAMOR_UPLOAD_DONE) { + glamor_fallback("Failed to upload mask texture.\n"); + goto fail; + } } - if (mask_pixmap) { - glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, - &mask_x_off, &mask_y_off); - } - - while (nrect--) { - INT16 x_source; - INT16 y_source; - INT16 x_mask; - INT16 y_mask; - INT16 x_dest; - INT16 y_dest; - CARD16 width; - CARD16 height; - - x_dest = rects->x_dst; - y_dest = rects->y_dst; - x_source = rects->x_src; - y_source = rects->y_src; - x_mask = rects->x_mask; - y_mask = rects->y_mask; - width = rects->width; - height = rects->height; - - x_dest += dest->pDrawable->x; - y_dest += dest->pDrawable->y; - if (source->pDrawable) { - x_source += source->pDrawable->x; - y_source += source->pDrawable->y; - } - if (mask && mask->pDrawable) { - x_mask += mask->pDrawable->x; - y_mask += mask->pDrawable->y; - } - - if (!miComputeCompositeRegion(®ion, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height)) - continue; - - x_source += source_x_off; - y_source += source_y_off; - x_mask += mask_x_off; - y_mask += mask_y_off; - - box = REGION_RECTS(®ion); - for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { - vertices[0] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); - vertices[2] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[4] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[6] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); - - if (glamor_priv->yInverted) { - vertices[1] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[3] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[5] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y2 + dest_y_off); - vertices[7] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y2 + dest_y_off); - - } else { - vertices[1] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[3] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[5] = v_from_x_coord_y(dest_pixmap, - box[i].y2 + dest_y_off); - vertices[7] = v_from_x_coord_y(dest_pixmap, - box[i].y2 + dest_y_off); - } - if (key.source != SHADER_SOURCE_SOLID) { - int tx1 = box[i].x1 + x_source - x_dest; - int ty1 = box[i].y1 + y_source - y_dest; - int tx2 = box[i].x2 + x_source - x_dest; - int ty2 = box[i].y2 + y_source - y_dest; - - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 0, tx1, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 2, tx2, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 4, tx2, ty2); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 6, tx1, ty2); - } - - if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { - float tx1 = box[i].x1 + x_mask - x_dest; - float ty1 = box[i].y1 + y_mask - y_dest; - float tx2 = box[i].x2 + x_mask - x_dest; - float ty2 = box[i].y2 + y_mask - y_dest; - - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 0, tx1, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 2, tx2, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 4, tx2, ty2); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 6, tx1, ty2); - } -#if 0 - else memset(mask_texcoords, 0, sizeof(mask_texcoords)); - for (i = 0; i < 4; i++) { - ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) " - "(%04.4f, %04.4f)\n", - i, - source_texcoords[i][0], source_texcoords[i][1], - mask_texcoords[i][0], mask_texcoords[i][1], - vertices[i][0], vertices[i][1]); - } + } #endif - glamor_emit_composite_rect(screen, source_texcoords, - mask_texcoords, vertices); - } - rects++; + glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); + + shader = glamor_lookup_composite_shader(screen, &key); + if (shader->prog == 0) { + glamor_fallback("no shader program for this render acccel mode\n"); + goto fail; + } + + glUseProgramObjectARB(shader->prog); + if (key.source == SHADER_SOURCE_SOLID) { + glamor_set_composite_solid(source, shader->source_uniform_location); + } else { + glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); + } + if (key.mask != SHADER_MASK_NONE) { + if (key.mask == SHADER_MASK_SOLID) { + glamor_set_composite_solid(mask, shader->mask_uniform_location); + } else { + glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); + } + } + + glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; + glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && + key.mask != SHADER_MASK_SOLID); + + glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, + &dest_x_off, &dest_y_off); + if (source_pixmap) { + glamor_get_drawable_deltas(source->pDrawable, source_pixmap, + &source_x_off, &source_y_off); + } + if (mask_pixmap) { + glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, + &mask_x_off, &mask_y_off); + } + while (nrect--) { + INT16 x_source; + INT16 y_source; + INT16 x_mask; + INT16 y_mask; + INT16 x_dest; + INT16 y_dest; + CARD16 width; + CARD16 height; + + x_dest = rects->x_dst; + y_dest = rects->y_dst; + x_source = rects->x_src; + y_source = rects->y_src; + x_mask = rects->x_mask; + y_mask = rects->y_mask; + width = rects->width; + height = rects->height; + + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + if (source->pDrawable) { + x_source += source->pDrawable->x; + y_source += source->pDrawable->y; + } + if (mask && mask->pDrawable) { + x_mask += mask->pDrawable->x; + y_mask += mask->pDrawable->y; } - glamor_flush_composite_rects(screen); + if (!miComputeCompositeRegion(®ion, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height)) + continue; - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); + x_source += source_x_off; + y_source += source_y_off; + x_mask += mask_x_off; + y_mask += mask_y_off; - REGION_UNINIT(dst->pDrawable->pScreen, ®ion); - glDisable(GL_BLEND); - glActiveTexture(GL_TEXTURE0); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glUseProgramObjectARB(0); - return TRUE; + box = REGION_RECTS(®ion); + for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { + vertices[0] = v_from_x_coord_x(dest_pixmap, + box[i].x1 + dest_x_off); + vertices[2] = v_from_x_coord_x(dest_pixmap, + box[i].x2 + dest_x_off); + vertices[4] = v_from_x_coord_x(dest_pixmap, + box[i].x2 + dest_x_off); + vertices[6] = v_from_x_coord_x(dest_pixmap, + box[i].x1 + dest_x_off); -fail: - glDisable(GL_BLEND); - glUseProgramObjectARB(0); - return FALSE; + if (glamor_priv->yInverted) { + vertices[1] = v_from_x_coord_y_inverted(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[3] = v_from_x_coord_y_inverted(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[5] = v_from_x_coord_y_inverted(dest_pixmap, + box[i].y2 + dest_y_off); + vertices[7] = v_from_x_coord_y_inverted(dest_pixmap, + box[i].y2 + dest_y_off); + + } else { + vertices[1] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[3] = v_from_x_coord_y(dest_pixmap, + box[i].y1 + dest_y_off); + vertices[5] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); + vertices[7] = v_from_x_coord_y(dest_pixmap, + box[i].y2 + dest_y_off); + } + if (key.source != SHADER_SOURCE_SOLID) { + int tx1 = box[i].x1 + x_source - x_dest; + int ty1 = box[i].y1 + y_source - y_dest; + int tx2 = box[i].x2 + x_source - x_dest; + int ty2 = box[i].y2 + y_source - y_dest; + + glamor_set_transformed_point(source, source_pixmap, + source_texcoords + 0, tx1, ty1); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords + 2, tx2, ty1); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords + 4, tx2, ty2); + glamor_set_transformed_point(source, source_pixmap, + source_texcoords + 6, tx1, ty2); + } + + if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { + float tx1 = box[i].x1 + x_mask - x_dest; + float ty1 = box[i].y1 + y_mask - y_dest; + float tx2 = box[i].x2 + x_mask - x_dest; + float ty2 = box[i].y2 + y_mask - y_dest; + + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords + 0, tx1, ty1); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords + 2, tx2, ty1); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords + 4, tx2, ty2); + glamor_set_transformed_point(mask, mask_pixmap, + mask_texcoords + 6, tx1, ty2); + } + glamor_emit_composite_rect(screen, source_texcoords, + mask_texcoords, vertices); + } + rects++; + } + glamor_flush_composite_rects(screen); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + REGION_UNINIT(dst->pDrawable->pScreen, ®ion); + glDisable(GL_BLEND); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glUseProgramObjectARB(0); + if (saved_source_format) + source->format = saved_source_format; + return TRUE; + + fail: + if (saved_source_format) + source->format = saved_source_format; + + glDisable(GL_BLEND); + glUseProgramObjectARB(0); + return FALSE; } void @@ -993,83 +1133,81 @@ glamor_composite(CARD8 op, CARD16 width, CARD16 height) { - glamor_composite_rect_t rect; + glamor_composite_rect_t rect; - /* Do two-pass PictOpOver componentAlpha, until we enable - * dual source color blending. - */ - if (mask && mask->componentAlpha) { - if (op == PictOpOver) { - glamor_composite(PictOpOutReverse, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - glamor_composite(PictOpAdd, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - return; - } else if (op != PictOpAdd && op != PictOpOutReverse) { - glamor_fallback("glamor_composite(): component alpha\n"); - goto fail; - } + /* Do two-pass PictOpOver componentAlpha, until we enable + * dual source color blending. + */ + if (mask && mask->componentAlpha) { + if (op == PictOpOver) { + glamor_composite(PictOpOutReverse, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + glamor_composite(PictOpAdd, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + return; + } else if (op != PictOpAdd && op != PictOpOutReverse) { + glamor_fallback("glamor_composite(): component alpha\n"); + goto fail; } + } - if (!mask) { - if (glamor_composite_with_copy(op, source, dest, - x_source, y_source, - x_dest, y_dest, - width, height)) - return; - } + if (!mask) { + if (glamor_composite_with_copy(op, source, dest, + x_source, y_source, + x_dest, y_dest, + width, height)) + return; + } - rect.x_src = x_source; - rect.y_src = y_source; - rect.x_mask = x_mask; - rect.y_mask = y_mask; - rect.x_dst = x_dest; - rect.y_dst = y_dest; - rect.width = width; - rect.height = height; - if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect)) - return; + rect.x_src = x_source; + rect.y_src = y_source; + rect.x_mask = x_mask; + rect.y_mask = y_mask; + rect.x_dst = x_dest; + rect.y_dst = y_dest; + rect.width = width; + rect.height = height; + if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect)) + return; -fail: - glamor_fallback("glamor_composite(): " - "from picts %p/%p(%c,%c) to pict %p (%c)\n", - source, mask, - glamor_get_picture_location(source), - glamor_get_picture_location(mask), - dest, - glamor_get_picture_location(dest)); + fail: + glamor_fallback("glamor_composite(): " + "from picts %p/%p(%c,%c) to pict %p (%c)\n", + source, mask, + glamor_get_picture_location(source), + glamor_get_picture_location(mask), + dest, + glamor_get_picture_location(dest)); - glUseProgramObjectARB(0); - glDisable(GL_BLEND); - if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) { - if (source->pDrawable == NULL || - glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO)) - { - if (!mask || mask->pDrawable == NULL || - glamor_prepare_access(mask->pDrawable, GLAMOR_ACCESS_RO)) - { - fbComposite(op, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - if (mask && mask->pDrawable != NULL) - glamor_finish_access(mask->pDrawable); - } - if (source->pDrawable != NULL) - glamor_finish_access(source->pDrawable); - } - glamor_finish_access(dest->pDrawable); - } + glUseProgramObjectARB(0); + glDisable(GL_BLEND); + if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO)) + { + if (!mask || + glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) + { + fbComposite(op, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, + width, height); + if (mask) + glamor_finish_access_picture(mask); + } + glamor_finish_access_picture(source); + } + glamor_finish_access_picture(dest); + } } @@ -1084,28 +1222,28 @@ glamor_create_mask_picture(ScreenPtr screen, CARD16 width, CARD16 height) { - PixmapPtr pixmap; - PicturePtr picture; - int error; + PixmapPtr pixmap; + PicturePtr picture; + int error; - if (!pict_format) { - if (dst->polyEdge == PolyEdgeSharp) - pict_format = PictureMatchFormat(screen, 1, PICT_a1); - else - pict_format = PictureMatchFormat(screen, 8, PICT_a8); - if (!pict_format) - return 0; - } + if (!pict_format) { + if (dst->polyEdge == PolyEdgeSharp) + pict_format = PictureMatchFormat(screen, 1, PICT_a1); + else + pict_format = PictureMatchFormat(screen, 8, PICT_a8); + if (!pict_format) + return 0; + } - pixmap = screen->CreatePixmap(screen, width, height, - pict_format->depth, - 0); - if (!pixmap) - return 0; - picture = CreatePicture(0, &pixmap->drawable, pict_format, - 0, 0, serverClient, &error); - screen->DestroyPixmap(pixmap); - return picture; + pixmap = screen->CreatePixmap(screen, width, height, + pict_format->depth, + 0); + if (!pixmap) + return 0; + picture = CreatePicture(0, &pixmap->drawable, pict_format, + 0, 0, serverClient, &error); + screen->DestroyPixmap(pixmap); + return picture; } /** @@ -1118,94 +1256,94 @@ glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps) { - ScreenPtr screen = dst->pDrawable->pScreen; - BoxRec bounds; - PicturePtr picture; - INT16 x_dst, y_dst; - INT16 x_rel, y_rel; - int width, height, stride; - PixmapPtr pixmap; - GCPtr gc; - pixman_image_t *image; - - /* If a mask format wasn't provided, we get to choose, but behavior should - * be as if there was no temporary mask the traps were accumulated into. - */ - if (!mask_format) { - if (dst->polyEdge == PolyEdgeSharp) - mask_format = PictureMatchFormat(screen, 1, PICT_a1); - else - mask_format = PictureMatchFormat(screen, 8, PICT_a8); - for (; ntrap; ntrap--, traps++) - glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, - 1, traps); - return; - } - - miTrapezoidBounds(ntrap, traps, &bounds); - - if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) - return; - - x_dst = traps[0].left.p1.x >> 16; - y_dst = traps[0].left.p1.y >> 16; - - width = bounds.x2 - bounds.x1; - height = bounds.y2 - bounds.y1; - stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8; - - picture = glamor_create_mask_picture(screen, dst, mask_format, - width, height); - if (!picture) - return; - - image = pixman_image_create_bits(picture->format, - width, height, - NULL, stride); - if (!image) { - FreePicture(picture, 0); - return; - } + ScreenPtr screen = dst->pDrawable->pScreen; + BoxRec bounds; + PicturePtr picture; + INT16 x_dst, y_dst; + INT16 x_rel, y_rel; + int width, height, stride; + PixmapPtr pixmap; + GCPtr gc; + pixman_image_t *image; + /* If a mask format wasn't provided, we get to choose, but behavior should + * be as if there was no temporary mask the traps were accumulated into. + */ + if (!mask_format) { + if (dst->polyEdge == PolyEdgeSharp) + mask_format = PictureMatchFormat(screen, 1, PICT_a1); + else + mask_format = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) - pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, - -bounds.x1, -bounds.y1); + glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, + 1, traps); + return; + } - pixmap = GetScratchPixmapHeader(screen, width, height, - mask_format->depth, - BitsPerPixel(mask_format->depth), - PixmapBytePad(width, mask_format->depth), - pixman_image_get_data(image)); - if (!pixmap) { - FreePicture(picture, 0); - pixman_image_unref(image); - return; - } + miTrapezoidBounds(ntrap, traps, &bounds); - gc = GetScratchGC(picture->pDrawable->depth, screen); - if (!gc) { - FreeScratchPixmapHeader(pixmap); - pixman_image_unref (image); - FreePicture(picture, 0); - return; - } - ValidateGC(picture->pDrawable, gc); + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return; - gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable, - gc, 0, 0, width, height, 0, 0); + x_dst = traps[0].left.p1.x >> 16; + y_dst = traps[0].left.p1.y >> 16; - FreeScratchGC(gc); - FreeScratchPixmapHeader(pixmap); - pixman_image_unref(image); + width = bounds.x2 - bounds.x1; + height = bounds.y2 - bounds.y1; + stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8; - x_rel = bounds.x1 + x_src - x_dst; - y_rel = bounds.y1 + y_src - y_dst; - CompositePicture(op, src, picture, dst, - x_rel, y_rel, - 0, 0, - bounds.x1, bounds.y1, - bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + picture = glamor_create_mask_picture(screen, dst, mask_format, + width, height); + if (!picture) + return; + + image = pixman_image_create_bits(picture->format, + width, height, + NULL, stride); + if (!image) { FreePicture(picture, 0); + return; + } + + for (; ntrap; ntrap--, traps++) + pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, + -bounds.x1, -bounds.y1); + + pixmap = GetScratchPixmapHeader(screen, width, height, + mask_format->depth, + BitsPerPixel(mask_format->depth), + PixmapBytePad(width, mask_format->depth), + pixman_image_get_data(image)); + if (!pixmap) { + FreePicture(picture, 0); + pixman_image_unref(image); + return; + } + + gc = GetScratchGC(picture->pDrawable->depth, screen); + if (!gc) { + FreeScratchPixmapHeader(pixmap); + pixman_image_unref (image); + FreePicture(picture, 0); + return; + } + ValidateGC(picture->pDrawable, gc); + + gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable, + gc, 0, 0, width, height, 0, 0); + + FreeScratchGC(gc); + FreeScratchPixmapHeader(pixmap); + pixman_image_unref(image); + + x_rel = bounds.x1 + x_src - x_dst; + y_rel = bounds.y1 + y_src - y_dst; + CompositePicture(op, src, picture, dst, + x_rel, y_rel, + 0, 0, + bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + FreePicture(picture, 0); } void @@ -1213,29 +1351,29 @@ glamor_composite_rects(CARD8 op, PicturePtr src, PicturePtr dst, int nrect, glamor_composite_rect_t *rects) { - int n; - glamor_composite_rect_t *r; + int n; + glamor_composite_rect_t *r; - ValidatePicture(src); - ValidatePicture(dst); + ValidatePicture(src); + ValidatePicture(dst); - if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects)) - return; + if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects)) + return; - n = nrect; - r = rects; + n = nrect; + r = rects; - while (n--) { - CompositePicture(op, - src, - NULL, - dst, - r->x_src, r->y_src, - 0, 0, - r->x_dst, r->y_dst, - r->width, r->height); - r++; - } + while (n--) { + CompositePicture(op, + src, + NULL, + dst, + r->x_src, r->y_src, + 0, 0, + r->x_dst, r->y_dst, + r->width, r->height); + r++; + } } #endif /* RENDER */ diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 6c1c2ff3f..253f20345 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -37,46 +37,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, { PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; - uint8_t *temp_src = NULL, *drawpixels_src = (uint8_t *)src; - int i, j; - int wmax = 0; + int ax, i; + uint8_t *drawpixels_src = (uint8_t *)src; RegionPtr clip = fbGetCompositeClip(gc); BoxRec *pbox; int x_off, y_off; - goto fail; - - for (i = 0 ; i < n; i++) { - if (wmax < widths[i]) - wmax = widths[i]; + if (glamor_get_tex_format_type_from_pixmap(dest_pixmap, + &format, + &type, + &ax + )) { + glamor_fallback("unknown depth. %d \n", + drawable->depth); + goto fail; } - switch (drawable->depth) { - case 1: - temp_src = malloc(wmax); - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - drawpixels_src = temp_src; - break; - case 8: - format = GL_ALPHA; - type = GL_UNSIGNED_BYTE; - break; - case 24: - format = GL_RGB; - type = GL_UNSIGNED_BYTE; - break; - case 32: - format = GL_BGRA; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - default: - glamor_fallback("glamor_set_spans()Unknown depth %d\n", - drawable->depth); - goto fail; - } - - if (!glamor_set_destination_pixmap(dest_pixmap)) + if (glamor_set_destination_pixmap(dest_pixmap)) goto fail; if (!glamor_set_planemask(dest_pixmap, gc->planemask)) goto fail; @@ -87,14 +64,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off); for (i = 0; i < n; i++) { - if (temp_src) { - for (j = 0; j < widths[i]; j++) { - if (src[j / 8] & (1 << (j % 8))) - temp_src[j] = 0xff; - else - temp_src[j] = 0; - } - } n = REGION_NUM_RECTS(clip); pbox = REGION_RECTS(clip); @@ -113,19 +82,14 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, format, type, drawpixels_src); } - if (temp_src) { - src += PixmapBytePad(widths[i], drawable->depth); - } else { drawpixels_src += PixmapBytePad(widths[i], drawable->depth); - } } fail: glDisable(GL_SCISSOR_TEST); glamor_set_planemask(dest_pixmap, ~0); glamor_set_alu(GXcopy); - free(temp_src); - glamor_fallback("glamor_set_spans(): to %p (%c)\n", + glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbSetSpans(drawable, gc, src, points, widths, n, sorted); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 5b1e73d5a..2991eddd5 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -91,24 +91,26 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile); float vertices[4][2]; float source_texcoords[4][2]; - if (glamor_priv->tile_prog == 0) { glamor_fallback("Tiling unsupported\n"); goto fail; } - if (!glamor_set_destination_pixmap(pixmap)) + if (glamor_set_destination_pixmap(pixmap)) { + glamor_fallback("dest has no fbo."); goto fail; + } - if (tile_priv->tex == 0) { + if (tile_priv->gl_tex == 0) { glamor_fallback("Non-texture tile pixmap\n"); goto fail; } - if (!glamor_set_planemask(pixmap, planemask)) + if (!glamor_set_planemask(pixmap, planemask)) { + glamor_fallback("unsupported planemask %lx\n", planemask); goto fail; + } glamor_set_alu(alu); - glUseProgramObjectARB(glamor_priv->tile_prog); glActiveTexture(GL_TEXTURE0); diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c index 027cfc52f..53bfbb995 100644 --- a/hw/kdrive/ephyr/ephyr_glamor.c +++ b/hw/kdrive/ephyr/ephyr_glamor.c @@ -45,7 +45,7 @@ ephyr_glamor_init(ScreenPtr screen) ephyr_glamor_host_create_context(kd_screen); - glamor_init(screen, 0); + glamor_init(screen, GLAMOR_HOSTX); return TRUE; } diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 665cd0aea..d0432b31e 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -113,8 +113,7 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); - glamor_set_pixmap_texture(screen->GetScreenPixmap(screen), - width, height, texture); + glamor_set_screen_pixmap_texture(screen, width, height, texture); glamor->root = image; scrn->virtualX = width; scrn->virtualY = height; From ca1908e11dcb56cb952f6bce55503e932aa9a27c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 22 Jun 2011 14:33:38 +0800 Subject: [PATCH 134/225] glamor: Concentrate and reduce some coords processing code. Concentrate the verties and texture coords processing code to a new file glamor_utils.h. Change most of the code to macro. Will have some performance benefit on slow machine. And reduce most of the duplicate code when calculate the normalized coords. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 52 +++++++--------- glamor/glamor_fill.c | 32 ++++------ glamor/glamor_getspans.c | 16 +++-- glamor/glamor_priv.h | 41 +------------ glamor/glamor_putimage.c | 106 +++++++++++++++------------------ glamor/glamor_render.c | 119 ++++++++++++------------------------- glamor/glamor_tile.c | 72 +++++++++++------------ glamor/glamor_utils.h | 124 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 287 insertions(+), 275 deletions(-) create mode 100644 glamor/glamor_utils.h diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 766c9e2b3..55437715a 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -199,11 +199,13 @@ glamor_copy_n_to_n_textured(DrawablePtr src, PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int i; - float vertices[4][2], texcoords[4][2]; + float vertices[8], texcoords[8]; glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv; int src_x_off, src_y_off, dst_x_off, dst_y_off; enum glamor_pixmap_status src_status = GLAMOR_NONE; + GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; + src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); @@ -237,6 +239,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src, } glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); + pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); @@ -258,42 +263,25 @@ glamor_copy_n_to_n_textured(DrawablePtr src, assert(GLEW_ARB_fragment_shader); glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); + for (i = 0; i < nbox; i++) { - vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off); - vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off); - vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off); - vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off); - texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); - texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); - texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx); - texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx); + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, + box[i].x1 + dst_x_off, + box[i].y1 + dst_y_off, + box[i].x2 + dst_x_off, + box[i].y2 + dst_y_off, + glamor_priv->yInverted, + vertices); - if(glamor_priv->yInverted) { + glamor_set_normalize_tcoords(src_xscale, src_yscale, + box[i].x1 + dx, box[i].y1 + dy, + box[i].x2 + dx, box[i].y2 + dy, + glamor_priv->yInverted, + texcoords); - vertices[0][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off); - vertices[1][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off); - vertices[2][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off); - vertices[3][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off); - - texcoords[0][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy); - texcoords[1][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy); - texcoords[2][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy); - texcoords[3][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy); - } else { - - vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); - vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off); - vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off); - vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off); - - texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); - texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy); - texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); - texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy); - } - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glUseProgramObjectARB(0); diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index fade2b3cd..48f85ce38 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -146,14 +146,16 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int x1 = x; int x2 = x + width; int y1 = y; int y2 = y + height; GLfloat color[4]; - float vertices[4][2]; - - if (glamor_set_destination_pixmap(pixmap)) { + float vertices[8]; + GLfloat xscale, yscale; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("dest has no fbo.\n"); goto fail; } @@ -162,6 +164,9 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glamor_fallback("Failedto set planemask in glamor_solid.\n"); goto fail; } + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_rgba_from_pixel(fg_pixel, &color[0], @@ -174,22 +179,11 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - vertices[0][0] = v_from_x_coord_x(pixmap, x1); - vertices[1][0] = v_from_x_coord_x(pixmap, x2); - vertices[2][0] = v_from_x_coord_x(pixmap, x2); - vertices[3][0] = v_from_x_coord_x(pixmap, x1); - - if (glamor_priv->yInverted) { - vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1); - vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1); - vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2); - vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2); - } else { - vertices[0][1] = v_from_x_coord_y(pixmap, y1); - vertices[1][1] = v_from_x_coord_y(pixmap, y1); - vertices[2][1] = v_from_x_coord_y(pixmap, y2); - vertices[3][1] = v_from_x_coord_y(pixmap, y2); - } + pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); + + glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, + glamor_priv->yInverted, + vertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 10fa2a2c3..7fe05f993 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -42,11 +42,17 @@ glamor_get_spans(DrawablePtr drawable, PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; int ax; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(drawable->pScreen); + glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int i; uint8_t *readpixels_dst = (uint8_t *)dst; int x_off, y_off; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { + glamor_fallback("pixmap has no fbo.\n"); + goto fail; + } + if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, @@ -57,10 +63,8 @@ glamor_get_spans(DrawablePtr drawable, goto fail; } - if (glamor_set_destination_pixmap(pixmap)) { - glamor_fallback("pixmap has no fbo.\n"); - goto fail; - } + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); for (i = 0; i < count; i++) { if (glamor_priv->yInverted) { diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index cf293b5dc..5b457e7fc 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -505,44 +505,6 @@ glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) extern int glamor_debug_level; -static inline float -v_from_x_coord_x(PixmapPtr pixmap, int x) -{ - return (float)x / pixmap->drawable.width * 2.0 - 1.0; -} - -static inline float -v_from_x_coord_y(PixmapPtr pixmap, int y) -{ - return (float)y / pixmap->drawable.height * -2.0 + 1.0; -} - -static inline float -v_from_x_coord_y_inverted(PixmapPtr pixmap, int y) -{ - return (float)y / pixmap->drawable.height * 2.0 - 1.0; -} - - -static inline float -t_from_x_coord_x(PixmapPtr pixmap, int x) -{ - return (float)x / pixmap->drawable.width; -} - -static inline float -t_from_x_coord_y(PixmapPtr pixmap, int y) -{ - return 1.0 - (float)y / pixmap->drawable.height; -} - -static inline float -t_from_x_coord_y_inverted(PixmapPtr pixmap, int y) -{ - return (float)y / pixmap->drawable.height; -} - - /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); @@ -791,4 +753,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD + +#include"glamor_utils.h" + #endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index d056576a0..e61425d11 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -87,17 +87,6 @@ glamor_init_putimage_shaders(ScreenPtr screen) glUseProgramObjectARB(0); } -static int -y_flip(PixmapPtr pixmap, int y) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (pixmap == screen_pixmap) - return (pixmap->drawable.height - 1) - y; - else - return y; -} /* Do an XYBitmap putimage. The bits are byte-aligned rows of bitmap * data (where each row starts at a bit index of left_pad), and the @@ -110,6 +99,21 @@ y_flip(PixmapPtr pixmap, int y) * case we might be better off just doing the fg/bg choosing in the CPU * and just draw the resulting texture to the destination. */ +#if 0 + +static int +y_flip(PixmapPtr pixmap, int y) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + + if (pixmap == screen_pixmap) + return (pixmap->drawable.height - 1) - y; + else + return y; +} + + static void glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, int x, int y, int w, int h, int left_pad, @@ -124,25 +128,27 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, RegionPtr clip; BoxPtr box; int nbox; - float dest_coords[4][2]; + float dest_coords[8]; const float bitmap_coords[8] = { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, }; + GLfloat xscale, yscale; + glamor_pixmap_private *pixmap_priv; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); - dest_coords[0][0] = v_from_x_coord_x(pixmap, x); - dest_coords[0][1] = v_from_x_coord_y(pixmap, y); - dest_coords[1][0] = v_from_x_coord_x(pixmap, x + w); - dest_coords[1][1] = v_from_x_coord_y(pixmap, y); - dest_coords[2][0] = v_from_x_coord_x(pixmap, x + w); - dest_coords[2][1] = v_from_x_coord_y(pixmap, y + h); - dest_coords[3][0] = v_from_x_coord_x(pixmap, x); - dest_coords[3][1] = v_from_x_coord_y(pixmap, y + h); + glamor_set_normalize_vcoords(xscale, yscale, + x, y, + x + w, y + h, + glamor_priv->yInverted, + dest_coords); - glamor_fallback("glamor_put_image_xybitmap: disabled\n"); + glamor_fallback("glamor_put_image_xybitmap: disabled\n"); goto fail; if (glamor_priv->put_image_xybitmap_prog == 0) { @@ -237,6 +243,8 @@ fail: glamor_finish_access(drawable); } } +#endif + void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, @@ -252,13 +260,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int nbox; int src_stride = PixmapBytePad(w, drawable->depth); int x_off, y_off; - float vertices[4][2], texcoords[4][2]; + float vertices[8], texcoords[8]; + GLfloat xscale, yscale, txscale, tyscale; GLuint tex; int ax = 0; if (image_format == XYBitmap) { assert(depth == 1); - glamor_put_image_xybitmap(drawable, gc, x, y, w, h, - left_pad, image_format, bits); + goto fail; return; } @@ -319,8 +327,12 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, y += drawable->y; glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - clip = fbGetCompositeClip(gc); + + txscale = 1.0/w; + tyscale = 1.0/h; + pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); + for (nbox = REGION_NUM_RECTS(clip), pbox = REGION_RECTS(clip); nbox--; @@ -330,7 +342,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int y1 = y; int x2 = x + w; int y2 = y + h; - float src_x1, src_x2, src_y1, src_y2; if (x1 < pbox->x1) x1 = pbox->x1; @@ -343,41 +354,18 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (x1 >= x2 || y1 >= y2) continue; - src_x1 = (float)(x1 - x) / w; - src_y1 = (float)(y1 - y) / h; - src_x2 = (float)(x2 - x) / w; - src_y2 = (float)(y2 - y) / h; + glamor_set_normalize_tcoords( txscale, tyscale, + x1 - x, y1 - y, + x2 - x, y2 - y, + 1, + texcoords); - vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off); - vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off); - vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off); - vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off); + glamor_set_normalize_vcoords( xscale, yscale, + x1 + x_off, y1 + y_off, + x2 + x_off, y2 + y_off, + glamor_priv->yInverted, + vertices); - texcoords[0][0] = src_x1; - texcoords[0][1] = src_y1; - texcoords[1][0] = src_x2; - texcoords[1][1] = src_y1; - texcoords[2][0] = src_x2; - texcoords[2][1] = src_y2; - texcoords[3][0] = src_x1; - texcoords[3][1] = src_y2; - - - if (glamor_priv->yInverted) { - - vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off); - vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off); - vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off); - vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off); - - } else { - - vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off); - vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off); - vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off); - vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off); - - } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index ca27b4d59..f991b0f17 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -533,41 +533,6 @@ good_dest_format(PicturePtr picture) } } -static inline float -xFixedToFloat(pixman_fixed_t val) -{ - return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)); -} - -static void -glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap, - float *texcoord, int x, int y) -{ - float result[3]; - int i; - float tx, ty; - ScreenPtr screen = picture->pDrawable->pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - - if (picture->transform) { - for (i = 0; i < 3; i++) { - result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x + - xFixedToFloat(picture->transform->matrix[i][1]) * y + - xFixedToFloat(picture->transform->matrix[i][2])); - } - tx = result[0] / result[2]; - ty = result[1] / result[2]; - } else { - tx = x; - ty = y; - } - texcoord[0] = t_from_x_coord_x(pixmap, tx); - if (glamor_priv->yInverted) - texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty); - else - texcoord[1] = t_from_x_coord_y(pixmap, ty); -} - static void glamor_setup_composite_vbo(ScreenPtr screen) { @@ -756,6 +721,8 @@ glamor_composite_with_shader(CARD8 op, glamor_pixmap_private *source_pixmap_priv = NULL; glamor_pixmap_private *mask_pixmap_priv = NULL; glamor_pixmap_private *dest_pixmap_priv = NULL; + GLfloat dst_xscale, dst_yscale; + GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1; struct shader_key key; glamor_composite_shader *shader; RegionRec region; @@ -768,6 +735,8 @@ glamor_composite_with_shader(CARD8 op, enum glamor_pixmap_status source_status = GLAMOR_NONE; enum glamor_pixmap_status mask_status = GLAMOR_NONE; PictFormatShort saved_source_format = 0; + float src_matrix[9], mask_matrix[9]; + dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { @@ -972,14 +941,24 @@ glamor_composite_with_shader(CARD8 op, glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, &dest_x_off, &dest_y_off); + pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale); + + + if (source_pixmap) { glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &source_x_off, &source_y_off); + pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale); + glamor_picture_get_matrixf(source, src_matrix); } + if (mask_pixmap) { glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &mask_x_off, &mask_y_off); + pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale); + glamor_picture_get_matrixf(mask, mask_matrix); } + while (nrect--) { INT16 x_source; INT16 y_source; @@ -1025,65 +1004,41 @@ glamor_composite_with_shader(CARD8 op, box = REGION_RECTS(®ion); for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { - vertices[0] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); - vertices[2] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[4] = v_from_x_coord_x(dest_pixmap, - box[i].x2 + dest_x_off); - vertices[6] = v_from_x_coord_x(dest_pixmap, - box[i].x1 + dest_x_off); + int vx1 = box[i].x1 + dest_x_off; + int vx2 = box[i].x2 + dest_x_off; + int vy1 = box[i].y1 + dest_y_off; + int vy2 = box[i].y2 + dest_y_off; + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, + glamor_priv->yInverted, vertices); - if (glamor_priv->yInverted) { - vertices[1] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[3] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[5] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y2 + dest_y_off); - vertices[7] = v_from_x_coord_y_inverted(dest_pixmap, - box[i].y2 + dest_y_off); - - } else { - vertices[1] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[3] = v_from_x_coord_y(dest_pixmap, - box[i].y1 + dest_y_off); - vertices[5] = v_from_x_coord_y(dest_pixmap, - box[i].y2 + dest_y_off); - vertices[7] = v_from_x_coord_y(dest_pixmap, - box[i].y2 + dest_y_off); - } if (key.source != SHADER_SOURCE_SOLID) { int tx1 = box[i].x1 + x_source - x_dest; int ty1 = box[i].y1 + y_source - y_dest; int tx2 = box[i].x2 + x_source - x_dest; int ty2 = box[i].y2 + y_source - y_dest; - - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 0, tx1, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 2, tx2, ty1); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 4, tx2, ty2); - glamor_set_transformed_point(source, source_pixmap, - source_texcoords + 6, tx1, ty2); - } + if (source->transform) + glamor_set_transformed_normalize_tcoords(src_matrix, src_xscale, src_yscale, + tx1, ty1, tx2, ty2, + glamor_priv->yInverted, + source_texcoords); + else + glamor_set_normalize_tcoords(src_xscale, src_yscale, tx1, ty1, tx2, ty2, + glamor_priv->yInverted, source_texcoords); + } if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { float tx1 = box[i].x1 + x_mask - x_dest; float ty1 = box[i].y1 + y_mask - y_dest; float tx2 = box[i].x2 + x_mask - x_dest; float ty2 = box[i].y2 + y_mask - y_dest; - - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 0, tx1, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 2, tx2, ty1); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 4, tx2, ty2); - glamor_set_transformed_point(mask, mask_pixmap, - mask_texcoords + 6, tx1, ty2); + if (mask->transform) + glamor_set_transformed_normalize_tcoords(mask_matrix, mask_xscale, mask_yscale, + tx1, ty1, tx2, ty2, + glamor_priv->yInverted, + mask_texcoords); + else + glamor_set_normalize_tcoords(mask_xscale, mask_yscale, tx1, ty1, tx2, ty2, + glamor_priv->yInverted, mask_texcoords); } glamor_emit_composite_rect(screen, source_texcoords, mask_texcoords, vertices); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 2991eddd5..90bf734be 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -88,70 +88,64 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int tile_x2 = tile_x + width; int tile_y1 = tile_y; int tile_y2 = tile_y + height; - glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile); - float vertices[4][2]; - float source_texcoords[4][2]; + float vertices[8]; + float source_texcoords[8]; + GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; + glamor_pixmap_private *src_pixmap_priv; + glamor_pixmap_private *dst_pixmap_priv; + + src_pixmap_priv = glamor_get_pixmap_private(tile); + dst_pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (glamor_priv->tile_prog == 0) { glamor_fallback("Tiling unsupported\n"); goto fail; } - if (glamor_set_destination_pixmap(pixmap)) { - glamor_fallback("dest has no fbo."); - goto fail; + + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { + glamor_fallback("dest has no fbo."); + goto fail; } - if (tile_priv->gl_tex == 0) { - glamor_fallback("Non-texture tile pixmap\n"); - goto fail; + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { + /* XXX dynamic uploading candidate. */ + glamor_fallback("Non-texture tile pixmap\n"); + goto fail; } if (!glamor_set_planemask(pixmap, planemask)) { glamor_fallback("unsupported planemask %lx\n", planemask); goto fail; } + + glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); + pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); + glamor_set_alu(alu); glUseProgramObjectARB(glamor_priv->tile_prog); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tile_priv->tex); + glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glEnable(GL_TEXTURE_2D); - vertices[0][0] = v_from_x_coord_x(pixmap, x1); - vertices[1][0] = v_from_x_coord_x(pixmap, x2); - vertices[2][0] = v_from_x_coord_x(pixmap, x2); - vertices[3][0] = v_from_x_coord_x(pixmap, x1); - source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1); - source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2); - source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2); - source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1); - - if (glamor_priv->yInverted) { - vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1); - vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1); - vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2); - vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2); + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, + x1, y1,x2, y2, + glamor_priv->yInverted, + vertices); - source_texcoords[0][1] = t_from_x_coord_y_inverted(tile, tile_y1); - source_texcoords[1][1] = t_from_x_coord_y_inverted(tile, tile_y1); - source_texcoords[2][1] = t_from_x_coord_y_inverted(tile, tile_y2); - source_texcoords[3][1] = t_from_x_coord_y_inverted(tile, tile_y2); - } else { + glamor_set_normalize_tcoords(src_xscale, src_yscale, + tile_x1, tile_y1, + tile_x2, tile_y2, + glamor_priv->yInverted, + source_texcoords); - vertices[0][1] = v_from_x_coord_y(pixmap, y1); - vertices[1][1] = v_from_x_coord_y(pixmap, y1); - vertices[2][1] = v_from_x_coord_y(pixmap, y2); - vertices[3][1] = v_from_x_coord_y(pixmap, y2); - - source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1); - source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1); - source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2); - source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2); - } glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h new file mode 100644 index 000000000..b8b437eb8 --- /dev/null +++ b/glamor/glamor_utils.h @@ -0,0 +1,124 @@ +#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_scale(_pixmap_priv_, _pxscale_, _pyscale_) \ + do { \ + *(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width; \ + *(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height; \ + } 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 glamor_set_transformed_point(matrix, xscale, yscale, texcoord, \ + x, y, yInverted) \ + do { \ + float result[4]; \ + int i; \ + float tx, ty; \ + \ + 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]; \ + \ + (texcoord)[0] = t_from_x_coord_x(xscale, tx); \ + if (yInverted) \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ + else \ + (texcoord)[1] = t_from_x_coord_y(yscale, ty); \ + } while(0) + + +#define glamor_set_transformed_normalize_tcoords( matrix, \ + xscale, \ + yscale, \ + tx1, ty1, tx2, ty2, \ + yInverted, texcoords) \ + do { \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords, tx1, ty1, \ + yInverted); \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords + 2, tx2, ty1, \ + yInverted); \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords + 4, tx2, ty2, \ + yInverted); \ + glamor_set_transformed_point(matrix, xscale, yscale, \ + texcoords + 6, tx1, ty2, \ + yInverted); \ + } while (0) + +#define glamor_set_normalize_tcoords(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)[4] = (vertices)[2]; \ + (vertices)[6] = (vertices)[0]; \ + if (yInverted) { \ + (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[5] = t_from_x_coord_y_inverted(yscale, y2); \ + } \ + else { \ + (vertices)[1] = t_from_x_coord_y(yscale, y1); \ + (vertices)[5] = t_from_x_coord_y(yscale, y2); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[7] = (vertices)[5]; \ + } while(0) + + +#define glamor_set_normalize_vcoords(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)[4] = (vertices)[2]; \ + (vertices)[6] = (vertices)[0]; \ + if (yInverted) { \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2); \ + } \ + else { \ + (vertices)[1] = v_from_x_coord_y(yscale, y1); \ + (vertices)[5] = v_from_x_coord_y(yscale, y2); \ + } \ + (vertices)[3] = (vertices)[1]; \ + (vertices)[7] = (vertices)[5]; \ + } while(0) + + +#endif From ca36ada041558d1823b12b1a0141e43b9f9ad939 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 22 Jun 2011 18:15:02 +0800 Subject: [PATCH 135/225] glamor: Don't always fallback everything when change window attr. Change the glamor_change_window_attributes's handling. We don't need to fallback every thing to cpu at the beginning. Only when there is a real need to change the pixmap's format, we need to do something. Otherwise, we need do nothing here. Signed-off-by: Zhigang Gong --- glamor/Makefile.am | 1 + glamor/glamor_core.c | 52 +++++------------------------ glamor/glamor_debug.h | 19 +++++++++-- glamor/glamor_render.c | 18 ++++++++-- glamor/glamor_tile.c | 5 ++- glamor/glamor_window.c | 74 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 51 deletions(-) create mode 100644 glamor/glamor_window.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 53877dcbe..e2678f060 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -33,6 +33,7 @@ libglamor_la_SOURCES = \ glamor_triangles.c\ glamor_pixmap.c\ glamor_picture.c\ + glamor_window.c\ glamor.h libglamor_la_LIBADD = \ glu3/libglu3.la diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index a61b8ae53..31734bed0 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -241,10 +241,13 @@ glamor_finish_access(DrawablePtr drawable) Bool glamor_prepare_access_gc(GCPtr gc) { - if (gc->stipple) + if (gc->stipple) { + glamor_fallback("has stipple %p\n", gc->stipple); if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO)) return FALSE; + } if (gc->fillStyle == FillTiled) { + glamor_fallback("has tile pixmap %p\n", gc->tile.pixmap); if (!glamor_prepare_access (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO)) { if (gc->stipple) @@ -332,6 +335,8 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) /* fb24_32ReformatTile will do direct access of a newly- * allocated pixmap. */ + glamor_fallback("GC %p tile FB_24_32 transformat %p.\n", gc, old_tile); + if (glamor_prepare_access(&old_tile->drawable, GLAMOR_ACCESS_RO)) { new_tile = fb24_32ReformatTile(old_tile, @@ -351,6 +356,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width * drawable->bitsPerPixel)) { + glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap); if (glamor_prepare_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) { fbPadPixmap(gc->tile.pixmap); @@ -367,6 +373,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) /* We can't inline stipple handling like we do for GCTile because * it sets fbgc privates. */ + glamor_fallback("GC %p stipple changed %p.\n", gc, gc->stipple); if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { fbValidateGC(gc, changes, drawable); glamor_finish_access(&gc->stipple->drawable); @@ -403,52 +410,11 @@ glamor_create_gc(GCPtr gc) return TRUE; } -Bool -glamor_prepare_access_window(WindowPtr window) -{ - if (window->backgroundState == BackgroundPixmap) { - if (!glamor_prepare_access(&window->background.pixmap->drawable, - GLAMOR_ACCESS_RO)) - return FALSE; - } - - if (window->borderIsPixel == FALSE) { - if (!glamor_prepare_access(&window->border.pixmap->drawable, - GLAMOR_ACCESS_RO)) { - if (window->backgroundState == BackgroundPixmap) - glamor_finish_access(&window->background.pixmap->drawable); - return FALSE; - } - } - return TRUE; -} - -void -glamor_finish_access_window(WindowPtr window) -{ - if (window->backgroundState == BackgroundPixmap) - glamor_finish_access(&window->background.pixmap->drawable); - - if (window->borderIsPixel == FALSE) - glamor_finish_access(&window->border.pixmap->drawable); -} - -Bool -glamor_change_window_attributes(WindowPtr window, unsigned long mask) -{ - Bool ret; - - if (!glamor_prepare_access_window(window)) - return FALSE; - ret = fbChangeWindowAttributes(window, mask); - glamor_finish_access_window(window); - return ret; -} - RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap) { RegionPtr ret; + glamor_fallback("pixmap %p \n", pixmap); if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) return NULL; ret = fbPixmapToRegion(pixmap); diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h index aad4b3ca6..48682e802 100644 --- a/glamor/glamor_debug.h +++ b/glamor/glamor_debug.h @@ -5,9 +5,24 @@ #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_DYNAMIC_UPLOAD 2 -#define GLAMOR_DEBUG_TEXTURE_DOWNLOAD 3 +#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__ ); \ + AbortServer(); \ + } while(0) + + #define __debug_output_message(_format_, _prefix_, ...) \ diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index f991b0f17..14c3fa8d8 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -748,6 +748,7 @@ glamor_composite_with_shader(CARD8 op, if (source->pSourcePict->type == SourcePictTypeSolidFill) { key.source = SHADER_SOURCE_SOLID; } else { + //key.source = SHADER_SOURCE_SOLID; glamor_fallback("gradient source\n"); goto fail; } @@ -1134,12 +1135,23 @@ glamor_composite(CARD8 op, return; fail: - glamor_fallback("glamor_composite(): " - "from picts %p/%p(%c,%c) to pict %p (%c)\n", - source, mask, + + glamor_fallback( + "from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c) to pict %p:%p %dx%d (%c)\n", + source, + source->pDrawable, + source->pDrawable ? source->pDrawable->width : 0, + source->pDrawable ? source->pDrawable->height : 0, + mask, + (!mask) ? NULL : mask->pDrawable, + (!mask || !mask->pDrawable)? 0 : mask->pDrawable->width, + (!mask || !mask->pDrawable)? 0 : mask->pDrawable->height, glamor_get_picture_location(source), glamor_get_picture_location(mask), dest, + dest->pDrawable, + dest->pDrawable->width, + dest->pDrawable->height, glamor_get_picture_location(dest)); glUseProgramObjectARB(0); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 90bf734be..c62392c1b 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -94,18 +94,17 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv; + src_pixmap_priv = glamor_get_pixmap_private(tile); dst_pixmap_priv = glamor_get_pixmap_private(pixmap); - if (glamor_priv->tile_prog == 0) { glamor_fallback("Tiling unsupported\n"); goto fail; } - if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { - glamor_fallback("dest has no fbo."); + glamor_fallback("dest has no fbo.\n"); goto fail; } diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c new file mode 100644 index 000000000..05555b204 --- /dev/null +++ b/glamor/glamor_window.c @@ -0,0 +1,74 @@ +/* + * Copyright © 2008 Intel Corporation + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "glamor_priv.h" + +/** @file glamor_window.c + * + * Screen Change Window Attribute implementation. + */ + + +static void +glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap) +{ + PixmapPtr pPixmap = *ppPixmap; + glamor_pixmap_private *pixmap_priv; + + if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) + { + pixmap_priv = glamor_get_pixmap_private(pPixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { + glamor_fallback("pixmap %p has no fbo\n", pPixmap); + goto fail; + } + glamor_debug_output(GLAMOR_DEBUG_UNIMPL, "To be implemented.\n"); + } + return; + +fail: + GLAMOR_PANIC(" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile" + " is broken for glamor. \n"); +} + +Bool +glamor_change_window_attributes(WindowPtr pWin, unsigned long mask) +{ + if (mask & CWBackPixmap) { + if (pWin->backgroundState == BackgroundPixmap) + glamor_fixup_window_pixmap(&pWin->drawable, &pWin->background.pixmap); + } + + if (mask & CWBorderPixmap) { + if (pWin->borderIsPixel == FALSE) + glamor_fixup_window_pixmap(&pWin->drawable, &pWin->border.pixmap); + } + return TRUE; +} + + + From 489e6c4e6f734d961ae8bbec67d78fccbeb9781f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sun, 26 Jun 2011 15:49:13 +0800 Subject: [PATCH 136/225] glamor: Initialize pixmap private's container to correct value. When calling from ephyr, we forgot to initialize it to the correct value. Will cause segfault when run Xephyr. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index c10ff4021..54304226e 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -197,6 +197,7 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth, pixmap_priv->tex = 0; pixmap_priv->gl_fbo = 1; pixmap_priv->gl_tex = 1; + pixmap_priv->container = pixmap; screen->CreatePixmap = glamor_create_pixmap; return pixmap; From bf782283371bc13c7b969a373c2a2eaaa3c81ec6 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sun, 26 Jun 2011 15:51:47 +0800 Subject: [PATCH 137/225] glamor: Fixed one bug when enable dynamic pixmap uploading. When try to upload a pixmap without yInverted set, we must set up a fbo for it to do the y flip. Previous implementation only consider the ax bit. After fix this problem, we can enable the dynamic uploading feature in copyarea function when the yInverted is not set (from Xephyr). Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 2 -- glamor/glamor_pixmap.c | 35 +++++++++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 55437715a..b1d8cfcea 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -224,8 +224,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); goto fail; #else - /* XXX in yInverted mode we have bug here.*/ - if (!glamor_priv->yInverted) goto fail; src_status = glamor_upload_pixmap_to_texture(src_pixmap); if (src_status != GLAMOR_UPLOAD_DONE) goto fail; diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 6e2d9d576..b532bb394 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -241,11 +241,19 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i } -/* */ +/* + * Prepare to upload a pixmap to texture memory. + * ax 1 means the format needs to wire alpha to 1. + * Two condtion need to setup a fbo for a pixmap + * 1. !yInverted, we need to do flip if we are not yInverted. + * 2. ax != 0, we need to wire the alpha. + * */ static int -glamor_pixmap_upload_prepare(PixmapPtr pixmap, int need_fbo) +glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax) { + int need_fbo; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); if (!glamor_check_fbo_width_height(pixmap->drawable.width , pixmap->drawable.height) || !glamor_check_fbo_depth(pixmap->drawable.depth)) { @@ -253,25 +261,28 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int need_fbo) pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth); return -1; } + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return 0; - if (pixmap_priv->tex == 0) { - /* Create a framebuffer object wrapping the texture so that we can render - * to it. - */ + + if (ax != 0 || !glamor_priv->yInverted) + need_fbo = 1; + else + need_fbo = 0; + + if (pixmap_priv->tex == 0) glGenTextures(1, &pixmap_priv->tex); + + if (need_fbo) { + if (pixmap_priv->fb == 0) + glGenFramebuffersEXT(1, &pixmap_priv->fb); glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); - } - - if (need_fbo && pixmap_priv->fb == 0) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, pixmap->drawable.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glGenFramebuffersEXT(1, &pixmap_priv->fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, @@ -304,7 +315,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap) pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth); - _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 0); + _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1); return GLAMOR_UPLOAD_DONE; } From b8e692d94eb7075409e0d072fdf3066ca1d5d5f3 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sun, 26 Jun 2011 15:54:24 +0800 Subject: [PATCH 138/225] glamor: Move the blend set up after the pixmap uploading. This is a bug, as if we do blend set up before do the pixmap dynamic uploading. We will have a incorrect blend env when doing the uploading. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 14c3fa8d8..2d89cd48d 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -734,7 +734,7 @@ glamor_composite_with_shader(CARD8 op, int mask_x_off, mask_y_off; enum glamor_pixmap_status source_status = GLAMOR_NONE; enum glamor_pixmap_status mask_status = GLAMOR_NONE; - PictFormatShort saved_source_format = 0; + PictFormatShort saved_source_format = 0; float src_matrix[9], mask_matrix[9]; dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); @@ -838,10 +838,6 @@ glamor_composite_with_shader(CARD8 op, if (!good_dest_format(dest)) { goto fail; } - if (!glamor_set_composite_op(screen, op, dest, mask)) { - goto fail; - } - #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD if (source_status == GLAMOR_UPLOAD_PENDING && mask_status == GLAMOR_UPLOAD_PENDING @@ -849,17 +845,13 @@ glamor_composite_with_shader(CARD8 op, if (source->format != mask->format) { saved_source_format = source->format; - /* XXX - * when need to flip the texture and mask and source share the same pixmap, - * there is a bug, need to be fixed. * - */ - if (!glamor_priv->yInverted) - goto fail; + if (!combine_pict_format(&source->format, source->format, mask->format, key.in)) { glamor_fallback("combine source %x mask %x failed.\n", source->format, mask->format); goto fail; } + if (source->format != saved_source_format) { glamor_picture_format_fixup(source, source_pixmap_priv); } @@ -913,7 +905,9 @@ glamor_composite_with_shader(CARD8 op, } } #endif - + if (!glamor_set_composite_op(screen, op, dest, mask)) { + goto fail; + } glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); shader = glamor_lookup_composite_shader(screen, &key); From cbedfe75135e3253c32ac8b89380f47d1b8a37c4 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sun, 26 Jun 2011 20:00:26 +0800 Subject: [PATCH 139/225] glamor: Don't need to read dest if op is SRC or CLEAR. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 2d89cd48d..59a74dfb3 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1084,6 +1084,7 @@ glamor_composite(CARD8 op, CARD16 height) { glamor_composite_rect_t rect; + glamor_access_t dest_access; /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. @@ -1150,7 +1151,11 @@ glamor_composite(CARD8 op, glUseProgramObjectARB(0); glDisable(GL_BLEND); - if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { + if (op == PictOpSrc || op == PictOpClear) + dest_access = GLAMOR_ACCESS_WO; + else + dest_access = GLAMOR_ACCESS_RW; + if (glamor_prepare_access_picture(dest, dest_access)) { if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO)) { if (!mask || From 4afa9e4080eebbee0752e5f45b2ff16df75cb9b1 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 28 Jun 2011 14:28:19 +0800 Subject: [PATCH 140/225] glamor: Prepare/finish access once if src equal to dst. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index b1d8cfcea..cebce218b 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -322,6 +322,7 @@ glamor_copy_n_to_n(DrawablePtr src, goto done; return; } + glamor_report_delayed_fallbacks(src->pScreen); glamor_report_delayed_fallbacks(dst->pScreen); @@ -329,11 +330,12 @@ glamor_copy_n_to_n(DrawablePtr src, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); - glamor_finish_access(src); + if (dst != src) + glamor_finish_access(src); } glamor_finish_access(dst); } From 9e4567afe6019ed7a330182d660880d8ea6c3685 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 28 Jun 2011 14:37:29 +0800 Subject: [PATCH 141/225] glamor: Change to use system memory for write only access. If the pixmap is write-only, then use a pbo mapping will not get too much benefit. And even worse, when the software rendering is access this mapped data range, it's much slower than just using a system memory. From the glamor_prepare_access glamor_finish_access view, we have two options here: option 1: 1.0 create a pbo 1.1 copy texture to the pbo 1.2 map the pbo to va 1.3 access the va directly in software rendering. 1.4 bind the pbo as unpack buffer & draw it back to texture. option 2: 2.0 allocate a block memory in system memory space. 2.1 read the texture memory to the system memory. 2.2 access the system memory and do rendering. 2.3 draw the system memory back to texture. In general, 1.1 plush 1.2 is much faster than 2.1. And 1.3 is slower than 2.2. 1.4 is faster than 2.3. If the access mode is read only or read write, option 1 may be fater, but if the access mode is write only. Then most of the time option 1 is much faster. Signed-off-by: Zhigang Gong --- glamor/glamor_pixmap.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index b532bb394..c76920a26 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -387,15 +387,23 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) } pixmap_priv->access_mode = access; - + glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD, + "Downloading pixmap %p %dx%d depth%d\n", + pixmap, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.depth); + + stride = pixmap->devKind; + switch (access) { case GLAMOR_ACCESS_RO: gl_access = GL_READ_ONLY_ARB; gl_usage = GL_STREAM_READ_ARB; break; case GLAMOR_ACCESS_WO: - gl_access = GL_WRITE_ONLY_ARB; - gl_usage = GL_STREAM_DRAW_ARB; + data = malloc(stride * pixmap->drawable.height); + goto done; break; case GLAMOR_ACCESS_RW: gl_access = GL_READ_WRITE_ARB; @@ -405,15 +413,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) ErrorF("Glamor: Invalid access code. %d\n", access); assert(0); } - - glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD, - "Downloading pixmap %p %dx%d depth%d\n", - pixmap, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->drawable.depth); - stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glPixelStorei(GL_PACK_ALIGNMENT, 1); @@ -429,8 +429,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT, stride * pixmap->drawable.height, NULL, gl_usage); - if (access != GLAMOR_ACCESS_WO) - glReadPixels (0, 0, + glReadPixels (0, 0, row_length, pixmap->drawable.height, format, type, 0); data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, gl_access); @@ -438,7 +437,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) if (!glamor_priv->yInverted) glPixelStorei(GL_PACK_INVERT_MESA, 0); - + glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); } else { data = malloc(stride * pixmap->drawable.height); assert(data); @@ -465,6 +464,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +done: pixmap->devPrivate.ptr = data; return TRUE; } From c303949aabacb6a105ca0e0c521ca293dbda7d43 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 28 Jun 2011 14:49:38 +0800 Subject: [PATCH 142/225] glamor: Reduce one extra copy in glamor_trapezoids. This reduce the time when running cairo-performance-trace with the firefox-planet-gnome.trace from 23.5 seconds to 21.5 seconds. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 43 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 59a74dfb3..27fff23b2 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -748,7 +748,6 @@ glamor_composite_with_shader(CARD8 op, if (source->pSourcePict->type == SourcePictTypeSolidFill) { key.source = SHADER_SOURCE_SOLID; } else { - //key.source = SHADER_SOURCE_SOLID; glamor_fallback("gradient source\n"); goto fail; } @@ -1201,7 +1200,7 @@ glamor_create_mask_picture(ScreenPtr screen, return 0; } - pixmap = screen->CreatePixmap(screen, width, height, + pixmap = screen->CreatePixmap(screen, 0, 0, pict_format->depth, 0); if (!pixmap) @@ -1229,7 +1228,6 @@ glamor_trapezoids(CARD8 op, INT16 x_rel, y_rel; int width, height, stride; PixmapPtr pixmap; - GCPtr gc; pixman_image_t *image; /* If a mask format wasn't provided, we get to choose, but behavior should @@ -1256,8 +1254,7 @@ glamor_trapezoids(CARD8 op, width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; - stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8; - + stride = PixmapBytePad(width, mask_format->depth); picture = glamor_create_mask_picture(screen, dst, mask_format, width, height); if (!picture) @@ -1275,32 +1272,13 @@ glamor_trapezoids(CARD8 op, pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); - pixmap = GetScratchPixmapHeader(screen, width, height, - mask_format->depth, - BitsPerPixel(mask_format->depth), - PixmapBytePad(width, mask_format->depth), - pixman_image_get_data(image)); - if (!pixmap) { - FreePicture(picture, 0); - pixman_image_unref(image); - return; - } - - gc = GetScratchGC(picture->pDrawable->depth, screen); - if (!gc) { - FreeScratchPixmapHeader(pixmap); - pixman_image_unref (image); - FreePicture(picture, 0); - return; - } - ValidateGC(picture->pDrawable, gc); - - gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable, - gc, 0, 0, width, height, 0, 0); - - FreeScratchGC(gc); - FreeScratchPixmapHeader(pixmap); - pixman_image_unref(image); + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + + screen->ModifyPixmapHeader(pixmap, width, height, + mask_format->depth, + BitsPerPixel(mask_format->depth), + PixmapBytePad(width, mask_format->depth), + pixman_image_get_data(image)); x_rel = bounds.x1 + x_src - x_dst; y_rel = bounds.y1 + y_src - y_dst; @@ -1309,6 +1287,9 @@ glamor_trapezoids(CARD8 op, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + + pixman_image_unref(image); + FreePicture(picture, 0); } From 8890b38857128181cf506356046bf4a5bce53ab0 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 28 Jun 2011 17:17:23 +0800 Subject: [PATCH 143/225] glamor: Don't map the vbo to system memory. Access mapped vbo address is too slow. And by use system memory directly, rgb10text/aa10text increases from 980K/1160K to 117K/140K. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 2 ++ glamor/glamor_render.c | 31 +++++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 54304226e..b78feb4ec 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -399,6 +399,8 @@ glamor_close_screen(int idx, ScreenPtr screen) ps->CreatePicture = glamor_priv->saved_create_picture; } #endif + if (glamor_priv->vb) + free(glamor_priv->vb); free(glamor_priv); return screen->CloseScreen(idx, screen); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 27fff23b2..e7a886c4b 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -285,10 +285,25 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key) return shader; } +#define GLAMOR_COMPOSITE_VBO_SIZE 8192 + +static void +glamor_reset_composite_vbo(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_priv->vbo_offset = 0; + glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_SIZE; + glamor_priv->render_nr_verts = 0; +} + void glamor_init_composite_shaders(ScreenPtr screen) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_priv->vb = malloc(GLAMOR_COMPOSITE_VBO_SIZE); + assert(glamor_priv->vb != NULL); + glamor_reset_composite_vbo(screen); } static Bool @@ -599,13 +614,11 @@ glamor_flush_composite_rects(ScreenPtr screen) if (!glamor_priv->render_nr_verts) return; - - glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); - glamor_priv->vb = NULL; + glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_offset, glamor_priv->vb, + GL_STREAM_DRAW_ARB); glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts); - glamor_priv->render_nr_verts = 0; - glamor_priv->vbo_size = 0; + glamor_reset_composite_vbo(screen); } static void @@ -622,16 +635,10 @@ glamor_emit_composite_rect(ScreenPtr screen, glamor_flush_composite_rects(screen); } - if (glamor_priv->vbo_size == 0) { + if (glamor_priv->vbo_offset == 0) { if (glamor_priv->vbo == 0) glGenBuffersARB(1, &glamor_priv->vbo); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); - glamor_priv->vbo_size = 4096; - glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL, - GL_STREAM_DRAW_ARB); - glamor_priv->vbo_offset = 0; - glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); glamor_setup_composite_vbo(screen); } From 33c6c78ae9c7e72a94cc27536f3b5f50cdcc9241 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 30 Jun 2011 16:01:57 +0800 Subject: [PATCH 144/225] glamor: Add one option to force create a cpu memory pixmap. Some special case we want to get a cpu memory pixmap. For example to gather a large cpu memory pixmap's block to a small pixmap. Add pixmap's priviate data's deallocation when destroy a pixmap. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 12 +++++++----- glamor/glamor_priv.h | 7 ++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index b78feb4ec..6bab8c124 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -116,11 +116,12 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, GLuint tex; int type = GLAMOR_PIXMAP_TEXTURE; glamor_pixmap_private *pixmap_priv; - if (w > 32767 || h > 32767) return NullPixmap; - if (!glamor_check_fbo_width_height(w,h) || !glamor_check_fbo_depth(depth)) { + if (!glamor_check_fbo_width_height(w,h) + || !glamor_check_fbo_depth(depth) + || usage == GLAMOR_CREATE_PIXMAP_CPU) { /* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo. If we exceed such limitation, we have to use framebuffer.*/ type = GLAMOR_PIXMAP_MEMORY; @@ -129,9 +130,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3, NULL); - - glamor_fallback("choose cpu memory for pixmap %p ," - " %d x %d depth %d\n", pixmap, w, h, depth); + if (usage != GLAMOR_CREATE_PIXMAP_CPU) + glamor_fallback("choose cpu memory for pixmap %p ," + " %d x %d depth %d\n", pixmap, w, h, depth); } else pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); @@ -217,6 +218,7 @@ glamor_destroy_pixmap(PixmapPtr pixmap) glDeleteTextures(1, &pixmap_priv->tex); if (pixmap_priv->pbo) glDeleteBuffersARB(1, &pixmap_priv->pbo); + dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP); } return fbDestroyPixmap(pixmap); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 5b457e7fc..4b0037333 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -50,9 +50,9 @@ #include "glamor_debug.h" -#define glamor_check_fbo_width_height(_w_, _h_) (_w_ > 0 && _h_ > 0 \ - && _w_ < MAX_WIDTH \ - && _h_ < MAX_HEIGHT) +#define glamor_check_fbo_width_height(_w_, _h_) ((_w_) > 0 && (_h_) > 0 \ + && (_w_) < MAX_WIDTH \ + && (_h_) < MAX_HEIGHT) #define glamor_check_fbo_depth(_depth_) ( \ _depth_ == 8 \ @@ -149,6 +149,7 @@ enum shader_in { SHADER_IN_COUNT, }; +#define GLAMOR_CREATE_PIXMAP_CPU 0x100 typedef struct glamor_screen_private { CloseScreenProcPtr saved_close_screen; CreateGCProcPtr saved_create_gc; From 1dca5d7b91ed6fced34f389453678407bc223e9c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 30 Jun 2011 16:04:59 +0800 Subject: [PATCH 145/225] glamor: Reduce source pixmap's size. If the dest pixmap is in texture memory, but source pixmap is not. Then we need to upload the source pixmap to texture memory. Previous version will upload the whole source pixmap. This commit preprocess the source pixmap, and reduce it to a smaller tempory pixmap only contains the required region. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 60 +++++++++++++++++++++++++++++++++++++--- glamor/glamor_utils.h | 38 +++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index cebce218b..2408e3aae 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -308,6 +308,23 @@ glamor_copy_n_to_n(DrawablePtr src, Pixel bitplane, void *closure) { + glamor_access_t dst_access; + PixmapPtr dst_pixmap, src_pixmap, temp_pixmap; + DrawablePtr temp_src = src; + glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; + BoxRec bound; + ScreenPtr screen; + int temp_dx = dx; + int temp_dy = dy; + dst_pixmap = glamor_get_drawable_pixmap(dst); + dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); + screen = dst_pixmap->drawable.pScreen; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { + glamor_fallback("dest pixmap %p has no fbo. \n", dst_pixmap); + goto fail; + } + if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { goto done; return; @@ -318,17 +335,50 @@ glamor_copy_n_to_n(DrawablePtr src, return; } - if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) { - goto done; - return; + src_pixmap = glamor_get_drawable_pixmap(src); + src_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); + + glamor_calculate_boxes_bound(&bound, box, nbox); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) + && ((bound.x2 - bound.x1) * (bound.y2 - bound.y1) + * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height)) { + + temp_pixmap = (*screen->CreatePixmap)(screen, + bound.x2 - bound.x1, + bound.y2 - bound.y1, + src_pixmap->drawable.depth, + GLAMOR_CREATE_PIXMAP_CPU); + if (!temp_src) + goto fail; + glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1); + fbCopyNtoN(src, temp_src, gc, box, nbox, + temp_dx + bound.x1, temp_dy + bound.y1, + reverse, upsidedown, bitplane, + closure); + glamor_transform_boxes(box, nbox, bound.x1, bound.y1); + temp_dx = -bound.x1; + temp_dy = -bound.y1; + temp_src = &temp_pixmap->drawable; } + if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) { + goto done; + } + + fail: glamor_report_delayed_fallbacks(src->pScreen); glamor_report_delayed_fallbacks(dst->pScreen); glamor_fallback("from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); + + if (gc && gc->alu != GXcopy) + dst_access = GLAMOR_ACCESS_RW; + else + dst_access = GLAMOR_ACCESS_WO; + if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { fbCopyNtoN(src, dst, gc, box, nbox, @@ -339,11 +389,13 @@ glamor_copy_n_to_n(DrawablePtr src, } glamor_finish_access(dst); } - return; done: glamor_clear_delayed_fallbacks(src->pScreen); glamor_clear_delayed_fallbacks(dst->pScreen); + if (temp_src != src) { + (*screen->DestroyPixmap)(temp_pixmap); + } } RegionPtr diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index b8b437eb8..2c6563232 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -121,4 +121,42 @@ } 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) + x_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_transform_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; + } +} #endif From 14503fbb819d07fa2b58d9bb741b55f93aff2cf6 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 30 Jun 2011 16:38:43 +0800 Subject: [PATCH 146/225] glamor: Fix the coords calculation in glamor_fill. glamor_fill is only called from internal functions glamor_fillspancs and glamor_polyfillrect. And both functions already add the offset to the coords, so the coords are already relative value, we can't add the offset once again. Signed-off-by: Zhigang Gong --- glamor/glamor_fill.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 48f85ce38..a41837b3a 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -41,14 +41,12 @@ glamor_fill(DrawablePtr drawable, int height) { PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); - int x_off, y_off; - glamor_get_drawable_deltas(drawable, dst_pixmap, &x_off, &y_off); switch (gc->fillStyle) { case FillSolid: if (!glamor_solid(dst_pixmap, - x + x_off, - y + y_off, + x, + y, width, height, gc->alu, @@ -60,24 +58,24 @@ glamor_fill(DrawablePtr drawable, case FillOpaqueStippled: if (!glamor_stipple(dst_pixmap, gc->stipple, - x+ x_off, - y + y_off, + x, + y, width, height, gc->alu, gc->planemask, gc->fgPixel, gc->bgPixel, - gc->patOrg.x + x_off, - gc->patOrg.y + y_off)) + gc->patOrg.x, + gc->patOrg.y)) goto fail; return; break; case FillTiled: if (!glamor_tile(dst_pixmap, gc->tile.pixmap, - x + x_off, - y + y_off, + x, + y, width, height, gc->alu, From 61e1ad39724e5baaed4f30ff3c86782e701f19fb Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 30 Jun 2011 16:40:32 +0800 Subject: [PATCH 147/225] glamor: Reduce source or mask picture size if possible. If we only need a short part of the source or mask's drawable pixmap, we can convert it to a new small picture before call to the low level compositing function. Then it will only upload the smaller picture latter. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 144 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 17 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index e7a886c4b..1c4c1b366 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1075,6 +1075,53 @@ glamor_composite_with_shader(CARD8 op, return FALSE; } +static PicturePtr +glamor_convert_gradient_picture(ScreenPtr screen, + PicturePtr source, + int x_source, + int y_source, + int width, + int height) +{ + PixmapPtr pixmap; + PicturePtr dst; + int error; + PictFormatShort format; + + if (!source->pDrawable) + format = PICT_a8r8g8b8; + else + format = source->format; + + pixmap = screen->CreatePixmap(screen, + width, + height, + PIXMAN_FORMAT_DEPTH(format), + GLAMOR_CREATE_PIXMAP_CPU); + + if (!pixmap) + return NULL; + + dst = CreatePicture(0, + &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH(format), + format), + 0, + 0, + serverClient, + &error); + screen->DestroyPixmap(pixmap); + if (!dst) + return NULL; + + ValidatePicture(dst); + + fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source, + 0, 0, 0, 0, width, height); + return dst; +} + void glamor_composite(CARD8 op, PicturePtr source, @@ -1089,27 +1136,84 @@ glamor_composite(CARD8 op, CARD16 width, CARD16 height) { + ScreenPtr screen = dest->pDrawable->pScreen; + glamor_pixmap_private *dest_pixmap_priv, *source_pixmap_priv, *mask_pixmap_priv; + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); + PixmapPtr source_pixmap, mask_pixmap; + PicturePtr temp_src = source, temp_mask = mask; + int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; glamor_composite_rect_t rect; glamor_access_t dest_access; + x_temp_src = x_source; + y_temp_src = y_source; + x_temp_mask = x_mask; + y_temp_mask = y_mask; + + dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); + /* Currently. Always fallback to cpu if destination is in CPU memory. */ + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { + goto fail; + } + + if (source->pDrawable) { + source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + } + + if (mask && mask->pDrawable) { + mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); + mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); + } + + if ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill)) + || (source->pDrawable + && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) + && (width * height * 4 + < (source_pixmap->drawable.width * source_pixmap->drawable.height)))){ + temp_src = glamor_convert_gradient_picture(screen, source, x_source, y_source, width, height); + if (!temp_src) { + temp_src = source; + goto fail; + } + x_temp_src = y_temp_src = 0; + } + + if (mask + && ((!mask->pDrawable && (mask->pSourcePict->type != SourcePictTypeSolidFill)) + || (mask->pDrawable + && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)) + && (width * height * 4 + < (mask_pixmap->drawable.width * mask_pixmap->drawable.height))))) { + /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity + * to do reduce one convertion. */ + temp_mask = glamor_convert_gradient_picture(screen, mask, x_mask, y_mask, width, height); + if (!temp_mask) { + temp_mask = mask; + goto fail; + } + x_temp_mask = y_temp_mask = 0; + } /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. */ + if (mask && mask->componentAlpha) { if (op == PictOpOver) { glamor_composite(PictOpOutReverse, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, + temp_src, temp_mask, dest, + x_temp_src, y_temp_src, + x_temp_mask, y_temp_mask, x_dest, y_dest, width, height); glamor_composite(PictOpAdd, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, + temp_src, temp_mask, dest, + x_temp_src, y_temp_src, + x_temp_mask, y_temp_mask, x_dest, y_dest, width, height); - return; + goto done; + } else if (op != PictOpAdd && op != PictOpOutReverse) { glamor_fallback("glamor_composite(): component alpha\n"); goto fail; @@ -1117,25 +1221,25 @@ glamor_composite(CARD8 op, } if (!mask) { - if (glamor_composite_with_copy(op, source, dest, - x_source, y_source, + if (glamor_composite_with_copy(op, temp_src, dest, + x_temp_src, y_temp_src, x_dest, y_dest, width, height)) - return; + goto done; } - rect.x_src = x_source; - rect.y_src = y_source; - rect.x_mask = x_mask; - rect.y_mask = y_mask; + rect.x_src = x_temp_src; + rect.y_src = y_temp_src; + rect.x_mask = x_temp_mask; + rect.y_mask = y_temp_mask; rect.x_dst = x_dest; rect.y_dst = y_dest; rect.width = width; rect.height = height; - if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect)) - return; + if (glamor_composite_with_shader(op, temp_src, temp_mask, dest, 1, &rect)) + goto done; - fail: +fail: glamor_fallback( "from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c) to pict %p:%p %dx%d (%c)\n", @@ -1157,6 +1261,7 @@ glamor_composite(CARD8 op, glUseProgramObjectARB(0); glDisable(GL_BLEND); + if (op == PictOpSrc || op == PictOpClear) dest_access = GLAMOR_ACCESS_WO; else @@ -1180,6 +1285,11 @@ glamor_composite(CARD8 op, } glamor_finish_access_picture(dest); } +done: + if (temp_src != source) + FreePicture(temp_src, 0); + if (temp_mask != mask) + FreePicture(temp_mask, 0); } From 2eb40a37920132d53e3b48830704f92d4c695f4c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 30 Jun 2011 16:49:40 +0800 Subject: [PATCH 148/225] glamor: Remove one extra area copy in glamor_glyph. Signed-off-by: Zhigang Gong --- glamor/glamor_glyphs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index 26e08470a..63ffd205c 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -375,6 +375,7 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen, ValidateGC(&cache_pixmap->drawable, gc); /* Create a temporary bo to stream the updates to the cache */ +#if 0 scratch = screen->CreatePixmap(screen, glyph->info.width, glyph->info.height, @@ -390,7 +391,8 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen, } else { scratch = glyph_pixmap; } - +#endif + scratch = glyph_pixmap; (void)glamor_copy_area(&scratch->drawable, &cache_pixmap->drawable, gc, From 734b10e9f7e729fc300ed432bd3c81e1ea7483f3 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 30 Jun 2011 16:50:23 +0800 Subject: [PATCH 149/225] glamor: Fix one typo bug in glamor_tile. It will return when the destination pixmap has a fbo but will continue when it doesn't have a fbo. Signed-off-by: Zhigang Gong --- glamor/glamor_tile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index c62392c1b..5bfdd7341 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -103,7 +103,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, goto fail; } - if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { glamor_fallback("dest has no fbo.\n"); goto fail; } From 1444fed4a8030ec59f4448b490f2f77db86f0b86 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 30 Jun 2011 16:53:24 +0800 Subject: [PATCH 150/225] glamor: silence compilation warnings. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 1c4c1b366..9599d978a 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1137,9 +1137,10 @@ glamor_composite(CARD8 op, CARD16 height) { ScreenPtr screen = dest->pDrawable->pScreen; - glamor_pixmap_private *dest_pixmap_priv, *source_pixmap_priv, *mask_pixmap_priv; + glamor_pixmap_private *dest_pixmap_priv; + glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL; PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); - PixmapPtr source_pixmap, mask_pixmap; + PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; PicturePtr temp_src = source, temp_mask = mask; int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; glamor_composite_rect_t rect; From ca614860fa2a56d469064b5e05070d8201597728 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 1 Jul 2011 17:02:10 +0800 Subject: [PATCH 151/225] glamor: convert if too large source or mask . Some strange web page has 20000*1 png picture, and actually only use partial of it. We force to convert it to a actuall size rather than its original size,if it is the case. Then to avoid latter's failure uploading. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 9599d978a..72e0f83c6 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1170,8 +1170,10 @@ glamor_composite(CARD8 op, if ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill)) || (source->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) - && (width * height * 4 - < (source_pixmap->drawable.width * source_pixmap->drawable.height)))){ + && ((width * height * 4 + < (source_pixmap->drawable.width * source_pixmap->drawable.height)) + || !(glamor_check_fbo_width_height(source_pixmap->drawable.width, + source_pixmap->drawable.height))))) { temp_src = glamor_convert_gradient_picture(screen, source, x_source, y_source, width, height); if (!temp_src) { temp_src = source; @@ -1184,8 +1186,10 @@ glamor_composite(CARD8 op, && ((!mask->pDrawable && (mask->pSourcePict->type != SourcePictTypeSolidFill)) || (mask->pDrawable && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)) - && (width * height * 4 - < (mask_pixmap->drawable.width * mask_pixmap->drawable.height))))) { + && ((width * height * 4 + < (mask_pixmap->drawable.width * mask_pixmap->drawable.height)) + || !(glamor_check_fbo_width_height(mask_pixmap->drawable.width, + mask_pixmap->drawable.height)))))) { /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity * to do reduce one convertion. */ temp_mask = glamor_convert_gradient_picture(screen, mask, x_mask, y_mask, width, height); From c68fb6ed723d7268a3c4950b40c20ddf9b4b9ca5 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 1 Jul 2011 22:36:31 +0800 Subject: [PATCH 152/225] glamor-ddx: Reinit crtc if we need to reopen the card. As the eglTerminate will close the card when close screen, we may need to reopen it at next time create a screen resource. and thus we need to re initialize the drmmode crtc also. Otherwise , the cursor handling will be broken as it has the wrong fd. --- hw/xfree86/glamor/glamor.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index d0432b31e..1da7eb20d 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -145,6 +145,12 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) return eglCreateDRMImageMESA(glamor->display, attribs); } +void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor) +{ + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + eglDestroyImageKHR(glamor->display, cursor); +} + void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch) { @@ -191,7 +197,7 @@ glamor_pre_init_ddx(ScrnInfoPtr scrn, int flags) if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); - goto fail; + goto fail; } scrn->currentMode = scrn->modes; @@ -272,6 +278,8 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen) glamor_fini(screen); + eglDestroyImageKHR(glamor->display, glamor->root); + eglMakeCurrent(glamor->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(glamor->display); @@ -279,6 +287,7 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen) drmmode_closefb(scrn); glamor->fd = -1; + glamor->root = EGL_NO_IMAGE_KHR; return TRUE; @@ -301,8 +310,16 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno)); return FALSE; } + if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Kernel modesetting setup failed\n"); + return FALSE; } + } + + + glamor->display = eglGetDRMDisplayMESA(glamor->fd); eglBindAPI(EGL_OPENGL_API); LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB)); From cb3b34ec53e00c6ca212891b314f473ee2f80a40 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 1 Jul 2011 22:54:45 +0800 Subject: [PATCH 153/225] glamor-ddx: Add missed drmmode_crtc_destroy function. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor_crtc.c | 16 +++++++++++++++- hw/xfree86/glamor/glamor_ddx.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index aba9b2c29..1f0396dbf 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -613,6 +613,20 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, size, red, green, blue); } +static void +drmmode_crtc_destroy(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + ScrnInfoPtr scrn = crtc->scrn; + if (drmmode_crtc->cursor) { + drmmode_hide_cursor(crtc); + glDeleteTextures(1, &drmmode_crtc->cursor_tex); + glamor_destroy_cursor(scrn, drmmode_crtc->cursor); + } + free(drmmode_crtc->cursor); + crtc->driver_private = NULL; +} static const xf86CrtcFuncsRec drmmode_crtc_funcs = { .dpms = drmmode_crtc_dpms, @@ -629,7 +643,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { .shadow_destroy = drmmode_crtc_shadow_destroy, #endif .gamma_set = drmmode_crtc_gamma_set, - .destroy = NULL, /* XXX */ + .destroy = drmmode_crtc_destroy }; diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index 6f8de11ac..0e164d3b7 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -9,6 +9,7 @@ Bool glamor_load_cursor(ScrnInfoPtr scrn, void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch); EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height); +void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor); Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp); void drmmode_closefb(ScrnInfoPtr scrn); From da66a76f276eccee90855bc0cb28092c3755ed7b Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 1 Jul 2011 23:48:21 +0800 Subject: [PATCH 154/225] Revert "glamor: Don't need to read dest if op is SRC or CLEAR." This reverts commit eb16fe0b7c8ea27b5cf9122d02e48bf585495228. As currently glamor_prepare_access/finish_access will touch the whole pixmap, not just the request region, then write only mode will not work correctly. We may need to revisit all fallback case, and convert the image to the right size before do the prepare/finish processing. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 72e0f83c6..30cc50739 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1144,7 +1144,6 @@ glamor_composite(CARD8 op, PicturePtr temp_src = source, temp_mask = mask; int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; glamor_composite_rect_t rect; - glamor_access_t dest_access; x_temp_src = x_source; y_temp_src = y_source; @@ -1266,12 +1265,7 @@ fail: glUseProgramObjectARB(0); glDisable(GL_BLEND); - - if (op == PictOpSrc || op == PictOpClear) - dest_access = GLAMOR_ACCESS_WO; - else - dest_access = GLAMOR_ACCESS_RW; - if (glamor_prepare_access_picture(dest, dest_access)) { + if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO)) { if (!mask || From fc23334e54b0b90d2f00b017a03cf47b70dc71aa Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 1 Jul 2011 23:51:42 +0800 Subject: [PATCH 155/225] glamor: Optimize fallback case for the polylines. When fallback to cpu for the polylines procedure, we can just download required region to CPU rather than to download the whole pixmap. This significant improve the performance if we have to fallback, for example do non-solid filling in the game Mines. Signed-off-by: Zhigang Gong --- glamor/glamor_polylines.c | 73 +++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index 914961161..3fdb26426 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -49,6 +49,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, xRectangle *rects; int x1, x2, y1, y2; int i; + int x_min = MAXSHORT; + int x_max = MINSHORT; + int y_min = MAXSHORT; + int y_max = MINSHORT; + DrawablePtr temp_dest; + PixmapPtr temp_pixmap; + GCPtr temp_gc; /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0) { /* This ends up in miSetSpans, which is accelerated as well as we @@ -103,16 +110,70 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, return; fail: + for(i = 0; i < n; i++) + { + if (x_min > points[i].x) + x_min = points[i].x; + if (x_max < points[i].x) + x_max = points[i].x; + + if (y_min > points[i].y) + y_min = points[i].y; + if (y_max < points[i].y) + y_max = points[i].y; + } + + temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen, + x_max - x_min + 1, y_max - y_min + 1, + drawable->depth, + 0); + if (temp_pixmap) { + temp_dest = &temp_pixmap->drawable; + temp_gc = GetScratchGC(temp_dest->depth, temp_dest->pScreen); + ValidateGC(temp_dest, temp_gc); + for(i = 0; i < n; i++) + { + points[i].x -= x_min; + points[i].y -= y_min; + } + (void)glamor_copy_area(drawable, + temp_dest, + temp_gc, + x_min, y_min, + x_max - x_min + 1, y_max - y_min + 1, + 0, 0); + + } + else + temp_dest = drawable; + if (gc->lineWidth == 0) { - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_gc(gc)) { - fbPolyLine(drawable, gc, mode, n, points); + fbPolyLine(temp_dest, gc, mode, n, points); glamor_finish_access_gc(gc); } - glamor_finish_access(drawable); + glamor_finish_access(temp_dest); } - return; - } + } + else { /* fb calls mi functions in the lineWidth != 0 case. */ - fbPolyLine(drawable, gc, mode, n, points); + fbPolyLine(drawable, gc, mode, n, points); + } + if (temp_dest != drawable) { + (void)glamor_copy_area(temp_dest, + drawable, + temp_gc, + 0, 0, + x_max - x_min + 1, y_max - y_min + 1, + x_min, y_min); + drawable->pScreen->DestroyPixmap(temp_pixmap); + for(i = 0; i < n; i++) + { + points[i].x += x_min; + points[i].y += y_min; + } + + FreeScratchGC(temp_gc); + } } From d49d48257917a4a900c84dae111d3f5e761a8d89 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sat, 2 Jul 2011 14:47:38 +0800 Subject: [PATCH 156/225] glamor: Fix multiple crtc setup. Now, support dual crtc configuration. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor_crtc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 1f0396dbf..cf4940291 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -1352,10 +1352,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) if (!crtc->enabled) continue; -#if 0 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); -#endif } return TRUE; From 477a54bc9ed8f252b3a42af8ac01ef1da7b5ab6b Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 7 Jul 2011 14:47:51 +0800 Subject: [PATCH 157/225] glamor: Fixed two unintialized warnings. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 7 ++++++- glamor/glamor_polylines.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 2408e3aae..9e2be123e 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -309,7 +309,7 @@ glamor_copy_n_to_n(DrawablePtr src, void *closure) { glamor_access_t dst_access; - PixmapPtr dst_pixmap, src_pixmap, temp_pixmap; + PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL; DrawablePtr temp_src = src; glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; BoxRec bound; @@ -361,6 +361,11 @@ glamor_copy_n_to_n(DrawablePtr src, temp_dy = -bound.y1; temp_src = &temp_pixmap->drawable; } + else { + temp_dx = dx; + temp_dy = dy; + temp_src = src; + } if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) { goto done; diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index 3fdb26426..d93b60209 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -55,7 +55,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, int y_max = MINSHORT; DrawablePtr temp_dest; PixmapPtr temp_pixmap; - GCPtr temp_gc; + GCPtr temp_gc = NULL; /* Don't try to do wide lines or non-solid fill style. */ if (gc->lineWidth != 0) { /* This ends up in miSetSpans, which is accelerated as well as we From 77ecd366933bbe726a4a7e57e35b1510b675df8d Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 7 Jul 2011 15:30:19 +0800 Subject: [PATCH 158/225] glamor: We don't need to check format in compositing. We already handle all format checking in pixmap uploading and converting, don't need to do that again. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 58 ------------------------------------------ 1 file changed, 58 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 30cc50739..41ee46b7d 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -501,53 +501,6 @@ glamor_composite_with_copy(CARD8 op, return TRUE; } -static Bool -good_source_format(PicturePtr picture) -{ - switch (picture->format) { - case PICT_a1: - case PICT_a8: - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - return TRUE; - default: - return TRUE; - glamor_fallback("Bad source format 0x%08x\n", picture->format); - return FALSE; - } -} - -static Bool -good_mask_format(PicturePtr picture) -{ - switch (picture->format) { - case PICT_a1: - case PICT_a8: - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - return TRUE; - default: - return TRUE; - glamor_fallback("Bad mask format 0x%08x\n", picture->format); - return FALSE; - } -} - -static Bool -good_dest_format(PicturePtr picture) -{ - switch (picture->format) { - case PICT_a8: - case PICT_a8r8g8b8: - case PICT_x8r8g8b8: - return TRUE; - default: - return TRUE; - glamor_fallback("Bad dest format 0x%08x\n", picture->format); - return FALSE; - } -} - static void glamor_setup_composite_vbo(ScreenPtr screen) { @@ -815,10 +768,6 @@ glamor_composite_with_shader(CARD8 op, goto fail; #endif } - if ((source_status != GLAMOR_UPLOAD_PENDING) - && !good_source_format(source)) { - goto fail; - } } if (key.mask == SHADER_MASK_TEXTURE || key.mask == SHADER_MASK_TEXTURE_ALPHA) { @@ -836,13 +785,6 @@ glamor_composite_with_shader(CARD8 op, goto fail; #endif } - if ((mask_status != GLAMOR_UPLOAD_PENDING) - && !good_mask_format(mask)) { - goto fail; - } - } - if (!good_dest_format(dest)) { - goto fail; } #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD if (source_status == GLAMOR_UPLOAD_PENDING From f961390db6fa0707895effb2e7672edda575f8ec Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 7 Jul 2011 15:31:35 +0800 Subject: [PATCH 159/225] glamor: Don't need to pad the tile image if pixmap is ni texture. Signed-off-by: Zhigang Gong --- glamor/glamor_core.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 31734bed0..da8b90b21 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -242,12 +242,10 @@ Bool glamor_prepare_access_gc(GCPtr gc) { if (gc->stipple) { - glamor_fallback("has stipple %p\n", gc->stipple); if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO)) return FALSE; } if (gc->fillStyle == FillTiled) { - glamor_fallback("has tile pixmap %p\n", gc->tile.pixmap); if (!glamor_prepare_access (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO)) { if (gc->stipple) @@ -353,16 +351,20 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) } #endif if (changes & GCTile) { - if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width * - drawable->bitsPerPixel)) - { - glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap); - if (glamor_prepare_access(&gc->tile.pixmap->drawable, + if (!gc->tileIsPixel) { + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(gc->tile.pixmap); + if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + && FbEvenTile(gc->tile.pixmap->drawable.width * + drawable->bitsPerPixel)) + { + glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap); + if (glamor_prepare_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) { fbPadPixmap(gc->tile.pixmap); glamor_finish_access(&gc->tile.pixmap->drawable); - } - } + } + } + } /* Mask out the GCTile change notification, now that we've done FB's * job for it. */ @@ -373,7 +375,6 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) /* We can't inline stipple handling like we do for GCTile because * it sets fbgc privates. */ - glamor_fallback("GC %p stipple changed %p.\n", gc, gc->stipple); if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { fbValidateGC(gc, changes, drawable); glamor_finish_access(&gc->stipple->drawable); From 7fbdc60fd4eb94c02b0b89d05cfe0243c3562ec1 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 7 Jul 2011 15:32:39 +0800 Subject: [PATCH 160/225] glamor: comment out the message when creating a system memory pixmap. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index 6bab8c124..2eec6f536 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -130,9 +130,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3, NULL); +#if 0 if (usage != GLAMOR_CREATE_PIXMAP_CPU) glamor_fallback("choose cpu memory for pixmap %p ," " %d x %d depth %d\n", pixmap, w, h, depth); +#endif } else pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); From fe0a6a29300055f8288c9d1f470fd3e24f5bb3bb Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 7 Jul 2011 16:54:18 +0800 Subject: [PATCH 161/225] glamor: Should return when done gl drawing. Signed-off-by: Zhigang Gong --- glamor/glamor_setspans.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 253f20345..9bc7d1567 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -84,10 +84,11 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, } drawpixels_src += PixmapBytePad(widths[i], drawable->depth); } -fail: - glDisable(GL_SCISSOR_TEST); glamor_set_planemask(dest_pixmap, ~0); glamor_set_alu(GXcopy); + glDisable(GL_SCISSOR_TEST); + return; +fail: glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); From 1caf741a4a41ef46a43980ba0be897770fea13db Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 20 Jul 2011 13:02:28 +0800 Subject: [PATCH 162/225] glamor: Fixed a bug when computing the bounds of boxes. Signed-off-by: Zhigang Gong --- glamor/glamor_utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index 2c6563232..30432cf1f 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -134,11 +134,11 @@ glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox) if (x_min > boxes[i].x1) x_min = boxes[i].x1; if (y_min > boxes[i].y1) - x_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) + if (y_max < boxes[i].y2) y_max = boxes[i].y2; } bound->x1 = x_min; From 5c4d53c5126bb9f603d04dac6874280b527319f5 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 20 Jul 2011 13:06:23 +0800 Subject: [PATCH 163/225] glamor: Implement delayed solid filling. When we need to solid fill an entire pixmap with a specific color, we do not need to draw it immediately. We can defer it to the following occasions: 1. The pixmap will be used as source, then we can just use a shader to instead of one copyarea. 2. The pixmap will be used as target, then we can do the filling just before drawing new pixel onto it. The filling and drawing will have the same target texture, we can save one time of fbo context switching. Actually, for the 2nd case, we have opportunity to further optimize it. We can just fill the untouched region. By applying this patch, the cairo-trace for the firefox-planet-gnome's rendering time decrease to 14seconds from 16 seconds. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 5 ++- glamor/glamor_copyarea.c | 69 ++++++++++++++++++++++++++-------------- glamor/glamor_fill.c | 22 ++++++++++--- glamor/glamor_getspans.c | 1 + glamor/glamor_pixmap.c | 68 ++++++++++++++++++++++++++++++++++++--- glamor/glamor_priv.h | 48 ++++++++++++++++++++++++++-- glamor/glamor_putimage.c | 3 +- glamor/glamor_render.c | 48 ++++++++++++++++++---------- glamor/glamor_setspans.c | 3 +- glamor/glamor_tile.c | 56 ++++++++++++++++++-------------- 10 files changed, 246 insertions(+), 77 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 2eec6f536..695230885 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -98,6 +98,7 @@ glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int te glamor_set_pixmap_texture(pixmap, w, h, tex); glamor_priv->screen_fbo = pixmap_priv->fb; + pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; } @@ -119,7 +120,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, if (w > 32767 || h > 32767) return NullPixmap; - if (!glamor_check_fbo_width_height(w,h) + if (!glamor_check_fbo_width_height(w,h) || !glamor_check_fbo_depth(depth) || usage == GLAMOR_CREATE_PIXMAP_CPU) { /* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo. @@ -201,6 +202,7 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth, pixmap_priv->gl_fbo = 1; pixmap_priv->gl_tex = 1; pixmap_priv->container = pixmap; + pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; screen->CreatePixmap = glamor_create_pixmap; return pixmap; @@ -369,6 +371,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_init_putimage_shaders(screen); glamor_init_finish_access_shaders(screen); glamor_glyphs_init(screen); + glamor_pixmap_init(screen); return TRUE; diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 9e2be123e..4cbb3c66b 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -59,6 +59,9 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); + if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) + return FALSE; + if (gc) { if (gc->alu != GXcopy) { glamor_delayed_fallback(screen, "non-copy ALU\n"); @@ -78,6 +81,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, if (glamor_set_destination_pixmap(dst_pixmap)) { return FALSE; } + glamor_validate_pixmap(dst_pixmap); glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); @@ -130,6 +134,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *pixmap_priv; int x_off, y_off, i; if (src != dst) { glamor_delayed_fallback(screen, "src != dest\n"); @@ -147,6 +152,9 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, } } + pixmap_priv = glamor_get_pixmap_private(dst_pixmap); + if (pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) + return TRUE; if (glamor_set_destination_pixmap(dst_pixmap)) { glamor_delayed_fallback(screen, "dst has no fbo.\n"); return FALSE; @@ -234,37 +242,47 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glamor_set_alu(gc->alu); if (!glamor_set_planemask(dst_pixmap, gc->planemask)) goto fail; + if (gc->alu != GXcopy) { + glamor_set_destination_pixmap_priv_nc(src_pixmap_priv); + glamor_validate_pixmap(src_pixmap); + } + } glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + glamor_validate_pixmap(dst_pixmap); + pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - dx += src_x_off; - dy += src_y_off; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); - glEnable(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - assert(GLEW_ARB_fragment_shader); - glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); - + if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { + glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); + dx += src_x_off; + dy += src_y_off; + pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); + glEnable(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); + } + else { + GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); + } + for (i = 0; i < nbox; i++) { - glamor_set_normalize_vcoords(dst_xscale, dst_yscale, box[i].x1 + dst_x_off, box[i].y1 + dst_y_off, @@ -273,11 +291,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glamor_priv->yInverted, vertices); - glamor_set_normalize_tcoords(src_xscale, src_yscale, - box[i].x1 + dx, box[i].y1 + dy, - box[i].x2 + dx, box[i].y2 + dy, - glamor_priv->yInverted, - texcoords); + if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) + glamor_set_normalize_tcoords(src_xscale, src_yscale, + box[i].x1 + dx, box[i].y1 + dy, + box[i].x2 + dx, box[i].y2 + dy, + glamor_priv->yInverted, + texcoords); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -285,8 +304,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glUseProgramObjectARB(0); glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_TEXTURE_2D); + if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); + } return TRUE; fail: @@ -352,6 +373,7 @@ glamor_copy_n_to_n(DrawablePtr src, if (!temp_src) goto fail; glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1); + temp_src = &temp_pixmap->drawable; fbCopyNtoN(src, temp_src, gc, box, nbox, temp_dx + bound.x1, temp_dy + bound.y1, reverse, upsidedown, bitplane, @@ -359,7 +381,6 @@ glamor_copy_n_to_n(DrawablePtr src, glamor_transform_boxes(box, nbox, bound.x1, bound.y1); temp_dx = -bound.x1; temp_dy = -bound.y1; - temp_src = &temp_pixmap->drawable; } else { temp_dx = dx; diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index a41837b3a..393f651ed 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -154,7 +154,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, GLfloat xscale, yscale; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { - glamor_fallback("dest has no fbo.\n"); + glamor_fallback("dest %p has no fbo.\n", pixmap); goto fail; } glamor_set_alu(alu); @@ -163,15 +163,29 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, goto fail; } - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - glUseProgramObjectARB(glamor_priv->solid_prog); glamor_get_rgba_from_pixel(fg_pixel, &color[0], &color[1], &color[2], &color[3], format_for_pixmap(pixmap)); +#ifdef GLAMOR_DELAYED_FILLING + if (x == 0 && y == 0 + && width == pixmap->drawable.width + && height == pixmap->drawable.height + && pixmap_priv->fb != glamor_priv->screen_fbo ) { + pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL; + memcpy(&pixmap_priv->pending_op.fill.color4fv, + color, 4*sizeof(GLfloat)); + pixmap_priv->pending_op.fill.colori = fg_pixel; + return TRUE; + } +#endif + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glamor_validate_pixmap(pixmap); + + glUseProgramObjectARB(glamor_priv->solid_prog); + glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color); glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 7fe05f993..237c1e789 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -64,6 +64,7 @@ glamor_get_spans(DrawablePtr drawable, } glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glamor_validate_pixmap(pixmap); glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); for (i = 0; i < count; i++) { diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index c76920a26..924a17369 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -26,14 +26,71 @@ glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, *y = 0; } + +static void +_glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, + glamor_pixmap_private *pixmap_priv) +{ + GLfloat vertices[8]; +// glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); + glEnableClientState(GL_VERTEX_ARRAY); + glUseProgramObjectARB(glamor_priv->solid_prog); + glUniform4fvARB(glamor_priv->solid_color_uniform_location, + 1, pixmap_priv->pending_op.fill.color4fv); + vertices[0] = -1; + vertices[1] = -1; + vertices[2] = 1; + vertices[3] = -1; + vertices[4] = 1; + vertices[5] = 1; + vertices[6] = -1; + vertices[7] = 1; + glDrawArrays(GL_QUADS, 0, 4); + glDisableClientState(GL_VERTEX_ARRAY); + glUseProgramObjectARB(0); + pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; +} + + +glamor_pixmap_validate_function_t pixmap_validate_funcs[] = { + NULL, + _glamor_pixmap_validate_filling +}; + +void +glamor_pixmap_init(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs; +} + +void +glamor_validate_pixmap(PixmapPtr pixmap) +{ + glamor_pixmap_validate_function_t validate_op; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_pixmap_private *pixmap_priv = + glamor_get_pixmap_private(pixmap); + + validate_op = glamor_priv->pixmap_validate_funcs[pixmap_priv->pending_op.type]; + if (validate_op) { + (*validate_op)(glamor_priv, pixmap_priv); + } +} + void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glMatrixMode(GL_PROJECTION); glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0, 0, pixmap_priv->container->drawable.width, pixmap_priv->container->drawable.height); + } int @@ -49,9 +106,11 @@ glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv) int glamor_set_destination_pixmap(PixmapPtr pixmap) { + int err; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - return glamor_set_destination_pixmap_priv(pixmap_priv); + err = glamor_set_destination_pixmap_priv(pixmap_priv); + return err; } Bool @@ -376,7 +435,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return TRUE; - + /* XXX we may don't need to validate it on GPU here, + * we can just validate it on CPU. */ if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, @@ -395,7 +455,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) pixmap->drawable.depth); stride = pixmap->devKind; - + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glamor_validate_pixmap(pixmap); switch (access) { case GLAMOR_ACCESS_RO: gl_access = GL_READ_ONLY_ARB; @@ -415,7 +476,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) } row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, row_length); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 4b0037333..b7fcfbdeb 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -149,6 +149,10 @@ enum shader_in { SHADER_IN_COUNT, }; +struct glamor_screen_private; +struct glamor_pixmap_private; +typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, + struct glamor_pixmap_private*); #define GLAMOR_CREATE_PIXMAP_CPU 0x100 typedef struct glamor_screen_private { CloseScreenProcPtr saved_close_screen; @@ -197,7 +201,7 @@ typedef struct glamor_screen_private { [SHADER_IN_COUNT]; Bool has_source_coords, has_mask_coords; int render_nr_verts; - + glamor_pixmap_validate_function_t *pixmap_validate_funcs; glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; int delayed_fallback_pending; @@ -220,9 +224,34 @@ typedef enum glamor_access { * @pbo: attached pbo. * @access_mode: access mode during the prepare/finish pair. * @pict_format: the corresponding picture's format. + * #pending_op: currently only support pending filling. * @container: The corresponding pixmap's pointer. **/ +#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv) \ + (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \ + && (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE)) + +#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv) \ + (pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE) + +enum _glamor_pending_op_type{ + GLAMOR_PENDING_NONE, + GLAMOR_PENDING_FILL +}; + +typedef struct _glamor_pending_fill { + unsigned int type; + GLfloat color4fv[4]; + CARD32 colori; +} glamor_pending_fill; + +typedef union _glamor_pending_op { + unsigned int type; + glamor_pending_fill fill; +} glamor_pending_op; + + typedef struct glamor_pixmap_private { unsigned char gl_fbo:1; unsigned char gl_tex:1; @@ -233,9 +262,20 @@ typedef struct glamor_pixmap_private { GLuint pbo; glamor_access_t access_mode; PictFormatShort pict_format; + glamor_pending_op pending_op; PixmapPtr container; } glamor_pixmap_private; +#define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \ + { \ + if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \ + glUseProgramObjectARB(_glamor_priv_->solid_prog); \ + glUniform4fvARB(_glamor_priv_->solid_color_uniform_location, 1, \ + _pixmap_priv_->pending_op.fill.color4fv); \ + } \ + } while(0) + + /* * Pixmap dynamic status, used by dynamic upload feature. * @@ -678,6 +718,8 @@ glamor_triangles (CARD8 op, /* glamor_pixmap.c */ +void +glamor_pixmap_init(ScreenPtr screen); /** * Download a pixmap's texture to cpu memory. If success, * One copy of current pixmap's texture will be put into @@ -724,7 +766,8 @@ glamor_upload_picture_to_texture(PicturePtr picture); void glamor_destroy_upload_pixmap(PixmapPtr pixmap); - +void +glamor_validate_pixmap(PixmapPtr pixmap); int glamor_create_picture(PicturePtr picture); @@ -753,6 +796,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD +#define GLAMOR_DELAYED_FILLING #include"glamor_utils.h" diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index e61425d11..0a910509c 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -296,6 +296,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, } /* XXX consider to reuse a function to do the following work. */ + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + glamor_validate_pixmap(pixmap); glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); @@ -303,7 +305,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glamor_set_destination_pixmap_priv_nc(pixmap_priv); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 41ee46b7d..f0a6e880c 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -395,16 +395,8 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, } static void -glamor_set_composite_solid(PicturePtr picture, GLint uniform_location) +glamor_set_composite_solid(float *color, GLint uniform_location) { - CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */ - float color[4]; /* rgba */ - - color[0] = ((c >> 16) & 0xff) / 255.0; - color[1] = ((c >> 8) & 0xff) / 255.0; - color[2] = ((c >> 0) & 0xff) / 255.0; - color[3] = ((c >> 24) & 0xff) / 255.0; - glUniform4fvARB(uniform_location, 1, color); } @@ -696,6 +688,7 @@ glamor_composite_with_shader(CARD8 op, enum glamor_pixmap_status mask_status = GLAMOR_NONE; PictFormatShort saved_source_format = 0; float src_matrix[9], mask_matrix[9]; + GLfloat source_solid_color[4], mask_solid_color[4]; dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); @@ -707,6 +700,12 @@ glamor_composite_with_shader(CARD8 op, if (!source->pDrawable) { if (source->pSourcePict->type == SourcePictTypeSolidFill) { key.source = SHADER_SOURCE_SOLID; + glamor_get_rgba_from_pixel(source->pSourcePict->solidFill.color, + &source_solid_color[0], + &source_solid_color[1], + &source_solid_color[2], + &source_solid_color[3], + PICT_a8r8g8b8); } else { glamor_fallback("gradient source\n"); goto fail; @@ -718,6 +717,12 @@ glamor_composite_with_shader(CARD8 op, if (!mask->pDrawable) { if (mask->pSourcePict->type == SourcePictTypeSolidFill) { key.mask = SHADER_MASK_SOLID; + glamor_get_rgba_from_pixel(mask->pSourcePict->solidFill.color, + &mask_solid_color[0], + &mask_solid_color[1], + &mask_solid_color[2], + &mask_solid_color[3], + PICT_a8r8g8b8); } else { glamor_fallback("gradient mask\n"); goto fail; @@ -767,6 +772,10 @@ glamor_composite_with_shader(CARD8 op, glamor_fallback("no texture in source\n"); goto fail; #endif + } + else if (source_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) { + key.source = SHADER_SOURCE_SOLID; + memcpy(source_solid_color, source_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float)); } } if (key.mask == SHADER_MASK_TEXTURE || @@ -785,6 +794,10 @@ glamor_composite_with_shader(CARD8 op, goto fail; #endif } + else if (mask_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) { + key.mask = SHADER_MASK_SOLID; + memcpy(mask_solid_color, mask_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float)); + } } #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD if (source_status == GLAMOR_UPLOAD_PENDING @@ -853,10 +866,11 @@ glamor_composite_with_shader(CARD8 op, } } #endif + glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); + glamor_validate_pixmap(dest_pixmap); if (!glamor_set_composite_op(screen, op, dest, mask)) { goto fail; } - glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); shader = glamor_lookup_composite_shader(screen, &key); if (shader->prog == 0) { @@ -866,13 +880,13 @@ glamor_composite_with_shader(CARD8 op, glUseProgramObjectARB(shader->prog); if (key.source == SHADER_SOURCE_SOLID) { - glamor_set_composite_solid(source, shader->source_uniform_location); + glamor_set_composite_solid(source_solid_color, shader->source_uniform_location); } else { glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); } if (key.mask != SHADER_MASK_NONE) { if (key.mask == SHADER_MASK_SOLID) { - glamor_set_composite_solid(mask, shader->mask_uniform_location); + glamor_set_composite_solid(mask_solid_color, shader->mask_uniform_location); } else { glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); } @@ -888,14 +902,14 @@ glamor_composite_with_shader(CARD8 op, - if (source_pixmap) { + if (glamor_priv->has_source_coords) { glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &source_x_off, &source_y_off); pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale); glamor_picture_get_matrixf(source, src_matrix); } - if (mask_pixmap) { + if (glamor_priv->has_mask_coords) { glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &mask_x_off, &mask_y_off); pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale); @@ -944,14 +958,14 @@ glamor_composite_with_shader(CARD8 op, y_source += source_y_off; x_mask += mask_x_off; y_mask += mask_y_off; - + box = REGION_RECTS(®ion); for (i = 0; i < REGION_NUM_RECTS(®ion); i++) { int vx1 = box[i].x1 + dest_x_off; int vx2 = box[i].x2 + dest_x_off; int vy1 = box[i].y1 + dest_y_off; int vy2 = box[i].y2 + dest_y_off; - glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, glamor_priv->yInverted, vertices); if (key.source != SHADER_SOURCE_SOLID) { @@ -1260,7 +1274,7 @@ glamor_create_mask_picture(ScreenPtr screen, pixmap = screen->CreatePixmap(screen, 0, 0, pict_format->depth, - 0); + GLAMOR_CREATE_PIXMAP_CPU); if (!pixmap) return 0; picture = CreatePicture(0, &pixmap->drawable, pict_format, diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 9bc7d1567..14a24378f 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -52,9 +52,10 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, drawable->depth); goto fail; } - if (glamor_set_destination_pixmap(dest_pixmap)) goto fail; + + glamor_validate_pixmap(dest_pixmap); if (!glamor_set_planemask(dest_pixmap, gc->planemask)) goto fail; glamor_set_alu(gc->alu); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 5bfdd7341..a78c30194 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -107,7 +107,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_fallback("dest has no fbo.\n"); goto fail; } - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { /* XXX dynamic uploading candidate. */ glamor_fallback("Non-texture tile pixmap\n"); @@ -118,48 +117,59 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_fallback("unsupported planemask %lx\n", planemask); goto fail; } - + if (alu != GXcopy) { + glamor_set_destination_pixmap_priv_nc(src_pixmap_priv); + glamor_validate_pixmap(tile); + } + glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + glamor_validate_pixmap(pixmap); pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); - pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); glamor_set_alu(alu); - glUseProgramObjectARB(glamor_priv->tile_prog); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glEnable(GL_TEXTURE_2D); + if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { + pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); + glUseProgramObjectARB(glamor_priv->tile_prog); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glEnable(GL_TEXTURE_2D); + glamor_set_normalize_tcoords(src_xscale, src_yscale, + tile_x1, tile_y1, + tile_x2, tile_y2, + glamor_priv->yInverted, + source_texcoords); + glClientActiveTexture(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + else { + GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); + } + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, x1, y1,x2, y2, glamor_priv->yInverted, vertices); - glamor_set_normalize_tcoords(src_xscale, src_yscale, - tile_x1, tile_y1, - tile_x2, tile_y2, - glamor_priv->yInverted, - source_texcoords); - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); + } glDisableClientState(GL_VERTEX_ARRAY); glUseProgramObjectARB(0); - glDisable(GL_TEXTURE_2D); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); return TRUE; From 1f3f3baf1469e74767474ddb383e92502384de80 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 20 Jul 2011 13:35:25 +0800 Subject: [PATCH 164/225] glamor: Avoid 2D bitblit if possible. It turns out that the use of fbo blit is one of the root cause which lead to slow drawing, especially slow filling rects. We guess there should be a performance bug in the mesa driver or even in the kernel drm driver. Currently, the only thing glamor can do is to avoid calling those functions. We check whether the copy source and destination has overlapped region, if it has, we have to call fbo blit function. If it has not, we can load the source texture directly and draw it to the target texture. We totally don't need the glCopyPixels here, so remove it. By apply this patch, the rendering time of firefox-planet-gnome decrease to 10.4 seconds. At the same platform, uxa driver get 13 seconds. This is the first time we get better performance than uxa driver. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 158 ++++++++++----------------------------- 1 file changed, 38 insertions(+), 120 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 4cbb3c66b..c8ccaaef1 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -47,15 +47,10 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int dst_x_off, dst_y_off, src_x_off, src_y_off, i; - if (src == dst) { - glamor_delayed_fallback(screen,"src == dest\n"); - return FALSE; - } - if (!GLEW_EXT_framebuffer_blit) { glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n"); return FALSE; - } + } src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); @@ -121,78 +116,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, return TRUE; } -static Bool -glamor_copy_n_to_n_copypixels(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, - BoxPtr box, - int nbox, - int dx, - int dy) -{ - ScreenPtr screen = dst->pScreen; - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_pixmap_private *pixmap_priv; - int x_off, y_off, i; - if (src != dst) { - glamor_delayed_fallback(screen, "src != dest\n"); - return FALSE; - } - - if (gc) { - if (gc->alu != GXcopy) { - glamor_delayed_fallback(screen,"non-copy ALU\n"); - return FALSE; - } - if (!glamor_pm_is_solid(dst, gc->planemask)) { - glamor_delayed_fallback(screen,"non-solid planemask\n"); - return FALSE; - } - } - - pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - if (pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) - return TRUE; - if (glamor_set_destination_pixmap(dst_pixmap)) { - glamor_delayed_fallback(screen, "dst has no fbo.\n"); - return FALSE; - } - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glOrtho(0, dst_pixmap->drawable.width, - 0, dst_pixmap->drawable.height, - -1, 1); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off); - - for (i = 0; i < nbox; i++) { - if(glamor_priv->yInverted) { - glRasterPos2i(box[i].x1 + x_off, - box[i].y1 + y_off); - glCopyPixels(box[i].x1 + dx + x_off, - box[i].y1 + dy + y_off, - box[i].x2 - box[i].x1, - box[i].y2 - box[i].y1, - GL_COLOR); - } else { - int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off; - glRasterPos2i(box[i].x1 + x_off, - flip_y1); - glCopyPixels(box[i].x1 + dx + x_off, - flip_y1 - dy, - box[i].x2 - box[i].x1, - box[i].y2 - box[i].y1, - GL_COLOR); - } - } - return TRUE; -} - static Bool glamor_copy_n_to_n_textured(DrawablePtr src, DrawablePtr dst, @@ -213,21 +136,17 @@ glamor_copy_n_to_n_textured(DrawablePtr src, int src_x_off, src_y_off, dst_x_off, dst_y_off; enum glamor_pixmap_status src_status = GLAMOR_NONE; GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; + int flush_needed = 0; src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - if (src == dst) { - glamor_delayed_fallback(dst->pScreen, "same src/dst\n"); - goto fail; - } - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n"); goto fail; } - if (!src_pixmap_priv->gl_tex) { + if (!src_pixmap_priv->gl_fbo) { #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); goto fail; @@ -237,6 +156,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src, goto fail; #endif } + else + flush_needed = 1; if (gc) { glamor_set_alu(gc->alu); @@ -246,7 +167,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glamor_set_destination_pixmap_priv_nc(src_pixmap_priv); glamor_validate_pixmap(src_pixmap); } - } glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); @@ -283,6 +203,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, } for (i = 0; i < nbox; i++) { + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, box[i].x1 + dst_x_off, box[i].y1 + dst_y_off, @@ -308,6 +229,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } + /* The source texture is bound to a fbo, we have to flush it here. */ + if (flush_needed) + glFlush(); return TRUE; fail: @@ -337,8 +261,14 @@ glamor_copy_n_to_n(DrawablePtr src, ScreenPtr screen; int temp_dx = dx; int temp_dy = dy; + int src_x_off, src_y_off, dst_x_off, dst_y_off; + int i; + int overlaped = 0; + dst_pixmap = glamor_get_drawable_pixmap(dst); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); + src_pixmap = glamor_get_drawable_pixmap(src); + src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); screen = dst_pixmap->drawable.pScreen; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { @@ -346,19 +276,29 @@ glamor_copy_n_to_n(DrawablePtr src, goto fail; } - if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { + glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); + + if (src_pixmap_priv->fb == dst_pixmap_priv->fb) { + int x_shift = abs(src_x_off - dx - dst_x_off); + int y_shift = abs(src_y_off - dy - dst_y_off); + for ( i = 0; i < nbox; i++) + { + if (x_shift < abs(box[i].x2 - box[i].x1) + && y_shift < abs(box[i].y2 - box[i].y1)) { + overlaped = 1; + break; + } + } + } + /* XXX need revisit to handle overlapped area copying. */ + + if ( overlaped + && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { goto done; return; } - if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)){ - goto done; - return; - } - - src_pixmap = glamor_get_drawable_pixmap(src); - src_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - glamor_calculate_boxes_bound(&bound, box, nbox); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) @@ -370,7 +310,7 @@ glamor_copy_n_to_n(DrawablePtr src, bound.y2 - bound.y1, src_pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU); - if (!temp_src) + if (!temp_pixmap) goto fail; glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1); temp_src = &temp_pixmap->drawable; @@ -391,6 +331,7 @@ glamor_copy_n_to_n(DrawablePtr src, if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) { goto done; } + fail: glamor_report_delayed_fallbacks(src->pScreen); @@ -406,7 +347,8 @@ glamor_copy_n_to_n(DrawablePtr src, dst_access = GLAMOR_ACCESS_WO; if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { - if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + if (dst == src + || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); @@ -428,34 +370,10 @@ RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty) { -#if 0 - ScreenPtr screen = dst->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); - glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); -#endif RegionPtr region; - region = miDoCopy(src, dst, gc, srcx, srcy, width, height, dstx, dsty, glamor_copy_n_to_n, 0, NULL); return region; - -#if 0 -fail: - glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst, - glamor_get_drawable_location(src), - glamor_get_drawable_location(dst)); - region = NULL; - if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { - region = fbCopyArea(src, dst, gc, srcx, srcy, width, height, - dstx, dsty); - glamor_finish_access(src); - } - glamor_finish_access(dst); - } - return region; -#endif } From 01489f9da9aa357c59799d4d41c7ca96b4cbd1d8 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 20 Jul 2011 14:02:15 +0800 Subject: [PATCH 165/225] glamor: Add simple introduction of how to setup glamor xserver. Signed-off-by: Zhigang Gong --- README | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/README b/README index b2499a059..05effbeba 100644 --- a/README +++ b/README @@ -1,4 +1,83 @@ - X Server + Glamor setup + +1. Prerequirement. +Please install makedepend and libudev-devel firstly. +Glamor need patch glew-1.5.8, here is the patch: + + +diff -ur ../Downloads/glew-1.5.8/Makefile glew-1.5.8/Makefile +--- ../Downloads/glew-1.5.8/Makefile 2011-01-31 22:17:27.000000000 +0800 ++++ glew-1.5.8/Makefile 2011-06-28 10:13:54.147700479 +0800 +@@ -63,8 +63,12 @@ + else + OPT = $(POPT) + endif +-INCLUDE = -Iinclude ++ ++NCLUDE = -Iinclude + CFLAGS = $(OPT) $(WARN) $(INCLUDE) $(CFLAGS.EXTRA) ++ifeq ($(NO_GLX), 1) ++CFLAGS += -D_NO_GLX_ ++endif + + LIB.SRCS = src/glew.c + LIB.OBJS = $(LIB.SRCS:.c=.o) +diff -ur ../Downloads/glew-1.5.8/src/glew.c glew-1.5.8/src/glew.c +--- ../Downloads/glew-1.5.8/src/glew.c 2011-01-31 22:17:27.000000000 +0800 ++++ glew-1.5.8/src/glew.c 2011-06-28 10:06:45.952700777 +0800 +@@ -11379,6 +11379,10 @@ + { + GLenum r; + if ( (r = glewContextInit()) ) return r; ++#if defined(_NO_GLX_) ++ return r; ++#endif ++ + #if defined(_WIN32) + return wglewContextInit(); + #elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ + + +As xserver's glx extension code has conflicts with glew's glx related +initialization, we have to disable it in glew currently. Please apply the +above patch to glew and then build the glew as follow which will +workaround the problem. + +glew-1.5.8# NO_GLX=1 make + +2. Build xserver-glamor. + +Then do the following steps one by one. +2.1. get latest glamor at github. + +2.2 Setup xorg development environment, use xserver-glamor to + replace the official xserver. + Here is the link of how to setup xorg development environment: + http://www.x.org/wiki/ModularDevelopersGuide + + For most of the packages, we prefer latest git version. Especially + for the mesa package. + + When build mesa, use the following parameters: (assume you want to + install the experimental xorg to /opt/gfx-test) +#mesa/./autogen.sh --prefix=/opt/gfx-test --with-egl-platforms=drm --disable-gallium --disable-gallium-egl + + build xserver-glamor as below: +#xserver-glamor/./autogen.sh --disable-glx --enable-kdrive --enable-xephyr + + Once you finish all the building process, you can have a try as below: +xserver-glamor#startx -- `pwd`/hw/xfree86/Xorg If you can find the + following messages on the console, then everything should work correctly. +Mesa: Initializing x86-64 optimizations + + +3. Restrictions: + +Currently, glamor doesn't support glx extension, will be fixed in the future. + +Glamor setup done. + + X Server The X server accepts requests from client applications to create windows, which are (normally rectangular) "virtual screens" that the client program From 9b667ffd564910ff7373547ce2f8d4a7c5d71137 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 20 Jul 2011 14:33:00 +0800 Subject: [PATCH 166/225] glamor: Use small internal texture format if possible. Reduce some texture memory requirement and also save some bandwidth. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 6 +++--- glamor/glamor_pixmap.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 695230885..33a33d690 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -151,10 +151,10 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY) return pixmap; - /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA. - * FBOs, which EXT_fbo forgot to do. - */ switch (depth) { + case 8: + format = GL_ALPHA; + break; case 24: format = GL_RGB; break; diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 924a17369..0f85d9687 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -199,7 +199,20 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); unsigned int stride, row_length; void *texels; - GLenum iformat = GL_RGBA; + GLenum iformat; + + switch (pixmap->drawable.depth) { + case 8: + iformat = GL_ALPHA; + break; + case 24: + iformat = GL_RGB; + break; + default: + iformat = GL_RGBA; + break; + } + stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; From 0ef1698be22750fb14418bd418114fc63039db0c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 21 Jul 2011 16:18:48 +0800 Subject: [PATCH 167/225] glamor: Fix one bug for Xephyr. Xephyr doesn't has a bounded valid texture. It seems that we can't load texture 0 directly sometimes. Especially in the copyarea, function if that is the case, we prefer to use fbo blit to read the screen pixmap rather than load the bound texture. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 2 +- glamor/glamor_copyarea.c | 3 ++- glamor/glamor_render.c | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 33a33d690..f3a83fa04 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -200,7 +200,7 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth, pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv->tex = 0; pixmap_priv->gl_fbo = 1; - pixmap_priv->gl_tex = 1; + pixmap_priv->gl_tex = 0; pixmap_priv->container = pixmap; pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index c8ccaaef1..c7d0d2163 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -293,7 +293,8 @@ glamor_copy_n_to_n(DrawablePtr src, } /* XXX need revisit to handle overlapped area copying. */ - if ( overlaped + if ((overlaped + || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex ) && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { goto done; return; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index f0a6e880c..a9015784e 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -765,7 +765,11 @@ glamor_composite_with_shader(CARD8 op, glamor_fallback("source == dest\n"); goto fail; } - if (!source_pixmap_priv || source_pixmap_priv->gl_tex == 0) { + if (!source_pixmap_priv || source_pixmap_priv->gl_fbo == 0) { + /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex + * equal to zero when the pixmap is screen pixmap. Then we may + * refer the tex zero directly latter in the composition. + * It seems that it works fine, but it may have potential problem*/ #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD source_status = GLAMOR_UPLOAD_PENDING; #else @@ -786,7 +790,7 @@ glamor_composite_with_shader(CARD8 op, glamor_fallback("mask == dest\n"); goto fail; } - if (!mask_pixmap_priv || mask_pixmap_priv->gl_tex == 0) { + if (!mask_pixmap_priv || mask_pixmap_priv->gl_fbo == 0) { #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD mask_status = GLAMOR_UPLOAD_PENDING; #else From 98f8ef5f991e3c9d4b434af9003c466ad1edc23e Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 2 Aug 2011 15:51:46 +0800 Subject: [PATCH 168/225] glamor: Change to use official APIs rather than ARB version function. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 24 ++++++++------ glamor/glamor_copyarea.c | 4 +-- glamor/glamor_core.c | 68 ++++++++++++++++++++-------------------- glamor/glamor_fill.c | 22 ++++++------- glamor/glamor_pixmap.c | 48 ++++++++++++++-------------- glamor/glamor_putimage.c | 32 +++++++++---------- glamor/glamor_render.c | 40 +++++++++++------------ glamor/glamor_tile.c | 22 ++++++------- 8 files changed, 132 insertions(+), 128 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index f3a83fa04..b6789844d 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -74,10 +74,10 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) */ pixmap_priv->gl_fbo = 1; pixmap_priv->gl_tex = 1; - glGenFramebuffersEXT(1, &pixmap_priv->fb); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, + glGenFramebuffers(1, &pixmap_priv->fb); + glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pixmap_priv->tex, 0); @@ -217,11 +217,11 @@ glamor_destroy_pixmap(PixmapPtr pixmap) if (pixmap->refcnt == 1) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->fb) - glDeleteFramebuffersEXT(1, &pixmap_priv->fb); + glDeleteFramebuffers(1, &pixmap_priv->fb); if (pixmap_priv->tex) glDeleteTextures(1, &pixmap_priv->tex); if (pixmap_priv->pbo) - glDeleteBuffersARB(1, &pixmap_priv->pbo); + glDeleteBuffers(1, &pixmap_priv->pbo); dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP); } @@ -293,6 +293,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) glewInit(); +#ifndef GLAMOR_GLES2 if (!GLEW_EXT_framebuffer_object) { ErrorF("GL_EXT_framebuffer_object required\n"); goto fail; @@ -305,14 +306,17 @@ glamor_init(ScreenPtr screen, unsigned int flags) ErrorF("GL_ARB_vertex_shader required\n"); goto fail; } - if (!GLEW_ARB_pixel_buffer_object) { - ErrorF("GL_ARB_pixel_buffer_object required\n"); - goto fail; - } if (!GLEW_EXT_bgra) { ErrorF("GL_EXT_bgra required\n"); goto fail; } +#endif + + if (!GLEW_ARB_pixel_buffer_object) { + ErrorF("GL_ARB_pixel_buffer_object required\n"); + goto fail; + } + if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, NULL)) { diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index c7d0d2163..acd1edc8c 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -196,7 +196,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); + glUseProgram(glamor_priv->finish_access_prog[0]); } else { GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); @@ -222,7 +222,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - glUseProgramObjectARB(0); + glUseProgram(0); glDisableClientState(GL_VERTEX_ARRAY); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index da8b90b21..d99560fd6 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -59,10 +59,10 @@ void glamor_get_transform_uniform_locations(GLint prog, glamor_transform_uniforms *uniform_locations) { - uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias"); - uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale"); - uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias"); - uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale"); + uniform_locations->x_bias = glGetUniformLocation(prog, "x_bias"); + uniform_locations->x_scale = glGetUniformLocation(prog, "x_scale"); + uniform_locations->y_bias = glGetUniformLocation(prog, "y_bias"); + uniform_locations->y_scale = glGetUniformLocation(prog, "y_scale"); } /* We don't use a full matrix for our transformations because it's @@ -73,10 +73,10 @@ void glamor_set_transform_for_pixmap(PixmapPtr pixmap, glamor_transform_uniforms *uniform_locations) { - glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); - glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); - glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); - glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); + glUniform1f(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); + glUniform1f(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); + glUniform1f(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); + glUniform1f(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); } GLint @@ -85,9 +85,9 @@ glamor_compile_glsl_prog(GLenum type, const char *source) GLint ok; GLint prog; - prog = glCreateShaderObjectARB(type); - glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL); - glCompileShaderARB(prog); + prog = glCreateShader(type); + glShaderSource(prog, 1, (const GLchar **)&source, NULL); + glCompileShader(prog); glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok); if (!ok) { GLchar *info; @@ -165,22 +165,22 @@ glamor_init_finish_access_shaders(ScreenPtr screen) GLint fs_prog, vs_prog, avs_prog, aswizzle_prog; - glamor_priv->finish_access_prog[0] = glCreateProgramObjectARB(); - glamor_priv->finish_access_prog[1] = glCreateProgramObjectARB(); + glamor_priv->finish_access_prog[0] = glCreateProgram(); + glamor_priv->finish_access_prog[1] = glCreateProgram(); if (GLEW_ARB_fragment_shader) { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source); - glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog); - glAttachObjectARB(glamor_priv->finish_access_prog[0], fs_prog); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); + glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); + glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); - avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); - aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source); - glAttachObjectARB(glamor_priv->finish_access_prog[1], avs_prog); - glAttachObjectARB(glamor_priv->finish_access_prog[1], aswizzle_prog); + avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); + aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source); + glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); + glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog); } else { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source); - glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); + glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); ErrorF("Lack of framgment shader support.\n"); } @@ -191,16 +191,16 @@ glamor_init_finish_access_shaders(ScreenPtr screen) GLint sampler_uniform_location; sampler_uniform_location = - glGetUniformLocationARB(glamor_priv->finish_access_prog[0], "sampler"); - glUseProgramObjectARB(glamor_priv->finish_access_prog[0]); - glUniform1iARB(sampler_uniform_location, 0); - glUseProgramObjectARB(0); + glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[0]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); sampler_uniform_location = - glGetUniformLocationARB(glamor_priv->finish_access_prog[1], "sampler"); - glUseProgramObjectARB(glamor_priv->finish_access_prog[1]); - glUniform1iARB(sampler_uniform_location, 0); - glUseProgramObjectARB(0); + glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[1]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); } } @@ -218,10 +218,10 @@ glamor_finish_access(DrawablePtr drawable) } if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) { - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); - glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0); + glBindBuffer (GL_PIXEL_UNPACK_BUFFER_EXT, 0); pixmap_priv->pbo_valid = FALSE; - glDeleteBuffersARB(1, &pixmap_priv->pbo); + glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->pbo = 0; } else free(pixmap->devPrivate.ptr); diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 393f651ed..14cce0c8c 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -122,20 +122,20 @@ glamor_init_solid_shader(ScreenPtr screen) "}\n"; GLint fs_prog, vs_prog; - glamor_priv->solid_prog = glCreateProgramObjectARB(); + glamor_priv->solid_prog = glCreateProgram(); if (GLEW_ARB_fragment_shader) { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, solid_fs); - glAttachObjectARB(glamor_priv->solid_prog, vs_prog); - glAttachObjectARB(glamor_priv->solid_prog, fs_prog); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs); + glAttachShader(glamor_priv->solid_prog, vs_prog); + glAttachShader(glamor_priv->solid_prog, fs_prog); } else { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs_only); - glAttachObjectARB(glamor_priv->solid_prog, vs_prog); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs_only); + glAttachShader(glamor_priv->solid_prog, vs_prog); } glamor_link_glsl_prog(glamor_priv->solid_prog); glamor_priv->solid_color_uniform_location = - glGetUniformLocationARB(glamor_priv->solid_prog, "color"); + glGetUniformLocation(glamor_priv->solid_prog, "color"); } Bool @@ -184,9 +184,9 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_validate_pixmap(pixmap); - glUseProgramObjectARB(glamor_priv->solid_prog); + glUseProgram(glamor_priv->solid_prog); - glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color); + glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); @@ -199,7 +199,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); - glUseProgramObjectARB(0); + glUseProgram(0); return TRUE; fail: glamor_set_alu(GXcopy); diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 0f85d9687..0f13f09c2 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -35,8 +35,8 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, // glamor_set_destination_pixmap_priv_nc(pixmap_priv); glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - glUseProgramObjectARB(glamor_priv->solid_prog); - glUniform4fvARB(glamor_priv->solid_color_uniform_location, + glUseProgram(glamor_priv->solid_prog); + glUniform4fv(glamor_priv->solid_color_uniform_location, 1, pixmap_priv->pending_op.fill.color4fv); vertices[0] = -1; vertices[1] = -1; @@ -48,7 +48,7 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, vertices[7] = 1; glDrawArrays(GL_QUADS, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); - glUseProgramObjectARB(0); + glUseProgram(0); pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; } @@ -223,7 +223,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, if (pixmap_priv->pbo && pixmap_priv->pbo_valid) { texels = NULL; - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); } else texels = pixmap->devPrivate.ptr; @@ -300,12 +300,12 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); - glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]); + glUseProgram(glamor_priv->finish_access_prog[ax]); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisable(GL_TEXTURE_2D); - glUseProgramObjectARB(0); + glUseProgram(0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); @@ -472,16 +472,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) glamor_validate_pixmap(pixmap); switch (access) { case GLAMOR_ACCESS_RO: - gl_access = GL_READ_ONLY_ARB; - gl_usage = GL_STREAM_READ_ARB; + gl_access = GL_READ_ONLY; + gl_usage = GL_STREAM_READ; break; case GLAMOR_ACCESS_WO: data = malloc(stride * pixmap->drawable.height); goto done; break; case GLAMOR_ACCESS_RW: - gl_access = GL_READ_WRITE_ARB; - gl_usage = GL_DYNAMIC_DRAW_ARB; + gl_access = GL_READ_WRITE; + gl_usage = GL_DYNAMIC_DRAW; break; default: ErrorF("Glamor: Invalid access code. %d\n", access); @@ -497,41 +497,41 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) if (!glamor_priv->yInverted) glPixelStorei(GL_PACK_INVERT_MESA, 1); if (pixmap_priv->pbo == 0) - glGenBuffersARB (1, &pixmap_priv->pbo); - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT, + glGenBuffers (1, &pixmap_priv->pbo); + glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glBufferData (GL_PIXEL_PACK_BUFFER_EXT, stride * pixmap->drawable.height, NULL, gl_usage); glReadPixels (0, 0, row_length, pixmap->drawable.height, format, type, 0); - data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, gl_access); + data = glMapBuffer (GL_PIXEL_PACK_BUFFER_EXT, gl_access); pixmap_priv->pbo_valid = TRUE; if (!glamor_priv->yInverted) glPixelStorei(GL_PACK_INVERT_MESA, 0); - glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0); + glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0); } else { data = malloc(stride * pixmap->drawable.height); assert(data); if (access != GLAMOR_ACCESS_WO) { if (pixmap_priv->pbo == 0) - glGenBuffersARB(1, &pixmap_priv->pbo); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + glGenBuffers(1, &pixmap_priv->pbo); + glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); + glBufferData(GL_PIXEL_PACK_BUFFER_EXT, stride * pixmap->drawable.height, - NULL, GL_STREAM_READ_ARB); + NULL, GL_STREAM_READ); glReadPixels (0, 0, row_length, pixmap->drawable.height, format, type, 0); - read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB); + read = glMapBuffer(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY); for (y = 0; y < pixmap->drawable.height; y++) memcpy(data + y * stride, read + (pixmap->drawable.height - y - 1) * stride, stride); - glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT); + glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0); pixmap_priv->pbo_valid = FALSE; - glDeleteBuffersARB(1, &pixmap_priv->pbo); + glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->pbo = 0; } } @@ -555,7 +555,7 @@ _glamor_destroy_upload_pixmap(PixmapPtr pixmap) if (pixmap_priv->tex) glDeleteTextures(1, &pixmap_priv->tex); if (pixmap_priv->pbo) - glDeleteBuffersARB(1, &pixmap_priv->pbo); + glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0; } diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 0a910509c..65e7cfdaa 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -66,25 +66,25 @@ glamor_init_putimage_shaders(ScreenPtr screen) if (!GLEW_ARB_fragment_shader) return; - prog = glCreateProgramObjectARB(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, xybitmap_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, xybitmap_fs); - glAttachObjectARB(prog, vs_prog); - glAttachObjectARB(prog, fs_prog); + prog = glCreateProgram(); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs); + glAttachShader(prog, vs_prog); + glAttachShader(prog, fs_prog); glamor_link_glsl_prog(prog); - glUseProgramObjectARB(prog); - sampler_uniform_location = glGetUniformLocationARB(prog, "bitmap_sampler"); - glUniform1iARB(sampler_uniform_location, 0); + glUseProgram(prog); + sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler"); + glUniform1i(sampler_uniform_location, 0); glamor_priv->put_image_xybitmap_fg_uniform_location = - glGetUniformLocationARB(prog, "fg"); + glGetUniformLocation(prog, "fg"); glamor_priv->put_image_xybitmap_bg_uniform_location = - glGetUniformLocationARB(prog, "bg"); + glGetUniformLocation(prog, "bg"); glamor_get_transform_uniform_locations(prog, &glamor_priv->put_image_xybitmap_transform); glamor_priv->put_image_xybitmap_prog = prog; - glUseProgramObjectARB(0); + glUseProgram(0); } @@ -160,13 +160,13 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, if (!glamor_set_planemask(pixmap, gc->planemask)) goto fail; - glUseProgramObjectARB(glamor_priv->put_image_xybitmap_prog); + glUseProgram(glamor_priv->put_image_xybitmap_prog); glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); - glUniform4fvARB(glamor_priv->put_image_xybitmap_fg_uniform_location, + glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg); glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); - glUniform4fvARB(glamor_priv->put_image_xybitmap_bg_uniform_location, + glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); glGenTextures(1, &tex); @@ -322,7 +322,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glEnable(GL_TEXTURE_2D); assert(GLEW_ARB_fragment_shader); - glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]); + glUseProgram(glamor_priv->finish_access_prog[ax]); x += drawable->x; y += drawable->y; @@ -371,7 +371,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, } glDisable(GL_TEXTURE_2D); - glUseProgramObjectARB(0); + glUseProgram(0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index a9015784e..dbb60812f 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -186,7 +186,7 @@ glamor_create_composite_fs(struct shader_key *key) in); - prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source); + prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source); free(source); return prog; @@ -223,7 +223,7 @@ glamor_create_composite_vs(struct shader_key *key) mask_coords_setup, main_closing); - prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source); + prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source); free(source); return prog; @@ -243,30 +243,30 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, if (fs == 0) return; - prog = glCreateProgramObjectARB(); - glAttachObjectARB(prog, vs); - glAttachObjectARB(prog, fs); + prog = glCreateProgram(); + glAttachShader(prog, vs); + glAttachShader(prog, fs); glamor_link_glsl_prog(prog); shader->prog = prog; - glUseProgramObjectARB(prog); + glUseProgram(prog); if (key->source == SHADER_SOURCE_SOLID) { - shader->source_uniform_location = glGetUniformLocationARB(prog, + shader->source_uniform_location = glGetUniformLocation(prog, "source"); } else { - source_sampler_uniform_location = glGetUniformLocationARB(prog, + source_sampler_uniform_location = glGetUniformLocation(prog, "source_sampler"); glUniform1i(source_sampler_uniform_location, 0); } if (key->mask != SHADER_MASK_NONE) { if (key->mask == SHADER_MASK_SOLID) { - shader->mask_uniform_location = glGetUniformLocationARB(prog, + shader->mask_uniform_location = glGetUniformLocation(prog, "mask"); } else { - mask_sampler_uniform_location = glGetUniformLocationARB(prog, + mask_sampler_uniform_location = glGetUniformLocation(prog, "mask_sampler"); glUniform1i(mask_sampler_uniform_location, 1); } @@ -397,7 +397,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, static void glamor_set_composite_solid(float *color, GLint uniform_location) { - glUniform4fvARB(uniform_location, 1, color); + glUniform4fv(uniform_location, 1, color); } static int @@ -504,7 +504,7 @@ glamor_setup_composite_vbo(ScreenPtr screen) if (glamor_priv->has_mask_coords) glamor_priv->vb_stride += 2 * sizeof(float); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo); + glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset)); glEnableClientState(GL_VERTEX_ARRAY); @@ -559,8 +559,8 @@ glamor_flush_composite_rects(ScreenPtr screen) if (!glamor_priv->render_nr_verts) return; - glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_offset, glamor_priv->vb, - GL_STREAM_DRAW_ARB); + glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb, + GL_STREAM_DRAW); glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts); glamor_reset_composite_vbo(screen); @@ -582,7 +582,7 @@ glamor_emit_composite_rect(ScreenPtr screen, if (glamor_priv->vbo_offset == 0) { if (glamor_priv->vbo == 0) - glGenBuffersARB(1, &glamor_priv->vbo); + glGenBuffers(1, &glamor_priv->vbo); glamor_setup_composite_vbo(screen); } @@ -882,7 +882,7 @@ glamor_composite_with_shader(CARD8 op, goto fail; } - glUseProgramObjectARB(shader->prog); + glUseProgram(shader->prog); if (key.source == SHADER_SOURCE_SOLID) { glamor_set_composite_solid(source_solid_color, shader->source_uniform_location); } else { @@ -1008,7 +1008,7 @@ glamor_composite_with_shader(CARD8 op, } glamor_flush_composite_rects(screen); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE1); @@ -1021,7 +1021,7 @@ glamor_composite_with_shader(CARD8 op, glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE1); glDisable(GL_TEXTURE_2D); - glUseProgramObjectARB(0); + glUseProgram(0); if (saved_source_format) source->format = saved_source_format; return TRUE; @@ -1031,7 +1031,7 @@ glamor_composite_with_shader(CARD8 op, source->format = saved_source_format; glDisable(GL_BLEND); - glUseProgramObjectARB(0); + glUseProgram(0); return FALSE; } @@ -1223,7 +1223,7 @@ fail: dest->pDrawable->height, glamor_get_picture_location(dest)); - glUseProgramObjectARB(0); + glUseProgram(0); glDisable(GL_BLEND); if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO)) diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index a78c30194..436e769f8 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -58,18 +58,18 @@ glamor_init_tile_shader(ScreenPtr screen) if (!GLEW_ARB_fragment_shader) return; - glamor_priv->tile_prog = glCreateProgramObjectARB(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, tile_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, tile_fs); - glAttachObjectARB(glamor_priv->tile_prog, vs_prog); - glAttachObjectARB(glamor_priv->tile_prog, fs_prog); + glamor_priv->tile_prog = glCreateProgram(); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs); + glAttachShader(glamor_priv->tile_prog, vs_prog); + glAttachShader(glamor_priv->tile_prog, fs_prog); glamor_link_glsl_prog(glamor_priv->tile_prog); sampler_uniform_location = - glGetUniformLocationARB(glamor_priv->tile_prog, "sampler"); - glUseProgramObjectARB(glamor_priv->tile_prog); - glUniform1iARB(sampler_uniform_location, 0); - glUseProgramObjectARB(0); + glGetUniformLocation(glamor_priv->tile_prog, "sampler"); + glUseProgram(glamor_priv->tile_prog); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); } Bool @@ -130,7 +130,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - glUseProgramObjectARB(glamor_priv->tile_prog); + glUseProgram(glamor_priv->tile_prog); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); @@ -169,7 +169,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, } glDisableClientState(GL_VERTEX_ARRAY); - glUseProgramObjectARB(0); + glUseProgram(0); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); return TRUE; From 68c3c6eb0cafd5eb2c208dd76a3a65187256700c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 2 Aug 2011 15:54:15 +0800 Subject: [PATCH 169/225] glamor-es2: Add gles2 option. First commit to enable gles2 support. --enable-glamor-ddx --enable-glamor-gles2 will set thwo MACROs GLAMOR_DDX and GLAMOR_GLES2. Currently, the gles2 support is still incomplete. Signed-off-by: Zhigang Gong --- Makefile.am | 6 +++++- configure.ac | 23 +++++++++++++++++++++++ glamor/glamor_priv.h | 18 ++++++++++++++++++ hw/xfree86/Makefile.am | 8 ++++++-- hw/xfree86/common/xf86pciBus.c | 4 ++++ hw/xfree86/glamor/Makefile.am | 7 +++++-- hw/xfree86/glamor/glamor.c | 7 ++++++- hw/xfree86/glamor/glamor_crtc.c | 18 ++++++++++++++++-- include/xorg-config.h.in | 11 +++++++++++ 9 files changed, 94 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0c701633d..632258eec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,10 @@ if RECORD RECORD_DIR=record endif +if GLAMOR +GLAMOR_DIR=glamor +endif + SUBDIRS = \ doc \ man \ @@ -38,7 +42,7 @@ SUBDIRS = \ $(COMPOSITE_DIR) \ $(GLX_DIR) \ exa \ - glamor \ + $(GLAMOR_DIR) \ config \ hw \ test diff --git a/configure.ac b/configure.ac index caefc4674..73c1bea0e 100644 --- a/configure.ac +++ b/configure.ac @@ -646,6 +646,8 @@ AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest serv AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto]) AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no]) AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto]) +#AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor server (default: no)]), [GLAMOR=$enableval], [GLAMOR=no]) +AC_ARG_ENABLE(glamor-ddx, AS_HELP_STRING([--enable-glamor-ddx], [Build glamor ddx (default: no)]), [GLAMOR_DDX=$enableval], [GLAMOR_DDX=no]) dnl kdrive and its subsystems AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no]) AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto]) @@ -655,6 +657,8 @@ dnl kdrive options AC_ARG_ENABLE(kdrive-kbd, AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto]) AC_ARG_ENABLE(kdrive-mouse, AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto]) AC_ARG_ENABLE(kdrive-evdev, AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto]) +dnl glamor options +AC_ARG_ENABLE(glamor-gles2, AS_HELP_STRING([--enable-glamor-gles2], [Build glamor based on gles2 (default: no)]), [GLAMOR_GLES2=$enableval], [GLAMOR_GLES2=no]) dnl chown/chmod to be setuid root as part of build @@ -1765,6 +1769,25 @@ AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes]) AM_CONDITIONAL([DGA], [test "x$DGA" = xyes]) AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) +dnl glamor + +AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes]) + +GLAMOR=yes + +if test "x$GLAMOR" = xyes; then + AC_DEFINE(GLAMOR,1,[Build Glamor]) + if test "x$GLAMOR_GLES2" = xyes; then + AC_DEFINE(GLAMOR_GLES2,1,[Build glamor over GLES2]) + else + AC_DEFINE(GLAMOR_GL,1,[Build glamor over GL]) + fi + + if test "x$GLAMOR_DDX" = xyes; then + AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver]) + fi +fi + dnl XWin DDX AC_MSG_CHECKING([whether to build XWin DDX]) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index b7fcfbdeb..6005a2cd9 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -29,10 +29,28 @@ #ifdef HAVE_DIX_CONFIG_H #include +#include #endif #include "glamor.h" + +#ifdef GLAMOR_GLES2 + +#define GLEW_ES_ONLY 1 + +#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_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 + +#endif + #include #ifdef RENDER diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index 830f17ac9..f76a36155 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -27,12 +27,16 @@ if INT10MODULE INT10_SUBDIR = int10 endif -SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw glamor os-support parser \ +if GLAMOR +GLAMOR_DIR=glamor +endif + +SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw $(GLAMOR_DIR) os-support parser \ ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ loader dixmods exa modes \ $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man -DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw glamor os-support \ +DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw $(GLAMOR_DIR) os-support \ parser ramdac shadowfb vbe vgahw xaa \ loader dixmods dri dri2 exa modes \ utils doc man diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 56fb62f64..663e70ad9 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -1118,7 +1118,11 @@ videoPtrToDriverList(struct pci_device *dev, } else if (dev->device_id == 0x8108) { break; /* "hooray" for poulsbo */ } else { +#if GLAMOR_DDX driverList[0] = "glamor"; +#else + driverList[0] = "intel"; +#endif } break; case 0x102b: driverList[0] = "mga"; break; diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index d691009eb..d9dc8a90a 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -12,8 +12,11 @@ glamor_la_CFLAGS = \ -I$(top_srcdir)/glamor \ -I/usr/include/drm -glamor_la_LDFLAGS = \ - -module -avoid-version -L$(libdir) -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW +glamor_la_LDFLAGS = \ + -module -avoid-version -L$(libdir) -lEGL \ + $(top_builddir)/glamor/libglamor.la \ + -L$(libdir)/../lib64 -lGLEW + glamor_ladir = $(moduledir)/drivers glamor_la_SOURCES = \ glamor.c \ diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 1da7eb20d..a1128da43 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -38,7 +38,13 @@ #define GL_GLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES #define EGL_DISPLAY_NO_X_MESA + +#if GLAMOR_GLES2 +#include +#else #include +#endif + #include #include @@ -322,7 +328,6 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) glamor->display = eglGetDRMDisplayMESA(glamor->fd); eglBindAPI(EGL_OPENGL_API); - LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB)); if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n"); diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index cf4940291..d2f98fb5f 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -53,7 +53,17 @@ #define GL_GLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES #define EGL_DISPLAY_NO_X_MESA + +#if GLAMOR_GLES2 +#include +#include +#ifndef GL_BGRA +#define GL_BGRA GL_BGRA_EXT +#endif +#else #include +#endif + #include #include @@ -482,11 +492,15 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor); } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, 64); glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); +#if GLAMOR_GLES2 + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, 64, 64, 0, + GL_BGRA, GL_UNSIGNED_BYTE, image); +#else + glPixelStorei(GL_UNPACK_ROW_LENGTH, 64); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image); +#endif } diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in index 0d1ea9142..c9760b090 100644 --- a/include/xorg-config.h.in +++ b/include/xorg-config.h.in @@ -139,4 +139,15 @@ /* Build with libdrm support */ #undef WITH_LIBDRM + +/* Build GLAMOR */ +#undef GLAMOR + +/* Build GLAMOR over GLES2*/ +#undef GLAMOR_GLES2 + +/* Build GLAMOR ddx*/ +#undef GLAMOR_DDX + + #endif /* _XORG_CONFIG_H_ */ From 94d884a198b97ed2e78a38ce5a71955bdbf893f8 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 3 Aug 2011 10:49:18 +0800 Subject: [PATCH 170/225] glamor-es2: Fix some non-es2 functions. ES2.0 doesn't support QUADS and also doesn't support some EXT APIs. Fix some of them in this commit. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 14 ++++++++------ glamor/glamor_copyarea.c | 8 +++++--- glamor/glamor_core.c | 18 ++++++++++-------- glamor/glamor_pixmap.c | 38 +++++++++++++++++++------------------- glamor/glamor_priv.h | 33 +++++++++++++++++++++++++++++++-- glamor/glamor_render.c | 9 +++++++-- 6 files changed, 80 insertions(+), 40 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index b6789844d..7acfc9853 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -291,9 +291,9 @@ glamor_init(ScreenPtr screen, unsigned int flags) return FALSE; } - glewInit(); #ifndef GLAMOR_GLES2 + glewInit(); if (!GLEW_EXT_framebuffer_object) { ErrorF("GL_EXT_framebuffer_object required\n"); goto fail; @@ -306,17 +306,19 @@ glamor_init(ScreenPtr screen, unsigned int flags) ErrorF("GL_ARB_vertex_shader required\n"); goto fail; } - if (!GLEW_EXT_bgra) { - ErrorF("GL_EXT_bgra required\n"); - goto fail; - } -#endif if (!GLEW_ARB_pixel_buffer_object) { ErrorF("GL_ARB_pixel_buffer_object required\n"); goto fail; } + if (!GLEW_EXT_bgra) { + ErrorF("GL_EXT_bgra required\n"); + goto fail; + } +#endif + + if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, NULL)) { diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index acd1edc8c..4b4a335e0 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -31,6 +31,7 @@ * * GC CopyArea implementation */ +#ifndef GLAMOR_GLES2 static Bool glamor_copy_n_to_n_fbo_blit(DrawablePtr src, DrawablePtr dst, @@ -51,7 +52,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n"); return FALSE; } - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) @@ -77,8 +77,8 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, return FALSE; } glamor_validate_pixmap(dst_pixmap); - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); src_y_off += dy; @@ -115,6 +115,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, } return TRUE; } +#endif static Bool glamor_copy_n_to_n_textured(DrawablePtr src, @@ -293,13 +294,14 @@ glamor_copy_n_to_n(DrawablePtr src, } /* XXX need revisit to handle overlapped area copying. */ +#ifndef GLAMOR_GLES2 if ((overlaped || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex ) && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { goto done; return; } - +#endif glamor_calculate_boxes_bound(&bound, box, nbox); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index d99560fd6..f33762887 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -88,15 +88,15 @@ glamor_compile_glsl_prog(GLenum type, const char *source) prog = glCreateShader(type); glShaderSource(prog, 1, (const GLchar **)&source, NULL); glCompileShader(prog); - glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok); + glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); if (!ok) { GLchar *info; GLint size; - glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); + glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); info = malloc(size); - glGetInfoLogARB(prog, size, NULL, info); + glGetShaderInfoLog(prog, size, NULL, info); ErrorF("Failed to compile %s: %s\n", type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); @@ -113,15 +113,15 @@ glamor_link_glsl_prog(GLint prog) GLint ok; glLinkProgram(prog); - glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok); + glGetProgramiv(prog, GL_LINK_STATUS, &ok); if (!ok) { GLchar *info; GLint size; - glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); info = malloc(size); - glGetInfoLogARB(prog, size, NULL, info); + glGetProgramInfoLog(prog, size, NULL, info); ErrorF("Failed to link: %s\n", info); FatalError("GLSL link failure\n"); @@ -209,6 +209,7 @@ glamor_finish_access(DrawablePtr drawable) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return; @@ -218,8 +219,9 @@ glamor_finish_access(DrawablePtr drawable) } if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) { - glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0); - glBindBuffer (GL_PIXEL_UNPACK_BUFFER_EXT, 0); + assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); + glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); + glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); pixmap_priv->pbo_valid = FALSE; glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->pbo = 0; diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 0f13f09c2..34fc408cc 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -46,7 +46,7 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, vertices[5] = 1; vertices[6] = -1; vertices[7] = 1; - glDrawArrays(GL_QUADS, 0, 4); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glUseProgram(0); pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; @@ -83,7 +83,7 @@ glamor_validate_pixmap(PixmapPtr pixmap) void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -223,7 +223,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, if (pixmap_priv->pbo && pixmap_priv->pbo_valid) { texels = NULL; - glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo); } else texels = pixmap->devPrivate.ptr; @@ -288,7 +288,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); + glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); glGenTextures(1, &tex); @@ -309,7 +309,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDeleteTextures(1, &tex); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -347,7 +347,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax) if (need_fbo) { if (pixmap_priv->fb == 0) - glGenFramebuffersEXT(1, &pixmap_priv->fb); + glGenFramebuffers(1, &pixmap_priv->fb); glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -355,9 +355,9 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax) pixmap->drawable.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, + glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pixmap_priv->tex, 0); @@ -498,45 +498,45 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) glPixelStorei(GL_PACK_INVERT_MESA, 1); if (pixmap_priv->pbo == 0) glGenBuffers (1, &pixmap_priv->pbo); - glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferData (GL_PIXEL_PACK_BUFFER_EXT, + glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); + glBufferData (GL_PIXEL_PACK_BUFFER, stride * pixmap->drawable.height, NULL, gl_usage); glReadPixels (0, 0, row_length, pixmap->drawable.height, format, type, 0); - data = glMapBuffer (GL_PIXEL_PACK_BUFFER_EXT, gl_access); + data = glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access); pixmap_priv->pbo_valid = TRUE; if (!glamor_priv->yInverted) glPixelStorei(GL_PACK_INVERT_MESA, 0); - glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0); + glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); } else { data = malloc(stride * pixmap->drawable.height); assert(data); if (access != GLAMOR_ACCESS_WO) { if (pixmap_priv->pbo == 0) glGenBuffers(1, &pixmap_priv->pbo); - glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo); - glBufferData(GL_PIXEL_PACK_BUFFER_EXT, + glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); + glBufferData(GL_PIXEL_PACK_BUFFER, stride * pixmap->drawable.height, NULL, GL_STREAM_READ); glReadPixels (0, 0, row_length, pixmap->drawable.height, format, type, 0); - read = glMapBuffer(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY); + read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); for (y = 0; y < pixmap->drawable.height; y++) memcpy(data + y * stride, read + (pixmap->drawable.height - y - 1) * stride, stride); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT); - glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); pixmap_priv->pbo_valid = FALSE; glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->pbo = 0; } } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); done: pixmap->devPrivate.ptr = data; return TRUE; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 6005a2cd9..ac51a729b 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -49,9 +49,31 @@ #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GLEW_ARB_fragment_shader 1 +#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 GLEW_MESA_pack_invert 0 +#define GL_PACK_INVERT_MESA 0x8758 + #endif +#ifdef GLAMOR_GLES2 +#define GL_GLEXT_PROTOTYPES +#include +#include +#else #include +#endif + #ifdef RENDER #include "glyphstr.h" @@ -171,6 +193,12 @@ struct glamor_screen_private; struct glamor_pixmap_private; typedef void (*glamor_pixmap_validate_function_t)(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 typedef struct glamor_screen_private { CloseScreenProcPtr saved_close_screen; @@ -196,6 +224,7 @@ typedef struct glamor_screen_private { int vbo_size; char *vb; int vb_stride; + enum glamor_gl_flavor gl_flavor; /* glamor_finishaccess */ GLint finish_access_prog[2]; @@ -287,8 +316,8 @@ typedef struct glamor_pixmap_private { #define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \ { \ if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \ - glUseProgramObjectARB(_glamor_priv_->solid_prog); \ - glUniform4fvARB(_glamor_priv_->solid_color_uniform_location, 1, \ + glUseProgram(_glamor_priv_->solid_prog); \ + glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1, \ _pixmap_priv_->pending_op.fill.color4fv); \ } \ } while(0) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index dbb60812f..224ae27cc 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -362,6 +362,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); switch (picture->repeatType) { case RepeatNone: +#ifdef GLAMOR_GLES2 + assert(0); +#endif glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); break; @@ -562,7 +565,7 @@ glamor_flush_composite_rects(ScreenPtr screen) glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb, GL_STREAM_DRAW); - glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts); + glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts); glamor_reset_composite_vbo(screen); } @@ -574,7 +577,7 @@ glamor_emit_composite_rect(ScreenPtr screen, { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride > + if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride > glamor_priv->vbo_size) { glamor_flush_composite_rects(screen); @@ -590,6 +593,8 @@ glamor_emit_composite_rect(ScreenPtr screen, glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0); glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1); glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2); glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3); } From ee33c947aac10b2b1ec2c5b070fbd81cef1773c6 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 3 Aug 2011 16:52:19 +0800 Subject: [PATCH 171/225] glamor-es: Use glVertexAttribPointer to replace glVertexPointer. As GLES2 doesn't support glVertexPointer. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 34 +++++++++++++++++---- glamor/glamor_core.c | 65 ++++++++++++++++++++++++++++++++++++++++ glamor/glamor_fill.c | 30 +++++++++++++++++-- glamor/glamor_pixmap.c | 41 +++++++++++++++++++++++-- glamor/glamor_priv.h | 8 ++++- glamor/glamor_putimage.c | 28 +++++++++++++++-- glamor/glamor_render.c | 63 ++++++++++++++++++++++++++++++++------ glamor/glamor_tile.c | 46 ++++++++++++++++++++++++++-- 8 files changed, 291 insertions(+), 24 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 4b4a335e0..7a84adbf2 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -176,29 +176,46 @@ glamor_copy_n_to_n_textured(DrawablePtr src, pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); + +#if 0 glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); +#else + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + vertices); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); dx += src_x_off; dy += src_y_off; pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - +#if 0 glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glUseProgram(glamor_priv->finish_access_prog[0]); - } +#else + + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + texcoords); + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glUseProgram(glamor_priv->finish_access_prog[2]); +#endif + + } else { GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); } @@ -223,13 +240,20 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - glUseProgram(0); - +#if 0 glDisableClientState(GL_VERTEX_ARRAY); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } +#else + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { + glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glDisable(GL_TEXTURE_2D); + } +#endif + glUseProgram(0); /* The source texture is bound to a fbo, we have to flush it here. */ if (flush_needed) glFlush(); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index f33762887..f585d6a2e 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -162,11 +162,42 @@ glamor_init_finish_access_shaders(ScreenPtr screen) "{\n" " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n" "}\n"; + const char *es_vs_source = + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord0;\n" + "varying vec2 source_texture;\n" + "void main()\n" + "{\n" + " gl_Position = v_position;\n" + " source_texture = v_texcoord0.xy;\n" + "}\n"; + + const char *es_fs_source = + "varying vec2 source_texture;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(sampler, source_texture);\n" + "}\n"; + + const char *es_aswizzle_source = + "varying vec2 source_texture;\n" + "varying vec2 texcoords;\n" + "uniform sampler2D sampler;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" + "}\n"; + + GLint fs_prog, vs_prog, avs_prog, aswizzle_prog; + GLint es_fs_prog, es_vs_prog, es_avs_prog, es_aswizzle_prog; glamor_priv->finish_access_prog[0] = glCreateProgram(); glamor_priv->finish_access_prog[1] = glCreateProgram(); + glamor_priv->finish_access_prog[2] = glCreateProgram(); + glamor_priv->finish_access_prog[3] = glCreateProgram(); if (GLEW_ARB_fragment_shader) { vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); @@ -178,15 +209,36 @@ glamor_init_finish_access_shaders(ScreenPtr screen) aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source); glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog); + + es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); + es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source); + glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog); + glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog); + + es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); + es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source); + glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog); + glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog); + } else { vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); ErrorF("Lack of framgment shader support.\n"); } + + glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]); glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); + glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_POS, "v_position"); + glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(glamor_priv->finish_access_prog[2]); + + glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_POS, "v_position"); + glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(glamor_priv->finish_access_prog[3]); + if (GLEW_ARB_fragment_shader) { GLint sampler_uniform_location; @@ -201,6 +253,19 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glUseProgram(glamor_priv->finish_access_prog[1]); glUniform1i(sampler_uniform_location, 0); glUseProgram(0); + + sampler_uniform_location = + glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[2]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); + + sampler_uniform_location = + glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[3]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); + } } diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 14cce0c8c..bfa30b2e3 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -103,16 +103,32 @@ glamor_init_solid_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); const char *solid_vs_only = +#if 0 +#else + "attribute vec4 v_position;" +#endif "uniform vec4 color;\n" "void main()\n" "{\n" +#if 0 " gl_Position = gl_Vertex;\n" +#else + " gl_Position = v_position;\n" +#endif " gl_Color = color;\n" "}\n"; const char *solid_vs = +#if 0 +#else + "attribute vec4 v_position;" +#endif "void main()\n" "{\n" +#if 0 " gl_Position = gl_Vertex;\n" +#else + " gl_Position = v_position;\n" +#endif "}\n"; const char *solid_fs = "uniform vec4 color;\n" @@ -132,6 +148,8 @@ glamor_init_solid_shader(ScreenPtr screen) vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs_only); glAttachShader(glamor_priv->solid_prog, vs_prog); } + + glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position"); glamor_link_glsl_prog(glamor_priv->solid_prog); glamor_priv->solid_color_uniform_location = @@ -188,17 +206,25 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); +#if 0 glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - +#else + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), vertices); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, glamor_priv->yInverted, vertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - +#if 0 glDisableClientState(GL_VERTEX_ARRAY); +#else + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif glUseProgram(0); return TRUE; fail: diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 34fc408cc..ce4ca0097 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -32,9 +32,14 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, glamor_pixmap_private *pixmap_priv) { GLfloat vertices[8]; -// glamor_set_destination_pixmap_priv_nc(pixmap_priv); +#if 0 glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); +#else + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), vertices); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif glUseProgram(glamor_priv->solid_prog); glUniform4fv(glamor_priv->solid_color_uniform_location, 1, pixmap_priv->pending_op.fill.color4fv); @@ -47,7 +52,11 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, vertices[6] = -1; vertices[7] = 1; glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +#if 0 glDisableClientState(GL_VERTEX_ARRAY); +#else + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif glUseProgram(0); pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; } @@ -84,8 +93,10 @@ void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) { glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); +#ifndef GLAMOR_GLES2 glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); +#endif glViewport(0, 0, pixmap_priv->container->drawable.width, @@ -129,6 +140,7 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask) void glamor_set_alu(unsigned char alu) { +#ifndef GLAMOR_GLES2 if (alu == GXcopy) { glDisable(GL_COLOR_LOGIC_OP); return; @@ -183,6 +195,10 @@ glamor_set_alu(unsigned char alu) default: FatalError("unknown logic op\n"); } +#else + if (alu != GXcopy) + ErrorF("unsupported alu %x \n", alu); +#endif } @@ -219,8 +235,9 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, glBindTexture(GL_TEXTURE_2D, tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +#ifndef GLAMOR_GLES2 glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); - +#endif if (pixmap_priv->pbo && pixmap_priv->pbo_valid) { texels = NULL; glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo); @@ -282,12 +299,23 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i ptexcoords = texcoords_inv; /* Slow path, we need to flip y or wire alpha to 1. */ +#if 0 glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#else + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + vertices); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + ptexcoords); + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#endif glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); @@ -300,14 +328,23 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); +#if 0 glUseProgram(glamor_priv->finish_access_prog[ax]); +#else + glUseProgram(glamor_priv->finish_access_prog[ax + 2]); +#endif glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisable(GL_TEXTURE_2D); glUseProgram(0); +#if 0 glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#else + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#endif glDeleteTextures(1, &tex); glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index ac51a729b..217600844 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -166,6 +166,12 @@ typedef struct { #define GLAMOR_NUM_GLYPH_CACHES 4 +enum glamor_vertex_type { + GLAMOR_VERTEX_POS, + GLAMOR_VERTEX_SOURCE, + GLAMOR_VERTEX_MASK +}; + enum shader_source { SHADER_SOURCE_SOLID, SHADER_SOURCE_TEXTURE, @@ -227,7 +233,7 @@ typedef struct glamor_screen_private { enum glamor_gl_flavor gl_flavor; /* glamor_finishaccess */ - GLint finish_access_prog[2]; + GLint finish_access_prog[4]; /* glamor_solid */ GLint solid_prog; diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 65e7cfdaa..4b2215a9f 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -298,17 +298,30 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, /* XXX consider to reuse a function to do the following work. */ glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_validate_pixmap(pixmap); +#if 0 glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - +#else + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + vertices); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + texcoords); + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#endif glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +#ifndef GLAMOR_GLES2 glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / pixmap->drawable.bitsPerPixel); +#endif glGenTextures(1, &tex); @@ -321,8 +334,11 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); - assert(GLEW_ARB_fragment_shader); +#if 0 glUseProgram(glamor_priv->finish_access_prog[ax]); +#else + glUseProgram(glamor_priv->finish_access_prog[ax + 2]); +#endif x += drawable->x; y += drawable->y; @@ -372,11 +388,17 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glDisable(GL_TEXTURE_2D); glUseProgram(0); +#if 0 glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#else + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#endif glDeleteTextures(1, &tex); +#ifndef GLAMOR_GLES2 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); +#endif glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); return; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 224ae27cc..6b8c7601b 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -36,7 +36,7 @@ #include "mipict.h" #include "fbpict.h" -#include "glu3/glu3.h" +//#include "glu3/glu3.h" struct shader_key { enum shader_source source; @@ -77,16 +77,18 @@ glamor_create_composite_fs(struct shader_key *key) " return source;\n" "}\n"; const char *source_alpha_pixmap_fetch = + "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "vec4 get_source()\n" "{\n" - " return texture2D(source_sampler, gl_TexCoord[0].xy);\n" + " return texture2D(source_sampler, source_texture);\n" "}\n"; const char *source_pixmap_fetch = + "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "vec4 get_source()\n" "{\n" - " return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb, 1);\n" + " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n" "}\n"; const char *mask_solid_fetch = "uniform vec4 mask;\n" @@ -95,16 +97,18 @@ glamor_create_composite_fs(struct shader_key *key) " return mask;\n" "}\n"; const char *mask_alpha_pixmap_fetch = + "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n" - " return texture2D(mask_sampler, gl_TexCoord[1].xy);\n" + " return texture2D(mask_sampler, mask_texture);\n" "}\n"; const char *mask_pixmap_fetch = + "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n" - " return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, 1);\n" + " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n" "}\n"; const char *in_source_only = "void main()\n" @@ -196,13 +200,18 @@ static GLuint glamor_create_composite_vs(struct shader_key *key) { const char *main_opening = + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord0;\n" + "attribute vec4 v_texcoord1;\n" + "varying vec2 source_texture;\n" + "varying vec2 mask_texture;\n" "void main()\n" "{\n" - " gl_Position = gl_Vertex;\n"; + " gl_Position = v_position;\n"; const char *source_coords = - " gl_TexCoord[0] = gl_MultiTexCoord0;\n"; + " source_texture = v_texcoord0.xy;\n"; const char *mask_coords = - " gl_TexCoord[1] = gl_MultiTexCoord1;\n"; + " mask_texture = v_texcoord1.xy;\n"; const char *main_closing = "}\n"; const char *source_coords_setup = ""; @@ -246,6 +255,11 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, prog = glCreateProgram(); glAttachShader(prog, vs); glAttachShader(prog, fs); + + glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position"); + glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); + glamor_link_glsl_prog(prog); shader->prog = prog; @@ -508,24 +522,48 @@ glamor_setup_composite_vbo(ScreenPtr screen) glamor_priv->vb_stride += 2 * sizeof(float); glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + +#if 0 glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset)); glEnableClientState(GL_VERTEX_ARRAY); +#else + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + glamor_priv->vb_stride, + (void *)((long)glamor_priv->vbo_offset)); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif if (glamor_priv->has_source_coords) { +#if 0 glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, (void *)(glamor_priv->vbo_offset + 2 * sizeof(float))); glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#else + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + glamor_priv->vb_stride, + (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float))); + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#endif } if (glamor_priv->has_mask_coords) { +#if 0 glClientActiveTexture(GL_TEXTURE1); glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, (void *)(glamor_priv->vbo_offset + (glamor_priv->has_source_coords ? 4 : 2) * sizeof(float))); glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#else + glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, + glamor_priv->vb_stride, + (void *)((long)glamor_priv->vbo_offset + + (glamor_priv->has_source_coords ? 4 : 2) * + sizeof(float))); + glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); +#endif } } @@ -888,6 +926,8 @@ glamor_composite_with_shader(CARD8 op, } glUseProgram(shader->prog); + + if (key.source == SHADER_SOURCE_SOLID) { glamor_set_composite_solid(source_solid_color, shader->source_uniform_location); } else { @@ -1014,12 +1054,17 @@ glamor_composite_with_shader(CARD8 op, glamor_flush_composite_rects(screen); glBindBuffer(GL_ARRAY_BUFFER, 0); +#if 0 glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE1); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); - +#else + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); +#endif REGION_UNINIT(dst->pDrawable->pScreen, ®ion); glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE0); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 436e769f8..cdb0611c6 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -41,16 +41,35 @@ glamor_init_tile_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); const char *tile_vs = +#if 0 +#else + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord0;\n" + "varying vec2 tile_texture;\n" +#endif "void main()\n" "{\n" +#if 0 " gl_Position = gl_Vertex;\n" " gl_TexCoord[0] = gl_MultiTexCoord0;\n" +#else + " gl_Position = v_position;\n" + " tile_texture = v_texcoord0.xy;\n" +#endif "}\n"; const char *tile_fs = +#if 0 +#else + "varying vec2 tile_texture;\n" +#endif "uniform sampler2D sampler;\n" "void main()\n" "{\n" +#if 0 " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" +#else + " gl_FragColor = texture2D(sampler, tile_texture);\n" +#endif "}\n"; GLint fs_prog, vs_prog; GLint sampler_uniform_location; @@ -63,6 +82,9 @@ glamor_init_tile_shader(ScreenPtr screen) fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs); glAttachShader(glamor_priv->tile_prog, vs_prog); glAttachShader(glamor_priv->tile_prog, fs_prog); + + glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position"); + glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glamor_link_glsl_prog(glamor_priv->tile_prog); sampler_uniform_location = @@ -144,9 +166,16 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords); +#if 0 glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#else + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + source_texcoords); + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#endif } else { GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); @@ -157,18 +186,31 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_priv->yInverted, vertices); +#if 0 glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); glEnableClientState(GL_VERTEX_ARRAY); - +#else + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + vertices); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +#if 0 if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } glDisableClientState(GL_VERTEX_ARRAY); - +#else + if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { + glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glDisable(GL_TEXTURE_2D); + } + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); +#endif glUseProgram(0); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); From 29e358f6b3838a56b53ec809665f2e7be1731722 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 9 Aug 2011 09:59:08 -0400 Subject: [PATCH 172/225] glamor: Fix one typo error in README. Signed-off-by: Zhigang Gong --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 05effbeba..fd31d9936 100644 --- a/README +++ b/README @@ -14,7 +14,7 @@ diff -ur ../Downloads/glew-1.5.8/Makefile glew-1.5.8/Makefile endif -INCLUDE = -Iinclude + -+NCLUDE = -Iinclude ++INCLUDE = -Iinclude CFLAGS = $(OPT) $(WARN) $(INCLUDE) $(CFLAGS.EXTRA) +ifeq ($(NO_GLX), 1) +CFLAGS += -D_NO_GLX_ From 36a93f62c7830af088a54514eab6bf4d92423df6 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 9 Aug 2011 09:59:56 -0400 Subject: [PATCH 173/225] glamor_gles2: Use gl_flavor to determine which version of GL. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 6 ++++++ glamor/glamor_pixmap.c | 48 +++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 7acfc9853..eeb85f23a 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -379,6 +379,12 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_glyphs_init(screen); glamor_pixmap_init(screen); +#ifdef GLAMOR_GLES2 + glamor_priv->gl_flavor = GLAMOR_GL_ES2; +#else + glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP; +#endif + return TRUE; fail: diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index ce4ca0097..5dd59756d 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -213,6 +213,7 @@ static void __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); unsigned int stride, row_length; void *texels; GLenum iformat; @@ -229,15 +230,24 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, break; } + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { + iformat = format; + type = GL_UNSIGNED_BYTE; + } stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; glBindTexture(GL_TEXTURE_2D, tex); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); -#ifndef GLAMOR_GLES2 - glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); -#endif + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); + } + else { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + } + if (pixmap_priv->pbo && pixmap_priv->pbo_valid) { texels = NULL; glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo); @@ -524,15 +534,26 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) ErrorF("Glamor: Invalid access code. %d\n", access); assert(0); } - + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) + data = malloc(stride * pixmap->drawable.height); row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ROW_LENGTH, row_length); + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ROW_LENGTH, row_length); + } + else { + glPixelStorei(GL_PACK_ALIGNMENT, 4); + // glPixelStorei(GL_PACK_ROW_LENGTH, 0); + } if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { - if (!glamor_priv->yInverted) + if (!glamor_priv->yInverted) { + assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); glPixelStorei(GL_PACK_INVERT_MESA, 1); + } + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (pixmap_priv->pbo == 0) glGenBuffers (1, &pixmap_priv->pbo); glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); @@ -545,9 +566,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) data = glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access); pixmap_priv->pbo_valid = TRUE; - if (!glamor_priv->yInverted) + if (!glamor_priv->yInverted) { + assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); glPixelStorei(GL_PACK_INVERT_MESA, 0); + } glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); + } else { + glReadPixels (0, 0, + row_length, pixmap->drawable.height, + format, type, data); + } } else { data = malloc(stride * pixmap->drawable.height); assert(data); @@ -588,7 +616,7 @@ _glamor_destroy_upload_pixmap(PixmapPtr pixmap) assert(pixmap_priv->gl_fbo == 0); if (pixmap_priv->fb) - glDeleteFramebuffersEXT(1, &pixmap_priv->fb); + glDeleteFramebuffers(1, &pixmap_priv->fb); if (pixmap_priv->tex) glDeleteTextures(1, &pixmap_priv->tex); if (pixmap_priv->pbo) From 7aecfa245facf754ff8e09d6ef1ad0ab802156fc Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 9 Aug 2011 10:01:39 -0400 Subject: [PATCH 174/225] glamor-es2: Add --enable-glamor-gles2 to build system. Now, to build a gles2 version of glamor server, we could use ./autogen.sh --enable-glamor-ddx --enable-glamor-gles2 Signed-off-by: Zhigang Gong --- configure.ac | 2 ++ glamor/Makefile.am | 6 +++++- glamor/glamor_core.c | 17 +++++++++++------ glamor/glamor_priv.h | 6 ++++++ glamor/glamor_putimage.c | 33 ++++++++++++++++++++++----------- glamor/glamor_render.c | 2 +- glamor/glamor_setspans.c | 2 ++ hw/xfree86/common/Makefile.am | 8 +++++++- hw/xfree86/common/xf86pciBus.c | 2 +- hw/xfree86/glamor/Makefile.am | 9 ++++++++- hw/xfree86/glamor/glamor.c | 13 ++++++++++++- hw/xfree86/glamor/glamor_crtc.c | 3 ++- 12 files changed, 79 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index 73c1bea0e..a94cd009a 100644 --- a/configure.ac +++ b/configure.ac @@ -1772,6 +1772,8 @@ AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) dnl glamor AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes]) +AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes]) +AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes]) GLAMOR=yes diff --git a/glamor/Makefile.am b/glamor/Makefile.am index e2678f060..97b677a8a 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -10,10 +10,14 @@ if XORG sdk_HEADERS = glamor.h endif +if GLAMOR_GLES2 +GLAMOR_GLES2_CFLAGS = -DGLAMOR_GLES2 +endif + INCLUDES = \ $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) +AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index f585d6a2e..096e40b20 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -141,6 +141,7 @@ void glamor_init_finish_access_shaders(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); +#ifndef GLAMOR_GLES2 const char *vs_source = "void main()\n" "{\n" @@ -154,7 +155,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) "{\n" " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" "}\n"; - + const char *aswizzle_source = "varying vec2 texcoords;\n" "uniform sampler2D sampler;\n" @@ -162,6 +163,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) "{\n" " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n" "}\n"; +#endif const char *es_vs_source = "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" @@ -200,6 +202,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glamor_priv->finish_access_prog[3] = glCreateProgram(); if (GLEW_ARB_fragment_shader) { +#ifndef GLAMOR_GLES2 vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); @@ -209,7 +212,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source); glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog); - +#endif es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source); glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog); @@ -221,16 +224,18 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog); } else { +#ifndef GLAMOR_GLES2 vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); ErrorF("Lack of framgment shader support.\n"); +#endif } - +#ifndef GLAMOR_GLES2 glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]); glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); - +#endif glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glamor_link_glsl_prog(glamor_priv->finish_access_prog[2]); @@ -241,7 +246,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) if (GLEW_ARB_fragment_shader) { GLint sampler_uniform_location; - +#ifndef GLAMOR_GLES2 sampler_uniform_location = glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); glUseProgram(glamor_priv->finish_access_prog[0]); @@ -253,7 +258,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glUseProgram(glamor_priv->finish_access_prog[1]); glUniform1i(sampler_uniform_location, 0); glUseProgram(0); - +#endif sampler_uniform_location = glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler"); glUseProgram(glamor_priv->finish_access_prog[2]); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 217600844..c04e118ed 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -60,10 +60,16 @@ #define GL_STREAM_DRAW 0x88E0 #define GL_STREAM_READ 0x88E1 #define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 #define GLEW_MESA_pack_invert 0 #define GL_PACK_INVERT_MESA 0x8758 +#define glMapBuffer(x, y) NULL +#define glUnmapBuffer(x) +#define glRasterPos2i(x,y) +#define glDrawPixels(x,y,z,a,b) + #endif #ifdef GLAMOR_GLES2 diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 4b2215a9f..a6aadce11 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -36,6 +36,7 @@ void glamor_init_putimage_shaders(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); +#if 0 const char *xybitmap_vs = "uniform float x_bias;\n" "uniform float x_scale;\n" @@ -85,6 +86,7 @@ glamor_init_putimage_shaders(ScreenPtr screen) &glamor_priv->put_image_xybitmap_transform); glamor_priv->put_image_xybitmap_prog = prog; glUseProgram(0); +#endif } @@ -254,7 +256,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glamor_get_screen_private(drawable->pScreen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - GLenum type, format; + GLenum type, format, iformat; RegionPtr clip; BoxPtr pbox; int nbox; @@ -317,17 +319,27 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); #endif - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); -#ifndef GLAMOR_GLES2 - glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / - pixmap->drawable.bitsPerPixel); -#endif - + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / + pixmap->drawable.bitsPerPixel); + } + else { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); +// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + } glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { + type = GL_UNSIGNED_BYTE; + iformat = format; + } + else { + iformat = GL_RGBA; + } + glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -396,9 +408,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); #endif glDeleteTextures(1, &tex); -#ifndef GLAMOR_GLES2 - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); -#endif + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); return; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6b8c7601b..0567f6717 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -377,7 +377,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, switch (picture->repeatType) { case RepeatNone: #ifdef GLAMOR_GLES2 - assert(0); + assert(1); #endif glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 14a24378f..af2664301 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -43,6 +43,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, BoxRec *pbox; int x_off, y_off; + goto fail; + if (glamor_get_tex_format_type_from_pixmap(dest_pixmap, &format, &type, diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index c031d4be3..173d76570 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -89,4 +89,10 @@ if LNXACPI XORG_CFLAGS += -DHAVE_ACPI endif -AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) +if GLAMOR_DDX +GLAMOR_DDX_CFLAGS = -DGLAMOR_DDX +endif + +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_DDX_CFLAGS) + + diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 663e70ad9..7ab3f2875 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -1118,7 +1118,7 @@ videoPtrToDriverList(struct pci_device *dev, } else if (dev->device_id == 0x8108) { break; /* "hooray" for poulsbo */ } else { -#if GLAMOR_DDX +#ifdef GLAMOR_DDX driverList[0] = "glamor"; #else driverList[0] = "intel"; diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index d9dc8a90a..71d491441 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -12,10 +12,17 @@ glamor_la_CFLAGS = \ -I$(top_srcdir)/glamor \ -I/usr/include/drm +if GLAMOR_GLES2 +glamor_la_CFLAGS+=-DGLAMOR_GLES2 +GLAMOR_GL_LIB = -lGLESv2 +else +GLAMOR_GL_LIB = -L$(libdir)/../lib64 -lGLEW +endif + glamor_la_LDFLAGS = \ -module -avoid-version -L$(libdir) -lEGL \ $(top_builddir)/glamor/libglamor.la \ - -L$(libdir)/../lib64 -lGLEW + -L$(libdir)/../lib64 $(GLAMOR_GL_LIB) glamor_ladir = $(moduledir)/drivers glamor_la_SOURCES = \ diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index a1128da43..82ebeeb52 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -306,6 +306,13 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); const char *version; VisualPtr visual; + EGLint config_attribs[] = { +#ifdef GLAMOR_GLES2 + EGL_CONTEXT_CLIENT_VERSION, 2, +#endif + EGL_NONE + }; + /* If serverGeneration != 1 then fd was closed during the last time closing screen, actually in eglTerminate(). */ @@ -327,7 +334,11 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) glamor->display = eglGetDRMDisplayMESA(glamor->fd); +#ifndef GLAMOR_GLES2 eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n"); @@ -338,7 +349,7 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) xf86Msg(X_INFO, "%s: EGL version %s:", glamor_name, version); glamor->context = eglCreateContext(glamor->display, - NULL, EGL_NO_CONTEXT, NULL); + NULL, EGL_NO_CONTEXT, config_attribs); if (glamor->context == EGL_NO_CONTEXT) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n"); diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index d2f98fb5f..5c2b5c124 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -493,7 +493,8 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor); } glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); -#if GLAMOR_GLES2 +#ifdef GLAMOR_GLES2 + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, 64, 64, 0, GL_BGRA, GL_UNSIGNED_BYTE, image); #else From 41b13fbd264594f88905b1cf8dcb2f14e7ee5b69 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 10 Aug 2011 01:42:26 -0700 Subject: [PATCH 175/225] glamor: Use function pointer to get extenstion calls This is the formal usage for extension functions. --- hw/xfree86/glamor/glamor.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 82ebeeb52..e7ee95631 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -45,6 +45,7 @@ #include #endif +#define MESA_EGL_NO_X11_HEADERS #include #include @@ -79,6 +80,10 @@ struct glamor_screen_private { CloseScreenProcPtr CloseScreen; int fd; int cpp; + + PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; + PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; + }; static inline struct glamor_screen_private * @@ -109,7 +114,7 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) attribs[1] = width; attribs[3] = height; - image = eglCreateDRMImageMESA(glamor->display, attribs); + image = (glamor->egl_create_drm_image_mesa)(glamor->display, attribs); if (image == EGL_NO_IMAGE_KHR) return FALSE; @@ -131,7 +136,7 @@ glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) { struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); EGLint name; - eglExportDRMImageMESA (glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch); + (glamor->egl_export_drm_image_mesa)(glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch); } EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) @@ -148,7 +153,7 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) attribs[1] = width; attribs[3] = height; - return eglCreateDRMImageMESA(glamor->display, attribs); + return (glamor->egl_create_drm_image_mesa)(glamor->display, attribs); } void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor) @@ -162,7 +167,7 @@ glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uin { struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); EGLint name; - eglExportDRMImageMESA (glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch); + (glamor->egl_export_drm_image_mesa)(glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch); ErrorF("cursor stride: %d\n", *pitch); } @@ -346,7 +351,16 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) } version = eglQueryString(glamor->display, EGL_VERSION); - xf86Msg(X_INFO, "%s: EGL version %s:", glamor_name, version); + xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); + + glamor->egl_create_drm_image_mesa = eglGetProcAddress("eglCreateDRMImageMESA"); + glamor->egl_export_drm_image_mesa = eglGetProcAddress("eglExportDRMImageMESA"); + + if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "eglGetProcAddress() failed\n"); + return FALSE; + } glamor->context = eglCreateContext(glamor->display, NULL, EGL_NO_CONTEXT, config_attribs); From b2bff334ce4f36352497f1c1d4e9f0e5b3336136 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 9 Aug 2011 19:37:17 -0700 Subject: [PATCH 176/225] glamor: Require libdrm CFLAGS for building Need to depend on libdrm CFLAGS for glamor building. --- glamor/Makefile.am | 2 +- hw/xfree86/glamor/Makefile.am | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 97b677a8a..2df76bd53 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -17,7 +17,7 @@ endif INCLUDES = \ $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS) +AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS) $(LIBDRM_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index 71d491441..a00f08ac5 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -1,7 +1,7 @@ glamor_la_LTLIBRARIES = glamor.la glamor_la_CFLAGS = \ -DHAVE_XORG_CONFIG_H \ - @DIX_CFLAGS@ @XORG_CFLAGS@ \ + @DIX_CFLAGS@ @XORG_CFLAGS@ @LIBDRM_CFLAGS@ \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/os-support/bus \ -I$(top_srcdir)/hw/xfree86/parser \ @@ -9,8 +9,7 @@ glamor_la_CFLAGS = \ -I$(top_srcdir)/hw/xfree86/ddc \ -I$(top_srcdir)/hw/xfree86/ramdac \ -I$(top_srcdir)/hw/xfree86/i2c \ - -I$(top_srcdir)/glamor \ - -I/usr/include/drm + -I$(top_srcdir)/glamor if GLAMOR_GLES2 glamor_la_CFLAGS+=-DGLAMOR_GLES2 From d66bd9714e1e1af4267fb4eb208143a070e65ee3 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 11 Aug 2011 09:54:28 -0400 Subject: [PATCH 177/225] glamor: Concentrate FBO's creation to one function. And add status checking for it. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 9 +-------- glamor/glamor_pixmap.c | 43 +++++++++++++++++++++++++++++++++--------- glamor/glamor_priv.h | 14 ++++++++++++++ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index eeb85f23a..dd0d69db7 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -74,14 +74,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) */ pixmap_priv->gl_fbo = 1; pixmap_priv->gl_tex = 1; - glGenFramebuffers(1, &pixmap_priv->fb); - glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); - glFramebufferTexture2D(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - pixmap_priv->tex, - 0); - + glamor_pixmap_ensure_fb(pixmap); screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3, diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 5dd59756d..d747ade43 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -359,6 +359,39 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i glBindFramebuffer(GL_FRAMEBUFFER, 0); } +void +glamor_pixmap_ensure_fb(PixmapPtr pixmap) +{ + int status; + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + if (pixmap_priv->fb == 0) + glGenFramebuffers(1, &pixmap_priv->fb); + assert(pixmap_priv->tex != 0); + glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + pixmap_priv->tex, + 0); + status = glCheckFramebufferStatus (GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + const char *str; + switch (status) { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: str= "incomplete attachment"; break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: str= "incomplete/missing attachment"; break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: str= "incomplete draw buffer"; break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: str= "incomplete read buffer"; break; + case GL_FRAMEBUFFER_UNSUPPORTED: str= "unsupported"; break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: str= "incomplete multiple"; break; + default: str = "unknown error"; break; + } + + LogMessageVerb(X_INFO, 0, + "destination is framebuffer incomplete: %s [%#x]\n", + str, status); + assert(0); + } +} /* * Prepare to upload a pixmap to texture memory. @@ -393,21 +426,13 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax) glGenTextures(1, &pixmap_priv->tex); if (need_fbo) { - if (pixmap_priv->fb == 0) - glGenFramebuffers(1, &pixmap_priv->fb); glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, pixmap->drawable.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); - glFramebufferTexture2D(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - pixmap_priv->tex, - 0); + glamor_pixmap_ensure_fb(pixmap); } return 0; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index c04e118ed..bf032b1cb 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -62,6 +62,10 @@ #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 GLEW_MESA_pack_invert 0 #define GL_PACK_INVERT_MESA 0x8758 @@ -802,6 +806,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access); **/ void glamor_restore_pixmap_to_texture(PixmapPtr pixmap); +/** + * Ensure to have a fbo attached to the pixmap. + * If the pixmap already has one fbo then do nothing. + * Otherwise, it will generate a new fbo, and bind + * the pixmap's texture to the fbo. + * The pixmap must has a valid texture before call this + * API, othersie, it will trigger a assert. + */ +void +glamor_pixmap_ensure_fb(PixmapPtr pixmap); /** * Upload a pixmap to gl texture. Used by dynamic pixmap From 2146a25bac4392c47ef06ecddbf12db184926b7e Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 11 Aug 2011 15:03:48 -0400 Subject: [PATCH 178/225] glamor-ddx: Silence one warning. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index e7ee95631..317342b13 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -353,8 +353,8 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) version = eglQueryString(glamor->display, EGL_VERSION); xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); - glamor->egl_create_drm_image_mesa = eglGetProcAddress("eglCreateDRMImageMESA"); - glamor->egl_export_drm_image_mesa = eglGetProcAddress("eglExportDRMImageMESA"); + glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA"); + glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA"); if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, From 172e8cfcd411b1abeaf8ede2e3882d6198cee5b8 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 11 Aug 2011 15:05:02 -0400 Subject: [PATCH 179/225] glamor: Remove GLEW dependency. Glamor doesn't need to use GLEW. We can parse the extension by ourself. This patch also fix the fbo size checking from a hard coded style to a dynamic checking style. Signed-off-by: Zhigang Gong --- README | 42 ----------- configure.ac | 9 --- glamor/glamor.c | 43 +++++------ glamor/glamor_copyarea.c | 6 +- glamor/glamor_core.c | 131 ++++++++++++++++++++++------------ glamor/glamor_fill.c | 13 ++-- glamor/glamor_pixmap.c | 4 +- glamor/glamor_priv.h | 35 ++++----- glamor/glamor_render.c | 5 +- glamor/glamor_tile.c | 3 - hw/kdrive/ephyr/Makefile.am | 9 ++- hw/xfree86/glamor/Makefile.am | 2 +- 12 files changed, 141 insertions(+), 161 deletions(-) diff --git a/README b/README index fd31d9936..c240ac775 100644 --- a/README +++ b/README @@ -2,48 +2,6 @@ 1. Prerequirement. Please install makedepend and libudev-devel firstly. -Glamor need patch glew-1.5.8, here is the patch: - - -diff -ur ../Downloads/glew-1.5.8/Makefile glew-1.5.8/Makefile ---- ../Downloads/glew-1.5.8/Makefile 2011-01-31 22:17:27.000000000 +0800 -+++ glew-1.5.8/Makefile 2011-06-28 10:13:54.147700479 +0800 -@@ -63,8 +63,12 @@ - else - OPT = $(POPT) - endif --INCLUDE = -Iinclude -+ -+INCLUDE = -Iinclude - CFLAGS = $(OPT) $(WARN) $(INCLUDE) $(CFLAGS.EXTRA) -+ifeq ($(NO_GLX), 1) -+CFLAGS += -D_NO_GLX_ -+endif - - LIB.SRCS = src/glew.c - LIB.OBJS = $(LIB.SRCS:.c=.o) -diff -ur ../Downloads/glew-1.5.8/src/glew.c glew-1.5.8/src/glew.c ---- ../Downloads/glew-1.5.8/src/glew.c 2011-01-31 22:17:27.000000000 +0800 -+++ glew-1.5.8/src/glew.c 2011-06-28 10:06:45.952700777 +0800 -@@ -11379,6 +11379,10 @@ - { - GLenum r; - if ( (r = glewContextInit()) ) return r; -+#if defined(_NO_GLX_) -+ return r; -+#endif -+ - #if defined(_WIN32) - return wglewContextInit(); - #elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ - - -As xserver's glx extension code has conflicts with glew's glx related -initialization, we have to disable it in glew currently. Please apply the -above patch to glew and then build the glew as follow which will -workaround the problem. - -glew-1.5.8# NO_GLX=1 make 2. Build xserver-glamor. diff --git a/configure.ac b/configure.ac index a94cd009a..737aa8487 100644 --- a/configure.ac +++ b/configure.ac @@ -2036,15 +2036,6 @@ if test "$KDRIVE" = yes; then AC_MSG_ERROR([Xephyr dependencies missing]) fi - AC_CHECK_LIB(GLEW, glewInit, [ - AC_CHECK_HEADER(GL/glew.h, [], [ - AC_MSG_ERROR([requires glew http://glew.sourceforge.net/]) - ]) - ], [ - AC_MSG_ERROR([requires glew http://glew.sourceforge.net/]) - ]) - XEPHYR_LIBS="$XEPHYR_LIBS -lGLEW" - # Xephyr needs nanosleep() which is in librt on Solaris AC_CHECK_FUNC([nanosleep], [], AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt")) diff --git a/glamor/glamor.c b/glamor/glamor.c index dd0d69db7..06103ace1 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -110,10 +110,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, GLuint tex; int type = GLAMOR_PIXMAP_TEXTURE; glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); if (w > 32767 || h > 32767) return NullPixmap; - if (!glamor_check_fbo_width_height(w,h) + if (!glamor_check_fbo_size(glamor_priv, w,h) || !glamor_check_fbo_depth(depth) || usage == GLAMOR_CREATE_PIXMAP_CPU) { /* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo. @@ -249,6 +250,7 @@ Bool glamor_init(ScreenPtr screen, unsigned int flags) { glamor_screen_private *glamor_priv; + int gl_version; #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); @@ -271,7 +273,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) LogMessage(X_WARNING, "glamor%d: Failed to allocate screen private\n", screen->myNum); - return FALSE; + goto fail; } dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); @@ -281,36 +283,27 @@ glamor_init(ScreenPtr screen, unsigned int flags) LogMessage(X_WARNING, "glamor%d: Failed to allocate pixmap private\n", screen->myNum); - return FALSE; + goto fail;; + } + + gl_version = glamor_gl_get_version(); + + if (gl_version < GLAMOR_GL_VERSION_ENCODE(1,3)) { + ErrorF("Require Opengl 1.3 or latter.\n"); + goto fail; } -#ifndef GLAMOR_GLES2 - glewInit(); - if (!GLEW_EXT_framebuffer_object) { - ErrorF("GL_EXT_framebuffer_object required\n"); - goto fail; - } - if (!GLEW_ARB_shader_objects) { - ErrorF("GL_ARB_shader_objects required\n"); - goto fail; - } - if (!GLEW_ARB_vertex_shader) { - ErrorF("GL_ARB_vertex_shader required\n"); - goto fail; - } - - if (!GLEW_ARB_pixel_buffer_object) { - ErrorF("GL_ARB_pixel_buffer_object required\n"); - goto fail; - } - - if (!GLEW_EXT_bgra) { - ErrorF("GL_EXT_bgra required\n"); +#ifdef GLAMOR_GLES2 + if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) { + ErrorF("GL_EXT_texture_format_BGRA8888 required\n"); goto fail; } #endif + glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert"); + glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit"); + glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 7a84adbf2..dca7160f9 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -48,7 +48,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int dst_x_off, dst_y_off, src_x_off, src_y_off, i; - if (!GLEW_EXT_framebuffer_blit) { + if (!glamor_priv->has_fbo_blit) { glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n"); return FALSE; } @@ -85,7 +85,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, for (i = 0; i < nbox; i++) { if(glamor_priv->yInverted) { - glBlitFramebufferEXT((box[i].x1 + dx + src_x_off), + glBlitFramebuffer((box[i].x1 + dx + src_x_off), (box[i].y1 + src_y_off), (box[i].x2 + dx + src_x_off), (box[i].y2 + src_y_off), @@ -101,7 +101,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off); int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off); - glBlitFramebufferEXT(box[i].x1 + dx + src_x_off, + glBlitFramebuffer(box[i].x1 + dx + src_x_off, flip_src_y1, box[i].x2 + dx + src_x_off, flip_src_y2, diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 096e40b20..09851a0dd 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -201,35 +201,27 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glamor_priv->finish_access_prog[2] = glCreateProgram(); glamor_priv->finish_access_prog[3] = glCreateProgram(); - if (GLEW_ARB_fragment_shader) { #ifndef GLAMOR_GLES2 - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); - glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); - glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); + glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); + glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); - avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); - aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source); - glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); - glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog); + avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); + aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source); + glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); + glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog); #endif - es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); - es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source); - glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog); - glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog); + es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); + es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source); + glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog); + glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog); - es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); - es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source); - glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog); - glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog); + es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); + es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source); + glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog); + glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog); - } else { -#ifndef GLAMOR_GLES2 - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); - glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); - ErrorF("Lack of framgment shader support.\n"); -#endif - } #ifndef GLAMOR_GLES2 @@ -244,34 +236,32 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glamor_link_glsl_prog(glamor_priv->finish_access_prog[3]); - if (GLEW_ARB_fragment_shader) { - GLint sampler_uniform_location; + GLint sampler_uniform_location; #ifndef GLAMOR_GLES2 - sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[0]); - glUniform1i(sampler_uniform_location, 0); - glUseProgram(0); + sampler_uniform_location = + glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[0]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); - sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[1]); - glUniform1i(sampler_uniform_location, 0); - glUseProgram(0); + sampler_uniform_location = + glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[1]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); #endif - sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[2]); - glUniform1i(sampler_uniform_location, 0); - glUseProgram(0); + sampler_uniform_location = + glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[2]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); - sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[3]); - glUniform1i(sampler_uniform_location, 0); - glUseProgram(0); + sampler_uniform_location = + glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler"); + glUseProgram(glamor_priv->finish_access_prog[3]); + glUniform1i(sampler_uniform_location, 0); + glUseProgram(0); - } } void @@ -494,3 +484,50 @@ glamor_bitmap_to_region(PixmapPtr pixmap) glamor_finish_access(&pixmap->drawable); return ret; } + +/* Borrow from cairo. */ +Bool +glamor_gl_has_extension(char *extension) +{ + const char *gl_extensions; + char *pext; + int ext_len; + ext_len = strlen(extension); + + gl_extensions = (const char*)glGetString(GL_EXTENSIONS); + pext = (char*)gl_extensions; + + if (pext == NULL || extension == NULL) + return FALSE; + + while((pext = strstr(pext, extension)) != NULL) { + if (pext[ext_len] == ' ' || pext[ext_len] == '\0') + return TRUE; + pext += ext_len; + } + return FALSE; +} + +int +glamor_gl_get_version (void) +{ + int major, minor; + const char *version = (const char *) glGetString (GL_VERSION); + const char *dot = version == NULL ? NULL : strchr (version, '.'); + const char *major_start = dot; + + /* Sanity check */ + if (dot == NULL || dot == version || *(dot + 1) == '\0') { + major = 0; + minor = 0; + } else { + /* Find the start of the major version in the string */ + while (major_start > version && *major_start != ' ') + --major_start; + major = strtol (major_start, NULL, 10); + minor = strtol (dot + 1, NULL, 10); + } + + return GLAMOR_GL_VERSION_ENCODE (major, minor); +} + diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index bfa30b2e3..556ff342c 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -139,15 +139,10 @@ glamor_init_solid_shader(ScreenPtr screen) GLint fs_prog, vs_prog; glamor_priv->solid_prog = glCreateProgram(); - if (GLEW_ARB_fragment_shader) { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs); - glAttachShader(glamor_priv->solid_prog, vs_prog); - glAttachShader(glamor_priv->solid_prog, fs_prog); - } else { - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs_only); - glAttachShader(glamor_priv->solid_prog, vs_prog); - } + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs); + glAttachShader(glamor_priv->solid_prog, vs_prog); + glAttachShader(glamor_priv->solid_prog, fs_prog); glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position"); glamor_link_glsl_prog(glamor_priv->solid_prog); diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index d747ade43..b105916d6 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -407,7 +407,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax) glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - if (!glamor_check_fbo_width_height(pixmap->drawable.width , pixmap->drawable.height) + if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width , pixmap->drawable.height) || !glamor_check_fbo_depth(pixmap->drawable.depth)) { glamor_fallback("upload failed reason: bad size or depth %d x %d @depth %d \n", pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth); @@ -571,7 +571,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) // glPixelStorei(GL_PACK_ROW_LENGTH, 0); } - if (GLEW_MESA_pack_invert || glamor_priv->yInverted) { + if (glamor_priv->has_pack_invert || glamor_priv->yInverted) { if (!glamor_priv->yInverted) { assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index bf032b1cb..69590a5c5 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -37,8 +37,6 @@ #ifdef GLAMOR_GLES2 -#define GLEW_ES_ONLY 1 - #define GL_BGRA GL_BGRA_EXT #define GL_COLOR_INDEX 0x1900 #define GL_BITMAP 0x1A00 @@ -49,7 +47,6 @@ #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GLEW_ARB_fragment_shader 1 #define GL_PIXEL_PACK_BUFFER 0x88EB #define GL_PIXEL_UNPACK_BUFFER 0x88EC #define GL_CLAMP_TO_BORDER 0x812D @@ -66,7 +63,6 @@ #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GLEW_MESA_pack_invert 0 #define GL_PACK_INVERT_MESA 0x8758 #define glMapBuffer(x, y) NULL @@ -76,12 +72,13 @@ #endif -#ifdef GLAMOR_GLES2 #define GL_GLEXT_PROTOTYPES +#ifdef GLAMOR_GLES2 #include #include #else -#include +#include +#include #endif @@ -90,19 +87,11 @@ #endif -#ifndef MAX_WIDTH -#define MAX_WIDTH 4096 -#endif - -#ifndef MAX_HEIGHT -#define MAX_HEIGHT 4096 -#endif - #include "glamor_debug.h" -#define glamor_check_fbo_width_height(_w_, _h_) ((_w_) > 0 && (_h_) > 0 \ - && (_w_) < MAX_WIDTH \ - && (_h_) < MAX_HEIGHT) +#define glamor_check_fbo_size(_glamor_,_w_, _h_) ((_w_) > 0 && (_h_) > 0 \ + && (_w_) < _glamor_->max_fbo_size \ + && (_h_) < _glamor_->max_fbo_size) #define glamor_check_fbo_depth(_depth_) ( \ _depth_ == 8 \ @@ -241,6 +230,9 @@ typedef struct glamor_screen_private { char *vb; int vb_stride; enum glamor_gl_flavor gl_flavor; + int has_pack_invert; + int has_fbo_blit; + int max_fbo_size; /* glamor_finishaccess */ GLint finish_access_prog[4]; @@ -674,6 +666,15 @@ void glamor_set_transform_for_pixmap(PixmapPtr pixmap, glamor_transform_uniforms *uniform_locations); Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); +Bool glamor_gl_has_extension(char *extension); +int glamor_gl_get_version(void); + +#define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \ + ((major) * 256) \ + + ((minor) * 1)) + + + /* glamor_fill.c */ void glamor_fill(DrawablePtr drawable, diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 0567f6717..12b09243d 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1154,6 +1154,7 @@ glamor_composite(CARD8 op, PicturePtr temp_src = source, temp_mask = mask; int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; glamor_composite_rect_t rect; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); x_temp_src = x_source; y_temp_src = y_source; @@ -1181,7 +1182,7 @@ glamor_composite(CARD8 op, && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) && ((width * height * 4 < (source_pixmap->drawable.width * source_pixmap->drawable.height)) - || !(glamor_check_fbo_width_height(source_pixmap->drawable.width, + || !(glamor_check_fbo_size(glamor_priv, source_pixmap->drawable.width, source_pixmap->drawable.height))))) { temp_src = glamor_convert_gradient_picture(screen, source, x_source, y_source, width, height); if (!temp_src) { @@ -1197,7 +1198,7 @@ glamor_composite(CARD8 op, && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)) && ((width * height * 4 < (mask_pixmap->drawable.width * mask_pixmap->drawable.height)) - || !(glamor_check_fbo_width_height(mask_pixmap->drawable.width, + || !(glamor_check_fbo_size(glamor_priv, mask_pixmap->drawable.width, mask_pixmap->drawable.height)))))) { /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity * to do reduce one convertion. */ diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index cdb0611c6..cb235527d 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -74,9 +74,6 @@ glamor_init_tile_shader(ScreenPtr screen) GLint fs_prog, vs_prog; GLint sampler_uniform_location; - if (!GLEW_ARB_fragment_shader) - return; - glamor_priv->tile_prog = glCreateProgram(); vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs); diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 7e10d6b79..744604eea 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -66,6 +66,12 @@ libxephyr_la_SOURCES = $(XEPHYR_SRCS) Xephyr_SOURCES = \ ephyrinit.c +if GLAMOR_GLES2 +GLAMOR_GL_LIB = -lGLESv2 +else +GLAMOR_GL_LIB = -lGL +endif + Xephyr_LDADD = \ libxephyr.la \ libxephyr-hostx.la \ @@ -74,7 +80,8 @@ Xephyr_LDADD = \ $(top_builddir)/exa/libexa.la \ $(top_builddir)/glamor/libglamor.la \ @KDRIVE_LIBS@ \ - @XEPHYR_LIBS@ + @XEPHYR_LIBS@ \ + $(GLAMOR_GL_LIB) Xephyr_DEPENDENCIES = \ libxephyr.la \ diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index a00f08ac5..dcd44b2d8 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -15,7 +15,7 @@ if GLAMOR_GLES2 glamor_la_CFLAGS+=-DGLAMOR_GLES2 GLAMOR_GL_LIB = -lGLESv2 else -GLAMOR_GL_LIB = -L$(libdir)/../lib64 -lGLEW +GLAMOR_GL_LIB = -lGL endif glamor_la_LDFLAGS = \ From 5e7fdbb498c47b6e89280b8354f0ebaaf61d0646 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 11 Aug 2011 15:08:12 -0400 Subject: [PATCH 180/225] glamor: Disable ALPHA8 fbo. As some platform doesn't support to use ALPHA8 texture as draw target, we have to disable it. It seems there is no easy way to check that. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 2 ++ glamor/glamor_pixmap.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index 06103ace1..cd261ac8b 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -146,9 +146,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, return pixmap; switch (depth) { +#if 0 case 8: format = GL_ALPHA; break; +#endif case 24: format = GL_RGB; break; diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index b105916d6..5ac62f4e7 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -219,9 +219,11 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLenum iformat; switch (pixmap->drawable.depth) { +#if 0 case 8: iformat = GL_ALPHA; break; +#endif case 24: iformat = GL_RGB; break; From 667d65534d64df30146cfa0d32522bced51e0697 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 11 Aug 2011 15:27:12 -0400 Subject: [PATCH 181/225] glamor: Unify the variable name which used to indicate no alpha. The original code use different name and the name is vague. Now change it to no_alpha. Signed-off-by: Zhigang Gong --- glamor/glamor_getspans.c | 4 ++-- glamor/glamor_pixmap.c | 39 ++++++++++++++++++++------------------- glamor/glamor_priv.h | 24 ++++++++++++------------ glamor/glamor_putimage.c | 8 ++++---- glamor/glamor_setspans.c | 5 +++-- 5 files changed, 41 insertions(+), 39 deletions(-) diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 237c1e789..e1a20baef 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -41,7 +41,7 @@ glamor_get_spans(DrawablePtr drawable, { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; - int ax; + int no_alpha; glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int i; @@ -56,7 +56,7 @@ glamor_get_spans(DrawablePtr drawable, if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &ax + &no_alpha )) { glamor_fallback("unknown depth. %d \n", drawable->depth); diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 5ac62f4e7..8ca1318ab 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -272,7 +272,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, * */ static void -_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, int ax, int flip) +_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, + GLenum type, int no_alpha, int flip) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -299,7 +300,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i /* Try fast path firstly, upload the pixmap to the texture attached * to the fbo directly. */ - if (ax == 0 && !need_flip) { + if (no_alpha == 0 && !need_flip) { __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex); return; } @@ -341,9 +342,9 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); #if 0 - glUseProgram(glamor_priv->finish_access_prog[ax]); + glUseProgram(glamor_priv->finish_access_prog[no_alpha]); #else - glUseProgram(glamor_priv->finish_access_prog[ax + 2]); + glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]); #endif glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -397,13 +398,13 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap) /* * Prepare to upload a pixmap to texture memory. - * ax 1 means the format needs to wire alpha to 1. + * no_alpha equals 1 means the format needs to wire alpha to 1. * Two condtion need to setup a fbo for a pixmap * 1. !yInverted, we need to do flip if we are not yInverted. - * 2. ax != 0, we need to wire the alpha. + * 2. no_alpha != 0, we need to wire the alpha. * */ static int -glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax) +glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha) { int need_fbo; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -419,7 +420,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax) if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return 0; - if (ax != 0 || !glamor_priv->yInverted) + if (no_alpha != 0 || !glamor_priv->yInverted) need_fbo = 1; else need_fbo = 0; @@ -444,16 +445,16 @@ enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr pixmap) { GLenum format, type; - int ax; + int no_alpha; if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &ax)) { + &no_alpha)) { glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); return GLAMOR_UPLOAD_FAILED; } - if (glamor_pixmap_upload_prepare(pixmap, ax)) + if (glamor_pixmap_upload_prepare(pixmap, no_alpha)) return GLAMOR_UPLOAD_FAILED; glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD, "Uploading pixmap %p %dx%d depth%d.\n", @@ -461,7 +462,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap) pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth); - _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1); + _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1); return GLAMOR_UPLOAD_DONE; } @@ -485,16 +486,16 @@ void glamor_restore_pixmap_to_texture(PixmapPtr pixmap) { GLenum format, type; - int ax; + int no_alpha; if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &ax)) { + &no_alpha)) { ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); assert(0); } - _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1); + _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1); } @@ -514,7 +515,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); unsigned int stride, row_length, y; GLenum format, type, gl_access, gl_usage; - int ax; + int no_alpha; uint8_t *data, *read; glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); @@ -522,12 +523,10 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return TRUE; - /* XXX we may don't need to validate it on GPU here, - * we can just validate it on CPU. */ if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &ax)) { + &no_alpha)) { ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); assert(0); // Should never happen. return FALSE; @@ -543,6 +542,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) stride = pixmap->devKind; glamor_set_destination_pixmap_priv_nc(pixmap_priv); + /* XXX we may don't need to validate it on GPU here, + * we can just validate it on CPU. */ glamor_validate_pixmap(pixmap); switch (access) { case GLAMOR_ACCESS_RO: diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 69590a5c5..2c2bf22d2 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -404,7 +404,7 @@ format_for_pixmap(PixmapPtr pixmap) /* * Map picture's format to the correct gl texture format and type. - * xa is used to indicate whehter we need to wire alpha to 1. + * no_alpha is used to indicate whehter we need to wire alpha to 1. * * Return 0 if find a matched texture type. Otherwise return -1. **/ @@ -412,41 +412,41 @@ static inline int glamor_get_tex_format_type_from_pictformat(PictFormatShort format, GLenum *tex_format, GLenum *tex_type, - int *xa) + int *no_alpha) { - *xa = 0; + *no_alpha = 0; switch (format) { case PICT_a1: *tex_format = GL_COLOR_INDEX; *tex_type = GL_BITMAP; break; case PICT_b8g8r8x8: - *xa = 1; + *no_alpha = 1; case PICT_b8g8r8a8: *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_INT_8_8_8_8; break; case PICT_x8r8g8b8: - *xa = 1; + *no_alpha = 1; case PICT_a8r8g8b8: *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; break; case PICT_x8b8g8r8: - *xa = 1; + *no_alpha = 1; case PICT_a8b8g8r8: *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; break; case PICT_x2r10g10b10: - *xa = 1; + *no_alpha = 1; case PICT_a2r10g10b10: *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; break; case PICT_x2b10g10r10: - *xa = 1; + *no_alpha = 1; case PICT_a2b10g10r10: *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; @@ -461,14 +461,14 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format, *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV; break; case PICT_x1b5g5r5: - *xa = 1; + *no_alpha = 1; case PICT_a1b5g5r5: *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case PICT_x1r5g5b5: - *xa = 1; + *no_alpha = 1; case PICT_a1r5g5b5: *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; @@ -478,14 +478,14 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format, *tex_type = GL_UNSIGNED_BYTE; break; case PICT_x4r4g4b4: - *xa = 1; + *no_alpha = 1; case PICT_a4r4g4b4: *tex_format = GL_BGRA; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; break; case PICT_x4b4g4r4: - *xa = 1; + *no_alpha = 1; case PICT_a4b4g4r4: *tex_format = GL_RGBA; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index a6aadce11..38da796af 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -265,7 +265,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, float vertices[8], texcoords[8]; GLfloat xscale, yscale, txscale, tyscale; GLuint tex; - int ax = 0; + int no_alpha; if (image_format == XYBitmap) { assert(depth == 1); goto fail; @@ -290,7 +290,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &ax + &no_alpha )) { glamor_fallback("unknown depth. %d \n", drawable->depth); @@ -347,9 +347,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glEnable(GL_TEXTURE_2D); #if 0 - glUseProgram(glamor_priv->finish_access_prog[ax]); + glUseProgram(glamor_priv->finish_access_prog[no_alpha]); #else - glUseProgram(glamor_priv->finish_access_prog[ax + 2]); + glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]); #endif x += drawable->x; diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index af2664301..d08be135f 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -37,18 +37,19 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, { PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; - int ax, i; + int no_alpha, i; uint8_t *drawpixels_src = (uint8_t *)src; RegionPtr clip = fbGetCompositeClip(gc); BoxRec *pbox; int x_off, y_off; + goto fail; if (glamor_get_tex_format_type_from_pixmap(dest_pixmap, &format, &type, - &ax + &no_alpha )) { glamor_fallback("unknown depth. %d \n", drawable->depth); From 5cbb2a4ca05f696d2af9a2e50bf106b6f2acd1c6 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 11 Aug 2011 15:35:26 -0400 Subject: [PATCH 182/225] glamor: Only fallbac glamor_setspan when we are using gles2. Signed-off-by: Zhigang Gong --- glamor/glamor_setspans.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index d08be135f..a1d5dc1a6 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -36,6 +36,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int n, int sorted) { PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + glamor_screen_private *glamor_priv; GLenum format, type; int no_alpha, i; uint8_t *drawpixels_src = (uint8_t *)src; @@ -43,8 +44,10 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, BoxRec *pbox; int x_off, y_off; + glamor_priv = glamor_get_screen_private(drawable->pScreen); - goto fail; + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) + goto fail; if (glamor_get_tex_format_type_from_pixmap(dest_pixmap, &format, From a228effbeb339ae6f0b73c633022b3ec9981148f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 11 Aug 2011 15:56:02 -0400 Subject: [PATCH 183/225] glamor: Remove useless glVertexPointer related code. As glVertexPointer is not supported by GLES2, I totally replaced it by VertexAttribArray. This commit remove those old code. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 22 +---------- glamor/glamor_core.c | 83 ++++++---------------------------------- glamor/glamor_fill.c | 31 --------------- glamor/glamor_pixmap.c | 20 +--------- glamor/glamor_priv.h | 2 +- glamor/glamor_putimage.c | 11 +----- glamor/glamor_render.c | 30 --------------- glamor/glamor_tile.c | 35 ----------------- 8 files changed, 15 insertions(+), 219 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index dca7160f9..1e160acb6 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -180,15 +180,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src, -#if 0 - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); @@ -201,19 +196,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -#if 0 - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glUseProgram(glamor_priv->finish_access_prog[0]); -#else glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(glamor_priv->finish_access_prog[2]); -#endif + glUseProgram(glamor_priv->finish_access_prog[0]); } else { @@ -240,19 +228,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } -#if 0 - glDisableClientState(GL_VERTEX_ARRAY); - if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_TEXTURE_2D); - } -#else glDisableVertexAttribArray(GLAMOR_VERTEX_POS); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisable(GL_TEXTURE_2D); } -#endif glUseProgram(0); /* The source texture is bound to a fbo, we have to flush it here. */ if (flush_needed) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 09851a0dd..9f0457380 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -141,30 +141,7 @@ void glamor_init_finish_access_shaders(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); -#ifndef GLAMOR_GLES2 const char *vs_source = - "void main()\n" - "{\n" - " gl_Position = gl_Vertex;\n" - " gl_TexCoord[0] = gl_MultiTexCoord0;\n" - "}\n"; - const char *fs_source = - "varying vec2 texcoords;\n" - "uniform sampler2D sampler;\n" - "void main()\n" - "{\n" - " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" - "}\n"; - - const char *aswizzle_source = - "varying vec2 texcoords;\n" - "uniform sampler2D sampler;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n" - "}\n"; -#endif - const char *es_vs_source = "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" "varying vec2 source_texture;\n" @@ -174,7 +151,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen) " source_texture = v_texcoord0.xy;\n" "}\n"; - const char *es_fs_source = + const char *fs_source = "varying vec2 source_texture;\n" "uniform sampler2D sampler;\n" "void main()\n" @@ -182,62 +159,37 @@ glamor_init_finish_access_shaders(ScreenPtr screen) " gl_FragColor = texture2D(sampler, source_texture);\n" "}\n"; - const char *es_aswizzle_source = + const char *set_alpha_source = "varying vec2 source_texture;\n" - "varying vec2 texcoords;\n" "uniform sampler2D sampler;\n" "void main()\n" "{\n" " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" "}\n"; - - - - GLint fs_prog, vs_prog, avs_prog, aswizzle_prog; - GLint es_fs_prog, es_vs_prog, es_avs_prog, es_aswizzle_prog; + GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; + GLint sampler_uniform_location; glamor_priv->finish_access_prog[0] = glCreateProgram(); glamor_priv->finish_access_prog[1] = glCreateProgram(); - glamor_priv->finish_access_prog[2] = glCreateProgram(); - glamor_priv->finish_access_prog[3] = glCreateProgram(); -#ifndef GLAMOR_GLES2 vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); - aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source); + set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, set_alpha_source); glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); - glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog); -#endif - es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); - es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source); - glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog); - glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog); + glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog); - es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source); - es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source); - glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog); - glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog); - - - -#ifndef GLAMOR_GLES2 + glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position"); + glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]); + + glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position"); + glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); -#endif - glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->finish_access_prog[2]); - glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->finish_access_prog[3]); - - GLint sampler_uniform_location; -#ifndef GLAMOR_GLES2 sampler_uniform_location = glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); glUseProgram(glamor_priv->finish_access_prog[0]); @@ -249,19 +201,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glUseProgram(glamor_priv->finish_access_prog[1]); glUniform1i(sampler_uniform_location, 0); glUseProgram(0); -#endif - sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[2]); - glUniform1i(sampler_uniform_location, 0); - glUseProgram(0); - - sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[3]); - glUniform1i(sampler_uniform_location, 0); - glUseProgram(0); - } void diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 556ff342c..660ffe014 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -102,33 +102,11 @@ void glamor_init_solid_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - const char *solid_vs_only = -#if 0 -#else - "attribute vec4 v_position;" -#endif - "uniform vec4 color;\n" - "void main()\n" - "{\n" -#if 0 - " gl_Position = gl_Vertex;\n" -#else - " gl_Position = v_position;\n" -#endif - " gl_Color = color;\n" - "}\n"; const char *solid_vs = -#if 0 -#else "attribute vec4 v_position;" -#endif "void main()\n" "{\n" -#if 0 - " gl_Position = gl_Vertex;\n" -#else " gl_Position = v_position;\n" -#endif "}\n"; const char *solid_fs = "uniform vec4 color;\n" @@ -201,25 +179,16 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); -#if 0 - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, glamor_priv->yInverted, vertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -#if 0 - glDisableClientState(GL_VERTEX_ARRAY); -#else glDisableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif glUseProgram(0); return TRUE; fail: diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 8ca1318ab..1dc1ee93c 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -32,14 +32,9 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, glamor_pixmap_private *pixmap_priv) { GLfloat vertices[8]; -#if 0 - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif glUseProgram(glamor_priv->solid_prog); glUniform4fv(glamor_priv->solid_color_uniform_location, 1, pixmap_priv->pending_op.fill.color4fv); @@ -52,11 +47,7 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, vertices[6] = -1; vertices[7] = 1; glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -#if 0 - glDisableClientState(GL_VERTEX_ARRAY); -#else glDisableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif glUseProgram(0); pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; } @@ -341,23 +332,14 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); -#if 0 glUseProgram(glamor_priv->finish_access_prog[no_alpha]); -#else - glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]); -#endif glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisable(GL_TEXTURE_2D); glUseProgram(0); -#if 0 - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#else glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); -#endif glDeleteTextures(1, &tex); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -516,7 +498,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) unsigned int stride, row_length, y; GLenum format, type, gl_access, gl_usage; int no_alpha; - uint8_t *data, *read; + uint8_t *data = NULL, *read; glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 2c2bf22d2..400988574 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -235,7 +235,7 @@ typedef struct glamor_screen_private { int max_fbo_size; /* glamor_finishaccess */ - GLint finish_access_prog[4]; + GLint finish_access_prog[2]; /* glamor_solid */ GLint solid_prog; diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 38da796af..addfdf2bd 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -35,8 +35,8 @@ void glamor_init_putimage_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); #if 0 + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); const char *xybitmap_vs = "uniform float x_bias;\n" "uniform float x_scale;\n" @@ -346,11 +346,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); -#if 0 glUseProgram(glamor_priv->finish_access_prog[no_alpha]); -#else - glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]); -#endif x += drawable->x; y += drawable->y; @@ -400,13 +396,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glDisable(GL_TEXTURE_2D); glUseProgram(0); -#if 0 - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#else glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); -#endif glDeleteTextures(1, &tex); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 12b09243d..6099af744 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -523,47 +523,25 @@ glamor_setup_composite_vbo(ScreenPtr screen) glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); -#if 0 - glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride, - (void *)((long)glamor_priv->vbo_offset)); - glEnableClientState(GL_VERTEX_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset)); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif if (glamor_priv->has_source_coords) { -#if 0 - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, - (void *)(glamor_priv->vbo_offset + 2 * sizeof(float))); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float))); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); -#endif } if (glamor_priv->has_mask_coords) { -#if 0 - glClientActiveTexture(GL_TEXTURE1); - glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride, - (void *)(glamor_priv->vbo_offset + - (glamor_priv->has_source_coords ? 4 : 2) * - sizeof(float))); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset + (glamor_priv->has_source_coords ? 4 : 2) * sizeof(float))); glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); -#endif } } @@ -1054,17 +1032,9 @@ glamor_composite_with_shader(CARD8 op, glamor_flush_composite_rects(screen); glBindBuffer(GL_ARRAY_BUFFER, 0); -#if 0 - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); -#else glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); -#endif REGION_UNINIT(dst->pDrawable->pScreen, ®ion); glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE0); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index cb235527d..5104f0b47 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -41,35 +41,20 @@ glamor_init_tile_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); const char *tile_vs = -#if 0 -#else "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" "varying vec2 tile_texture;\n" -#endif "void main()\n" "{\n" -#if 0 - " gl_Position = gl_Vertex;\n" - " gl_TexCoord[0] = gl_MultiTexCoord0;\n" -#else " gl_Position = v_position;\n" " tile_texture = v_texcoord0.xy;\n" -#endif "}\n"; const char *tile_fs = -#if 0 -#else "varying vec2 tile_texture;\n" -#endif "uniform sampler2D sampler;\n" "void main()\n" "{\n" -#if 0 - " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n" -#else " gl_FragColor = texture2D(sampler, tile_texture);\n" -#endif "}\n"; GLint fs_prog, vs_prog; GLint sampler_uniform_location; @@ -163,16 +148,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords); -#if 0 - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), source_texcoords); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); -#endif } else { GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); @@ -183,31 +162,17 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_priv->yInverted, vertices); -#if 0 - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -#if 0 - if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_TEXTURE_2D); - } - glDisableClientState(GL_VERTEX_ARRAY); -#else if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisable(GL_TEXTURE_2D); } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); -#endif glUseProgram(0); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); From 23c1fba5e5a5fe8dd18c4c8a9b5a958ce4671160 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Sat, 13 Aug 2011 15:41:18 -0400 Subject: [PATCH 184/225] glamor: Remove glu3 which is unnecessary. Signed-off-by: Zhigang Gong --- configure.ac | 1 - glamor/Makefile.am | 5 +- glamor/glu3/Makefile.am | 15 -- glamor/glu3/glu3.h | 161 ---------------- glamor/glu3/glu3_scalar.h | 388 -------------------------------------- glamor/glu3/matrix.c | 217 --------------------- 6 files changed, 1 insertion(+), 786 deletions(-) delete mode 100644 glamor/glu3/Makefile.am delete mode 100644 glamor/glu3/glu3.h delete mode 100644 glamor/glu3/glu3_scalar.h delete mode 100644 glamor/glu3/matrix.c diff --git a/configure.ac b/configure.ac index 737aa8487..69b1ac3c5 100644 --- a/configure.ac +++ b/configure.ac @@ -2163,7 +2163,6 @@ Xi/Makefile xfixes/Makefile exa/Makefile glamor/Makefile -glamor/glu3/Makefile hw/Makefile hw/xfree86/Makefile hw/xfree86/common/Makefile diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 2df76bd53..ec38ac4e8 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -4,8 +4,6 @@ noinst_LTLIBRARIES = libglamor.la # built (in hw/xfree86/os-support/solaris) until after glamor is built SOLARIS_ASM_CFLAGS="" -SUBDIRS = glu3 - if XORG sdk_HEADERS = glamor.h endif @@ -39,5 +37,4 @@ libglamor_la_SOURCES = \ glamor_picture.c\ glamor_window.c\ glamor.h -libglamor_la_LIBADD = \ - glu3/libglu3.la + diff --git a/glamor/glu3/Makefile.am b/glamor/glu3/Makefile.am deleted file mode 100644 index 7d141a7fc..000000000 --- a/glamor/glu3/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -noinst_LTLIBRARIES = libglu3.la - -# Override these since glu3 doesn't need them and the needed files aren't -# built (in hw/xfree86/os-support/solaris) until after glu3 is built -SOLARIS_ASM_CFLAGS="" - -INCLUDES = \ - $(XORG_INCS) - -AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) - -libglu3_la_SOURCES = \ - matrix.c \ - glu3.h \ - glu3_scalar.h diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h deleted file mode 100644 index 0a698cc02..000000000 --- a/glamor/glu3/glu3.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright © 2009 Ian D. Romanick - * - * 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. - */ - -#ifndef __glu3_h__ -#define __glu3_h__ - -#include - -#define GLU_VERSION_3_0 - -struct GLUmat4; - -struct GLUvec4 { - GLfloat values[4]; - -#ifdef __cplusplus - inline GLUvec4(void) - { - } - - inline GLUvec4(GLfloat x , GLfloat y, GLfloat z, GLfloat w) - { - values[0] = x; - values[1] = y; - values[2] = z; - values[3] = w; - } - - inline GLUvec4(const GLUvec4 &v) - { - values[0] = v.values[0]; - values[1] = v.values[1]; - values[2] = v.values[2]; - values[3] = v.values[3]; - } - - GLUvec4 operator *(const GLUmat4 &) const; - GLUvec4 operator *(const GLUvec4 &) const; - GLUvec4 operator *(GLfloat) const; - - GLUvec4 operator +(const GLUvec4 &) const; - GLUvec4 operator -(const GLUvec4 &) const; -#endif /* __cplusplus */ -}; - - -struct GLUmat4 { - struct GLUvec4 col[4]; - -#ifdef __cplusplus - inline GLUmat4(void) - { - } - - inline GLUmat4(const GLUvec4 & c0, const GLUvec4 & c1, - const GLUvec4 & c2, const GLUvec4 & c3) - { - col[0] = c0; - col[1] = c1; - col[2] = c2; - col[3] = c3; - } - - inline GLUmat4(const GLUmat4 &m) - { - col[0] = m.col[0]; - col[1] = m.col[1]; - col[2] = m.col[2]; - col[3] = m.col[3]; - } - - - GLUvec4 operator *(const GLUvec4 &) const; - GLUmat4 operator *(const GLUmat4 &) const; - GLUmat4 operator *(GLfloat) const; - - GLUmat4 operator +(const GLUmat4 &) const; - GLUmat4 operator -(const GLUmat4 &) const; -#endif /* __cplusplus */ -}; - -#define GLU_MAX_STACK_DEPTH 32 - -struct GLUmat4Stack { - struct GLUmat4 stack[GLU_MAX_STACK_DEPTH]; - unsigned top; - -#ifdef __cplusplus - GLUmat4Stack() : top(0) - { - /* empty */ - } -#endif /* __cplusplus */ -}; - -#ifndef __cplusplus -typedef struct GLUvec4 GLUvec4; -typedef struct GLUmat4 GLUmat4; -typedef struct GLUmat4Stack GLUmat4Stack; -#endif /* __cplusplus */ - - -#ifdef __cplusplus -extern "C" { -#endif - -void gluScale4v(GLUmat4 *result, const GLUvec4 *); -void gluTranslate4v(GLUmat4 *result, const GLUvec4 *); -void gluRotate4v(GLUmat4 *result, const GLUvec4 *axis, GLfloat angle); -void gluLookAt4v(GLUmat4 *result, const GLUvec4 *eye, const GLUvec4 *center, - const GLUvec4 *up); -void gluPerspective4f(GLUmat4 *result, GLfloat fovy, GLfloat aspect, - GLfloat near, GLfloat far); -void gluFrustum6f(GLUmat4 *result, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat near, GLfloat far); -void gluOrtho6f(GLUmat4 *result, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat near, GLfloat far); -extern const GLUmat4 gluIdentityMatrix; - -#ifdef __cplusplus -}; -#endif - -#ifdef __cplusplus -GLfloat gluDot4(const GLUvec4 &, const GLUvec4 &); -GLfloat gluDot3(const GLUvec4 &, const GLUvec4 &); -GLfloat gluDot2(const GLUvec4 &, const GLUvec4 &); - -GLUvec4 gluCross(const GLUvec4 &, const GLUvec4 &); -GLUvec4 gluNormalize(const GLUvec4 &); -GLfloat gluLength(const GLUvec4 &); -GLfloat gluLengthSqr(const GLUvec4 &); -#endif /* __cplusplus */ - -#include "glu3_scalar.h" - -#endif /* __glu3_h__ */ diff --git a/glamor/glu3/glu3_scalar.h b/glamor/glu3/glu3_scalar.h deleted file mode 100644 index 00592f0dc..000000000 --- a/glamor/glu3/glu3_scalar.h +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright © 2009 Ian D. Romanick - * - * 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. - */ - -#include -#include - -static inline void gluMult4v_4v(GLUvec4 *result, - const GLUvec4 *v1, const GLUvec4 *v2) -{ - result->values[0] = v1->values[0] * v2->values[0]; - result->values[1] = v1->values[1] * v2->values[1]; - result->values[2] = v1->values[2] * v2->values[2]; - result->values[3] = v1->values[3] * v2->values[3]; -} - - -static inline void gluDiv4v_4v(GLUvec4 *result, - const GLUvec4 *v1, const GLUvec4 *v2) -{ - result->values[0] = v1->values[0] / v2->values[0]; - result->values[1] = v1->values[1] / v2->values[1]; - result->values[2] = v1->values[2] / v2->values[2]; - result->values[3] = v1->values[3] / v2->values[3]; -} - - -static inline void gluAdd4v_4v(GLUvec4 *result, - const GLUvec4 *v1, const GLUvec4 *v2) -{ - result->values[0] = v1->values[0] + v2->values[0]; - result->values[1] = v1->values[1] + v2->values[1]; - result->values[2] = v1->values[2] + v2->values[2]; - result->values[3] = v1->values[3] + v2->values[3]; -} - - -static inline void gluSub4v_4v(GLUvec4 *result, - const GLUvec4 *v1, const GLUvec4 *v2) -{ - result->values[0] = v1->values[0] - v2->values[0]; - result->values[1] = v1->values[1] - v2->values[1]; - result->values[2] = v1->values[2] - v2->values[2]; - result->values[3] = v1->values[3] - v2->values[3]; -} - - -static inline void gluMult4v_f(GLUvec4 *result, - const GLUvec4 *v1, GLfloat f) -{ - result->values[0] = v1->values[0] * f; - result->values[1] = v1->values[1] * f; - result->values[2] = v1->values[2] * f; - result->values[3] = v1->values[3] * f; -} - - -static inline void gluDiv4v_f(GLUvec4 *result, - const GLUvec4 *v1, GLfloat f) -{ - result->values[0] = v1->values[0] / f; - result->values[1] = v1->values[1] / f; - result->values[2] = v1->values[2] / f; - result->values[3] = v1->values[3] / f; -} - - -static inline void gluAdd4v_f(GLUvec4 *result, - const GLUvec4 *v1, GLfloat f) -{ - result->values[0] = v1->values[0] + f; - result->values[1] = v1->values[1] + f; - result->values[2] = v1->values[2] + f; - result->values[3] = v1->values[3] + f; -} - - -static inline void gluSub4v_f(GLUvec4 *result, - const GLUvec4 *v1, GLfloat f) -{ - result->values[0] = v1->values[0] - f; - result->values[1] = v1->values[1] - f; - result->values[2] = v1->values[2] - f; - result->values[3] = v1->values[3] - f; -} - - -static inline void gluMult4m_f(GLUmat4 *result, - const GLUmat4 *m, GLfloat f) -{ - GLUmat4 temp; - - gluMult4v_f(& temp.col[0], & m->col[0], f); - gluMult4v_f(& temp.col[1], & m->col[1], f); - gluMult4v_f(& temp.col[2], & m->col[2], f); - gluMult4v_f(& temp.col[3], & m->col[3], f); - *result = temp; -} - - -static inline void gluMult4m_4v(GLUvec4 *result, - const GLUmat4 *m, const GLUvec4 *v) -{ - GLUvec4 temp[6]; - unsigned i; - - for (i = 0; i < 4; i++) { - gluMult4v_f(& temp[i], & m->col[i], v->values[i]); - } - - gluAdd4v_4v(& temp[4], & temp[0], & temp[1]); - gluAdd4v_4v(& temp[5], & temp[2], & temp[3]); - gluAdd4v_4v(result, & temp[4], & temp[5]); -} - - -static inline void gluAdd4m_4m(GLUmat4 *result, - const GLUmat4 *m1, const GLUmat4 *m2) -{ - GLUmat4 temp; - - gluAdd4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]); - gluAdd4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]); - gluAdd4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]); - gluAdd4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]); - *result = temp; -} - -static inline void gluSub4m_4m(GLUmat4 *result, - const GLUmat4 *m1, const GLUmat4 *m2) -{ - GLUmat4 temp; - - gluSub4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]); - gluSub4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]); - gluSub4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]); - gluSub4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]); - *result = temp; -} - -static inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2) -{ - return v1->values[0] * v2->values[0] - + v1->values[1] * v2->values[1] - + v1->values[2] * v2->values[2] - + v1->values[3] * v2->values[3]; -} - - -static inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2) -{ - return v1->values[0] * v2->values[0] - + v1->values[1] * v2->values[1] - + v1->values[2] * v2->values[2]; -} - - -static inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2) -{ - return v1->values[0] * v2->values[0] - + v1->values[1] * v2->values[1]; -} - - -static inline void gluCross4v(GLUvec4 *result, - const GLUvec4 *v1, const GLUvec4 *v2) -{ - GLUvec4 temp; - - temp.values[0] = (v1->values[1] * v2->values[2]) - - (v1->values[2] * v2->values[1]); - temp.values[1] = (v1->values[2] * v2->values[0]) - - (v1->values[0] * v2->values[2]); - temp.values[2] = (v1->values[0] * v2->values[1]) - - (v1->values[1] * v2->values[0]); - temp.values[3] = 0.0; - *result = temp; -} - - -static inline void gluOuter4v(GLUmat4 *result, - const GLUvec4 *v1, const GLUvec4 *v2) -{ - GLUmat4 temp; - - gluMult4v_f(& temp.col[0], v1, v2->values[0]); - gluMult4v_f(& temp.col[1], v1, v2->values[1]); - gluMult4v_f(& temp.col[2], v1, v2->values[2]); - gluMult4v_f(& temp.col[3], v1, v2->values[3]); - *result = temp; -} - - -static inline GLfloat gluLengthSqr4v(const GLUvec4 *v) -{ - return gluDot4_4v(v, v); -} - - -static inline GLfloat gluLength4v(const GLUvec4 *v) -{ - return sqrt(gluLengthSqr4v(v)); -} - - -static inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v) -{ - gluDiv4v_f(result, v, gluLength4v(v)); -} - - - -static inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m) -{ - unsigned i; - unsigned j; - GLUmat4 temp; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - temp.col[i].values[j] = m->col[j].values[i]; - } - } - - *result = temp; -} - - -static inline void gluMult4m_4m(GLUmat4 *result, - const GLUmat4 *m1, const GLUmat4 *m2) -{ - GLUmat4 temp; - unsigned i; - - for (i = 0; i < 4; i++) { - gluMult4m_4v(& temp.col[i], m1, & m2->col[i]); - } - - *result = temp; -} - - - -static inline void gluTranslate3f(GLUmat4 *result, - GLfloat x, GLfloat y, GLfloat z) -{ - memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix)); - result->col[3].values[0] = x; - result->col[3].values[1] = y; - result->col[3].values[2] = z; -} - - -#ifdef __cplusplus -static inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2) -{ - return v1.values[0] * v2.values[0] - + v1.values[1] * v2.values[1] - + v1.values[2] * v2.values[2] - + v1.values[3] * v2.values[3]; -} - - -static inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2) -{ - return v1.values[0] * v2.values[0] - + v1.values[1] * v2.values[1] - + v1.values[2] * v2.values[2]; -} - - -static inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2) -{ - return v1.values[0] * v2.values[0] - + v1.values[1] * v2.values[1]; -} - - -inline GLUvec4 GLUvec4::operator+(const GLUvec4 &v) const -{ - return GLUvec4(values[0] + v.values[0], - values[1] + v.values[1], - values[2] + v.values[2], - values[3] + v.values[3]); -} - - -inline GLUvec4 GLUvec4::operator-(const GLUvec4 &v) const -{ - return GLUvec4(values[0] - v.values[0], - values[1] - v.values[1], - values[2] - v.values[2], - values[3] - v.values[3]); -} - - -inline GLUvec4 GLUvec4::operator*(const GLUvec4 &v) const -{ - return GLUvec4(values[0] * v.values[0], - values[1] * v.values[1], - values[2] * v.values[2], - values[3] * v.values[3]); -} - - -inline GLUvec4 GLUvec4::operator*(GLfloat f) const -{ - return GLUvec4(values[0] * f, - values[1] * f, - values[2] * f, - values[3] * f); -} - - -inline GLUvec4 GLUvec4::operator*(const GLUmat4 &m) const -{ - return GLUvec4(gluDot4(*this, m.col[0]), - gluDot4(*this, m.col[1]), - gluDot4(*this, m.col[2]), - gluDot4(*this, m.col[3])); -} - - -inline GLUmat4 GLUmat4::operator+(const GLUmat4 &m) const -{ - GLUmat4 temp; - - gluAdd4m_4m(& temp, this, &m); - return temp; -} - - -inline GLUmat4 GLUmat4::operator-(const GLUmat4 &m) const -{ - return GLUmat4(col[0] - m.col[0], - col[1] - m.col[1], - col[2] - m.col[2], - col[3] - m.col[3]); -} - - -inline GLUmat4 GLUmat4::operator*(GLfloat f) const -{ - GLUmat4 temp; - - gluMult4m_f(& temp, this, f); - return temp; -} - - -inline GLUvec4 GLUmat4::operator*(const GLUvec4 &v) const -{ - return (col[0] * v.values[0]) - + (col[1] * v.values[1]) - + (col[2] * v.values[2]) - + (col[3] * v.values[3]); -} - - -inline GLUmat4 GLUmat4::operator*(const GLUmat4 &m) const -{ - GLUmat4 temp; - - gluMult4m_4m(& temp, this, &m); - return temp; -} - - -#endif /* __cplusplus */ diff --git a/glamor/glu3/matrix.c b/glamor/glu3/matrix.c deleted file mode 100644 index b3d5819f7..000000000 --- a/glamor/glu3/matrix.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright © 2009 Ian D. Romanick - * - * 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. - */ - -#include -#include "glu3.h" - -#define DEG2RAD(d) ((d) * M_PI / 180.0) - -const GLUmat4 gluIdentityMatrix = { - { - { { 1.0f, 0.0f, 0.0f, 0.0f } }, - { { 0.0f, 1.0f, 0.0f, 0.0f } }, - { { 0.0f, 0.0f, 1.0f, 0.0f } }, - { { 0.0f, 0.0f, 0.0f, 1.0f } } - } -}; - - -void gluTranslate4v(GLUmat4 *result, const GLUvec4 *t) -{ - memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix)); - result->col[3] = *t; - result->col[3].values[3] = 1.0f; -} - - -void gluScale4v(GLUmat4 *result, const GLUvec4 *t) -{ - memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix)); - result->col[0].values[0] = t->values[0]; - result->col[1].values[1] = t->values[1]; - result->col[2].values[2] = t->values[2]; -} - - -void gluLookAt4v(GLUmat4 *result, - const GLUvec4 *_eye, - const GLUvec4 *_center, - const GLUvec4 *_up) -{ - static const GLUvec4 col3 = { { 0.0f, 0.0f, 0.0f, 1.0f } }; - const GLUvec4 e = { - { -_eye->values[0], -_eye->values[1], -_eye->values[2], 0.0f } - }; - GLUmat4 translate; - GLUmat4 rotate; - GLUmat4 rotateT; - GLUvec4 f; - GLUvec4 s; - GLUvec4 u; - GLUvec4 center, up; - - center = *_center; - center.values[3] = 0; - up = *_up; - up.values[3] = 0; - - gluAdd4v_4v(& f, ¢er, &e); - gluNormalize4v(& f, & f); - - gluNormalize4v(& u, &up); - - gluCross4v(& s, & f, & u); - gluCross4v(& u, & s, & f); - - rotate.col[0] = s; - rotate.col[1] = u; - rotate.col[2].values[0] = -f.values[0]; - rotate.col[2].values[1] = -f.values[1]; - rotate.col[2].values[2] = -f.values[2]; - rotate.col[2].values[3] = 0.0f; - rotate.col[3] = col3; - gluTranspose4m(& rotateT, & rotate); - - gluTranslate4v(& translate, & e); - gluMult4m_4m(result, & rotateT, & translate); -} - - -void gluRotate4v(GLUmat4 *result, const GLUvec4 *_axis, GLfloat angle) -{ - GLUvec4 axis; - const float c = cos(angle); - const float s = sin(angle); - const float one_c = 1.0 - c; - - float xx; - float yy; - float zz; - - float xs; - float ys; - float zs; - - float xy; - float xz; - float yz; - - /* Only normalize the 3-component axis. A gluNormalize3v might be - * appropriate to save us some computation. - */ - axis = *_axis; - axis.values[3] = 0; - gluNormalize4v(&axis, &axis); - - xx = axis.values[0] * axis.values[0]; - yy = axis.values[1] * axis.values[1]; - zz = axis.values[2] * axis.values[2]; - - xs = axis.values[0] * s; - ys = axis.values[1] * s; - zs = axis.values[2] * s; - - xy = axis.values[0] * axis.values[1]; - xz = axis.values[0] * axis.values[2]; - yz = axis.values[1] * axis.values[2]; - - - result->col[0].values[0] = (one_c * xx) + c; - result->col[0].values[1] = (one_c * xy) + zs; - result->col[0].values[2] = (one_c * xz) - ys; - result->col[0].values[3] = 0.0; - - result->col[1].values[0] = (one_c * xy) - zs; - result->col[1].values[1] = (one_c * yy) + c; - result->col[1].values[2] = (one_c * yz) + xs; - result->col[1].values[3] = 0.0; - - - result->col[2].values[0] = (one_c * xz) + ys; - result->col[2].values[1] = (one_c * yz) - xs; - result->col[2].values[2] = (one_c * zz) + c; - result->col[2].values[3] = 0.0; - - result->col[3].values[0] = 0.0; - result->col[3].values[1] = 0.0; - result->col[3].values[2] = 0.0; - result->col[3].values[3] = 1.0; -} - - -void -gluPerspective4f(GLUmat4 *result, - GLfloat fovy, GLfloat aspect, GLfloat near, GLfloat far) -{ - const double sine = sin(DEG2RAD(fovy / 2.0)); - const double cosine = cos(DEG2RAD(fovy / 2.0)); - const double sine_aspect = sine * aspect; - const double dz = far - near; - - - memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix)); - if ((sine == 0.0) || (dz == 0.0) || (sine_aspect == 0.0)) { - return; - } - - result->col[0].values[0] = cosine / sine_aspect; - result->col[1].values[1] = cosine / sine; - result->col[2].values[2] = -(far + near) / dz; - result->col[2].values[3] = -1.0; - result->col[3].values[2] = -2.0 * near * far / dz; - result->col[3].values[3] = 0.0; -} - -void gluFrustum6f(GLUmat4 *result, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat near, GLfloat far) -{ - memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix)); - - result->col[0].values[0] = (2.0 * near) / (right - left); - result->col[1].values[1] = (2.0 * near) / (top - bottom); - result->col[2].values[0] = (right + left) / (right - left); - result->col[2].values[1] = (top + bottom) / (top - bottom); - result->col[2].values[2] = -(far + near) / (far - near); - result->col[2].values[3] = -1.0; - result->col[3].values[2] = -2.0 * near * far / (far - near); - result->col[3].values[3] = 0.0; -} - -void gluOrtho6f(GLUmat4 *result, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat near, GLfloat far) -{ - memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix)); - - result->col[0].values[0] = 2.0f / (right - left); - result->col[3].values[0] = -(right + left) / (right - left); - - result->col[1].values[1] = 2.0f / (top - bottom); - result->col[3].values[1] = -(top + bottom) / (top - bottom); - - result->col[2].values[2] = -2.0f / (far - near); - result->col[3].values[2] = -(far + near) / (far - near); -} From f84cc8b84b2944b60eb2a8225e3c44a1cdfb228d Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 16 Aug 2011 00:09:38 +0800 Subject: [PATCH 185/225] glamor-ddx: Hardware cursor's format should be GL_RGBA. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor_crtc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 5c2b5c124..959201397 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -494,9 +494,14 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) } glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); #ifdef GLAMOR_GLES2 - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, 64, 64, 0, - GL_BGRA, GL_UNSIGNED_BYTE, image); + /* XXX Actually, the image is BGRA not RGBA, so the r and b + * should be swapped. But as normally, they are the same value + * ignore this currently, don't want to let CPU to do the swizzle. + * considering to put this function to the glamor rendering directory. + * Thus we can reuse the shader to do this.*/ + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); #else glPixelStorei(GL_UNPACK_ROW_LENGTH, 64); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, From 504e03c0b59f4dc3b8058abdce79706a72cd0dde Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 16 Aug 2011 00:17:58 +0800 Subject: [PATCH 186/225] glamor: GLES2 doesn't support GL_CLAMP_TO_BORDER. Simply comments it out. Need revisit latter. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6099af744..cec6c8d25 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -376,11 +376,11 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); switch (picture->repeatType) { case RepeatNone: -#ifdef GLAMOR_GLES2 - assert(1); -#endif +#ifndef GLAMOR_GLES2 + /* XXX GLES2 doesn't support GL_CLAMP_TO_BORDER. */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); +#endif break; case RepeatNormal: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -407,8 +407,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; } - +#ifndef GLAMOR_GLES2 glEnable(GL_TEXTURE_2D); +#endif } static void @@ -1037,10 +1038,12 @@ glamor_composite_with_shader(CARD8 op, glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); REGION_UNINIT(dst->pDrawable->pScreen, ®ion); glDisable(GL_BLEND); +#ifndef GLAMOR_GLES2 glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE1); glDisable(GL_TEXTURE_2D); +#endif glUseProgram(0); if (saved_source_format) source->format = saved_source_format; From 0eea084db54fb88b9933fd1326a2b0b059b3f9d7 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 16 Aug 2011 00:20:01 +0800 Subject: [PATCH 187/225] glamor: GLES2 doesn't support glEnable/Disable Texture 2D. Signed-off-by: Zhigang Gong --- glamor/glamor_tile.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 5104f0b47..25ad63583 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -140,9 +140,11 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); +#ifndef GLAMOR_GLES2 glEnable(GL_TEXTURE_2D); +#endif glamor_set_normalize_tcoords(src_xscale, src_yscale, tile_x1, tile_y1, tile_x2, tile_y2, @@ -170,7 +172,9 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#ifndef GLAMOR_GLES2 glDisable(GL_TEXTURE_2D); +#endif } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glUseProgram(0); From 67da52ec13a87846201a99d5a31db28668d9fdfd Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 16 Aug 2011 00:21:09 +0800 Subject: [PATCH 188/225] glamor: Add color conversion support by using new shader. There are two places we need to do color conversion. 1. When upload a image data to a texture. 2. When download a texture to a memory buffer. As the color format may not be supported in GLES2. We may need to do the following two operations to convert dat. a. revert argb to bgra / abgr to rgba. b. swap argb to abgr / bgra to rgba. Signed-off-by: Zhigang Gong --- glamor/glamor_core.c | 52 +++++++++++- glamor/glamor_fill.c | 1 - glamor/glamor_pixmap.c | 179 ++++++++++++++++++++++++++++++--------- glamor/glamor_priv.h | 132 ++++++++++++++++++++++++++++- glamor/glamor_putimage.c | 29 +++---- glamor/glamor_setspans.c | 11 ++- 6 files changed, 339 insertions(+), 65 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 9f0457380..d4588e28a 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -133,7 +133,6 @@ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - return glamor_download_pixmap_to_cpu(pixmap, access); } @@ -154,17 +153,47 @@ glamor_init_finish_access_shaders(ScreenPtr screen) const char *fs_source = "varying vec2 source_texture;\n" "uniform sampler2D sampler;\n" + "uniform int no_revert;" + "uniform int swap_rb;" "void main()\n" "{\n" - " gl_FragColor = texture2D(sampler, source_texture);\n" + " if (no_revert == 1) \n" + " { \n" + " if (swap_rb == 1) \n" + " gl_FragColor = texture2D(sampler, source_texture).bgra;\n" + " else \n" + " gl_FragColor = texture2D(sampler, source_texture).rgba;\n" + " } \n" + " else \n" + " { \n" + " if (swap_rb == 1) \n" + " gl_FragColor = texture2D(sampler, source_texture).argb;\n" + " else \n" + " gl_FragColor = texture2D(sampler, source_texture).abgr;\n" + " } \n" "}\n"; const char *set_alpha_source = "varying vec2 source_texture;\n" "uniform sampler2D sampler;\n" + "uniform int no_revert;" + "uniform int swap_rb;" "void main()\n" "{\n" - " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" + " if (no_revert == 1) \n" + " { \n" + " if (swap_rb == 1) \n" + " gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n" + " else \n" + " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" + " } \n" + " else \n" + " { \n" + " if (swap_rb == 1) \n" + " gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n" + " else \n" + " gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n" + " } \n" "}\n"; GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; GLint sampler_uniform_location; @@ -190,17 +219,31 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); + glamor_priv->finish_access_no_revert[0] = + glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert"); + + glamor_priv->finish_access_swap_rb[0] = + glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb"); sampler_uniform_location = glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); glUseProgram(glamor_priv->finish_access_prog[0]); glUniform1i(sampler_uniform_location, 0); + glUniform1i(glamor_priv->finish_access_no_revert[0],1); + glUniform1i(glamor_priv->finish_access_swap_rb[0],0); glUseProgram(0); + glamor_priv->finish_access_no_revert[1] = + glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert"); + glamor_priv->finish_access_swap_rb[1] = + glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb"); sampler_uniform_location = glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); glUseProgram(glamor_priv->finish_access_prog[1]); + glUniform1i(glamor_priv->finish_access_no_revert[1],1); glUniform1i(sampler_uniform_location, 0); + glUniform1i(glamor_priv->finish_access_swap_rb[1],0); glUseProgram(0); + } void @@ -224,8 +267,9 @@ glamor_finish_access(DrawablePtr drawable) pixmap_priv->pbo_valid = FALSE; glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->pbo = 0; - } else + } else { free(pixmap->devPrivate.ptr); + } pixmap->devPrivate.ptr = NULL; } diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 660ffe014..873f383a5 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -143,7 +143,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, GLfloat color[4]; float vertices[8]; GLfloat xscale, yscale; - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("dest %p has no fbo.\n", pixmap); goto fail; diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 1dc1ee93c..1e17069f1 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -83,12 +83,15 @@ glamor_validate_pixmap(PixmapPtr pixmap) void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) { - glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); -#ifndef GLAMOR_GLES2 - glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); glLoadIdentity(); -#endif +// glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); + glamor_pixmap_ensure_fb(pixmap_priv->container); +#ifndef GLAMOR_GLES2 + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +#endif glViewport(0, 0, pixmap_priv->container->drawable.width, pixmap_priv->container->drawable.height); @@ -199,7 +202,7 @@ glamor_set_alu(unsigned char alu) * Upload pixmap to a specified texture. * This texture may not be the one attached to it. **/ - +int in_restore = 0; static void __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex) { @@ -225,7 +228,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { iformat = format; - type = GL_UNSIGNED_BYTE; } stride = pixmap->devKind; @@ -264,7 +266,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, static void _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, - GLenum type, int no_alpha, int flip) + GLenum type, int no_alpha, int no_revert, + int flip) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -290,8 +293,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, /* Try fast path firstly, upload the pixmap to the texture attached * to the fbo directly. */ - - if (no_alpha == 0 && !need_flip) { + if (no_alpha == 0 && no_revert == 1 && !need_flip) { __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex); return; } @@ -303,14 +305,6 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, ptexcoords = texcoords_inv; /* Slow path, we need to flip y or wire alpha to 1. */ -#if 0 - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); - - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); @@ -319,10 +313,8 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, 2 * sizeof(float), ptexcoords); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); -#endif - glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); - glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height); + glamor_set_destination_pixmap_priv_nc(pixmap_priv); glGenTextures(1, &tex); __glamor_upload_pixmap_to_texture(pixmap, format, type, tex); @@ -331,12 +323,18 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +#ifndef GLAMOR_GLES2 glEnable(GL_TEXTURE_2D); +#endif glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); + glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +#ifndef GLAMOR_GLES2 glDisable(GL_TEXTURE_2D); +#endif glUseProgram(0); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); @@ -386,7 +384,7 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap) * 2. no_alpha != 0, we need to wire the alpha. * */ static int -glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha) +glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert) { int need_fbo; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -402,7 +400,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha) if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return 0; - if (no_alpha != 0 || !glamor_priv->yInverted) + if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted) need_fbo = 1; else need_fbo = 0; @@ -427,16 +425,17 @@ enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr pixmap) { GLenum format, type; - int no_alpha; + int no_alpha, no_revert; if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &no_alpha)) { + &no_alpha, + &no_revert)) { glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); return GLAMOR_UPLOAD_FAILED; } - if (glamor_pixmap_upload_prepare(pixmap, no_alpha)) + if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert)) return GLAMOR_UPLOAD_FAILED; glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD, "Uploading pixmap %p %dx%d depth%d.\n", @@ -444,7 +443,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap) pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth); - _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1); + _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1); return GLAMOR_UPLOAD_DONE; } @@ -468,18 +467,101 @@ void glamor_restore_pixmap_to_texture(PixmapPtr pixmap) { GLenum format, type; - int no_alpha; + int no_alpha, no_revert; if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &no_alpha)) { + &no_alpha, + &no_revert)) { ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); assert(0); } - _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1); + + in_restore = 1; + _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1); + in_restore = 0; } +/* + * as gles2 only support a very small set of color format and + * type when do glReadPixel, + * Before we use glReadPixels to get back a textured pixmap, + * Use shader to convert it to a supported format and thus + * get a new temporary pixmap returned. + * */ + +PixmapPtr +glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, + GLenum *type, int no_alpha, int no_revert) +{ + glamor_pixmap_private *source_priv; + glamor_screen_private *glamor_priv; + ScreenPtr screen; + PixmapPtr temp_pixmap; + glamor_pixmap_private *temp_pixmap_priv; + static float vertices[8] = {-1, -1, + 1, -1, + 1, 1, + -1, 1}; + static float texcoords[8] = {0, 0, + 1, 0, + 1, 1, + 0, 1}; + + int swap_rb = 0; + + screen = source->drawable.pScreen; + + glamor_priv = glamor_get_screen_private(screen); + source_priv = glamor_get_pixmap_private(source); + if (*format == GL_BGRA) { + *format = GL_RGBA; + swap_rb = 1; + } + + + temp_pixmap = (*screen->CreatePixmap)(screen, + source->drawable.width, + source->drawable.height, + source->drawable.depth, + 0); + + temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); + + glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex); + glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, + source->drawable.height, 0, + *format, *type, NULL); + + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + vertices); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + 2 * sizeof(float), + texcoords); + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, source_priv->tex); + + glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv); + + glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); + glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glUseProgram(0); + glFlush(); + return temp_pixmap; +} + /** * Move a pixmap to CPU memory. @@ -497,18 +579,21 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); unsigned int stride, row_length, y; GLenum format, type, gl_access, gl_usage; - int no_alpha; + int no_alpha, no_revert; uint8_t *data = NULL, *read; + PixmapPtr temp_pixmap = NULL; + ScreenPtr screen; glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - - + + screen = pixmap->drawable.pScreen; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return TRUE; if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &no_alpha)) { + &no_alpha, + &no_revert)) { ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth); assert(0); // Should never happen. return FALSE; @@ -521,13 +606,21 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth); - + stride = pixmap->devKind; + glamor_set_destination_pixmap_priv_nc(pixmap_priv); /* XXX we may don't need to validate it on GPU here, * we can just validate it on CPU. */ glamor_validate_pixmap(pixmap); - switch (access) { + + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 + && ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA) || no_revert != 1)) { + + temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format, &type, no_alpha, no_revert); + + } + switch (access) { case GLAMOR_ACCESS_RO: gl_access = GL_READ_ONLY; gl_usage = GL_STREAM_READ; @@ -544,9 +637,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) ErrorF("Glamor: Invalid access code. %d\n", access); assert(0); } - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { data = malloc(stride * pixmap->drawable.height); + } row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, row_length); @@ -582,8 +677,10 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) } glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); } else { + if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) + type = GL_UNSIGNED_SHORT_5_5_5_1; glReadPixels (0, 0, - row_length, pixmap->drawable.height, + pixmap->drawable.width, pixmap->drawable.height, format, type, data); } } else { @@ -614,6 +711,12 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) glBindFramebuffer(GL_FRAMEBUFFER, 0); done: pixmap->devPrivate.ptr = data; + + if (temp_pixmap) { + glFlush(); + (*screen->DestroyPixmap)(temp_pixmap); + } + return TRUE; } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 400988574..1f3e8c464 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -43,6 +43,7 @@ #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 @@ -236,6 +237,8 @@ typedef struct glamor_screen_private { /* glamor_finishaccess */ GLint finish_access_prog[2]; + GLint finish_access_no_revert[2]; + GLint finish_access_swap_rb[2]; /* glamor_solid */ GLint solid_prog; @@ -408,13 +411,16 @@ format_for_pixmap(PixmapPtr pixmap) * * 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 *no_alpha, + int *no_revert) { *no_alpha = 0; + *no_revert = 1; switch (format) { case PICT_a1: *tex_format = GL_COLOR_INDEX; @@ -497,13 +503,125 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format, } return 0; } +#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 *no_revert) +{ + *no_alpha = 0; + *no_revert = IS_LITTLE_ENDIAN; + + switch (format) { + case PICT_b8g8r8x8: + *no_alpha = 1; + case PICT_b8g8r8a8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_BYTE; + *no_revert = !IS_LITTLE_ENDIAN; + break; + + case PICT_x8r8g8b8: + *no_alpha = 1; + case PICT_a8r8g8b8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_BYTE; + 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_BGRA; + *tex_type = GL_UNSIGNED_INT_10_10_10_2; + *no_revert = TRUE; + break; + + case PICT_x2b10g10r10: + *no_alpha = 1; + case PICT_a2b10g10r10: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_INT_10_10_10_2; + *no_revert = TRUE; + break; + + case PICT_r5g6b5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + *no_revert = TRUE; + break; + + case PICT_b5g6r5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + *no_revert = FALSE; + break; + + case PICT_x1b5g5r5: + *no_alpha = 1; + case PICT_a1b5g5r5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *no_revert = TRUE; + break; + + case PICT_x1r5g5b5: + *no_alpha = 1; + case PICT_a1r5g5b5: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *no_revert = TRUE; + break; + + case PICT_a8: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *no_revert = TRUE; + break; + + case PICT_x4r4g4b4: + *no_alpha = 1; + case PICT_a4r4g4b4: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + *no_revert = TRUE; + break; + + case PICT_x4b4g4r4: + *no_alpha = 1; + case PICT_a4b4g4r4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + *no_revert = TRUE; + break; + + default: + LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format); + return -1; + } + return 0; +} + + +#endif static inline int glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type, - int *ax) + int *no_alpha, + int *no_revert) { glamor_pixmap_private *pixmap_priv; PictFormatShort pict_format; @@ -515,7 +633,8 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, pict_format = format_for_depth(pixmap->drawable.depth); return glamor_get_tex_format_type_from_pictformat(pict_format, - format, type, ax); + format, type, + no_alpha, no_revert); } @@ -658,6 +777,11 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv); * */ void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv); + +PixmapPtr +glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, + GLenum *type, int no_alpha, int no_revert); + void glamor_set_alu(unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); void glamor_get_transform_uniform_locations(GLint prog, @@ -870,7 +994,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD -#define GLAMOR_DELAYED_FILLING +//#define GLAMOR_DELAYED_FILLING #include"glamor_utils.h" diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index addfdf2bd..a7a6186ee 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -265,7 +265,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, float vertices[8], texcoords[8]; GLfloat xscale, yscale, txscale, tyscale; GLuint tex; - int no_alpha; + int no_alpha, no_revert; if (image_format == XYBitmap) { assert(depth == 1); goto fail; @@ -290,7 +290,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &no_alpha + &no_alpha, + &no_revert )) { glamor_fallback("unknown depth. %d \n", drawable->depth); @@ -300,14 +301,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, /* XXX consider to reuse a function to do the following work. */ glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_validate_pixmap(pixmap); -#if 0 - glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices); - glEnableClientState(GL_VERTEX_ARRAY); - - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -#else glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); @@ -317,7 +310,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, 2 * sizeof(float), texcoords); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); -#endif if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -333,20 +325,25 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { - type = GL_UNSIGNED_BYTE; iformat = format; } else { iformat = GL_RGBA; } + glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +#ifndef GLAMOR_GLES2 glEnable(GL_TEXTURE_2D); +#endif glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); + glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0); x += drawable->x; y += drawable->y; @@ -394,7 +391,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } +#ifndef GLAMOR_GLES2 glDisable(GL_TEXTURE_2D); +#endif glUseProgram(0); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); @@ -409,9 +408,9 @@ fail: glamor_set_planemask(pixmap, ~0); glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { - fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format, + if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) { + fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h, left_pad, image_format, bits); - glamor_finish_access(drawable); + glamor_finish_access(&pixmap->drawable); } } diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index a1d5dc1a6..8b2676b4b 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -38,7 +38,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); glamor_screen_private *glamor_priv; GLenum format, type; - int no_alpha, i; + int no_alpha, no_revert, i; uint8_t *drawpixels_src = (uint8_t *)src; RegionPtr clip = fbGetCompositeClip(gc); BoxRec *pbox; @@ -46,18 +46,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, glamor_priv = glamor_get_screen_private(drawable->pScreen); - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { + glamor_fallback("ES2 fallback.\n"); goto fail; + } if (glamor_get_tex_format_type_from_pixmap(dest_pixmap, &format, &type, - &no_alpha + &no_alpha, + &no_revert )) { glamor_fallback("unknown depth. %d \n", drawable->depth); goto fail; } + + if (glamor_set_destination_pixmap(dest_pixmap)) goto fail; From 1f129c491bfc825465c3bc0e9b745b7f66dea720 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 16 Aug 2011 00:32:57 +0800 Subject: [PATCH 189/225] glamor: Convert pixmap to supported format before getspans. Signed-off-by: Zhigang Gong --- glamor/glamor_getspans.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index e1a20baef..ba409dc23 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -41,9 +41,10 @@ glamor_get_spans(DrawablePtr drawable, { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); GLenum format, type; - int no_alpha; + int no_alpha, no_revert; glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + PixmapPtr temp_pixmap = NULL; int i; uint8_t *readpixels_dst = (uint8_t *)dst; int x_off, y_off; @@ -56,7 +57,8 @@ glamor_get_spans(DrawablePtr drawable, if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, - &no_alpha + &no_alpha, + &no_revert )) { glamor_fallback("unknown depth. %d \n", drawable->depth); @@ -65,7 +67,15 @@ glamor_get_spans(DrawablePtr drawable, glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_validate_pixmap(pixmap); - + + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { + /* XXX prepare whole pixmap is not efficient. */ + temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format, + &type, no_alpha, no_revert); + pixmap_priv = glamor_get_pixmap_private(temp_pixmap); + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + } + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); for (i = 0; i < count; i++) { if (glamor_priv->yInverted) { @@ -85,6 +95,8 @@ glamor_get_spans(DrawablePtr drawable, } readpixels_dst += PixmapBytePad(widths[i], drawable->depth); } + if (temp_pixmap) + pixmap->drawable.pScreen->DestroyPixmap(temp_pixmap); return; fail: From 1658454dea4330144ebc0b02e1b42feed6db4f41 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 16 Aug 2011 00:33:35 +0800 Subject: [PATCH 190/225] glamor: Fix the copy of overlaped region in one pixmap. Originaly, we use fbo blit to handle overlaped region copy. But GLES2 doesn't support that, just simply copy the needed region to another texture can fix this problem. Signed-off-by: Zhigang Gong --- glamor/glamor_copyarea.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 1e160acb6..3e6e6b9fc 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -124,7 +124,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src, BoxPtr box, int nbox, int dx, - int dy) + int dy + ) { glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pScreen); @@ -193,7 +194,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); +#ifndef GLAMOR_GLES2 glEnable(GL_TEXTURE_2D); +#endif glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -202,6 +205,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src, texcoords); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glUseProgram(glamor_priv->finish_access_prog[0]); + glUniform1i(glamor_priv->finish_access_no_revert[0], 1); + glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); } else { @@ -231,7 +236,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glDisableVertexAttribArray(GLAMOR_VERTEX_POS); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); +#ifndef GLAMOR_GLES2 glDisable(GL_TEXTURE_2D); +#endif } glUseProgram(0); /* The source texture is bound to a fbo, we have to flush it here. */ @@ -308,23 +315,29 @@ glamor_copy_n_to_n(DrawablePtr src, #endif glamor_calculate_boxes_bound(&bound, box, nbox); - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) + /* Overlaped indicate the src and dst are the same pixmap. */ + if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) && ((bound.x2 - bound.x1) * (bound.y2 - bound.y1) - * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height)) { + * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height))) { temp_pixmap = (*screen->CreatePixmap)(screen, bound.x2 - bound.x1, bound.y2 - bound.y1, src_pixmap->drawable.depth, - GLAMOR_CREATE_PIXMAP_CPU); + overlaped ? 0 : GLAMOR_CREATE_PIXMAP_CPU); if (!temp_pixmap) goto fail; glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1); temp_src = &temp_pixmap->drawable; - fbCopyNtoN(src, temp_src, gc, box, nbox, - temp_dx + bound.x1, temp_dy + bound.y1, - reverse, upsidedown, bitplane, - closure); + + if (overlaped) + glamor_copy_n_to_n_textured(src, temp_src, gc, box, nbox, + temp_dx + bound.x1, temp_dy + bound.y1); + else + fbCopyNtoN(src, temp_src, gc, box, nbox, + temp_dx + bound.x1, temp_dy + bound.y1, + reverse, upsidedown, bitplane, + closure); glamor_transform_boxes(box, nbox, bound.x1, bound.y1); temp_dx = -bound.x1; temp_dy = -bound.y1; From eaa07998c432f68485423c4d108220ce1d72e7b6 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 16 Aug 2011 14:05:25 +0800 Subject: [PATCH 191/225] glamor: Add device independent glamor to the installation package. Other ddx driver may link libglamor_dix to utilize glamor. Signed-off-by: Zhigang Gong --- configure.ac | 10 +++++++++- glamor/Makefile.am | 12 +++++++++--- hw/xfree86/dixmods/Makefile.am | 8 +++++++- hw/xfree86/glamor/Makefile.am | 10 +++------- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 69b1ac3c5..d67e7cb10 100644 --- a/configure.ac +++ b/configure.ac @@ -801,7 +801,8 @@ LIBUDEV="libudev >= 143" LIBSELINUX="libselinux >= 2.0.86" LIBDBUS="dbus-1 >= 1.0" LIBPIXMAN="pixman-1 >= 0.21.8" - +LIBEGL="egl >= 7.12.0" +LIBGLESV2="glesv2 >= 7.11.0" dnl Pixman is always required, but we separate it out so we can link dnl specific modules against it PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN) @@ -1779,14 +1780,21 @@ GLAMOR=yes if test "x$GLAMOR" = xyes; then AC_DEFINE(GLAMOR,1,[Build Glamor]) + if test "x$GLAMOR_GLES2" = xyes; then AC_DEFINE(GLAMOR_GLES2,1,[Build glamor over GLES2]) + PKG_CHECK_MODULES(GLESV2, $LIBGLESV2) + REQUIRED_LIBS="$REQUIRED_LIBS $LIBGLESV2" else AC_DEFINE(GLAMOR_GL,1,[Build glamor over GL]) + PKG_CHECK_MODULES(GL, $LIBGL) + REQUIRED_LIBS="$REQUIRED_LIBS $LIBGL" fi if test "x$GLAMOR_DDX" = xyes; then AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver]) + PKG_CHECK_MODULES(EGL, $LIBEGL) + REQUIRED_LIBS="$REQUIRED_LIBS $LIBEGL" fi fi diff --git a/glamor/Makefile.am b/glamor/Makefile.am index ec38ac4e8..fcde76503 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -9,13 +9,20 @@ sdk_HEADERS = glamor.h endif if GLAMOR_GLES2 -GLAMOR_GLES2_CFLAGS = -DGLAMOR_GLES2 +libglamor_la_LIBADD = $(GLESV2_LIBS) +else +libglamor_la_LIBADD = $(GL_LIBS) +endif + +if XORG +sdk_HEADERS = glamor.h endif INCLUDES = \ $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS) $(LIBDRM_CFLAGS) + +AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ @@ -37,4 +44,3 @@ libglamor_la_SOURCES = \ glamor_picture.c\ glamor_window.c\ glamor.h - diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am index 1a162ab1c..6dc63ceb7 100644 --- a/hw/xfree86/dixmods/Makefile.am +++ b/hw/xfree86/dixmods/Makefile.am @@ -16,7 +16,8 @@ endif module_LTLIBRARIES = libfb.la \ libwfb.la \ - libshadow.la + libshadow.la \ + libglamor_dix.la extsmoduledir = $(moduledir)/extensions extsmodule_LTLIBRARIES = $(RECORDMOD) \ @@ -34,6 +35,11 @@ libdbe_la_LDFLAGS = -avoid-version libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la libdbe_la_SOURCES = dbemodule.c +libglamor_dix_la_LDFLAGS = -avoid-version +libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la +libglamor_dix_la_SOURCES = +libglamor_dix_la_CFLAGS = $(AM_CFLAGS) + libfb_la_LDFLAGS = -avoid-version libfb_la_LIBADD = $(top_builddir)/fb/libfb.la libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index dcd44b2d8..8432645ca 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -13,15 +13,11 @@ glamor_la_CFLAGS = \ if GLAMOR_GLES2 glamor_la_CFLAGS+=-DGLAMOR_GLES2 -GLAMOR_GL_LIB = -lGLESv2 -else -GLAMOR_GL_LIB = -lGL endif -glamor_la_LDFLAGS = \ - -module -avoid-version -L$(libdir) -lEGL \ - $(top_builddir)/glamor/libglamor.la \ - -L$(libdir)/../lib64 $(GLAMOR_GL_LIB) +glamor_la_LDFLAGS = -module -avoid-version \ + $(top_builddir)/glamor/libglamor.la \ + $(EGL_LIBS) glamor_ladir = $(moduledir)/drivers glamor_la_SOURCES = \ From 3648e35b5d0ffcb2ea5d40c842a7f8dd39b27b50 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 19 Aug 2011 10:53:44 +0800 Subject: [PATCH 192/225] glamor-ddx: Add code to check required egl extensions. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 317342b13..3ac003dc2 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -304,6 +304,31 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen) return TRUE; } + + +static Bool +glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension) +{ + const char *egl_extensions; + char *pext; + int ext_len; + ext_len = strlen(extension); + + egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS); + pext = (char*)egl_extensions; + + if (pext == NULL || extension == NULL) + return FALSE; + while((pext = strstr(pext, extension)) != NULL) { + if (pext[ext_len] == ' ' || pext[ext_len] == '\0') + return TRUE; + pext += ext_len; + } + return FALSE; +} + + + static Bool glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) { @@ -353,6 +378,20 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) version = eglQueryString(glamor->display, EGL_VERSION); xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); +#define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ + if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) { \ + ErrorF("EGL_" #EXT "required.\n"); \ + return FALSE; \ + } + + GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image); + GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image); +#ifdef GLAMOR_GLES2 + GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2); +#else + GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl); +#endif + glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA"); glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA"); From 52cce9333fed2035da9623f338428a5d220b577d Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 19 Aug 2011 11:05:21 +0800 Subject: [PATCH 193/225] glamor: egl version 7.11 should be ok for us. Signed-off-by: Zhigang Gong --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d67e7cb10..25e9dd362 100644 --- a/configure.ac +++ b/configure.ac @@ -801,7 +801,7 @@ LIBUDEV="libudev >= 143" LIBSELINUX="libselinux >= 2.0.86" LIBDBUS="dbus-1 >= 1.0" LIBPIXMAN="pixman-1 >= 0.21.8" -LIBEGL="egl >= 7.12.0" +LIBEGL="egl >= 7.11.0" LIBGLESV2="glesv2 >= 7.11.0" dnl Pixman is always required, but we separate it out so we can link dnl specific modules against it From ef3ea0f46bf1b688249cd37d54cfa67ec55041b0 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 19 Aug 2011 11:06:56 +0800 Subject: [PATCH 194/225] glamor: Don't need to check status when set the target. As we already checked the status when create the fbo. Signed-off-by: Zhigang Gong --- glamor/glamor_pixmap.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 1e17069f1..15fc01448 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -83,9 +83,7 @@ glamor_validate_pixmap(PixmapPtr pixmap) void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) { -// glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); - - glamor_pixmap_ensure_fb(pixmap_priv->container); + glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); #ifndef GLAMOR_GLES2 glMatrixMode(GL_PROJECTION); glLoadIdentity(); From 65812b538f23bfccc32a7bbc0b2c4e93e1cd8fe8 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 23 Aug 2011 10:31:50 +0800 Subject: [PATCH 195/225] glamor-dix: Make a glamor dix module. And modify the header file to export three APIs to the ddx driver. Signed-off-by: Zhigang Gong --- configure.ac | 6 ++-- glamor/glamor.h | 6 ++-- hw/xfree86/dixmods/Makefile.am | 12 +++++--- hw/xfree86/dixmods/glamor_module.c | 47 ++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 hw/xfree86/dixmods/glamor_module.c diff --git a/configure.ac b/configure.ac index 25e9dd362..2a1c7869d 100644 --- a/configure.ac +++ b/configure.ac @@ -646,7 +646,7 @@ AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest serv AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto]) AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no]) AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto]) -#AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor server (default: no)]), [GLAMOR=$enableval], [GLAMOR=no]) +AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: no)]), [GLAMOR=$enableval], [GLAMOR=no]) AC_ARG_ENABLE(glamor-ddx, AS_HELP_STRING([--enable-glamor-ddx], [Build glamor ddx (default: no)]), [GLAMOR_DDX=$enableval], [GLAMOR_DDX=no]) dnl kdrive and its subsystems AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no]) @@ -1772,12 +1772,10 @@ AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) dnl glamor -AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes]) +AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes || test "x$GLAMOR" = xyes]) AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes]) AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes]) -GLAMOR=yes - if test "x$GLAMOR" = xyes; then AC_DEFINE(GLAMOR,1,[Build Glamor]) diff --git a/glamor/glamor.h b/glamor/glamor.h index 2c1b241ba..25f4506d2 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -43,6 +43,6 @@ #define GLAMOR_HOSTX 2 #define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX) -Bool glamor_init(ScreenPtr screen, unsigned int flags); -void glamor_fini(ScreenPtr screen); -void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); +extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); +extern _X_EXPORT void glamor_fini(ScreenPtr screen); +extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am index 6dc63ceb7..84c909b9c 100644 --- a/hw/xfree86/dixmods/Makefile.am +++ b/hw/xfree86/dixmods/Makefile.am @@ -14,10 +14,14 @@ if RECORD RECORDMOD = librecord.la endif +if GLAMOR +LIBGLAMOR_DIX = libglamor_dix.la +endif + module_LTLIBRARIES = libfb.la \ libwfb.la \ libshadow.la \ - libglamor_dix.la + $(LIBGLAMOR_DIX) extsmoduledir = $(moduledir)/extensions extsmodule_LTLIBRARIES = $(RECORDMOD) \ @@ -34,12 +38,12 @@ INCLUDES = @XORG_INCS@ \ libdbe_la_LDFLAGS = -avoid-version libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la libdbe_la_SOURCES = dbemodule.c - +if GLAMOR libglamor_dix_la_LDFLAGS = -avoid-version libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la -libglamor_dix_la_SOURCES = +libglamor_dix_la_SOURCES = glamor_module.c libglamor_dix_la_CFLAGS = $(AM_CFLAGS) - +endif libfb_la_LDFLAGS = -avoid-version libfb_la_LIBADD = $(top_builddir)/fb/libfb.la libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c diff --git a/hw/xfree86/dixmods/glamor_module.c b/hw/xfree86/dixmods/glamor_module.c new file mode 100644 index 000000000..ee2dba871 --- /dev/null +++ b/hw/xfree86/dixmods/glamor_module.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 1998 The XFree86 Project, Inc. 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 THE + * XFREE86 PROJECT 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. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include "xf86Module.h" + +static XF86ModuleVersionInfo VersRec = +{ + "glamor_dix", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_ANSIC, /* Only need the ansic layer */ + ABI_ANSIC_VERSION, + MOD_CLASS_NONE, + {0,0,0,0} /* signature, to be patched into the file by a tool */ +}; + +_X_EXPORT XF86ModuleData glamor_dixModuleData = { &VersRec, NULL, NULL }; From bd0ea43f3999e29ae5953ca5257b1795916dd5e7 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 23 Aug 2011 13:27:48 +0800 Subject: [PATCH 196/225] glamor: Change to use the original drawable in glamor_fill. As glamor_fill may fallback to software rasterization, we'd better to use the original drawable as input paramter. Signed-off-by: Zhigang Gong --- glamor/glamor_fill.c | 19 +++++++++++-------- glamor/glamor_fillspans.c | 6 +----- glamor/glamor_polyfillrect.c | 7 ++----- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 873f383a5..cbd2b59f6 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -41,12 +41,15 @@ glamor_fill(DrawablePtr drawable, int height) { PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); + int off_x, off_y; + + glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y); switch (gc->fillStyle) { case FillSolid: if (!glamor_solid(dst_pixmap, - x, - y, + x + off_x, + y + off_y, width, height, gc->alu, @@ -58,8 +61,8 @@ glamor_fill(DrawablePtr drawable, case FillOpaqueStippled: if (!glamor_stipple(dst_pixmap, gc->stipple, - x, - y, + x + off_x, + y + off_y, width, height, gc->alu, @@ -74,14 +77,14 @@ glamor_fill(DrawablePtr drawable, case FillTiled: if (!glamor_tile(dst_pixmap, gc->tile.pixmap, - x, - y, + x + off_x, + y + off_y, width, height, gc->alu, gc->planemask, - drawable->x + x - gc->patOrg.x, - drawable->y + y - gc->patOrg.y)) + drawable->x + x + off_x - gc->patOrg.x, + drawable->y + y + off_y - gc->patOrg.y)) goto fail; break; } diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index b1f79a9d8..9a97da250 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -42,15 +42,11 @@ glamor_fill_spans(DrawablePtr drawable, int nbox; BoxPtr pbox; int x1, x2, y; - int off_x, off_y; RegionPtr pClip = fbGetCompositeClip(gc); - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) goto fail; - glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); ppt = points; while (n--) { x1 = ppt->x; @@ -74,7 +70,7 @@ glamor_fill_spans(DrawablePtr drawable, if (x2 <= x1) continue; glamor_fill (drawable,gc, - x1 + off_x, y + off_y, + x1, y, x2 - x1 , 1); pbox++; } diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index 218c308dd..3cc4b527d 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -47,16 +47,13 @@ glamor_poly_fill_rect(DrawablePtr drawable, int xorg, yorg; int n; register BoxPtr pbox; - int off_x, off_y; RegionPtr pClip = fbGetCompositeClip(gc); - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) { goto fail; } xorg = drawable->x; yorg = drawable->y; - glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); while (nrect--) { fullX1 = prect->x + xorg; @@ -92,8 +89,8 @@ glamor_poly_fill_rect(DrawablePtr drawable, continue; glamor_fill(drawable, gc, - x1 + off_x, - y1 + off_y, + x1, + y1, x2 - x1, y2 - y1); } From b4f265c7f9bcb7824df19ea915ab32fe84d9ec53 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 23 Aug 2011 13:30:54 +0800 Subject: [PATCH 197/225] glamor: Fallback to software fb when repeat is needed. Need to be fixed latter. We should not need any fallback here. But currently, the implementation for repeating tiling is broken. Signed-off-by: Zhigang Gong --- glamor/glamor_tile.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 25ad63583..8fe4b3891 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -98,10 +98,14 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv; - src_pixmap_priv = glamor_get_pixmap_private(tile); dst_pixmap_priv = glamor_get_pixmap_private(pixmap); + if (((tile_x != 0) && (tile_x + width > tile->drawable.width)) + || ((tile_y != 0) && (tile_y + height > tile->drawable.height))) { + ErrorF("tile_x = %d tile_y = %d \n", tile_x, tile_y); + goto fail; + } if (glamor_priv->tile_prog == 0) { glamor_fallback("Tiling unsupported\n"); goto fail; From 54c91079d2bd21d3fd97b6d5fa3ba5c4a86b6337 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 23 Aug 2011 14:04:07 +0800 Subject: [PATCH 198/225] glamor-gles2: Add explicit precision qualifiers for gles2. Signed-off-by: Zhigang Gong --- glamor/glamor_core.c | 10 ++++++---- glamor/glamor_fill.c | 1 + glamor/glamor_priv.h | 7 ++++++- glamor/glamor_render.c | 10 ++++++++++ glamor/glamor_tile.c | 1 + 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index d4588e28a..3609600bc 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -151,10 +151,11 @@ glamor_init_finish_access_shaders(ScreenPtr screen) "}\n"; const char *fs_source = + GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" "uniform sampler2D sampler;\n" - "uniform int no_revert;" - "uniform int swap_rb;" + "uniform int no_revert;\n" + "uniform int swap_rb;\n" "void main()\n" "{\n" " if (no_revert == 1) \n" @@ -174,10 +175,11 @@ glamor_init_finish_access_shaders(ScreenPtr screen) "}\n"; const char *set_alpha_source = + GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" "uniform sampler2D sampler;\n" - "uniform int no_revert;" - "uniform int swap_rb;" + "uniform int no_revert;\n" + "uniform int swap_rb;\n" "void main()\n" "{\n" " if (no_revert == 1) \n" diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index cbd2b59f6..0b3d5fddf 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -112,6 +112,7 @@ glamor_init_solid_shader(ScreenPtr screen) " gl_Position = v_position;\n" "}\n"; const char *solid_fs = + GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n" "void main()\n" "{\n" diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 1f3e8c464..4feb0048e 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -36,7 +36,6 @@ #include "glamor.h" #ifdef GLAMOR_GLES2 - #define GL_BGRA GL_BGRA_EXT #define GL_COLOR_INDEX 0x1900 #define GL_BITMAP 0x1A00 @@ -77,9 +76,15 @@ #ifdef GLAMOR_GLES2 #include #include + +#define GLAMOR_DEFAULT_PRECISION \ + "precision mediump float;\n" + #else #include #include + +#define GLAMOR_DEFAULT_PRECISION #endif diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index cec6c8d25..bc6347883 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -71,12 +71,14 @@ static GLuint glamor_create_composite_fs(struct shader_key *key) { const char *source_solid_fetch = + GLAMOR_DEFAULT_PRECISION "uniform vec4 source;\n" "vec4 get_source()\n" "{\n" " return source;\n" "}\n"; const char *source_alpha_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "vec4 get_source()\n" @@ -84,6 +86,7 @@ glamor_create_composite_fs(struct shader_key *key) " return texture2D(source_sampler, source_texture);\n" "}\n"; const char *source_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" "vec4 get_source()\n" @@ -91,12 +94,14 @@ glamor_create_composite_fs(struct shader_key *key) " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n" "}\n"; const char *mask_solid_fetch = + GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n" "vec4 get_mask()\n" "{\n" " return mask;\n" "}\n"; const char *mask_alpha_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" @@ -104,6 +109,7 @@ glamor_create_composite_fs(struct shader_key *key) " return texture2D(mask_sampler, mask_texture);\n" "}\n"; const char *mask_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" @@ -111,21 +117,25 @@ glamor_create_composite_fs(struct shader_key *key) " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n" "}\n"; const char *in_source_only = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" " gl_FragColor = get_source();\n" "}\n"; const char *in_normal = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" " gl_FragColor = get_source() * get_mask().a;\n" "}\n"; const char *in_ca_source = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" " gl_FragColor = get_source() * get_mask();\n" "}\n"; const char *in_ca_alpha = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" " gl_FragColor = get_source().a * get_mask();\n" diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 8fe4b3891..c184dac26 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -50,6 +50,7 @@ glamor_init_tile_shader(ScreenPtr screen) " tile_texture = v_texcoord0.xy;\n" "}\n"; const char *tile_fs = + GLAMOR_DEFAULT_PRECISION "varying vec2 tile_texture;\n" "uniform sampler2D sampler;\n" "void main()\n" From 3854409e9ad25418c6188f491410bb05eaf92fc6 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Mon, 22 Aug 2011 23:27:24 -0700 Subject: [PATCH 199/225] glamor: Fix direct call for glEGLImageTargetTexture2DOES Follow extension call rule to call glEGLImageTargetTexture2DOES. --- hw/xfree86/glamor/glamor.c | 40 ++++----------------------------- hw/xfree86/glamor/glamor_crtc.c | 3 ++- hw/xfree86/glamor/glamor_ddx.h | 37 ++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 3ac003dc2..109477bad 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -35,19 +35,6 @@ #include #include -#define GL_GLEXT_PROTOTYPES -#define EGL_EGLEXT_PROTOTYPES -#define EGL_DISPLAY_NO_X_MESA - -#if GLAMOR_GLES2 -#include -#else -#include -#endif - -#define MESA_EGL_NO_X11_HEADERS -#include -#include #include "../../../mi/micmap.h" #include @@ -70,27 +57,6 @@ glamor_identify(int flags) xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver\n", glamor_name); } -struct glamor_screen_private { - EGLDisplay display; - EGLContext context; - EGLImageKHR root; - EGLint major, minor; - - CreateScreenResourcesProcPtr CreateScreenResources; - CloseScreenProcPtr CloseScreen; - int fd; - int cpp; - - PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; - PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; - -}; - -static inline struct glamor_screen_private * -glamor_get_screen_private(ScrnInfoPtr scrn) -{ - return (struct glamor_screen_private *) (scrn->driverPrivate); -} Bool glamor_resize(ScrnInfoPtr scrn, int width, int height) @@ -122,7 +88,7 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); glamor_set_screen_pixmap_texture(screen, width, height, texture); glamor->root = image; @@ -394,8 +360,10 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA"); glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA"); + glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); - if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa) { + if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa || + !glamor->egl_image_target_texture2d_oes) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglGetProcAddress() failed\n"); return FALSE; diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 959201397..ef6ee2946 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -478,6 +478,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; ScrnInfoPtr scrn = crtc->scrn; + struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); if (drmmode_crtc->cursor == NULL) { @@ -490,7 +491,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor); + (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, drmmode_crtc->cursor); } glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); #ifdef GLAMOR_GLES2 diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index 0e164d3b7..6d9e410f0 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -1,6 +1,43 @@ #ifndef GLAMOR_DDX_H #define GLAMOR_DDX_H +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#define EGL_DISPLAY_NO_X_MESA + +#if GLAMOR_GLES2 +#include +#include +#else +#include +#endif + +#define MESA_EGL_NO_X11_HEADERS +#include +#include + +struct glamor_screen_private { + EGLDisplay display; + EGLContext context; + EGLImageKHR root; + EGLint major, minor; + + CreateScreenResourcesProcPtr CreateScreenResources; + CloseScreenProcPtr CloseScreen; + int fd; + int cpp; + + PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; + PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; +}; + +inline struct glamor_screen_private * +glamor_get_screen_private(ScrnInfoPtr scrn) +{ + return (struct glamor_screen_private *) (scrn->driverPrivate); +} + Bool glamor_resize(ScrnInfoPtr scrn, int width, int height); void glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch); From 60f14d60f6169272951d41d8ca9e0a294c2ca3d0 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 24 Aug 2011 16:54:32 +0800 Subject: [PATCH 200/225] glamor-egl: Move EGL surfaceless related code to dix module. The functions in glamor_egl.c could be shared by any egl back end drivers. Signed-off-by: Zhigang Gong --- glamor/glamor.h | 8 + glamor/glamor_egl.c | 296 +++++++++++++++++++++++++++++++++ hw/xfree86/dixmods/Makefile.am | 5 +- 3 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 glamor/glamor_egl.c diff --git a/glamor/glamor.h b/glamor/glamor.h index 25f4506d2..ef13b7a66 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -43,6 +43,14 @@ #define GLAMOR_HOSTX 2 #define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX) +#define GLAMOR_EGL_EXTERNAL_BUFFER 3 + extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT void glamor_fini(ScreenPtr screen); extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); + +extern _X_EXPORT Bool glamor_egl_init(ScreenPtr screen, int fd); +extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride); +extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen); +extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags); + diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c new file mode 100644 index 000000000..a92993b7a --- /dev/null +++ b/glamor/glamor_egl.c @@ -0,0 +1,296 @@ +/* + * Copyright © 2010 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 HAVE_DIX_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#define EGL_DISPLAY_NO_X_MESA + +#if GLAMOR_GLES2 +#include +#else +#include +#endif + +#define MESA_EGL_NO_X11_HEADERS +#include +#include + +#include + +#define GLAMOR_VERSION_MAJOR 0 +#define GLAMOR_VERSION_MINOR 1 +#define GLAMOR_VERSION_PATCH 0 + +static const char glamor_name[] = "glamor"; + +static void +glamor_identify(int flags) +{ + xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n", glamor_name); +} + +struct glamor_screen_private { + EGLDisplay display; + EGLContext context; + EGLImageKHR root; + EGLint major, minor; + + + CreateScreenResourcesProcPtr CreateScreenResources; + CloseScreenProcPtr CloseScreen; + int fd; + int front_buffer_handle; + int cpp; + + PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; + PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; + PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; + +}; + +int xf86GlamorEGLPrivateIndex = -1; + +static struct glamor_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn) +{ + return (struct glamor_screen_private *) scrn->privates[xf86GlamorEGLPrivateIndex].ptr; +} + +static Bool +_glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int stride) +{ + + struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + EGLImageKHR image; + GLuint texture; + EGLint attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_STRIDE_MESA, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA | + EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + + if (glamor->root) { + eglDestroyImageKHR(glamor->display, glamor->root); + glamor->root = EGL_NO_IMAGE_KHR; + } + + attribs[1] = width; + attribs[3] = height; + attribs[5] = stride / 4; + image = glamor->egl_create_image_khr (glamor->display, + glamor->context, + EGL_DRM_BUFFER_MESA, + (void*)glamor->front_buffer_handle, + attribs); + if (image == EGL_NO_IMAGE_KHR) + return FALSE; + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + + glamor_set_screen_pixmap_texture(screen, width, height, texture); + glamor->root = image; + return TRUE; +} + +Bool +glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); + struct drm_gem_flink flink; + flink.handle = handle; + + if (ioctl(glamor->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Couldn't flink front buffer handle\n"); + return FALSE; + } + + glamor->front_buffer_handle = flink.name; + + return _glamor_create_egl_screen_image(scrn, scrn->virtualX, scrn->virtualY, stride); +} + +Bool +glamor_close_egl_screen(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); + glamor_fini(screen); + + eglDestroyImageKHR(glamor->display, glamor->root); + + + glamor->root = EGL_NO_IMAGE_KHR; + + return TRUE; +} + + + +static Bool +glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension) +{ + const char *egl_extensions; + char *pext; + int ext_len; + ext_len = strlen(extension); + + egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS); + pext = (char*)egl_extensions; + + if (pext == NULL || extension == NULL) + return FALSE; + while((pext = strstr(pext, extension)) != NULL) { + if (pext[ext_len] == ' ' || pext[ext_len] == '\0') + return TRUE; + pext += ext_len; + } + return FALSE; +} + + +Bool glamor_egl_init(ScreenPtr screen, int fd) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_screen_private *glamor; + const char *version; + EGLint config_attribs[] = { +#ifdef GLAMOR_GLES2 + EGL_CONTEXT_CLIENT_VERSION, 2, +#endif + EGL_NONE + }; + + glamor_identify(0); + glamor = calloc(sizeof(*glamor), 1); + if (xf86GlamorEGLPrivateIndex == -1) + xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); + + scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor; + + glamor->fd = fd; + glamor->display = eglGetDRMDisplayMESA(glamor->fd); +#ifndef GLAMOR_GLES2 + eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif + if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "eglInitialize() failed\n"); + return FALSE; + } + + version = eglQueryString(glamor->display, EGL_VERSION); + xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); + +#define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ + if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) { \ + ErrorF("EGL_" #EXT "required.\n"); \ + return FALSE; \ + } + + GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image); + GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image); +#ifdef GLAMOR_GLES2 + GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2); +#else + GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl); +#endif + + glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA) + eglGetProcAddress("eglExportDRMImageMESA"); + glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) + eglGetProcAddress("eglCreateImageKHR"); + + if (!glamor->egl_create_image_khr + || !glamor->egl_export_drm_image_mesa) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "eglGetProcAddress() failed\n"); + return FALSE; + } + + glamor->context = eglCreateContext(glamor->display, + NULL, EGL_NO_CONTEXT, config_attribs); + if (glamor->context == EGL_NO_CONTEXT) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to create EGL context\n"); + return FALSE; + } + + if (!eglMakeCurrent(glamor->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to make EGL context current\n"); + return FALSE; + } + + if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to initialize glamor\n"); + return FALSE; + } + return TRUE; +} + +void +glamor_free_egl_screen(int scrnIndex, int flags) +{ + ScrnInfoPtr scrn = xf86Screens[scrnIndex]; + struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); + + if (glamor != NULL) + { + if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) { + eglMakeCurrent(glamor->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + eglTerminate(glamor->display); + } + free(glamor); + } +} diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am index 84c909b9c..ba4aeb402 100644 --- a/hw/xfree86/dixmods/Makefile.am +++ b/hw/xfree86/dixmods/Makefile.am @@ -34,6 +34,7 @@ INCLUDES = @XORG_INCS@ \ -I$(top_srcdir)/hw/xfree86/loader \ -I$(top_srcdir)/miext/shadow \ -I$(top_srcdir)/glx + libdbe_la_LDFLAGS = -avoid-version libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la @@ -41,8 +42,8 @@ libdbe_la_SOURCES = dbemodule.c if GLAMOR libglamor_dix_la_LDFLAGS = -avoid-version libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la -libglamor_dix_la_SOURCES = glamor_module.c -libglamor_dix_la_CFLAGS = $(AM_CFLAGS) +libglamor_dix_la_SOURCES = glamor_module.c $(top_srcdir)/glamor/glamor_egl.c +libglamor_dix_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/glamor $(LIBDRM_CFLAGS) endif libfb_la_LDFLAGS = -avoid-version libfb_la_LIBADD = $(top_builddir)/fb/libfb.la From 6cb4abca697c24bdc644502cce8a2ca9bbf131e3 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 24 Aug 2011 17:13:35 +0800 Subject: [PATCH 201/225] glamor: Remove the version check for EGL/gles. As PVR's gles2 has different version number from mesa's, just simply remove the version check here to let both platform could build it. Signed-off-by: Zhigang Gong --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 2a1c7869d..82c845ba7 100644 --- a/configure.ac +++ b/configure.ac @@ -801,8 +801,8 @@ LIBUDEV="libudev >= 143" LIBSELINUX="libselinux >= 2.0.86" LIBDBUS="dbus-1 >= 1.0" LIBPIXMAN="pixman-1 >= 0.21.8" -LIBEGL="egl >= 7.11.0" -LIBGLESV2="glesv2 >= 7.11.0" +LIBEGL="egl" +LIBGLESV2="glesv2" dnl Pixman is always required, but we separate it out so we can link dnl specific modules against it PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN) From d4f4d1272e1745752840eb7e8ec04eb155ac38d1 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 24 Aug 2011 17:17:48 +0800 Subject: [PATCH 202/225] glamor-egl: Fix direct call for glEGLImageTargetTexture2DOES. Signed-off-by: Zhigang Gong --- glamor/glamor_egl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index a92993b7a..7848c51ef 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -42,6 +42,7 @@ #if GLAMOR_GLES2 #include +#include #else #include #endif @@ -80,7 +81,7 @@ struct glamor_screen_private { PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; - + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; }; int xf86GlamorEGLPrivateIndex = -1; @@ -128,7 +129,8 @@ _glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int str glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + + (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); glamor_set_screen_pixmap_texture(screen, width, height, texture); glamor->root = image; @@ -247,8 +249,12 @@ Bool glamor_egl_init(ScreenPtr screen, int fd) glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); + glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) + eglGetProcAddress("glEGLImageTargetTexture2DOES"); + if (!glamor->egl_create_image_khr - || !glamor->egl_export_drm_image_mesa) { + || !glamor->egl_export_drm_image_mesa + || !glamor->egl_image_target_texture2d_oes) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglGetProcAddress() failed\n"); return FALSE; From ae38bd7c459982d3e05f6f672ee68d187e97421c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 25 Aug 2011 10:05:11 +0800 Subject: [PATCH 203/225] glamor: Change glamor_egl_init API. Slightly change the API glamor_egl_init, as this initialization is to initialize the display not the screen, we should call it in xxx_preinit rather than xxxScreenInit(). we change the input parameter as below, as in preInit, the screen may not be allocated at all. And in glamor_egl_init, it will not call glamor_init. Driver should call glamor_init at screen_init stage. Signed-off-by: Zhigang Gong --- glamor/glamor.h | 3 ++- glamor/glamor_egl.c | 8 +------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/glamor/glamor.h b/glamor/glamor.h index ef13b7a66..3c74c723e 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -29,6 +29,7 @@ #define GLAMOR_H #include "scrnintstr.h" +#include "xf86str.h" #include "pixmapstr.h" #include "windowstr.h" #include "gcstruct.h" @@ -49,7 +50,7 @@ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT void glamor_fini(ScreenPtr screen); extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); -extern _X_EXPORT Bool glamor_egl_init(ScreenPtr screen, int fd); +extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd); extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride); extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen); extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags); diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 7848c51ef..293e8dea9 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -195,9 +195,8 @@ glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension) } -Bool glamor_egl_init(ScreenPtr screen, int fd) +Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) { - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_screen_private *glamor; const char *version; EGLint config_attribs[] = { @@ -275,11 +274,6 @@ Bool glamor_egl_init(ScreenPtr screen, int fd) return FALSE; } - if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Failed to initialize glamor\n"); - return FALSE; - } return TRUE; } From bf4cbbd4e9c8ee104293a3c4eb202c880a139b73 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 30 Aug 2011 17:37:47 +0800 Subject: [PATCH 204/225] glamor: Move glamor_glyphs_init to create screen resources stage. As in glamor_glyphs_init, we may need to create pixmap. Thus it must be called after the pixmap resources allocation. Just move it to screen resource creation stage is good enough for mow. Also introduce a macro GLAMOR_FOR_XORG to glamor.h. As glamor may be used by Xephyr which doesn't don't have those xorg header files and also don't need the egl extension. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 1 - glamor/glamor.h | 6 +++++- glamor/glamor_egl.c | 2 ++ hw/kdrive/ephyr/ephyr.c | 8 ++++++-- hw/xfree86/glamor/glamor.c | 3 ++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index cd261ac8b..53fe71d49 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -364,7 +364,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_init_tile_shader(screen); glamor_init_putimage_shaders(screen); glamor_init_finish_access_shaders(screen); - glamor_glyphs_init(screen); glamor_pixmap_init(screen); #ifdef GLAMOR_GLES2 diff --git a/glamor/glamor.h b/glamor/glamor.h index 3c74c723e..7a0e89923 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -29,7 +29,9 @@ #define GLAMOR_H #include "scrnintstr.h" +#ifdef GLAMOR_FOR_XORG #include "xf86str.h" +#endif #include "pixmapstr.h" #include "windowstr.h" #include "gcstruct.h" @@ -49,9 +51,11 @@ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT void glamor_fini(ScreenPtr screen); extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); +extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen); +#ifdef GLAMOR_FOR_XORG extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd); extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride); extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen); extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags); - +#endif diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 293e8dea9..bdb2da711 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -51,6 +51,8 @@ #include #include +#define GLAMOR_FOR_XORG + #include #define GLAMOR_VERSION_MAJOR 0 diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 4bead1f36..e2cd7a49d 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -684,6 +684,7 @@ ephyrInitScreen (ScreenPtr pScreen) return TRUE; } + Bool ephyrFinishInitScreen (ScreenPtr pScreen) { @@ -700,6 +701,7 @@ ephyrFinishInitScreen (ScreenPtr pScreen) return TRUE; } +extern Bool ephyr_glamor; Bool ephyrCreateResources (ScreenPtr pScreen) @@ -710,14 +712,16 @@ ephyrCreateResources (ScreenPtr pScreen) EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d", pScreen, pScreen->myNum, scrpriv->shadow); - if (scrpriv->shadow) return KdShadowSet (pScreen, scrpriv->randr, ephyrShadowUpdate, ephyrWindowLinear); - else + else { + if (ephyr_glamor) + if (!glamor_glyphs_init(pScreen)) return FALSE; return ephyrSetInternalDamage(pScreen); + } } void diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 109477bad..9c9be894f 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -233,7 +233,8 @@ glamor_create_screen_resources_ddx(ScreenPtr screen) screen->CreateScreenResources = glamor->CreateScreenResources; if (!(*screen->CreateScreenResources) (screen)) return FALSE; - + if (!glamor_glyphs_init(screen)) + return FALSE; if (!xf86SetDesiredModes(scrn)) return FALSE; From 16659622708db82caaeb12527ba09545ad15b4c3 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 30 Aug 2011 17:45:07 +0800 Subject: [PATCH 205/225] glamor: Improve glyphs cache mechanism. This commit applying the latest uxa's glyphs cache mechanism and give up the old hash based cache algorithm. And the cache picture now is much larger than the previous one also. This new algorithm can avoid the hash insert/remove and also the expensive sha1 checking. It could obtain about 10% performance gain when rendering glyphs. Signed-off-by: Zhigang Gong --- glamor/glamor_glyphs.c | 1419 ++++++++++++++++++++-------------------- glamor/glamor_priv.h | 43 +- glamor/glamor_render.c | 8 +- 3 files changed, 714 insertions(+), 756 deletions(-) diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index 63ffd205c..af6ec71a1 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -60,13 +60,16 @@ * max texture size of the driver; this may need to actually come from * the driver. */ -#define CACHE_PICTURE_WIDTH 1024 /* Maximum number of glyphs we buffer on the stack before flushing * rendering to the mask or destination surface. */ -#define GLYPH_BUFFER_SIZE 256 +#define GLYPH_BUFFER_SIZE 1024 +#define CACHE_PICTURE_SIZE 1024 +#define GLYPH_MIN_SIZE 8 +#define GLYPH_MAX_SIZE 64 +#define GLYPH_CACHE_SIZE (CACHE_PICTURE_SIZE * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE)) typedef struct { PicturePtr source; @@ -74,76 +77,64 @@ typedef struct { int count; } glamor_glyph_buffer_t; +struct glamor_glyph +{ + glamor_glyph_cache_t *cache; + uint16_t x, y; + uint16_t size, pos; +}; + typedef enum { GLAMOR_GLYPH_SUCCESS, /* Glyph added to render buffer */ GLAMOR_GLYPH_FAIL, /* out of memory, etc */ GLAMOR_GLYPH_NEED_FLUSH, /* would evict a glyph already in the buffer */ } glamor_glyph_cache_result_t; -void glamor_glyphs_init(ScreenPtr screen) -{ - glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); - int i = 0; - memset(glamor_screen->glyph_caches, 0, sizeof(glamor_screen->glyph_caches)); - - glamor_screen->glyph_caches[i].format = PICT_a8; - glamor_screen->glyph_caches[i].glyph_width = - glamor_screen->glyph_caches[i].glyph_height = 16; - i++; - glamor_screen->glyph_caches[i].format = PICT_a8; - glamor_screen->glyph_caches[i].glyph_width = - glamor_screen->glyph_caches[i].glyph_height = 32; - i++; - glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8; - glamor_screen->glyph_caches[i].glyph_width = - glamor_screen->glyph_caches[i].glyph_height = 16; - i++; - glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8; - glamor_screen->glyph_caches[i].glyph_width = - glamor_screen->glyph_caches[i].glyph_height = 32; - i++; - - assert(i == GLAMOR_NUM_GLYPH_CACHES); - - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { - glamor_screen->glyph_caches[i].columns = - CACHE_PICTURE_WIDTH / glamor_screen->glyph_caches[i].glyph_width; - glamor_screen->glyph_caches[i].size = 256; - glamor_screen->glyph_caches[i].hash_size = 557; - } -} - -static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format) -{ - glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); - int i; - - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { - glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; - - if (cache->format != format) - continue; - - if (cache->picture) { - FreePicture((pointer) cache->picture, (XID) 0); - cache->picture = NULL; - } - - if (cache->hash_entries) { - free(cache->hash_entries); - cache->hash_entries = NULL; - } - - if (cache->glyphs) { - free(cache->glyphs); - cache->glyphs = NULL; - } - cache->glyph_count = 0; - } -} #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) +static DevPrivateKeyRec glamor_glyph_key; + +static inline struct glamor_glyph * +glamor_glyph_get_private (GlyphPtr glyph) +{ + return dixGetPrivate (&glyph->devPrivates, &glamor_glyph_key); +} + +static inline void +glamor_glyph_set_private (GlyphPtr glyph, struct glamor_glyph *priv) +{ + dixSetPrivate (&glyph->devPrivates, &glamor_glyph_key, priv); +} + + +static void +glamor_unrealize_glyph_caches (ScreenPtr pScreen) +{ + glamor_screen_private *glamor = glamor_get_screen_private (pScreen); + int i; + + if (!glamor->glyph_cache_initialized) + return; + + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) + { + glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; + + if (cache->picture) + FreePicture (cache->picture, 0); + + if (cache->glyphs) + free (cache->glyphs); + } + glamor->glyph_cache_initialized = FALSE; +} + +void +glamor_glyphs_fini (ScreenPtr pScreen) +{ + glamor_unrealize_glyph_caches (pScreen); +} /* All caches for a single format share a single pixmap for glyph storage, * allowing mixing glyphs of different sizes without paying a penalty @@ -154,512 +145,221 @@ static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format) * This function allocates the storage pixmap, and then fills in the * rest of the allocated structures for all caches with the given format. */ -static Bool glamor_realize_glyph_caches(ScreenPtr screen, unsigned int format) +static Bool +glamor_realize_glyph_caches (ScreenPtr pScreen) { - glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); - int depth = PIXMAN_FORMAT_DEPTH(format); - PictFormatPtr pict_format; - PixmapPtr pixmap; - PicturePtr picture; - CARD32 component_alpha; - int height; - int i; - int error; + glamor_screen_private *glamor = glamor_get_screen_private (pScreen); + unsigned int formats[] = { + PIXMAN_a8, + PIXMAN_a8r8g8b8, + }; + int i; - pict_format = PictureMatchFormat(screen, depth, format); - if (!pict_format) - return FALSE; - - /* Compute the total vertical size needed for the format */ - - height = 0; - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { - glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; - int rows; - - if (cache->format != format) - continue; - - cache->y_offset = height; - - rows = (cache->size + cache->columns - 1) / cache->columns; - height += rows * cache->glyph_height; - } - - /* Now allocate the pixmap and picture */ - - pixmap = screen->CreatePixmap(screen, - CACHE_PICTURE_WIDTH, - height, depth, - 0); - if (!pixmap) - return FALSE; - - component_alpha = NeedsComponent(pict_format->format); - picture = CreatePicture(0, &pixmap->drawable, pict_format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - - screen->DestroyPixmap(pixmap); /* picture holds a refcount */ - - if (!picture) - return FALSE; - - /* And store the picture in all the caches for the format */ - - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { - glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; - int j; - - if (cache->format != format) - continue; - - cache->picture = picture; - cache->picture->refcnt++; - cache->hash_entries = malloc(sizeof(int) * cache->hash_size); - cache->glyphs = - malloc(sizeof(glamor_cached_glyph_t) * cache->size); - cache->glyph_count = 0; - - if (!cache->hash_entries || !cache->glyphs) - goto bail; - - for (j = 0; j < cache->hash_size; j++) - cache->hash_entries[j] = -1; - - cache->eviction_position = rand() % cache->size; - } - - /* Each cache references the picture individually */ - FreePicture(picture, 0); + if (glamor->glyph_cache_initialized) return TRUE; - bail: - glamor_unrealize_glyph_caches(screen, format); + glamor->glyph_cache_initialized = TRUE; + memset (glamor->glyphCaches, 0, sizeof (glamor->glyphCaches)); + + for (i = 0; i < sizeof (formats) / sizeof (formats[0]); i++) + { + glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; + PixmapPtr pixmap; + PicturePtr picture; + CARD32 component_alpha; + int depth = PIXMAN_FORMAT_DEPTH (formats[i]); + int error; + PictFormatPtr pPictFormat = + PictureMatchFormat (pScreen, depth, formats[i]); + if (!pPictFormat) + goto bail; + + /* Now allocate the pixmap and picture */ + pixmap = pScreen->CreatePixmap (pScreen, + CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE, + depth, 0); + if (!pixmap) + goto bail; + + component_alpha = NeedsComponent (pPictFormat->format); + picture = CreatePicture (0, &pixmap->drawable, pPictFormat, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + pScreen->DestroyPixmap (pixmap); + if (!picture) + goto bail; + + ValidatePicture (picture); + + cache->picture = picture; + cache->glyphs = calloc (sizeof (GlyphPtr), GLYPH_CACHE_SIZE); + if (!cache->glyphs) + goto bail; + + cache->evict = rand () % GLYPH_CACHE_SIZE; + } + assert (i == GLAMOR_NUM_GLYPH_CACHE_FORMATS); + + return TRUE; + +bail: + glamor_unrealize_glyph_caches (pScreen); + return FALSE; +} + + +Bool +glamor_glyphs_init (ScreenPtr pScreen) +{ + if (!dixRegisterPrivateKey (&glamor_glyph_key, PRIVATE_GLYPH, 0)) return FALSE; + + /* Skip pixmap creation if we don't intend to use it. */ + + return glamor_realize_glyph_caches (pScreen); } -void glamor_glyphs_fini(ScreenPtr screen) -{ - glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); - int i; - - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { - glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; - - if (cache->picture) - glamor_unrealize_glyph_caches(screen, cache->format); - } -} - -static int -glamor_glyph_cache_hash_lookup(glamor_glyph_cache_t * cache, GlyphPtr glyph) -{ - int slot; - - slot = (*(CARD32 *) glyph->sha1) % cache->hash_size; - - while (TRUE) { /* hash table can never be full */ - int entryPos = cache->hash_entries[slot]; - if (entryPos == -1) - return -1; - - if (memcmp(glyph->sha1, cache->glyphs[entryPos].sha1, - sizeof(glyph->sha1)) == 0) { - return entryPos; - } - - slot--; - if (slot < 0) - slot = cache->hash_size - 1; - } -} - -static void -glamor_glyph_cache_hash_insert(glamor_glyph_cache_t * cache, GlyphPtr glyph, int pos) -{ - int slot; - - memcpy(cache->glyphs[pos].sha1, glyph->sha1, sizeof(glyph->sha1)); - - slot = (*(CARD32 *) glyph->sha1) % cache->hash_size; - - while (TRUE) { /* hash table can never be full */ - if (cache->hash_entries[slot] == -1) { - cache->hash_entries[slot] = pos; - return; - } - - slot--; - if (slot < 0) - slot = cache->hash_size - 1; - } -} - -static void glamor_glyph_cache_hash_remove(glamor_glyph_cache_t * cache, int pos) -{ - int slot; - int emptied_slot = -1; - - slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hash_size; - - while (TRUE) { /* hash table can never be full */ - int entryPos = cache->hash_entries[slot]; - - if (entryPos == -1) - return; - - if (entryPos == pos) { - cache->hash_entries[slot] = -1; - emptied_slot = slot; - } else if (emptied_slot != -1) { - /* See if we can move this entry into the emptied slot, - * we can't do that if if entry would have hashed - * between the current position and the emptied slot. - * (taking wrapping into account). Bad positions - * are: - * - * | XXXXXXXXXX | - * i j - * - * |XXX XXXX| - * j i - * - * i - slot, j - emptied_slot - * - * (Knuth 6.4R) - */ - - int entry_slot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % - cache->hash_size; - - if (!((entry_slot >= slot && entry_slot < emptied_slot) || - (emptied_slot < slot - && (entry_slot < emptied_slot - || entry_slot >= slot)))) { - cache->hash_entries[emptied_slot] = entryPos; - cache->hash_entries[slot] = -1; - emptied_slot = slot; - } - } - - slot--; - if (slot < 0) - slot = cache->hash_size - 1; - } -} - -#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyph_width) -#define CACHE_Y(pos) (cache->y_offset + ((pos) / cache->columns) * cache->glyph_height) - /* The most efficient thing to way to upload the glyph to the screen * is to use CopyArea; glamor pixmaps are always offscreen. */ -static Bool -glamor_glyph_cache_upload_glyph(ScreenPtr screen, - glamor_glyph_cache_t * cache, - int pos, GlyphPtr glyph) +static void +glamor_glyph_cache_upload_glyph (ScreenPtr screen, + glamor_glyph_cache_t * cache, + GlyphPtr glyph, int x, int y) { - PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum]; - PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable; - PixmapPtr cache_pixmap = (PixmapPtr) cache->picture->pDrawable; - PixmapPtr scratch; - GCPtr gc; + PicturePtr pGlyphPicture = GlyphPicture (glyph)[screen->myNum]; + PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable; + PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable; + PixmapPtr scratch; + GCPtr gc; - /* UploadToScreen only works if bpp match */ - if (glyph_pixmap->drawable.bitsPerPixel != - cache_pixmap->drawable.bitsPerPixel) - return FALSE; + gc = GetScratchGC (pCachePixmap->drawable.depth, screen); + if (!gc) + return; - gc = GetScratchGC(cache_pixmap->drawable.depth, screen); - ValidateGC(&cache_pixmap->drawable, gc); + ValidateGC (&pCachePixmap->drawable, gc); - /* Create a temporary bo to stream the updates to the cache */ + scratch = pGlyphPixmap; #if 0 - scratch = screen->CreatePixmap(screen, - glyph->info.width, - glyph->info.height, - glyph_pixmap->drawable.depth, - 0); - if (scratch) { - (void)glamor_copy_area(&glyph_pixmap->drawable, - &scratch->drawable, - gc, - 0, 0, - glyph->info.width, glyph->info.height, - 0, 0); - } else { - scratch = glyph_pixmap; - } -#endif - scratch = glyph_pixmap; - (void)glamor_copy_area(&scratch->drawable, - &cache_pixmap->drawable, - gc, - 0, 0, glyph->info.width, glyph->info.height, - CACHE_X(pos), CACHE_Y(pos)); + /* Create a temporary bo to stream the updates to the cache */ + if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth || + !uxa_pixmap_is_offscreen (scratch)) + { + scratch = screen->CreatePixmap (screen, + glyph->info.width, + glyph->info.height, + pCachePixmap->drawable.depth, 0); + if (scratch) + { + if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) + { + PicturePtr picture; + int error; - if (scratch != glyph_pixmap) - screen->DestroyPixmap(scratch); - - FreeScratchGC(gc); - - return TRUE; -} - -static glamor_glyph_cache_result_t -glamor_glyph_cache_buffer_glyph(ScreenPtr screen, - glamor_glyph_cache_t * cache, - glamor_glyph_buffer_t * buffer, - GlyphPtr glyph, int x_glyph, int y_glyph) -{ - glamor_composite_rect_t *rect; - int pos; - - if (buffer->source && buffer->source != cache->picture) - return GLAMOR_GLYPH_NEED_FLUSH; - - if (!cache->picture) { - if (!glamor_realize_glyph_caches(screen, cache->format)) - return GLAMOR_GLYPH_FAIL; - } - - DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n", - cache->glyph_width, cache->glyph_height, - cache->format == PICT_a8 ? "A" : "ARGB", - (long)*(CARD32 *) glyph->sha1)); - - pos = glamor_glyph_cache_hash_lookup(cache, glyph); - if (pos != -1) { - DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos)); - } else { - if (cache->glyph_count < cache->size) { - /* Space remaining; we fill from the start */ - pos = cache->glyph_count; - cache->glyph_count++; - DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos)); - - glamor_glyph_cache_hash_insert(cache, glyph, pos); - - } else { - /* Need to evict an entry. We have to see if any glyphs - * already in the output buffer were at this position in - * the cache - */ - - pos = cache->eviction_position; - DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos)); - if (buffer->count) { - int x, y; - int i; - - x = CACHE_X(pos); - y = CACHE_Y(pos); - - for (i = 0; i < buffer->count; i++) { - if (buffer->rects[i].x_src == x - && buffer->rects[i].y_src == y) { - DBG_GLYPH_CACHE((" must flush buffer\n")); - return GLAMOR_GLYPH_NEED_FLUSH; - } + picture = CreatePicture (0, &scratch->drawable, + PictureMatchFormat (screen, + pCachePixmap-> + drawable.depth, + cache->picture-> + format), 0, NULL, + serverClient, &error); + if (picture) + { + ValidatePicture (picture); + uxa_composite (PictOpSrc, pGlyphPicture, NULL, picture, + 0, 0, + 0, 0, + 0, 0, glyph->info.width, glyph->info.height); + FreePicture (picture, 0); } } - - /* OK, we're all set, swap in the new glyph */ - glamor_glyph_cache_hash_remove(cache, pos); - glamor_glyph_cache_hash_insert(cache, glyph, pos); - - /* And pick a new eviction position */ - cache->eviction_position = rand() % cache->size; - } - - /* Now actually upload the glyph into the cache picture; if - * we can't do it with UploadToScreen (because the glyph is - * offscreen, etc), we fall back to CompositePicture. - */ - if (!glamor_glyph_cache_upload_glyph(screen, cache, pos, glyph)) { - CompositePicture(PictOpSrc, - GlyphPicture(glyph)[screen->myNum], - None, - cache->picture, - 0, 0, - 0, 0, - CACHE_X(pos), - CACHE_Y(pos), - glyph->info.width, - glyph->info.height); - } - - } - - buffer->source = cache->picture; - - rect = &buffer->rects[buffer->count]; - rect->x_src = CACHE_X(pos); - rect->y_src = CACHE_Y(pos); - rect->x_dst = x_glyph - glyph->info.x; - rect->y_dst = y_glyph - glyph->info.y; - rect->width = glyph->info.width; - rect->height = glyph->info.height; - - buffer->count++; - - return GLAMOR_GLYPH_SUCCESS; -} - -#undef CACHE_X -#undef CACHE_Y - -static glamor_glyph_cache_result_t -glamor_buffer_glyph(ScreenPtr screen, - glamor_glyph_buffer_t *buffer, - GlyphPtr glyph, int x_glyph, int y_glyph) -{ - glamor_screen_private *glamor_screen = glamor_get_screen_private(screen); - unsigned int format = (GlyphPicture(glyph)[screen->myNum])->format; - int width = glyph->info.width; - int height = glyph->info.height; - glamor_composite_rect_t *rect; - PicturePtr source; - int i; - - if (buffer->count == GLYPH_BUFFER_SIZE) - return GLAMOR_GLYPH_NEED_FLUSH; - - if (PICT_FORMAT_BPP(format) == 1) - format = PICT_a8; - - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) { - glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i]; - - if (format == cache->format && - width <= cache->glyph_width && - height <= cache->glyph_height) { - glamor_glyph_cache_result_t result = - glamor_glyph_cache_buffer_glyph(screen, - &glamor_screen->glyph_caches[i], - buffer, - glyph, x_glyph, - y_glyph); - switch (result) { - case GLAMOR_GLYPH_FAIL: - break; - case GLAMOR_GLYPH_SUCCESS: - case GLAMOR_GLYPH_NEED_FLUSH: - return result; + else + { + glamor_copy_area (&pGlyphPixmap->drawable, + &scratch->drawable, + gc, + 0, 0, + glyph->info.width, glyph->info.height, 0, 0); } } + else + { + scratch = pGlyphPixmap; + } } - - /* Couldn't find the glyph in the cache, use the glyph picture directly */ - - source = GlyphPicture(glyph)[screen->myNum]; - if (buffer->source && buffer->source != source) - return GLAMOR_GLYPH_NEED_FLUSH; - - buffer->source = source; - - rect = &buffer->rects[buffer->count]; - rect->x_src = 0; - rect->y_src = 0; - rect->x_dst = x_glyph - glyph->info.x; - rect->y_dst = y_glyph - glyph->info.y; - rect->width = glyph->info.width; - rect->height = glyph->info.height; - - buffer->count++; - - return GLAMOR_GLYPH_SUCCESS; -} - -static void glamor_glyphs_to_mask(PicturePtr mask, - glamor_glyph_buffer_t *buffer) -{ -#ifdef RENDER - - glamor_composite_rects(PictOpAdd, buffer->source, mask, - buffer->count, buffer->rects); #endif + glamor_copy_area (&scratch->drawable, &pCachePixmap->drawable, gc, + 0, 0, glyph->info.width, glyph->info.height, x, y); - buffer->count = 0; - buffer->source = NULL; + if (scratch != pGlyphPixmap) + screen->DestroyPixmap (scratch); + + FreeScratchGC (gc); } -static void -glamor_glyphs_to_dst(CARD8 op, - PicturePtr src, - PicturePtr dst, - glamor_glyph_buffer_t *buffer, - INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst) + +void +glamor_glyph_unrealize (ScreenPtr screen, GlyphPtr glyph) { - int i; + struct glamor_glyph *priv; - for (i = 0; i < buffer->count; i++) { - glamor_composite_rect_t *rect = &buffer->rects[i]; + /* Use Lookup in case we have not attached to this glyph. */ + priv = dixLookupPrivate (&glyph->devPrivates, &glamor_glyph_key); + if (priv == NULL) + return; - CompositePicture(op, - src, - buffer->source, - dst, - x_src + rect->x_dst - x_dst, - y_src + rect->y_dst - y_dst, - rect->x_src, - rect->y_src, - rect->x_dst, - rect->y_dst, rect->width, rect->height); - } + priv->cache->glyphs[priv->pos] = NULL; - buffer->count = 0; - buffer->source = NULL; + glamor_glyph_set_private (glyph, NULL); + free (priv); } /* Cut and paste from render/glyph.c - probably should export it instead */ static void -glamor_glyph_extents(int nlist, - GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents) +glamor_glyph_extents (int nlist, + GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents) { - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; + int x1, x2, y1, y2; + int x, y, n; - x = 0; - y = 0; - extents->x1 = MAXSHORT; - extents->x2 = MINSHORT; - extents->y1 = MAXSHORT; - extents->y2 = MINSHORT; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) { - glyph = *glyphs++; - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - if (x1 < extents->x1) - extents->x1 = x1; - if (x2 > extents->x2) - extents->x2 = x2; - if (y1 < extents->y1) - extents->y1 = y1; - if (y2 > extents->y2) - extents->y2 = y2; - x += glyph->info.xOff; - y += glyph->info.yOff; + x1 = y1 = MAXSHORT; + x2 = y2 = MINSHORT; + x = y = 0; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) + { + GlyphPtr glyph = *glyphs++; + int v; + + v = x - glyph->info.x; + if (v < x1) + x1 = v; + v += glyph->info.width; + if (v > x2) + x2 = v; + + v = y - glyph->info.y; + if (v < y1) + y1 = v; + v += glyph->info.height; + if (v > y2) + y2 = v; + + x += glyph->info.xOff; + y += glyph->info.yOff; } } + + extents->x1 = x1 < MINSHORT ? MINSHORT : x1; + extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2; + extents->y1 = y1 < MINSHORT ? MINSHORT : y1; + extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2; } /** @@ -667,217 +367,494 @@ glamor_glyph_extents(int nlist, * bounding box, which appears to be good enough to catch most cases at least. */ static Bool -glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) +glamor_glyphs_intersect (int nlist, GlyphListPtr list, GlyphPtr * glyphs) { - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - BoxRec extents; - Bool first = TRUE; + int x1, x2, y1, y2; + int n; + int x, y; + BoxRec extents; + Bool first = TRUE; - x = 0; - y = 0; - extents.x1 = 0; - extents.y1 = 0; - extents.x2 = 0; - extents.y2 = 0; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) { - glyph = *glyphs++; + x = 0; + y = 0; + extents.x1 = 0; + extents.y1 = 0; + extents.x2 = 0; + extents.y2 = 0; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) + { + GlyphPtr glyph = *glyphs++; - if (glyph->info.width == 0 || glyph->info.height == 0) { - x += glyph->info.xOff; - y += glyph->info.yOff; - continue; + if (glyph->info.width == 0 || glyph->info.height == 0) + { + x += glyph->info.xOff; + y += glyph->info.yOff; + continue; } - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; - if (first) { - extents.x1 = x1; - extents.y1 = y1; - extents.x2 = x2; - extents.y2 = y2; - first = FALSE; - } else { - if (x1 < extents.x2 && x2 > extents.x1 && - y1 < extents.y2 && y2 > extents.y1) { - return TRUE; + if (first) + { + extents.x1 = x1; + extents.y1 = y1; + extents.x2 = x2; + extents.y2 = y2; + first = FALSE; + } + else + { + if (x1 < extents.x2 && x2 > extents.x1 && + y1 < extents.y2 && y2 > extents.y1) + { + return TRUE; } - if (x1 < extents.x1) - extents.x1 = x1; - if (x2 > extents.x2) - extents.x2 = x2; - if (y1 < extents.y1) - extents.y1 = y1; - if (y2 > extents.y2) - extents.y2 = y2; + if (x1 < extents.x1) + extents.x1 = x1; + if (x2 > extents.x2) + extents.x2 = x2; + if (y1 < extents.y1) + extents.y1 = y1; + if (y2 > extents.y2) + extents.y2 = y2; } - x += glyph->info.xOff; - y += glyph->info.yOff; + x += glyph->info.xOff; + y += glyph->info.yOff; } } - return FALSE; + return FALSE; +} + + +static inline unsigned int +glamor_glyph_size_to_count (int size) +{ + size /= GLYPH_MIN_SIZE; + return size * size; +} + +static inline unsigned int +glamor_glyph_count_to_mask (int count) +{ + return ~(count - 1); +} + +static inline unsigned int +glamor_glyph_size_to_mask (int size) +{ + return glamor_glyph_count_to_mask (glamor_glyph_size_to_count (size)); +} + +static PicturePtr +glamor_glyph_cache (ScreenPtr screen, GlyphPtr glyph, int *out_x, int *out_y) +{ + glamor_screen_private *glamor = glamor_get_screen_private (screen); + PicturePtr glyph_picture = GlyphPicture (glyph)[screen->myNum]; + glamor_glyph_cache_t *cache = + &glamor->glyphCaches[PICT_FORMAT_RGB (glyph_picture->format) != 0]; + struct glamor_glyph *priv = NULL; + int size, mask, pos, s; + + if (glyph->info.width > GLYPH_MAX_SIZE + || glyph->info.height > GLYPH_MAX_SIZE) + return NULL; + + for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2) + if (glyph->info.width <= size && glyph->info.height <= size) + break; + + s = glamor_glyph_size_to_count (size); + mask = glamor_glyph_count_to_mask (s); + pos = (cache->count + s - 1) & mask; + if (pos < GLYPH_CACHE_SIZE) + { + cache->count = pos + s; + } + else + { + for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) + { + int i = cache->evict & glamor_glyph_size_to_mask (s); + GlyphPtr evicted = cache->glyphs[i]; + if (evicted == NULL) + continue; + + priv = glamor_glyph_get_private (evicted); + if (priv->size >= s) + { + cache->glyphs[i] = NULL; + glamor_glyph_set_private (evicted, NULL); + pos = cache->evict & glamor_glyph_size_to_mask (size); + } + else + priv = NULL; + break; + } + if (priv == NULL) + { + int count = glamor_glyph_size_to_count (size); + mask = glamor_glyph_count_to_mask (count); + pos = cache->evict & mask; + for (s = 0; s < count; s++) + { + GlyphPtr evicted = cache->glyphs[pos + s]; + if (evicted != NULL) + { + if (priv != NULL) + free (priv); + + priv = glamor_glyph_get_private (evicted); + glamor_glyph_set_private (evicted, NULL); + cache->glyphs[pos + s] = NULL; + } + } + } + /* And pick a new eviction position */ + cache->evict = rand () % GLYPH_CACHE_SIZE; + } + + if (priv == NULL) + { + priv = malloc (sizeof (struct glamor_glyph)); + if (priv == NULL) + return NULL; + } + + glamor_glyph_set_private (glyph, priv); + cache->glyphs[pos] = glyph; + + priv->cache = cache; + priv->size = size; + priv->pos = pos; + s = + pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) * + (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE)); + priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE; + priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE; + for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) + { + if (pos & 1) + priv->x += s; + if (pos & 2) + priv->y += s; + pos >>= 2; + } + + glamor_glyph_cache_upload_glyph (screen, cache, glyph, priv->x, priv->y); + + *out_x = priv->x; + *out_y = priv->y; + return cache->picture; +} + +static glamor_glyph_cache_result_t +glamor_buffer_glyph (ScreenPtr screen, + glamor_glyph_buffer_t * buffer, + GlyphPtr glyph, int x_glyph, int y_glyph) +{ + glamor_screen_private *glamor_screen = glamor_get_screen_private (screen); + unsigned int format = (GlyphPicture (glyph)[screen->myNum])->format; + glamor_composite_rect_t *rect; + PicturePtr source; + struct glamor_glyph *priv; + int x, y; + PicturePtr glyph_picture = GlyphPicture (glyph)[screen->myNum]; + glamor_glyph_cache_t *cache; + + if (PICT_FORMAT_BPP (format) == 1) + format = PICT_a8; + + cache = &glamor_screen->glyphCaches[PICT_FORMAT_RGB (glyph_picture->format) != 0]; + + if (buffer->source && buffer->source != cache->picture) + return GLAMOR_GLYPH_NEED_FLUSH; + + if (buffer->count == GLYPH_BUFFER_SIZE) + return GLAMOR_GLYPH_NEED_FLUSH; + + priv = glamor_glyph_get_private (glyph); + + if (priv) + { + rect = &buffer->rects[buffer->count++]; + rect->x_src = priv->x; + rect->y_src = priv->y; + if (buffer->source == NULL) buffer->source = priv->cache->picture; + } + else + { + source = glamor_glyph_cache (screen, glyph, &x, &y); + if (source != NULL) + { + rect = &buffer->rects[buffer->count++]; + rect->x_src = x; + rect->y_src = y; + if (buffer->source == NULL) buffer->source = source; + } + else + { + source = GlyphPicture (glyph)[screen->myNum]; + if (buffer->source && buffer->source != source) + return GLAMOR_GLYPH_NEED_FLUSH; + buffer->source = source; + + rect = &buffer->rects[buffer->count++]; + rect->x_src = 0; + rect->y_src = 0; + } + } + + rect->x_dst = x_glyph - glyph->info.x; + rect->y_dst = y_glyph - glyph->info.y; + rect->width = glyph->info.width; + rect->height = glyph->info.height; + + /* Couldn't find the glyph in the cache, use the glyph picture directly */ + + return GLAMOR_GLYPH_SUCCESS; +} + + +static void +glamor_glyphs_flush_mask (PicturePtr mask, glamor_glyph_buffer_t * buffer) +{ +#ifdef RENDER + glamor_composite_rects (PictOpAdd, buffer->source, NULL, mask, + buffer->count, buffer->rects); +#endif + buffer->count = 0; + buffer->source = NULL; +} + +static void +glamor_glyphs_via_mask (CARD8 op, + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, + int nlist, GlyphListPtr list, GlyphPtr * glyphs) +{ + PixmapPtr mask_pixmap = 0; + PicturePtr mask; + ScreenPtr screen = dst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int x_dst = list->xOff, y_dst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = { 0, 0, 0, 0 }; + CARD32 component_alpha; + glamor_glyph_buffer_t buffer; + + GCPtr gc; + + glamor_glyph_extents (nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + + if (mask_format->depth == 1) + { + PictFormatPtr a8Format = PictureMatchFormat (screen, 8, PICT_a8); + + if (a8Format) + mask_format = a8Format; + } + + mask_pixmap = screen->CreatePixmap (screen, width, height, + mask_format->depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!mask_pixmap) + return; + component_alpha = NeedsComponent (mask_format->format); + mask = CreatePicture (0, &mask_pixmap->drawable, + mask_format, CPComponentAlpha, + &component_alpha, serverClient, &error); + if (!mask) + { + screen->DestroyPixmap (mask_pixmap); + return; + } + gc = GetScratchGC (mask_pixmap->drawable.depth, screen); + ValidateGC (&mask_pixmap->drawable, gc); + glamor_fill (&mask_pixmap->drawable, gc, 0, 0, width, height); + FreeScratchGC (gc); + x = -extents.x1; + y = -extents.y1; + + buffer.count = 0; + buffer.source = NULL; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) + { + glyph = *glyphs++; + + if (glyph->info.width > 0 && glyph->info.height > 0 && + glamor_buffer_glyph (screen, &buffer, glyph, x, + y) == GLAMOR_GLYPH_NEED_FLUSH) + { + + glamor_glyphs_flush_mask (mask, &buffer); + + glamor_buffer_glyph (screen, &buffer, glyph, x, y); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + + if (buffer.count) + glamor_glyphs_flush_mask (mask, &buffer); + + x = extents.x1; + y = extents.y1; + CompositePicture (op, + src, + mask, + dst, + x_src + x - x_dst, + y_src + y - y_dst, 0, 0, x, y, width, height); + FreePicture (mask, 0); + screen->DestroyPixmap (mask_pixmap); +} + +static void +glamor_glyphs_flush_dst (CARD8 op, + PicturePtr src, + PicturePtr dst, + glamor_glyph_buffer_t * buffer, + INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst) +{ + int i; + glamor_composite_rect_t *rect = &buffer->rects[0]; + for (i = 0; i < buffer->count; i++, rect++) + { + rect->x_mask = rect->x_src; + rect->y_mask = rect->y_src; + rect->x_src = x_src + rect->x_dst - x_dst; + rect->y_src = y_src + rect->y_dst - y_dst; + } + + glamor_composite_rects (op, src, buffer->source, dst, + buffer->count, &buffer->rects[0]); + + buffer->count = 0; + buffer->source = NULL; +} + +static void +glamor_glyphs_to_dst (CARD8 op, + PicturePtr src, + PicturePtr dst, + INT16 x_src, + INT16 y_src, + int nlist, GlyphListPtr list, GlyphPtr * glyphs) +{ + ScreenPtr screen = dst->pDrawable->pScreen; + int x = 0, y = 0; + int x_dst = list->xOff, y_dst = list->yOff; + int n; + GlyphPtr glyph; + glamor_glyph_buffer_t buffer; + + buffer.count = 0; + buffer.source = NULL; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) + { + glyph = *glyphs++; + + if (glyph->info.width > 0 && glyph->info.height > 0 && + glamor_buffer_glyph (screen, &buffer, glyph, x, + y) == GLAMOR_GLYPH_NEED_FLUSH) + { + glamor_glyphs_flush_dst (op, src, dst, + &buffer, x_src, y_src, x_dst, y_dst); + glamor_buffer_glyph (screen, &buffer, glyph, x, y); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + + if (buffer.count) + glamor_glyphs_flush_dst (op, src, dst, &buffer, + x_src, y_src, x_dst, y_dst); } void -glamor_glyphs(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs) +glamor_glyphs (CARD8 op, + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { - PicturePtr picture; - PixmapPtr mask_pixmap = 0; - PicturePtr mask; - ScreenPtr screen = dst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y; - int x_dst = list->xOff, y_dst = list->yOff; - int n; - GlyphPtr glyph; - int error; - BoxRec extents = { 0, 0, 0, 0 }; - CARD32 component_alpha; - glamor_glyph_buffer_t buffer; + /* If we don't have a mask format but all the glyphs have the same format + * and don't intersect, use the glyph format as mask format for the full + * benefits of the glyph cache. + */ + if (!mask_format) + { + Bool same_format = TRUE; + int i; - /* If we don't have a mask format but all the glyphs have the same format - * and don't intersect, use the glyph format as mask format for the full - * benefits of the glyph cache. - */ - if (!mask_format) { - Bool same_format = TRUE; - int i; + mask_format = list[0].format; - mask_format = list[0].format; - - for (i = 0; i < nlist; i++) { - if (mask_format->format != list[i].format->format) { - same_format = FALSE; - break; + for (i = 0; i < nlist; i++) + { + if (mask_format->format != list[i].format->format) + { + same_format = FALSE; + break; } } - if (!same_format || (mask_format->depth != 1 && - glamor_glyphs_intersect(nlist, list, - glyphs))) { - mask_format = NULL; + if (!same_format || (mask_format->depth != 1 && + glamor_glyphs_intersect (nlist, list, glyphs))) + { + mask_format = NULL; } } - if (mask_format) { - GCPtr gc; - xRectangle rect; - - glamor_glyph_extents(nlist, list, glyphs, &extents); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - - if (mask_format->depth == 1) { - PictFormatPtr a8Format = - PictureMatchFormat(screen, 8, PICT_a8); - - if (a8Format) - mask_format = a8Format; - } - - mask_pixmap = screen->CreatePixmap(screen, width, height, - mask_format->depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!mask_pixmap) - return; - component_alpha = NeedsComponent(mask_format->format); - mask = CreatePicture(0, &mask_pixmap->drawable, - mask_format, CPComponentAlpha, - &component_alpha, serverClient, &error); - if (!mask) { - screen->DestroyPixmap(mask_pixmap); - return; - } - gc = GetScratchGC(mask_pixmap->drawable.depth, screen); - ValidateGC(&mask_pixmap->drawable, gc); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - gc->ops->PolyFillRect(&mask_pixmap->drawable, gc, 1, &rect); - FreeScratchGC(gc); - x = -extents.x1; - y = -extents.y1; - } else { - mask = dst; - x = 0; - y = 0; - } - buffer.count = 0; - buffer.source = NULL; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - while (n--) { - glyph = *glyphs++; - picture = GlyphPicture(glyph)[screen->myNum]; - - if (glyph->info.width > 0 && glyph->info.height > 0 && - glamor_buffer_glyph(screen, &buffer, glyph, x, - y) == GLAMOR_GLYPH_NEED_FLUSH) { - if (mask_format) - glamor_glyphs_to_mask(mask, &buffer); - else - glamor_glyphs_to_dst(op, src, dst, - &buffer, x_src, y_src, - x_dst, y_dst); - - glamor_buffer_glyph(screen, &buffer, glyph, x, y); - } - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - } - - if (buffer.count) { - if (mask_format) - glamor_glyphs_to_mask(mask, &buffer); - else - glamor_glyphs_to_dst(op, src, dst, &buffer, - x_src, y_src, x_dst, y_dst); - } - - if (mask_format) { - x = extents.x1; - y = extents.y1; - CompositePicture(op, - src, - mask, - dst, - x_src + x - x_dst, - y_src + y - y_dst, 0, 0, x, y, width, height); - FreePicture(mask, 0); - screen->DestroyPixmap(mask_pixmap); - } + if (mask_format) + glamor_glyphs_via_mask (op, src, dst, mask_format, + x_src, y_src, nlist, list, glyphs); + else + glamor_glyphs_to_dst (op, src, dst, x_src, y_src, nlist, list, glyphs); } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 4feb0048e..76e21ea1e 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -138,38 +138,16 @@ typedef struct { INT16 height; } glamor_composite_rect_t; -typedef struct { - unsigned char sha1[20]; -} glamor_cached_glyph_t; +#define GLAMOR_NUM_GLYPH_CACHES 4 +#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 typedef struct { - /* The identity of the cache, statically configured at initialization */ - unsigned int format; - int glyph_width; - int glyph_height; - - /* Size of cache; eventually this should be dynamically determined */ - int size; - - /* Hash table mapping from glyph sha1 to position in the glyph; we use - * open addressing with a hash table size determined based on size and large - * enough so that we always have a good amount of free space, so we can - * use linear probing. (Linear probing is preferrable to double hashing - * here because it allows us to easily remove entries.) - */ - int *hash_entries; - int hash_size; - - glamor_cached_glyph_t *glyphs; - int glyph_count; /* Current number of glyphs */ - - PicturePtr picture; /* Where the glyphs of the cache are stored */ - int y_offset; /* y location within the picture where the cache starts */ - int columns; /* Number of columns the glyphs are layed out in */ - int eviction_position; /* Next random position to evict a glyph */ + PicturePtr picture; /* Where the glyphs of the cache are stored */ + GlyphPtr *glyphs; + uint16_t count; + uint16_t evict; } glamor_glyph_cache_t; -#define GLAMOR_NUM_GLYPH_CACHES 4 enum glamor_vertex_type { GLAMOR_VERTEX_POS, @@ -268,6 +246,10 @@ typedef struct glamor_screen_private { glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; int delayed_fallback_pending; + + glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; + Bool glyph_cache_initialized; + } glamor_screen_private; typedef enum glamor_access { @@ -838,7 +820,6 @@ glamor_get_spans(DrawablePtr drawable, char *dst_start); /* glamor_glyphs.c */ -void glamor_glyphs_init(ScreenPtr screen); void glamor_glyphs_fini(ScreenPtr screen); void glamor_glyphs(CARD8 op, PicturePtr pSrc, @@ -888,7 +869,7 @@ void glamor_trapezoids(CARD8 op, int ntrap, xTrapezoid *traps); void glamor_init_composite_shaders(ScreenPtr screen); void glamor_composite_rects(CARD8 op, - PicturePtr src, PicturePtr dst, + PicturePtr src, PicturePtr mask, PicturePtr dst, int nrect, glamor_composite_rect_t *rects); /* glamor_tile.c */ @@ -999,7 +980,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD -//#define GLAMOR_DELAYED_FILLING +#define GLAMOR_DELAYED_FILLING #include"glamor_utils.h" diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index bc6347883..258a09b9d 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1405,7 +1405,7 @@ glamor_trapezoids(CARD8 op, void glamor_composite_rects(CARD8 op, - PicturePtr src, PicturePtr dst, + PicturePtr src, PicturePtr mask, PicturePtr dst, int nrect, glamor_composite_rect_t *rects) { int n; @@ -1414,7 +1414,7 @@ glamor_composite_rects(CARD8 op, ValidatePicture(src); ValidatePicture(dst); - if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects)) + if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects)) return; n = nrect; @@ -1423,10 +1423,10 @@ glamor_composite_rects(CARD8 op, while (n--) { CompositePicture(op, src, - NULL, + mask, dst, r->x_src, r->y_src, - 0, 0, + r->x_mask, r->y_mask, r->x_dst, r->y_dst, r->width, r->height); r++; From f08988455cd4f6339187e74df8edb5783b61f8fa Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 30 Aug 2011 18:24:53 +0800 Subject: [PATCH 206/225] glamor: Route UnrealizeGlyph to glamor_glyph_unrealize. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 3 +++ glamor/glamor_priv.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/glamor/glamor.c b/glamor/glamor.c index 53fe71d49..c0f9d51b5 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -359,6 +359,9 @@ glamor_init(ScreenPtr screen, unsigned int flags) ps->CreatePicture = glamor_create_picture; glamor_priv->saved_destroy_picture = ps->DestroyPicture; ps->DestroyPicture = glamor_destroy_picture; + + glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph; + ps->UnrealizeGlyph = glamor_glyph_unrealize; #endif glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 76e21ea1e..325fa4343 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -205,6 +205,7 @@ typedef struct glamor_screen_private { TrianglesProcPtr saved_triangles; CreatePictureProcPtr saved_create_picture; DestroyPictureProcPtr saved_destroy_picture; + UnrealizeGlyphProcPtr saved_unrealize_glyph; int yInverted; int screen_fbo; @@ -828,6 +829,8 @@ void glamor_glyphs(CARD8 op, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs); +void +glamor_glyph_unrealize (ScreenPtr screen, GlyphPtr glyph); /* glamor_setspans.c */ void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int n, int sorted); From 7daf9af086624133d6c4857ed92d57ad2a492d86 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 31 Aug 2011 17:43:46 +0800 Subject: [PATCH 207/225] glamor: Let GLAMOR_DDX implicit GLAMOR. If user only enable GLAMOR_DDX, he must also want GLAMOR. Signed-off-by: Zhigang Gong --- configure.ac | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 82c845ba7..80daf828b 100644 --- a/configure.ac +++ b/configure.ac @@ -1772,7 +1772,11 @@ AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) dnl glamor -AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes || test "x$GLAMOR" = xyes]) +if [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes] ; then + GLAMOR=yes +fi + +AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes]) AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes]) AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes]) From 0dff23d65b8bcec615f4c7a49efa7a5bf220b299 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 8 Sep 2011 14:05:46 +0800 Subject: [PATCH 208/225] glamor: Don't direct call to any gl functions. Create a new structure glamor_gl_dispatch to hold all the gl function's pointer and initialize them at run time , rather than use them directly. To do this is to avoid symbol conflicts. Signed-off-by: Zhigang Gong --- glamor/Makefile.am | 1 + glamor/glamor.c | 30 +++-- glamor/glamor.h | 2 + glamor/glamor_copyarea.c | 50 ++++---- glamor/glamor_core.c | 121 +++++++----------- glamor/glamor_egl.c | 21 ++- glamor/glamor_fill.c | 36 +++--- glamor/glamor_getspans.c | 5 +- glamor/glamor_gl_dispatch.c | 73 +++++++++++ glamor/glamor_gl_dispatch.h | 101 +++++++++++++++ glamor/glamor_pixmap.c | 227 +++++++++++++++++---------------- glamor/glamor_priv.h | 17 ++- glamor/glamor_putimage.c | 131 +++++++++---------- glamor/glamor_render.c | 146 +++++++++++---------- glamor/glamor_setspans.c | 19 ++- glamor/glamor_tile.c | 66 +++++----- hw/xfree86/glamor/glamor.c | 12 ++ hw/xfree86/glamor/glamor_ddx.h | 2 + 18 files changed, 638 insertions(+), 422 deletions(-) create mode 100644 glamor/glamor_gl_dispatch.c create mode 100644 glamor/glamor_gl_dispatch.h diff --git a/glamor/Makefile.am b/glamor/Makefile.am index fcde76503..8712e765a 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -43,4 +43,5 @@ libglamor_la_SOURCES = \ glamor_pixmap.c\ glamor_picture.c\ glamor_window.c\ + glamor_gl_dispatch.c\ glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c index c0f9d51b5..ea4099ed2 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -59,7 +59,7 @@ glamor_get_drawable_pixmap(DrawablePtr drawable) return (PixmapPtr)drawable; } -static void +void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) { ScreenPtr screen = pixmap->drawable.pScreen; @@ -111,6 +111,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, int type = GLAMOR_PIXMAP_TEXTURE; glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; if (w > 32767 || h > 32767) return NullPixmap; @@ -141,6 +142,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv->container = pixmap; + pixmap_priv->glamor_priv = glamor_priv; if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY) return pixmap; @@ -160,11 +162,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, } /* Create the texture used to store the pixmap's data. */ - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, + dispatch->glGenTextures(1, &tex); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, NULL); glamor_set_pixmap_texture(pixmap, w, h, tex); @@ -210,14 +212,16 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth, static Bool glamor_destroy_pixmap(PixmapPtr pixmap) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; if (pixmap->refcnt == 1) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->fb) - glDeleteFramebuffers(1, &pixmap_priv->fb); + dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb); if (pixmap_priv->tex) - glDeleteTextures(1, &pixmap_priv->tex); + dispatch->glDeleteTextures(1, &pixmap_priv->tex); if (pixmap_priv->pbo) - glDeleteBuffers(1, &pixmap_priv->pbo); + dispatch->glDeleteBuffers(1, &pixmap_priv->pbo); dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP); } @@ -227,7 +231,8 @@ glamor_destroy_pixmap(PixmapPtr pixmap) static void glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask) { - glFlush(); + glamor_gl_dispatch *dispatch = data; + dispatch->glFlush(); } static void @@ -295,6 +300,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) goto fail; } + glamor_gl_dispatch_init(screen, &glamor_priv->dispatch, gl_version); #ifdef GLAMOR_GLES2 if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) { @@ -305,11 +311,11 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert"); glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit"); - glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); + glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, glamor_wakeup_handler, - NULL)) { + (void*)&glamor_priv->dispatch)) { goto fail; } diff --git a/glamor/glamor.h b/glamor/glamor.h index 7a0e89923..e8719fb2f 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -52,10 +52,12 @@ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT void glamor_fini(ScreenPtr screen); extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen); +void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex); #ifdef GLAMOR_FOR_XORG extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd); extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride); +extern _X_EXPORT Bool glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride); extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen); extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags); #endif diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 3e6e6b9fc..ec57520e8 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -46,6 +46,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); glamor_pixmap_private *src_pixmap_priv; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; int dst_x_off, dst_y_off, src_x_off, src_y_off, i; if (!glamor_priv->has_fbo_blit) { @@ -78,14 +79,14 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, } glamor_validate_pixmap(dst_pixmap); - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); + dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); src_y_off += dy; for (i = 0; i < nbox; i++) { if(glamor_priv->yInverted) { - glBlitFramebuffer((box[i].x1 + dx + src_x_off), + dispatch->glBlitFramebuffer((box[i].x1 + dx + src_x_off), (box[i].y1 + src_y_off), (box[i].x2 + dx + src_x_off), (box[i].y2 + src_y_off), @@ -101,7 +102,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off); int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off); - glBlitFramebuffer(box[i].x1 + dx + src_x_off, + dispatch->glBlitFramebuffer(box[i].x1 + dx + src_x_off, flip_src_y1, box[i].x2 + dx + src_x_off, flip_src_y2, @@ -129,6 +130,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, { glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int i; @@ -162,7 +164,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, flush_needed = 1; if (gc) { - glamor_set_alu(gc->alu); + glamor_set_alu(dispatch, gc->alu); if (!glamor_set_planemask(dst_pixmap, gc->planemask)) goto fail; if (gc->alu != GXcopy) { @@ -181,10 +183,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src, - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); @@ -192,25 +194,25 @@ glamor_copy_n_to_n_textured(DrawablePtr src, dy += src_y_off; pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); #ifndef GLAMOR_GLES2 - glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(glamor_priv->finish_access_prog[0]); - glUniform1i(glamor_priv->finish_access_no_revert[0], 1); - glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); + dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); } else { - GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); + GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv); } for (i = 0; i < nbox; i++) { @@ -230,24 +232,24 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glamor_priv->yInverted, texcoords); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); #ifndef GLAMOR_GLES2 - glDisable(GL_TEXTURE_2D); + dispatch->glDisable(GL_TEXTURE_2D); #endif } - glUseProgram(0); + dispatch->glUseProgram(0); /* The source texture is bound to a fbo, we have to flush it here. */ if (flush_needed) - glFlush(); + dispatch->glFlush(); return TRUE; fail: - glamor_set_alu(GXcopy); + glamor_set_alu(dispatch, GXcopy); glamor_set_planemask(dst_pixmap, ~0); return FALSE; } diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 3609600bc..2249ac800 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -54,49 +54,24 @@ glamor_get_drawable_location(const DrawablePtr drawable) return 'f'; } - -void -glamor_get_transform_uniform_locations(GLint prog, - glamor_transform_uniforms *uniform_locations) -{ - uniform_locations->x_bias = glGetUniformLocation(prog, "x_bias"); - uniform_locations->x_scale = glGetUniformLocation(prog, "x_scale"); - uniform_locations->y_bias = glGetUniformLocation(prog, "y_bias"); - uniform_locations->y_scale = glGetUniformLocation(prog, "y_scale"); -} - -/* We don't use a full matrix for our transformations because it's - * wasteful when all we want is to rescale to NDC and possibly do a flip - * if it's the front buffer. - */ -void -glamor_set_transform_for_pixmap(PixmapPtr pixmap, - glamor_transform_uniforms *uniform_locations) -{ - glUniform1f(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f); - glUniform1f(uniform_locations->x_scale, 2.0f / pixmap->drawable.width); - glUniform1f(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f); - glUniform1f(uniform_locations->y_scale, -2.0f / pixmap->drawable.height); -} - GLint -glamor_compile_glsl_prog(GLenum type, const char *source) +glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source) { GLint ok; GLint prog; - prog = glCreateShader(type); - glShaderSource(prog, 1, (const GLchar **)&source, NULL); - glCompileShader(prog); - glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); + prog = dispatch->glCreateShader(type); + dispatch->glShaderSource(prog, 1, (const GLchar **)&source, NULL); + dispatch->glCompileShader(prog); + dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); if (!ok) { GLchar *info; GLint size; - glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); + dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); info = malloc(size); - glGetShaderInfoLog(prog, size, NULL, info); + dispatch->glGetShaderInfoLog(prog, size, NULL, info); ErrorF("Failed to compile %s: %s\n", type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); @@ -108,20 +83,20 @@ glamor_compile_glsl_prog(GLenum type, const char *source) } void -glamor_link_glsl_prog(GLint prog) +glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog) { GLint ok; - glLinkProgram(prog); - glGetProgramiv(prog, GL_LINK_STATUS, &ok); + dispatch->glLinkProgram(prog); + dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok); if (!ok) { GLchar *info; GLint size; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); + dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); info = malloc(size); - glGetProgramInfoLog(prog, size, NULL, info); + dispatch->glGetProgramInfoLog(prog, size, NULL, info); ErrorF("Failed to link: %s\n", info); FatalError("GLSL link failure\n"); @@ -140,6 +115,7 @@ void glamor_init_finish_access_shaders(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; const char *vs_source = "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" @@ -200,51 +176,51 @@ glamor_init_finish_access_shaders(ScreenPtr screen) GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; GLint sampler_uniform_location; - glamor_priv->finish_access_prog[0] = glCreateProgram(); - glamor_priv->finish_access_prog[1] = glCreateProgram(); + glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram(); + glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); - glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); - glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, fs_source); + dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); + dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); - avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); - set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, set_alpha_source); - glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); - glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog); + avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); + set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, set_alpha_source); + dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); + dispatch->glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog); - glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]); + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[0]); - glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[1]); glamor_priv->finish_access_no_revert[0] = - glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert"); + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert"); glamor_priv->finish_access_swap_rb[0] = - glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb"); + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb"); sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[0]); - glUniform1i(sampler_uniform_location, 0); - glUniform1i(glamor_priv->finish_access_no_revert[0],1); - glUniform1i(glamor_priv->finish_access_swap_rb[0],0); - glUseProgram(0); + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); + dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); + dispatch->glUniform1i(sampler_uniform_location, 0); + dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0],1); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],0); + dispatch->glUseProgram(0); glamor_priv->finish_access_no_revert[1] = - glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert"); + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert"); glamor_priv->finish_access_swap_rb[1] = - glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb"); + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb"); sampler_uniform_location = - glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); - glUseProgram(glamor_priv->finish_access_prog[1]); - glUniform1i(glamor_priv->finish_access_no_revert[1],1); - glUniform1i(sampler_uniform_location, 0); - glUniform1i(glamor_priv->finish_access_swap_rb[1],0); - glUseProgram(0); + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); + dispatch->glUseProgram(glamor_priv->finish_access_prog[1]); + dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1],1); + dispatch->glUniform1i(sampler_uniform_location, 0); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1],0); + dispatch->glUseProgram(0); } @@ -254,6 +230,7 @@ glamor_finish_access(DrawablePtr drawable) PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) return; @@ -264,10 +241,10 @@ glamor_finish_access(DrawablePtr drawable) if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) { assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); - glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); + dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); + dispatch->glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); pixmap_priv->pbo_valid = FALSE; - glDeleteBuffers(1, &pixmap_priv->pbo); + dispatch->glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->pbo = 0; } else { free(pixmap->devPrivate.ptr); diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index bdb2da711..773f90e2e 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -54,6 +54,7 @@ #define GLAMOR_FOR_XORG #include +#include #define GLAMOR_VERSION_MAJOR 0 #define GLAMOR_VERSION_MINOR 1 @@ -84,6 +85,7 @@ struct glamor_screen_private { PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; + struct glamor_gl_dispatch *dispatch; }; int xf86GlamorEGLPrivateIndex = -1; @@ -127,10 +129,10 @@ _glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int str if (image == EGL_NO_IMAGE_KHR) return FALSE; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glamor->dispatch->glGenTextures(1, &texture); + glamor->dispatch->glBindTexture(GL_TEXTURE_2D, texture); + glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); @@ -296,3 +298,14 @@ glamor_free_egl_screen(int scrnIndex, int flags) free(glamor); } } + +Bool +glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); + if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress)) + return FALSE; + glamor_egl->dispatch = dispatch; + return TRUE; +} diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 0b3d5fddf..7254167cb 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -105,6 +105,7 @@ void glamor_init_solid_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; const char *solid_vs = "attribute vec4 v_position;" "void main()\n" @@ -120,17 +121,17 @@ glamor_init_solid_shader(ScreenPtr screen) "}\n"; GLint fs_prog, vs_prog; - glamor_priv->solid_prog = glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs); - glAttachShader(glamor_priv->solid_prog, vs_prog); - glAttachShader(glamor_priv->solid_prog, fs_prog); + glamor_priv->solid_prog = dispatch->glCreateProgram(); + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs); + dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog); + dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog); - glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position"); - glamor_link_glsl_prog(glamor_priv->solid_prog); + dispatch->glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position"); + glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog); glamor_priv->solid_color_uniform_location = - glGetUniformLocation(glamor_priv->solid_prog, "color"); + dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color"); } Bool @@ -140,6 +141,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; int x1 = x; int x2 = x + width; int y1 = y; @@ -151,7 +153,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glamor_fallback("dest %p has no fbo.\n", pixmap); goto fail; } - glamor_set_alu(alu); + glamor_set_alu(dispatch, alu); if (!glamor_set_planemask(pixmap, planemask)) { glamor_fallback("Failedto set planemask in glamor_solid.\n"); goto fail; @@ -178,24 +180,24 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_validate_pixmap(pixmap); - glUseProgram(glamor_priv->solid_prog); + dispatch->glUseProgram(glamor_priv->solid_prog); - glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); + dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, glamor_priv->yInverted, vertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(0); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glUseProgram(0); return TRUE; fail: - glamor_set_alu(GXcopy); + glamor_set_alu(dispatch, GXcopy); glamor_set_planemask(pixmap, ~0); return FALSE; } diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index ba409dc23..224af1ba5 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -44,6 +44,7 @@ glamor_get_spans(DrawablePtr drawable, int no_alpha, no_revert; glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; PixmapPtr temp_pixmap = NULL; int i; uint8_t *readpixels_dst = (uint8_t *)dst; @@ -79,14 +80,14 @@ glamor_get_spans(DrawablePtr drawable, glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); for (i = 0; i < count; i++) { if (glamor_priv->yInverted) { - glReadPixels(points[i].x + x_off, + dispatch->glReadPixels(points[i].x + x_off, (points[i].y + y_off), widths[i], 1, format, type, readpixels_dst); } else { - glReadPixels(points[i].x + x_off, + dispatch->glReadPixels(points[i].x + x_off, pixmap->drawable.height - 1 - (points[i].y + y_off), widths[i], 1, diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c new file mode 100644 index 000000000..823262494 --- /dev/null +++ b/glamor/glamor_gl_dispatch.c @@ -0,0 +1,73 @@ +#include "glamor_priv.h" + +#define INIT_FUNC(dst,func_name,get) \ + dst->func_name = get(#func_name); \ + if (dst->func_name == NULL) \ + { ErrorF("Failed to get fun %s", #func_name); \ + goto fail; } + +Bool +glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, + int gl_version, + void *(*get_proc_address)(const char*)) +{ + INIT_FUNC(dispatch, glMatrixMode, get_proc_address); + INIT_FUNC(dispatch, glLoadIdentity, get_proc_address); + INIT_FUNC(dispatch, glViewport, get_proc_address); + INIT_FUNC(dispatch, glRasterPos2i, get_proc_address); + INIT_FUNC(dispatch, glDrawArrays, get_proc_address); + INIT_FUNC(dispatch, glReadPixels, get_proc_address); + INIT_FUNC(dispatch, glDrawPixels, get_proc_address); + INIT_FUNC(dispatch, glPixelStorei, get_proc_address); + INIT_FUNC(dispatch, glTexParameteri, get_proc_address); + INIT_FUNC(dispatch, glTexImage2D, get_proc_address); + INIT_FUNC(dispatch, glGenTextures, get_proc_address); + INIT_FUNC(dispatch, glDeleteTextures, get_proc_address); + INIT_FUNC(dispatch, glBindTexture, get_proc_address); + INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address); + INIT_FUNC(dispatch, glFlush, get_proc_address); + INIT_FUNC(dispatch, glGetIntegerv, get_proc_address); + INIT_FUNC(dispatch, glGetString, get_proc_address); + INIT_FUNC(dispatch, glScissor, get_proc_address); + INIT_FUNC(dispatch, glEnable, get_proc_address); + INIT_FUNC(dispatch, glDisable, get_proc_address); + INIT_FUNC(dispatch, glBlendFunc, get_proc_address); + INIT_FUNC(dispatch, glLogicOp, get_proc_address); + INIT_FUNC(dispatch, glActiveTexture, get_proc_address); + INIT_FUNC(dispatch, glGenBuffers, get_proc_address); + INIT_FUNC(dispatch, glBufferData, get_proc_address); + INIT_FUNC(dispatch, glMapBuffer, get_proc_address); + INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address); + INIT_FUNC(dispatch, glBindBuffer, get_proc_address); + INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address); + INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address); + INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address); + INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address); + INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address); + INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address); + INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address); + INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address); + INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address); + INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address); + INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address); + INIT_FUNC(dispatch, glLinkProgram, get_proc_address); + INIT_FUNC(dispatch, glShaderSource, get_proc_address); + + INIT_FUNC(dispatch, glUseProgram, get_proc_address); + INIT_FUNC(dispatch, glUniform1i, get_proc_address); + INIT_FUNC(dispatch, glUniform4f, get_proc_address); + INIT_FUNC(dispatch, glUniform4fv, get_proc_address); + INIT_FUNC(dispatch, glCreateProgram, get_proc_address); + INIT_FUNC(dispatch, glCreateShader, get_proc_address); + INIT_FUNC(dispatch, glCompileShader, get_proc_address); + INIT_FUNC(dispatch, glAttachShader, get_proc_address); + INIT_FUNC(dispatch, glGetShaderiv, get_proc_address); + INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address); + INIT_FUNC(dispatch, glGetProgramiv, get_proc_address); + INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address); + INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address); + + return TRUE; +fail: + return FALSE; +} diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h new file mode 100644 index 000000000..c519667f6 --- /dev/null +++ b/glamor/glamor_gl_dispatch.h @@ -0,0 +1,101 @@ +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 ); + + /* 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 (*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); + 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 (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat *value); + GLuint (*glCreateProgram) (void); + GLuint (*glCreateShader) (GLenum type); + void (*glCompileShader) (GLuint shader); + void (*glAttachShader) (GLuint program, 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; + +Bool +glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, + int gl_version, + void *(*get_proc_address)(const char*)); + + +Bool +glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version); + + + diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 15fc01448..28ad57a4d 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -31,12 +31,13 @@ static void _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, glamor_pixmap_private *pixmap_priv) { + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; GLfloat vertices[8]; - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(glamor_priv->solid_prog); - glUniform4fv(glamor_priv->solid_color_uniform_location, + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glUseProgram(glamor_priv->solid_prog); + dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, pixmap_priv->pending_op.fill.color4fv); vertices[0] = -1; vertices[1] = -1; @@ -46,9 +47,9 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, vertices[5] = 1; vertices[6] = -1; vertices[7] = 1; - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(0); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glUseProgram(0); pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; } @@ -83,14 +84,15 @@ glamor_validate_pixmap(PixmapPtr pixmap) void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) { - glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); + glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch; + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); #ifndef GLAMOR_GLES2 - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + dispatch->glMatrixMode(GL_PROJECTION); + dispatch->glLoadIdentity(); + dispatch->glMatrixMode(GL_MODELVIEW); + dispatch->glLoadIdentity(); #endif - glViewport(0, 0, + dispatch->glViewport(0, 0, pixmap_priv->container->drawable.width, pixmap_priv->container->drawable.height); @@ -130,59 +132,59 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask) void -glamor_set_alu(unsigned char alu) +glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu) { #ifndef GLAMOR_GLES2 if (alu == GXcopy) { - glDisable(GL_COLOR_LOGIC_OP); + dispatch->glDisable(GL_COLOR_LOGIC_OP); return; } - glEnable(GL_COLOR_LOGIC_OP); + dispatch->glEnable(GL_COLOR_LOGIC_OP); switch (alu) { case GXclear: - glLogicOp(GL_CLEAR); + dispatch->glLogicOp(GL_CLEAR); break; case GXand: - glLogicOp(GL_AND); + dispatch->glLogicOp(GL_AND); break; case GXandReverse: - glLogicOp(GL_AND_REVERSE); + dispatch->glLogicOp(GL_AND_REVERSE); break; case GXandInverted: - glLogicOp(GL_AND_INVERTED); + dispatch->glLogicOp(GL_AND_INVERTED); break; case GXnoop: - glLogicOp(GL_NOOP); + dispatch->glLogicOp(GL_NOOP); break; case GXxor: - glLogicOp(GL_XOR); + dispatch->glLogicOp(GL_XOR); break; case GXor: - glLogicOp(GL_OR); + dispatch->glLogicOp(GL_OR); break; case GXnor: - glLogicOp(GL_NOR); + dispatch->glLogicOp(GL_NOR); break; case GXequiv: - glLogicOp(GL_EQUIV); + dispatch->glLogicOp(GL_EQUIV); break; case GXinvert: - glLogicOp(GL_INVERT); + dispatch->glLogicOp(GL_INVERT); break; case GXorReverse: - glLogicOp(GL_OR_REVERSE); + dispatch->glLogicOp(GL_OR_REVERSE); break; case GXcopyInverted: - glLogicOp(GL_COPY_INVERTED); + dispatch->glLogicOp(GL_COPY_INVERTED); break; case GXorInverted: - glLogicOp(GL_OR_INVERTED); + dispatch->glLogicOp(GL_OR_INVERTED); break; case GXnand: - glLogicOp(GL_NAND); + dispatch->glLogicOp(GL_NAND); break; case GXset: - glLogicOp(GL_SET); + dispatch->glLogicOp(GL_SET); break; default: FatalError("unknown logic op\n"); @@ -206,6 +208,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; unsigned int stride, row_length; void *texels; GLenum iformat; @@ -231,24 +234,24 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, stride = pixmap->devKind; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; - glBindTexture(GL_TEXTURE_2D, tex); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); + dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); } else { - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); } if (pixmap_priv->pbo && pixmap_priv->pbo_valid) { texels = NULL; - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo); + dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo); } else texels = pixmap->devPrivate.ptr; - glTexImage2D(GL_TEXTURE_2D, + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat, pixmap->drawable.width, @@ -271,6 +274,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; static float vertices[8] = {-1, -1, 1, -1, 1, 1, @@ -303,41 +307,41 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, ptexcoords = texcoords_inv; /* Slow path, we need to flip y or wire alpha to 1. */ - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), ptexcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glamor_set_destination_pixmap_priv_nc(pixmap_priv); - glGenTextures(1, &tex); + dispatch->glGenTextures(1, &tex); __glamor_upload_pixmap_to_texture(pixmap, format, type, tex); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); #ifndef GLAMOR_GLES2 - glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif - glUseProgram(glamor_priv->finish_access_prog[no_alpha]); - glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); - glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0); + dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); #ifndef GLAMOR_GLES2 - glDisable(GL_TEXTURE_2D); + dispatch->glDisable(GL_TEXTURE_2D); #endif - glUseProgram(0); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glDeleteTextures(1, &tex); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + dispatch->glUseProgram(0); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDeleteTextures(1, &tex); + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0); } void @@ -345,16 +349,18 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap) { int status; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch; + if (pixmap_priv->fb == 0) - glGenFramebuffers(1, &pixmap_priv->fb); + dispatch->glGenFramebuffers(1, &pixmap_priv->fb); assert(pixmap_priv->tex != 0); - glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); - glFramebufferTexture2D(GL_FRAMEBUFFER, + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); + dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pixmap_priv->tex, 0); - status = glCheckFramebufferStatus (GL_FRAMEBUFFER); + status = dispatch->glCheckFramebufferStatus (GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { const char *str; switch (status) { @@ -387,6 +393,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert) int need_fbo; glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width , pixmap->drawable.height) || !glamor_check_fbo_depth(pixmap->drawable.depth)) { @@ -404,13 +411,13 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert) need_fbo = 0; if (pixmap_priv->tex == 0) - glGenTextures(1, &pixmap_priv->tex); + dispatch->glGenTextures(1, &pixmap_priv->tex); if (need_fbo) { - glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, + dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, pixmap->drawable.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glamor_pixmap_ensure_fb(pixmap); @@ -498,6 +505,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, ScreenPtr screen; PixmapPtr temp_pixmap; glamor_pixmap_private *temp_pixmap_priv; + glamor_gl_dispatch *dispatch; static float vertices[8] = {-1, -1, 1, -1, 1, 1, @@ -513,6 +521,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, glamor_priv = glamor_get_screen_private(screen); source_priv = glamor_get_pixmap_private(source); + dispatch = &glamor_priv->dispatch; if (*format == GL_BGRA) { *format = GL_RGBA; swap_rb = 1; @@ -527,36 +536,35 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); - glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex); - glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, + dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex); + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, source->drawable.height, 0, *format, *type, NULL); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, source_priv->tex); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex); glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv); - glUseProgram(glamor_priv->finish_access_prog[no_alpha]); - glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); - glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb); + dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); - glFlush(); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(0); return temp_pixmap; } @@ -583,6 +591,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) ScreenPtr screen; glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; screen = pixmap->drawable.pScreen; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) @@ -641,43 +650,43 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ROW_LENGTH, row_length); + dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1); + dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length); } else { - glPixelStorei(GL_PACK_ALIGNMENT, 4); - // glPixelStorei(GL_PACK_ROW_LENGTH, 0); + dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4); + // dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0); } - if (glamor_priv->has_pack_invert || glamor_priv->yInverted) { if (!glamor_priv->yInverted) { assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - glPixelStorei(GL_PACK_INVERT_MESA, 1); + dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1); } if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (pixmap_priv->pbo == 0) - glGenBuffers (1, &pixmap_priv->pbo); - glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); - glBufferData (GL_PIXEL_PACK_BUFFER, + dispatch->glGenBuffers (1, &pixmap_priv->pbo); + dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); + dispatch->glBufferData (GL_PIXEL_PACK_BUFFER, stride * pixmap->drawable.height, NULL, gl_usage); - glReadPixels (0, 0, + dispatch->glReadPixels (0, 0, row_length, pixmap->drawable.height, format, type, 0); - data = glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access); + data = dispatch->glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access); pixmap_priv->pbo_valid = TRUE; if (!glamor_priv->yInverted) { assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - glPixelStorei(GL_PACK_INVERT_MESA, 0); + dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0); } - glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); + dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); + } else { if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) type = GL_UNSIGNED_SHORT_5_5_5_1; - glReadPixels (0, 0, + dispatch->glReadPixels (0, 0, pixmap->drawable.width, pixmap->drawable.height, format, type, data); } @@ -686,32 +695,31 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) assert(data); if (access != GLAMOR_ACCESS_WO) { if (pixmap_priv->pbo == 0) - glGenBuffers(1, &pixmap_priv->pbo); - glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); - glBufferData(GL_PIXEL_PACK_BUFFER, + dispatch->glGenBuffers(1, &pixmap_priv->pbo); + dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); + dispatch->glBufferData(GL_PIXEL_PACK_BUFFER, stride * pixmap->drawable.height, NULL, GL_STREAM_READ); - glReadPixels (0, 0, row_length, pixmap->drawable.height, + dispatch->glReadPixels (0, 0, row_length, pixmap->drawable.height, format, type, 0); - read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); + read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); for (y = 0; y < pixmap->drawable.height; y++) memcpy(data + y * stride, read + (pixmap->drawable.height - y - 1) * stride, stride); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); pixmap_priv->pbo_valid = FALSE; - glDeleteBuffers(1, &pixmap_priv->pbo); + dispatch->glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->pbo = 0; } } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0); done: pixmap->devPrivate.ptr = data; if (temp_pixmap) { - glFlush(); (*screen->DestroyPixmap)(temp_pixmap); } @@ -724,14 +732,15 @@ static void _glamor_destroy_upload_pixmap(PixmapPtr pixmap) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch; assert(pixmap_priv->gl_fbo == 0); if (pixmap_priv->fb) - glDeleteFramebuffers(1, &pixmap_priv->fb); + dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb); if (pixmap_priv->tex) - glDeleteTextures(1, &pixmap_priv->tex); + dispatch->glDeleteTextures(1, &pixmap_priv->tex); if (pixmap_priv->pbo) - glDeleteBuffers(1, &pixmap_priv->pbo); + dispatch->glDeleteBuffers(1, &pixmap_priv->pbo); pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0; } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 325fa4343..0cbc258f3 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -178,6 +178,8 @@ enum shader_in { SHADER_IN_COUNT, }; +#include "glamor_gl_dispatch.h" + struct glamor_screen_private; struct glamor_pixmap_private; typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, @@ -251,6 +253,7 @@ typedef struct glamor_screen_private { glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; Bool glyph_cache_initialized; + struct glamor_gl_dispatch dispatch; } glamor_screen_private; typedef enum glamor_access { @@ -310,18 +313,18 @@ typedef struct glamor_pixmap_private { PictFormatShort pict_format; glamor_pending_op pending_op; PixmapPtr container; + glamor_screen_private *glamor_priv; } glamor_pixmap_private; -#define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \ +#define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \ { \ if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \ - glUseProgram(_glamor_priv_->solid_prog); \ - glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1, \ + _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \ + _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1, \ _pixmap_priv_->pending_op.fill.color4fv); \ } \ } while(0) - /* * Pixmap dynamic status, used by dynamic upload feature. * @@ -752,8 +755,8 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, 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(GLenum type, const char *source); -void glamor_link_glsl_prog(GLint prog); +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); @@ -770,7 +773,7 @@ PixmapPtr glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, GLenum *type, int no_alpha, int no_revert); -void glamor_set_alu(unsigned char alu); +void glamor_set_alu(struct glamor_gl_dispatch * dispatch, unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); void glamor_get_transform_uniform_locations(GLint prog, glamor_transform_uniforms *uniform_locations); diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index a7a6186ee..cdcde5e7e 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -67,25 +67,25 @@ glamor_init_putimage_shaders(ScreenPtr screen) if (!GLEW_ARB_fragment_shader) return; - prog = glCreateProgram(); + prog = dispatch->glCreateProgram(); vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs); - glAttachShader(prog, vs_prog); - glAttachShader(prog, fs_prog); + dispatch->glAttachShader(prog, vs_prog); + dispatch->glAttachShader(prog, fs_prog); glamor_link_glsl_prog(prog); - glUseProgram(prog); - sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler"); - glUniform1i(sampler_uniform_location, 0); + dispatch->glUseProgram(prog); + sampler_uniform_location = dispatch->glGetUniformLocation(prog, "bitmap_sampler"); + dispatch->glUniform1i(sampler_uniform_location, 0); glamor_priv->put_image_xybitmap_fg_uniform_location = - glGetUniformLocation(prog, "fg"); + dispatch->glGetUniformLocation(prog, "fg"); glamor_priv->put_image_xybitmap_bg_uniform_location = - glGetUniformLocation(prog, "bg"); + dispatch->glGetUniformLocation(prog, "bg"); glamor_get_transform_uniform_locations(prog, &glamor_priv->put_image_xybitmap_transform); glamor_priv->put_image_xybitmap_prog = prog; - glUseProgram(0); + dispatch->glUseProgram(0); #endif } @@ -162,42 +162,42 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, if (!glamor_set_planemask(pixmap, gc->planemask)) goto fail; - glUseProgram(glamor_priv->put_image_xybitmap_prog); + dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog); glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); - glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, + dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg); glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); - glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location, + dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); - glGenTextures(1, &tex); - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, + dispatch->glGenTextures(1, &tex); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glEnable(GL_TEXTURE_2D); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); + dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glEnable(GL_TEXTURE_2D); + dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + dispatch->glEnable(GL_TEXTURE_2D); /* Now that we've set up our bitmap texture and the shader, shove * the destination rectangle through the cliprects and run the * shader on the resulting fragments. */ - glVertexPointer(2, GL_FLOAT, 0, dest_coords); - glEnableClientState(GL_VERTEX_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords); + dispatch->glEnableClientState(GL_VERTEX_ARRAY); + dispatch->glClientActiveTexture(GL_TEXTURE0); + dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); + dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnable(GL_SCISSOR_TEST); + dispatch->glEnable(GL_SCISSOR_TEST); clip = fbGetCompositeClip(gc); for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); @@ -220,20 +220,20 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, if (x1 >= x2 || y1 >= y2) continue; - glScissor(box->x1, + dispatch->glScissor(box->x1, y_flip(pixmap, box->y1), box->x2 - box->x1, box->y2 - box->y1); - glDrawArrays(GL_QUADS, 0, 4); + dispatch->glDrawArrays(GL_QUADS, 0, 4); } - glDisable(GL_SCISSOR_TEST); + dispatch->glDisable(GL_SCISSOR_TEST); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); - glDeleteTextures(1, &tex); - glDisable(GL_TEXTURE_2D); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + dispatch->glDeleteTextures(1, &tex); + dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glDisableClientState(GL_VERTEX_ARRAY); + dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY); return; glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); @@ -254,6 +254,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, { glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); GLenum type, format, iformat; @@ -285,7 +286,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (!glamor_set_planemask(pixmap, gc->planemask)) { goto fail; } - glamor_set_alu(gc->alu); + glamor_set_alu(dispatch, gc->alu); if (glamor_get_tex_format_type_from_pixmap(pixmap, &format, @@ -301,29 +302,29 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, /* XXX consider to reuse a function to do the following work. */ glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_validate_pixmap(pixmap); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / + dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / pixmap->drawable.bitsPerPixel); } else { - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); -// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); +// dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } - glGenTextures(1, &tex); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); + dispatch->glGenTextures(1, &tex); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { iformat = format; } @@ -331,19 +332,19 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, iformat = GL_RGBA; } - glTexImage2D(GL_TEXTURE_2D, 0, iformat, + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); #ifndef GLAMOR_GLES2 - glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif - glUseProgram(glamor_priv->finish_access_prog[no_alpha]); - glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); - glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0); + dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0); x += drawable->x; y += drawable->y; @@ -388,19 +389,19 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glamor_priv->yInverted, vertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } #ifndef GLAMOR_GLES2 - glDisable(GL_TEXTURE_2D); + dispatch->glDisable(GL_TEXTURE_2D); #endif - glUseProgram(0); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glDeleteTextures(1, &tex); + dispatch->glUseProgram(0); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDeleteTextures(1, &tex); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glamor_set_alu(GXcopy); + dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glamor_set_alu(dispatch, GXcopy); glamor_set_planemask(pixmap, ~0); return; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 258a09b9d..d649c9813 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -68,7 +68,7 @@ static struct blendinfo composite_op_info[] = { }; static GLuint -glamor_create_composite_fs(struct shader_key *key) +glamor_create_composite_fs(glamor_gl_dispatch *dispatch, struct shader_key *key) { const char *source_solid_fetch = GLAMOR_DEFAULT_PRECISION @@ -200,14 +200,14 @@ glamor_create_composite_fs(struct shader_key *key) in); - prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source); + prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source); free(source); return prog; } static GLuint -glamor_create_composite_vs(struct shader_key *key) +glamor_create_composite_vs(glamor_gl_dispatch *dispatch, struct shader_key *key) { const char *main_opening = "attribute vec4 v_position;\n" @@ -242,7 +242,7 @@ glamor_create_composite_vs(struct shader_key *key) mask_coords_setup, main_closing); - prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source); + prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source); free(source); return prog; @@ -254,45 +254,47 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, { GLuint vs, fs, prog; GLint source_sampler_uniform_location, mask_sampler_uniform_location; + glamor_screen_private *glamor = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor->dispatch; - vs = glamor_create_composite_vs(key); + vs = glamor_create_composite_vs(dispatch, key); if (vs == 0) return; - fs = glamor_create_composite_fs(key); + fs = glamor_create_composite_fs(dispatch, key); if (fs == 0) return; - prog = glCreateProgram(); - glAttachShader(prog, vs); - glAttachShader(prog, fs); + prog = dispatch->glCreateProgram(); + dispatch->glAttachShader(prog, vs); + dispatch->glAttachShader(prog, fs); - glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); + dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); - glamor_link_glsl_prog(prog); + glamor_link_glsl_prog(dispatch, prog); shader->prog = prog; - glUseProgram(prog); + dispatch->glUseProgram(prog); if (key->source == SHADER_SOURCE_SOLID) { - shader->source_uniform_location = glGetUniformLocation(prog, + shader->source_uniform_location = dispatch->glGetUniformLocation(prog, "source"); } else { - source_sampler_uniform_location = glGetUniformLocation(prog, + source_sampler_uniform_location = dispatch->glGetUniformLocation(prog, "source_sampler"); - glUniform1i(source_sampler_uniform_location, 0); + dispatch->glUniform1i(source_sampler_uniform_location, 0); } if (key->mask != SHADER_MASK_NONE) { if (key->mask == SHADER_MASK_SOLID) { - shader->mask_uniform_location = glGetUniformLocation(prog, + shader->mask_uniform_location = dispatch->glGetUniformLocation(prog, "mask"); } else { - mask_sampler_uniform_location = glGetUniformLocation(prog, + mask_sampler_uniform_location = dispatch->glGetUniformLocation(prog, "mask_sampler"); - glUniform1i(mask_sampler_uniform_location, 1); + dispatch->glUniform1i(mask_sampler_uniform_location, 1); } } } @@ -336,6 +338,8 @@ glamor_set_composite_op(ScreenPtr screen, { GLenum source_blend, dest_blend; struct blendinfo *op_info; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; if (op >= ARRAY_SIZE(composite_op_info)) { glamor_fallback("unsupported render op %d \n", op); @@ -370,10 +374,10 @@ glamor_set_composite_op(ScreenPtr screen, } if (source_blend == GL_ONE && dest_blend == GL_ZERO) { - glDisable(GL_BLEND); + dispatch->glDisable(GL_BLEND); } else { - glEnable(GL_BLEND); - glBlendFunc(source_blend, dest_blend); + dispatch->glEnable(GL_BLEND); + dispatch->glBlendFunc(source_blend, dest_blend); } return TRUE; } @@ -382,50 +386,52 @@ static void glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glamor_pixmap_private *pixmap_priv) { - glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; + dispatch->glActiveTexture(GL_TEXTURE0 + unit); + dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); switch (picture->repeatType) { case RepeatNone: #ifndef GLAMOR_GLES2 /* XXX GLES2 doesn't support GL_CLAMP_TO_BORDER. */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); #endif break; case RepeatNormal: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); break; case RepeatPad: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); break; case RepeatReflect: - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); break; } switch (picture->filter) { case PictFilterNearest: - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; case PictFilterBilinear: default: - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; } #ifndef GLAMOR_GLES2 - glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif } static void -glamor_set_composite_solid(float *color, GLint uniform_location) +glamor_set_composite_solid(glamor_gl_dispatch *dispatch, float *color, GLint uniform_location) { - glUniform4fv(uniform_location, 1, color); + dispatch->glUniform4fv(uniform_location, 1, color); } static int @@ -525,6 +531,7 @@ static void glamor_setup_composite_vbo(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_priv->vb_stride = 2 * sizeof(float); if (glamor_priv->has_source_coords) @@ -532,27 +539,27 @@ glamor_setup_composite_vbo(ScreenPtr screen) if (glamor_priv->has_mask_coords) glamor_priv->vb_stride += 2 * sizeof(float); - glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset)); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); if (glamor_priv->has_source_coords) { - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float))); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); } if (glamor_priv->has_mask_coords) { - glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, glamor_priv->vb_stride, (void *)((long)glamor_priv->vbo_offset + (glamor_priv->has_source_coords ? 4 : 2) * sizeof(float))); - glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); } } @@ -586,13 +593,13 @@ static void glamor_flush_composite_rects(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; if (!glamor_priv->render_nr_verts) return; - glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb, + dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb, GL_STREAM_DRAW); - glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts); + dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts); glamor_reset_composite_vbo(screen); } @@ -603,6 +610,7 @@ glamor_emit_composite_rect(ScreenPtr screen, const float *dst_coords) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride > glamor_priv->vbo_size) @@ -612,7 +620,7 @@ glamor_emit_composite_rect(ScreenPtr screen, if (glamor_priv->vbo_offset == 0) { if (glamor_priv->vbo == 0) - glGenBuffers(1, &glamor_priv->vbo); + dispatch->glGenBuffers(1, &glamor_priv->vbo); glamor_setup_composite_vbo(screen); } @@ -700,6 +708,7 @@ glamor_composite_with_shader(CARD8 op, { ScreenPtr screen = dest->pDrawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; glamor_pixmap_private *source_pixmap_priv = NULL; @@ -914,17 +923,17 @@ glamor_composite_with_shader(CARD8 op, goto fail; } - glUseProgram(shader->prog); + dispatch->glUseProgram(shader->prog); if (key.source == SHADER_SOURCE_SOLID) { - glamor_set_composite_solid(source_solid_color, shader->source_uniform_location); + glamor_set_composite_solid(dispatch, source_solid_color, shader->source_uniform_location); } else { glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); } if (key.mask != SHADER_MASK_NONE) { if (key.mask == SHADER_MASK_SOLID) { - glamor_set_composite_solid(mask_solid_color, shader->mask_uniform_location); + glamor_set_composite_solid(dispatch, mask_solid_color, shader->mask_uniform_location); } else { glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); } @@ -1042,19 +1051,19 @@ glamor_composite_with_shader(CARD8 op, } glamor_flush_composite_rects(screen); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); REGION_UNINIT(dst->pDrawable->pScreen, ®ion); - glDisable(GL_BLEND); + dispatch->glDisable(GL_BLEND); #ifndef GLAMOR_GLES2 - glActiveTexture(GL_TEXTURE0); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glActiveTexture(GL_TEXTURE1); + dispatch->glDisable(GL_TEXTURE_2D); #endif - glUseProgram(0); + dispatch->glUseProgram(0); if (saved_source_format) source->format = saved_source_format; return TRUE; @@ -1063,8 +1072,8 @@ glamor_composite_with_shader(CARD8 op, if (saved_source_format) source->format = saved_source_format; - glDisable(GL_BLEND); - glUseProgram(0); + dispatch->glDisable(GL_BLEND); + dispatch->glUseProgram(0); return FALSE; } @@ -1138,6 +1147,7 @@ glamor_composite(CARD8 op, int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; glamor_composite_rect_t rect; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; x_temp_src = x_source; y_temp_src = y_source; @@ -1257,8 +1267,8 @@ fail: dest->pDrawable->height, glamor_get_picture_location(dest)); - glUseProgram(0); - glDisable(GL_BLEND); + dispatch->glUseProgram(0); + dispatch->glDisable(GL_BLEND); if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO)) { diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 8b2676b4b..bb4bffdd9 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -36,7 +36,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int n, int sorted) { PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); - glamor_screen_private *glamor_priv; + glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; GLenum format, type; int no_alpha, no_revert, i; uint8_t *drawpixels_src = (uint8_t *)src; @@ -44,8 +45,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, BoxRec *pbox; int x_off, y_off; - glamor_priv = glamor_get_screen_private(drawable->pScreen); - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { glamor_fallback("ES2 fallback.\n"); goto fail; @@ -69,7 +68,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, glamor_validate_pixmap(dest_pixmap); if (!glamor_set_planemask(dest_pixmap, gc->planemask)) goto fail; - glamor_set_alu(gc->alu); + glamor_set_alu(dispatch, gc->alu); if (!glamor_set_planemask(dest_pixmap, gc->planemask)) goto fail; @@ -82,14 +81,14 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, while (n--) { if (pbox->y1 > points[i].y) break; - glScissor(pbox->x1, + dispatch->glScissor(pbox->x1, points[i].y + y_off, pbox->x2 - pbox->x1, 1); - glEnable(GL_SCISSOR_TEST); - glRasterPos2i(points[i].x + x_off, + dispatch->glEnable(GL_SCISSOR_TEST); + dispatch->glRasterPos2i(points[i].x + x_off, points[i].y + y_off); - glDrawPixels(widths[i], + dispatch->glDrawPixels(widths[i], 1, format, type, drawpixels_src); @@ -97,8 +96,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, drawpixels_src += PixmapBytePad(widths[i], drawable->depth); } glamor_set_planemask(dest_pixmap, ~0); - glamor_set_alu(GXcopy); - glDisable(GL_SCISSOR_TEST); + glamor_set_alu(dispatch, GXcopy); + dispatch->glDisable(GL_SCISSOR_TEST); return; fail: diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index c184dac26..687cc6a41 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -40,6 +40,7 @@ void glamor_init_tile_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; const char *tile_vs = "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" @@ -60,21 +61,21 @@ glamor_init_tile_shader(ScreenPtr screen) GLint fs_prog, vs_prog; GLint sampler_uniform_location; - glamor_priv->tile_prog = glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs); - glAttachShader(glamor_priv->tile_prog, vs_prog); - glAttachShader(glamor_priv->tile_prog, fs_prog); + glamor_priv->tile_prog = dispatch->glCreateProgram(); + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs); + dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog); + dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog); - glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->tile_prog); + dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog); sampler_uniform_location = - glGetUniformLocation(glamor_priv->tile_prog, "sampler"); - glUseProgram(glamor_priv->tile_prog); - glUniform1i(sampler_uniform_location, 0); - glUseProgram(0); + dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler"); + dispatch->glUseProgram(glamor_priv->tile_prog); + dispatch->glUniform1i(sampler_uniform_location, 0); + dispatch->glUseProgram(0); } Bool @@ -85,6 +86,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; int x1 = x; int x2 = x + width; int y1 = y; @@ -135,33 +137,33 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_validate_pixmap(pixmap); pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); - glamor_set_alu(alu); + glamor_set_alu(dispatch, alu); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - glUseProgram(glamor_priv->tile_prog); + dispatch->glUseProgram(glamor_priv->tile_prog); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); #ifndef GLAMOR_GLES2 - glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif glamor_set_normalize_tcoords(src_xscale, src_yscale, tile_x1, tile_y1, tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords); - glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), source_texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); } else { - GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); + GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv); } glamor_set_normalize_vcoords(dst_xscale, dst_yscale, @@ -169,21 +171,21 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glamor_priv->yInverted, vertices); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); #ifndef GLAMOR_GLES2 - glDisable(GL_TEXTURE_2D); + dispatch->glDisable(GL_TEXTURE_2D); #endif } - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(0); - glamor_set_alu(GXcopy); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glUseProgram(0); + glamor_set_alu(dispatch, GXcopy); glamor_set_planemask(pixmap, ~0); return TRUE; diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 9c9be894f..90357d201 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -584,6 +584,18 @@ glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin) } } +Bool +glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_screen_private *glamor_egl = glamor_get_screen_private(scrn); + if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress)) + return FALSE; + glamor_egl->dispatch = dispatch; + return TRUE; +} + + static XF86ModuleVersionInfo glamor_version_info = { glamor_name, MODULEVENDORSTRING, diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index 6d9e410f0..2c14ca18e 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -16,6 +16,7 @@ #include #include +#include "glamor_gl_dispatch.h" struct glamor_screen_private { EGLDisplay display; EGLContext context; @@ -30,6 +31,7 @@ struct glamor_screen_private { PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; + struct glamor_gl_dispatch *dispatch; }; inline struct glamor_screen_private * From 2a9dfc963f610abfbf12d5efdf5ba5b3f55a4305 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 8 Sep 2011 15:14:43 +0800 Subject: [PATCH 209/225] glamor: Re-arrange some macros/definitions in header files. Signed-off-by: Zhigang Gong --- glamor/glamor_glext.h | 32 +++ glamor/glamor_priv.h | 491 +++--------------------------------------- glamor/glamor_utils.h | 380 ++++++++++++++++++++++++++++++++ 3 files changed, 445 insertions(+), 458 deletions(-) create mode 100644 glamor/glamor_glext.h diff --git a/glamor/glamor_glext.h b/glamor/glamor_glext.h new file mode 100644 index 000000000..f734d1313 --- /dev/null +++ b/glamor/glamor_glext.h @@ -0,0 +1,32 @@ +#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 + +#endif diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 0cbc258f3..5f82c7883 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -35,89 +35,26 @@ #include "glamor.h" -#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 glMapBuffer(x, y) NULL -#define glUnmapBuffer(x) -#define glRasterPos2i(x,y) -#define glDrawPixels(x,y,z,a,b) - -#endif - #define GL_GLEXT_PROTOTYPES + #ifdef GLAMOR_GLES2 #include #include -#define GLAMOR_DEFAULT_PRECISION \ - "precision mediump float;\n" - +#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" -#define glamor_check_fbo_size(_glamor_,_w_, _h_) ((_w_) > 0 && (_h_) > 0 \ - && (_w_) < _glamor_->max_fbo_size \ - && (_h_) < _glamor_->max_fbo_size) - -#define glamor_check_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->is_picture == 1) -#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == 1) - -typedef struct glamor_transform_uniforms { - GLint x_bias; - GLint x_scale; - GLint y_bias; - GLint y_scale; -} glamor_transform_uniforms; - typedef struct glamor_composite_shader { GLuint prog; GLint dest_to_dest_uniform_location; @@ -138,16 +75,6 @@ typedef struct { INT16 height; } glamor_composite_rect_t; -#define GLAMOR_NUM_GLYPH_CACHES 4 -#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 - -typedef struct { - PicturePtr picture; /* Where the glyphs of the cache are stored */ - GlyphPtr *glyphs; - uint16_t count; - uint16_t evict; -} glamor_glyph_cache_t; - enum glamor_vertex_type { GLAMOR_VERTEX_POS, @@ -178,8 +105,6 @@ enum shader_in { SHADER_IN_COUNT, }; -#include "glamor_gl_dispatch.h" - struct glamor_screen_private; struct glamor_pixmap_private; typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, @@ -191,6 +116,20 @@ enum glamor_gl_flavor { }; #define GLAMOR_CREATE_PIXMAP_CPU 0x100 + +#define GLAMOR_NUM_GLYPH_CACHES 4 +#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 + +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" + typedef struct glamor_screen_private { CloseScreenProcPtr saved_close_screen; CreateGCProcPtr saved_create_gc; @@ -235,7 +174,6 @@ typedef struct glamor_screen_private { /* glamor_putimage */ GLint put_image_xybitmap_prog; - glamor_transform_uniforms put_image_xybitmap_transform; GLint put_image_xybitmap_fg_uniform_location; GLint put_image_xybitmap_bg_uniform_location; @@ -252,7 +190,6 @@ typedef struct glamor_screen_private { glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; Bool glyph_cache_initialized; - struct glamor_gl_dispatch dispatch; } glamor_screen_private; @@ -262,28 +199,6 @@ typedef enum glamor_access { GLAMOR_ACCESS_WO, } glamor_access_t; -/* - * glamor_pixmap_private - glamor pixmap's private structure. - * @gl_fbo: The pixmap is attached to a fbo originally. - * @gl_tex: The pixmap is in a gl texture originally. - * @pbo_valid: The pbo has a valid copy of the pixmap's data. - * @is_picture: The drawable is attached to a picture. - * @tex: attached texture. - * @fb: attached fbo. - * @pbo: attached pbo. - * @access_mode: access mode during the prepare/finish pair. - * @pict_format: the corresponding picture's format. - * #pending_op: currently only support pending filling. - * @container: The corresponding pixmap's pointer. - **/ - -#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv) \ - (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \ - && (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE)) - -#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv) \ - (pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE) - enum _glamor_pending_op_type{ GLAMOR_PENDING_NONE, GLAMOR_PENDING_FILL @@ -300,6 +215,20 @@ typedef union _glamor_pending_op { glamor_pending_fill fill; } glamor_pending_op; +/* + * glamor_pixmap_private - glamor pixmap's private structure. + * @gl_fbo: The pixmap is attached to a fbo originally. + * @gl_tex: The pixmap is in a gl texture originally. + * @pbo_valid: The pbo has a valid copy of the pixmap's data. + * @is_picture: The drawable is attached to a picture. + * @tex: attached texture. + * @fb: attached fbo. + * @pbo: attached pbo. + * @access_mode: access mode during the prepare/finish pair. + * @pict_format: the corresponding picture's format. + * #pending_op: currently only support pending filling. + * @container: The corresponding pixmap's pointer. + **/ typedef struct glamor_pixmap_private { unsigned char gl_fbo:1; @@ -316,15 +245,6 @@ typedef struct glamor_pixmap_private { glamor_screen_private *glamor_priv; } glamor_pixmap_private; -#define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \ - { \ - if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \ - _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \ - _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1, \ - _pixmap_priv_->pending_op.fill.color4fv); \ - } \ - } while(0) - /* * Pixmap dynamic status, used by dynamic upload feature. * @@ -356,347 +276,6 @@ glamor_get_pixmap_private(PixmapPtr pixmap) return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); } -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -/** - * 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 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->pict_format; - else - pict_format = format_for_depth(pixmap->drawable.depth); - - return pict_format; -} - -/* - * 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. - * - * 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 *no_revert) -{ - *no_alpha = 0; - *no_revert = 1; - switch (format) { - case PICT_a1: - *tex_format = GL_COLOR_INDEX; - *tex_type = GL_BITMAP; - 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; -} -#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 *no_revert) -{ - *no_alpha = 0; - *no_revert = IS_LITTLE_ENDIAN; - - switch (format) { - case PICT_b8g8r8x8: - *no_alpha = 1; - case PICT_b8g8r8a8: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_BYTE; - *no_revert = !IS_LITTLE_ENDIAN; - break; - - case PICT_x8r8g8b8: - *no_alpha = 1; - case PICT_a8r8g8b8: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_BYTE; - 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_BGRA; - *tex_type = GL_UNSIGNED_INT_10_10_10_2; - *no_revert = TRUE; - break; - - case PICT_x2b10g10r10: - *no_alpha = 1; - case PICT_a2b10g10r10: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_INT_10_10_10_2; - *no_revert = TRUE; - break; - - case PICT_r5g6b5: - *tex_format = GL_RGB; - *tex_type = GL_UNSIGNED_SHORT_5_6_5; - *no_revert = TRUE; - break; - - case PICT_b5g6r5: - *tex_format = GL_RGB; - *tex_type = GL_UNSIGNED_SHORT_5_6_5; - *no_revert = FALSE; - break; - - case PICT_x1b5g5r5: - *no_alpha = 1; - case PICT_a1b5g5r5: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - *no_revert = TRUE; - break; - - case PICT_x1r5g5b5: - *no_alpha = 1; - case PICT_a1r5g5b5: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - *no_revert = TRUE; - break; - - case PICT_a8: - *tex_format = GL_ALPHA; - *tex_type = GL_UNSIGNED_BYTE; - *no_revert = TRUE; - break; - - case PICT_x4r4g4b4: - *no_alpha = 1; - case PICT_a4r4g4b4: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; - *no_revert = TRUE; - break; - - case PICT_x4b4g4r4: - *no_alpha = 1; - case PICT_a4b4g4r4: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; - *no_revert = TRUE; - break; - - default: - LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format); - return -1; - } - return 0; -} - - -#endif - - -static inline int -glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, - GLenum *format, - GLenum *type, - int *no_alpha, - int *no_revert) -{ - 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->pict_format; - else - pict_format = format_for_depth(pixmap->drawable.depth); - - return glamor_get_tex_format_type_from_pictformat(pict_format, - format, type, - no_alpha, no_revert); -} - - -/* 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; -} - /** * Returns TRUE if the given planemask covers all the significant bits in the @@ -775,10 +354,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, void glamor_set_alu(struct glamor_gl_dispatch * dispatch, unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); -void glamor_get_transform_uniform_locations(GLint prog, - glamor_transform_uniforms *uniform_locations); -void glamor_set_transform_for_pixmap(PixmapPtr pixmap, - glamor_transform_uniforms *uniform_locations); Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); Bool glamor_gl_has_extension(char *extension); @@ -977,6 +552,8 @@ glamor_upload_picture_to_texture(PicturePtr picture); void glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv); +#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, @@ -984,11 +561,9 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr * fallback the whole process to cpu. Most of the time, * this will increase performance obviously. */ - #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD #define GLAMOR_DELAYED_FILLING -#include"glamor_utils.h" #endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index 30432cf1f..fe5bd4e1e 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -159,4 +159,384 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy) boxes[i].y2 += dy; } } + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) +#define MIN(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) + +#define glamor_check_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->is_picture == 1) +#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == 1) + +#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv) \ + (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \ + && (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE)) + +#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv) \ + (pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE) + +#define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \ + { \ + if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \ + _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \ + _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1, \ + _pixmap_priv_->pending_op.fill.color4fv); \ + } \ + } while(0) + + +/** + * 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 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->pict_format; + else + pict_format = format_for_depth(pixmap->drawable.depth); + + return pict_format; +} + +/* + * 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. + * + * 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 *no_revert) +{ + *no_alpha = 0; + *no_revert = 1; + switch (format) { + case PICT_a1: + *tex_format = GL_COLOR_INDEX; + *tex_type = GL_BITMAP; + 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; +} +#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 *no_revert) +{ + *no_alpha = 0; + *no_revert = IS_LITTLE_ENDIAN; + + switch (format) { + case PICT_b8g8r8x8: + *no_alpha = 1; + case PICT_b8g8r8a8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_BYTE; + *no_revert = !IS_LITTLE_ENDIAN; + break; + + case PICT_x8r8g8b8: + *no_alpha = 1; + case PICT_a8r8g8b8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_BYTE; + 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_BGRA; + *tex_type = GL_UNSIGNED_INT_10_10_10_2; + *no_revert = TRUE; + break; + + case PICT_x2b10g10r10: + *no_alpha = 1; + case PICT_a2b10g10r10: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_INT_10_10_10_2; + *no_revert = TRUE; + break; + + case PICT_r5g6b5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + *no_revert = TRUE; + break; + + case PICT_b5g6r5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + *no_revert = FALSE; + break; + + case PICT_x1b5g5r5: + *no_alpha = 1; + case PICT_a1b5g5r5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *no_revert = TRUE; + break; + + case PICT_x1r5g5b5: + *no_alpha = 1; + case PICT_a1r5g5b5: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *no_revert = TRUE; + break; + + case PICT_a8: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *no_revert = TRUE; + break; + + case PICT_x4r4g4b4: + *no_alpha = 1; + case PICT_a4r4g4b4: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + *no_revert = TRUE; + break; + + case PICT_x4b4g4r4: + *no_alpha = 1; + case PICT_a4b4g4r4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + *no_revert = TRUE; + break; + + default: + LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format); + return -1; + } + return 0; +} + + +#endif + + +static inline int +glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, + GLenum *format, + GLenum *type, + int *no_alpha, + int *no_revert) +{ + 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->pict_format; + else + pict_format = format_for_depth(pixmap->drawable.depth); + + return glamor_get_tex_format_type_from_pictformat(pict_format, + format, type, + no_alpha, no_revert); +} + + +/* 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; +} + + + + + + #endif From 67dbe0ddf87a6dd602d3d4a6049072f6386d757e Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 8 Sep 2011 15:16:01 +0800 Subject: [PATCH 210/225] glamor-egl: Added new function to create image for a pixmap. This function is used to support dri2. In the underlying driver, it will create a buffer object for a given pixmap. And then call this api to create a egl image from that buffer object, and then bind that image to a texture, and then bind that texture to the pixmap. Normally, this pixmap's content is shared between a dri2 client and the x server. Signed-off-by: Zhigang Gong --- glamor/glamor_egl.c | 193 ++++++++++++++++++++++++++++---------------- 1 file changed, 125 insertions(+), 68 deletions(-) diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 773f90e2e..d95828e55 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -54,7 +54,7 @@ #define GLAMOR_FOR_XORG #include -#include +#include "glamor_gl_dispatch.h" #define GLAMOR_VERSION_MAJOR 0 #define GLAMOR_VERSION_MINOR 1 @@ -68,13 +68,12 @@ glamor_identify(int flags) xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n", glamor_name); } -struct glamor_screen_private { +struct glamor_egl_screen_private { EGLDisplay display; EGLContext context; EGLImageKHR root; EGLint major, minor; - CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; int fd; @@ -90,19 +89,15 @@ struct glamor_screen_private { int xf86GlamorEGLPrivateIndex = -1; -static struct glamor_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn) +static struct glamor_egl_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn) { - return (struct glamor_screen_private *) scrn->privates[xf86GlamorEGLPrivateIndex].ptr; + return (struct glamor_egl_screen_private *) scrn->privates[xf86GlamorEGLPrivateIndex].ptr; } -static Bool -_glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int stride) +static EGLImageKHR +_glamor_create_egl_image(struct glamor_egl_screen_private *glamor_egl, int width, int height, int stride, int name) { - - struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); - ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; EGLImageKHR image; - GLuint texture; EGLint attribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, @@ -113,64 +108,122 @@ _glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int str EGL_NONE }; - if (glamor->root) { - eglDestroyImageKHR(glamor->display, glamor->root); - glamor->root = EGL_NO_IMAGE_KHR; - } - + attribs[1] = width; attribs[3] = height; attribs[5] = stride / 4; - image = glamor->egl_create_image_khr (glamor->display, - glamor->context, - EGL_DRM_BUFFER_MESA, - (void*)glamor->front_buffer_handle, - attribs); + image = glamor_egl->egl_create_image_khr (glamor_egl->display, + glamor_egl->context, + EGL_DRM_BUFFER_MESA, + (void*)name, + attribs); if (image == EGL_NO_IMAGE_KHR) - return FALSE; + return EGL_NO_IMAGE_KHR; - glamor->dispatch->glGenTextures(1, &texture); - glamor->dispatch->glBindTexture(GL_TEXTURE_2D, texture); - glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); - - glamor_set_screen_pixmap_texture(screen, width, height, texture); - glamor->root = image; - return TRUE; + return image; } +static int +glamor_get_flink_name(int fd, int handle, int *name) +{ + struct drm_gem_flink flink; + flink.handle = handle; + if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) + return FALSE; + *name = flink.name; + return TRUE; +} + +static Bool +glamor_create_texture_from_image(struct glamor_egl_screen_private *glamor_egl, EGLImageKHR image, GLuint *texture) +{ + glamor_egl->dispatch->glGenTextures(1, texture); + glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture); + glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + (glamor_egl->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); + return TRUE; +} + + Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); - struct drm_gem_flink flink; - flink.handle = handle; + struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); + EGLImageKHR image; + GLuint texture; - if (ioctl(glamor->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, + if (!glamor_get_flink_name(glamor_egl->fd, handle, &glamor_egl->front_buffer_handle)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't flink front buffer handle\n"); - return FALSE; + return FALSE; } - glamor->front_buffer_handle = flink.name; + if (glamor_egl->root) { + eglDestroyImageKHR(glamor_egl->display, glamor_egl->root); + glamor_egl->root = EGL_NO_IMAGE_KHR; + } + + image = _glamor_create_egl_image( glamor_egl, + scrn->virtualX, + scrn->virtualY, + stride, + glamor_egl->front_buffer_handle); + if (image == EGL_NO_IMAGE_KHR) + return FALSE; + + glamor_create_texture_from_image(glamor_egl, image, &texture); + glamor_set_screen_pixmap_texture(screen, scrn->virtualX, scrn->virtualY, texture); + glamor_egl->root = image; + return TRUE; +} - return _glamor_create_egl_screen_image(scrn, scrn->virtualX, scrn->virtualY, stride); +/* + * This function will be called from the dri buffer allocation. + * It is somehow very familiar with the create screen image. + */ +Bool +glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); + EGLImageKHR image; + GLuint texture; + int name; + if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Couldn't flink pixmap handle\n"); + return FALSE; + } + + image = _glamor_create_egl_image( glamor_egl, + pixmap->drawable.width, + pixmap->drawable.height, + stride, + name); + if (image == EGL_NO_IMAGE_KHR) + return FALSE; + + glamor_create_texture_from_image(glamor_egl, image, &texture); + glamor_set_pixmap_texture(pixmap, pixmap->drawable.width, pixmap->drawable.height, texture); + return TRUE; } Bool glamor_close_egl_screen(ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); + struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); glamor_fini(screen); - eglDestroyImageKHR(glamor->display, glamor->root); + eglDestroyImageKHR(glamor_egl->display, glamor_egl->root); - glamor->root = EGL_NO_IMAGE_KHR; + glamor_egl->root = EGL_NO_IMAGE_KHR; return TRUE; } @@ -178,14 +231,14 @@ glamor_close_egl_screen(ScreenPtr screen) static Bool -glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension) +glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, char *extension) { const char *egl_extensions; char *pext; int ext_len; ext_len = strlen(extension); - egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS); + egl_extensions = (const char*)eglQueryString(glamor_egl->display, EGL_EXTENSIONS); pext = (char*)egl_extensions; if (pext == NULL || extension == NULL) @@ -201,7 +254,7 @@ glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension) Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) { - struct glamor_screen_private *glamor; + struct glamor_egl_screen_private *glamor_egl; const char *version; EGLint config_attribs[] = { #ifdef GLAMOR_GLES2 @@ -211,30 +264,30 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) }; glamor_identify(0); - glamor = calloc(sizeof(*glamor), 1); + glamor_egl = calloc(sizeof(*glamor_egl), 1); if (xf86GlamorEGLPrivateIndex == -1) xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); - scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor; + scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl; - glamor->fd = fd; - glamor->display = eglGetDRMDisplayMESA(glamor->fd); + glamor_egl->fd = fd; + glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd); #ifndef GLAMOR_GLES2 eglBindAPI(EGL_OPENGL_API); #else eglBindAPI(EGL_OPENGL_ES_API); #endif - if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) { + if (!eglInitialize(glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n"); return FALSE; } - version = eglQueryString(glamor->display, EGL_VERSION); + version = eglQueryString(glamor_egl->display, EGL_VERSION); xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); #define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ - if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) { \ + if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) { \ ErrorF("EGL_" #EXT "required.\n"); \ return FALSE; \ } @@ -247,37 +300,39 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl); #endif - glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA) + glamor_egl->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA) eglGetProcAddress("eglExportDRMImageMESA"); - glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) + glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); - glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) + glamor_egl->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES"); - if (!glamor->egl_create_image_khr - || !glamor->egl_export_drm_image_mesa - || !glamor->egl_image_target_texture2d_oes) { + if (!glamor_egl->egl_create_image_khr + || !glamor_egl->egl_export_drm_image_mesa + || !glamor_egl->egl_image_target_texture2d_oes) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglGetProcAddress() failed\n"); return FALSE; } - glamor->context = eglCreateContext(glamor->display, + glamor_egl->context = eglCreateContext(glamor_egl->display, NULL, EGL_NO_CONTEXT, config_attribs); - if (glamor->context == EGL_NO_CONTEXT) { + if (glamor_egl->context == EGL_NO_CONTEXT) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n"); return FALSE; } - if (!eglMakeCurrent(glamor->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) { + if (!eglMakeCurrent(glamor_egl->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to make EGL context current\n"); return FALSE; } + + return TRUE; } @@ -285,25 +340,27 @@ void glamor_free_egl_screen(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn); + struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); - if (glamor != NULL) + if (glamor_egl != NULL) { if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) { - eglMakeCurrent(glamor->display, + eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglTerminate(glamor->display); + eglTerminate(glamor_egl->display); } - free(glamor); + free(glamor_egl); } } +/* egl version. */ + Bool glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); + struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress)) return FALSE; glamor_egl->dispatch = dispatch; From 82a9b0c540dcf1064f5184c36a05d6216fb11034 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 16 Sep 2011 13:37:13 +0800 Subject: [PATCH 211/225] glamor-ddx: Change naming of glamor ddx module. Use glamor_ddx prefix for all standalone glamor ddx functions. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor.c | 110 ++++++++++++++++---------------- hw/xfree86/glamor/glamor_crtc.c | 2 +- hw/xfree86/glamor/glamor_ddx.h | 8 +-- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 90357d201..eef8eeb4f 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -49,19 +49,19 @@ #define GLAMOR_VERSION_MINOR 1 #define GLAMOR_VERSION_PATCH 0 -static const char glamor_name[] = "glamor"; +static const char glamor_ddx_name[] = "glamor"; static void -glamor_identify(int flags) +glamor_ddx_identify(int flags) { - xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver\n", glamor_name); + xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name); } Bool glamor_resize(ScrnInfoPtr scrn, int width, int height) { - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; EGLImageKHR image; GLuint texture; @@ -100,14 +100,14 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) void glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) { - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); EGLint name; (glamor->egl_export_drm_image_mesa)(glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch); } EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) { - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); EGLint attribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, @@ -124,14 +124,14 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor) { - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); eglDestroyImageKHR(glamor->display, cursor); } void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch) { - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); EGLint name; (glamor->egl_export_drm_image_mesa)(glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch); ErrorF("cursor stride: %d\n", *pitch); @@ -139,9 +139,9 @@ glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uin char * dri_device_name = "/dev/dri/card0"; static Bool -glamor_pre_init_ddx(ScrnInfoPtr scrn, int flags) +glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags) { - struct glamor_screen_private *glamor; + struct glamor_ddx_screen_private *glamor; rgb defaultWeight = { 0, 0, 0 }; glamor = xnfcalloc(sizeof *glamor, 1); @@ -193,15 +193,15 @@ fail: } static void -glamor_adjust_frame_ddx(int scrnIndex, int x, int y, int flags) +glamor_ddx_adjust_frame(int scrnIndex, int x, int y, int flags) { } static Bool -glamor_enter_vt_ddx(int scrnIndex, int flags) +glamor_ddx_enter_vt(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); if (drmSetMaster(glamor->fd)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -216,19 +216,19 @@ glamor_enter_vt_ddx(int scrnIndex, int flags) } static void -glamor_leave_vt_ddx(int scrnIndex, int flags) +glamor_ddx_leave_vt(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); drmDropMaster(glamor->fd); } static Bool -glamor_create_screen_resources_ddx(ScreenPtr screen) +glamor_ddx_create_screen_resources(ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); screen->CreateScreenResources = glamor->CreateScreenResources; if (!(*screen->CreateScreenResources) (screen)) @@ -243,16 +243,16 @@ glamor_create_screen_resources_ddx(ScreenPtr screen) } static Bool -glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen) +glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); screen->CloseScreen = glamor->CloseScreen; (*screen->CloseScreen) (scrnIndex, screen); if (scrn->vtSema == TRUE) - glamor_leave_vt_ddx(scrnIndex, 0); + glamor_ddx_leave_vt(scrnIndex, 0); glamor_fini(screen); @@ -274,7 +274,7 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen) static Bool -glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension) +glamor_egl_has_extension(struct glamor_ddx_screen_private *glamor, char *extension) { const char *egl_extensions; char *pext; @@ -297,10 +297,10 @@ glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension) static Bool -glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) +glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); const char *version; VisualPtr visual; EGLint config_attribs[] = { @@ -343,7 +343,7 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) } version = eglQueryString(glamor->display, EGL_VERSION); - xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); + xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_ddx_name, version); #define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) { \ @@ -446,14 +446,14 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) * later memory should be bound when allocating, e.g rotate_mem */ scrn->vtSema = TRUE; - if (!glamor_enter_vt_ddx(scrnIndex, 0)) + if (!glamor_ddx_enter_vt(scrnIndex, 0)) return FALSE; screen->SaveScreen = xf86SaveScreen; glamor->CreateScreenResources = screen->CreateScreenResources; - screen->CreateScreenResources = glamor_create_screen_resources_ddx; + screen->CreateScreenResources = glamor_ddx_create_screen_resources; glamor->CloseScreen = screen->CloseScreen; - screen->CloseScreen = glamor_close_screen_ddx; + screen->CloseScreen = glamor_ddx_close_screen; /* Fixme should we init crtc screen here? */ if (!xf86CrtcScreenInit(screen)) return FALSE; @@ -467,10 +467,10 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv) } static void -glamor_free_screen_ddx(int scrnIndex, int flags) +glamor_ddx_free_screen(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); if (glamor != NULL) { close(glamor->fd); @@ -480,7 +480,7 @@ glamor_free_screen_ddx(int scrnIndex, int flags) } static ModeStatus -glamor_valid_mode_ddx(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +glamor_ddx_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { if (mode->Flags & V_INTERLACE) { if (verbose) { @@ -494,13 +494,13 @@ glamor_valid_mode_ddx(int scrnIndex, DisplayModePtr mode, Bool verbose, int flag } static Bool -glamor_probe(struct _DriverRec *drv, int flags) +glamor_ddx_probe(struct _DriverRec *drv, int flags) { ScrnInfoPtr scrn = NULL; GDevPtr *sections; int entity, n; - n = xf86MatchDevice(glamor_name, §ions); + n = xf86MatchDevice(glamor_ddx_name, §ions); if (n <= 0) return FALSE; @@ -513,29 +513,29 @@ glamor_probe(struct _DriverRec *drv, int flags) } scrn->driverVersion = 1; - scrn->driverName = (char *) glamor_name; - scrn->name = (char *) glamor_name; + scrn->driverName = (char *) glamor_ddx_name; + scrn->name = (char *) glamor_ddx_name; scrn->Probe = NULL; - scrn->PreInit = glamor_pre_init_ddx; - scrn->ScreenInit = glamor_screen_init_ddx; - scrn->AdjustFrame = glamor_adjust_frame_ddx; - scrn->EnterVT = glamor_enter_vt_ddx; - scrn->LeaveVT = glamor_leave_vt_ddx; - scrn->FreeScreen = glamor_free_screen_ddx; - scrn->ValidMode = glamor_valid_mode_ddx; + scrn->PreInit = glamor_ddx_pre_init; + scrn->ScreenInit = glamor_ddx_screen_init; + scrn->AdjustFrame = glamor_ddx_adjust_frame; + scrn->EnterVT = glamor_ddx_enter_vt; + scrn->LeaveVT = glamor_ddx_leave_vt; + scrn->FreeScreen = glamor_ddx_free_screen; + scrn->ValidMode = glamor_ddx_valid_mode; return TRUE; } static const OptionInfoRec * -glamor_available_options(int chipid, int busid) +glamor_ddx_available_options(int chipid, int busid) { return NULL; } static Bool -glamor_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) +glamor_ddx_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) { xorgHWFlags *flag; @@ -550,19 +550,19 @@ glamor_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) } } -_X_EXPORT DriverRec glamor = { +_X_EXPORT DriverRec glamor_ddx = { 1, "glamor", - glamor_identify, - glamor_probe, - glamor_available_options, + glamor_ddx_identify, + glamor_ddx_probe, + glamor_ddx_available_options, NULL, 0, - glamor_driver_func, + glamor_ddx_driver_func, }; static pointer -glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin) +glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin) { static Bool setupDone = 0; @@ -570,7 +570,7 @@ glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin) */ if (!setupDone) { setupDone = 1; - xf86AddDriver(&glamor, module, HaveDriverFuncs); + xf86AddDriver(&glamor_ddx, module, HaveDriverFuncs); /* * The return value must be non-NULL on success even though there @@ -588,7 +588,7 @@ Bool glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_screen_private *glamor_egl = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor_egl = glamor_ddx_get_screen_private(scrn); if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress)) return FALSE; glamor_egl->dispatch = dispatch; @@ -596,8 +596,8 @@ glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, i } -static XF86ModuleVersionInfo glamor_version_info = { - glamor_name, +static XF86ModuleVersionInfo glamor_ddx_version_info = { + glamor_ddx_name, MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, @@ -612,7 +612,7 @@ static XF86ModuleVersionInfo glamor_version_info = { }; _X_EXPORT XF86ModuleData glamorModuleData = { - &glamor_version_info, - glamor_setup, + &glamor_ddx_version_info, + glamor_ddx_setup, NULL }; diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index ef6ee2946..60af8b544 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -478,7 +478,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; ScrnInfoPtr scrn = crtc->scrn; - struct glamor_screen_private *glamor = glamor_get_screen_private(scrn); + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); if (drmmode_crtc->cursor == NULL) { diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index 2c14ca18e..e083864ad 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -17,7 +17,7 @@ #include #include "glamor_gl_dispatch.h" -struct glamor_screen_private { +struct glamor_ddx_screen_private { EGLDisplay display; EGLContext context; EGLImageKHR root; @@ -34,10 +34,10 @@ struct glamor_screen_private { struct glamor_gl_dispatch *dispatch; }; -inline struct glamor_screen_private * -glamor_get_screen_private(ScrnInfoPtr scrn) +inline struct glamor_ddx_screen_private * +glamor_ddx_get_screen_private(ScrnInfoPtr scrn) { - return (struct glamor_screen_private *) (scrn->driverPrivate); + return (struct glamor_ddx_screen_private *) (scrn->driverPrivate); } Bool glamor_resize(ScrnInfoPtr scrn, int width, int height); From 4c8ed1756aa5121a559aa604926a730180a1403f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 19 Sep 2011 06:31:57 +0800 Subject: [PATCH 212/225] glamor-ddx: Use gbm to allocate front buffer and cursor image. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor.c | 67 ++++++++++++++++++---------------- hw/xfree86/glamor/glamor_ddx.h | 8 +++- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index eef8eeb4f..a51593994 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -30,12 +30,14 @@ #ifdef HAVE_DIX_CONFIG_H #include #endif + +#include + #include #include #include #include - #include "../../../mi/micmap.h" #include #include @@ -57,7 +59,6 @@ glamor_ddx_identify(int flags) xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name); } - Bool glamor_resize(ScrnInfoPtr scrn, int width, int height) { @@ -65,25 +66,25 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; EGLImageKHR image; GLuint texture; - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, - EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA | - EGL_DRM_BUFFER_USE_SCANOUT_MESA, - EGL_NONE - }; if (glamor->root != EGL_NO_IMAGE_KHR && scrn->virtualX == width && scrn->virtualY == height) return TRUE; - attribs[1] = width; - attribs[3] = height; - image = (glamor->egl_create_drm_image_mesa)(glamor->display, attribs); - if (image == EGL_NO_IMAGE_KHR) + glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, + GBM_BO_FORMAT_ARGB8888, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + + if (glamor->root_bo == NULL) return FALSE; + image = glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->root_bo, NULL); + + if (image == EGL_NO_IMAGE_KHR) { + gbm_bo_destroy(glamor->root_bo); + return FALSE; + } + glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -101,39 +102,36 @@ void glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) { struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - EGLint name; - (glamor->egl_export_drm_image_mesa)(glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch); + *handle = gbm_bo_get_handle(glamor->root_bo).u32; + *pitch = gbm_bo_get_pitch(glamor->root_bo); } EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) { struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, - EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA | - EGL_DRM_BUFFER_USE_SCANOUT_MESA | EGL_DRM_BUFFER_USE_CURSOR_MESA, - EGL_NONE - }; + glamor->cursor_bo = gbm_bo_create(glamor->gbm, width, height, + GBM_BO_FORMAT_ARGB8888, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_CURSOR_64X64); - attribs[1] = width; - attribs[3] = height; - return (glamor->egl_create_drm_image_mesa)(glamor->display, attribs); + if (glamor->cursor_bo == NULL) + return EGL_NO_IMAGE_KHR; + + return glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->cursor_bo, NULL); } void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor) { struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); eglDestroyImageKHR(glamor->display, cursor); + gbm_bo_destroy(glamor->cursor_bo); } void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch) { struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - EGLint name; - (glamor->egl_export_drm_image_mesa)(glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch); + *handle = gbm_bo_get_handle(glamor->cursor_bo).u32; + *pitch = gbm_bo_get_pitch(glamor->cursor_bo); ErrorF("cursor stride: %d\n", *pitch); } @@ -257,6 +255,7 @@ glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen) glamor_fini(screen); eglDestroyImageKHR(glamor->display, glamor->root); + gbm_bo_destroy(glamor->root_bo); eglMakeCurrent(glamor->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -328,9 +327,13 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) } + glamor->gbm = gbm_create_device(glamor->fd); + if (glamor->gbm == NULL) { + ErrorF("couldn't create gbm device\n"); + return FALSE; + } - - glamor->display = eglGetDRMDisplayMESA(glamor->fd); + glamor->display = eglGetDisplay(glamor->gbm); #ifndef GLAMOR_GLES2 eglBindAPI(EGL_OPENGL_API); #else @@ -360,6 +363,8 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) #endif glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA"); + glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) + eglGetProcAddress("eglCreateImageKHR"); glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA"); glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index e083864ad..bed7bb921 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -16,25 +16,31 @@ #include #include +#include #include "glamor_gl_dispatch.h" struct glamor_ddx_screen_private { EGLDisplay display; EGLContext context; EGLImageKHR root; + struct gbm_bo *root_bo; + struct gbm_bo *cursor_bo; + EGLint major, minor; CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; int fd; int cpp; + struct gbm_device *gbm; PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; + PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; struct glamor_gl_dispatch *dispatch; }; -inline struct glamor_ddx_screen_private * +inline static struct glamor_ddx_screen_private * glamor_ddx_get_screen_private(ScrnInfoPtr scrn) { return (struct glamor_ddx_screen_private *) (scrn->driverPrivate); From 2d4d40a4b5938249f3c73ed14fe5c5b926c2fefd Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 19 Sep 2011 09:45:32 +0800 Subject: [PATCH 213/225] glamor-ddx: Fix the broken switching between VTs. Now we can allocate frame buffer during the screen initialization. And set mode major when enter VT. This is the correct logic. The previous implementation defer the set mode major to create screen resource which will cause the switching between VTs broken. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor.c | 42 ++++++++++++++++++++++++++------- hw/xfree86/glamor/glamor_crtc.c | 16 +++++++++++-- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index a51593994..1bb5835db 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -70,11 +70,18 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height) if (glamor->root != EGL_NO_IMAGE_KHR && scrn->virtualX == width && scrn->virtualY == height) return TRUE; + else if (scrn->virtualX != width || scrn->virtualY != height) { - glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, + if (glamor->root != EGL_NO_IMAGE_KHR) { + eglDestroyImageKHR(glamor->display, glamor->root); + gbm_bo_destroy(glamor->root_bo); + glamor->root = EGL_NO_IMAGE_KHR; + } + glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, GBM_BO_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - + } + if (glamor->root_bo == NULL) return FALSE; @@ -206,10 +213,8 @@ glamor_ddx_enter_vt(int scrnIndex, int flags) "drmSetMaster failed: %s\n", strerror(errno)); return FALSE; } -#if 0 if (!xf86SetDesiredModes(scrn)) return FALSE; -#endif return TRUE; } @@ -227,15 +232,15 @@ glamor_ddx_create_screen_resources(ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); + int width = scrn->virtualX; + int height = scrn->virtualY; screen->CreateScreenResources = glamor->CreateScreenResources; if (!(*screen->CreateScreenResources) (screen)) return FALSE; if (!glamor_glyphs_init(screen)) return FALSE; - - if (!xf86SetDesiredModes(scrn)) - return FALSE; + glamor_resize(scrn, width, height); return TRUE; } @@ -293,7 +298,23 @@ glamor_egl_has_extension(struct glamor_ddx_screen_private *glamor, char *extensi return FALSE; } +static Bool +glamor_ddx_init_front_buffer(ScrnInfoPtr scrn) +{ + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); + int width = scrn->virtualX; + int height = scrn->virtualY; + glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, + GBM_BO_FORMAT_ARGB8888, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + + if (glamor->root_bo == NULL) + return FALSE; + + /* XXX shall we update displayWidth here ? */ + return TRUE; +} static Bool glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) @@ -304,10 +325,10 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) VisualPtr visual; EGLint config_attribs[] = { #ifdef GLAMOR_GLES2 - EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_CLIENT_VERSION, 2, #endif EGL_NONE - }; + }; /* If serverGeneration != 1 then fd was closed during the last @@ -398,6 +419,9 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) if (!miSetPixmapDepths()) return FALSE; + if (!glamor_ddx_init_front_buffer(scrn)) + return FALSE; + if (!fbScreenInit(screen, NULL, scrn->virtualX, scrn->virtualY, scrn->xDpi, scrn->yDpi, diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 60af8b544..4cb378058 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -372,10 +372,22 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, int ret = TRUE; int i; int fb_id; + uint32_t handle, pitch; drmModeModeInfo kmode; - if (!drmmode_update_fb(scrn, scrn->virtualX, scrn->virtualY)) - return FALSE; + if (drmmode->fb_id == 0) { + + glamor_frontbuffer_handle(scrn, &handle, &pitch); + ret = drmModeAddFB(drmmode->fd, + scrn->virtualX, scrn->virtualY, + scrn->depth, scrn->bitsPerPixel, + pitch, handle, + &drmmode->fb_id); + if (ret < 0) { + ErrorF("failed to add fb\n"); + return FALSE; + } + } saved_mode = crtc->mode; saved_x = crtc->x; From 1590da001129ea61d6f7f8758d1d2842825be81b Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 20 Sep 2011 15:14:49 +0800 Subject: [PATCH 214/225] glamor-egl: Add gbm device support. Latest mesa EGL implementation move to use gbm to manage/allocate buffers. To keep backward compatibility, we still try to use eglGetDRMDisplayMESA firstly, and if failed, then turn to use eglGetDisplay(gbm). Signed-off-by: Zhigang Gong --- glamor/glamor_egl.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index d95828e55..921023eae 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -40,6 +40,8 @@ #define EGL_EGLEXT_PROTOTYPES #define EGL_DISPLAY_NO_X_MESA +#include + #if GLAMOR_GLES2 #include #include @@ -79,6 +81,7 @@ struct glamor_egl_screen_private { int fd; int front_buffer_handle; int cpp; + struct gbm_device *gbm; PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; @@ -184,6 +187,8 @@ glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride) /* * This function will be called from the dri buffer allocation. * It is somehow very familiar with the create screen image. + * XXX the egl image here is not stored at any data structure. + * Does this cause a leak problem? */ Bool glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride) @@ -271,7 +276,18 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl; glamor_egl->fd = fd; - glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd); + + glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd); + + if (glamor_egl->display == EGL_NO_DISPLAY) { + glamor_egl->gbm = gbm_create_device(glamor_egl->fd); + if (glamor_egl->gbm == NULL) { + ErrorF("couldn't get display device\n"); + return FALSE; + } + } + + glamor_egl->display = eglGetDisplay(glamor_egl->gbm); #ifndef GLAMOR_GLES2 eglBindAPI(EGL_OPENGL_API); #else From 09c63d320112fbb4995696d813c488e82915c2f5 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 20 Sep 2011 15:19:13 +0800 Subject: [PATCH 215/225] glamor-ddx: Reuse glamor_dix module to handle egl platform. We already have a glamor egl module at glamor directory which could initialize and create egl context and also can attach a gbm buffer to a specified pixmap or to the screen pixmap. This commit remove all the duplicated code here and use the glamor_dix module directly. As we don't want to handle egl stuffs in this layer, we have to change the way to handle hardware cursor. Previous method is to call egl functions to create a egl image and then bind the image to a texutre then call gl functions to load texture image to the cursor bo. Now we can bind the cursor bo to a cursor pixmap and then use putimage to load new image to the cursor bo. Then we can completely avoid to call egl or gl functions directly in this ddx driver. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/Makefile.am | 3 +- hw/xfree86/glamor/glamor.c | 263 ++++++++++---------------------- hw/xfree86/glamor/glamor_crtc.c | 72 +++------ hw/xfree86/glamor/glamor_ddx.h | 44 ++---- 4 files changed, 121 insertions(+), 261 deletions(-) diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index 8432645ca..fbd561cd1 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -9,14 +9,13 @@ glamor_la_CFLAGS = \ -I$(top_srcdir)/hw/xfree86/ddc \ -I$(top_srcdir)/hw/xfree86/ramdac \ -I$(top_srcdir)/hw/xfree86/i2c \ - -I$(top_srcdir)/glamor + -I$(top_srcdir)/glamor if GLAMOR_GLES2 glamor_la_CFLAGS+=-DGLAMOR_GLES2 endif glamor_la_LDFLAGS = -module -avoid-version \ - $(top_builddir)/glamor/libglamor.la \ $(EGL_LIBS) glamor_ladir = $(moduledir)/drivers diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 1bb5835db..0dbee1806 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -41,9 +41,9 @@ #include "../../../mi/micmap.h" #include #include -#define GC XORG_GC +//#define GC XORG_GC #include -#undef GC +//#undef GC #include "glamor_ddx.h" @@ -59,50 +59,50 @@ glamor_ddx_identify(int flags) xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name); } -Bool -glamor_resize(ScrnInfoPtr scrn, int width, int height) +static Bool +glamor_ddx_init_front_buffer(ScrnInfoPtr scrn, int width, int height) { struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; - EGLImageKHR image; - GLuint texture; - if (glamor->root != EGL_NO_IMAGE_KHR && - scrn->virtualX == width && scrn->virtualY == height) - return TRUE; - else if (scrn->virtualX != width || scrn->virtualY != height) { - - if (glamor->root != EGL_NO_IMAGE_KHR) { - eglDestroyImageKHR(glamor->display, glamor->root); - gbm_bo_destroy(glamor->root_bo); - glamor->root = EGL_NO_IMAGE_KHR; - } - glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, + glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, GBM_BO_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - } - + if (glamor->root_bo == NULL) return FALSE; - image = glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->root_bo, NULL); + scrn->virtualX = width; + scrn->virtualY = height; + /* XXX shall we update displayWidth here ? */ + return TRUE; +} - if (image == EGL_NO_IMAGE_KHR) { - gbm_bo_destroy(glamor->root_bo); - return FALSE; - } +static Bool +glamor_create_screen_image(ScrnInfoPtr scrn) +{ + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + unsigned int handle, stride; + handle = gbm_bo_get_handle(glamor->root_bo).u32; + stride = gbm_bo_get_pitch(glamor->root_bo); + return glamor_create_egl_screen_image(screen, handle, stride); +} - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); +Bool +glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height) +{ + struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; - glamor_set_screen_pixmap_texture(screen, width, height, texture); - glamor->root = image; - scrn->virtualX = width; - scrn->virtualY = height; - return TRUE; + if (glamor->root_bo != NULL) { + glamor_close_egl_screen(screen); + gbm_bo_destroy(glamor->root_bo); + glamor->root_bo = NULL; + } + + if (!glamor_ddx_init_front_buffer(scrn, width, height)) + return FALSE; + return glamor_create_screen_image(scrn); } void @@ -113,32 +113,56 @@ glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) *pitch = gbm_bo_get_pitch(glamor->root_bo); } -EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height) +Bool +glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height) { struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - glamor->cursor_bo = gbm_bo_create(glamor->gbm, width, height, + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + unsigned int handle, stride; + + + if (cursor->cursor_pixmap) + glamor_destroy_cursor(scrn, cursor); + + cursor->cursor_pixmap = screen->CreatePixmap(screen, 0, 0, 32, 0); + if (cursor->cursor_pixmap == NULL) + return FALSE; + screen->ModifyPixmapHeader(cursor->cursor_pixmap, width, height, 0, 0, 0, 0); + cursor->cursor_bo = gbm_bo_create(glamor->gbm, width, height, GBM_BO_FORMAT_ARGB8888, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_CURSOR_64X64); + GBM_BO_USE_SCANOUT + | GBM_BO_USE_RENDERING + | GBM_BO_USE_CURSOR_64X64); - if (glamor->cursor_bo == NULL) - return EGL_NO_IMAGE_KHR; + if (cursor->cursor_bo == NULL) + goto fail; + glamor_cursor_handle(cursor, &handle, &stride); + if (!glamor_create_egl_pixmap_image(cursor->cursor_pixmap, handle, stride)) + goto fail; - return glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->cursor_bo, NULL); + return TRUE; + +fail: + glamor_destroy_cursor(scrn, cursor); + return FALSE; } -void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor) +void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor) { - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - eglDestroyImageKHR(glamor->display, cursor); - gbm_bo_destroy(glamor->cursor_bo); + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + if (cursor->cursor_pixmap) + screen->DestroyPixmap(cursor->cursor_pixmap); + if (cursor->cursor_bo) + gbm_bo_destroy(cursor->cursor_bo); + cursor->cursor_bo = NULL; + cursor->cursor_pixmap = NULL; } void -glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch) +glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch) { - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - *handle = gbm_bo_get_handle(glamor->cursor_bo).u32; - *pitch = gbm_bo_get_pitch(glamor->cursor_bo); + *handle = gbm_bo_get_handle(cursor->cursor_bo).u32; + *pitch = gbm_bo_get_pitch(cursor->cursor_bo); ErrorF("cursor stride: %d\n", *pitch); } @@ -189,6 +213,9 @@ glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags) if (!xf86LoadSubModule(scrn, "fb")) goto fail; + if (!xf86LoadSubModule(scrn, "glamor_dix")) + goto fail; + return TRUE; fail: @@ -232,16 +259,16 @@ glamor_ddx_create_screen_resources(ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - int width = scrn->virtualX; - int height = scrn->virtualY; screen->CreateScreenResources = glamor->CreateScreenResources; if (!(*screen->CreateScreenResources) (screen)) return FALSE; if (!glamor_glyphs_init(screen)) return FALSE; - glamor_resize(scrn, width, height); - + if (glamor->root_bo == NULL) + return FALSE; + if (!glamor_create_screen_image(scrn)) + return FALSE; return TRUE; } @@ -258,79 +285,22 @@ glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen) glamor_ddx_leave_vt(scrnIndex, 0); glamor_fini(screen); - - eglDestroyImageKHR(glamor->display, glamor->root); + glamor_close_egl_screen(screen); gbm_bo_destroy(glamor->root_bo); - eglMakeCurrent(glamor->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglTerminate(glamor->display); - drmmode_closefb(scrn); glamor->fd = -1; - glamor->root = EGL_NO_IMAGE_KHR; - return TRUE; } - - -static Bool -glamor_egl_has_extension(struct glamor_ddx_screen_private *glamor, char *extension) -{ - const char *egl_extensions; - char *pext; - int ext_len; - ext_len = strlen(extension); - - egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS); - pext = (char*)egl_extensions; - - if (pext == NULL || extension == NULL) - return FALSE; - while((pext = strstr(pext, extension)) != NULL) { - if (pext[ext_len] == ' ' || pext[ext_len] == '\0') - return TRUE; - pext += ext_len; - } - return FALSE; -} - -static Bool -glamor_ddx_init_front_buffer(ScrnInfoPtr scrn) -{ - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - int width = scrn->virtualX; - int height = scrn->virtualY; - - glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, - GBM_BO_FORMAT_ARGB8888, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - - if (glamor->root_bo == NULL) - return FALSE; - - /* XXX shall we update displayWidth here ? */ - return TRUE; -} - static Bool glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - const char *version; VisualPtr visual; - EGLint config_attribs[] = { -#ifdef GLAMOR_GLES2 - EGL_CONTEXT_CLIENT_VERSION, 2, -#endif - EGL_NONE - }; - - /* If serverGeneration != 1 then fd was closed during the last time closing screen, actually in eglTerminate(). */ @@ -354,62 +324,7 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) return FALSE; } - glamor->display = eglGetDisplay(glamor->gbm); -#ifndef GLAMOR_GLES2 - eglBindAPI(EGL_OPENGL_API); -#else - eglBindAPI(EGL_OPENGL_ES_API); -#endif - if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "eglInitialize() failed\n"); - return FALSE; - } - - version = eglQueryString(glamor->display, EGL_VERSION); - xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_ddx_name, version); - -#define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ - if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) { \ - ErrorF("EGL_" #EXT "required.\n"); \ - return FALSE; \ - } - - GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image); - GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image); -#ifdef GLAMOR_GLES2 - GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2); -#else - GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl); -#endif - - glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA"); - glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) - eglGetProcAddress("eglCreateImageKHR"); - glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA"); - glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); - - if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa || - !glamor->egl_image_target_texture2d_oes) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "eglGetProcAddress() failed\n"); - return FALSE; - } - - glamor->context = eglCreateContext(glamor->display, - NULL, EGL_NO_CONTEXT, config_attribs); - if (glamor->context == EGL_NO_CONTEXT) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Failed to create EGL context\n"); - return FALSE; - } - - if (!eglMakeCurrent(glamor->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Failed to make EGL context current\n"); - return FALSE; - } + glamor_egl_init(scrn, glamor->fd); miClearVisualTypes(); if (!miSetVisualTypes(scrn->depth, @@ -419,7 +334,7 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) if (!miSetPixmapDepths()) return FALSE; - if (!glamor_ddx_init_front_buffer(scrn)) + if (!glamor_ddx_init_front_buffer(scrn, scrn->virtualX, scrn->virtualY)) return FALSE; if (!fbScreenInit(screen, NULL, @@ -613,18 +528,6 @@ glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin) } } -Bool -glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_ddx_screen_private *glamor_egl = glamor_ddx_get_screen_private(scrn); - if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress)) - return FALSE; - glamor_egl->dispatch = dispatch; - return TRUE; -} - - static XF86ModuleVersionInfo glamor_ddx_version_info = { glamor_ddx_name, MODULEVENDORSTRING, diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 4cb378058..854e81645 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -50,23 +50,6 @@ #include #include -#define GL_GLEXT_PROTOTYPES -#define EGL_EGLEXT_PROTOTYPES -#define EGL_DISPLAY_NO_X_MESA - -#if GLAMOR_GLES2 -#include -#include -#ifndef GL_BGRA -#define GL_BGRA GL_BGRA_EXT -#endif -#else -#include -#endif - -#include -#include - #include "glamor_ddx.h" typedef struct { @@ -85,8 +68,7 @@ typedef struct { drmmode_ptr drmmode; drmModeCrtcPtr mode_crtc; uint32_t rotate_fb_id; - EGLImageKHR cursor; - unsigned int cursor_tex; + struct glamor_gbm_cursor *cursor; } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct { @@ -341,7 +323,7 @@ drmmode_update_fb (ScrnInfoPtr scrn, int width, int height) if (drmmode->fb_id != 0 && scrn->virtualX == width && scrn->virtualY == height) return TRUE; - if (!glamor_resize(scrn, width, height)) + if (!glamor_front_buffer_resize(scrn, width, height)) return FALSE; if (drmmode->fb_id != 0) drmModeRmFB(drmmode->fd, drmmode->fb_id); @@ -490,37 +472,33 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; ScrnInfoPtr scrn = crtc->scrn; + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); + GCPtr gc; if (drmmode_crtc->cursor == NULL) { - drmmode_crtc->cursor = glamor_create_cursor_argb(scrn, 64, 64); - if (drmmode_crtc->cursor == EGL_NO_IMAGE_KHR) + drmmode_crtc->cursor = calloc(1, sizeof(*drmmode_crtc->cursor)); + if (drmmode_crtc->cursor == NULL) { + ErrorF("Failed to allocate cursor.\n"); + return; + } + if (!glamor_create_cursor(scrn, drmmode_crtc->cursor, 64, 64)) { + free(drmmode_crtc->cursor); + drmmode_crtc->cursor = NULL; + ErrorF("Failed to create glamor cursor.\n"); return; - glGenTextures(1, &drmmode_crtc->cursor_tex); - glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, GL_NEAREST); - (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, drmmode_crtc->cursor); + } } - glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex); -#ifdef GLAMOR_GLES2 - /* XXX Actually, the image is BGRA not RGBA, so the r and b - * should be swapped. But as normally, they are the same value - * ignore this currently, don't want to let CPU to do the swizzle. - * considering to put this function to the glamor rendering directory. - * Thus we can reuse the shader to do this.*/ - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image); -#else - glPixelStorei(GL_UNPACK_ROW_LENGTH, 64); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image); -#endif + gc = GetScratchGC (drmmode_crtc->cursor->cursor_pixmap->drawable.depth, screen); + if (!gc) + return; + + ValidateGC (&drmmode_crtc->cursor->cursor_pixmap->drawable, gc); + (*gc->ops->PutImage)(&drmmode_crtc->cursor->cursor_pixmap->drawable, gc, + 32, 0, 0, 64, 64, 0, ZPixmap, (char*)image); + FreeScratchGC (gc); } @@ -537,13 +515,12 @@ drmmode_hide_cursor (xf86CrtcPtr crtc) static void drmmode_show_cursor (xf86CrtcPtr crtc) { - ScrnInfoPtr scrn = crtc->scrn; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; uint32_t handle, stride; ErrorF("show cursor\n"); - glamor_cursor_handle(scrn, drmmode_crtc->cursor, &handle, &stride); + glamor_cursor_handle(drmmode_crtc->cursor, &handle, &stride); drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64); @@ -654,8 +631,9 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc) ScrnInfoPtr scrn = crtc->scrn; if (drmmode_crtc->cursor) { drmmode_hide_cursor(crtc); - glDeleteTextures(1, &drmmode_crtc->cursor_tex); glamor_destroy_cursor(scrn, drmmode_crtc->cursor); + free(drmmode_crtc->cursor); + drmmode_crtc->cursor = NULL; } free(drmmode_crtc->cursor); crtc->driver_private = NULL; diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h index bed7bb921..3ffd48852 100644 --- a/hw/xfree86/glamor/glamor_ddx.h +++ b/hw/xfree86/glamor/glamor_ddx.h @@ -1,43 +1,23 @@ #ifndef GLAMOR_DDX_H #define GLAMOR_DDX_H -#define GL_GLEXT_PROTOTYPES -#define EGL_EGLEXT_PROTOTYPES -#define EGL_DISPLAY_NO_X_MESA - -#if GLAMOR_GLES2 -#include -#include -#else -#include -#endif - -#define MESA_EGL_NO_X11_HEADERS -#include -#include - #include -#include "glamor_gl_dispatch.h" +#define GLAMOR_FOR_XORG 1 +#include struct glamor_ddx_screen_private { - EGLDisplay display; - EGLContext context; - EGLImageKHR root; struct gbm_bo *root_bo; struct gbm_bo *cursor_bo; - - EGLint major, minor; + struct gbm_device *gbm; CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; int fd; int cpp; - struct gbm_device *gbm; +}; - PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; - PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; - PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; - PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; - struct glamor_gl_dispatch *dispatch; +struct glamor_gbm_cursor { + struct gbm_bo *cursor_bo; + PixmapPtr cursor_pixmap; }; inline static struct glamor_ddx_screen_private * @@ -46,15 +26,15 @@ glamor_ddx_get_screen_private(ScrnInfoPtr scrn) return (struct glamor_ddx_screen_private *) (scrn->driverPrivate); } -Bool glamor_resize(ScrnInfoPtr scrn, int width, int height); +Bool glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height); void glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch); Bool glamor_load_cursor(ScrnInfoPtr scrn, - CARD32 *image, int width, int height); + int width, int height); -void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch); -EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height); -void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor); +void glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch); +Bool glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height); +void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor) ; Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp); void drmmode_closefb(ScrnInfoPtr scrn); From f1c36c611efaa56e49758d8e8b19d07c10a8277e Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 20 Sep 2011 17:10:50 +0800 Subject: [PATCH 216/225] glamor-ddx: Don't need to call preInit in screen_init. The previous implementation call preInit again to reopen the device if the device is closed by eglTerminate. Now we don't need it anymore, as glamor dix doesn't call eglTerminate any more when close screen. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c index 0dbee1806..f4b37ab6b 100644 --- a/hw/xfree86/glamor/glamor.c +++ b/hw/xfree86/glamor/glamor.c @@ -287,11 +287,8 @@ glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen) glamor_fini(screen); glamor_close_egl_screen(screen); gbm_bo_destroy(glamor->root_bo); - drmmode_closefb(scrn); - glamor->fd = -1; - return TRUE; } @@ -301,22 +298,6 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) ScrnInfoPtr scrn = xf86Screens[screen->myNum]; struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); VisualPtr visual; - /* If serverGeneration != 1 then fd was closed during the last - time closing screen, actually in eglTerminate(). */ - - if (glamor->fd == -1 && serverGeneration != 1) { - glamor->fd = open(dri_device_name, O_RDWR); - if (glamor->fd == -1 ) { - ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno)); - return FALSE; - } - if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Kernel modesetting setup failed\n"); - return FALSE; - } - - } glamor->gbm = gbm_create_device(glamor->fd); if (glamor->gbm == NULL) { From 483717484afb4ccf5b48483b3a21a9fe91213dd4 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Tue, 20 Sep 2011 17:15:12 +0800 Subject: [PATCH 217/225] glamor-ddx: Destroy all the pixmap cursors when close current screen. As now we use pixmap to handle cursor, and pixmaps are related to current screen. If we close the screen, then we have to destroy all the related cursors. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor_crtc.c | 37 +++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index 854e81645..e86466abd 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -512,6 +512,34 @@ drmmode_hide_cursor (xf86CrtcPtr crtc) 0, 64, 64); } + +static void +_drmmode_destroy_cursor(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr + drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->cursor == NULL) + return; + drmmode_hide_cursor(crtc); + glamor_destroy_cursor(crtc->scrn, drmmode_crtc->cursor); + free(drmmode_crtc->cursor); + drmmode_crtc->cursor = NULL; +} + +static void +drmmode_destroy_cursor(ScrnInfoPtr scrn) +{ + int i; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + + for (i = 0; i < xf86_config->num_crtc; i++) + _drmmode_destroy_cursor(xf86_config->crtc[i]); +} + + + + static void drmmode_show_cursor (xf86CrtcPtr crtc) { @@ -629,12 +657,7 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc) drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; ScrnInfoPtr scrn = crtc->scrn; - if (drmmode_crtc->cursor) { - drmmode_hide_cursor(crtc); - glamor_destroy_cursor(scrn, drmmode_crtc->cursor); - free(drmmode_crtc->cursor); - drmmode_crtc->cursor = NULL; - } + _drmmode_destroy_cursor(crtc); free(drmmode_crtc->cursor); crtc->driver_private = NULL; } @@ -1539,6 +1562,8 @@ void drmmode_closefb(ScrnInfoPtr scrn) drmmode_crtc = xf86_config->crtc[0]->driver_private; drmmode = drmmode_crtc->drmmode; + drmmode_destroy_cursor(scrn); + drmModeRmFB(drmmode->fd, drmmode->fb_id); drmmode->fb_id = 0; } From 937d3bcecf04305c01159f5c5084833f28014061 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Thu, 22 Sep 2011 13:39:01 +0800 Subject: [PATCH 218/225] glamor: Correct the version check for GLES2. If we are using GLES2, then the version number should be no less than 2.0 rather than no less than 1.3 which is for GL API. --- glamor/glamor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index ea4099ed2..a35fbee52 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -295,10 +295,17 @@ glamor_init(ScreenPtr screen, unsigned int flags) gl_version = glamor_gl_get_version(); +#ifndef GLAMOR_GLES2 if (gl_version < GLAMOR_GL_VERSION_ENCODE(1,3)) { - ErrorF("Require Opengl 1.3 or latter.\n"); + ErrorF("Require OpenGL version 1.3 or latter.\n"); goto fail; } +#else + if (gl_version < GLAMOR_GL_VERSION_ENCODE(2,0)) { + ErrorF("Require Open GLES2.0 or latter.\n"); + goto fail; + } +#endif glamor_gl_dispatch_init(screen, &glamor_priv->dispatch, gl_version); From df070205600cd736750d8a43426976a518b1fbae Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 26 Sep 2011 16:01:03 +0800 Subject: [PATCH 219/225] ephyr-glamor: Set texture 0 to screen pixmap. In Xephyr, screen pixmap is different from other pixmap. It use fbo zero and texture zero. We initialize it during creating screen resources. Signed-off-by: Zhigang Gong --- hw/kdrive/ephyr/ephyr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index e2cd7a49d..5e217487f 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -718,8 +718,12 @@ ephyrCreateResources (ScreenPtr pScreen) ephyrShadowUpdate, ephyrWindowLinear); else { - if (ephyr_glamor) + if (ephyr_glamor) { + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; if (!glamor_glyphs_init(pScreen)) return FALSE; + glamor_set_screen_pixmap_texture(pScreen, screen->width, screen->height, 0); + } return ephyrSetInternalDamage(pScreen); } } From 1fb58860cc02d28545c66a916956a45918596870 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 26 Sep 2011 16:05:52 +0800 Subject: [PATCH 220/225] ephyr-glamor: Implment gl disptach function for host glx. We should pass back the glXGetProcAddress to the underlying gl dispatch initialization function to get those gl function pointers. Signed-off-by: Zhigang Gong --- hw/kdrive/ephyr/hostx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 15dfc70ae..935c7c667 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -1532,3 +1532,15 @@ ephyr_glamor_paint_rect (EphyrScreenInfo screen, host_screen->win_width, host_screen->win_height); #endif } + +struct glamor_gl_dispatch; +extern Bool +glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, int gl_version, void* func); + +Bool +glamor_gl_dispatch_init(void *screen, struct glamor_gl_dispatch *dispatch, int gl_version) +{ + if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, glXGetProcAddress)) + return FALSE; + return TRUE; +} From fe4c95ce843afffed981ac8bb89ca433bd20f1e2 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 26 Sep 2011 16:08:29 +0800 Subject: [PATCH 221/225] glamor: Refine the screen pixmap initialization for Xephyr. The previous implementation is to override the CreatePixmap firstly and assume the first call to CreatePixmap must be screen pixmap. This is not clean. Now Refine it to normal way. Let the Xephyr to set texture 0 to screen pixmap during creating screen resources. Signed-off-by: Zhigang Gong --- glamor/glamor.c | 52 +++++++++---------------------------------------- 1 file changed, 9 insertions(+), 43 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index a35fbee52..ee83fd3e9 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -73,8 +73,14 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) * to it. */ pixmap_priv->gl_fbo = 1; - pixmap_priv->gl_tex = 1; - glamor_pixmap_ensure_fb(pixmap); + if (tex != 0) { + glamor_pixmap_ensure_fb(pixmap); + pixmap_priv->gl_tex = 1; + } + else { + pixmap_priv->fb = 0; + pixmap_priv->gl_tex = 0; + } screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3, @@ -173,42 +179,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, return pixmap; } - -/** - * For Xephyr use only. set up the screen pixmap to correct state. - **/ -static PixmapPtr -glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth, - unsigned int usage) -{ - PixmapPtr pixmap; - glamor_pixmap_private *pixmap_priv; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - assert(w ==0 && h == 0); - - glamor_priv->screen_fbo = 0; - pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); - - if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { - fbDestroyPixmap(pixmap); - ErrorF("Fail to allocate privates for PIXMAP.\n"); - return NullPixmap; - } - - pixmap_priv = glamor_get_pixmap_private(pixmap); - pixmap_priv->tex = 0; - pixmap_priv->gl_fbo = 1; - pixmap_priv->gl_tex = 0; - pixmap_priv->container = pixmap; - pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; - - screen->CreatePixmap = glamor_create_pixmap; - return pixmap; -} - - - - static Bool glamor_destroy_pixmap(PixmapPtr pixmap) { @@ -334,11 +304,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) screen->CreateGC = glamor_create_gc; glamor_priv->saved_create_pixmap = screen->CreatePixmap; - - if (flags & GLAMOR_HOSTX) - screen->CreatePixmap = glamor_create_screen_pixmap; - else - screen->CreatePixmap = glamor_create_pixmap; + screen->CreatePixmap = glamor_create_pixmap; glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap; screen->DestroyPixmap = glamor_destroy_pixmap; From 6a7ad1c92934b35eb2431c3e0f11c0c56a097dc9 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 26 Sep 2011 16:13:57 +0800 Subject: [PATCH 222/225] glamor-ddx: Don't double free the cursor memory. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/glamor_crtc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c index e86466abd..ce4f31f54 100644 --- a/hw/xfree86/glamor/glamor_crtc.c +++ b/hw/xfree86/glamor/glamor_crtc.c @@ -516,8 +516,7 @@ drmmode_hide_cursor (xf86CrtcPtr crtc) static void _drmmode_destroy_cursor(xf86CrtcPtr crtc) { - drmmode_crtc_private_ptr - drmmode_crtc = crtc->driver_private; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; if (drmmode_crtc->cursor == NULL) return; @@ -654,11 +653,8 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, static void drmmode_crtc_destroy(xf86CrtcPtr crtc) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - ScrnInfoPtr scrn = crtc->scrn; _drmmode_destroy_cursor(crtc); - free(drmmode_crtc->cursor); crtc->driver_private = NULL; } From 101b69dddff6cc538cb369c70377bbad825aa765 Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 26 Sep 2011 16:33:52 +0800 Subject: [PATCH 223/225] glamor: Check libgbm if enable glamor ddx. Signed-off-by: Zhigang Gong --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index 80daf828b..bf174351f 100644 --- a/configure.ac +++ b/configure.ac @@ -803,6 +803,7 @@ LIBDBUS="dbus-1 >= 1.0" LIBPIXMAN="pixman-1 >= 0.21.8" LIBEGL="egl" LIBGLESV2="glesv2" +LIBGBM="gbm" dnl Pixman is always required, but we separate it out so we can link dnl specific modules against it PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN) @@ -1796,6 +1797,7 @@ if test "x$GLAMOR" = xyes; then if test "x$GLAMOR_DDX" = xyes; then AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver]) PKG_CHECK_MODULES(EGL, $LIBEGL) + PKG_CHECK_MODULES(EGL, $LIBGBM) REQUIRED_LIBS="$REQUIRED_LIBS $LIBEGL" fi fi From 284328a6beb0bd0ab6653973ce52b5a68b4e791f Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 26 Sep 2011 17:04:56 +0800 Subject: [PATCH 224/225] glamor-ddx: Rename glamor.c to glamor_ddx.c. As glamor's dix module already has a glamor.c, rename this glamor.c to other name to avoid file name conflict which may confuse gdb. Signed-off-by: Zhigang Gong --- hw/xfree86/glamor/Makefile.am | 2 +- hw/xfree86/glamor/{glamor.c => glamor_ddx.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename hw/xfree86/glamor/{glamor.c => glamor_ddx.c} (100%) diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am index fbd561cd1..1d729f46b 100644 --- a/hw/xfree86/glamor/Makefile.am +++ b/hw/xfree86/glamor/Makefile.am @@ -20,7 +20,7 @@ glamor_la_LDFLAGS = -module -avoid-version \ glamor_ladir = $(moduledir)/drivers glamor_la_SOURCES = \ - glamor.c \ + glamor_ddx.c \ glamor_crtc.c \ glamor_ddx.h diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor_ddx.c similarity index 100% rename from hw/xfree86/glamor/glamor.c rename to hw/xfree86/glamor/glamor_ddx.c From 7982eca622bbc4b6a4845801a77da8a16138004a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 18 Dec 2013 11:16:15 -0800 Subject: [PATCH 225/225] Revert changes outside of glamor from the glamor branch. We want to merge the external glamor code to the xserver, with the internal history retained. However, we don't want a bunch of non-building changes along the way, so remove all the build system and support code outside of glamor for now. --- Makefile.am | 6 - README | 39 +- configure.ac | 45 +- hw/kdrive/ephyr/Makefile.am | 16 +- hw/kdrive/ephyr/ephyr.c | 16 +- hw/kdrive/ephyr/ephyr.h | 7 - hw/kdrive/ephyr/ephyr_glamor.c | 67 -- hw/kdrive/ephyr/ephyrinit.c | 11 - hw/kdrive/ephyr/hostx.c | 103 +- hw/kdrive/ephyr/hostx.h | 3 - hw/xfree86/Makefile.am | 8 +- hw/xfree86/common/Makefile.am | 8 +- hw/xfree86/common/xf86pciBus.c | 6 +- hw/xfree86/dixmods/Makefile.am | 15 +- hw/xfree86/dixmods/glamor_module.c | 47 - hw/xfree86/glamor/Makefile.am | 28 - hw/xfree86/glamor/glamor_crtc.c | 1565 ---------------------------- hw/xfree86/glamor/glamor_ddx.c | 531 ---------- hw/xfree86/glamor/glamor_ddx.h | 42 - include/xorg-config.h.in | 11 - 20 files changed, 15 insertions(+), 2559 deletions(-) delete mode 100644 hw/kdrive/ephyr/ephyr_glamor.c delete mode 100644 hw/xfree86/dixmods/glamor_module.c delete mode 100644 hw/xfree86/glamor/Makefile.am delete mode 100644 hw/xfree86/glamor/glamor_crtc.c delete mode 100644 hw/xfree86/glamor/glamor_ddx.c delete mode 100644 hw/xfree86/glamor/glamor_ddx.h diff --git a/Makefile.am b/Makefile.am index 632258eec..cea140bea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,10 +17,6 @@ if RECORD RECORD_DIR=record endif -if GLAMOR -GLAMOR_DIR=glamor -endif - SUBDIRS = \ doc \ man \ @@ -42,7 +38,6 @@ SUBDIRS = \ $(COMPOSITE_DIR) \ $(GLX_DIR) \ exa \ - $(GLAMOR_DIR) \ config \ hw \ test @@ -93,7 +88,6 @@ DIST_SUBDIRS = \ composite \ glx \ exa \ - glamor \ config \ hw \ test diff --git a/README b/README index c240ac775..b2499a059 100644 --- a/README +++ b/README @@ -1,41 +1,4 @@ - Glamor setup - -1. Prerequirement. -Please install makedepend and libudev-devel firstly. - -2. Build xserver-glamor. - -Then do the following steps one by one. -2.1. get latest glamor at github. - -2.2 Setup xorg development environment, use xserver-glamor to - replace the official xserver. - Here is the link of how to setup xorg development environment: - http://www.x.org/wiki/ModularDevelopersGuide - - For most of the packages, we prefer latest git version. Especially - for the mesa package. - - When build mesa, use the following parameters: (assume you want to - install the experimental xorg to /opt/gfx-test) -#mesa/./autogen.sh --prefix=/opt/gfx-test --with-egl-platforms=drm --disable-gallium --disable-gallium-egl - - build xserver-glamor as below: -#xserver-glamor/./autogen.sh --disable-glx --enable-kdrive --enable-xephyr - - Once you finish all the building process, you can have a try as below: -xserver-glamor#startx -- `pwd`/hw/xfree86/Xorg If you can find the - following messages on the console, then everything should work correctly. -Mesa: Initializing x86-64 optimizations - - -3. Restrictions: - -Currently, glamor doesn't support glx extension, will be fixed in the future. - -Glamor setup done. - - X Server + X Server The X server accepts requests from client applications to create windows, which are (normally rectangular) "virtual screens" that the client program diff --git a/configure.ac b/configure.ac index bf174351f..b0d26435a 100644 --- a/configure.ac +++ b/configure.ac @@ -646,8 +646,6 @@ AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest serv AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto]) AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no]) AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto]) -AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: no)]), [GLAMOR=$enableval], [GLAMOR=no]) -AC_ARG_ENABLE(glamor-ddx, AS_HELP_STRING([--enable-glamor-ddx], [Build glamor ddx (default: no)]), [GLAMOR_DDX=$enableval], [GLAMOR_DDX=no]) dnl kdrive and its subsystems AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no]) AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto]) @@ -657,8 +655,6 @@ dnl kdrive options AC_ARG_ENABLE(kdrive-kbd, AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto]) AC_ARG_ENABLE(kdrive-mouse, AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto]) AC_ARG_ENABLE(kdrive-evdev, AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto]) -dnl glamor options -AC_ARG_ENABLE(glamor-gles2, AS_HELP_STRING([--enable-glamor-gles2], [Build glamor based on gles2 (default: no)]), [GLAMOR_GLES2=$enableval], [GLAMOR_GLES2=no]) dnl chown/chmod to be setuid root as part of build @@ -801,9 +797,7 @@ LIBUDEV="libudev >= 143" LIBSELINUX="libselinux >= 2.0.86" LIBDBUS="dbus-1 >= 1.0" LIBPIXMAN="pixman-1 >= 0.21.8" -LIBEGL="egl" -LIBGLESV2="glesv2" -LIBGBM="gbm" + dnl Pixman is always required, but we separate it out so we can link dnl specific modules against it PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN) @@ -1771,37 +1765,6 @@ AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes]) AM_CONDITIONAL([DGA], [test "x$DGA" = xyes]) AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes]) -dnl glamor - -if [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes] ; then - GLAMOR=yes -fi - -AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes]) -AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes]) -AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes]) - -if test "x$GLAMOR" = xyes; then - AC_DEFINE(GLAMOR,1,[Build Glamor]) - - if test "x$GLAMOR_GLES2" = xyes; then - AC_DEFINE(GLAMOR_GLES2,1,[Build glamor over GLES2]) - PKG_CHECK_MODULES(GLESV2, $LIBGLESV2) - REQUIRED_LIBS="$REQUIRED_LIBS $LIBGLESV2" - else - AC_DEFINE(GLAMOR_GL,1,[Build glamor over GL]) - PKG_CHECK_MODULES(GL, $LIBGL) - REQUIRED_LIBS="$REQUIRED_LIBS $LIBGL" - fi - - if test "x$GLAMOR_DDX" = xyes; then - AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver]) - PKG_CHECK_MODULES(EGL, $LIBEGL) - PKG_CHECK_MODULES(EGL, $LIBGBM) - REQUIRED_LIBS="$REQUIRED_LIBS $LIBEGL" - fi -fi - dnl XWin DDX AC_MSG_CHECKING([whether to build XWin DDX]) @@ -2035,10 +1998,6 @@ if test "$KDRIVE" = yes; then if test "x$DRI" = xyes && test "x$GLX" = xyes; then XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm" fi - # The glamor stuff requires libGL, but that conflicts with GLX currently. - if test "x$GLX" = xno; then - XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS gl" - fi PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"]) if test "x$XEPHYR" = xauto; then @@ -2174,7 +2133,6 @@ Xext/Makefile Xi/Makefile xfixes/Makefile exa/Makefile -glamor/Makefile hw/Makefile hw/xfree86/Makefile hw/xfree86/common/Makefile @@ -2212,7 +2170,6 @@ hw/xfree86/utils/Makefile hw/xfree86/utils/man/Makefile hw/xfree86/utils/cvt/Makefile hw/xfree86/utils/gtf/Makefile -hw/xfree86/glamor/Makefile hw/dmx/config/Makefile hw/dmx/config/man/Makefile hw/dmx/doc/Makefile diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 744604eea..9d9b64ee5 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -7,8 +7,7 @@ INCLUDES = \ @XEPHYR_CFLAGS@ \ @DRIPROTO_CFLAGS@ \ -I$(top_srcdir) \ - -I$(top_srcdir)/exa \ - -I$(top_srcdir)/glamor + -I$(top_srcdir)/exa if XV LIBXEPHYR_HOSTXV=libxephyr-hostxv.la @@ -48,7 +47,6 @@ XEPHYR_SRCS = \ ephyr.h \ ephyrlog.h \ ephyr_draw.c \ - ephyr_glamor.c \ os.c libxephyr_hostx_la_SOURCES = $(HOSTX_SRCS) @@ -66,28 +64,18 @@ libxephyr_la_SOURCES = $(XEPHYR_SRCS) Xephyr_SOURCES = \ ephyrinit.c -if GLAMOR_GLES2 -GLAMOR_GL_LIB = -lGLESv2 -else -GLAMOR_GL_LIB = -lGL -endif - Xephyr_LDADD = \ libxephyr.la \ libxephyr-hostx.la \ $(LIBXEPHYR_HOSTXV) \ $(LIBXEPHYR_HOSTDRI) \ $(top_builddir)/exa/libexa.la \ - $(top_builddir)/glamor/libglamor.la \ @KDRIVE_LIBS@ \ - @XEPHYR_LIBS@ \ - $(GLAMOR_GL_LIB) + @XEPHYR_LIBS@ Xephyr_DEPENDENCIES = \ libxephyr.la \ libxephyr-hostx.la \ - $(top_builddir)/exa/libexa.la \ - $(top_builddir)/glamor/libglamor.la \ $(LIBXEPHYR_HOSTXV) \ $(LIBXEPHYR_HOSTDRI) \ @KDRIVE_LOCAL_LIBS@ diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 5e217487f..7ebf1c253 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -394,7 +394,7 @@ ephyrSetInternalDamage (ScreenPtr pScreen) KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; PixmapPtr pPixmap = NULL; - + scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0, (DamageDestroyFunc) 0, DamageReportNone, @@ -669,9 +669,7 @@ ephyrInitScreen (ScreenPtr pScreen) } if (!ephyrNoDRI) { ephyrDRIExtensionInit (pScreen) ; -#if 0 ephyrHijackGLXExtension () ; -#endif } #endif @@ -684,7 +682,6 @@ ephyrInitScreen (ScreenPtr pScreen) return TRUE; } - Bool ephyrFinishInitScreen (ScreenPtr pScreen) { @@ -701,7 +698,6 @@ ephyrFinishInitScreen (ScreenPtr pScreen) return TRUE; } -extern Bool ephyr_glamor; Bool ephyrCreateResources (ScreenPtr pScreen) @@ -712,20 +708,14 @@ ephyrCreateResources (ScreenPtr pScreen) EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d", pScreen, pScreen->myNum, scrpriv->shadow); + if (scrpriv->shadow) return KdShadowSet (pScreen, scrpriv->randr, ephyrShadowUpdate, ephyrWindowLinear); - else { - if (ephyr_glamor) { - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - if (!glamor_glyphs_init(pScreen)) return FALSE; - glamor_set_screen_pixmap_texture(pScreen, screen->width, screen->height, 0); - } + else return ephyrSetInternalDamage(pScreen); - } } void diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index 9dcde8d56..23848004c 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -196,13 +196,6 @@ ephyrDrawDisable(ScreenPtr pScreen); void ephyrDrawFini(ScreenPtr pScreen); -/* ephyr_glamor.c */ -Bool ephyr_glamor_init(ScreenPtr pScreen); -void ephyr_glamor_enable(ScreenPtr pScreen); -void ephyr_glamor_disable(ScreenPtr pScreen); -void ephyr_glamor_fini(ScreenPtr pScreen); -void ephyr_glamor_host_paint_rect(ScreenPtr pScreen); - /*ephyvideo.c*/ Bool ephyrInitVideo(ScreenPtr pScreen) ; diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c deleted file mode 100644 index 53bfbb995..000000000 --- a/hw/kdrive/ephyr/ephyr_glamor.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "ephyr.h" -#include "glamor.h" - -/** - * This function initializes EXA to use the fake acceleration implementation - * which just falls through to software. The purpose is to have a reliable, - * correct driver with which to test changes to the EXA core. - */ -Bool -ephyr_glamor_init(ScreenPtr screen) -{ - KdScreenPriv(screen); - KdScreenInfo *kd_screen = pScreenPriv->screen; - - ephyr_glamor_host_create_context(kd_screen); - - glamor_init(screen, GLAMOR_HOSTX); - - return TRUE; -} - -void -ephyr_glamor_enable(ScreenPtr screen) -{ -} - -void -ephyr_glamor_disable(ScreenPtr screen) -{ -} - -void -ephyr_glamor_fini(ScreenPtr screen) -{ - glamor_fini(screen); -} diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index 9155d0861..b674bb8d0 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -31,7 +31,6 @@ extern Window EphyrPreExistingHostWin; extern Bool EphyrWantGrayScale; -extern Bool ephyr_glamor; extern Bool kdHasPointer; extern Bool kdHasKbd; @@ -118,7 +117,6 @@ ddxUseMsg (void) ErrorF("-host-cursor Re-use exisiting X host server cursor\n"); ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); ErrorF("-grayscale Simulate 8bit grayscale\n"); - ErrorF("-glamor Enable 2D acceleration using glamor\n"); ErrorF("-fakexa Simulate acceleration using software rendering\n"); ErrorF("-verbosity Set log verbosity level\n"); #ifdef GLXEXT @@ -222,15 +220,6 @@ ddxProcessArgument (int argc, char **argv, int i) EphyrWantGrayScale = 1; return 1; } - else if (!strcmp (argv[i], "-glamor")) - { - ephyr_glamor = TRUE; - ephyrFuncs.initAccel = ephyr_glamor_init; - ephyrFuncs.enableAccel = ephyr_glamor_enable; - ephyrFuncs.disableAccel = ephyr_glamor_disable; - ephyrFuncs.finiAccel = ephyr_glamor_fini; - return 1; - } else if (!strcmp (argv[i], "-fakexa")) { ephyrFuncs.initAccel = ephyrDrawInit; diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 935c7c667..4caf4516d 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -46,7 +46,6 @@ #include #include /* for memset */ #include -#include #include #include @@ -62,7 +61,6 @@ #include #endif /* XF86DRI */ #include "ephyrlog.h" -#include "GL/glx.h" #ifdef XF86DRI extern Bool XF86DRIQueryExtension (Display *dpy, @@ -97,7 +95,6 @@ struct EphyrHostXVars Display *dpy; int screen; Visual *visual; - XVisualInfo *visual_info; Window winroot; GC gc; int depth; @@ -126,14 +123,10 @@ extern int monitorResolution; char *ephyrResName = NULL; int ephyrResNameFromCmd = 0; char *ephyrTitle = NULL; -Bool ephyr_glamor = FALSE; static void hostx_set_fullscreen_hint(void); -static void -ephyr_glamor_get_visual(void); - /* X Error traps */ static int trapped_error_code = 0; @@ -369,11 +362,8 @@ hostx_init (void) HostX.winroot = RootWindow(HostX.dpy, HostX.screen); HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL); HostX.depth = DefaultDepth(HostX.dpy, HostX.screen); - if (ephyr_glamor) { - ephyr_glamor_get_visual(); - } else { - HostX.visual = DefaultVisual(HostX.dpy, HostX.screen); - } + HostX.visual = DefaultVisual(HostX.dpy, HostX.screen); + class_hint = XAllocClassHint(); for (index = 0 ; index < HostX.n_screens ; index++) @@ -767,11 +757,6 @@ hostx_screen_init (EphyrScreenInfo screen, static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen, int x, int y, int width, int height); -static void -ephyr_glamor_paint_rect (EphyrScreenInfo screen, - int sx, int sy, - int dx, int dy, - int width, int height); void hostx_paint_rect (EphyrScreenInfo screen, @@ -783,11 +768,6 @@ hostx_paint_rect (EphyrScreenInfo screen, EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ; - if (ephyr_glamor) { - ephyr_glamor_paint_rect(screen, sx, sy, dx, dy, width, height); - return; - } - /* * Copy the image data updated by the shadow layer * on to the window @@ -1465,82 +1445,3 @@ hostx_has_glx (void) } #endif /* XF86DRI */ - -static void -ephyr_glamor_get_visual(void) -{ - Display *dpy = HostX.dpy; - int attribs[] = {GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_DOUBLEBUFFER, 1, - None}; - XVisualInfo *visual_info; - int event_base = 0, error_base = 0; - - if (!glXQueryExtension (dpy, &event_base, &error_base)) - errx(1, "Couldn't find GLX extension\n"); - - visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs); - if (visual_info == NULL) - errx(1, "Couldn't get RGB visual\n"); - - HostX.visual_info = visual_info; - HostX.visual = visual_info->visual; -} - -void -ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen) -{ - Display *dpy = HostX.dpy; - GLXContext ctx; - struct EphyrHostScreen *host_screen; - - host_screen = host_screen_from_screen_info(ephyr_screen); - - ctx = glXCreateContext(dpy, HostX.visual_info, NULL, True); - if (ctx == NULL) - errx(1, "glXCreateContext failed\n"); - - if (!glXMakeCurrent(dpy, host_screen->win, ctx)) - errx(1, "glXMakeCurrent failed\n"); -} - -static void -ephyr_glamor_paint_rect (EphyrScreenInfo screen, - int sx, int sy, - int dx, int dy, - int width, int height) -{ - struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen); - static PFNGLXCOPYSUBBUFFERMESAPROC pglXCopySubBufferMESA = NULL; - - if (!pglXCopySubBufferMESA) { - pglXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC) - glXGetProcAddressARB((const GLubyte*)"glXCopySubBufferMESA"); - assert(pglXCopySubBufferMESA); - } - - /* Always copy the full screen until we get things rendering correctly. */ -#if 0 - pglXCopySubBufferMESA(HostX.dpy, host_screen->win, - sx, sy, width, height); -#else - pglXCopySubBufferMESA(HostX.dpy, host_screen->win, - 0, 0, - host_screen->win_width, host_screen->win_height); -#endif -} - -struct glamor_gl_dispatch; -extern Bool -glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, int gl_version, void* func); - -Bool -glamor_gl_dispatch_init(void *screen, struct glamor_gl_dispatch *dispatch, int gl_version) -{ - if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, glXGetProcAddress)) - return FALSE; - return TRUE; -} diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h index d5cb0faa6..42578576a 100644 --- a/hw/kdrive/ephyr/hostx.h +++ b/hw/kdrive/ephyr/hostx.h @@ -261,7 +261,4 @@ int hostx_has_dri (void) ; int hostx_has_glx (void) ; #endif /* XF86DRI */ -/* ephyr_glamor_host.c */ -void ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen); - #endif /*_XLIBS_STUFF_H_*/ diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index f76a36155..e3ef14fc1 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -27,16 +27,12 @@ if INT10MODULE INT10_SUBDIR = int10 endif -if GLAMOR -GLAMOR_DIR=glamor -endif - -SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw $(GLAMOR_DIR) os-support parser \ +SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \ ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ loader dixmods exa modes \ $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man -DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw $(GLAMOR_DIR) os-support \ +DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ parser ramdac shadowfb vbe vgahw xaa \ loader dixmods dri dri2 exa modes \ utils doc man diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 173d76570..c031d4be3 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -89,10 +89,4 @@ if LNXACPI XORG_CFLAGS += -DHAVE_ACPI endif -if GLAMOR_DDX -GLAMOR_DDX_CFLAGS = -DGLAMOR_DDX -endif - -AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_DDX_CFLAGS) - - +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 7ab3f2875..447b19229 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -1118,11 +1118,7 @@ videoPtrToDriverList(struct pci_device *dev, } else if (dev->device_id == 0x8108) { break; /* "hooray" for poulsbo */ } else { -#ifdef GLAMOR_DDX - driverList[0] = "glamor"; -#else - driverList[0] = "intel"; -#endif + driverList[0] = "intel"; } break; case 0x102b: driverList[0] = "mga"; break; diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am index ba4aeb402..1a162ab1c 100644 --- a/hw/xfree86/dixmods/Makefile.am +++ b/hw/xfree86/dixmods/Makefile.am @@ -14,14 +14,9 @@ if RECORD RECORDMOD = librecord.la endif -if GLAMOR -LIBGLAMOR_DIX = libglamor_dix.la -endif - module_LTLIBRARIES = libfb.la \ libwfb.la \ - libshadow.la \ - $(LIBGLAMOR_DIX) + libshadow.la extsmoduledir = $(moduledir)/extensions extsmodule_LTLIBRARIES = $(RECORDMOD) \ @@ -34,17 +29,11 @@ INCLUDES = @XORG_INCS@ \ -I$(top_srcdir)/hw/xfree86/loader \ -I$(top_srcdir)/miext/shadow \ -I$(top_srcdir)/glx - libdbe_la_LDFLAGS = -avoid-version libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la libdbe_la_SOURCES = dbemodule.c -if GLAMOR -libglamor_dix_la_LDFLAGS = -avoid-version -libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la -libglamor_dix_la_SOURCES = glamor_module.c $(top_srcdir)/glamor/glamor_egl.c -libglamor_dix_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/glamor $(LIBDRM_CFLAGS) -endif + libfb_la_LDFLAGS = -avoid-version libfb_la_LIBADD = $(top_builddir)/fb/libfb.la libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c diff --git a/hw/xfree86/dixmods/glamor_module.c b/hw/xfree86/dixmods/glamor_module.c deleted file mode 100644 index ee2dba871..000000000 --- a/hw/xfree86/dixmods/glamor_module.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 1998 The XFree86 Project, Inc. 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 THE - * XFREE86 PROJECT 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. - * - * Except as contained in this notice, the name of the XFree86 Project shall - * not be used in advertising or otherwise to promote the sale, use or other - * dealings in this Software without prior written authorization from the - * XFree86 Project. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include "xf86Module.h" - -static XF86ModuleVersionInfo VersRec = -{ - "glamor_dix", - MODULEVENDORSTRING, - MODINFOSTRING1, - MODINFOSTRING2, - XORG_VERSION_CURRENT, - 1, 0, 0, - ABI_CLASS_ANSIC, /* Only need the ansic layer */ - ABI_ANSIC_VERSION, - MOD_CLASS_NONE, - {0,0,0,0} /* signature, to be patched into the file by a tool */ -}; - -_X_EXPORT XF86ModuleData glamor_dixModuleData = { &VersRec, NULL, NULL }; diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am deleted file mode 100644 index 1d729f46b..000000000 --- a/hw/xfree86/glamor/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -glamor_la_LTLIBRARIES = glamor.la -glamor_la_CFLAGS = \ - -DHAVE_XORG_CONFIG_H \ - @DIX_CFLAGS@ @XORG_CFLAGS@ @LIBDRM_CFLAGS@ \ - -I$(top_srcdir)/hw/xfree86/common \ - -I$(top_srcdir)/hw/xfree86/os-support/bus \ - -I$(top_srcdir)/hw/xfree86/parser \ - -I$(top_srcdir)/hw/xfree86/modes \ - -I$(top_srcdir)/hw/xfree86/ddc \ - -I$(top_srcdir)/hw/xfree86/ramdac \ - -I$(top_srcdir)/hw/xfree86/i2c \ - -I$(top_srcdir)/glamor - -if GLAMOR_GLES2 -glamor_la_CFLAGS+=-DGLAMOR_GLES2 -endif - -glamor_la_LDFLAGS = -module -avoid-version \ - $(EGL_LIBS) - -glamor_ladir = $(moduledir)/drivers -glamor_la_SOURCES = \ - glamor_ddx.c \ - glamor_crtc.c \ - glamor_ddx.h - -glamor_la_DEPENDENCIES = \ - $(top_builddir)/glamor/libglamor.la diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c deleted file mode 100644 index ce4f31f54..000000000 --- a/hw/xfree86/glamor/glamor_crtc.c +++ /dev/null @@ -1,1565 +0,0 @@ -/* - * Copyright © 2007 Red Hat, Inc. - * Copyright © 2010 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: - * Dave Airlie - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "glamor_ddx.h" - -typedef struct { - int fd; - uint32_t fb_id; - drmModeResPtr mode_res; - int cpp; - - drmEventContext event_context; - void *event_data; - int old_fb_id; - int flip_count; -} drmmode_rec, *drmmode_ptr; - -typedef struct { - drmmode_ptr drmmode; - drmModeCrtcPtr mode_crtc; - uint32_t rotate_fb_id; - struct glamor_gbm_cursor *cursor; -} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; - -typedef struct { - drmModePropertyPtr mode_prop; - uint64_t value; - int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ - Atom *atoms; -} drmmode_prop_rec, *drmmode_prop_ptr; - -struct fixed_panel_lvds { - int hdisplay; - int vdisplay; -}; -typedef struct { - drmmode_ptr drmmode; - int output_id; - drmModeConnectorPtr mode_output; - drmModeEncoderPtr mode_encoder; - drmModePropertyBlobPtr edid_blob; - int num_props; - drmmode_prop_ptr props; - void *private_data; - int dpms_mode; - char *backlight_iface; - int backlight_active_level; - int backlight_max; -} drmmode_output_private_rec, *drmmode_output_private_ptr; - -static void -drmmode_output_dpms(xf86OutputPtr output, int mode); -static Bool -drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height); - -#define BACKLIGHT_CLASS "/sys/class/backlight" - -/* - * List of available kernel interfaces in priority order - */ -static char *backlight_interfaces[] = { - "asus-laptop", - "eeepc", - "thinkpad_screen", - "acpi_video1", - "acpi_video0", - "fujitsu-laptop", - "sony", - "samsung", - NULL, -}; -/* - * Must be long enough for BACKLIGHT_CLASS + '/' + longest in above table + - * '/' + "max_backlight" - */ -#define BACKLIGHT_PATH_LEN 80 -/* Enough for 10 digits of backlight + '\n' + '\0' */ -#define BACKLIGHT_VALUE_LEN 12 - -static void -drmmode_backlight_set(xf86OutputPtr output, int level) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; - int fd, len, ret; - - if (level > drmmode_output->backlight_max) - level = drmmode_output->backlight_max; - if (! drmmode_output->backlight_iface || level < 0) - return; - - len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level); - sprintf(path, "%s/%s/brightness", - BACKLIGHT_CLASS, drmmode_output->backlight_iface); - fd = open(path, O_RDWR); - if (fd == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s for backlight " - "control: %s\n", path, strerror(errno)); - return; - } - - ret = write(fd, val, len); - if (ret == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "write to %s for backlight " - "control failed: %s\n", path, strerror(errno)); - } - - close(fd); -} - -static int -drmmode_backlight_get(xf86OutputPtr output) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; - int fd, level; - - if (! drmmode_output->backlight_iface) - return -1; - - sprintf(path, "%s/%s/actual_brightness", - BACKLIGHT_CLASS, drmmode_output->backlight_iface); - fd = open(path, O_RDONLY); - if (fd == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s " - "for backlight control: %s\n", path, strerror(errno)); - return -1; - } - - memset(val, 0, sizeof(val)); - if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) { - close(fd); - return -1; - } - - close(fd); - - level = atoi(val); - if (level > drmmode_output->backlight_max) - level = drmmode_output->backlight_max; - if (level < 0) - level = -1; - return level; -} - -static int -drmmode_backlight_get_max(xf86OutputPtr output) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; - int fd, max = 0; - - sprintf(path, "%s/%s/max_brightness", - BACKLIGHT_CLASS, drmmode_output->backlight_iface); - fd = open(path, O_RDONLY); - if (fd == -1) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s " - "for backlight control: %s\n", path, strerror(errno)); - return 0; - } - - memset(val, 0, sizeof(val)); - if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) { - close(fd); - return -1; - } - - close(fd); - - max = atoi(val); - if (max <= 0) - max = -1; - return max; -} - -static void -drmmode_backlight_init(xf86OutputPtr output) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - char path[BACKLIGHT_PATH_LEN]; - struct stat buf; - int i; - - for (i = 0; backlight_interfaces[i] != NULL; i++) { - sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]); - if (!stat(path, &buf)) { - drmmode_output->backlight_iface = backlight_interfaces[i]; - xf86DrvMsg(output->scrn->scrnIndex, X_INFO, - "found backlight control interface %s\n", path); - drmmode_output->backlight_max = drmmode_backlight_get_max(output); - drmmode_output->backlight_active_level = drmmode_backlight_get(output); - return; - } - } - drmmode_output->backlight_iface = NULL; -} - - -static void -drmmode_ConvertFromKMode(ScrnInfoPtr scrn, - drmModeModeInfoPtr kmode, - DisplayModePtr mode) -{ - memset(mode, 0, sizeof(DisplayModeRec)); - mode->status = MODE_OK; - - mode->Clock = kmode->clock; - - mode->HDisplay = kmode->hdisplay; - mode->HSyncStart = kmode->hsync_start; - mode->HSyncEnd = kmode->hsync_end; - mode->HTotal = kmode->htotal; - mode->HSkew = kmode->hskew; - - mode->VDisplay = kmode->vdisplay; - mode->VSyncStart = kmode->vsync_start; - mode->VSyncEnd = kmode->vsync_end; - mode->VTotal = kmode->vtotal; - mode->VScan = kmode->vscan; - - mode->Flags = kmode->flags; //& FLAG_BITS; - mode->name = strdup(kmode->name); - - if (kmode->type & DRM_MODE_TYPE_DRIVER) - mode->type = M_T_DRIVER; - if (kmode->type & DRM_MODE_TYPE_PREFERRED) - mode->type |= M_T_PREFERRED; - xf86SetModeCrtc (mode, scrn->adjustFlags); -} - -static void -drmmode_ConvertToKMode(ScrnInfoPtr scrn, - drmModeModeInfoPtr kmode, - DisplayModePtr mode) -{ - memset(kmode, 0, sizeof(*kmode)); - - kmode->clock = mode->Clock; - kmode->hdisplay = mode->HDisplay; - kmode->hsync_start = mode->HSyncStart; - kmode->hsync_end = mode->HSyncEnd; - kmode->htotal = mode->HTotal; - kmode->hskew = mode->HSkew; - - kmode->vdisplay = mode->VDisplay; - kmode->vsync_start = mode->VSyncStart; - kmode->vsync_end = mode->VSyncEnd; - kmode->vtotal = mode->VTotal; - kmode->vscan = mode->VScan; - - kmode->flags = mode->Flags; //& FLAG_BITS; - if (mode->name) - strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); - kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; - -} - -static void -drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode) -{ - -} - -static Bool -drmmode_update_fb (ScrnInfoPtr scrn, int width, int height) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - drmmode_crtc_private_ptr - drmmode_crtc = xf86_config->crtc[0]->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - uint32_t handle, pitch; - int ret; - - if (drmmode->fb_id != 0 && - scrn->virtualX == width && scrn->virtualY == height) - return TRUE; - if (!glamor_front_buffer_resize(scrn, width, height)) - return FALSE; - if (drmmode->fb_id != 0) - drmModeRmFB(drmmode->fd, drmmode->fb_id); - glamor_frontbuffer_handle(scrn, &handle, &pitch); - ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, - scrn->bitsPerPixel, pitch /** drmmode->cpp*/, - handle, &drmmode->fb_id); - if (ret) - /* FIXME: Undo glamor_resize() */ - return FALSE; - - return TRUE; -} - -static Bool -drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, - Rotation rotation, int x, int y) -{ - ScrnInfoPtr scrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - int saved_x, saved_y; - Rotation saved_rotation; - DisplayModeRec saved_mode; - uint32_t *output_ids; - int output_count = 0; - int ret = TRUE; - int i; - int fb_id; - uint32_t handle, pitch; - drmModeModeInfo kmode; - - if (drmmode->fb_id == 0) { - - glamor_frontbuffer_handle(scrn, &handle, &pitch); - ret = drmModeAddFB(drmmode->fd, - scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, - pitch, handle, - &drmmode->fb_id); - if (ret < 0) { - ErrorF("failed to add fb\n"); - return FALSE; - } - } - - saved_mode = crtc->mode; - saved_x = crtc->x; - saved_y = crtc->y; - saved_rotation = crtc->rotation; - - crtc->mode = *mode; - crtc->x = x; - crtc->y = y; - crtc->rotation = rotation; - - output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); - if (!output_ids) { - ret = FALSE; - goto done; - } - - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - drmmode_output_private_ptr drmmode_output; - - if (output->crtc != crtc) - continue; - - drmmode_output = output->driver_private; - output_ids[output_count] = - drmmode_output->mode_output->connector_id; - output_count++; - } - -#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0) - if (!xf86CrtcRotate(crtc, mode, rotation)) - goto done; -#else - if (!xf86CrtcRotate(crtc)) - goto done; -#endif - -#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); -#endif - - drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); - - - fb_id = drmmode->fb_id; - if (drmmode_crtc->rotate_fb_id) { - fb_id = drmmode_crtc->rotate_fb_id; - x = 0; - y = 0; - } - ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - fb_id, x, y, output_ids, output_count, &kmode); - if (ret) - xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, - "failed to set mode: %s", strerror(-ret)); - else - ret = TRUE; - - /* Turn on any outputs on this crtc that may have been disabled */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - - if (output->crtc != crtc) - continue; - - drmmode_output_dpms(output, DPMSModeOn); - } - - if (scrn->pScreen) - xf86_reload_cursors(scrn->pScreen); -done: - if (!ret) { - crtc->x = saved_x; - crtc->y = saved_y; - crtc->rotation = saved_rotation; - crtc->mode = saved_mode; - } - return ret; -} - -static void -drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) -{ - -} - -static void -drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - - drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); -} - -static void -drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - ScrnInfoPtr scrn = crtc->scrn; - ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - GCPtr gc; - - if (drmmode_crtc->cursor == NULL) - { - drmmode_crtc->cursor = calloc(1, sizeof(*drmmode_crtc->cursor)); - if (drmmode_crtc->cursor == NULL) { - ErrorF("Failed to allocate cursor.\n"); - return; - } - if (!glamor_create_cursor(scrn, drmmode_crtc->cursor, 64, 64)) { - free(drmmode_crtc->cursor); - drmmode_crtc->cursor = NULL; - ErrorF("Failed to create glamor cursor.\n"); - return; - } - } - - gc = GetScratchGC (drmmode_crtc->cursor->cursor_pixmap->drawable.depth, screen); - if (!gc) - return; - - ValidateGC (&drmmode_crtc->cursor->cursor_pixmap->drawable, gc); - (*gc->ops->PutImage)(&drmmode_crtc->cursor->cursor_pixmap->drawable, gc, - 32, 0, 0, 64, 64, 0, ZPixmap, (char*)image); - FreeScratchGC (gc); -} - - -static void -drmmode_hide_cursor (xf86CrtcPtr crtc) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - - drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - 0, 64, 64); -} - - -static void -_drmmode_destroy_cursor(xf86CrtcPtr crtc) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - - if (drmmode_crtc->cursor == NULL) - return; - drmmode_hide_cursor(crtc); - glamor_destroy_cursor(crtc->scrn, drmmode_crtc->cursor); - free(drmmode_crtc->cursor); - drmmode_crtc->cursor = NULL; -} - -static void -drmmode_destroy_cursor(ScrnInfoPtr scrn) -{ - int i; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - - for (i = 0; i < xf86_config->num_crtc; i++) - _drmmode_destroy_cursor(xf86_config->crtc[i]); -} - - - - -static void -drmmode_show_cursor (xf86CrtcPtr crtc) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - uint32_t handle, stride; - - ErrorF("show cursor\n"); - glamor_cursor_handle(drmmode_crtc->cursor, &handle, &stride); - - drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - handle, 64, 64); -} - -#if 0 -static void * -drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) -{ - ScrnInfoPtr scrn = crtc->scrn; - intel_screen_private *intel = intel_get_screen_private(scrn); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - int size, ret; - unsigned long rotate_pitch; - - width = i830_pad_drawable_width(width, drmmode->cpp); - rotate_pitch = width * drmmode->cpp; - size = rotate_pitch * height; - - drmmode_crtc->rotate_bo = - drm_intel_bo_alloc(intel->bufmgr, "rotate", size, 4096); - - if (!drmmode_crtc->rotate_bo) { - xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, - "Couldn't allocate shadow memory for rotated CRTC\n"); - return NULL; - } - - drm_intel_bo_disable_reuse(drmmode_crtc->rotate_bo); - - ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, - crtc->scrn->bitsPerPixel, rotate_pitch, - drmmode_crtc->rotate_bo->handle, - &drmmode_crtc->rotate_fb_id); - if (ret) { - ErrorF("failed to add rotate fb\n"); - drm_intel_bo_unreference(drmmode_crtc->rotate_bo); - return NULL; - } - - return drmmode_crtc->rotate_bo; -} - -static PixmapPtr -drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) -{ - ScrnInfoPtr scrn = crtc->scrn; - intel_screen_private *intel = intel_get_screen_private(scrn); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - unsigned long rotate_pitch; - PixmapPtr rotate_pixmap; - - if (!data) { - data = drmmode_crtc_shadow_allocate (crtc, width, height); - if (!data) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Couldn't allocate shadow pixmap for rotated CRTC\n"); - return NULL; - } - } - - rotate_pitch = - i830_pad_drawable_width(width, drmmode->cpp) * drmmode->cpp; - rotate_pixmap = GetScratchPixmapHeader(scrn->pScreen, - width, height, - scrn->depth, - scrn->bitsPerPixel, - rotate_pitch, - NULL); - - if (rotate_pixmap == NULL) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Couldn't allocate shadow pixmap for rotated CRTC\n"); - return NULL; - } - - if (drmmode_crtc->rotate_bo) - i830_set_pixmap_bo(rotate_pixmap, drmmode_crtc->rotate_bo); - - intel->shadow_present = TRUE; - - return rotate_pixmap; -} - -static void -drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) -{ -} -#endif - -static void -drmmode_crtc_gamma_set(xf86CrtcPtr crtc, - CARD16 *red, CARD16 *green, CARD16 *blue, int size) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - - drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - size, red, green, blue); -} -static void -drmmode_crtc_destroy(xf86CrtcPtr crtc) -{ - ScrnInfoPtr scrn = crtc->scrn; - _drmmode_destroy_cursor(crtc); - crtc->driver_private = NULL; -} - -static const xf86CrtcFuncsRec drmmode_crtc_funcs = { - .dpms = drmmode_crtc_dpms, - .set_mode_major = drmmode_set_mode_major, - .set_cursor_colors = drmmode_set_cursor_colors, - .set_cursor_position = drmmode_set_cursor_position, - .show_cursor = drmmode_show_cursor, - .hide_cursor = drmmode_hide_cursor, - .load_cursor_argb = drmmode_load_cursor_argb, - .load_cursor_image = NULL, -#if 0 - .shadow_create = drmmode_crtc_shadow_create, - .shadow_allocate = drmmode_crtc_shadow_allocate, - .shadow_destroy = drmmode_crtc_shadow_destroy, -#endif - .gamma_set = drmmode_crtc_gamma_set, - .destroy = drmmode_crtc_destroy -}; - - -static void -drmmode_crtc_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) -{ - xf86CrtcPtr crtc; - drmmode_crtc_private_ptr drmmode_crtc; - - crtc = xf86CrtcCreate(scrn, &drmmode_crtc_funcs); - if (crtc == NULL) - return; - - drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); - drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, - drmmode->mode_res->crtcs[num]); - drmmode_crtc->drmmode = drmmode; - crtc->driver_private = drmmode_crtc; - - return; -} - -static xf86OutputStatus -drmmode_output_detect(xf86OutputPtr output) -{ - /* go to the hw and retrieve a new output struct */ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmmode_ptr drmmode = drmmode_output->drmmode; - xf86OutputStatus status; - drmModeFreeConnector(drmmode_output->mode_output); - - drmmode_output->mode_output = - drmModeGetConnector(drmmode->fd, drmmode_output->output_id); - - switch (drmmode_output->mode_output->connection) { - case DRM_MODE_CONNECTED: - status = XF86OutputStatusConnected; - break; - case DRM_MODE_DISCONNECTED: - status = XF86OutputStatusDisconnected; - break; - default: - case DRM_MODE_UNKNOWNCONNECTION: - status = XF86OutputStatusUnknown; - break; - } - return status; -} - -static Bool -drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - struct fixed_panel_lvds *p_lvds = drmmode_output->private_data; - - /* - * If the connector type is LVDS, we will use the panel limit to - * verfiy whether the mode is valid. - */ - if ((koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) && p_lvds) { - if (pModes->HDisplay > p_lvds->hdisplay || - pModes->VDisplay > p_lvds->vdisplay) - return MODE_PANEL; - else - return MODE_OK; - } - return MODE_OK; -} - -static void fill_detailed_lvds_block(struct detailed_monitor_section *det_mon, - DisplayModePtr mode) -{ - struct detailed_timings *timing = &det_mon->section.d_timings; - - det_mon->type = DT; - timing->clock = mode->Clock * 1000; - timing->h_active = mode->HDisplay; - timing->h_blanking = mode->HTotal - mode->HDisplay; - timing->v_active = mode->VDisplay; - timing->v_blanking = mode->VTotal - mode->VDisplay; - timing->h_sync_off = mode->HSyncStart - mode->HDisplay; - timing->h_sync_width = mode->HSyncEnd - mode->HSyncStart; - timing->v_sync_off = mode->VSyncStart - mode->VDisplay; - timing->v_sync_width = mode->VSyncEnd - mode->VSyncStart; - - if (mode->Flags & V_PVSYNC) - timing->misc |= 0x02; - - if (mode->Flags & V_PHSYNC) - timing->misc |= 0x01; -} - -static int drmmode_output_lvds_edid(xf86OutputPtr output, - struct fixed_panel_lvds *p_lvds) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - int i, j; - DisplayModePtr pmode; - xf86MonPtr edid_mon; - drmModeModeInfo *mode_ptr; - struct detailed_monitor_section *det_mon; - - if (output->MonInfo) { - /* - * If there exists the EDID, we will either find a DS_RANGES - * or replace a DS_VENDOR block, smashing it into a DS_RANGES - * block with opern refresh to match all the default modes. - */ - int edid_det_block_num; - edid_mon = output->MonInfo; - edid_mon->features.msc |= 0x01; - j = -1; - edid_det_block_num = sizeof(edid_mon->det_mon) / - sizeof(edid_mon->det_mon[0]); - for (i = 0; i < edid_det_block_num; i++) { - if (edid_mon->det_mon[i].type >= DS_VENDOR && j == -1) - j = i; - if (edid_mon->det_mon[i].type == DS_RANGES) { - j = i; - break; - } - } - if (j != -1) { - struct monitor_ranges *ranges = - &edid_mon->det_mon[j].section.ranges; - edid_mon->det_mon[j].type = DS_RANGES; - ranges->min_v = 0; - ranges->max_v = 200; - ranges->min_h = 0; - ranges->max_h = 200; - } - return 0; - } - /* - * If there is no EDID, we will construct a bogus EDID for LVDS output - * device. This is similar to what we have done in i830_lvds.c - */ - edid_mon = NULL; - edid_mon = calloc(1, sizeof(xf86Monitor)); - if (!edid_mon) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "Can't allocate memory for edid_mon.\n"); - return 0; - } - /* Find the fixed panel mode. - * In theory when there is no EDID, KMS kernel will return only one - * mode. And this can be regarded as fixed lvds panel mode. - * But it will be better to traverse the mode list to get the fixed - * lvds panel mode again as we don't know whether some new modes - * are added for the LVDS output device - */ - j = 0; - for (i = 0; i < koutput->count_modes; i++) { - mode_ptr = &koutput->modes[i]; - if ((mode_ptr->hdisplay == p_lvds->hdisplay) && - (mode_ptr->vdisplay == p_lvds->vdisplay)) { - /* find the fixed panel mode */ - j = i; - break; - } - } - pmode = xnfalloc(sizeof(DisplayModeRec)); - drmmode_ConvertFromKMode(output->scrn, &koutput->modes[j], pmode); - /*support DPM, instead of DPMS*/ - edid_mon->features.dpms |= 0x1; - /*defaultly support RGB color display*/ - edid_mon->features.display_type |= 0x1; - /*defaultly display support continuous-freqencey*/ - edid_mon->features.msc |= 0x1; - /*defaultly the EDID version is 1.4 */ - edid_mon->ver.version = 1; - edid_mon->ver.revision = 4; - det_mon = edid_mon->det_mon; - if (pmode) { - /* now we construct new EDID monitor, - * so filled one detailed timing block - */ - fill_detailed_lvds_block(det_mon, pmode); - /* the filed timing block should be set preferred*/ - edid_mon->features.msc |= 0x2; - det_mon = det_mon + 1; - } - /* Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - det_mon->type = DS_RANGES; - det_mon->section.ranges.min_v = 0; - det_mon->section.ranges.max_v = 200; - det_mon->section.ranges.min_h = 0; - det_mon->section.ranges.max_h = 200; - output->MonInfo = edid_mon; - return 0; -} - -static DisplayModePtr -drmmode_output_get_modes(xf86OutputPtr output) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; - int i; - DisplayModePtr Modes = NULL, Mode; - drmModePropertyPtr props; - struct fixed_panel_lvds *p_lvds; - drmModeModeInfo *mode_ptr; - - /* look for an EDID property */ - for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); - if (!props) - continue; - if (!(props->flags & DRM_MODE_PROP_BLOB)) { - drmModeFreeProperty(props); - continue; - } - - if (!strcmp(props->name, "EDID")) { - drmModeFreePropertyBlob(drmmode_output->edid_blob); - drmmode_output->edid_blob = - drmModeGetPropertyBlob(drmmode->fd, - koutput->prop_values[i]); - } - drmModeFreeProperty(props); - } - - if (drmmode_output->edid_blob) - xf86OutputSetEDID(output, - xf86InterpretEDID(output->scrn->scrnIndex, - drmmode_output->edid_blob->data)); - else - xf86OutputSetEDID(output, - xf86InterpretEDID(output->scrn->scrnIndex, - NULL)); - - /* modes should already be available */ - for (i = 0; i < koutput->count_modes; i++) { - Mode = xnfalloc(sizeof(DisplayModeRec)); - - drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], - Mode); - Modes = xf86ModesAdd(Modes, Mode); - - } - p_lvds = drmmode_output->private_data; - /* - * If the connector type is LVDS, we will traverse the kernel mode to - * get the panel limit. - * If it is incorrect, please fix me. - */ - if ((koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) && p_lvds) { - p_lvds->hdisplay = 0; - p_lvds->vdisplay = 0; - for (i = 0; i < koutput->count_modes; i++) { - mode_ptr = &koutput->modes[i]; - if ((mode_ptr->hdisplay >= p_lvds->hdisplay) && - (mode_ptr->vdisplay >= p_lvds->vdisplay)) { - p_lvds->hdisplay = mode_ptr->hdisplay; - p_lvds->vdisplay = mode_ptr->vdisplay; - } - } - if (!p_lvds->hdisplay || !p_lvds->vdisplay) - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "Incorrect KMS mode.\n"); - drmmode_output_lvds_edid(output, p_lvds); - } - return Modes; -} - -static void -drmmode_output_destroy(xf86OutputPtr output) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - int i; - - if (drmmode_output->edid_blob) - drmModeFreePropertyBlob(drmmode_output->edid_blob); - for (i = 0; i < drmmode_output->num_props; i++) { - drmModeFreeProperty(drmmode_output->props[i].mode_prop); - free(drmmode_output->props[i].atoms); - } - free(drmmode_output->props); - drmModeFreeConnector(drmmode_output->mode_output); - if (drmmode_output->private_data) { - free(drmmode_output->private_data); - drmmode_output->private_data = NULL; - } - if (drmmode_output->backlight_iface) - drmmode_backlight_set(output, drmmode_output->backlight_active_level); - free(drmmode_output); - output->driver_private = NULL; -} - -static void -drmmode_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - - if (!drmmode_output->backlight_iface) - return; - - if (mode == DPMSModeOn) { - /* If we're going from off->on we may need to turn on the backlight. */ - if (oldmode != DPMSModeOn) - drmmode_backlight_set(output, drmmode_output->backlight_active_level); - } else { - /* Only save the current backlight value if we're going from on to off. */ - if (oldmode == DPMSModeOn) - drmmode_output->backlight_active_level = drmmode_backlight_get(output); - drmmode_backlight_set(output, 0); - } -} - -static void -drmmode_output_dpms(xf86OutputPtr output, int mode) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; - int i; - drmModePropertyPtr props; - - for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); - if (!props) - continue; - - if (!strcmp(props->name, "DPMS")) { - drmModeConnectorSetProperty(drmmode->fd, - drmmode_output->output_id, - props->prop_id, - mode); - drmmode_output_dpms_backlight(output, - drmmode_output->dpms_mode, - mode); - drmmode_output->dpms_mode = mode; - drmModeFreeProperty(props); - return; - } - drmModeFreeProperty(props); - } -} - -static Bool -drmmode_property_ignore(drmModePropertyPtr prop) -{ - if (!prop) - return TRUE; - /* ignore blob prop */ - if (prop->flags & DRM_MODE_PROP_BLOB) - return TRUE; - /* ignore standard property */ - if (!strcmp(prop->name, "EDID") || - !strcmp(prop->name, "DPMS")) - return TRUE; - - return FALSE; -} - -#define BACKLIGHT_NAME "Backlight" -#define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT" -static Atom backlight_atom, backlight_deprecated_atom; - -static void -drmmode_output_create_resources(xf86OutputPtr output) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr mode_output = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; - drmModePropertyPtr drmmode_prop; - int i, j, err; - - drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); - if (!drmmode_output->props) - return; - - drmmode_output->num_props = 0; - for (i = 0, j = 0; i < mode_output->count_props; i++) { - drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); - if (drmmode_property_ignore(drmmode_prop)) { - drmModeFreeProperty(drmmode_prop); - continue; - } - drmmode_output->props[j].mode_prop = drmmode_prop; - drmmode_output->props[j].value = mode_output->prop_values[i]; - drmmode_output->num_props++; - j++; - } - - for (i = 0; i < drmmode_output->num_props; i++) { - drmmode_prop_ptr p = &drmmode_output->props[i]; - drmmode_prop = p->mode_prop; - - if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { - INT32 range[2]; - - p->num_atoms = 1; - p->atoms = calloc(p->num_atoms, sizeof(Atom)); - if (!p->atoms) - continue; - p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); - range[0] = drmmode_prop->values[0]; - range[1] = drmmode_prop->values[1]; - err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], - FALSE, TRUE, - drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, - 2, range); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - err = RRChangeOutputProperty(output->randr_output, p->atoms[0], - XA_INTEGER, 32, PropModeReplace, 1, &p->value, FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { - p->num_atoms = drmmode_prop->count_enums + 1; - p->atoms = calloc(p->num_atoms, sizeof(Atom)); - if (!p->atoms) - continue; - p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); - for (j = 1; j <= drmmode_prop->count_enums; j++) { - struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1]; - p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); - } - err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], - FALSE, FALSE, - drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, - p->num_atoms - 1, (INT32 *)&p->atoms[1]); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - for (j = 0; j < drmmode_prop->count_enums; j++) - if (drmmode_prop->enums[j].value == p->value) - break; - /* there's always a matching value */ - err = RRChangeOutputProperty(output->randr_output, p->atoms[0], - XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - } - } - - if (drmmode_output->backlight_iface) { - INT32 data, backlight_range[2]; - /* Set up the backlight property, which takes effect immediately - * and accepts values only within the backlight_range. */ - backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1, TRUE); - backlight_deprecated_atom = MakeAtom(BACKLIGHT_DEPRECATED_NAME, - sizeof(BACKLIGHT_DEPRECATED_NAME) - 1, TRUE); - - backlight_range[0] = 0; - backlight_range[1] = drmmode_output->backlight_max; - err = RRConfigureOutputProperty(output->randr_output, backlight_atom, - FALSE, TRUE, FALSE, 2, backlight_range); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - err = RRConfigureOutputProperty(output->randr_output, backlight_deprecated_atom, - FALSE, TRUE, FALSE, 2, backlight_range); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - /* Set the current value of the backlight property */ - data = drmmode_output->backlight_active_level; - err = RRChangeOutputProperty(output->randr_output, backlight_atom, - XA_INTEGER, 32, PropModeReplace, 1, &data, - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - err = RRChangeOutputProperty(output->randr_output, backlight_deprecated_atom, - XA_INTEGER, 32, PropModeReplace, 1, &data, - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - } -} - -static Bool -drmmode_output_set_property(xf86OutputPtr output, Atom property, - RRPropertyValuePtr value) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmmode_ptr drmmode = drmmode_output->drmmode; - int i; - - if (property == backlight_atom || property == backlight_deprecated_atom) { - INT32 val; - - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - { - return FALSE; - } - - val = *(INT32 *)value->data; - if (val < 0 || val > drmmode_output->backlight_max) - return FALSE; - - if (drmmode_output->dpms_mode == DPMSModeOn) - drmmode_backlight_set(output, val); - drmmode_output->backlight_active_level = val; - return TRUE; - } - - for (i = 0; i < drmmode_output->num_props; i++) { - drmmode_prop_ptr p = &drmmode_output->props[i]; - - if (p->atoms[0] != property) - continue; - - if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { - uint32_t val; - - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - return FALSE; - val = *(uint32_t *)value->data; - - drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, - p->mode_prop->prop_id, (uint64_t)val); - return TRUE; - } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { - Atom atom; - const char *name; - int j; - - if (value->type != XA_ATOM || value->format != 32 || value->size != 1) - return FALSE; - memcpy(&atom, value->data, 4); - name = NameForAtom(atom); - - /* search for matching name string, then set its value down */ - for (j = 0; j < p->mode_prop->count_enums; j++) { - if (!strcmp(p->mode_prop->enums[j].name, name)) { - drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, - p->mode_prop->prop_id, p->mode_prop->enums[j].value); - return TRUE; - } - } - return FALSE; - } - } - - return TRUE; -} - -static Bool -drmmode_output_get_property(xf86OutputPtr output, Atom property) -{ - drmmode_output_private_ptr drmmode_output = output->driver_private; - int err; - - if (property == backlight_atom || property == backlight_deprecated_atom) { - INT32 val; - - if (! drmmode_output->backlight_iface) - return FALSE; - - val = drmmode_backlight_get(output); - if (val < 0) - return FALSE; - err = RRChangeOutputProperty(output->randr_output, property, - XA_INTEGER, 32, PropModeReplace, 1, &val, - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - return FALSE; - } - - return TRUE; - } - - return TRUE; -} - -static const xf86OutputFuncsRec drmmode_output_funcs = { - .create_resources = drmmode_output_create_resources, -#ifdef RANDR_12_INTERFACE - .set_property = drmmode_output_set_property, - .get_property = drmmode_output_get_property, -#endif - .dpms = drmmode_output_dpms, - .detect = drmmode_output_detect, - .mode_valid = drmmode_output_mode_valid, - - .get_modes = drmmode_output_get_modes, - .destroy = drmmode_output_destroy -}; - -static int subpixel_conv_table[7] = { 0, SubPixelUnknown, - SubPixelHorizontalRGB, - SubPixelHorizontalBGR, - SubPixelVerticalRGB, - SubPixelVerticalBGR, - SubPixelNone }; - -static const char *output_names[] = { "None", - "VGA", - "DVI", - "DVI", - "DVI", - "Composite", - "TV", - "LVDS", - "CTV", - "DIN", - "DP", - "HDMI", - "HDMI", -}; - - -static void -drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) -{ - xf86OutputPtr output; - drmModeConnectorPtr koutput; - drmModeEncoderPtr kencoder; - drmmode_output_private_ptr drmmode_output; - char name[32]; - - koutput = drmModeGetConnector(drmmode->fd, - drmmode->mode_res->connectors[num]); - if (!koutput) - return; - - kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]); - if (!kencoder) { - drmModeFreeConnector(koutput); - return; - } - - snprintf(name, 32, "%s%d", output_names[koutput->connector_type], - koutput->connector_type_id); - - output = xf86OutputCreate (scrn, &drmmode_output_funcs, name); - if (!output) { - drmModeFreeEncoder(kencoder); - drmModeFreeConnector(koutput); - return; - } - - drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); - if (!drmmode_output) { - xf86OutputDestroy(output); - drmModeFreeConnector(koutput); - drmModeFreeEncoder(kencoder); - return; - } - /* - * If the connector type of the output device is LVDS, we will - * allocate the private_data to store the panel limit. - * For example: hdisplay, vdisplay - */ - drmmode_output->private_data = NULL; - if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) { - drmmode_output->private_data = calloc( - sizeof(struct fixed_panel_lvds), 1); - if (!drmmode_output->private_data) - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Can't allocate private memory for LVDS.\n"); - } - drmmode_output->output_id = drmmode->mode_res->connectors[num]; - drmmode_output->mode_output = koutput; - drmmode_output->mode_encoder = kencoder; - drmmode_output->drmmode = drmmode; - output->mm_width = koutput->mmWidth; - output->mm_height = koutput->mmHeight; - - output->subpixel_order = subpixel_conv_table[koutput->subpixel]; - output->driver_private = drmmode_output; - - if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) - drmmode_backlight_init(output); - - output->possible_crtcs = kencoder->possible_crtcs; - output->possible_clones = kencoder->possible_clones; - return; -} - - -static Bool -drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int i; - - if (!drmmode_update_fb(scrn, width, height)) - return FALSE; - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - - if (!crtc->enabled) - continue; - drmmode_set_mode_major(crtc, &crtc->mode, - crtc->rotation, crtc->x, crtc->y); - } - - return TRUE; -} - -static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { - drmmode_xf86crtc_resize -}; - -#if 0 -Bool -drmmode_do_pageflip(ScreenPtr screen, dri_bo *new_front, dri_bo *old_front, - void *data) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - intel_screen_private *intel = intel_get_screen_private(scrn); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - unsigned int pitch = scrn->displayWidth * intel->cpp; - int i, old_fb_id; - unsigned int crtc_id; - - /* - * Create a new handle for the back buffer - */ - old_fb_id = drmmode->fb_id; - if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, pitch, - new_front->handle, &drmmode->fb_id)) - goto error_out; - - /* - * Queue flips on all enabled CRTCs - * Note that if/when we get per-CRTC buffers, we'll have to update this. - * Right now it assumes a single shared fb across all CRTCs, with the - * kernel fixing up the offset of each CRTC as necessary. - * - * Also, flips queued on disabled or incorrectly configured displays - * may never complete; this is a configuration error. - */ - for (i = 0; i < config->num_crtc; i++) { - xf86CrtcPtr crtc = config->crtc[i]; - - if (!crtc->enabled) - continue; - - drmmode_crtc = crtc->driver_private; - crtc_id = drmmode_crtc->mode_crtc->crtc_id; - drmmode->event_data = data; - drmmode->flip_count++; - if (drmModePageFlip(drmmode->fd, crtc_id, drmmode->fb_id, - DRM_MODE_PAGE_FLIP_EVENT, drmmode)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "flip queue failed: %s\n", strerror(errno)); - goto error_undo; - } - } - - dri_bo_pin(new_front, 0); - dri_bo_unpin(new_front); - - scrn->fbOffset = new_front->offset; - intel->front_buffer->bo = new_front; - intel->front_buffer->offset = new_front->offset; - drmmode->old_fb_id = old_fb_id; - - return TRUE; - -error_undo: - drmModeRmFB(drmmode->fd, drmmode->fb_id); - drmmode->fb_id = old_fb_id; - -error_out: - xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", - strerror(errno)); - return FALSE; -} - -static void -drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data) -{ - I830DRI2FrameEventHandler(frame, tv_sec, tv_usec, event_data); -} - -static void -drmmode_page_flip_handler(int fd, unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data) -{ - drmmode_ptr drmmode = event_data; - - drmmode->flip_count--; - if (drmmode->flip_count > 0) - return; - - drmModeRmFB(drmmode->fd, drmmode->old_fb_id); - - I830DRI2FlipEventHandler(frame, tv_sec, tv_usec, drmmode->event_data); -} - -static void -drm_wakeup_handler(pointer data, int err, pointer p) -{ - drmmode_ptr drmmode = data; - fd_set *read_mask = p; - - if (err >= 0 && FD_ISSET(drmmode->fd, read_mask)) - drmHandleEvent(drmmode->fd, &drmmode->event_context); -} -#endif - -Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) -{ - drmmode_ptr drmmode; - unsigned int i; - - drmmode = xnfalloc(sizeof *drmmode); - drmmode->fd = fd; - drmmode->fb_id = 0; - - xf86CrtcConfigInit(scrn, &drmmode_xf86crtc_config_funcs); - - drmmode->cpp = cpp; - drmmode->mode_res = drmModeGetResources(drmmode->fd); - if (!drmmode->mode_res) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "failed to get resources: %s\n", strerror(errno)); - return FALSE; - } - - xf86CrtcSetSizeRange(scrn, 320, 200, drmmode->mode_res->max_width, - drmmode->mode_res->max_height); - for (i = 0; i < drmmode->mode_res->count_crtcs; i++) - drmmode_crtc_init(scrn, drmmode, i); - - for (i = 0; i < drmmode->mode_res->count_connectors; i++) - drmmode_output_init(scrn, drmmode, i); - - xf86InitialConfiguration(scrn, TRUE); - -#if 0 - gp.param = I915_PARAM_HAS_PAGEFLIPPING; - gp.value = &has_flipping; - (void)drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp, - sizeof(gp)); - if (has_flipping) { - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "Kernel page flipping support detected, enabling\n"); - intel->use_pageflipping = TRUE; - drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; - drmmode->event_context.vblank_handler = drmmode_vblank_handler; - drmmode->event_context.page_flip_handler = - drmmode_page_flip_handler; - AddGeneralSocket(fd); - RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, - drm_wakeup_handler, drmmode); - } -#endif - - return TRUE; -} - -void drmmode_closefb(ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr xf86_config; - drmmode_crtc_private_ptr drmmode_crtc; - drmmode_ptr drmmode; - - xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - - drmmode_crtc = xf86_config->crtc[0]->driver_private; - drmmode = drmmode_crtc->drmmode; - - drmmode_destroy_cursor(scrn); - - drmModeRmFB(drmmode->fd, drmmode->fb_id); - drmmode->fb_id = 0; -} diff --git a/hw/xfree86/glamor/glamor_ddx.c b/hw/xfree86/glamor/glamor_ddx.c deleted file mode 100644 index f4b37ab6b..000000000 --- a/hw/xfree86/glamor/glamor_ddx.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright © 2010 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: - * Kristian Høgsberg - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include -#include -#include -#include - -#include "../../../mi/micmap.h" -#include -#include -//#define GC XORG_GC -#include -//#undef GC - -#include "glamor_ddx.h" - -#define GLAMOR_VERSION_MAJOR 0 -#define GLAMOR_VERSION_MINOR 1 -#define GLAMOR_VERSION_PATCH 0 - -static const char glamor_ddx_name[] = "glamor"; - -static void -glamor_ddx_identify(int flags) -{ - xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name); -} - -static Bool -glamor_ddx_init_front_buffer(ScrnInfoPtr scrn, int width, int height) -{ - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - - glamor->root_bo = gbm_bo_create(glamor->gbm, width, height, - GBM_BO_FORMAT_ARGB8888, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - - if (glamor->root_bo == NULL) - return FALSE; - - scrn->virtualX = width; - scrn->virtualY = height; - /* XXX shall we update displayWidth here ? */ - return TRUE; -} - -static Bool -glamor_create_screen_image(ScrnInfoPtr scrn) -{ - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; - unsigned int handle, stride; - handle = gbm_bo_get_handle(glamor->root_bo).u32; - stride = gbm_bo_get_pitch(glamor->root_bo); - return glamor_create_egl_screen_image(screen, handle, stride); -} - -Bool -glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height) -{ - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; - - if (glamor->root_bo != NULL) { - glamor_close_egl_screen(screen); - gbm_bo_destroy(glamor->root_bo); - glamor->root_bo = NULL; - } - - if (!glamor_ddx_init_front_buffer(scrn, width, height)) - return FALSE; - return glamor_create_screen_image(scrn); -} - -void -glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch) -{ - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - *handle = gbm_bo_get_handle(glamor->root_bo).u32; - *pitch = gbm_bo_get_pitch(glamor->root_bo); -} - -Bool -glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height) -{ - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; - unsigned int handle, stride; - - - if (cursor->cursor_pixmap) - glamor_destroy_cursor(scrn, cursor); - - cursor->cursor_pixmap = screen->CreatePixmap(screen, 0, 0, 32, 0); - if (cursor->cursor_pixmap == NULL) - return FALSE; - screen->ModifyPixmapHeader(cursor->cursor_pixmap, width, height, 0, 0, 0, 0); - cursor->cursor_bo = gbm_bo_create(glamor->gbm, width, height, - GBM_BO_FORMAT_ARGB8888, - GBM_BO_USE_SCANOUT - | GBM_BO_USE_RENDERING - | GBM_BO_USE_CURSOR_64X64); - - if (cursor->cursor_bo == NULL) - goto fail; - glamor_cursor_handle(cursor, &handle, &stride); - if (!glamor_create_egl_pixmap_image(cursor->cursor_pixmap, handle, stride)) - goto fail; - - return TRUE; - -fail: - glamor_destroy_cursor(scrn, cursor); - return FALSE; -} - -void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor) -{ - ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; - if (cursor->cursor_pixmap) - screen->DestroyPixmap(cursor->cursor_pixmap); - if (cursor->cursor_bo) - gbm_bo_destroy(cursor->cursor_bo); - cursor->cursor_bo = NULL; - cursor->cursor_pixmap = NULL; -} - -void -glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch) -{ - *handle = gbm_bo_get_handle(cursor->cursor_bo).u32; - *pitch = gbm_bo_get_pitch(cursor->cursor_bo); - ErrorF("cursor stride: %d\n", *pitch); -} - -char * dri_device_name = "/dev/dri/card0"; -static Bool -glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags) -{ - struct glamor_ddx_screen_private *glamor; - rgb defaultWeight = { 0, 0, 0 }; - - glamor = xnfcalloc(sizeof *glamor, 1); - - scrn->driverPrivate = glamor; - glamor->fd = open(dri_device_name, O_RDWR); - if (glamor->fd == -1 ) { - ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno)); - goto fail; - } - - glamor->cpp = 4; - - scrn->monitor = scrn->confScreen->monitor; - scrn->progClock = TRUE; - scrn->rgbBits = 8; - - if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb)) - goto fail; - - xf86PrintDepthBpp(scrn); - - if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) - goto fail; - if (!xf86SetDefaultVisual(scrn, -1)) - goto fail; - - glamor->cpp = scrn->bitsPerPixel / 8; - - if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Kernel modesetting setup failed\n"); - goto fail; - } - - scrn->currentMode = scrn->modes; - xf86SetDpi(scrn, 0, 0); - - /* Load the required sub modules */ - if (!xf86LoadSubModule(scrn, "fb")) - goto fail; - - if (!xf86LoadSubModule(scrn, "glamor_dix")) - goto fail; - - return TRUE; - -fail: - scrn->driverPrivate = NULL; - free(glamor); - return FALSE; -} - -static void -glamor_ddx_adjust_frame(int scrnIndex, int x, int y, int flags) -{ -} - -static Bool -glamor_ddx_enter_vt(int scrnIndex, int flags) -{ - ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - - if (drmSetMaster(glamor->fd)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "drmSetMaster failed: %s\n", strerror(errno)); - return FALSE; - } - if (!xf86SetDesiredModes(scrn)) - return FALSE; - return TRUE; -} - -static void -glamor_ddx_leave_vt(int scrnIndex, int flags) -{ - ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - - drmDropMaster(glamor->fd); -} - -static Bool -glamor_ddx_create_screen_resources(ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - - screen->CreateScreenResources = glamor->CreateScreenResources; - if (!(*screen->CreateScreenResources) (screen)) - return FALSE; - if (!glamor_glyphs_init(screen)) - return FALSE; - if (glamor->root_bo == NULL) - return FALSE; - if (!glamor_create_screen_image(scrn)) - return FALSE; - return TRUE; -} - -static Bool -glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen) -{ - ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - - screen->CloseScreen = glamor->CloseScreen; - (*screen->CloseScreen) (scrnIndex, screen); - - if (scrn->vtSema == TRUE) - glamor_ddx_leave_vt(scrnIndex, 0); - - glamor_fini(screen); - glamor_close_egl_screen(screen); - gbm_bo_destroy(glamor->root_bo); - drmmode_closefb(scrn); - - return TRUE; -} - -static Bool -glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv) -{ - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - VisualPtr visual; - - glamor->gbm = gbm_create_device(glamor->fd); - if (glamor->gbm == NULL) { - ErrorF("couldn't create gbm device\n"); - return FALSE; - } - - glamor_egl_init(scrn, glamor->fd); - - miClearVisualTypes(); - if (!miSetVisualTypes(scrn->depth, - miGetDefaultVisualMask(scrn->depth), - scrn->rgbBits, scrn->defaultVisual)) - return FALSE; - if (!miSetPixmapDepths()) - return FALSE; - - if (!glamor_ddx_init_front_buffer(scrn, scrn->virtualX, scrn->virtualY)) - return FALSE; - - if (!fbScreenInit(screen, NULL, - scrn->virtualX, scrn->virtualY, - scrn->xDpi, scrn->yDpi, - 1, scrn->bitsPerPixel)) - return FALSE; - - if (scrn->bitsPerPixel > 8) { - /* Fixup RGB ordering */ - visual = screen->visuals + screen->numVisuals; - while(--visual >= screen->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = scrn->offset.red; - visual->offsetGreen = scrn->offset.green; - visual->offsetBlue = scrn->offset.blue; - visual->redMask = scrn->mask.red; - visual->blueMask = scrn->mask.blue; - } - } - } - - fbPictureInit(screen, NULL, 0); - xf86SetBlackWhitePixels(screen); - - if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Failed to initialize glamor\n"); - return FALSE; - } - - miInitializeBackingStore(screen); - xf86SetBackingStore(screen); - xf86SetSilkenMouse(screen); - miDCInitialize(screen, xf86GetPointerScreenFuncs()); - - xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n"); - - if (!xf86_cursors_init(screen, 64, 64, - (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | - HARDWARE_CURSOR_INVERT_MASK | - HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | - HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | - HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED | - HARDWARE_CURSOR_UPDATE_UNHIDDEN | - HARDWARE_CURSOR_ARGB))) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - } - - /* Must force it before EnterVT, so we are in control of VT and - * later memory should be bound when allocating, e.g rotate_mem */ - scrn->vtSema = TRUE; - - if (!glamor_ddx_enter_vt(scrnIndex, 0)) - return FALSE; - - screen->SaveScreen = xf86SaveScreen; - glamor->CreateScreenResources = screen->CreateScreenResources; - screen->CreateScreenResources = glamor_ddx_create_screen_resources; - glamor->CloseScreen = screen->CloseScreen; - screen->CloseScreen = glamor_ddx_close_screen; - /* Fixme should we init crtc screen here? */ - if (!xf86CrtcScreenInit(screen)) - return FALSE; - if (!miCreateDefColormap(screen)) - return FALSE; - /* Fixme should we add handle colormap here? */ - - xf86DPMSInit(screen, xf86DPMSSet, 0); - - return TRUE; -} - -static void -glamor_ddx_free_screen(int scrnIndex, int flags) -{ - ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn); - if (glamor != NULL) - { - close(glamor->fd); - free(glamor); - scrn->driverPrivate = NULL; - } -} - -static ModeStatus -glamor_ddx_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) -{ - if (mode->Flags & V_INTERLACE) { - if (verbose) { - xf86DrvMsg(scrnIndex, X_PROBED, - "Removing interlaced mode \"%s\"\n", - mode->name); - } - return MODE_BAD; - } - return MODE_OK; -} - -static Bool -glamor_ddx_probe(struct _DriverRec *drv, int flags) -{ - ScrnInfoPtr scrn = NULL; - GDevPtr *sections; - int entity, n; - - n = xf86MatchDevice(glamor_ddx_name, §ions); - if (n <= 0) - return FALSE; - - entity = xf86ClaimFbSlot(drv, 0, sections[0], TRUE); - - scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL); - if (scrn == NULL) { - xf86Msg(X_ERROR, "Failed to add fb entity\n"); - return FALSE; - } - - scrn->driverVersion = 1; - scrn->driverName = (char *) glamor_ddx_name; - scrn->name = (char *) glamor_ddx_name; - scrn->Probe = NULL; - - scrn->PreInit = glamor_ddx_pre_init; - scrn->ScreenInit = glamor_ddx_screen_init; - scrn->AdjustFrame = glamor_ddx_adjust_frame; - scrn->EnterVT = glamor_ddx_enter_vt; - scrn->LeaveVT = glamor_ddx_leave_vt; - scrn->FreeScreen = glamor_ddx_free_screen; - scrn->ValidMode = glamor_ddx_valid_mode; - - return TRUE; -} - -static const OptionInfoRec * -glamor_ddx_available_options(int chipid, int busid) -{ - return NULL; -} - -static Bool -glamor_ddx_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) -{ - xorgHWFlags *flag; - - switch (op) { - case GET_REQUIRED_HW_INTERFACES: - flag = (CARD32*)ptr; - (*flag) = 0; - return TRUE; - default: - /* Unknown or deprecated function */ - return FALSE; - } -} - -_X_EXPORT DriverRec glamor_ddx = { - 1, - "glamor", - glamor_ddx_identify, - glamor_ddx_probe, - glamor_ddx_available_options, - NULL, - 0, - glamor_ddx_driver_func, -}; - -static pointer -glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin) -{ - static Bool setupDone = 0; - - /* This module should be loaded only once, but check to be sure. - */ - if (!setupDone) { - setupDone = 1; - xf86AddDriver(&glamor_ddx, module, HaveDriverFuncs); - - /* - * The return value must be non-NULL on success even though there - * is no TearDownProc. - */ - return (pointer) 1; - } else { - if (errmaj) - *errmaj = LDR_ONCEONLY; - return NULL; - } -} - -static XF86ModuleVersionInfo glamor_ddx_version_info = { - glamor_ddx_name, - MODULEVENDORSTRING, - MODINFOSTRING1, - MODINFOSTRING2, - XORG_VERSION_CURRENT, - GLAMOR_VERSION_MAJOR, - GLAMOR_VERSION_MINOR, - GLAMOR_VERSION_PATCH, - ABI_CLASS_VIDEODRV, - ABI_VIDEODRV_VERSION, - MOD_CLASS_VIDEODRV, - {0, 0, 0, 0} -}; - -_X_EXPORT XF86ModuleData glamorModuleData = { - &glamor_ddx_version_info, - glamor_ddx_setup, - NULL -}; diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h deleted file mode 100644 index 3ffd48852..000000000 --- a/hw/xfree86/glamor/glamor_ddx.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef GLAMOR_DDX_H -#define GLAMOR_DDX_H - -#include -#define GLAMOR_FOR_XORG 1 -#include -struct glamor_ddx_screen_private { - struct gbm_bo *root_bo; - struct gbm_bo *cursor_bo; - struct gbm_device *gbm; - - CreateScreenResourcesProcPtr CreateScreenResources; - CloseScreenProcPtr CloseScreen; - int fd; - int cpp; -}; - -struct glamor_gbm_cursor { - struct gbm_bo *cursor_bo; - PixmapPtr cursor_pixmap; -}; - -inline static struct glamor_ddx_screen_private * -glamor_ddx_get_screen_private(ScrnInfoPtr scrn) -{ - return (struct glamor_ddx_screen_private *) (scrn->driverPrivate); -} - -Bool glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height); -void glamor_frontbuffer_handle(ScrnInfoPtr scrn, - uint32_t *handle, uint32_t *pitch); -Bool glamor_load_cursor(ScrnInfoPtr scrn, - int width, int height); - -void glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch); -Bool glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height); -void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor) ; - -Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp); -void drmmode_closefb(ScrnInfoPtr scrn); - -#endif diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in index c9760b090..0d1ea9142 100644 --- a/include/xorg-config.h.in +++ b/include/xorg-config.h.in @@ -139,15 +139,4 @@ /* Build with libdrm support */ #undef WITH_LIBDRM - -/* Build GLAMOR */ -#undef GLAMOR - -/* Build GLAMOR over GLES2*/ -#undef GLAMOR_GLES2 - -/* Build GLAMOR ddx*/ -#undef GLAMOR_DDX - - #endif /* _XORG_CONFIG_H_ */