From 14d82a2bc3179160803c62c20746630d14e1b7d7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 13 Mar 2014 23:29:54 -0700 Subject: [PATCH 01/34] ephyr: Deal with non-root visual for window glx will sometimes select a non-root visual, deal with that by creating a suitable colormap and using that instead of attempting to use the default colormap. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- hw/kdrive/ephyr/hostx.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 435919e0a..b156fb9b8 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -287,7 +287,8 @@ hostx_set_title(char *title) int hostx_init(void) { - uint32_t attr; + uint32_t attrs[2]; + uint32_t attr_mask = 0; xcb_cursor_t empty_cursor; xcb_pixmap_t cursor_pxm; uint16_t red, green, blue; @@ -299,7 +300,7 @@ hostx_init(void) const xcb_query_extension_reply_t *shm_rep; xcb_screen_t *xscreen; - attr = + attrs[0] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION @@ -307,6 +308,7 @@ hostx_init(void) | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; + attr_mask |= XCB_CW_EVENT_MASK; EPHYR_DBG("mark"); #ifdef GLAMOR @@ -325,9 +327,18 @@ hostx_init(void) HostX.gc = xcb_generate_id(HostX.conn); HostX.depth = xscreen->root_depth; #ifdef GLAMOR - if (ephyr_glamor) + if (ephyr_glamor) { HostX.visual = ephyr_glamor_get_visual(); - else + if (HostX.visual->visual_id != xscreen->root_visual) { + attrs[1] = xcb_generate_id(HostX.conn); + attr_mask |= XCB_CW_COLORMAP; + xcb_create_colormap(HostX.conn, + XCB_COLORMAP_ALLOC_NONE, + attrs[1], + HostX.winroot, + HostX.visual->visual_id); + } + } else #endif HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual); @@ -379,9 +390,9 @@ hostx_init(void) scrpriv->win_height, 0, XCB_WINDOW_CLASS_COPY_FROM_PARENT, - XCB_COPY_FROM_PARENT, - XCB_CW_EVENT_MASK, - &attr); + HostX.visual->visual_id, + attr_mask, + attrs); } else { xcb_create_window(HostX.conn, @@ -391,9 +402,9 @@ hostx_init(void) 0,0,100,100, /* will resize */ 0, XCB_WINDOW_CLASS_COPY_FROM_PARENT, - XCB_COPY_FROM_PARENT, - XCB_CW_EVENT_MASK, - &attr); + HostX.visual->visual_id, + attr_mask, + attrs); hostx_set_win_title(screen, "(ctrl+shift grabs mouse and keyboard)"); From bf1429b2034a577c994ff16b60d809d05ca99241 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 7 May 2014 09:56:39 -0700 Subject: [PATCH 02/34] mi: Create miPolylines as a general-purpose line drawing function Instead of requiring all drivers to figure out which mi function to call for each of the four cases, create a single wrapper in mi that handles them correctly. Now drivers can simply use miPolylines in all cases. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- mi/mi.h | 6 ++++++ mi/miwideline.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/mi/mi.h b/mi/mi.h index 1209a16c4..b8a4f0568 100644 --- a/mi/mi.h +++ b/mi/mi.h @@ -452,6 +452,12 @@ extern _X_EXPORT void miWideDash(DrawablePtr /*pDrawable */ , DDXPointPtr /*pPts */ ); +extern _X_EXPORT void miPolylines(DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr pPts); + /* miwindow.c */ extern _X_EXPORT void miClearToBackground(WindowPtr /*pWin */ , diff --git a/mi/miwideline.c b/mi/miwideline.c index b76e7a818..29ba12c69 100644 --- a/mi/miwideline.c +++ b/mi/miwideline.c @@ -1979,3 +1979,23 @@ miWideDash(DrawablePtr pDrawable, GCPtr pGC, if (spanData) miCleanupSpanData(pDrawable, pGC, spanData); } + +void +miPolylines(DrawablePtr drawable, + GCPtr gc, + int mode, + int n, + DDXPointPtr points) +{ + if (gc->lineWidth == 0) { + if (gc->lineStyle == LineSolid) + miZeroLine(drawable, gc, mode, n, points); + else + miZeroDashLine(drawable, gc, mode, n, points); + } else { + if (gc->lineStyle == LineSolid) + miWideLine(drawable, gc, mode, n, points); + else + miWideDash(drawable, gc, mode, n, points); + } +} From a7fce36affb8211990e5b4956adea4d75f0e73c9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 7 May 2014 09:58:26 -0700 Subject: [PATCH 03/34] mi: Make miPolyArc draw fast zero-width when possible Instead of forcing drivers to figure out when to call miZeroPolyArc, have miPolyArc call that when possible. This involved renaming the existing miPolyArc call to miWideArc and creating a new miPolyArc wrapper function as miZeroPolyArc falls back to miWideArc when the arc is too large to be drawn with the zero-width code (ellipses larger than 800x800). Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- mi/mi.h | 5 +++++ mi/miarc.c | 11 ++++++++++- mi/mizerarc.c | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/mi/mi.h b/mi/mi.h index b8a4f0568..cacb2e076 100644 --- a/mi/mi.h +++ b/mi/mi.h @@ -67,6 +67,11 @@ typedef struct _miDash *miDashPtr; /* miarc.c */ +extern _X_EXPORT void miWideArc(DrawablePtr pDraw, + GCPtr pGC, + int narcs, + xArc * parcs); + extern _X_EXPORT void miPolyArc(DrawablePtr /*pDraw */ , GCPtr /*pGC */ , int /*narcs */ , diff --git a/mi/miarc.c b/mi/miarc.c index 0f56c7db3..e55108a44 100644 --- a/mi/miarc.c +++ b/mi/miarc.c @@ -886,7 +886,7 @@ miFillWideEllipse(DrawablePtr pDraw, GCPtr pGC, xArc * parc) */ void -miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) +miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) { int i; xArc *parc; @@ -3396,3 +3396,12 @@ drawQuadrant(struct arc_def *def, y--; } } + +void +miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) +{ + if (pGC->lineWidth == 0) + miZeroPolyArc(pDraw, pGC, narcs, parcs); + else + miWideArc(pDraw, pGC, narcs, parcs); +} diff --git a/mi/mizerarc.c b/mi/mizerarc.c index 9dac180d1..b216cf43d 100644 --- a/mi/mizerarc.c +++ b/mi/mizerarc.c @@ -656,7 +656,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) for (arc = parcs, i = narcs; --i >= 0; arc++) { if (!miCanZeroArc(arc)) - miPolyArc(pDraw, pGC, 1, arc); + miWideArc(pDraw, pGC, 1, arc); else { if (arc->width > arc->height) n = arc->width + (arc->height >> 1); From ea678a73c5688f73071d5581b6406808b7a0230f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 25 Apr 2014 22:43:51 -0700 Subject: [PATCH 04/34] mi: Fill spans for multiple arcs in miPolyFillArc This allocates span data for multiple arcs and draws the whole set in one call, rather than doing them one at a time. For modern hardware, this is a significant performance improvement. v2: Limit the number of spans per buffer to 4M to avoid integer overflow in computing the malloc size. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- mi/mifillarc.c | 144 +++++++++++++++++++++++-------------------------- 1 file changed, 66 insertions(+), 78 deletions(-) diff --git a/mi/mifillarc.c b/mi/mifillarc.c index 337343dd1..08484d703 100644 --- a/mi/mifillarc.c +++ b/mi/mifillarc.c @@ -476,26 +476,16 @@ miFillArcSliceSetup(xArc * arc, miArcSliceRec * slice, GCPtr pGC) *wids++ = slw; \ } -static void -miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int x, y, e; int yk, xk, ym, xm, dx, dy, xorg, yorg; int slw; miFillArcRec info; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; - points = malloc(sizeof(DDXPointRec) * arc->height); - if (!points) - return; - widths = malloc(sizeof(int) * arc->height); - if (!widths) { - free(points); - return; - } miFillArcSetup(arc, &info); MIFILLARCSETUP(); if (pGC->miTranslate) { @@ -508,31 +498,19 @@ miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) MIFILLARCSTEP(slw); ADDSPANS(); } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } -static void -miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int x, y; int xorg, yorg, dx, dy, slw; double e, yk, xk, ym, xm; miFillArcDRec info; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; - points = malloc(sizeof(DDXPointRec) * arc->height); - if (!points) - return; - widths = malloc(sizeof(int) * arc->height); - if (!widths) { - free(points); - return; - } miFillArcDSetup(arc, &info); MIFILLARCSETUP(); if (pGC->miTranslate) { @@ -545,9 +523,7 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) MIFILLARCSTEP(slw); ADDSPANS(); } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } #define ADDSPAN(l,r) \ @@ -572,17 +548,15 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) ADDSPAN(xl, xc); \ } -static void -miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int yk, xk, ym, xm, dx, dy, xorg, yorg, slw; int x, y, e; miFillArcRec info; miArcSliceRec slice; int ya, xl, xr, xc; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; miFillArcSetup(arc, &info); @@ -591,14 +565,6 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) slw = arc->height; if (slice.flip_top || slice.flip_bot) slw += (arc->height >> 1) + 1; - points = malloc(sizeof(DDXPointRec) * slw); - if (!points) - return; - widths = malloc(sizeof(int) * slw); - if (!widths) { - free(points); - return; - } if (pGC->miTranslate) { xorg += pDraw->x; yorg += pDraw->y; @@ -622,13 +588,11 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc) ADDSLICESPANS(slice.flip_bot); } } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } -static void -miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) +static int +miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths) { int x, y; int dx, dy, xorg, yorg, slw; @@ -636,9 +600,7 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) miFillArcDRec info; miArcSliceRec slice; int ya, xl, xr, xc; - DDXPointPtr points; DDXPointPtr pts; - int *widths; int *wids; miFillArcDSetup(arc, &info); @@ -647,14 +609,6 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) slw = arc->height; if (slice.flip_top || slice.flip_bot) slw += (arc->height >> 1) + 1; - points = malloc(sizeof(DDXPointRec) * slw); - if (!points) - return; - widths = malloc(sizeof(int) * slw); - if (!widths) { - free(points); - return; - } if (pGC->miTranslate) { xorg += pDraw->x; yorg += pDraw->y; @@ -678,35 +632,69 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc) ADDSLICESPANS(slice.flip_bot); } } - (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE); - free(widths); - free(points); + return pts - points; } /* MIPOLYFILLARC -- The public entry for the PolyFillArc request. * Since we don't have to worry about overlapping segments, we can just * fill each arc as it comes. */ -void -miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) -{ - int i; - xArc *arc; - for (i = narcs, arc = parcs; --i >= 0; arc++) { - if (miFillArcEmpty(arc)) - continue; - if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE)) { - if (miCanFillArc(arc)) - miFillEllipseI(pDraw, pGC, arc); - else - miFillEllipseD(pDraw, pGC, arc); +/* Limit the number of spans in a single draw request to avoid integer + * overflow in the computation of the span buffer size. + */ +#define MAX_SPANS_PER_LOOP (4 * 1024 * 1024) + +void +miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, xArc * parcs) +{ + while (narcs_all > 0) { + int narcs; + int i; + xArc *arc; + int nspans = 0; + DDXPointPtr pts, points; + int *wids, *widths; + int n; + + for (narcs = 0, arc = parcs; narcs < narcs_all; narcs++, arc++) { + if (narcs && nspans + arc->height > MAX_SPANS_PER_LOOP) + break; + nspans += arc->height; } - else { - if (miCanFillArc(arc)) - miFillArcSliceI(pDraw, pGC, arc); - else - miFillArcSliceD(pDraw, pGC, arc); + + pts = points = malloc (sizeof (DDXPointRec) * nspans + + sizeof(int) * nspans); + if (points) { + wids = widths = (int *) (points + nspans); + + for (i = 0, arc = parcs; i < narcs; arc++, i++) { + if (miFillArcEmpty(arc)) + continue; + if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE)) + { + if (miCanFillArc(arc)) + n = miFillEllipseI(pDraw, pGC, arc, pts, wids); + else + n = miFillEllipseD(pDraw, pGC, arc, pts, wids); + } + else + { + if (miCanFillArc(arc)) + n = miFillArcSliceI(pDraw, pGC, arc, pts, wids); + else + n = miFillArcSliceD(pDraw, pGC, arc, pts, wids); + } + pts += n; + wids += n; + } + nspans = pts - points; + if (nspans) + (*pGC->ops->FillSpans) (pDraw, pGC, nspans, points, + widths, FALSE); + free (points); } + parcs += narcs; + narcs_all -= narcs; } } From 3ac481c9dac591ffc33812ab047fc793d8a43d4f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 7 May 2014 10:31:16 -0700 Subject: [PATCH 05/34] mi: Draw multiple lines in one FillSpans call in miZeroLine miZeroLine allocates enough space to draw a line spanning the entire width/height of the target drawable. When drawing multiple shorter lines, this leaves most of the space in that buffer unfilled. Let multiple lines be drawn into the buffer if there is plenty of space. Speeds up glamor fallback zero-width lines: Before 6000000 trep @ 0.0020 msec (508000.0/sec): 1-pixel line 6000000 trep @ 0.0020 msec (492000.0/sec): 10-pixel line 6000000 trep @ 0.0023 msec (427000.0/sec): 100-pixel line 4000000 trep @ 0.0035 msec (282000.0/sec): 500-pixel line After: 600000000 trep @ 0.0000 msec (43400000.0/sec): 1-pixel line 140000000 trep @ 0.0001 msec (13000000.0/sec): 10-pixel line 16000000 trep @ 0.0008 msec (1300000.0/sec): 100-pixel line 4000000 trep @ 0.0038 msec (261000.0/sec): 500-pixel line (500 pixel lines do not change in performance because the buffer can only one one of them.) Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- mi/mizerline.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mi/mizerline.c b/mi/mizerline.c index 90798dbdf..f30e01239 100644 --- a/mi/mizerline.c +++ b/mi/mizerline.c @@ -179,14 +179,6 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */ MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom); while (--npt > 0) { - if (Nspans > 0) - (*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit, - pwidthInit, FALSE); - Nspans = 0; - new_span = TRUE; - spans = pspanInit - 1; - widths = pwidthInit - 1; - x1 = x2; y1 = y2; oc1 = oc2; @@ -208,6 +200,14 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant); + if (ady + 1 > (list_len - Nspans)) { + (*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit, + pwidthInit, FALSE); + Nspans = 0; + spans = pspanInit - 1; + widths = pwidthInit - 1; + } + new_span = TRUE; if (adx > ady) { e1 = ady << 1; e2 = e1 - (adx << 1); From 15e4d14dfae054c026b7e965ac33985e5cf6a168 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 15 Mar 2014 13:27:14 -0700 Subject: [PATCH 06/34] glamor: Replace fallback preparation code These offer a simpler and more efficient means for temporarily transitioning to CPU-accessible memory for fallback implementations. v2: Do not attempt fallbacks with GLAMOR_DRM_ONLY pixmaps glamor cannot transfer pixels for GLAMOR_DRM_ONLY pixmaps using glReadPixels and glTexSubImage2D, and so there's no way to perform fallback operations with these pixmaps. v3: Clear ->pbo field when deleting the PBO. Otherwise, we'd reuse the old name next time we fall back on the pixmap, which would potentially conflict with some other pixmap that genned a new name, or just do a lazy allocation of the name (compat GL context, like we currently use) or error out (core GL context, like we hope to use some day). Also, style fixes. Changes by anholt, acked by keithp. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/Makefile.am | 2 + glamor/glamor.c | 4 + glamor/glamor_core.c | 106 ---------------- glamor/glamor_picture.c | 18 --- glamor/glamor_prepare.c | 274 ++++++++++++++++++++++++++++++++++++++++ glamor/glamor_prepare.h | 52 ++++++++ glamor/glamor_priv.h | 15 +-- glamor/glamor_render.c | 63 +-------- glamor/glamor_utils.h | 2 + 9 files changed, 346 insertions(+), 190 deletions(-) create mode 100644 glamor/glamor_prepare.c create mode 100644 glamor/glamor_prepare.h diff --git a/glamor/Makefile.am b/glamor/Makefile.am index bde58b632..cb81872b4 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -21,6 +21,8 @@ libglamor_la_SOURCES = \ glamor_image.c \ glamor_render.c \ glamor_gradient.c \ + glamor_prepare.c \ + glamor_prepare.h \ glamor_program.c \ glamor_program.h \ glamor_rects.c \ diff --git a/glamor/glamor.c b/glamor/glamor.c index 08f6ba174..6aaf1b40f 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -397,6 +397,10 @@ glamor_init(ScreenPtr screen, unsigned int flags) } } + glamor_priv->has_rw_pbo = FALSE; + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + glamor_priv->has_rw_pbo = TRUE; + glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug"); glamor_priv->has_pack_invert = epoxy_has_gl_extension("GL_MESA_pack_invert"); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index b34943761..ffb6eba4b 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -114,27 +114,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) } } -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); - - if (pixmap->devPrivate.ptr) { - /* Already mapped, nothing needs to be done. Note that we - * aren't allowing promotion from RO to RW, because it would - * require re-mapping the PBO. - */ - assert(!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) || - access == GLAMOR_ACCESS_RO || - pixmap_priv->base.map_access == GLAMOR_ACCESS_RW); - return TRUE; - } - pixmap_priv->base.map_access = access; - - return glamor_download_pixmap_to_cpu(pixmap, access); -} - /* * When downloading a unsupported color format to CPU memory, we need to shuffle the color elements and then use a supported @@ -313,91 +292,6 @@ glamor_fini_finish_access_shaders(ScreenPtr screen) glDeleteProgram(glamor_priv->finish_access_prog[1]); } -void -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_DOWNLOADED(pixmap_priv)) - return; - - /* If we are doing a series of unmaps from a nested map, we're - * done. None of the callers do any rendering to maps after - * starting an unmap sequence, so we don't need to delay until the - * last nested unmap. - */ - if (!pixmap->devPrivate.ptr) - return; - - if (pixmap_priv->base.map_access == GLAMOR_ACCESS_RW) { - glamor_restore_pixmap_to_texture(pixmap); - } - - if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) { - assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - - glamor_make_current(glamor_priv); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo); - - pixmap_priv->base.fbo->pbo_valid = FALSE; - pixmap_priv->base.fbo->pbo = 0; - } - else { - free(pixmap->devPrivate.ptr); - } - - if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) - pixmap->devKind = pixmap_priv->base.drm_stride; - - if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED) - pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL; - - 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); -} - Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, int x, int y, int width, int height, diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c index 5fdc5f9b0..cbbc19406 100644 --- a/glamor/glamor_picture.c +++ b/glamor/glamor_picture.c @@ -45,24 +45,6 @@ glamor_upload_picture_to_texture(PicturePtr picture) 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 have drawable attached to it, if it has one. * Then set the attached pixmap to is_picture format, and set diff --git a/glamor/glamor_prepare.c b/glamor/glamor_prepare.c new file mode 100644 index 000000000..561c55d19 --- /dev/null +++ b/glamor/glamor_prepare.c @@ -0,0 +1,274 @@ +/* + * Copyright © 2014 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "glamor_priv.h" +#include "glamor_prepare.h" +#include "glamor_transfer.h" + +/* + * Make a pixmap ready to draw with fb by + * creating a PBO large enough for the whole object + * and downloading all of the FBOs into it. + */ + +static Bool +glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + int gl_access, gl_usage; + RegionRec region; + + if (priv->type == GLAMOR_DRM_ONLY) + return FALSE; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) + return TRUE; + + RegionInit(®ion, box, 1); + + /* See if it's already mapped */ + if (pixmap->devPrivate.ptr) { + /* + * Someone else has mapped this pixmap; + * we'll assume that it's directly mapped + * by a lower level driver + */ + if (!priv->base.prepared) + return TRUE; + + /* In X, multiple Drawables can be stored in the same Pixmap (such as + * each individual window in a non-composited screen pixmap, or the + * reparented window contents inside the window-manager-decorated window + * pixmap on a composited screen). + * + * As a result, when doing a series of mappings for a fallback, we may + * need to add more boxes to the set of data we've downloaded, as we go. + */ + RegionSubtract(®ion, ®ion, &priv->base.prepare_region); + if (!RegionNotEmpty(®ion)) + return TRUE; + + if (access == GLAMOR_ACCESS_RW) + FatalError("attempt to remap buffer as writable"); + + if (priv->base.pbo) { + glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + pixmap->devPrivate.ptr = NULL; + } + } else { + RegionInit(&priv->base.prepare_region, box, 1); + + if (glamor_priv->has_rw_pbo) { + if (priv->base.pbo == 0) + glGenBuffers(1, &priv->base.pbo); + + if (access == GLAMOR_ACCESS_RW) + gl_usage = GL_DYNAMIC_DRAW; + else + gl_usage = GL_STREAM_READ; + + glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo); + glBufferData(GL_PIXEL_PACK_BUFFER, + pixmap->devKind * pixmap->drawable.height, NULL, + gl_usage); + } else { + pixmap->devPrivate.ptr = malloc(pixmap->devKind * + pixmap->drawable.height); + if (!pixmap->devPrivate.ptr) + return FALSE; + } + priv->base.map_access = access; + } + + glamor_download_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion), + 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); + + RegionUninit(®ion); + + if (glamor_priv->has_rw_pbo) { + if (priv->base.map_access == GLAMOR_ACCESS_RW) + gl_access = GL_READ_WRITE; + else + gl_access = GL_READ_ONLY; + + pixmap->devPrivate.ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + } + + priv->base.prepared = TRUE; + return TRUE; +} + +/* + * When we're done with the drawable, unmap the PBO, reupload + * if we were writing to it and then unbind it to release the memory + */ + +static void +glamor_fini_pixmap(PixmapPtr pixmap) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) + return; + + if (!priv->base.prepared) + return; + + if (glamor_priv->has_rw_pbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + pixmap->devPrivate.ptr = NULL; + } + + if (priv->base.map_access == GLAMOR_ACCESS_RW) { + glamor_upload_boxes(pixmap, + RegionRects(&priv->base.prepare_region), + RegionNumRects(&priv->base.prepare_region), + 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind); + } + + RegionUninit(&priv->base.prepare_region); + + if (glamor_priv->has_rw_pbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glDeleteBuffers(1, &priv->base.pbo); + priv->base.pbo = 0; + } else { + free(pixmap->devPrivate.ptr); + pixmap->devPrivate.ptr = NULL; + } + + priv->base.prepared = FALSE; +} + +Bool +glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + BoxRec box; + int off_x, off_y; + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + + box.x1 = drawable->x + off_x; + box.x2 = box.x1 + drawable->width; + box.y1 = drawable->y + off_y; + box.y2 = box.y1 + drawable->height; + return glamor_prep_pixmap_box(pixmap, access, &box); +} + +Bool +glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access, + int x, int y, int w, int h) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + BoxRec box; + int off_x, off_y; + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + box.x1 = drawable->x + x + off_x; + box.x2 = box.x1 + w; + box.y1 = drawable->y + y + off_y; + box.y2 = box.y1 + h; + return glamor_prep_pixmap_box(pixmap, access, &box); +} + +void +glamor_finish_access(DrawablePtr drawable) +{ + glamor_fini_pixmap(glamor_get_drawable_pixmap(drawable)); +} + +/* + * Make a picture ready to use with fb. + */ + +Bool +glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) +{ + if (!picture || !picture->pDrawable) + return TRUE; + + return glamor_prepare_access(picture->pDrawable, access); +} + +Bool +glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access, + int x, int y, int w, int h) +{ + if (!picture || !picture->pDrawable) + return TRUE; + return glamor_prepare_access_box(picture->pDrawable, access, + x, y, w, h); +} + +void +glamor_finish_access_picture(PicturePtr picture) +{ + if (!picture || !picture->pDrawable) + return; + + glamor_finish_access(picture->pDrawable); +} + +/* + * Make a GC ready to use with fb. This just + * means making sure the appropriate fill pixmap is + * in CPU memory again + */ + +Bool +glamor_prepare_access_gc(GCPtr gc) +{ + switch (gc->fillStyle) { + case FillTiled: + return glamor_prepare_access(&gc->tile.pixmap->drawable, + GLAMOR_ACCESS_RO); + case FillStippled: + case FillOpaqueStippled: + return glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO); + } + return TRUE; +} + +/* + * Free any temporary CPU pixmaps for the GC + */ +void +glamor_finish_access_gc(GCPtr gc) +{ + switch (gc->fillStyle) { + case FillTiled: + glamor_finish_access(&gc->tile.pixmap->drawable); + break; + case FillStippled: + case FillOpaqueStippled: + glamor_finish_access(&gc->stipple->drawable); + break; + } +} diff --git a/glamor/glamor_prepare.h b/glamor/glamor_prepare.h new file mode 100644 index 000000000..85fa79574 --- /dev/null +++ b/glamor/glamor_prepare.h @@ -0,0 +1,52 @@ +/* + * Copyright © 2014 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#ifndef _GLAMOR_PREPARE_H_ +#define _GLAMOR_PREPARE_H_ + +Bool +glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); + +Bool +glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access, + int x, int y, int w, int h); + +void +glamor_finish_access(DrawablePtr drawable); + +Bool +glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); + +Bool +glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access, + int x, int y, int w, int h); + +void +glamor_finish_access_picture(PicturePtr picture); + +Bool +glamor_prepare_access_gc(GCPtr gc); + +void +glamor_finish_access_gc(GCPtr gc); + +#endif /* _GLAMOR_PREPARE_H_ */ diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index c56c55973..531d25d17 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -209,6 +209,7 @@ typedef struct glamor_screen_private { int has_buffer_storage; int has_khr_debug; int max_fbo_size; + int has_rw_pbo; struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; @@ -430,6 +431,9 @@ typedef struct glamor_pixmap_private_base { int drm_stride; glamor_screen_private *glamor_priv; PicturePtr picture; + GLuint pbo; + RegionRec prepare_region; + Bool prepared; #if GLAMOR_HAS_GBM EGLImageKHR image; #endif @@ -624,14 +628,9 @@ void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, Bool upsidedown, Pixel bitplane, void *closure); /* 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_prepare_access_gc(GCPtr gc); -void glamor_finish_access_gc(GCPtr gc); void glamor_init_finish_access_shaders(ScreenPtr screen); void glamor_fini_finish_access_shaders(ScreenPtr screen); + const Bool glamor_get_drawable_location(const DrawablePtr drawable); void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y); @@ -919,10 +918,6 @@ int glamor_create_picture(PicturePtr picture); void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap); -Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); - -void glamor_finish_access_picture(PicturePtr picture); - void glamor_destroy_picture(PicturePtr picture); /* fixup a fbo to the exact size as the pixmap. */ diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 5a7a23880..8952023f1 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1586,15 +1586,6 @@ _glamor_composite(CARD8 op, RegionRec region; BoxPtr extent; int nbox, ok = FALSE; - PixmapPtr sub_dest_pixmap = NULL; - PixmapPtr sub_source_pixmap = NULL; - PixmapPtr sub_mask_pixmap = NULL; - int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y; - int source_x_off, source_y_off, saved_source_x, saved_source_y; - int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y; - DrawablePtr saved_dest_drawable; - DrawablePtr saved_source_drawable; - DrawablePtr saved_mask_drawable; int force_clip = 0; dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); @@ -1737,34 +1728,13 @@ _glamor_composite(CARD8 op, dest->pDrawable->width, dest->pDrawable->height, glamor_get_picture_location(dest)); -#define GET_SUB_PICTURE(p, access) do { \ - glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap, \ - & p ##_x_off, & p ##_y_off); \ - sub_ ##p ##_pixmap = glamor_get_sub_pixmap(p ##_pixmap, \ - x_ ##p + p ##_x_off + p->pDrawable->x, \ - y_ ##p + p ##_y_off + p->pDrawable->y, \ - width, height, access); \ - if (sub_ ##p ##_pixmap != NULL) { \ - saved_ ##p ##_drawable = p->pDrawable; \ - saved_ ##p ##_x = x_ ##p; \ - saved_ ##p ##_y = y_ ##p; \ - if (p->pCompositeClip) \ - pixman_region_translate (p->pCompositeClip, \ - -p->pDrawable->x - x_ ##p, \ - -p->pDrawable->y - y_ ##p); \ - p->pDrawable = &sub_ ##p ##_pixmap->drawable; \ - x_ ##p = 0; \ - y_ ##p = 0; \ - } } while(0) - GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); - if (source->pDrawable && !source->transform) - GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO); - if (mask && mask->pDrawable && !mask->transform) - GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); - - if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW) && - glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO) && - glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) { + if (glamor_prepare_access_picture_box(dest, GLAMOR_ACCESS_RW, + x_dest, y_dest, width, height) && + glamor_prepare_access_picture_box(source, GLAMOR_ACCESS_RO, + x_source, y_source, width, height) && + glamor_prepare_access_picture_box(mask, GLAMOR_ACCESS_RO, + x_mask, y_mask, width, height)) + { fbComposite(op, source, mask, dest, x_source, y_source, @@ -1774,25 +1744,6 @@ _glamor_composite(CARD8 op, glamor_finish_access_picture(source); glamor_finish_access_picture(dest); -#define PUT_SUB_PICTURE(p, access) do { \ - if (sub_ ##p ##_pixmap != NULL) { \ - x_ ##p = saved_ ##p ##_x; \ - y_ ##p = saved_ ##p ##_y; \ - p->pDrawable = saved_ ##p ##_drawable; \ - if (p->pCompositeClip) \ - pixman_region_translate (p->pCompositeClip, \ - p->pDrawable->x + x_ ##p, \ - p->pDrawable->y + y_ ##p); \ - glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap, \ - x_ ##p + p ##_x_off + p->pDrawable->x, \ - y_ ##p + p ##_y_off + p->pDrawable->y, \ - width, height, access); \ - }} while(0) - if (mask && mask->pDrawable) - PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); - if (source->pDrawable) - PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO); - PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); done: return ret; } diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index 4c1581ef5..5a568f1c2 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -32,6 +32,8 @@ #ifndef __GLAMOR_UTILS_H__ #define __GLAMOR_UTILS_H__ +#include "glamor_prepare.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) From 0e08a79599c773f77c0667d557376a5ccee3f89c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Apr 2014 14:05:35 -0700 Subject: [PATCH 07/34] glamor: Directly reference the private key records There's no reason to use a pointer here, it just wastes time. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/glamor.c | 16 +++++++--------- glamor/glamor_priv.h | 13 +++++++------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 6aaf1b40f..ac23d5216 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -35,10 +35,8 @@ #include "glamor_priv.h" -static DevPrivateKeyRec glamor_screen_private_key_index; -DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index; -static DevPrivateKeyRec glamor_pixmap_private_key_index; -DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index; +DevPrivateKeyRec glamor_screen_private_key; +DevPrivateKeyRec glamor_pixmap_private_key; /** * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable. @@ -68,7 +66,7 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type) glamor_get_screen_private(pixmap->drawable.pScreen); pixmap_priv = dixLookupPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key); + &glamor_pixmap_private_key); if (pixmap_priv == NULL) { pixmap_priv = calloc(sizeof(*pixmap_priv), 1); glamor_set_pixmap_private(pixmap, pixmap_priv); @@ -335,7 +333,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) else glamor_priv->yInverted = FALSE; - if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) { + if (!dixRegisterPrivateKey(&glamor_screen_private_key, PRIVATE_SCREEN, 0)) { LogMessage(X_WARNING, "glamor%d: Failed to allocate screen private\n", screen->myNum); @@ -344,7 +342,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_set_screen_private(screen, glamor_priv); - if (!dixRegisterPrivateKey(glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) { + if (!dixRegisterPrivateKey(&glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) { LogMessage(X_WARNING, "glamor%d: Failed to allocate pixmap private\n", screen->myNum); @@ -559,7 +557,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv) glamor_pixmap_private *old_priv; glamor_pixmap_fbo *fbo; - old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); + old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key); if (priv) { assert(old_priv == NULL); @@ -572,7 +570,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv) free(old_priv); } - dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv); + dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key, priv); } Bool diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 531d25d17..0af6092b5 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -548,19 +548,20 @@ typedef enum glamor_pixmap_status { GLAMOR_UPLOAD_FAILED } glamor_pixmap_status_t; -extern DevPrivateKey glamor_screen_private_key; -extern DevPrivateKey glamor_pixmap_private_key; +extern DevPrivateKeyRec glamor_screen_private_key; +extern DevPrivateKeyRec 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); + dixLookupPrivate(&screen->devPrivates, &glamor_screen_private_key); } static inline void glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv) { - dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, priv); + dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv); } static inline glamor_pixmap_private * @@ -568,11 +569,11 @@ glamor_get_pixmap_private(PixmapPtr pixmap) { glamor_pixmap_private *priv; - priv = dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); + priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key); if (!priv) { glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY); priv = dixLookupPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key); + &glamor_pixmap_private_key); } return priv; } From 45ebc4e3fac7f1a85167d05e2833949b89f02d64 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 15 Mar 2014 13:31:18 -0700 Subject: [PATCH 08/34] glamor: Add glamor_program based copy acceleration Paints with textures, using a temporary buffer for overlapping copies Performs CPU to GPU transfers for pixmaps in memory. Accelerates copy plane when both objects are in the GPU. Includes copy_window acceleration too. v2: Use NV_texture_barrier for non-overlapping copies within the same drawable v3: Switch to glamor_make_current v4: Do overlap check on the bounding box of the region rather than on individual boxes v5: Use Eric Anholt's re-written comments which provide a more accurate description of the code v6: Use floating point uniform for copy plane bit multiplier. This avoids an int to float conversion in the copy plane fragment shader. Use round() instead of adding 0.5 in copy plane. round() and +0.5 end up generating equivalent code, and performance measurements confirm that they are the same speed. Round() is a bit clearer though, so we'll use it. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/Makefile.am | 4 +- glamor/glamor.c | 2 + glamor/glamor.h | 11 + glamor/glamor_copy.c | 693 ++++++++++++++++++++++++++++++++++++ glamor/glamor_copyarea.c | 626 -------------------------------- glamor/glamor_copyplane.c | 75 ---- glamor/glamor_copywindow.c | 56 --- glamor/glamor_glyphs.c | 6 +- glamor/glamor_largepixmap.c | 13 +- glamor/glamor_priv.h | 42 ++- glamor/glamor_program.c | 10 +- glamor/glamor_program.h | 3 + glamor/glamor_render.c | 11 +- 13 files changed, 763 insertions(+), 789 deletions(-) create mode 100644 glamor/glamor_copy.c delete mode 100644 glamor/glamor_copyarea.c delete mode 100644 glamor/glamor_copyplane.c delete mode 100644 glamor/glamor_copywindow.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index cb81872b4..c0d82d67d 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -7,8 +7,7 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS) libglamor_la_SOURCES = \ glamor.c \ glamor_context.h \ - glamor_copyarea.c \ - glamor_copywindow.c \ + glamor_copy.c \ glamor_core.c \ glamor_debug.h \ glamor_fill.c \ @@ -36,7 +35,6 @@ libglamor_la_SOURCES = \ glamor_tile.c \ glamor_triangles.c\ glamor_addtraps.c\ - glamor_copyplane.c\ glamor_glyphblt.c\ glamor_points.c\ glamor_priv.h\ diff --git a/glamor/glamor.c b/glamor/glamor.c index ac23d5216..3468b51c3 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -408,6 +408,8 @@ glamor_init(ScreenPtr screen, unsigned int flags) epoxy_has_gl_extension("GL_ARB_map_buffer_range"); glamor_priv->has_buffer_storage = epoxy_has_gl_extension("GL_ARB_buffer_storage"); + glamor_priv->has_nv_texture_barrier = + epoxy_has_gl_extension("GL_NV_texture_barrier"); glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); #ifdef MAX_FBO_SIZE glamor_priv->max_fbo_size = MAX_FBO_SIZE; diff --git a/glamor/glamor.h b/glamor/glamor.h index b0f2212d9..77fa01e8d 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -354,6 +354,17 @@ extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src, Bool upsidedown, Pixel bitplane, void *closure); +extern _X_EXPORT Bool glamor_copy_nf(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, Pixel bitplane, + void *closure); + extern _X_EXPORT Bool glamor_composite_nf(CARD8 op, PicturePtr source, PicturePtr mask, diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c new file mode 100644 index 000000000..bfcde43db --- /dev/null +++ b/glamor/glamor_copy.c @@ -0,0 +1,693 @@ +/* + * Copyright © 2014 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "glamor_priv.h" +#include "glamor_transfer.h" +#include "glamor_prepare.h" +#include "glamor_transform.h" + +struct copy_args { + PixmapPtr src_pixmap; + glamor_pixmap_fbo *src; + uint32_t bitplane; + int dx, dy; +}; + +static Bool +use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) +{ + struct copy_args *args = arg; + glamor_pixmap_fbo *src = args->src; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, src->tex); + + glUniform2f(prog->fill_offset_uniform, args->dx, args->dy); + glUniform2f(prog->fill_size_uniform, src->width, src->height); + + return TRUE; +} + +static const glamor_facet glamor_facet_copyarea = { + "copy_area", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (GLAMOR_POS(gl_Position, primitive.xy) + " fill_pos = (fill_offset + primitive.xy) / fill_size;\n"), + .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n", + .locations = glamor_program_location_fill, + .use = use_copyarea, +}; + +/* + * Configure the copy plane program for the current operation + */ + +static Bool +use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg) +{ + struct copy_args *args = arg; + glamor_pixmap_fbo *src = args->src; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, src->tex); + + glUniform2f(prog->fill_offset_uniform, args->dx, args->dy); + glUniform2f(prog->fill_size_uniform, src->width, src->height); + + glamor_set_color(dst, gc->fgPixel, prog->fg_uniform); + glamor_set_color(dst, gc->bgPixel, prog->bg_uniform); + + /* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */ + switch (args->src_pixmap->drawable.depth) { + case 24: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 16) & 0xff, + (args->bitplane >> 8) & 0xff, + (args->bitplane ) & 0xff, + 0); + + glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0); + break; + case 32: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 16) & 0xff, + (args->bitplane >> 8) & 0xff, + (args->bitplane ) & 0xff, + (args->bitplane >> 24) & 0xff); + + glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0xff); + break; + case 16: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 11) & 0x1f, + (args->bitplane >> 5) & 0x3f, + (args->bitplane ) & 0x1f, + 0); + + glUniform4f(prog->bitmul_uniform, 0x1f, 0x3f, 0x1f, 0); + break; + case 15: + glUniform4ui(prog->bitplane_uniform, + (args->bitplane >> 10) & 0x1f, + (args->bitplane >> 5) & 0x1f, + (args->bitplane ) & 0x1f, + 0); + + glUniform4f(prog->bitmul_uniform, 0x1f, 0x1f, 0x1f, 0); + break; + case 8: + glUniform4ui(prog->bitplane_uniform, + 0, 0, 0, args->bitplane); + glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff); + break; + case 1: + glUniform4ui(prog->bitplane_uniform, + 0, 0, 0, args->bitplane); + glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff); + break; + } + + return TRUE; +} + +static const glamor_facet glamor_facet_copyplane = { + "copy_plane", + .version = 130, + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy)) + " fill_pos = (fill_offset + primitive.xy) / fill_size;\n"), + .fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n" + " if ((bits & bitplane) != uvec4(0,0,0,0))\n" + " gl_FragColor = fg;\n" + " else\n" + " gl_FragColor = bg;\n"), + .locations = glamor_program_location_fill|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane, + .use = use_copyplane, +}; + +/* + * When all else fails, pull the bits out of the GPU and do the + * operation with fb + */ + +static void +glamor_copy_bail(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + if (bitplane) { + if (src->bitsPerPixel > 1) + fbCopyNto1(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + else + fbCopy1toN(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } else { + fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } + } + glamor_finish_access(dst); + glamor_finish_access(src); +} + +/** + * Implements CopyPlane and CopyArea from the GPU to the GPU by using + * the source as a texture and painting that into the destination. + * + * This requires that source and dest are different textures, or that + * (if the copy area doesn't overlap), GL_NV_texture_barrier is used + * to ensure that the caches are flushed at the right times. + */ +static Bool +glamor_copy_cpu_fbo(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + FbBits *src_bits; + FbStride src_stride; + int src_bpp; + int src_xoff, src_yoff; + int dst_xoff, dst_yoff; + + if (gc && gc->alu != GXcopy) + goto bail; + + if (gc && !glamor_pm_is_solid(dst, gc->planemask)) + goto bail; + + glamor_make_current(glamor_priv); + glamor_prepare_access(src, GLAMOR_ACCESS_RO); + + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff); + + fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff); + + glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy, + dst_xoff, dst_yoff, + (uint8_t *) src_bits, src_stride * sizeof (FbBits)); + glamor_finish_access(src); + + return TRUE; + +bail: + return FALSE; +} + +/* + * Copy from GPU to GPU by using the source + * as a texture and painting that into the destination + */ + +static Bool +glamor_copy_fbo_fbo_draw(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); + glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap); + int src_box_x, src_box_y, dst_box_x, dst_box_y; + int dst_off_x, dst_off_y; + int src_off_x, src_off_y; + GLshort *v; + char *vbo_offset; + struct copy_args args; + glamor_program *prog; + const glamor_facet *copy_facet; + Bool set_scissor; + int n; + + glamor_make_current(glamor_priv); + + if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask)) + goto bail_ctx; + + if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) + goto bail_ctx; + + if (bitplane) { + prog = &glamor_priv->copy_plane_prog; + copy_facet = &glamor_facet_copyplane; + } else { + prog = &glamor_priv->copy_area_prog; + copy_facet = &glamor_facet_copyarea; + } + + if (prog->failed) + goto bail_ctx; + + if (!prog->prog) { + if (!glamor_build_program(screen, prog, + copy_facet, NULL)) + goto bail_ctx; + } + + args.src_pixmap = src_pixmap; + args.bitplane = bitplane; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(dst->pScreen, nbox * 8 * sizeof (int16_t), &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, + 2 * sizeof (GLshort), vbo_offset); + + for (n = 0; n < nbox; n++) { + v[0] = box->x1; v[1] = box->y1; + v[2] = box->x1; v[3] = box->y2; + v[4] = box->x2; v[5] = box->y2; + v[6] = box->x2; v[7] = box->y1; + v += 8; + box++; + } + + glamor_put_vbo_space(screen); + + glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y); + + set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE; + if (set_scissor) + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(src_priv, src_box_x, src_box_y) { + BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y); + + args.dx = dx + src_off_x - src_box->x1; + args.dy = dy + src_off_y - src_box->y1; + args.src = glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y); + + if (!glamor_use_program(dst_pixmap, gc, prog, &args)) + goto bail_ctx; + + glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) { + glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE, + prog->matrix_uniform, &dst_off_x, &dst_off_y); + + if (set_scissor) + glScissor(dst_off_x - args.dx, + dst_off_y - args.dy, + src_box->x2 - src_box->x1, + src_box->y2 - src_box->y1); + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + glDrawArrays(GL_QUADS, 0, nbox * 4); + else { + int i; + for (i = 0; i < nbox; i++) + glDrawArrays(GL_TRIANGLE_FAN, i*4, 4); + } + } + } + if (set_scissor) + glDisable(GL_SCISSOR_TEST); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + glDisable(GL_COLOR_LOGIC_OP); + return TRUE; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); + return FALSE; +} + +/** + * Copies from the GPU to the GPU using a temporary pixmap in between, + * to correctly handle overlapping copies. + */ + +static Bool +glamor_copy_fbo_fbo_temp(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + PixmapPtr tmp_pixmap; + BoxRec bounds; + int n; + BoxPtr tmp_box; + + if (nbox == 0) + return TRUE; + + /* Sanity check state to avoid getting halfway through and bailing + * at the last second. Might be nice to have checks that didn't + * involve setting state. + */ + glamor_make_current(glamor_priv); + + if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask)) + goto bail_ctx; + + if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) + goto bail_ctx; + glDisable(GL_COLOR_LOGIC_OP); + + /* Find the size of the area to copy + */ + bounds = box[0]; + for (n = 1; n < nbox; n++) { + bounds.x1 = min(bounds.x1, box[n].x1); + bounds.x2 = max(bounds.x2, box[n].x2); + bounds.y1 = min(bounds.y1, box[n].y1); + bounds.y2 = max(bounds.y2, box[n].y2); + } + + /* Allocate a suitable temporary pixmap + */ + tmp_pixmap = glamor_create_pixmap(screen, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1, + src->depth, 0); + if (!tmp_pixmap) + goto bail; + + tmp_box = calloc(nbox, sizeof (BoxRec)); + if (!tmp_box) + goto bail_pixmap; + + /* Convert destination boxes into tmp pixmap boxes + */ + for (n = 0; n < nbox; n++) { + tmp_box[n].x1 = box[n].x1 - bounds.x1; + tmp_box[n].x2 = box[n].x2 - bounds.x1; + tmp_box[n].y1 = box[n].y1 - bounds.y1; + tmp_box[n].y2 = box[n].y2 - bounds.y1; + } + + if (!glamor_copy_fbo_fbo_draw(src, + &tmp_pixmap->drawable, + NULL, + tmp_box, + nbox, + dx + bounds.x1, + dy + bounds.y1, + FALSE, FALSE, + 0, NULL)) + goto bail_box; + + if (!glamor_copy_fbo_fbo_draw(&tmp_pixmap->drawable, + dst, + gc, + box, + nbox, + -bounds.x1, + -bounds.y1, + FALSE, FALSE, + bitplane, closure)) + goto bail_box; + + free(tmp_box); + + glamor_destroy_pixmap(tmp_pixmap); + + return TRUE; +bail_box: + free(tmp_box); +bail_pixmap: + glamor_destroy_pixmap(tmp_pixmap); +bail: + return FALSE; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); + return FALSE; +} + +/** + * Returns TRUE if the copy has to be implemented with + * glamor_copy_fbo_fbo_temp() instead of glamor_copy_fbo_fbo(). + * + * If the src and dst are in the same pixmap, then glamor_copy_fbo_fbo()'s + * sampling would give undefined results (since the same texture would be + * bound as an FBO destination and as a texture source). However, if we + * have GL_NV_texture_barrier, we can take advantage of the exception it + * added: + * + * "- If a texel has been written, then in order to safely read the result + * a texel fetch must be in a subsequent Draw separated by the command + * + * void TextureBarrierNV(void); + * + * TextureBarrierNV() will guarantee that writes have completed and caches + * have been invalidated before subsequent Draws are executed." + */ +static Bool +glamor_copy_needs_temp(DrawablePtr src, + DrawablePtr dst, + BoxPtr box, + int nbox, + int dx, + int dy) +{ + PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); + PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); + ScreenPtr screen = dst->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + int n; + int dst_off_x, dst_off_y; + int src_off_x, src_off_y; + BoxRec bounds; + + if (src_pixmap != dst_pixmap) + return FALSE; + + if (nbox == 0) + return FALSE; + + if (!glamor_priv->has_nv_texture_barrier) + return TRUE; + + glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y); + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y); + + bounds = box[0]; + for (n = 1; n < nbox; n++) { + bounds.x1 = min(bounds.x1, box[n].x1); + bounds.y1 = min(bounds.y1, box[n].y1); + + bounds.x2 = max(bounds.x2, box[n].x2); + bounds.y2 = max(bounds.y2, box[n].y2); + } + + /* Check to see if the pixmap-relative boxes overlap in both X and Y, + * in which case we can't rely on NV_texture_barrier and must + * make a temporary copy + * + * dst.x1 < src.x2 && + * src.x1 < dst.x2 && + * + * dst.y1 < src.y2 && + * src.y1 < dst.y2 + */ + if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x && + bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x && + + bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y && + bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) { + return TRUE; + } + + glTextureBarrierNV(); + + return FALSE; +} + +static Bool +glamor_copy_gl(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); + glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); + glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap); + + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv)) { + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv)) { + if (glamor_copy_needs_temp(src, dst, box, nbox, dx, dy)) + return glamor_copy_fbo_fbo_temp(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + else + return glamor_copy_fbo_fbo_draw(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } + if (bitplane == 0) + return glamor_copy_cpu_fbo(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } + return FALSE; +} + +void +glamor_copy(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_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure)) + return; + glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); +} + +RegionPtr +glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty) +{ + return miDoCopy(src, dst, gc, + srcx, srcy, width, height, + dstx, dsty, glamor_copy, 0, NULL); +} + +RegionPtr +glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty, + unsigned long bitplane) +{ + if ((bitplane & FbFullMask(src->depth)) == 0) + return miHandleExposures(src, dst, gc, + srcx, srcy, width, height, dstx, dsty, + bitplane); + return miDoCopy(src, dst, gc, + srcx, srcy, width, height, + dstx, dsty, glamor_copy, bitplane, NULL); +} + +void +glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(&window->drawable); + DrawablePtr drawable = &pixmap->drawable; + RegionRec dst_region; + int dx, dy; + + dx = old_origin.x - window->drawable.x; + dy = old_origin.y - window->drawable.y; + RegionTranslate(src_region, -dx, -dy); + + RegionNull(&dst_region); + + RegionIntersect(&dst_region, &window->borderClip, src_region); + +#ifdef COMPOSITE + if (pixmap->screen_x || pixmap->screen_y) + RegionTranslate(&dst_region, -pixmap->screen_x, -pixmap->screen_y); +#endif + + miCopyRegion(drawable, drawable, + 0, &dst_region, dx, dy, glamor_copy, 0, 0); + + RegionUninit(&dst_region); +} + +Bool +glamor_copy_n_to_n_nf(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_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure)) + return TRUE; + if (glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst)) + return FALSE; + glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); + return TRUE; +} + +Bool +glamor_copy_plane_nf(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int w, int h, int dstx, int dsty, + unsigned long bitplane, RegionPtr *region) +{ + if (glamor_ddx_fallback_check_pixmap(src) && + glamor_ddx_fallback_check_pixmap(dst) && + glamor_ddx_fallback_check_gc(gc)) + return FALSE; + + *region = glamor_copy_plane(src, dst, gc, + srcx, srcy, w, h, dstx, dsty, + bitplane); + return TRUE; +} diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c deleted file mode 100644 index e1988225f..000000000 --- a/glamor/glamor_copyarea.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * 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. - * - * Authors: - * Eric Anholt - * Zhigang Gong - */ - -#include "glamor_priv.h" - -/** @file glamor_copyarea.c - * - * 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, *dst_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; - int fbo_x_off, fbo_y_off; - int src_fbo_x_off, src_fbo_y_off; - - if (!glamor_priv->has_fbo_blit) { - glamor_delayed_fallback(screen, "no EXT_framebuffer_blit\n"); - return FALSE; - } - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - - if (gc) { - if (gc->alu != GXcopy) { - glamor_delayed_fallback(screen, "non-copy ALU\n"); - 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; - - pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off); - pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off); - - glamor_make_current(glamor_priv); - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->base.fbo->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); - dst_x_off += fbo_x_off; - dst_y_off += fbo_y_off; - src_y_off += dy + src_fbo_y_off; - src_x_off += src_fbo_x_off; - - for (i = 0; i < nbox; i++) { - if (glamor_priv->yInverted) { - 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, - 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); - int flip_src_y2 = - src_pixmap->drawable.height - (box[i].y1 + src_y_off); - - glBlitFramebuffer(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); - } - } - glamor_priv->state = BLIT_STATE; - 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); - PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); - int i; - 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); - - if (src_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) { -#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD - glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); - return FALSE; -#else - src_status = glamor_upload_pixmap_to_texture(src_pixmap); - if (src_status != GLAMOR_UPLOAD_DONE) - return FALSE; - - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); -#endif - } - - pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); - pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - - glamor_make_current(glamor_priv); - - glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - dx += src_x_off; - dy += src_y_off; - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - 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_revert[0], REVERT_NONE); - glUniform1i(glamor_priv->finish_access_swap_rb[0], SWAP_NONE_UPLOADING); - - for (i = 0; i < nbox; i++) { - - glamor_set_normalize_vcoords(dst_pixmap_priv, - 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); - - glamor_set_normalize_tcoords(src_pixmap_priv, - 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); - } - - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - /* The source texture is bound to a fbo, we have to flush it here. */ - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - return TRUE; -} - -static Bool -__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 dst_pixmap, src_pixmap, temp_pixmap = NULL; - DrawablePtr temp_src = src; - glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; - glamor_screen_private *glamor_priv; - BoxRec bound; - 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; - Bool ret = FALSE; - - 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; - glamor_priv = glamor_get_screen_private(dst->pScreen); - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - - if (src_pixmap_priv->base.fbo - && src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->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; - } - } - } - DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n", - box[0].x1, box[0].y1, - box[0].x2 - box[0].x1, box[0].y2 - box[0].y1, - dx, dy, src_pixmap, dst_pixmap); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && - !overlaped && - (glamor_priv->state != RENDER_STATE - || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex) - && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { - ret = TRUE; - goto done; - } - glamor_calculate_boxes_bound(&bound, box, nbox); - - /* 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) - || !(glamor_check_fbo_size(glamor_priv, - src_pixmap->drawable.width, - src_pixmap->drawable. - height))))) { - - temp_pixmap = glamor_create_pixmap(screen, - bound.x2 - bound.x1, - bound.y2 - bound.y1, - src_pixmap->drawable.depth, - overlaped ? 0 : - GLAMOR_CREATE_PIXMAP_CPU); - assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size); - assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size); - if (!temp_pixmap) - goto done; - glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1); - temp_src = &temp_pixmap->drawable; - - 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_translate_boxes(box, nbox, bound.x1, bound.y1); - temp_dx = -bound.x1; - temp_dy = -bound.y1; - } - 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)) { - ret = TRUE; - } - done: - if (temp_src != src) - glamor_destroy_pixmap(temp_pixmap); - return ret; -} - -static Bool -_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, Bool fallback) -{ - ScreenPtr screen = dst->pScreen; - PixmapPtr dst_pixmap, src_pixmap; - glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; - glamor_screen_private *glamor_priv; - BoxPtr extent; - RegionRec region; - int src_x_off, src_y_off, dst_x_off, dst_y_off; - Bool ok = FALSE; - int force_clip = 0; - - if (nbox == 0) - return TRUE; - 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); - - glamor_priv = glamor_get_screen_private(screen); - - DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n", - box[0].x1, box[0].y1, - box[0].x2 - box[0].x1, box[0].y2 - box[0].y1, - dx, dy, src_pixmap, dst_pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) - goto fall_back; - - if (gc) { - if (!glamor_set_planemask(dst_pixmap, gc->planemask)) - goto fall_back; - glamor_make_current(glamor_priv); - if (!glamor_set_alu(screen, gc->alu)) { - goto fail_noregion; - } - } - - if (!src_pixmap_priv) { - glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY); - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - } - - glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); - glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); - - RegionInitBoxes(®ion, box, nbox); - extent = RegionExtents(®ion); - - if (!glamor_check_fbo_size(glamor_priv, - extent->x2 - extent->x1, extent->y2 - extent->y1) - && (src_pixmap_priv->type == GLAMOR_MEMORY - || (src_pixmap_priv == dst_pixmap_priv))) { - force_clip = 1; - } - - if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE - || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - glamor_pixmap_clipped_regions *clipped_dst_regions; - int n_dst_region, i, j; - PixmapPtr temp_source_pixmap; - glamor_pixmap_private *temp_source_priv = NULL; - - RegionTranslate(®ion, dst_x_off, dst_y_off); - if (!force_clip) - clipped_dst_regions = - glamor_compute_clipped_regions(dst_pixmap_priv, ®ion, - &n_dst_region, 0, reverse, - upsidedown); - else - clipped_dst_regions = - glamor_compute_clipped_regions_ext(dst_pixmap_priv, ®ion, - &n_dst_region, - glamor_priv->max_fbo_size, - glamor_priv->max_fbo_size, - reverse, upsidedown); - for (i = 0; i < n_dst_region; i++) { - int n_src_region; - glamor_pixmap_clipped_regions *clipped_src_regions; - BoxPtr current_boxes; - int n_current_boxes; - - SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, - clipped_dst_regions[i].block_idx); - - temp_source_pixmap = NULL; - if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - RegionTranslate(clipped_dst_regions[i].region, - -dst_x_off + src_x_off + dx, - -dst_y_off + src_y_off + dy); - clipped_src_regions = - glamor_compute_clipped_regions(src_pixmap_priv, - clipped_dst_regions[i]. - region, &n_src_region, 0, - reverse, upsidedown); - DEBUGF("Source is large pixmap.\n"); - for (j = 0; j < n_src_region; j++) { - if (src_pixmap_priv != dst_pixmap_priv) - SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, - clipped_src_regions[j]. - block_idx); - else if (src_pixmap_priv == dst_pixmap_priv && - clipped_src_regions[j].block_idx != - clipped_dst_regions[i].block_idx) { - /* source and the dest are the same, but need different block_idx. - * we create a empty pixmap and fill the required source fbo and box to - * it. It's a little hacky, but avoid extra copy. */ - temp_source_pixmap = - glamor_create_pixmap(src->pScreen, 0, 0, src->depth, - 0); - if (!temp_source_pixmap) { - ok = FALSE; - goto fail; - } - src->pScreen->ModifyPixmapHeader(temp_source_pixmap, - src_pixmap->drawable. - width, - src_pixmap->drawable. - height, 0, 0, - src_pixmap->devKind, - NULL); - temp_source_priv = - glamor_get_pixmap_private(temp_source_pixmap); - *temp_source_priv = *src_pixmap_priv; - temp_source_priv->large.box = - src_pixmap_priv->large. - box_array[clipped_src_regions[j].block_idx]; - temp_source_priv->base.fbo = - src_pixmap_priv->large. - fbo_array[clipped_src_regions[j].block_idx]; - temp_source_priv->base.pixmap = temp_source_pixmap; - } - assert(temp_source_pixmap || - !(src_pixmap_priv == dst_pixmap_priv && - (clipped_src_regions[j].block_idx != - clipped_dst_regions[i].block_idx))); - - RegionTranslate(clipped_src_regions[j].region, - -src_x_off - dx, -src_y_off - dy); - current_boxes = RegionRects(clipped_src_regions[j].region); - n_current_boxes = - RegionNumRects(clipped_src_regions[j].region); - DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n", - clipped_dst_regions[i].block_idx, - clipped_src_regions[j].block_idx); - DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", - current_boxes[0].x1, current_boxes[0].y1, - current_boxes[0].x2, current_boxes[0].y2, dx, dy, - src_pixmap, dst_pixmap); - if (!temp_source_pixmap) - ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, - n_current_boxes, dx, dy, - reverse, upsidedown, bitplane, - closure); - else { - ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable, - dst, gc, current_boxes, - n_current_boxes, dx, dy, - reverse, upsidedown, bitplane, - closure); - temp_source_priv->type = GLAMOR_MEMORY; - temp_source_priv->base.fbo = NULL; - glamor_destroy_pixmap(temp_source_pixmap); - temp_source_pixmap = NULL; - } - - RegionDestroy(clipped_src_regions[j].region); - if (!ok) { - assert(0); - goto fail; - } - } - - if (n_src_region == 0) - ok = TRUE; - free(clipped_src_regions); - } - else { - RegionTranslate(clipped_dst_regions[i].region, - -dst_x_off, -dst_y_off); - current_boxes = RegionRects(clipped_dst_regions[i].region); - n_current_boxes = RegionNumRects(clipped_dst_regions[i].region); - - DEBUGF("dest pixmap fbo idx %d \n", - clipped_dst_regions[i].block_idx); - DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", - current_boxes[0].x1, current_boxes[0].y1, - current_boxes[0].x2, current_boxes[0].y2, - dx, dy, src_pixmap, dst_pixmap); - - ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, - n_current_boxes, dx, dy, reverse, - upsidedown, bitplane, closure); - - } - RegionDestroy(clipped_dst_regions[i].region); - } - if (n_dst_region == 0) - ok = TRUE; - free(clipped_dst_regions); - } - else { - ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy, - reverse, upsidedown, bitplane, closure); - } - - fail: - RegionUninit(®ion); - fail_noregion: - glamor_make_current(glamor_priv); - glamor_set_alu(screen, GXcopy); - - if (ok) - return TRUE; - fall_back: - if (!fallback && glamor_ddx_fallback_check_pixmap(src) - && glamor_ddx_fallback_check_pixmap(dst)) - goto done; - - if (src_pixmap_priv->type == GLAMOR_DRM_ONLY - || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) { - LogMessage(X_WARNING, - "Access a DRM only pixmap is not allowed within glamor.\n"); - return TRUE; - } - 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 (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && - glamor_prepare_access(src, GLAMOR_ACCESS_RO) && - glamor_prepare_access_gc(gc)) { - fbCopyNtoN(src, dst, gc, box, nbox, - dx, dy, reverse, upsidedown, bitplane, closure); - } - glamor_finish_access_gc(gc); - glamor_finish_access(src); - glamor_finish_access(dst); - ok = TRUE; - - done: - glamor_clear_delayed_fallbacks(src->pScreen); - glamor_clear_delayed_fallbacks(dst->pScreen); - return ok; -} - -RegionPtr -glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, - int srcx, int srcy, int width, int height, int dstx, int dsty) -{ - RegionPtr region; - - region = miDoCopy(src, dst, gc, - srcx, srcy, width, height, - dstx, dsty, glamor_copy_n_to_n, 0, NULL); - - return region; -} - -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_copy_n_to_n(src, dst, gc, box, nbox, dx, - dy, reverse, upsidedown, bitplane, closure, TRUE); -} - -Bool -glamor_copy_n_to_n_nf(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, - BoxPtr box, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure) -{ - return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, - dy, reverse, upsidedown, bitplane, closure, - FALSE); -} diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c deleted file mode 100644 index 2bd2de30d..000000000 --- a/glamor/glamor_copyplane.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 - * - */ - -#include "glamor_priv.h" - -static Bool -_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane, RegionPtr *pRegion, Bool fallback) -{ - if (!fallback && glamor_ddx_fallback_check_gc(pGC) - && glamor_ddx_fallback_check_pixmap(pSrc) - && glamor_ddx_fallback_check_pixmap(pDst)) - goto fail; - - if (glamor_prepare_access(pDst, GLAMOR_ACCESS_RW) && - glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO) && - glamor_prepare_access_gc(pGC)) { - *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane); - } - glamor_finish_access_gc(pGC); - glamor_finish_access(pSrc); - glamor_finish_access(pDst); - return TRUE; - - fail: - return FALSE; -} - -RegionPtr -glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane) -{ - RegionPtr ret; - - _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane, &ret, TRUE); - return ret; -} - -Bool -glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane, RegionPtr *pRegion) -{ - return _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane, pRegion, FALSE); -} diff --git a/glamor/glamor_copywindow.c b/glamor/glamor_copywindow.c deleted file mode 100644 index 1ced4b336..000000000 --- a/glamor/glamor_copywindow.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -#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_glyphs.c b/glamor/glamor_glyphs.c index 42f5f65f6..ba7d342b9 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -448,9 +448,9 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen, box.y1 = y; box.x2 = x + glyph->info.width; box.y2 = y + glyph->info.height; - glamor_copy_n_to_n_nf(&scratch->drawable, - &pCachePixmap->drawable, NULL, - &box, 1, -x, -y, FALSE, FALSE, 0, NULL); + glamor_copy(&scratch->drawable, + &pCachePixmap->drawable, NULL, + &box, 1, -x, -y, FALSE, FALSE, 0, NULL); if (scratch != pGlyphPixmap) screen->DestroyPixmap(scratch); diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c index b3a8d5d20..5a4bec571 100644 --- a/glamor/glamor_largepixmap.c +++ b/glamor/glamor_largepixmap.c @@ -797,9 +797,9 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, copy_box.y2 = temp_extent->y2 - temp_extent->y1; dx = temp_extent->x1; dy = temp_extent->y1; - glamor_copy_n_to_n(&priv->base.pixmap->drawable, - &temp_pixmap->drawable, - NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); + glamor_copy(&priv->base.pixmap->drawable, + &temp_pixmap->drawable, + NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); // glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, // temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00); } @@ -829,9 +829,10 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, copy_box.x1, copy_box.y1, copy_box.x2, copy_box.y2, dx, dy); - glamor_copy_n_to_n(&priv->base.pixmap->drawable, - &temp_pixmap->drawable, - NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); + glamor_copy(&priv->base.pixmap->drawable, + &temp_pixmap->drawable, + NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL); + box++; } } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 0af6092b5..1ae4e94f4 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -208,6 +208,7 @@ typedef struct glamor_screen_private { int has_map_buffer_range; int has_buffer_storage; int has_khr_debug; + int has_nv_texture_barrier; int max_fbo_size; int has_rw_pbo; @@ -236,6 +237,10 @@ typedef struct glamor_screen_private { glamor_program te_text_prog; glamor_program image_text_prog; + /* glamor copy shaders */ + glamor_program copy_area_prog; + glamor_program copy_plane_prog; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -619,15 +624,6 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv, int flag, int block_w, int block_h, glamor_pixmap_private *); -/* glamor_copyarea.c */ -RegionPtr - -glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, - int srcx, int srcy, int width, int height, int dstx, int dsty); -void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, - BoxPtr box, int nbox, int dx, int dy, Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure); - /* glamor_core.c */ void glamor_init_finish_access_shaders(ScreenPtr screen); void glamor_fini_finish_access_shaders(ScreenPtr screen); @@ -931,11 +927,6 @@ void glamor_picture_format_fixup(PicturePtr picture, void glamor_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap *traps); -RegionPtr glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, - int dstx, int dsty, - unsigned long bitPlane); - /* glamor_text.c */ int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars); @@ -977,6 +968,29 @@ void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); +/* glamor_copy.c */ +void +glamor_copy(DrawablePtr src, + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +RegionPtr +glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty); + +RegionPtr +glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, + int srcx, int srcy, int width, int height, int dstx, int dsty, + unsigned long bitplane); + /* glamor_glyphblt.c */ void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c index 0f4d0f06a..6ee6580ff 100644 --- a/glamor/glamor_program.c +++ b/glamor/glamor_program.c @@ -117,6 +117,11 @@ static glamor_location_var location_vars[] = { .location = glamor_program_location_font, .fs_vars = "uniform usampler2D font;\n", }, + { + .location = glamor_program_location_bitplane, + .fs_vars = ("uniform uvec4 bitplane;\n" + "uniform vec4 bitmul;\n"), + }, }; #define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0]) @@ -196,6 +201,8 @@ static const glamor_facet facet_null_fill = { .name = "" }; +#define DBG 0 + static GLint glamor_get_uniform(glamor_program *prog, glamor_program_location location, @@ -281,7 +288,6 @@ glamor_build_program(ScreenPtr screen, if (!vs_prog_string || !fs_prog_string) goto fail; -#define DBG 0 #if DBG ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s", prim->name, fill->name, vs_prog_string, fs_prog_string); @@ -318,6 +324,8 @@ glamor_build_program(ScreenPtr screen, prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset"); prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size"); prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font"); + prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane"); + prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul"); if (glGetError() != GL_NO_ERROR) goto fail; diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h index 88efc3593..118f97838 100644 --- a/glamor/glamor_program.h +++ b/glamor/glamor_program.h @@ -29,6 +29,7 @@ typedef enum { glamor_program_location_bg = 2, glamor_program_location_fill = 4, glamor_program_location_font = 8, + glamor_program_location_bitplane = 16, } glamor_program_location; typedef enum { @@ -61,6 +62,8 @@ struct _glamor_program { GLint fill_size_uniform; GLint fill_offset_uniform; GLint font_uniform; + GLint bitplane_uniform; + GLint bitmul_uniform; glamor_program_location locations; glamor_program_flag flags; glamor_use prim_use; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 8952023f1..6da38da32 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -651,11 +651,12 @@ glamor_composite_with_copy(CARD8 op, if (region->extents.y2 + y_source - y_dest > source->pDrawable->height) goto cleanup_region; } - ret = glamor_copy_n_to_n_nf(source->pDrawable, - dest->pDrawable, NULL, - RegionRects(region), RegionNumRects(region), - x_source - x_dest, y_source - y_dest, - FALSE, FALSE, 0, NULL); + glamor_copy(source->pDrawable, + dest->pDrawable, NULL, + RegionRects(region), RegionNumRects(region), + x_source - x_dest, y_source - y_dest, + FALSE, FALSE, 0, NULL); + ret = TRUE; cleanup_region: return ret; } From 51075ebd37dca8d17c42425fb756ad3090e157c4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 21 Mar 2014 18:03:07 -0700 Subject: [PATCH 09/34] glamor: Use glamor_program for glamor_push_pixels This uses the same shaders as glamor_poly_glyph_blt. v2: Wrap some long lines (changes by anholt). Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/glamor_glyphblt.c | 154 +++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 88 deletions(-) diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c index 1c511ff2b..73b1df51e 100644 --- a/glamor/glamor_glyphblt.c +++ b/glamor/glamor_glyphblt.c @@ -56,7 +56,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, glamor_make_current(glamor_priv); - prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs, + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_glyph_blt_progs, &glamor_facet_poly_glyph_blt); if (!prog) goto bail_ctx; @@ -74,7 +75,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, int off_x, off_y; char *vbo_offset; - glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y); + glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, + prog->matrix_uniform, &off_x, &off_y); max_points = 500; num_points = 0; @@ -105,10 +107,12 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, if (!num_points) { points = glamor_get_vbo_space(screen, - max_points * (2 * sizeof (INT16)), + max_points * + (2 * sizeof (INT16)), &vbo_offset); - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, + glVertexAttribPointer(GLAMOR_VERTEX_POS, + 2, GL_SHORT, GL_FALSE, 0, vbo_offset); } @@ -149,7 +153,8 @@ glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc, int start_x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyph_base) { - if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base)) + if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, + pglyph_base)) return; miPolyGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base); @@ -160,10 +165,13 @@ glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc, int start_x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyph_base) { - if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base)) + if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, + pglyph_base)) return TRUE; - if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc)) + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_gc(gc)) { return FALSE; + } miPolyGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base); return TRUE; @@ -179,8 +187,8 @@ glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc, } static Bool -glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, - DrawablePtr drawable, int w, int h, int x, int y) +glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap, + DrawablePtr drawable, int w, int h, int x, int y) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -188,65 +196,40 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, glamor_pixmap_private *pixmap_priv; uint8_t *bitmap_data = bitmap->devPrivate.ptr; int bitmap_stride = bitmap->devKind; - int off_x, off_y; + glamor_program *prog; + RegionPtr clip = gc->pCompositeClip; + int box_x, box_y; int yy, xx; - GLfloat xscale, yscale; - float color[4]; - unsigned long fg_pixel = gc->fgPixel; - float *points, *next_point; - int num_points = 0; + int num_points; + INT16 *points = NULL; char *vbo_offset; - RegionPtr clip; if (w * h > MAXINT / (2 * sizeof(float))) - return FALSE; - - if (gc->fillStyle != FillSolid) { - glamor_fallback("gc fillstyle not solid\n"); - return FALSE; - } + goto bail; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return FALSE; + goto bail; glamor_make_current(glamor_priv); - if (!glamor_set_alu(screen, gc->alu)) { - if (gc->alu == GXclear) - fg_pixel = 0; - else { - glamor_fallback("unsupported alu %x\n", gc->alu); - return FALSE; - } - } - if (!glamor_set_planemask(pixmap, gc->planemask)) { - glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__); - return FALSE; - } + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_glyph_blt_progs, + &glamor_facet_poly_glyph_blt); + if (!prog) + goto bail_ctx; - glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); - - glUseProgram(glamor_priv->solid_prog); - - glamor_get_rgba_from_pixel(fg_pixel, - &color[0], &color[1], &color[2], &color[3], - format_for_pixmap(pixmap)); - glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); - - points = glamor_get_vbo_space(screen, w * h * sizeof(float) * 2, + points = glamor_get_vbo_space(screen, w * h * sizeof(INT16) * 2, &vbo_offset); - next_point = points; - - clip = fbGetCompositeClip(gc); + num_points = 0; /* Note that because fb sets miTranslate in the GC, our incoming X * and Y are in screen coordinate space (same for spans, but not * other operations). */ + for (yy = 0; yy < h; yy++) { uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride; for (xx = 0; xx < w; xx++) { @@ -255,63 +238,58 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, x + xx, y + yy, NULL)) { - next_point[0] = v_from_x_coord_x(xscale, x + xx + off_x + 0.5); - if (glamor_priv->yInverted) - next_point[1] = v_from_x_coord_y_inverted(yscale, y + yy + off_y + 0.5); - else - next_point[1] = v_from_x_coord_y(yscale, y + yy + off_y + 0.5); - - next_point += 2; + *points++ = x + xx; + *points++ = y + yy; num_points++; } } } - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - vbo_offset); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, + GL_FALSE, 0, vbo_offset); glamor_put_vbo_space(screen); - glDrawArrays(GL_POINTS, 0, num_points); + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, + prog->matrix_uniform, NULL, NULL); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - - return TRUE; -} - -static Bool -_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y, - Bool fallback) -{ - glamor_pixmap_private *pixmap_priv; - - if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) - && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable) - && glamor_ddx_fallback_check_gc(pGC)) - return FALSE; - - pixmap_priv = glamor_get_pixmap_private(pBitmap); - if (pixmap_priv->type == GLAMOR_MEMORY) { - if (glamor_push_pixels_points(pGC, pBitmap, pDrawable, w, h, x, y)) - return TRUE; + glDrawArrays(GL_POINTS, 0, num_points); } - miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); return TRUE; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return FALSE; } void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { - _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE); + if (glamor_push_pixels_gl(pGC, pBitmap, pDrawable, w, h, x, y)) + return; + + miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); } Bool -glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y) +glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap, + DrawablePtr drawable, int w, int h, int x, int y) { - return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE); + if (glamor_push_pixels_gl(gc, bitmap, drawable, w, h, x, y)) + return TRUE; + + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_pixmap(&bitmap->drawable) && + glamor_ddx_fallback_check_gc(gc)) + { + return FALSE; + } + + miPushPixels(gc, bitmap, drawable, w, h, x, y); + return TRUE; } From dc9fa9080a1cb994b4e54a341d2245f442dac576 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 23 Mar 2014 20:59:02 -0700 Subject: [PATCH 10/34] glamor: Use glamor_program and GL_LINES for 0-width lines GL lines are nearly X compliant; you just need to fill in the last pixel when the client hasn't requested CapNotLast. v2: switch to glamor_make_current v3: use miPolylines instead of custom glamor fallback path. Wrap code to 80 columns. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/Makefile.am | 4 +- glamor/glamor_lines.c | 171 +++++++++++++++++++++++++++++++++++++ glamor/glamor_polylines.c | 136 ------------------------------ glamor/glamor_priv.h | 25 +++--- glamor/glamor_segment.c | 44 ---------- glamor/glamor_segs.c | 173 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 361 insertions(+), 192 deletions(-) create mode 100644 glamor/glamor_lines.c delete mode 100644 glamor/glamor_polylines.c delete mode 100644 glamor/glamor_segment.c create mode 100644 glamor/glamor_segs.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index c0d82d67d..8fd6ec194 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -15,9 +15,9 @@ libglamor_la_SOURCES = \ glamor_font.h \ glamor_glx.c \ glamor_glyphs.c \ - glamor_polylines.c \ - glamor_segment.c \ glamor_image.c \ + glamor_lines.c \ + glamor_segs.c \ glamor_render.c \ glamor_gradient.c \ glamor_prepare.c \ diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c new file mode 100644 index 000000000..ca3cccf8c --- /dev/null +++ b/glamor/glamor_lines.c @@ -0,0 +1,171 @@ +/* + * Copyright © 2014 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "glamor_priv.h" +#include "glamor_program.h" +#include "glamor_transform.h" +#include "glamor_prepare.h" + +static const glamor_facet glamor_facet_poly_lines = { + .name = "poly_lines", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (" vec2 pos = vec2(0.0,0.0);\n" + GLAMOR_POS(gl_Position, primitive.xy)), +}; + +static Bool +glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + glamor_program *prog; + int off_x, off_y; + DDXPointPtr v; + char *vbo_offset; + int box_x, box_y; + int add_last; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + if (gc->lineWidth != 0) + goto bail; + + if (gc->lineStyle != LineSolid) + goto bail; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + if (n < 2) + return TRUE; + + glamor_make_current(glamor_priv); + + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_line_program, + &glamor_facet_poly_lines); + + if (!prog) + goto bail_ctx; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (n + add_last) * sizeof (DDXPointRec), + &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, + sizeof (DDXPointRec), vbo_offset); + + if (mode == CoordModePrevious) { + int i; + DDXPointRec here = { 0, 0 }; + + for (i = 0; i < n; i++) { + here.x += points[i].x; + here.y += points[i].y; + v[i] = here; + } + } else { + memcpy(v, points, n * sizeof (DDXPointRec)); + } + + if (add_last) { + v[n].x = v[n-1].x + 1; + v[n].y = v[n-1].y; + } + + glamor_put_vbo_space(screen); + + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + int nbox = RegionNumRects(gc->pCompositeClip); + BoxPtr box = RegionRects(gc->pCompositeClip); + + glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, + prog->matrix_uniform, &off_x, &off_y); + + while (nbox--) { + glScissor(box->x1 + off_x, + box->y1 + off_y, + box->x2 - box->x1, + box->y2 - box->y1); + box++; + glDrawArrays(GL_LINE_STRIP, 0, n + add_last); + } + } + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + return TRUE; +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return FALSE; +} + +static void +glamor_poly_lines_bail(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + glamor_fallback("to %p (%c)\n", drawable, + glamor_get_drawable_location(drawable)); + + miPolylines(drawable, gc, mode, n, points); +} + +void +glamor_poly_lines(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + if (glamor_poly_lines_gl(drawable, gc, mode, n, points)) + return; + glamor_poly_lines_bail(drawable, gc, mode, n, points); +} + +Bool +glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + if (glamor_poly_lines_gl(drawable, gc, mode, n, points)) + return TRUE; + + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_gc(gc)) + { + return FALSE; + } + + glamor_poly_lines_bail(drawable, gc, mode, n, points); + return TRUE; +} + diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c deleted file mode 100644 index 1adf45ddc..000000000 --- a/glamor/glamor_polylines.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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 - * - */ - -#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. - */ -static Bool -_glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points, Bool fallback) -{ - 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. - */ - goto fail; - } - - if (gc->lineStyle != LineSolid) { - glamor_fallback("non-solid fill line style %d\n", gc->lineStyle); - goto fail; - } - rects = malloc(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) { - free(rects); - glamor_fallback("stub diagonal poly_line\n"); - goto fail; - } - 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); - free(rects); - return TRUE; - - fail: - if (!fallback && glamor_ddx_fallback_check_pixmap(drawable) - && glamor_ddx_fallback_check_gc(gc)) - return FALSE; - - switch (gc->lineStyle) { - case LineSolid: - if (gc->lineWidth == 0) - miZeroLine(drawable, gc, mode, n, points); - else - miWideLine(drawable, gc, mode, n, points); - break; - case LineOnOffDash: - case LineDoubleDash: - miWideDash(drawable, gc, mode, n, points); - break; - } - - return TRUE; -} - -void -glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) -{ - _glamor_poly_lines(drawable, gc, mode, n, points, TRUE); -} - -Bool -glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) -{ - return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE); -} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 1ae4e94f4..07e1b890f 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -241,6 +241,12 @@ typedef struct glamor_screen_private { glamor_program copy_area_prog; glamor_program copy_plane_prog; + /* glamor line shader */ + glamor_program_fill poly_line_program; + + /* glamor segment shaders */ + glamor_program_fill poly_segment_program; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -683,10 +689,6 @@ void glamor_glyphs(CARD8 op, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs); -/* glamor_polylines.c */ -void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points); - /* glamor_render.c */ Bool glamor_composite_clipped_region(CARD8 op, PicturePtr source, @@ -967,6 +969,15 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); +/* glamor_lines.c */ +void +glamor_poly_lines(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points); + +/* glamor_segs.c */ +void +glamor_poly_segment(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs); /* glamor_copy.c */ void @@ -1006,12 +1017,6 @@ void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt); -void glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg); - -void glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt); - void glamor_composite_rectangles(CARD8 op, PicturePtr dst, xRenderColor *color, diff --git a/glamor/glamor_segment.c b/glamor/glamor_segment.c deleted file mode 100644 index 53f7da0cb..000000000 --- a/glamor/glamor_segment.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright © 2014 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#include "glamor_priv.h" - -Bool -glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, int nseg, - xSegment *seg) -{ - if (glamor_ddx_fallback_check_pixmap(drawable) && - glamor_ddx_fallback_check_gc(gc)) { - return FALSE; - } - - miPolySegment(drawable, gc, nseg, seg); - - return TRUE; -} - -void -glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg, - xSegment *seg) -{ - miPolySegment(drawable, gc, nseg, seg); -} diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c new file mode 100644 index 000000000..0168d053f --- /dev/null +++ b/glamor/glamor_segs.c @@ -0,0 +1,173 @@ +/* + * Copyright © 2014 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "glamor_priv.h" +#include "glamor_program.h" +#include "glamor_transform.h" +#include "glamor_prepare.h" + +static const glamor_facet glamor_facet_poly_segment = { + .name = "poly_segment", + .vs_vars = "attribute vec2 primitive;\n", + .vs_exec = (" vec2 pos = vec2(0.0,0.0);\n" + GLAMOR_POS(gl_Position, primitive.xy)), +}; + +static Bool +glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + glamor_program *prog; + int off_x, off_y; + xSegment *v; + char *vbo_offset; + int box_x, box_y; + int add_last; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + if (gc->lineWidth != 0) + goto bail; + + if (gc->lineStyle != LineSolid) + goto bail; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + glamor_make_current(glamor_priv); + + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->poly_segment_program, + &glamor_facet_poly_segment); + + if (!prog) + goto bail_ctx; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (nseg << add_last) * sizeof (xSegment), + &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, + sizeof(DDXPointRec), vbo_offset); + + if (add_last) { + int i, j; + for (i = 0, j=0; i < nseg; i++) { + v[j++] = segs[i]; + v[j].x1 = segs[i].x2; + v[j].y1 = segs[i].y2; + v[j].x2 = segs[i].x2+1; + v[j].y2 = segs[i].y2; + j++; + } + } else + memcpy(v, segs, nseg * sizeof (xSegment)); + + glamor_put_vbo_space(screen); + + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + int nbox = RegionNumRects(gc->pCompositeClip); + BoxPtr box = RegionRects(gc->pCompositeClip); + + glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, + prog->matrix_uniform, &off_x, &off_y); + + while (nbox--) { + glScissor(box->x1 + off_x, + box->y1 + off_y, + box->x2 - box->x1, + box->y2 - box->y1); + box++; + glDrawArrays(GL_LINES, 0, nseg << (1 + add_last)); + } + } + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + + return TRUE; +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return FALSE; +} + +static void +glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + glamor_fallback("to %p (%c)\n", drawable, + glamor_get_drawable_location(drawable)); + + if (gc->lineWidth == 0) { + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { + fbPolySegment(drawable, gc, nseg, segs); + } + glamor_finish_access_gc(gc); + glamor_finish_access(drawable); + } else + miPolySegment(drawable, gc, nseg, segs); +} + + +void +glamor_poly_segment(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + if (glamor_poly_segment_gl(drawable, gc, nseg, segs)) + return; + + glamor_poly_segment_bail(drawable, gc, nseg, segs); +} + +Bool +glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + if (glamor_poly_segment_gl(drawable, gc, nseg, segs)) + return TRUE; + + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_gc(gc)) + { + return FALSE; + } + + glamor_poly_segment_bail(drawable, gc, nseg, segs); + return TRUE; +} + From d18f5801c9a632dd4d9f8b7912491b6623e943d5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Apr 2014 14:07:20 -0700 Subject: [PATCH 11/34] glamor: Add glamor_program based 0-width dashed lines This makes sure the pixelization for dashed lines matches non-dashed lines, while also speeding them up. v2: Switch to glamor_make_current v3: Create dash pattern pixmap without GLAMOR_CREATE_FBO_NO_FBO v4: Adopt suggestions from Eric's review: - Drops power-of-two alignment of our line vertex data, simplifying the code. - Stops reading from the VBO. While on keithp's and my machines the VBO is mapped cached, on many implementations it will be mapped WC, making those reads extremely expensive. - Style fixes (line wrapping, spaces around operators). v5: Adopt suggestions from Markus' review: - Use max when computing zero-width dashed line length. Don't open code max here. - Embed CoordModePrevious into VBO writing for dashed lines Instead of pre-computing the coord mode previous results, just embed this in the loop which fills the vertex buffer. Saves re-writing the request buffer, and shortens the code a bit v6: Export glamor_destroy_gc for UXA UXA needs to call glamor_destroy_gc from its GCFuncs, so export it. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/Makefile.am | 1 + glamor/glamor.c | 11 +- glamor/glamor.h | 4 + glamor/glamor_core.c | 26 ++- glamor/glamor_dash.c | 370 ++++++++++++++++++++++++++++++++++++++++ glamor/glamor_lines.c | 32 +++- glamor/glamor_priv.h | 29 +++- glamor/glamor_program.c | 7 + glamor/glamor_program.h | 3 + glamor/glamor_segs.c | 33 +++- 10 files changed, 496 insertions(+), 20 deletions(-) create mode 100644 glamor/glamor_dash.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 8fd6ec194..9dd06ebf0 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -9,6 +9,7 @@ libglamor_la_SOURCES = \ glamor_context.h \ glamor_copy.c \ glamor_core.c \ + glamor_dash.c \ glamor_debug.h \ glamor_fill.c \ glamor_font.c \ diff --git a/glamor/glamor.c b/glamor/glamor.c index 3468b51c3..1ae0382fc 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -37,6 +37,7 @@ DevPrivateKeyRec glamor_screen_private_key; DevPrivateKeyRec glamor_pixmap_private_key; +DevPrivateKeyRec glamor_gc_private_key; /** * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable. @@ -346,7 +347,15 @@ glamor_init(ScreenPtr screen, unsigned int flags) LogMessage(X_WARNING, "glamor%d: Failed to allocate pixmap private\n", screen->myNum); - goto fail;; + goto fail; + } + + if (!dixRegisterPrivateKey(&glamor_gc_private_key, PRIVATE_GC, + sizeof (glamor_gc_private))) { + LogMessage(X_WARNING, + "glamor%d: Failed to allocate gc private\n", + screen->myNum); + goto fail; } if (epoxy_is_desktop_gl()) diff --git a/glamor/glamor.h b/glamor/glamor.h index 77fa01e8d..2cdb1d431 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -321,6 +321,10 @@ extern _X_EXPORT int glamor_create_gc(GCPtr gc); extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable); +extern _X_EXPORT void glamor_destroy_gc(GCPtr gc); + +#define HAS_GLAMOR_DESTROY_GC 1 + extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index ffb6eba4b..31cf3dce6 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -409,14 +409,35 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) fbValidateGC(gc, changes, drawable); } + if (changes & GCDashList) { + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (gc_priv->dash) { + glamor_destroy_pixmap(gc_priv->dash); + gc_priv->dash = NULL; + } + } + gc->ops = &glamor_gc_ops; } +void +glamor_destroy_gc(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (gc_priv->dash) { + glamor_destroy_pixmap(gc_priv->dash); + gc_priv->dash = NULL; + } + miDestroyGC(gc); +} + static GCFuncs glamor_gc_funcs = { glamor_validate_gc, miChangeGC, miCopyGC, - miDestroyGC, + glamor_destroy_gc, miChangeClip, miDestroyClip, miCopyClip @@ -429,6 +450,9 @@ static GCFuncs glamor_gc_funcs = { int glamor_create_gc(GCPtr gc) { + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + gc_priv->dash = NULL; if (!fbCreateGC(gc)) return FALSE; diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c new file mode 100644 index 000000000..e8f60fa10 --- /dev/null +++ b/glamor/glamor_dash.c @@ -0,0 +1,370 @@ +/* + * Copyright © 2014 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "glamor_priv.h" +#include "glamor_program.h" +#include "glamor_transform.h" +#include "glamor_transfer.h" +#include "glamor_prepare.h" + +static const char dash_vs_vars[] = + "attribute vec3 primitive;\n" + "varying float dash_offset;\n"; + +static const char dash_vs_exec[] = + " dash_offset = primitive.z / dash_length;\n" + GLAMOR_POS(gl_Position, primitive.xy); + +static const char dash_fs_vars[] = + "varying float dash_offset;\n"; + +static const char on_off_fs_exec[] = + " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n" + " if (pattern == 0.0)\n" + " discard;\n"; + +/* XXX deal with stippled double dashed lines once we have stippling support */ +static const char double_fs_exec[] = + " float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n" + " if (pattern == 0.0)\n" + " gl_FragColor = bg;\n" + " else\n" + " gl_FragColor = fg;\n"; + + +static const glamor_facet glamor_facet_on_off_dash_lines = { + .version = 130, + .name = "poly_lines_on_off_dash", + .vs_vars = dash_vs_vars, + .vs_exec = dash_vs_exec, + .fs_vars = dash_fs_vars, + .fs_exec = on_off_fs_exec, + .locations = glamor_program_location_dash, +}; + +static const glamor_facet glamor_facet_double_dash_lines = { + .version = 130, + .name = "poly_lines_double_dash", + .vs_vars = dash_vs_vars, + .vs_exec = dash_vs_exec, + .fs_vars = dash_fs_vars, + .fs_exec = double_fs_exec, + .locations = (glamor_program_location_dash| + glamor_program_location_fg| + glamor_program_location_bg), +}; + +static PixmapPtr +glamor_get_dash_pixmap(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + ScreenPtr screen = gc->pScreen; + PixmapPtr pixmap; + int offset; + int d; + uint32_t pixel; + GCPtr scratch_gc; + + if (gc_priv->dash) + return gc_priv->dash; + + offset = 0; + for (d = 0; d < gc->numInDashList; d++) + offset += gc->dash[d]; + + pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0); + if (!pixmap) + goto bail; + + scratch_gc = GetScratchGC(8, screen); + if (!scratch_gc) + goto bail_pixmap; + + pixel = 0xffffffff; + offset = 0; + for (d = 0; d < gc->numInDashList; d++) { + xRectangle rect; + ChangeGCVal changes; + + changes.val = pixel; + (void) ChangeGC(NullClient, scratch_gc, + GCForeground, &changes); + ValidateGC(&pixmap->drawable, scratch_gc); + rect.x = offset; + rect.y = 0; + rect.width = gc->dash[d]; + rect.height = 1; + scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect); + offset += gc->dash[d]; + pixel = ~pixel; + } + FreeScratchGC(scratch_gc); + + gc_priv->dash = pixmap; + return pixmap; + +bail_pixmap: + glamor_destroy_pixmap(pixmap); +bail: + return NULL; +} + +static glamor_program * +glamor_dash_setup(DrawablePtr drawable, GCPtr gc) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + PixmapPtr dash_pixmap; + glamor_pixmap_private *dash_priv; + glamor_program *prog; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + if (gc->lineWidth != 0) + goto bail; + + dash_pixmap = glamor_get_dash_pixmap(gc); + dash_priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dash_priv)) + goto bail; + + glamor_make_current(glamor_priv); + + switch (gc->lineStyle) { + case LineOnOffDash: + prog = glamor_use_program_fill(pixmap, gc, + &glamor_priv->on_off_dash_line_progs, + &glamor_facet_on_off_dash_lines); + if (!prog) + goto bail_ctx; + break; + case LineDoubleDash: + if (gc->fillStyle != FillSolid) + goto bail_ctx; + + prog = &glamor_priv->double_dash_line_prog; + + if (!prog->prog) { + if (!glamor_build_program(screen, prog, + &glamor_facet_double_dash_lines, + NULL)) + goto bail_ctx; + } + + if (!glamor_use_program(pixmap, gc, prog, NULL)) + goto bail_ctx; + + glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform); + glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); + break; + + default: + goto bail_ctx; + } + + + /* Set the dash pattern as texture 1 */ + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex); + glUniform1i(prog->dash_uniform, 1); + glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width); + + return prog; + +bail_ctx: + glDisable(GL_COLOR_LOGIC_OP); +bail: + return NULL; +} + +static void +glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog, + int n, GLenum mode) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + int box_x, box_y; + int off_x, off_y; + + glEnable(GL_SCISSOR_TEST); + + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + int nbox = RegionNumRects(gc->pCompositeClip); + BoxPtr box = RegionRects(gc->pCompositeClip); + + glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, + prog->matrix_uniform, &off_x, &off_y); + + while (nbox--) { + glScissor(box->x1 + off_x, + box->y1 + off_y, + box->x2 - box->x1, + box->y2 - box->y1); + box++; + glDrawArrays(mode, 0, n); + } + } + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_COLOR_LOGIC_OP); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); +} + +static int +glamor_line_length(short x1, short y1, short x2, short y2) +{ + return max(abs(x2 - x1), abs(y2 - y1)); +} + +Bool +glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + ScreenPtr screen = drawable->pScreen; + glamor_program *prog; + short *v; + char *vbo_offset; + int add_last; + int dash_pos; + int prev_x, prev_y; + int i; + + if (n < 2) + return TRUE; + + if (!(prog = glamor_dash_setup(drawable, gc))) + return FALSE; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (n + add_last) * 3 * sizeof (short), + &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE, + 3 * sizeof (short), vbo_offset); + + dash_pos = gc->dashOffset; + prev_x = prev_y = 0; + for (i = 0; i < n; i++) { + int this_x = points[i].x; + int this_y = points[i].y; + if (i) { + if (mode == CoordModePrevious) { + this_x += prev_x; + this_y += prev_y; + } + dash_pos += glamor_line_length(prev_x, prev_y, + this_x, this_y); + } + v[0] = prev_x = this_x; + v[1] = prev_y = this_y; + v[2] = dash_pos; + v += 3; + } + + if (add_last) { + v[0] = prev_x + 1; + v[1] = prev_y; + v[2] = dash_pos + 1; + } + + glamor_put_vbo_space(screen); + + glamor_dash_loop(drawable, gc, prog, n + add_last, GL_LINE_STRIP); + + return TRUE; +} + +static short * +glamor_add_segment(short *v, short x1, short y1, short x2, short y2, + int dash_start, int dash_end) +{ + v[0] = x1; + v[1] = y1; + v[2] = dash_start; + + v[3] = x2; + v[4] = y2; + v[5] = dash_end; + return v + 6; +} + +Bool +glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + ScreenPtr screen = drawable->pScreen; + glamor_program *prog; + short *v; + char *vbo_offset; + int dash_start = gc->dashOffset; + int add_last; + int i; + + if (!(prog = glamor_dash_setup(drawable, gc))) + return FALSE; + + add_last = 0; + if (gc->capStyle != CapNotLast) + add_last = 1; + + /* Set up the vertex buffers for the points */ + + v = glamor_get_vbo_space(drawable->pScreen, + (nseg<pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -51,12 +51,6 @@ glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc, if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; - if (gc->lineWidth != 0) - goto bail; - - if (gc->lineStyle != LineSolid) - goto bail; - add_last = 0; if (gc->capStyle != CapNotLast) add_last = 1; @@ -133,6 +127,28 @@ bail: return FALSE; } +static Bool +glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points) +{ + if (gc->lineWidth != 0) + return FALSE; + + switch (gc->lineStyle) { + case LineSolid: + return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points); + case LineOnOffDash: + return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points); + case LineDoubleDash: + if (gc->fillStyle == FillTiled) + return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points); + else + return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points); + default: + return FALSE; + } +} + static void glamor_poly_lines_bail(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 07e1b890f..6480eb607 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -247,6 +247,10 @@ typedef struct glamor_screen_private { /* glamor segment shaders */ glamor_program_fill poly_segment_program; + /* glamor dash line shader */ + glamor_program_fill on_off_dash_line_progs; + glamor_program double_dash_line_prog; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -559,6 +563,13 @@ typedef enum glamor_pixmap_status { GLAMOR_UPLOAD_FAILED } glamor_pixmap_status_t; +/* GC private structure. Currently holds only any computed dash pixmap */ + +typedef struct { + PixmapPtr dash; +} glamor_gc_private; + +extern DevPrivateKeyRec glamor_gc_private_key; extern DevPrivateKeyRec glamor_screen_private_key; extern DevPrivateKeyRec glamor_pixmap_private_key; @@ -591,6 +602,12 @@ glamor_get_pixmap_private(PixmapPtr pixmap) void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv); +static inline glamor_gc_private * +glamor_get_gc_private(GCPtr gc) +{ + return dixLookupPrivate(&gc->devPrivates, &glamor_gc_private_key); +} + /** * Returns TRUE if the given planemask covers all the significant bits in the * pixel values for pDrawable. @@ -969,7 +986,17 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); -/* glamor_lines.c */ + +/* glamor_dash.c */ +Bool +glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points); + +Bool +glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs); + +/* glamor_lines.c */ void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points); diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c index 6ee6580ff..f3d4477fb 100644 --- a/glamor/glamor_program.c +++ b/glamor/glamor_program.c @@ -122,6 +122,11 @@ static glamor_location_var location_vars[] = { .fs_vars = ("uniform uvec4 bitplane;\n" "uniform vec4 bitmul;\n"), }, + { + .location = glamor_program_location_dash, + .vs_vars = "uniform float dash_length;\n", + .fs_vars = "uniform sampler2D dash;\n", + }, }; #define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0]) @@ -326,6 +331,8 @@ glamor_build_program(ScreenPtr screen, prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font"); prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane"); prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul"); + prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash"); + prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length"); if (glGetError() != GL_NO_ERROR) goto fail; diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h index 118f97838..56ba03aa8 100644 --- a/glamor/glamor_program.h +++ b/glamor/glamor_program.h @@ -30,6 +30,7 @@ typedef enum { glamor_program_location_fill = 4, glamor_program_location_font = 8, glamor_program_location_bitplane = 16, + glamor_program_location_dash = 32, } glamor_program_location; typedef enum { @@ -64,6 +65,8 @@ struct _glamor_program { GLint font_uniform; GLint bitplane_uniform; GLint bitmul_uniform; + GLint dash_uniform; + GLint dash_length_uniform; glamor_program_location locations; glamor_program_flag flags; glamor_use prim_use; diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c index 0168d053f..ff0daef10 100644 --- a/glamor/glamor_segs.c +++ b/glamor/glamor_segs.c @@ -33,8 +33,8 @@ static const glamor_facet glamor_facet_poly_segment = { }; static Bool -glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc, - int nseg, xSegment *segs) +glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -51,12 +51,6 @@ glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc, if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; - if (gc->lineWidth != 0) - goto bail; - - if (gc->lineStyle != LineSolid) - goto bail; - add_last = 0; if (gc->capStyle != CapNotLast) add_last = 1; @@ -125,6 +119,28 @@ bail: return FALSE; } +static Bool +glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc, + int nseg, xSegment *segs) +{ + if (gc->lineWidth != 0) + return FALSE; + + switch (gc->lineStyle) { + case LineSolid: + return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs); + case LineOnOffDash: + return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs); + case LineDoubleDash: + if (gc->fillStyle == FillTiled) + return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs); + else + return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs); + default: + return FALSE; + } +} + static void glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs) @@ -143,7 +159,6 @@ glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc, miPolySegment(drawable, gc, nseg, segs); } - void glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg, xSegment *segs) From bd3b2c48f69a5169aefb261c041462271c69a07a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 3 Apr 2014 14:22:52 -0700 Subject: [PATCH 12/34] glamor: Add accelerated stipple support This copies the stipple to a 8bpp pixmap and uses that to paint the texture from. v2: Create deep stipple pixmap without GLAMOR_CREATE_FBO_NO_FBO v3: Fix stipple origin sign (matches tiles now). Track changes to original stipple with damage. This isn't required by the X spec, but java appears to depend on it, so we'll just do it. When Glamor switches to 8bpp bitmaps, we'll be able to render directly from them and not need this anymore. v4: Review comments from Eric: * Remove stray whitespace change * Avoid "large" pixmap for stipple by using GLAMOR_CREATE_NO_LARGE * Wrap to 80 columns v5: Don't crash when stipple damage tracker is destroyed The stipple damage tracker is automatically destroyed when the associated stipple pixmap is destroyed. When this happens, just clear the pointer from the GC rather than calling glamor_invalidate_stipple; that function would call DamageUnregister on the now invalid stipple damage pointer and crash. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/glamor_core.c | 59 +++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 5 +++ glamor/glamor_program.c | 39 +++++++++++++-------- glamor/glamor_transform.c | 74 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 158 insertions(+), 19 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 31cf3dce6..bafc42052 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -326,6 +326,58 @@ GCOps glamor_gc_ops = { .PushPixels = glamor_push_pixels, }; +/* + * When the stipple is changed or drawn to, invalidate any + * cached copy + */ +static void +glamor_invalidate_stipple(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (gc_priv->stipple) { + if (gc_priv->stipple_damage) + DamageUnregister(gc_priv->stipple_damage); + glamor_destroy_pixmap(gc_priv->stipple); + gc_priv->stipple = NULL; + } +} + +static void +glamor_stipple_damage_report(DamagePtr damage, RegionPtr region, + void *closure) +{ + GCPtr gc = closure; + + glamor_invalidate_stipple(gc); +} + +static void +glamor_stipple_damage_destroy(DamagePtr damage, void *closure) +{ + GCPtr gc = closure; + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + gc_priv->stipple_damage = NULL; + glamor_invalidate_stipple(gc); +} + +void +glamor_track_stipple(GCPtr gc) +{ + if (gc->stipple) { + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + + if (!gc_priv->stipple_damage) + gc_priv->stipple_damage = DamageCreate(glamor_stipple_damage_report, + glamor_stipple_damage_destroy, + DamageReportNonEmpty, + TRUE, gc->pScreen, gc); + if (gc_priv->stipple_damage) + DamageRegister(&gc->stipple->drawable, gc_priv->stipple_damage); + } +} + /** * uxa_validate_gc() sets the ops to glamor's implementations, which may be * accelerated or may sync the card and fall back to fb. @@ -396,6 +448,9 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) changes &= ~GCTile; } + if (changes & GCStipple) + glamor_invalidate_stipple(gc); + if (changes & GCStipple && gc->stipple) { /* We can't inline stipple handling like we do for GCTile because * it sets fbgc privates. @@ -430,6 +485,9 @@ glamor_destroy_gc(GCPtr gc) glamor_destroy_pixmap(gc_priv->dash); gc_priv->dash = NULL; } + glamor_invalidate_stipple(gc); + if (gc_priv->stipple_damage) + DamageDestroy(gc_priv->stipple_damage); miDestroyGC(gc); } @@ -453,6 +511,7 @@ glamor_create_gc(GCPtr gc) glamor_gc_private *gc_priv = glamor_get_gc_private(gc); gc_priv->dash = NULL; + gc_priv->stipple = NULL; if (!fbCreateGC(gc)) return FALSE; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 6480eb607..129eaaadf 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -567,6 +567,8 @@ typedef enum glamor_pixmap_status { typedef struct { PixmapPtr dash; + PixmapPtr stipple; + DamagePtr stipple_damage; } glamor_gc_private; extern DevPrivateKeyRec glamor_gc_private_key; @@ -684,6 +686,9 @@ Bool glamor_set_alu(ScreenPtr screen, unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); +void +glamor_track_stipple(GCPtr gc); + /* glamor_fill.c */ Bool glamor_fill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height, Bool fallback); diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c index f3d4477fb..1d0328f2b 100644 --- a/glamor/glamor_program.c +++ b/glamor/glamor_program.c @@ -51,42 +51,51 @@ static const glamor_facet glamor_fill_tile = { .use = use_tile, }; -#if 0 static Bool -use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog) +use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) { - return glamor_set_stippled(pixmap, gc, prog->fg_uniform, prog->fill_offset_uniform, prog->fill_size_uniform); + return glamor_set_stippled(pixmap, gc, prog->fg_uniform, + prog->fill_offset_uniform, + prog->fill_size_uniform); } static const glamor_facet glamor_fill_stipple = { .name = "stipple", - .version = 130, - .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n"; - .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n" + .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n", + .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n" + " if (a == 0.0)\n" " discard;\n" - " gl_FragColor = fg;\n") - .locations = glamor_program_location_fg | glamor_program_location_fill + " gl_FragColor = fg;\n"), + .locations = glamor_program_location_fg | glamor_program_location_fill, .use = use_stipple, }; +static Bool +use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) +{ + if (!use_stipple(pixmap, gc, prog, arg)) + return FALSE; + glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); + return TRUE; +} + static const glamor_facet glamor_fill_opaque_stipple = { .name = "opaque_stipple", - .version = 130, - .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n"; - .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n" + .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n", + .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n" + " if (a == 0.0)\n" " gl_FragColor = bg;\n" " else\n" " gl_FragColor = fg;\n"), - .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill + .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill, .use = use_opaque_stipple }; -#endif static const glamor_facet *glamor_facet_fill[4] = { &glamor_fill_solid, &glamor_fill_tile, - NULL, - NULL, + &glamor_fill_stipple, + &glamor_fill_opaque_stipple, }; typedef struct { diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c index d6ba56421..c1df56018 100644 --- a/glamor/glamor_transform.c +++ b/glamor/glamor_transform.c @@ -198,6 +198,64 @@ glamor_set_tiled(PixmapPtr pixmap, size_uniform); } +static PixmapPtr +glamor_get_stipple_pixmap(GCPtr gc) +{ + glamor_gc_private *gc_priv = glamor_get_gc_private(gc); + ScreenPtr screen = gc->pScreen; + PixmapPtr bitmap; + PixmapPtr pixmap; + GCPtr scratch_gc; + ChangeGCVal changes[2]; + + if (gc_priv->stipple) + return gc_priv->stipple; + + bitmap = gc->stipple; + if (!bitmap) + goto bail; + + pixmap = glamor_create_pixmap(screen, + bitmap->drawable.width, + bitmap->drawable.height, + 8, GLAMOR_CREATE_NO_LARGE); + if (!pixmap) + goto bail; + + scratch_gc = GetScratchGC(8, screen); + if (!scratch_gc) + goto bail_pixmap; + + changes[0].val = 0xff; + changes[1].val = 0x00; + if (ChangeGC(NullClient, scratch_gc, + GCForeground|GCBackground, changes) != Success) + goto bail_gc; + ValidateGC(&pixmap->drawable, scratch_gc); + + (*scratch_gc->ops->CopyPlane)(&bitmap->drawable, + &pixmap->drawable, + scratch_gc, + 0, 0, + bitmap->drawable.width, + bitmap->drawable.height, + 0, 0, 0x1); + + FreeScratchGC(scratch_gc); + gc_priv->stipple = pixmap; + + glamor_track_stipple(gc); + + return pixmap; + +bail_gc: + FreeScratchGC(scratch_gc); +bail_pixmap: + glamor_destroy_pixmap(pixmap); +bail: + return NULL; +} + Bool glamor_set_stippled(PixmapPtr pixmap, GCPtr gc, @@ -205,11 +263,19 @@ glamor_set_stippled(PixmapPtr pixmap, GLint offset_uniform, GLint size_uniform) { + PixmapPtr stipple; + + stipple = glamor_get_stipple_pixmap(gc); + if (!stipple) + return FALSE; + if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform)) return FALSE; - if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform)) - return FALSE; - - return TRUE; + return glamor_set_texture(pixmap, + stipple, + -gc->patOrg.x, + -gc->patOrg.y, + offset_uniform, + size_uniform); } From 18c09e60bf16b28060ade5d24110f2aa6bc19b57 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Mar 2014 20:49:28 -0700 Subject: [PATCH 13/34] glamor: Replace glamor_solid_boxes and glamor_solid with GC using code This provides glamor_solid_boxes and glamor_solid using regular GC operations instead of calling directly to underlying rendering functions. This will allow the old rendering code to be removed. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/Makefile.am | 2 +- glamor/glamor.c | 2 - glamor/glamor_fill.c | 356 -------------------------------------- glamor/glamor_priv.h | 45 +++-- glamor/glamor_trapezoid.c | 9 +- glamor/glamor_utils.c | 82 +++++++++ 6 files changed, 106 insertions(+), 390 deletions(-) delete mode 100644 glamor/glamor_fill.c create mode 100644 glamor/glamor_utils.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 9dd06ebf0..30fcef101 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -11,7 +11,6 @@ libglamor_la_SOURCES = \ glamor_core.c \ glamor_dash.c \ glamor_debug.h \ - glamor_fill.c \ glamor_font.c \ glamor_font.h \ glamor_glx.c \ @@ -46,6 +45,7 @@ libglamor_la_SOURCES = \ glamor_window.c\ glamor_fbo.c\ glamor_compositerects.c\ + glamor_utils.c\ glamor_utils.h\ glamor.h diff --git a/glamor/glamor.c b/glamor/glamor.c index 1ae0382fc..689188108 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -514,7 +514,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_init_vbo(screen); glamor_init_pixmap_fbo(screen); - glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_init_trapezoid_shader(screen); @@ -547,7 +546,6 @@ glamor_release_screen_priv(ScreenPtr screen) #endif glamor_fini_vbo(screen); glamor_fini_pixmap_fbo(screen); - glamor_fini_solid_shader(screen); glamor_fini_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_fini_trapezoid_shader(screen); diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c deleted file mode 100644 index 073904d2a..000000000 --- a/glamor/glamor_fill.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * 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. - * - * Authors: - * Eric Anholt - * Zhigang Gong - */ - -#include "glamor_priv.h" - -/** @file glamor_fill.c - * - * GC fill implementation, based loosely on fb_fill.c - */ - -/** - * Fills the given rectangle of a drawable with the GC's fill style. - */ -Bool -glamor_fill(DrawablePtr drawable, - GCPtr gc, int x, int y, int width, int height, Bool fallback) -{ - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); - int off_x, off_y; - PixmapPtr sub_pixmap = NULL; - glamor_access_t sub_pixmap_access; - DrawablePtr saved_drawable = NULL; - int saved_x = x, saved_y = y; - - glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y); - - switch (gc->fillStyle) { - case FillSolid: - if (!glamor_solid(dst_pixmap, - x + off_x, - y + off_y, - width, height, gc->alu, gc->planemask, gc->fgPixel)) - goto fail; - break; - case FillStippled: - case FillOpaqueStippled: - if (!glamor_stipple(dst_pixmap, - gc->stipple, - x + off_x, - y + off_y, - width, - height, - gc->alu, - gc->planemask, - gc->fgPixel, - gc->bgPixel, gc->patOrg.x, gc->patOrg.y)) - goto fail; - break; - case FillTiled: - if (!glamor_tile(dst_pixmap, - gc->tile.pixmap, - x + off_x, - y + off_y, - width, - height, - gc->alu, - gc->planemask, - x - drawable->x - gc->patOrg.x, - y - drawable->y - gc->patOrg.y)) - goto fail; - break; - } - return TRUE; - - fail: - if (!fallback) { - if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable) - && glamor_ddx_fallback_check_gc(gc)) - return FALSE; - } - /* Is it possible to set the access as WO? */ - - sub_pixmap_access = GLAMOR_ACCESS_RW; - - sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x, - y + off_y, width, height, - sub_pixmap_access); - - if (sub_pixmap != NULL) { - if (gc->fillStyle != FillSolid) { - gc->patOrg.x += (drawable->x - x); - gc->patOrg.y += (drawable->y - y); - } - saved_drawable = drawable; - drawable = &sub_pixmap->drawable; - saved_x = x; - saved_y = y; - x = 0; - y = 0; - } - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && - glamor_prepare_access_gc(gc)) { - fbFill(drawable, gc, x, y, width, height); - } - glamor_finish_access_gc(gc); - glamor_finish_access(drawable); - - if (sub_pixmap != NULL) { - if (gc->fillStyle != FillSolid) { - gc->patOrg.x -= (saved_drawable->x - saved_x); - gc->patOrg.y -= (saved_drawable->y - saved_y); - } - - x = saved_x; - y = saved_y; - - glamor_put_sub_pixmap(sub_pixmap, dst_pixmap, - x + off_x, y + off_y, - width, height, sub_pixmap_access); - } - - return TRUE; -} - -void -glamor_init_solid_shader(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv; - const char *solid_vs = - "attribute vec4 v_position;" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - "}\n"; - const char *solid_fs = - GLAMOR_DEFAULT_PRECISION - "uniform vec4 color;\n" - "void main()\n" - "{\n" - " gl_FragColor = color;\n" - "}\n"; - GLint fs_prog, vs_prog; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - 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); - - glBindAttribLocation(glamor_priv->solid_prog, - GLAMOR_VERTEX_POS, "v_position"); - glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid"); - - glamor_priv->solid_color_uniform_location = - glGetUniformLocation(glamor_priv->solid_prog, "color"); -} - -void -glamor_fini_solid_shader(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - glDeleteProgram(glamor_priv->solid_prog); -} - -static void -_glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) -{ - 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); - GLfloat xscale, yscale; - float stack_vertices[32]; - float *vertices = stack_vertices; - int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2); - - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - glamor_make_current(glamor_priv); - glUseProgram(glamor_priv->solid_prog); - - glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); - - pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); - - if (nbox > valid_nbox) { - int allocated_nbox; - float *new_vertices; - - if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6) - allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6; - else - allocated_nbox = nbox; - new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float)); - if (new_vertices) { - vertices = new_vertices; - valid_nbox = allocated_nbox; - } - } - - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - - while (nbox) { - int box_cnt, i; - float *next_box; - - next_box = vertices; - box_cnt = nbox > valid_nbox ? valid_nbox : nbox; - for (i = 0; i < box_cnt; i++) { - glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale, - box[i].x1, box[i].y1, - box[i].x2, box[i].y2, - glamor_priv->yInverted, - next_box); - next_box += 4 * 2; - } - if (box_cnt == 1) - glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4); - else { - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6, - GL_UNSIGNED_SHORT, NULL); - } else { - glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT, - NULL); - } - } - nbox -= box_cnt; - box += box_cnt; - } - - if (vertices != stack_vertices) - free(vertices); - - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; -} - -/** - * Fills the given rectangles of pixmap with an X pixel value. - * - * This is a helper used by other code after clipping and translation - * of coordinates to a glamor backing pixmap. - */ -Bool -glamor_solid_boxes(PixmapPtr pixmap, - BoxPtr box, int nbox, unsigned long fg_pixel) -{ - glamor_pixmap_private *pixmap_priv; - GLfloat color[4]; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return FALSE; - - glamor_get_rgba_from_pixel(fg_pixel, - &color[0], - &color[1], - &color[2], &color[3], format_for_pixmap(pixmap)); - - if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - RegionRec region; - int n_region; - glamor_pixmap_clipped_regions *clipped_regions; - int i; - - RegionInitBoxes(®ion, box, nbox); - clipped_regions = - glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0, - 0, 0); - for (i = 0; i < n_region; i++) { - BoxPtr inner_box; - int inner_nbox; - - SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx); - - inner_box = RegionRects(clipped_regions[i].region); - inner_nbox = RegionNumRects(clipped_regions[i].region); - _glamor_solid_boxes(pixmap, inner_box, inner_nbox, color); - RegionDestroy(clipped_regions[i].region); - } - free(clipped_regions); - RegionUninit(®ion); - } - else - _glamor_solid_boxes(pixmap, box, nbox, color); - - return TRUE; -} - -/** - * Fills a rectangle of a pixmap with an X pixel value. - * - * This is a helper used by other glamor code mostly for clearing of - * buffers to 0. - */ -Bool -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); - glamor_pixmap_private *pixmap_priv; - BoxRec box; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return FALSE; - - if (!glamor_set_planemask(pixmap, planemask)) { - glamor_fallback("Failedto set planemask in glamor_solid.\n"); - return FALSE; - } - - glamor_make_current(glamor_priv); - if (!glamor_set_alu(screen, alu)) { - if (alu == GXclear) - fg_pixel = 0; - else { - glamor_fallback("unsupported alu %x\n", alu); - return FALSE; - } - } - box.x1 = x; - box.y1 = y; - box.x2 = x + width; - box.y2 = y + height; - glamor_solid_boxes(pixmap, &box, 1, fg_pixel); - - glamor_set_alu(screen, GXcopy); - - return TRUE; -} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 129eaaadf..187a9b5a8 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -216,10 +216,6 @@ typedef struct glamor_screen_private { fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; unsigned long fbo_cache_watermark; - /* glamor_solid */ - GLint solid_prog; - GLint solid_color_uniform_location; - /* glamor point shader */ glamor_program point_prog; @@ -547,7 +543,7 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv) for (y = 0; y < glamor_pixmap_hcnt(priv); y++) \ for (x = 0; x < glamor_pixmap_wcnt(priv); x++) -/* +/* * Pixmap dynamic status, used by dynamic upload feature. * * GLAMOR_NONE: initial status, don't need to do anything. @@ -672,7 +668,7 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv); void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int); /* nc means no check. caller must ensure this pixmap has valid fbo. - * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. + * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. * */ void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv); @@ -689,18 +685,6 @@ RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); void glamor_track_stipple(GCPtr gc); -/* glamor_fill.c */ -Bool glamor_fill(DrawablePtr drawable, - GCPtr gc, int x, int y, int width, int height, Bool fallback); -Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - unsigned long fg_pixel); -Bool glamor_solid_boxes(PixmapPtr pixmap, - BoxPtr box, int nbox, unsigned long fg_pixel); - -void glamor_init_solid_shader(ScreenPtr screen); -void glamor_fini_solid_shader(ScreenPtr screen); - /* glamor_glyphs.c */ Bool glamor_realize_glyph_caches(ScreenPtr screen); void glamor_glyphs_fini(ScreenPtr screen); @@ -821,10 +805,10 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset); void glamor_put_vbo_space(ScreenPtr screen); -/** +/** * Download a pixmap's texture to cpu memory. If success, * One copy of current pixmap's texture will be put into - * the pixmap->devPrivate.ptr. Will use pbo to map to + * the pixmap->devPrivate.ptr. Will use pbo to map to * the pointer if possible. * The pixmap must be a gl texture pixmap. gl_fbo must be GLAMOR_FBO_NORMAL and * gl_tex must be 1. Used by glamor_prepare_access. @@ -837,9 +821,9 @@ void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, 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. + * 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 originally be a texture -- gl_fbo must be * GLAMOR_FBO_NORMAL. @@ -1054,6 +1038,17 @@ void glamor_composite_rectangles(CARD8 op, xRenderColor *color, int num_rects, xRectangle *rects); +/* glamor_util.c */ +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_boxes(PixmapPtr pixmap, + BoxPtr box, int nbox, unsigned long fg_pixel); + + /* glamor_xv */ typedef struct { uint32_t transform_index; @@ -1080,10 +1075,10 @@ void glamor_fini_xv_shader(ScreenPtr screen); #include"glamor_utils.h" -/* Dynamic pixmap upload to texture if needed. +/* 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 + * 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. */ diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c index 4aba469af..4ad067240 100644 --- a/glamor/glamor_trapezoid.c +++ b/glamor/glamor_trapezoid.c @@ -1392,12 +1392,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, } /* First, clear all to zero */ - if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width, - pixmap_priv->base.pixmap->drawable.height, - GXclear, 0xFFFFFFFF, 0)) { - DEBUGF("glamor_solid failed, fallback\n"); - return FALSE; - } + glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width, + pixmap_priv->base.pixmap->drawable.height, + GXclear, 0xFFFFFFFF, 0); glamor_make_current(glamor_priv); diff --git a/glamor/glamor_utils.c b/glamor/glamor_utils.c new file mode 100644 index 000000000..5459d79cc --- /dev/null +++ b/glamor/glamor_utils.c @@ -0,0 +1,82 @@ +/* + * Copyright © 2014 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "glamor_priv.h" + +void +glamor_solid_boxes(PixmapPtr pixmap, + BoxPtr box, int nbox, unsigned long fg_pixel) +{ + DrawablePtr drawable = &pixmap->drawable; + GCPtr gc; + xRectangle *rect; + int n; + + rect = malloc(nbox * sizeof (xRectangle)); + if (!rect) + return; + for (n = 0; n < nbox; n++) { + rect[n].x = box[n].x1; + rect[n].y = box[n].y1; + rect[n].width = box[n].x2 - box[n].x1; + rect[n].height = box[n].y2 - box[n].y1; + } + + gc = GetScratchGC(drawable->depth, drawable->pScreen); + if (gc) { + ChangeGCVal vals[1]; + + vals[0].val = fg_pixel; + ChangeGC(NullClient, gc, GCForeground, vals); + ValidateGC(drawable, gc); + gc->ops->PolyFillRect(drawable, gc, nbox, rect); + FreeScratchGC(gc); + } + free(rect); +} + +void +glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, + unsigned long fg_pixel) +{ + DrawablePtr drawable = &pixmap->drawable; + GCPtr gc; + ChangeGCVal vals[3]; + xRectangle rect; + + vals[0].val = alu; + vals[1].val = planemask; + vals[2].val = fg_pixel; + gc = GetScratchGC(drawable->depth, drawable->pScreen); + if (!gc) + return; + ChangeGC(NullClient, gc, GCFunction|GCPlaneMask|GCForeground, vals); + ValidateGC(drawable, gc); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + gc->ops->PolyFillRect(drawable, gc, 1, &rect); + FreeScratchGC(gc); +} + From ef2bf0e645ed8242a0b637ed6a9d5b8c03b6b481 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 21 Mar 2014 14:30:33 -0700 Subject: [PATCH 14/34] glamor: Remove 'tiling' shader code The core rendering paths all use the glamor_program fill functions now Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/Makefile.am | 1 - glamor/glamor.c | 2 - glamor/glamor_priv.h | 12 -- glamor/glamor_tile.c | 293 ------------------------------------------- 4 files changed, 308 deletions(-) delete mode 100644 glamor/glamor_tile.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 30fcef101..b24863885 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -32,7 +32,6 @@ libglamor_la_SOURCES = \ glamor_transform.c \ glamor_transform.h \ glamor_trapezoid.c \ - glamor_tile.c \ glamor_triangles.c\ glamor_addtraps.c\ glamor_glyphblt.c\ diff --git a/glamor/glamor.c b/glamor/glamor.c index 689188108..9fb9c67ce 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -514,7 +514,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_init_vbo(screen); glamor_init_pixmap_fbo(screen); - glamor_init_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_init_trapezoid_shader(screen); #endif @@ -546,7 +545,6 @@ glamor_release_screen_priv(ScreenPtr screen) #endif glamor_fini_vbo(screen); glamor_fini_pixmap_fbo(screen); - glamor_fini_tile_shader(screen); #ifdef GLAMOR_TRAPEZOID_SHADER glamor_fini_trapezoid_shader(screen); #endif diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 187a9b5a8..6cb074ef2 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -273,10 +273,6 @@ typedef struct glamor_screen_private { GLint finish_access_revert[2]; GLint finish_access_swap_rb[2]; - /* glamor_tile */ - GLint tile_prog; - GLint tile_wh; - /* glamor gradient, 0 for small nstops, 1 for large nstops and 2 for dynamic generate. */ GLint gradient_prog[SHADER_GRADIENT_COUNT][3]; @@ -760,14 +756,6 @@ void glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps); -/* glamor_tile.c */ -Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, - int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - int tile_x, int tile_y); -void glamor_init_tile_shader(ScreenPtr screen); -void glamor_fini_tile_shader(ScreenPtr screen); - /* glamor_gradient.c */ void glamor_init_gradient_shader(ScreenPtr screen); void glamor_fini_gradient_shader(ScreenPtr screen); diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c deleted file mode 100644 index 4e479763e..000000000 --- a/glamor/glamor_tile.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * 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 - * Zhigang Gong - * - */ - -#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; - const char *tile_vs = - "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord0;\n" - "varying vec2 tile_texture;\n" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - " tile_texture = v_texcoord0.xy;\n" - "}\n"; - const char *tile_fs = - GLAMOR_DEFAULT_PRECISION - "varying vec2 tile_texture;\n" - "uniform sampler2D sampler;\n" - "uniform vec2 wh;" - "void main()\n" - "{\n" - " vec2 rel_tex;" - " rel_tex = tile_texture * wh; \n" - " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n" - " gl_FragColor = texture2D(sampler, rel_tex);\n" - "}\n"; - GLint fs_prog, vs_prog; - GLint sampler_uniform_location; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - 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); - - glBindAttribLocation(glamor_priv->tile_prog, - GLAMOR_VERTEX_POS, "v_position"); - glBindAttribLocation(glamor_priv->tile_prog, - GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(screen, glamor_priv->tile_prog, "tile"); - - sampler_uniform_location = - glGetUniformLocation(glamor_priv->tile_prog, "sampler"); - glUseProgram(glamor_priv->tile_prog); - glUniform1i(sampler_uniform_location, 0); - - glamor_priv->tile_wh = - glGetUniformLocation(glamor_priv->tile_prog, "wh"); -} - -void -glamor_fini_tile_shader(ScreenPtr screen) -{ - glamor_screen_private *glamor_priv; - - glamor_priv = glamor_get_screen_private(screen); - glamor_make_current(glamor_priv); - glDeleteProgram(glamor_priv->tile_prog); -} - -static void -_glamor_tile(PixmapPtr pixmap, PixmapPtr tile, - int x, int y, int width, int height, 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; - int tile_x2 = tile_x + width; - int tile_y1 = tile_y; - int tile_y2 = tile_y + height; - 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; - float wh[4]; - - src_pixmap_priv = glamor_get_pixmap_private(tile); - dst_pixmap_priv = glamor_get_pixmap_private(pixmap); - - glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); - pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); - pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); - glamor_make_current(glamor_priv); - glUseProgram(glamor_priv->tile_prog); - - glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv); - glUniform2fv(glamor_priv->tile_wh, 1, wh); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->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); - glamor_set_repeat_normalize_tcoords - (src_pixmap_priv, RepeatNormal, - 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, - 2 * sizeof(float), source_texcoords); - glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - - glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale, - x1, y1, - x2, y2, glamor_priv->yInverted, vertices); - - glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, - 2 * sizeof(float), vertices); - glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; -} - -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) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_pixmap_private *dst_pixmap_priv; - glamor_pixmap_private *src_pixmap_priv; - - dst_pixmap_priv = glamor_get_pixmap_private(pixmap); - src_pixmap_priv = glamor_get_pixmap_private(tile); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) - return FALSE; - - if (glamor_priv->tile_prog == 0) { - glamor_fallback("Tiling unsupported\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_make_current(glamor_priv); - if (!glamor_set_alu(screen, alu)) { - glamor_fallback("unsupported alu %x\n", alu); - goto fail; - } - - if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE - || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - glamor_pixmap_clipped_regions *clipped_dst_regions; - int n_dst_region, i, j, k; - BoxRec box; - RegionRec region; - - box.x1 = x; - box.y1 = y; - box.x2 = x + width; - box.y2 = y + height; - RegionInitBoxes(®ion, &box, 1); - clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv, - ®ion, - &n_dst_region, 0, - 0, 0); - for (i = 0; i < n_dst_region; i++) { - int n_src_region; - glamor_pixmap_clipped_regions *clipped_src_regions; - BoxPtr current_boxes; - int n_current_boxes; - - SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, - clipped_dst_regions[i].block_idx); - - if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - RegionTranslate(clipped_dst_regions[i].region, - tile_x - x, tile_y - y); - DEBUGF("tiled a large src pixmap. %dx%d \n", - tile->drawable.width, tile->drawable.height); - clipped_src_regions = - glamor_compute_clipped_regions(src_pixmap_priv, - clipped_dst_regions[i]. - region, &n_src_region, 1, 0, - 0); - DEBUGF("got %d src regions %d \n", n_src_region); - for (j = 0; j < n_src_region; j++) { - - SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, - clipped_src_regions[j].block_idx); - - RegionTranslate(clipped_src_regions[j].region, - x - tile_x, y - tile_y); - current_boxes = RegionRects(clipped_src_regions[j].region); - n_current_boxes = - RegionNumRects(clipped_src_regions[j].region); - for (k = 0; k < n_current_boxes; k++) { - DEBUGF - ("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n", - current_boxes[k].x1, current_boxes[k].y1, - current_boxes[k].x2 - current_boxes[k].x1, - current_boxes[k].y2 - current_boxes[k].y1, - clipped_dst_regions[i].block_idx, - clipped_src_regions[j].block_idx, - (tile_x + (current_boxes[k].x1 - x)), - tile_y + (current_boxes[k].y1 - y)); - - _glamor_tile(pixmap, tile, - current_boxes[k].x1, current_boxes[k].y1, - current_boxes[k].x2 - current_boxes[k].x1, - current_boxes[k].y2 - current_boxes[k].y1, - (tile_x + (current_boxes[k].x1 - x)), - (tile_y + (current_boxes[k].y1 - y))); - } - - RegionDestroy(clipped_src_regions[j].region); - } - free(clipped_src_regions); - } - else { - current_boxes = RegionRects(clipped_dst_regions[i].region); - n_current_boxes = RegionNumRects(clipped_dst_regions[i].region); - for (k = 0; k < n_current_boxes; k++) { - _glamor_tile(pixmap, tile, - current_boxes[k].x1, current_boxes[k].y1, - current_boxes[k].x2 - current_boxes[k].x1, - current_boxes[k].y2 - current_boxes[k].y1, - (tile_x + (current_boxes[k].x1 - x)), - (tile_y + (current_boxes[k].y1 - y))); - } - } - RegionDestroy(clipped_dst_regions[i].region); - } - free(clipped_dst_regions); - RegionUninit(®ion); - } - else - _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y); - - glamor_set_alu(screen, GXcopy); - return TRUE; - fail: - return FALSE; - -} From a6aaa51752f301de24abce264976ba3c3a50863c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 21 Mar 2014 14:55:47 -0700 Subject: [PATCH 15/34] glamor: Remove stubbed-out glamor_stipple function This function isn't used anymore. Signed-off-by: Keith Packard Reviewed-by: Eric Anholt --- glamor/glamor_core.c | 11 ----------- glamor/glamor_priv.h | 5 ----- 2 files changed, 16 deletions(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index bafc42052..737b2744b 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -292,17 +292,6 @@ glamor_fini_finish_access_shaders(ScreenPtr screen) glDeleteProgram(glamor_priv->finish_access_prog[1]); } -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) -{ - 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, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 6cb074ef2..f2e92600e 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -648,11 +648,6 @@ void glamor_fini_finish_access_shaders(ScreenPtr screen); const Bool glamor_get_drawable_location(const DrawablePtr drawable); void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y); -Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, - int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - unsigned long fg_pixel, unsigned long bg_pixel, - int stipple_x, int stipple_y); GLint glamor_compile_glsl_prog(GLenum type, const char *source); void glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4); From 1d90e8811a7d4db328c0c944bec0aa3ed6afb70d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Dec 2013 21:34:44 -0800 Subject: [PATCH 16/34] xorg: Remove duplicated definitions of some XV-related structs. These were field-for-field identical, so we can just typedef them to be the same, and memcpy their contents. v2: Fix missed strdup(). Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- hw/xfree86/common/xf86xv.c | 53 +++++++++----------------------------- hw/xfree86/common/xf86xv.h | 36 ++------------------------ 2 files changed, 14 insertions(+), 75 deletions(-) diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c index b16cb5df3..e212a7387 100644 --- a/hw/xfree86/common/xf86xv.c +++ b/hw/xfree86/common/xf86xv.c @@ -359,15 +359,11 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number) XvPortRecPrivatePtr portPriv; XvPortPtr pPort, pp; int numPort; - XF86AttributePtr attributePtr; - XvAttributePtr pAttribute, pat; XF86VideoFormatPtr formatPtr; XvFormatPtr pFormat, pf; int numFormat, totFormat; XF86VideoEncodingPtr encodingPtr; XvEncodingPtr pEncode, pe; - XF86ImagePtr imagePtr; - XvImagePtr pImage, pi; int numVisuals; VisualPtr pVisual; int i; @@ -445,49 +441,24 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number) } if (adaptorPtr->nImages && - (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) { - - for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages; - i < adaptorPtr->nImages; i++, pi++, imagePtr++) { - pi->id = imagePtr->id; - pi->type = imagePtr->type; - pi->byte_order = imagePtr->byte_order; - memcpy(pi->guid, imagePtr->guid, 16); - pi->bits_per_pixel = imagePtr->bits_per_pixel; - pi->format = imagePtr->format; - pi->num_planes = imagePtr->num_planes; - pi->depth = imagePtr->depth; - pi->red_mask = imagePtr->red_mask; - pi->green_mask = imagePtr->green_mask; - pi->blue_mask = imagePtr->blue_mask; - pi->y_sample_bits = imagePtr->y_sample_bits; - pi->u_sample_bits = imagePtr->u_sample_bits; - pi->v_sample_bits = imagePtr->v_sample_bits; - pi->horz_y_period = imagePtr->horz_y_period; - pi->horz_u_period = imagePtr->horz_u_period; - pi->horz_v_period = imagePtr->horz_v_period; - pi->vert_y_period = imagePtr->vert_y_period; - pi->vert_u_period = imagePtr->vert_u_period; - pi->vert_v_period = imagePtr->vert_v_period; - memcpy(pi->component_order, imagePtr->component_order, 32); - pi->scanline_order = imagePtr->scanline_order; - } + (pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) { + memcpy(pa->pImages, adaptorPtr->pImages, + adaptorPtr->nImages * sizeof(XvImageRec)); pa->nImages = adaptorPtr->nImages; - pa->pImages = pImage; } if (adaptorPtr->nAttributes && - (pAttribute = - calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) { - for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = - 0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) { - pat->flags = attributePtr->flags; - pat->min_value = attributePtr->min_value; - pat->max_value = attributePtr->max_value; - pat->name = strdup(attributePtr->name); + (pa->pAttributes = calloc(adaptorPtr->nAttributes, + sizeof(XvAttributeRec)))) { + memcpy(pa->pAttributes, adaptorPtr->pAttributes, + adaptorPtr->nAttributes * sizeof(XvAttributeRec)); + + for (i = 0; i < adaptorPtr->nAttributes; i++) { + pa->pAttributes[i].name = + strdup(adaptorPtr->pAttributes[i].name); } + pa->nAttributes = adaptorPtr->nAttributes; - pa->pAttributes = pAttribute; } totFormat = adaptorPtr->nFormats; diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h index 8986e2e57..de17eb133 100644 --- a/hw/xfree86/common/xf86xv.h +++ b/hw/xfree86/common/xf86xv.h @@ -42,34 +42,7 @@ */ #define VIDEO_CLIP_TO_VIEWPORT 0x00000010 -typedef struct { - int id; - int type; - int byte_order; - unsigned char guid[16]; - int bits_per_pixel; - int format; - int num_planes; - - /* for RGB formats only */ - int depth; - unsigned int red_mask; - unsigned int green_mask; - unsigned int blue_mask; - - /* for YUV formats only */ - unsigned int y_sample_bits; - unsigned int u_sample_bits; - unsigned int v_sample_bits; - unsigned int horz_y_period; - unsigned int horz_u_period; - unsigned int horz_v_period; - unsigned int vert_y_period; - unsigned int vert_u_period; - unsigned int vert_v_period; - char component_order[32]; - int scanline_order; -} XF86ImageRec, *XF86ImagePtr; +typedef XvImageRec XF86ImageRec, *XF86ImagePtr; typedef struct { ScrnInfoPtr pScrn; @@ -147,12 +120,7 @@ typedef struct { short class; } XF86VideoFormatRec, *XF86VideoFormatPtr; -typedef struct { - int flags; - int min_value; - int max_value; - const char *name; -} XF86AttributeRec, *XF86AttributePtr; +typedef XvAttributeRec XF86AttributeRec, *XF86AttributePtr; typedef struct { unsigned int type; From 0edc0a78fbfac4578b0f809aef17332c1eb461e3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 6 Apr 2014 08:12:35 +0100 Subject: [PATCH 17/34] kdrive: Do a little more cleanup from the XV struct deduplication. Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- hw/kdrive/ephyr/ephyrvideo.c | 10 +++++----- hw/kdrive/src/kxv.c | 30 ++++++++++++------------------ hw/kdrive/src/kxv.h | 8 ++------ 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c index c6728351f..160c9658b 100644 --- a/hw/kdrive/ephyr/ephyrvideo.c +++ b/hw/kdrive/ephyr/ephyrvideo.c @@ -69,7 +69,7 @@ static Bool ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this); static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen); -static Bool ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs, +static Bool ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs, int a_attrs_len, const char *a_attr_name, int a_attr_value, Bool *a_is_valid); @@ -363,7 +363,7 @@ translate_xv_attributes(KdVideoAdaptorPtr adaptor, it = xcb_xv_query_port_attributes_attributes_iterator(reply); for (i = 0; i < reply->num_attributes; i++) { - KdAttributePtr attribute = &adaptor->pAttributes[i]; + XvAttributePtr attribute = &adaptor->pAttributes[i]; attribute->flags = it.data->flags; attribute->min_value = it.data->min; @@ -397,7 +397,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor, return FALSE; adaptor->nImages = reply->num_formats; - adaptor->pImages = calloc(reply->num_formats, sizeof(KdImageRec)); + adaptor->pImages = calloc(reply->num_formats, sizeof(XvImageRec)); if (!adaptor->pImages) { free(reply); return FALSE; @@ -405,7 +405,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor, formats = xcb_xv_list_image_formats_format(reply); for (i = 0; i < reply->num_formats; i++) { - KdImagePtr image = &adaptor->pImages[i]; + XvImagePtr image = &adaptor->pImages[i]; image->id = formats[i].id; image->type = formats[i].type; @@ -655,7 +655,7 @@ ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen) } static Bool -ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs, +ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs, int a_attrs_len, const char *a_attr_name, int a_attr_value, Bool *a_is_valid) diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c index 9cc0edd8a..508577034 100644 --- a/hw/kdrive/src/kxv.c +++ b/hw/kdrive/src/kxv.c @@ -295,15 +295,11 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number) XvPortRecPrivatePtr portPriv; XvPortPtr pPort, pp; int numPort; - KdAttributePtr attributePtr; - XvAttributePtr pAttribute, pat; KdVideoFormatPtr formatPtr; XvFormatPtr pFormat, pf; int numFormat, totFormat; KdVideoEncodingPtr encodingPtr; XvEncodingPtr pEncode, pe; - KdImagePtr imagePtr; - XvImagePtr pImage, pi; int numVisuals; VisualPtr pVisual; int i; @@ -381,26 +377,24 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number) } if (adaptorPtr->nImages && - (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) { - - for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages; - i < adaptorPtr->nImages; i++, pi++, imagePtr++) { - memcpy(pi, imagePtr, sizeof(*pi)); - } + (pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) { + memcpy(pa->pImages, adaptorPtr->pImages, + adaptorPtr->nImages * sizeof(XvImageRec)); pa->nImages = adaptorPtr->nImages; - pa->pImages = pImage; } if (adaptorPtr->nAttributes && - (pAttribute = - calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) { - for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = - 0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) { - memcpy(pat, attributePtr, sizeof(*pat)); - pat->name = strdup(attributePtr->name); + (pa->pAttributes = calloc(adaptorPtr->nAttributes, + sizeof(XvAttributeRec)))) { + memcpy(pa->pAttributes, adaptorPtr->pAttributes, + adaptorPtr->nAttributes * sizeof(XvAttributeRec)); + + for (i = 0; i < adaptorPtr->nAttributes; i++) { + pa->pAttributes[i].name = + strdup(adaptorPtr->pAttributes[i].name); } + pa->nAttributes = adaptorPtr->nAttributes; - pa->pAttributes = pAttribute; } totFormat = adaptorPtr->nFormats; diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h index 85a030ee9..f479de131 100644 --- a/hw/kdrive/src/kxv.h +++ b/hw/kdrive/src/kxv.h @@ -56,8 +56,6 @@ of the copyright holder. #define VIDEO_OVERLAID_STILLS 0x00000008 #define VIDEO_CLIP_TO_VIEWPORT 0x00000010 -typedef XvImageRec KdImageRec, *KdImagePtr; - typedef struct { KdScreenInfo *screen; int id; @@ -131,8 +129,6 @@ typedef struct { short class; } KdVideoFormatRec, *KdVideoFormatPtr; -typedef XvAttributeRec KdAttributeRec, *KdAttributePtr; - typedef struct { unsigned int type; int flags; @@ -144,9 +140,9 @@ typedef struct { int nPorts; DevUnion *pPortPrivates; int nAttributes; - KdAttributePtr pAttributes; + XvAttributePtr pAttributes; int nImages; - KdImagePtr pImages; + XvImagePtr pImages; PutVideoFuncPtr PutVideo; PutStillFuncPtr PutStill; GetVideoFuncPtr GetVideo; From 55aad7399d4470bc46c064aafe07d12a6c293982 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 4 Apr 2014 12:09:01 +0100 Subject: [PATCH 18/34] kdrive: Remove dead generic XV adaptors code. I couldn't find any callers in the history of the tree. Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- hw/kdrive/ephyr/ephyrvideo.c | 6 +---- hw/kdrive/src/kxv.c | 43 ------------------------------------ hw/kdrive/src/kxv.h | 9 -------- 3 files changed, 1 insertion(+), 57 deletions(-) diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c index 160c9658b..4c9d13afb 100644 --- a/hw/kdrive/ephyr/ephyrvideo.c +++ b/hw/kdrive/ephyr/ephyrvideo.c @@ -612,8 +612,6 @@ ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this) static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen) { - KdScreenPriv(a_screen); - KdScreenInfo *screen = pScreenPriv->screen; Bool is_ok = FALSE; KdVideoAdaptorPtr *adaptors = NULL, *registered_adaptors = NULL; int num_registered_adaptors = 0, i = 0, num_adaptors = 0; @@ -624,10 +622,8 @@ ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen) if (!a_this->num_adaptors) goto out; - num_registered_adaptors = - KdXVListGenericAdaptors(screen, ®istered_adaptors); - num_adaptors = num_registered_adaptors + a_this->num_adaptors; + num_adaptors = a_this->num_adaptors; adaptors = calloc(num_adaptors, sizeof(KdVideoAdaptorPtr)); if (!adaptors) { EPHYR_LOG_ERROR("failed to allocate adaptors tab\n"); diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c index 508577034..d1c453058 100644 --- a/hw/kdrive/src/kxv.c +++ b/hw/kdrive/src/kxv.c @@ -116,49 +116,6 @@ static unsigned long PortResource = 0; #define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \ dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey)) -static KdXVInitGenericAdaptorPtr *GenDrivers = NULL; -static int NumGenDrivers = 0; - -int -KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc) -{ - KdXVInitGenericAdaptorPtr *newdrivers; - -/* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */ - - newdrivers = realloc(GenDrivers, sizeof(KdXVInitGenericAdaptorPtr) * - (1 + NumGenDrivers)); - if (!newdrivers) - return 0; - GenDrivers = newdrivers; - - GenDrivers[NumGenDrivers++] = InitFunc; - - return 1; -} - -int -KdXVListGenericAdaptors(KdScreenInfo * screen, KdVideoAdaptorPtr ** adaptors) -{ - int i, j, n, num; - KdVideoAdaptorPtr *DrivAdap, *new; - - num = 0; - *adaptors = NULL; - for (i = 0; i < NumGenDrivers; i++) { - n = GenDrivers[i] (screen, &DrivAdap); - if (0 == n) - continue; - new = realloc(*adaptors, sizeof(KdVideoAdaptorPtr) * (num + n)); - if (NULL == new) - continue; - *adaptors = new; - for (j = 0; j < n; j++, num++) - (*adaptors)[num] = DrivAdap[j]; - } - return num; -} - KdVideoAdaptorPtr KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen) { diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h index f479de131..13efcbd79 100644 --- a/hw/kdrive/src/kxv.h +++ b/hw/kdrive/src/kxv.h @@ -159,15 +159,6 @@ typedef struct { Bool KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * Adaptors, int num); -typedef int (*KdXVInitGenericAdaptorPtr) (KdScreenInfo * screen, - KdVideoAdaptorPtr ** Adaptors); - -int - KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc); - -int - KdXVListGenericAdaptors(KdScreenInfo * screen, KdVideoAdaptorPtr ** Adaptors); - void KdXVCopyPackedData(KdScreenInfo * screen, CARD8 *src, CARD8 *dst, int randr, From a5662193f1c3dd63f615d96d1a300f70086ccbc6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 5 Apr 2014 12:26:33 +0100 Subject: [PATCH 19/34] kdrive: Simplify the adaptor setup interface. Now that we don't have to worry about the generic adaptors code, there's no need to have a list of pointers to different sets of adaptors. Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- hw/kdrive/ephyr/ephyrvideo.c | 20 ++------------------ hw/kdrive/src/kxv.c | 8 ++++---- hw/kdrive/src/kxv.h | 2 +- 3 files changed, 7 insertions(+), 23 deletions(-) diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c index 4c9d13afb..ab18c7afa 100644 --- a/hw/kdrive/ephyr/ephyrvideo.c +++ b/hw/kdrive/ephyr/ephyrvideo.c @@ -613,8 +613,6 @@ static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen) { Bool is_ok = FALSE; - KdVideoAdaptorPtr *adaptors = NULL, *registered_adaptors = NULL; - int num_registered_adaptors = 0, i = 0, num_adaptors = 0; EPHYR_RETURN_VAL_IF_FAIL(a_this && a_screen, FALSE); @@ -623,28 +621,14 @@ ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen) if (!a_this->num_adaptors) goto out; - num_adaptors = a_this->num_adaptors; - adaptors = calloc(num_adaptors, sizeof(KdVideoAdaptorPtr)); - if (!adaptors) { - EPHYR_LOG_ERROR("failed to allocate adaptors tab\n"); - goto out; - } - memmove(adaptors, registered_adaptors, num_registered_adaptors); - for (i = 0; i < a_this->num_adaptors; i++) { - *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i]; - } - if (!KdXVScreenInit(a_screen, adaptors, num_adaptors)) { + if (!KdXVScreenInit(a_screen, a_this->adaptors, a_this->num_adaptors)) { EPHYR_LOG_ERROR("failed to register adaptors\n"); goto out; } - EPHYR_LOG("there are %d registered adaptors\n", num_adaptors); + EPHYR_LOG("there are %d registered adaptors\n", a_this->num_adaptors); is_ok = TRUE; out: - free(registered_adaptors); - registered_adaptors = NULL; - free(adaptors); - adaptors = NULL; EPHYR_LOG("leave\n"); return is_ok; diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c index d1c453058..60a83458c 100644 --- a/hw/kdrive/src/kxv.c +++ b/hw/kdrive/src/kxv.c @@ -98,7 +98,7 @@ static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2); static void KdXVClipNotify(WindowPtr pWin, int dx, int dy); /* misc */ -static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr *, int); +static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr, int); static DevPrivateKeyRec KdXVWindowKeyRec; @@ -129,7 +129,7 @@ KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr) } Bool -KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * adaptors, int num) +KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr adaptors, int num) { KdXVScreenPtr ScreenPriv; XvScreenPtr pxvs; @@ -239,7 +239,7 @@ KdXVFreeAdaptor(XvAdaptorPtr pAdaptor) } static Bool -KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number) +KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number) { KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; @@ -268,7 +268,7 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number) return FALSE; for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) { - adaptorPtr = infoPtr[na]; + adaptorPtr = &infoPtr[na]; if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute || !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize) diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h index 13efcbd79..e50615b2d 100644 --- a/hw/kdrive/src/kxv.h +++ b/hw/kdrive/src/kxv.h @@ -157,7 +157,7 @@ typedef struct { } KdVideoAdaptorRec, *KdVideoAdaptorPtr; Bool - KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * Adaptors, int num); + KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr Adaptors, int num); void From 65efc14b6ae1ee73bf6db379d7826b6bc9fd6d33 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 5 Apr 2014 11:50:51 +0100 Subject: [PATCH 20/34] glamor: Split the XV code into XF86-dependent parts and generic. I want to expose this from Xephyr as well, both to be able to test XV changes rapidly, and beause the XV passthrough to the host's overlay really doesn't work out well when we glXSwapBuffers() over the colorkey. Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- glamor/Makefile.am | 1 + glamor/glamor_priv.h | 19 +- glamor/glamor_xv.c | 335 +++++-------------------- hw/xfree86/glamor_egl/Makefile.am | 3 +- hw/xfree86/glamor_egl/glamor_xf86_xv.c | 287 +++++++++++++++++++++ 5 files changed, 374 insertions(+), 271 deletions(-) create mode 100644 hw/xfree86/glamor_egl/glamor_xf86_xv.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index b24863885..334d8fc20 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -46,6 +46,7 @@ libglamor_la_SOURCES = \ glamor_compositerects.c\ glamor_utils.c\ glamor_utils.h\ + glamor_xv.c \ glamor.h libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index f2e92600e..a0b1062d7 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -31,6 +31,7 @@ #include #include "glamor.h" +#include "xvdix.h" #include #if GLAMOR_HAS_GBM @@ -1053,8 +1054,22 @@ typedef struct { int src_pix_w, src_pix_h; } glamor_port_private; -void glamor_init_xv_shader(ScreenPtr screen); -void glamor_fini_xv_shader(ScreenPtr screen); +extern XvAttributeRec glamor_xv_attributes[]; +extern int glamor_xv_num_attributes; +extern XvImageRec glamor_xv_images[]; +extern int glamor_xv_num_images; + +void glamor_xv_init_port(glamor_port_private *port_priv); +void glamor_xv_stop_video(glamor_port_private *port_priv); +int glamor_xv_set_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 value); +int glamor_xv_get_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 *value); +int glamor_xv_query_image_attributes(int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets); +void glamor_xv_core_init(ScreenPtr screen); +void glamor_xv_render(glamor_port_private *port_priv); #include"glamor_utils.h" diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index 369b02b61..4aaa866c5 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -36,12 +36,10 @@ #include #endif -#include "xf86xv.h" -#define GLAMOR_FOR_XORG #include "glamor_priv.h" #include -#include "fourcc.h" +#include "../hw/xfree86/common/fourcc.h" /* Reference color space transform data */ typedef struct tagREF_TRANSFORM { float RefLuma; @@ -90,7 +88,28 @@ static const char *xv_ps = GLAMOR_DEFAULT_PRECISION "gl_FragColor = temp1;\n" "}\n"; -void +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +XvAttributeRec glamor_xv_attributes[] = { + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_BRIGHTNESS"}, + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_CONTRAST"}, + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_SATURATION"}, + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_HUE"}, + {XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE"}, + {0, 0, 0, NULL} +}; +int glamor_xv_num_attributes = ARRAY_SIZE(glamor_xv_attributes) - 1; + +Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue, + glamorColorspace, glamorGamma; + +XvImageRec glamor_xv_images[] = { + XVIMAGE_YV12, + XVIMAGE_I420, +}; +int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images); + +static void glamor_init_xv_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv; @@ -113,43 +132,12 @@ glamor_init_xv_shader(ScreenPtr screen) } #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) -#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) -static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace, - xvGamma; - -#define NUM_ATTRIBUTES 5 -static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES + 1] = { - {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, - {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"}, - {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}, - {XvSettable | XvGettable, -1000, 1000, "XV_HUE"}, - {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"}, - {0, 0, 0, NULL} -}; - -#define NUM_FORMATS 3 - -static XF86VideoFormatRec Formats[NUM_FORMATS] = { - {15, TrueColor}, {16, TrueColor}, {24, TrueColor} -}; - -#define NUM_IMAGES 2 - -static XF86ImageRec Images[NUM_IMAGES] = { - XVIMAGE_YV12, - XVIMAGE_I420, -}; - -static void -glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup) +void +glamor_xv_stop_video(glamor_port_private *port_priv) { - glamor_port_private *port_priv = (glamor_port_private *) data; int i; - if (!cleanup) - return; - for (i = 0; i < 3; i++) { if (port_priv->src_pix[i]) { glamor_destroy_pixmap(port_priv->src_pix[i]); @@ -158,46 +146,42 @@ glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup) } } -static int -glamor_xv_set_port_attribute(ScrnInfoPtr pScrn, - Atom attribute, INT32 value, void *data) +int +glamor_xv_set_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 value) { - glamor_port_private *port_priv = (glamor_port_private *) data; - - if (attribute == xvBrightness) + if (attribute == glamorBrightness) port_priv->brightness = ClipValue(value, -1000, 1000); - else if (attribute == xvHue) + else if (attribute == glamorHue) port_priv->hue = ClipValue(value, -1000, 1000); - else if (attribute == xvContrast) + else if (attribute == glamorContrast) port_priv->contrast = ClipValue(value, -1000, 1000); - else if (attribute == xvSaturation) + else if (attribute == glamorSaturation) port_priv->saturation = ClipValue(value, -1000, 1000); - else if (attribute == xvGamma) + else if (attribute == glamorGamma) port_priv->gamma = ClipValue(value, 100, 10000); - else if (attribute == xvColorspace) + else if (attribute == glamorColorspace) port_priv->transform_index = ClipValue(value, 0, 1); else return BadMatch; return Success; } -static int -glamor_xv_get_port_attribute(ScrnInfoPtr pScrn, - Atom attribute, INT32 *value, void *data) +int +glamor_xv_get_port_attribute(glamor_port_private *port_priv, + Atom attribute, INT32 *value) { - glamor_port_private *port_priv = (glamor_port_private *) data; - - if (attribute == xvBrightness) + if (attribute == glamorBrightness) *value = port_priv->brightness; - else if (attribute == xvHue) + else if (attribute == glamorHue) *value = port_priv->hue; - else if (attribute == xvContrast) + else if (attribute == glamorContrast) *value = port_priv->contrast; - else if (attribute == xvSaturation) + else if (attribute == glamorSaturation) *value = port_priv->saturation; - else if (attribute == xvGamma) + else if (attribute == glamorGamma) *value = port_priv->gamma; - else if (attribute == xvColorspace) + else if (attribute == glamorColorspace) *value = port_priv->transform_index; else return BadMatch; @@ -205,20 +189,8 @@ glamor_xv_get_port_attribute(ScrnInfoPtr pScrn, return Success; } -static void -glamor_xv_query_best_size(ScrnInfoPtr pScrn, - Bool motion, - short vid_w, short vid_h, - short drw_w, short drw_h, - unsigned int *p_w, unsigned int *p_h, void *data) -{ - *p_w = drw_w; - *p_h = drw_h; -} - -static int -glamor_xv_query_image_attributes(ScrnInfoPtr pScrn, - int id, +int +glamor_xv_query_image_attributes(int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) { @@ -258,8 +230,8 @@ static REF_TRANSFORM trans[2] = { {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */ }; -static void -glamor_display_textured_video(glamor_port_private *port_priv) +void +glamor_xv_render(glamor_port_private *port_priv) { ScreenPtr screen = port_priv->pPixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -282,6 +254,9 @@ glamor_display_textured_video(glamor_port_private *port_priv) int ref = port_priv->transform_index; GLint uloc, sampler_loc; + if (!glamor_priv->xv_prog) + glamor_init_xv_shader(screen); + cont = RTFContrast(port_priv->contrast); bright = RTFBrightness(port_priv->brightness); gamma = (float) port_priv->gamma / 1000.0; @@ -405,202 +380,26 @@ glamor_display_textured_video(glamor_port_private *port_priv) DamageDamageRegion(port_priv->pDraw, &port_priv->clip); } -static int -glamor_xv_put_image(ScrnInfoPtr pScrn, - short src_x, short src_y, - short drw_x, short drw_y, - short src_w, short src_h, - short drw_w, short drw_h, - int id, - unsigned char *buf, - short width, - short height, - Bool sync, - RegionPtr clipBoxes, void *data, DrawablePtr pDrawable) +void +glamor_xv_init_port(glamor_port_private *port_priv) { - ScreenPtr screen = pDrawable->pScreen; - glamor_port_private *port_priv = (glamor_port_private *) data; - INT32 x1, x2, y1, y2; - int srcPitch, srcPitch2; - BoxRec dstBox; - int top, nlines; - int s2offset, s3offset, tmp; + port_priv->brightness = 0; + port_priv->contrast = 0; + port_priv->saturation = 0; + port_priv->hue = 0; + port_priv->gamma = 1000; + port_priv->transform_index = 0; - s2offset = s3offset = srcPitch2 = 0; - - /* Clip */ - x1 = src_x; - x2 = src_x + src_w; - y1 = src_y; - y2 = src_y + src_h; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - if (!xf86XVClipVideoHelper - (&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height)) - return Success; - - if ((x1 >= x2) || (y1 >= y2)) - return Success; - - srcPitch = width; - srcPitch2 = width >> 1; - - if (!port_priv->src_pix[0] || - (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { - int i; - - for (i = 0; i < 3; i++) - if (port_priv->src_pix[i]) - glamor_destroy_pixmap(port_priv->src_pix[i]); - - port_priv->src_pix[0] = - glamor_create_pixmap(screen, width, height, 8, 0); - port_priv->src_pix[1] = - glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); - port_priv->src_pix[2] = - glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); - port_priv->src_pix_w = width; - port_priv->src_pix_h = height; - - if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || - !port_priv->src_pix[2]) - return BadAlloc; - } - - top = (y1 >> 16) & ~1; - nlines = ((y2 + 0xffff) >> 16) - top; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - s2offset = srcPitch * height; - s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); - s2offset += ((top >> 1) * srcPitch2); - s3offset += ((top >> 1) * srcPitch2); - if (id == FOURCC_YV12) { - tmp = s2offset; - s2offset = s3offset; - s3offset = tmp; - } - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0], - 0, 0, srcPitch, nlines, - port_priv->src_pix[0]->devKind, - buf + (top * srcPitch), 0); - - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1], - 0, 0, srcPitch2, (nlines + 1) >> 1, - port_priv->src_pix[1]->devKind, - buf + s2offset, 0); - - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2], - 0, 0, srcPitch2, (nlines + 1) >> 1, - port_priv->src_pix[2]->devKind, - buf + s3offset, 0); - break; - default: - return BadMatch; - } - - if (pDrawable->type == DRAWABLE_WINDOW) - port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable); - else - port_priv->pPixmap = (PixmapPtr) pDrawable; - - if (!RegionEqual(&port_priv->clip, clipBoxes)) { - RegionCopy(&port_priv->clip, clipBoxes); - } - - port_priv->src_x = src_x; - port_priv->src_y = src_y; - port_priv->src_w = src_w; - port_priv->src_h = src_h; - port_priv->dst_w = drw_w; - port_priv->dst_h = drw_h; - port_priv->drw_x = drw_x; - port_priv->drw_y = drw_y; - port_priv->w = width; - port_priv->h = height; - port_priv->pDraw = pDrawable; - glamor_display_textured_video(port_priv); - return Success; + REGION_NULL(pScreen, &port_priv->clip); } -static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = { - { - 0, - "XV_IMAGE", - 8192, 8192, - {1, 1} - } -}; - -XF86VideoAdaptorPtr -glamor_xv_init(ScreenPtr screen, int num_texture_ports) +void +glamor_xv_core_init(ScreenPtr screen) { - glamor_port_private *port_priv; - XF86VideoAdaptorPtr adapt; - int i; - - glamor_init_xv_shader(screen); - - adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports * - (sizeof(glamor_port_private) + sizeof(DevUnion))); - if (adapt == NULL) - return NULL; - - xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); - xvContrast = MAKE_ATOM("XV_CONTRAST"); - xvSaturation = MAKE_ATOM("XV_SATURATION"); - xvHue = MAKE_ATOM("XV_HUE"); - xvGamma = MAKE_ATOM("XV_GAMMA"); - xvColorspace = MAKE_ATOM("XV_COLORSPACE"); - - adapt->type = XvWindowMask | XvInputMask | XvImageMask; - adapt->flags = 0; - adapt->name = "GLAMOR Textured Video"; - adapt->nEncodings = 1; - adapt->pEncodings = DummyEncodingGLAMOR; - - adapt->nFormats = NUM_FORMATS; - adapt->pFormats = Formats; - adapt->nPorts = num_texture_ports; - adapt->pPortPrivates = (DevUnion *) (&adapt[1]); - - adapt->pAttributes = Attributes_glamor; - adapt->nAttributes = NUM_ATTRIBUTES; - - port_priv = - (glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]); - adapt->pImages = Images; - adapt->nImages = NUM_IMAGES; - adapt->PutVideo = NULL; - adapt->PutStill = NULL; - adapt->GetVideo = NULL; - adapt->GetStill = NULL; - adapt->StopVideo = glamor_xv_stop_video; - adapt->SetPortAttribute = glamor_xv_set_port_attribute; - adapt->GetPortAttribute = glamor_xv_get_port_attribute; - adapt->QueryBestSize = glamor_xv_query_best_size; - adapt->PutImage = glamor_xv_put_image; - adapt->ReputImage = NULL; - adapt->QueryImageAttributes = glamor_xv_query_image_attributes; - - for (i = 0; i < num_texture_ports; i++) { - glamor_port_private *pPriv = &port_priv[i]; - - pPriv->brightness = 0; - pPriv->contrast = 0; - pPriv->saturation = 0; - pPriv->hue = 0; - pPriv->gamma = 1000; - pPriv->transform_index = 0; - - REGION_NULL(pScreen, &pPriv->clip); - - adapt->pPortPrivates[i].ptr = (void *) (pPriv); - } - return adapt; + glamorBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + glamorContrast = MAKE_ATOM("XV_CONTRAST"); + glamorSaturation = MAKE_ATOM("XV_SATURATION"); + glamorHue = MAKE_ATOM("XV_HUE"); + glamorGamma = MAKE_ATOM("XV_GAMMA"); + glamorColorspace = MAKE_ATOM("XV_COLORSPACE"); } diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am index 85e1c0c06..e697c8296 100644 --- a/hw/xfree86/glamor_egl/Makefile.am +++ b/hw/xfree86/glamor_egl/Makefile.am @@ -24,7 +24,7 @@ module_LTLIBRARIES = libglamoregl.la libglamoregl_la_SOURCES = \ $(top_srcdir)/glamor/glamor_egl.c \ $(top_srcdir)/glamor/glamor_eglmodule.c \ - $(top_srcdir)/glamor/glamor_xv.c \ + glamor_xf86_xv.c \ $() libglamoregl_la_LDFLAGS = \ @@ -38,6 +38,7 @@ libglamoregl_la_LIBADD = \ AM_CPPFLAGS = $(XORG_INCS) \ -I$(top_srcdir)/dri3 \ + -I$(top_srcdir)/glamor \ $() AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS) diff --git a/hw/xfree86/glamor_egl/glamor_xf86_xv.c b/hw/xfree86/glamor_egl/glamor_xf86_xv.c new file mode 100644 index 000000000..a54c9a937 --- /dev/null +++ b/hw/xfree86/glamor_egl/glamor_xf86_xv.c @@ -0,0 +1,287 @@ +/* + * Copyright © 2013 Red Hat + * + * 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 + * + * some code is derived from the xf86-video-ati radeon driver, mainly + * the calculations. + */ + +/** @file glamor_xf86_xv.c + * + * This implements the XF86 XV interface, and calls into glamor core + * for its support of the suspiciously similar XF86 and Kdrive + * device-dependent XV interfaces. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#define GLAMOR_FOR_XORG +#include "glamor_priv.h" + +#include +#include "fourcc.h" + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = { + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +static void +glamor_xf86_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup) +{ + if (!cleanup) + return; + + glamor_xv_stop_video(data); +} + +static int +glamor_xf86_xv_set_port_attribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 value, void *data) +{ + return glamor_xv_set_port_attribute(data, attribute, value); +} + +static int +glamor_xf86_xv_get_port_attribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 *value, void *data) +{ + return glamor_xv_get_port_attribute(data, attribute, value); +} + +static void +glamor_xf86_xv_query_best_size(ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, void *data) +{ + *p_w = drw_w; + *p_h = drw_h; +} + +static int +glamor_xf86_xv_query_image_attributes(ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) +{ + return glamor_xv_query_image_attributes(id, w, h, pitches, offsets); +} + +static int +glamor_xf86_xv_put_image(ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes, void *data, DrawablePtr pDrawable) +{ + ScreenPtr screen = pDrawable->pScreen; + glamor_port_private *port_priv = (glamor_port_private *) data; + INT32 x1, x2, y1, y2; + int srcPitch, srcPitch2; + BoxRec dstBox; + int top, nlines; + int s2offset, s3offset, tmp; + + s2offset = s3offset = srcPitch2 = 0; + + /* Clip */ + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + if (!xf86XVClipVideoHelper + (&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height)) + return Success; + + if ((x1 >= x2) || (y1 >= y2)) + return Success; + + srcPitch = width; + srcPitch2 = width >> 1; + + if (!port_priv->src_pix[0] || + (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { + int i; + + for (i = 0; i < 3; i++) + if (port_priv->src_pix[i]) + glamor_destroy_pixmap(port_priv->src_pix[i]); + + port_priv->src_pix[0] = + glamor_create_pixmap(screen, width, height, 8, 0); + port_priv->src_pix[1] = + glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix[2] = + glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix_w = width; + port_priv->src_pix_h = height; + + if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || + !port_priv->src_pix[2]) + return BadAlloc; + } + + top = (y1 >> 16) & ~1; + nlines = ((y2 + 0xffff) >> 16) - top; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + s2offset = srcPitch * height; + s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); + s2offset += ((top >> 1) * srcPitch2); + s3offset += ((top >> 1) * srcPitch2); + if (id == FOURCC_YV12) { + tmp = s2offset; + s2offset = s3offset; + s3offset = tmp; + } + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0], + 0, 0, srcPitch, nlines, + port_priv->src_pix[0]->devKind, + buf + (top * srcPitch), 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[1]->devKind, + buf + s2offset, 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[2]->devKind, + buf + s3offset, 0); + break; + default: + return BadMatch; + } + + if (pDrawable->type == DRAWABLE_WINDOW) + port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable); + else + port_priv->pPixmap = (PixmapPtr) pDrawable; + + if (!RegionEqual(&port_priv->clip, clipBoxes)) { + RegionCopy(&port_priv->clip, clipBoxes); + } + + port_priv->src_x = src_x; + port_priv->src_y = src_y; + port_priv->src_w = src_w; + port_priv->src_h = src_h; + port_priv->dst_w = drw_w; + port_priv->dst_h = drw_h; + port_priv->drw_x = drw_x; + port_priv->drw_y = drw_y; + port_priv->w = width; + port_priv->h = height; + port_priv->pDraw = pDrawable; + glamor_xv_render(port_priv); + return Success; +} + +static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = { + { + 0, + "XV_IMAGE", + 8192, 8192, + {1, 1} + } +}; + +XF86VideoAdaptorPtr +glamor_xv_init(ScreenPtr screen, int num_texture_ports) +{ + glamor_port_private *port_priv; + XF86VideoAdaptorPtr adapt; + int i; + + glamor_xv_core_init(screen); + + adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports * + (sizeof(glamor_port_private) + sizeof(DevUnion))); + if (adapt == NULL) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = 0; + adapt->name = "GLAMOR Textured Video"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncodingGLAMOR; + + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = num_texture_ports; + adapt->pPortPrivates = (DevUnion *) (&adapt[1]); + + adapt->pAttributes = glamor_xv_attributes; + adapt->nAttributes = glamor_xv_num_attributes; + + port_priv = + (glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]); + adapt->pImages = glamor_xv_images; + adapt->nImages = glamor_xv_num_images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = glamor_xf86_xv_stop_video; + adapt->SetPortAttribute = glamor_xf86_xv_set_port_attribute; + adapt->GetPortAttribute = glamor_xf86_xv_get_port_attribute; + adapt->QueryBestSize = glamor_xf86_xv_query_best_size; + adapt->PutImage = glamor_xf86_xv_put_image; + adapt->ReputImage = NULL; + adapt->QueryImageAttributes = glamor_xf86_xv_query_image_attributes; + + for (i = 0; i < num_texture_ports; i++) { + glamor_port_private *pPriv = &port_priv[i]; + + pPriv->brightness = 0; + pPriv->contrast = 0; + pPriv->saturation = 0; + pPriv->hue = 0; + pPriv->gamma = 1000; + pPriv->transform_index = 0; + + REGION_NULL(pScreen, &pPriv->clip); + + adapt->pPortPrivates[i].ptr = (void *) (pPriv); + } + return adapt; +} From 23d303bf905e76a70bda942037bdfbdcd06e55d2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 5 Apr 2014 12:57:16 +0100 Subject: [PATCH 21/34] kdrive: Mark XV names const to avoid warnings. No code modifies it at runtime, and it's common to store string literals to it. Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- hw/kdrive/src/kxv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h index e50615b2d..3a49a659f 100644 --- a/hw/kdrive/src/kxv.h +++ b/hw/kdrive/src/kxv.h @@ -119,7 +119,7 @@ typedef enum { typedef struct { int id; - char *name; + const char *name; unsigned short width, height; XvRationalRec rate; } KdVideoEncodingRec, *KdVideoEncodingPtr; @@ -132,7 +132,7 @@ typedef struct { typedef struct { unsigned int type; int flags; - char *name; + const char *name; int nEncodings; KdVideoEncodingPtr pEncodings; int nFormats; From 34884e16bf7c97434e7883d025c6814e083b0def Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 5 Apr 2014 12:30:28 +0100 Subject: [PATCH 22/34] ephyr: Add support for XV using glamor. Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- hw/kdrive/ephyr/Makefile.am | 5 + hw/kdrive/ephyr/ephyr.c | 4 +- hw/kdrive/ephyr/ephyr.h | 10 ++ hw/kdrive/ephyr/ephyr_glamor_xv.c | 244 ++++++++++++++++++++++++++++++ 4 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 hw/kdrive/ephyr/ephyr_glamor_xv.c diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 00a53d0df..10c59174f 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -35,9 +35,14 @@ XV_SRCS = ephyrvideo.c endif if GLAMOR +if XV +GLAMOR_XV_SRCS = ephyr_glamor_xv.c +endif + GLAMOR_SRCS = \ ephyr_glamor_glx.c \ ephyr_glamor_glx.h \ + $(GLAMOR_XV_SRCS) \ $() endif diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index def50d8d8..17a862ac4 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -650,7 +650,9 @@ ephyrInitScreen(ScreenPtr pScreen) #ifdef XV if (!ephyrNoXV) { - if (!ephyrInitVideo(pScreen)) { + if (ephyr_glamor) + ephyr_glamor_xv_init(pScreen); + else if (!ephyrInitVideo(pScreen)) { EPHYR_LOG_ERROR("failed to initialize xvideo\n"); } else { diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index 34ce4601b..609a641a5 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -221,4 +221,14 @@ void ephyr_glamor_host_paint_rect(ScreenPtr pScreen); Bool ephyrInitVideo(ScreenPtr pScreen); +/* ephyr_glamor_xv.c */ +#ifdef GLAMOR +void ephyr_glamor_xv_init(ScreenPtr screen); +#else /* !GLAMOR */ +static inline void +ephyr_glamor_xv_init(ScreenPtr screen) +{ +} +#endif /* !GLAMOR */ + #endif diff --git a/hw/kdrive/ephyr/ephyr_glamor_xv.c b/hw/kdrive/ephyr/ephyr_glamor_xv.c new file mode 100644 index 000000000..3fc97471c --- /dev/null +++ b/hw/kdrive/ephyr/ephyr_glamor_xv.c @@ -0,0 +1,244 @@ +/* + * Copyright © 2014 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. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "kdrive.h" +#include "kxv.h" +#include "ephyr.h" +#include "glamor_priv.h" + +#include +#include "fourcc.h" + +#define NUM_FORMATS 3 + +static KdVideoFormatRec Formats[NUM_FORMATS] = { + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +static void +ephyr_glamor_xv_stop_video(KdScreenInfo *screen, void *data, Bool cleanup) +{ + if (!cleanup) + return; + + glamor_xv_stop_video(data); +} + +static int +ephyr_glamor_xv_set_port_attribute(KdScreenInfo *screen, + Atom attribute, INT32 value, void *data) +{ + return glamor_xv_set_port_attribute(data, attribute, value); +} + +static int +ephyr_glamor_xv_get_port_attribute(KdScreenInfo *screen, + Atom attribute, INT32 *value, void *data) +{ + return glamor_xv_get_port_attribute(data, attribute, value); +} + +static void +ephyr_glamor_xv_query_best_size(KdScreenInfo *screen, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + void *data) +{ + *p_w = drw_w; + *p_h = drw_h; +} + +static int +ephyr_glamor_xv_query_image_attributes(KdScreenInfo *screen, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) +{ + return glamor_xv_query_image_attributes(id, w, h, pitches, offsets); +} + +static int +ephyr_glamor_xv_put_image(KdScreenInfo *screen, + DrawablePtr pDrawable, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes, void *data) +{ + ScreenPtr pScreen = pDrawable->pScreen; + glamor_port_private *port_priv = (glamor_port_private *) data; + int srcPitch, srcPitch2; + int top, nlines; + int s2offset, s3offset, tmp; + + s2offset = s3offset = srcPitch2 = 0; + + srcPitch = width; + srcPitch2 = width >> 1; + + if (!port_priv->src_pix[0] || + (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { + int i; + + for (i = 0; i < 3; i++) + if (port_priv->src_pix[i]) + glamor_destroy_pixmap(port_priv->src_pix[i]); + + port_priv->src_pix[0] = + glamor_create_pixmap(pScreen, width, height, 8, 0); + port_priv->src_pix[1] = + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix[2] = + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix_w = width; + port_priv->src_pix_h = height; + + if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || + !port_priv->src_pix[2]) + return BadAlloc; + } + + top = (src_y) & ~1; + nlines = (src_y + height) - top; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + s2offset = srcPitch * height; + s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); + s2offset += ((top >> 1) * srcPitch2); + s3offset += ((top >> 1) * srcPitch2); + if (id == FOURCC_YV12) { + tmp = s2offset; + s2offset = s3offset; + s3offset = tmp; + } + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0], + 0, 0, srcPitch, nlines, + port_priv->src_pix[0]->devKind, + buf + (top * srcPitch), 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[1]->devKind, + buf + s2offset, 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[2]->devKind, + buf + s3offset, 0); + break; + default: + return BadMatch; + } + + if (pDrawable->type == DRAWABLE_WINDOW) + port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable); + else + port_priv->pPixmap = (PixmapPtr) pDrawable; + + if (!RegionEqual(&port_priv->clip, clipBoxes)) { + RegionCopy(&port_priv->clip, clipBoxes); + } + + port_priv->src_x = src_x; + port_priv->src_y = src_y; + port_priv->src_w = src_w; + port_priv->src_h = src_h; + port_priv->dst_w = drw_w; + port_priv->dst_h = drw_h; + port_priv->drw_x = drw_x; + port_priv->drw_y = drw_y; + port_priv->w = width; + port_priv->h = height; + port_priv->pDraw = pDrawable; + glamor_xv_render(port_priv); + return Success; +} + +void +ephyr_glamor_xv_init(ScreenPtr screen) +{ + KdVideoAdaptorRec *adaptor; + glamor_port_private *port_privates; + KdVideoEncodingRec encoding = { + 0, + "XV_IMAGE", + /* These sizes should probably be GL_MAX_TEXTURE_SIZE instead + * of 2048, but our context isn't set up yet. + */ + 2048, 2048, + {1, 1} + }; + int i; + + glamor_xv_core_init(screen); + + adaptor = xnfcalloc(1, sizeof(*adaptor)); + + adaptor->name = "glamor textured video"; + adaptor->type = XvWindowMask | XvInputMask | XvImageMask; + adaptor->flags = 0; + adaptor->nEncodings = 1; + adaptor->pEncodings = &encoding; + + adaptor->pFormats = Formats; + adaptor->nFormats = NUM_FORMATS; + + adaptor->nPorts = 16; /* Some absurd number */ + port_privates = xnfcalloc(adaptor->nPorts, + sizeof(glamor_port_private)); + adaptor->pPortPrivates = xnfcalloc(adaptor->nPorts, + sizeof(glamor_port_private *)); + for (i = 0; i < adaptor->nPorts; i++) { + adaptor->pPortPrivates[i].ptr = &port_privates[i]; + glamor_xv_init_port(&port_privates[i]); + } + + adaptor->pAttributes = glamor_xv_attributes; + adaptor->nAttributes = glamor_xv_num_attributes; + + adaptor->pImages = glamor_xv_images; + adaptor->nImages = glamor_xv_num_images; + + adaptor->StopVideo = ephyr_glamor_xv_stop_video; + adaptor->SetPortAttribute = ephyr_glamor_xv_set_port_attribute; + adaptor->GetPortAttribute = ephyr_glamor_xv_get_port_attribute; + adaptor->QueryBestSize = ephyr_glamor_xv_query_best_size; + adaptor->PutImage = ephyr_glamor_xv_put_image; + adaptor->QueryImageAttributes = ephyr_glamor_xv_query_image_attributes; + + KdXVScreenInit(screen, adaptor, 1); +} From 98b6158bc1e32aaca375829452266e013a520e14 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 6 Apr 2014 07:44:20 +0100 Subject: [PATCH 23/34] glamor: Share code for put_image handling. The difference between the two is that XF86 has the clip helper that lets you upload less data when rendering video that's clipped. I don't think that's really worth the trouble, especially in a world of compositors, so I've dropped it to get to shared code. It turns out the clipping code was broken on xf86-video-intel anyway. To reproduce, run without a compositor, and use another window to clip the top half of your XV output on the glamor XV adaptor: the rendering got confused about which half of the window was being drawn to. Signed-off-by: Eric Anholt Reviewed-by: Adam Jackson --- glamor/glamor_priv.h | 12 +++ glamor/glamor_xv.c | 104 ++++++++++++++++++++++ hw/kdrive/ephyr/ephyr_glamor_xv.c | 95 ++------------------- hw/xfree86/glamor_egl/glamor_xf86_xv.c | 114 ++----------------------- 4 files changed, 128 insertions(+), 197 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index a0b1062d7..535d0ca08 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -1068,6 +1068,18 @@ int glamor_xv_get_port_attribute(glamor_port_private *port_priv, int glamor_xv_query_image_attributes(int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets); +int glamor_xv_put_image(glamor_port_private *port_priv, + DrawablePtr pDrawable, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes); void glamor_xv_core_init(ScreenPtr screen); void glamor_xv_render(glamor_port_private *port_priv); diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index 4aaa866c5..1e8bdb885 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -380,6 +380,110 @@ glamor_xv_render(glamor_port_private *port_priv) DamageDamageRegion(port_priv->pDraw, &port_priv->clip); } +int +glamor_xv_put_image(glamor_port_private *port_priv, + DrawablePtr pDrawable, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes) +{ + ScreenPtr pScreen = pDrawable->pScreen; + int srcPitch, srcPitch2; + int top, nlines; + int s2offset, s3offset, tmp; + + s2offset = s3offset = srcPitch2 = 0; + + srcPitch = width; + srcPitch2 = width >> 1; + + if (!port_priv->src_pix[0] || + (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { + int i; + + for (i = 0; i < 3; i++) + if (port_priv->src_pix[i]) + glamor_destroy_pixmap(port_priv->src_pix[i]); + + port_priv->src_pix[0] = + glamor_create_pixmap(pScreen, width, height, 8, 0); + port_priv->src_pix[1] = + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix[2] = + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix_w = width; + port_priv->src_pix_h = height; + + if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || + !port_priv->src_pix[2]) + return BadAlloc; + } + + top = (src_y) & ~1; + nlines = (src_y + height) - top; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + s2offset = srcPitch * height; + s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); + s2offset += ((top >> 1) * srcPitch2); + s3offset += ((top >> 1) * srcPitch2); + if (id == FOURCC_YV12) { + tmp = s2offset; + s2offset = s3offset; + s3offset = tmp; + } + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0], + 0, 0, srcPitch, nlines, + port_priv->src_pix[0]->devKind, + buf + (top * srcPitch), 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[1]->devKind, + buf + s2offset, 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[2]->devKind, + buf + s3offset, 0); + break; + default: + return BadMatch; + } + + if (pDrawable->type == DRAWABLE_WINDOW) + port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable); + else + port_priv->pPixmap = (PixmapPtr) pDrawable; + + if (!RegionEqual(&port_priv->clip, clipBoxes)) { + RegionCopy(&port_priv->clip, clipBoxes); + } + + port_priv->src_x = src_x; + port_priv->src_y = src_y; + port_priv->src_w = src_w; + port_priv->src_h = src_h; + port_priv->dst_w = drw_w; + port_priv->dst_h = drw_h; + port_priv->drw_x = drw_x; + port_priv->drw_y = drw_y; + port_priv->w = width; + port_priv->h = height; + port_priv->pDraw = pDrawable; + glamor_xv_render(port_priv); + return Success; +} + void glamor_xv_init_port(glamor_port_private *port_priv) { diff --git a/hw/kdrive/ephyr/ephyr_glamor_xv.c b/hw/kdrive/ephyr/ephyr_glamor_xv.c index 3fc97471c..b9c3464d8 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_xv.c +++ b/hw/kdrive/ephyr/ephyr_glamor_xv.c @@ -97,95 +97,12 @@ ephyr_glamor_xv_put_image(KdScreenInfo *screen, Bool sync, RegionPtr clipBoxes, void *data) { - ScreenPtr pScreen = pDrawable->pScreen; - glamor_port_private *port_priv = (glamor_port_private *) data; - int srcPitch, srcPitch2; - int top, nlines; - int s2offset, s3offset, tmp; - - s2offset = s3offset = srcPitch2 = 0; - - srcPitch = width; - srcPitch2 = width >> 1; - - if (!port_priv->src_pix[0] || - (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { - int i; - - for (i = 0; i < 3; i++) - if (port_priv->src_pix[i]) - glamor_destroy_pixmap(port_priv->src_pix[i]); - - port_priv->src_pix[0] = - glamor_create_pixmap(pScreen, width, height, 8, 0); - port_priv->src_pix[1] = - glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); - port_priv->src_pix[2] = - glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); - port_priv->src_pix_w = width; - port_priv->src_pix_h = height; - - if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || - !port_priv->src_pix[2]) - return BadAlloc; - } - - top = (src_y) & ~1; - nlines = (src_y + height) - top; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - s2offset = srcPitch * height; - s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); - s2offset += ((top >> 1) * srcPitch2); - s3offset += ((top >> 1) * srcPitch2); - if (id == FOURCC_YV12) { - tmp = s2offset; - s2offset = s3offset; - s3offset = tmp; - } - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0], - 0, 0, srcPitch, nlines, - port_priv->src_pix[0]->devKind, - buf + (top * srcPitch), 0); - - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1], - 0, 0, srcPitch2, (nlines + 1) >> 1, - port_priv->src_pix[1]->devKind, - buf + s2offset, 0); - - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2], - 0, 0, srcPitch2, (nlines + 1) >> 1, - port_priv->src_pix[2]->devKind, - buf + s3offset, 0); - break; - default: - return BadMatch; - } - - if (pDrawable->type == DRAWABLE_WINDOW) - port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable); - else - port_priv->pPixmap = (PixmapPtr) pDrawable; - - if (!RegionEqual(&port_priv->clip, clipBoxes)) { - RegionCopy(&port_priv->clip, clipBoxes); - } - - port_priv->src_x = src_x; - port_priv->src_y = src_y; - port_priv->src_w = src_w; - port_priv->src_h = src_h; - port_priv->dst_w = drw_w; - port_priv->dst_h = drw_h; - port_priv->drw_x = drw_x; - port_priv->drw_y = drw_y; - port_priv->w = width; - port_priv->h = height; - port_priv->pDraw = pDrawable; - glamor_xv_render(port_priv); - return Success; + return glamor_xv_put_image(data, pDrawable, + src_x, src_y, + drw_x, drw_y, + src_w, src_h, + drw_w, drw_h, + id, buf, width, height, sync, clipBoxes); } void diff --git a/hw/xfree86/glamor_egl/glamor_xf86_xv.c b/hw/xfree86/glamor_egl/glamor_xf86_xv.c index a54c9a937..8535fa0c9 100644 --- a/hw/xfree86/glamor_egl/glamor_xf86_xv.c +++ b/hw/xfree86/glamor_egl/glamor_xf86_xv.c @@ -106,114 +106,12 @@ glamor_xf86_xv_put_image(ScrnInfoPtr pScrn, Bool sync, RegionPtr clipBoxes, void *data, DrawablePtr pDrawable) { - ScreenPtr screen = pDrawable->pScreen; - glamor_port_private *port_priv = (glamor_port_private *) data; - INT32 x1, x2, y1, y2; - int srcPitch, srcPitch2; - BoxRec dstBox; - int top, nlines; - int s2offset, s3offset, tmp; - - s2offset = s3offset = srcPitch2 = 0; - - /* Clip */ - x1 = src_x; - x2 = src_x + src_w; - y1 = src_y; - y2 = src_y + src_h; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - if (!xf86XVClipVideoHelper - (&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height)) - return Success; - - if ((x1 >= x2) || (y1 >= y2)) - return Success; - - srcPitch = width; - srcPitch2 = width >> 1; - - if (!port_priv->src_pix[0] || - (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { - int i; - - for (i = 0; i < 3; i++) - if (port_priv->src_pix[i]) - glamor_destroy_pixmap(port_priv->src_pix[i]); - - port_priv->src_pix[0] = - glamor_create_pixmap(screen, width, height, 8, 0); - port_priv->src_pix[1] = - glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); - port_priv->src_pix[2] = - glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0); - port_priv->src_pix_w = width; - port_priv->src_pix_h = height; - - if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || - !port_priv->src_pix[2]) - return BadAlloc; - } - - top = (y1 >> 16) & ~1; - nlines = ((y2 + 0xffff) >> 16) - top; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - s2offset = srcPitch * height; - s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); - s2offset += ((top >> 1) * srcPitch2); - s3offset += ((top >> 1) * srcPitch2); - if (id == FOURCC_YV12) { - tmp = s2offset; - s2offset = s3offset; - s3offset = tmp; - } - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0], - 0, 0, srcPitch, nlines, - port_priv->src_pix[0]->devKind, - buf + (top * srcPitch), 0); - - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1], - 0, 0, srcPitch2, (nlines + 1) >> 1, - port_priv->src_pix[1]->devKind, - buf + s2offset, 0); - - glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2], - 0, 0, srcPitch2, (nlines + 1) >> 1, - port_priv->src_pix[2]->devKind, - buf + s3offset, 0); - break; - default: - return BadMatch; - } - - if (pDrawable->type == DRAWABLE_WINDOW) - port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable); - else - port_priv->pPixmap = (PixmapPtr) pDrawable; - - if (!RegionEqual(&port_priv->clip, clipBoxes)) { - RegionCopy(&port_priv->clip, clipBoxes); - } - - port_priv->src_x = src_x; - port_priv->src_y = src_y; - port_priv->src_w = src_w; - port_priv->src_h = src_h; - port_priv->dst_w = drw_w; - port_priv->dst_h = drw_h; - port_priv->drw_x = drw_x; - port_priv->drw_y = drw_y; - port_priv->w = width; - port_priv->h = height; - port_priv->pDraw = pDrawable; - glamor_xv_render(port_priv); - return Success; + return glamor_xv_put_image(data, pDrawable, + src_x, src_y, + drw_x, drw_y, + src_w, src_h, + drw_w, drw_h, + id, buf, width, height, sync, clipBoxes); } static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = { From 199d9a6a942af9b443616f6ef6d26052ef3f48b9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Dec 2013 11:12:27 -0800 Subject: [PATCH 24/34] xephyr: Allow initializing glamor with gles2 (on GLX). This should be useful for glamor development, so you can test both paths (which are significantly different, and apparently glamor_gradient.c was broken on GLES2 as of the import). Signed-off-by: Eric Anholt Reviewed-by: Keith Packard Reviewed-by: Adam Jackson --- hw/kdrive/ephyr/ephyr_glamor_glx.c | 24 +++++++++++++++++++++++- hw/kdrive/ephyr/ephyrinit.c | 12 +++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c index eaf565496..8fe751693 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_glx.c +++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -52,6 +52,7 @@ static Display *dpy; static XVisualInfo *visual_info; static GLXFBConfig fb_config; +Bool ephyr_glamor_gles2; /** @} */ /** @@ -145,6 +146,10 @@ ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor) "}\n"; const char *fs_source = + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "\n" "varying vec2 t;\n" "uniform sampler2D s; /* initially 0 */\n" "\n" @@ -276,7 +281,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win) glx_win = glXCreateWindow(dpy, fb_config, win, NULL); - ctx = glXCreateContext(dpy, visual_info, NULL, True); + if (ephyr_glamor_gles2) { + static const int context_attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 2, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT, + 0, + }; + if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy), + "GLX_EXT_create_context_es2_profile")) { + ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True, + context_attribs); + } else { + FatalError("Xephyr -glamor_gles2 rquires " + "GLX_EXT_create_context_es2_profile\n"); + } + } else { + ctx = glXCreateContext(dpy, visual_info, NULL, True); + } if (ctx == NULL) FatalError("glXCreateContext failed\n"); diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index fac84cd13..17f070dcb 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -35,7 +35,7 @@ extern Bool EphyrWantGrayScale; extern Bool EphyrWantResize; extern Bool kdHasPointer; extern Bool kdHasKbd; -extern Bool ephyr_glamor; +extern Bool ephyr_glamor, ephyr_glamor_gles2; #ifdef GLXEXT extern Bool ephyrNoDRI; @@ -138,6 +138,7 @@ ddxUseMsg(void) ErrorF("-resizeable Make Xephyr windows resizeable\n"); #ifdef GLAMOR ErrorF("-glamor Enable 2D acceleration using glamor\n"); + ErrorF("-glamor_gles2 Enable 2D acceleration using glamor (with GLES2 only)\n"); #endif ErrorF ("-fakexa Simulate acceleration using software rendering\n"); @@ -251,6 +252,15 @@ ddxProcessArgument(int argc, char **argv, int i) ephyrFuncs.finiAccel = ephyr_glamor_fini; return 1; } + else if (!strcmp (argv[i], "-glamor_gles2")) { + ephyr_glamor = TRUE; + ephyr_glamor_gles2 = TRUE; + ephyrFuncs.initAccel = ephyr_glamor_init; + ephyrFuncs.enableAccel = ephyr_glamor_enable; + ephyrFuncs.disableAccel = ephyr_glamor_disable; + ephyrFuncs.finiAccel = ephyr_glamor_fini; + return 1; + } #endif else if (!strcmp(argv[i], "-fakexa")) { ephyrFuncs.initAccel = ephyrDrawInit; From 2ab0fba9df695f19f0b43321d01395736f865c69 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 2 Apr 2014 13:41:09 -0700 Subject: [PATCH 25/34] glamor: Drop unnecessary glTexParameteri() in SetSpans(). If this path needed the filters set, so would all the other glDrawArrays() callers. But they don't. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_spans.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c index 46ba6c38f..582d11df3 100644 --- a/glamor/glamor_spans.c +++ b/glamor/glamor_spans.c @@ -326,9 +326,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src, glamor_make_current(glamor_priv); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glamor_pixmap_loop(pixmap_priv, box_x, box_y) { From 1140a89d7762540965ff865d154cb0528049066f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 2 Apr 2014 12:12:06 -0700 Subject: [PATCH 26/34] glamor: Use MIN/MAX macros to clean up glamor_transfer.c Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_transfer.c | 45 +++++++++------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c index ad875c962..4eea902ad 100644 --- a/glamor/glamor_transfer.c +++ b/glamor/glamor_transfer.c @@ -90,27 +90,14 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, while (nbox--) { /* compute drawable coordinates */ - int x1 = boxes->x1 + dx_dst; - int x2 = boxes->x2 + dx_dst; - int y1 = boxes->y1 + dy_dst; - int y2 = boxes->y2 + dy_dst; + int x1 = MAX(boxes->x1 + dx_dst, box->x1); + int x2 = MIN(boxes->x2 + dx_dst, box->x2); + int y1 = MAX(boxes->y1 + dy_dst, box->y1); + int y2 = MIN(boxes->y2 + dy_dst, box->y2); boxes++; - if (x1 < box->x1) - x1 = box->x1; - if (box->x2 < x2) - x2 = box->x2; - - if (x2 <= x1) - continue; - - if (y1 < box->y1) - y1 = box->y1; - if (box->y2 < y2) - y2 = box->y2; - - if (y2 <= y1) + if (x2 <= x1 || y2 <= y1) continue; glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src); @@ -195,26 +182,14 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, while (nbox--) { /* compute drawable coordinates */ - int x1 = boxes->x1 + dx_src; - int x2 = boxes->x2 + dx_src; - int y1 = boxes->y1 + dy_src; - int y2 = boxes->y2 + dy_src; + int x1 = MAX(boxes->x1 + dx_src, box->x1); + int x2 = MIN(boxes->x2 + dx_src, box->x2); + int y1 = MAX(boxes->y1 + dy_src, box->y1); + int y2 = MIN(boxes->y2 + dy_src, box->y2); boxes++; - if (x1 < box->x1) - x1 = box->x1; - if (box->x2 < x2) - x2 = box->x2; - - if (y1 < box->y1) - y1 = box->y1; - if (box->y2 < y2) - y2 = box->y2; - - if (x2 <= x1) - continue; - if (y2 <= y1) + if (x2 <= x1 || y2 <= y1) continue; glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst); From db9bff5c389f96991df8d6c62df1174e62e937d3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 2 Apr 2014 12:09:47 -0700 Subject: [PATCH 27/34] glamor: Drop unnecessary glTexParameteri() in upload of texture data. We're not drawing, and we're not initially setting up the texture for later drawing. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_transfer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c index 4eea902ad..891415565 100644 --- a/glamor/glamor_transfer.c +++ b/glamor/glamor_transfer.c @@ -72,9 +72,6 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, glamor_make_current(glamor_priv); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel); From d71ecbb458c15fda608654b78d99683ebeab3c60 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 6 Apr 2014 07:22:26 -0700 Subject: [PATCH 28/34] glamor: Drop constant arguments to glamor_solid(). After keithp's change to drop the old glamor_fill() code, nothing ever changed these values. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_glyphs.c | 4 ++-- glamor/glamor_priv.h | 1 - glamor/glamor_trapezoid.c | 3 +-- glamor/glamor_utils.c | 9 +++------ 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index ba7d342b9..f570d7519 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -168,7 +168,7 @@ clear_mask_cache(struct glamor_glyph_mask_cache *maskcache) struct glamor_glyph_mask_cache_entry *mce; glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE, - MASK_CACHE_MAX_SIZE, GXcopy, 0xFFFFFFFF, 0); + MASK_CACHE_MAX_SIZE, 0); mce = &maskcache->mcache[0]; while (cnt--) { mce->width = 0; @@ -1433,7 +1433,7 @@ glamor_glyphs_via_mask(CARD8 op, glamor_destroy_pixmap(mask_pixmap); return; } - glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0); + glamor_solid(mask_pixmap, 0, 0, width, height, 0); component_alpha = NeedsComponent(mask_format->format); mask = CreatePicture(0, &mask_pixmap->drawable, mask_format, CPComponentAlpha, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 535d0ca08..670cdd344 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -1025,7 +1025,6 @@ void glamor_composite_rectangles(CARD8 op, /* glamor_util.c */ void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, unsigned long fg_pixel); void diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c index 4ad067240..cdf5fa247 100644 --- a/glamor/glamor_trapezoid.c +++ b/glamor/glamor_trapezoid.c @@ -1393,8 +1393,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, /* First, clear all to zero */ glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width, - pixmap_priv->base.pixmap->drawable.height, - GXclear, 0xFFFFFFFF, 0); + pixmap_priv->base.pixmap->drawable.height, 0); glamor_make_current(glamor_priv); diff --git a/glamor/glamor_utils.c b/glamor/glamor_utils.c index 5459d79cc..f06896096 100644 --- a/glamor/glamor_utils.c +++ b/glamor/glamor_utils.c @@ -56,21 +56,18 @@ glamor_solid_boxes(PixmapPtr pixmap, void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, unsigned long fg_pixel) { DrawablePtr drawable = &pixmap->drawable; GCPtr gc; - ChangeGCVal vals[3]; + ChangeGCVal vals[1]; xRectangle rect; - vals[0].val = alu; - vals[1].val = planemask; - vals[2].val = fg_pixel; + vals[0].val = fg_pixel; gc = GetScratchGC(drawable->depth, drawable->pScreen); if (!gc) return; - ChangeGC(NullClient, gc, GCFunction|GCPlaneMask|GCForeground, vals); + ChangeGC(NullClient, gc, GCForeground, vals); ValidateGC(drawable, gc); rect.x = x; rect.y = y; From e310387f443b6333edf02c8980daa303505382b4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 12 Jan 2014 10:19:10 -0800 Subject: [PATCH 29/34] glamor: Remove always-true yInverted flag. All users of glamor had the same value set, and it complicated things for no reason. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor.c | 5 - glamor/glamor.h | 8 +- glamor/glamor_gradient.c | 19 ++-- glamor/glamor_pixmap.c | 77 +++----------- glamor/glamor_priv.h | 1 - glamor/glamor_render.c | 13 +-- glamor/glamor_trapezoid.c | 14 +-- glamor/glamor_utils.h | 216 ++++++++++++-------------------------- glamor/glamor_xv.c | 4 +- hw/kdrive/ephyr/hostx.c | 3 +- 10 files changed, 104 insertions(+), 256 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 9fb9c67ce..5e6003df6 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -328,11 +328,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) return FALSE; glamor_priv->flags = flags; - if (flags & GLAMOR_INVERTED_Y_AXIS) { - glamor_priv->yInverted = TRUE; - } - else - glamor_priv->yInverted = FALSE; if (!dixRegisterPrivateKey(&glamor_screen_private_key, PRIVATE_SCREEN, 0)) { LogMessage(X_WARNING, diff --git a/glamor/glamor.h b/glamor/glamor.h index 2cdb1d431..405dbe8ed 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -63,7 +63,7 @@ typedef enum glamor_pixmap_type { } glamor_pixmap_type_t; #define GLAMOR_EGL_EXTERNAL_BUFFER 3 -#define GLAMOR_INVERTED_Y_AXIS 1 +#define GLAMOR_INVERTED_Y_AXIS 1 /* compat stub */ #define GLAMOR_USE_SCREEN (1 << 1) #define GLAMOR_USE_PICTURE_SCREEN (1 << 2) #define GLAMOR_USE_EGL_SCREEN (1 << 3) @@ -79,12 +79,6 @@ typedef enum glamor_pixmap_type { * @screen: Current screen pointer. * @flags: Please refer the flags description above. * - * @GLAMOR_INVERTED_Y_AXIS: - * set 1 means the GL env's origin (0,0) is at top-left. - * EGL/DRM platform is an example need to set this bit. - * glx platform's origin is at bottom-left thus need to - * clear this bit. - * * @GLAMOR_USE_SCREEN: * If running in an pre-existing X environment, and the * gl context is GLX, then you should set this bit and diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c index 28d66917f..4ded89dcd 100644 --- a/glamor/glamor_gradient.c +++ b/glamor/glamor_gradient.c @@ -699,7 +699,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, width), (INT16) (dst_picture->pDrawable-> height), - glamor_priv->yInverted, vertices); + vertices); if (tex_normalize) { glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale, @@ -710,17 +710,14 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen, (INT16) (dst_picture-> pDrawable->height + y_source), - glamor_priv->yInverted, tex_vertices); } else { - glamor_set_tcoords_tri_strip((INT16) (dst_picture->pDrawable->width), - (INT16) (dst_picture->pDrawable->height), - x_source, y_source, + glamor_set_tcoords_tri_strip(x_source, y_source, (INT16) (dst_picture->pDrawable->width) + x_source, (INT16) (dst_picture->pDrawable->height) + - y_source, glamor_priv->yInverted, + y_source, tex_vertices); } @@ -1084,13 +1081,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2. radius); - glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted, - cxy); + glamor_set_circle_centre(width, height, c1x, c1y, cxy); glUniform2fv(c1_uniform_location, 1, cxy); glUniform1f(r1_uniform_location, r1); - glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted, - cxy); + glamor_set_circle_centre(width, height, c2x, c2y, cxy); glUniform2fv(c2_uniform_location, 1, cxy); glUniform1f(r2_uniform_location, r2); @@ -1322,7 +1317,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, linear.p1.x), pixman_fixed_to_double(src_picture->pSourcePict-> linear.p1.y), - glamor_priv->yInverted, pt1); + pt1); DEBUGF("pt1:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x), pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y), @@ -1333,7 +1328,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, linear.p2.x), pixman_fixed_to_double(src_picture->pSourcePict-> linear.p2.y), - glamor_priv->yInverted, pt2); + pt2); DEBUGF("pt2:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x), pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y), diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 54b414bc2..8dbeb2220 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -746,11 +746,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, glamor_get_screen_private(pixmap->drawable.pScreen); static float vertices[8]; - static float texcoords[8] = { 0, 1, - 1, 1, - 1, 0, - 0, 0 - }; static float texcoords_inv[8] = { 0, 0, 1, 0, 1, 1, @@ -759,11 +754,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, float *ptexcoords; float dst_xscale, dst_yscale; GLuint tex = 0; - int need_flip; int need_free_bits = 0; - need_flip = !glamor_priv->yInverted; - if (bits == NULL) goto ready_to_upload; @@ -797,7 +789,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, /* Try fast path firstly, upload the pixmap to the texture attached * to the fbo directly. */ if (no_alpha == 0 - && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING && !need_flip + && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING #ifdef WALKAROUND_LARGE_TEXTURE_MAP && pixmap_priv->type != GLAMOR_TEXTURE_LARGE #endif @@ -817,17 +809,14 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, return TRUE; } - if (need_flip) - ptexcoords = texcoords; - else - ptexcoords = texcoords_inv; + ptexcoords = texcoords_inv; pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale); glamor_set_normalize_vcoords(pixmap_priv, dst_xscale, dst_yscale, x, y, x + w, y + h, - glamor_priv->yInverted, vertices); + vertices); /* Slow path, we need to flip y or wire alpha to 1. */ glamor_make_current(glamor_priv); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, @@ -864,10 +853,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, /* * Prepare to upload a pixmap to texture memory. * 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. no_alpha != 0, we need to wire the alpha. - * */ + */ static int glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int revert, int swap_rb) @@ -895,8 +881,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, return 0; if (!(no_alpha || (revert == REVERT_NORMAL) - || (swap_rb != SWAP_NONE_UPLOADING) - || !glamor_priv->yInverted)) { + || (swap_rb != SWAP_NONE_UPLOADING))) { /* We don't need a fbo, a simple texture uploading should work. */ flag = GLAMOR_CREATE_FBO_NO_FBO; @@ -1141,7 +1126,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL, temp_xscale, temp_yscale, 0, 0, w, h, - glamor_priv->yInverted, vertices); + vertices); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); @@ -1152,7 +1137,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, source_yscale, x, y, x + w, y + h, - glamor_priv->yInverted, texcoords); + texcoords); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); @@ -1190,7 +1175,7 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format, { glamor_pixmap_private *pixmap_priv; GLenum gl_access = 0, gl_usage = 0; - void *data, *read; + void *data; glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); glamor_pixmap_fbo *temp_fbo = NULL; @@ -1252,46 +1237,17 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format, glPixelStorei(GL_PACK_ALIGNMENT, 4); - 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); - } - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) { - assert(pbo > 0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); - glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, gl_usage); - } - - glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data); - - if (!glamor_priv->yInverted) { - assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - glPixelStorei(GL_PACK_INVERT_MESA, 0); - } - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) { - bits = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - } + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) { + assert(pbo > 0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); + glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, gl_usage); } - else { - unsigned int temp_pbo; - int yy; - glamor_make_current(glamor_priv); - glGenBuffers(1, &temp_pbo); - glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo); - glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, GL_STREAM_READ); - glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, 0); - read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - for (yy = 0; yy < pixmap->drawable.height; yy++) - memcpy((char *) data + yy * stride, - (char *) read + (h - yy - 1) * stride, stride); - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data); + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) { + bits = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - glDeleteBuffers(1, &temp_pbo); } glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1461,7 +1417,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) stride = pixmap->devKind; if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted) || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { data = malloc(stride * pixmap->drawable.height); } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 670cdd344..144cbfd7a 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -200,7 +200,6 @@ struct glamor_saved_procs { #define RENDER_IDEL_MAX 32 typedef struct glamor_screen_private { - Bool yInverted; unsigned int tick; enum glamor_gl_flavor gl_flavor; int glsl_version; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6da38da32..add376f11 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -793,30 +793,29 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv, float *matrix, float xscale, float yscale, int x1, int y1, int x2, int y2, - int yInverted, float *texcoords, + float *texcoords, int stride) { if (!matrix && repeat_type == RepeatNone) glamor_set_normalize_tcoords_ext(priv, xscale, yscale, x1, y1, - x2, y2, yInverted, texcoords, stride); + x2, y2, texcoords, stride); else if (matrix && repeat_type == RepeatNone) glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, yscale, x1, y1, x2, y2, - yInverted, texcoords, stride); else if (!matrix && repeat_type != RepeatNone) glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, xscale, yscale, x1, y1, x2, y2, - yInverted, texcoords, stride); + texcoords, stride); else if (matrix && repeat_type != RepeatNone) glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type, matrix, xscale, yscale, x1, y1, x2, - y2, yInverted, + y2, texcoords, stride); } @@ -1266,7 +1265,7 @@ glamor_composite_with_shader(CARD8 op, glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale, dst_yscale, x_dest, y_dest, x_dest + width, y_dest + height, - glamor_priv->yInverted, vertices, + vertices, vb_stride); vertices += 2; if (key.source != SHADER_SOURCE_SOLID) { @@ -1276,7 +1275,6 @@ glamor_composite_with_shader(CARD8 op, src_yscale, x_source, y_source, x_source + width, y_source + height, - glamor_priv->yInverted, vertices, vb_stride); vertices += 2; } @@ -1288,7 +1286,6 @@ glamor_composite_with_shader(CARD8 op, mask_yscale, x_mask, y_mask, x_mask + width, y_mask + height, - glamor_priv->yInverted, vertices, vb_stride); vertices += 2; } diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c index cdf5fa247..d61d11f79 100644 --- a/glamor/glamor_trapezoid.c +++ b/glamor/glamor_trapezoid.c @@ -908,7 +908,6 @@ _glamor_trapezoids_with_shader(CARD8 op, clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1]; glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale, clipped_vtx_tmp, - glamor_priv->yInverted, vertices); DEBUGF("vertices of triangle: (%f X %f), (%f X %f), " "(%f X %f)\n", vertices[0], vertices[1], @@ -920,14 +919,12 @@ _glamor_trapezoids_with_shader(CARD8 op, glamor_set_transformed_normalize_tri_tcoords (source_pixmap_priv, src_matrix, src_xscale, src_yscale, clipped_vtx_tmp, - glamor_priv->yInverted, source_texcoords); + source_texcoords); } else { glamor_set_normalize_tri_tcoords(src_xscale, src_yscale, clipped_vtx_tmp, - glamor_priv-> - yInverted, source_texcoords); } @@ -1439,11 +1436,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, miTrapezoidBounds(1, ptrap, &one_trap_bound); vertices += 2; - glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width), - (pixmap_priv->base.pixmap->drawable.height), - (one_trap_bound.x1), (one_trap_bound.y1), + glamor_set_tcoords_ext((one_trap_bound.x1), (one_trap_bound.y1), (one_trap_bound.x2), (one_trap_bound.y2), - glamor_priv->yInverted, vertices, stride); + vertices, stride); DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0], vertices[1], vertices[1 * stride], vertices[1 * stride + 1], @@ -1463,8 +1458,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, one_trap_bound.y1, one_trap_bound.x2, one_trap_bound.y2, - glamor_priv->yInverted, vertices, - stride); + vertices, stride); DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0], vertices[1], vertices[1 * stride], vertices[1 * stride + 1], diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index 5a568f1c2..c15d17ca3 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -313,21 +313,17 @@ } while(0) #define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \ - texcoord, yInverted) \ + texcoord) \ do { \ (texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \ - if (_X_LIKELY(yInverted)) \ - (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\ - else \ - (texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \ DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \ (texcoord)[1]); \ } while(0) #define glamor_set_transformed_point(priv, matrix, xscale, \ yscale, texcoord, \ - x, y, \ - yInverted) \ + x, y) \ do { \ float tx, ty; \ int fbo_x_off, fbo_y_off; \ @@ -339,10 +335,7 @@ tx += fbo_x_off; \ ty += fbo_y_off; \ (texcoord)[0] = t_from_x_coord_x(xscale, tx); \ - if (_X_LIKELY(yInverted)) \ - (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ - else \ - (texcoord)[1] = t_from_x_coord_y(yscale, ty); \ + (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \ DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \ } while(0) @@ -351,18 +344,14 @@ xscale, \ yscale, \ vtx, \ - yInverted, \ texcoords) \ do { \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords, (vtx)[0], (vtx)[1], \ - yInverted); \ + texcoords, (vtx)[0], (vtx)[1]); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords+2, (vtx)[2], (vtx)[3], \ - yInverted); \ + texcoords+2, (vtx)[2], (vtx)[3]); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords+4, (vtx)[4], (vtx)[5], \ - yInverted); \ + texcoords+4, (vtx)[4], (vtx)[5]); \ } while (0) #define glamor_set_transformed_normalize_tcoords_ext( priv, \ @@ -370,21 +359,17 @@ xscale, \ yscale, \ tx1, ty1, tx2, ty2, \ - yInverted, texcoords, \ + texcoords, \ stride) \ do { \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords, tx1, ty1, \ - yInverted); \ + texcoords, tx1, ty1); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords + 1 * stride, tx2, ty1, \ - yInverted); \ + texcoords + 1 * stride, tx2, ty1); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords + 2 * stride, tx2, ty2, \ - yInverted); \ + texcoords + 2 * stride, tx2, ty2); \ glamor_set_transformed_point(priv, matrix, xscale, yscale, \ - texcoords + 3 * stride, tx1, ty2, \ - yInverted); \ + texcoords + 3 * stride, tx1, ty2); \ } while (0) #define glamor_set_transformed_normalize_tcoords( priv, \ @@ -392,35 +377,31 @@ xscale, \ yscale, \ tx1, ty1, tx2, ty2, \ - yInverted, texcoords) \ + texcoords) \ do { \ glamor_set_transformed_normalize_tcoords_ext( priv, \ matrix, \ xscale, \ yscale, \ tx1, ty1, tx2, ty2, \ - yInverted, texcoords, \ + texcoords, \ 2); \ } while (0) #define glamor_set_normalize_tri_tcoords(xscale, \ yscale, \ vtx, \ - yInverted, \ texcoords) \ do { \ _glamor_set_normalize_tpoint(xscale, yscale, \ (vtx)[0], (vtx)[1], \ - texcoords, \ - yInverted); \ + texcoords); \ _glamor_set_normalize_tpoint(xscale, yscale, \ (vtx)[2], (vtx)[3], \ - texcoords+2, \ - yInverted); \ + texcoords+2); \ _glamor_set_normalize_tpoint(xscale, yscale, \ (vtx)[4], (vtx)[5], \ - texcoords+4, \ - yInverted); \ + texcoords+4); \ } while (0) #define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \ @@ -430,14 +411,13 @@ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ - yInverted, \ texcoords, \ stride) \ do { \ if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \ glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \ yscale, _x1_, _y1_, \ - _x2_, _y2_, yInverted, \ + _x2_, _y2_, \ texcoords, stride); \ } else { \ float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \ @@ -464,13 +444,13 @@ DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \ ttx2, tty2, ttx3, tty3, ttx4, tty4); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \ - texcoords, yInverted); \ + texcoords); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \ - texcoords + 1 * stride, yInverted); \ + texcoords + 1 * stride); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \ - texcoords + 2 * stride, yInverted); \ + texcoords + 2 * stride); \ _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \ - texcoords + 3 * stride, yInverted); \ + texcoords + 3 * stride); \ } \ } while (0) @@ -481,7 +461,6 @@ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ - yInverted, \ texcoords) \ do { \ glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \ @@ -491,14 +470,13 @@ yscale, \ _x1_, _y1_, \ _x2_, _y2_, \ - yInverted, \ texcoords, \ 2); \ } while (0) #define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \ ty1, tx2, ty2, \ - yInverted, vertices, stride) \ + vertices, stride) \ do { \ /* vertices may be write-only, so we use following \ * temporary variable. */ \ @@ -507,21 +485,15 @@ (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \ - (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\ - } \ - else { \ - (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \ - (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);\ - } \ + (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \ + (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) #define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, stride) \ + vertices, stride) \ do { \ if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \ float tx1, tx2, ty1, ty2; \ @@ -532,26 +504,26 @@ ty1 = y1 + fbo_y_off; \ ty2 = y2 + fbo_y_off; \ _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ - tx2, ty2, yInverted, vertices, \ + tx2, ty2, vertices, \ stride); \ } else \ _glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \ - x2, y2, yInverted, vertices, stride);\ + x2, y2, vertices, stride); \ } while(0) #define glamor_set_normalize_tcoords(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, 2); \ + vertices, 2); \ } while(0) #define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ - yInverted, vertices, stride)\ + vertices, stride) \ do { \ if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \ float tx1, tx2, ty1, ty2; \ @@ -566,130 +538,99 @@ _x1_, _y1_, _x2_, _y2_); \ } \ _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ - tx2, ty2, yInverted, vertices, \ + tx2, ty2, vertices, \ stride); \ } else \ _glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \ - _x2_, _y2_, yInverted, vertices, \ + _x2_, _y2_, vertices, \ stride); \ } while(0) #define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ - yInverted, vertices, 2); \ + vertices, 2); \ } while(0) #define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ (vertices)[0] = t_from_x_coord_x(xscale, x1); \ (vertices)[2] = t_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ - (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \ - } \ - else { \ - (vertices)[1] = t_from_x_coord_y(yscale, y1); \ - (vertices)[7] = t_from_x_coord_y(yscale, y2); \ - } \ + (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) -#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \ - yInverted, vertices) \ +#define glamor_set_tcoords(x1, y1, x2, y2, vertices) \ do { \ (vertices)[0] = (x1); \ (vertices)[2] = (x2); \ (vertices)[4] = (vertices)[2]; \ (vertices)[6] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = (y1); \ - (vertices)[5] = (y2); \ - } \ - else { \ - (vertices)[1] = height - (y2); \ - (vertices)[5] = height - (y1); \ - } \ + (vertices)[1] = (y1); \ + (vertices)[5] = (y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[7] = (vertices)[5]; \ } while(0) -#define glamor_set_tcoords_ext(width, height, x1, y1, x2, y2, \ - yInverted, vertices, stride) \ +#define glamor_set_tcoords_ext(x1, y1, x2, y2, vertices, stride) \ do { \ (vertices)[0] = (x1); \ (vertices)[1*stride] = (x2); \ (vertices)[2*stride] = (vertices)[1*stride]; \ (vertices)[3*stride] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = (y1); \ - (vertices)[2*stride + 1] = (y2); \ - } \ - else { \ - (vertices)[1] = height - (y2); \ - (vertices)[2*stride + 1] = height - (y1); \ - } \ + (vertices)[1] = (y1); \ + (vertices)[2*stride + 1] = (y2); \ (vertices)[1*stride + 1] = (vertices)[1]; \ (vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \ } while(0) #define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \ - yInverted, vertices) \ + vertices) \ do { \ (vertices)[0] = v_from_x_coord_x(xscale, x); \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \ - } else { \ - (vertices)[1] = v_from_x_coord_y(yscale, y); \ - } \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \ } while(0) #define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_normalize_one_vcoord(xscale, yscale, \ (vtx)[0], (vtx)[1], \ - yInverted, vertices); \ + vertices); \ glamor_set_normalize_one_vcoord(xscale, yscale, \ (vtx)[2], (vtx)[3], \ - yInverted, vertices+2); \ + vertices+2); \ glamor_set_normalize_one_vcoord(xscale, yscale, \ (vtx)[4], (vtx)[5], \ - yInverted, vertices+4); \ + vertices+4); \ } while(0) -#define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2, \ - yInverted, vertices) \ +#define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \ do { \ (vertices)[0] = (x1); \ (vertices)[2] = (x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = (y1); \ - (vertices)[7] = (y2); \ - } \ - else { \ - (vertices)[1] = height - (y2); \ - (vertices)[7] = height - (y1); \ - } \ + (vertices)[1] = (y1); \ + (vertices)[7] = (y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) #define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, stride) \ + vertices, stride) \ do { \ int fbo_x_off, fbo_y_off; \ /* vertices may be write-only, so we use following \ @@ -701,29 +642,22 @@ x2 + fbo_x_off); \ (vertices)[2 * stride] = _t2_; \ (vertices)[3 * stride] = _t0_; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \ - y1 + fbo_y_off); \ - (vertices)[2 * stride + 1] = _t5_ = \ - v_from_x_coord_y_inverted(yscale, \ - y2 + fbo_y_off); \ - } \ - else { \ - (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \ - (vertices)[2 * stride + 1] = _t5_ = v_from_x_coord_y(yscale, \ - y2 + fbo_y_off); \ - } \ + (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \ + y1 + fbo_y_off); \ + (vertices)[2 * stride + 1] = _t5_ = \ + v_from_x_coord_y_inverted(yscale, \ + y2 + fbo_y_off); \ (vertices)[1 * stride + 1] = _t1_; \ (vertices)[3 * stride + 1] = _t5_; \ } while(0) #define glamor_set_normalize_vcoords(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices, 2); \ + vertices, 2); \ } while(0) #define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \ @@ -738,44 +672,30 @@ #define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \ x1, y1, x2, y2, \ - yInverted, vertices) \ + vertices) \ do { \ (vertices)[0] = v_from_x_coord_x(xscale, x1); \ (vertices)[2] = v_from_x_coord_x(xscale, x2); \ (vertices)[6] = (vertices)[2]; \ (vertices)[4] = (vertices)[0]; \ - if (_X_LIKELY(yInverted)) { \ - (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ - (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \ - } \ - else { \ - (vertices)[1] = v_from_x_coord_y(yscale, y1); \ - (vertices)[7] = v_from_x_coord_y(yscale, y2); \ - } \ + (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \ + (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \ (vertices)[3] = (vertices)[1]; \ (vertices)[5] = (vertices)[7]; \ } while(0) #define glamor_set_normalize_pt(xscale, yscale, x, y, \ - yInverted, pt) \ + pt) \ do { \ (pt)[0] = t_from_x_coord_x(xscale, x); \ - if (_X_LIKELY(yInverted)) { \ - (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \ - } else { \ - (pt)[1] = t_from_x_coord_y(yscale, y); \ - } \ + (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \ } while(0) #define glamor_set_circle_centre(width, height, x, y, \ - yInverted, c) \ + c) \ do { \ (c)[0] = (float)x; \ - if (_X_LIKELY(yInverted)) { \ - (c)[1] = (float)y; \ - } else { \ - (c)[1] = (float)height - (float)y; \ - } \ + (c)[1] = (float)y; \ } while(0) inline static void diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index 1e8bdb885..68a06a413 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -360,7 +360,7 @@ glamor_xv_render(glamor_port_private *port_priv) dsty, dstx + dstw, dsty + dsth, - glamor_priv->yInverted, vertices); + vertices); glamor_set_normalize_tcoords(src_pixmap_priv[0], src_xscale[0], @@ -369,7 +369,7 @@ glamor_xv_render(glamor_port_private *port_priv) srcy, srcx + srcw, srcy + srch, - glamor_priv->yInverted, texcoords); + texcoords); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index b156fb9b8..1c759743d 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -1245,8 +1245,7 @@ ephyr_glamor_init(ScreenPtr screen) glamor_init(screen, GLAMOR_USE_SCREEN | - GLAMOR_USE_PICTURE_SCREEN | - GLAMOR_INVERTED_Y_AXIS); + GLAMOR_USE_PICTURE_SCREEN); return TRUE; } From b6181007de357da58125e022992f165b10eda65d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 16 Jun 2014 07:04:01 +0100 Subject: [PATCH 30/34] glamor: Drop dead get/pub sub pixmap functions. These were replaced by the new glamor_prepare.c code. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_pixmap.c | 129 ----------------------------------------- glamor/glamor_priv.h | 5 -- 2 files changed, 134 deletions(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 8dbeb2220..00e38277d 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -1512,132 +1512,3 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv) return ret; } - -/* - * We may use this function to reduce a large pixmap to a small sub - * pixmap. Two scenarios currently: - * 1. When fallback a large textured pixmap to CPU but we do need to - * do rendering within a small sub region, then we can just get a - * sub region. - * - * 2. When uploading a large pixmap to texture but we only need to - * use part of the source/mask picture. As glTexImage2D will be more - * efficient to upload a contingent region rather than a sub block - * in a large buffer. We use this function to gather the sub region - * to a contingent sub pixmap. - * - * The sub-pixmap must have the same format as the source pixmap. - * - * */ -PixmapPtr -glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, - glamor_access_t access) -{ - glamor_screen_private *glamor_priv; - PixmapPtr sub_pixmap; - glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv; - void *data; - int pbo; - int flag; - - if (x < 0 || y < 0) - return NULL; - w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w; - h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h; - - glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return NULL; - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 || - pixmap_priv->type == GLAMOR_TEXTURE_LARGE) - flag = GLAMOR_CREATE_PIXMAP_CPU; - else - flag = GLAMOR_CREATE_PIXMAP_MAP; - - sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h, - pixmap->drawable.depth, flag); - - if (sub_pixmap == NULL) - return NULL; - - sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap); - pbo = - sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base. - fbo->pbo : 0) : 0; - - if (pixmap_priv->base.is_picture) { - sub_pixmap_priv->base.picture = pixmap_priv->base.picture; - sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture; - } - - if (pbo) - data = NULL; - else - data = sub_pixmap->devPrivate.ptr; - - data = - glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, - sub_pixmap->devKind, data, pbo, - access); - if (data == NULL) { - fbDestroyPixmap(sub_pixmap); - return NULL; - } - if (pbo) { - assert(sub_pixmap->devPrivate.ptr == NULL); - sub_pixmap->devPrivate.ptr = data; - sub_pixmap_priv->base.fbo->pbo_valid = 1; - } -#if 0 - struct pixman_box16 box; - PixmapPtr new_sub_pixmap; - int dx, dy; - - box.x1 = 0; - box.y1 = 0; - box.x2 = w; - box.y2 = h; - - dx = x; - dy = y; - - new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h, - pixmap->drawable.depth, - GLAMOR_CREATE_PIXMAP_CPU); - glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box, - 1, dx, dy, 0, 0, 0, NULL); - glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1); -#endif - - return sub_pixmap; -} - -void -glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, - int w, int h, glamor_access_t access) -{ - void *bits; - int pbo; - glamor_pixmap_private *sub_pixmap_priv; - - if (access != GLAMOR_ACCESS_RO) { - sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap); - if (sub_pixmap_priv->base.fbo && sub_pixmap_priv->base.fbo->pbo_valid) { - bits = NULL; - pbo = sub_pixmap_priv->base.fbo->pbo; - } - else { - bits = sub_pixmap->devPrivate.ptr; - pbo = 0; - } - - assert(x >= 0 && y >= 0); - w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w; - h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h; - glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, - sub_pixmap->devKind, bits, pbo); - } - glamor_destroy_pixmap(sub_pixmap); -} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 144cbfd7a..24f8674a2 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -833,11 +833,6 @@ Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, int stride, void *bits, int pbo); -PixmapPtr glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, - int w, int h, glamor_access_t access); -void glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, - int w, int h, glamor_access_t access); - glamor_pixmap_clipped_regions * glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *clipped_nbox, From 98155bd9d9b2a15a4dbcf80b2b57a7636efb14da Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 16 Jun 2014 07:01:28 +0100 Subject: [PATCH 31/34] glamor: Drop dead glamor_download_pixmap_to_cpu() Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_pixmap.c | 314 ----------------------------------------- glamor/glamor_priv.h | 15 -- 2 files changed, 329 deletions(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 00e38277d..2275ede32 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -923,26 +923,6 @@ glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits, } } -/* - * download sub region from a large region. - */ -static void -glamor_get_bits(char *dst_bits, int dst_stride, char *src_bits, - int src_stride, int bpp, int x, int y, int w, int h) -{ - int j; - int byte_per_pixel; - - byte_per_pixel = bpp / 8; - dst_bits += y * dst_stride + x * byte_per_pixel; - - for (j = y; j < y + h; j++) { - memcpy(dst_bits, src_bits, w * byte_per_pixel); - src_bits += src_stride; - dst_bits += dst_stride; - } -} - Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, int stride, void *bits, int pbo) @@ -1160,300 +1140,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, return temp_fbo; } -/* - * Download a sub region of pixmap to a specified memory region. - * The pixmap must have a valid FBO, otherwise return a NULL. - * */ - -static void * -_glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format, - GLenum type, int no_alpha, - int revert, int swap_rb, - int x, int y, int w, int h, - int stride, void *bits, int pbo, - glamor_access_t access) -{ - glamor_pixmap_private *pixmap_priv; - GLenum gl_access = 0, gl_usage = 0; - void *data; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - glamor_pixmap_fbo *temp_fbo = NULL; - int need_post_conversion = 0; - int need_free_data = 0; - int fbo_x_off, fbo_y_off; - - data = bits; - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return NULL; - - switch (access) { - case GLAMOR_ACCESS_RO: - gl_access = GL_READ_ONLY; - gl_usage = GL_STREAM_READ; - break; - case GLAMOR_ACCESS_RW: - gl_access = GL_READ_WRITE; - gl_usage = GL_DYNAMIC_DRAW; - break; - default: - ErrorF("Glamor: Invalid access code. %d\n", access); - assert(0); - } - - glamor_make_current(glamor_priv); - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - need_post_conversion = (revert > REVERT_NORMAL); - if (need_post_conversion) { - if (pixmap->drawable.depth == 1) { - int temp_stride; - - temp_stride = (((w * 8 + 7) / 8) + 3) & ~3; - data = malloc(temp_stride * h); - if (data == NULL) - return NULL; - need_free_data = 1; - } - } - - pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off); - - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - && !need_post_conversion - && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) { - if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h, - format, type, no_alpha, - revert, swap_rb))) { - free(data); - return NULL; - } - x = 0; - y = 0; - fbo_x_off = 0; - fbo_y_off = 0; - } - - glPixelStorei(GL_PACK_ALIGNMENT, 4); - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) { - assert(pbo > 0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); - glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, gl_usage); - } - - glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data); - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) { - bits = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - if (need_post_conversion) { - /* As OpenGL desktop version never enters here. - * Don't need to consider if the pbo is valid.*/ - bits = glamor_color_convert_to_bits(data, bits, - w, h, - stride, no_alpha, revert, swap_rb); - } - - if (temp_fbo != NULL) - glamor_destroy_fbo(temp_fbo); - if (need_free_data) - free(data); - - return bits; -} - -void * -glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h, - int stride, void *bits, int pbo, - glamor_access_t access) -{ - GLenum format, type; - int no_alpha, revert, swap_rb; - glamor_pixmap_private *pixmap_priv; - Bool force_clip; - - if (glamor_get_tex_format_type_from_pixmap(pixmap, - &format, - &type, - &no_alpha, - &revert, &swap_rb, 0)) { - glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); - return NULL; - } - - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return NULL; - - force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP - && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h); - - if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) { - - RegionRec region; - BoxRec box; - int n_region; - glamor_pixmap_clipped_regions *clipped_regions; - void *sub_bits; - int i, j; - - sub_bits = malloc(h * stride); - if (sub_bits == NULL) - return FALSE; - box.x1 = x; - box.y1 = y; - box.x2 = x + w; - box.y2 = y + h; - RegionInitBoxes(®ion, &box, 1); - - if (!force_clip) - clipped_regions = - glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, - 0, 0, 0); - else - clipped_regions = - glamor_compute_clipped_regions_ext(pixmap_priv, ®ion, - &n_region, - pixmap_priv->large.block_w, - pixmap_priv->large.block_h, - 0, - 0); - - DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h); - for (i = 0; i < n_region; i++) { - BoxPtr boxes; - int nbox; - int temp_stride; - void *temp_bits; - - assert(pbo == 0); - SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx); - - boxes = RegionRects(clipped_regions[i].region); - nbox = RegionNumRects(clipped_regions[i].region); - for (j = 0; j < nbox; j++) { - temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1, - pixmap->drawable.depth); - - if (boxes[j].x1 == x && temp_stride == stride) { - temp_bits = (char *) bits + (boxes[j].y1 - y) * stride; - } - else { - temp_bits = sub_bits; - } - DEBUGF("download x %d y %d w %d h %d temp stride %d \n", - boxes[j].x1, boxes[j].y1, - boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1, temp_stride); - - /* For large pixmap, we don't support pbo currently. */ - assert(pbo == 0); - if (_glamor_download_sub_pixmap_to_cpu - (pixmap, format, type, no_alpha, revert, swap_rb, - boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits, pbo, - access) == FALSE) { - RegionUninit(®ion); - free(sub_bits); - assert(0); - return NULL; - } - if (boxes[j].x1 != x || temp_stride != stride) - glamor_get_bits(bits, stride, temp_bits, temp_stride, - pixmap->drawable.bitsPerPixel, - boxes[j].x1 - x, boxes[j].y1 - y, - boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1); - } - - RegionDestroy(clipped_regions[i].region); - } - free(sub_bits); - free(clipped_regions); - RegionUninit(®ion); - return bits; - } - else - return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type, - no_alpha, revert, swap_rb, x, - y, w, h, stride, bits, pbo, - access); -} - -/** - * 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; - void *data = NULL, *dst; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - int pbo = 0; - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return TRUE; - - 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; - - if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - data = malloc(stride * pixmap->drawable.height); - } - else { - glamor_make_current(glamor_priv); - if (pixmap_priv->base.fbo->pbo == 0) - glGenBuffers(1, &pixmap_priv->base.fbo->pbo); - pbo = pixmap_priv->base.fbo->pbo; - } - - if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) { - stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth); - pixmap_priv->base.drm_stride = pixmap->devKind; - pixmap->devKind = stride; - } - - dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->devKind, data, pbo, access); - - if (!dst) { - if (data) - free(data); - return FALSE; - } - - if (pbo != 0) - pixmap_priv->base.fbo->pbo_valid = 1; - - pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED; - - pixmap->devPrivate.ptr = dst; - - return TRUE; -} - /* fixup a fbo to the exact size as the pixmap. */ /* XXX LARGE pixmap? */ Bool diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 24f8674a2..17406abdc 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -788,21 +788,6 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset); void glamor_put_vbo_space(ScreenPtr screen); -/** - * Download a pixmap's texture to cpu memory. If success, - * One copy of current pixmap's texture will be put into - * the pixmap->devPrivate.ptr. Will use pbo to map to - * the pointer if possible. - * The pixmap must be a gl texture pixmap. gl_fbo must be GLAMOR_FBO_NORMAL and - * gl_tex must be 1. Used by glamor_prepare_access. - * - */ -Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access); - -void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, - int h, int stride, void *bits, int pbo, - glamor_access_t access); - /** * Restore a pixmap's data which is downloaded by * glamor_download_pixmap_to_cpu to its original From b5f94df319469ad44b0e88374a0d389414803f7a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 16 Jun 2014 07:06:30 +0100 Subject: [PATCH 32/34] glamor: Drop dead glamor_restore_pixmap_to_texture(). Unused since the glamor_prepare.c replacement of glamor_finish_access(). Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_pixmap.c | 7 ------- glamor/glamor_priv.h | 10 ---------- 2 files changed, 17 deletions(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 2275ede32..725fa5e7f 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -1064,13 +1064,6 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap) return ret; } -void -glamor_restore_pixmap_to_texture(PixmapPtr pixmap) -{ - if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE) - LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n"); -} - /* * as gles2 only support a very small set of color format and * type when do glReadPixel, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 17406abdc..61f393d8f 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -788,16 +788,6 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset); void glamor_put_vbo_space(ScreenPtr screen); -/** - * 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 originally be a texture -- gl_fbo must be - * GLAMOR_FBO_NORMAL. - **/ -void glamor_restore_pixmap_to_texture(PixmapPtr pixmap); - /** * According to the flag, * if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure From b03a581d8cbe3f29140935063b865285e2a00333 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 16 Jun 2014 07:15:58 +0100 Subject: [PATCH 33/34] glamor: Remove a dead prototype. The corresponding code was deleted in 2ff41008494e6c5909c058f1f80b4f66617dada1 (2012) Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_priv.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 61f393d8f..dc4f9b842 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -866,12 +866,6 @@ Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type, int no_alpha, int revert, int swap_rb, void *bits); -/** - * Destroy all the resources allocated on the uploading - * phase, includs the tex and fbo. - **/ -void glamor_destroy_upload_pixmap(PixmapPtr pixmap); - int glamor_create_picture(PicturePtr picture); void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap); From 9ddcb20f47b5e199989c8990512b0bca1354af86 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 16 Jun 2014 07:24:09 +0100 Subject: [PATCH 34/34] glamor: Drop the "are we doing a series of blits or draws" logic. It's unused since keithp's copy acceleration code completely replaced glamor_copyarea.c and removed the blit path. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor.c | 5 ----- glamor/glamor_points.c | 3 --- glamor/glamor_priv.h | 7 ------- glamor/glamor_render.c | 2 -- glamor/glamor_text.c | 6 ------ 5 files changed, 23 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 5e6003df6..a82c46fdf 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -250,11 +250,6 @@ glamor_block_handler(ScreenPtr screen) glamor_priv->tick++; glFlush(); glamor_fbo_expire(glamor_priv); - if (glamor_priv->state == RENDER_STATE - && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) { - glamor_priv->state = IDLE_STATE; - glamor_priv->render_idle_cnt = 0; - } } static void diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c index d4525e294..84383d254 100644 --- a/glamor/glamor_points.c +++ b/glamor/glamor_points.c @@ -105,9 +105,6 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint glDisable(GL_COLOR_LOGIC_OP); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - return TRUE; bail_ctx: diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index dc4f9b842..2a9eccef4 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -194,11 +194,6 @@ struct glamor_saved_procs { #define GLAMOR_TICK_AFTER(t0, t1) \ (((int)(t1) - (int)(t0)) < 0) -#define IDLE_STATE 0 -#define RENDER_STATE 1 -#define BLIT_STATE 2 -#define RENDER_IDEL_MAX 32 - typedef struct glamor_screen_private { unsigned int tick; enum glamor_gl_flavor gl_flavor; @@ -288,8 +283,6 @@ typedef struct glamor_screen_private { char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; int delayed_fallback_pending; int flags; - int state; - unsigned int render_idle_cnt; ScreenPtr screen; int dri3_enabled; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index add376f11..b212fe1fc 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1313,8 +1313,6 @@ glamor_composite_with_shader(CARD8 op, glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); glDisable(GL_BLEND); DEBUGF("finish rendering.\n"); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; if (saved_source_format) source->format = saved_source_format; diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c index 6e02b9aa8..59cd0fdc8 100644 --- a/glamor/glamor_text.c +++ b/glamor/glamor_text.c @@ -293,9 +293,6 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc, glDisable(GL_COLOR_LOGIC_OP); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - *final_pos = x; return TRUE; @@ -493,9 +490,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc, (void) glamor_text(drawable, gc, glamor_font, prog, x, y, count, chars, charinfo, sixteen); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - return TRUE; bail: