From 4d52ae7f2dca78d493e11375d764c978db5567ed Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 Dec 2008 15:14:31 -0800 Subject: [PATCH] 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); +}