diff --git a/glamor/Makefile.am b/glamor/Makefile.am index ca8fc3fbf..c7e300096 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -53,9 +53,9 @@ if EGL LIBGLAMOREGL = libglamoregl.la module_LTLIBRARIES = $(LIBGLAMOREGL) libglamoregl_la_DEPENDENCIES = libglamor.la -libglamoregl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor +libglamoregl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor $(GLX_SYS_LIBS) libglamoregl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c -libglamoregl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS) +libglamoregl_la_CFLAGS = $(AM_CFLAGS) $(GLX_DEFINES) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS) endif diff --git a/glamor/glamor.c b/glamor/glamor.c index 0245fdac8..6b6330f4c 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -83,11 +83,9 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex) ScreenPtr screen = pixmap->drawable.pScreen; glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; glamor_pixmap_fbo *fbo; glamor_priv = glamor_get_screen_private(screen); - dispatch = &glamor_priv->dispatch; pixmap_priv = glamor_get_pixmap_private(pixmap); if (pixmap_priv->fbo) { @@ -130,7 +128,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_pixmap_fbo *fbo; int pitch; int flag; @@ -149,7 +146,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, fbDestroyPixmap(pixmap); return fbCreatePixmap(screen, w, h, depth, usage); } - glamor_set_pixmap_private(pixmap, pixmap_priv); pixmap_priv->container = pixmap; @@ -201,11 +197,14 @@ glamor_block_handler(ScreenPtr screen) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; + GLAMOR_DEFINE_CONTEXT; + GLAMOR_SET_CONTEXT(glamor_priv); glamor_priv->tick++; dispatch->glFlush(); dispatch->glFinish(); glamor_fbo_expire(glamor_priv); + GLAMOR_RESTORE_CONTEXT(glamor_priv); } static void @@ -392,6 +391,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_pixmap_init(screen); glamor_priv->flags = flags; + glamor_priv->screen = screen; return TRUE; diff --git a/glamor/glamor.h b/glamor/glamor.h index 3d6e5fe7f..712a7a9b2 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -145,6 +145,10 @@ extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen); +extern _X_EXPORT void * glamor_egl_make_current(ScreenPtr screen); + +extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen, void *context); + #ifdef GLAMOR_FOR_XORG #define GLAMOR_EGL_MODULE_NAME "glamoregl" diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index f2d710a90..e6569343e 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -308,6 +308,7 @@ _glamor_copy_n_to_n(DrawablePtr src, 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; @@ -315,7 +316,8 @@ _glamor_copy_n_to_n(DrawablePtr src, int src_x_off, src_y_off, dst_x_off, dst_y_off; int i; int overlaped = 0; - Bool ret = TRUE; + Bool ret = FALSE; + GLAMOR_DEFINE_CONTEXT; dst_pixmap = glamor_get_drawable_pixmap(dst); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); @@ -323,6 +325,9 @@ _glamor_copy_n_to_n(DrawablePtr src, src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); screen = dst_pixmap->drawable.pScreen; + glamor_priv = glamor_get_screen_private(dst->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { glamor_fallback("dest pixmap %p has no fbo. \n", dst_pixmap); @@ -356,6 +361,7 @@ _glamor_copy_n_to_n(DrawablePtr src, || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex) && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { + ret = TRUE; goto done; } #endif @@ -400,6 +406,7 @@ _glamor_copy_n_to_n(DrawablePtr src, if (glamor_copy_n_to_n_textured (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) { + ret = TRUE; goto done; } @@ -408,10 +415,8 @@ _glamor_copy_n_to_n(DrawablePtr src, if (!fallback && glamor_ddx_fallback_check_pixmap(src) - && glamor_ddx_fallback_check_pixmap(dst)) { - ret = FALSE; + && glamor_ddx_fallback_check_pixmap(dst)) goto done; - } glamor_report_delayed_fallbacks(src->pScreen); glamor_report_delayed_fallbacks(dst->pScreen); @@ -436,12 +441,14 @@ _glamor_copy_n_to_n(DrawablePtr src, } glamor_finish_access(dst, GLAMOR_ACCESS_RW); } + ret = TRUE; done: glamor_clear_delayed_fallbacks(src->pScreen); glamor_clear_delayed_fallbacks(dst->pScreen); if (temp_src != src) glamor_destroy_pixmap(temp_pixmap); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return ret; } diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c index 288d7eddc..b6b26a50c 100644 --- a/glamor/glamor_copyplane.c +++ b/glamor/glamor_copyplane.c @@ -37,17 +37,24 @@ _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) { + GLAMOR_DEFINE_CONTEXT; + glamor_screen_private *glamor_priv; + if (!fallback && glamor_ddx_fallback_check_gc(pGC) && glamor_ddx_fallback_check_pixmap(pSrc) && glamor_ddx_fallback_check_pixmap(pDst)) goto fail; + + glamor_priv = glamor_get_screen_private(pDst->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); glamor_prepare_access(pDst, GLAMOR_ACCESS_RW); glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO); *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); glamor_finish_access(pSrc, GLAMOR_ACCESS_RO); glamor_finish_access(pDst, GLAMOR_ACCESS_RW); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; fail: diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 027722e23..a339527d8 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -63,6 +63,9 @@ #include "glamor.h" #include "glamor_gl_dispatch.h" +#ifdef GLX_USE_SHARED_DISPATCH +#include "glapi.h" +#endif static const char glamor_name[] = "glamor"; @@ -90,6 +93,7 @@ struct glamor_egl_screen_private { struct gbm_device *gbm; #endif int has_gem; + void *gl_context; PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr; @@ -101,13 +105,46 @@ struct glamor_egl_screen_private { int xf86GlamorEGLPrivateIndex = -1; -static struct glamor_egl_screen_private -* +static struct glamor_egl_screen_private * glamor_egl_get_screen_private(ScrnInfoPtr scrn) { return (struct glamor_egl_screen_private *) scrn->privates[xf86GlamorEGLPrivateIndex].ptr; } +#ifdef GLX_USE_SHARED_DISPATCH +_X_EXPORT void * +glamor_egl_make_current(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + GET_CURRENT_CONTEXT(current); + + if (glamor_egl->gl_context != current) { + eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (!eglMakeCurrent(glamor_egl->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, + glamor_egl->context)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to make EGL context current\n"); + return NULL; + } + return current; + } + return NULL; +} + +_X_EXPORT void +glamor_egl_restore_context(ScreenPtr screen, void *context) +{ + if (context) + SET_CURRENT_CONTEXT(context); +} +#else +#define glamor_egl_make_current(x) NULL +#define glamor_egl_restore_context(s, c) +#endif static EGLImageKHR _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl, @@ -215,9 +252,12 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) EGLImageKHR image; GLuint texture; int name; + void *prev_context; + Bool ret = FALSE; glamor_egl = glamor_egl_get_screen_private(scrn); + prev_context = glamor_egl_make_current(screen); if (glamor_egl->has_gem) { if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, @@ -234,16 +274,20 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) ((stride * 8 + 7) / pixmap->drawable.bitsPerPixel), name, pixmap->drawable.depth); - if (image == EGL_NO_IMAGE_KHR) - return FALSE; + if (image == EGL_NO_IMAGE_KHR) + goto done; glamor_create_texture_from_image(glamor_egl, image, &texture); glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_texture(pixmap, texture); dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image); + ret = TRUE; - return TRUE; +done: + if (prev_context) + glamor_egl_restore_context(screen, prev_context); + return ret; } static void @@ -447,7 +491,10 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) "Failed to make EGL context current\n"); return FALSE; } - +#ifdef GLX_USE_SHARED_DISPATCH + GET_CURRENT_CONTEXT(current); + glamor_egl->gl_context = current; +#endif glamor_egl->saved_free_screen = scrn->FreeScreen; scrn->FreeScreen = glamor_egl_free_screen; return TRUE; diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index 2243564f6..929cababa 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -126,6 +126,9 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv, void glamor_purge_fbo(glamor_pixmap_fbo *fbo) { + GLAMOR_DEFINE_CONTEXT; + + GLAMOR_SET_CONTEXT(fbo->glamor_priv); glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch; if (fbo->fb) dispatch->glDeleteFramebuffers(1, &fbo->fb); @@ -133,6 +136,7 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo) dispatch->glDeleteTextures(1, &fbo->tex); if (fbo->pbo) dispatch->glDeleteBuffers(1, &fbo->pbo); + GLAMOR_RESTORE_CONTEXT(fbo->glamor_priv); free(fbo); } @@ -166,7 +170,6 @@ glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, int w, int h, int depth, GLint tex, int flag) { - glamor_gl_dispatch *dispatch; glamor_pixmap_fbo *fbo; GLenum format; @@ -276,8 +279,6 @@ glamor_fini_pixmap_fbo(ScreenPtr screen) void glamor_destroy_fbo(glamor_pixmap_fbo *fbo) { - glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch; - list_del(&fbo->list); glamor_pixmap_fbo_cache_put(fbo); @@ -291,6 +292,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo; int cache_flag = GLAMOR_CACHE_TEXTURE; GLuint tex; + GLAMOR_DEFINE_CONTEXT; if (flag == GLAMOR_CREATE_TEXTURE_EXACT_SIZE) cache_flag |= GLAMOR_CACHE_EXACT_SIZE; @@ -303,6 +305,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv, if (fbo == NULL) return NULL; + GLAMOR_SET_CONTEXT(glamor_priv); list_init(&fbo->list); dispatch = &glamor_priv->dispatch; @@ -319,6 +322,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv, fbo->height = h; fbo->format = format; fbo->glamor_priv = glamor_priv; + GLAMOR_RESTORE_CONTEXT(glamor_priv); return fbo; } @@ -340,6 +344,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv, GLenum format; GLint tex; int cache_flag; + GLAMOR_DEFINE_CONTEXT; if (!glamor_check_fbo_size(glamor_priv, w, h) || !glamor_check_fbo_depth(depth)) @@ -359,6 +364,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv, if (fbo) return fbo; new_fbo: + + GLAMOR_SET_CONTEXT(glamor_priv); dispatch = &glamor_priv->dispatch; dispatch->glGenTextures(1, &tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex); @@ -370,6 +377,7 @@ new_fbo: GL_UNSIGNED_BYTE, NULL); fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return fbo; } diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index 97c4403ce..97e449784 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -40,6 +40,12 @@ _glamor_fill_spans(DrawablePtr drawable, BoxPtr pbox; int x1, x2, y; RegionPtr pClip = fbGetCompositeClip(gc); + glamor_screen_private *glamor_priv; + GLAMOR_DEFINE_CONTEXT; + Bool ret = FALSE; + + glamor_priv = glamor_get_screen_private(drawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) goto fail; @@ -71,13 +77,15 @@ _glamor_fill_spans(DrawablePtr drawable, pbox++; } } - return TRUE; + ret = TRUE; + goto done; - fail: +fail: if (!fallback && glamor_ddx_fallback_check_pixmap(drawable) - && glamor_ddx_fallback_check_gc(gc)) - return FALSE; + && glamor_ddx_fallback_check_gc(gc)) { + goto done; + } glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { @@ -88,7 +96,11 @@ _glamor_fill_spans(DrawablePtr drawable, } glamor_finish_access(drawable, GLAMOR_ACCESS_RW); } - return TRUE; + ret = TRUE; + +done: + GLAMOR_RESTORE_CONTEXT(glamor_priv); + return ret; } diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c index 377783cb6..7caf2a372 100644 --- a/glamor/glamor_getimage.c +++ b/glamor/glamor_getimage.c @@ -46,8 +46,14 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, int no_alpha, no_revert; PixmapPtr temp_pixmap = NULL; glamor_gl_dispatch * dispatch; + GLAMOR_DEFINE_CONTEXT; + Bool ret = FALSE; goto fall_back; + + glamor_priv = glamor_get_screen_private(drawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); + if (format != ZPixmap) goto fall_back; @@ -113,10 +119,14 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, tex_type, d); if (temp_pixmap) glamor_destroy_pixmap(temp_pixmap); - return TRUE; + + ret = TRUE; fall_back: - miGetImage(drawable, x, y, w, h, format, planeMask, d); + + GLAMOR_RESTORE_CONTEXT(glamor_priv); + if (ret == FALSE) + miGetImage(drawable, x, y, w, h, format, planeMask, d); return TRUE; } diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 6c50d1b5b..2d30f37a8 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -49,7 +49,10 @@ _glamor_get_spans(DrawablePtr drawable, int i; uint8_t *readpixels_dst = (uint8_t *) dst; int x_off, y_off; + GLAMOR_DEFINE_CONTEXT; + Bool ret = FALSE; + GLAMOR_SET_CONTEXT(glamor_priv); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("pixmap has no fbo.\n"); goto fail; @@ -97,20 +100,24 @@ _glamor_get_spans(DrawablePtr drawable, } if (temp_pixmap) glamor_destroy_pixmap(temp_pixmap); - return TRUE; - fail: + ret = TRUE; + goto done; +fail: if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)) - return FALSE; + goto done; + glamor_fallback("from %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) { fbGetSpans(drawable, wmax, points, widths, count, dst); glamor_finish_access(drawable, GLAMOR_ACCESS_RO); } - return TRUE; +done: + GLAMOR_RESTORE_CONTEXT(glamor_priv); + return ret; } void diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c index c9a35a0f1..8c853e91a 100644 --- a/glamor/glamor_glyphblt.c +++ b/glamor/glamor_glyphblt.c @@ -37,15 +37,22 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase, Bool fallback) { + GLAMOR_DEFINE_CONTEXT; + glamor_screen_private *glamor_priv; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) && glamor_ddx_fallback_check_gc(pGC)) goto fail; + + glamor_priv = glamor_get_screen_private(pDrawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW); glamor_prepare_access_gc(pGC); fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); glamor_finish_access_gc(pGC); glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; fail: return FALSE; @@ -72,15 +79,22 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase, Bool fallback) { + GLAMOR_DEFINE_CONTEXT; + glamor_screen_private *glamor_priv; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) && glamor_ddx_fallback_check_gc(pGC)) goto fail; + + glamor_priv = glamor_get_screen_private(pDrawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW); glamor_prepare_access_gc(pGC); fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); glamor_finish_access_gc(pGC); glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; fail: return FALSE; @@ -106,11 +120,17 @@ static Bool _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback) { + GLAMOR_DEFINE_CONTEXT; + glamor_screen_private *glamor_priv; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable) && glamor_ddx_fallback_check_gc(pGC)) goto fail; + + glamor_priv = glamor_get_screen_private(pDrawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW); glamor_prepare_access(&pBitmap->drawable, GLAMOR_ACCESS_RO); glamor_prepare_access_gc(pGC); @@ -118,6 +138,7 @@ _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, glamor_finish_access_gc(pGC); glamor_finish_access(&pBitmap->drawable, GLAMOR_ACCESS_RO); glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; fail: return FALSE; diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index 32afd093b..8b362415f 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -45,8 +45,14 @@ _glamor_poly_fill_rect(DrawablePtr drawable, int xorg, yorg; int n; register BoxPtr pbox; - RegionPtr pClip = fbGetCompositeClip(gc); + Bool ret = FALSE; + glamor_screen_private *glamor_priv; + GLAMOR_DEFINE_CONTEXT; + + glamor_priv = glamor_get_screen_private(drawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); + if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) { goto fail; } @@ -91,14 +97,15 @@ _glamor_poly_fill_rect(DrawablePtr drawable, goto fail; } } - return TRUE; + ret = TRUE; + goto done; - fail: +fail: if (!fallback && glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc)) - return FALSE; + goto done; glamor_fallback(" to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); @@ -109,7 +116,11 @@ _glamor_poly_fill_rect(DrawablePtr drawable, } glamor_finish_access(drawable, GLAMOR_ACCESS_RW); } - return TRUE; + ret = TRUE; + +done: + GLAMOR_RESTORE_CONTEXT(glamor_priv); + return ret; } diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index 0217e8fcb..0d37a1dd1 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -49,6 +49,9 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, xRectangle *rects; int x1, x2, y1, y2; int i; + glamor_screen_private *glamor_priv; + GLAMOR_DEFINE_CONTEXT; + /* 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 @@ -108,6 +111,8 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, && glamor_ddx_fallback_check_gc(gc)) return FALSE; + glamor_priv = glamor_get_screen_private(drawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); if (gc->lineWidth == 0) { if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_gc(gc)) { @@ -121,6 +126,7 @@ wide_line: /* fb calls mi functions in the lineWidth != 0 case. */ fbPolyLine(drawable, gc, mode, n, points); } + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; } diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c index 6188bb23f..ca21b8b9a 100644 --- a/glamor/glamor_polyops.c +++ b/glamor/glamor_polyops.c @@ -36,15 +36,22 @@ static Bool _glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt, Bool fallback) { + GLAMOR_DEFINE_CONTEXT; + glamor_screen_private *glamor_priv; + if (!fallback && glamor_ddx_fallback_check_gc(pGC) && glamor_ddx_fallback_check_pixmap(pDrawable)) goto fail; + + glamor_priv = glamor_get_screen_private(pDrawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); glamor_prepare_access_gc(pGC); glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW); fbPolyPoint(pDrawable, pGC, mode, npt, ppt); glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW); glamor_finish_access_gc(pGC); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; fail: @@ -69,10 +76,16 @@ static Bool _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg, Bool fallback) { + GLAMOR_DEFINE_CONTEXT; + glamor_screen_private *glamor_priv; + if (!fallback && glamor_ddx_fallback_check_gc(pGC) && glamor_ddx_fallback_check_pixmap(pDrawable)) goto fail; + + glamor_priv = glamor_get_screen_private(pDrawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); /* For lineWidth is not zero, fb calls to mi functions. */ if (pGC->lineWidth == 0) { glamor_prepare_access_gc(pGC); @@ -83,6 +96,7 @@ _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, } else fbPolySegment(pDrawable, pGC, nseg, pSeg); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; fail: @@ -107,11 +121,17 @@ static Bool _glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt, Bool fallback) { + GLAMOR_DEFINE_CONTEXT; + glamor_screen_private *glamor_priv; + if (!fallback && glamor_ddx_fallback_check_gc(pGC) && glamor_ddx_fallback_check_pixmap(pDrawable)) goto fail; /* For lineWidth is not zero, fb calls to mi functions. */ + + glamor_priv = glamor_get_screen_private(pDrawable->pScreen); + GLAMOR_SET_CONTEXT(glamor_priv); if (pGC->lineWidth == 0) { glamor_prepare_access_gc(pGC); glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW); @@ -121,6 +141,7 @@ _glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, } else fbPolyLine(pDrawable, pGC, mode, npt, ppt); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return TRUE; fail: diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index b19a30402..d04421b6a 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -219,6 +219,7 @@ typedef struct glamor_screen_private { int delayed_fallback_pending; glamor_pixmap_validate_function_t *pixmap_validate_funcs; int flags; + ScreenPtr screen; } glamor_screen_private; typedef enum glamor_access { diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 26d5cf766..581382261 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -230,7 +230,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, glamor_set_planemask(pixmap, ~0); glamor_fallback(": to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); - fail: +fail: if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); @@ -265,6 +265,10 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, GLfloat xscale, yscale, txscale, tyscale; GLuint tex; int no_alpha, no_revert; + GLAMOR_DEFINE_CONTEXT; + Bool ret = FALSE; + + GLAMOR_SET_CONTEXT(glamor_priv); if (image_format == XYBitmap) { assert(depth == 1); goto fail; @@ -396,14 +400,16 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glamor_set_alu(dispatch, GXcopy); glamor_set_planemask(pixmap, ~0); - return TRUE; - fail: + ret = TRUE; + goto done; + +fail: glamor_set_planemask(pixmap, ~0); if (!fallback && glamor_ddx_fallback_check_pixmap(&pixmap->drawable)) - return FALSE; + goto done; glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); @@ -412,7 +418,11 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, left_pad, image_format, bits); glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RW); } - return TRUE; + ret = TRUE; + +done: + GLAMOR_RESTORE_CONTEXT(glamor_priv); + return ret; } void diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 789c684c2..b240eac6a 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -870,7 +870,10 @@ glamor_composite_with_shader(CARD8 op, dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); int vert_stride = 4; int nrect_max; + GLAMOR_DEFINE_CONTEXT; + Bool ret = FALSE; + GLAMOR_SET_CONTEXT(glamor_priv); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { glamor_fallback("dest has no fbo.\n"); goto fail; @@ -1230,15 +1233,20 @@ glamor_composite_with_shader(CARD8 op, dispatch->glUseProgram(0); if (saved_source_format) source->format = saved_source_format; - return TRUE; - fail: + ret = TRUE; + goto done; + +fail: if (saved_source_format) source->format = saved_source_format; dispatch->glDisable(GL_BLEND); dispatch->glUseProgram(0); - return FALSE; + +done: + GLAMOR_RESTORE_CONTEXT(glamor_priv); + return ret; } static PicturePtr @@ -1308,11 +1316,11 @@ _glamor_composite(CARD8 op, int prect_size = ARRAY_SIZE(rect); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; Bool ret = TRUE; RegionRec region; BoxPtr box; int nbox, i, ok; + GLAMOR_DEFINE_CONTEXT; x_temp_src = x_source; y_temp_src = y_source; @@ -1320,6 +1328,7 @@ _glamor_composite(CARD8 op, y_temp_mask = y_mask; dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); + GLAMOR_SET_CONTEXT(glamor_priv); /* Currently. Always fallback to cpu if destination is in CPU memory. */ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { goto fail; @@ -1473,10 +1482,8 @@ _glamor_composite(CARD8 op, if (ok) goto done; - fail: +fail: - dispatch->glUseProgram(0); - dispatch->glDisable(GL_BLEND); if (!fallback && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable) && (!source_pixmap @@ -1528,6 +1535,7 @@ _glamor_composite(CARD8 op, FreePicture(temp_mask, 0); if (prect != rect) free(prect); + GLAMOR_RESTORE_CONTEXT(glamor_priv); return ret; } diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 26e774bc6..07c94ab57 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -47,7 +47,10 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, RegionPtr clip = fbGetCompositeClip(gc); BoxRec *pbox; int x_off, y_off; + GLAMOR_DEFINE_CONTEXT; + Bool ret = FALSE; + GLAMOR_SET_CONTEXT(glamor_priv); dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { glamor_fallback("pixmap has no fbo.\n"); @@ -100,18 +103,25 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, glamor_set_planemask(dest_pixmap, ~0); glamor_set_alu(dispatch, GXcopy); dispatch->glDisable(GL_SCISSOR_TEST); - return TRUE; - fail: + ret = TRUE; + goto done; + +fail: if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)) - return FALSE; + goto done; + glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbSetSpans(drawable, gc, src, points, widths, n, sorted); glamor_finish_access(drawable, GLAMOR_ACCESS_RW); } - return TRUE; + ret = TRUE; + +done: + GLAMOR_RESTORE_CONTEXT(glamor_priv); + return ret; } void diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index 74ce6cd0f..a66e24802 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -663,4 +663,33 @@ static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int } glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); } + +static inline void *glamor_make_current(ScreenPtr screen) +{ + return glamor_egl_make_current(screen); +} + +static inline void glamor_restore_current(ScreenPtr screen, void *previous_context) +{ + glamor_egl_restore_context(screen, previous_context); +} + +#ifdef GLX_USE_SHARED_DISPATCH +#define GLAMOR_DEFINE_CONTEXT void *_previous_context_ = NULL +#define GLAMOR_SET_CONTEXT(glamor_priv) \ + if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) \ + _previous_context_ = glamor_make_current(glamor_priv->screen) + +#define GLAMOR_RESTORE_CONTEXT(glamor_priv) \ + if ((glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) \ + && _previous_context_ != NULL) \ + glamor_restore_current(glamor_priv->screen, _previous_context_) +#else + +#define GLAMOR_DEFINE_CONTEXT +#define GLAMOR_SET_CONTEXT(glamor_priv) +#define GLAMOR_RESTORE_CONTEXT(glamor_priv) + +#endif + #endif diff --git a/glamor/glapi.h b/glamor/glapi.h new file mode 100644 index 000000000..da521aa7c --- /dev/null +++ b/glamor/glapi.h @@ -0,0 +1,121 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * \mainpage Mesa GL API Module + * + * \section GLAPIIntroduction Introduction + * + * The Mesa GL API module is responsible for dispatching all the + * gl*() functions. All GL functions are dispatched by jumping through + * the current dispatch table (basically a struct full of function + * pointers.) + * + * A per-thread current dispatch table and per-thread current context + * pointer are managed by this module too. + * + * This module is intended to be non-Mesa-specific so it can be used + * with the X/DRI libGL also. + */ + +#ifndef _GLAPI_H +#define _GLAPI_H + +#define GL_GLEXT_PROTOTYPES + +#if GLAMOR_GLES2 +#include +#include +#else +#include +#include "GL/glext.h" +#endif + +/* Is this needed? It is incomplete anyway. */ +#ifdef USE_MGL_NAMESPACE +#define _glapi_set_dispatch _mglapi_set_dispatch +#define _glapi_get_dispatch _mglapi_get_dispatch +#define _glapi_set_context _mglapi_set_context +#define _glapi_get_context _mglapi_get_context +#define _glapi_Dispatch _mglapi_Dispatch +#define _glapi_Context _mglapi_Context +#endif + +typedef void (*_glapi_proc)(void); +struct _glapi_table; + + +#if defined (GLX_USE_TLS) + +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); + +extern __thread void * _glapi_tls_Context + __attribute__((tls_model("initial-exec"))); + +extern const struct _glapi_table *_glapi_Dispatch; +extern const void *_glapi_Context; + +# define GET_DISPATCH() _glapi_tls_Dispatch +# define GET_CURRENT_CONTEXT(C) struct gl_context *C = (struct gl_context *) _glapi_tls_Context +# define SET_CURRENT_CONTEXT(C) _glapi_tls_Context = (void*)C + +#else + +extern struct _glapi_table *_glapi_Dispatch; +extern void *_glapi_Context; + +# ifdef THREADS + +# define GET_DISPATCH() \ + (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch()) + +# define GET_CURRENT_CONTEXT(C) struct gl_context *C = (struct gl_context *) \ + (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context()) + + +# define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context)) \ + _glapi_Context = (void*)C; \ + else \ + _glapi_set_context(C); } while(0) + +# else + +# define GET_DISPATCH() _glapi_Dispatch +# define GET_CURRENT_CONTEXT(C) struct gl_context *C = (struct gl_context *) _glapi_Context +# define SET_CURRENT_CONTEXT(C) _glapi_Context = (void*)C + +# endif + +#endif /* defined (GLX_USE_TLS) */ + + +extern void +_glapi_set_context(void *context); + +extern void * +_glapi_get_context(void); + +#endif