From d84d71029ae9e462559d64eff7259e2cc7732fac Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 18 Dec 2013 11:59:07 -0800 Subject: [PATCH] glamor: Apply x-indent.sh. Signed-off-by: Eric Anholt Reviewed-by: Zhigang Gong Reviewed-by: Keith Packard --- glamor/compiler.h | 2 +- glamor/glamor.c | 808 +++++---- glamor/glamor.h | 249 +-- glamor/glamor_addtraps.c | 34 +- glamor/glamor_compositerects.c | 458 +++-- glamor/glamor_copyarea.c | 1161 +++++++------ glamor/glamor_copyplane.c | 50 +- glamor/glamor_copywindow.c | 34 +- glamor/glamor_core.c | 824 +++++---- glamor/glamor_debug.h | 9 - glamor/glamor_egl.c | 1167 +++++++------ glamor/glamor_eglmodule.c | 20 +- glamor/glamor_fbo.c | 877 +++++----- glamor/glamor_fill.c | 582 +++---- glamor/glamor_fillspans.c | 121 +- glamor/glamor_getimage.c | 97 +- glamor/glamor_getspans.c | 90 +- glamor/glamor_gl_dispatch.c | 138 +- glamor/glamor_gl_dispatch.h | 244 ++- glamor/glamor_glext.h | 1 - glamor/glamor_glyphblt.c | 83 +- glamor/glamor_glyphs.c | 2951 ++++++++++++++++---------------- glamor/glamor_gradient.c | 2531 +++++++++++++-------------- glamor/glamor_largepixmap.c | 2437 +++++++++++++------------- glamor/glamor_picture.c | 111 +- glamor/glamor_pixmap.c | 2239 ++++++++++++------------ glamor/glamor_polyfillrect.c | 135 +- glamor/glamor_polylines.c | 155 +- glamor/glamor_polyops.c | 43 +- glamor/glamor_priv.h | 853 ++++----- glamor/glamor_putimage.c | 550 +++--- glamor/glamor_render.c | 3699 ++++++++++++++++++++-------------------- glamor/glamor_setspans.c | 119 +- glamor/glamor_tile.c | 512 +++--- glamor/glamor_trapezoid.c | 3219 +++++++++++++++++----------------- glamor/glamor_triangles.c | 61 +- glamor/glamor_utils.h | 1711 ++++++++++--------- glamor/glamor_window.c | 102 +- glamor/glamor_xv.c | 1014 ++++++----- glamor/glapi.h | 45 +- 40 files changed, 14757 insertions(+), 14779 deletions(-) diff --git a/glamor/compiler.h b/glamor/compiler.h index fa28959..5f2d4ea 100644 --- a/glamor/compiler.h +++ b/glamor/compiler.h @@ -56,4 +56,4 @@ #define COMPILE_TIME_ASSERT(E) ((void)sizeof(char[1 - 2*!(E)])) -#endif /* _SNA_COMPILER_H_ */ +#endif /* _SNA_COMPILER_H_ */ diff --git a/glamor/glamor.c b/glamor/glamor.c index 93d3c5e..216fab4 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -54,197 +54,192 @@ DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index; PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable) { - if (drawable->type == DRAWABLE_WINDOW) - return drawable-> - pScreen->GetWindowPixmap((WindowPtr) drawable); - else - return (PixmapPtr) drawable; + if (drawable->type == DRAWABLE_WINDOW) + return drawable->pScreen->GetWindowPixmap((WindowPtr) drawable); + else + return (PixmapPtr) drawable; } _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type) { - glamor_pixmap_private *pixmap_priv; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - - pixmap_priv = dixLookupPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key); - if (pixmap_priv == NULL) { - pixmap_priv = calloc(sizeof(*pixmap_priv), 1); - glamor_set_pixmap_private(pixmap, pixmap_priv); - pixmap_priv->base.pixmap = pixmap; - pixmap_priv->base.glamor_priv = glamor_priv; - } - pixmap_priv->type = type; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + + pixmap_priv = dixLookupPrivate(&pixmap->devPrivates, + glamor_pixmap_private_key); + if (pixmap_priv == NULL) { + pixmap_priv = calloc(sizeof(*pixmap_priv), 1); + glamor_set_pixmap_private(pixmap, pixmap_priv); + pixmap_priv->base.pixmap = pixmap; + pixmap_priv->base.glamor_priv = glamor_priv; + } + pixmap_priv->type = type; } _X_EXPORT void 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_pixmap_fbo *fbo; - GLenum format; - - glamor_priv = glamor_get_screen_private(screen); - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (pixmap_priv->base.fbo) { - fbo = glamor_pixmap_detach_fbo(pixmap_priv); - glamor_destroy_fbo(fbo); - } - - gl_iformat_for_depth(pixmap->drawable.depth, &format); - fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width, - pixmap->drawable.height, - format, tex, 0); - - if (fbo == NULL) { - ErrorF("XXX fail to create fbo.\n"); - return; - } - - glamor_pixmap_attach_fbo(pixmap, fbo); + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv; + glamor_pixmap_fbo *fbo; + GLenum format; + + glamor_priv = glamor_get_screen_private(screen); + pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (pixmap_priv->base.fbo) { + fbo = glamor_pixmap_detach_fbo(pixmap_priv); + glamor_destroy_fbo(fbo); + } + + gl_iformat_for_depth(pixmap->drawable.depth, &format); + fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width, + pixmap->drawable.height, format, tex, 0); + + if (fbo == NULL) { + ErrorF("XXX fail to create fbo.\n"); + return; + } + + glamor_pixmap_attach_fbo(pixmap, fbo); } void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap) { - glamor_pixmap_private *pixmap_priv; - glamor_screen_private *glamor_priv; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv; - glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen); - pixmap_priv = glamor_get_pixmap_private(screen_pixmap); - glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb; + glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen); + pixmap_priv = glamor_get_pixmap_private(screen_pixmap); + glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb; - pixmap_priv->base.fbo->width = screen_pixmap->drawable.width; - pixmap_priv->base.fbo->height = screen_pixmap->drawable.height; + pixmap_priv->base.fbo->width = screen_pixmap->drawable.width; + pixmap_priv->base.fbo->height = screen_pixmap->drawable.height; - glamor_priv->back_pixmap = back_pixmap; + glamor_priv->back_pixmap = back_pixmap; } PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, - unsigned int usage) + unsigned int usage) { - PixmapPtr pixmap; - glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY; - glamor_pixmap_private *pixmap_priv; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_pixmap_fbo *fbo; - int pitch; - GLenum format; - - if (w > 32767 || h > 32767) - return NullPixmap; - - if ((usage == GLAMOR_CREATE_PIXMAP_CPU - || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64) - || (w == 0 && h == 0) - || !glamor_check_pixmap_fbo_depth(depth)) - || (!GLAMOR_TEXTURED_LARGE_PIXMAP && - !glamor_check_fbo_size(glamor_priv, w, h))) - return fbCreatePixmap(screen, w, h, depth, usage); - else - pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); - - pixmap_priv = calloc(1, sizeof(*pixmap_priv)); - - if (!pixmap_priv) { - fbDestroyPixmap(pixmap); - return fbCreatePixmap(screen, w, h, depth, usage); - } - glamor_set_pixmap_private(pixmap, pixmap_priv); - - if (usage == GLAMOR_CREATE_PIXMAP_MAP) - type = GLAMOR_MEMORY_MAP; - - pixmap_priv->base.pixmap = pixmap; - pixmap_priv->base.glamor_priv = glamor_priv; - - gl_iformat_for_depth(depth, &format); - - pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3; - screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL); - - if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) { - pixmap_priv->type = type; - fbo = glamor_create_fbo(glamor_priv, w, h, format, usage); - } - else { - DEBUGF("Create LARGE pixmap %p width %d height %d\n", pixmap, w, h); - pixmap_priv->type = GLAMOR_TEXTURE_LARGE; - fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage, - glamor_priv->max_fbo_size, - glamor_priv->max_fbo_size, - pixmap_priv); - } - - if (fbo == NULL) { - fbDestroyPixmap(pixmap); - free(pixmap_priv); - return fbCreatePixmap(screen, w, h, depth, usage); - } - - glamor_pixmap_attach_fbo(pixmap, fbo); - - return pixmap; + PixmapPtr pixmap; + glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_fbo *fbo; + int pitch; + GLenum format; + + if (w > 32767 || h > 32767) + return NullPixmap; + + if ((usage == GLAMOR_CREATE_PIXMAP_CPU + || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64) + || (w == 0 && h == 0) + || !glamor_check_pixmap_fbo_depth(depth)) + || (!GLAMOR_TEXTURED_LARGE_PIXMAP && + !glamor_check_fbo_size(glamor_priv, w, h))) + return fbCreatePixmap(screen, w, h, depth, usage); + else + pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); + + pixmap_priv = calloc(1, sizeof(*pixmap_priv)); + + if (!pixmap_priv) { + fbDestroyPixmap(pixmap); + return fbCreatePixmap(screen, w, h, depth, usage); + } + glamor_set_pixmap_private(pixmap, pixmap_priv); + + if (usage == GLAMOR_CREATE_PIXMAP_MAP) + type = GLAMOR_MEMORY_MAP; + + pixmap_priv->base.pixmap = pixmap; + pixmap_priv->base.glamor_priv = glamor_priv; + + gl_iformat_for_depth(depth, &format); + + pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3; + screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL); + + if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) { + pixmap_priv->type = type; + fbo = glamor_create_fbo(glamor_priv, w, h, format, usage); + } + else { + DEBUGF("Create LARGE pixmap %p width %d height %d\n", pixmap, w, h); + pixmap_priv->type = GLAMOR_TEXTURE_LARGE; + fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage, + glamor_priv->max_fbo_size, + glamor_priv->max_fbo_size, pixmap_priv); + } + + if (fbo == NULL) { + fbDestroyPixmap(pixmap); + free(pixmap_priv); + return fbCreatePixmap(screen, w, h, depth, usage); + } + + glamor_pixmap_attach_fbo(pixmap, fbo); + + return pixmap; } void glamor_destroy_textured_pixmap(PixmapPtr pixmap) { - if (pixmap->refcnt == 1) { - glamor_pixmap_private *pixmap_priv; + if (pixmap->refcnt == 1) { + glamor_pixmap_private *pixmap_priv; - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (pixmap_priv != NULL) - glamor_pixmap_destroy_fbo(pixmap_priv); - } + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (pixmap_priv != NULL) + glamor_pixmap_destroy_fbo(pixmap_priv); + } } Bool glamor_destroy_pixmap(PixmapPtr pixmap) { - glamor_screen_private - *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - if (glamor_priv->dri3_enabled) - glamor_egl_destroy_textured_pixmap(pixmap); - else - glamor_destroy_textured_pixmap(pixmap); - return fbDestroyPixmap(pixmap); + glamor_screen_private + * glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + if (glamor_priv->dri3_enabled) + glamor_egl_destroy_textured_pixmap(pixmap); + else + glamor_destroy_textured_pixmap(pixmap); + return fbDestroyPixmap(pixmap); } void glamor_block_handler(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch; - - dispatch = glamor_get_dispatch(glamor_priv); - glamor_priv->tick++; - dispatch->glFlush(); - glamor_fbo_expire(glamor_priv); - glamor_put_dispatch(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; - } + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; + + dispatch = glamor_get_dispatch(glamor_priv); + glamor_priv->tick++; + dispatch->glFlush(); + glamor_fbo_expire(glamor_priv); + glamor_put_dispatch(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 -_glamor_block_handler(void *data, OSTimePtr timeout, - void *last_select_mask) +_glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask) { - glamor_screen_private *glamor_priv = data; - glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glFlush(); - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv = data; + glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv); + + dispatch->glFlush(); + glamor_put_dispatch(glamor_priv); } static void @@ -255,12 +250,13 @@ _glamor_wakeup_handler(void *data, int result, void *last_select_mask) static void glamor_set_debug_level(int *debug_level) { - char *debug_level_string; - debug_level_string = getenv("GLAMOR_DEBUG"); - if (debug_level_string - && sscanf(debug_level_string, "%d", debug_level) == 1) - return; - *debug_level = 0; + char *debug_level_string; + + debug_level_string = getenv("GLAMOR_DEBUG"); + if (debug_level_string + && sscanf(debug_level_string, "%d", debug_level) == 1) + return; + *debug_level = 0; } int glamor_debug_level; @@ -269,360 +265,350 @@ int glamor_debug_level; Bool glamor_init(ScreenPtr screen, unsigned int flags) { - glamor_screen_private *glamor_priv; - int gl_version; + glamor_screen_private *glamor_priv; + int gl_version; #ifdef RENDER - PictureScreenPtr ps = GetPictureScreenIfSet(screen); + PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif - if (flags & ~GLAMOR_VALID_FLAGS) { - ErrorF("glamor_init: Invalid flags %x\n", flags); - return FALSE; - } - glamor_priv = calloc(1, sizeof(*glamor_priv)); - if (glamor_priv == NULL) - return FALSE; - - if (flags & GLAMOR_INVERTED_Y_AXIS) { - glamor_priv->yInverted = 1; - } else - glamor_priv->yInverted = 0; - - if (!dixRegisterPrivateKey - (glamor_screen_private_key, PRIVATE_SCREEN, 0)) { - LogMessage(X_WARNING, - "glamor%d: Failed to allocate screen private\n", - screen->myNum); - goto fail; - } - - glamor_set_screen_private(screen, glamor_priv); - - if (!dixRegisterPrivateKey - (glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) { - LogMessage(X_WARNING, - "glamor%d: Failed to allocate pixmap private\n", - screen->myNum); - goto fail;; - } - - gl_version = glamor_gl_get_version(); + if (flags & ~GLAMOR_VALID_FLAGS) { + ErrorF("glamor_init: Invalid flags %x\n", flags); + return FALSE; + } + glamor_priv = calloc(1, sizeof(*glamor_priv)); + if (glamor_priv == NULL) + return FALSE; + + if (flags & GLAMOR_INVERTED_Y_AXIS) { + glamor_priv->yInverted = 1; + } + else + glamor_priv->yInverted = 0; + + if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) { + LogMessage(X_WARNING, + "glamor%d: Failed to allocate screen private\n", + screen->myNum); + goto fail; + } + + glamor_set_screen_private(screen, glamor_priv); + + if (!dixRegisterPrivateKey(glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) { + LogMessage(X_WARNING, + "glamor%d: Failed to allocate pixmap private\n", + screen->myNum); + goto fail;; + } + + gl_version = glamor_gl_get_version(); #ifndef GLAMOR_GLES2 - if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) { - ErrorF("Require OpenGL version 1.3 or latter.\n"); - goto fail; - } + if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) { + ErrorF("Require OpenGL version 1.3 or latter.\n"); + goto fail; + } #else - if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) { - ErrorF("Require Open GLES2.0 or latter.\n"); - goto fail; - } + if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) { + ErrorF("Require Open GLES2.0 or latter.\n"); + goto fail; + } #endif - glamor_gl_dispatch_init(screen, &glamor_priv->_dispatch, gl_version); + glamor_gl_dispatch_init(screen, &glamor_priv->_dispatch, gl_version); #ifdef GLAMOR_GLES2 - if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) { - ErrorF("GL_EXT_texture_format_BGRA8888 required\n"); - goto fail; - } + if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) { + ErrorF("GL_EXT_texture_format_BGRA8888 required\n"); + goto fail; + } #endif - glamor_priv->has_pack_invert = - glamor_gl_has_extension("GL_MESA_pack_invert"); - glamor_priv->has_fbo_blit = - glamor_gl_has_extension("GL_EXT_framebuffer_blit"); - glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, - &glamor_priv->max_fbo_size); + glamor_priv->has_pack_invert = + glamor_gl_has_extension("GL_MESA_pack_invert"); + glamor_priv->has_fbo_blit = + glamor_gl_has_extension("GL_EXT_framebuffer_blit"); + glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, + &glamor_priv->max_fbo_size); #ifdef MAX_FBO_SIZE - glamor_priv->max_fbo_size = MAX_FBO_SIZE; + glamor_priv->max_fbo_size = MAX_FBO_SIZE; #endif - glamor_set_debug_level(&glamor_debug_level); + glamor_set_debug_level(&glamor_debug_level); #ifdef GLAMOR_GLES2 - glamor_priv->gl_flavor = GLAMOR_GL_ES2; + glamor_priv->gl_flavor = GLAMOR_GL_ES2; #else - glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP; + glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP; #endif - /* If we are using egl screen, call egl screen init to - * register correct close screen function. */ - if (flags & GLAMOR_USE_EGL_SCREEN) - glamor_egl_screen_init(screen); + /* If we are using egl screen, call egl screen init to + * register correct close screen function. */ + if (flags & GLAMOR_USE_EGL_SCREEN) + glamor_egl_screen_init(screen); - glamor_priv->saved_procs.close_screen = screen->CloseScreen; - screen->CloseScreen = glamor_close_screen; + glamor_priv->saved_procs.close_screen = screen->CloseScreen; + screen->CloseScreen = glamor_close_screen; - if (flags & GLAMOR_USE_SCREEN) { - if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler, - _glamor_wakeup_handler, - glamor_priv)) { - goto fail; - } + if (flags & GLAMOR_USE_SCREEN) { + if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler, + _glamor_wakeup_handler, + glamor_priv)) { + goto fail; + } - glamor_priv->saved_procs.create_gc = screen->CreateGC; - screen->CreateGC = glamor_create_gc; + glamor_priv->saved_procs.create_gc = screen->CreateGC; + screen->CreateGC = glamor_create_gc; - glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap; - screen->CreatePixmap = glamor_create_pixmap; + glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap; + screen->CreatePixmap = glamor_create_pixmap; - glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap; - screen->DestroyPixmap = glamor_destroy_pixmap; + glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap; + screen->DestroyPixmap = glamor_destroy_pixmap; - glamor_priv->saved_procs.get_spans = screen->GetSpans; - screen->GetSpans = glamor_get_spans; + glamor_priv->saved_procs.get_spans = screen->GetSpans; + screen->GetSpans = glamor_get_spans; - glamor_priv->saved_procs.get_image = screen->GetImage; - screen->GetImage = glamor_get_image; + glamor_priv->saved_procs.get_image = screen->GetImage; + screen->GetImage = glamor_get_image; - glamor_priv->saved_procs.change_window_attributes = - screen->ChangeWindowAttributes; - screen->ChangeWindowAttributes = - glamor_change_window_attributes; + glamor_priv->saved_procs.change_window_attributes = + screen->ChangeWindowAttributes; + screen->ChangeWindowAttributes = glamor_change_window_attributes; - glamor_priv->saved_procs.copy_window = screen->CopyWindow; - screen->CopyWindow = glamor_copy_window; + glamor_priv->saved_procs.copy_window = screen->CopyWindow; + screen->CopyWindow = glamor_copy_window; - glamor_priv->saved_procs.bitmap_to_region = - screen->BitmapToRegion; - screen->BitmapToRegion = glamor_bitmap_to_region; - } + glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion; + screen->BitmapToRegion = glamor_bitmap_to_region; + } #ifdef RENDER - if (flags & GLAMOR_USE_PICTURE_SCREEN) { - glamor_priv->saved_procs.composite = ps->Composite; - ps->Composite = glamor_composite; - + if (flags & GLAMOR_USE_PICTURE_SCREEN) { + glamor_priv->saved_procs.composite = ps->Composite; + ps->Composite = glamor_composite; - glamor_priv->saved_procs.trapezoids = ps->Trapezoids; - ps->Trapezoids = glamor_trapezoids; + glamor_priv->saved_procs.trapezoids = ps->Trapezoids; + ps->Trapezoids = glamor_trapezoids; + glamor_priv->saved_procs.triangles = ps->Triangles; + ps->Triangles = glamor_triangles; - glamor_priv->saved_procs.triangles = ps->Triangles; - ps->Triangles = glamor_triangles; + glamor_priv->saved_procs.addtraps = ps->AddTraps; + ps->AddTraps = glamor_add_traps; - glamor_priv->saved_procs.addtraps = ps->AddTraps; - ps->AddTraps = glamor_add_traps; + } - } + glamor_priv->saved_procs.composite_rects = ps->CompositeRects; + ps->CompositeRects = glamor_composite_rectangles; - glamor_priv->saved_procs.composite_rects = ps->CompositeRects; - ps->CompositeRects = glamor_composite_rectangles; + glamor_priv->saved_procs.glyphs = ps->Glyphs; + ps->Glyphs = glamor_glyphs; - glamor_priv->saved_procs.glyphs = ps->Glyphs; - ps->Glyphs = glamor_glyphs; + glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph; + ps->UnrealizeGlyph = glamor_glyph_unrealize; - glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph; - ps->UnrealizeGlyph = glamor_glyph_unrealize; + glamor_priv->saved_procs.create_picture = ps->CreatePicture; + ps->CreatePicture = glamor_create_picture; - glamor_priv->saved_procs.create_picture = ps->CreatePicture; - ps->CreatePicture = glamor_create_picture; + glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap; + screen->SetWindowPixmap = glamor_set_window_pixmap; - glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap; - screen->SetWindowPixmap = glamor_set_window_pixmap; - - glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture; - ps->DestroyPicture = glamor_destroy_picture; - glamor_init_composite_shaders(screen); + glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture; + ps->DestroyPicture = glamor_destroy_picture; + glamor_init_composite_shaders(screen); #endif - glamor_init_pixmap_fbo(screen); - glamor_init_solid_shader(screen); - glamor_init_tile_shader(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); + glamor_init_trapezoid_shader(screen); #endif - glamor_init_putimage_shaders(screen); - glamor_init_finish_access_shaders(screen); + glamor_init_putimage_shaders(screen); + glamor_init_finish_access_shaders(screen); #ifdef GLAMOR_GRADIENT_SHADER - glamor_init_gradient_shader(screen); + glamor_init_gradient_shader(screen); #endif #ifdef GLAMOR_XV - glamor_init_xv_shader(screen); + glamor_init_xv_shader(screen); #endif - glamor_pixmap_init(screen); + glamor_pixmap_init(screen); - glamor_priv->flags = flags; - glamor_priv->screen = screen; + glamor_priv->flags = flags; + glamor_priv->screen = screen; - return TRUE; + return TRUE; - fail: - free(glamor_priv); - glamor_set_screen_private(screen, NULL); - return FALSE; + fail: + free(glamor_priv); + glamor_set_screen_private(screen, NULL); + return FALSE; } static void glamor_release_screen_priv(ScreenPtr screen) { - glamor_screen_private *glamor_priv; + glamor_screen_private *glamor_priv; - glamor_priv = glamor_get_screen_private(screen); + glamor_priv = glamor_get_screen_private(screen); #ifdef GLAMOR_XV - glamor_fini_xv_shader(screen); + glamor_fini_xv_shader(screen); #endif #ifdef RENDER - glamor_fini_composite_shaders(screen); + glamor_fini_composite_shaders(screen); #endif - glamor_fini_pixmap_fbo(screen); - glamor_fini_solid_shader(screen); - glamor_fini_tile_shader(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); + glamor_fini_trapezoid_shader(screen); #endif - glamor_fini_putimage_shaders(screen); - glamor_fini_finish_access_shaders(screen); + glamor_fini_putimage_shaders(screen); + glamor_fini_finish_access_shaders(screen); #ifdef GLAMOR_GRADIENT_SHADER - glamor_fini_gradient_shader(screen); + glamor_fini_gradient_shader(screen); #endif - glamor_pixmap_fini(screen); - free(glamor_priv); + glamor_pixmap_fini(screen); + free(glamor_priv); - glamor_set_screen_private(screen, NULL); + glamor_set_screen_private(screen, NULL); } _X_EXPORT void -glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv) +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); - - if (priv) { - assert(old_priv == NULL); - } else { - if (old_priv == NULL) - return; - fbo = glamor_pixmap_detach_fbo(old_priv); - glamor_purge_fbo(fbo); - free(old_priv); - } - - dixSetPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key, - priv); + glamor_pixmap_private *old_priv; + glamor_pixmap_fbo *fbo; + + old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); + + if (priv) { + assert(old_priv == NULL); + } + else { + if (old_priv == NULL) + return; + fbo = glamor_pixmap_detach_fbo(old_priv); + glamor_purge_fbo(fbo); + free(old_priv); + } + + dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv); } Bool glamor_close_screen(CLOSE_SCREEN_ARGS_DECL) { - glamor_screen_private *glamor_priv; - PixmapPtr screen_pixmap; - int flags; + glamor_screen_private *glamor_priv; + PixmapPtr screen_pixmap; + int flags; + #ifdef RENDER - PictureScreenPtr ps = GetPictureScreenIfSet(screen); + PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif - glamor_priv = glamor_get_screen_private(screen); - flags = glamor_priv->flags; - glamor_glyphs_fini(screen); - screen->CloseScreen = glamor_priv->saved_procs.close_screen; - if (flags & GLAMOR_USE_SCREEN) { - - screen->CreateGC = glamor_priv->saved_procs.create_gc; - screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap; - screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap; - screen->GetSpans = glamor_priv->saved_procs.get_spans; - screen->ChangeWindowAttributes = - glamor_priv->saved_procs.change_window_attributes; - screen->CopyWindow = glamor_priv->saved_procs.copy_window; - screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region; - } + glamor_priv = glamor_get_screen_private(screen); + flags = glamor_priv->flags; + glamor_glyphs_fini(screen); + screen->CloseScreen = glamor_priv->saved_procs.close_screen; + if (flags & GLAMOR_USE_SCREEN) { + + screen->CreateGC = glamor_priv->saved_procs.create_gc; + screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap; + screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap; + screen->GetSpans = glamor_priv->saved_procs.get_spans; + screen->ChangeWindowAttributes = + glamor_priv->saved_procs.change_window_attributes; + screen->CopyWindow = glamor_priv->saved_procs.copy_window; + screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region; + } #ifdef RENDER - if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) { - - ps->Composite = glamor_priv->saved_procs.composite; - ps->Trapezoids = glamor_priv->saved_procs.trapezoids; - ps->Triangles = glamor_priv->saved_procs.triangles; - ps->CreatePicture = glamor_priv->saved_procs.create_picture; - } - ps->CompositeRects = glamor_priv->saved_procs.composite_rects; - ps->Glyphs = glamor_priv->saved_procs.glyphs; - ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph; - screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap; + if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) { + + ps->Composite = glamor_priv->saved_procs.composite; + ps->Trapezoids = glamor_priv->saved_procs.trapezoids; + ps->Triangles = glamor_priv->saved_procs.triangles; + ps->CreatePicture = glamor_priv->saved_procs.create_picture; + } + ps->CompositeRects = glamor_priv->saved_procs.composite_rects; + ps->Glyphs = glamor_priv->saved_procs.glyphs; + ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph; + screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap; #endif - screen_pixmap = screen->GetScreenPixmap(screen); - glamor_set_pixmap_private(screen_pixmap, NULL); - if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap) - glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL); + screen_pixmap = screen->GetScreenPixmap(screen); + glamor_set_pixmap_private(screen_pixmap, NULL); + if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap) + glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL); - glamor_release_screen_priv(screen); + glamor_release_screen_priv(screen); - return screen->CloseScreen(CLOSE_SCREEN_ARGS); + return screen->CloseScreen(CLOSE_SCREEN_ARGS); } - void glamor_fini(ScreenPtr screen) { - /* Do nothing currently. */ + /* Do nothing currently. */ } -void glamor_enable_dri3(ScreenPtr screen) +void +glamor_enable_dri3(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_priv->dri3_enabled = TRUE; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + glamor_priv->dri3_enabled = TRUE; } -Bool glamor_is_dri3_support_enabled(ScreenPtr screen) +Bool +glamor_is_dri3_support_enabled(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - return glamor_priv->dri3_enabled; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + return glamor_priv->dri3_enabled; } int -glamor_dri3_fd_from_pixmap (ScreenPtr screen, - PixmapPtr pixmap, - CARD16 *stride, - CARD32 *size) +glamor_dri3_fd_from_pixmap(ScreenPtr screen, + PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { - glamor_pixmap_private *pixmap_priv; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (pixmap_priv == NULL || !glamor_priv->dri3_enabled) - return -1; - switch (pixmap_priv->type) - { - case GLAMOR_TEXTURE_DRM: - case GLAMOR_TEXTURE_ONLY: - glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0); - return glamor_egl_dri3_fd_name_from_tex(screen, - pixmap, - pixmap_priv->base.fbo->tex, - FALSE, - stride, - size); - default: break; - } - return -1; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (pixmap_priv == NULL || !glamor_priv->dri3_enabled) + return -1; + switch (pixmap_priv->type) { + case GLAMOR_TEXTURE_DRM: + case GLAMOR_TEXTURE_ONLY: + glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0); + return glamor_egl_dri3_fd_name_from_tex(screen, + pixmap, + pixmap_priv->base.fbo->tex, + FALSE, stride, size); + default: + break; + } + return -1; } int -glamor_dri3_name_from_pixmap (PixmapPtr pixmap) +glamor_dri3_name_from_pixmap(PixmapPtr pixmap) { - glamor_pixmap_private *pixmap_priv; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (pixmap_priv == NULL || !glamor_priv->dri3_enabled) - return -1; - switch (pixmap_priv->type) - { - case GLAMOR_TEXTURE_DRM: - case GLAMOR_TEXTURE_ONLY: - glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0); - return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen, - pixmap, - pixmap_priv->base.fbo->tex, - TRUE, - NULL, - NULL); - default: break; - } - return -1; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (pixmap_priv == NULL || !glamor_priv->dri3_enabled) + return -1; + switch (pixmap_priv->type) { + case GLAMOR_TEXTURE_DRM: + case GLAMOR_TEXTURE_ONLY: + glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0); + return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen, + pixmap, + pixmap_priv->base.fbo->tex, + TRUE, NULL, NULL); + default: + break; + } + return -1; } diff --git a/glamor/glamor.h b/glamor/glamor.h index 1bb48ed..1507565 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -48,15 +48,15 @@ * @DRM_ONLY: pixmap is in a external DRM buffer. * @TEXTURE_ONLY: pixmap is in an internal texture. */ -typedef enum glamor_pixmap_type { - GLAMOR_MEMORY, - GLAMOR_MEMORY_MAP, - GLAMOR_TEXTURE_DRM, - GLAMOR_SEPARATE_TEXTURE, - GLAMOR_DRM_ONLY, - GLAMOR_TEXTURE_ONLY, - GLAMOR_TEXTURE_LARGE, - GLAMOR_TEXTURE_PACK +typedef enum glamor_pixmap_type { + GLAMOR_MEMORY, + GLAMOR_MEMORY_MAP, + GLAMOR_TEXTURE_DRM, + GLAMOR_SEPARATE_TEXTURE, + GLAMOR_DRM_ONLY, + GLAMOR_TEXTURE_ONLY, + GLAMOR_TEXTURE_LARGE, + GLAMOR_TEXTURE_PACK } glamor_pixmap_type_t; #define GLAMOR_EGL_EXTERNAL_BUFFER 3 @@ -122,11 +122,11 @@ extern _X_EXPORT Bool glamor_close_screen(int scrnIndex, ScreenPtr screen); extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen); #endif - /* Let glamor to know the screen's fbo. The low level * driver should already assign a tex * to this pixmap through the set_pixmap_texture. */ -extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap); +extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, + PixmapPtr *back_pixmap); /* @glamor_glyphs_init: Initialize glyphs internal data structures. * @@ -139,13 +139,14 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPt extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen); extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, - unsigned int tex); + unsigned int tex); -extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type); +extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, + glamor_pixmap_type_t type); extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap); extern _X_EXPORT void glamor_block_handler(ScreenPtr screen); -extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, - unsigned int usage); +extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, + int depth, unsigned int usage); extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen); @@ -160,14 +161,21 @@ extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen); * Used by the DRI2 page flip. This function will exchange the KHR images and * fbos of the two pixmaps. * */ -extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back); +extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, + PixmapPtr back); -extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back); +extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, + PixmapPtr back); /* The DDX is not supposed to call these three functions */ extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen); -extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h); -extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr, unsigned int, Bool, CARD16*, CARD32*); +extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr + screen, + int w, + int h); +extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr, + unsigned int, Bool, + CARD16 *, CARD32 *); /* @glamor_is_dri3_support_enabled: Returns if DRI3 support is enabled. * @@ -194,10 +202,9 @@ extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen); * content. * Returns the fd on success, -1 on error. * */ -extern _X_EXPORT int glamor_dri3_fd_from_pixmap (ScreenPtr screen, - PixmapPtr pixmap, - CARD16 *stride, - CARD32 *size); +extern _X_EXPORT int glamor_dri3_fd_from_pixmap(ScreenPtr screen, + PixmapPtr pixmap, + CARD16 *stride, CARD32 *size); /* @glamor_dri3_name_from_pixmap: helper to get an gem name from a pixmap. * @@ -208,7 +215,7 @@ extern _X_EXPORT int glamor_dri3_fd_from_pixmap (ScreenPtr screen, * glamor DRI3 support to be activated. * Returns the name on success, -1 on error. * */ -extern _X_EXPORT int glamor_dri3_name_from_pixmap (PixmapPtr pixmap); +extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap); /* @glamor_egl_dri3_pixmap_from_fd: DRI3 helper to get a pixmap from a dma-buf fd. * @@ -222,13 +229,13 @@ extern _X_EXPORT int glamor_dri3_name_from_pixmap (PixmapPtr pixmap); * * Returns a valid pixmap if the import succeeded, else NULL. * */ -extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen, - int fd, - CARD16 width, - CARD16 height, - CARD16 stride, - CARD8 depth, - CARD8 bpp); +extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, + int fd, + CARD16 width, + CARD16 height, + CARD16 stride, + CARD8 depth, + CARD8 bpp); #ifdef GLAMOR_FOR_XORG @@ -265,8 +272,7 @@ extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen); * screen pixmap is a special, we handle it separately in this function. */ extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen, - int handle, - int stride); + int handle, int stride); /* @glamor_egl_create_textured_screen_ext: * @@ -275,9 +281,10 @@ extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen, * the DDX's close screen, we have to free all the glamor related resources. */ extern _X_EXPORT Bool glamor_egl_create_textured_screen_ext(ScreenPtr screen, - int handle, - int stride, - PixmapPtr *back_pixmap); + int handle, + int stride, + PixmapPtr + *back_pixmap); /* * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from @@ -292,8 +299,7 @@ extern _X_EXPORT Bool glamor_egl_create_textured_screen_ext(ScreenPtr screen, * as well. Return true if successful, otherwise return FALSE. */ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap, - int handle, - int stride); + int handle, int stride); /* * @glamor_egl_create_textured_pixmap_from_bo: Try to create a textured pixmap @@ -305,8 +311,7 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap, * This function is similar to glamor_egl_create_textured_pixmap. */ extern _X_EXPORT Bool - glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, - void *bo); + glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo); #endif @@ -314,119 +319,129 @@ extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap); 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_validate_gc(GCPtr gc, unsigned long changes, + DrawablePtr drawable); /* Glamor rendering/drawing functions with XXX_nf. * nf means no fallback within glamor internal if possible. If glamor * fail to accelerate the operation, glamor will return a false, and the * caller need to implement fallback method. Return a true means the * rendering request get done successfully. */ extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable, - GCPtr gc, - int n, DDXPointPtr points, - int *widths, int sorted); + GCPtr gc, + int n, DDXPointPtr points, + int *widths, int sorted); extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable, - GCPtr gc, - int nrect, - xRectangle * prect); + GCPtr gc, + int nrect, xRectangle *prect); extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable, - GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, - int image_format, char *bits); + GCPtr gc, int depth, int x, int y, + int w, int h, int left_pad, + int image_format, char *bits); extern _X_EXPORT 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); + 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, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, INT16 y_dest, - CARD16 width, CARD16 height); + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, + CARD16 width, CARD16 height); extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op, - PicturePtr src, PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, INT16 y_src, - int ntrap, xTrapezoid * traps); + PicturePtr src, PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, INT16 y_src, + int ntrap, xTrapezoid * traps); extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, int nlist, - GlyphListPtr list, GlyphPtr * glyphs); + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, int nlist, + GlyphListPtr list, GlyphPtr * glyphs); extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, - int ntris, xTriangle * tris); - + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, + int ntris, xTriangle * tris); extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph); -extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src, - DDXPointPtr points, int *widths, int n, int sorted); +extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, + char *src, DDXPointPtr points, + int *widths, int n, int sorted); extern _X_EXPORT Bool glamor_get_spans_nf(DrawablePtr drawable, int wmax, - DDXPointPtr points, int *widths, int count, char *dst); + DDXPointPtr points, int *widths, + int count, char *dst); -extern _X_EXPORT Bool glamor_composite_rects_nf (CARD8 op, - PicturePtr pDst, - xRenderColor *color, - int nRect, - xRectangle *rects); +extern _X_EXPORT Bool glamor_composite_rects_nf(CARD8 op, + PicturePtr pDst, + xRenderColor * color, + int nRect, xRectangle *rects); -extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d); +extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, + int w, int h, unsigned int format, + unsigned long planeMask, char *d); extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture, - INT16 x_off, - INT16 y_off, int ntrap, xTrap * traps); - -extern _X_EXPORT 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); - -extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase); + INT16 x_off, + INT16 y_off, int ntrap, + xTrap * traps); + +extern _X_EXPORT 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); + +extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable, + GCPtr pGC, int x, int y, + unsigned int nglyph, + CharInfoPtr * ppci, + pointer pglyphBase); extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase); + int x, int y, + unsigned int nglyph, + CharInfoPtr * ppci, + pointer pglyphBase); extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y); + DrawablePtr pDrawable, int w, int h, + int x, int y); -extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt); +extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr ppt); -extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg); +extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, + int nseg, xSegment * pSeg); -extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt); +extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr ppt); -extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points); +extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, + int mode, int n, DDXPointPtr points); -extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen, int num_texture_ports); +extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen, + int num_texture_ports); -#endif /* GLAMOR_H */ +#endif /* GLAMOR_H */ diff --git a/glamor/glamor_addtraps.c b/glamor/glamor_addtraps.c index ac85296..7a918b7 100644 --- a/glamor/glamor_addtraps.c +++ b/glamor/glamor_addtraps.c @@ -30,36 +30,32 @@ static Bool _glamor_add_traps(PicturePtr pPicture, - INT16 x_off, - INT16 y_off, int ntrap, xTrap * traps, - Bool fallback) + INT16 x_off, + INT16 y_off, int ntrap, xTrap * traps, Bool fallback) { - if (!fallback - && ( !pPicture->pDrawable - || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable))) - return FALSE; + if (!fallback + && (!pPicture->pDrawable + || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable))) + return FALSE; - if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) { - fbAddTraps(pPicture, x_off, y_off, ntrap, traps); - glamor_finish_access_picture(pPicture, GLAMOR_ACCESS_RW); - } + if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) { + fbAddTraps(pPicture, x_off, y_off, ntrap, traps); + glamor_finish_access_picture(pPicture, GLAMOR_ACCESS_RW); + } - return TRUE; + return TRUE; } void glamor_add_traps(PicturePtr pPicture, - INT16 x_off, - INT16 y_off, int ntrap, xTrap * traps) + INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) { - _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE); + _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE); } Bool glamor_add_traps_nf(PicturePtr pPicture, - INT16 x_off, - INT16 y_off, int ntrap, xTrap * traps) + INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) { - return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE); + return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE); } - diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c index 1a57699..a0d5980 100644 --- a/glamor/glamor_compositerects.c +++ b/glamor/glamor_compositerects.c @@ -36,243 +36,241 @@ * compositeRects acceleration implementation */ -static int16_t bound(int16_t a, uint16_t b) +static int16_t +bound(int16_t a, uint16_t b) { - int v = (int)a + (int)b; - if (v > MAXSHORT) - return MAXSHORT; - return v; + int v = (int) a + (int) b; + + if (v > MAXSHORT) + return MAXSHORT; + return v; } static Bool -_pixman_region_init_clipped_rectangles(pixman_region16_t *region, - unsigned int num_rects, - xRectangle *rects, - int tx, int ty, - BoxPtr extents) +_pixman_region_init_clipped_rectangles(pixman_region16_t * region, + unsigned int num_rects, + xRectangle *rects, + int tx, int ty, BoxPtr extents) { - pixman_box16_t stack_boxes[64], *boxes = stack_boxes; - pixman_bool_t ret; - unsigned int i, j; - - if (num_rects > ARRAY_SIZE(stack_boxes)) { - boxes = malloc(sizeof(pixman_box16_t) * num_rects); - if (boxes == NULL) - return FALSE; - } - - for (i = j = 0; i < num_rects; i++) { - boxes[j].x1 = rects[i].x + tx; - if (boxes[j].x1 < extents->x1) - boxes[j].x1 = extents->x1; - - boxes[j].y1 = rects[i].y + ty; - if (boxes[j].y1 < extents->y1) - boxes[j].y1 = extents->y1; - - boxes[j].x2 = bound(rects[i].x + tx, rects[i].width); - if (boxes[j].x2 > extents->x2) - boxes[j].x2 = extents->x2; - - boxes[j].y2 = bound(rects[i].y + ty, rects[i].height); - if (boxes[j].y2 > extents->y2) - boxes[j].y2 = extents->y2; - - if (boxes[j].x2 > boxes[j].x1 && boxes[j].y2 > boxes[j].y1) - j++; - } - - ret = FALSE; - if (j) - ret = pixman_region_init_rects(region, boxes, j); - - if (boxes != stack_boxes) - free(boxes); - - DEBUGF("%s: nrects=%d, region=(%d, %d), (%d, %d) x %d\n", - __FUNCTION__, num_rects, - region->extents.x1, region->extents.y1, - region->extents.x2, region->extents.y2, - j); - return ret; + pixman_box16_t stack_boxes[64], *boxes = stack_boxes; + pixman_bool_t ret; + unsigned int i, j; + + if (num_rects > ARRAY_SIZE(stack_boxes)) { + boxes = malloc(sizeof(pixman_box16_t) * num_rects); + if (boxes == NULL) + return FALSE; + } + + for (i = j = 0; i < num_rects; i++) { + boxes[j].x1 = rects[i].x + tx; + if (boxes[j].x1 < extents->x1) + boxes[j].x1 = extents->x1; + + boxes[j].y1 = rects[i].y + ty; + if (boxes[j].y1 < extents->y1) + boxes[j].y1 = extents->y1; + + boxes[j].x2 = bound(rects[i].x + tx, rects[i].width); + if (boxes[j].x2 > extents->x2) + boxes[j].x2 = extents->x2; + + boxes[j].y2 = bound(rects[i].y + ty, rects[i].height); + if (boxes[j].y2 > extents->y2) + boxes[j].y2 = extents->y2; + + if (boxes[j].x2 > boxes[j].x1 && boxes[j].y2 > boxes[j].y1) + j++; + } + + ret = FALSE; + if (j) + ret = pixman_region_init_rects(region, boxes, j); + + if (boxes != stack_boxes) + free(boxes); + + DEBUGF("%s: nrects=%d, region=(%d, %d), (%d, %d) x %d\n", + __FUNCTION__, num_rects, + region->extents.x1, region->extents.y1, + region->extents.x2, region->extents.y2, j); + return ret; } - void -glamor_composite_rectangles(CARD8 op, - PicturePtr dst, - xRenderColor *color, - int num_rects, - xRectangle *rects) +glamor_composite_rectangles(CARD8 op, + PicturePtr dst, + xRenderColor * color, + int num_rects, xRectangle *rects) { - PixmapPtr pixmap; - struct glamor_pixmap_private *priv; - pixman_region16_t region; - pixman_box16_t *boxes; - int dst_x, dst_y; - int num_boxes; - PicturePtr source = NULL; - Bool need_free_region = FALSE; - - DEBUGF("%s(op=%d, %08x x %d [(%d, %d)x(%d, %d) ...])\n", - __FUNCTION__, op, - (color->alpha >> 8 << 24) | - (color->red >> 8 << 16) | - (color->green >> 8 << 8) | - (color->blue >> 8 << 0), - num_rects, - rects[0].x, rects[0].y, rects[0].width, rects[0].height); - - if (!num_rects) - return; - - if (region_is_empty(dst->pCompositeClip)) { - DEBUGF("%s: empty clip, skipping\n", __FUNCTION__); - return; - } - - if ((color->red|color->green|color->blue|color->alpha) <= 0x00ff) { - switch (op) { - case PictOpOver: - case PictOpOutReverse: - case PictOpAdd: - return; - case PictOpInReverse: - case PictOpSrc: - op = PictOpClear; - break; - case PictOpAtopReverse: - op = PictOpOut; - break; - case PictOpXor: - op = PictOpOverReverse; - break; - } - } - if (color->alpha <= 0x00ff) { - switch (op) { - case PictOpOver: - case PictOpOutReverse: - return; - case PictOpInReverse: - op = PictOpClear; - break; - case PictOpAtopReverse: - op = PictOpOut; - break; - case PictOpXor: - op = PictOpOverReverse; - break; - } - } else if (color->alpha >= 0xff00) { - switch (op) { - case PictOpOver: - op = PictOpSrc; - break; - case PictOpInReverse: - return; - case PictOpOutReverse: - op = PictOpClear; - break; - case PictOpAtopReverse: - op = PictOpOverReverse; - break; - case PictOpXor: - op = PictOpOut; - break; - } - } - DEBUGF("%s: converted to op %d\n", __FUNCTION__, op); - - if (!_pixman_region_init_clipped_rectangles(®ion, - num_rects, rects, - dst->pDrawable->x, - dst->pDrawable->y, - &dst->pCompositeClip->extents)) - { - DEBUGF("%s: allocation failed for region\n", __FUNCTION__); - return; - } - - pixmap = glamor_get_drawable_pixmap(dst->pDrawable); - priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) - goto fallback; - if (dst->alphaMap) { - DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__); - goto fallback; - } - - need_free_region = TRUE; - - DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n", - __FUNCTION__, - RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, - RegionExtents(®ion)->x2, RegionExtents(®ion)->y2, - RegionNumRects(®ion)); - - if (dst->pCompositeClip->data && - (!pixman_region_intersect(®ion, ®ion, dst->pCompositeClip) || - region_is_empty(®ion))) { - DEBUGF("%s: zero-intersection between rectangles and clip\n", - __FUNCTION__); - pixman_region_fini(®ion); - return; - } - - DEBUGF("%s: clipped extents (%d, %d),(%d, %d) x %d\n", - __FUNCTION__, - RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, - RegionExtents(®ion)->x2, RegionExtents(®ion)->y2, - RegionNumRects(®ion)); - - glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y); - pixman_region_translate(®ion, dst_x, dst_y); - - DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n", - __FUNCTION__, dst_x, dst_y, - RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, - RegionExtents(®ion)->x2, RegionExtents(®ion)->y2); - - - boxes = pixman_region_rectangles(®ion, &num_boxes); - if (op == PictOpSrc || op == PictOpClear) { - CARD32 pixel; - if (op == PictOpClear) - pixel = 0; - else - miRenderColorToPixel(dst->pFormat, color, &pixel); - glamor_solid_boxes(pixmap, boxes, num_boxes, pixel); - - goto done; - } else { - if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) { - int error; - - source = CreateSolidPicture(0, color, &error); - if (!source) - goto done; - if (glamor_composite_clipped_region(op, source, - NULL, dst, - NULL, NULL, priv, - ®ion, - 0,0,0,0,0,0)) - goto done; - } - } -fallback: - miCompositeRects(op, dst, color, num_rects, rects); -done: - /* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must - * manually append the damaged regions ourselves. - */ - DamageRegionAppend(&pixmap->drawable, ®ion); - DamageRegionProcessPending(&pixmap->drawable); - - if (need_free_region) - pixman_region_fini(®ion); - if (source) - FreePicture(source, 0); - return; + PixmapPtr pixmap; + struct glamor_pixmap_private *priv; + pixman_region16_t region; + pixman_box16_t *boxes; + int dst_x, dst_y; + int num_boxes; + PicturePtr source = NULL; + Bool need_free_region = FALSE; + + DEBUGF("%s(op=%d, %08x x %d [(%d, %d)x(%d, %d) ...])\n", + __FUNCTION__, op, + (color->alpha >> 8 << 24) | + (color->red >> 8 << 16) | + (color->green >> 8 << 8) | + (color->blue >> 8 << 0), + num_rects, rects[0].x, rects[0].y, rects[0].width, rects[0].height); + + if (!num_rects) + return; + + if (region_is_empty(dst->pCompositeClip)) { + DEBUGF("%s: empty clip, skipping\n", __FUNCTION__); + return; + } + + if ((color->red | color->green | color->blue | color->alpha) <= 0x00ff) { + switch (op) { + case PictOpOver: + case PictOpOutReverse: + case PictOpAdd: + return; + case PictOpInReverse: + case PictOpSrc: + op = PictOpClear; + break; + case PictOpAtopReverse: + op = PictOpOut; + break; + case PictOpXor: + op = PictOpOverReverse; + break; + } + } + if (color->alpha <= 0x00ff) { + switch (op) { + case PictOpOver: + case PictOpOutReverse: + return; + case PictOpInReverse: + op = PictOpClear; + break; + case PictOpAtopReverse: + op = PictOpOut; + break; + case PictOpXor: + op = PictOpOverReverse; + break; + } + } + else if (color->alpha >= 0xff00) { + switch (op) { + case PictOpOver: + op = PictOpSrc; + break; + case PictOpInReverse: + return; + case PictOpOutReverse: + op = PictOpClear; + break; + case PictOpAtopReverse: + op = PictOpOverReverse; + break; + case PictOpXor: + op = PictOpOut; + break; + } + } + DEBUGF("%s: converted to op %d\n", __FUNCTION__, op); + + if (!_pixman_region_init_clipped_rectangles(®ion, + num_rects, rects, + dst->pDrawable->x, + dst->pDrawable->y, + &dst->pCompositeClip->extents)) + { + DEBUGF("%s: allocation failed for region\n", __FUNCTION__); + return; + } + + pixmap = glamor_get_drawable_pixmap(dst->pDrawable); + priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv)) + goto fallback; + if (dst->alphaMap) { + DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__); + goto fallback; + } + + need_free_region = TRUE; + + DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n", + __FUNCTION__, + RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, + RegionExtents(®ion)->x2, RegionExtents(®ion)->y2, + RegionNumRects(®ion)); + + if (dst->pCompositeClip->data && + (!pixman_region_intersect(®ion, ®ion, dst->pCompositeClip) || + region_is_empty(®ion))) { + DEBUGF("%s: zero-intersection between rectangles and clip\n", + __FUNCTION__); + pixman_region_fini(®ion); + return; + } + + DEBUGF("%s: clipped extents (%d, %d),(%d, %d) x %d\n", + __FUNCTION__, + RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, + RegionExtents(®ion)->x2, RegionExtents(®ion)->y2, + RegionNumRects(®ion)); + + glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y); + pixman_region_translate(®ion, dst_x, dst_y); + + DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n", + __FUNCTION__, dst_x, dst_y, + RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, + RegionExtents(®ion)->x2, RegionExtents(®ion)->y2); + + boxes = pixman_region_rectangles(®ion, &num_boxes); + if (op == PictOpSrc || op == PictOpClear) { + CARD32 pixel; + + if (op == PictOpClear) + pixel = 0; + else + miRenderColorToPixel(dst->pFormat, color, &pixel); + glamor_solid_boxes(pixmap, boxes, num_boxes, pixel); + + goto done; + } + else { + if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) { + int error; + + source = CreateSolidPicture(0, color, &error); + if (!source) + goto done; + if (glamor_composite_clipped_region(op, source, + NULL, dst, + NULL, NULL, priv, + ®ion, 0, 0, 0, 0, 0, 0)) + goto done; + } + } + fallback: + miCompositeRects(op, dst, color, num_rects, rects); + done: + /* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must + * manually append the damaged regions ourselves. + */ + DamageRegionAppend(&pixmap->drawable, ®ion); + DamageRegionProcessPending(&pixmap->drawable); + + if (need_free_region) + pixman_region_fini(®ion); + if (source) + FreePicture(source, 0); + return; } diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 4e6f953..2735ba0 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -34,643 +34,624 @@ #ifndef GLAMOR_GLES2 static Bool glamor_copy_n_to_n_fbo_blit(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, BoxPtr box, int nbox, int dx, int dy) + 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); - glamor_gl_dispatch *dispatch; - 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); - - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->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) { - dispatch->glBlitFramebuffer((box[i].x1 + dx + - src_x_off), - (box[i].y1 + - src_y_off), - (box[i].x2 + dx + - src_x_off), - (box[i].y2 + - src_y_off), - (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); - - dispatch->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_put_dispatch(glamor_priv); - glamor_priv->state = BLIT_STATE; - return TRUE; + 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); + glamor_gl_dispatch *dispatch; + 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); + + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->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) { + dispatch->glBlitFramebuffer((box[i].x1 + dx + + src_x_off), + (box[i].y1 + + src_y_off), + (box[i].x2 + dx + + src_x_off), + (box[i].y2 + + src_y_off), + (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); + + dispatch->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_put_dispatch(glamor_priv); + glamor_priv->state = BLIT_STATE; + return TRUE; } #endif static Bool glamor_copy_n_to_n_textured(DrawablePtr src, - DrawablePtr dst, - GCPtr gc, BoxPtr box, int nbox, int dx, int dy) + DrawablePtr dst, + GCPtr gc, BoxPtr box, int nbox, int dx, int dy) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(dst->pScreen); - glamor_gl_dispatch *dispatch; - 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_screen_private *glamor_priv = + glamor_get_screen_private(dst->pScreen); + glamor_gl_dispatch *dispatch; + 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) { #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD - glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); - return FALSE; + 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_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); + 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); - 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_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, - &dst_y_off); + dispatch = glamor_get_dispatch(glamor_priv); - dispatch = glamor_get_dispatch(glamor_priv); + glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), vertices); + dispatch->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; - glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - vertices); - dispatch->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; - - dispatch->glActiveTexture(GL_TEXTURE0); - dispatch->glBindTexture(GL_TEXTURE_2D, - src_pixmap_priv->base.fbo->tex); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex); #ifndef GLAMOR_GLES2 - dispatch->glEnable(GL_TEXTURE_2D); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_BORDER); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_BORDER); + dispatch->glEnable(GL_TEXTURE_2D); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); #endif - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, - GL_FLOAT, GL_FALSE, - 2 * sizeof(float), - texcoords); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); - dispatch->glUniform1i(glamor_priv->finish_access_revert[0], - REVERT_NONE); - dispatch->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); - dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, + GL_FLOAT, GL_FALSE, + 2 * sizeof(float), texcoords); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); + dispatch->glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE); + dispatch->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); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); #ifndef GLAMOR_GLES2 - dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glDisable(GL_TEXTURE_2D); #endif - dispatch->glUseProgram(0); - /* The source texture is bound to a fbo, we have to flush it here. */ - glamor_put_dispatch(glamor_priv); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - return TRUE; + dispatch->glUseProgram(0); + /* The source texture is bound to a fbo, we have to flush it here. */ + glamor_put_dispatch(glamor_priv); + 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) + 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); + 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); #ifndef GLAMOR_GLES2 - if (!overlaped && - (glamor_priv->state != RENDER_STATE - || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex) - && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, - dy)) { - ret = TRUE; - goto done; - } + if (!overlaped && + (glamor_priv->state != RENDER_STATE + || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex) + && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { + ret = TRUE; + goto done; + } #endif - 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; + 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) + DrawablePtr dst, + GCPtr gc, + BoxPtr box, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, Pixel bitplane, + void *closure, Bool fallback) { - PixmapPtr dst_pixmap, src_pixmap; - glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - 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(dst->pScreen); - - 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; - dispatch = glamor_get_dispatch(glamor_priv); - if (!glamor_set_alu(dispatch, gc->alu)) { - glamor_put_dispatch(glamor_priv); - goto fail; - } - glamor_put_dispatch(glamor_priv); - } - - 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); - RegionUninit(®ion); - } else { - ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy, - reverse, upsidedown, bitplane, - closure); - } - -fail: - dispatch = glamor_get_dispatch(glamor_priv); - glamor_set_alu(dispatch, GXcopy); - glamor_put_dispatch(glamor_priv); - - 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)) { - if (dst == src - || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { - fbCopyNtoN(src, dst, gc, box, nbox, - dx, dy, reverse, upsidedown, bitplane, - closure); - if (dst != src) - glamor_finish_access(src, GLAMOR_ACCESS_RO); - } - glamor_finish_access(dst, GLAMOR_ACCESS_RW); - } - ok = TRUE; - - done: - glamor_clear_delayed_fallbacks(src->pScreen); - glamor_clear_delayed_fallbacks(dst->pScreen); - return ok; + PixmapPtr dst_pixmap, src_pixmap; + glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + 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(dst->pScreen); + + 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; + dispatch = glamor_get_dispatch(glamor_priv); + if (!glamor_set_alu(dispatch, gc->alu)) { + glamor_put_dispatch(glamor_priv); + goto fail; + } + glamor_put_dispatch(glamor_priv); + } + + 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); + RegionUninit(®ion); + } + else { + ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy, + reverse, upsidedown, bitplane, closure); + } + + fail: + dispatch = glamor_get_dispatch(glamor_priv); + glamor_set_alu(dispatch, GXcopy); + glamor_put_dispatch(glamor_priv); + + 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)) { + if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + fbCopyNtoN(src, dst, gc, box, nbox, + dx, dy, reverse, upsidedown, bitplane, closure); + if (dst != src) + glamor_finish_access(src, GLAMOR_ACCESS_RO); + } + glamor_finish_access(dst, GLAMOR_ACCESS_RW); + } + 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) + 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); + RegionPtr region; - return 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) + 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); + _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) + 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); + 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 index 3f2652a..c42d33e 100644 --- a/glamor/glamor_copyplane.c +++ b/glamor/glamor_copyplane.c @@ -30,43 +30,43 @@ 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) + 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 (!fallback && glamor_ddx_fallback_check_gc(pGC) + && glamor_ddx_fallback_check_pixmap(pSrc) + && glamor_ddx_fallback_check_pixmap(pDst)) + goto fail; - 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); - return TRUE; + 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); + return TRUE; fail: - return FALSE; + 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) + 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; + 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) + 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); + 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 index b181ff5..1ced4b3 100644 --- a/glamor/glamor_copywindow.c +++ b/glamor/glamor_copywindow.c @@ -29,30 +29,28 @@ */ void -glamor_copy_window(WindowPtr win, DDXPointRec old_origin, - RegionPtr src_region) +glamor_copy_window(WindowPtr win, DDXPointRec old_origin, RegionPtr src_region) { - RegionRec dst_region; - int dx, dy; - PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win); + 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); + 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_INIT(win->drawable.pScreen, &dst_region, NullBox, 0); - REGION_INTERSECT(win->drawable.pScreen, &dst_region, - &win->borderClip, src_region); + 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); + 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); + miCopyRegion(&pixmap->drawable, &pixmap->drawable, + NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL); - REGION_UNINIT(win->drawable.pScreen, &dst_region); + REGION_UNINIT(win->drawable.pScreen, &dst_region); } diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index eb1a08d..4213961 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -38,76 +38,76 @@ const Bool glamor_get_drawable_location(const DrawablePtr drawable) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = - glamor_get_pixmap_private(pixmap); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(drawable->pScreen); - if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0) - return 'm'; - if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo) - return 's'; - else - return 'f'; + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(drawable->pScreen); + if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0) + return 'm'; + if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo) + return 's'; + else + return 'f'; } GLint glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type, - const char *source) + const char *source) { - GLint ok; - GLint prog; - - prog = dispatch->glCreateShader(type); - dispatch->glShaderSource(prog, 1, (const GLchar **) &source, NULL); - dispatch->glCompileShader(prog); - dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); - if (!ok) { - GLchar *info; - GLint size; - - dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); - info = malloc(size); - if (info) { - dispatch->glGetShaderInfoLog(prog, size, NULL, info); - ErrorF("Failed to compile %s: %s\n", - type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); - ErrorF("Program source:\n%s", source); - free(info); - } else - ErrorF("Failed to get shader compilation info.\n"); - FatalError("GLSL compile failure\n"); - } - - return prog; + GLint ok; + GLint prog; + + prog = dispatch->glCreateShader(type); + dispatch->glShaderSource(prog, 1, (const GLchar **) &source, NULL); + dispatch->glCompileShader(prog); + dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); + if (!ok) { + GLchar *info; + GLint size; + + dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); + if (info) { + dispatch->glGetShaderInfoLog(prog, size, NULL, info); + ErrorF("Failed to compile %s: %s\n", + type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); + ErrorF("Program source:\n%s", source); + free(info); + } + else + ErrorF("Failed to get shader compilation info.\n"); + FatalError("GLSL compile failure\n"); + } + + return prog; } void glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog) { - GLint ok; + GLint ok; - dispatch->glLinkProgram(prog); - dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok); - if (!ok) { - GLchar *info; - GLint size; + dispatch->glLinkProgram(prog); + dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok); + if (!ok) { + GLchar *info; + GLint size; - dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); - info = malloc(size); + dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); - dispatch->glGetProgramInfoLog(prog, size, NULL, info); - ErrorF("Failed to link: %s\n", info); - FatalError("GLSL link failure\n"); - } + dispatch->glGetProgramInfoLog(prog, size, NULL, info); + ErrorF("Failed to link: %s\n", info); + FatalError("GLSL link failure\n"); + } } - Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - return glamor_download_pixmap_to_cpu(pixmap, access); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + + return glamor_download_pixmap_to_cpu(pixmap, access); } /* @@ -142,221 +142,202 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) void glamor_init_finish_access_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - const char *vs_source = - "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord0;\n" - "varying vec2 source_texture;\n" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - " source_texture = v_texcoord0.xy;\n" "}\n"; - - const char *common_source = - GLAMOR_DEFAULT_PRECISION - "varying vec2 source_texture;\n" - "uniform sampler2D sampler;\n" - "uniform int revert;\n" - "uniform int swap_rb;\n" - - "#define REVERT_NONE 0\n" - "#define REVERT_NORMAL 1\n" - "#define SWAP_NONE_DOWNLOADING 0\n" - "#define SWAP_DOWNLOADING 1\n" - "#define SWAP_UPLOADING 2\n" - "#define SWAP_NONE_UPLOADING 3\n"; - - const char *fs_source = - "void main()\n" - "{\n" - " if (revert == REVERT_NONE) \n" - " { \n" - " if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n" - " gl_FragColor = texture2D(sampler, source_texture).bgra;\n" - " else \n" - " gl_FragColor = texture2D(sampler, source_texture).rgba;\n" - " } \n" - " else \n" - " { \n" - " if (swap_rb == SWAP_DOWNLOADING) \n" - " gl_FragColor = texture2D(sampler, source_texture).argb;\n" - " else if (swap_rb == SWAP_NONE_DOWNLOADING)\n" - " gl_FragColor = texture2D(sampler, source_texture).abgr;\n" - " else if (swap_rb == SWAP_UPLOADING)\n" - " gl_FragColor = texture2D(sampler, source_texture).gbar;\n" - " else if (swap_rb == SWAP_NONE_UPLOADING)\n" - " gl_FragColor = texture2D(sampler, source_texture).abgr;\n" - " } \n" "}\n"; - - const char *set_alpha_source = - "void main()\n" - "{\n" - " if (revert == REVERT_NONE) \n" - " { \n" - " if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n" - " gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n" - " else \n" - " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" - " } \n" - " else \n" - " { \n" - " if (swap_rb == SWAP_DOWNLOADING) \n" - " gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n" - " else if (swap_rb == SWAP_NONE_DOWNLOADING)\n" - " gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n" - " else if (swap_rb == SWAP_UPLOADING)\n" - " gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n" - " else if (swap_rb == SWAP_NONE_UPLOADING)\n" - " gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n" - " } \n" - "}\n"; - GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; - GLint sampler_uniform_location; - char *source; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram(); - glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram(); - - vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, - vs_source); - - XNFasprintf(&source, "%s%s", common_source, fs_source); - fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - source); - free(source); - - dispatch->glAttachShader(glamor_priv->finish_access_prog[0], - vs_prog); - dispatch->glAttachShader(glamor_priv->finish_access_prog[0], - fs_prog); - - avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, - vs_source); - - XNFasprintf(&source, "%s%s", common_source, set_alpha_source); - set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - source); - free(source); - - dispatch->glAttachShader(glamor_priv->finish_access_prog[1], - avs_prog); - dispatch->glAttachShader(glamor_priv->finish_access_prog[1], - set_alpha_prog); - - dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], - GLAMOR_VERTEX_POS, "v_position"); - dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], - GLAMOR_VERTEX_SOURCE, - "v_texcoord0"); - glamor_link_glsl_prog(dispatch, - glamor_priv->finish_access_prog[0]); - - dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], - GLAMOR_VERTEX_POS, "v_position"); - dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], - GLAMOR_VERTEX_SOURCE, - "v_texcoord0"); - glamor_link_glsl_prog(dispatch, - glamor_priv->finish_access_prog[1]); - - glamor_priv->finish_access_revert[0] = - dispatch-> - glGetUniformLocation(glamor_priv->finish_access_prog[0], - "revert"); - - glamor_priv->finish_access_swap_rb[0] = - dispatch-> - glGetUniformLocation(glamor_priv->finish_access_prog[0], - "swap_rb"); - sampler_uniform_location = - dispatch-> - glGetUniformLocation(glamor_priv->finish_access_prog[0], - "sampler"); - dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); - dispatch->glUniform1i(sampler_uniform_location, 0); - dispatch->glUniform1i(glamor_priv->finish_access_revert[0], 0); - dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); - dispatch->glUseProgram(0); - - glamor_priv->finish_access_revert[1] = - dispatch-> - glGetUniformLocation(glamor_priv->finish_access_prog[1], - "revert"); - glamor_priv->finish_access_swap_rb[1] = - dispatch-> - glGetUniformLocation(glamor_priv->finish_access_prog[1], - "swap_rb"); - sampler_uniform_location = - dispatch-> - glGetUniformLocation(glamor_priv->finish_access_prog[1], - "sampler"); - dispatch->glUseProgram(glamor_priv->finish_access_prog[1]); - dispatch->glUniform1i(glamor_priv->finish_access_revert[1], 0); - dispatch->glUniform1i(sampler_uniform_location, 0); - dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + const char *vs_source = + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord0;\n" + "varying vec2 source_texture;\n" + "void main()\n" + "{\n" + " gl_Position = v_position;\n" + " source_texture = v_texcoord0.xy;\n" "}\n"; + + const char *common_source = + GLAMOR_DEFAULT_PRECISION + "varying vec2 source_texture;\n" + "uniform sampler2D sampler;\n" + "uniform int revert;\n" + "uniform int swap_rb;\n" + "#define REVERT_NONE 0\n" + "#define REVERT_NORMAL 1\n" + "#define SWAP_NONE_DOWNLOADING 0\n" + "#define SWAP_DOWNLOADING 1\n" + "#define SWAP_UPLOADING 2\n" + "#define SWAP_NONE_UPLOADING 3\n"; + + const char *fs_source = + "void main()\n" + "{\n" + " if (revert == REVERT_NONE) \n" + " { \n" + " if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n" + " gl_FragColor = texture2D(sampler, source_texture).bgra;\n" + " else \n" + " gl_FragColor = texture2D(sampler, source_texture).rgba;\n" + " } \n" + " else \n" + " { \n" + " if (swap_rb == SWAP_DOWNLOADING) \n" + " gl_FragColor = texture2D(sampler, source_texture).argb;\n" + " else if (swap_rb == SWAP_NONE_DOWNLOADING)\n" + " gl_FragColor = texture2D(sampler, source_texture).abgr;\n" + " else if (swap_rb == SWAP_UPLOADING)\n" + " gl_FragColor = texture2D(sampler, source_texture).gbar;\n" + " else if (swap_rb == SWAP_NONE_UPLOADING)\n" + " gl_FragColor = texture2D(sampler, source_texture).abgr;\n" + " } \n" "}\n"; + + const char *set_alpha_source = + "void main()\n" + "{\n" + " if (revert == REVERT_NONE) \n" + " { \n" + " if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n" + " gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n" + " else \n" + " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" + " } \n" + " else \n" + " { \n" + " if (swap_rb == SWAP_DOWNLOADING) \n" + " gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n" + " else if (swap_rb == SWAP_NONE_DOWNLOADING)\n" + " gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n" + " else if (swap_rb == SWAP_UPLOADING)\n" + " gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n" + " else if (swap_rb == SWAP_NONE_UPLOADING)\n" + " gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n" + " } \n" "}\n"; + GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; + GLint sampler_uniform_location; + char *source; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram(); + glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram(); + + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); + + XNFasprintf(&source, "%s%s", common_source, fs_source); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source); + free(source); + + dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); + dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); + + avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); + + XNFasprintf(&source, "%s%s", common_source, set_alpha_source); + set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, + source); + free(source); + + dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); + dispatch->glAttachShader(glamor_priv->finish_access_prog[1], + set_alpha_prog); + + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], + GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], + GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[0]); + + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], + GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], + GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[1]); + + glamor_priv->finish_access_revert[0] = + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], + "revert"); + + glamor_priv->finish_access_swap_rb[0] = + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], + "swap_rb"); + sampler_uniform_location = + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], + "sampler"); + dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); + dispatch->glUniform1i(sampler_uniform_location, 0); + dispatch->glUniform1i(glamor_priv->finish_access_revert[0], 0); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); + dispatch->glUseProgram(0); + + glamor_priv->finish_access_revert[1] = + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], + "revert"); + glamor_priv->finish_access_swap_rb[1] = + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], + "swap_rb"); + sampler_uniform_location = + dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], + "sampler"); + dispatch->glUseProgram(glamor_priv->finish_access_prog[1]); + dispatch->glUniform1i(glamor_priv->finish_access_revert[1], 0); + dispatch->glUniform1i(sampler_uniform_location, 0); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); } void glamor_fini_finish_access_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]); - dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]); - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]); + dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]); + glamor_put_dispatch(glamor_priv); } void glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode) { - 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); + 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 (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)) + return; - if (access_mode != GLAMOR_ACCESS_RO) { - glamor_restore_pixmap_to_texture(pixmap); - } + if (access_mode != GLAMOR_ACCESS_RO) { + glamor_restore_pixmap_to_texture(pixmap); + } - if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) { - glamor_gl_dispatch *dispatch; + if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) { + glamor_gl_dispatch *dispatch; - assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); + assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - dispatch->glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo); - glamor_put_dispatch(glamor_priv); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + dispatch->glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo); + glamor_put_dispatch(glamor_priv); - pixmap_priv->base.fbo->pbo_valid = FALSE; - pixmap_priv->base.fbo->pbo = 0; - } else { - free(pixmap->devPrivate.ptr); - } + 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->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; + if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED) + pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL; - pixmap->devPrivate.ptr = NULL; + pixmap->devPrivate.ptr = NULL; } - /** * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the * current fill style. @@ -368,22 +349,19 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode) 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, - GLAMOR_ACCESS_RO); - return FALSE; - } - } - return TRUE; + 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, GLAMOR_ACCESS_RO); + return FALSE; + } + } + return TRUE; } /** @@ -392,45 +370,44 @@ glamor_prepare_access_gc(GCPtr gc) void glamor_finish_access_gc(GCPtr gc) { - if (gc->fillStyle == FillTiled) - glamor_finish_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO); - if (gc->stipple) - glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO); + if (gc->fillStyle == FillTiled) + glamor_finish_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO); + if (gc->stipple) + glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO); } 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) + 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; + glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth); + return FALSE; } GCOps glamor_gc_ops = { - .FillSpans = glamor_fill_spans, - .SetSpans = glamor_set_spans, - .PutImage = glamor_put_image, - .CopyArea = glamor_copy_area, - .CopyPlane = glamor_copy_plane, - .PolyPoint = glamor_poly_point, - .Polylines = glamor_poly_lines, - .PolySegment = glamor_poly_segment, - .PolyRectangle = miPolyRectangle, - .PolyArc = miPolyArc, - .FillPolygon = miFillPolygon, - .PolyFillRect = glamor_poly_fill_rect, - .PolyFillArc = miPolyFillArc, - .PolyText8 = miPolyText8, - .PolyText16 = miPolyText16, - .ImageText8 = miImageText8, - .ImageText16 = miImageText16, - .ImageGlyphBlt = glamor_image_glyph_blt, //miImageGlyphBlt, - .PolyGlyphBlt = glamor_poly_glyph_blt, //miPolyGlyphBlt, - .PushPixels = glamor_push_pixels, //miPushPixels, + .FillSpans = glamor_fill_spans, + .SetSpans = glamor_set_spans, + .PutImage = glamor_put_image, + .CopyArea = glamor_copy_area, + .CopyPlane = glamor_copy_plane, + .PolyPoint = glamor_poly_point, + .Polylines = glamor_poly_lines, + .PolySegment = glamor_poly_segment, + .PolyRectangle = miPolyRectangle, + .PolyArc = miPolyArc, + .FillPolygon = miFillPolygon, + .PolyFillRect = glamor_poly_fill_rect, + .PolyFillArc = miPolyFillArc, + .PolyText8 = miPolyText8, + .PolyText16 = miPolyText16, + .ImageText8 = miImageText8, + .ImageText16 = miImageText16, + .ImageGlyphBlt = glamor_image_glyph_blt, //miImageGlyphBlt, + .PolyGlyphBlt = glamor_poly_glyph_blt, //miPolyGlyphBlt, + .PushPixels = glamor_push_pixels, //miPushPixels, }; /** @@ -440,104 +417,94 @@ GCOps glamor_gc_ops = { void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) { - /* fbValidateGC will do direct access to pixmaps if the tiling has changed. - * Preempt fbValidateGC by doing its work and masking the change out, so - * that we can do the Prepare/finish_access. - */ + /* fbValidateGC will do direct access to pixmaps if the tiling has changed. + * Preempt fbValidateGC by doing its work and masking the change out, so + * that we can do the Prepare/finish_access. + */ #ifdef FB_24_32BIT - if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { - gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); - fbGetRotatedPixmap(gc) = 0; - } - - if (gc->fillStyle == FillTiled) { - PixmapPtr old_tile, new_tile; - - old_tile = gc->tile.pixmap; - if (old_tile->drawable.bitsPerPixel != - drawable->bitsPerPixel) { - new_tile = fbGetRotatedPixmap(gc); - if (!new_tile || - new_tile->drawable.bitsPerPixel != - drawable->bitsPerPixel) { - if (new_tile) - gc->pScreen->DestroyPixmap - (new_tile); - /* fb24_32ReformatTile will do direct access of a newly- - * allocated pixmap. - */ - glamor_fallback - ("GC %p tile FB_24_32 transformat %p.\n", - gc, old_tile); - - if (glamor_prepare_access - (&old_tile->drawable, - GLAMOR_ACCESS_RO)) { - new_tile = - fb24_32ReformatTile - (old_tile, - drawable->bitsPerPixel); - glamor_finish_access - (&old_tile->drawable, GLAMOR_ACCESS_RO); - } - } - if (new_tile) { - fbGetRotatedPixmap(gc) = old_tile; - gc->tile.pixmap = new_tile; - changes |= GCTile; - } - } - } + if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { + gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); + fbGetRotatedPixmap(gc) = 0; + } + + if (gc->fillStyle == FillTiled) { + PixmapPtr old_tile, new_tile; + + old_tile = gc->tile.pixmap; + if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { + new_tile = fbGetRotatedPixmap(gc); + if (!new_tile || + new_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { + if (new_tile) + gc->pScreen->DestroyPixmap(new_tile); + /* fb24_32ReformatTile will do direct access of a newly- + * allocated pixmap. + */ + glamor_fallback + ("GC %p tile FB_24_32 transformat %p.\n", gc, old_tile); + + if (glamor_prepare_access + (&old_tile->drawable, GLAMOR_ACCESS_RO)) { + new_tile = + fb24_32ReformatTile(old_tile, drawable->bitsPerPixel); + glamor_finish_access(&old_tile->drawable, GLAMOR_ACCESS_RO); + } + } + if (new_tile) { + fbGetRotatedPixmap(gc) = old_tile; + gc->tile.pixmap = new_tile; + changes |= GCTile; + } + } + } #endif - if (changes & GCTile) { - if (!gc->tileIsPixel) { - glamor_pixmap_private *pixmap_priv = - glamor_get_pixmap_private(gc->tile.pixmap); - if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - && FbEvenTile(gc->tile.pixmap->drawable.width * - drawable->bitsPerPixel)) { - glamor_fallback - ("GC %p tile changed %p.\n", gc, - gc->tile.pixmap); - if (glamor_prepare_access - (&gc->tile.pixmap->drawable, - GLAMOR_ACCESS_RW)) { - fbPadPixmap(gc->tile.pixmap); - glamor_finish_access - (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW); - } - } - } - /* Mask out the GCTile change notification, now that we've done FB's - * job for it. - */ - changes &= ~GCTile; - } - - if (changes & GCStipple && gc->stipple) { - /* We can't inline stipple handling like we do for GCTile because - * it sets fbgc privates. - */ - if (glamor_prepare_access - (&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { - fbValidateGC(gc, changes, drawable); - glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW); - } - } else { - fbValidateGC(gc, changes, drawable); - } - - gc->ops = &glamor_gc_ops; + if (changes & GCTile) { + if (!gc->tileIsPixel) { + glamor_pixmap_private *pixmap_priv = + glamor_get_pixmap_private(gc->tile.pixmap); + if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + && FbEvenTile(gc->tile.pixmap->drawable.width * + drawable->bitsPerPixel)) { + glamor_fallback + ("GC %p tile changed %p.\n", gc, gc->tile.pixmap); + if (glamor_prepare_access + (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) { + fbPadPixmap(gc->tile.pixmap); + glamor_finish_access + (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW); + } + } + } + /* Mask out the GCTile change notification, now that we've done FB's + * job for it. + */ + changes &= ~GCTile; + } + + if (changes & GCStipple && gc->stipple) { + /* We can't inline stipple handling like we do for GCTile because + * it sets fbgc privates. + */ + if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { + fbValidateGC(gc, changes, drawable); + glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW); + } + } + else { + fbValidateGC(gc, changes, drawable); + } + + gc->ops = &glamor_gc_ops; } static GCFuncs glamor_gc_funcs = { - glamor_validate_gc, - miChangeGC, - miCopyGC, - miDestroyGC, - miChangeClip, - miDestroyClip, - miCopyClip + glamor_validate_gc, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip }; /** @@ -547,66 +514,69 @@ static GCFuncs glamor_gc_funcs = { int glamor_create_gc(GCPtr gc) { - if (!fbCreateGC(gc)) - return FALSE; + if (!fbCreateGC(gc)) + return FALSE; - gc->funcs = &glamor_gc_funcs; + gc->funcs = &glamor_gc_funcs; - return TRUE; + return TRUE; } RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap) { - RegionPtr ret; - glamor_fallback("pixmap %p \n", pixmap); - if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) - return NULL; - ret = fbPixmapToRegion(pixmap); - glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); - return ret; + RegionPtr ret; + + glamor_fallback("pixmap %p \n", pixmap); + if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) + return NULL; + ret = fbPixmapToRegion(pixmap); + glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); + return ret; } /* Borrow from cairo. */ Bool glamor_gl_has_extension(const char *extension) { - const char *pext; - int ext_len; - ext_len = strlen(extension); + const char *pext; + int ext_len; + + ext_len = strlen(extension); - pext = (const char*)glGetString(GL_EXTENSIONS); + pext = (const char *) glGetString(GL_EXTENSIONS); - if (pext == NULL || extension == NULL) - return FALSE; + if (pext == NULL || extension == NULL) + return FALSE; - while ((pext = strstr(pext, extension)) != NULL) { - if (pext[ext_len] == ' ' || pext[ext_len] == '\0') - return TRUE; - pext += ext_len; - } - return FALSE; + while ((pext = strstr(pext, extension)) != NULL) { + if (pext[ext_len] == ' ' || pext[ext_len] == '\0') + return TRUE; + pext += ext_len; + } + return FALSE; } int glamor_gl_get_version(void) { - int major, minor; - const char *version = (const char *) glGetString(GL_VERSION); - const char *dot = version == NULL ? NULL : strchr(version, '.'); - const char *major_start = dot; - - /* Sanity check */ - if (dot == NULL || dot == version || *(dot + 1) == '\0') { - major = 0; - minor = 0; - } else { - /* Find the start of the major version in the string */ - while (major_start > version && *major_start != ' ') - --major_start; - major = strtol(major_start, NULL, 10); - minor = strtol(dot + 1, NULL, 10); - } - - return GLAMOR_GL_VERSION_ENCODE(major, minor); + int major, minor; + const char *version = (const char *) glGetString(GL_VERSION); + const char *dot = version == NULL ? NULL : strchr(version, '.'); + const char *major_start = dot; + + /* Sanity check */ + if (dot == NULL || dot == version || *(dot + 1) == '\0') { + major = 0; + minor = 0; + } + else { + /* Find the start of the major version in the string */ + while (major_start > version && *major_start != ' ') + --major_start; + major = strtol(major_start, NULL, 10); + minor = strtol(dot + 1, NULL, 10); + } + + return GLAMOR_GL_VERSION_ENCODE(major, minor); } diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h index f0c969b..638bee2 100644 --- a/glamor/glamor_debug.h +++ b/glamor/glamor_debug.h @@ -29,7 +29,6 @@ #ifndef __GLAMOR_DEBUG_H__ #define __GLAMOR_DEBUG_H__ - #define GLAMOR_DELAYED_STRING_MAX 64 #define GLAMOR_DEBUG_NONE 0 @@ -51,9 +50,6 @@ AbortServer(void) exit(1); \ } while(0) - - - #define __debug_output_message(_format_, _prefix_, ...) \ LogMessageVerb(X_NONE, 0, \ "%32s:\t" _format_ , \ @@ -69,7 +65,6 @@ AbortServer(void) ##__VA_ARGS__); \ } while(0) - #define glamor_fallback(_format_,...) \ do { \ if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) \ @@ -77,8 +72,6 @@ AbortServer(void) "Glamor fallback", \ ##__VA_ARGS__);} while(0) - - #define glamor_delayed_fallback(_screen_, _format_,...) \ do { \ if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) { \ @@ -90,7 +83,6 @@ AbortServer(void) "glamor delayed fallback: \t%s " _format_ , \ __FUNCTION__, ##__VA_ARGS__); } } while(0) - #define glamor_clear_delayed_fallbacks(_screen_) \ do { \ if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) { \ @@ -112,5 +104,4 @@ AbortServer(void) #define DEBUGRegionPrint(x) do {} while (0) //#define DEBUGRegionPrint RegionPrint - #endif diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index ff4c0bd..c65f701 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -69,41 +69,42 @@ static const char glamor_name[] = "glamor"; static DevPrivateKeyRec glamor_egl_pixmap_private_key_index; -DevPrivateKey glamor_egl_pixmap_private_key = &glamor_egl_pixmap_private_key_index; +DevPrivateKey glamor_egl_pixmap_private_key = + &glamor_egl_pixmap_private_key_index; static void glamor_identify(int flags) { - xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n", - glamor_name); + xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n", + glamor_name); } struct glamor_egl_screen_private { - EGLDisplay display; - EGLContext context; - EGLint major, minor; - - CreateScreenResourcesProcPtr CreateScreenResources; - CloseScreenProcPtr CloseScreen; - int fd; - EGLImageKHR front_image; - PixmapPtr *back_pixmap; - int cpp; + EGLDisplay display; + EGLContext context; + EGLint major, minor; + + CreateScreenResourcesProcPtr CreateScreenResources; + CloseScreenProcPtr CloseScreen; + int fd; + EGLImageKHR front_image; + PixmapPtr *back_pixmap; + int cpp; #ifdef GLAMOR_HAS_GBM - struct gbm_device *gbm; + struct gbm_device *gbm; #endif - int has_gem; - void *glamor_context; - void *current_context; - int gl_context_depth; - int dri3_capable; - - PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; - PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr; - PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; - struct glamor_gl_dispatch *dispatch; - CloseScreenProcPtr saved_close_screen; - xf86FreeScreenProc *saved_free_screen; + int has_gem; + void *glamor_context; + void *current_context; + int gl_context_depth; + int dri3_capable; + + PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; + PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; + struct glamor_gl_dispatch *dispatch; + CloseScreenProcPtr saved_close_screen; + xf86FreeScreenProc *saved_free_screen; }; int xf86GlamorEGLPrivateIndex = -1; @@ -111,46 +112,47 @@ int xf86GlamorEGLPrivateIndex = -1; static struct glamor_egl_screen_private * glamor_egl_get_screen_private(ScrnInfoPtr scrn) { - return (struct glamor_egl_screen_private *) - scrn->privates[xf86GlamorEGLPrivateIndex].ptr; + 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 = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - - if (glamor_egl->gl_context_depth++) - return; - - GET_CURRENT_CONTEXT(glamor_egl->current_context); - - if (glamor_egl->glamor_context != glamor_egl->current_context) { - 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)) { - FatalError("Failed to make EGL context current\n"); - } - } + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + + if (glamor_egl->gl_context_depth++) + return; + + GET_CURRENT_CONTEXT(glamor_egl->current_context); + + if (glamor_egl->glamor_context != glamor_egl->current_context) { + 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)) { + FatalError("Failed to make EGL context current\n"); + } + } } _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); - if (--glamor_egl->gl_context_depth) - return; + if (--glamor_egl->gl_context_depth) + return; - if (glamor_egl->current_context && - glamor_egl->glamor_context != glamor_egl->current_context) - SET_CURRENT_CONTEXT(glamor_egl->current_context); + if (glamor_egl->current_context && + glamor_egl->glamor_context != glamor_egl->current_context) + SET_CURRENT_CONTEXT(glamor_egl->current_context); } #else #define glamor_egl_make_current(x) @@ -159,598 +161,591 @@ glamor_egl_restore_context(ScreenPtr screen) static EGLImageKHR _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl, - int width, int height, int stride, int name, int depth) + int width, int height, int stride, int name, int depth) { - EGLImageKHR image; - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_DRM_BUFFER_STRIDE_MESA, 0, - EGL_DRM_BUFFER_FORMAT_MESA, - EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, - EGL_DRM_BUFFER_USE_MESA, - EGL_DRM_BUFFER_USE_SHARE_MESA | - EGL_DRM_BUFFER_USE_SCANOUT_MESA, - EGL_NONE - }; - attribs[1] = width; - attribs[3] = height; - attribs[5] = stride; - if (depth != 32 && depth != 24) - return EGL_NO_IMAGE_KHR; - image = glamor_egl->egl_create_image_khr(glamor_egl->display, - glamor_egl->context, - EGL_DRM_BUFFER_MESA, - (void *) (uintptr_t)name, attribs); - if (image == EGL_NO_IMAGE_KHR) - return EGL_NO_IMAGE_KHR; - - - return image; + EGLImageKHR image; + + EGLint attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_STRIDE_MESA, 0, + EGL_DRM_BUFFER_FORMAT_MESA, + EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, + EGL_DRM_BUFFER_USE_SHARE_MESA | EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + attribs[1] = width; + attribs[3] = height; + attribs[5] = stride; + if (depth != 32 && depth != 24) + return EGL_NO_IMAGE_KHR; + image = glamor_egl->egl_create_image_khr(glamor_egl->display, + glamor_egl->context, + EGL_DRM_BUFFER_MESA, + (void *) (uintptr_t) name, + attribs); + if (image == EGL_NO_IMAGE_KHR) + return EGL_NO_IMAGE_KHR; + + return image; } static int glamor_get_flink_name(int fd, int handle, int *name) { - struct drm_gem_flink flink; - flink.handle = handle; - if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) - return FALSE; - *name = flink.name; - return TRUE; + struct drm_gem_flink flink; + + flink.handle = handle; + if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) + return FALSE; + *name = flink.name; + return TRUE; } static Bool glamor_create_texture_from_image(struct glamor_egl_screen_private - *glamor_egl, - EGLImageKHR image, GLuint * texture) + *glamor_egl, + EGLImageKHR image, GLuint * texture) { - glamor_egl->dispatch->glGenTextures(1, texture); - glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture); - glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - - (glamor_egl->egl_image_target_texture2d_oes) (GL_TEXTURE_2D, - image); - glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, 0); - return TRUE; + glamor_egl->dispatch->glGenTextures(1, texture); + glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture); + glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + (glamor_egl->egl_image_target_texture2d_oes) (GL_TEXTURE_2D, image); + glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, 0); + return TRUE; } unsigned int -glamor_egl_create_argb8888_based_texture(ScreenPtr screen, - int w, - int h) +glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl; - EGLImageKHR image; - GLuint texture; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl; + EGLImageKHR image; + GLuint texture; + #ifdef GLAMOR_HAS_DRI3_SUPPORT - struct gbm_bo *bo; - EGLNativePixmapType native_pixmap; - glamor_egl = glamor_egl_get_screen_private(scrn); - bo = gbm_bo_create (glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888, - GBM_BO_USE_RENDERING | - GBM_BO_USE_SCANOUT); - if (!bo) - return 0; - - /* If the following assignment raises an error or a warning - * then that means EGLNativePixmapType is not struct gbm_bo * - * on your platform: This code won't work and you should not - * compile with dri3 support enabled */ - native_pixmap = bo; - - image = glamor_egl->egl_create_image_khr(glamor_egl->display, - EGL_NO_CONTEXT, - EGL_NATIVE_PIXMAP_KHR, - native_pixmap, NULL); - gbm_bo_destroy(bo); - if (image == EGL_NO_IMAGE_KHR) - return 0; - glamor_create_texture_from_image(glamor_egl, image, &texture); - glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); - - return texture; + struct gbm_bo *bo; + EGLNativePixmapType native_pixmap; + + glamor_egl = glamor_egl_get_screen_private(scrn); + bo = gbm_bo_create(glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888, + GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT); + if (!bo) + return 0; + + /* If the following assignment raises an error or a warning + * then that means EGLNativePixmapType is not struct gbm_bo * + * on your platform: This code won't work and you should not + * compile with dri3 support enabled */ + native_pixmap = bo; + + image = glamor_egl->egl_create_image_khr(glamor_egl->display, + EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, + native_pixmap, NULL); + gbm_bo_destroy(bo); + if (image == EGL_NO_IMAGE_KHR) + return 0; + glamor_create_texture_from_image(glamor_egl, image, &texture); + glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); + + return texture; #else - return 0; /* this path should never happen */ + return 0; /* this path should never happen */ #endif } Bool glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl; - PixmapPtr screen_pixmap; - - glamor_egl = glamor_egl_get_screen_private(scrn); - screen_pixmap = screen->GetScreenPixmap(screen); - - if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create textured screen."); - return FALSE; - } - - glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates, - glamor_egl_pixmap_private_key); - glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap); - return TRUE; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl; + PixmapPtr screen_pixmap; + + glamor_egl = glamor_egl_get_screen_private(scrn); + screen_pixmap = screen->GetScreenPixmap(screen); + + if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to create textured screen."); + return FALSE; + } + + glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates, + glamor_egl_pixmap_private_key); + glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap); + return TRUE; } Bool glamor_egl_create_textured_screen_ext(ScreenPtr screen, - int handle, - int stride, - PixmapPtr *back_pixmap) + int handle, + int stride, PixmapPtr *back_pixmap) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl; - glamor_egl = glamor_egl_get_screen_private(scrn); + glamor_egl = glamor_egl_get_screen_private(scrn); - glamor_egl->back_pixmap = back_pixmap; - if (!glamor_egl_create_textured_screen(screen, handle, stride)) - return FALSE; - return TRUE; + glamor_egl->back_pixmap = back_pixmap; + if (!glamor_egl_create_textured_screen(screen, handle, stride)) + return FALSE; + return TRUE; } static Bool glamor_egl_check_has_gem(int fd) { - struct drm_gem_flink flink; - flink.handle = 0; + struct drm_gem_flink flink; - ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); - if (errno == ENOENT || errno == EINVAL) - return TRUE; - return FALSE; + flink.handle = 0; + + ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (errno == ENOENT || errno == EINVAL) + return TRUE; + return FALSE; } Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) { - ScreenPtr screen = pixmap->drawable.pScreen; - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl; - EGLImageKHR image; - GLuint texture; - int name; - Bool ret = FALSE; - - glamor_egl = glamor_egl_get_screen_private(scrn); - - 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, - "Couldn't flink pixmap handle\n"); - glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY); - assert(0); - return FALSE; - } - } else - name = handle; - - image = _glamor_egl_create_image(glamor_egl, - pixmap->drawable.width, - pixmap->drawable.height, - ((stride * 8 + 7) / pixmap->drawable.bitsPerPixel), - name, - pixmap->drawable.depth); - if (image == EGL_NO_IMAGE_KHR) { - glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY); - 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; - -done: - glamor_egl_restore_context(screen); - return ret; + ScreenPtr screen = pixmap->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl; + EGLImageKHR image; + GLuint texture; + int name; + Bool ret = FALSE; + + glamor_egl = glamor_egl_get_screen_private(scrn); + + 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, + "Couldn't flink pixmap handle\n"); + glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY); + assert(0); + return FALSE; + } + } + else + name = handle; + + image = _glamor_egl_create_image(glamor_egl, + pixmap->drawable.width, + pixmap->drawable.height, + ((stride * 8 + + 7) / pixmap->drawable.bitsPerPixel), + name, pixmap->drawable.depth); + if (image == EGL_NO_IMAGE_KHR) { + glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY); + 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; + + done: + glamor_egl_restore_context(screen); + return ret; } Bool glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo) { - ScreenPtr screen = pixmap->drawable.pScreen; - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl; - EGLImageKHR image; - GLuint texture; - Bool ret = FALSE; - - glamor_egl = glamor_egl_get_screen_private(scrn); - - glamor_egl_make_current(screen); - - image = glamor_egl->egl_create_image_khr(glamor_egl->display, - glamor_egl->context, - EGL_NATIVE_PIXMAP_KHR, - bo, NULL); - if (image == EGL_NO_IMAGE_KHR) { - glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY); - 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; - -done: - glamor_egl_restore_context(screen); - return ret; + ScreenPtr screen = pixmap->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl; + EGLImageKHR image; + GLuint texture; + Bool ret = FALSE; + + glamor_egl = glamor_egl_get_screen_private(scrn); + + glamor_egl_make_current(screen); + + image = glamor_egl->egl_create_image_khr(glamor_egl->display, + glamor_egl->context, + EGL_NATIVE_PIXMAP_KHR, bo, NULL); + if (image == EGL_NO_IMAGE_KHR) { + glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY); + 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; + + done: + glamor_egl_restore_context(screen); + return ret; } #ifdef GLAMOR_HAS_DRI3_SUPPORT -int glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd); -void glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name); +int glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd); +void glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name); int -glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd) +glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd) { - union gbm_bo_handle handle; - struct drm_prime_handle args; - - handle = gbm_bo_get_handle(bo); - args.handle = handle.u32; - args.flags = DRM_CLOEXEC; - if (ioctl (gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args)) - return FALSE; - *fd = args.fd; - return TRUE; + union gbm_bo_handle handle; + struct drm_prime_handle args; + + handle = gbm_bo_get_handle(bo); + args.handle = handle.u32; + args.flags = DRM_CLOEXEC; + if (ioctl(gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args)) + return FALSE; + *fd = args.fd; + return TRUE; } void -glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name) +glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name) { - union gbm_bo_handle handle; + union gbm_bo_handle handle; - handle = gbm_bo_get_handle(bo); - if (!glamor_get_flink_name(gbm_fd, handle.u32, name)) - *name = -1; + handle = gbm_bo_get_handle(bo); + if (!glamor_get_flink_name(gbm_fd, handle.u32, name)) + *name = -1; } #endif -int glamor_egl_dri3_fd_name_from_tex (ScreenPtr screen, - PixmapPtr pixmap, - unsigned int tex, - Bool want_name, - CARD16 *stride, - CARD32 *size) +int +glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, + PixmapPtr pixmap, + unsigned int tex, + Bool want_name, CARD16 *stride, CARD32 *size) { #ifdef GLAMOR_HAS_DRI3_SUPPORT - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl; - EGLImageKHR image; - struct gbm_bo* bo; - int fd = -1; - - EGLint attribs[] = { - EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, - EGL_GL_TEXTURE_LEVEL_KHR, 0, - EGL_NONE - }; - - glamor_egl = glamor_egl_get_screen_private(scrn); - - glamor_egl_make_current(screen); - - image = dixLookupPrivate(&pixmap->devPrivates, - glamor_egl_pixmap_private_key); - - if (image == EGL_NO_IMAGE_KHR || image == NULL) - { - image = glamor_egl->egl_create_image_khr(glamor_egl->display, - glamor_egl->context, - EGL_GL_TEXTURE_2D_KHR, - (EGLClientBuffer)(uintptr_t)tex, attribs); - if (image == EGL_NO_IMAGE_KHR) - goto failure; - - dixSetPrivate(&pixmap->devPrivates, - glamor_egl_pixmap_private_key, - image); - glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); - } - - bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); - if (!bo) - goto failure; - - pixmap->devKind = gbm_bo_get_stride(bo); - - if (want_name) - { - if (glamor_egl->has_gem) - glamor_get_name_from_bo(glamor_egl->fd, bo, &fd); - } - else - { - if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd)) - { - *stride = pixmap->devKind; - *size = pixmap->devKind * gbm_bo_get_height(bo); - } - } - - gbm_bo_destroy(bo); -failure: - glamor_egl_restore_context(screen); - return fd; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl; + EGLImageKHR image; + struct gbm_bo *bo; + int fd = -1; + + EGLint attribs[] = { + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_GL_TEXTURE_LEVEL_KHR, 0, + EGL_NONE + }; + + glamor_egl = glamor_egl_get_screen_private(scrn); + + glamor_egl_make_current(screen); + + image = dixLookupPrivate(&pixmap->devPrivates, + glamor_egl_pixmap_private_key); + + if (image == EGL_NO_IMAGE_KHR || image == NULL) { + image = glamor_egl->egl_create_image_khr(glamor_egl->display, + glamor_egl->context, + EGL_GL_TEXTURE_2D_KHR, + (EGLClientBuffer) (uintptr_t) + tex, attribs); + if (image == EGL_NO_IMAGE_KHR) + goto failure; + + dixSetPrivate(&pixmap->devPrivates, + glamor_egl_pixmap_private_key, image); + glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); + } + + bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); + if (!bo) + goto failure; + + pixmap->devKind = gbm_bo_get_stride(bo); + + if (want_name) { + if (glamor_egl->has_gem) + glamor_get_name_from_bo(glamor_egl->fd, bo, &fd); + } + else { + if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd)) { + *stride = pixmap->devKind; + *size = pixmap->devKind * gbm_bo_get_height(bo); + } + } + + gbm_bo_destroy(bo); + failure: + glamor_egl_restore_context(screen); + return fd; #else - return -1; + return -1; #endif } -PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen, - int fd, - CARD16 width, - CARD16 height, - CARD16 stride, - CARD8 depth, - CARD8 bpp) +PixmapPtr +glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, + int fd, + CARD16 width, + CARD16 height, + CARD16 stride, CARD8 depth, CARD8 bpp) { #ifdef GLAMOR_HAS_DRI3_SUPPORT - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl; - struct gbm_bo* bo; - EGLImageKHR image; - PixmapPtr pixmap; - Bool ret = FALSE; - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, - EGL_DMA_BUF_PLANE0_FD_EXT, 0, - EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, - EGL_DMA_BUF_PLANE0_PITCH_EXT, 0, - EGL_NONE - }; - - glamor_egl = glamor_egl_get_screen_private(scrn); - - if (!glamor_egl->dri3_capable) - return NULL; - - if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0) - return NULL; - - attribs[1] = width; - attribs[3] = height; - attribs[7] = fd; - attribs[11] = stride; - image = glamor_egl->egl_create_image_khr(glamor_egl->display, - EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - NULL, attribs); - - if (image == EGL_NO_IMAGE_KHR) - return NULL; - - /* EGL_EXT_image_dma_buf_import can impose restrictions on the - * usage of the image. Use gbm_bo to bypass the limitations. */ - - bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); - glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); - - if (!bo) - return NULL; - - pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); - screen->ModifyPixmapHeader (pixmap, width, height, 0, 0, stride, NULL); - - ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); - gbm_bo_destroy(bo); - - if (ret) - return pixmap; - else - { - screen->DestroyPixmap(pixmap); - return NULL; - } + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl; + struct gbm_bo *bo; + EGLImageKHR image; + PixmapPtr pixmap; + Bool ret = FALSE; + + EGLint attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, + EGL_DMA_BUF_PLANE0_FD_EXT, 0, + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, + EGL_DMA_BUF_PLANE0_PITCH_EXT, 0, + EGL_NONE + }; + + glamor_egl = glamor_egl_get_screen_private(scrn); + + if (!glamor_egl->dri3_capable) + return NULL; + + if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0) + return NULL; + + attribs[1] = width; + attribs[3] = height; + attribs[7] = fd; + attribs[11] = stride; + image = glamor_egl->egl_create_image_khr(glamor_egl->display, + EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + NULL, attribs); + + if (image == EGL_NO_IMAGE_KHR) + return NULL; + + /* EGL_EXT_image_dma_buf_import can impose restrictions on the + * usage of the image. Use gbm_bo to bypass the limitations. */ + + bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); + glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); + + if (!bo) + return NULL; + + pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); + screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL); + + ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); + gbm_bo_destroy(bo); + + if (ret) + return pixmap; + else { + screen->DestroyPixmap(pixmap); + return NULL; + } #else - return NULL; + return NULL; #endif } static void _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap) { - ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); - EGLImageKHR image; - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - - image = dixLookupPrivate(&pixmap->devPrivates, - glamor_egl_pixmap_private_key); - if (image != EGL_NO_IMAGE_KHR && image != NULL) { - /* Before destroy an image which was attached to - * a texture. we must call glFlush to make sure the - * operation on that texture has been done.*/ - glamor_block_handler(pixmap->drawable.pScreen); - glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); - dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL); - } + ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); + EGLImageKHR image; + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + + image = dixLookupPrivate(&pixmap->devPrivates, + glamor_egl_pixmap_private_key); + if (image != EGL_NO_IMAGE_KHR && image != NULL) { + /* Before destroy an image which was attached to + * a texture. we must call glFlush to make sure the + * operation on that texture has been done.*/ + glamor_block_handler(pixmap->drawable.pScreen); + glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); + dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, + NULL); + } } _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back) { - ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen); - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - EGLImageKHR old_front_image; - EGLImageKHR new_front_image; - - glamor_pixmap_exchange_fbos(front, back); - new_front_image = dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key); - old_front_image = dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key); - dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key, new_front_image); - dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key, old_front_image); - glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM); - glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM); - glamor_egl->front_image = new_front_image; + ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + EGLImageKHR old_front_image; + EGLImageKHR new_front_image; + + glamor_pixmap_exchange_fbos(front, back); + new_front_image = + dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key); + old_front_image = + dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key); + dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key, + new_front_image); + dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key, + old_front_image); + glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM); + glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM); + glamor_egl->front_image = new_front_image; } void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap) { - if (pixmap->refcnt == 1) - _glamor_egl_destroy_pixmap_image(pixmap); - glamor_destroy_textured_pixmap(pixmap); + if (pixmap->refcnt == 1) + _glamor_egl_destroy_pixmap_image(pixmap); + glamor_destroy_textured_pixmap(pixmap); } static Bool glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL) { - ScrnInfoPtr scrn; - struct glamor_egl_screen_private *glamor_egl; - PixmapPtr screen_pixmap; - EGLImageKHR back_image; - - scrn = xf86ScreenToScrn(screen); - glamor_egl = glamor_egl_get_screen_private(scrn); - screen_pixmap = screen->GetScreenPixmap(screen); - - glamor_egl->egl_destroy_image_khr(glamor_egl->display, glamor_egl->front_image); - dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL); - glamor_egl->front_image = NULL; - if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) { - back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates, - glamor_egl_pixmap_private_key); - if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) { - glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image); - dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates, - glamor_egl_pixmap_private_key, NULL); - } - } - - screen->CloseScreen = glamor_egl->saved_close_screen; - - return screen->CloseScreen(CLOSE_SCREEN_ARGS); + ScrnInfoPtr scrn; + struct glamor_egl_screen_private *glamor_egl; + PixmapPtr screen_pixmap; + EGLImageKHR back_image; + + scrn = xf86ScreenToScrn(screen); + glamor_egl = glamor_egl_get_screen_private(scrn); + screen_pixmap = screen->GetScreenPixmap(screen); + + glamor_egl->egl_destroy_image_khr(glamor_egl->display, + glamor_egl->front_image); + dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, + NULL); + glamor_egl->front_image = NULL; + if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) { + back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates, + glamor_egl_pixmap_private_key); + if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) { + glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image); + dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates, + glamor_egl_pixmap_private_key, NULL); + } + } + + screen->CloseScreen = glamor_egl->saved_close_screen; + + return screen->CloseScreen(CLOSE_SCREEN_ARGS); } static Bool glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, - const char *extension) + const char *extension) { - const char *pext; - int ext_len; - - ext_len = strlen(extension); - pext = - (const char *) eglQueryString(glamor_egl->display, - EGL_EXTENSIONS); - if (pext == NULL || extension == NULL) - return FALSE; - while ((pext = strstr(pext, extension)) != NULL) { - if (pext[ext_len] == ' ' || pext[ext_len] == '\0') - return TRUE; - pext += ext_len; - } - return FALSE; + const char *pext; + int ext_len; + + ext_len = strlen(extension); + pext = (const char *) eglQueryString(glamor_egl->display, EGL_EXTENSIONS); + if (pext == NULL || extension == NULL) + return FALSE; + while ((pext = strstr(pext, extension)) != NULL) { + if (pext[ext_len] == ' ' || pext[ext_len] == '\0') + return TRUE; + pext += ext_len; + } + return FALSE; } void glamor_egl_screen_init(ScreenPtr screen) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); - glamor_egl->saved_close_screen = screen->CloseScreen; - screen->CloseScreen = glamor_egl_close_screen; + glamor_egl->saved_close_screen = screen->CloseScreen; + screen->CloseScreen = glamor_egl_close_screen; } static void glamor_egl_free_screen(FREE_SCREEN_ARGS_DECL) { - ScrnInfoPtr scrn; - struct glamor_egl_screen_private *glamor_egl; + ScrnInfoPtr scrn; + struct glamor_egl_screen_private *glamor_egl; + #ifndef XF86_SCRN_INTERFACE - scrn = xf86Screens[arg]; + scrn = xf86Screens[arg]; #else - scrn = arg; + scrn = arg; #endif - glamor_egl = glamor_egl_get_screen_private(scrn); - if (glamor_egl != NULL) { + glamor_egl = glamor_egl_get_screen_private(scrn); + if (glamor_egl != NULL) { - eglMakeCurrent(glamor_egl->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); + eglMakeCurrent(glamor_egl->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); #ifdef GLAMOR_HAS_GBM - if (glamor_egl->gbm) - gbm_device_destroy(glamor_egl->gbm); + if (glamor_egl->gbm) + gbm_device_destroy(glamor_egl->gbm); #endif - scrn->FreeScreen = glamor_egl->saved_free_screen; - free(glamor_egl); - scrn->FreeScreen(FREE_SCREEN_ARGS); - } + scrn->FreeScreen = glamor_egl->saved_free_screen; + free(glamor_egl); + scrn->FreeScreen(FREE_SCREEN_ARGS); + } } Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) { - struct glamor_egl_screen_private *glamor_egl; - const char *version; - EGLint config_attribs[] = { + struct glamor_egl_screen_private *glamor_egl; + const char *version; + + EGLint config_attribs[] = { #ifdef GLAMOR_GLES2 - EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_CLIENT_VERSION, 2, #endif - EGL_NONE - }; - - glamor_identify(0); - glamor_egl = calloc(sizeof(*glamor_egl), 1); - if (glamor_egl == NULL) - return FALSE; - if (xf86GlamorEGLPrivateIndex == -1) - xf86GlamorEGLPrivateIndex = - xf86AllocateScrnInfoPrivateIndex(); - - scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl; - glamor_egl->fd = fd; + EGL_NONE + }; + + glamor_identify(0); + glamor_egl = calloc(sizeof(*glamor_egl), 1); + if (glamor_egl == NULL) + return FALSE; + if (xf86GlamorEGLPrivateIndex == -1) + xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); + + scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl; + glamor_egl->fd = fd; #ifdef GLAMOR_HAS_GBM - glamor_egl->gbm = gbm_create_device(glamor_egl->fd); - if (glamor_egl->gbm == NULL) { - ErrorF("couldn't get display device\n"); - return FALSE; - } - glamor_egl->display = eglGetDisplay(glamor_egl->gbm); + glamor_egl->gbm = gbm_create_device(glamor_egl->fd); + if (glamor_egl->gbm == NULL) { + ErrorF("couldn't get display device\n"); + return FALSE; + } + glamor_egl->display = eglGetDisplay(glamor_egl->gbm); #else - glamor_egl->display = eglGetDisplay((EGLNativeDisplayType)(intptr_t)fd); + glamor_egl->display = eglGetDisplay((EGLNativeDisplayType) (intptr_t) fd); #endif - glamor_egl->has_gem = glamor_egl_check_has_gem(fd); + glamor_egl->has_gem = glamor_egl_check_has_gem(fd); #ifndef GLAMOR_GLES2 - eglBindAPI(EGL_OPENGL_API); + eglBindAPI(EGL_OPENGL_API); #else - eglBindAPI(EGL_OPENGL_ES_API); + eglBindAPI(EGL_OPENGL_ES_API); #endif - if (!eglInitialize - (glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) - { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "eglInitialize() failed\n"); - return FALSE; - } + if (!eglInitialize + (glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n"); + return FALSE; + } - version = eglQueryString(glamor_egl->display, EGL_VERSION); - xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); + version = eglQueryString(glamor_egl->display, EGL_VERSION); + xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); #define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) { \ @@ -765,96 +760,94 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) return FALSE; \ } - GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image); - GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image); + GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image); + GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image); #ifdef GLAMOR_GLES2 - GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_gles2); + GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_gles2); #else - GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_opengl); + GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, + KHR_surfaceless_opengl); #endif #ifdef GLAMOR_HAS_DRI3_SUPPORT - if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") && - glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import") ) - glamor_egl->dri3_capable = TRUE; + if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") && + glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import")) + glamor_egl->dri3_capable = TRUE; #endif - glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) - eglGetProcAddress("eglCreateImageKHR"); - - glamor_egl->egl_destroy_image_khr = (PFNEGLDESTROYIMAGEKHRPROC) - eglGetProcAddress("eglDestroyImageKHR"); - - glamor_egl->egl_image_target_texture2d_oes = - (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) - eglGetProcAddress("glEGLImageTargetTexture2DOES"); - - if (!glamor_egl->egl_create_image_khr - || !glamor_egl->egl_image_target_texture2d_oes) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "eglGetProcAddress() failed\n"); - return FALSE; - } - - glamor_egl->context = eglCreateContext(glamor_egl->display, - NULL, EGL_NO_CONTEXT, - config_attribs); - if (glamor_egl->context == EGL_NO_CONTEXT) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Failed to create EGL context\n"); - return FALSE; - } - - if (!eglMakeCurrent(glamor_egl->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - glamor_egl->context)) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "Failed to make EGL context current\n"); - return FALSE; - } + glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) + eglGetProcAddress("eglCreateImageKHR"); + + glamor_egl->egl_destroy_image_khr = (PFNEGLDESTROYIMAGEKHRPROC) + eglGetProcAddress("eglDestroyImageKHR"); + + glamor_egl->egl_image_target_texture2d_oes = + (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) + eglGetProcAddress("glEGLImageTargetTexture2DOES"); + + if (!glamor_egl->egl_create_image_khr + || !glamor_egl->egl_image_target_texture2d_oes) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglGetProcAddress() failed\n"); + return FALSE; + } + + glamor_egl->context = eglCreateContext(glamor_egl->display, + NULL, EGL_NO_CONTEXT, + config_attribs); + if (glamor_egl->context == EGL_NO_CONTEXT) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n"); + return FALSE; + } + + if (!eglMakeCurrent(glamor_egl->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "Failed to make EGL context current\n"); + return FALSE; + } #ifdef GLX_USE_SHARED_DISPATCH - GET_CURRENT_CONTEXT(glamor_egl->glamor_context); + GET_CURRENT_CONTEXT(glamor_egl->glamor_context); #endif - glamor_egl->saved_free_screen = scrn->FreeScreen; - scrn->FreeScreen = glamor_egl_free_screen; + glamor_egl->saved_free_screen = scrn->FreeScreen; + scrn->FreeScreen = glamor_egl_free_screen; #ifdef GLAMOR_GLES2 - xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using GLES2.\n"); + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using GLES2.\n"); #ifdef GLX_USE_SHARED_DISPATCH - xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Glamor is using GLES2 but GLX needs GL. " - "Indirect GLX may not work correctly.\n"); + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Glamor is using GLES2 but GLX needs GL. " + "Indirect GLX may not work correctly.\n"); #endif #endif - return TRUE; + return TRUE; } Bool glamor_egl_init_textured_pixmap(ScreenPtr screen) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - if (!dixRegisterPrivateKey - (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) { - LogMessage(X_WARNING, - "glamor%d: Failed to allocate egl pixmap private\n", - screen->myNum); - return FALSE; - } - if (glamor_egl->dri3_capable) - glamor_enable_dri3(screen); - return TRUE; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + if (!dixRegisterPrivateKey + (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) { + LogMessage(X_WARNING, + "glamor%d: Failed to allocate egl pixmap private\n", + screen->myNum); + return FALSE; + } + if (glamor_egl->dri3_capable) + glamor_enable_dri3(screen); + return TRUE; } Bool glamor_gl_dispatch_init(ScreenPtr screen, - struct glamor_gl_dispatch *dispatch, - int gl_version) + struct glamor_gl_dispatch *dispatch, int gl_version) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - if (!glamor_gl_dispatch_init_impl - (dispatch, gl_version, (get_proc_address_t)eglGetProcAddress)) - return FALSE; - glamor_egl->dispatch = dispatch; - return TRUE; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + if (!glamor_gl_dispatch_init_impl + (dispatch, gl_version, (get_proc_address_t) eglGetProcAddress)) + return FALSE; + glamor_egl->dispatch = dispatch; + return TRUE; } diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c index 9a0dec9..e7c8eda 100644 --- a/glamor/glamor_eglmodule.c +++ b/glamor/glamor_eglmodule.c @@ -37,16 +37,16 @@ #include "glamor.h" static XF86ModuleVersionInfo VersRec = { - GLAMOR_EGL_MODULE_NAME, - MODULEVENDORSTRING, - MODINFOSTRING1, - MODINFOSTRING2, - XORG_VERSION_CURRENT, - PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, - ABI_CLASS_ANSIC, /* Only need the ansic layer */ - ABI_ANSIC_VERSION, - MOD_CLASS_NONE, - {0, 0, 0, 0} /* signature, to be patched into the file by a tool */ + GLAMOR_EGL_MODULE_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, + ABI_CLASS_ANSIC, /* Only need the ansic layer */ + ABI_ANSIC_VERSION, + MOD_CLASS_NONE, + {0, 0, 0, 0} /* signature, to be patched into the file by a tool */ }; _X_EXPORT XF86ModuleData glamoreglModuleData = { &VersRec, NULL, NULL }; diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index d1b087e..76d5ddf 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -44,547 +44,552 @@ &pos->member != (head); \ pos = __container_of(pos->member.prev, pos, member)) - #define xorg_list_for_each_entry_safe_reverse(pos, tmp, head, member) \ for (pos = __container_of((head)->prev, pos, member), \ tmp = __container_of(pos->member.prev, pos, member); \ &pos->member != (head); \ pos = tmp, tmp = __container_of(pos->member.prev, tmp, member)) -inline static int cache_wbucket(int size) +inline static int +cache_wbucket(int size) { - int order = __fls(size / 32); - if (order >= CACHE_BUCKET_WCOUNT) - order = CACHE_BUCKET_WCOUNT - 1; - return order; + int order = __fls(size / 32); + + if (order >= CACHE_BUCKET_WCOUNT) + order = CACHE_BUCKET_WCOUNT - 1; + return order; } -inline static int cache_hbucket(int size) +inline static int +cache_hbucket(int size) { - int order = __fls(size / 32); - if (order >= CACHE_BUCKET_HCOUNT) - order = CACHE_BUCKET_HCOUNT - 1; - return order; + int order = __fls(size / 32); + + if (order >= CACHE_BUCKET_HCOUNT) + order = CACHE_BUCKET_HCOUNT - 1; + return order; } static glamor_pixmap_fbo * -glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, int flag) +glamor_pixmap_fbo_cache_get(glamor_screen_private * glamor_priv, + int w, int h, GLenum format, int flag) { - struct xorg_list *cache; - glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL; - int n_format; + struct xorg_list *cache; + glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL; + int n_format; + #ifdef NO_FBO_CACHE - return NULL; + return NULL; #else - n_format = cache_format(format); - if (n_format == -1) - return NULL; - cache = &glamor_priv->fbo_cache[n_format] - [cache_wbucket(w)] - [cache_hbucket(h)]; - if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) { - xorg_list_for_each_entry(fbo_entry, cache, list) { - if (fbo_entry->width >= w && fbo_entry->height >= h) { - - DEBUGF("Request w %d h %d format %x \n", w, h, format); - DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n", - fbo_entry, fbo_entry->width, fbo_entry->height, - fbo_entry->fb, fbo_entry->tex); - xorg_list_del(&fbo_entry->list); - ret_fbo = fbo_entry; - break; - } - } - } - else { - xorg_list_for_each_entry(fbo_entry, cache, list) { - if (fbo_entry->width == w && fbo_entry->height == h) { - - DEBUGF("Request w %d h %d format %x \n", w, h, format); - DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n", - fbo_entry, fbo_entry->width, fbo_entry->height, - fbo_entry->fb, fbo_entry->tex, fbo_entry->format); - assert(format == fbo_entry->format); - xorg_list_del(&fbo_entry->list); - ret_fbo = fbo_entry; - break; - } - } - } - - if (ret_fbo) - glamor_priv->fbo_cache_watermark -= ret_fbo->width * ret_fbo->height; - - assert(glamor_priv->fbo_cache_watermark >= 0); - - return ret_fbo; + n_format = cache_format(format); + if (n_format == -1) + return NULL; + cache = &glamor_priv->fbo_cache[n_format] + [cache_wbucket(w)] + [cache_hbucket(h)]; + if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) { + xorg_list_for_each_entry(fbo_entry, cache, list) { + if (fbo_entry->width >= w && fbo_entry->height >= h) { + + DEBUGF("Request w %d h %d format %x \n", w, h, format); + DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n", + fbo_entry, fbo_entry->width, fbo_entry->height, + fbo_entry->fb, fbo_entry->tex); + xorg_list_del(&fbo_entry->list); + ret_fbo = fbo_entry; + break; + } + } + } + else { + xorg_list_for_each_entry(fbo_entry, cache, list) { + if (fbo_entry->width == w && fbo_entry->height == h) { + + DEBUGF("Request w %d h %d format %x \n", w, h, format); + DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n", + fbo_entry, fbo_entry->width, fbo_entry->height, + fbo_entry->fb, fbo_entry->tex, fbo_entry->format); + assert(format == fbo_entry->format); + xorg_list_del(&fbo_entry->list); + ret_fbo = fbo_entry; + break; + } + } + } + + if (ret_fbo) + glamor_priv->fbo_cache_watermark -= ret_fbo->width * ret_fbo->height; + + assert(glamor_priv->fbo_cache_watermark >= 0); + + return ret_fbo; #endif } void -glamor_purge_fbo(glamor_pixmap_fbo *fbo) +glamor_purge_fbo(glamor_pixmap_fbo * fbo) { - glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv); - if (fbo->fb) - dispatch->glDeleteFramebuffers(1, &fbo->fb); - if (fbo->tex) - dispatch->glDeleteTextures(1, &fbo->tex); - if (fbo->pbo) - dispatch->glDeleteBuffers(1, &fbo->pbo); - glamor_put_dispatch(fbo->glamor_priv); - - free(fbo); + glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv); + + if (fbo->fb) + dispatch->glDeleteFramebuffers(1, &fbo->fb); + if (fbo->tex) + dispatch->glDeleteTextures(1, &fbo->tex); + if (fbo->pbo) + dispatch->glDeleteBuffers(1, &fbo->pbo); + glamor_put_dispatch(fbo->glamor_priv); + + free(fbo); } static void -glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo) +glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo * fbo) { - struct xorg_list *cache; - int n_format; + struct xorg_list *cache; + int n_format; #ifdef NO_FBO_CACHE - glamor_purge_fbo(fbo); - return; + glamor_purge_fbo(fbo); + return; #else - n_format = cache_format(fbo->format); - - if (fbo->fb == 0 || n_format == -1 - || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) { - fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX; - glamor_fbo_expire(fbo->glamor_priv); - glamor_purge_fbo(fbo); - return; - } - - cache = &fbo->glamor_priv->fbo_cache[n_format] - [cache_wbucket(fbo->width)] - [cache_hbucket(fbo->height)]; - DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache, - fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex); - - fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height; - xorg_list_add(&fbo->list, cache); - fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX; + n_format = cache_format(fbo->format); + + if (fbo->fb == 0 || n_format == -1 + || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) { + fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX; + glamor_fbo_expire(fbo->glamor_priv); + glamor_purge_fbo(fbo); + return; + } + + cache = &fbo->glamor_priv->fbo_cache[n_format] + [cache_wbucket(fbo->width)] + [cache_hbucket(fbo->height)]; + DEBUGF + ("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", + fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex); + + fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height; + xorg_list_add(&fbo->list, cache); + fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX; #endif } static void -glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo) +glamor_pixmap_ensure_fb(glamor_pixmap_fbo * fbo) { - glamor_gl_dispatch *dispatch; - int status; - - dispatch = glamor_get_dispatch(fbo->glamor_priv); - - if (fbo->fb == 0) - dispatch->glGenFramebuffers(1, &fbo->fb); - assert(fbo->tex != 0); - dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); - dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, fbo->tex, - 0); - status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - const char *str; - switch (status) { - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - str = "incomplete attachment"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - str = "incomplete/missing attachment"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - str = "incomplete draw buffer"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - str = "incomplete read buffer"; - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - str = "unsupported"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - str = "incomplete multiple"; - break; - default: - str = "unknown error"; - break; - } - - FatalError("destination is framebuffer incomplete: %s [%x]\n", - str, status); - } - glamor_put_dispatch(fbo->glamor_priv); + glamor_gl_dispatch *dispatch; + int status; + + dispatch = glamor_get_dispatch(fbo->glamor_priv); + + if (fbo->fb == 0) + dispatch->glGenFramebuffers(1, &fbo->fb); + assert(fbo->tex != 0); + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); + dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, fbo->tex, 0); + status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + const char *str; + + switch (status) { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + str = "incomplete attachment"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + str = "incomplete/missing attachment"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + str = "incomplete draw buffer"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + str = "incomplete read buffer"; + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + str = "unsupported"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + str = "incomplete multiple"; + break; + default: + str = "unknown error"; + break; + } + + FatalError("destination is framebuffer incomplete: %s [%x]\n", + str, status); + } + glamor_put_dispatch(fbo->glamor_priv); } glamor_pixmap_fbo * -glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, GLint tex, int flag) +glamor_create_fbo_from_tex(glamor_screen_private * glamor_priv, + int w, int h, GLenum format, GLint tex, int flag) { - glamor_pixmap_fbo *fbo; + glamor_pixmap_fbo *fbo; - fbo = calloc(1, sizeof(*fbo)); - if (fbo == NULL) - return NULL; + fbo = calloc(1, sizeof(*fbo)); + if (fbo == NULL) + return NULL; - xorg_list_init(&fbo->list); + xorg_list_init(&fbo->list); - fbo->tex = tex; - fbo->width = w; - fbo->height = h; - fbo->format = format; - fbo->glamor_priv = glamor_priv; + fbo->tex = tex; + fbo->width = w; + fbo->height = h; + fbo->format = format; + fbo->glamor_priv = glamor_priv; - if (flag == GLAMOR_CREATE_PIXMAP_MAP) { - glamor_gl_dispatch *dispatch; - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glGenBuffers(1, &fbo->pbo); - glamor_put_dispatch(glamor_priv); - goto done; - } + if (flag == GLAMOR_CREATE_PIXMAP_MAP) { + glamor_gl_dispatch *dispatch; - if (flag != GLAMOR_CREATE_FBO_NO_FBO) - glamor_pixmap_ensure_fb(fbo); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glGenBuffers(1, &fbo->pbo); + glamor_put_dispatch(glamor_priv); + goto done; + } -done: - return fbo; -} + if (flag != GLAMOR_CREATE_FBO_NO_FBO) + glamor_pixmap_ensure_fb(fbo); + done: + return fbo; +} void -glamor_fbo_expire(glamor_screen_private *glamor_priv) +glamor_fbo_expire(glamor_screen_private * glamor_priv) { - struct xorg_list *cache; - glamor_pixmap_fbo *fbo_entry, *tmp; - int i,j,k; - - for(i = 0; i < CACHE_FORMAT_COUNT; i++) - for(j = 0; j < CACHE_BUCKET_WCOUNT; j++) - for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) { - cache = &glamor_priv->fbo_cache[i][j][k]; - xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) { - if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) { - break; - } - - glamor_priv->fbo_cache_watermark -= fbo_entry->width * fbo_entry->height; - xorg_list_del(&fbo_entry->list); - DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry, - fbo_entry->expire, glamor_priv->tick); - glamor_purge_fbo(fbo_entry); - } - } + struct xorg_list *cache; + glamor_pixmap_fbo *fbo_entry, *tmp; + int i, j, k; + + for (i = 0; i < CACHE_FORMAT_COUNT; i++) + for (j = 0; j < CACHE_BUCKET_WCOUNT; j++) + for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) { + cache = &glamor_priv->fbo_cache[i][j][k]; + xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, + list) { + if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) { + break; + } + + glamor_priv->fbo_cache_watermark -= + fbo_entry->width * fbo_entry->height; + xorg_list_del(&fbo_entry->list); + DEBUGF("cache %p fbo %p expired %d current %d \n", cache, + fbo_entry, fbo_entry->expire, glamor_priv->tick); + glamor_purge_fbo(fbo_entry); + } + } } void glamor_init_pixmap_fbo(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - int i,j,k; - - glamor_priv = glamor_get_screen_private(screen); - for(i = 0; i < CACHE_FORMAT_COUNT; i++) - for(j = 0; j < CACHE_BUCKET_WCOUNT; j++) - for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) - { - xorg_list_init(&glamor_priv->fbo_cache[i][j][k]); - } - glamor_priv->fbo_cache_watermark = 0; + glamor_screen_private *glamor_priv; + int i, j, k; + + glamor_priv = glamor_get_screen_private(screen); + for (i = 0; i < CACHE_FORMAT_COUNT; i++) + for (j = 0; j < CACHE_BUCKET_WCOUNT; j++) + for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) { + xorg_list_init(&glamor_priv->fbo_cache[i][j][k]); + } + glamor_priv->fbo_cache_watermark = 0; } void glamor_fini_pixmap_fbo(ScreenPtr screen) { - struct xorg_list *cache; - glamor_screen_private *glamor_priv; - glamor_pixmap_fbo *fbo_entry, *tmp; - int i,j,k; - - glamor_priv = glamor_get_screen_private(screen); - for(i = 0; i < CACHE_FORMAT_COUNT; i++) - for(j = 0; j < CACHE_BUCKET_WCOUNT; j++) - for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) - { - cache = &glamor_priv->fbo_cache[i][j][k]; - xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) { - xorg_list_del(&fbo_entry->list); - glamor_purge_fbo(fbo_entry); - } - } + struct xorg_list *cache; + glamor_screen_private *glamor_priv; + glamor_pixmap_fbo *fbo_entry, *tmp; + int i, j, k; + + glamor_priv = glamor_get_screen_private(screen); + for (i = 0; i < CACHE_FORMAT_COUNT; i++) + for (j = 0; j < CACHE_BUCKET_WCOUNT; j++) + for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) { + cache = &glamor_priv->fbo_cache[i][j][k]; + xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, + list) { + xorg_list_del(&fbo_entry->list); + glamor_purge_fbo(fbo_entry); + } + } } void -glamor_destroy_fbo(glamor_pixmap_fbo *fbo) +glamor_destroy_fbo(glamor_pixmap_fbo * fbo) { - xorg_list_del(&fbo->list); - glamor_pixmap_fbo_cache_put(fbo); + xorg_list_del(&fbo->list); + glamor_pixmap_fbo_cache_put(fbo); } static int -_glamor_create_tex(glamor_screen_private *glamor_priv, - int w, int h, GLenum format) +_glamor_create_tex(glamor_screen_private * glamor_priv, + int w, int h, GLenum format) { - glamor_gl_dispatch *dispatch; - unsigned int tex = 0; - - /* With dri3, we want to allocate ARGB8888 pixmaps only. - * Depending on the implementation, GL_RGBA might not - * give us ARGB8888. We ask glamor_egl to use get - * an ARGB8888 based texture for us. */ - if (glamor_priv->dri3_enabled && format == GL_RGBA) - { - tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen, - w, h); - } - if (!tex) - { - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glGenTextures(1, &tex); - dispatch->glBindTexture(GL_TEXTURE_2D, tex); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, - format, GL_UNSIGNED_BYTE, NULL); - glamor_put_dispatch(glamor_priv); - } - return tex; + glamor_gl_dispatch *dispatch; + unsigned int tex = 0; + + /* With dri3, we want to allocate ARGB8888 pixmaps only. + * Depending on the implementation, GL_RGBA might not + * give us ARGB8888. We ask glamor_egl to use get + * an ARGB8888 based texture for us. */ + if (glamor_priv->dri3_enabled && format == GL_RGBA) { + tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen, + w, h); + } + if (!tex) { + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glGenTextures(1, &tex); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, + format, GL_UNSIGNED_BYTE, NULL); + glamor_put_dispatch(glamor_priv); + } + return tex; } glamor_pixmap_fbo * -glamor_create_fbo(glamor_screen_private *glamor_priv, - int w, int h, - GLenum format, - int flag) +glamor_create_fbo(glamor_screen_private * glamor_priv, + int w, int h, GLenum format, int flag) { - glamor_pixmap_fbo *fbo; - GLint tex = 0; - int cache_flag; - - if (!glamor_check_fbo_size(glamor_priv, w, h)) - return NULL; - - if (flag == GLAMOR_CREATE_FBO_NO_FBO) - goto new_fbo; - - if (flag == GLAMOR_CREATE_PIXMAP_MAP) - goto no_tex; - - if (flag == GLAMOR_CREATE_PIXMAP_FIXUP) - cache_flag = GLAMOR_CACHE_EXACT_SIZE; - else - cache_flag = 0; - - fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, - format, cache_flag); - if (fbo) - return fbo; -new_fbo: - tex = _glamor_create_tex(glamor_priv, w, h, format); -no_tex: - fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag); - - return fbo; + glamor_pixmap_fbo *fbo; + GLint tex = 0; + int cache_flag; + + if (!glamor_check_fbo_size(glamor_priv, w, h)) + return NULL; + + if (flag == GLAMOR_CREATE_FBO_NO_FBO) + goto new_fbo; + + if (flag == GLAMOR_CREATE_PIXMAP_MAP) + goto no_tex; + + if (flag == GLAMOR_CREATE_PIXMAP_FIXUP) + cache_flag = GLAMOR_CACHE_EXACT_SIZE; + else + cache_flag = 0; + + fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format, cache_flag); + if (fbo) + return fbo; + new_fbo: + tex = _glamor_create_tex(glamor_priv, w, h, format); + no_tex: + fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag); + + return fbo; } static glamor_pixmap_fbo * -_glamor_create_fbo_array(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, int flag, - int block_w, int block_h, - glamor_pixmap_private *pixmap_priv, - int has_fbo) +_glamor_create_fbo_array(glamor_screen_private * glamor_priv, + int w, int h, GLenum format, int flag, + int block_w, int block_h, + glamor_pixmap_private * pixmap_priv, int has_fbo) { - int block_wcnt; - int block_hcnt; - glamor_pixmap_fbo **fbo_array; - BoxPtr box_array; - int i,j; - glamor_pixmap_private_large_t *priv; - - priv = &pixmap_priv->large; - - block_wcnt = (w + block_w - 1) / block_w; - block_hcnt = (h + block_h - 1) / block_h; - - box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0])); - if (box_array == NULL) - return NULL; - - fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo*)); - if (fbo_array == NULL) { - free(box_array); - return FALSE; - } - for(i = 0; i < block_hcnt; i++) - { - int block_y1, block_y2; - int fbo_w, fbo_h; - - block_y1 = i * block_h; - block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h); - fbo_h = block_y2 - block_y1; - - for (j = 0; j < block_wcnt; j++) - { - box_array[i * block_wcnt + j].x1 = j * block_w; - box_array[i * block_wcnt + j].y1 = block_y1; - box_array[i * block_wcnt + j].x2 = (j + 1) * block_w > w ? w : (j + 1) * block_w; - box_array[i * block_wcnt + j].y2 = block_y2; - fbo_w = box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt + j].x1; - if (!has_fbo) - fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv, - fbo_w, fbo_h, format, - GLAMOR_CREATE_PIXMAP_FIXUP); - else - fbo_array[i * block_wcnt + j] = priv->base.fbo; - if (fbo_array[i * block_wcnt + j] == NULL) - goto cleanup; - } - } - - priv->box = box_array[0]; - priv->box_array = box_array; - priv->fbo_array = fbo_array; - priv->block_wcnt = block_wcnt; - priv->block_hcnt = block_hcnt; - return fbo_array[0]; - -cleanup: - for(i = 0; i < block_wcnt * block_hcnt; i++) - if ((fbo_array)[i]) - glamor_destroy_fbo((fbo_array)[i]); - free(box_array); - free(fbo_array); - return NULL; + int block_wcnt; + int block_hcnt; + glamor_pixmap_fbo **fbo_array; + BoxPtr box_array; + int i, j; + glamor_pixmap_private_large_t *priv; + + priv = &pixmap_priv->large; + + block_wcnt = (w + block_w - 1) / block_w; + block_hcnt = (h + block_h - 1) / block_h; + + box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0])); + if (box_array == NULL) + return NULL; + + fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo *)); + if (fbo_array == NULL) { + free(box_array); + return FALSE; + } + for (i = 0; i < block_hcnt; i++) { + int block_y1, block_y2; + int fbo_w, fbo_h; + + block_y1 = i * block_h; + block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h); + fbo_h = block_y2 - block_y1; + + for (j = 0; j < block_wcnt; j++) { + box_array[i * block_wcnt + j].x1 = j * block_w; + box_array[i * block_wcnt + j].y1 = block_y1; + box_array[i * block_wcnt + j].x2 = + (j + 1) * block_w > w ? w : (j + 1) * block_w; + box_array[i * block_wcnt + j].y2 = block_y2; + fbo_w = + box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt + + j].x1; + if (!has_fbo) + fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv, + fbo_w, fbo_h, + format, + GLAMOR_CREATE_PIXMAP_FIXUP); + else + fbo_array[i * block_wcnt + j] = priv->base.fbo; + if (fbo_array[i * block_wcnt + j] == NULL) + goto cleanup; + } + } + + priv->box = box_array[0]; + priv->box_array = box_array; + priv->fbo_array = fbo_array; + priv->block_wcnt = block_wcnt; + priv->block_hcnt = block_hcnt; + return fbo_array[0]; + + cleanup: + for (i = 0; i < block_wcnt * block_hcnt; i++) + if ((fbo_array)[i]) + glamor_destroy_fbo((fbo_array)[i]); + free(box_array); + free(fbo_array); + return NULL; } - /* Create a fbo array to cover the w*h region, by using block_w*block_h * block.*/ glamor_pixmap_fbo * -glamor_create_fbo_array(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, int flag, - int block_w, int block_h, - glamor_pixmap_private *pixmap_priv) +glamor_create_fbo_array(glamor_screen_private * glamor_priv, + int w, int h, GLenum format, int flag, + int block_w, int block_h, + glamor_pixmap_private * pixmap_priv) { - pixmap_priv->large.block_w = block_w; - pixmap_priv->large.block_h = block_h; - return _glamor_create_fbo_array(glamor_priv, w, h, format, flag, - block_w, block_h, pixmap_priv, 0); + pixmap_priv->large.block_w = block_w; + pixmap_priv->large.block_h = block_h; + return _glamor_create_fbo_array(glamor_priv, w, h, format, flag, + block_w, block_h, pixmap_priv, 0); } glamor_pixmap_fbo * -glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv) +glamor_pixmap_detach_fbo(glamor_pixmap_private * pixmap_priv) { - glamor_pixmap_fbo *fbo; + glamor_pixmap_fbo *fbo; - if (pixmap_priv == NULL) - return NULL; + if (pixmap_priv == NULL) + return NULL; - fbo = pixmap_priv->base.fbo; - if (fbo == NULL) - return NULL; + fbo = pixmap_priv->base.fbo; + if (fbo == NULL) + return NULL; - pixmap_priv->base.fbo = NULL; - return fbo; + pixmap_priv->base.fbo = NULL; + return fbo; } /* The pixmap must not be attached to another fbo. */ void -glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo) +glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo * fbo) { - glamor_pixmap_private *pixmap_priv; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (pixmap_priv->base.fbo) - return; - - pixmap_priv->base.fbo = fbo; - - switch (pixmap_priv->type) { - case GLAMOR_TEXTURE_LARGE: - case GLAMOR_TEXTURE_ONLY: - case GLAMOR_TEXTURE_DRM: - pixmap_priv->base.gl_fbo = 1; - if (fbo->tex != 0) - pixmap_priv->base.gl_tex = 1; - else { - /* XXX For the Xephyr only, may be broken now.*/ - pixmap_priv->base.gl_tex = 0; - } - case GLAMOR_MEMORY_MAP: - pixmap->devPrivate.ptr = NULL; - break; - default: - break; - } + glamor_pixmap_private *pixmap_priv; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (pixmap_priv->base.fbo) + return; + + pixmap_priv->base.fbo = fbo; + + switch (pixmap_priv->type) { + case GLAMOR_TEXTURE_LARGE: + case GLAMOR_TEXTURE_ONLY: + case GLAMOR_TEXTURE_DRM: + pixmap_priv->base.gl_fbo = 1; + if (fbo->tex != 0) + pixmap_priv->base.gl_tex = 1; + else { + /* XXX For the Xephyr only, may be broken now. */ + pixmap_priv->base.gl_tex = 0; + } + case GLAMOR_MEMORY_MAP: + pixmap->devPrivate.ptr = NULL; + break; + default: + break; + } } void -glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv) +glamor_pixmap_destroy_fbo(glamor_pixmap_private * priv) { - glamor_pixmap_fbo *fbo; - if (priv->type == GLAMOR_TEXTURE_LARGE) { - int i; - glamor_pixmap_private_large_t *large = &priv->large; - for(i = 0; i < large->block_wcnt * large->block_hcnt; i++) - glamor_destroy_fbo(large->fbo_array[i]); - free(large->fbo_array); - } else { - fbo = glamor_pixmap_detach_fbo(priv); - if (fbo) - glamor_destroy_fbo(fbo); - } - - free(priv); + glamor_pixmap_fbo *fbo; + + if (priv->type == GLAMOR_TEXTURE_LARGE) { + int i; + glamor_pixmap_private_large_t *large = &priv->large; + + for (i = 0; i < large->block_wcnt * large->block_hcnt; i++) + glamor_destroy_fbo(large->fbo_array[i]); + free(large->fbo_array); + } + else { + fbo = glamor_pixmap_detach_fbo(priv); + if (fbo) + glamor_destroy_fbo(fbo); + } + + free(priv); } Bool glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag) { - glamor_screen_private *glamor_priv; - glamor_pixmap_private *pixmap_priv; - glamor_pixmap_fbo *fbo; - - glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (pixmap_priv->base.fbo == NULL) { - - fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width, - pixmap->drawable.height, - format, - flag); - if (fbo == NULL) - return FALSE; - - glamor_pixmap_attach_fbo(pixmap, fbo); - } else { - /* We do have a fbo, but it may lack of fb or tex. */ - if (!pixmap_priv->base.fbo->tex) - pixmap_priv->base.fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width, - pixmap->drawable.height, format); - - if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0) - glamor_pixmap_ensure_fb(pixmap_priv->base.fbo); - } - - return TRUE; + glamor_screen_private *glamor_priv; + glamor_pixmap_private *pixmap_priv; + glamor_pixmap_fbo *fbo; + + glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (pixmap_priv->base.fbo == NULL) { + + fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width, + pixmap->drawable.height, format, flag); + if (fbo == NULL) + return FALSE; + + glamor_pixmap_attach_fbo(pixmap, fbo); + } + else { + /* We do have a fbo, but it may lack of fb or tex. */ + if (!pixmap_priv->base.fbo->tex) + pixmap_priv->base.fbo->tex = + _glamor_create_tex(glamor_priv, pixmap->drawable.width, + pixmap->drawable.height, format); + + if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0) + glamor_pixmap_ensure_fb(pixmap_priv->base.fbo); + } + + return TRUE; } _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back) { - glamor_pixmap_private *front_priv, *back_priv; - glamor_pixmap_fbo *temp_fbo; - - front_priv = glamor_get_pixmap_private(front); - back_priv = glamor_get_pixmap_private(back); - temp_fbo = front_priv->base.fbo; - front_priv->base.fbo = back_priv->base.fbo; - back_priv->base.fbo = temp_fbo; + glamor_pixmap_private *front_priv, *back_priv; + glamor_pixmap_fbo *temp_fbo; + + front_priv = glamor_get_pixmap_private(front); + back_priv = glamor_get_pixmap_private(back); + temp_fbo = front_priv->base.fbo; + front_priv->base.fbo = back_priv->base.fbo; + back_priv->base.fbo = temp_fbo; } diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index fbc8739..47d27bc 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -33,332 +33,318 @@ */ Bool glamor_fill(DrawablePtr drawable, - GCPtr gc, int x, int y, int width, int height, Bool fallback) + 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)) { - if (glamor_prepare_access_gc(gc)) { - fbFill(drawable, gc, x, y, width, height); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); - } - - 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; + 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)) { + if (glamor_prepare_access_gc(gc)) { + fbFill(drawable, gc, x, y, width, height); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + } + + 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; - glamor_gl_dispatch *dispatch; - 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); - dispatch = glamor_get_dispatch(glamor_priv); - glamor_priv->solid_prog = dispatch->glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs); - fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - solid_fs); - dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog); - dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog); - - dispatch->glBindAttribLocation(glamor_priv->solid_prog, - GLAMOR_VERTEX_POS, "v_position"); - glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog); - - glamor_priv->solid_color_uniform_location = - dispatch->glGetUniformLocation(glamor_priv->solid_prog, - "color"); - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + 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); + dispatch = glamor_get_dispatch(glamor_priv); + glamor_priv->solid_prog = dispatch->glCreateProgram(); + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs); + dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog); + dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog); + + dispatch->glBindAttribLocation(glamor_priv->solid_prog, + GLAMOR_VERTEX_POS, "v_position"); + glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog); + + glamor_priv->solid_color_uniform_location = + dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color"); + glamor_put_dispatch(glamor_priv); } void glamor_fini_solid_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glDeleteProgram(glamor_priv->solid_prog); - glamor_put_dispatch(glamor_priv); + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glDeleteProgram(glamor_priv->solid_prog); + glamor_put_dispatch(glamor_priv); } 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); - glamor_gl_dispatch *dispatch; - GLfloat xscale, yscale; - float vertices[32]; - float *pvertices = vertices; - int valid_nbox = ARRAY_SIZE(vertices); - - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glUseProgram(glamor_priv->solid_prog); - - dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, - 1, color); - - pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); - - if (unlikely(nbox*4*2 > ARRAY_SIZE(vertices))) { - int allocated_box; - - if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) { - allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6; - } else - allocated_box = nbox; - pvertices = malloc(allocated_box * 4 * 2 * sizeof(float)); - if (pvertices) - valid_nbox = allocated_box; - else { - pvertices = vertices; - valid_nbox = ARRAY_SIZE(vertices) / (4*2); - } - } - - if (unlikely(nbox > 1)) - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - pvertices); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - - while(nbox) { - int box_cnt, i; - float *valid_vertices; - valid_vertices = pvertices; - 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, - valid_vertices); - valid_vertices += 4*2; - } - if (box_cnt == 1) - dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4); - else + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_gl_dispatch *dispatch; + GLfloat xscale, yscale; + float vertices[32]; + float *pvertices = vertices; + int valid_nbox = ARRAY_SIZE(vertices); + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glUseProgram(glamor_priv->solid_prog); + + dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); + + pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); + + if (unlikely(nbox * 4 * 2 > ARRAY_SIZE(vertices))) { + int allocated_box; + + if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) { + allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6; + } + else + allocated_box = nbox; + pvertices = malloc(allocated_box * 4 * 2 * sizeof(float)); + if (pvertices) + valid_nbox = allocated_box; + else { + pvertices = vertices; + valid_nbox = ARRAY_SIZE(vertices) / (4 * 2); + } + } + + if (unlikely(nbox > 1)) + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), pvertices); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + + while (nbox) { + int box_cnt, i; + float *valid_vertices; + + valid_vertices = pvertices; + 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, + valid_vertices); + valid_vertices += 4 * 2; + } + if (box_cnt == 1) + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4); + else #ifndef GLAMOR_GLES2 - dispatch->glDrawRangeElements(GL_TRIANGLES, - 0, - box_cnt * 4, - box_cnt * 6, - GL_UNSIGNED_SHORT, - NULL); + dispatch->glDrawRangeElements(GL_TRIANGLES, + 0, + box_cnt * 4, + box_cnt * 6, GL_UNSIGNED_SHORT, NULL); #else - dispatch->glDrawElements(GL_TRIANGLES, - box_cnt * 6, - GL_UNSIGNED_SHORT, - NULL); + dispatch->glDrawElements(GL_TRIANGLES, + box_cnt * 6, GL_UNSIGNED_SHORT, NULL); #endif - nbox -= box_cnt; - box += box_cnt; - } - - if (pvertices != vertices) - free(pvertices); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; + nbox -= box_cnt; + box += box_cnt; + } + + if (pvertices != vertices) + free(pvertices); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); + glamor_priv->state = RENDER_STATE; + glamor_priv->render_idle_cnt = 0; } Bool glamor_solid_boxes(PixmapPtr pixmap, - BoxPtr box, int nbox, - unsigned long fg_pixel) + 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; + 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; } Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - unsigned long fg_pixel) + 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; - glamor_gl_dispatch *dispatch; - 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; - } - - dispatch = glamor_get_dispatch(glamor_priv); - if (!glamor_set_alu(dispatch, alu)) { - if (alu == GXclear) - fg_pixel = 0; - else { - glamor_fallback("unsupported alu %x\n", alu); - glamor_put_dispatch(glamor_priv); - 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(dispatch, GXcopy); - glamor_put_dispatch(glamor_priv); - - return TRUE; + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *pixmap_priv; + glamor_gl_dispatch *dispatch; + 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; + } + + dispatch = glamor_get_dispatch(glamor_priv); + if (!glamor_set_alu(dispatch, alu)) { + if (alu == GXclear) + fg_pixel = 0; + else { + glamor_fallback("unsupported alu %x\n", alu); + glamor_put_dispatch(glamor_priv); + 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(dispatch, GXcopy); + glamor_put_dispatch(glamor_priv); + + return TRUE; } - diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index 35e881f..7261d28 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -28,86 +28,81 @@ static Bool _glamor_fill_spans(DrawablePtr drawable, - GCPtr gc, - int n, DDXPointPtr points, int *widths, int sorted, Bool fallback) + GCPtr gc, + int n, DDXPointPtr points, int *widths, int sorted, + Bool fallback) { - DDXPointPtr ppt; - int nbox; - BoxPtr pbox; - int x1, x2, y; - RegionPtr pClip = fbGetCompositeClip(gc); - Bool ret = FALSE; + DDXPointPtr ppt; + int nbox; + BoxPtr pbox; + int x1, x2, y; + RegionPtr pClip = fbGetCompositeClip(gc); + Bool ret = FALSE; - if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) - goto fail; + if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) + goto fail; - ppt = points; - while (n--) { - x1 = ppt->x; - y = ppt->y; - x2 = x1 + (int) *widths; - ppt++; - widths++; + ppt = points; + while (n--) { + x1 = ppt->x; + y = ppt->y; + x2 = x1 + (int) *widths; + ppt++; + widths++; - nbox = REGION_NUM_RECTS(pClip); - pbox = REGION_RECTS(pClip); - while (nbox--) { - int real_x1 = x1, real_x2 = x2; + nbox = REGION_NUM_RECTS(pClip); + pbox = REGION_RECTS(pClip); + while (nbox--) { + int real_x1 = x1, real_x2 = x2; - if (real_x1 < pbox->x1) - real_x1 = pbox->x1; + if (real_x1 < pbox->x1) + real_x1 = pbox->x1; - if (real_x2 > pbox->x2) - real_x2 = pbox->x2; + if (real_x2 > pbox->x2) + real_x2 = pbox->x2; - if (real_x2 > real_x1 && pbox->y1 <= y && pbox->y2 > y) { - if (!glamor_fill(drawable, gc, real_x1, y, - real_x2 - real_x1, 1, fallback)) - goto fail; - } - pbox++; - } - } - ret = TRUE; - goto done; + if (real_x2 > real_x1 && pbox->y1 <= y && pbox->y2 > y) { + if (!glamor_fill(drawable, gc, real_x1, y, + real_x2 - real_x1, 1, fallback)) + goto fail; + } + pbox++; + } + } + ret = TRUE; + goto done; -fail: - if (!fallback - && glamor_ddx_fallback_check_pixmap(drawable) - && 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)) { - if (glamor_prepare_access_gc(gc)) { - fbFillSpans(drawable, gc, n, points, widths, - sorted); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); - } - ret = TRUE; + fail: + if (!fallback && glamor_ddx_fallback_check_pixmap(drawable) + && 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)) { + if (glamor_prepare_access_gc(gc)) { + fbFillSpans(drawable, gc, n, points, widths, sorted); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + } + ret = TRUE; -done: - return ret; + done: + return ret; } - void glamor_fill_spans(DrawablePtr drawable, - GCPtr gc, - int n, DDXPointPtr points, int *widths, int sorted) + GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted) { - _glamor_fill_spans(drawable, gc, n, points, widths, sorted, TRUE); + _glamor_fill_spans(drawable, gc, n, points, widths, sorted, TRUE); } Bool glamor_fill_spans_nf(DrawablePtr drawable, - GCPtr gc, - int n, DDXPointPtr points, int *widths, int sorted) + GCPtr gc, + int n, DDXPointPtr points, int *widths, int sorted) { - return _glamor_fill_spans(drawable, gc, n, points, widths, sorted, FALSE); + return _glamor_fill_spans(drawable, gc, n, points, widths, sorted, FALSE); } - - diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c index 5df576c..5609e70 100644 --- a/glamor/glamor_getimage.c +++ b/glamor/glamor_getimage.c @@ -28,74 +28,71 @@ #include "glamor_priv.h" - static Bool _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d, - Bool fallback) + unsigned int format, unsigned long planeMask, char *d, + Bool fallback) { - PixmapPtr pixmap, sub_pixmap; - struct glamor_pixmap_private *pixmap_priv; - int x_off, y_off; - int stride; - void *data; - - pixmap = glamor_get_drawable_pixmap(drawable); - glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); + PixmapPtr pixmap, sub_pixmap; + struct glamor_pixmap_private *pixmap_priv; + int x_off, y_off; + int stride; + void *data; - if (format != ZPixmap) - goto fall_back; - pixmap = glamor_get_drawable_pixmap(drawable); - glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); + pixmap = glamor_get_drawable_pixmap(drawable); + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - if (!glamor_set_planemask(pixmap, planeMask)) { - glamor_fallback - ("Failedto set planemask in glamor_solid.\n"); - goto fall_back; - } - pixmap_priv = glamor_get_pixmap_private(pixmap); + if (format != ZPixmap) + goto fall_back; + pixmap = glamor_get_drawable_pixmap(drawable); + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); + if (!glamor_set_planemask(pixmap, planeMask)) { + glamor_fallback("Failedto set planemask in glamor_solid.\n"); + goto fall_back; + } + pixmap_priv = glamor_get_pixmap_private(pixmap); - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - goto fall_back; - stride = PixmapBytePad(w, drawable->depth); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto fall_back; + stride = PixmapBytePad(w, drawable->depth); - x += drawable->x + x_off; - y += drawable->y + y_off; + x += drawable->x + x_off; + y += drawable->y + y_off; - data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride, - d, 0, GLAMOR_ACCESS_RO); - if (data != NULL) { - assert(data == d); - return TRUE; - } -fall_back: - sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, - y + y_off + drawable->y, w, h, - GLAMOR_ACCESS_RO); - if (sub_pixmap) { - fbGetImage(&sub_pixmap->drawable, 0, 0, w, h, format, planeMask, d); - glamor_put_sub_pixmap(sub_pixmap, pixmap, - x + x_off + drawable->x, - y + y_off + drawable->y, - w, h, GLAMOR_ACCESS_RO); - } else - miGetImage(drawable, x, y, w, h, format, planeMask, d); + data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride, + d, 0, GLAMOR_ACCESS_RO); + if (data != NULL) { + assert(data == d); + return TRUE; + } + fall_back: + sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, + y + y_off + drawable->y, w, h, + GLAMOR_ACCESS_RO); + if (sub_pixmap) { + fbGetImage(&sub_pixmap->drawable, 0, 0, w, h, format, planeMask, d); + glamor_put_sub_pixmap(sub_pixmap, pixmap, + x + x_off + drawable->x, + y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RO); + } + else + miGetImage(drawable, x, y, w, h, format, planeMask, d); - return TRUE; + return TRUE; } void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d) + unsigned int format, unsigned long planeMask, char *d) { - _glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE); + _glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE); } Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d) + unsigned int format, unsigned long planeMask, char *d) { - return _glamor_get_image(pDrawable, x, y, w, - h, format, planeMask, d, FALSE); + return _glamor_get_image(pDrawable, x, y, w, + h, format, planeMask, d, FALSE); } diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 6d6c8e9..afb76f6 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -28,68 +28,64 @@ #include "glamor_priv.h" -static Bool +static Bool _glamor_get_spans(DrawablePtr drawable, - int wmax, - DDXPointPtr points, int *widths, int count, char *dst, - Bool fallback) + int wmax, + DDXPointPtr points, int *widths, int count, char *dst, + Bool fallback) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = - glamor_get_pixmap_private(pixmap); - int i; - uint8_t *readpixels_dst = (uint8_t *) dst; - void *data; - int x_off, y_off; - Bool ret = FALSE; + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + int i; + uint8_t *readpixels_dst = (uint8_t *) dst; + void *data; + int x_off, y_off; + Bool ret = FALSE; - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - goto fail; + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto fail; - glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - for (i = 0; i < count; i++) { - data = glamor_download_sub_pixmap_to_cpu(pixmap, points[i].x + x_off, - points[i].y + y_off, widths[i], 1, - PixmapBytePad(widths[i], drawable->depth), - readpixels_dst, 0, GLAMOR_ACCESS_RO); - assert(data == readpixels_dst); - readpixels_dst += PixmapBytePad(widths[i], drawable->depth); - } + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); + for (i = 0; i < count; i++) { + data = glamor_download_sub_pixmap_to_cpu(pixmap, points[i].x + x_off, + points[i].y + y_off, widths[i], + 1, PixmapBytePad(widths[i], + drawable-> + depth), + readpixels_dst, 0, + GLAMOR_ACCESS_RO); + assert(data == readpixels_dst); + readpixels_dst += PixmapBytePad(widths[i], drawable->depth); + } - ret = TRUE; - goto done; -fail: + ret = TRUE; + goto done; + fail: - if (!fallback - && glamor_ddx_fallback_check_pixmap(drawable)) - goto done; + if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)) + goto done; - ret = TRUE; - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) { - fbGetSpans(drawable, wmax, points, widths, count, dst); - glamor_finish_access(drawable, GLAMOR_ACCESS_RO); - } -done: - return ret; + ret = TRUE; + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) { + fbGetSpans(drawable, wmax, points, widths, count, dst); + glamor_finish_access(drawable, GLAMOR_ACCESS_RO); + } + done: + return ret; } void glamor_get_spans(DrawablePtr drawable, - int wmax, - DDXPointPtr points, int *widths, int count, char *dst) + int wmax, + DDXPointPtr points, int *widths, int count, char *dst) { - _glamor_get_spans(drawable, wmax, points, - widths, count, dst, TRUE); + _glamor_get_spans(drawable, wmax, points, widths, count, dst, TRUE); } Bool glamor_get_spans_nf(DrawablePtr drawable, - int wmax, - DDXPointPtr points, int *widths, int count, char *dst) + int wmax, + DDXPointPtr points, int *widths, int count, char *dst) { - return _glamor_get_spans(drawable, wmax, points, - widths, count, dst, FALSE); + return _glamor_get_spans(drawable, wmax, points, widths, count, dst, FALSE); } - - - diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c index da99e26..0bdda9c 100644 --- a/glamor/glamor_gl_dispatch.c +++ b/glamor/glamor_gl_dispatch.c @@ -41,78 +41,78 @@ _X_EXPORT Bool glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, - int gl_version, - void *(*get_proc_address) (const char *)) + int gl_version, + void *(*get_proc_address) (const char *)) { #ifndef GLAMOR_GLES2 - INIT_FUNC(dispatch, glMatrixMode, get_proc_address); - INIT_FUNC(dispatch, glLoadIdentity, get_proc_address); - INIT_FUNC(dispatch, glRasterPos2i, get_proc_address); - INIT_FUNC(dispatch, glDrawPixels, get_proc_address); - INIT_FUNC(dispatch, glLogicOp, get_proc_address); - INIT_FUNC(dispatch, glMapBuffer, get_proc_address); - INIT_FUNC(dispatch, glMapBufferRange, get_proc_address); - INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address); - INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address); - INIT_FUNC(dispatch, glDrawRangeElements, get_proc_address); + INIT_FUNC(dispatch, glMatrixMode, get_proc_address); + INIT_FUNC(dispatch, glLoadIdentity, get_proc_address); + INIT_FUNC(dispatch, glRasterPos2i, get_proc_address); + INIT_FUNC(dispatch, glDrawPixels, get_proc_address); + INIT_FUNC(dispatch, glLogicOp, get_proc_address); + INIT_FUNC(dispatch, glMapBuffer, get_proc_address); + INIT_FUNC(dispatch, glMapBufferRange, get_proc_address); + INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address); + INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address); + INIT_FUNC(dispatch, glDrawRangeElements, get_proc_address); #endif - INIT_FUNC(dispatch, glViewport, get_proc_address); - INIT_FUNC(dispatch, glDrawArrays, get_proc_address); - INIT_FUNC(dispatch, glDrawElements, get_proc_address); - INIT_FUNC(dispatch, glReadPixels, get_proc_address); - INIT_FUNC(dispatch, glPixelStorei, get_proc_address); - INIT_FUNC(dispatch, glTexParameteri, get_proc_address); - INIT_FUNC(dispatch, glTexImage2D, get_proc_address); - INIT_FUNC(dispatch, glGenTextures, get_proc_address); - INIT_FUNC(dispatch, glDeleteTextures, get_proc_address); - INIT_FUNC(dispatch, glBindTexture, get_proc_address); - INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address); - INIT_FUNC(dispatch, glFlush, get_proc_address); - INIT_FUNC(dispatch, glFinish, get_proc_address); - INIT_FUNC(dispatch, glGetIntegerv, get_proc_address); - INIT_FUNC(dispatch, glGetString, get_proc_address); - INIT_FUNC(dispatch, glScissor, get_proc_address); - INIT_FUNC(dispatch, glEnable, get_proc_address); - INIT_FUNC(dispatch, glDisable, get_proc_address); - INIT_FUNC(dispatch, glBlendFunc, get_proc_address); - INIT_FUNC(dispatch, glActiveTexture, get_proc_address); - INIT_FUNC(dispatch, glGenBuffers, get_proc_address); - INIT_FUNC(dispatch, glBufferData, get_proc_address); - INIT_FUNC(dispatch, glBindBuffer, get_proc_address); - INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address); - INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address); - INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address); - INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address); - INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address); - INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address); - INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address); - INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address); - INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address); - INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address); - INIT_FUNC(dispatch, glLinkProgram, get_proc_address); - INIT_FUNC(dispatch, glShaderSource, get_proc_address); + INIT_FUNC(dispatch, glViewport, get_proc_address); + INIT_FUNC(dispatch, glDrawArrays, get_proc_address); + INIT_FUNC(dispatch, glDrawElements, get_proc_address); + INIT_FUNC(dispatch, glReadPixels, get_proc_address); + INIT_FUNC(dispatch, glPixelStorei, get_proc_address); + INIT_FUNC(dispatch, glTexParameteri, get_proc_address); + INIT_FUNC(dispatch, glTexImage2D, get_proc_address); + INIT_FUNC(dispatch, glGenTextures, get_proc_address); + INIT_FUNC(dispatch, glDeleteTextures, get_proc_address); + INIT_FUNC(dispatch, glBindTexture, get_proc_address); + INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address); + INIT_FUNC(dispatch, glFlush, get_proc_address); + INIT_FUNC(dispatch, glFinish, get_proc_address); + INIT_FUNC(dispatch, glGetIntegerv, get_proc_address); + INIT_FUNC(dispatch, glGetString, get_proc_address); + INIT_FUNC(dispatch, glScissor, get_proc_address); + INIT_FUNC(dispatch, glEnable, get_proc_address); + INIT_FUNC(dispatch, glDisable, get_proc_address); + INIT_FUNC(dispatch, glBlendFunc, get_proc_address); + INIT_FUNC(dispatch, glActiveTexture, get_proc_address); + INIT_FUNC(dispatch, glGenBuffers, get_proc_address); + INIT_FUNC(dispatch, glBufferData, get_proc_address); + INIT_FUNC(dispatch, glBindBuffer, get_proc_address); + INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address); + INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address); + INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address); + INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address); + INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address); + INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address); + INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address); + INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address); + INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address); + INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address); + INIT_FUNC(dispatch, glLinkProgram, get_proc_address); + INIT_FUNC(dispatch, glShaderSource, get_proc_address); - INIT_FUNC(dispatch, glUseProgram, get_proc_address); - INIT_FUNC(dispatch, glUniform1i, get_proc_address); - INIT_FUNC(dispatch, glUniform1f, get_proc_address); - INIT_FUNC(dispatch, glUniform4f, get_proc_address); - INIT_FUNC(dispatch, glUniform4fv, get_proc_address); - INIT_FUNC(dispatch, glUniform1fv, get_proc_address); - INIT_FUNC(dispatch, glUniform2fv, get_proc_address); - INIT_FUNC(dispatch, glUniformMatrix3fv, get_proc_address); - INIT_FUNC(dispatch, glCreateProgram, get_proc_address); - INIT_FUNC(dispatch, glDeleteProgram, get_proc_address); - INIT_FUNC(dispatch, glCreateShader, get_proc_address); - INIT_FUNC(dispatch, glCompileShader, get_proc_address); - INIT_FUNC(dispatch, glAttachShader, get_proc_address); - INIT_FUNC(dispatch, glDeleteShader, get_proc_address); - INIT_FUNC(dispatch, glGetShaderiv, get_proc_address); - INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address); - INIT_FUNC(dispatch, glGetProgramiv, get_proc_address); - INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address); - INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address); + INIT_FUNC(dispatch, glUseProgram, get_proc_address); + INIT_FUNC(dispatch, glUniform1i, get_proc_address); + INIT_FUNC(dispatch, glUniform1f, get_proc_address); + INIT_FUNC(dispatch, glUniform4f, get_proc_address); + INIT_FUNC(dispatch, glUniform4fv, get_proc_address); + INIT_FUNC(dispatch, glUniform1fv, get_proc_address); + INIT_FUNC(dispatch, glUniform2fv, get_proc_address); + INIT_FUNC(dispatch, glUniformMatrix3fv, get_proc_address); + INIT_FUNC(dispatch, glCreateProgram, get_proc_address); + INIT_FUNC(dispatch, glDeleteProgram, get_proc_address); + INIT_FUNC(dispatch, glCreateShader, get_proc_address); + INIT_FUNC(dispatch, glCompileShader, get_proc_address); + INIT_FUNC(dispatch, glAttachShader, get_proc_address); + INIT_FUNC(dispatch, glDeleteShader, get_proc_address); + INIT_FUNC(dispatch, glGetShaderiv, get_proc_address); + INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address); + INIT_FUNC(dispatch, glGetProgramiv, get_proc_address); + INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address); + INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address); - return TRUE; - fail: - return FALSE; + return TRUE; + fail: + return FALSE; } diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h index 76dadd4..63790b4 100644 --- a/glamor/glamor_gl_dispatch.h +++ b/glamor/glamor_gl_dispatch.h @@ -1,138 +1,128 @@ typedef struct glamor_gl_dispatch { - /* Transformation functions */ - void (*glMatrixMode) (GLenum mode); - void (*glLoadIdentity) (void); - void (*glViewport) (GLint x, GLint y, GLsizei width, - GLsizei height); - /* Drawing functions */ - void (*glRasterPos2i) (GLint x, GLint y); - - /* Vertex Array */ - void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count); - - /* Elements Array*/ - void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices); - void (*glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices); - - /* Raster functions */ - void (*glReadPixels) (GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid * pixels); - - void (*glDrawPixels) (GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels); - void (*glPixelStorei) (GLenum pname, GLint param); - /* Texture Mapping */ - - void (*glTexParameteri) (GLenum target, GLenum pname, GLint param); - void (*glTexImage2D) (GLenum target, GLint level, - GLint internalFormat, - GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, - const GLvoid * pixels); - /* 1.1 */ - void (*glGenTextures) (GLsizei n, GLuint * textures); - void (*glDeleteTextures) (GLsizei n, const GLuint * textures); - void (*glBindTexture) (GLenum target, GLuint texture); - void (*glTexSubImage2D) (GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels); - /* MISC */ - void (*glFlush) (void); - void (*glFinish) (void); - void (*glGetIntegerv) (GLenum pname, GLint * params); - const GLubyte *(*glGetString) (GLenum name); - void (*glScissor) (GLint x, GLint y, GLsizei width, - GLsizei height); - void (*glEnable) (GLenum cap); - void (*glDisable) (GLenum cap); - void (*glBlendFunc) (GLenum sfactor, GLenum dfactor); - void (*glLogicOp) (GLenum opcode); - - /* 1.3 */ - void (*glActiveTexture) (GLenum texture); - - /* GL Extentions */ - void (*glGenBuffers) (GLsizei n, GLuint * buffers); - void (*glBufferData) (GLenum target, GLsizeiptr size, - const GLvoid * data, GLenum usage); - GLvoid *(*glMapBuffer) (GLenum target, GLenum access); - GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); - GLboolean (*glUnmapBuffer) (GLenum target); - void (*glBindBuffer) (GLenum target, GLuint buffer); - void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers); - - void (*glFramebufferTexture2D) (GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level); - void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); - void (*glDeleteFramebuffers) (GLsizei n, - const GLuint * framebuffers); - void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers); - GLenum (*glCheckFramebufferStatus) (GLenum target); - void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, - GLint srcY1, GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - - void (*glVertexAttribPointer) (GLuint index, GLint size, - GLenum type, GLboolean normalized, - GLsizei stride, - const GLvoid * pointer); - void (*glDisableVertexAttribArray) (GLuint index); - void (*glEnableVertexAttribArray) (GLuint index); - void (*glBindAttribLocation) (GLuint program, GLuint index, - const GLchar * name); - - void (*glLinkProgram) (GLuint program); - void (*glShaderSource) (GLuint shader, GLsizei count, - const GLchar * *string, - const GLint * length); - void (*glUseProgram) (GLuint program); - void (*glUniform1i) (GLint location, GLint v0); - void (*glUniform1f) (GLint location, GLfloat v0); - void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, - GLfloat v2, GLfloat v3); - void (*glUniform1fv) (GLint location, GLsizei count, - const GLfloat * value); - void (*glUniform2fv) (GLint location, GLsizei count, - const GLfloat * value); - void (*glUniform4fv) (GLint location, GLsizei count, - const GLfloat * value); - void (*glUniformMatrix3fv) (GLint location, GLsizei count, - GLboolean transpose, const GLfloat* value); - GLuint (*glCreateProgram) (void); - GLuint (*glDeleteProgram) (GLuint); - GLuint (*glCreateShader) (GLenum type); - void (*glCompileShader) (GLuint shader); - void (*glAttachShader) (GLuint program, GLuint shader); - void (*glDeleteShader) (GLuint shader); - void (*glGetShaderiv) (GLuint shader, GLenum pname, - GLint * params); - void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize, - GLsizei * length, GLchar * infoLog); - void (*glGetProgramiv) (GLuint program, GLenum pname, - GLint * params); - void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize, - GLsizei * length, GLchar * infoLog); - GLint (*glGetUniformLocation) (GLuint program, - const GLchar * name); + /* Transformation functions */ + void (*glMatrixMode) (GLenum mode); + void (*glLoadIdentity) (void); + void (*glViewport) (GLint x, GLint y, GLsizei width, GLsizei height); + /* Drawing functions */ + void (*glRasterPos2i) (GLint x, GLint y); + + /* Vertex Array */ + void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count); + + /* Elements Array */ + void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices); + void (*glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid * indices); + + /* Raster functions */ + void (*glReadPixels) (GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid * pixels); + + void (*glDrawPixels) (GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid * pixels); + void (*glPixelStorei) (GLenum pname, GLint param); + /* Texture Mapping */ + + void (*glTexParameteri) (GLenum target, GLenum pname, GLint param); + void (*glTexImage2D) (GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid * pixels); + /* 1.1 */ + void (*glGenTextures) (GLsizei n, GLuint * textures); + void (*glDeleteTextures) (GLsizei n, const GLuint * textures); + void (*glBindTexture) (GLenum target, GLuint texture); + void (*glTexSubImage2D) (GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid * pixels); + /* MISC */ + void (*glFlush) (void); + void (*glFinish) (void); + void (*glGetIntegerv) (GLenum pname, GLint * params); + const GLubyte *(*glGetString) (GLenum name); + void (*glScissor) (GLint x, GLint y, GLsizei width, GLsizei height); + void (*glEnable) (GLenum cap); + void (*glDisable) (GLenum cap); + void (*glBlendFunc) (GLenum sfactor, GLenum dfactor); + void (*glLogicOp) (GLenum opcode); + + /* 1.3 */ + void (*glActiveTexture) (GLenum texture); + + /* GL Extentions */ + void (*glGenBuffers) (GLsizei n, GLuint * buffers); + void (*glBufferData) (GLenum target, GLsizeiptr size, + const GLvoid * data, GLenum usage); + GLvoid *(*glMapBuffer) (GLenum target, GLenum access); + GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset, + GLsizeiptr length, GLbitfield access); + GLboolean(*glUnmapBuffer) (GLenum target); + void (*glBindBuffer) (GLenum target, GLuint buffer); + void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers); + + void (*glFramebufferTexture2D) (GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level); + void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); + void (*glDeleteFramebuffers) (GLsizei n, const GLuint * framebuffers); + void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers); + GLenum(*glCheckFramebufferStatus) (GLenum target); + void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, + GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + + void (*glVertexAttribPointer) (GLuint index, GLint size, + GLenum type, GLboolean normalized, + GLsizei stride, const GLvoid * pointer); + void (*glDisableVertexAttribArray) (GLuint index); + void (*glEnableVertexAttribArray) (GLuint index); + void (*glBindAttribLocation) (GLuint program, GLuint index, + const GLchar * name); + + void (*glLinkProgram) (GLuint program); + void (*glShaderSource) (GLuint shader, GLsizei count, + const GLchar * *string, const GLint * length); + void (*glUseProgram) (GLuint program); + void (*glUniform1i) (GLint location, GLint v0); + void (*glUniform1f) (GLint location, GLfloat v0); + void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, + GLfloat v2, GLfloat v3); + void (*glUniform1fv) (GLint location, GLsizei count, const GLfloat * value); + void (*glUniform2fv) (GLint location, GLsizei count, const GLfloat * value); + void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat * value); + void (*glUniformMatrix3fv) (GLint location, GLsizei count, + GLboolean transpose, const GLfloat * value); + GLuint(*glCreateProgram) (void); + GLuint(*glDeleteProgram) (GLuint); + GLuint(*glCreateShader) (GLenum type); + void (*glCompileShader) (GLuint shader); + void (*glAttachShader) (GLuint program, GLuint shader); + void (*glDeleteShader) (GLuint shader); + void (*glGetShaderiv) (GLuint shader, GLenum pname, GLint * params); + void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize, + GLsizei * length, GLchar * infoLog); + void (*glGetProgramiv) (GLuint program, GLenum pname, GLint * params); + void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize, + GLsizei * length, GLchar * infoLog); + GLint(*glGetUniformLocation) (GLuint program, const GLchar * name); } glamor_gl_dispatch; - typedef void *(*get_proc_address_t) (const char *); _X_EXPORT Bool -glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, - int gl_version, - get_proc_address_t get_proc_address); +glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, + int gl_version, + get_proc_address_t get_proc_address); _X_EXPORT Bool + glamor_gl_dispatch_init(ScreenPtr screen, - struct glamor_gl_dispatch *dispatch, - int gl_version); + struct glamor_gl_dispatch *dispatch, int gl_version); diff --git a/glamor/glamor_glext.h b/glamor/glamor_glext.h index 1f7206b..2a220c3 100644 --- a/glamor/glamor_glext.h +++ b/glamor/glamor_glext.h @@ -26,7 +26,6 @@ * */ - #ifdef GLAMOR_GLES2 #define GL_BGRA GL_BGRA_EXT diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c index b55327c..ac97157 100644 --- a/glamor/glamor_glyphblt.c +++ b/glamor/glamor_glyphblt.c @@ -30,89 +30,90 @@ static Bool _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase, Bool fallback) + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase, Bool fallback) { - if (!fallback - && glamor_ddx_fallback_check_pixmap(pDrawable) - && glamor_ddx_fallback_check_gc(pGC)) - return FALSE; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) + && glamor_ddx_fallback_check_gc(pGC)) + return FALSE; - miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - return TRUE; + miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + return TRUE; } void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase) + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase) { - _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, TRUE); + _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, + TRUE); } Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase) + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase) { - return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, FALSE); + return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, + pglyphBase, FALSE); } static Bool _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase, Bool fallback) + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase, Bool fallback) { - if (!fallback - && glamor_ddx_fallback_check_pixmap(pDrawable) - && glamor_ddx_fallback_check_gc(pGC)) - return FALSE; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) + && glamor_ddx_fallback_check_gc(pGC)) + return FALSE; - miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - return TRUE; + miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + return TRUE; } void glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase) + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase) { - _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, TRUE); + _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, + TRUE); } Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase) + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase) { - return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, FALSE); + return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, + pglyphBase, FALSE); } static Bool _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback) + DrawablePtr pDrawable, int w, int h, int x, int y, + Bool fallback) { - if (!fallback - && glamor_ddx_fallback_check_pixmap(pDrawable) - && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable) - && glamor_ddx_fallback_check_gc(pGC)) - return FALSE; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) + && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable) + && glamor_ddx_fallback_check_gc(pGC)) + return FALSE; - miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); - return TRUE; + miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); + return TRUE; } void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y) + DrawablePtr pDrawable, int w, int h, int x, int y) { - _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE); + _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE); } Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y) + DrawablePtr pDrawable, int w, int h, int x, int y) { - return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE); + return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE); } - diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index fc361df..ed7cfc2 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -71,25 +71,25 @@ #define MASK_CACHE_MASK ((1LL << (MASK_CACHE_WIDTH)) - 1) typedef struct { - PicturePtr source; - glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4]; - int count; + PicturePtr source; + glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4]; + int count; } glamor_glyph_buffer_t; struct glamor_glyph { - glamor_glyph_cache_t *cache; - uint16_t x, y; - uint16_t size, pos; - unsigned long long left_x1_map, left_x2_map; - unsigned long long right_x1_map, right_x2_map; /* Use to check real intersect or not. */ - Bool has_edge_map; - Bool cached; + glamor_glyph_cache_t *cache; + uint16_t x, y; + uint16_t size, pos; + unsigned long long left_x1_map, left_x2_map; + unsigned long long right_x1_map, right_x2_map; /* Use to check real intersect or not. */ + Bool has_edge_map; + Bool cached; }; typedef enum { - GLAMOR_GLYPH_SUCCESS, /* Glyph added to render buffer */ - GLAMOR_GLYPH_FAIL, /* out of memory, etc */ - GLAMOR_GLYPH_NEED_FLUSH, /* would evict a glyph already in the buffer */ + GLAMOR_GLYPH_SUCCESS, /* Glyph added to render buffer */ + GLAMOR_GLYPH_FAIL, /* out of memory, etc */ + GLAMOR_GLYPH_NEED_FLUSH, /* would evict a glyph already in the buffer */ } glamor_glyph_cache_result_t; #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) @@ -98,7 +98,7 @@ static DevPrivateKeyRec glamor_glyph_key; static inline struct glamor_glyph * glamor_glyph_get_private(GlyphPtr glyph) { - return (struct glamor_glyph*)glyph->devPrivates; + return (struct glamor_glyph *) glyph->devPrivates; } /* @@ -122,170 +122,175 @@ glamor_glyph_get_private(GlyphPtr glyph) */ struct glamor_glyph_mask_cache_entry { - int idx; - int width; - int height; - int x; - int y; + int idx; + int width; + int height; + int x; + int y; }; static struct glamor_glyph_mask_cache { - PixmapPtr pixmap; - struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH]; - unsigned int free_bitmap; - unsigned int cleared_bitmap; -}*mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS] = {NULL}; + PixmapPtr pixmap; + struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH]; + unsigned int free_bitmap; + unsigned int cleared_bitmap; +} *mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS] = { +NULL}; static void clear_mask_cache_bitmap(struct glamor_glyph_mask_cache *maskcache, - unsigned int clear_mask_bits) + unsigned int clear_mask_bits) { - unsigned int i = 0; - BoxRec box[MASK_CACHE_WIDTH]; - int box_cnt = 0; - - assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0); - for(i = 0; i < MASK_CACHE_WIDTH;i++) - { - if (clear_mask_bits & (1 << i)) { - box[box_cnt].x1 = maskcache->mcache[i].x; - box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE; - box[box_cnt].y1 = maskcache->mcache[i].y; - box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE; - box_cnt++; - } - } - glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0); - maskcache->cleared_bitmap |= clear_mask_bits; + unsigned int i = 0; + BoxRec box[MASK_CACHE_WIDTH]; + int box_cnt = 0; + + assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0); + for (i = 0; i < MASK_CACHE_WIDTH; i++) { + if (clear_mask_bits & (1 << i)) { + box[box_cnt].x1 = maskcache->mcache[i].x; + box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE; + box[box_cnt].y1 = maskcache->mcache[i].y; + box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE; + box_cnt++; + } + } + glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0); + maskcache->cleared_bitmap |= clear_mask_bits; } static void clear_mask_cache(struct glamor_glyph_mask_cache *maskcache) { - int x = 0; - int cnt = MASK_CACHE_WIDTH; - unsigned int i = 0; - 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); - mce = &maskcache->mcache[0]; - while(cnt--) { - mce->width = 0; - mce->height = 0; - mce->x = x; - mce->y = CACHE_PICTURE_SIZE; - mce->idx = i++; - x += MASK_CACHE_MAX_SIZE; - mce++; - } - maskcache->free_bitmap = MASK_CACHE_MASK; - maskcache->cleared_bitmap = MASK_CACHE_MASK; + int x = 0; + int cnt = MASK_CACHE_WIDTH; + unsigned int i = 0; + 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); + mce = &maskcache->mcache[0]; + while (cnt--) { + mce->width = 0; + mce->height = 0; + mce->x = x; + mce->y = CACHE_PICTURE_SIZE; + mce->idx = i++; + x += MASK_CACHE_MAX_SIZE; + mce++; + } + maskcache->free_bitmap = MASK_CACHE_MASK; + maskcache->cleared_bitmap = MASK_CACHE_MASK; } static int find_continuous_bits(unsigned int bits, int bits_cnt, unsigned int *pbits_mask) { - int idx = 0; - unsigned int bits_mask; - bits_mask = ((1LL << bits_cnt) - 1); - - if (unlikely(bits_cnt > 56)) { - while(bits) { - if ((bits & bits_mask) == bits_mask) { - *pbits_mask = bits_mask << idx; - return idx; - } - bits >>= 1; - idx++; - } - } else { - idx = __fls(bits); - while(bits) { - unsigned int temp_bits; - temp_bits = bits_mask << (idx - bits_cnt + 1); - if ((bits & temp_bits) == temp_bits) { - *pbits_mask = temp_bits; - return (idx - bits_cnt + 1); - } - /* Find first zero. And clear the tested bit.*/ - bits &= ~(1LL< 56)) { + while (bits) { + if ((bits & bits_mask) == bits_mask) { + *pbits_mask = bits_mask << idx; + return idx; + } + bits >>= 1; + idx++; + } + } + else { + idx = __fls(bits); + while (bits) { + unsigned int temp_bits; + + temp_bits = bits_mask << (idx - bits_cnt + 1); + if ((bits & temp_bits) == temp_bits) { + *pbits_mask = temp_bits; + return (idx - bits_cnt + 1); + } + /* Find first zero. And clear the tested bit. */ + bits &= ~(1LL << idx); + idx = __fls(~bits); + bits &= ~((1LL << idx) - 1); + idx--; + } + } + return -1; } static struct glamor_glyph_mask_cache_entry * get_mask_cache(struct glamor_glyph_mask_cache *maskcache, int blocks) { - int free_cleared_bit, idx = -1; - int retry_cnt = 0; - unsigned int bits_mask = 0; - - if (maskcache->free_bitmap == 0) - return NULL; -retry: - free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap; - if (free_cleared_bit && blocks == 1) { - idx = __fls(free_cleared_bit); - bits_mask = 1 << idx; - } else if (free_cleared_bit && blocks > 1) { - idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask); - } - - if (idx < 0) { - clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap); - if (retry_cnt++ > 2) - return NULL; - goto retry; - } - - maskcache->cleared_bitmap &= ~bits_mask; - maskcache->free_bitmap &= ~bits_mask; - DEBUGF("get idx %d free %x clear %x \n", - idx, maskcache->free_bitmap, maskcache->cleared_bitmap); - return &maskcache->mcache[idx]; + int free_cleared_bit, idx = -1; + int retry_cnt = 0; + unsigned int bits_mask = 0; + + if (maskcache->free_bitmap == 0) + return NULL; + retry: + free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap; + if (free_cleared_bit && blocks == 1) { + idx = __fls(free_cleared_bit); + bits_mask = 1 << idx; + } + else if (free_cleared_bit && blocks > 1) { + idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask); + } + + if (idx < 0) { + clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap); + if (retry_cnt++ > 2) + return NULL; + goto retry; + } + + maskcache->cleared_bitmap &= ~bits_mask; + maskcache->free_bitmap &= ~bits_mask; + DEBUGF("get idx %d free %x clear %x \n", + idx, maskcache->free_bitmap, maskcache->cleared_bitmap); + return &maskcache->mcache[idx]; } static void put_mask_cache_bitmap(struct glamor_glyph_mask_cache *maskcache, - unsigned int bitmap) + unsigned int bitmap) { - maskcache->free_bitmap |= bitmap; - DEBUGF("put bitmap %x free %x clear %x \n", - bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap); + maskcache->free_bitmap |= bitmap; + DEBUGF("put bitmap %x free %x clear %x \n", + bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap); } static void glamor_unrealize_glyph_caches(ScreenPtr pScreen) { - glamor_screen_private *glamor = glamor_get_screen_private(pScreen); - int i; + glamor_screen_private *glamor = glamor_get_screen_private(pScreen); + int i; - if (!glamor->glyph_cache_initialized) - return; + if (!glamor->glyph_cache_initialized) + return; - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) { - glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; + for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) { + glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; - if (cache->picture) - FreePicture(cache->picture, 0); + if (cache->picture) + FreePicture(cache->picture, 0); - if (cache->glyphs) - free(cache->glyphs); + if (cache->glyphs) + free(cache->glyphs); - if (mask_cache[i]) - free(mask_cache[i]); - } - glamor->glyph_cache_initialized = FALSE; + if (mask_cache[i]) + free(mask_cache[i]); + } + glamor->glyph_cache_initialized = FALSE; } void glamor_glyphs_fini(ScreenPtr pScreen) { - glamor_unrealize_glyph_caches(pScreen); + glamor_unrealize_glyph_caches(pScreen); } /* All caches for a single format share a single pixmap for glyph storage, @@ -301,80 +306,80 @@ glamor_glyphs_fini(ScreenPtr pScreen) static Bool glamor_realize_glyph_caches(ScreenPtr pScreen) { - glamor_screen_private *glamor = glamor_get_screen_private(pScreen); - unsigned int formats[] = { - PIXMAN_a8, - PIXMAN_a8r8g8b8, - }; - int i; - - if (glamor->glyph_cache_initialized) - return TRUE; - - glamor->glyph_cache_initialized = TRUE; - memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches)); - - for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) { - glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; - PixmapPtr pixmap; - PicturePtr picture; - XID component_alpha; - int depth = PIXMAN_FORMAT_DEPTH(formats[i]); - int error; - PictFormatPtr pPictFormat = - PictureMatchFormat(pScreen, depth, formats[i]); - if (!pPictFormat) - goto bail; - - /* Now allocate the pixmap and picture */ - pixmap = pScreen->CreatePixmap(pScreen, - CACHE_PICTURE_SIZE, - CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE, depth, - 0); - if (!pixmap) - goto bail; - - component_alpha = NeedsComponent(pPictFormat->format); - picture = CreatePicture(0, &pixmap->drawable, pPictFormat, - CPComponentAlpha, &component_alpha, - serverClient, &error); - - pScreen->DestroyPixmap(pixmap); - if (!picture) - goto bail; - - ValidatePicture(picture); - - cache->picture = picture; - cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE); - if (!cache->glyphs) - goto bail; - - cache->evict = rand() % GLYPH_CACHE_SIZE; - mask_cache[i] = calloc(1, sizeof(*mask_cache[i])); - mask_cache[i]->pixmap = pixmap; - clear_mask_cache(mask_cache[i]); - } - assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS); - - return TRUE; - - bail: - glamor_unrealize_glyph_caches(pScreen); - return FALSE; + glamor_screen_private *glamor = glamor_get_screen_private(pScreen); + + unsigned int formats[] = { + PIXMAN_a8, + PIXMAN_a8r8g8b8, + }; + int i; + + if (glamor->glyph_cache_initialized) + return TRUE; + + glamor->glyph_cache_initialized = TRUE; + memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches)); + + for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) { + glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; + PixmapPtr pixmap; + PicturePtr picture; + XID component_alpha; + int depth = PIXMAN_FORMAT_DEPTH(formats[i]); + int error; + PictFormatPtr pPictFormat = + PictureMatchFormat(pScreen, depth, formats[i]); + if (!pPictFormat) + goto bail; + + /* Now allocate the pixmap and picture */ + pixmap = pScreen->CreatePixmap(pScreen, + CACHE_PICTURE_SIZE, + CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE, + depth, 0); + if (!pixmap) + goto bail; + + component_alpha = NeedsComponent(pPictFormat->format); + picture = CreatePicture(0, &pixmap->drawable, pPictFormat, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + pScreen->DestroyPixmap(pixmap); + if (!picture) + goto bail; + + ValidatePicture(picture); + + cache->picture = picture; + cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE); + if (!cache->glyphs) + goto bail; + + cache->evict = rand() % GLYPH_CACHE_SIZE; + mask_cache[i] = calloc(1, sizeof(*mask_cache[i])); + mask_cache[i]->pixmap = pixmap; + clear_mask_cache(mask_cache[i]); + } + assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS); + + return TRUE; + + bail: + glamor_unrealize_glyph_caches(pScreen); + return FALSE; } - Bool glamor_glyphs_init(ScreenPtr pScreen) { - if (!dixRegisterPrivateKey(&glamor_glyph_key, - PRIVATE_GLYPH, sizeof(struct glamor_glyph))) - return FALSE; + if (!dixRegisterPrivateKey(&glamor_glyph_key, + PRIVATE_GLYPH, sizeof(struct glamor_glyph))) + return FALSE; - /* Skip pixmap creation if we don't intend to use it. */ + /* Skip pixmap creation if we don't intend to use it. */ - return glamor_realize_glyph_caches(pScreen); + return glamor_realize_glyph_caches(pScreen); } /* The most efficient thing to way to upload the glyph to the screen @@ -382,209 +387,209 @@ glamor_glyphs_init(ScreenPtr pScreen) */ static void glamor_glyph_cache_upload_glyph(ScreenPtr screen, - glamor_glyph_cache_t * cache, - GlyphPtr glyph, int x, int y) + glamor_glyph_cache_t * cache, + GlyphPtr glyph, int x, int y) { - PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum]; - PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable; - PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable; - PixmapPtr scratch; - BoxRec box; - GCPtr gc; - - gc = GetScratchGC(pCachePixmap->drawable.depth, screen); - if (!gc) - return; - - ValidateGC(&pCachePixmap->drawable, gc); - - scratch = pGlyphPixmap; - if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) { - - scratch = glamor_create_pixmap(screen, - glyph->info.width, - glyph->info.height, - pCachePixmap-> - drawable.depth, 0); - if (scratch) { - PicturePtr picture; - int error; - - picture = - CreatePicture(0, - &scratch->drawable, - PictureMatchFormat - (screen, - pCachePixmap-> - drawable.depth, - cache->picture->format), - 0, NULL, serverClient, - &error); - if (picture) { - ValidatePicture(picture); - glamor_composite(PictOpSrc, - pGlyphPicture, - NULL, picture, - 0, 0, 0, 0, 0, - 0, - glyph->info.width, - glyph->info.height); - FreePicture(picture, 0); - } - } else { - scratch = pGlyphPixmap; - } - } - - box.x1 = x; - 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); - if (scratch != pGlyphPixmap) - screen->DestroyPixmap(scratch); - - FreeScratchGC(gc); + PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum]; + PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable; + PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable; + PixmapPtr scratch; + BoxRec box; + GCPtr gc; + + gc = GetScratchGC(pCachePixmap->drawable.depth, screen); + if (!gc) + return; + + ValidateGC(&pCachePixmap->drawable, gc); + + scratch = pGlyphPixmap; + if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) { + + scratch = glamor_create_pixmap(screen, + glyph->info.width, + glyph->info.height, + pCachePixmap->drawable.depth, 0); + if (scratch) { + PicturePtr picture; + int error; + + picture = + CreatePicture(0, + &scratch->drawable, + PictureMatchFormat + (screen, + pCachePixmap->drawable.depth, + cache->picture->format), + 0, NULL, serverClient, &error); + if (picture) { + ValidatePicture(picture); + glamor_composite(PictOpSrc, + pGlyphPicture, + NULL, picture, + 0, 0, 0, 0, 0, + 0, glyph->info.width, glyph->info.height); + FreePicture(picture, 0); + } + } + else { + scratch = pGlyphPixmap; + } + } + + box.x1 = x; + 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); + if (scratch != pGlyphPixmap) + screen->DestroyPixmap(scratch); + + FreeScratchGC(gc); } - void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph) { - struct glamor_glyph *priv; + struct glamor_glyph *priv; - /* Use Lookup in case we have not attached to this glyph. */ - priv = glamor_glyph_get_private(glyph); + /* Use Lookup in case we have not attached to this glyph. */ + priv = glamor_glyph_get_private(glyph); - if (priv->cached) - priv->cache->glyphs[priv->pos] = NULL; + if (priv->cached) + priv->cache->glyphs[priv->pos] = NULL; } /* Cut and paste from render/glyph.c - probably should export it instead */ static void glamor_glyph_extents(int nlist, - GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents) + GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents) { - int x1, x2, y1, y2; - int x, y, n; - - x1 = y1 = MAXSHORT; - x2 = y2 = MINSHORT; - x = y = 0; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) { - GlyphPtr glyph = *glyphs++; - int v; - - v = x - glyph->info.x; - if (v < x1) - x1 = v; - v += glyph->info.width; - if (v > x2) - x2 = v; - - v = y - glyph->info.y; - if (v < y1) - y1 = v; - v += glyph->info.height; - if (v > y2) - y2 = v; - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } - - extents->x1 = x1 < MINSHORT ? MINSHORT : x1; - extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2; - extents->y1 = y1 < MINSHORT ? MINSHORT : y1; - extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2; + int x1, x2, y1, y2; + int x, y, n; + + x1 = y1 = MAXSHORT; + x2 = y2 = MINSHORT; + x = y = 0; + while (nlist--) { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) { + GlyphPtr glyph = *glyphs++; + int v; + + v = x - glyph->info.x; + if (v < x1) + x1 = v; + v += glyph->info.width; + if (v > x2) + x2 = v; + + v = y - glyph->info.y; + if (v < y1) + y1 = v; + v += glyph->info.height; + if (v > y2) + y2 = v; + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + } + + extents->x1 = x1 < MINSHORT ? MINSHORT : x1; + extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2; + extents->y1 = y1 < MINSHORT ? MINSHORT : y1; + extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2; } static void glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv, - PicturePtr glyph_picture) + PicturePtr glyph_picture) { - PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable; - int j; - unsigned long long left_x1_map = 0, left_x2_map = 0; - unsigned long long right_x1_map = 0, right_x2_map = 0; - int bitsPerPixel; - int stride; - void *bits; - int width; - unsigned int left_x1_data = 0, left_x2_data = 0; - unsigned int right_x1_data = 0, right_x2_data = 0; - - bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel; - stride = glyph_pixmap->devKind; - bits = glyph_pixmap->devPrivate.ptr; - width = glyph->info.width; - - if (glyph_pixmap->drawable.width < 2 - || !(glyph_pixmap->drawable.depth == 8 - || glyph_pixmap->drawable.depth == 1 - || glyph_pixmap->drawable.depth == 32)) { - priv->has_edge_map = FALSE; - return; - } - - left_x1_map = left_x2_map = 0; - right_x1_map = right_x2_map = 0; - - for(j = 0; j < glyph_pixmap->drawable.height; j++) - { - if (bitsPerPixel == 8) { - unsigned char *data; - data = (unsigned char*)((unsigned char*)bits + stride * j); - left_x1_data = *data++; - left_x2_data = *data; - data = (unsigned char*)((unsigned char*)bits + stride * j + width - 2); - right_x1_data = *data++; - right_x2_data = *data; - } else if (bitsPerPixel == 32) { - left_x1_data = *((unsigned int*)bits + stride/4 * j); - left_x2_data = *((unsigned int*)bits + stride/4 * j + 1); - right_x1_data = *((unsigned int*)bits + stride/4 * j + width - 2); - right_x2_data = *((unsigned int*)bits + stride/4 * j + width - 1); - } else if (bitsPerPixel == 1) { - unsigned char temp; - temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr - + glyph_pixmap->devKind * j) & 0x3; - left_x1_data = temp & 0x1; - left_x2_data = temp & 0x2; - - temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr - + glyph_pixmap->devKind * j - + (glyph_pixmap->drawable.width - 2)/8); - right_x1_data = temp - & (1 << ((glyph_pixmap->drawable.width - 2) % 8)); - temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr - + glyph_pixmap->devKind * j - + (glyph_pixmap->drawable.width - 1)/8); - right_x2_data = temp - & (1 << ((glyph_pixmap->drawable.width - 1) % 8)); - } - left_x1_map |= (left_x1_data !=0) << j; - left_x2_map |= (left_x2_data !=0) << j; - right_x1_map |= (right_x1_data !=0) << j; - right_x2_map |= (right_x2_data !=0) << j; - } - - priv->left_x1_map = left_x1_map; - priv->left_x2_map = left_x2_map; - priv->right_x1_map = right_x1_map; - priv->right_x2_map = right_x2_map; - priv->has_edge_map = TRUE; - return; + PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable; + int j; + unsigned long long left_x1_map = 0, left_x2_map = 0; + unsigned long long right_x1_map = 0, right_x2_map = 0; + int bitsPerPixel; + int stride; + void *bits; + int width; + unsigned int left_x1_data = 0, left_x2_data = 0; + unsigned int right_x1_data = 0, right_x2_data = 0; + + bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel; + stride = glyph_pixmap->devKind; + bits = glyph_pixmap->devPrivate.ptr; + width = glyph->info.width; + + if (glyph_pixmap->drawable.width < 2 + || !(glyph_pixmap->drawable.depth == 8 + || glyph_pixmap->drawable.depth == 1 + || glyph_pixmap->drawable.depth == 32)) { + priv->has_edge_map = FALSE; + return; + } + + left_x1_map = left_x2_map = 0; + right_x1_map = right_x2_map = 0; + + for (j = 0; j < glyph_pixmap->drawable.height; j++) { + if (bitsPerPixel == 8) { + unsigned char *data; + + data = (unsigned char *) ((unsigned char *) bits + stride * j); + left_x1_data = *data++; + left_x2_data = *data; + data = + (unsigned char *) ((unsigned char *) bits + stride * j + width - + 2); + right_x1_data = *data++; + right_x2_data = *data; + } + else if (bitsPerPixel == 32) { + left_x1_data = *((unsigned int *) bits + stride / 4 * j); + left_x2_data = *((unsigned int *) bits + stride / 4 * j + 1); + right_x1_data = + *((unsigned int *) bits + stride / 4 * j + width - 2); + right_x2_data = + *((unsigned int *) bits + stride / 4 * j + width - 1); + } + else if (bitsPerPixel == 1) { + unsigned char temp; + + temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr + + glyph_pixmap->devKind * j) & 0x3; + left_x1_data = temp & 0x1; + left_x2_data = temp & 0x2; + + temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr + + glyph_pixmap->devKind * j + + (glyph_pixmap->drawable.width - 2) / 8); + right_x1_data = temp + & (1 << ((glyph_pixmap->drawable.width - 2) % 8)); + temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr + + glyph_pixmap->devKind * j + + (glyph_pixmap->drawable.width - 1) / 8); + right_x2_data = temp + & (1 << ((glyph_pixmap->drawable.width - 1) % 8)); + } + left_x1_map |= (left_x1_data != 0) << j; + left_x2_map |= (left_x2_data != 0) << j; + right_x1_map |= (right_x1_data != 0) << j; + right_x2_map |= (right_x2_data != 0) << j; + } + + priv->left_x1_map = left_x1_map; + priv->left_x2_map = left_x2_map; + priv->right_x1_map = right_x1_map; + priv->right_x2_map = right_x2_map; + priv->has_edge_map = TRUE; + return; } /** @@ -597,82 +602,80 @@ glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv, #define INTERSECTED 1 struct glamor_glyph_list { - int nlist; - GlyphListPtr list; - GlyphPtr *glyphs; - int type; + int nlist; + GlyphListPtr list; + GlyphPtr *glyphs; + int type; }; static Bool glyph_new_fixed_list(struct glamor_glyph_list *fixed_list, - GlyphPtr *cur_glyphs, - GlyphPtr **head_glyphs, - GlyphListPtr cur_list, - int cur_pos, int cur_x, int cur_y, - int x1, int y1, int x2, int y2, - GlyphListPtr *head_list, - int *head_pos, - int *head_x, - int *head_y, - int *fixed_cnt, - int type, - BoxPtr prev_extents - ) + GlyphPtr * cur_glyphs, + GlyphPtr ** head_glyphs, + GlyphListPtr cur_list, + int cur_pos, int cur_x, int cur_y, + int x1, int y1, int x2, int y2, + GlyphListPtr * head_list, + int *head_pos, + int *head_x, + int *head_y, int *fixed_cnt, int type, BoxPtr prev_extents) { - int x_off = 0; - int y_off = 0; - int n_off = 0; - int list_cnt; - if (type == NON_INTERSECTED) { - if (x1 < prev_extents->x2 && x2 > prev_extents->x1 - && y1 < prev_extents->y2 && y2 > prev_extents->y1) - return FALSE; - x_off = (*(cur_glyphs-1))->info.xOff; - y_off = (*(cur_glyphs-1))->info.yOff; - n_off = 1; - } - - list_cnt = cur_list - *head_list + 1; - if (cur_pos <= n_off) { - DEBUGF("break at %d n_off %d\n", cur_pos, n_off); - list_cnt--; - if (cur_pos < n_off) { - /* we overlap with previous list's last glyph. */ - x_off += cur_list->xOff; - y_off += cur_list->yOff; - cur_list--; - cur_pos = cur_list->len; - if (cur_pos <= n_off) { - list_cnt--; - } - } - } - DEBUGF("got %d lists\n", list_cnt); - if (list_cnt != 0) { - fixed_list->list = malloc(list_cnt * sizeof(*cur_list)); - memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list)); - fixed_list->list[0].xOff = *head_x; - fixed_list->list[0].yOff = *head_y; - fixed_list->glyphs = *head_glyphs; - fixed_list->type = type & INTERSECTED_TYPE_MASK; - fixed_list->nlist = list_cnt; - if (cur_list != *head_list) { - fixed_list->list[0].len = (*head_list)->len - *head_pos; - if (cur_pos != n_off) - fixed_list->list[list_cnt - 1].len = cur_pos - n_off; - } else - fixed_list->list[0].len = cur_pos - *head_pos - n_off; - (*fixed_cnt)++; - } - - if (type <= INTERSECTED) { - *head_list = cur_list; - *head_pos = cur_pos - n_off; - *head_x = cur_x - x_off; - *head_y = cur_y - y_off; - *head_glyphs = cur_glyphs - n_off; - } - return TRUE; + int x_off = 0; + int y_off = 0; + int n_off = 0; + int list_cnt; + + if (type == NON_INTERSECTED) { + if (x1 < prev_extents->x2 && x2 > prev_extents->x1 + && y1 < prev_extents->y2 && y2 > prev_extents->y1) + return FALSE; + x_off = (*(cur_glyphs - 1))->info.xOff; + y_off = (*(cur_glyphs - 1))->info.yOff; + n_off = 1; + } + + list_cnt = cur_list - *head_list + 1; + if (cur_pos <= n_off) { + DEBUGF("break at %d n_off %d\n", cur_pos, n_off); + list_cnt--; + if (cur_pos < n_off) { + /* we overlap with previous list's last glyph. */ + x_off += cur_list->xOff; + y_off += cur_list->yOff; + cur_list--; + cur_pos = cur_list->len; + if (cur_pos <= n_off) { + list_cnt--; + } + } + } + DEBUGF("got %d lists\n", list_cnt); + if (list_cnt != 0) { + fixed_list->list = malloc(list_cnt * sizeof(*cur_list)); + memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list)); + fixed_list->list[0].xOff = *head_x; + fixed_list->list[0].yOff = *head_y; + fixed_list->glyphs = *head_glyphs; + fixed_list->type = type & INTERSECTED_TYPE_MASK; + fixed_list->nlist = list_cnt; + if (cur_list != *head_list) { + fixed_list->list[0].len = (*head_list)->len - *head_pos; + if (cur_pos != n_off) + fixed_list->list[list_cnt - 1].len = cur_pos - n_off; + } + else + fixed_list->list[0].len = cur_pos - *head_pos - n_off; + (*fixed_cnt)++; + } + + if (type <= INTERSECTED) { + *head_list = cur_list; + *head_pos = cur_pos - n_off; + *head_x = cur_x - x_off; + *head_y = cur_y - y_off; + *head_glyphs = cur_glyphs - n_off; + } + return TRUE; } /* @@ -693,462 +696,468 @@ glyph_new_fixed_list(struct glamor_glyph_list *fixed_list, static int glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs, - PictFormatShort mask_format, - ScreenPtr screen, Bool check_fake_overlap, - struct glamor_glyph_list * fixed_list, - int fixed_size) + PictFormatShort mask_format, + ScreenPtr screen, Bool check_fake_overlap, + struct glamor_glyph_list *fixed_list, int fixed_size) { - int x1, x2, y1, y2; - int n; - int x, y; - BoxPtr extents; - BoxRec prev_extents; - Bool first = TRUE, first_list = TRUE; - Bool need_free_list_region = FALSE; - Bool need_free_fixed_list = FALSE; - struct glamor_glyph *priv = NULL; - Bool in_non_intersected_list = -1; - GlyphListPtr head_list; - int head_x, head_y, head_pos; - int fixed_cnt = 0; - GlyphPtr *head_glyphs; - GlyphListPtr cur_list = list; - RegionRec list_region; - RegionRec current_region; - BoxRec current_box; - - if (nlist > 1) { - pixman_region_init(&list_region); - need_free_list_region = TRUE; - } - - pixman_region_init(¤t_region); - - extents = pixman_region_extents(¤t_region); - - x = 0; - y = 0; - x1 = x2 = y1 = y2 = 0; - n = 0; - extents->x1 = 0; - extents->y1 = 0; - extents->x2 = 0; - extents->y2 = 0; - - head_list = list; - DEBUGF("has %d lists.\n", nlist); - while (nlist--) { - BoxRec left_box, right_box = {0}; - Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE; - Bool left_to_right; - struct glamor_glyph *left_priv = NULL, *right_priv = NULL; - - x += list->xOff; - y += list->yOff; - n = list->len; - left_to_right = TRUE; - cur_list = list++; - - if (unlikely(!first_list)) { - pixman_region_init_with_extents(¤t_region, extents); - pixman_region_union(&list_region, &list_region, ¤t_region); - first = TRUE; - } else { - head_list = cur_list; - head_pos = cur_list->len - n; - head_x = x; - head_y = y; - head_glyphs = glyphs; - } - - DEBUGF("current list %p has %d glyphs\n", cur_list, n); - while (n--) { - GlyphPtr glyph = *glyphs++; - - DEBUGF("the %dth glyph\n", cur_list->len - n - 1); - if (glyph->info.width == 0 - || glyph->info.height == 0) { - x += glyph->info.xOff; - y += glyph->info.yOff; - continue; - } - if (mask_format - && mask_format != GlyphPicture(glyph)[screen->myNum]->format) { - need_free_fixed_list = TRUE; - goto done; - } - - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - if (check_fake_overlap) - priv = glamor_glyph_get_private(glyph); - - x2 = x1 + glyph->info.width; - y2 = y1 + glyph->info.height; - - if (x2 > MAXSHORT) - x2 = MAXSHORT; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - - if (first) { - extents->x1 = x1; - extents->y1 = y1; - extents->x2 = x2; - extents->y2 = y2; - - prev_extents = *extents; - - first = FALSE; - if (check_fake_overlap && priv - && priv->has_edge_map && glyph->info.yOff == 0) { - left_box.x1 = x1; - left_box.x2 = x1 + 1; - left_box.y1 = y1; - - right_box.x1 = x2 - 2; - right_box.x2 = x2 - 1; - right_box.y1 = y1; - left_priv = right_priv = priv; - has_left_edge_box = TRUE; - has_right_edge_box = TRUE; - } - } else { - if (unlikely(!first_list)) { - current_box.x1 = x1; - current_box.y1 = y1; - current_box.x2 = x2; - current_box.y2 = y2; - if (pixman_region_contains_rectangle(&list_region, ¤t_box) != PIXMAN_REGION_OUT) { - need_free_fixed_list = TRUE; - goto done; - } - } - - if (x1 < extents->x2 && x2 > extents->x1 - && y1 < extents->y2 - && y2 > extents->y1) { - - if (check_fake_overlap && (has_left_edge_box || has_right_edge_box) - && priv->has_edge_map && glyph->info.yOff == 0) { - int left_dx, right_dx; - unsigned long long intersected; - - left_dx = has_left_edge_box ? 1 : 0; - right_dx = has_right_edge_box ? 1 : 0; - if (x1 + 1 < extents->x2 - right_dx && x2 - 1 > extents->x1 + left_dx) - goto real_intersected; - - if (left_to_right && has_right_edge_box) { - if (x1 == right_box.x1) { - intersected = ((priv->left_x1_map & right_priv->right_x1_map) - | (priv->left_x2_map & right_priv->right_x2_map)); - if (intersected) - goto real_intersected; - } else if (x1 == right_box.x2) { - intersected = (priv->left_x1_map & right_priv->right_x2_map); - if (intersected) { - #ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK - /* tolerate with two pixels overlap. */ - intersected &= ~(1<<__fls(intersected)); - if ((intersected & (intersected - 1))) - #endif - goto real_intersected; - } - } - } else if (!left_to_right && has_left_edge_box) { - if (x2 - 1 == left_box.x1) { - intersected = (priv->right_x2_map & left_priv->left_x1_map); - if (intersected) { - #ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK - /* tolerate with two pixels overlap. */ - intersected &= ~(1<<__fls(intersected)); - if ((intersected & (intersected - 1))) - #endif - goto real_intersected; - } - } else if (x2 - 1 == right_box.x2) { - if ((priv->right_x1_map & left_priv->left_x1_map) - || (priv->right_x2_map & left_priv->left_x2_map)) - goto real_intersected; - } - } else { - if (x1 < extents->x2 && x1 + 2 > extents->x1) - goto real_intersected; - } - goto non_intersected; - } else { -real_intersected: - DEBUGF("overlap with previous glyph.\n"); - if (in_non_intersected_list == 1) { - if (fixed_cnt >= fixed_size) { - need_free_fixed_list = TRUE; - goto done; - } - if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], - glyphs - 1, - &head_glyphs, - cur_list, - cur_list->len - (n + 1), x, y, - x1, y1, x2, y2, - &head_list, - &head_pos, - &head_x, - &head_y, &fixed_cnt, - NON_INTERSECTED, - &prev_extents - )){ - need_free_fixed_list = TRUE; - goto done; - } - } - - in_non_intersected_list = 0; - - } - } else { -non_intersected: - DEBUGF("doesn't overlap with previous glyph.\n"); - if (in_non_intersected_list == 0) { - if (fixed_cnt >= fixed_size) { - need_free_fixed_list = TRUE; - goto done; - } - if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], - glyphs - 1, - &head_glyphs, - cur_list, - cur_list->len - (n + 1), x, y, - x1, y1, x2, y2, - &head_list, - &head_pos, - &head_x, - &head_y, &fixed_cnt, - INTERSECTED, - &prev_extents - )) { - need_free_fixed_list = TRUE; - goto done; - } - } - in_non_intersected_list = 1; - } - prev_extents = *extents; - } - - if (check_fake_overlap && priv - && priv->has_edge_map && glyph->info.yOff == 0) { - if (!has_left_edge_box || x1 < extents->x1) { - left_box.x1 = x1; - left_box.x2 = x1 + 1; - left_box.y1 = y1; - has_left_edge_box = TRUE; - left_priv = priv; - } - - if (!has_right_edge_box || x2 > extents->x2) { - right_box.x1 = x2 - 2; - right_box.x2 = x2 - 1; - right_box.y1 = y1; - has_right_edge_box = TRUE; - right_priv = priv; - } - } - - if (x1 < extents->x1) - extents->x1 = x1; - if (x2 > extents->x2) - extents->x2 = x2; - - if (y1 < extents->y1) - extents->y1 = y1; - if (y2 > extents->y2) - extents->y2 = y2; - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - first_list = FALSE; - } - - if (in_non_intersected_list == 0 && fixed_cnt == 0) { - fixed_cnt = -1; - goto done; - } - - if ((in_non_intersected_list != -1 - || head_pos != n) && (fixed_cnt > 0)) { - if (fixed_cnt >= fixed_size) { - need_free_fixed_list = TRUE; - goto done; - } - if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], - glyphs - 1, - &head_glyphs, - cur_list, - cur_list->len - (n + 1), x, y, - x1, y1, x2, y2, - &head_list, - &head_pos, - &head_x, - &head_y, &fixed_cnt, - (!in_non_intersected_list) | 0x80, - &prev_extents - )) { - need_free_fixed_list = TRUE; - goto done; - } - } - -done: - if (need_free_list_region) - pixman_region_fini(&list_region); - pixman_region_fini(¤t_region); - - if (need_free_fixed_list && fixed_cnt >= 0) { - while(fixed_cnt--) { - free(fixed_list[fixed_cnt].list); - } - } - - DEBUGF("Got %d fixed list \n", fixed_cnt); - return fixed_cnt; + int x1, x2, y1, y2; + int n; + int x, y; + BoxPtr extents; + BoxRec prev_extents; + Bool first = TRUE, first_list = TRUE; + Bool need_free_list_region = FALSE; + Bool need_free_fixed_list = FALSE; + struct glamor_glyph *priv = NULL; + Bool in_non_intersected_list = -1; + GlyphListPtr head_list; + int head_x, head_y, head_pos; + int fixed_cnt = 0; + GlyphPtr *head_glyphs; + GlyphListPtr cur_list = list; + RegionRec list_region; + RegionRec current_region; + BoxRec current_box; + + if (nlist > 1) { + pixman_region_init(&list_region); + need_free_list_region = TRUE; + } + + pixman_region_init(¤t_region); + + extents = pixman_region_extents(¤t_region); + + x = 0; + y = 0; + x1 = x2 = y1 = y2 = 0; + n = 0; + extents->x1 = 0; + extents->y1 = 0; + extents->x2 = 0; + extents->y2 = 0; + + head_list = list; + DEBUGF("has %d lists.\n", nlist); + while (nlist--) { + BoxRec left_box, right_box = { 0 }; + Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE; + Bool left_to_right; + struct glamor_glyph *left_priv = NULL, *right_priv = NULL; + + x += list->xOff; + y += list->yOff; + n = list->len; + left_to_right = TRUE; + cur_list = list++; + + if (unlikely(!first_list)) { + pixman_region_init_with_extents(¤t_region, extents); + pixman_region_union(&list_region, &list_region, ¤t_region); + first = TRUE; + } + else { + head_list = cur_list; + head_pos = cur_list->len - n; + head_x = x; + head_y = y; + head_glyphs = glyphs; + } + + DEBUGF("current list %p has %d glyphs\n", cur_list, n); + while (n--) { + GlyphPtr glyph = *glyphs++; + + DEBUGF("the %dth glyph\n", cur_list->len - n - 1); + if (glyph->info.width == 0 || glyph->info.height == 0) { + x += glyph->info.xOff; + y += glyph->info.yOff; + continue; + } + if (mask_format + && mask_format != GlyphPicture(glyph)[screen->myNum]->format) { + need_free_fixed_list = TRUE; + goto done; + } + + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + if (check_fake_overlap) + priv = glamor_glyph_get_private(glyph); + + x2 = x1 + glyph->info.width; + y2 = y1 + glyph->info.height; + + if (x2 > MAXSHORT) + x2 = MAXSHORT; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + + if (first) { + extents->x1 = x1; + extents->y1 = y1; + extents->x2 = x2; + extents->y2 = y2; + + prev_extents = *extents; + + first = FALSE; + if (check_fake_overlap && priv + && priv->has_edge_map && glyph->info.yOff == 0) { + left_box.x1 = x1; + left_box.x2 = x1 + 1; + left_box.y1 = y1; + + right_box.x1 = x2 - 2; + right_box.x2 = x2 - 1; + right_box.y1 = y1; + left_priv = right_priv = priv; + has_left_edge_box = TRUE; + has_right_edge_box = TRUE; + } + } + else { + if (unlikely(!first_list)) { + current_box.x1 = x1; + current_box.y1 = y1; + current_box.x2 = x2; + current_box.y2 = y2; + if (pixman_region_contains_rectangle + (&list_region, ¤t_box) != PIXMAN_REGION_OUT) { + need_free_fixed_list = TRUE; + goto done; + } + } + + if (x1 < extents->x2 && x2 > extents->x1 + && y1 < extents->y2 && y2 > extents->y1) { + + if (check_fake_overlap && + (has_left_edge_box || has_right_edge_box) + && priv->has_edge_map && glyph->info.yOff == 0) { + int left_dx, right_dx; + unsigned long long intersected; + + left_dx = has_left_edge_box ? 1 : 0; + right_dx = has_right_edge_box ? 1 : 0; + if (x1 + 1 < extents->x2 - right_dx && + x2 - 1 > extents->x1 + left_dx) + goto real_intersected; + + if (left_to_right && has_right_edge_box) { + if (x1 == right_box.x1) { + intersected = + ((priv->left_x1_map & right_priv-> + right_x1_map) + | (priv->left_x2_map & right_priv-> + right_x2_map)); + if (intersected) + goto real_intersected; + } + else if (x1 == right_box.x2) { + intersected = + (priv->left_x1_map & right_priv-> + right_x2_map); + if (intersected) { +#ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK + /* tolerate with two pixels overlap. */ + intersected &= ~(1 << __fls(intersected)); + if ((intersected & (intersected - 1))) +#endif + goto real_intersected; + } + } + } + else if (!left_to_right && has_left_edge_box) { + if (x2 - 1 == left_box.x1) { + intersected = + (priv->right_x2_map & left_priv-> + left_x1_map); + if (intersected) { +#ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK + /* tolerate with two pixels overlap. */ + intersected &= ~(1 << __fls(intersected)); + if ((intersected & (intersected - 1))) +#endif + goto real_intersected; + } + } + else if (x2 - 1 == right_box.x2) { + if ((priv->right_x1_map & left_priv-> + left_x1_map) + || (priv->right_x2_map & left_priv-> + left_x2_map)) + goto real_intersected; + } + } + else { + if (x1 < extents->x2 && x1 + 2 > extents->x1) + goto real_intersected; + } + goto non_intersected; + } + else { + real_intersected: + DEBUGF("overlap with previous glyph.\n"); + if (in_non_intersected_list == 1) { + if (fixed_cnt >= fixed_size) { + need_free_fixed_list = TRUE; + goto done; + } + if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], + glyphs - 1, + &head_glyphs, + cur_list, + cur_list->len - (n + 1), + x, y, x1, y1, x2, y2, + &head_list, &head_pos, + &head_x, &head_y, + &fixed_cnt, + NON_INTERSECTED, + &prev_extents)) { + need_free_fixed_list = TRUE; + goto done; + } + } + + in_non_intersected_list = 0; + + } + } + else { + non_intersected: + DEBUGF("doesn't overlap with previous glyph.\n"); + if (in_non_intersected_list == 0) { + if (fixed_cnt >= fixed_size) { + need_free_fixed_list = TRUE; + goto done; + } + if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], + glyphs - 1, + &head_glyphs, + cur_list, + cur_list->len - (n + 1), x, y, + x1, y1, x2, y2, + &head_list, + &head_pos, + &head_x, + &head_y, &fixed_cnt, + INTERSECTED, &prev_extents)) { + need_free_fixed_list = TRUE; + goto done; + } + } + in_non_intersected_list = 1; + } + prev_extents = *extents; + } + + if (check_fake_overlap && priv + && priv->has_edge_map && glyph->info.yOff == 0) { + if (!has_left_edge_box || x1 < extents->x1) { + left_box.x1 = x1; + left_box.x2 = x1 + 1; + left_box.y1 = y1; + has_left_edge_box = TRUE; + left_priv = priv; + } + + if (!has_right_edge_box || x2 > extents->x2) { + right_box.x1 = x2 - 2; + right_box.x2 = x2 - 1; + right_box.y1 = y1; + has_right_edge_box = TRUE; + right_priv = priv; + } + } + + if (x1 < extents->x1) + extents->x1 = x1; + if (x2 > extents->x2) + extents->x2 = x2; + + if (y1 < extents->y1) + extents->y1 = y1; + if (y2 > extents->y2) + extents->y2 = y2; + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + first_list = FALSE; + } + + if (in_non_intersected_list == 0 && fixed_cnt == 0) { + fixed_cnt = -1; + goto done; + } + + if ((in_non_intersected_list != -1 || head_pos != n) && (fixed_cnt > 0)) { + if (fixed_cnt >= fixed_size) { + need_free_fixed_list = TRUE; + goto done; + } + if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], + glyphs - 1, + &head_glyphs, + cur_list, + cur_list->len - (n + 1), x, y, + x1, y1, x2, y2, + &head_list, + &head_pos, + &head_x, + &head_y, &fixed_cnt, + (!in_non_intersected_list) | 0x80, + &prev_extents)) { + need_free_fixed_list = TRUE; + goto done; + } + } + + done: + if (need_free_list_region) + pixman_region_fini(&list_region); + pixman_region_fini(¤t_region); + + if (need_free_fixed_list && fixed_cnt >= 0) { + while (fixed_cnt--) { + free(fixed_list[fixed_cnt].list); + } + } + + DEBUGF("Got %d fixed list \n", fixed_cnt); + return fixed_cnt; } static inline unsigned int glamor_glyph_size_to_count(int size) { - size /= GLYPH_MIN_SIZE; - return size * size; + size /= GLYPH_MIN_SIZE; + return size * size; } static inline unsigned int glamor_glyph_count_to_mask(int count) { - return ~(count - 1); + return ~(count - 1); } static inline unsigned int glamor_glyph_size_to_mask(int size) { - return - glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size)); + return glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size)); } static PicturePtr -glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x, - int *out_y) +glamor_glyph_cache(glamor_screen_private * glamor, GlyphPtr glyph, int *out_x, + int *out_y) { - ScreenPtr screen = glamor->screen; - PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum]; - glamor_glyph_cache_t *cache = - &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) != - 0]; - struct glamor_glyph *priv = NULL, *evicted_priv = NULL; - int size, mask, pos, s; - - if (glyph->info.width > GLYPH_MAX_SIZE - || glyph->info.height > GLYPH_MAX_SIZE) - return NULL; - - for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2) - if (glyph->info.width <= size - && glyph->info.height <= size) - break; - - s = glamor_glyph_size_to_count(size); - mask = glamor_glyph_count_to_mask(s); - pos = (cache->count + s - 1) & mask; - - priv = glamor_glyph_get_private(glyph); - if (pos < GLYPH_CACHE_SIZE) { - cache->count = pos + s; - } else { - for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) { - int i = - cache->evict & glamor_glyph_size_to_mask(s); - GlyphPtr evicted = cache->glyphs[i]; - if (evicted == NULL) - continue; - - evicted_priv = glamor_glyph_get_private(evicted); - assert(evicted_priv->pos == i); - if (evicted_priv->size >= s) { - cache->glyphs[i] = NULL; - evicted_priv->cached = FALSE; - pos = cache->evict & - glamor_glyph_size_to_mask(size); - } else - evicted_priv = NULL; - break; - } - if (evicted_priv == NULL) { - int count = glamor_glyph_size_to_count(size); - mask = glamor_glyph_count_to_mask(count); - pos = cache->evict & mask; - for (s = 0; s < count; s++) { - GlyphPtr evicted = cache->glyphs[pos + s]; - if (evicted != NULL) { - - evicted_priv = - glamor_glyph_get_private - (evicted); - - assert(evicted_priv->pos == pos + s); - evicted_priv->cached = FALSE; - cache->glyphs[pos + s] = NULL; - } - } - - } - /* And pick a new eviction position */ - cache->evict = rand() % GLYPH_CACHE_SIZE; - } - - - cache->glyphs[pos] = glyph; - - priv->cache = cache; - priv->size = size; - priv->pos = pos; - s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) * - (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE)); - priv->x = - s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE; - priv->y = - (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE; - for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) { - if (pos & 1) - priv->x += s; - if (pos & 2) - priv->y += s; - pos >>= 2; - } - - glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x, - priv->y); + ScreenPtr screen = glamor->screen; + PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum]; + glamor_glyph_cache_t *cache = + &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) != 0]; + struct glamor_glyph *priv = NULL, *evicted_priv = NULL; + int size, mask, pos, s; + + if (glyph->info.width > GLYPH_MAX_SIZE + || glyph->info.height > GLYPH_MAX_SIZE) + return NULL; + + for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2) + if (glyph->info.width <= size && glyph->info.height <= size) + break; + + s = glamor_glyph_size_to_count(size); + mask = glamor_glyph_count_to_mask(s); + pos = (cache->count + s - 1) & mask; + + priv = glamor_glyph_get_private(glyph); + if (pos < GLYPH_CACHE_SIZE) { + cache->count = pos + s; + } + else { + for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) { + int i = cache->evict & glamor_glyph_size_to_mask(s); + GlyphPtr evicted = cache->glyphs[i]; + + if (evicted == NULL) + continue; + + evicted_priv = glamor_glyph_get_private(evicted); + assert(evicted_priv->pos == i); + if (evicted_priv->size >= s) { + cache->glyphs[i] = NULL; + evicted_priv->cached = FALSE; + pos = cache->evict & glamor_glyph_size_to_mask(size); + } + else + evicted_priv = NULL; + break; + } + if (evicted_priv == NULL) { + int count = glamor_glyph_size_to_count(size); + + mask = glamor_glyph_count_to_mask(count); + pos = cache->evict & mask; + for (s = 0; s < count; s++) { + GlyphPtr evicted = cache->glyphs[pos + s]; + + if (evicted != NULL) { + + evicted_priv = glamor_glyph_get_private(evicted); + + assert(evicted_priv->pos == pos + s); + evicted_priv->cached = FALSE; + cache->glyphs[pos + s] = NULL; + } + } + + } + /* And pick a new eviction position */ + cache->evict = rand() % GLYPH_CACHE_SIZE; + } + + cache->glyphs[pos] = glyph; + + priv->cache = cache; + priv->size = size; + priv->pos = pos; + s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) * + (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE)); + priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE; + priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE; + for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) { + if (pos & 1) + priv->x += s; + if (pos & 2) + priv->y += s; + pos >>= 2; + } + + glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x, priv->y); #ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK - if (priv->has_edge_map == FALSE && glyph->info.width >= 2) - glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture); + if (priv->has_edge_map == FALSE && glyph->info.width >= 2) + glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture); #endif - priv->cached = TRUE; + priv->cached = TRUE; - *out_x = priv->x; - *out_y = priv->y; - return cache->picture; + *out_x = priv->x; + *out_y = priv->y; + return cache->picture; } -typedef void (*glyphs_flush_func)(void * arg); + +typedef void (*glyphs_flush_func) (void *arg); struct glyphs_flush_dst_arg { - CARD8 op; - PicturePtr src; - PicturePtr dst; - glamor_glyph_buffer_t * buffer; - int x_src,y_src; - int x_dst, y_dst; + CARD8 op; + PicturePtr src; + PicturePtr dst; + glamor_glyph_buffer_t *buffer; + int x_src, y_src; + int x_dst, y_dst; }; static struct glyphs_flush_dst_arg dst_arg; @@ -1157,650 +1166,638 @@ static glamor_glyph_buffer_t dst_buffer; static glamor_glyph_buffer_t mask_buffer; unsigned long long mask_glyphs_cnt = 0; unsigned long long dst_glyphs_cnt = 0; + #define GLYPHS_DST_MODE_VIA_MASK 0 #define GLYPHS_DST_MODE_VIA_MASK_CACHE 1 #define GLYPHS_DST_MODE_TO_DST 2 #define GLYPHS_DST_MODE_MASK_TO_DST 3 struct glyphs_flush_mask_arg { - PicturePtr mask; - glamor_glyph_buffer_t *buffer; - struct glamor_glyph_mask_cache *maskcache; - unsigned int used_bitmap; + PicturePtr mask; + glamor_glyph_buffer_t *buffer; + struct glamor_glyph_mask_cache *maskcache; + unsigned int used_bitmap; }; static void glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg) { - if (arg->buffer->count>0) { + if (arg->buffer->count > 0) { #ifdef RENDER - glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source, - NULL, arg->mask, - arg->buffer->count, - arg->buffer->rects); + glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source, + NULL, arg->mask, + arg->buffer->count, arg->buffer->rects); #endif - } - arg->buffer->count = 0; - arg->buffer->source = NULL; + } + arg->buffer->count = 0; + arg->buffer->source = NULL; } static void -glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg * arg) +glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg *arg) { - if (!arg->buffer) - return; - - if (mask_buffer.count > 0) { - glamor_glyphs_flush_mask(&mask_arg); - } - if (mask_arg.used_bitmap) { - put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap); - mask_arg.used_bitmap = 0; - } - - if (arg->buffer->count > 0) { - glamor_composite_glyph_rects(arg->op, arg->src, - arg->buffer->source, arg->dst, - arg->buffer->count, - &arg->buffer->rects[0]); - arg->buffer->count = 0; - arg->buffer->source = NULL; - } + if (!arg->buffer) + return; + + if (mask_buffer.count > 0) { + glamor_glyphs_flush_mask(&mask_arg); + } + if (mask_arg.used_bitmap) { + put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap); + mask_arg.used_bitmap = 0; + } + + if (arg->buffer->count > 0) { + glamor_composite_glyph_rects(arg->op, arg->src, + arg->buffer->source, arg->dst, + arg->buffer->count, + &arg->buffer->rects[0]); + arg->buffer->count = 0; + arg->buffer->source = NULL; + } } - static glamor_glyph_cache_result_t -glamor_buffer_glyph(glamor_screen_private *glamor_priv, - glamor_glyph_buffer_t * buffer, - PictFormatShort format, - GlyphPtr glyph, struct glamor_glyph *priv, - int x_glyph, int y_glyph, - int dx, int dy, int w, int h, - int glyphs_dst_mode, - glyphs_flush_func glyphs_flush, void *flush_arg) +glamor_buffer_glyph(glamor_screen_private * glamor_priv, + glamor_glyph_buffer_t * buffer, + PictFormatShort format, + GlyphPtr glyph, struct glamor_glyph *priv, + int x_glyph, int y_glyph, + int dx, int dy, int w, int h, + int glyphs_dst_mode, + glyphs_flush_func glyphs_flush, void *flush_arg) { - ScreenPtr screen = glamor_priv->screen; - glamor_composite_rect_t *rect; - PicturePtr source; - int x, y; - glamor_glyph_cache_t *cache; - - if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) - priv = glamor_glyph_get_private(glyph); - - if (PICT_FORMAT_BPP(format) == 1) - format = PICT_a8; - - cache = - &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0]; - - if (buffer->source - && buffer->source != cache->picture - && glyphs_flush) { - (*glyphs_flush)(flush_arg); - glyphs_flush = NULL; - } - - if (buffer->count == GLYPH_BUFFER_SIZE - && glyphs_flush) { - (*glyphs_flush)(flush_arg); - glyphs_flush = NULL; - } - - if (priv && priv->cached) { - rect = &buffer->rects[buffer->count++]; - rect->x_src = priv->x + dx; - rect->y_src = priv->y + dy; - if (buffer->source == NULL) - buffer->source = priv->cache->picture; - if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE) - assert(priv->cache->glyphs[priv->pos] == glyph); - } else { - assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST); - if (glyphs_flush) - (*glyphs_flush)(flush_arg); - source = glamor_glyph_cache(glamor_priv, glyph, &x, &y); - - if (source != NULL) { - rect = &buffer->rects[buffer->count++]; - rect->x_src = x + dx; - rect->y_src = y + dy; - if (buffer->source == NULL) - buffer->source = source; - if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) { - glamor_gl_dispatch *dispatch; - /* mode 1 means we are using global mask cache, - * thus we have to composite from the cache picture - * to the cache picture, we need a flush here to make - * sure latter we get the corret glyphs data.*/ - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glFlush(); - glamor_put_dispatch(glamor_priv); - } - } else { - /* Couldn't find the glyph in the cache, use the glyph picture directly */ - source = GlyphPicture(glyph)[screen->myNum]; - if (buffer->source - && buffer->source != source - && glyphs_flush) - (*glyphs_flush)(flush_arg); - buffer->source = source; - - rect = &buffer->rects[buffer->count++]; - rect->x_src = 0 + dx; - rect->y_src = 0 + dy; - } - priv = glamor_glyph_get_private(glyph); - } - - rect->x_dst = x_glyph; - rect->y_dst = y_glyph; - if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) { - rect->x_dst -= glyph->info.x; - rect->y_dst -= glyph->info.y; - } - rect->width = w; - rect->height = h; - if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) { - rect->x_mask = rect->x_src; - rect->y_mask = rect->y_src; - rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst; - rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst; - } - - return GLAMOR_GLYPH_SUCCESS; + ScreenPtr screen = glamor_priv->screen; + glamor_composite_rect_t *rect; + PicturePtr source; + int x, y; + glamor_glyph_cache_t *cache; + + if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) + priv = glamor_glyph_get_private(glyph); + + if (PICT_FORMAT_BPP(format) == 1) + format = PICT_a8; + + cache = &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0]; + + if (buffer->source && buffer->source != cache->picture && glyphs_flush) { + (*glyphs_flush) (flush_arg); + glyphs_flush = NULL; + } + + if (buffer->count == GLYPH_BUFFER_SIZE && glyphs_flush) { + (*glyphs_flush) (flush_arg); + glyphs_flush = NULL; + } + + if (priv && priv->cached) { + rect = &buffer->rects[buffer->count++]; + rect->x_src = priv->x + dx; + rect->y_src = priv->y + dy; + if (buffer->source == NULL) + buffer->source = priv->cache->picture; + if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE) + assert(priv->cache->glyphs[priv->pos] == glyph); + } + else { + assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST); + if (glyphs_flush) + (*glyphs_flush) (flush_arg); + source = glamor_glyph_cache(glamor_priv, glyph, &x, &y); + + if (source != NULL) { + rect = &buffer->rects[buffer->count++]; + rect->x_src = x + dx; + rect->y_src = y + dy; + if (buffer->source == NULL) + buffer->source = source; + if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) { + glamor_gl_dispatch *dispatch; + + /* mode 1 means we are using global mask cache, + * thus we have to composite from the cache picture + * to the cache picture, we need a flush here to make + * sure latter we get the corret glyphs data.*/ + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glFlush(); + glamor_put_dispatch(glamor_priv); + } + } + else { + /* Couldn't find the glyph in the cache, use the glyph picture directly */ + source = GlyphPicture(glyph)[screen->myNum]; + if (buffer->source && buffer->source != source && glyphs_flush) + (*glyphs_flush) (flush_arg); + buffer->source = source; + + rect = &buffer->rects[buffer->count++]; + rect->x_src = 0 + dx; + rect->y_src = 0 + dy; + } + priv = glamor_glyph_get_private(glyph); + } + + rect->x_dst = x_glyph; + rect->y_dst = y_glyph; + if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) { + rect->x_dst -= glyph->info.x; + rect->y_dst -= glyph->info.y; + } + rect->width = w; + rect->height = h; + if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) { + rect->x_mask = rect->x_src; + rect->y_mask = rect->y_src; + rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst; + rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst; + } + + return GLAMOR_GLYPH_SUCCESS; } - static void -glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv, - BoxPtr rects, - int nrect, PictFormatShort format, - GlyphPtr glyph, struct glamor_glyph *priv, - int glyph_x, int glyph_y, - int glyph_dx, int glyph_dy, - int width, int height, - int glyphs_mode, - glyphs_flush_func flush_func, - void *arg - ) +glamor_buffer_glyph_clip(glamor_screen_private * glamor_priv, + BoxPtr rects, + int nrect, PictFormatShort format, + GlyphPtr glyph, struct glamor_glyph *priv, + int glyph_x, int glyph_y, + int glyph_dx, int glyph_dy, + int width, int height, + int glyphs_mode, + glyphs_flush_func flush_func, void *arg) { - int i; - for (i = 0; i < nrect; i++) { - int dst_x, dst_y; - int dx, dy; - int x2, y2; - - dst_x = glyph_x - glyph_dx; - dst_y = glyph_y - glyph_dy; - x2 = dst_x + width; - y2 = dst_y + height; - dx = dy = 0; - if (rects[i].y1 >= y2) - break; - - if (dst_x < rects[i].x1) - dx = rects[i].x1 - dst_x, dst_x = rects[i].x1; - if (x2 > rects[i].x2) - x2 = rects[i].x2; - if (dst_y < rects[i].y1) - dy = rects[i].y1 - dst_y, dst_y = rects[i].y1; - if (y2 > rects[i].y2) - y2 = rects[i].y2; - if (dst_x < x2 && dst_y < y2) { - - glamor_buffer_glyph(glamor_priv, - &dst_buffer, - format, - glyph, priv, - dst_x + glyph_dx, - dst_y + glyph_dy, - dx, dy, - x2 - dst_x, y2 - dst_y, - glyphs_mode, - flush_func, - arg); - } - } + int i; + + for (i = 0; i < nrect; i++) { + int dst_x, dst_y; + int dx, dy; + int x2, y2; + + dst_x = glyph_x - glyph_dx; + dst_y = glyph_y - glyph_dy; + x2 = dst_x + width; + y2 = dst_y + height; + dx = dy = 0; + if (rects[i].y1 >= y2) + break; + + if (dst_x < rects[i].x1) + dx = rects[i].x1 - dst_x, dst_x = rects[i].x1; + if (x2 > rects[i].x2) + x2 = rects[i].x2; + if (dst_y < rects[i].y1) + dy = rects[i].y1 - dst_y, dst_y = rects[i].y1; + if (y2 > rects[i].y2) + y2 = rects[i].y2; + if (dst_x < x2 && dst_y < y2) { + + glamor_buffer_glyph(glamor_priv, + &dst_buffer, + format, + glyph, priv, + dst_x + glyph_dx, + dst_y + glyph_dy, + dx, dy, + x2 - dst_x, y2 - dst_y, + glyphs_mode, flush_func, arg); + } + } } - static void glamor_glyphs_via_mask(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, - int nlist, GlyphListPtr list, GlyphPtr * glyphs, - Bool use_mask_cache) + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, + int nlist, GlyphListPtr list, GlyphPtr * glyphs, + Bool use_mask_cache) { - PixmapPtr mask_pixmap = 0; - PicturePtr mask; - ScreenPtr screen = dst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y; - int x_dst = list->xOff, y_dst = list->yOff; - int n; - GlyphPtr glyph; - int error; - BoxRec extents = { 0, 0, 0, 0 }; - XID component_alpha; - glamor_screen_private *glamor_priv; - int need_free_mask = FALSE; - glamor_glyph_buffer_t buffer; - struct glyphs_flush_mask_arg arg; - glamor_glyph_buffer_t *pmask_buffer; - struct glyphs_flush_mask_arg *pmask_arg; - struct glamor_glyph_mask_cache_entry *mce = NULL; - struct glamor_glyph_mask_cache *maskcache; - glamor_glyph_cache_t *cache; - int glyphs_dst_mode; - - glamor_glyph_extents(nlist, list, glyphs, &extents); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - glamor_priv = glamor_get_screen_private(screen); - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - - if (mask_format->depth == 1) { - PictFormatPtr a8Format = - PictureMatchFormat(screen, 8, PICT_a8); - - if (a8Format) - mask_format = a8Format; - } - - cache = &glamor_priv->glyphCaches - [PICT_FORMAT_RGB(mask_format->format) != 0]; - maskcache = mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0]; - - x = -extents.x1; - y = -extents.y1; - if (!use_mask_cache - || width > (CACHE_PICTURE_SIZE/4) - || height > MASK_CACHE_MAX_SIZE) { -new_mask_pixmap: - mask_pixmap = glamor_create_pixmap(screen, width, height, - mask_format->depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!mask_pixmap) { - glamor_destroy_pixmap(mask_pixmap); - return; - } - glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0); - component_alpha = NeedsComponent(mask_format->format); - mask = CreatePicture(0, &mask_pixmap->drawable, - mask_format, CPComponentAlpha, - &component_alpha, serverClient, &error); - if (!mask) - return; - need_free_mask = TRUE; - pmask_arg = &arg; - pmask_buffer = &buffer; - pmask_buffer->count = 0; - pmask_buffer->source = NULL; - pmask_arg->used_bitmap = 0; - glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK; - } else { - int retry_cnt = 0; -retry: - mce = get_mask_cache(maskcache, - (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE); - - if (mce == NULL) { - glamor_glyphs_flush_dst(&dst_arg); - retry_cnt++; - if (retry_cnt > 2) { - assert(0); - goto new_mask_pixmap; - } - goto retry; - } - - mask = cache->picture; - x += mce->x; - y += mce->y; - mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE; - mce->height = 1; - if (mask_arg.mask && mask_arg.mask != mask - && mask_buffer.count != 0) - glamor_glyphs_flush_dst(&dst_arg); - pmask_arg = &mask_arg; - pmask_buffer = &mask_buffer; - pmask_arg->maskcache = maskcache; - glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE; - } - pmask_arg->mask = mask; - pmask_arg->buffer = pmask_buffer; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - mask_glyphs_cnt += n; - while (n--) { - glyph = *glyphs++; - if (glyph->info.width > 0 - && glyph->info.height > 0) { - glyphs_flush_func flush_func; - void *temp_arg; - if (need_free_mask) { - if (pmask_buffer->count) - flush_func = (glyphs_flush_func)glamor_glyphs_flush_mask; - else - flush_func = NULL; - temp_arg = pmask_arg; - } else { - /* If we are using global mask cache, then we need to - * flush dst instead of mask. As some dst depends on the - * previous mask result. Just flush mask can't get all previous's - * overlapped glyphs.*/ - if (dst_buffer.count || mask_buffer.count) - flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst; - else - flush_func = NULL; - temp_arg = &dst_arg; - } - glamor_buffer_glyph(glamor_priv, pmask_buffer, - mask_format->format, - glyph, NULL, x, y, - 0, 0, - glyph->info.width, glyph->info.height, - glyphs_dst_mode, - flush_func, - (void*)temp_arg); - } - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - } - - x = extents.x1; - y = extents.y1; - if (need_free_mask) { - glamor_glyphs_flush_mask(pmask_arg); - CompositePicture(op, - src, - mask, - dst, - x_src + x - x_dst, - y_src + y - y_dst, 0, 0, x, y, width, height); - FreePicture(mask, 0); - glamor_destroy_pixmap(mask_pixmap); - } else { - struct glamor_glyph priv; - glyphs_flush_func flush_func; - BoxPtr rects; - int nrect; - - priv.cache = cache; - priv.x = mce->x; - priv.y = mce->y; - priv.cached = TRUE; - rects = REGION_RECTS(dst->pCompositeClip); - nrect = REGION_NUM_RECTS(dst->pCompositeClip); - - pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx; - dst_arg.op = op; - dst_arg.src = src; - dst_arg.dst = dst; - dst_arg.buffer = &dst_buffer; - dst_arg.x_src = x_src; - dst_arg.y_src = y_src; - dst_arg.x_dst = x_dst; - dst_arg.y_dst = y_dst; - - if (dst_buffer.source == NULL) { - dst_buffer.source = cache->picture; - } else if (dst_buffer.source != cache->picture) { - glamor_glyphs_flush_dst(&dst_arg); - dst_buffer.source = cache->picture; - } - - x += dst->pDrawable->x; - y += dst->pDrawable->y; - - if (dst_buffer.count || mask_buffer.count) - flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst; - else - flush_func = NULL; - - glamor_buffer_glyph_clip(glamor_priv, - rects, nrect, - mask_format->format, - NULL, &priv, - x, y, - 0, 0, - width, height, - GLYPHS_DST_MODE_MASK_TO_DST, - flush_func, - (void *)&dst_arg - ); - } + PixmapPtr mask_pixmap = 0; + PicturePtr mask; + ScreenPtr screen = dst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int x_dst = list->xOff, y_dst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = { 0, 0, 0, 0 }; + XID component_alpha; + glamor_screen_private *glamor_priv; + int need_free_mask = FALSE; + glamor_glyph_buffer_t buffer; + struct glyphs_flush_mask_arg arg; + glamor_glyph_buffer_t *pmask_buffer; + struct glyphs_flush_mask_arg *pmask_arg; + struct glamor_glyph_mask_cache_entry *mce = NULL; + struct glamor_glyph_mask_cache *maskcache; + glamor_glyph_cache_t *cache; + int glyphs_dst_mode; + + glamor_glyph_extents(nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + glamor_priv = glamor_get_screen_private(screen); + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + + if (mask_format->depth == 1) { + PictFormatPtr a8Format = PictureMatchFormat(screen, 8, PICT_a8); + + if (a8Format) + mask_format = a8Format; + } + + cache = &glamor_priv->glyphCaches + [PICT_FORMAT_RGB(mask_format->format) != 0]; + maskcache = mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0]; + + x = -extents.x1; + y = -extents.y1; + if (!use_mask_cache || width > (CACHE_PICTURE_SIZE / 4) + || height > MASK_CACHE_MAX_SIZE) { + new_mask_pixmap: + mask_pixmap = glamor_create_pixmap(screen, width, height, + mask_format->depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!mask_pixmap) { + glamor_destroy_pixmap(mask_pixmap); + return; + } + glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0); + component_alpha = NeedsComponent(mask_format->format); + mask = CreatePicture(0, &mask_pixmap->drawable, + mask_format, CPComponentAlpha, + &component_alpha, serverClient, &error); + if (!mask) + return; + need_free_mask = TRUE; + pmask_arg = &arg; + pmask_buffer = &buffer; + pmask_buffer->count = 0; + pmask_buffer->source = NULL; + pmask_arg->used_bitmap = 0; + glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK; + } + else { + int retry_cnt = 0; + + retry: + mce = get_mask_cache(maskcache, + (width + MASK_CACHE_MAX_SIZE - + 1) / MASK_CACHE_MAX_SIZE); + + if (mce == NULL) { + glamor_glyphs_flush_dst(&dst_arg); + retry_cnt++; + if (retry_cnt > 2) { + assert(0); + goto new_mask_pixmap; + } + goto retry; + } + + mask = cache->picture; + x += mce->x; + y += mce->y; + mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE; + mce->height = 1; + if (mask_arg.mask && mask_arg.mask != mask && mask_buffer.count != 0) + glamor_glyphs_flush_dst(&dst_arg); + pmask_arg = &mask_arg; + pmask_buffer = &mask_buffer; + pmask_arg->maskcache = maskcache; + glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE; + } + pmask_arg->mask = mask; + pmask_arg->buffer = pmask_buffer; + while (nlist--) { + x += list->xOff; + y += list->yOff; + n = list->len; + mask_glyphs_cnt += n; + while (n--) { + glyph = *glyphs++; + if (glyph->info.width > 0 && glyph->info.height > 0) { + glyphs_flush_func flush_func; + void *temp_arg; + + if (need_free_mask) { + if (pmask_buffer->count) + flush_func = + (glyphs_flush_func) glamor_glyphs_flush_mask; + else + flush_func = NULL; + temp_arg = pmask_arg; + } + else { + /* If we are using global mask cache, then we need to + * flush dst instead of mask. As some dst depends on the + * previous mask result. Just flush mask can't get all previous's + * overlapped glyphs.*/ + if (dst_buffer.count || mask_buffer.count) + flush_func = + (glyphs_flush_func) glamor_glyphs_flush_dst; + else + flush_func = NULL; + temp_arg = &dst_arg; + } + glamor_buffer_glyph(glamor_priv, pmask_buffer, + mask_format->format, + glyph, NULL, x, y, + 0, 0, + glyph->info.width, glyph->info.height, + glyphs_dst_mode, + flush_func, (void *) temp_arg); + } + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + + x = extents.x1; + y = extents.y1; + if (need_free_mask) { + glamor_glyphs_flush_mask(pmask_arg); + CompositePicture(op, + src, + mask, + dst, + x_src + x - x_dst, + y_src + y - y_dst, 0, 0, x, y, width, height); + FreePicture(mask, 0); + glamor_destroy_pixmap(mask_pixmap); + } + else { + struct glamor_glyph priv; + glyphs_flush_func flush_func; + BoxPtr rects; + int nrect; + + priv.cache = cache; + priv.x = mce->x; + priv.y = mce->y; + priv.cached = TRUE; + rects = REGION_RECTS(dst->pCompositeClip); + nrect = REGION_NUM_RECTS(dst->pCompositeClip); + + pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx; + dst_arg.op = op; + dst_arg.src = src; + dst_arg.dst = dst; + dst_arg.buffer = &dst_buffer; + dst_arg.x_src = x_src; + dst_arg.y_src = y_src; + dst_arg.x_dst = x_dst; + dst_arg.y_dst = y_dst; + + if (dst_buffer.source == NULL) { + dst_buffer.source = cache->picture; + } + else if (dst_buffer.source != cache->picture) { + glamor_glyphs_flush_dst(&dst_arg); + dst_buffer.source = cache->picture; + } + + x += dst->pDrawable->x; + y += dst->pDrawable->y; + + if (dst_buffer.count || mask_buffer.count) + flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst; + else + flush_func = NULL; + + glamor_buffer_glyph_clip(glamor_priv, + rects, nrect, + mask_format->format, + NULL, &priv, + x, y, + 0, 0, + width, height, + GLYPHS_DST_MODE_MASK_TO_DST, + flush_func, (void *) &dst_arg); + } } static void glamor_glyphs_to_dst(CARD8 op, - PicturePtr src, - PicturePtr dst, - INT16 x_src, - INT16 y_src, - int nlist, GlyphListPtr list, - GlyphPtr * glyphs) + PicturePtr src, + PicturePtr dst, + INT16 x_src, + INT16 y_src, + int nlist, GlyphListPtr list, GlyphPtr * glyphs) { - ScreenPtr screen = dst->pDrawable->pScreen; - int x = 0, y = 0; - int x_dst = list->xOff, y_dst = list->yOff; - int n; - GlyphPtr glyph; - BoxPtr rects; - int nrect; - glamor_screen_private *glamor_priv; - - rects = REGION_RECTS(dst->pCompositeClip); - nrect = REGION_NUM_RECTS(dst->pCompositeClip); - - glamor_priv = glamor_get_screen_private(screen); - - dst_arg.op = op; - dst_arg.src = src; - dst_arg.dst = dst; - dst_arg.buffer = &dst_buffer; - dst_arg.x_src = x_src; - dst_arg.y_src = y_src; - dst_arg.x_dst = x_dst; - dst_arg.y_dst = y_dst; - - x = dst->pDrawable->x; - y = dst->pDrawable->y; - - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - dst_glyphs_cnt += n; - while (n--) { - glyph = *glyphs++; - - if (glyph->info.width > 0 - && glyph->info.height > 0) { - glyphs_flush_func flush_func; - - if (dst_buffer.count || mask_buffer.count) - flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst; - else - flush_func = NULL; - glamor_buffer_glyph_clip(glamor_priv, - rects, nrect, - (GlyphPicture(glyph)[screen->myNum])->format, - glyph, NULL, - x, y, - glyph->info.x, glyph->info.y, - glyph->info.width, glyph->info.height, - GLYPHS_DST_MODE_TO_DST, - flush_func, - (void *)&dst_arg - ); - } - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - } + ScreenPtr screen = dst->pDrawable->pScreen; + int x = 0, y = 0; + int x_dst = list->xOff, y_dst = list->yOff; + int n; + GlyphPtr glyph; + BoxPtr rects; + int nrect; + glamor_screen_private *glamor_priv; + + rects = REGION_RECTS(dst->pCompositeClip); + nrect = REGION_NUM_RECTS(dst->pCompositeClip); + + glamor_priv = glamor_get_screen_private(screen); + + dst_arg.op = op; + dst_arg.src = src; + dst_arg.dst = dst; + dst_arg.buffer = &dst_buffer; + dst_arg.x_src = x_src; + dst_arg.y_src = y_src; + dst_arg.x_dst = x_dst; + dst_arg.y_dst = y_dst; + + x = dst->pDrawable->x; + y = dst->pDrawable->y; + + while (nlist--) { + x += list->xOff; + y += list->yOff; + n = list->len; + dst_glyphs_cnt += n; + while (n--) { + glyph = *glyphs++; + + if (glyph->info.width > 0 && glyph->info.height > 0) { + glyphs_flush_func flush_func; + + if (dst_buffer.count || mask_buffer.count) + flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst; + else + flush_func = NULL; + glamor_buffer_glyph_clip(glamor_priv, + rects, nrect, + (GlyphPicture(glyph)[screen->myNum])-> + format, glyph, NULL, x, y, + glyph->info.x, glyph->info.y, + glyph->info.width, glyph->info.height, + GLYPHS_DST_MODE_TO_DST, flush_func, + (void *) &dst_arg); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } } + #define MAX_FIXED_SIZE static void -glamor_glyphs_reset_buffer(glamor_glyph_buffer_t *buffer) +glamor_glyphs_reset_buffer(glamor_glyph_buffer_t * buffer) { - buffer->count = 0; - buffer->source = NULL; + buffer->count = 0; + buffer->source = NULL; } static Bool _glamor_glyphs(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, int nlist, GlyphListPtr list, - GlyphPtr * glyphs, Bool fallback) + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, int nlist, GlyphListPtr list, + GlyphPtr * glyphs, Bool fallback) { - PictFormatShort format; - int fixed_size, fixed_cnt = 0; - struct glamor_glyph_list *fixed_list = NULL; - Bool need_free_list = FALSE; + PictFormatShort format; + int fixed_size, fixed_cnt = 0; + struct glamor_glyph_list *fixed_list = NULL; + Bool need_free_list = FALSE; + #ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK - Bool check_fake_overlap = TRUE; - if (!(op == PictOpOver - || op == PictOpAdd - || op == PictOpXor)) { - /* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)). - * For those op, (A IN (C ADD D)) OP B != (A IN D) OP ((A IN C) OP B) - * or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B) - * We need to split the faked regions to three or two, and composite the disoverlapped small - * boxes one by one. For other Ops, it's safe to composite the whole box. */ - check_fake_overlap = FALSE; - } + Bool check_fake_overlap = TRUE; + + if (!(op == PictOpOver || op == PictOpAdd || op == PictOpXor)) { + /* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)). + * For those op, (A IN (C ADD D)) OP B != (A IN D) OP ((A IN C) OP B) + * or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B) + * We need to split the faked regions to three or two, and composite the disoverlapped small + * boxes one by one. For other Ops, it's safe to composite the whole box. */ + check_fake_overlap = FALSE; + } #else - Bool check_fake_overlap = FALSE; + Bool check_fake_overlap = FALSE; #endif - if (mask_format) - format = mask_format->depth << 24 | mask_format->format; - else - format = 0; - - fixed_size = 32; - glamor_glyphs_reset_buffer(&dst_buffer); - - if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd) - && (dst->format == ((mask_format->depth << 24) | mask_format->format)))) { - glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, - list, glyphs); - goto last_flush; - } - - glamor_glyphs_reset_buffer(&mask_buffer); - - /* We have mask_format. Need to check the real overlap or not.*/ - format = mask_format->depth << 24 | mask_format->format; - - fixed_list = calloc(fixed_size, sizeof(*fixed_list)); - if (unlikely(fixed_list == NULL)) - fixed_size = 0; - fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs, - format, dst->pDrawable->pScreen, - check_fake_overlap, - fixed_list, fixed_size); - if (fixed_cnt == 0) - mask_format = NULL; - need_free_list = TRUE; - - if (fixed_cnt <= 0) { - if (mask_format == NULL) { - glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, - list, glyphs); - goto last_flush; - } else { - glamor_glyphs_via_mask(op, src, dst, mask_format, - x_src, y_src, nlist, list, glyphs, - FALSE); - goto free_fixed_list; - } - } else { - - /* We have splitted the original list to serval list, some are overlapped - * and some are non-overlapped. For the non-overlapped, we render it to - * dst directly. For the overlapped, we render it to mask picture firstly, - * then render the mask to dst. If we can use mask cache which is in the - * glyphs cache's last row, we can accumulate the rendering of mask to dst - * with the other dst_buffer's rendering operations thus can reduce the call - * of glDrawElements. - * - * */ - struct glamor_glyph_list *saved_list; - - saved_list = fixed_list; - mask_arg.used_bitmap = 0; - while(fixed_cnt--) { - if (fixed_list->type == NON_INTERSECTED) { - glamor_glyphs_to_dst(op, src, dst, - x_src, y_src, - fixed_list->nlist, - fixed_list->list, - fixed_list->glyphs); - } - else - glamor_glyphs_via_mask(op, src, dst, - mask_format, x_src, y_src, - fixed_list->nlist, - fixed_list->list, - fixed_list->glyphs, TRUE); - - free(fixed_list->list); - fixed_list++; - } - free(saved_list); - need_free_list = FALSE; - } - -last_flush: - if (dst_buffer.count || mask_buffer.count) - glamor_glyphs_flush_dst(&dst_arg); -free_fixed_list: - if(need_free_list) { - assert(fixed_cnt <= 0); - free(fixed_list); - } - return TRUE; + if (mask_format) + format = mask_format->depth << 24 | mask_format->format; + else + format = 0; + + fixed_size = 32; + glamor_glyphs_reset_buffer(&dst_buffer); + + if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd) + && (dst->format == + ((mask_format->depth << 24) | mask_format-> + format)))) { + glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, list, glyphs); + goto last_flush; + } + + glamor_glyphs_reset_buffer(&mask_buffer); + + /* We have mask_format. Need to check the real overlap or not. */ + format = mask_format->depth << 24 | mask_format->format; + + fixed_list = calloc(fixed_size, sizeof(*fixed_list)); + if (unlikely(fixed_list == NULL)) + fixed_size = 0; + fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs, + format, dst->pDrawable->pScreen, + check_fake_overlap, + fixed_list, fixed_size); + if (fixed_cnt == 0) + mask_format = NULL; + need_free_list = TRUE; + + if (fixed_cnt <= 0) { + if (mask_format == NULL) { + glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, + list, glyphs); + goto last_flush; + } + else { + glamor_glyphs_via_mask(op, src, dst, mask_format, + x_src, y_src, nlist, list, glyphs, FALSE); + goto free_fixed_list; + } + } + else { + + /* We have splitted the original list to serval list, some are overlapped + * and some are non-overlapped. For the non-overlapped, we render it to + * dst directly. For the overlapped, we render it to mask picture firstly, + * then render the mask to dst. If we can use mask cache which is in the + * glyphs cache's last row, we can accumulate the rendering of mask to dst + * with the other dst_buffer's rendering operations thus can reduce the call + * of glDrawElements. + * + * */ + struct glamor_glyph_list *saved_list; + + saved_list = fixed_list; + mask_arg.used_bitmap = 0; + while (fixed_cnt--) { + if (fixed_list->type == NON_INTERSECTED) { + glamor_glyphs_to_dst(op, src, dst, + x_src, y_src, + fixed_list->nlist, + fixed_list->list, fixed_list->glyphs); + } + else + glamor_glyphs_via_mask(op, src, dst, + mask_format, x_src, y_src, + fixed_list->nlist, + fixed_list->list, + fixed_list->glyphs, TRUE); + + free(fixed_list->list); + fixed_list++; + } + free(saved_list); + need_free_list = FALSE; + } + + last_flush: + if (dst_buffer.count || mask_buffer.count) + glamor_glyphs_flush_dst(&dst_arg); + free_fixed_list: + if (need_free_list) { + assert(fixed_cnt <= 0); + free(fixed_list); + } + return TRUE; } void glamor_glyphs(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs) + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { - _glamor_glyphs(op, src, dst, mask_format, x_src, - y_src, nlist, list, glyphs, TRUE); + _glamor_glyphs(op, src, dst, mask_format, x_src, + y_src, nlist, list, glyphs, TRUE); } Bool glamor_glyphs_nf(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, int nlist, - GlyphListPtr list, GlyphPtr * glyphs) + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { - return _glamor_glyphs(op, src, dst, mask_format, x_src, - y_src, nlist, list, glyphs, FALSE); + return _glamor_glyphs(op, src, dst, mask_format, x_src, + y_src, nlist, list, glyphs, FALSE); } - diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c index 4abc82d..df6c3bb 100644 --- a/glamor/glamor_gradient.c +++ b/glamor/glamor_gradient.c @@ -43,15 +43,16 @@ #ifdef GLAMOR_GRADIENT_SHADER static GLint -_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_array) +_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, + int use_array) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; - char *gradient_fs = NULL; - GLint fs_getcolor_prog; + char *gradient_fs = NULL; + GLint fs_getcolor_prog; - #define gradient_fs_getcolor\ +#define gradient_fs_getcolor\ GLAMOR_DEFAULT_PRECISION\ "uniform int n_stop;\n"\ "uniform float stops[%d];\n"\ @@ -82,163 +83,86 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar " return gradient_color;\n"\ "}\n" - /* Because the array access for shader is very slow, the performance is very low - if use array. So use global uniform to replace for it if the number of n_stops is small.*/ - const char *gradient_fs_getcolor_no_array = - GLAMOR_DEFAULT_PRECISION - "uniform int n_stop;\n" - "uniform float stop0;\n" - "uniform float stop1;\n" - "uniform float stop2;\n" - "uniform float stop3;\n" - "uniform float stop4;\n" - "uniform float stop5;\n" - "uniform float stop6;\n" - "uniform float stop7;\n" - "uniform vec4 stop_color0;\n" - "uniform vec4 stop_color1;\n" - "uniform vec4 stop_color2;\n" - "uniform vec4 stop_color3;\n" - "uniform vec4 stop_color4;\n" - "uniform vec4 stop_color5;\n" - "uniform vec4 stop_color6;\n" - "uniform vec4 stop_color7;\n" - "\n" - "vec4 get_color(float stop_len)\n" - "{\n" - " float stop_after;\n" - " float stop_before;\n" - " vec4 stop_color_before;\n" - " vec4 stop_color_after;\n" - " float new_alpha; \n" - " vec4 gradient_color;\n" - " float percentage; \n" - " \n" - " if((stop_len < stop0) && (n_stop >= 1)) {\n" - " stop_color_before = stop_color0;\n" - " stop_color_after = stop_color0;\n" - " stop_after = stop0;\n" - " stop_before = stop0;\n" - " } else if((stop_len < stop1) && (n_stop >= 2)) {\n" - " stop_color_before = stop_color0;\n" - " stop_color_after = stop_color1;\n" - " stop_after = stop1;\n" - " stop_before = stop0;\n" - " } else if((stop_len < stop2) && (n_stop >= 3)) {\n" - " stop_color_before = stop_color1;\n" - " stop_color_after = stop_color2;\n" - " stop_after = stop2;\n" - " stop_before = stop1;\n" - " } else if((stop_len < stop3) && (n_stop >= 4)){\n" - " stop_color_before = stop_color2;\n" - " stop_color_after = stop_color3;\n" - " stop_after = stop3;\n" - " stop_before = stop2;\n" - " } else if((stop_len < stop4) && (n_stop >= 5)){\n" - " stop_color_before = stop_color3;\n" - " stop_color_after = stop_color4;\n" - " stop_after = stop4;\n" - " stop_before = stop3;\n" - " } else if((stop_len < stop5) && (n_stop >= 6)){\n" - " stop_color_before = stop_color4;\n" - " stop_color_after = stop_color5;\n" - " stop_after = stop5;\n" - " stop_before = stop4;\n" - " } else if((stop_len < stop6) && (n_stop >= 7)){\n" - " stop_color_before = stop_color5;\n" - " stop_color_after = stop_color6;\n" - " stop_after = stop6;\n" - " stop_before = stop5;\n" - " } else if((stop_len < stop7) && (n_stop >= 8)){\n" - " stop_color_before = stop_color6;\n" - " stop_color_after = stop_color7;\n" - " stop_after = stop7;\n" - " stop_before = stop6;\n" - " } else {\n" - " stop_color_before = stop_color7;\n" - " stop_color_after = stop_color7;\n" - " stop_after = stop7;\n" - " stop_before = stop7;\n" - " }\n" - " if(stop_after - stop_before > 2.0)\n" - " percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow. - " else if(stop_after - stop_before < 0.000001)\n" - " percentage = 0.0;\n" - " else \n" - " percentage = (stop_len - stop_before)/(stop_after - stop_before);\n" - " new_alpha = percentage * stop_color_after.a + \n" - " (1.0-percentage) * stop_color_before.a; \n" - " gradient_color = vec4((percentage * stop_color_after.rgb \n" - " + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n" - " new_alpha);\n" - " \n" - " return gradient_color;\n" - "}\n"; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - - if(use_array) { - XNFasprintf(&gradient_fs, - gradient_fs_getcolor, stops_count, stops_count); - fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - gradient_fs); - free(gradient_fs); - } else { - fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - gradient_fs_getcolor_no_array); - } - - return fs_getcolor_prog; + /* Because the array access for shader is very slow, the performance is very low + if use array. So use global uniform to replace for it if the number of n_stops is small. */ + const char *gradient_fs_getcolor_no_array = GLAMOR_DEFAULT_PRECISION "uniform int n_stop;\n" "uniform float stop0;\n" "uniform float stop1;\n" "uniform float stop2;\n" "uniform float stop3;\n" "uniform float stop4;\n" "uniform float stop5;\n" "uniform float stop6;\n" "uniform float stop7;\n" "uniform vec4 stop_color0;\n" "uniform vec4 stop_color1;\n" "uniform vec4 stop_color2;\n" "uniform vec4 stop_color3;\n" "uniform vec4 stop_color4;\n" "uniform vec4 stop_color5;\n" "uniform vec4 stop_color6;\n" "uniform vec4 stop_color7;\n" "\n" "vec4 get_color(float stop_len)\n" "{\n" " float stop_after;\n" " float stop_before;\n" " vec4 stop_color_before;\n" " vec4 stop_color_after;\n" " float new_alpha; \n" " vec4 gradient_color;\n" " float percentage; \n" " \n" " if((stop_len < stop0) && (n_stop >= 1)) {\n" " stop_color_before = stop_color0;\n" " stop_color_after = stop_color0;\n" " stop_after = stop0;\n" " stop_before = stop0;\n" " } else if((stop_len < stop1) && (n_stop >= 2)) {\n" " stop_color_before = stop_color0;\n" " stop_color_after = stop_color1;\n" " stop_after = stop1;\n" " stop_before = stop0;\n" " } else if((stop_len < stop2) && (n_stop >= 3)) {\n" " stop_color_before = stop_color1;\n" " stop_color_after = stop_color2;\n" " stop_after = stop2;\n" " stop_before = stop1;\n" " } else if((stop_len < stop3) && (n_stop >= 4)){\n" " stop_color_before = stop_color2;\n" " stop_color_after = stop_color3;\n" " stop_after = stop3;\n" " stop_before = stop2;\n" " } else if((stop_len < stop4) && (n_stop >= 5)){\n" " stop_color_before = stop_color3;\n" " stop_color_after = stop_color4;\n" " stop_after = stop4;\n" " stop_before = stop3;\n" " } else if((stop_len < stop5) && (n_stop >= 6)){\n" " stop_color_before = stop_color4;\n" " stop_color_after = stop_color5;\n" " stop_after = stop5;\n" " stop_before = stop4;\n" " } else if((stop_len < stop6) && (n_stop >= 7)){\n" " stop_color_before = stop_color5;\n" " stop_color_after = stop_color6;\n" " stop_after = stop6;\n" " stop_before = stop5;\n" " } else if((stop_len < stop7) && (n_stop >= 8)){\n" " stop_color_before = stop_color6;\n" " stop_color_after = stop_color7;\n" " stop_after = stop7;\n" " stop_before = stop6;\n" " } else {\n" " stop_color_before = stop_color7;\n" " stop_color_after = stop_color7;\n" " stop_after = stop7;\n" " stop_before = stop7;\n" " }\n" " if(stop_after - stop_before > 2.0)\n" " percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow. + " else if(stop_after - stop_before < 0.000001)\n" + " percentage = 0.0;\n" + " else \n" + " percentage = (stop_len - stop_before)/(stop_after - stop_before);\n" + " new_alpha = percentage * stop_color_after.a + \n" + " (1.0-percentage) * stop_color_before.a; \n" + " gradient_color = vec4((percentage * stop_color_after.rgb \n" + " + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n" + " new_alpha);\n" + " \n" " return gradient_color;\n" "}\n"; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + + if (use_array) { + XNFasprintf(&gradient_fs, + gradient_fs_getcolor, stops_count, stops_count); + fs_getcolor_prog = + glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, gradient_fs); + free(gradient_fs); + } + else { + fs_getcolor_prog = + glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, + gradient_fs_getcolor_no_array); + } + + return fs_getcolor_prog; } static void -_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen) +_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, + int dyn_gen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - int index; - - GLint gradient_prog = 0; - char *gradient_fs = NULL; - GLint fs_main_prog, fs_getcolor_prog, vs_prog; - - const char *gradient_vs = - GLAMOR_DEFAULT_PRECISION - "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord;\n" - "varying vec2 source_texture;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - " source_texture = v_texcoord.xy;\n" - "}\n"; - - /* - * Refer to pixman radial gradient. - * - * The problem is given the two circles of c1 and c2 with the radius of r1 and - * r1, we need to caculate the t, which is used to do interpolate with stops, - * using the fomula: - * length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2 - * expand the fomula with xy coond, get the following: - * sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y)) - * = (1-t)r1 + t*r2 - * <====> At*t- 2Bt + C = 0 - * where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1) - * B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1) - * C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1 - * - * solve the fomula and we get the result of - * t = (B + sqrt(B*B - A*C)) / A or - * t = (B - sqrt(B*B - A*C)) / A (quadratic equation have two solutions) - * - * The solution we are going to prefer is the bigger one, unless the - * radius associated to it is negative (or it falls outside the valid t range) - */ - - #define gradient_radial_fs_template\ + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + int index; + + GLint gradient_prog = 0; + char *gradient_fs = NULL; + GLint fs_main_prog, fs_getcolor_prog, vs_prog; + + const char *gradient_vs = + GLAMOR_DEFAULT_PRECISION + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord;\n" + "varying vec2 source_texture;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = v_position;\n" + " source_texture = v_texcoord.xy;\n" "}\n"; + + /* + * Refer to pixman radial gradient. + * + * The problem is given the two circles of c1 and c2 with the radius of r1 and + * r1, we need to caculate the t, which is used to do interpolate with stops, + * using the fomula: + * length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2 + * expand the fomula with xy coond, get the following: + * sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y)) + * = (1-t)r1 + t*r2 + * <====> At*t- 2Bt + C = 0 + * where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1) + * B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1) + * C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1 + * + * solve the fomula and we get the result of + * t = (B + sqrt(B*B - A*C)) / A or + * t = (B - sqrt(B*B - A*C)) / A (quadratic equation have two solutions) + * + * The solution we are going to prefer is the bigger one, unless the + * radius associated to it is negative (or it falls outside the valid t range) + */ + +#define gradient_radial_fs_template\ GLAMOR_DEFAULT_PRECISION\ "uniform mat3 transform_mat;\n"\ "uniform int repeat_type;\n"\ @@ -344,149 +268,164 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dy " }\n"\ "}\n" - glamor_priv = glamor_get_screen_private(screen); - - if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) { - /* Very Good, not to generate again. */ - return; - } - - dispatch = glamor_get_dispatch(glamor_priv); - - if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) { - dispatch->glDeleteShader( - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]); - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0; - - dispatch->glDeleteShader( - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]); - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0; - - dispatch->glDeleteShader( - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]); - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0; - - dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]); - glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0; - } - - gradient_prog = dispatch->glCreateProgram(); - - vs_prog = glamor_compile_glsl_prog(dispatch, - GL_VERTEX_SHADER, gradient_vs); - - XNFasprintf(&gradient_fs, - gradient_radial_fs_template, - PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT); - - fs_main_prog = glamor_compile_glsl_prog(dispatch, - GL_FRAGMENT_SHADER, gradient_fs); - - free(gradient_fs); - - fs_getcolor_prog = - _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0)); - - dispatch->glAttachShader(gradient_prog, vs_prog); - dispatch->glAttachShader(gradient_prog, fs_getcolor_prog); - dispatch->glAttachShader(gradient_prog, fs_main_prog); - - dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_positionsition"); - dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord"); - - glamor_link_glsl_prog(dispatch, gradient_prog); - - dispatch->glUseProgram(0); - - if (dyn_gen) { - index = 2; - glamor_priv->radial_max_nstops = stops_count; - } else if (stops_count) { - index = 1; - } else { - index = 0; - } - - glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog; - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog; - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog; - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog; - - glamor_put_dispatch(glamor_priv); + glamor_priv = glamor_get_screen_private(screen); + + if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) { + /* Very Good, not to generate again. */ + return; + } + + dispatch = glamor_get_dispatch(glamor_priv); + + if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) { + dispatch->glDeleteShader(glamor_priv-> + radial_gradient_shaders + [SHADER_GRADIENT_VS_PROG][2]); + glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0; + + dispatch->glDeleteShader(glamor_priv-> + radial_gradient_shaders + [SHADER_GRADIENT_FS_MAIN_PROG][2]); + glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = + 0; + + dispatch->glDeleteShader(glamor_priv-> + radial_gradient_shaders + [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]); + glamor_priv-> + radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0; + + dispatch->glDeleteProgram(glamor_priv-> + gradient_prog[SHADER_GRADIENT_RADIAL][2]); + glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0; + } + + gradient_prog = dispatch->glCreateProgram(); + + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, gradient_vs); + + XNFasprintf(&gradient_fs, + gradient_radial_fs_template, + PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, + PIXMAN_REPEAT_REFLECT); + + fs_main_prog = glamor_compile_glsl_prog(dispatch, + GL_FRAGMENT_SHADER, gradient_fs); + + free(gradient_fs); + + fs_getcolor_prog = + _glamor_create_getcolor_fs_program(screen, stops_count, + (stops_count > 0)); + + dispatch->glAttachShader(gradient_prog, vs_prog); + dispatch->glAttachShader(gradient_prog, fs_getcolor_prog); + dispatch->glAttachShader(gradient_prog, fs_main_prog); + + dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, + "v_positionsition"); + dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, + "v_texcoord"); + + glamor_link_glsl_prog(dispatch, gradient_prog); + + dispatch->glUseProgram(0); + + if (dyn_gen) { + index = 2; + glamor_priv->radial_max_nstops = stops_count; + } + else if (stops_count) { + index = 1; + } + else { + index = 0; + } + + glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog; + glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = + vs_prog; + glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = + fs_main_prog; + glamor_priv-> + radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = + fs_getcolor_prog; + + glamor_put_dispatch(glamor_priv); } static void -_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen) +_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, + int dyn_gen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - - int index = 0; - GLint gradient_prog = 0; - char *gradient_fs = NULL; - GLint fs_main_prog, fs_getcolor_prog, vs_prog; - - const char *gradient_vs = - GLAMOR_DEFAULT_PRECISION - "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord;\n" - "varying vec2 source_texture;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - " source_texture = v_texcoord.xy;\n" - "}\n"; - - /* - * | - * |\ - * | \ - * | \ - * | \ - * |\ \ - * | \ \ - * cos_val = |\ p1d \ / - * sqrt(1/(slope*slope+1.0)) ------>\ \ \ / - * | \ \ \ - * | \ \ / \ - * | \ *Pt1\ - * *p1 | \ \ *P - * \ | / \ \ / - * \ | / \ \ / - * \ | pd \ - * \ | \ / \ - * p2* | \ / \ / - * slope = (p2.y - p1.y) / | / p2d / - * (p2.x - p1.x) | / \ / - * | / \ / - * | / / - * | / / - * | / *Pt2 - * | / - * | / - * | / - * | / - * | / - * -------+--------------------------------- - * O| - * | - * | - * - * step 1: compute the distance of p, pt1 and pt2 in the slope direction. - * Caculate the distance on Y axis first and multiply cos_val to - * get the value on slope direction(pd, p1d and p2d represent the - * distance of p, pt1, and pt2 respectively). - * - * step 2: caculate the percentage of (pd - p1d)/(p2d - p1d). - * If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d) - * to make it in the range of [0, (p2d - p1d)]. - * - * step 3: compare the percentage to every stop and find the stpos just - * before and after it. Use the interpolation fomula to compute RGBA. - */ - - #define gradient_fs_template \ + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + + int index = 0; + GLint gradient_prog = 0; + char *gradient_fs = NULL; + GLint fs_main_prog, fs_getcolor_prog, vs_prog; + + const char *gradient_vs = + GLAMOR_DEFAULT_PRECISION + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord;\n" + "varying vec2 source_texture;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = v_position;\n" + " source_texture = v_texcoord.xy;\n" "}\n"; + + /* + * | + * |\ + * | \ + * | \ + * | \ + * |\ \ + * | \ \ + * cos_val = |\ p1d \ / + * sqrt(1/(slope*slope+1.0)) ------>\ \ \ / + * | \ \ \ + * | \ \ / \ + * | \ *Pt1\ + * *p1 | \ \ *P + * \ | / \ \ / + * \ | / \ \ / + * \ | pd \ + * \ | \ / \ + * p2* | \ / \ / + * slope = (p2.y - p1.y) / | / p2d / + * (p2.x - p1.x) | / \ / + * | / \ / + * | / / + * | / / + * | / *Pt2 + * | / + * | / + * | / + * | / + * | / + * -------+--------------------------------- + * O| + * | + * | + * + * step 1: compute the distance of p, pt1 and pt2 in the slope direction. + * Caculate the distance on Y axis first and multiply cos_val to + * get the value on slope direction(pd, p1d and p2d represent the + * distance of p, pt1, and pt2 respectively). + * + * step 2: caculate the percentage of (pd - p1d)/(p2d - p1d). + * If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d) + * to make it in the range of [0, (p2d - p1d)]. + * + * step 3: compare the percentage to every stop and find the stpos just + * before and after it. Use the interpolation fomula to compute RGBA. + */ + +#define gradient_fs_template \ GLAMOR_DEFAULT_PRECISION\ "uniform mat3 transform_mat;\n"\ "uniform int repeat_type;\n"\ @@ -569,1016 +508,1086 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dy " gl_FragColor = get_color(stop_len);\n"\ "}\n" - glamor_priv = glamor_get_screen_private(screen); - - if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) { - /* Very Good, not to generate again. */ - return; - } - - dispatch = glamor_get_dispatch(glamor_priv); - if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) { - dispatch->glDeleteShader( - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]); - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0; - - dispatch->glDeleteShader( - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]); - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0; - - dispatch->glDeleteShader( - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]); - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0; - - dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]); - glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0; - } - - gradient_prog = dispatch->glCreateProgram(); - - vs_prog = glamor_compile_glsl_prog(dispatch, - GL_VERTEX_SHADER, gradient_vs); - - XNFasprintf(&gradient_fs, - gradient_fs_template, - PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT); - - fs_main_prog = glamor_compile_glsl_prog(dispatch, - GL_FRAGMENT_SHADER, gradient_fs); - free(gradient_fs); - - fs_getcolor_prog = - _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0)); - - dispatch->glAttachShader(gradient_prog, vs_prog); - dispatch->glAttachShader(gradient_prog, fs_getcolor_prog); - dispatch->glAttachShader(gradient_prog, fs_main_prog); - - dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position"); - dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord"); - - glamor_link_glsl_prog(dispatch, gradient_prog); - - dispatch->glUseProgram(0); - - if (dyn_gen) { - index = 2; - glamor_priv->linear_max_nstops = stops_count; - } else if (stops_count) { - index = 1; - } else { - index = 0; - } - - glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog; - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog; - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog; - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog; - - glamor_put_dispatch(glamor_priv); + glamor_priv = glamor_get_screen_private(screen); + + if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) { + /* Very Good, not to generate again. */ + return; + } + + dispatch = glamor_get_dispatch(glamor_priv); + if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) { + dispatch->glDeleteShader(glamor_priv-> + linear_gradient_shaders + [SHADER_GRADIENT_VS_PROG][2]); + glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0; + + dispatch->glDeleteShader(glamor_priv-> + linear_gradient_shaders + [SHADER_GRADIENT_FS_MAIN_PROG][2]); + glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = + 0; + + dispatch->glDeleteShader(glamor_priv-> + linear_gradient_shaders + [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]); + glamor_priv-> + linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0; + + dispatch->glDeleteProgram(glamor_priv-> + gradient_prog[SHADER_GRADIENT_LINEAR][2]); + glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0; + } + + gradient_prog = dispatch->glCreateProgram(); + + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, gradient_vs); + + XNFasprintf(&gradient_fs, + gradient_fs_template, + PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT); + + fs_main_prog = glamor_compile_glsl_prog(dispatch, + GL_FRAGMENT_SHADER, gradient_fs); + free(gradient_fs); + + fs_getcolor_prog = + _glamor_create_getcolor_fs_program(screen, stops_count, + (stops_count > 0)); + + dispatch->glAttachShader(gradient_prog, vs_prog); + dispatch->glAttachShader(gradient_prog, fs_getcolor_prog); + dispatch->glAttachShader(gradient_prog, fs_main_prog); + + dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, + "v_position"); + dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, + "v_texcoord"); + + glamor_link_glsl_prog(dispatch, gradient_prog); + + dispatch->glUseProgram(0); + + if (dyn_gen) { + index = 2; + glamor_priv->linear_max_nstops = stops_count; + } + else if (stops_count) { + index = 1; + } + else { + index = 0; + } + + glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog; + glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = + vs_prog; + glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = + fs_main_prog; + glamor_priv-> + linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = + fs_getcolor_prog; + + glamor_put_dispatch(glamor_priv); } void glamor_init_gradient_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - int i; - - glamor_priv = glamor_get_screen_private(screen); - - for (i = 0; i < 3; i++) { - glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0; - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0; - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0; - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0; - - glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0; - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0; - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0; - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0; - } - glamor_priv->linear_max_nstops = 0; - glamor_priv->radial_max_nstops = 0; - - _glamor_create_linear_gradient_program(screen, 0, 0); - _glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0); - - _glamor_create_radial_gradient_program(screen, 0, 0); - _glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0); + glamor_screen_private *glamor_priv; + int i; + + glamor_priv = glamor_get_screen_private(screen); + + for (i = 0; i < 3; i++) { + glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0; + glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0; + glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = + 0; + glamor_priv-> + linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0; + + glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0; + glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0; + glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = + 0; + glamor_priv-> + radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0; + } + glamor_priv->linear_max_nstops = 0; + glamor_priv->radial_max_nstops = 0; + + _glamor_create_linear_gradient_program(screen, 0, 0); + _glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0); + + _glamor_create_radial_gradient_program(screen, 0, 0); + _glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0); } void glamor_fini_gradient_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - int i = 0; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - - for (i = 0; i < 3; i++) { - /* Linear Gradient */ - if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]) - dispatch->glDeleteShader( - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]); - - if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]) - dispatch->glDeleteShader( - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]); - - if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]) - dispatch->glDeleteShader( - glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]); - - if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]) - dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]); - - /* Radial Gradient */ - if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]) - dispatch->glDeleteShader( - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]); - - if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]) - dispatch->glDeleteShader( - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]); - - if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]) - dispatch->glDeleteShader( - glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]); - - if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]) - dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]); - } - - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + int i = 0; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + + for (i = 0; i < 3; i++) { + /* Linear Gradient */ + if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]) + dispatch->glDeleteShader(glamor_priv-> + linear_gradient_shaders + [SHADER_GRADIENT_VS_PROG][i]); + + if (glamor_priv-> + linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]) + dispatch->glDeleteShader(glamor_priv-> + linear_gradient_shaders + [SHADER_GRADIENT_FS_MAIN_PROG][i]); + + if (glamor_priv-> + linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]) + dispatch->glDeleteShader(glamor_priv-> + linear_gradient_shaders + [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]); + + if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]) + dispatch->glDeleteProgram(glamor_priv-> + gradient_prog[SHADER_GRADIENT_LINEAR][i]); + + /* Radial Gradient */ + if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]) + dispatch->glDeleteShader(glamor_priv-> + radial_gradient_shaders + [SHADER_GRADIENT_VS_PROG][i]); + + if (glamor_priv-> + radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]) + dispatch->glDeleteShader(glamor_priv-> + radial_gradient_shaders + [SHADER_GRADIENT_FS_MAIN_PROG][i]); + + if (glamor_priv-> + radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]) + dispatch->glDeleteShader(glamor_priv-> + radial_gradient_shaders + [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]); + + if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]) + dispatch->glDeleteProgram(glamor_priv-> + gradient_prog[SHADER_GRADIENT_RADIAL][i]); + } + + glamor_put_dispatch(glamor_priv); } static void -_glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3], - int width, int height, int normalize) +_glamor_gradient_convert_trans_matrix(PictTransform * from, float to[3][3], + int width, int height, int normalize) { - /* - * Because in the shader program, we normalize all the pixel cood to [0, 1], - * so with the transform matrix, the correct logic should be: - * v_s = A*T*v - * v_s: point vector in shader after normalized. - * A: The transition matrix from width X height --> 1.0 X 1.0 - * T: The transform matrix. - * v: point vector in width X height space. - * - * result is OK if we use this fomula. But for every point in width X height space, - * we can just use their normalized point vector in shader, namely we can just - * use the result of A*v in shader. So we have no chance to insert T in A*v. - * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the - * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v) - * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and - * we name this matrix T_s. - * - * Firstly, because A is for the scale convertion, we find - * -- -- - * |1/w 0 0 | - * A = | 0 1/h 0 | - * | 0 0 1.0| - * -- -- - * so T_s = A*T*inv(a) and result - * - * -- -- - * | t11 h*t12/w t13/w| - * T_s = | w*t21/h t22 t23/h| - * | w*t31 h*t32 t33 | - * -- -- - */ - - to[0][0] = (float)pixman_fixed_to_double(from->matrix[0][0]); - to[0][1] = (float)pixman_fixed_to_double(from->matrix[0][1]) - * (normalize ? (((float)height) / ((float)width)) : 1.0); - to[0][2] = (float)pixman_fixed_to_double(from->matrix[0][2]) - / (normalize ? ((float)width) : 1.0); - - to[1][0] = (float)pixman_fixed_to_double(from->matrix[1][0]) - * (normalize ? (((float)width) / ((float)height)) : 1.0); - to[1][1] = (float)pixman_fixed_to_double(from->matrix[1][1]); - to[1][2] = (float)pixman_fixed_to_double(from->matrix[1][2]) - / (normalize ? ((float)height) : 1.0); - - to[2][0] = (float)pixman_fixed_to_double(from->matrix[2][0]) - * (normalize ? ((float)width) : 1.0); - to[2][1] = (float)pixman_fixed_to_double(from->matrix[2][1]) - * (normalize ? ((float)height) : 1.0); - to[2][2] = (float)pixman_fixed_to_double(from->matrix[2][2]); - - DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n", - to[0][0], to[0][1], to[0][2], - to[1][0], to[1][1], to[1][2], - to[2][0], to[2][1], to[2][2]); + /* + * Because in the shader program, we normalize all the pixel cood to [0, 1], + * so with the transform matrix, the correct logic should be: + * v_s = A*T*v + * v_s: point vector in shader after normalized. + * A: The transition matrix from width X height --> 1.0 X 1.0 + * T: The transform matrix. + * v: point vector in width X height space. + * + * result is OK if we use this fomula. But for every point in width X height space, + * we can just use their normalized point vector in shader, namely we can just + * use the result of A*v in shader. So we have no chance to insert T in A*v. + * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the + * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v) + * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and + * we name this matrix T_s. + * + * Firstly, because A is for the scale convertion, we find + * -- -- + * |1/w 0 0 | + * A = | 0 1/h 0 | + * | 0 0 1.0| + * -- -- + * so T_s = A*T*inv(a) and result + * + * -- -- + * | t11 h*t12/w t13/w| + * T_s = | w*t21/h t22 t23/h| + * | w*t31 h*t32 t33 | + * -- -- + */ + + to[0][0] = (float) pixman_fixed_to_double(from->matrix[0][0]); + to[0][1] = (float) pixman_fixed_to_double(from->matrix[0][1]) + * (normalize ? (((float) height) / ((float) width)) : 1.0); + to[0][2] = (float) pixman_fixed_to_double(from->matrix[0][2]) + / (normalize ? ((float) width) : 1.0); + + to[1][0] = (float) pixman_fixed_to_double(from->matrix[1][0]) + * (normalize ? (((float) width) / ((float) height)) : 1.0); + to[1][1] = (float) pixman_fixed_to_double(from->matrix[1][1]); + to[1][2] = (float) pixman_fixed_to_double(from->matrix[1][2]) + / (normalize ? ((float) height) : 1.0); + + to[2][0] = (float) pixman_fixed_to_double(from->matrix[2][0]) + * (normalize ? ((float) width) : 1.0); + to[2][1] = (float) pixman_fixed_to_double(from->matrix[2][1]) + * (normalize ? ((float) height) : 1.0); + to[2][2] = (float) pixman_fixed_to_double(from->matrix[2][2]); + + DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n", + to[0][0], to[0][1], to[0][2], + to[1][0], to[1][1], to[1][2], to[2][0], to[2][1], to[2][2]); } static int _glamor_gradient_set_pixmap_destination(ScreenPtr screen, - glamor_screen_private *glamor_priv, + glamor_screen_private * glamor_priv, PicturePtr dst_picture, - GLfloat *xscale, GLfloat *yscale, + GLfloat * xscale, GLfloat * yscale, int x_source, int y_source, float vertices[8], float tex_vertices[8], - int tex_normalize) + int tex_normalize) { - glamor_pixmap_private *pixmap_priv; - PixmapPtr pixmap = NULL; - glamor_gl_dispatch *dispatch = NULL; - - pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable); - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */ - return 0; - } - - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale); - - DEBUGF("xscale = %f, yscale = %f," - " x_source = %d, y_source = %d, width = %d, height = %d\n", - *xscale, *yscale, x_source, y_source, - dst_picture->pDrawable->width, dst_picture->pDrawable->height); - - glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale, - 0, 0, - (INT16)(dst_picture->pDrawable->width), - (INT16)(dst_picture->pDrawable->height), - glamor_priv->yInverted, vertices); - - if (tex_normalize) { - glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale, - x_source, y_source, - (INT16)(dst_picture->pDrawable->width + x_source), - (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, - (INT16)(dst_picture->pDrawable->width) + x_source, - (INT16)(dst_picture->pDrawable->height) + y_source, - glamor_priv->yInverted, tex_vertices); - } - - DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f," - "rightbottom: %f X %f, leftbottom : %f X %f\n", - vertices[0], vertices[1], vertices[2], vertices[3], - vertices[4], vertices[5], vertices[6], vertices[7]); - DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f," - "rightbottom: %f X %f, leftbottom : %f X %f\n", - tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3], - tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]); - - dispatch = glamor_get_dispatch(glamor_priv); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 0, vertices); - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, - GL_FALSE, 0, tex_vertices); - - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - - glamor_put_dispatch(glamor_priv); - - return 1; + glamor_pixmap_private *pixmap_priv; + PixmapPtr pixmap = NULL; + glamor_gl_dispatch *dispatch = NULL; + + pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable); + pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */ + return 0; + } + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + + pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale); + + DEBUGF("xscale = %f, yscale = %f," + " x_source = %d, y_source = %d, width = %d, height = %d\n", + *xscale, *yscale, x_source, y_source, + dst_picture->pDrawable->width, dst_picture->pDrawable->height); + + glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale, + 0, 0, + (INT16) (dst_picture->pDrawable-> + width), + (INT16) (dst_picture->pDrawable-> + height), + glamor_priv->yInverted, vertices); + + if (tex_normalize) { + glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale, + x_source, y_source, + (INT16) (dst_picture-> + pDrawable->width + + x_source), + (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, + (INT16) (dst_picture->pDrawable->width) + + x_source, + (INT16) (dst_picture->pDrawable->height) + + y_source, glamor_priv->yInverted, + tex_vertices); + } + + DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f," + "rightbottom: %f X %f, leftbottom : %f X %f\n", + vertices[0], vertices[1], vertices[2], vertices[3], + vertices[4], vertices[5], vertices[6], vertices[7]); + DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f," + "rightbottom: %f X %f, leftbottom : %f X %f\n", + tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3], + tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]); + + dispatch = glamor_get_dispatch(glamor_priv); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 0, vertices); + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, + GL_FALSE, 0, tex_vertices); + + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + glamor_put_dispatch(glamor_priv); + + return 1; } static int _glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient, - GLfloat *stop_colors, GLfloat *n_stops) + GLfloat * stop_colors, GLfloat * n_stops) { - int i; - int count = 1; - - for (i = 0; i < pgradient->nstops; i++) { - stop_colors[count*4] = pixman_fixed_to_double( - pgradient->stops[i].color.red); - stop_colors[count*4+1] = pixman_fixed_to_double( - pgradient->stops[i].color.green); - stop_colors[count*4+2] = pixman_fixed_to_double( - pgradient->stops[i].color.blue); - stop_colors[count*4+3] = pixman_fixed_to_double( - pgradient->stops[i].color.alpha); - - n_stops[count] = (GLfloat)pixman_fixed_to_double( - pgradient->stops[i].x); - count++; - } - - /* for the end stop. */ - count++; - - switch (src_picture->repeatType) { + int i; + int count = 1; + + for (i = 0; i < pgradient->nstops; i++) { + stop_colors[count * 4] = + pixman_fixed_to_double(pgradient->stops[i].color.red); + stop_colors[count * 4 + 1] = + pixman_fixed_to_double(pgradient->stops[i].color.green); + stop_colors[count * 4 + 2] = + pixman_fixed_to_double(pgradient->stops[i].color.blue); + stop_colors[count * 4 + 3] = + pixman_fixed_to_double(pgradient->stops[i].color.alpha); + + n_stops[count] = + (GLfloat) pixman_fixed_to_double(pgradient->stops[i].x); + count++; + } + + /* for the end stop. */ + count++; + + switch (src_picture->repeatType) { #define REPEAT_FILL_STOPS(m, n) \ stop_colors[(m)*4 + 0] = stop_colors[(n)*4 + 0]; \ stop_colors[(m)*4 + 1] = stop_colors[(n)*4 + 1]; \ stop_colors[(m)*4 + 2] = stop_colors[(n)*4 + 2]; \ stop_colors[(m)*4 + 3] = stop_colors[(n)*4 + 3]; - default: - case PIXMAN_REPEAT_NONE: - stop_colors[0] = 0.0; //R - stop_colors[1] = 0.0; //G - stop_colors[2] = 0.0; //B - stop_colors[3] = 0.0; //Alpha - n_stops[0] = -(float)INT_MAX; //should be small enough. - - stop_colors[0 + (count-1)*4] = 0.0; //R - stop_colors[1 + (count-1)*4] = 0.0; //G - stop_colors[2 + (count-1)*4] = 0.0; //B - stop_colors[3 + (count-1)*4] = 0.0; //Alpha - n_stops[count-1] = (float)INT_MAX; //should be large enough. - break; - case PIXMAN_REPEAT_NORMAL: - REPEAT_FILL_STOPS(0, count - 2); - n_stops[0] = n_stops[count-2] - 1.0; - - REPEAT_FILL_STOPS(count - 1, 1); - n_stops[count-1] = n_stops[1] + 1.0; - break; - case PIXMAN_REPEAT_REFLECT: - REPEAT_FILL_STOPS(0, 1); - n_stops[0] = -n_stops[1]; - - REPEAT_FILL_STOPS(count - 1, count - 2); - n_stops[count-1] = 1.0 + 1.0 - n_stops[count-2]; - break; - case PIXMAN_REPEAT_PAD: - REPEAT_FILL_STOPS(0, 1); - n_stops[0] = -(float)INT_MAX; - - REPEAT_FILL_STOPS(count - 1, count - 2); - n_stops[count-1] = (float)INT_MAX; - break; + default: + case PIXMAN_REPEAT_NONE: + stop_colors[0] = 0.0; //R + stop_colors[1] = 0.0; //G + stop_colors[2] = 0.0; //B + stop_colors[3] = 0.0; //Alpha + n_stops[0] = -(float) INT_MAX; //should be small enough. + + stop_colors[0 + (count - 1) * 4] = 0.0; //R + stop_colors[1 + (count - 1) * 4] = 0.0; //G + stop_colors[2 + (count - 1) * 4] = 0.0; //B + stop_colors[3 + (count - 1) * 4] = 0.0; //Alpha + n_stops[count - 1] = (float) INT_MAX; //should be large enough. + break; + case PIXMAN_REPEAT_NORMAL: + REPEAT_FILL_STOPS(0, count - 2); + n_stops[0] = n_stops[count - 2] - 1.0; + + REPEAT_FILL_STOPS(count - 1, 1); + n_stops[count - 1] = n_stops[1] + 1.0; + break; + case PIXMAN_REPEAT_REFLECT: + REPEAT_FILL_STOPS(0, 1); + n_stops[0] = -n_stops[1]; + + REPEAT_FILL_STOPS(count - 1, count - 2); + n_stops[count - 1] = 1.0 + 1.0 - n_stops[count - 2]; + break; + case PIXMAN_REPEAT_PAD: + REPEAT_FILL_STOPS(0, 1); + n_stops[0] = -(float) INT_MAX; + + REPEAT_FILL_STOPS(count - 1, count - 2); + n_stops[count - 1] = (float) INT_MAX; + break; #undef REPEAT_FILL_STOPS - } + } - for (i = 0; i < count; i++) { - DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n", - i, n_stops[i], - stop_colors[i*4], stop_colors[i*4+1], - stop_colors[i*4+2], stop_colors[i*4+3]); - } + for (i = 0; i < count; i++) { + DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n", + i, n_stops[i], + stop_colors[i * 4], stop_colors[i * 4 + 1], + stop_colors[i * 4 + 2], stop_colors[i * 4 + 3]); + } - return count; + return count; } PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen, - PicturePtr src_picture, - int x_source, int y_source, - int width, int height, - PictFormatShort format) + PicturePtr src_picture, + int x_source, int y_source, + int width, int height, + PictFormatShort format) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - PicturePtr dst_picture = NULL; - PixmapPtr pixmap = NULL; - GLint gradient_prog = 0; - int error; - float tex_vertices[8]; - int stops_count = 0; - int count = 0; - GLfloat *stop_colors = NULL; - GLfloat *n_stops = NULL; - GLfloat xscale, yscale; - float vertices[8]; - float transform_mat[3][3]; - static const float identity_mat[3][3] = {{1.0, 0.0, 0.0}, - {0.0, 1.0, 0.0}, - {0.0, 0.0, 1.0}}; - GLfloat stop_colors_st[RADIAL_SMALL_STOPS*4]; - GLfloat n_stops_st[RADIAL_SMALL_STOPS]; - GLfloat A_value; - GLfloat cxy[4]; - float c1x, c1y, c2x, c2y, r1, r2; - - GLint transform_mat_uniform_location = 0; - GLint repeat_type_uniform_location = 0; - GLint n_stop_uniform_location = 0; - GLint stops_uniform_location = 0; - GLint stop_colors_uniform_location = 0; - GLint stop0_uniform_location = 0; - GLint stop1_uniform_location = 0; - GLint stop2_uniform_location = 0; - GLint stop3_uniform_location = 0; - GLint stop4_uniform_location = 0; - GLint stop5_uniform_location = 0; - GLint stop6_uniform_location = 0; - GLint stop7_uniform_location = 0; - GLint stop_color0_uniform_location = 0; - GLint stop_color1_uniform_location = 0; - GLint stop_color2_uniform_location = 0; - GLint stop_color3_uniform_location = 0; - GLint stop_color4_uniform_location = 0; - GLint stop_color5_uniform_location = 0; - GLint stop_color6_uniform_location = 0; - GLint stop_color7_uniform_location = 0; - GLint A_value_uniform_location = 0; - GLint c1_uniform_location = 0; - GLint r1_uniform_location = 0; - GLint c2_uniform_location = 0; - GLint r2_uniform_location = 0; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - - /* Create a pixmap with VBO. */ - pixmap = glamor_create_pixmap(screen, - width, height, - PIXMAN_FORMAT_DEPTH(format), - 0); - if (!pixmap) - goto GRADIENT_FAIL; - - dst_picture = CreatePicture(0, &pixmap->drawable, - PictureMatchFormat(screen, - PIXMAN_FORMAT_DEPTH(format), format), - 0, 0, serverClient, &error); - - /* Release the reference, picture will hold the last one. */ - glamor_destroy_pixmap(pixmap); - - if (!dst_picture) - goto GRADIENT_FAIL; - - ValidatePicture(dst_picture); - - stops_count = src_picture->pSourcePict->radial.nstops + 2; - - /* Because the max value of nstops is unkown, so create a program - when nstops > LINEAR_LARGE_STOPS.*/ - if (stops_count <= RADIAL_SMALL_STOPS) { - gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0]; - } else if (stops_count <= RADIAL_LARGE_STOPS) { - gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1]; - } else { - _glamor_create_radial_gradient_program(screen, - src_picture->pSourcePict->linear.nstops + 2, - 1); - gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]; - } - - /* Bind all the uniform vars .*/ - transform_mat_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "transform_mat"); - repeat_type_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "repeat_type"); - n_stop_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "n_stop"); - A_value_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "A_value"); - repeat_type_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "repeat_type"); - c1_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "c1"); - r1_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "r1"); - c2_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "c2"); - r2_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "r2"); - - if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) { - stop0_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop0"); - stop1_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop1"); - stop2_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop2"); - stop3_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop3"); - stop4_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop4"); - stop5_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop5"); - stop6_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop6"); - stop7_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop7"); - - stop_color0_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color0"); - stop_color1_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color1"); - stop_color2_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color2"); - stop_color3_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color3"); - stop_color4_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color4"); - stop_color5_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color5"); - stop_color6_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color6"); - stop_color7_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color7"); - } else { - stops_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stops"); - stop_colors_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_colors"); - } - - dispatch->glUseProgram(gradient_prog); - - dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType); - - - if (src_picture->transform) { - _glamor_gradient_convert_trans_matrix(src_picture->transform, - transform_mat, - width, height, 0); - dispatch->glUniformMatrix3fv(transform_mat_uniform_location, - 1, 1, &transform_mat[0][0]); - } else { - dispatch->glUniformMatrix3fv(transform_mat_uniform_location, - 1, 1, &identity_mat[0][0]); - } - - if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture, - &xscale, &yscale, x_source, y_source, - vertices, tex_vertices, 0)) - goto GRADIENT_FAIL; - - /* Set all the stops and colors to shader. */ - if (stops_count > RADIAL_SMALL_STOPS) { - stop_colors = malloc(4 * stops_count * sizeof(float)); - if (stop_colors == NULL) { - ErrorF("Failed to allocate stop_colors memory.\n"); - goto GRADIENT_FAIL; - } - - n_stops = malloc(stops_count * sizeof(float)); - if (n_stops == NULL) { - ErrorF("Failed to allocate n_stops memory.\n"); - goto GRADIENT_FAIL; - } - } else { - stop_colors = stop_colors_st; - n_stops = n_stops_st; - } - - count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient, - stop_colors, n_stops); - - if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) { - int j = 0; - dispatch->glUniform4f(stop_color0_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color1_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color2_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color3_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color4_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color5_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color6_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color7_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - - j = 0; - dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]); - dispatch->glUniform1i(n_stop_uniform_location, count); - } else { - dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors); - dispatch->glUniform1fv(stops_uniform_location, count, n_stops); - dispatch->glUniform1i(n_stop_uniform_location, count); - } - - c1x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x); - c1y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y); - c2x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x); - c2y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y); - - r1 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.radius); - r2 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.radius); - - glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted, cxy); - dispatch->glUniform2fv(c1_uniform_location, 1, cxy); - dispatch->glUniform1f(r1_uniform_location, r1); - - glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted, cxy); - dispatch->glUniform2fv(c2_uniform_location, 1, cxy); - dispatch->glUniform1f(r2_uniform_location, r2); - - A_value = (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 - r1) * (r2 - r1); - dispatch->glUniform1f(A_value_uniform_location, A_value); - - DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n", - c1x, c1y, r1, c2x, c2y, r2, A_value); - - /* Now rendering. */ - dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - /* Do the clear logic.*/ - if (stops_count > RADIAL_SMALL_STOPS) { - free(n_stops); - free(stop_colors); - } - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glUseProgram(0); - - glamor_put_dispatch(glamor_priv); - return dst_picture; - -GRADIENT_FAIL: - if (dst_picture) { - FreePicture(dst_picture, 0); - } - - if (stops_count > RADIAL_SMALL_STOPS) { - if (n_stops) - free(n_stops); - if (stop_colors) - free(stop_colors); - } - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); - return NULL; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + PicturePtr dst_picture = NULL; + PixmapPtr pixmap = NULL; + GLint gradient_prog = 0; + int error; + float tex_vertices[8]; + int stops_count = 0; + int count = 0; + GLfloat *stop_colors = NULL; + GLfloat *n_stops = NULL; + GLfloat xscale, yscale; + float vertices[8]; + float transform_mat[3][3]; + static const float identity_mat[3][3] = { {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0} + }; + GLfloat stop_colors_st[RADIAL_SMALL_STOPS * 4]; + GLfloat n_stops_st[RADIAL_SMALL_STOPS]; + GLfloat A_value; + GLfloat cxy[4]; + float c1x, c1y, c2x, c2y, r1, r2; + + GLint transform_mat_uniform_location = 0; + GLint repeat_type_uniform_location = 0; + GLint n_stop_uniform_location = 0; + GLint stops_uniform_location = 0; + GLint stop_colors_uniform_location = 0; + GLint stop0_uniform_location = 0; + GLint stop1_uniform_location = 0; + GLint stop2_uniform_location = 0; + GLint stop3_uniform_location = 0; + GLint stop4_uniform_location = 0; + GLint stop5_uniform_location = 0; + GLint stop6_uniform_location = 0; + GLint stop7_uniform_location = 0; + GLint stop_color0_uniform_location = 0; + GLint stop_color1_uniform_location = 0; + GLint stop_color2_uniform_location = 0; + GLint stop_color3_uniform_location = 0; + GLint stop_color4_uniform_location = 0; + GLint stop_color5_uniform_location = 0; + GLint stop_color6_uniform_location = 0; + GLint stop_color7_uniform_location = 0; + GLint A_value_uniform_location = 0; + GLint c1_uniform_location = 0; + GLint r1_uniform_location = 0; + GLint c2_uniform_location = 0; + GLint r2_uniform_location = 0; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + + /* Create a pixmap with VBO. */ + pixmap = glamor_create_pixmap(screen, + width, height, + PIXMAN_FORMAT_DEPTH(format), 0); + if (!pixmap) + goto GRADIENT_FAIL; + + dst_picture = CreatePicture(0, &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH(format), + format), 0, 0, serverClient, + &error); + + /* Release the reference, picture will hold the last one. */ + glamor_destroy_pixmap(pixmap); + + if (!dst_picture) + goto GRADIENT_FAIL; + + ValidatePicture(dst_picture); + + stops_count = src_picture->pSourcePict->radial.nstops + 2; + + /* Because the max value of nstops is unkown, so create a program + when nstops > LINEAR_LARGE_STOPS. */ + if (stops_count <= RADIAL_SMALL_STOPS) { + gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0]; + } + else if (stops_count <= RADIAL_LARGE_STOPS) { + gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1]; + } + else { + _glamor_create_radial_gradient_program(screen, + src_picture->pSourcePict->linear. + nstops + 2, 1); + gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]; + } + + /* Bind all the uniform vars . */ + transform_mat_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "transform_mat"); + repeat_type_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "repeat_type"); + n_stop_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "n_stop"); + A_value_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "A_value"); + repeat_type_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "repeat_type"); + c1_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "c1"); + r1_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "r1"); + c2_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "c2"); + r2_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "r2"); + + if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) { + stop0_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop0"); + stop1_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop1"); + stop2_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop2"); + stop3_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop3"); + stop4_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop4"); + stop5_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop5"); + stop6_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop6"); + stop7_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop7"); + + stop_color0_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color0"); + stop_color1_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color1"); + stop_color2_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color2"); + stop_color3_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color3"); + stop_color4_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color4"); + stop_color5_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color5"); + stop_color6_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color6"); + stop_color7_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color7"); + } + else { + stops_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stops"); + stop_colors_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_colors"); + } + + dispatch->glUseProgram(gradient_prog); + + dispatch->glUniform1i(repeat_type_uniform_location, + src_picture->repeatType); + + if (src_picture->transform) { + _glamor_gradient_convert_trans_matrix(src_picture->transform, + transform_mat, width, height, 0); + dispatch->glUniformMatrix3fv(transform_mat_uniform_location, + 1, 1, &transform_mat[0][0]); + } + else { + dispatch->glUniformMatrix3fv(transform_mat_uniform_location, + 1, 1, &identity_mat[0][0]); + } + + if (!_glamor_gradient_set_pixmap_destination + (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source, + vertices, tex_vertices, 0)) + goto GRADIENT_FAIL; + + /* Set all the stops and colors to shader. */ + if (stops_count > RADIAL_SMALL_STOPS) { + stop_colors = malloc(4 * stops_count * sizeof(float)); + if (stop_colors == NULL) { + ErrorF("Failed to allocate stop_colors memory.\n"); + goto GRADIENT_FAIL; + } + + n_stops = malloc(stops_count * sizeof(float)); + if (n_stops == NULL) { + ErrorF("Failed to allocate n_stops memory.\n"); + goto GRADIENT_FAIL; + } + } + else { + stop_colors = stop_colors_st; + n_stops = n_stops_st; + } + + count = + _glamor_gradient_set_stops(src_picture, + &src_picture->pSourcePict->gradient, + stop_colors, n_stops); + + if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) { + int j = 0; + + dispatch->glUniform4f(stop_color0_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color1_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color2_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color3_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color4_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color5_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color6_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color7_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + + j = 0; + dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]); + dispatch->glUniform1i(n_stop_uniform_location, count); + } + else { + dispatch->glUniform4fv(stop_colors_uniform_location, count, + stop_colors); + dispatch->glUniform1fv(stops_uniform_location, count, n_stops); + dispatch->glUniform1i(n_stop_uniform_location, count); + } + + c1x = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x); + c1y = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y); + c2x = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x); + c2y = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y); + + r1 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1. + radius); + r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2. + radius); + + glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted, + cxy); + dispatch->glUniform2fv(c1_uniform_location, 1, cxy); + dispatch->glUniform1f(r1_uniform_location, r1); + + glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted, + cxy); + dispatch->glUniform2fv(c2_uniform_location, 1, cxy); + dispatch->glUniform1f(r2_uniform_location, r2); + + A_value = + (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 - + r1) * (r2 - + r1); + dispatch->glUniform1f(A_value_uniform_location, A_value); + + DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n", + c1x, c1y, r1, c2x, c2y, r2, A_value); + + /* Now rendering. */ + dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + /* Do the clear logic. */ + if (stops_count > RADIAL_SMALL_STOPS) { + free(n_stops); + free(stop_colors); + } + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(0); + + glamor_put_dispatch(glamor_priv); + return dst_picture; + + GRADIENT_FAIL: + if (dst_picture) { + FreePicture(dst_picture, 0); + } + + if (stops_count > RADIAL_SMALL_STOPS) { + if (n_stops) + free(n_stops); + if (stop_colors) + free(stop_colors); + } + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); + return NULL; } PicturePtr glamor_generate_linear_gradient_picture(ScreenPtr screen, - PicturePtr src_picture, - int x_source, int y_source, - int width, int height, - PictFormatShort format) + PicturePtr src_picture, + int x_source, int y_source, + int width, int height, + PictFormatShort format) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - PicturePtr dst_picture = NULL; - PixmapPtr pixmap = NULL; - GLint gradient_prog = 0; - int error; - float pt_distance; - float p1_distance; - GLfloat cos_val; - float tex_vertices[8]; - int stops_count = 0; - GLfloat *stop_colors = NULL; - GLfloat *n_stops = NULL; - int count = 0; - float slope; - GLfloat xscale, yscale; - GLfloat pt1[2], pt2[2]; - float vertices[8]; - float transform_mat[3][3]; - static const float identity_mat[3][3] = {{1.0, 0.0, 0.0}, - {0.0, 1.0, 0.0}, - {0.0, 0.0, 1.0}}; - GLfloat stop_colors_st[LINEAR_SMALL_STOPS*4]; - GLfloat n_stops_st[LINEAR_SMALL_STOPS]; - - GLint transform_mat_uniform_location = 0; - GLint n_stop_uniform_location = 0; - GLint stops_uniform_location = 0; - GLint stop0_uniform_location = 0; - GLint stop1_uniform_location = 0; - GLint stop2_uniform_location = 0; - GLint stop3_uniform_location = 0; - GLint stop4_uniform_location = 0; - GLint stop5_uniform_location = 0; - GLint stop6_uniform_location = 0; - GLint stop7_uniform_location = 0; - GLint stop_colors_uniform_location = 0; - GLint stop_color0_uniform_location = 0; - GLint stop_color1_uniform_location = 0; - GLint stop_color2_uniform_location = 0; - GLint stop_color3_uniform_location = 0; - GLint stop_color4_uniform_location = 0; - GLint stop_color5_uniform_location = 0; - GLint stop_color6_uniform_location = 0; - GLint stop_color7_uniform_location = 0; - GLint pt_slope_uniform_location = 0; - GLint repeat_type_uniform_location = 0; - GLint hor_ver_uniform_location = 0; - GLint cos_val_uniform_location = 0; - GLint p1_distance_uniform_location = 0; - GLint pt_distance_uniform_location = 0; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - - /* Create a pixmap with VBO. */ - pixmap = glamor_create_pixmap(screen, - width, height, - PIXMAN_FORMAT_DEPTH(format), - 0); - - if (!pixmap) - goto GRADIENT_FAIL; - - dst_picture = CreatePicture(0, &pixmap->drawable, - PictureMatchFormat(screen, - PIXMAN_FORMAT_DEPTH(format), format), - 0, 0, serverClient, &error); - - /* Release the reference, picture will hold the last one. */ - glamor_destroy_pixmap(pixmap); - - if (!dst_picture) - goto GRADIENT_FAIL; - - ValidatePicture(dst_picture); - - stops_count = src_picture->pSourcePict->linear.nstops + 2; - - /* Because the max value of nstops is unkown, so create a program - when nstops > LINEAR_LARGE_STOPS.*/ - if (stops_count <= LINEAR_SMALL_STOPS) { - gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0]; - } else if (stops_count <= LINEAR_LARGE_STOPS) { - gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1]; - } else { - _glamor_create_linear_gradient_program(screen, - src_picture->pSourcePict->linear.nstops + 2, 1); - gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]; - } - - /* Bind all the uniform vars .*/ - n_stop_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "n_stop"); - pt_slope_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "pt_slope"); - repeat_type_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "repeat_type"); - hor_ver_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "hor_ver"); - transform_mat_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "transform_mat"); - cos_val_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "cos_val"); - p1_distance_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "p1_distance"); - pt_distance_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "pt_distance"); - - if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) { - stop0_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop0"); - stop1_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop1"); - stop2_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop2"); - stop3_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop3"); - stop4_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop4"); - stop5_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop5"); - stop6_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop6"); - stop7_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop7"); - - stop_color0_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color0"); - stop_color1_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color1"); - stop_color2_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color2"); - stop_color3_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color3"); - stop_color4_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color4"); - stop_color5_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color5"); - stop_color6_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color6"); - stop_color7_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_color7"); - } else { - stops_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stops"); - stop_colors_uniform_location = - dispatch->glGetUniformLocation(gradient_prog, "stop_colors"); - } - - dispatch->glUseProgram(gradient_prog); - - dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType); - - /* set the transform matrix. */ - if (src_picture->transform) { - _glamor_gradient_convert_trans_matrix(src_picture->transform, - transform_mat, - width, height, 1); - dispatch->glUniformMatrix3fv(transform_mat_uniform_location, - 1, 1, &transform_mat[0][0]); - } else { - dispatch->glUniformMatrix3fv(transform_mat_uniform_location, - 1, 1, &identity_mat[0][0]); - } - - if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture, - &xscale, &yscale, x_source, y_source, - vertices, tex_vertices, 1)) - goto GRADIENT_FAIL; - - /* Normalize the PTs. */ - glamor_set_normalize_pt(xscale, yscale, - pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x), - pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y), - glamor_priv->yInverted, - 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), pt1[0], pt1[1]); - - glamor_set_normalize_pt(xscale, yscale, - pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x), - pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y), - glamor_priv->yInverted, - 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), pt2[0], pt2[1]); - - /* Set all the stops and colors to shader. */ - if (stops_count > LINEAR_SMALL_STOPS) { - stop_colors = malloc(4 * stops_count * sizeof(float)); - if (stop_colors == NULL) { - ErrorF("Failed to allocate stop_colors memory.\n"); - goto GRADIENT_FAIL; - } - - n_stops = malloc(stops_count * sizeof(float)); - if (n_stops == NULL) { - ErrorF("Failed to allocate n_stops memory.\n"); - goto GRADIENT_FAIL; - } - } else { - stop_colors = stop_colors_st; - n_stops = n_stops_st; - } - - count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient, - stop_colors, n_stops); - - if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) { - int j = 0; - dispatch->glUniform4f(stop_color0_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color1_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color2_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color3_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color4_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color5_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color6_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - j++; - dispatch->glUniform4f(stop_color7_uniform_location, - stop_colors[4*j+0], stop_colors[4*j+1], - stop_colors[4*j+2], stop_colors[4*j+3]); - - j = 0; - dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]); - dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]); - - dispatch->glUniform1i(n_stop_uniform_location, count); - } else { - dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors); - dispatch->glUniform1fv(stops_uniform_location, count, n_stops); - dispatch->glUniform1i(n_stop_uniform_location, count); - } - - if (src_picture->pSourcePict->linear.p2.y == - src_picture->pSourcePict->linear.p1.y) { // The horizontal case. - dispatch->glUniform1i(hor_ver_uniform_location, 1); - DEBUGF("p1.y: %f, p2.y: %f, enter the horizontal case\n", - pt1[1], pt2[1]); - - p1_distance = pt1[0]; - pt_distance = (pt2[0] - p1_distance); - dispatch->glUniform1f(p1_distance_uniform_location, p1_distance); - dispatch->glUniform1f(pt_distance_uniform_location, pt_distance); - } else { - /* The slope need to compute here. In shader, the viewport set will change - the orginal slope and the slope which is vertical to it will not be correct.*/ - slope = - (float)(src_picture->pSourcePict->linear.p2.x - - src_picture->pSourcePict->linear.p1.x) / - (float)(src_picture->pSourcePict->linear.p2.y - - src_picture->pSourcePict->linear.p1.y); - slope = slope * yscale / xscale; - dispatch->glUniform1f(pt_slope_uniform_location, slope); - dispatch->glUniform1i(hor_ver_uniform_location, 0); - - cos_val = sqrt(1.0 / (slope * slope + 1.0)); - dispatch->glUniform1f(cos_val_uniform_location, cos_val); - - p1_distance = (pt1[1] - pt1[0] * slope) * cos_val; - pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance; - dispatch->glUniform1f(p1_distance_uniform_location, p1_distance); - dispatch->glUniform1f(pt_distance_uniform_location, pt_distance); - } - - /* Now rendering. */ - dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - /* Do the clear logic.*/ - if (stops_count > LINEAR_SMALL_STOPS) { - free(n_stops); - free(stop_colors); - } - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glUseProgram(0); - - glamor_put_dispatch(glamor_priv); - return dst_picture; - -GRADIENT_FAIL: - if (dst_picture) { - FreePicture(dst_picture, 0); - } - - if (stops_count > LINEAR_SMALL_STOPS) { - if (n_stops) - free(n_stops); - if (stop_colors) - free(stop_colors); - } - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); - return NULL; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + PicturePtr dst_picture = NULL; + PixmapPtr pixmap = NULL; + GLint gradient_prog = 0; + int error; + float pt_distance; + float p1_distance; + GLfloat cos_val; + float tex_vertices[8]; + int stops_count = 0; + GLfloat *stop_colors = NULL; + GLfloat *n_stops = NULL; + int count = 0; + float slope; + GLfloat xscale, yscale; + GLfloat pt1[2], pt2[2]; + float vertices[8]; + float transform_mat[3][3]; + static const float identity_mat[3][3] = { {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0} + }; + GLfloat stop_colors_st[LINEAR_SMALL_STOPS * 4]; + GLfloat n_stops_st[LINEAR_SMALL_STOPS]; + + GLint transform_mat_uniform_location = 0; + GLint n_stop_uniform_location = 0; + GLint stops_uniform_location = 0; + GLint stop0_uniform_location = 0; + GLint stop1_uniform_location = 0; + GLint stop2_uniform_location = 0; + GLint stop3_uniform_location = 0; + GLint stop4_uniform_location = 0; + GLint stop5_uniform_location = 0; + GLint stop6_uniform_location = 0; + GLint stop7_uniform_location = 0; + GLint stop_colors_uniform_location = 0; + GLint stop_color0_uniform_location = 0; + GLint stop_color1_uniform_location = 0; + GLint stop_color2_uniform_location = 0; + GLint stop_color3_uniform_location = 0; + GLint stop_color4_uniform_location = 0; + GLint stop_color5_uniform_location = 0; + GLint stop_color6_uniform_location = 0; + GLint stop_color7_uniform_location = 0; + GLint pt_slope_uniform_location = 0; + GLint repeat_type_uniform_location = 0; + GLint hor_ver_uniform_location = 0; + GLint cos_val_uniform_location = 0; + GLint p1_distance_uniform_location = 0; + GLint pt_distance_uniform_location = 0; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + + /* Create a pixmap with VBO. */ + pixmap = glamor_create_pixmap(screen, + width, height, + PIXMAN_FORMAT_DEPTH(format), 0); + + if (!pixmap) + goto GRADIENT_FAIL; + + dst_picture = CreatePicture(0, &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH(format), + format), 0, 0, serverClient, + &error); + + /* Release the reference, picture will hold the last one. */ + glamor_destroy_pixmap(pixmap); + + if (!dst_picture) + goto GRADIENT_FAIL; + + ValidatePicture(dst_picture); + + stops_count = src_picture->pSourcePict->linear.nstops + 2; + + /* Because the max value of nstops is unkown, so create a program + when nstops > LINEAR_LARGE_STOPS. */ + if (stops_count <= LINEAR_SMALL_STOPS) { + gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0]; + } + else if (stops_count <= LINEAR_LARGE_STOPS) { + gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1]; + } + else { + _glamor_create_linear_gradient_program(screen, + src_picture->pSourcePict->linear. + nstops + 2, 1); + gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]; + } + + /* Bind all the uniform vars . */ + n_stop_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "n_stop"); + pt_slope_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "pt_slope"); + repeat_type_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "repeat_type"); + hor_ver_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "hor_ver"); + transform_mat_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "transform_mat"); + cos_val_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "cos_val"); + p1_distance_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "p1_distance"); + pt_distance_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "pt_distance"); + + if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) { + stop0_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop0"); + stop1_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop1"); + stop2_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop2"); + stop3_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop3"); + stop4_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop4"); + stop5_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop5"); + stop6_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop6"); + stop7_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop7"); + + stop_color0_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color0"); + stop_color1_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color1"); + stop_color2_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color2"); + stop_color3_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color3"); + stop_color4_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color4"); + stop_color5_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color5"); + stop_color6_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color6"); + stop_color7_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_color7"); + } + else { + stops_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stops"); + stop_colors_uniform_location = + dispatch->glGetUniformLocation(gradient_prog, "stop_colors"); + } + + dispatch->glUseProgram(gradient_prog); + + dispatch->glUniform1i(repeat_type_uniform_location, + src_picture->repeatType); + + /* set the transform matrix. */ + if (src_picture->transform) { + _glamor_gradient_convert_trans_matrix(src_picture->transform, + transform_mat, width, height, 1); + dispatch->glUniformMatrix3fv(transform_mat_uniform_location, + 1, 1, &transform_mat[0][0]); + } + else { + dispatch->glUniformMatrix3fv(transform_mat_uniform_location, + 1, 1, &identity_mat[0][0]); + } + + if (!_glamor_gradient_set_pixmap_destination + (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source, + vertices, tex_vertices, 1)) + goto GRADIENT_FAIL; + + /* Normalize the PTs. */ + glamor_set_normalize_pt(xscale, yscale, + pixman_fixed_to_double(src_picture->pSourcePict-> + linear.p1.x), + pixman_fixed_to_double(src_picture->pSourcePict-> + linear.p1.y), + glamor_priv->yInverted, 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), + pt1[0], pt1[1]); + + glamor_set_normalize_pt(xscale, yscale, + pixman_fixed_to_double(src_picture->pSourcePict-> + linear.p2.x), + pixman_fixed_to_double(src_picture->pSourcePict-> + linear.p2.y), + glamor_priv->yInverted, 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), + pt2[0], pt2[1]); + + /* Set all the stops and colors to shader. */ + if (stops_count > LINEAR_SMALL_STOPS) { + stop_colors = malloc(4 * stops_count * sizeof(float)); + if (stop_colors == NULL) { + ErrorF("Failed to allocate stop_colors memory.\n"); + goto GRADIENT_FAIL; + } + + n_stops = malloc(stops_count * sizeof(float)); + if (n_stops == NULL) { + ErrorF("Failed to allocate n_stops memory.\n"); + goto GRADIENT_FAIL; + } + } + else { + stop_colors = stop_colors_st; + n_stops = n_stops_st; + } + + count = + _glamor_gradient_set_stops(src_picture, + &src_picture->pSourcePict->gradient, + stop_colors, n_stops); + + if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) { + int j = 0; + + dispatch->glUniform4f(stop_color0_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color1_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color2_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color3_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color4_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color5_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color6_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + j++; + dispatch->glUniform4f(stop_color7_uniform_location, + stop_colors[4 * j + 0], stop_colors[4 * j + 1], + stop_colors[4 * j + 2], stop_colors[4 * j + 3]); + + j = 0; + dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]); + dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]); + + dispatch->glUniform1i(n_stop_uniform_location, count); + } + else { + dispatch->glUniform4fv(stop_colors_uniform_location, count, + stop_colors); + dispatch->glUniform1fv(stops_uniform_location, count, n_stops); + dispatch->glUniform1i(n_stop_uniform_location, count); + } + + if (src_picture->pSourcePict->linear.p2.y == src_picture->pSourcePict->linear.p1.y) { // The horizontal case. + dispatch->glUniform1i(hor_ver_uniform_location, 1); + DEBUGF("p1.y: %f, p2.y: %f, enter the horizontal case\n", + pt1[1], pt2[1]); + + p1_distance = pt1[0]; + pt_distance = (pt2[0] - p1_distance); + dispatch->glUniform1f(p1_distance_uniform_location, p1_distance); + dispatch->glUniform1f(pt_distance_uniform_location, pt_distance); + } + else { + /* The slope need to compute here. In shader, the viewport set will change + the orginal slope and the slope which is vertical to it will not be correct. */ + slope = -(float) (src_picture->pSourcePict->linear.p2.x + - src_picture->pSourcePict->linear.p1.x) / + (float) (src_picture->pSourcePict->linear.p2.y + - src_picture->pSourcePict->linear.p1.y); + slope = slope * yscale / xscale; + dispatch->glUniform1f(pt_slope_uniform_location, slope); + dispatch->glUniform1i(hor_ver_uniform_location, 0); + + cos_val = sqrt(1.0 / (slope * slope + 1.0)); + dispatch->glUniform1f(cos_val_uniform_location, cos_val); + + p1_distance = (pt1[1] - pt1[0] * slope) * cos_val; + pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance; + dispatch->glUniform1f(p1_distance_uniform_location, p1_distance); + dispatch->glUniform1f(pt_distance_uniform_location, pt_distance); + } + + /* Now rendering. */ + dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + /* Do the clear logic. */ + if (stops_count > LINEAR_SMALL_STOPS) { + free(n_stops); + free(stop_colors); + } + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(0); + + glamor_put_dispatch(glamor_priv); + return dst_picture; + + GRADIENT_FAIL: + if (dst_picture) { + FreePicture(dst_picture, 0); + } + + if (stops_count > LINEAR_SMALL_STOPS) { + if (n_stops) + free(n_stops); + if (stop_colors) + free(stop_colors); + } + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); + return NULL; } -#endif /* End of GLAMOR_GRADIENT_SHADER */ +#endif /* End of GLAMOR_GRADIENT_SHADER */ -#endif /* End of RENDER */ +#endif /* End of RENDER */ diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c index 91ee8f2..b9c140b 100644 --- a/glamor/glamor_largepixmap.c +++ b/glamor/glamor_largepixmap.c @@ -17,117 +17,117 @@ static glamor_pixmap_clipped_regions * __glamor_compute_clipped_regions(int block_w, - int block_h, - int block_stride, - int x, int y, - int w, int h, - RegionPtr region, - int *n_region, - int reverse, - int upsidedown) + int block_h, + int block_stride, + int x, int y, + int w, int h, + RegionPtr region, + int *n_region, int reverse, int upsidedown) { - glamor_pixmap_clipped_regions * clipped_regions; - BoxPtr extent; - int start_x, start_y, end_x, end_y; - int start_block_x, start_block_y; - int end_block_x, end_block_y; - int loop_start_block_x, loop_start_block_y; - int loop_end_block_x, loop_end_block_y; - int loop_block_stride; - int i, j, delta_i, delta_j; - RegionRec temp_region; - RegionPtr current_region; - int block_idx; - int k = 0; - int temp_block_idx; - - extent = RegionExtents(region); - start_x = MAX(x, extent->x1); - start_y = MAX(y, extent->y1); - end_x = MIN(x + w, extent->x2); - end_y = MIN(y + h, extent->y2); - - DEBUGF("start compute clipped regions:\n"); - DEBUGF("block w %d h %d x %d y %d w %d h %d, block_stride %d \n", - block_w, block_h, x, y, w, h, block_stride); - DEBUGRegionPrint(region); - - DEBUGF("start_x %d start_y %d end_x %d end_y %d \n", start_x, start_y, end_x, end_y); - - if (start_x >= end_x || start_y >= end_y) { - *n_region = 0; - return NULL; - } - - start_block_x = (start_x - x)/ block_w; - start_block_y = (start_y - y)/ block_h; - end_block_x = (end_x - x)/ block_w; - end_block_y = (end_y - y)/ block_h; - - clipped_regions = calloc((end_block_x - start_block_x + 1) - * (end_block_y - start_block_y + 1), - sizeof(*clipped_regions)); - - - DEBUGF("startx %d starty %d endx %d endy %d \n", - start_x, start_y, end_x, end_y); - DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x); - DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y); - - if (!reverse) { - loop_start_block_x = start_block_x; - loop_end_block_x = end_block_x + 1; - delta_i = 1; - } else { - loop_start_block_x = end_block_x; - loop_end_block_x = start_block_x - 1; - delta_i = -1; - } - - if (!upsidedown) { - loop_start_block_y = start_block_y; - loop_end_block_y = end_block_y + 1; - delta_j = 1; - } else { - loop_start_block_y = end_block_y; - loop_end_block_y = start_block_y - 1; - delta_j = -1; - } - - loop_block_stride = delta_j * block_stride; - block_idx = (loop_start_block_y - delta_j) * block_stride; - - for(j = loop_start_block_y; j != loop_end_block_y; j += delta_j) - { - block_idx += loop_block_stride; - temp_block_idx = block_idx + loop_start_block_x; - for(i = loop_start_block_x; - i != loop_end_block_x; i += delta_i, temp_block_idx += delta_i) - { - BoxRec temp_box; - temp_box.x1 = x + i * block_w; - temp_box.y1 = y + j * block_h; - temp_box.x2 = MIN(temp_box.x1 + block_w, end_x); - temp_box.y2 = MIN(temp_box.y1 + block_h, end_y); - RegionInitBoxes(&temp_region, &temp_box, 1); - DEBUGF("block idx %d \n",temp_block_idx); - DEBUGRegionPrint(&temp_region); - current_region = RegionCreate(NULL, 4); - RegionIntersect(current_region, &temp_region, region); - DEBUGF("i %d j %d region: \n",i ,j); - DEBUGRegionPrint(current_region); - if (RegionNumRects(current_region)) { - clipped_regions[k].region = current_region; - clipped_regions[k].block_idx = temp_block_idx; - k++; - } else - RegionDestroy(current_region); - RegionUninit(&temp_region); - } - } - - *n_region = k; - return clipped_regions; + glamor_pixmap_clipped_regions *clipped_regions; + BoxPtr extent; + int start_x, start_y, end_x, end_y; + int start_block_x, start_block_y; + int end_block_x, end_block_y; + int loop_start_block_x, loop_start_block_y; + int loop_end_block_x, loop_end_block_y; + int loop_block_stride; + int i, j, delta_i, delta_j; + RegionRec temp_region; + RegionPtr current_region; + int block_idx; + int k = 0; + int temp_block_idx; + + extent = RegionExtents(region); + start_x = MAX(x, extent->x1); + start_y = MAX(y, extent->y1); + end_x = MIN(x + w, extent->x2); + end_y = MIN(y + h, extent->y2); + + DEBUGF("start compute clipped regions:\n"); + DEBUGF("block w %d h %d x %d y %d w %d h %d, block_stride %d \n", + block_w, block_h, x, y, w, h, block_stride); + DEBUGRegionPrint(region); + + DEBUGF("start_x %d start_y %d end_x %d end_y %d \n", start_x, start_y, + end_x, end_y); + + if (start_x >= end_x || start_y >= end_y) { + *n_region = 0; + return NULL; + } + + start_block_x = (start_x - x) / block_w; + start_block_y = (start_y - y) / block_h; + end_block_x = (end_x - x) / block_w; + end_block_y = (end_y - y) / block_h; + + clipped_regions = calloc((end_block_x - start_block_x + 1) + * (end_block_y - start_block_y + 1), + sizeof(*clipped_regions)); + + DEBUGF("startx %d starty %d endx %d endy %d \n", + start_x, start_y, end_x, end_y); + DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x); + DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y); + + if (!reverse) { + loop_start_block_x = start_block_x; + loop_end_block_x = end_block_x + 1; + delta_i = 1; + } + else { + loop_start_block_x = end_block_x; + loop_end_block_x = start_block_x - 1; + delta_i = -1; + } + + if (!upsidedown) { + loop_start_block_y = start_block_y; + loop_end_block_y = end_block_y + 1; + delta_j = 1; + } + else { + loop_start_block_y = end_block_y; + loop_end_block_y = start_block_y - 1; + delta_j = -1; + } + + loop_block_stride = delta_j * block_stride; + block_idx = (loop_start_block_y - delta_j) * block_stride; + + for (j = loop_start_block_y; j != loop_end_block_y; j += delta_j) { + block_idx += loop_block_stride; + temp_block_idx = block_idx + loop_start_block_x; + for (i = loop_start_block_x; + i != loop_end_block_x; i += delta_i, temp_block_idx += delta_i) { + BoxRec temp_box; + + temp_box.x1 = x + i * block_w; + temp_box.y1 = y + j * block_h; + temp_box.x2 = MIN(temp_box.x1 + block_w, end_x); + temp_box.y2 = MIN(temp_box.y1 + block_h, end_y); + RegionInitBoxes(&temp_region, &temp_box, 1); + DEBUGF("block idx %d \n", temp_block_idx); + DEBUGRegionPrint(&temp_region); + current_region = RegionCreate(NULL, 4); + RegionIntersect(current_region, &temp_region, region); + DEBUGF("i %d j %d region: \n", i, j); + DEBUGRegionPrint(current_region); + if (RegionNumRects(current_region)) { + clipped_regions[k].region = current_region; + clipped_regions[k].block_idx = temp_block_idx; + k++; + } + else + RegionDestroy(current_region); + RegionUninit(&temp_region); + } + } + + *n_region = k; + return clipped_regions; } /** @@ -144,83 +144,88 @@ __glamor_compute_clipped_regions(int block_w, */ glamor_pixmap_clipped_regions * -glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv, - RegionPtr region, - int *n_region, - int inner_block_w, int inner_block_h, - int reverse, int upsidedown) +glamor_compute_clipped_regions_ext(glamor_pixmap_private * pixmap_priv, + RegionPtr region, + int *n_region, + int inner_block_w, int inner_block_h, + int reverse, int upsidedown) { - glamor_pixmap_clipped_regions * clipped_regions, *inner_regions, *result_regions; - int i, j, x, y, k, inner_n_regions; - int width, height; - glamor_pixmap_private_large_t *priv; - priv = &pixmap_priv->large; - - DEBUGF("ext called \n"); - - if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { - clipped_regions = calloc(1, sizeof(*clipped_regions)); - if (clipped_regions == NULL) { - *n_region = 0; - return NULL; - } - clipped_regions[0].region = RegionCreate(NULL, 1); - clipped_regions[0].block_idx = 0; - RegionCopy(clipped_regions[0].region, region); - *n_region = 1; - priv->block_w = priv->base.pixmap->drawable.width; - priv->block_h = priv->base.pixmap->drawable.height; - priv->box_array = &priv->box; - priv->box.x1 = priv->box.y1 = 0; - priv->box.x2 = priv->block_w; - priv->box.y2 = priv->block_h; - } else { - clipped_regions = __glamor_compute_clipped_regions(priv->block_w, - priv->block_h, - priv->block_wcnt, - 0, 0, - priv->base.pixmap->drawable.width, - priv->base.pixmap->drawable.height, - region, n_region, reverse, upsidedown - ); - - if (clipped_regions == NULL) { - *n_region = 0; - return NULL; - } - } - if (inner_block_w >= priv->block_w - && inner_block_h >= priv->block_h) - return clipped_regions; - result_regions = calloc(*n_region - * ((priv->block_w + inner_block_w - 1)/inner_block_w) - * ((priv->block_h + inner_block_h - 1)/ inner_block_h), - sizeof(*result_regions)); - k = 0; - for(i = 0; i < *n_region; i++) - { - x = priv->box_array[clipped_regions[i].block_idx].x1; - y = priv->box_array[clipped_regions[i].block_idx].y1; - width = priv->box_array[clipped_regions[i].block_idx].x2 - x; - height = priv->box_array[clipped_regions[i].block_idx].y2 - y; - inner_regions = __glamor_compute_clipped_regions(inner_block_w, - inner_block_h, - 0, x, y, - width, - height, - clipped_regions[i].region, - &inner_n_regions, reverse, upsidedown); - for(j = 0; j < inner_n_regions; j++) - { - result_regions[k].region = inner_regions[j].region; - result_regions[k].block_idx = clipped_regions[i].block_idx; - k++; - } - free(inner_regions); - } - *n_region = k; - free(clipped_regions); - return result_regions; + glamor_pixmap_clipped_regions *clipped_regions, *inner_regions, + *result_regions; + int i, j, x, y, k, inner_n_regions; + int width, height; + glamor_pixmap_private_large_t *priv; + + priv = &pixmap_priv->large; + + DEBUGF("ext called \n"); + + if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { + clipped_regions = calloc(1, sizeof(*clipped_regions)); + if (clipped_regions == NULL) { + *n_region = 0; + return NULL; + } + clipped_regions[0].region = RegionCreate(NULL, 1); + clipped_regions[0].block_idx = 0; + RegionCopy(clipped_regions[0].region, region); + *n_region = 1; + priv->block_w = priv->base.pixmap->drawable.width; + priv->block_h = priv->base.pixmap->drawable.height; + priv->box_array = &priv->box; + priv->box.x1 = priv->box.y1 = 0; + priv->box.x2 = priv->block_w; + priv->box.y2 = priv->block_h; + } + else { + clipped_regions = __glamor_compute_clipped_regions(priv->block_w, + priv->block_h, + priv->block_wcnt, + 0, 0, + priv->base.pixmap-> + drawable.width, + priv->base.pixmap-> + drawable.height, + region, n_region, + reverse, upsidedown); + + if (clipped_regions == NULL) { + *n_region = 0; + return NULL; + } + } + if (inner_block_w >= priv->block_w && inner_block_h >= priv->block_h) + return clipped_regions; + result_regions = calloc(*n_region + * ((priv->block_w + inner_block_w - 1) / + inner_block_w) + * ((priv->block_h + inner_block_h - 1) / + inner_block_h), sizeof(*result_regions)); + k = 0; + for (i = 0; i < *n_region; i++) { + x = priv->box_array[clipped_regions[i].block_idx].x1; + y = priv->box_array[clipped_regions[i].block_idx].y1; + width = priv->box_array[clipped_regions[i].block_idx].x2 - x; + height = priv->box_array[clipped_regions[i].block_idx].y2 - y; + inner_regions = __glamor_compute_clipped_regions(inner_block_w, + inner_block_h, + 0, x, y, + width, + height, + clipped_regions[i]. + region, + &inner_n_regions, + reverse, upsidedown); + for (j = 0; j < inner_n_regions; j++) { + result_regions[k].region = inner_regions[j].region; + result_regions[k].block_idx = clipped_regions[i].block_idx; + k++; + } + free(inner_regions); + } + *n_region = k; + free(clipped_regions); + return result_regions; } /* @@ -232,35 +237,36 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv, static RegionPtr _glamor_convert_pad_region(RegionPtr region, int w, int h) { - RegionPtr pad_region; - int nrect; - BoxPtr box; - int overlap; - - nrect = RegionNumRects(region); - box = RegionRects(region); - pad_region = RegionCreate(NULL, 4); - if (pad_region == NULL) - return NULL; - while(nrect--) { - BoxRec pad_box; - RegionRec temp_region; - pad_box = *box; - if (pad_box.x1 < 0 && pad_box.x2 <= 0) - pad_box.x2 = 1; - else if (pad_box.x1 >= w && pad_box.x2 > w) - pad_box.x1 = w - 1; - if (pad_box.y1 < 0 && pad_box.y2 <=0) - pad_box.y2 = 1; - else if (pad_box.y1 >= h && pad_box.y2 > h) - pad_box.y1 = h - 1; - RegionInitBoxes(&temp_region, &pad_box, 1); - RegionAppend(pad_region, &temp_region); - RegionUninit(&temp_region); - box++; - } - RegionValidate(pad_region, &overlap); - return pad_region; + RegionPtr pad_region; + int nrect; + BoxPtr box; + int overlap; + + nrect = RegionNumRects(region); + box = RegionRects(region); + pad_region = RegionCreate(NULL, 4); + if (pad_region == NULL) + return NULL; + while (nrect--) { + BoxRec pad_box; + RegionRec temp_region; + + pad_box = *box; + if (pad_box.x1 < 0 && pad_box.x2 <= 0) + pad_box.x2 = 1; + else if (pad_box.x1 >= w && pad_box.x2 > w) + pad_box.x1 = w - 1; + if (pad_box.y1 < 0 && pad_box.y2 <= 0) + pad_box.y2 = 1; + else if (pad_box.y1 >= h && pad_box.y2 > h) + pad_box.y1 = h - 1; + RegionInitBoxes(&temp_region, &pad_box, 1); + RegionAppend(pad_region, &temp_region); + RegionUninit(&temp_region); + box++; + } + RegionValidate(pad_region, &overlap); + return pad_region; } /* @@ -278,32 +284,35 @@ _glamor_convert_pad_region(RegionPtr region, int w, int h) static void _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh) { - int odd1, odd2; - int c1, c2; - - if (*xy2 - *xy1 > wh) { - *xy1 = 0; - *xy2 = wh; - return; - } - modulus(*xy1, wh, c1); - odd1 = ((*xy1 - c1) / wh) & 0x1; - modulus(*xy2, wh, c2); - odd2 = ((*xy2 - c2) / wh) & 0x1; - - if (odd1 && odd2) { - *xy1 = wh - c2; - *xy2 = wh - c1; - } else if (odd1 && !odd2) { - *xy1 = 0; - *xy2 = MAX(c2, wh - c1); - } else if (!odd1 && odd2) { - *xy2 = wh; - *xy1 = MIN(c1, wh - c2); - } else { - *xy1 = c1; - *xy2 = c2; - } + int odd1, odd2; + int c1, c2; + + if (*xy2 - *xy1 > wh) { + *xy1 = 0; + *xy2 = wh; + return; + } + modulus(*xy1, wh, c1); + odd1 = ((*xy1 - c1) / wh) & 0x1; + modulus(*xy2, wh, c2); + odd2 = ((*xy2 - c2) / wh) & 0x1; + + if (odd1 && odd2) { + *xy1 = wh - c2; + *xy2 = wh - c1; + } + else if (odd1 && !odd2) { + *xy1 = 0; + *xy2 = MAX(c2, wh - c1); + } + else if (!odd1 && odd2) { + *xy2 = wh; + *xy1 = MIN(c1, wh - c2); + } + else { + *xy1 = c1; + *xy2 = c2; + } } /** @@ -316,367 +325,405 @@ _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh) * */ static glamor_pixmap_clipped_regions * -_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv, - RegionPtr region, int *n_region, - int repeat_type, int is_transform, - int reverse, int upsidedown) +_glamor_compute_clipped_regions(glamor_pixmap_private * pixmap_priv, + RegionPtr region, int *n_region, + int repeat_type, int is_transform, + int reverse, int upsidedown) { - glamor_pixmap_clipped_regions * clipped_regions; - BoxPtr extent; - int i, j; - RegionPtr current_region; - int pixmap_width, pixmap_height; - int m; - BoxRec repeat_box; - RegionRec repeat_region; - int right_shift = 0; - int down_shift = 0; - int x_center_shift = 0, y_center_shift = 0; - glamor_pixmap_private_large_t *priv; - priv = &pixmap_priv->large; - - DEBUGRegionPrint(region); - if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { - clipped_regions = calloc(1, sizeof(*clipped_regions)); - clipped_regions[0].region = RegionCreate(NULL, 1); - clipped_regions[0].block_idx = 0; - RegionCopy(clipped_regions[0].region, region); - *n_region = 1; - return clipped_regions; - } - - pixmap_width = priv->base.pixmap->drawable.width; - pixmap_height = priv->base.pixmap->drawable.height; - if (repeat_type == 0 || repeat_type == RepeatPad) { - RegionPtr saved_region = NULL; - if (repeat_type == RepeatPad) { - saved_region = region; - region = _glamor_convert_pad_region(saved_region, pixmap_width, pixmap_height); - if (region == NULL) { - *n_region = 0; - return NULL; - } - } - clipped_regions = __glamor_compute_clipped_regions(priv->block_w, - priv->block_h, - priv->block_wcnt, - 0, 0, - priv->base.pixmap->drawable.width, - priv->base.pixmap->drawable.height, - region, n_region, reverse, upsidedown - ); - if (saved_region) - RegionDestroy(region); - return clipped_regions; - } - extent = RegionExtents(region); - - x_center_shift = extent->x1 / pixmap_width; - if (x_center_shift < 0) - x_center_shift--; - if (abs(x_center_shift) & 1) - x_center_shift++; - y_center_shift = extent->y1 / pixmap_height; - if (y_center_shift < 0) - y_center_shift--; - if (abs(y_center_shift) & 1) - y_center_shift++; - - if (extent->x1 < 0) - right_shift = ((-extent->x1 + pixmap_width - 1) / pixmap_width ); - if (extent->y1 < 0) - down_shift = ((-extent->y1 + pixmap_height - 1) / pixmap_height ); - - if (right_shift != 0 || down_shift != 0) { - if (repeat_type == RepeatReflect) { - right_shift = (right_shift + 1)&~1; - down_shift = (down_shift + 1)&~1; - } - RegionTranslate(region, right_shift * pixmap_width, down_shift * pixmap_height); - } - - extent = RegionExtents(region); - /* Tile a large pixmap to another large pixmap. - * We can't use the target large pixmap as the - * loop variable, instead we need to loop for all - * the blocks in the tile pixmap. - * - * simulate repeat each single block to cover the - * target's blocks. Two special case: - * a block_wcnt == 1 or block_hcnt ==1, then we - * only need to loop one direction as the other - * direction is fully included in the first block. - * - * For the other cases, just need to start - * from a proper shiftx/shifty, and then increase - * y by tile_height each time to walk trhough the - * target block and then walk trhough the target - * at x direction by increate tile_width each time. - * - * This way, we can consolidate all the sub blocks - * of the target boxes into one tile source's block. - * - * */ - m = 0; - clipped_regions = calloc(priv->block_wcnt * priv->block_hcnt, - sizeof(*clipped_regions)); - if (clipped_regions == NULL) { - *n_region = 0; - return NULL; - } - if (right_shift != 0 || down_shift != 0) { - DEBUGF("region to be repeated shifted \n"); - DEBUGRegionPrint(region); - } - DEBUGF("repeat pixmap width %d height %d \n", pixmap_width, pixmap_height); - DEBUGF("extent x1 %d y1 %d x2 %d y2 %d \n", extent->x1, extent->y1, extent->x2, extent->y2); - for(j = 0; j < priv->block_hcnt; j++) - { - for(i = 0; i < priv->block_wcnt; i++) - { - int dx = pixmap_width; - int dy = pixmap_height; - int idx; - int shift_x; - int shift_y; - int saved_y1, saved_y2; - int x_idx = 0, y_idx = 0, saved_y_idx = 0; - RegionRec temp_region; - BoxRec reflect_repeat_box; - BoxPtr valid_repeat_box; - - shift_x = (extent->x1 / pixmap_width) * pixmap_width; - shift_y = (extent->y1 / pixmap_height) * pixmap_height; - idx = j * priv->block_wcnt + i; - if (repeat_type == RepeatReflect) { - x_idx = (extent->x1 / pixmap_width); - y_idx = (extent->y1 / pixmap_height); - } - - /* Construct a rect to clip the target region. */ - repeat_box.x1 = shift_x + priv->box_array[idx].x1; - repeat_box.y1 = shift_y + priv->box_array[idx].y1; - if (priv->block_wcnt == 1) { - repeat_box.x2 = extent->x2; - dx = extent->x2 - repeat_box.x1; - } else - repeat_box.x2 = shift_x + priv->box_array[idx].x2; - if (priv->block_hcnt == 1) { - repeat_box.y2 = extent->y2; - dy = extent->y2 - repeat_box.y1; - } else - repeat_box.y2 = shift_y + priv->box_array[idx].y2; - - current_region = RegionCreate(NULL, 4); - RegionInit(&temp_region, NULL, 4); - DEBUGF("init repeat box %d %d %d %d \n", - repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2); - - if (repeat_type == RepeatNormal) { - saved_y1 = repeat_box.y1; - saved_y2 = repeat_box.y2; - for(; repeat_box.x1 < extent->x2; - repeat_box.x1 += dx, repeat_box.x2 += dx) - { - repeat_box.y1 = saved_y1; - repeat_box.y2 = saved_y2; - for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2; - repeat_box.y1 < extent->y2; - repeat_box.y1 += dy, repeat_box.y2 += dy) - { - - RegionInitBoxes(&repeat_region, &repeat_box, 1); - DEBUGF("Start to clip repeat region: \n"); - DEBUGRegionPrint(&repeat_region); - RegionIntersect(&temp_region, &repeat_region, region); - DEBUGF("clip result:\n"); - DEBUGRegionPrint(&temp_region); - RegionAppend(current_region, &temp_region); - RegionUninit(&repeat_region); - } - } - } else if (repeat_type == RepeatReflect) { - saved_y1 = repeat_box.y1; - saved_y2 = repeat_box.y2; - saved_y_idx = y_idx; - for(; ; repeat_box.x1 += dx, repeat_box.x2 += dx) - { - repeat_box.y1 = saved_y1; - repeat_box.y2 = saved_y2; - y_idx = saved_y_idx; - reflect_repeat_box.x1 = (x_idx & 1) ? - ((2 * x_idx + 1) * dx - repeat_box.x2) : repeat_box.x1; - reflect_repeat_box.x2 = (x_idx & 1) ? - ((2 * x_idx + 1) * dx - repeat_box.x1) : repeat_box.x2; - valid_repeat_box = &reflect_repeat_box; - - if (valid_repeat_box->x1 >= extent->x2) - break; - for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2; - ; - repeat_box.y1 += dy, repeat_box.y2 += dy) - { - - DEBUGF("x_idx %d y_idx %d dx %d dy %d\n", x_idx, y_idx, dx, dy); - DEBUGF("repeat box %d %d %d %d \n", - repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2); - - if (priv->block_hcnt > 1) { - reflect_repeat_box.y1 = (y_idx & 1) ? - ((2 * y_idx + 1) * dy - repeat_box.y2) : repeat_box.y1; - reflect_repeat_box.y2 = (y_idx & 1) ? - ((2 * y_idx + 1) * dy - repeat_box.y1) : repeat_box.y2; - } else { - reflect_repeat_box.y1 = repeat_box.y1; - reflect_repeat_box.y2 = repeat_box.y2; - } - - DEBUGF("valid_repeat_box x1 %d y1 %d \n", - valid_repeat_box->x1, valid_repeat_box->y1); - if (valid_repeat_box->y1 >= extent->y2) - break; - RegionInitBoxes(&repeat_region, valid_repeat_box, 1); - DEBUGF("start to clip repeat[reflect] region: \n"); - DEBUGRegionPrint(&repeat_region); - RegionIntersect(&temp_region, &repeat_region, region); - DEBUGF("result:\n"); - DEBUGRegionPrint(&temp_region); - if (is_transform && RegionNumRects(&temp_region)) { - BoxRec temp_box; - BoxPtr temp_extent; - temp_extent = RegionExtents(&temp_region); - if (priv->block_wcnt > 1) { - if (x_idx & 1) { - temp_box.x1 = ((2 * x_idx + 1)*dx - temp_extent->x2); - temp_box.x2 = ((2 * x_idx + 1)*dx - temp_extent->x1); - } else { - temp_box.x1 = temp_extent->x1; - temp_box.x2 = temp_extent->x2; - } - modulus(temp_box.x1, pixmap_width, temp_box.x1); - modulus(temp_box.x2, pixmap_width, temp_box.x2); - if (temp_box.x2 == 0) temp_box.x2 = pixmap_width; - } else { - temp_box.x1 = temp_extent->x1; - temp_box.x2 = temp_extent->x2; - _glamor_largepixmap_reflect_fixup(&temp_box.x1, &temp_box.x2, pixmap_width); - } - - if (priv->block_hcnt > 1) { - if (y_idx & 1) { - temp_box.y1 = ((2 * y_idx + 1)*dy - temp_extent->y2); - temp_box.y2 = ((2 * y_idx + 1)*dy - temp_extent->y1); - } else { - temp_box.y1 = temp_extent->y1; - temp_box.y2 = temp_extent->y2; - } - - modulus(temp_box.y1, pixmap_height, temp_box.y1); - modulus(temp_box.y2, pixmap_height, temp_box.y2); - if (temp_box.y2 == 0) temp_box.y2 = pixmap_height; - } else { - temp_box.y1 = temp_extent->y1; - temp_box.y2 = temp_extent->y2; - _glamor_largepixmap_reflect_fixup(&temp_box.y1, &temp_box.y2, pixmap_height); - } - - RegionInitBoxes(&temp_region, &temp_box, 1); - RegionTranslate(&temp_region, x_center_shift * pixmap_width, y_center_shift * pixmap_height); - DEBUGF("for transform result:\n"); - DEBUGRegionPrint(&temp_region); - } - RegionAppend(current_region, &temp_region); - RegionUninit(&repeat_region); - y_idx++; - } - x_idx++; - } - } - DEBUGF("dx %d dy %d \n", dx, dy); - - if (RegionNumRects(current_region)) { - - if ((right_shift != 0 || down_shift != 0) && !(is_transform && repeat_type == RepeatReflect)) - RegionTranslate(current_region, - -right_shift * pixmap_width, - -down_shift * pixmap_height); - clipped_regions[m].region = current_region; - clipped_regions[m].block_idx = idx; - m++; - } else - RegionDestroy(current_region); - RegionUninit(&temp_region); - } - } - - if (right_shift != 0 || down_shift != 0) - RegionTranslate(region, -right_shift * pixmap_width, -down_shift * pixmap_height); - *n_region = m; - - return clipped_regions; + glamor_pixmap_clipped_regions *clipped_regions; + BoxPtr extent; + int i, j; + RegionPtr current_region; + int pixmap_width, pixmap_height; + int m; + BoxRec repeat_box; + RegionRec repeat_region; + int right_shift = 0; + int down_shift = 0; + int x_center_shift = 0, y_center_shift = 0; + glamor_pixmap_private_large_t *priv; + + priv = &pixmap_priv->large; + + DEBUGRegionPrint(region); + if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { + clipped_regions = calloc(1, sizeof(*clipped_regions)); + clipped_regions[0].region = RegionCreate(NULL, 1); + clipped_regions[0].block_idx = 0; + RegionCopy(clipped_regions[0].region, region); + *n_region = 1; + return clipped_regions; + } + + pixmap_width = priv->base.pixmap->drawable.width; + pixmap_height = priv->base.pixmap->drawable.height; + if (repeat_type == 0 || repeat_type == RepeatPad) { + RegionPtr saved_region = NULL; + + if (repeat_type == RepeatPad) { + saved_region = region; + region = + _glamor_convert_pad_region(saved_region, pixmap_width, + pixmap_height); + if (region == NULL) { + *n_region = 0; + return NULL; + } + } + clipped_regions = __glamor_compute_clipped_regions(priv->block_w, + priv->block_h, + priv->block_wcnt, + 0, 0, + priv->base.pixmap-> + drawable.width, + priv->base.pixmap-> + drawable.height, + region, n_region, + reverse, upsidedown); + if (saved_region) + RegionDestroy(region); + return clipped_regions; + } + extent = RegionExtents(region); + + x_center_shift = extent->x1 / pixmap_width; + if (x_center_shift < 0) + x_center_shift--; + if (abs(x_center_shift) & 1) + x_center_shift++; + y_center_shift = extent->y1 / pixmap_height; + if (y_center_shift < 0) + y_center_shift--; + if (abs(y_center_shift) & 1) + y_center_shift++; + + if (extent->x1 < 0) + right_shift = ((-extent->x1 + pixmap_width - 1) / pixmap_width); + if (extent->y1 < 0) + down_shift = ((-extent->y1 + pixmap_height - 1) / pixmap_height); + + if (right_shift != 0 || down_shift != 0) { + if (repeat_type == RepeatReflect) { + right_shift = (right_shift + 1) & ~1; + down_shift = (down_shift + 1) & ~1; + } + RegionTranslate(region, right_shift * pixmap_width, + down_shift * pixmap_height); + } + + extent = RegionExtents(region); + /* Tile a large pixmap to another large pixmap. + * We can't use the target large pixmap as the + * loop variable, instead we need to loop for all + * the blocks in the tile pixmap. + * + * simulate repeat each single block to cover the + * target's blocks. Two special case: + * a block_wcnt == 1 or block_hcnt ==1, then we + * only need to loop one direction as the other + * direction is fully included in the first block. + * + * For the other cases, just need to start + * from a proper shiftx/shifty, and then increase + * y by tile_height each time to walk trhough the + * target block and then walk trhough the target + * at x direction by increate tile_width each time. + * + * This way, we can consolidate all the sub blocks + * of the target boxes into one tile source's block. + * + * */ + m = 0; + clipped_regions = calloc(priv->block_wcnt * priv->block_hcnt, + sizeof(*clipped_regions)); + if (clipped_regions == NULL) { + *n_region = 0; + return NULL; + } + if (right_shift != 0 || down_shift != 0) { + DEBUGF("region to be repeated shifted \n"); + DEBUGRegionPrint(region); + } + DEBUGF("repeat pixmap width %d height %d \n", pixmap_width, pixmap_height); + DEBUGF("extent x1 %d y1 %d x2 %d y2 %d \n", extent->x1, extent->y1, + extent->x2, extent->y2); + for (j = 0; j < priv->block_hcnt; j++) { + for (i = 0; i < priv->block_wcnt; i++) { + int dx = pixmap_width; + int dy = pixmap_height; + int idx; + int shift_x; + int shift_y; + int saved_y1, saved_y2; + int x_idx = 0, y_idx = 0, saved_y_idx = 0; + RegionRec temp_region; + BoxRec reflect_repeat_box; + BoxPtr valid_repeat_box; + + shift_x = (extent->x1 / pixmap_width) * pixmap_width; + shift_y = (extent->y1 / pixmap_height) * pixmap_height; + idx = j * priv->block_wcnt + i; + if (repeat_type == RepeatReflect) { + x_idx = (extent->x1 / pixmap_width); + y_idx = (extent->y1 / pixmap_height); + } + + /* Construct a rect to clip the target region. */ + repeat_box.x1 = shift_x + priv->box_array[idx].x1; + repeat_box.y1 = shift_y + priv->box_array[idx].y1; + if (priv->block_wcnt == 1) { + repeat_box.x2 = extent->x2; + dx = extent->x2 - repeat_box.x1; + } + else + repeat_box.x2 = shift_x + priv->box_array[idx].x2; + if (priv->block_hcnt == 1) { + repeat_box.y2 = extent->y2; + dy = extent->y2 - repeat_box.y1; + } + else + repeat_box.y2 = shift_y + priv->box_array[idx].y2; + + current_region = RegionCreate(NULL, 4); + RegionInit(&temp_region, NULL, 4); + DEBUGF("init repeat box %d %d %d %d \n", + repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2); + + if (repeat_type == RepeatNormal) { + saved_y1 = repeat_box.y1; + saved_y2 = repeat_box.y2; + for (; repeat_box.x1 < extent->x2; + repeat_box.x1 += dx, repeat_box.x2 += dx) { + repeat_box.y1 = saved_y1; + repeat_box.y2 = saved_y2; + for (repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2; + repeat_box.y1 < extent->y2; + repeat_box.y1 += dy, repeat_box.y2 += dy) { + + RegionInitBoxes(&repeat_region, &repeat_box, 1); + DEBUGF("Start to clip repeat region: \n"); + DEBUGRegionPrint(&repeat_region); + RegionIntersect(&temp_region, &repeat_region, region); + DEBUGF("clip result:\n"); + DEBUGRegionPrint(&temp_region); + RegionAppend(current_region, &temp_region); + RegionUninit(&repeat_region); + } + } + } + else if (repeat_type == RepeatReflect) { + saved_y1 = repeat_box.y1; + saved_y2 = repeat_box.y2; + saved_y_idx = y_idx; + for (;; repeat_box.x1 += dx, repeat_box.x2 += dx) { + repeat_box.y1 = saved_y1; + repeat_box.y2 = saved_y2; + y_idx = saved_y_idx; + reflect_repeat_box.x1 = (x_idx & 1) ? + ((2 * x_idx + 1) * dx - repeat_box.x2) : repeat_box.x1; + reflect_repeat_box.x2 = (x_idx & 1) ? + ((2 * x_idx + 1) * dx - repeat_box.x1) : repeat_box.x2; + valid_repeat_box = &reflect_repeat_box; + + if (valid_repeat_box->x1 >= extent->x2) + break; + for (repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;; + repeat_box.y1 += dy, repeat_box.y2 += dy) { + + DEBUGF("x_idx %d y_idx %d dx %d dy %d\n", x_idx, y_idx, + dx, dy); + DEBUGF("repeat box %d %d %d %d \n", repeat_box.x1, + repeat_box.y1, repeat_box.x2, repeat_box.y2); + + if (priv->block_hcnt > 1) { + reflect_repeat_box.y1 = (y_idx & 1) ? + ((2 * y_idx + 1) * dy - + repeat_box.y2) : repeat_box.y1; + reflect_repeat_box.y2 = + (y_idx & 1) ? ((2 * y_idx + 1) * dy - + repeat_box.y1) : repeat_box.y2; + } + else { + reflect_repeat_box.y1 = repeat_box.y1; + reflect_repeat_box.y2 = repeat_box.y2; + } + + DEBUGF("valid_repeat_box x1 %d y1 %d \n", + valid_repeat_box->x1, valid_repeat_box->y1); + if (valid_repeat_box->y1 >= extent->y2) + break; + RegionInitBoxes(&repeat_region, valid_repeat_box, 1); + DEBUGF("start to clip repeat[reflect] region: \n"); + DEBUGRegionPrint(&repeat_region); + RegionIntersect(&temp_region, &repeat_region, region); + DEBUGF("result:\n"); + DEBUGRegionPrint(&temp_region); + if (is_transform && RegionNumRects(&temp_region)) { + BoxRec temp_box; + BoxPtr temp_extent; + + temp_extent = RegionExtents(&temp_region); + if (priv->block_wcnt > 1) { + if (x_idx & 1) { + temp_box.x1 = + ((2 * x_idx + 1) * dx - + temp_extent->x2); + temp_box.x2 = + ((2 * x_idx + 1) * dx - + temp_extent->x1); + } + else { + temp_box.x1 = temp_extent->x1; + temp_box.x2 = temp_extent->x2; + } + modulus(temp_box.x1, pixmap_width, temp_box.x1); + modulus(temp_box.x2, pixmap_width, temp_box.x2); + if (temp_box.x2 == 0) + temp_box.x2 = pixmap_width; + } + else { + temp_box.x1 = temp_extent->x1; + temp_box.x2 = temp_extent->x2; + _glamor_largepixmap_reflect_fixup(&temp_box.x1, + &temp_box.x2, + pixmap_width); + } + + if (priv->block_hcnt > 1) { + if (y_idx & 1) { + temp_box.y1 = + ((2 * y_idx + 1) * dy - + temp_extent->y2); + temp_box.y2 = + ((2 * y_idx + 1) * dy - + temp_extent->y1); + } + else { + temp_box.y1 = temp_extent->y1; + temp_box.y2 = temp_extent->y2; + } + + modulus(temp_box.y1, pixmap_height, + temp_box.y1); + modulus(temp_box.y2, pixmap_height, + temp_box.y2); + if (temp_box.y2 == 0) + temp_box.y2 = pixmap_height; + } + else { + temp_box.y1 = temp_extent->y1; + temp_box.y2 = temp_extent->y2; + _glamor_largepixmap_reflect_fixup(&temp_box.y1, + &temp_box.y2, + pixmap_height); + } + + RegionInitBoxes(&temp_region, &temp_box, 1); + RegionTranslate(&temp_region, + x_center_shift * pixmap_width, + y_center_shift * pixmap_height); + DEBUGF("for transform result:\n"); + DEBUGRegionPrint(&temp_region); + } + RegionAppend(current_region, &temp_region); + RegionUninit(&repeat_region); + y_idx++; + } + x_idx++; + } + } + DEBUGF("dx %d dy %d \n", dx, dy); + + if (RegionNumRects(current_region)) { + + if ((right_shift != 0 || down_shift != 0) && + !(is_transform && repeat_type == RepeatReflect)) + RegionTranslate(current_region, -right_shift * pixmap_width, + -down_shift * pixmap_height); + clipped_regions[m].region = current_region; + clipped_regions[m].block_idx = idx; + m++; + } + else + RegionDestroy(current_region); + RegionUninit(&temp_region); + } + } + + if (right_shift != 0 || down_shift != 0) + RegionTranslate(region, -right_shift * pixmap_width, + -down_shift * pixmap_height); + *n_region = m; + + return clipped_regions; } glamor_pixmap_clipped_regions * -glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, - int *n_region, int repeat_type, - int reverse, int upsidedown) +glamor_compute_clipped_regions(glamor_pixmap_private * priv, RegionPtr region, + int *n_region, int repeat_type, + int reverse, int upsidedown) { - return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0, reverse, upsidedown); + return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, + 0, reverse, upsidedown); } /* XXX overflow still exist. maybe we need to change to use region32. * by default. Or just use region32 for repeat cases? **/ glamor_pixmap_clipped_regions * -glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform, - RegionPtr region, int *n_region, int dx, int dy, int repeat_type, - int reverse, int upsidedown) +glamor_compute_transform_clipped_regions(glamor_pixmap_private * priv, + struct pixman_transform * transform, + RegionPtr region, int *n_region, + int dx, int dy, int repeat_type, + int reverse, int upsidedown) { - BoxPtr temp_extent; - struct pixman_box32 temp_box; - struct pixman_box16 short_box; - RegionPtr temp_region; - glamor_pixmap_clipped_regions *ret; - - temp_region = RegionCreate(NULL, 4); - temp_extent = RegionExtents(region); - DEBUGF("dest region \n"); - DEBUGRegionPrint(region); - /* dx/dy may exceed MAX SHORT. we have to use - * a box32 to represent it.*/ - temp_box.x1 = temp_extent->x1 + dx; - temp_box.x2 = temp_extent->x2 + dx; - temp_box.y1 = temp_extent->y1 + dy; - temp_box.y2 = temp_extent->y2 + dy; - - DEBUGF("source box %d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2); - if (transform) - glamor_get_transform_extent_from_box(&temp_box, transform); - if (repeat_type == RepeatNone) { - if (temp_box.x1 < 0) temp_box.x1 = 0; - if (temp_box.y1 < 0) temp_box.y1 = 0; - temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width); - temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height); - } - /* Now copy back the box32 to a box16 box. */ - short_box.x1 = temp_box.x1; - short_box.y1 = temp_box.y1; - short_box.x2 = temp_box.x2; - short_box.y2 = temp_box.y2; - RegionInitBoxes(temp_region, &short_box, 1); - DEBUGF("copy to temp source region \n"); - DEBUGRegionPrint(temp_region); - ret = _glamor_compute_clipped_regions(priv, - temp_region, - n_region, - repeat_type, - 1, reverse, - upsidedown); - DEBUGF("n_regions = %d \n", *n_region); - RegionDestroy(temp_region); - - return ret; + BoxPtr temp_extent; + struct pixman_box32 temp_box; + struct pixman_box16 short_box; + RegionPtr temp_region; + glamor_pixmap_clipped_regions *ret; + + temp_region = RegionCreate(NULL, 4); + temp_extent = RegionExtents(region); + DEBUGF("dest region \n"); + DEBUGRegionPrint(region); + /* dx/dy may exceed MAX SHORT. we have to use + * a box32 to represent it.*/ + temp_box.x1 = temp_extent->x1 + dx; + temp_box.x2 = temp_extent->x2 + dx; + temp_box.y1 = temp_extent->y1 + dy; + temp_box.y2 = temp_extent->y2 + dy; + + DEBUGF("source box %d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, + temp_box.y2); + if (transform) + glamor_get_transform_extent_from_box(&temp_box, transform); + if (repeat_type == RepeatNone) { + if (temp_box.x1 < 0) + temp_box.x1 = 0; + if (temp_box.y1 < 0) + temp_box.y1 = 0; + temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width); + temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height); + } + /* Now copy back the box32 to a box16 box. */ + short_box.x1 = temp_box.x1; + short_box.y1 = temp_box.y1; + short_box.x2 = temp_box.x2; + short_box.y2 = temp_box.y2; + RegionInitBoxes(temp_region, &short_box, 1); + DEBUGF("copy to temp source region \n"); + DEBUGRegionPrint(temp_region); + ret = _glamor_compute_clipped_regions(priv, + temp_region, + n_region, + repeat_type, 1, reverse, upsidedown); + DEBUGF("n_regions = %d \n", *n_region); + RegionDestroy(temp_region); + + return ret; } + /* * As transform and repeatpad mode. * We may get a clipped result which in multipe regions. @@ -689,120 +736,121 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pix * if the clipped result cross the region boundary. */ static void -glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, int repeat_type, - glamor_pixmap_clipped_regions *clipped_regions, - int *n_regions, int *need_clean_fbo) +glamor_merge_clipped_regions(glamor_pixmap_private * pixmap_priv, + int repeat_type, + glamor_pixmap_clipped_regions * clipped_regions, + int *n_regions, int *need_clean_fbo) { - BoxPtr temp_extent; - BoxRec temp_box, copy_box; - RegionPtr temp_region; - glamor_pixmap_private *temp_priv; - PixmapPtr temp_pixmap; - int overlap; - int i; - int pixmap_width, pixmap_height; - glamor_pixmap_private_large_t *priv; - - priv = &pixmap_priv->large; - pixmap_width = priv->base.pixmap->drawable.width; - pixmap_height = priv->base.pixmap->drawable.height; - - temp_region = RegionCreate(NULL, 4); - for(i = 0; i < *n_regions; i++) - { - DEBUGF("Region %d:\n", i); - DEBUGRegionPrint(clipped_regions[i].region); - RegionAppend(temp_region, clipped_regions[i].region); - } - - RegionValidate(temp_region, &overlap); - DEBUGF("temp region: \n"); - DEBUGRegionPrint(temp_region); - temp_extent = RegionExtents(temp_region); - - temp_box = *temp_extent; - - DEBUGF("need copy region: \n"); - DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2); - temp_pixmap = glamor_create_pixmap(priv->base.pixmap->drawable.pScreen, - temp_box.x2 - temp_box.x1, - temp_box.y2 - temp_box.y1, - priv->base.pixmap->drawable.depth, - GLAMOR_CREATE_PIXMAP_FIXUP); - if (temp_pixmap == NULL) { - assert(0); - return; - } - - temp_priv = glamor_get_pixmap_private(temp_pixmap); - assert(temp_priv->type != GLAMOR_TEXTURE_LARGE); - - priv->box = temp_box; - if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width - && temp_extent->y1 >= 0 && temp_extent->y2 <= pixmap_height) { - int dx, dy; - copy_box.x1 = 0; - copy_box.y1 = 0; - copy_box.x2 = temp_extent->x2 - temp_extent->x1; - 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_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, -// temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00); - } else { - for (i = 0; i < *n_regions; i++) - { - BoxPtr box; - int nbox; - box = REGION_RECTS(clipped_regions[i].region); - nbox = REGION_NUM_RECTS(clipped_regions[i].region); - while(nbox--) { - int dx, dy, c, d; - DEBUGF("box x1 %d y1 %d x2 %d y2 %d \n", - box->x1, box->y1, box->x2, box->y2); - modulus(box->x1, pixmap_width, c); - dx = c - (box->x1 - temp_box.x1); - copy_box.x1 = box->x1 - temp_box.x1; - copy_box.x2 = box->x2 - temp_box.x1; - - modulus(box->y1, pixmap_height, d); - dy = d - (box->y1 - temp_box.y1); - copy_box.y1 = box->y1 - temp_box.y1; - copy_box.y2 = box->y2 - temp_box.y1; - - DEBUGF("copying box %d %d %d %d, dx %d dy %d\n", - 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); - box++; - } - } - //glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, - // temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff); - } - /* The first region will be released at caller side. */ - for(i = 1; i < *n_regions; i++) - RegionDestroy(clipped_regions[i].region); - RegionDestroy(temp_region); - priv->box = temp_box; - priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv); - DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n", - priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2); - glamor_destroy_pixmap(temp_pixmap); - *need_clean_fbo = 1; - *n_regions = 1; + BoxPtr temp_extent; + BoxRec temp_box, copy_box; + RegionPtr temp_region; + glamor_pixmap_private *temp_priv; + PixmapPtr temp_pixmap; + int overlap; + int i; + int pixmap_width, pixmap_height; + glamor_pixmap_private_large_t *priv; + + priv = &pixmap_priv->large; + pixmap_width = priv->base.pixmap->drawable.width; + pixmap_height = priv->base.pixmap->drawable.height; + + temp_region = RegionCreate(NULL, 4); + for (i = 0; i < *n_regions; i++) { + DEBUGF("Region %d:\n", i); + DEBUGRegionPrint(clipped_regions[i].region); + RegionAppend(temp_region, clipped_regions[i].region); + } + + RegionValidate(temp_region, &overlap); + DEBUGF("temp region: \n"); + DEBUGRegionPrint(temp_region); + temp_extent = RegionExtents(temp_region); + + temp_box = *temp_extent; + + DEBUGF("need copy region: \n"); + DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, + temp_box.y2); + temp_pixmap = + glamor_create_pixmap(priv->base.pixmap->drawable.pScreen, + temp_box.x2 - temp_box.x1, + temp_box.y2 - temp_box.y1, + priv->base.pixmap->drawable.depth, + GLAMOR_CREATE_PIXMAP_FIXUP); + if (temp_pixmap == NULL) { + assert(0); + return; + } + + temp_priv = glamor_get_pixmap_private(temp_pixmap); + assert(temp_priv->type != GLAMOR_TEXTURE_LARGE); + + priv->box = temp_box; + if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width + && temp_extent->y1 >= 0 && temp_extent->y2 <= pixmap_height) { + int dx, dy; + + copy_box.x1 = 0; + copy_box.y1 = 0; + copy_box.x2 = temp_extent->x2 - temp_extent->x1; + 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_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, +// temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00); + } + else { + for (i = 0; i < *n_regions; i++) { + BoxPtr box; + int nbox; + + box = REGION_RECTS(clipped_regions[i].region); + nbox = REGION_NUM_RECTS(clipped_regions[i].region); + while (nbox--) { + int dx, dy, c, d; + + DEBUGF("box x1 %d y1 %d x2 %d y2 %d \n", + box->x1, box->y1, box->x2, box->y2); + modulus(box->x1, pixmap_width, c); + dx = c - (box->x1 - temp_box.x1); + copy_box.x1 = box->x1 - temp_box.x1; + copy_box.x2 = box->x2 - temp_box.x1; + + modulus(box->y1, pixmap_height, d); + dy = d - (box->y1 - temp_box.y1); + copy_box.y1 = box->y1 - temp_box.y1; + copy_box.y2 = box->y2 - temp_box.y1; + + DEBUGF("copying box %d %d %d %d, dx %d dy %d\n", + 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); + box++; + } + } + //glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width, + // temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff); + } + /* The first region will be released at caller side. */ + for (i = 1; i < *n_regions; i++) + RegionDestroy(clipped_regions[i].region); + RegionDestroy(temp_region); + priv->box = temp_box; + priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv); + DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n", + priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2); + glamor_destroy_pixmap(temp_pixmap); + *need_clean_fbo = 1; + *n_regions = 1; } - - /** * Given an expected transformed block width and block height, * @@ -817,45 +865,47 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, int repeat_type **/ Bool glamor_get_transform_block_size(struct pixman_transform *transform, - int block_w, int block_h, - int *transformed_block_w, - int *transformed_block_h) + int block_w, int block_h, + int *transformed_block_w, + int *transformed_block_h) { - double a,b,c,d,e,f,g,h; - double scale; - int width, height; - a = pixman_fixed_to_double(transform->matrix[0][0]); - b = pixman_fixed_to_double(transform->matrix[0][1]); - c = pixman_fixed_to_double(transform->matrix[1][0]); - d = pixman_fixed_to_double(transform->matrix[1][1]); - scale = pixman_fixed_to_double(transform->matrix[2][2]); - if (block_w > 2048) { - /* For large block size, we shrink it to smaller box, - * thus latter we may get less cross boundary regions and - * thus can avoid some extra copy. - * - **/ - width = block_w / 4; - height = block_h / 4; - } else { - width = block_w - 2; - height = block_h - 2; - } - e = a + b; - f = c + d; - - g = a - b; - h = c - d; - - e = MIN(block_w, floor(width * scale) / MAX(fabs(e), fabs(g))); - f = MIN(block_h, floor(height * scale) / MAX(fabs(f), fabs(h))); - *transformed_block_w = MIN(e, f) - 1; - *transformed_block_h = *transformed_block_w; - if (*transformed_block_w <= 0 || *transformed_block_h <= 0) - return FALSE; - DEBUGF("original block_w/h %d %d, fixed %d %d \n", block_w, block_h, - *transformed_block_w, *transformed_block_h); - return TRUE; + double a, b, c, d, e, f, g, h; + double scale; + int width, height; + + a = pixman_fixed_to_double(transform->matrix[0][0]); + b = pixman_fixed_to_double(transform->matrix[0][1]); + c = pixman_fixed_to_double(transform->matrix[1][0]); + d = pixman_fixed_to_double(transform->matrix[1][1]); + scale = pixman_fixed_to_double(transform->matrix[2][2]); + if (block_w > 2048) { + /* For large block size, we shrink it to smaller box, + * thus latter we may get less cross boundary regions and + * thus can avoid some extra copy. + * + **/ + width = block_w / 4; + height = block_h / 4; + } + else { + width = block_w - 2; + height = block_h - 2; + } + e = a + b; + f = c + d; + + g = a - b; + h = c - d; + + e = MIN(block_w, floor(width * scale) / MAX(fabs(e), fabs(g))); + f = MIN(block_h, floor(height * scale) / MAX(fabs(f), fabs(h))); + *transformed_block_w = MIN(e, f) - 1; + *transformed_block_h = *transformed_block_w; + if (*transformed_block_w <= 0 || *transformed_block_h <= 0) + return FALSE; + DEBUGF("original block_w/h %d %d, fixed %d %d \n", block_w, block_h, + *transformed_block_w, *transformed_block_h); + return TRUE; } #define VECTOR_FROM_POINT(p, x, y) \ @@ -864,314 +914,341 @@ glamor_get_transform_block_size(struct pixman_transform *transform, p.v[2] = 1.0; void glamor_get_transform_extent_from_box(struct pixman_box32 *box, - struct pixman_transform *transform) + struct pixman_transform *transform) { - struct pixman_f_vector p0, p1, p2, p3; - float min_x, min_y, max_x, max_y; - - struct pixman_f_transform ftransform; - - VECTOR_FROM_POINT(p0, box->x1, box->y1) - VECTOR_FROM_POINT(p1, box->x2, box->y1) - VECTOR_FROM_POINT(p2, box->x2, box->y2) - VECTOR_FROM_POINT(p3, box->x1, box->y2) - - pixman_f_transform_from_pixman_transform(&ftransform, transform); - pixman_f_transform_point(&ftransform, &p0); - pixman_f_transform_point(&ftransform, &p1); - pixman_f_transform_point(&ftransform, &p2); - pixman_f_transform_point(&ftransform, &p3); - - min_x = MIN(p0.v[0], p1.v[0]); - min_x = MIN(min_x, p2.v[0]); - min_x = MIN(min_x, p3.v[0]); - - min_y = MIN(p0.v[1], p1.v[1]); - min_y = MIN(min_y, p2.v[1]); - min_y = MIN(min_y, p3.v[1]); - - max_x = MAX(p0.v[0], p1.v[0]); - max_x = MAX(max_x, p2.v[0]); - max_x = MAX(max_x, p3.v[0]); - - max_y = MAX(p0.v[1], p1.v[1]); - max_y = MAX(max_y, p2.v[1]); - max_y = MAX(max_y, p3.v[1]); - box->x1 = floor(min_x) - 1; - box->y1 = floor(min_y) - 1; - box->x2 = ceil(max_x) + 1; - box->y2 = ceil(max_y) + 1; + struct pixman_f_vector p0, p1, p2, p3; + float min_x, min_y, max_x, max_y; + + struct pixman_f_transform ftransform; + + VECTOR_FROM_POINT(p0, box->x1, box->y1) + VECTOR_FROM_POINT(p1, box->x2, box->y1) + VECTOR_FROM_POINT(p2, box->x2, box->y2) + VECTOR_FROM_POINT(p3, box->x1, box->y2) + + pixman_f_transform_from_pixman_transform(&ftransform, transform); + pixman_f_transform_point(&ftransform, &p0); + pixman_f_transform_point(&ftransform, &p1); + pixman_f_transform_point(&ftransform, &p2); + pixman_f_transform_point(&ftransform, &p3); + + min_x = MIN(p0.v[0], p1.v[0]); + min_x = MIN(min_x, p2.v[0]); + min_x = MIN(min_x, p3.v[0]); + + min_y = MIN(p0.v[1], p1.v[1]); + min_y = MIN(min_y, p2.v[1]); + min_y = MIN(min_y, p3.v[1]); + + max_x = MAX(p0.v[0], p1.v[0]); + max_x = MAX(max_x, p2.v[0]); + max_x = MAX(max_x, p3.v[0]); + + max_y = MAX(p0.v[1], p1.v[1]); + max_y = MAX(max_y, p2.v[1]); + max_y = MAX(max_y, p3.v[1]); + box->x1 = floor(min_x) - 1; + box->y1 = floor(min_y) - 1; + box->x2 = ceil(max_x) + 1; + box->y2 = ceil(max_y) + 1; } static void -_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv, - int repeat_type, - glamor_pixmap_clipped_regions *clipped_regions, - int *n_regions, int *need_clean_fbo) +_glamor_process_transformed_clipped_region(glamor_pixmap_private * priv, + int repeat_type, + glamor_pixmap_clipped_regions * + clipped_regions, int *n_regions, + int *need_clean_fbo) { - int shift_x, shift_y; - if (*n_regions != 1) { - /* Merge all source regions into one region. */ - glamor_merge_clipped_regions(priv, repeat_type, - clipped_regions, n_regions, - need_clean_fbo); - } else { - SET_PIXMAP_FBO_CURRENT(priv, - clipped_regions[0].block_idx); - if (repeat_type == RepeatReflect || repeat_type == RepeatNormal) { - /* The required source areas are in one region, - * we need to shift the corresponding box's coords to proper position, - * thus we can calculate the relative coords correctly.*/ - BoxPtr temp_box; - int rem; - temp_box = RegionExtents(clipped_regions[0].region); - modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem); - shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width; - modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem); - shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height; - - if (shift_x != 0) { - priv->large.box.x1 += shift_x * priv->base.pixmap->drawable.width; - priv->large.box.x2 += shift_x * priv->base.pixmap->drawable.width; - } - if (shift_y != 0) { - priv->large.box.y1 += shift_y * priv->base.pixmap->drawable.height; - priv->large.box.y2 += shift_y * priv->base.pixmap->drawable.height; - } - } - } + int shift_x, shift_y; + + if (*n_regions != 1) { + /* Merge all source regions into one region. */ + glamor_merge_clipped_regions(priv, repeat_type, + clipped_regions, n_regions, + need_clean_fbo); + } + else { + SET_PIXMAP_FBO_CURRENT(priv, clipped_regions[0].block_idx); + if (repeat_type == RepeatReflect || repeat_type == RepeatNormal) { + /* The required source areas are in one region, + * we need to shift the corresponding box's coords to proper position, + * thus we can calculate the relative coords correctly.*/ + BoxPtr temp_box; + int rem; + + temp_box = RegionExtents(clipped_regions[0].region); + modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem); + shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width; + modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem); + shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height; + + if (shift_x != 0) { + priv->large.box.x1 += + shift_x * priv->base.pixmap->drawable.width; + priv->large.box.x2 += + shift_x * priv->base.pixmap->drawable.width; + } + if (shift_y != 0) { + priv->large.box.y1 += + shift_y * priv->base.pixmap->drawable.height; + priv->large.box.y2 += + shift_y * priv->base.pixmap->drawable.height; + } + } + } } - Bool glamor_composite_largepixmap_region(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - glamor_pixmap_private * source_pixmap_priv, - glamor_pixmap_private * mask_pixmap_priv, - glamor_pixmap_private * dest_pixmap_priv, - RegionPtr region, Bool force_clip, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, INT16 y_dest, - CARD16 width, CARD16 height) + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private * source_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, + RegionPtr region, Bool force_clip, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, + CARD16 width, CARD16 height) { - glamor_screen_private *glamor_priv; - glamor_pixmap_clipped_regions *clipped_dest_regions; - glamor_pixmap_clipped_regions *clipped_source_regions; - glamor_pixmap_clipped_regions *clipped_mask_regions; - int n_dest_regions; - int n_mask_regions; - int n_source_regions; - int i,j,k; - int need_clean_source_fbo = 0; - int need_clean_mask_fbo = 0; - int is_normal_source_fbo = 0; - int is_normal_mask_fbo = 0; - int fixed_block_width, fixed_block_height; - int null_source, null_mask; - glamor_pixmap_private * need_free_source_pixmap_priv = NULL; - glamor_pixmap_private * need_free_mask_pixmap_priv = NULL; - int source_repeat_type = 0, mask_repeat_type = 0; - int ok = TRUE; - - if (source->repeat) - source_repeat_type = source->repeatType; - else - source_repeat_type = RepeatNone; - - if (mask && mask->repeat) - mask_repeat_type = mask->repeatType; - else - mask_repeat_type = RepeatNone; - - glamor_priv = dest_pixmap_priv->base.glamor_priv; - fixed_block_width = glamor_priv->max_fbo_size; - fixed_block_height = glamor_priv->max_fbo_size; - /* If we got an totally out-of-box region for a source or mask - * region without repeat, we need to set it as null_source and - * give it a solid color (0,0,0,0). */ - null_source = 0; - null_mask = 0; - RegionTranslate(region, -dest->pDrawable->x, - -dest->pDrawable->y); - - /* need to transform the dest region to the correct sourcei/mask region. - * it's a little complex, as one single edge of the - * target region may be transformed to cross a block boundary of the - * source or mask. Then it's impossible to handle it as usual way. - * We may have to split the original dest region to smaller region, and - * make sure each region's transformed region can fit into one texture, - * and then continue this loop again, and each time when a transformed region - * cross the bound, we need to copy it to a single pixmap and do the composition - * with the new pixmap. If the transformed region doesn't cross a source/mask's - * boundary then we don't need to copy. - * - */ - if (source_pixmap_priv - && source->transform - && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - int source_transformed_block_width, source_transformed_block_height; - if (!glamor_get_transform_block_size(source->transform, - source_pixmap_priv->large.block_w, - source_pixmap_priv->large.block_h, - &source_transformed_block_width, - &source_transformed_block_height)) { - DEBUGF("source block size less than 1, fallback.\n"); - RegionTranslate(region, dest->pDrawable->x, - dest->pDrawable->y); - return FALSE; - } - fixed_block_width = min(fixed_block_width , source_transformed_block_width); - fixed_block_height = min(fixed_block_height , source_transformed_block_height); - DEBUGF("new source block size %d x %d \n", fixed_block_width, fixed_block_height); - } - - if (mask_pixmap_priv - && mask->transform - && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - int mask_transformed_block_width, mask_transformed_block_height; - if (!glamor_get_transform_block_size(mask->transform, - mask_pixmap_priv->large.block_w, - mask_pixmap_priv->large.block_h, - &mask_transformed_block_width, - &mask_transformed_block_height)) { - DEBUGF("mask block size less than 1, fallback.\n"); - RegionTranslate(region, dest->pDrawable->x, - dest->pDrawable->y); - return FALSE; - } - fixed_block_width = min(fixed_block_width , mask_transformed_block_width); - fixed_block_height = min(fixed_block_height , mask_transformed_block_height); - DEBUGF("new mask block size %d x %d \n", fixed_block_width, fixed_block_height); - } - - /*compute the correct block width and height whose transformed source/mask - *region can fit into one texture.*/ - if (force_clip || fixed_block_width < glamor_priv->max_fbo_size - || fixed_block_height < glamor_priv->max_fbo_size) - clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap_priv, - region, - &n_dest_regions, - fixed_block_width, - fixed_block_height, - 0, 0); - else - clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv, - region, - &n_dest_regions, - 0, 0, 0); - DEBUGF("dest clipped result %d region: \n", n_dest_regions); - if (source_pixmap_priv - && (source_pixmap_priv == dest_pixmap_priv || source_pixmap_priv == mask_pixmap_priv) - && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - /* XXX self-copy...*/ - need_free_source_pixmap_priv = source_pixmap_priv; - source_pixmap_priv = malloc(sizeof(*source_pixmap_priv)); - *source_pixmap_priv = *need_free_source_pixmap_priv; - need_free_source_pixmap_priv = source_pixmap_priv; - } - assert(mask_pixmap_priv != dest_pixmap_priv); - - for(i = 0; i < n_dest_regions; i++) - { - DEBUGF("dest region %d idx %d\n", i, clipped_dest_regions[i].block_idx); - DEBUGRegionPrint(clipped_dest_regions[i].region); - SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv, clipped_dest_regions[i].block_idx); - if ( source_pixmap_priv && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - if (!source->transform && source_repeat_type != RepeatPad) { - RegionTranslate(clipped_dest_regions[i].region, - x_source - x_dest, - y_source - y_dest); - clipped_source_regions = glamor_compute_clipped_regions(source_pixmap_priv, - clipped_dest_regions[i].region, - &n_source_regions, source_repeat_type, - 0, 0); - is_normal_source_fbo = 1; - } - else { - clipped_source_regions = glamor_compute_transform_clipped_regions(source_pixmap_priv, - source->transform, - clipped_dest_regions[i].region, - &n_source_regions, - x_source - x_dest, y_source - y_dest, - source_repeat_type, 0, 0); - is_normal_source_fbo = 0; - if (n_source_regions == 0) { - /* Pad the out-of-box region to (0,0,0,0). */ - null_source = 1; - n_source_regions = 1; - } else - _glamor_process_transformed_clipped_region(source_pixmap_priv, - source_repeat_type, clipped_source_regions, &n_source_regions, - &need_clean_source_fbo); - } - DEBUGF("source clipped result %d region: \n", n_source_regions); - for(j = 0; j < n_source_regions; j++) - { - if (is_normal_source_fbo) - SET_PIXMAP_FBO_CURRENT(source_pixmap_priv, - clipped_source_regions[j].block_idx); - - if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - if (is_normal_mask_fbo && is_normal_source_fbo) { - /* both mask and source are normal fbo box without transform or repeatpad. - * The region is clipped against source and then we clip it against mask here.*/ - DEBUGF("source region %d idx %d\n", j, clipped_source_regions[j].block_idx); - DEBUGRegionPrint(clipped_source_regions[j].region); - RegionTranslate(clipped_source_regions[j].region, - - x_source + x_mask, - - y_source + y_mask); - clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv, - clipped_source_regions[j].region, - &n_mask_regions, mask_repeat_type, - 0, 0); - is_normal_mask_fbo = 1; - } else if (is_normal_mask_fbo && !is_normal_source_fbo) { - assert(n_source_regions == 1); - /* The source fbo is not a normal fbo box, it has transform or repeatpad. - * the valid clip region should be the clip dest region rather than the - * clip source region.*/ - RegionTranslate(clipped_dest_regions[i].region, - - x_dest + x_mask, - - y_dest + y_mask); - clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv, - clipped_dest_regions[i].region, - &n_mask_regions, mask_repeat_type, - 0, 0); - is_normal_mask_fbo = 1; - } else { - /* This mask region has transform or repeatpad, we need clip it agains the previous - * valid region rather than the mask region. */ - if (!is_normal_source_fbo) - clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv, - mask->transform, - clipped_dest_regions[i].region, - &n_mask_regions, - x_mask - x_dest, - y_mask - y_dest, - mask_repeat_type, 0, 0); - else - clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv, - mask->transform, - clipped_source_regions[j].region, - &n_mask_regions, - x_mask - x_source, y_mask - y_source, - mask_repeat_type, 0, 0); - is_normal_mask_fbo = 0; - if (n_mask_regions == 0) { - /* Pad the out-of-box region to (0,0,0,0). */ - null_mask = 1; - n_mask_regions = 1; - } else - _glamor_process_transformed_clipped_region(mask_pixmap_priv, - mask_repeat_type, clipped_mask_regions, &n_mask_regions, - &need_clean_mask_fbo); - } - DEBUGF("mask clipped result %d region: \n", n_mask_regions); + glamor_screen_private *glamor_priv; + glamor_pixmap_clipped_regions *clipped_dest_regions; + glamor_pixmap_clipped_regions *clipped_source_regions; + glamor_pixmap_clipped_regions *clipped_mask_regions; + int n_dest_regions; + int n_mask_regions; + int n_source_regions; + int i, j, k; + int need_clean_source_fbo = 0; + int need_clean_mask_fbo = 0; + int is_normal_source_fbo = 0; + int is_normal_mask_fbo = 0; + int fixed_block_width, fixed_block_height; + int null_source, null_mask; + glamor_pixmap_private *need_free_source_pixmap_priv = NULL; + glamor_pixmap_private *need_free_mask_pixmap_priv = NULL; + int source_repeat_type = 0, mask_repeat_type = 0; + int ok = TRUE; + + if (source->repeat) + source_repeat_type = source->repeatType; + else + source_repeat_type = RepeatNone; + + if (mask && mask->repeat) + mask_repeat_type = mask->repeatType; + else + mask_repeat_type = RepeatNone; + + glamor_priv = dest_pixmap_priv->base.glamor_priv; + fixed_block_width = glamor_priv->max_fbo_size; + fixed_block_height = glamor_priv->max_fbo_size; + /* If we got an totally out-of-box region for a source or mask + * region without repeat, we need to set it as null_source and + * give it a solid color (0,0,0,0). */ + null_source = 0; + null_mask = 0; + RegionTranslate(region, -dest->pDrawable->x, -dest->pDrawable->y); + + /* need to transform the dest region to the correct sourcei/mask region. + * it's a little complex, as one single edge of the + * target region may be transformed to cross a block boundary of the + * source or mask. Then it's impossible to handle it as usual way. + * We may have to split the original dest region to smaller region, and + * make sure each region's transformed region can fit into one texture, + * and then continue this loop again, and each time when a transformed region + * cross the bound, we need to copy it to a single pixmap and do the composition + * with the new pixmap. If the transformed region doesn't cross a source/mask's + * boundary then we don't need to copy. + * + */ + if (source_pixmap_priv + && source->transform + && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + int source_transformed_block_width, source_transformed_block_height; + + if (!glamor_get_transform_block_size(source->transform, + source_pixmap_priv->large.block_w, + source_pixmap_priv->large.block_h, + &source_transformed_block_width, + &source_transformed_block_height)) + { + DEBUGF("source block size less than 1, fallback.\n"); + RegionTranslate(region, dest->pDrawable->x, dest->pDrawable->y); + return FALSE; + } + fixed_block_width = + min(fixed_block_width, source_transformed_block_width); + fixed_block_height = + min(fixed_block_height, source_transformed_block_height); + DEBUGF("new source block size %d x %d \n", fixed_block_width, + fixed_block_height); + } + + if (mask_pixmap_priv + && mask->transform && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + int mask_transformed_block_width, mask_transformed_block_height; + + if (!glamor_get_transform_block_size(mask->transform, + mask_pixmap_priv->large.block_w, + mask_pixmap_priv->large.block_h, + &mask_transformed_block_width, + &mask_transformed_block_height)) { + DEBUGF("mask block size less than 1, fallback.\n"); + RegionTranslate(region, dest->pDrawable->x, dest->pDrawable->y); + return FALSE; + } + fixed_block_width = + min(fixed_block_width, mask_transformed_block_width); + fixed_block_height = + min(fixed_block_height, mask_transformed_block_height); + DEBUGF("new mask block size %d x %d \n", fixed_block_width, + fixed_block_height); + } + + /*compute the correct block width and height whose transformed source/mask + *region can fit into one texture.*/ + if (force_clip || fixed_block_width < glamor_priv->max_fbo_size + || fixed_block_height < glamor_priv->max_fbo_size) + clipped_dest_regions = + glamor_compute_clipped_regions_ext(dest_pixmap_priv, region, + &n_dest_regions, + fixed_block_width, + fixed_block_height, 0, 0); + else + clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv, + region, + &n_dest_regions, + 0, 0, 0); + DEBUGF("dest clipped result %d region: \n", n_dest_regions); + if (source_pixmap_priv + && (source_pixmap_priv == dest_pixmap_priv || + source_pixmap_priv == mask_pixmap_priv) + && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + /* XXX self-copy... */ + need_free_source_pixmap_priv = source_pixmap_priv; + source_pixmap_priv = malloc(sizeof(*source_pixmap_priv)); + *source_pixmap_priv = *need_free_source_pixmap_priv; + need_free_source_pixmap_priv = source_pixmap_priv; + } + assert(mask_pixmap_priv != dest_pixmap_priv); + + for (i = 0; i < n_dest_regions; i++) { + DEBUGF("dest region %d idx %d\n", i, + clipped_dest_regions[i].block_idx); + DEBUGRegionPrint(clipped_dest_regions[i].region); + SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv, + clipped_dest_regions[i].block_idx); + if (source_pixmap_priv && + source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + if (!source->transform && source_repeat_type != RepeatPad) { + RegionTranslate(clipped_dest_regions[i].region, + x_source - x_dest, y_source - y_dest); + clipped_source_regions = + glamor_compute_clipped_regions(source_pixmap_priv, + clipped_dest_regions[i]. + region, &n_source_regions, + source_repeat_type, 0, 0); + is_normal_source_fbo = 1; + } + else { + clipped_source_regions = + glamor_compute_transform_clipped_regions(source_pixmap_priv, + source->transform, + clipped_dest_regions + [i].region, + &n_source_regions, + x_source - x_dest, + y_source - y_dest, + source_repeat_type, + 0, 0); + is_normal_source_fbo = 0; + if (n_source_regions == 0) { + /* Pad the out-of-box region to (0,0,0,0). */ + null_source = 1; + n_source_regions = 1; + } + else + _glamor_process_transformed_clipped_region + (source_pixmap_priv, source_repeat_type, + clipped_source_regions, &n_source_regions, + &need_clean_source_fbo); + } + DEBUGF("source clipped result %d region: \n", n_source_regions); + for (j = 0; j < n_source_regions; j++) { + if (is_normal_source_fbo) + SET_PIXMAP_FBO_CURRENT(source_pixmap_priv, + clipped_source_regions[j].block_idx); + + if (mask_pixmap_priv && + mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + if (is_normal_mask_fbo && is_normal_source_fbo) { + /* both mask and source are normal fbo box without transform or repeatpad. + * The region is clipped against source and then we clip it against mask here.*/ + DEBUGF("source region %d idx %d\n", j, + clipped_source_regions[j].block_idx); + DEBUGRegionPrint(clipped_source_regions[j].region); + RegionTranslate(clipped_source_regions[j].region, + -x_source + x_mask, -y_source + y_mask); + clipped_mask_regions = + glamor_compute_clipped_regions(mask_pixmap_priv, + clipped_source_regions + [j].region, + &n_mask_regions, + mask_repeat_type, 0, + 0); + is_normal_mask_fbo = 1; + } + else if (is_normal_mask_fbo && !is_normal_source_fbo) { + assert(n_source_regions == 1); + /* The source fbo is not a normal fbo box, it has transform or repeatpad. + * the valid clip region should be the clip dest region rather than the + * clip source region.*/ + RegionTranslate(clipped_dest_regions[i].region, + -x_dest + x_mask, -y_dest + y_mask); + clipped_mask_regions = + glamor_compute_clipped_regions(mask_pixmap_priv, + clipped_dest_regions + [i].region, + &n_mask_regions, + mask_repeat_type, 0, + 0); + is_normal_mask_fbo = 1; + } + else { + /* This mask region has transform or repeatpad, we need clip it agains the previous + * valid region rather than the mask region. */ + if (!is_normal_source_fbo) + clipped_mask_regions = + glamor_compute_transform_clipped_regions + (mask_pixmap_priv, mask->transform, + clipped_dest_regions[i].region, + &n_mask_regions, x_mask - x_dest, + y_mask - y_dest, mask_repeat_type, 0, 0); + else + clipped_mask_regions = + glamor_compute_transform_clipped_regions + (mask_pixmap_priv, mask->transform, + clipped_source_regions[j].region, + &n_mask_regions, x_mask - x_source, + y_mask - y_source, mask_repeat_type, 0, 0); + is_normal_mask_fbo = 0; + if (n_mask_regions == 0) { + /* Pad the out-of-box region to (0,0,0,0). */ + null_mask = 1; + n_mask_regions = 1; + } + else + _glamor_process_transformed_clipped_region + (mask_pixmap_priv, mask_repeat_type, + clipped_mask_regions, &n_mask_regions, + &need_clean_mask_fbo); + } + DEBUGF("mask clipped result %d region: \n", n_mask_regions); #define COMPOSITE_REGION(region) do { \ if (!glamor_composite_clipped_region(op, \ @@ -1186,139 +1263,157 @@ glamor_composite_largepixmap_region(CARD8 op, } \ } while(0) - for(k = 0; k < n_mask_regions; k++) - { - DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx); - DEBUGRegionPrint(clipped_mask_regions[k].region); - if (is_normal_mask_fbo) { - SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv, - clipped_mask_regions[k].block_idx); - DEBUGF("mask fbo off %d %d \n", - mask_pixmap_priv->large.box.x1, - mask_pixmap_priv->large.box.y1); - DEBUGF("start composite mask hasn't transform.\n"); - RegionTranslate(clipped_mask_regions[k].region, - x_dest - x_mask + dest->pDrawable->x, - y_dest - y_mask + dest->pDrawable->y); - COMPOSITE_REGION(clipped_mask_regions[k].region); - } else if (!is_normal_mask_fbo && !is_normal_source_fbo) { - DEBUGF("start composite both mask and source have transform.\n"); - RegionTranslate(clipped_dest_regions[i].region, - dest->pDrawable->x, - dest->pDrawable->y); - COMPOSITE_REGION(clipped_dest_regions[i].region); - } else { - DEBUGF("start composite only mask has transform.\n"); - RegionTranslate(clipped_source_regions[j].region, - x_dest - x_source + dest->pDrawable->x, - y_dest - y_source + dest->pDrawable->y); - COMPOSITE_REGION(clipped_source_regions[j].region); - } - RegionDestroy(clipped_mask_regions[k].region); - } - free(clipped_mask_regions); - if (null_mask) null_mask = 0; - if (need_clean_mask_fbo) { - assert(is_normal_mask_fbo == 0); - glamor_destroy_fbo(mask_pixmap_priv->base.fbo); - mask_pixmap_priv->base.fbo = NULL; - need_clean_mask_fbo = 0; - } - } else { - if (is_normal_source_fbo) { - RegionTranslate(clipped_source_regions[j].region, - -x_source + x_dest + dest->pDrawable->x, - -y_source + y_dest + dest->pDrawable->y); - COMPOSITE_REGION(clipped_source_regions[j].region); - } else { - /* Source has transform or repeatPad. dest regions is the right - * region to do the composite. */ - RegionTranslate(clipped_dest_regions[i].region, - dest->pDrawable->x, - dest->pDrawable->y); - COMPOSITE_REGION(clipped_dest_regions[i].region); - } - } - if (clipped_source_regions && clipped_source_regions[j].region) - RegionDestroy(clipped_source_regions[j].region); - } - free(clipped_source_regions); - if (null_source) null_source = 0; - if (need_clean_source_fbo) { - assert(is_normal_source_fbo == 0); - glamor_destroy_fbo(source_pixmap_priv->base.fbo); - source_pixmap_priv->base.fbo = NULL; - need_clean_source_fbo = 0; - } - } - else { - if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - if (!mask->transform && mask_repeat_type != RepeatPad) { - RegionTranslate(clipped_dest_regions[i].region, - x_mask - x_dest, - y_mask - y_dest); - clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv, - clipped_dest_regions[i].region, - &n_mask_regions, mask_repeat_type, 0, 0); - is_normal_mask_fbo = 1; - } - else { - clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv, - mask->transform, - clipped_dest_regions[i].region, - &n_mask_regions, - x_mask - x_dest, y_mask - y_dest, - mask_repeat_type, 0, 0); - is_normal_mask_fbo = 0; - if (n_mask_regions == 0) { - /* Pad the out-of-box region to (0,0,0,0). */ - null_mask = 1; - n_mask_regions = 1; - } else - _glamor_process_transformed_clipped_region(mask_pixmap_priv, - mask_repeat_type, clipped_mask_regions, &n_mask_regions, - &need_clean_mask_fbo); - } - - for(k = 0; k < n_mask_regions; k++) - { - DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx); - DEBUGRegionPrint(clipped_mask_regions[k].region); - if (is_normal_mask_fbo) { - SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv, - clipped_mask_regions[k].block_idx); - RegionTranslate(clipped_mask_regions[k].region, - x_dest - x_mask + dest->pDrawable->x, - y_dest - y_mask + dest->pDrawable->y); - COMPOSITE_REGION(clipped_mask_regions[k].region); - } else { - RegionTranslate(clipped_dest_regions[i].region, - dest->pDrawable->x, - dest->pDrawable->y); - COMPOSITE_REGION(clipped_dest_regions[i].region); - } - RegionDestroy(clipped_mask_regions[k].region); - } - free(clipped_mask_regions); - if (null_mask) null_mask = 0; - if (need_clean_mask_fbo) { - glamor_destroy_fbo(mask_pixmap_priv->base.fbo); - mask_pixmap_priv->base.fbo = NULL; - need_clean_mask_fbo = 0; - } - } - else { - RegionTranslate(clipped_dest_regions[i].region, - dest->pDrawable->x, - dest->pDrawable->y); - COMPOSITE_REGION(clipped_dest_regions[i].region); - } - } - RegionDestroy(clipped_dest_regions[i].region); - } - free(clipped_dest_regions); - free(need_free_source_pixmap_priv); - free(need_free_mask_pixmap_priv); - ok = TRUE; - return ok; + for (k = 0; k < n_mask_regions; k++) { + DEBUGF("mask region %d idx %d\n", k, + clipped_mask_regions[k].block_idx); + DEBUGRegionPrint(clipped_mask_regions[k].region); + if (is_normal_mask_fbo) { + SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv, + clipped_mask_regions[k]. + block_idx); + DEBUGF("mask fbo off %d %d \n", + mask_pixmap_priv->large.box.x1, + mask_pixmap_priv->large.box.y1); + DEBUGF("start composite mask hasn't transform.\n"); + RegionTranslate(clipped_mask_regions[k].region, + x_dest - x_mask + + dest->pDrawable->x, + y_dest - y_mask + + dest->pDrawable->y); + COMPOSITE_REGION(clipped_mask_regions[k].region); + } + else if (!is_normal_mask_fbo && !is_normal_source_fbo) { + DEBUGF + ("start composite both mask and source have transform.\n"); + RegionTranslate(clipped_dest_regions[i].region, + dest->pDrawable->x, + dest->pDrawable->y); + COMPOSITE_REGION(clipped_dest_regions[i].region); + } + else { + DEBUGF + ("start composite only mask has transform.\n"); + RegionTranslate(clipped_source_regions[j].region, + x_dest - x_source + + dest->pDrawable->x, + y_dest - y_source + + dest->pDrawable->y); + COMPOSITE_REGION(clipped_source_regions[j].region); + } + RegionDestroy(clipped_mask_regions[k].region); + } + free(clipped_mask_regions); + if (null_mask) + null_mask = 0; + if (need_clean_mask_fbo) { + assert(is_normal_mask_fbo == 0); + glamor_destroy_fbo(mask_pixmap_priv->base.fbo); + mask_pixmap_priv->base.fbo = NULL; + need_clean_mask_fbo = 0; + } + } + else { + if (is_normal_source_fbo) { + RegionTranslate(clipped_source_regions[j].region, + -x_source + x_dest + dest->pDrawable->x, + -y_source + y_dest + + dest->pDrawable->y); + COMPOSITE_REGION(clipped_source_regions[j].region); + } + else { + /* Source has transform or repeatPad. dest regions is the right + * region to do the composite. */ + RegionTranslate(clipped_dest_regions[i].region, + dest->pDrawable->x, dest->pDrawable->y); + COMPOSITE_REGION(clipped_dest_regions[i].region); + } + } + if (clipped_source_regions && clipped_source_regions[j].region) + RegionDestroy(clipped_source_regions[j].region); + } + free(clipped_source_regions); + if (null_source) + null_source = 0; + if (need_clean_source_fbo) { + assert(is_normal_source_fbo == 0); + glamor_destroy_fbo(source_pixmap_priv->base.fbo); + source_pixmap_priv->base.fbo = NULL; + need_clean_source_fbo = 0; + } + } + else { + if (mask_pixmap_priv && + mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + if (!mask->transform && mask_repeat_type != RepeatPad) { + RegionTranslate(clipped_dest_regions[i].region, + x_mask - x_dest, y_mask - y_dest); + clipped_mask_regions = + glamor_compute_clipped_regions(mask_pixmap_priv, + clipped_dest_regions[i]. + region, &n_mask_regions, + mask_repeat_type, 0, 0); + is_normal_mask_fbo = 1; + } + else { + clipped_mask_regions = + glamor_compute_transform_clipped_regions + (mask_pixmap_priv, mask->transform, + clipped_dest_regions[i].region, &n_mask_regions, + x_mask - x_dest, y_mask - y_dest, mask_repeat_type, 0, + 0); + is_normal_mask_fbo = 0; + if (n_mask_regions == 0) { + /* Pad the out-of-box region to (0,0,0,0). */ + null_mask = 1; + n_mask_regions = 1; + } + else + _glamor_process_transformed_clipped_region + (mask_pixmap_priv, mask_repeat_type, + clipped_mask_regions, &n_mask_regions, + &need_clean_mask_fbo); + } + + for (k = 0; k < n_mask_regions; k++) { + DEBUGF("mask region %d idx %d\n", k, + clipped_mask_regions[k].block_idx); + DEBUGRegionPrint(clipped_mask_regions[k].region); + if (is_normal_mask_fbo) { + SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv, + clipped_mask_regions[k]. + block_idx); + RegionTranslate(clipped_mask_regions[k].region, + x_dest - x_mask + dest->pDrawable->x, + y_dest - y_mask + dest->pDrawable->y); + COMPOSITE_REGION(clipped_mask_regions[k].region); + } + else { + RegionTranslate(clipped_dest_regions[i].region, + dest->pDrawable->x, dest->pDrawable->y); + COMPOSITE_REGION(clipped_dest_regions[i].region); + } + RegionDestroy(clipped_mask_regions[k].region); + } + free(clipped_mask_regions); + if (null_mask) + null_mask = 0; + if (need_clean_mask_fbo) { + glamor_destroy_fbo(mask_pixmap_priv->base.fbo); + mask_pixmap_priv->base.fbo = NULL; + need_clean_mask_fbo = 0; + } + } + else { + RegionTranslate(clipped_dest_regions[i].region, + dest->pDrawable->x, dest->pDrawable->y); + COMPOSITE_REGION(clipped_dest_regions[i].region); + } + } + RegionDestroy(clipped_dest_regions[i].region); + } + free(clipped_dest_regions); + free(need_free_source_pixmap_priv); + free(need_free_mask_pixmap_priv); + ok = TRUE; + return ok; } diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c index 7d5ffbb..f2afbc3 100644 --- a/glamor/glamor_picture.c +++ b/glamor/glamor_picture.c @@ -37,30 +37,30 @@ enum glamor_pixmap_status glamor_upload_picture_to_texture(PicturePtr picture) { - PixmapPtr pixmap; - assert(picture->pDrawable); - pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + PixmapPtr pixmap; - return glamor_upload_pixmap_to_texture(pixmap); -} + assert(picture->pDrawable); + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + return glamor_upload_pixmap_to_texture(pixmap); +} Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) { - if (!picture || !picture->pDrawable) - return TRUE; + if (!picture || !picture->pDrawable) + return TRUE; - return glamor_prepare_access(picture->pDrawable, access); + return glamor_prepare_access(picture->pDrawable, access); } void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access) { - if (!picture || !picture->pDrawable) - return; + if (!picture || !picture->pDrawable) + return; - glamor_finish_access(picture->pDrawable, access); + glamor_finish_access(picture->pDrawable, access); } /* @@ -71,61 +71,62 @@ glamor_finish_access_picture(PicturePtr picture, glamor_access_t access) int glamor_create_picture(PicturePtr picture) { - PixmapPtr pixmap; - glamor_pixmap_private *pixmap_priv; - - if (!picture || !picture->pDrawable) - return 0; - - pixmap = glamor_get_drawable_pixmap(picture->pDrawable); - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (!pixmap_priv) { - /* We must create a pixmap priv to track the picture format even - * if the pixmap is a pure in memory pixmap. The reason is that - * we may need to upload this pixmap to a texture on the fly. During - * the uploading, we need to know the picture format. */ - glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY); - pixmap_priv = glamor_get_pixmap_private(pixmap); - } else { - if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { - /* If the picture format is not compatible with glamor fbo format, - * we have to mark this pixmap as a separated texture, and don't - * fallback to DDX layer. */ - if (pixmap_priv->type == GLAMOR_TEXTURE_DRM - && !glamor_pict_format_is_compatible(picture->format, - pixmap->drawable.depth)) - glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE); - } - } - - pixmap_priv->base.is_picture = 1; - pixmap_priv->base.picture = picture; - - return miCreatePicture(picture); + PixmapPtr pixmap; + glamor_pixmap_private *pixmap_priv; + + if (!picture || !picture->pDrawable) + return 0; + + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!pixmap_priv) { + /* We must create a pixmap priv to track the picture format even + * if the pixmap is a pure in memory pixmap. The reason is that + * we may need to upload this pixmap to a texture on the fly. During + * the uploading, we need to know the picture format. */ + glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY); + pixmap_priv = glamor_get_pixmap_private(pixmap); + } + else { + if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { + /* If the picture format is not compatible with glamor fbo format, + * we have to mark this pixmap as a separated texture, and don't + * fallback to DDX layer. */ + if (pixmap_priv->type == GLAMOR_TEXTURE_DRM + && !glamor_pict_format_is_compatible(picture->format, + pixmap->drawable.depth)) + glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE); + } + } + + pixmap_priv->base.is_picture = 1; + pixmap_priv->base.picture = picture; + + return miCreatePicture(picture); } void glamor_destroy_picture(PicturePtr picture) { - PixmapPtr pixmap; - glamor_pixmap_private *pixmap_priv; + PixmapPtr pixmap; + glamor_pixmap_private *pixmap_priv; - if (!picture || !picture->pDrawable) - return; + if (!picture || !picture->pDrawable) + return; - pixmap = glamor_get_drawable_pixmap(picture->pDrawable); - pixmap_priv = glamor_get_pixmap_private(pixmap); + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + pixmap_priv = glamor_get_pixmap_private(pixmap); - if (pixmap_priv) { - pixmap_priv->base.is_picture = 0; - pixmap_priv->base.picture = NULL; - } - miDestroyPicture(picture); + if (pixmap_priv) { + pixmap_priv->base.is_picture = 0; + pixmap_priv->base.picture = NULL; + } + miDestroyPicture(picture); } void glamor_picture_format_fixup(PicturePtr picture, - glamor_pixmap_private * pixmap_priv) + glamor_pixmap_private * pixmap_priv) { - pixmap_priv->base.picture = picture; + pixmap_priv->base.picture = picture; } diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index be7aa3d..69e581c 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -37,21 +37,20 @@ */ void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, - int *x, int *y) + int *x, int *y) { #ifdef COMPOSITE - if (drawable->type == DRAWABLE_WINDOW) { - *x = -pixmap->screen_x; - *y = -pixmap->screen_y; - return; - } + if (drawable->type == DRAWABLE_WINDOW) { + *x = -pixmap->screen_x; + *y = -pixmap->screen_y; + return; + } #endif - *x = 0; - *y = 0; + *x = 0; + *y = 0; } - void glamor_pixmap_init(ScreenPtr screen) { @@ -64,173 +63,168 @@ glamor_pixmap_fini(ScreenPtr screen) } void -glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int width, int height) +glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, + int width, int height) { - glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv); - dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); + glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv); + + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb); #ifndef GLAMOR_GLES2 - dispatch->glMatrixMode(GL_PROJECTION); - dispatch->glLoadIdentity(); - dispatch->glMatrixMode(GL_MODELVIEW); - dispatch->glLoadIdentity(); + dispatch->glMatrixMode(GL_PROJECTION); + dispatch->glLoadIdentity(); + dispatch->glMatrixMode(GL_MODELVIEW); + dispatch->glLoadIdentity(); #endif - dispatch->glViewport(x0, y0, - width, height); + dispatch->glViewport(x0, y0, width, height); - glamor_put_dispatch(fbo->glamor_priv); + glamor_put_dispatch(fbo->glamor_priv); } void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv) { - int w,h; + int w, h; - PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h); - glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, - w, h); + PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h); + glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, w, h); } int glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv) { - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - return -1; + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return -1; - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - return 0; + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + return 0; } int glamor_set_destination_pixmap(PixmapPtr pixmap) { - int err; - glamor_pixmap_private *pixmap_priv = - glamor_get_pixmap_private(pixmap); + int err; + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - err = glamor_set_destination_pixmap_priv(pixmap_priv); - return err; + err = glamor_set_destination_pixmap_priv(pixmap_priv); + return err; } Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask) { - if (glamor_pm_is_solid(&pixmap->drawable, planemask)) { - return GL_TRUE; - } + if (glamor_pm_is_solid(&pixmap->drawable, planemask)) { + return GL_TRUE; + } - glamor_fallback("unsupported planemask %lx\n", planemask); - return GL_FALSE; + glamor_fallback("unsupported planemask %lx\n", planemask); + return GL_FALSE; } Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu) { #ifndef GLAMOR_GLES2 - if (alu == GXcopy) { - dispatch->glDisable(GL_COLOR_LOGIC_OP); - return TRUE; - } - dispatch->glEnable(GL_COLOR_LOGIC_OP); - switch (alu) { - case GXclear: - dispatch->glLogicOp(GL_CLEAR); - break; - case GXand: - dispatch->glLogicOp(GL_AND); - break; - case GXandReverse: - dispatch->glLogicOp(GL_AND_REVERSE); - break; - case GXandInverted: - dispatch->glLogicOp(GL_AND_INVERTED); - break; - case GXnoop: - dispatch->glLogicOp(GL_NOOP); - break; - case GXxor: - dispatch->glLogicOp(GL_XOR); - break; - case GXor: - dispatch->glLogicOp(GL_OR); - break; - case GXnor: - dispatch->glLogicOp(GL_NOR); - break; - case GXequiv: - dispatch->glLogicOp(GL_EQUIV); - break; - case GXinvert: - dispatch->glLogicOp(GL_INVERT); - break; - case GXorReverse: - dispatch->glLogicOp(GL_OR_REVERSE); - break; - case GXcopyInverted: - dispatch->glLogicOp(GL_COPY_INVERTED); - break; - case GXorInverted: - dispatch->glLogicOp(GL_OR_INVERTED); - break; - case GXnand: - dispatch->glLogicOp(GL_NAND); - break; - case GXset: - dispatch->glLogicOp(GL_SET); - break; - default: - glamor_fallback("unsupported alu %x\n", alu); - return FALSE; - } + if (alu == GXcopy) { + dispatch->glDisable(GL_COLOR_LOGIC_OP); + return TRUE; + } + dispatch->glEnable(GL_COLOR_LOGIC_OP); + switch (alu) { + case GXclear: + dispatch->glLogicOp(GL_CLEAR); + break; + case GXand: + dispatch->glLogicOp(GL_AND); + break; + case GXandReverse: + dispatch->glLogicOp(GL_AND_REVERSE); + break; + case GXandInverted: + dispatch->glLogicOp(GL_AND_INVERTED); + break; + case GXnoop: + dispatch->glLogicOp(GL_NOOP); + break; + case GXxor: + dispatch->glLogicOp(GL_XOR); + break; + case GXor: + dispatch->glLogicOp(GL_OR); + break; + case GXnor: + dispatch->glLogicOp(GL_NOR); + break; + case GXequiv: + dispatch->glLogicOp(GL_EQUIV); + break; + case GXinvert: + dispatch->glLogicOp(GL_INVERT); + break; + case GXorReverse: + dispatch->glLogicOp(GL_OR_REVERSE); + break; + case GXcopyInverted: + dispatch->glLogicOp(GL_COPY_INVERTED); + break; + case GXorInverted: + dispatch->glLogicOp(GL_OR_INVERTED); + break; + case GXnand: + dispatch->glLogicOp(GL_NAND); + break; + case GXset: + dispatch->glLogicOp(GL_SET); + break; + default: + glamor_fallback("unsupported alu %x\n", alu); + return FALSE; + } #else - if (alu != GXcopy) - return FALSE; + if (alu != GXcopy) + return FALSE; #endif - return TRUE; + return TRUE; } static void * -_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride, int revert) +_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, + int stride, int revert) { - PictFormatShort dst_format, src_format; - pixman_image_t *dst_image; - pixman_image_t *src_image; - int src_stride; - - if (revert == REVERT_UPLOADING_A1) { - src_format = PICT_a1; - dst_format = PICT_a8; - src_stride = PixmapBytePad(w, 1); - } else { - dst_format = PICT_a1; - src_format = PICT_a8; - src_stride = (((w * 8 + 7) / 8) + 3) & ~3; - } - - dst_image = pixman_image_create_bits(dst_format, - w, h, - dst_bits, - stride); - if (dst_image == NULL) { - return NULL; - } - - src_image = pixman_image_create_bits(src_format, - w, h, - src_bits, - src_stride); - - if (src_image == NULL) { - pixman_image_unref(dst_image); - return NULL; - } - - pixman_image_composite(PictOpSrc, src_image, NULL, dst_image, - 0, 0, 0, 0, 0, 0, - w,h); - - pixman_image_unref(src_image); - pixman_image_unref(dst_image); - return dst_bits; + PictFormatShort dst_format, src_format; + pixman_image_t *dst_image; + pixman_image_t *src_image; + int src_stride; + + if (revert == REVERT_UPLOADING_A1) { + src_format = PICT_a1; + dst_format = PICT_a8; + src_stride = PixmapBytePad(w, 1); + } + else { + dst_format = PICT_a1; + src_format = PICT_a8; + src_stride = (((w * 8 + 7) / 8) + 3) & ~3; + } + + dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride); + if (dst_image == NULL) { + return NULL; + } + + src_image = pixman_image_create_bits(src_format, + w, h, src_bits, src_stride); + + if (src_image == NULL) { + pixman_image_unref(dst_image); + return NULL; + } + + pixman_image_composite(PictOpSrc, src_image, NULL, dst_image, + 0, 0, 0, 0, 0, 0, w, h); + + pixman_image_unref(src_image); + pixman_image_unref(dst_image); + return dst_bits; } #define ADJUST_BITS(d, src_bits, dst_bits) (((dst_bits) == (src_bits)) ? (d) : \ @@ -273,76 +267,77 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st } while (0) static void * -_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb) +_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, + int stride, int no_alpha, int revert, + int swap_rb) { - int x,y; - unsigned int *words, *saved_words, *source_words; - int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING); - - source_words = src_bits; - words = dst_bits; - saved_words = words; - - for (y = 0; y < h; y++) - { - DEBUGF("Line %d : ", y); - for (x = 0; x < w; x++) - { - unsigned int pixel = source_words[x]; - - if (revert == REVERT_DOWNLOADING_2_10_10_10) - GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, - 24, 8, 16, 8, 8, 8, 0, 8, - 30, 2, 20, 10, 10, 10, 0, 10); - else - GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, - 30, 2, 20, 10, 10, 10, 0, 10, - 24, 8, 16, 8, 8, 8, 0, 8); - DEBUGF("%x:%x ", pixel, words[x]); - } - DEBUGF("\n"); - words += stride / sizeof(*words); - source_words += stride / sizeof(*words); - } - DEBUGF("\n"); - return saved_words; + int x, y; + unsigned int *words, *saved_words, *source_words; + int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || + swap_rb == SWAP_NONE_UPLOADING); + + source_words = src_bits; + words = dst_bits; + saved_words = words; + + for (y = 0; y < h; y++) { + DEBUGF("Line %d : ", y); + for (x = 0; x < w; x++) { + unsigned int pixel = source_words[x]; + + if (revert == REVERT_DOWNLOADING_2_10_10_10) + GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, + 24, 8, 16, 8, 8, 8, 0, 8, + 30, 2, 20, 10, 10, 10, 0, 10); + else + GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, + 30, 2, 20, 10, 10, 10, 0, 10, + 24, 8, 16, 8, 8, 8, 0, 8); + DEBUGF("%x:%x ", pixel, words[x]); + } + DEBUGF("\n"); + words += stride / sizeof(*words); + source_words += stride / sizeof(*words); + } + DEBUGF("\n"); + return saved_words; } static void * -_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb) +_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, + int stride, int no_alpha, int revert, int swap_rb) { - int x,y; - unsigned short *words, *saved_words, *source_words; - int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING); - - words = dst_bits; - source_words = src_bits; - saved_words = words; - - for (y = 0; y < h; y++) - { - DEBUGF("Line %d : ", y); - for (x = 0; x < w; x++) - { - unsigned short pixel = source_words[x]; - - if (revert == REVERT_DOWNLOADING_1_5_5_5) - GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, - 0, 1, 1, 5, 6, 5, 11, 5, - 15, 1, 10, 5, 5, 5, 0, 5); - else - GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, - 15, 1, 10, 5, 5, 5, 0, 5, - 0, 1, 1, 5, 6, 5, 11, 5); - DEBUGF("%04x:%04x ", pixel, words[x]); - } - DEBUGF("\n"); - words += stride / sizeof(*words); - source_words += stride / sizeof(*words); - } - DEBUGF("\n"); - return saved_words; + int x, y; + unsigned short *words, *saved_words, *source_words; + int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || + swap_rb == SWAP_NONE_UPLOADING); + + words = dst_bits; + source_words = src_bits; + saved_words = words; + + for (y = 0; y < h; y++) { + DEBUGF("Line %d : ", y); + for (x = 0; x < w; x++) { + unsigned short pixel = source_words[x]; + + if (revert == REVERT_DOWNLOADING_1_5_5_5) + GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, + 0, 1, 1, 5, 6, 5, 11, 5, + 15, 1, 10, 5, 5, 5, 0, 5); + else + GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap, + 15, 1, 10, 5, 5, 5, 0, 5, + 0, 1, 1, 5, 6, 5, 11, 5); + DEBUGF("%04x:%04x ", pixel, words[x]); + } + DEBUGF("\n"); + words += stride / sizeof(*words); + source_words += stride / sizeof(*words); + } + DEBUGF("\n"); + return saved_words; } /* @@ -364,18 +359,28 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int */ static void * -glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb) +glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, + int stride, int no_alpha, int revert, int swap_rb) { - if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) { - return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride, revert); - } else if (revert == REVERT_DOWNLOADING_2_10_10_10 || revert == REVERT_UPLOADING_2_10_10_10) { - return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb); - } else if (revert == REVERT_DOWNLOADING_1_5_5_5 || revert == REVERT_UPLOADING_1_5_5_5) { - return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb); - } else - ErrorF("convert a non-supported mode %x.\n", revert); - - return NULL; + if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) { + return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride, + revert); + } + else if (revert == REVERT_DOWNLOADING_2_10_10_10 || + revert == REVERT_UPLOADING_2_10_10_10) { + return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h, + stride, no_alpha, revert, + swap_rb); + } + else if (revert == REVERT_DOWNLOADING_1_5_5_5 || + revert == REVERT_UPLOADING_1_5_5_5) { + return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride, + no_alpha, revert, swap_rb); + } + else + ErrorF("convert a non-supported mode %x.\n", revert); + + return NULL; } /** @@ -385,198 +390,182 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int s int in_restore = 0; static void __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex, - GLenum format, - GLenum type, - int x, int y, int w, int h, - void *bits, int pbo) + GLenum format, + GLenum type, + int x, int y, int w, int h, + void *bits, int pbo) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - glamor_gl_dispatch *dispatch; - int non_sub = 0; - unsigned int iformat = 0; - - dispatch = glamor_get_dispatch(glamor_priv); - if (*tex == 0) { - dispatch->glGenTextures(1, tex); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - gl_iformat_for_depth(pixmap->drawable.depth, &iformat); - else - iformat = format; - non_sub = 1; - assert(x == 0 && y == 0); - } - - dispatch->glBindTexture(GL_TEXTURE_2D, *tex); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - - if (bits == NULL) - dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, - pbo); - if (non_sub) - dispatch->glTexImage2D(GL_TEXTURE_2D, - 0, iformat, w, h, 0, - format, type, - bits); - else - dispatch->glTexSubImage2D(GL_TEXTURE_2D, - 0, x, y, w, h, - format, type, - bits); - - if (bits == NULL) - dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch; + int non_sub = 0; + unsigned int iformat = 0; + + dispatch = glamor_get_dispatch(glamor_priv); + if (*tex == 0) { + dispatch->glGenTextures(1, tex); + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + gl_iformat_for_depth(pixmap->drawable.depth, &iformat); + else + iformat = format; + non_sub = 1; + assert(x == 0 && y == 0); + } + + dispatch->glBindTexture(GL_TEXTURE_2D, *tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + if (bits == NULL) + dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + if (non_sub) + dispatch->glTexImage2D(GL_TEXTURE_2D, + 0, iformat, w, h, 0, format, type, bits); + else + dispatch->glTexSubImage2D(GL_TEXTURE_2D, + 0, x, y, w, h, format, type, bits); + + if (bits == NULL) + dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glamor_put_dispatch(glamor_priv); } static Bool -_glamor_upload_bits_to_pixmap_texture(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_upload_bits_to_pixmap_texture(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_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - glamor_gl_dispatch *dispatch; - 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, - 0, 1 - }; - 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; - - if (revert > REVERT_NORMAL) { - /* XXX if we are restoring the pixmap, then we may not need to allocate - * new buffer */ - void *converted_bits; - - if (pixmap->drawable.depth == 1) - stride = (((w * 8 + 7) / 8) + 3) & ~3; - - converted_bits = malloc(h * stride); - - if (converted_bits == NULL) - return FALSE; - bits = glamor_color_convert_to_bits(bits, converted_bits, w, h, - stride, - no_alpha, revert, swap_rb); - if (bits == NULL) { - ErrorF("Failed to convert pixmap no_alpha %d," - "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb); - return FALSE; - } - no_alpha = 0; - revert = REVERT_NONE; - swap_rb = SWAP_NONE_UPLOADING; - need_free_bits = TRUE; - } - -ready_to_upload: - - /* 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 + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch; + 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, + 0, 1 + }; + 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; + + if (revert > REVERT_NORMAL) { + /* XXX if we are restoring the pixmap, then we may not need to allocate + * new buffer */ + void *converted_bits; + + if (pixmap->drawable.depth == 1) + stride = (((w * 8 + 7) / 8) + 3) & ~3; + + converted_bits = malloc(h * stride); + + if (converted_bits == NULL) + return FALSE; + bits = glamor_color_convert_to_bits(bits, converted_bits, w, h, + stride, no_alpha, revert, swap_rb); + if (bits == NULL) { + ErrorF("Failed to convert pixmap no_alpha %d," + "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb); + return FALSE; + } + no_alpha = 0; + revert = REVERT_NONE; + swap_rb = SWAP_NONE_UPLOADING; + need_free_bits = TRUE; + } + + ready_to_upload: + + /* 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 #ifdef WALKAROUND_LARGE_TEXTURE_MAP - && pixmap_priv->type != GLAMOR_TEXTURE_LARGE + && pixmap_priv->type != GLAMOR_TEXTURE_LARGE #endif - ) { - int fbo_x_off, fbo_y_off; - assert(pixmap_priv->base.fbo->tex); - pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off); - - assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0); - assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width); - assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height); - __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex, - format, type, - x + fbo_x_off, y + fbo_y_off, w, h, - bits, pbo); - return TRUE; - } - - if (need_flip) - ptexcoords = texcoords; - else - 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); - /* Slow path, we need to flip y or wire alpha to 1. */ - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - vertices); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - ptexcoords); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - __glamor_upload_pixmap_to_texture(pixmap, &tex, - format, type, - 0, 0, w, h, - bits, pbo); - dispatch->glActiveTexture(GL_TEXTURE0); - dispatch->glBindTexture(GL_TEXTURE_2D, tex); - - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_NEAREST); + ) { + int fbo_x_off, fbo_y_off; + + assert(pixmap_priv->base.fbo->tex); + pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off); + + assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0); + assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width); + assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height); + __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex, + format, type, + x + fbo_x_off, y + fbo_y_off, w, h, + bits, pbo); + return TRUE; + } + + if (need_flip) + ptexcoords = texcoords; + else + 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); + /* Slow path, we need to flip y or wire alpha to 1. */ + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), vertices); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), ptexcoords); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + __glamor_upload_pixmap_to_texture(pixmap, &tex, + format, type, 0, 0, w, h, bits, pbo); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); + + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); #ifndef GLAMOR_GLES2 - dispatch->glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif - dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); - dispatch->glUniform1i(glamor_priv-> - finish_access_revert[no_alpha], - revert); - dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], - swap_rb); + dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], + swap_rb); - dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); #ifndef GLAMOR_GLES2 - dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glDisable(GL_TEXTURE_2D); #endif - dispatch->glUseProgram(0); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glDeleteTextures(1, &tex); - dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0); + dispatch->glUseProgram(0); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDeleteTextures(1, &tex); + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0); - glamor_put_dispatch(glamor_priv); + glamor_put_dispatch(glamor_priv); - if (need_free_bits) - free(bits); - return TRUE; + if (need_free_bits) + free(bits); + return TRUE; } /* @@ -587,54 +576,53 @@ ready_to_upload: * 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) +glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, + int revert, int swap_rb) { - int flag = 0; - glamor_pixmap_private *pixmap_priv; - glamor_screen_private *glamor_priv; - glamor_pixmap_fbo *fbo; - GLenum iformat; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - - if (pixmap_priv->base.gl_fbo) - return 0; - - if (pixmap_priv->base.fbo - && (pixmap_priv->base.fbo->width < pixmap->drawable.width - || pixmap_priv->base.fbo->height < pixmap->drawable.height)) { - fbo = glamor_pixmap_detach_fbo(pixmap_priv); - glamor_destroy_fbo(fbo); - } - - if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb) - return 0; - - if (!(no_alpha - || (revert == REVERT_NORMAL) - || (swap_rb != SWAP_NONE_UPLOADING) - || !glamor_priv->yInverted)) { - /* We don't need a fbo, a simple texture uploading should work. */ - - flag = GLAMOR_CREATE_FBO_NO_FBO; - } - - if ((flag == GLAMOR_CREATE_FBO_NO_FBO - && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex) - || (flag == 0 - && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)) - return 0; - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - gl_iformat_for_depth(pixmap->drawable.depth, &iformat); - else - iformat = format; - - if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag)) - return -1; - - return 0; + int flag = 0; + glamor_pixmap_private *pixmap_priv; + glamor_screen_private *glamor_priv; + glamor_pixmap_fbo *fbo; + GLenum iformat; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); + + if (pixmap_priv->base.gl_fbo) + return 0; + + if (pixmap_priv->base.fbo + && (pixmap_priv->base.fbo->width < pixmap->drawable.width + || pixmap_priv->base.fbo->height < pixmap->drawable.height)) { + fbo = glamor_pixmap_detach_fbo(pixmap_priv); + glamor_destroy_fbo(fbo); + } + + if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb) + return 0; + + if (!(no_alpha || (revert == REVERT_NORMAL) + || (swap_rb != SWAP_NONE_UPLOADING) + || !glamor_priv->yInverted)) { + /* We don't need a fbo, a simple texture uploading should work. */ + + flag = GLAMOR_CREATE_FBO_NO_FBO; + } + + if ((flag == GLAMOR_CREATE_FBO_NO_FBO + && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex) + || (flag == 0 && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)) + return 0; + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + gl_iformat_for_depth(pixmap->drawable.depth, &iformat); + else + iformat = format; + + if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag)) + return -1; + + return 0; } /* @@ -642,185 +630,188 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int * */ static void glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits, - int src_stride, int bpp, - int x, int y, int w, int h) + int src_stride, int bpp, int x, int y, int w, int h) { - int j; - int byte_per_pixel; - - byte_per_pixel = bpp / 8; - src_bits += y * src_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; - } + int j; + int byte_per_pixel; + + byte_per_pixel = bpp / 8; + src_bits += y * src_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; + } } + /* * 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 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; - } -} + 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) +glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, + int h, int stride, void *bits, int pbo) { - 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, 1)) { - glamor_fallback("Unknown pixmap depth %d.\n", - pixmap->drawable.depth); - return TRUE; - } - if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb)) - return FALSE; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - 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->base.glamor_priv->max_fbo_size, - pixmap_priv->base.glamor_priv->max_fbo_size, 0, 0); - DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap); - 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); - DEBUGF("split to %d boxes\n", nbox); - 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; - glamor_put_bits(temp_bits, temp_stride, bits, stride, - pixmap->drawable.bitsPerPixel, - boxes[j].x1 - x, boxes[j].y1 - y, - boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1); - } - DEBUGF("upload x %d y %d w %d h %d temp stride %d \n", - boxes[j].x1 - x, boxes[j].y1 - y, - boxes[j].x2 - boxes[j].x1, - boxes[j].y2 - boxes[j].y1, temp_stride); - if (_glamor_upload_bits_to_pixmap_texture(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) == FALSE) { - RegionUninit(®ion); - free(sub_bits); - assert(0); - return FALSE; - } - } - RegionDestroy(clipped_regions[i].region); - } - free(sub_bits); - free(clipped_regions); - RegionUninit(®ion); - return TRUE; - } else - return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb, - x, y, w, h, stride, bits, pbo); + 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, 1)) { + glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); + return TRUE; + } + if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb)) + return FALSE; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + 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->base. + glamor_priv->max_fbo_size, + pixmap_priv->base. + glamor_priv->max_fbo_size, 0, + 0); + DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap); + 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); + DEBUGF("split to %d boxes\n", nbox); + 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; + glamor_put_bits(temp_bits, temp_stride, bits, stride, + pixmap->drawable.bitsPerPixel, + boxes[j].x1 - x, boxes[j].y1 - y, + boxes[j].x2 - boxes[j].x1, + boxes[j].y2 - boxes[j].y1); + } + DEBUGF("upload x %d y %d w %d h %d temp stride %d \n", + boxes[j].x1 - x, boxes[j].y1 - y, + boxes[j].x2 - boxes[j].x1, + boxes[j].y2 - boxes[j].y1, temp_stride); + if (_glamor_upload_bits_to_pixmap_texture + (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) == FALSE) { + RegionUninit(®ion); + free(sub_bits); + assert(0); + return FALSE; + } + } + RegionDestroy(clipped_regions[i].region); + } + free(sub_bits); + free(clipped_regions); + RegionUninit(®ion); + return TRUE; + } + else + return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, + no_alpha, revert, swap_rb, + x, y, w, h, stride, bits, + pbo); } enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr pixmap) { - glamor_pixmap_private *pixmap_priv; - void *data; - int pbo; - int ret; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if ((pixmap_priv->base.fbo) - && (pixmap_priv->base.fbo->pbo_valid)) { - data = NULL; - pbo = pixmap_priv->base.fbo->pbo; - } else { - data = pixmap->devPrivate.ptr; - pbo = 0; - } - - if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->devKind, - data, pbo)) - ret = GLAMOR_UPLOAD_DONE; - else - ret = GLAMOR_UPLOAD_FAILED; - - return ret; + glamor_pixmap_private *pixmap_priv; + void *data; + int pbo; + int ret; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + + if ((pixmap_priv->base.fbo) + && (pixmap_priv->base.fbo->pbo_valid)) { + data = NULL; + pbo = pixmap_priv->base.fbo->pbo; + } + else { + data = pixmap->devPrivate.ptr; + pbo = 0; + } + + if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->devKind, data, pbo)) + ret = GLAMOR_UPLOAD_DONE; + else + ret = GLAMOR_UPLOAD_FAILED; + + 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"); + if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE) + LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n"); } /* @@ -832,83 +823,68 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap) * */ glamor_pixmap_fbo * -glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format, - GLenum type, int no_alpha, int revert, int swap_rb) - +glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, + GLenum format, GLenum type, int no_alpha, + int revert, int swap_rb) { - glamor_pixmap_private *source_priv; - glamor_screen_private *glamor_priv; - ScreenPtr screen; - glamor_pixmap_fbo *temp_fbo; - glamor_gl_dispatch *dispatch; - float temp_xscale, temp_yscale, source_xscale, source_yscale; - static float vertices[8]; - static float texcoords[8]; - - screen = source->drawable.pScreen; - - glamor_priv = glamor_get_screen_private(screen); - source_priv = glamor_get_pixmap_private(source); - temp_fbo = glamor_create_fbo(glamor_priv, - w, h, - format, - 0); - if (temp_fbo == NULL) - return NULL; - - dispatch = glamor_get_dispatch(glamor_priv); - temp_xscale = 1.0 / w; - temp_yscale = 1.0 / h; - - glamor_set_normalize_vcoords((struct glamor_pixmap_private*)NULL,temp_xscale, - temp_yscale, - 0, 0, - w, h, - glamor_priv->yInverted, - vertices); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - vertices); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - - pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale); - glamor_set_normalize_tcoords(source_priv, source_xscale, - source_yscale, - x, y, - x + w, y + h, - glamor_priv->yInverted, - texcoords); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - texcoords); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - - dispatch->glActiveTexture(GL_TEXTURE0); - dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - - glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h); - dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); - dispatch->glUniform1i(glamor_priv-> - finish_access_revert[no_alpha], - revert); - dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], - swap_rb); - - dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); - return temp_fbo; + glamor_pixmap_private *source_priv; + glamor_screen_private *glamor_priv; + ScreenPtr screen; + glamor_pixmap_fbo *temp_fbo; + glamor_gl_dispatch *dispatch; + float temp_xscale, temp_yscale, source_xscale, source_yscale; + static float vertices[8]; + static float texcoords[8]; + + screen = source->drawable.pScreen; + + glamor_priv = glamor_get_screen_private(screen); + source_priv = glamor_get_pixmap_private(source); + temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0); + if (temp_fbo == NULL) + return NULL; + + dispatch = glamor_get_dispatch(glamor_priv); + temp_xscale = 1.0 / w; + temp_yscale = 1.0 / h; + + glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL, + temp_xscale, temp_yscale, 0, 0, w, h, + glamor_priv->yInverted, vertices); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), vertices); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + + pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale); + glamor_set_normalize_tcoords(source_priv, source_xscale, + source_yscale, + x, y, + x + w, y + h, + glamor_priv->yInverted, texcoords); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), texcoords); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h); + dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); + dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert); + dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], + swap_rb); + + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); + return temp_fbo; } /* @@ -918,263 +894,263 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe 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) + 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, *read; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(pixmap->drawable.pScreen); - glamor_gl_dispatch *dispatch; - 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_WO: - return bits; - 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_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; - } - - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->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); - dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1); - } - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) { - assert(pbo > 0); - dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); - dispatch->glBufferData(GL_PIXEL_PACK_BUFFER, - stride * - h, - NULL, gl_usage); - } - - dispatch->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); - dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0); - } - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) { - bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, - gl_access); - dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - } - } else { - unsigned int temp_pbo; - int yy; - - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glGenBuffers(1, &temp_pbo); - dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, - temp_pbo); - dispatch->glBufferData(GL_PIXEL_PACK_BUFFER, - stride * - h, - NULL, GL_STREAM_READ); - dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, - format, type, 0); - read = dispatch->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); - dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - dispatch->glDeleteBuffers(1, &temp_pbo); - } - - dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0); - glamor_put_dispatch(glamor_priv); - - 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; + glamor_pixmap_private *pixmap_priv; + GLenum gl_access = 0, gl_usage = 0; + void *data, *read; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(pixmap->drawable.pScreen); + glamor_gl_dispatch *dispatch; + 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_WO: + return bits; + 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_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; + } + + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->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); + dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1); + } + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) { + assert(pbo > 0); + dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); + dispatch->glBufferData(GL_PIXEL_PACK_BUFFER, + stride * h, NULL, gl_usage); + } + + dispatch->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); + dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0); + } + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) { + bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access); + dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + } + } + else { + unsigned int temp_pbo; + int yy; + + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glGenBuffers(1, &temp_pbo); + dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo); + dispatch->glBufferData(GL_PIXEL_PACK_BUFFER, + stride * h, NULL, GL_STREAM_READ); + dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, + format, type, 0); + read = dispatch->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); + dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + dispatch->glDeleteBuffers(1, &temp_pbo); + } + + dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0); + glamor_put_dispatch(glamor_priv); + + 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) + 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->base.glamor_priv->max_fbo_size, - pixmap_priv->base.glamor_priv->max_fbo_size, 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); + 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->base. + glamor_priv->max_fbo_size, + pixmap_priv->base. + glamor_priv->max_fbo_size, 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. @@ -1187,128 +1163,123 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h, 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); - glamor_gl_dispatch *dispatch; - 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 (access == GLAMOR_ACCESS_WO - || 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); - } else { - dispatch = glamor_get_dispatch(glamor_priv); - if (pixmap_priv->base.fbo->pbo == 0) - dispatch->glGenBuffers(1, - &pixmap_priv->base.fbo->pbo); - glamor_put_dispatch(glamor_priv); - 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; + 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); + glamor_gl_dispatch *dispatch; + 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 (access == GLAMOR_ACCESS_WO + || 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); + } + else { + dispatch = glamor_get_dispatch(glamor_priv); + if (pixmap_priv->base.fbo->pbo == 0) + dispatch->glGenBuffers(1, &pixmap_priv->base.fbo->pbo); + glamor_put_dispatch(glamor_priv); + 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 -glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv) +glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private * pixmap_priv) { - glamor_pixmap_fbo *old_fbo; - glamor_pixmap_fbo *new_fbo = NULL; - PixmapPtr scratch = NULL; - glamor_pixmap_private *scratch_priv; - DrawablePtr drawable; - GCPtr gc = NULL; - int ret = FALSE; - - drawable = &pixmap_priv->base.pixmap->drawable; - - if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)) - return TRUE; - - old_fbo = pixmap_priv->base.fbo; - - if (!old_fbo) - return FALSE; - - gc = GetScratchGC(drawable->depth, screen); - if (!gc) - goto fail; - - scratch = glamor_create_pixmap(screen, drawable->width, drawable->height, - drawable->depth, - GLAMOR_CREATE_PIXMAP_FIXUP); - - scratch_priv = glamor_get_pixmap_private(scratch); - - if (!scratch_priv->base.fbo) - goto fail; - - ValidateGC(&scratch->drawable, gc); - glamor_copy_area(drawable, - &scratch->drawable, - gc, 0, 0, - drawable->width, drawable->height, - 0, 0); - old_fbo = glamor_pixmap_detach_fbo(pixmap_priv); - new_fbo = glamor_pixmap_detach_fbo(scratch_priv); - glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo); - glamor_pixmap_attach_fbo(scratch, old_fbo); - - DEBUGF("old %dx%d type %d\n", - drawable->width, drawable->height, pixmap_priv->type); - DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n", - old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, new_fbo->width, new_fbo->height); - ret = TRUE; -fail: - if (gc) - FreeScratchGC(gc); - if (scratch) - glamor_destroy_pixmap(scratch); - - return ret; + glamor_pixmap_fbo *old_fbo; + glamor_pixmap_fbo *new_fbo = NULL; + PixmapPtr scratch = NULL; + glamor_pixmap_private *scratch_priv; + DrawablePtr drawable; + GCPtr gc = NULL; + int ret = FALSE; + + drawable = &pixmap_priv->base.pixmap->drawable; + + if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)) + return TRUE; + + old_fbo = pixmap_priv->base.fbo; + + if (!old_fbo) + return FALSE; + + gc = GetScratchGC(drawable->depth, screen); + if (!gc) + goto fail; + + scratch = glamor_create_pixmap(screen, drawable->width, drawable->height, + drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP); + + scratch_priv = glamor_get_pixmap_private(scratch); + + if (!scratch_priv->base.fbo) + goto fail; + + ValidateGC(&scratch->drawable, gc); + glamor_copy_area(drawable, + &scratch->drawable, + gc, 0, 0, drawable->width, drawable->height, 0, 0); + old_fbo = glamor_pixmap_detach_fbo(pixmap_priv); + new_fbo = glamor_pixmap_detach_fbo(scratch_priv); + glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo); + glamor_pixmap_attach_fbo(scratch, old_fbo); + + DEBUGF("old %dx%d type %d\n", + drawable->width, drawable->height, pixmap_priv->type); + DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n", + old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, + new_fbo->width, new_fbo->height); + ret = TRUE; + fail: + if (gc) + FreeScratchGC(gc); + if (scratch) + glamor_destroy_pixmap(scratch); + + return ret; } /* @@ -1328,106 +1299,120 @@ fail: * * */ PixmapPtr -glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access) +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; - if (access == GLAMOR_ACCESS_WO) { - sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h, - pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU); - return sub_pixmap; - } - - 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; - } + 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; + if (access == GLAMOR_ACCESS_WO) { + sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h, + pixmap->drawable.depth, + GLAMOR_CREATE_PIXMAP_CPU); + return sub_pixmap; + } + + 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); + 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; + 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) +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); + 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_polyfillrect.c b/glamor/glamor_polyfillrect.c index 4e1f7b3..a25fc4e 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -35,93 +35,90 @@ static Bool _glamor_poly_fill_rect(DrawablePtr drawable, - GCPtr gc, int nrect, xRectangle * prect, Bool fallback) + GCPtr gc, int nrect, xRectangle *prect, Bool fallback) { - int fullX1, fullX2, fullY1, fullY2; - int xorg, yorg; - int n; - register BoxPtr pbox; - RegionPtr pClip = fbGetCompositeClip(gc); - Bool ret = FALSE; + int fullX1, fullX2, fullY1, fullY2; + int xorg, yorg; + int n; + register BoxPtr pbox; + RegionPtr pClip = fbGetCompositeClip(gc); + Bool ret = FALSE; - xorg = drawable->x; - yorg = drawable->y; + xorg = drawable->x; + yorg = drawable->y; - while (nrect--) { - fullX1 = prect->x + xorg; - fullY1 = prect->y + yorg; - fullX2 = fullX1 + (int) prect->width; - fullY2 = fullY1 + (int) prect->height; + while (nrect--) { + fullX1 = prect->x + xorg; + fullY1 = prect->y + yorg; + fullX2 = fullX1 + (int) prect->width; + fullY2 = fullY1 + (int) prect->height; - n = REGION_NUM_RECTS(pClip); - pbox = REGION_RECTS(pClip); - /* - * clip the rectangle to each box in the clip region - * this is logically equivalent to calling Intersect(), - * but rectangles may overlap each other here. - */ - while (n--) { - int x1 = fullX1; - int x2 = fullX2; - int y1 = fullY1; - int y2 = fullY2; + n = REGION_NUM_RECTS(pClip); + pbox = REGION_RECTS(pClip); + /* + * clip the rectangle to each box in the clip region + * this is logically equivalent to calling Intersect(), + * but rectangles may overlap each other here. + */ + while (n--) { + int x1 = fullX1; + int x2 = fullX2; + int y1 = fullY1; + int y2 = fullY2; - if (pbox->x1 > x1) - x1 = pbox->x1; - if (pbox->x2 < x2) - x2 = pbox->x2; - if (pbox->y1 > y1) - y1 = pbox->y1; - if (pbox->y2 < y2) - y2 = pbox->y2; + if (pbox->x1 > x1) + x1 = pbox->x1; + if (pbox->x2 < x2) + x2 = pbox->x2; + if (pbox->y1 > y1) + y1 = pbox->y1; + if (pbox->y2 < y2) + y2 = pbox->y2; - pbox++; - if (x1 >= x2 || y1 >= y2) - continue; - if (!glamor_fill(drawable, gc, x1, y1, x2 - x1, - y2 - y1, fallback)) { - nrect++; - goto fail; - } - } - prect++; - } - ret = TRUE; - goto done; + pbox++; + if (x1 >= x2 || y1 >= y2) + continue; + if (!glamor_fill(drawable, gc, x1, y1, x2 - x1, y2 - y1, fallback)) { + nrect++; + goto fail; + } + } + prect++; + } + ret = TRUE; + goto done; -fail: + fail: - if (!fallback - && glamor_ddx_fallback_check_pixmap(drawable) - && glamor_ddx_fallback_check_gc(gc)) - goto done; + if (!fallback && glamor_ddx_fallback_check_pixmap(drawable) + && 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)) { - if (glamor_prepare_access_gc(gc)) { - fbPolyFillRect(drawable, gc, nrect, prect); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); - } - ret = TRUE; + glamor_fallback(" to %p (%c)\n", + drawable, glamor_get_drawable_location(drawable)); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_gc(gc)) { + fbPolyFillRect(drawable, gc, nrect, prect); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + } + ret = TRUE; -done: - return ret; + done: + return ret; } - void glamor_poly_fill_rect(DrawablePtr drawable, - GCPtr gc, int nrect, xRectangle * prect) + GCPtr gc, int nrect, xRectangle *prect) { - _glamor_poly_fill_rect(drawable, gc, nrect, prect, TRUE); + _glamor_poly_fill_rect(drawable, gc, nrect, prect, TRUE); } Bool glamor_poly_fill_rect_nf(DrawablePtr drawable, - GCPtr gc, int nrect, xRectangle * prect) + GCPtr gc, int nrect, xRectangle *prect) { - return _glamor_poly_fill_rect(drawable, gc, nrect, prect, FALSE); + return _glamor_poly_fill_rect(drawable, gc, nrect, prect, FALSE); } diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index e723e95..b941617 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -40,96 +40,97 @@ */ static Bool _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points, Bool fallback) + DDXPointPtr points, Bool fallback) { - xRectangle *rects; - int x1, x2, y1, y2; - int i; + 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 wide_line; - } - 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; - } + /* 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 wide_line; + } + 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; + 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; + fail: + if (!fallback && glamor_ddx_fallback_check_pixmap(drawable) + && glamor_ddx_fallback_check_gc(gc)) + return FALSE; - if (gc->lineWidth == 0) { - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_gc(gc)) { - fbPolyLine(drawable, gc, mode, n, points); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); - } - } else { -wide_line: - /* fb calls mi functions in the lineWidth != 0 case. */ - fbPolyLine(drawable, gc, mode, n, points); - } - return TRUE; + if (gc->lineWidth == 0) { + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_gc(gc)) { + fbPolyLine(drawable, gc, mode, n, points); + glamor_finish_access_gc(gc); + } + glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + } + } + else { + wide_line: + /* fb calls mi functions in the lineWidth != 0 case. */ + fbPolyLine(drawable, gc, mode, n, points); + } + return TRUE; } void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) + DDXPointPtr points) { - _glamor_poly_lines(drawable, gc, mode, n, points, TRUE); + _glamor_poly_lines(drawable, gc, mode, n, points, TRUE); } Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points) + DDXPointPtr points) { - return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE); + return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE); } diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c index 5930178..99c4de9 100644 --- a/glamor/glamor_polyops.c +++ b/glamor/glamor_polyops.c @@ -30,56 +30,53 @@ static Bool _glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt, Bool fallback) + DDXPointPtr ppt, Bool fallback) { - if (!fallback - && glamor_ddx_fallback_check_gc(pGC) - && glamor_ddx_fallback_check_pixmap(pDrawable)) - return FALSE; + if (!fallback && glamor_ddx_fallback_check_gc(pGC) + && glamor_ddx_fallback_check_pixmap(pDrawable)) + return FALSE; - miPolyPoint(pDrawable, pGC, mode, npt, ppt); + miPolyPoint(pDrawable, pGC, mode, npt, ppt); - return TRUE; + return TRUE; } void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt) + DDXPointPtr ppt) { - _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, TRUE); + _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, TRUE); } Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt) + DDXPointPtr ppt) { - return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE); + return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE); } static Bool _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg, Bool fallback) + xSegment * pSeg, Bool fallback) { - if (!fallback - && glamor_ddx_fallback_check_gc(pGC) - && glamor_ddx_fallback_check_pixmap(pDrawable)) - return FALSE; + if (!fallback && glamor_ddx_fallback_check_gc(pGC) + && glamor_ddx_fallback_check_pixmap(pDrawable)) + return FALSE; - miPolySegment(pDrawable, pGC, nseg, pSeg); + miPolySegment(pDrawable, pGC, nseg, pSeg); - return TRUE; + return TRUE; } void -glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg) +glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg) { - _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE); + _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE); } Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg) + xSegment * pSeg) { - return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE); + return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE); } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 7b8f762..39226a8 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -78,108 +78,106 @@ struct glamor_pixmap_private; typedef struct glamor_composite_shader { - GLuint prog; - GLint dest_to_dest_uniform_location; - GLint dest_to_source_uniform_location; - GLint dest_to_mask_uniform_location; - GLint source_uniform_location; - GLint mask_uniform_location; - GLint source_wh; - GLint mask_wh; - GLint source_repeat_mode; - GLint mask_repeat_mode; - union { - float source_solid_color[4]; - struct { - struct glamor_pixmap_private *source_priv; - PicturePtr source; - }; - }; - - union { - float mask_solid_color[4]; - struct { - struct glamor_pixmap_private *mask_priv; - PicturePtr mask; - }; - }; + GLuint prog; + GLint dest_to_dest_uniform_location; + GLint dest_to_source_uniform_location; + GLint dest_to_mask_uniform_location; + GLint source_uniform_location; + GLint mask_uniform_location; + GLint source_wh; + GLint mask_wh; + GLint source_repeat_mode; + GLint mask_repeat_mode; + union { + float source_solid_color[4]; + struct { + struct glamor_pixmap_private *source_priv; + PicturePtr source; + }; + }; + + union { + float mask_solid_color[4]; + struct { + struct glamor_pixmap_private *mask_priv; + PicturePtr mask; + }; + }; } glamor_composite_shader; enum shader_source { - SHADER_SOURCE_SOLID, - SHADER_SOURCE_TEXTURE, - SHADER_SOURCE_TEXTURE_ALPHA, - SHADER_SOURCE_COUNT, + SHADER_SOURCE_SOLID, + SHADER_SOURCE_TEXTURE, + SHADER_SOURCE_TEXTURE_ALPHA, + SHADER_SOURCE_COUNT, }; enum shader_mask { - SHADER_MASK_NONE, - SHADER_MASK_SOLID, - SHADER_MASK_TEXTURE, - SHADER_MASK_TEXTURE_ALPHA, - SHADER_MASK_COUNT, + SHADER_MASK_NONE, + SHADER_MASK_SOLID, + SHADER_MASK_TEXTURE, + SHADER_MASK_TEXTURE_ALPHA, + SHADER_MASK_COUNT, }; enum shader_in { - SHADER_IN_SOURCE_ONLY, - SHADER_IN_NORMAL, - SHADER_IN_CA_SOURCE, - SHADER_IN_CA_ALPHA, - SHADER_IN_COUNT, + SHADER_IN_SOURCE_ONLY, + SHADER_IN_NORMAL, + SHADER_IN_CA_SOURCE, + SHADER_IN_CA_ALPHA, + SHADER_IN_COUNT, }; struct shader_key { - enum shader_source source; - enum shader_mask mask; - enum shader_in in; + enum shader_source source; + enum shader_mask mask; + enum shader_in in; }; struct blendinfo { - Bool dest_alpha; - Bool source_alpha; - GLenum source_blend; - GLenum dest_blend; + Bool dest_alpha; + Bool source_alpha; + GLenum source_blend; + GLenum dest_blend; }; typedef struct { - INT16 x_src; - INT16 y_src; - INT16 x_mask; - INT16 y_mask; - INT16 x_dst; - INT16 y_dst; - INT16 width; - INT16 height; + INT16 x_src; + INT16 y_src; + INT16 x_mask; + INT16 y_mask; + INT16 x_dst; + INT16 y_dst; + INT16 width; + INT16 height; } glamor_composite_rect_t; - enum glamor_vertex_type { - GLAMOR_VERTEX_POS, - GLAMOR_VERTEX_SOURCE, - GLAMOR_VERTEX_MASK + GLAMOR_VERTEX_POS, + GLAMOR_VERTEX_SOURCE, + GLAMOR_VERTEX_MASK }; - enum gradient_shader { - SHADER_GRADIENT_LINEAR, - SHADER_GRADIENT_RADIAL, - SHADER_GRADIENT_CONICAL, - SHADER_GRADIENT_COUNT, + SHADER_GRADIENT_LINEAR, + SHADER_GRADIENT_RADIAL, + SHADER_GRADIENT_CONICAL, + SHADER_GRADIENT_COUNT, }; enum gradient_shader_prog { - SHADER_GRADIENT_VS_PROG, - SHADER_GRADIENT_FS_MAIN_PROG, - SHADER_GRADIENT_FS_GETCOLOR_PROG, - SHADER_GRADIENT_PROG_COUNT, + SHADER_GRADIENT_VS_PROG, + SHADER_GRADIENT_FS_MAIN_PROG, + SHADER_GRADIENT_FS_GETCOLOR_PROG, + SHADER_GRADIENT_PROG_COUNT, }; struct glamor_screen_private; struct glamor_pixmap_private; enum glamor_gl_flavor { - GLAMOR_GL_DESKTOP, // OPENGL API - GLAMOR_GL_ES2 // OPENGL ES2.0 API + GLAMOR_GL_DESKTOP, // OPENGL API + GLAMOR_GL_ES2 // OPENGL ES2.0 API }; #define GLAMOR_CREATE_PIXMAP_CPU 0x100 @@ -194,34 +192,34 @@ enum glamor_gl_flavor { #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024) typedef struct { - PicturePtr picture; /* Where the glyphs of the cache are stored */ - GlyphPtr *glyphs; - uint16_t count; - uint16_t evict; + PicturePtr picture; /* Where the glyphs of the cache are stored */ + GlyphPtr *glyphs; + uint16_t count; + uint16_t evict; } glamor_glyph_cache_t; #include "glamor_gl_dispatch.h" -struct glamor_saved_procs { - CloseScreenProcPtr close_screen; - CreateGCProcPtr create_gc; - CreatePixmapProcPtr create_pixmap; - DestroyPixmapProcPtr destroy_pixmap; - GetSpansProcPtr get_spans; - GetImageProcPtr get_image; - CompositeProcPtr composite; - CompositeRectsProcPtr composite_rects; - TrapezoidsProcPtr trapezoids; - GlyphsProcPtr glyphs; - ChangeWindowAttributesProcPtr change_window_attributes; - CopyWindowProcPtr copy_window; - BitmapToRegionProcPtr bitmap_to_region; - TrianglesProcPtr triangles; - AddTrapsProcPtr addtraps; - CreatePictureProcPtr create_picture; - DestroyPictureProcPtr destroy_picture; - UnrealizeGlyphProcPtr unrealize_glyph; - SetWindowPixmapProcPtr set_window_pixmap; +struct glamor_saved_procs { + CloseScreenProcPtr close_screen; + CreateGCProcPtr create_gc; + CreatePixmapProcPtr create_pixmap; + DestroyPixmapProcPtr destroy_pixmap; + GetSpansProcPtr get_spans; + GetImageProcPtr get_image; + CompositeProcPtr composite; + CompositeRectsProcPtr composite_rects; + TrapezoidsProcPtr trapezoids; + GlyphsProcPtr glyphs; + ChangeWindowAttributesProcPtr change_window_attributes; + CopyWindowProcPtr copy_window; + BitmapToRegionProcPtr bitmap_to_region; + TrianglesProcPtr triangles; + AddTrapsProcPtr addtraps; + CreatePictureProcPtr create_picture; + DestroyPictureProcPtr destroy_picture; + UnrealizeGlyphProcPtr unrealize_glyph; + SetWindowPixmapProcPtr set_window_pixmap; }; #ifdef GLAMOR_GLES2 @@ -242,79 +240,80 @@ struct glamor_saved_procs { #define RENDER_IDEL_MAX 32 typedef struct glamor_screen_private { - struct glamor_gl_dispatch _dispatch; - int yInverted; - unsigned int tick; - enum glamor_gl_flavor gl_flavor; - int has_pack_invert; - int has_fbo_blit; - int max_fbo_size; - - struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; - unsigned long fbo_cache_watermark; - - /* glamor_solid */ - GLint solid_prog; - GLint solid_color_uniform_location; - - /* vertext/elment_index buffer object for render */ - GLuint vbo, ebo; - int vbo_offset; - int vbo_size; - char *vb; - int vb_stride; - Bool has_source_coords, has_mask_coords; - int render_nr_verts; - glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] - [SHADER_MASK_COUNT] - [SHADER_IN_COUNT]; - glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; - Bool glyph_cache_initialized; - - /* shaders to restore a texture to another texture.*/ - GLint finish_access_prog[2]; - GLint finish_access_revert[2]; - GLint finish_access_swap_rb[2]; - - /* glamor_tile */ - GLint tile_prog; - GLint tile_wh; - - /* glamor gradient, 0 for small nstops, 1 for - large nstops and 2 for dynamic generate. */ - GLint gradient_prog[SHADER_GRADIENT_COUNT][3]; - GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3]; - int linear_max_nstops; - GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3]; - int radial_max_nstops; - - /* glamor trapezoid shader. */ - GLint trapezoid_prog; - - /* glamor_putimage */ - GLint put_image_xybitmap_prog; - GLint put_image_xybitmap_fg_uniform_location; - GLint put_image_xybitmap_bg_uniform_location; - - PixmapPtr *back_pixmap; - int screen_fbo; - struct glamor_saved_procs saved_procs; - char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; - int delayed_fallback_pending; - int flags; - int state; - unsigned int render_idle_cnt; - ScreenPtr screen; - int dri3_enabled; - - /* xv */ - GLint xv_prog; + struct glamor_gl_dispatch _dispatch; + int yInverted; + unsigned int tick; + enum glamor_gl_flavor gl_flavor; + int has_pack_invert; + int has_fbo_blit; + int max_fbo_size; + + struct xorg_list + fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; + unsigned long fbo_cache_watermark; + + /* glamor_solid */ + GLint solid_prog; + GLint solid_color_uniform_location; + + /* vertext/elment_index buffer object for render */ + GLuint vbo, ebo; + int vbo_offset; + int vbo_size; + char *vb; + int vb_stride; + Bool has_source_coords, has_mask_coords; + int render_nr_verts; + glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] + [SHADER_MASK_COUNT] + [SHADER_IN_COUNT]; + glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; + Bool glyph_cache_initialized; + + /* shaders to restore a texture to another texture. */ + GLint finish_access_prog[2]; + GLint finish_access_revert[2]; + GLint finish_access_swap_rb[2]; + + /* glamor_tile */ + GLint tile_prog; + GLint tile_wh; + + /* glamor gradient, 0 for small nstops, 1 for + large nstops and 2 for dynamic generate. */ + GLint gradient_prog[SHADER_GRADIENT_COUNT][3]; + GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3]; + int linear_max_nstops; + GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3]; + int radial_max_nstops; + + /* glamor trapezoid shader. */ + GLint trapezoid_prog; + + /* glamor_putimage */ + GLint put_image_xybitmap_prog; + GLint put_image_xybitmap_fg_uniform_location; + GLint put_image_xybitmap_bg_uniform_location; + + PixmapPtr *back_pixmap; + int screen_fbo; + struct glamor_saved_procs saved_procs; + char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; + int delayed_fallback_pending; + int flags; + int state; + unsigned int render_idle_cnt; + ScreenPtr screen; + int dri3_enabled; + + /* xv */ + GLint xv_prog; } glamor_screen_private; typedef enum glamor_access { - GLAMOR_ACCESS_RO, - GLAMOR_ACCESS_RW, - GLAMOR_ACCESS_WO, + GLAMOR_ACCESS_RO, + GLAMOR_ACCESS_RW, + GLAMOR_ACCESS_WO, } glamor_access_t; #define GLAMOR_FBO_NORMAL 1 @@ -335,17 +334,17 @@ typedef enum glamor_access { * @glamor_priv: point to glamor private data. */ typedef struct glamor_pixmap_fbo { - struct xorg_list list; - unsigned int expire; - unsigned char pbo_valid; - GLuint tex; - GLuint fb; - GLuint pbo; - int width; - int height; - GLenum format; - GLenum type; - glamor_screen_private *glamor_priv; + struct xorg_list list; + unsigned int expire; + unsigned char pbo_valid; + GLuint tex; + GLuint fb; + GLuint pbo; + int width; + int height; + GLenum format; + GLenum type; + glamor_screen_private *glamor_priv; } glamor_pixmap_fbo; /* @@ -414,9 +413,9 @@ typedef struct glamor_pixmap_fbo { * **/ -typedef struct glamor_pixmap_clipped_regions{ - int block_idx; - RegionPtr region; +typedef struct glamor_pixmap_clipped_regions { + int block_idx; + RegionPtr region; } glamor_pixmap_clipped_regions; #define SET_PIXMAP_FBO_CURRENT(priv, idx) \ @@ -428,16 +427,16 @@ typedef struct glamor_pixmap_clipped_regions{ } while(0) typedef struct glamor_pixmap_private_base { - glamor_pixmap_type_t type; - unsigned char gl_fbo:2; - unsigned char is_picture:1; - unsigned char gl_tex:1; - glamor_pixmap_fbo *fbo; - PixmapPtr pixmap; - int drm_stride; - glamor_screen_private *glamor_priv; - PicturePtr picture; -}glamor_pixmap_private_base_t; + glamor_pixmap_type_t type; + unsigned char gl_fbo:2; + unsigned char is_picture:1; + unsigned char gl_tex:1; + glamor_pixmap_fbo *fbo; + PixmapPtr pixmap; + int drm_stride; + glamor_screen_private *glamor_priv; + PicturePtr picture; +} glamor_pixmap_private_base_t; /* * @base.fbo: current fbo. @@ -452,39 +451,39 @@ typedef struct glamor_pixmap_private_base { * **/ typedef struct glamor_pixmap_private_large { - union { - glamor_pixmap_type_t type; - glamor_pixmap_private_base_t base; - }; - BoxRec box; - int block_w; - int block_h; - int block_wcnt; - int block_hcnt; - int nbox; - BoxPtr box_array; - glamor_pixmap_fbo **fbo_array; -}glamor_pixmap_private_large_t; + union { + glamor_pixmap_type_t type; + glamor_pixmap_private_base_t base; + }; + BoxRec box; + int block_w; + int block_h; + int block_wcnt; + int block_hcnt; + int nbox; + BoxPtr box_array; + glamor_pixmap_fbo **fbo_array; +} glamor_pixmap_private_large_t; /* * @box: the relative coords in the corresponding fbo. */ typedef struct glamor_pixmap_private_atlas { - union { - glamor_pixmap_type_t type; - glamor_pixmap_private_base_t base; - }; - BoxRec box; -}glamor_pixmap_private_atlas_t; + union { + glamor_pixmap_type_t type; + glamor_pixmap_private_base_t base; + }; + BoxRec box; +} glamor_pixmap_private_atlas_t; typedef struct glamor_pixmap_private { - union { - glamor_pixmap_type_t type; - glamor_pixmap_private_base_t base; - glamor_pixmap_private_large_t large; - glamor_pixmap_private_atlas_t atlas; - }; -}glamor_pixmap_private; + union { + glamor_pixmap_type_t type; + glamor_pixmap_private_base_t base; + glamor_pixmap_private_large_t large; + glamor_pixmap_private_atlas_t atlas; + }; +} glamor_pixmap_private; /* * Pixmap dynamic status, used by dynamic upload feature. @@ -496,10 +495,10 @@ typedef struct glamor_pixmap_private { * * */ typedef enum glamor_pixmap_status { - GLAMOR_NONE, - GLAMOR_UPLOAD_PENDING, - GLAMOR_UPLOAD_DONE, - GLAMOR_UPLOAD_FAILED + GLAMOR_NONE, + GLAMOR_UPLOAD_PENDING, + GLAMOR_UPLOAD_DONE, + GLAMOR_UPLOAD_FAILED } glamor_pixmap_status_t; extern DevPrivateKey glamor_screen_private_key; @@ -507,36 +506,31 @@ extern DevPrivateKey glamor_pixmap_private_key; static inline glamor_screen_private * glamor_get_screen_private(ScreenPtr screen) { - return (glamor_screen_private *) - dixLookupPrivate(&screen->devPrivates, - glamor_screen_private_key); + return (glamor_screen_private *) + dixLookupPrivate(&screen->devPrivates, glamor_screen_private_key); } static inline void -glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv) +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 * glamor_get_pixmap_private(PixmapPtr pixmap) { - glamor_pixmap_private *priv; - priv = dixLookupPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key); - if (!priv) { - glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY); - priv = dixLookupPrivate(&pixmap->devPrivates, - glamor_pixmap_private_key); - } - return priv; + glamor_pixmap_private *priv; + + priv = dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); + if (!priv) { + glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY); + priv = dixLookupPrivate(&pixmap->devPrivates, + glamor_pixmap_private_key); + } + return priv; } -void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv); +void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private * priv); /** * Returns TRUE if the given planemask covers all the significant bits in the @@ -545,8 +539,8 @@ void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv); static inline Bool glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) { - return (planemask & FbFullMask(drawable->depth)) == - FbFullMask(drawable->depth); + return (planemask & FbFullMask(drawable->depth)) == + FbFullMask(drawable->depth); } extern int glamor_debug_level; @@ -556,38 +550,41 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); Bool glamor_destroy_pixmap(PixmapPtr pixmap); -glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv); -void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo); -glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, GLint tex, int flag); -glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, int flag); -void glamor_destroy_fbo(glamor_pixmap_fbo *fbo); -void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv); -void glamor_purge_fbo(glamor_pixmap_fbo *fbo); +glamor_pixmap_fbo *glamor_pixmap_detach_fbo(glamor_pixmap_private * + pixmap_priv); +void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo * fbo); +glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private * + glamor_priv, int w, int h, + GLenum format, GLint tex, + int flag); +glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private * glamor_priv, int w, + int h, GLenum format, int flag); +void glamor_destroy_fbo(glamor_pixmap_fbo * fbo); +void glamor_pixmap_destroy_fbo(glamor_pixmap_private * priv); +void glamor_purge_fbo(glamor_pixmap_fbo * fbo); void glamor_init_pixmap_fbo(ScreenPtr screen); void glamor_fini_pixmap_fbo(ScreenPtr screen); Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap); -void glamor_fbo_expire(glamor_screen_private *glamor_priv); +void glamor_fbo_expire(glamor_screen_private * glamor_priv); -glamor_pixmap_fbo * -glamor_create_fbo_array(glamor_screen_private *glamor_priv, - int w, int h, GLenum format, int flag, - int block_w, int block_h, glamor_pixmap_private *); +glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private * glamor_priv, + int w, int h, GLenum format, + int flag, int block_w, int block_h, + glamor_pixmap_private *); /* glamor_copyarea.c */ RegionPtr + glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, - int srcx, int srcy, int width, int height, int dstx, - int dsty); + 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); + BoxPtr box, int nbox, int dx, int dy, Bool reverse, + Bool upsidedown, Pixel bitplane, void *closure); /* glamor_copywindow.c */ void glamor_copy_window(WindowPtr win, DDXPointRec old_origin, - RegionPtr src_region); + RegionPtr src_region); /* glamor_core.c */ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); @@ -600,36 +597,34 @@ 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); + 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); + int x, int y, int width, int height, + unsigned char alu, unsigned long planemask, + unsigned long fg_pixel, unsigned long bg_pixel, + int stipple_x, int stipple_y); GLint glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type, - const char *source); + const char *source); void glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog); void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, - unsigned long fg_pixel, - GLfloat * color); + unsigned long fg_pixel, GLfloat * color); int glamor_set_destination_pixmap(PixmapPtr pixmap); -int glamor_set_destination_pixmap_priv(glamor_pixmap_private * - pixmap_priv); +int glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv); void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int); /* nc means no check. caller must ensure this pixmap has valid fbo. * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. * */ -void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * - pixmap_priv); +void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv); -glamor_pixmap_fbo * -glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format, - GLenum type, int no_alpha, int revert, int swap_rb); +glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, + int y, int w, int h, + GLenum format, GLenum type, + int no_alpha, int revert, + int swap_rb); -Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch, - unsigned char alu); +Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); @@ -640,24 +635,21 @@ int glamor_gl_get_version(void); ((major) * 256) \ + ((minor) * 1)) - - - /* glamor_fill.c */ Bool glamor_fill(DrawablePtr drawable, - GCPtr gc, int x, int y, int width, int height, Bool fallback); + 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); + unsigned char alu, unsigned long planemask, + unsigned long fg_pixel); Bool + glamor_solid_boxes(PixmapPtr pixmap, - BoxPtr box, int nbox, - unsigned long fg_pixel); + BoxPtr box, int nbox, unsigned long fg_pixel); /* glamor_fillspans.c */ void glamor_fill_spans(DrawablePtr drawable, - GCPtr gc, - int n, DDXPointPtr points, int *widths, int sorted); + GCPtr gc, + int n, DDXPointPtr points, int *widths, int sorted); void glamor_init_solid_shader(ScreenPtr screen); void glamor_fini_solid_shader(ScreenPtr screen); @@ -665,82 +657,80 @@ void glamor_fini_solid_shader(ScreenPtr screen); /* glamor_getspans.c */ void + glamor_get_spans(DrawablePtr drawable, - int wmax, - DDXPointPtr points, - int *widths, int nspans, char *dst_start); + int wmax, + DDXPointPtr points, int *widths, int nspans, char *dst_start); /* glamor_glyphs.c */ void glamor_glyphs_fini(ScreenPtr screen); void glamor_glyphs(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, int nlist, GlyphListPtr list, - GlyphPtr * glyphs); + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs); /* glamor_setspans.c */ void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, - DDXPointPtr points, int *widths, int n, int sorted); + DDXPointPtr points, int *widths, int n, int sorted); /* glamor_polyfillrect.c */ void + glamor_poly_fill_rect(DrawablePtr drawable, - GCPtr gc, int nrect, xRectangle * prect); + GCPtr gc, int nrect, xRectangle *prect); /* glamor_polylines.c */ void + glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, - DDXPointPtr points); + DDXPointPtr points); /* glamor_putimage.c */ void + glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int leftPad, int format, char *bits); + int w, int h, int leftPad, int format, char *bits); void glamor_init_putimage_shaders(ScreenPtr screen); void glamor_fini_putimage_shaders(ScreenPtr screen); /* glamor_render.c */ Bool + glamor_composite_clipped_region(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - glamor_pixmap_private *soruce_pixmap_priv, - glamor_pixmap_private *mask_pixmap_priv, - glamor_pixmap_private *dest_pixmap_priv, - RegionPtr region, - int x_source, - int y_source, - int x_mask, - int y_mask, - int x_dest, - int y_dest); + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private * soruce_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, + RegionPtr region, + int x_source, + int y_source, + int x_mask, int y_mask, int x_dest, int y_dest); void glamor_composite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); void glamor_init_composite_shaders(ScreenPtr screen); void glamor_fini_composite_shaders(ScreenPtr screen); void glamor_composite_glyph_rects(CARD8 op, - PicturePtr src, PicturePtr mask, - PicturePtr dst, int nrect, - glamor_composite_rect_t * rects); -void glamor_composite_rects (CARD8 op, - PicturePtr pDst, - xRenderColor *color, - int nRect, - xRectangle *rects); + PicturePtr src, PicturePtr mask, + PicturePtr dst, int nrect, + glamor_composite_rect_t * rects); +void glamor_composite_rects(CARD8 op, + PicturePtr pDst, + xRenderColor * color, int nRect, xRectangle *rects); void glamor_init_trapezoid_shader(ScreenPtr screen); void glamor_fini_trapezoid_shader(ScreenPtr screen); PicturePtr glamor_convert_gradient_picture(ScreenPtr screen, @@ -752,19 +742,20 @@ Bool glamor_composite_choose_shader(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, - glamor_pixmap_private *source_pixmap_priv, - glamor_pixmap_private *mask_pixmap_priv, - glamor_pixmap_private *dest_pixmap_priv, + glamor_pixmap_private * source_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, struct shader_key *s_key, - glamor_composite_shader **shader, - struct blendinfo *op_info, - PictFormatShort *psaved_source_format); + glamor_composite_shader ** shader, + struct blendinfo *op_info, + PictFormatShort * psaved_source_format); void -glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv, - struct shader_key *key, - glamor_composite_shader *shader, - struct blendinfo *op_info); + +glamor_composite_set_shader_blend(glamor_pixmap_private * dest_priv, + struct shader_key *key, + glamor_composite_shader * shader, + struct blendinfo *op_info); void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts); void glamor_emit_composite_vert(ScreenPtr screen, @@ -774,15 +765,15 @@ void glamor_emit_composite_vert(ScreenPtr screen, /* glamor_trapezoid.c */ void glamor_trapezoids(CARD8 op, - PicturePtr src, PicturePtr dst, - PictFormatPtr mask_format, INT16 x_src, INT16 y_src, - int ntrap, xTrapezoid * traps); + PicturePtr src, PicturePtr dst, + PictFormatPtr mask_format, INT16 x_src, INT16 y_src, + int ntrap, xTrapezoid * traps); /* glamor_tile.c */ Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, - int x, int y, int width, int height, - unsigned char alu, unsigned long planemask, - int tile_x, int tile_y); + 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); @@ -803,16 +794,18 @@ PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen, /* glamor_triangles.c */ void + glamor_triangles(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris); + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris); /* glamor_pixmap.c */ void glamor_pixmap_init(ScreenPtr screen); void glamor_pixmap_fini(ScreenPtr screen); + /** * Download a pixmap's texture to cpu memory. If success, * One copy of current pixmap's texture will be put into @@ -822,13 +815,11 @@ void glamor_pixmap_fini(ScreenPtr screen); * 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); +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 @@ -849,7 +840,7 @@ void glamor_restore_pixmap_to_texture(PixmapPtr pixmap); * If the fbo already has a valid glfbo then do nothing. */ Bool -glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag); + glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag); /** * Upload a pixmap to gl texture. Used by dynamic pixmap @@ -857,61 +848,70 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag); * This function will change current FBO and current shaders. */ enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr - pixmap); + pixmap); Bool -glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, - int stride, void *bits, int pbo); + +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); + int w, int h, glamor_access_t access); void -glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, - int w, int h, glamor_access_t access); -glamor_pixmap_clipped_regions * -glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, - int *clipped_nbox, int repeat_type, - int reverse, int upsidedown); - -glamor_pixmap_clipped_regions * -glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv, - RegionPtr region, - int *n_region, - int inner_block_w, int inner_block_h, - int reverse, int upsidedown); - -glamor_pixmap_clipped_regions * -glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform, - RegionPtr region, int *n_region, int dx, int dy, int repeat_type, - int reverse, int upsidedown); +glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, + int w, int h, glamor_access_t access); + +glamor_pixmap_clipped_regions + *glamor_compute_clipped_regions(glamor_pixmap_private * priv, + RegionPtr region, int *clipped_nbox, + int repeat_type, int reverse, + int upsidedown); + +glamor_pixmap_clipped_regions + *glamor_compute_clipped_regions_ext(glamor_pixmap_private * pixmap_priv, + RegionPtr region, int *n_region, + int inner_block_w, int inner_block_h, + int reverse, int upsidedown); + +glamor_pixmap_clipped_regions + *glamor_compute_transform_clipped_regions(glamor_pixmap_private * priv, + struct pixman_transform + *transform, RegionPtr region, + int *n_region, int dx, int dy, + int repeat_type, int reverse, + int upsidedown); Bool + glamor_composite_largepixmap_region(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - glamor_pixmap_private * source_pixmap_priv, - glamor_pixmap_private * mask_pixmap_priv, - glamor_pixmap_private * dest_pixmap_priv, - RegionPtr region, Bool force_clip, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, INT16 y_dest, - CARD16 width, CARD16 height); + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private * source_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, + RegionPtr region, Bool force_clip, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, + CARD16 width, CARD16 height); Bool + glamor_get_transform_block_size(struct pixman_transform *transform, - int block_w, int block_h, - int *transformed_block_w, - int *transformed_block_h); + int block_w, int block_h, + int *transformed_block_w, + int *transformed_block_h); void + glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box, - struct pixman_transform *transform); + struct pixman_transform *transform); /** * Upload a picture to gl texture. Similar to the @@ -925,8 +925,9 @@ enum glamor_pixmap_status * convert the bits to the specified format/type format * if the conversion is unavoidable. **/ -Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type, - int no_alpha, int revert, int swap_rb, void *bits); +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 @@ -939,7 +940,7 @@ 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); + glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access); @@ -947,63 +948,73 @@ void glamor_destroy_picture(PicturePtr picture); /* fixup a fbo to the exact size as the pixmap. */ Bool -glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv); + +glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private * pixmap_priv); void + glamor_picture_format_fixup(PicturePtr picture, - glamor_pixmap_private * pixmap_priv); + glamor_pixmap_private * pixmap_priv); void + glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d); + unsigned int format, unsigned long planeMask, char *d); void + glamor_add_traps(PicturePtr pPicture, - INT16 x_off, - INT16 y_off, int ntrap, xTrap * traps); + 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); + int srcx, int srcy, int w, int h, int dstx, int dsty, + unsigned long bitPlane); void + glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase); + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase); void + glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr * ppci, pointer pglyphBase); + int x, int y, unsigned int nglyph, + CharInfoPtr * ppci, pointer pglyphBase); void + glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, int w, int h, int x, int y); + DrawablePtr pDrawable, int w, int h, int x, int y); void + glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt); + DDXPointPtr ppt); void + glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg); + xSegment * pSeg); void + glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt); + DDXPointPtr ppt); void -glamor_composite_rectangles(CARD8 op, - PicturePtr dst, - xRenderColor *color, - int num_rects, - xRectangle *rects); + +glamor_composite_rectangles(CARD8 op, + PicturePtr dst, + xRenderColor * color, + int num_rects, xRectangle *rects); /* glamor_xv */ typedef struct { - uint32_t transform_index; - uint32_t gamma; /* gamma value x 1000 */ + uint32_t transform_index; + uint32_t gamma; /* gamma value x 1000 */ int brightness; int saturation; int hue; @@ -1016,8 +1027,8 @@ typedef struct { int src_w, src_h, dst_w, dst_h; int src_x, src_y, drw_x, drw_y; int w, h; - RegionRec clip; - PixmapPtr src_pix[3]; /* y, u, v for planar */ + RegionRec clip; + PixmapPtr src_pix[3]; /* y, u, v for planar */ int src_pix_w, src_pix_h; } glamor_port_private; @@ -1039,9 +1050,9 @@ void glamor_fini_xv_shader(ScreenPtr screen); #define GLAMOR_TEXTURED_LARGE_PIXMAP 1 #define WALKAROUND_LARGE_TEXTURE_MAP #if 0 -#define MAX_FBO_SIZE 32 /* For test purpose only. */ +#define MAX_FBO_SIZE 32 /* For test purpose only. */ #endif //#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK #define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK -#endif /* GLAMOR_PRIV_H */ +#endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 99f7ac6..5d06912 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -26,7 +26,6 @@ * */ - /** @file glamor_putaimge.c * * XPutImage implementation @@ -37,54 +36,52 @@ void glamor_init_putimage_shaders(ScreenPtr screen) { #if 0 - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - const char *xybitmap_vs = - "uniform float x_bias;\n" "uniform float x_scale;\n" - "uniform float y_bias;\n" "uniform float y_scale;\n" - "varying vec2 bitmap_coords;\n" "void main()\n" "{\n" - " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" - " (gl_Vertex.y + y_bias) * y_scale,\n" - " 0,\n" - " 1);\n" - " bitmap_coords = gl_MultiTexCoord0.xy;\n" "}\n"; - const char *xybitmap_fs = - "uniform vec4 fg, bg;\n" "varying vec2 bitmap_coords;\n" - "uniform sampler2D bitmap_sampler;\n" "void main()\n" "{\n" - " float bitmap_value = texture2D(bitmap_sampler,\n" - " bitmap_coords).x;\n" - " gl_FragColor = mix(bg, fg, bitmap_value);\n" "}\n"; - GLint fs_prog, vs_prog, prog; - GLint sampler_uniform_location; - - if (!GLEW_ARB_fragment_shader) - return; - - prog = dispatch->glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs); - fs_prog = - glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs); - dispatch->glAttachShader(prog, vs_prog); - dispatch->glAttachShader(prog, fs_prog); - glamor_link_glsl_prog(prog); - - dispatch->glUseProgram(prog); - sampler_uniform_location = - dispatch->glGetUniformLocation(prog, "bitmap_sampler"); - dispatch->glUniform1i(sampler_uniform_location, 0); - - glamor_priv->put_image_xybitmap_fg_uniform_location = - dispatch->glGetUniformLocation(prog, "fg"); - glamor_priv->put_image_xybitmap_bg_uniform_location = - dispatch->glGetUniformLocation(prog, "bg"); - glamor_get_transform_uniform_locations(prog, - &glamor_priv->put_image_xybitmap_transform); - glamor_priv->put_image_xybitmap_prog = prog; - dispatch->glUseProgram(0); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + const char *xybitmap_vs = + "uniform float x_bias;\n" "uniform float x_scale;\n" + "uniform float y_bias;\n" "uniform float y_scale;\n" + "varying vec2 bitmap_coords;\n" "void main()\n" "{\n" + " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" + " (gl_Vertex.y + y_bias) * y_scale,\n" + " 0,\n" + " 1);\n" + " bitmap_coords = gl_MultiTexCoord0.xy;\n" "}\n"; + const char *xybitmap_fs = + "uniform vec4 fg, bg;\n" "varying vec2 bitmap_coords;\n" + "uniform sampler2D bitmap_sampler;\n" "void main()\n" "{\n" + " float bitmap_value = texture2D(bitmap_sampler,\n" + " bitmap_coords).x;\n" + " gl_FragColor = mix(bg, fg, bitmap_value);\n" "}\n"; + GLint fs_prog, vs_prog, prog; + GLint sampler_uniform_location; + + if (!GLEW_ARB_fragment_shader) + return; + + prog = dispatch->glCreateProgram(); + vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs); + fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs); + dispatch->glAttachShader(prog, vs_prog); + dispatch->glAttachShader(prog, fs_prog); + glamor_link_glsl_prog(prog); + + dispatch->glUseProgram(prog); + sampler_uniform_location = + dispatch->glGetUniformLocation(prog, "bitmap_sampler"); + dispatch->glUniform1i(sampler_uniform_location, 0); + + glamor_priv->put_image_xybitmap_fg_uniform_location = + dispatch->glGetUniformLocation(prog, "fg"); + glamor_priv->put_image_xybitmap_bg_uniform_location = + dispatch->glGetUniformLocation(prog, "bg"); + glamor_get_transform_uniform_locations(prog, + &glamor_priv-> + put_image_xybitmap_transform); + glamor_priv->put_image_xybitmap_prog = prog; + dispatch->glUseProgram(0); #endif } - /* Do an XYBitmap putimage. The bits are byte-aligned rows of bitmap * data (where each row starts at a bit index of left_pad), and the * destination gets filled with the gc's fg color where the bitmap is set @@ -101,141 +98,136 @@ glamor_init_putimage_shaders(ScreenPtr screen) static int y_flip(PixmapPtr pixmap, int y) { - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - if (pixmap == screen_pixmap) - return (pixmap->drawable.height - 1) - y; - else - return y; + if (pixmap == screen_pixmap) + return (pixmap->drawable.height - 1) - y; + else + return y; } - static void glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, - int x, int y, int w, int h, int left_pad, - int image_format, char *bits) + int x, int y, int w, int h, int left_pad, + int image_format, char *bits) { - ScreenPtr screen = drawable->pScreen; - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - float fg[4], bg[4]; - GLuint tex; - unsigned int stride = PixmapBytePad(1, w + left_pad); - RegionPtr clip; - BoxPtr box; - int nbox; - float dest_coords[8]; - const float bitmap_coords[8] = { - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - }; - GLfloat xscale, yscale; - glamor_pixmap_private *pixmap_priv; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); - - glamor_set_normalize_vcoords(xscale, yscale, - x, y, - x + w, y + h, - glamor_priv->yInverted, dest_coords); - - glamor_fallback("glamor_put_image_xybitmap: disabled\n"); - goto fail; - - if (glamor_priv->put_image_xybitmap_prog == 0) { - ErrorF("no program for xybitmap putimage\n"); - goto fail; - } - - glamor_set_alu(gc->alu); - if (!glamor_set_planemask(pixmap, gc->planemask)) - goto fail; - - dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog); - - glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); - dispatch->glUniform4fv - (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg); - glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); - dispatch->glUniform4fv - (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); - - dispatch->glGenTextures(1, &tex); - dispatch->glActiveTexture(GL_TEXTURE0); - dispatch->glEnable(GL_TEXTURE_2D); - dispatch->glBindTexture(GL_TEXTURE_2D, tex); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); - dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); - dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, - w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits); - dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - - /* Now that we've set up our bitmap texture and the shader, shove - * the destination rectangle through the cliprects and run the - * shader on the resulting fragments. - */ - dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords); - dispatch->glEnableClientState(GL_VERTEX_ARRAY); - dispatch->glClientActiveTexture(GL_TEXTURE0); - dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); - dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - dispatch->glEnable(GL_SCISSOR_TEST); - clip = fbGetCompositeClip(gc); - for (nbox = REGION_NUM_RECTS(clip), - box = REGION_RECTS(clip); nbox--; box++) { - int x1 = x; - int y1 = y; - int x2 = x + w; - int y2 = y + h; - - if (x1 < box->x1) - x1 = box->x1; - if (y1 < box->y1) - y1 = box->y1; - if (x2 > box->x2) - x2 = box->x2; - if (y2 > box->y2) - y2 = box->y2; - if (x1 >= x2 || y1 >= y2) - continue; - - dispatch->glScissor(box->x1, - y_flip(pixmap, box->y1), - box->x2 - box->x1, box->y2 - box->y1); - dispatch->glDrawArrays(GL_QUADS, 0, 4); - } - - dispatch->glDisable(GL_SCISSOR_TEST); - glamor_set_alu(GXcopy); - glamor_set_planemask(pixmap, ~0); - dispatch->glDeleteTextures(1, &tex); - dispatch->glDisable(GL_TEXTURE_2D); - dispatch->glDisableClientState(GL_VERTEX_ARRAY); - dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY); - return; - glamor_set_alu(GXcopy); - glamor_set_planemask(pixmap, ~0); - glamor_fallback(": to %p (%c)\n", - drawable, glamor_get_drawable_location(drawable)); -fail: - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { - fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, - bits); - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); - } + ScreenPtr screen = drawable->pScreen; + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + float fg[4], bg[4]; + GLuint tex; + unsigned int stride = PixmapBytePad(1, w + left_pad); + RegionPtr clip; + BoxPtr box; + int nbox; + float dest_coords[8]; + + const float bitmap_coords[8] = { + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + }; + GLfloat xscale, yscale; + glamor_pixmap_private *pixmap_priv; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + + pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); + + glamor_set_normalize_vcoords(xscale, yscale, + x, y, + x + w, y + h, + glamor_priv->yInverted, dest_coords); + + glamor_fallback("glamor_put_image_xybitmap: disabled\n"); + goto fail; + + if (glamor_priv->put_image_xybitmap_prog == 0) { + ErrorF("no program for xybitmap putimage\n"); + goto fail; + } + + glamor_set_alu(gc->alu); + if (!glamor_set_planemask(pixmap, gc->planemask)) + goto fail; + + dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog); + + glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); + dispatch->glUniform4fv + (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg); + glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); + dispatch->glUniform4fv + (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); + + dispatch->glGenTextures(1, &tex); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glEnable(GL_TEXTURE_2D); + dispatch->glBindTexture(GL_TEXTURE_2D, tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); + dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); + dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, + w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits); + dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + + /* Now that we've set up our bitmap texture and the shader, shove + * the destination rectangle through the cliprects and run the + * shader on the resulting fragments. + */ + dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords); + dispatch->glEnableClientState(GL_VERTEX_ARRAY); + dispatch->glClientActiveTexture(GL_TEXTURE0); + dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); + dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + dispatch->glEnable(GL_SCISSOR_TEST); + clip = fbGetCompositeClip(gc); + for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); nbox--; box++) { + int x1 = x; + int y1 = y; + int x2 = x + w; + int y2 = y + h; + + if (x1 < box->x1) + x1 = box->x1; + if (y1 < box->y1) + y1 = box->y1; + if (x2 > box->x2) + x2 = box->x2; + if (y2 > box->y2) + y2 = box->y2; + if (x1 >= x2 || y1 >= y2) + continue; + + dispatch->glScissor(box->x1, + y_flip(pixmap, box->y1), + box->x2 - box->x1, box->y2 - box->y1); + dispatch->glDrawArrays(GL_QUADS, 0, 4); + } + + dispatch->glDisable(GL_SCISSOR_TEST); + glamor_set_alu(GXcopy); + glamor_set_planemask(pixmap, ~0); + dispatch->glDeleteTextures(1, &tex); + dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glDisableClientState(GL_VERTEX_ARRAY); + dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY); + return; + glamor_set_alu(GXcopy); + glamor_set_planemask(pixmap, ~0); + glamor_fallback(": to %p (%c)\n", + drawable, glamor_get_drawable_location(drawable)); + fail: + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); + glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + } } #endif @@ -244,120 +236,120 @@ glamor_fini_putimage_shaders(ScreenPtr screen) { } - -static Bool +static Bool _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, int image_format, char *bits, Bool fallback) + int w, int h, int left_pad, int image_format, char *bits, + Bool fallback) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = - glamor_get_pixmap_private(pixmap); - RegionPtr clip; - int x_off, y_off; - Bool ret = FALSE; - PixmapPtr temp_pixmap, sub_pixmap; - glamor_pixmap_private *temp_pixmap_priv; - BoxRec box; - - glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - clip = fbGetCompositeClip(gc); - if (image_format == XYBitmap) { - assert(depth == 1); - goto fail; - } - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { - glamor_fallback("has no fbo.\n"); - goto fail; - } - - if (image_format != ZPixmap) { - glamor_fallback("non-ZPixmap\n"); - goto fail; - } - - if (!glamor_set_planemask(pixmap, gc->planemask)) { - goto fail; - } - /* create a temporary pixmap and upload the bits to that - * pixmap, then apply clip copy it to the destination pixmap.*/ - box.x1 = x + drawable->x; - box.y1 = y + drawable->y; - box.x2 = x + w + drawable->x; - box.y2 = y + h + drawable->y; - - if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN) - || gc->alu != GXcopy) { - temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0); - if (temp_pixmap == NULL) - goto fail; - - temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); - - if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) { - temp_pixmap_priv->base.picture = pixmap_priv->base.picture; - temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture; - } - - glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h, - pixmap->devKind, bits, 0); - - glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y); - glamor_destroy_pixmap(temp_pixmap); - } else - glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off, - w, h, PixmapBytePad(w, depth), bits, 0); - ret = TRUE; - goto done; - -fail: - glamor_set_planemask(pixmap, ~0); - - if (!fallback - && glamor_ddx_fallback_check_pixmap(&pixmap->drawable)) - goto done; - - glamor_fallback("to %p (%c)\n", - drawable, glamor_get_drawable_location(drawable)); - - sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, - y + y_off + drawable->y, w, h, - GLAMOR_ACCESS_RW); - if (sub_pixmap) { - if (clip != NULL) - pixman_region_translate (clip, -x - drawable->x, -y - drawable->y); - - fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h, - left_pad, image_format, bits); - - glamor_put_sub_pixmap(sub_pixmap, pixmap, - x + x_off + drawable->x, - y + y_off + drawable->y, - w, h, GLAMOR_ACCESS_RW); - if (clip != NULL) - pixman_region_translate (clip, x + drawable->x, y + drawable->y); - } else - fbPutImage(drawable, gc, depth, x, y, w, h, - left_pad, image_format, bits); - ret = TRUE; - -done: - return ret; + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + RegionPtr clip; + int x_off, y_off; + Bool ret = FALSE; + PixmapPtr temp_pixmap, sub_pixmap; + glamor_pixmap_private *temp_pixmap_priv; + BoxRec box; + + glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); + clip = fbGetCompositeClip(gc); + if (image_format == XYBitmap) { + assert(depth == 1); + goto fail; + } + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { + glamor_fallback("has no fbo.\n"); + goto fail; + } + + if (image_format != ZPixmap) { + glamor_fallback("non-ZPixmap\n"); + goto fail; + } + + if (!glamor_set_planemask(pixmap, gc->planemask)) { + goto fail; + } + /* create a temporary pixmap and upload the bits to that + * pixmap, then apply clip copy it to the destination pixmap.*/ + box.x1 = x + drawable->x; + box.y1 = y + drawable->y; + box.x2 = x + w + drawable->x; + box.y2 = y + h + drawable->y; + + if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN) + || gc->alu != GXcopy) { + temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0); + if (temp_pixmap == NULL) + goto fail; + + temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); + + if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) { + temp_pixmap_priv->base.picture = pixmap_priv->base.picture; + temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture; + } + + glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h, + pixmap->devKind, bits, 0); + + glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, + y); + glamor_destroy_pixmap(temp_pixmap); + } + else + glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, + y + drawable->y + y_off, w, h, + PixmapBytePad(w, depth), bits, 0); + ret = TRUE; + goto done; + + fail: + glamor_set_planemask(pixmap, ~0); + + if (!fallback && glamor_ddx_fallback_check_pixmap(&pixmap->drawable)) + goto done; + + glamor_fallback("to %p (%c)\n", + drawable, glamor_get_drawable_location(drawable)); + + sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, + y + y_off + drawable->y, w, h, + GLAMOR_ACCESS_RW); + if (sub_pixmap) { + if (clip != NULL) + pixman_region_translate(clip, -x - drawable->x, -y - drawable->y); + + fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h, + left_pad, image_format, bits); + + glamor_put_sub_pixmap(sub_pixmap, pixmap, + x + x_off + drawable->x, + y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW); + if (clip != NULL) + pixman_region_translate(clip, x + drawable->x, y + drawable->y); + } + else + fbPutImage(drawable, gc, depth, x, y, w, h, + left_pad, image_format, bits); + ret = TRUE; + + done: + return ret; } void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, int image_format, char *bits) + int w, int h, int left_pad, int image_format, char *bits) { - _glamor_put_image(drawable, gc, depth, x, y, w, h, - left_pad, image_format, bits, TRUE); + _glamor_put_image(drawable, gc, depth, x, y, w, h, + left_pad, image_format, bits, TRUE); } Bool glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, int image_format, char *bits) + int w, int h, int left_pad, int image_format, char *bits) { - return _glamor_put_image(drawable, gc, depth, x, y, w, h, - left_pad, image_format, bits, FALSE); + return _glamor_put_image(drawable, gc, depth, x, y, w, h, + left_pad, image_format, bits, FALSE); } - diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 76a571f..d6ccf81 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -45,1425 +45,1403 @@ #endif static struct blendinfo composite_op_info[] = { - [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, - [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, - [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, - [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, - [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, - [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, - [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, - [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, - [PictOpXor] = - {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, - [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, + [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, + [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, + [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, + [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, + [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, + [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, + [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, + [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, + [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, }; + #define RepeatFix 10 static GLuint glamor_create_composite_fs(glamor_gl_dispatch * dispatch, - struct shader_key *key) + struct shader_key *key) { - const char *repeat_define = - "#define RepeatNone 0\n" - "#define RepeatNormal 1\n" - "#define RepeatPad 2\n" - "#define RepeatReflect 3\n" - "#define RepeatFix 10\n" - "uniform int source_repeat_mode;\n" - "uniform int mask_repeat_mode;\n"; - const char *relocate_texture = - GLAMOR_DEFAULT_PRECISION - "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n" - "{\n" - " vec2 rel_tex; \n" - " rel_tex = texture * wh.xy; \n" - " if (repeat == RepeatNone)\n" - " return rel_tex; \n" - " else if (repeat == RepeatNormal) \n" - " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n" - " else if(repeat == RepeatPad) { \n" - " if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n" - " else if(rel_tex.x < 0.0) rel_tex.x = 0.0; \n" - " if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n" - " else if(rel_tex.y < 0.0) rel_tex.y = 0.0; \n" - " rel_tex = rel_tex / wh.xy; \n" - " } \n" - " else if(repeat == RepeatReflect) {\n" - " if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n" - " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n" - " else \n" - " rel_tex.x = fract(rel_tex.x)/wh.x;\n" - " if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n" - " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n" - " else \n" - " rel_tex.y = fract(rel_tex.y)/wh.y;\n" - " } \n" - " return rel_tex; \n" - "}\n"; - /* The texture and the pixmap size is not match eaxctly, so can't sample it directly. - * rel_sampler will recalculate the texture coords.*/ - const char *rel_sampler = - " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n" - "{\n" - " tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n" - " if (repeat == RepeatFix) {\n" - " if (!(tex.x >= 0.0 && tex.x < 1.0 \n" - " && tex.y >= 0.0 && tex.y < 1.0))\n" - " return vec4(0.0, 0.0, 0.0, set_alpha);\n" - " tex = (fract(tex) / wh.xy);\n" - " }\n" - " if (set_alpha != 1)\n" - " return texture2D(tex_image, tex);\n" - " else\n" - " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n" - "}\n"; - - const char *source_solid_fetch = - GLAMOR_DEFAULT_PRECISION - "uniform vec4 source;\n" - "vec4 get_source()\n" "{\n" " return source;\n" "}\n"; - const char *source_alpha_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION - "varying vec2 source_texture;\n" - "uniform sampler2D source_sampler;\n" - "uniform vec4 source_wh;" - "vec4 get_source()\n" - "{\n" - " if (source_repeat_mode < RepeatFix)\n" - " return texture2D(source_sampler, source_texture);\n" - " else \n" - " return rel_sampler(source_sampler, source_texture,\n" - " source_wh, source_repeat_mode, 0);\n" - "}\n"; - const char *source_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" - "uniform sampler2D source_sampler;\n" - "uniform vec4 source_wh;\n" - "vec4 get_source()\n" - "{\n" - " if (source_repeat_mode < RepeatFix) \n" - " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n" - " else \n" - " return rel_sampler(source_sampler, source_texture,\n" - " source_wh, source_repeat_mode, 1);\n" - "}\n"; - const char *mask_solid_fetch = - GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n" - "vec4 get_mask()\n" "{\n" " return mask;\n" "}\n"; - const char *mask_alpha_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" - "uniform sampler2D mask_sampler;\n" - "uniform vec4 mask_wh;\n" - "vec4 get_mask()\n" - "{\n" - " if (mask_repeat_mode < RepeatFix) \n" - " return texture2D(mask_sampler, mask_texture);\n" - " else \n" - " return rel_sampler(mask_sampler, mask_texture,\n" - " mask_wh, mask_repeat_mode, 0);\n" - "}\n"; - const char *mask_pixmap_fetch = - GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" - "uniform sampler2D mask_sampler;\n" - "uniform vec4 mask_wh;\n" - "vec4 get_mask()\n" - "{\n" - " if (mask_repeat_mode < RepeatFix) \n" - " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n" - " else \n" - " return rel_sampler(mask_sampler, mask_texture,\n" - " mask_wh, mask_repeat_mode, 1);\n" - "}\n"; - const char *in_source_only = - GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" - " gl_FragColor = get_source();\n" "}\n"; - const char *in_normal = - GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" - " gl_FragColor = get_source() * get_mask().a;\n" "}\n"; - const char *in_ca_source = - GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" - " gl_FragColor = get_source() * get_mask();\n" "}\n"; - const char *in_ca_alpha = - GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" - " gl_FragColor = get_source().a * get_mask();\n" "}\n"; - char *source; - const char *source_fetch; - const char *mask_fetch = ""; - const char *in; - GLuint prog; - - switch (key->source) { - case SHADER_SOURCE_SOLID: - source_fetch = source_solid_fetch; - break; - case SHADER_SOURCE_TEXTURE_ALPHA: - source_fetch = source_alpha_pixmap_fetch; - break; - case SHADER_SOURCE_TEXTURE: - source_fetch = source_pixmap_fetch; - break; - default: - FatalError("Bad composite shader source"); - } - - switch (key->mask) { - case SHADER_MASK_NONE: - break; - case SHADER_MASK_SOLID: - mask_fetch = mask_solid_fetch; - break; - case SHADER_MASK_TEXTURE_ALPHA: - mask_fetch = mask_alpha_pixmap_fetch; - break; - case SHADER_MASK_TEXTURE: - mask_fetch = mask_pixmap_fetch; - break; - default: - FatalError("Bad composite shader mask"); - } - - switch (key->in) { - case SHADER_IN_SOURCE_ONLY: - in = in_source_only; - break; - case SHADER_IN_NORMAL: - in = in_normal; - break; - case SHADER_IN_CA_SOURCE: - in = in_ca_source; - break; - case SHADER_IN_CA_ALPHA: - in = in_ca_alpha; - break; - default: - FatalError("Bad composite IN type"); - } - - XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture, rel_sampler,source_fetch, mask_fetch, in); - - - prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - source); - free(source); - - return prog; + const char *repeat_define = + "#define RepeatNone 0\n" + "#define RepeatNormal 1\n" + "#define RepeatPad 2\n" + "#define RepeatReflect 3\n" + "#define RepeatFix 10\n" + "uniform int source_repeat_mode;\n" + "uniform int mask_repeat_mode;\n"; + const char *relocate_texture = + GLAMOR_DEFAULT_PRECISION + "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n" + "{\n" + " vec2 rel_tex; \n" + " rel_tex = texture * wh.xy; \n" + " if (repeat == RepeatNone)\n" + " return rel_tex; \n" + " else if (repeat == RepeatNormal) \n" + " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n" + " else if(repeat == RepeatPad) { \n" + " if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n" + " else if(rel_tex.x < 0.0) rel_tex.x = 0.0; \n" + " if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n" + " else if(rel_tex.y < 0.0) rel_tex.y = 0.0; \n" + " rel_tex = rel_tex / wh.xy; \n" + " } \n" + " else if(repeat == RepeatReflect) {\n" + " if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n" + " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n" + " else \n" + " rel_tex.x = fract(rel_tex.x)/wh.x;\n" + " if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n" + " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n" + " else \n" + " rel_tex.y = fract(rel_tex.y)/wh.y;\n" + " } \n" " return rel_tex; \n" "}\n"; + /* The texture and the pixmap size is not match eaxctly, so can't sample it directly. + * rel_sampler will recalculate the texture coords.*/ + const char *rel_sampler = + " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n" + "{\n" + " tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n" + " if (repeat == RepeatFix) {\n" + " if (!(tex.x >= 0.0 && tex.x < 1.0 \n" + " && tex.y >= 0.0 && tex.y < 1.0))\n" + " return vec4(0.0, 0.0, 0.0, set_alpha);\n" + " tex = (fract(tex) / wh.xy);\n" + " }\n" + " if (set_alpha != 1)\n" + " return texture2D(tex_image, tex);\n" + " else\n" + " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n" + "}\n"; + + const char *source_solid_fetch = + GLAMOR_DEFAULT_PRECISION + "uniform vec4 source;\n" + "vec4 get_source()\n" "{\n" " return source;\n" "}\n"; + const char *source_alpha_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION + "varying vec2 source_texture;\n" + "uniform sampler2D source_sampler;\n" + "uniform vec4 source_wh;" + "vec4 get_source()\n" + "{\n" + " if (source_repeat_mode < RepeatFix)\n" + " return texture2D(source_sampler, source_texture);\n" + " else \n" + " return rel_sampler(source_sampler, source_texture,\n" + " source_wh, source_repeat_mode, 0);\n" + "}\n"; + const char *source_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" + "uniform sampler2D source_sampler;\n" + "uniform vec4 source_wh;\n" + "vec4 get_source()\n" + "{\n" + " if (source_repeat_mode < RepeatFix) \n" + " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n" + " else \n" + " return rel_sampler(source_sampler, source_texture,\n" + " source_wh, source_repeat_mode, 1);\n" + "}\n"; + const char *mask_solid_fetch = + GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n" + "vec4 get_mask()\n" "{\n" " return mask;\n" "}\n"; + const char *mask_alpha_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" + "uniform sampler2D mask_sampler;\n" + "uniform vec4 mask_wh;\n" + "vec4 get_mask()\n" + "{\n" + " if (mask_repeat_mode < RepeatFix) \n" + " return texture2D(mask_sampler, mask_texture);\n" + " else \n" + " return rel_sampler(mask_sampler, mask_texture,\n" + " mask_wh, mask_repeat_mode, 0);\n" + "}\n"; + const char *mask_pixmap_fetch = + GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" + "uniform sampler2D mask_sampler;\n" + "uniform vec4 mask_wh;\n" + "vec4 get_mask()\n" + "{\n" + " if (mask_repeat_mode < RepeatFix) \n" + " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n" + " else \n" + " return rel_sampler(mask_sampler, mask_texture,\n" + " mask_wh, mask_repeat_mode, 1);\n" + "}\n"; + const char *in_source_only = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" + " gl_FragColor = get_source();\n" "}\n"; + const char *in_normal = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" + " gl_FragColor = get_source() * get_mask().a;\n" "}\n"; + const char *in_ca_source = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" + " gl_FragColor = get_source() * get_mask();\n" "}\n"; + const char *in_ca_alpha = + GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" + " gl_FragColor = get_source().a * get_mask();\n" "}\n"; + char *source; + const char *source_fetch; + const char *mask_fetch = ""; + const char *in; + GLuint prog; + + switch (key->source) { + case SHADER_SOURCE_SOLID: + source_fetch = source_solid_fetch; + break; + case SHADER_SOURCE_TEXTURE_ALPHA: + source_fetch = source_alpha_pixmap_fetch; + break; + case SHADER_SOURCE_TEXTURE: + source_fetch = source_pixmap_fetch; + break; + default: + FatalError("Bad composite shader source"); + } + + switch (key->mask) { + case SHADER_MASK_NONE: + break; + case SHADER_MASK_SOLID: + mask_fetch = mask_solid_fetch; + break; + case SHADER_MASK_TEXTURE_ALPHA: + mask_fetch = mask_alpha_pixmap_fetch; + break; + case SHADER_MASK_TEXTURE: + mask_fetch = mask_pixmap_fetch; + break; + default: + FatalError("Bad composite shader mask"); + } + + switch (key->in) { + case SHADER_IN_SOURCE_ONLY: + in = in_source_only; + break; + case SHADER_IN_NORMAL: + in = in_normal; + break; + case SHADER_IN_CA_SOURCE: + in = in_ca_source; + break; + case SHADER_IN_CA_ALPHA: + in = in_ca_alpha; + break; + default: + FatalError("Bad composite IN type"); + } + + XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture, + rel_sampler, source_fetch, mask_fetch, in); + + prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source); + free(source); + + return prog; } static GLuint glamor_create_composite_vs(glamor_gl_dispatch * dispatch, - struct shader_key *key) + struct shader_key *key) { - const char *main_opening = - "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord0;\n" - "attribute vec4 v_texcoord1;\n" - "varying vec2 source_texture;\n" - "varying vec2 mask_texture;\n" - "void main()\n" "{\n" " gl_Position = v_position;\n"; - const char *source_coords = - " source_texture = v_texcoord0.xy;\n"; - const char *mask_coords = " mask_texture = v_texcoord1.xy;\n"; - const char *main_closing = "}\n"; - const char *source_coords_setup = ""; - const char *mask_coords_setup = ""; - char *source; - GLuint prog; - - if (key->source != SHADER_SOURCE_SOLID) - source_coords_setup = source_coords; - - if (key->mask != SHADER_MASK_NONE - && key->mask != SHADER_MASK_SOLID) - mask_coords_setup = mask_coords; - - XNFasprintf(&source, - "%s%s%s%s", - main_opening, - source_coords_setup, mask_coords_setup, main_closing); - - prog = - glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source); - free(source); - - return prog; + const char *main_opening = + "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord0;\n" + "attribute vec4 v_texcoord1;\n" + "varying vec2 source_texture;\n" + "varying vec2 mask_texture;\n" + "void main()\n" "{\n" " gl_Position = v_position;\n"; + const char *source_coords = " source_texture = v_texcoord0.xy;\n"; + const char *mask_coords = " mask_texture = v_texcoord1.xy;\n"; + const char *main_closing = "}\n"; + const char *source_coords_setup = ""; + const char *mask_coords_setup = ""; + char *source; + GLuint prog; + + if (key->source != SHADER_SOURCE_SOLID) + source_coords_setup = source_coords; + + if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID) + mask_coords_setup = mask_coords; + + XNFasprintf(&source, + "%s%s%s%s", + main_opening, + source_coords_setup, mask_coords_setup, main_closing); + + prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source); + free(source); + + return prog; } static void glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, - glamor_composite_shader * shader) + glamor_composite_shader * shader) { - GLuint vs, fs, prog; - GLint source_sampler_uniform_location, - mask_sampler_uniform_location; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch; - - dispatch = glamor_get_dispatch(glamor_priv); - vs = glamor_create_composite_vs(dispatch, key); - if (vs == 0) - goto out; - fs = glamor_create_composite_fs(dispatch, key); - if (fs == 0) - goto out; - - prog = dispatch->glCreateProgram(); - dispatch->glAttachShader(prog, vs); - dispatch->glAttachShader(prog, fs); - - dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, - "v_position"); - dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, - "v_texcoord0"); - dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, - "v_texcoord1"); - - glamor_link_glsl_prog(dispatch, prog); - - shader->prog = prog; - - dispatch->glUseProgram(prog); - - if (key->source == SHADER_SOURCE_SOLID) { - shader->source_uniform_location = - dispatch->glGetUniformLocation(prog, "source"); - } else { - source_sampler_uniform_location = - dispatch->glGetUniformLocation(prog, "source_sampler"); - dispatch->glUniform1i(source_sampler_uniform_location, 0); - shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh"); - shader->source_repeat_mode = dispatch->glGetUniformLocation(prog, "source_repeat_mode"); - } - - if (key->mask != SHADER_MASK_NONE) { - if (key->mask == SHADER_MASK_SOLID) { - shader->mask_uniform_location = - dispatch->glGetUniformLocation(prog, "mask"); - } else { - mask_sampler_uniform_location = - dispatch->glGetUniformLocation(prog, - "mask_sampler"); - dispatch->glUniform1i - (mask_sampler_uniform_location, 1); - shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh"); - shader->mask_repeat_mode = dispatch->glGetUniformLocation(prog, "mask_repeat_mode"); - } - } - -out: - glamor_put_dispatch(glamor_priv); + GLuint vs, fs, prog; + GLint source_sampler_uniform_location, mask_sampler_uniform_location; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; + + dispatch = glamor_get_dispatch(glamor_priv); + vs = glamor_create_composite_vs(dispatch, key); + if (vs == 0) + goto out; + fs = glamor_create_composite_fs(dispatch, key); + if (fs == 0) + goto out; + + prog = dispatch->glCreateProgram(); + dispatch->glAttachShader(prog, vs); + dispatch->glAttachShader(prog, fs); + + dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); + + glamor_link_glsl_prog(dispatch, prog); + + shader->prog = prog; + + dispatch->glUseProgram(prog); + + if (key->source == SHADER_SOURCE_SOLID) { + shader->source_uniform_location = + dispatch->glGetUniformLocation(prog, "source"); + } + else { + source_sampler_uniform_location = + dispatch->glGetUniformLocation(prog, "source_sampler"); + dispatch->glUniform1i(source_sampler_uniform_location, 0); + shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh"); + shader->source_repeat_mode = + dispatch->glGetUniformLocation(prog, "source_repeat_mode"); + } + + if (key->mask != SHADER_MASK_NONE) { + if (key->mask == SHADER_MASK_SOLID) { + shader->mask_uniform_location = + dispatch->glGetUniformLocation(prog, "mask"); + } + else { + mask_sampler_uniform_location = + dispatch->glGetUniformLocation(prog, "mask_sampler"); + dispatch->glUniform1i(mask_sampler_uniform_location, 1); + shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh"); + shader->mask_repeat_mode = + dispatch->glGetUniformLocation(prog, "mask_repeat_mode"); + } + } + + out: + glamor_put_dispatch(glamor_priv); } static glamor_composite_shader * glamor_lookup_composite_shader(ScreenPtr screen, struct - shader_key - *key) + shader_key + *key) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_composite_shader *shader; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_composite_shader *shader; - shader = - &glamor_priv->composite_shader[key->source][key-> - mask][key->in]; - if (shader->prog == 0) - glamor_create_composite_shader(screen, key, shader); + shader = &glamor_priv->composite_shader[key->source][key->mask][key->in]; + if (shader->prog == 0) + glamor_create_composite_shader(screen, key, shader); - return shader; + return shader; } static void glamor_init_eb(unsigned short *eb, int vert_cnt) { - int i, j; - for(i = 0, j = 0; j < vert_cnt; i += 6, j += 4) - { - eb[i] = j; - eb[i + 1] = j + 1; - eb[i + 2] = j + 2; - eb[i + 3] = j; - eb[i + 4] = j + 2; - eb[i + 5] = j + 3; - } + int i, j; + + for (i = 0, j = 0; j < vert_cnt; i += 6, j += 4) { + eb[i] = j; + eb[i + 1] = j + 1; + eb[i + 2] = j + 2; + eb[i + 3] = j; + eb[i + 4] = j + 2; + eb[i + 5] = j + 3; + } } void glamor_init_composite_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - unsigned short *eb; - float *vb = NULL; - int eb_size; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glGenBuffers(1, &glamor_priv->vbo); - dispatch->glGenBuffers(1, &glamor_priv->ebo); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); - - eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2; - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER, - eb_size, - NULL, GL_STATIC_DRAW); - eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else { - vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2); - if (vb == NULL) - FatalError("Failed to allocate vb memory.\n"); - eb = malloc(eb_size); - } - - if (eb == NULL) - FatalError("fatal error, fail to get element buffer. GL context may be not created correctly.\n"); - glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT); - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } else { - dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER, - eb_size, - eb, GL_STATIC_DRAW); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - dispatch->glBufferData(GL_ARRAY_BUFFER, - GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2, - NULL, GL_DYNAMIC_DRAW); - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - - free(eb); - glamor_priv->vb = (char*)vb; - } - - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + unsigned short *eb; + float *vb = NULL; + int eb_size; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glGenBuffers(1, &glamor_priv->vbo); + dispatch->glGenBuffers(1, &glamor_priv->ebo); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); + + eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2; + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER, + eb_size, NULL, GL_STATIC_DRAW); + eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + } + else { + vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2); + if (vb == NULL) + FatalError("Failed to allocate vb memory.\n"); + eb = malloc(eb_size); + } + + if (eb == NULL) + FatalError + ("fatal error, fail to get element buffer. GL context may be not created correctly.\n"); + glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT); + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + else { + dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER, + eb_size, eb, GL_STATIC_DRAW); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + dispatch->glBufferData(GL_ARRAY_BUFFER, + GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * + 2, NULL, GL_DYNAMIC_DRAW); + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + + free(eb); + glamor_priv->vb = (char *) vb; + } + + glamor_put_dispatch(glamor_priv); } void glamor_fini_composite_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - glamor_composite_shader *shader; - int i,j,k; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glDeleteBuffers(1, &glamor_priv->vbo); - dispatch->glDeleteBuffers(1, &glamor_priv->ebo); - - for(i = 0; i < SHADER_SOURCE_COUNT; i++) - for(j = 0; j < SHADER_MASK_COUNT; j++) - for(k = 0; k < SHADER_IN_COUNT; k++) - { - shader = &glamor_priv->composite_shader[i][j][k]; - if (shader->prog) - dispatch->glDeleteProgram(shader->prog); - } - if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP - && glamor_priv->vb) - free(glamor_priv->vb); - - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + glamor_composite_shader *shader; + int i, j, k; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glDeleteBuffers(1, &glamor_priv->vbo); + dispatch->glDeleteBuffers(1, &glamor_priv->ebo); + + for (i = 0; i < SHADER_SOURCE_COUNT; i++) + for (j = 0; j < SHADER_MASK_COUNT; j++) + for (k = 0; k < SHADER_IN_COUNT; k++) { + shader = &glamor_priv->composite_shader[i][j][k]; + if (shader->prog) + dispatch->glDeleteProgram(shader->prog); + } + if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && glamor_priv->vb) + free(glamor_priv->vb); + + glamor_put_dispatch(glamor_priv); } static Bool glamor_set_composite_op(ScreenPtr screen, - CARD8 op, struct blendinfo *op_info_result, - PicturePtr dest, PicturePtr mask) + CARD8 op, struct blendinfo *op_info_result, + PicturePtr dest, PicturePtr mask) { - GLenum source_blend, dest_blend; - struct blendinfo *op_info; - - if (op >= ARRAY_SIZE(composite_op_info)) { - glamor_fallback("unsupported render op %d \n", op); - return GL_FALSE; - } - op_info = &composite_op_info[op]; - - source_blend = op_info->source_blend; - dest_blend = op_info->dest_blend; - - /* If there's no dst alpha channel, adjust the blend op so that we'll treat - * it as always 1. - */ - if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) { - if (source_blend == GL_DST_ALPHA) - source_blend = GL_ONE; - else if (source_blend == GL_ONE_MINUS_DST_ALPHA) - source_blend = GL_ZERO; - } - - /* Set up the source alpha value for blending in component alpha mode. */ - if (mask && mask->componentAlpha - && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) - { - if (dest_blend == GL_SRC_ALPHA) - dest_blend = GL_SRC_COLOR; - else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA) - dest_blend = GL_ONE_MINUS_SRC_COLOR; - } - - op_info_result->source_blend = source_blend; - op_info_result->dest_blend = dest_blend; - op_info_result->source_alpha = op_info->source_alpha; - op_info_result->dest_alpha = op_info->dest_alpha; - - return TRUE; + GLenum source_blend, dest_blend; + struct blendinfo *op_info; + + if (op >= ARRAY_SIZE(composite_op_info)) { + glamor_fallback("unsupported render op %d \n", op); + return GL_FALSE; + } + op_info = &composite_op_info[op]; + + source_blend = op_info->source_blend; + dest_blend = op_info->dest_blend; + + /* If there's no dst alpha channel, adjust the blend op so that we'll treat + * it as always 1. + */ + if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) { + if (source_blend == GL_DST_ALPHA) + source_blend = GL_ONE; + else if (source_blend == GL_ONE_MINUS_DST_ALPHA) + source_blend = GL_ZERO; + } + + /* Set up the source alpha value for blending in component alpha mode. */ + if (mask && mask->componentAlpha + && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) { + if (dest_blend == GL_SRC_ALPHA) + dest_blend = GL_SRC_COLOR; + else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA) + dest_blend = GL_ONE_MINUS_SRC_COLOR; + } + + op_info_result->source_blend = source_blend; + op_info_result->dest_blend = dest_blend; + op_info_result->source_alpha = op_info->source_alpha; + op_info_result->dest_alpha = op_info->dest_alpha; + + return TRUE; } static void -glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit, - PicturePtr picture, - glamor_pixmap_private * pixmap_priv, - GLuint wh_location, GLuint repeat_location) +glamor_set_composite_texture(glamor_screen_private * glamor_priv, int unit, + PicturePtr picture, + glamor_pixmap_private * pixmap_priv, + GLuint wh_location, GLuint repeat_location) { - glamor_gl_dispatch *dispatch; - float wh[4]; - int repeat_type; - - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glActiveTexture(GL_TEXTURE0 + unit); - dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex); - repeat_type = picture->repeatType; - switch (picture->repeatType) { - case RepeatNone: + glamor_gl_dispatch *dispatch; + float wh[4]; + int repeat_type; + + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glActiveTexture(GL_TEXTURE0 + unit); + dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex); + repeat_type = picture->repeatType; + switch (picture->repeatType) { + case RepeatNone: #ifndef GLAMOR_GLES2 - /* XXX GLES2 doesn't support GL_CLAMP_TO_BORDER. */ - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_BORDER); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_BORDER); + /* XXX GLES2 doesn't support GL_CLAMP_TO_BORDER. */ + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_BORDER); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_BORDER); #else - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); #endif - break; - case RepeatNormal: - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_REPEAT); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - GL_REPEAT); - break; - case RepeatPad: - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE); - break; - case RepeatReflect: - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_MIRRORED_REPEAT); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - GL_MIRRORED_REPEAT); - break; - } - - switch (picture->filter) { - default: - case PictFilterFast: - case PictFilterNearest: - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - break; - case PictFilterGood: - case PictFilterBest: - case PictFilterBilinear: - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_LINEAR); - break; - } + break; + case RepeatNormal: + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case RepeatPad: + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + break; + case RepeatReflect: + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_MIRRORED_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GL_MIRRORED_REPEAT); + break; + } + + switch (picture->filter) { + default: + case PictFilterFast: + case PictFilterNearest: + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case PictFilterGood: + case PictFilterBest: + case PictFilterBilinear: + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_LINEAR); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + } #ifndef GLAMOR_GLES2 - dispatch->glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif - /* - * GLES2 doesn't support RepeatNone. We need to fix it anyway. - * - **/ - if (repeat_type != RepeatNone) - repeat_type += RepeatFix; - else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - if (picture->transform - || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))) - repeat_type += RepeatFix; - } - if (repeat_type >= RepeatFix) { - glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv); - if ((wh[0] != 1.0 || wh[1] != 1.0 ) - || (glamor_priv->gl_flavor == GLAMOR_GL_ES2 - && repeat_type == RepeatFix)) - dispatch->glUniform4fv(wh_location, 1, wh); - else - repeat_type -= RepeatFix; - } - dispatch->glUniform1i(repeat_location, repeat_type); - glamor_put_dispatch(glamor_priv); + /* + * GLES2 doesn't support RepeatNone. We need to fix it anyway. + * + **/ + if (repeat_type != RepeatNone) + repeat_type += RepeatFix; + else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 + || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + if (picture->transform + || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))) + repeat_type += RepeatFix; + } + if (repeat_type >= RepeatFix) { + glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv); + if ((wh[0] != 1.0 || wh[1] != 1.0) + || (glamor_priv->gl_flavor == GLAMOR_GL_ES2 + && repeat_type == RepeatFix)) + dispatch->glUniform4fv(wh_location, 1, wh); + else + repeat_type -= RepeatFix; + } + dispatch->glUniform1i(repeat_location, repeat_type); + glamor_put_dispatch(glamor_priv); } static void glamor_set_composite_solid(glamor_gl_dispatch * dispatch, float *color, - GLint uniform_location) + GLint uniform_location) { - dispatch->glUniform4fv(uniform_location, 1, color); + dispatch->glUniform4fv(uniform_location, 1, color); } static int compatible_formats(CARD8 op, PicturePtr dst, PicturePtr src) { - if (op == PictOpSrc) { - if (src->format == dst->format) - return 1; - - if (src->format == PICT_a8r8g8b8 - && dst->format == PICT_x8r8g8b8) - return 1; - - if (src->format == PICT_a8b8g8r8 - && dst->format == PICT_x8b8g8r8) - return 1; - } else if (op == PictOpOver) { - if (src->alphaMap || dst->alphaMap) - return 0; - - if (src->format != dst->format) - return 0; - - if (src->format == PICT_x8r8g8b8 - || src->format == PICT_x8b8g8r8) - return 1; - } - - return 0; + if (op == PictOpSrc) { + if (src->format == dst->format) + return 1; + + if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8) + return 1; + + if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8) + return 1; + } + else if (op == PictOpOver) { + if (src->alphaMap || dst->alphaMap) + return 0; + + if (src->format != dst->format) + return 0; + + if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8) + return 1; + } + + return 0; } static char glamor_get_picture_location(PicturePtr picture) { - if (picture == NULL) - return ' '; - - if (picture->pDrawable == NULL) { - switch (picture->pSourcePict->type) { - case SourcePictTypeSolidFill: - return 'c'; - case SourcePictTypeLinear: - return 'l'; - case SourcePictTypeRadial: - return 'r'; - default: - return '?'; - } - } - return glamor_get_drawable_location(picture->pDrawable); + if (picture == NULL) + return ' '; + + if (picture->pDrawable == NULL) { + switch (picture->pSourcePict->type) { + case SourcePictTypeSolidFill: + return 'c'; + case SourcePictTypeLinear: + return 'l'; + case SourcePictTypeRadial: + return 'r'; + default: + return '?'; + } + } + return glamor_get_drawable_location(picture->pDrawable); } static Bool glamor_composite_with_copy(CARD8 op, - PicturePtr source, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_dest, - INT16 y_dest, - RegionPtr region) + PicturePtr source, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_dest, INT16 y_dest, RegionPtr region) { - int ret = FALSE; - if (!source->pDrawable) - return FALSE; - - if (!compatible_formats(op, dest, source)) - return FALSE; - - if (source->repeat || source->transform) { - return FALSE; - } - - x_dest += dest->pDrawable->x; - y_dest += dest->pDrawable->y; - x_source += source->pDrawable->x; - y_source += source->pDrawable->y; - if (PICT_FORMAT_A(source->format) == 0) { - /* Fallback if we sample outside the source so that we - * swizzle the correct clear color for out-of-bounds texels. - */ - if (region->extents.x1 + x_source - x_dest < 0) - goto cleanup_region; - if (region->extents.x2 + x_source - x_dest > source->pDrawable->width) - goto cleanup_region; - - if (region->extents.y1 + y_source - y_dest < 0) - goto cleanup_region; - 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); -cleanup_region: - return ret; + int ret = FALSE; + + if (!source->pDrawable) + return FALSE; + + if (!compatible_formats(op, dest, source)) + return FALSE; + + if (source->repeat || source->transform) { + return FALSE; + } + + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + x_source += source->pDrawable->x; + y_source += source->pDrawable->y; + if (PICT_FORMAT_A(source->format) == 0) { + /* Fallback if we sample outside the source so that we + * swizzle the correct clear color for out-of-bounds texels. + */ + if (region->extents.x1 + x_source - x_dest < 0) + goto cleanup_region; + if (region->extents.x2 + x_source - x_dest > source->pDrawable->width) + goto cleanup_region; + + if (region->extents.y1 + y_source - y_dest < 0) + goto cleanup_region; + 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); + cleanup_region: + return ret; } void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch; - int vert_size; - - glamor_priv->render_nr_verts = 0; - glamor_priv->vb_stride = 2 * sizeof(float); - if (glamor_priv->has_source_coords) - glamor_priv->vb_stride += 2 * sizeof(float); - if (glamor_priv->has_mask_coords) - glamor_priv->vb_stride += 2 * sizeof(float); - - vert_size = n_verts * glamor_priv->vb_stride; - - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) { - glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * - glamor_priv->vb_stride; - glamor_priv->vbo_offset = 0; - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_size, - NULL, GL_STREAM_DRAW); - } - - glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - vert_size, - GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); - assert(glamor_priv->vb != NULL); - glamor_priv->vb -= glamor_priv->vbo_offset; - } else - glamor_priv->vbo_offset = 0; - - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long) - glamor_priv->vbo_offset)); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - - if (glamor_priv->has_source_coords) { - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, - GL_FLOAT, GL_FALSE, - glamor_priv->vb_stride, - (void *) ((long) - glamor_priv->vbo_offset - + - 2 * - sizeof(float))); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - } - - if (glamor_priv->has_mask_coords) { - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, - GL_FLOAT, GL_FALSE, - glamor_priv->vb_stride, - (void *) ((long) - glamor_priv->vbo_offset - + - (glamor_priv->has_source_coords - ? 4 : 2) * - sizeof(float))); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); - } - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; + int vert_size; + + glamor_priv->render_nr_verts = 0; + glamor_priv->vb_stride = 2 * sizeof(float); + if (glamor_priv->has_source_coords) + glamor_priv->vb_stride += 2 * sizeof(float); + if (glamor_priv->has_mask_coords) + glamor_priv->vb_stride += 2 * sizeof(float); + + vert_size = n_verts * glamor_priv->vb_stride; + + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) { + glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * + glamor_priv->vb_stride; + glamor_priv->vbo_offset = 0; + dispatch->glBufferData(GL_ARRAY_BUFFER, + glamor_priv->vbo_size, NULL, GL_STREAM_DRAW); + } + + glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, + glamor_priv->vbo_offset, + vert_size, + GL_MAP_WRITE_BIT | + GL_MAP_UNSYNCHRONIZED_BIT); + assert(glamor_priv->vb != NULL); + glamor_priv->vb -= glamor_priv->vbo_offset; + } + else + glamor_priv->vbo_offset = 0; + + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, glamor_priv->vb_stride, + (void *) ((long) + glamor_priv->vbo_offset)); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + + if (glamor_priv->has_source_coords) { + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, + GL_FLOAT, GL_FALSE, + glamor_priv->vb_stride, (void *) ((long) + glamor_priv-> + vbo_offset + + + 2 * + sizeof + (float))); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + } + + if (glamor_priv->has_mask_coords) { + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, + GL_FLOAT, GL_FALSE, + glamor_priv->vb_stride, (void *) ((long) + glamor_priv-> + vbo_offset + + + (glamor_priv-> + has_source_coords + ? 4 : + 2) * + sizeof + (float))); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); + } + glamor_put_dispatch(glamor_priv); } void glamor_emit_composite_vert(ScreenPtr screen, - const float *src_coords, - const float *mask_coords, - const float *dst_coords, int i) + const float *src_coords, + const float *mask_coords, + const float *dst_coords, int i) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset); - int j = 0; - - vb[j++] = dst_coords[i * 2 + 0]; - vb[j++] = dst_coords[i * 2 + 1]; - if (glamor_priv->has_source_coords) { - vb[j++] = src_coords[i * 2 + 0]; - vb[j++] = src_coords[i * 2 + 1]; - } - if (glamor_priv->has_mask_coords) { - vb[j++] = mask_coords[i * 2 + 0]; - vb[j++] = mask_coords[i * 2 + 1]; - } - - glamor_priv->render_nr_verts++; - glamor_priv->vbo_offset += glamor_priv->vb_stride; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset); + int j = 0; + + vb[j++] = dst_coords[i * 2 + 0]; + vb[j++] = dst_coords[i * 2 + 1]; + if (glamor_priv->has_source_coords) { + vb[j++] = src_coords[i * 2 + 0]; + vb[j++] = src_coords[i * 2 + 1]; + } + if (glamor_priv->has_mask_coords) { + vb[j++] = mask_coords[i * 2 + 0]; + vb[j++] = mask_coords[i * 2 + 1]; + } + + glamor_priv->render_nr_verts++; + glamor_priv->vbo_offset += glamor_priv->vb_stride; } - - static void glamor_flush_composite_rects(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; - dispatch = glamor_get_dispatch(glamor_priv); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); - else { + dispatch = glamor_get_dispatch(glamor_priv); + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); + else { - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - glamor_priv->vb, GL_DYNAMIC_DRAW); - } + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + dispatch->glBufferData(GL_ARRAY_BUFFER, + glamor_priv->vbo_offset, + glamor_priv->vb, GL_DYNAMIC_DRAW); + } - if (!glamor_priv->render_nr_verts) - return; + if (!glamor_priv->render_nr_verts) + return; #ifndef GLAMOR_GLES2 - dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts, - (glamor_priv->render_nr_verts * 3) / 2, - GL_UNSIGNED_SHORT, NULL); + dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts, + (glamor_priv->render_nr_verts * 3) / 2, + GL_UNSIGNED_SHORT, NULL); #else - dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2, - GL_UNSIGNED_SHORT, NULL); + dispatch->glDrawElements(GL_TRIANGLES, + (glamor_priv->render_nr_verts * 3) / 2, + GL_UNSIGNED_SHORT, NULL); #endif - glamor_put_dispatch(glamor_priv); + glamor_put_dispatch(glamor_priv); } int pict_format_combine_tab[][3] = { - {PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB}, - {PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR}, + {PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB}, + {PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR}, }; static Bool combine_pict_format(PictFormatShort * des, const PictFormatShort src, - const PictFormatShort mask, enum shader_in in_ca) + const PictFormatShort mask, enum shader_in in_ca) { - PictFormatShort new_vis; - int src_type, mask_type, src_bpp, mask_bpp; - int i; - if (src == mask) { - *des = src; - return TRUE; - } - src_bpp = PICT_FORMAT_BPP(src); - mask_bpp = PICT_FORMAT_BPP(mask); - - assert(src_bpp == mask_bpp); - - new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask); - - switch (in_ca) { - case SHADER_IN_SOURCE_ONLY: - return TRUE; - case SHADER_IN_NORMAL: - src_type = PICT_FORMAT_TYPE(src); - mask_type = PICT_TYPE_A; - break; - case SHADER_IN_CA_SOURCE: - src_type = PICT_FORMAT_TYPE(src); - mask_type = PICT_FORMAT_TYPE(mask); - break; - case SHADER_IN_CA_ALPHA: - src_type = PICT_TYPE_A; - mask_type = PICT_FORMAT_TYPE(mask); - break; - default: - return FALSE; - } - - if (src_type == mask_type) { - *des = PICT_VISFORMAT(src_bpp, src_type, new_vis); - return TRUE; - } - - for (i = 0; - i < - sizeof(pict_format_combine_tab) / - sizeof(pict_format_combine_tab[0]); i++) { - if ((src_type == pict_format_combine_tab[i][0] - && mask_type == pict_format_combine_tab[i][1]) - || (src_type == pict_format_combine_tab[i][1] - && mask_type == pict_format_combine_tab[i][0])) { - *des = PICT_VISFORMAT(src_bpp, - pict_format_combine_tab[i] - [2], new_vis); - return TRUE; - } - } - return FALSE; + PictFormatShort new_vis; + int src_type, mask_type, src_bpp, mask_bpp; + int i; + + if (src == mask) { + *des = src; + return TRUE; + } + src_bpp = PICT_FORMAT_BPP(src); + mask_bpp = PICT_FORMAT_BPP(mask); + + assert(src_bpp == mask_bpp); + + new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask); + + switch (in_ca) { + case SHADER_IN_SOURCE_ONLY: + return TRUE; + case SHADER_IN_NORMAL: + src_type = PICT_FORMAT_TYPE(src); + mask_type = PICT_TYPE_A; + break; + case SHADER_IN_CA_SOURCE: + src_type = PICT_FORMAT_TYPE(src); + mask_type = PICT_FORMAT_TYPE(mask); + break; + case SHADER_IN_CA_ALPHA: + src_type = PICT_TYPE_A; + mask_type = PICT_FORMAT_TYPE(mask); + break; + default: + return FALSE; + } + + if (src_type == mask_type) { + *des = PICT_VISFORMAT(src_bpp, src_type, new_vis); + return TRUE; + } + + for (i = 0; + i < + sizeof(pict_format_combine_tab) / + sizeof(pict_format_combine_tab[0]); i++) { + if ((src_type == pict_format_combine_tab[i][0] + && mask_type == pict_format_combine_tab[i][1]) + || (src_type == pict_format_combine_tab[i][1] + && mask_type == pict_format_combine_tab[i][0])) { + *des = PICT_VISFORMAT(src_bpp, pict_format_combine_tab[i] + [2], new_vis); + return TRUE; + } + } + return FALSE; } static void -glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv, - int repeat_type, - float *matrix, - float xscale, float yscale, - int x1, int y1, int x2, int y2, - int yInverted, float *texcoords, - int stride) +glamor_set_normalize_tcoords_generic(glamor_pixmap_private * priv, + int repeat_type, + float *matrix, + float xscale, float yscale, + int x1, int y1, int x2, int y2, + int yInverted, float *texcoords, + int stride) { - if (!matrix && repeat_type == RepeatNone) - glamor_set_normalize_tcoords_ext(priv, xscale, yscale, - x1, y1, - x2, y2, - yInverted, - 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); - else if (matrix && repeat_type != RepeatNone) - glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type, - matrix, xscale, yscale, - x1, y1, - x2, y2, - yInverted, - texcoords, stride); + if (!matrix && repeat_type == RepeatNone) + glamor_set_normalize_tcoords_ext(priv, xscale, yscale, + x1, y1, + x2, y2, yInverted, 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); + else if (matrix && repeat_type != RepeatNone) + glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type, + matrix, xscale, + yscale, x1, y1, x2, + y2, yInverted, + texcoords, stride); } -Bool glamor_composite_choose_shader(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - glamor_pixmap_private *source_pixmap_priv, - glamor_pixmap_private *mask_pixmap_priv, - glamor_pixmap_private *dest_pixmap_priv, - struct shader_key *s_key, - glamor_composite_shader **shader, - struct blendinfo *op_info, - PictFormatShort *psaved_source_format) +Bool +glamor_composite_choose_shader(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private * source_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, + struct shader_key *s_key, + glamor_composite_shader ** shader, + struct blendinfo *op_info, + PictFormatShort * psaved_source_format) { - ScreenPtr screen = dest->pDrawable->pScreen; - PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap; - PixmapPtr source_pixmap = NULL; - PixmapPtr mask_pixmap = NULL; - enum glamor_pixmap_status source_status = GLAMOR_NONE; - enum glamor_pixmap_status mask_status = GLAMOR_NONE; - PictFormatShort saved_source_format = 0; - struct shader_key key; - GLfloat source_solid_color[4]; - GLfloat mask_solid_color[4]; - Bool ret = FALSE; - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { - glamor_fallback("dest has no fbo.\n"); - goto fail; - } - - memset(&key, 0, sizeof(key)); - if (!source) { - key.source = SHADER_SOURCE_SOLID; - source_solid_color[0] = 0.0; - source_solid_color[1] = 0.0; - source_solid_color[2] = 0.0; - source_solid_color[3] = 0.0; - } else if (!source->pDrawable) { - if (source->pSourcePict->type == SourcePictTypeSolidFill) { - key.source = SHADER_SOURCE_SOLID; - glamor_get_rgba_from_pixel(source-> - pSourcePict->solidFill. - color, - &source_solid_color[0], - &source_solid_color[1], - &source_solid_color[2], - &source_solid_color[3], - PICT_a8r8g8b8); - } else - goto fail; - } else { - key.source = SHADER_SOURCE_TEXTURE_ALPHA; - } - - if (mask) { - if (!mask->pDrawable) { - if (mask->pSourcePict->type == - SourcePictTypeSolidFill) { - key.mask = SHADER_MASK_SOLID; - glamor_get_rgba_from_pixel - (mask->pSourcePict->solidFill.color, - &mask_solid_color[0], - &mask_solid_color[1], - &mask_solid_color[2], - &mask_solid_color[3], PICT_a8r8g8b8); - } else - goto fail; - } else { - key.mask = SHADER_MASK_TEXTURE_ALPHA; - } - - if (!mask->componentAlpha) { - key.in = SHADER_IN_NORMAL; - } else { - if (op == PictOpClear) - key.mask = SHADER_MASK_NONE; - else if (op == PictOpSrc || op == PictOpAdd - || op == PictOpIn || op == PictOpOut - || op == PictOpOverReverse) - key.in = SHADER_IN_CA_SOURCE; - else if (op == PictOpOutReverse || op == PictOpInReverse) { - key.in = SHADER_IN_CA_ALPHA; - } else { - glamor_fallback("Unsupported component alpha op: %d\n", op); - goto fail; - } - } - } else { - key.mask = SHADER_MASK_NONE; - key.in = SHADER_IN_SOURCE_ONLY; - } - - if (source && source->alphaMap) { - glamor_fallback("source alphaMap\n"); - goto fail; - } - if (mask && mask->alphaMap) { - glamor_fallback("mask alphaMap\n"); - goto fail; - } - - if (key.source == SHADER_SOURCE_TEXTURE || - key.source == SHADER_SOURCE_TEXTURE_ALPHA) { - source_pixmap = source_pixmap_priv->base.pixmap; - if (source_pixmap == dest_pixmap) { - /* XXX source and the dest share the same texture. - * Does it need special handle? */ - glamor_fallback("source == dest\n"); - } - if (source_pixmap_priv->base.gl_fbo == 0) { - /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex - * equal to zero when the pixmap is screen pixmap. Then we may - * refer the tex zero directly latter in the composition. - * It seems that it works fine, but it may have potential problem*/ + ScreenPtr screen = dest->pDrawable->pScreen; + PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap; + PixmapPtr source_pixmap = NULL; + PixmapPtr mask_pixmap = NULL; + enum glamor_pixmap_status source_status = GLAMOR_NONE; + enum glamor_pixmap_status mask_status = GLAMOR_NONE; + PictFormatShort saved_source_format = 0; + struct shader_key key; + GLfloat source_solid_color[4]; + GLfloat mask_solid_color[4]; + Bool ret = FALSE; + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { + glamor_fallback("dest has no fbo.\n"); + goto fail; + } + + memset(&key, 0, sizeof(key)); + if (!source) { + key.source = SHADER_SOURCE_SOLID; + source_solid_color[0] = 0.0; + source_solid_color[1] = 0.0; + source_solid_color[2] = 0.0; + source_solid_color[3] = 0.0; + } + else if (!source->pDrawable) { + if (source->pSourcePict->type == SourcePictTypeSolidFill) { + key.source = SHADER_SOURCE_SOLID; + glamor_get_rgba_from_pixel(source->pSourcePict->solidFill.color, + &source_solid_color[0], + &source_solid_color[1], + &source_solid_color[2], + &source_solid_color[3], PICT_a8r8g8b8); + } + else + goto fail; + } + else { + key.source = SHADER_SOURCE_TEXTURE_ALPHA; + } + + if (mask) { + if (!mask->pDrawable) { + if (mask->pSourcePict->type == SourcePictTypeSolidFill) { + key.mask = SHADER_MASK_SOLID; + glamor_get_rgba_from_pixel + (mask->pSourcePict->solidFill.color, + &mask_solid_color[0], + &mask_solid_color[1], + &mask_solid_color[2], &mask_solid_color[3], PICT_a8r8g8b8); + } + else + goto fail; + } + else { + key.mask = SHADER_MASK_TEXTURE_ALPHA; + } + + if (!mask->componentAlpha) { + key.in = SHADER_IN_NORMAL; + } + else { + if (op == PictOpClear) + key.mask = SHADER_MASK_NONE; + else if (op == PictOpSrc || op == PictOpAdd + || op == PictOpIn || op == PictOpOut + || op == PictOpOverReverse) + key.in = SHADER_IN_CA_SOURCE; + else if (op == PictOpOutReverse || op == PictOpInReverse) { + key.in = SHADER_IN_CA_ALPHA; + } + else { + glamor_fallback("Unsupported component alpha op: %d\n", op); + goto fail; + } + } + } + else { + key.mask = SHADER_MASK_NONE; + key.in = SHADER_IN_SOURCE_ONLY; + } + + if (source && source->alphaMap) { + glamor_fallback("source alphaMap\n"); + goto fail; + } + if (mask && mask->alphaMap) { + glamor_fallback("mask alphaMap\n"); + goto fail; + } + + if (key.source == SHADER_SOURCE_TEXTURE || + key.source == SHADER_SOURCE_TEXTURE_ALPHA) { + source_pixmap = source_pixmap_priv->base.pixmap; + if (source_pixmap == dest_pixmap) { + /* XXX source and the dest share the same texture. + * Does it need special handle? */ + glamor_fallback("source == dest\n"); + } + if (source_pixmap_priv->base.gl_fbo == 0) { + /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex + * equal to zero when the pixmap is screen pixmap. Then we may + * refer the tex zero directly latter in the composition. + * It seems that it works fine, but it may have potential problem*/ #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD - source_status = GLAMOR_UPLOAD_PENDING; + source_status = GLAMOR_UPLOAD_PENDING; #else - glamor_fallback("no texture in source\n"); - goto fail; + glamor_fallback("no texture in source\n"); + goto fail; #endif - } - } - - if (key.mask == SHADER_MASK_TEXTURE || - key.mask == SHADER_MASK_TEXTURE_ALPHA) { - mask_pixmap = mask_pixmap_priv->base.pixmap; - if (mask_pixmap == dest_pixmap) { - glamor_fallback("mask == dest\n"); - goto fail; - } - if (mask_pixmap_priv->base.gl_fbo == 0) { + } + } + + if (key.mask == SHADER_MASK_TEXTURE || + key.mask == SHADER_MASK_TEXTURE_ALPHA) { + mask_pixmap = mask_pixmap_priv->base.pixmap; + if (mask_pixmap == dest_pixmap) { + glamor_fallback("mask == dest\n"); + goto fail; + } + if (mask_pixmap_priv->base.gl_fbo == 0) { #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD - mask_status = GLAMOR_UPLOAD_PENDING; + mask_status = GLAMOR_UPLOAD_PENDING; #else - glamor_fallback("no texture in mask\n"); - goto fail; + glamor_fallback("no texture in mask\n"); + goto fail; #endif - } - } + } + } #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD - if (source_status == GLAMOR_UPLOAD_PENDING - && mask_status == GLAMOR_UPLOAD_PENDING - && source_pixmap == mask_pixmap) { - - if (source->format != mask->format) { - saved_source_format = source->format; - - if (!combine_pict_format(&source->format, source->format, - mask->format, key.in)) { - glamor_fallback("combine source %x mask %x failed.\n", - source->format, mask->format); - goto fail; - } - - if (source->format != saved_source_format) { - glamor_picture_format_fixup(source, - source_pixmap_priv); - } - /* XXX - * By default, glamor_upload_picture_to_texture will wire alpha to 1 - * if one picture doesn't have alpha. So we don't do that again in - * rendering function. But here is a special case, as source and - * mask share the same texture but may have different formats. For - * example, source doesn't have alpha, but mask has alpha. Then the - * texture will have the alpha value for the mask. And will not wire - * to 1 for the source. In this case, we have to use different shader - * to wire the source's alpha to 1. - * - * But this may cause a potential problem if the source's repeat mode - * is REPEAT_NONE, and if the source is smaller than the dest, then - * for the region not covered by the source may be painted incorrectly. - * because we wire the alpha to 1. - * - **/ - if (!PICT_FORMAT_A(saved_source_format) - && PICT_FORMAT_A(mask->format)) - key.source = SHADER_SOURCE_TEXTURE; - - if (!PICT_FORMAT_A(mask->format) - && PICT_FORMAT_A(saved_source_format)) - key.mask = SHADER_MASK_TEXTURE; - - mask_status = GLAMOR_NONE; - } - - source_status = glamor_upload_picture_to_texture(source); - if (source_status != GLAMOR_UPLOAD_DONE) { - glamor_fallback("Failed to upload source texture.\n"); - goto fail; - } - } else { - if (source_status == GLAMOR_UPLOAD_PENDING) { - source_status = glamor_upload_picture_to_texture(source); - if (source_status != GLAMOR_UPLOAD_DONE) { - glamor_fallback("Failed to upload source texture.\n"); - goto fail; - } - } - - if (mask_status == GLAMOR_UPLOAD_PENDING) { - mask_status = glamor_upload_picture_to_texture(mask); - if (mask_status != GLAMOR_UPLOAD_DONE) { - glamor_fallback("Failed to upload mask texture.\n"); - goto fail; - } - } - } + if (source_status == GLAMOR_UPLOAD_PENDING + && mask_status == GLAMOR_UPLOAD_PENDING + && source_pixmap == mask_pixmap) { + + if (source->format != mask->format) { + saved_source_format = source->format; + + if (!combine_pict_format(&source->format, source->format, + mask->format, key.in)) { + glamor_fallback("combine source %x mask %x failed.\n", + source->format, mask->format); + goto fail; + } + + if (source->format != saved_source_format) { + glamor_picture_format_fixup(source, source_pixmap_priv); + } + /* XXX + * By default, glamor_upload_picture_to_texture will wire alpha to 1 + * if one picture doesn't have alpha. So we don't do that again in + * rendering function. But here is a special case, as source and + * mask share the same texture but may have different formats. For + * example, source doesn't have alpha, but mask has alpha. Then the + * texture will have the alpha value for the mask. And will not wire + * to 1 for the source. In this case, we have to use different shader + * to wire the source's alpha to 1. + * + * But this may cause a potential problem if the source's repeat mode + * is REPEAT_NONE, and if the source is smaller than the dest, then + * for the region not covered by the source may be painted incorrectly. + * because we wire the alpha to 1. + * + **/ + if (!PICT_FORMAT_A(saved_source_format) + && PICT_FORMAT_A(mask->format)) + key.source = SHADER_SOURCE_TEXTURE; + + if (!PICT_FORMAT_A(mask->format) + && PICT_FORMAT_A(saved_source_format)) + key.mask = SHADER_MASK_TEXTURE; + + mask_status = GLAMOR_NONE; + } + + source_status = glamor_upload_picture_to_texture(source); + if (source_status != GLAMOR_UPLOAD_DONE) { + glamor_fallback("Failed to upload source texture.\n"); + goto fail; + } + } + else { + if (source_status == GLAMOR_UPLOAD_PENDING) { + source_status = glamor_upload_picture_to_texture(source); + if (source_status != GLAMOR_UPLOAD_DONE) { + glamor_fallback("Failed to upload source texture.\n"); + goto fail; + } + } + + if (mask_status == GLAMOR_UPLOAD_PENDING) { + mask_status = glamor_upload_picture_to_texture(mask); + if (mask_status != GLAMOR_UPLOAD_DONE) { + glamor_fallback("Failed to upload mask texture.\n"); + goto fail; + } + } + } #endif - /*Before enter the rendering stage, we need to fixup - * transformed source and mask, if the transform is not int translate. */ - if (key.source != SHADER_SOURCE_SOLID - && source->transform - && !pixman_transform_is_int_translate(source->transform) - && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { - if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv)) - goto fail; - } - if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID - && mask->transform - && !pixman_transform_is_int_translate(mask->transform) - && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { - if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv)) - goto fail; - } - - - if (!glamor_set_composite_op(screen, op, op_info, dest, mask)) - goto fail; - - *shader = glamor_lookup_composite_shader(screen, &key); - if ((*shader)->prog == 0) { - glamor_fallback("no shader program for this" - "render acccel mode\n"); - goto fail; - } - - if (key.source == SHADER_SOURCE_SOLID) - memcpy(&(*shader)->source_solid_color[0], - source_solid_color, 4*sizeof(float)); - else { - (*shader)->source_priv = source_pixmap_priv; - (*shader)->source = source; - } - - if (key.mask == SHADER_MASK_SOLID) - memcpy(&(*shader)->mask_solid_color[0], - mask_solid_color, 4*sizeof(float)); - else { - (*shader)->mask_priv = mask_pixmap_priv; - (*shader)->mask = mask; - } - - ret = TRUE; - memcpy(s_key, &key, sizeof(key)); - *psaved_source_format = saved_source_format; - goto done; - -fail: - if (saved_source_format) - source->format = saved_source_format; -done: - return ret; + /*Before enter the rendering stage, we need to fixup + * transformed source and mask, if the transform is not int translate. */ + if (key.source != SHADER_SOURCE_SOLID + && source->transform + && !pixman_transform_is_int_translate(source->transform) + && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { + if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv)) + goto fail; + } + if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID + && mask->transform + && !pixman_transform_is_int_translate(mask->transform) + && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { + if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv)) + goto fail; + } + + if (!glamor_set_composite_op(screen, op, op_info, dest, mask)) + goto fail; + + *shader = glamor_lookup_composite_shader(screen, &key); + if ((*shader)->prog == 0) { + glamor_fallback("no shader program for this" "render acccel mode\n"); + goto fail; + } + + if (key.source == SHADER_SOURCE_SOLID) + memcpy(&(*shader)->source_solid_color[0], + source_solid_color, 4 * sizeof(float)); + else { + (*shader)->source_priv = source_pixmap_priv; + (*shader)->source = source; + } + + if (key.mask == SHADER_MASK_SOLID) + memcpy(&(*shader)->mask_solid_color[0], + mask_solid_color, 4 * sizeof(float)); + else { + (*shader)->mask_priv = mask_pixmap_priv; + (*shader)->mask = mask; + } + + ret = TRUE; + memcpy(s_key, &key, sizeof(key)); + *psaved_source_format = saved_source_format; + goto done; + + fail: + if (saved_source_format) + source->format = saved_source_format; + done: + return ret; } void -glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv, - struct shader_key *key, - glamor_composite_shader *shader, - struct blendinfo *op_info) +glamor_composite_set_shader_blend(glamor_pixmap_private * dest_priv, + struct shader_key *key, + glamor_composite_shader * shader, + struct blendinfo *op_info) { - glamor_gl_dispatch *dispatch; - glamor_screen_private *glamor_priv; - - glamor_priv = dest_priv->base.glamor_priv; - - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glUseProgram(shader->prog); - - if (key->source == SHADER_SOURCE_SOLID) { - glamor_set_composite_solid(dispatch, - shader->source_solid_color, - shader->source_uniform_location); - } else { - glamor_set_composite_texture(glamor_priv, 0, - shader->source, - shader->source_priv, shader->source_wh, - shader->source_repeat_mode); - } - - if (key->mask != SHADER_MASK_NONE) { - if (key->mask == SHADER_MASK_SOLID) { - glamor_set_composite_solid(dispatch, - shader->mask_solid_color, - shader->mask_uniform_location); - } else { - glamor_set_composite_texture(glamor_priv, 1, - shader->mask, - shader->mask_priv, shader->mask_wh, - shader->mask_repeat_mode); - } - } - - if (op_info->source_blend == GL_ONE - && op_info->dest_blend == GL_ZERO) { - dispatch->glDisable(GL_BLEND); - } else { - dispatch->glEnable(GL_BLEND); - dispatch->glBlendFunc(op_info->source_blend, - op_info->dest_blend); - } - - glamor_put_dispatch(glamor_priv); + glamor_gl_dispatch *dispatch; + glamor_screen_private *glamor_priv; + + glamor_priv = dest_priv->base.glamor_priv; + + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glUseProgram(shader->prog); + + if (key->source == SHADER_SOURCE_SOLID) { + glamor_set_composite_solid(dispatch, + shader->source_solid_color, + shader->source_uniform_location); + } + else { + glamor_set_composite_texture(glamor_priv, 0, + shader->source, + shader->source_priv, shader->source_wh, + shader->source_repeat_mode); + } + + if (key->mask != SHADER_MASK_NONE) { + if (key->mask == SHADER_MASK_SOLID) { + glamor_set_composite_solid(dispatch, + shader->mask_solid_color, + shader->mask_uniform_location); + } + else { + glamor_set_composite_texture(glamor_priv, 1, + shader->mask, + shader->mask_priv, shader->mask_wh, + shader->mask_repeat_mode); + } + } + + if (op_info->source_blend == GL_ONE && op_info->dest_blend == GL_ZERO) { + dispatch->glDisable(GL_BLEND); + } + else { + dispatch->glEnable(GL_BLEND); + dispatch->glBlendFunc(op_info->source_blend, op_info->dest_blend); + } + + glamor_put_dispatch(glamor_priv); } static Bool glamor_composite_with_shader(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - glamor_pixmap_private *source_pixmap_priv, - glamor_pixmap_private *mask_pixmap_priv, - glamor_pixmap_private *dest_pixmap_priv, - int nrect, glamor_composite_rect_t * rects, - Bool two_pass_ca) + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private * source_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, + int nrect, glamor_composite_rect_t * rects, + Bool two_pass_ca) { - ScreenPtr screen = dest->pDrawable->pScreen; - glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv; - PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap; - PixmapPtr source_pixmap = NULL; - PixmapPtr mask_pixmap = NULL; - glamor_gl_dispatch *dispatch = NULL; - GLfloat dst_xscale, dst_yscale; - GLfloat mask_xscale = 1, mask_yscale = 1, - src_xscale = 1, src_yscale = 1; - struct shader_key key, key_ca; - float *vertices; - int dest_x_off, dest_y_off; - int source_x_off, source_y_off; - int mask_x_off, mask_y_off; - PictFormatShort saved_source_format = 0; - float src_matrix[9], mask_matrix[9]; - float *psrc_matrix = NULL, *pmask_matrix = NULL; - int vert_stride = 4; - int nrect_max; - Bool ret = FALSE; - glamor_composite_shader *shader = NULL, *shader_ca = NULL; - struct blendinfo op_info, op_info_ca; - - if(!glamor_composite_choose_shader(op, source, mask, dest, - source_pixmap_priv, mask_pixmap_priv, - dest_pixmap_priv, - &key, &shader, &op_info, - &saved_source_format)) { - glamor_fallback("glamor_composite_choose_shader failed\n"); - return ret; - } - if (two_pass_ca) { - if(!glamor_composite_choose_shader(PictOpAdd, source, mask, dest, - source_pixmap_priv, mask_pixmap_priv, - dest_pixmap_priv, - &key_ca, &shader_ca, &op_info_ca, - &saved_source_format)) { - glamor_fallback("glamor_composite_choose_shader failed\n"); - return ret; - } - } - - glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); - glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info); - - dispatch = glamor_get_dispatch(glamor_priv); - - glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; - glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && - key.mask != SHADER_MASK_SOLID); - - dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); - dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); - glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, - &dest_x_off, &dest_y_off); - pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale); - - if (glamor_priv->has_source_coords) { - source_pixmap = source_pixmap_priv->base.pixmap; - glamor_get_drawable_deltas(source->pDrawable, - source_pixmap, &source_x_off, - &source_y_off); - pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, - &src_yscale); - if (source->transform) { - psrc_matrix = src_matrix; - glamor_picture_get_matrixf(source, psrc_matrix); - } - vert_stride += 4; - } - - if (glamor_priv->has_mask_coords) { - mask_pixmap = mask_pixmap_priv->base.pixmap; - glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, - &mask_x_off, &mask_y_off); - pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, - &mask_yscale); - if (mask->transform) { - pmask_matrix = mask_matrix; - glamor_picture_get_matrixf(mask, pmask_matrix); - } - vert_stride += 4; - } - - nrect_max = (vert_stride * nrect) > GLAMOR_COMPOSITE_VBO_VERT_CNT ? - (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nrect; - - while(nrect) { - int mrect, rect_processed; - int vb_stride; - - mrect = nrect > nrect_max ? nrect_max : nrect ; - glamor_setup_composite_vbo(screen, mrect * vert_stride); - rect_processed = mrect; - vb_stride = glamor_priv->vb_stride/sizeof(float); - while (mrect--) { - INT16 x_source; - INT16 y_source; - INT16 x_mask; - INT16 y_mask; - INT16 x_dest; - INT16 y_dest; - CARD16 width; - CARD16 height; - - x_dest = rects->x_dst + dest_x_off; - y_dest = rects->y_dst + dest_y_off; - x_source = rects->x_src + source_x_off; - y_source = rects->y_src + source_y_off; - x_mask = rects->x_mask + mask_x_off; - y_mask = rects->y_mask + mask_y_off; - width = rects->width; - height = rects->height; - - DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n", - x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height); - vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset); - assert(glamor_priv->vbo_offset < glamor_priv->vbo_size - glamor_priv->vb_stride); - 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, vb_stride); - vertices += 2; - if (key.source != SHADER_SOURCE_SOLID) { - glamor_set_normalize_tcoords_generic( - source_pixmap_priv, source->repeatType, psrc_matrix, - src_xscale, src_yscale, x_source, y_source, - x_source + width, y_source + height, - glamor_priv->yInverted, vertices, vb_stride); - vertices += 2; - } - - if (key.mask != SHADER_MASK_NONE - && key.mask != SHADER_MASK_SOLID) { - glamor_set_normalize_tcoords_generic( - mask_pixmap_priv, mask->repeatType, pmask_matrix, - mask_xscale, mask_yscale, x_mask, y_mask, - x_mask + width, y_mask + height, - glamor_priv->yInverted, vertices, vb_stride); - } - glamor_priv->render_nr_verts += 4; - glamor_priv->vbo_offset += glamor_priv->vb_stride * 4; - rects++; - } - glamor_flush_composite_rects(screen); - nrect -= rect_processed; - if (two_pass_ca) { - glamor_composite_set_shader_blend(dest_pixmap_priv, - &key_ca, shader_ca, - &op_info_ca); - glamor_flush_composite_rects(screen); - if (nrect) - glamor_composite_set_shader_blend(dest_pixmap_priv, - &key, shader, - &op_info); - } - } - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); - dispatch->glDisable(GL_BLEND); + ScreenPtr screen = dest->pDrawable->pScreen; + glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv; + PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap; + PixmapPtr source_pixmap = NULL; + PixmapPtr mask_pixmap = NULL; + glamor_gl_dispatch *dispatch = NULL; + GLfloat dst_xscale, dst_yscale; + GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1; + struct shader_key key, key_ca; + float *vertices; + int dest_x_off, dest_y_off; + int source_x_off, source_y_off; + int mask_x_off, mask_y_off; + PictFormatShort saved_source_format = 0; + float src_matrix[9], mask_matrix[9]; + float *psrc_matrix = NULL, *pmask_matrix = NULL; + int vert_stride = 4; + int nrect_max; + Bool ret = FALSE; + glamor_composite_shader *shader = NULL, *shader_ca = NULL; + struct blendinfo op_info, op_info_ca; + + if (!glamor_composite_choose_shader(op, source, mask, dest, + source_pixmap_priv, mask_pixmap_priv, + dest_pixmap_priv, + &key, &shader, &op_info, + &saved_source_format)) { + glamor_fallback("glamor_composite_choose_shader failed\n"); + return ret; + } + if (two_pass_ca) { + if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest, + source_pixmap_priv, + mask_pixmap_priv, dest_pixmap_priv, + &key_ca, &shader_ca, &op_info_ca, + &saved_source_format)) { + glamor_fallback("glamor_composite_choose_shader failed\n"); + return ret; + } + } + + glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); + glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info); + + dispatch = glamor_get_dispatch(glamor_priv); + + glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; + glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && + key.mask != SHADER_MASK_SOLID); + + dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); + dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); + glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap, + &dest_x_off, &dest_y_off); + pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale); + + if (glamor_priv->has_source_coords) { + source_pixmap = source_pixmap_priv->base.pixmap; + glamor_get_drawable_deltas(source->pDrawable, + source_pixmap, &source_x_off, &source_y_off); + pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale); + if (source->transform) { + psrc_matrix = src_matrix; + glamor_picture_get_matrixf(source, psrc_matrix); + } + vert_stride += 4; + } + + if (glamor_priv->has_mask_coords) { + mask_pixmap = mask_pixmap_priv->base.pixmap; + glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, + &mask_x_off, &mask_y_off); + pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale); + if (mask->transform) { + pmask_matrix = mask_matrix; + glamor_picture_get_matrixf(mask, pmask_matrix); + } + vert_stride += 4; + } + + nrect_max = (vert_stride * nrect) > GLAMOR_COMPOSITE_VBO_VERT_CNT ? + (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nrect; + + while (nrect) { + int mrect, rect_processed; + int vb_stride; + + mrect = nrect > nrect_max ? nrect_max : nrect; + glamor_setup_composite_vbo(screen, mrect * vert_stride); + rect_processed = mrect; + vb_stride = glamor_priv->vb_stride / sizeof(float); + while (mrect--) { + INT16 x_source; + INT16 y_source; + INT16 x_mask; + INT16 y_mask; + INT16 x_dest; + INT16 y_dest; + CARD16 width; + CARD16 height; + + x_dest = rects->x_dst + dest_x_off; + y_dest = rects->y_dst + dest_y_off; + x_source = rects->x_src + source_x_off; + y_source = rects->y_src + source_y_off; + x_mask = rects->x_mask + mask_x_off; + y_mask = rects->y_mask + mask_y_off; + width = rects->width; + height = rects->height; + + DEBUGF + ("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n", + x_dest, y_dest, x_source, y_source, x_mask, y_mask, width, + height); + vertices = (float *) (glamor_priv->vb + glamor_priv->vbo_offset); + assert(glamor_priv->vbo_offset < + glamor_priv->vbo_size - glamor_priv->vb_stride); + 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, + vb_stride); + vertices += 2; + if (key.source != SHADER_SOURCE_SOLID) { + glamor_set_normalize_tcoords_generic(source_pixmap_priv, + source->repeatType, + psrc_matrix, src_xscale, + src_yscale, x_source, + y_source, x_source + width, + y_source + height, + glamor_priv->yInverted, + vertices, vb_stride); + vertices += 2; + } + + if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) { + glamor_set_normalize_tcoords_generic(mask_pixmap_priv, + mask->repeatType, + pmask_matrix, mask_xscale, + mask_yscale, x_mask, + y_mask, x_mask + width, + y_mask + height, + glamor_priv->yInverted, + vertices, vb_stride); + } + glamor_priv->render_nr_verts += 4; + glamor_priv->vbo_offset += glamor_priv->vb_stride * 4; + rects++; + } + glamor_flush_composite_rects(screen); + nrect -= rect_processed; + if (two_pass_ca) { + glamor_composite_set_shader_blend(dest_pixmap_priv, + &key_ca, shader_ca, &op_info_ca); + glamor_flush_composite_rects(screen); + if (nrect) + glamor_composite_set_shader_blend(dest_pixmap_priv, + &key, shader, &op_info); + } + } + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); + dispatch->glDisable(GL_BLEND); #ifndef GLAMOR_GLES2 - dispatch->glActiveTexture(GL_TEXTURE0); - dispatch->glDisable(GL_TEXTURE_2D); - dispatch->glActiveTexture(GL_TEXTURE1); - dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glActiveTexture(GL_TEXTURE1); + dispatch->glDisable(GL_TEXTURE_2D); #endif - DEBUGF("finish rendering.\n"); - dispatch->glUseProgram(0); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; - if (saved_source_format) - source->format = saved_source_format; - glamor_put_dispatch(glamor_priv); - - ret = TRUE; - return ret; + DEBUGF("finish rendering.\n"); + dispatch->glUseProgram(0); + glamor_priv->state = RENDER_STATE; + glamor_priv->render_idle_cnt = 0; + if (saved_source_format) + source->format = saved_source_format; + glamor_put_dispatch(glamor_priv); + + ret = TRUE; + return ret; } PicturePtr @@ -1472,411 +1450,412 @@ glamor_convert_gradient_picture(ScreenPtr screen, int x_source, int y_source, int width, int height) { - PixmapPtr pixmap; - PicturePtr dst = NULL; - int error; - PictFormatShort format; - if (!source->pDrawable) - format = PICT_a8r8g8b8; - else - format = source->format; + PixmapPtr pixmap; + PicturePtr dst = NULL; + int error; + PictFormatShort format; + + if (!source->pDrawable) + format = PICT_a8r8g8b8; + else + format = source->format; #ifdef GLAMOR_GRADIENT_SHADER - if (!source->pDrawable) { - if (source->pSourcePict->type == SourcePictTypeLinear) { - dst = glamor_generate_linear_gradient_picture(screen, - source, x_source, y_source, width, height, format); - } else if (source->pSourcePict->type == SourcePictTypeRadial) { - dst = glamor_generate_radial_gradient_picture(screen, - source, x_source, y_source, width, height, format); - } - - if (dst) { -#if 0 /* Debug to compare it to pixman, Enable it if needed. */ - glamor_compare_pictures(screen, source, - dst, x_source, y_source, width, height, - 0, 3); + if (!source->pDrawable) { + if (source->pSourcePict->type == SourcePictTypeLinear) { + dst = glamor_generate_linear_gradient_picture(screen, + source, x_source, + y_source, width, + height, format); + } + else if (source->pSourcePict->type == SourcePictTypeRadial) { + dst = glamor_generate_radial_gradient_picture(screen, + source, x_source, + y_source, width, + height, format); + } + + if (dst) { +#if 0 /* Debug to compare it to pixman, Enable it if needed. */ + glamor_compare_pictures(screen, source, + dst, x_source, y_source, width, height, + 0, 3); #endif - return dst; - } - } + return dst; + } + } #endif - pixmap = glamor_create_pixmap(screen, - width, - height, - PIXMAN_FORMAT_DEPTH(format), - GLAMOR_CREATE_PIXMAP_CPU); - - if (!pixmap) - return NULL; - - dst = CreatePicture(0, - &pixmap->drawable, - PictureMatchFormat(screen, - PIXMAN_FORMAT_DEPTH(format), - format), - 0, 0, serverClient, &error); - glamor_destroy_pixmap(pixmap); - if (!dst) - return NULL; - - ValidatePicture(dst); - - fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source, - 0, 0, 0, 0, width, height); - return dst; + pixmap = glamor_create_pixmap(screen, + width, + height, + PIXMAN_FORMAT_DEPTH(format), + GLAMOR_CREATE_PIXMAP_CPU); + + if (!pixmap) + return NULL; + + dst = CreatePicture(0, + &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH(format), + format), 0, 0, serverClient, &error); + glamor_destroy_pixmap(pixmap); + if (!dst) + return NULL; + + ValidatePicture(dst); + + fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source, + 0, 0, 0, 0, width, height); + return dst; } Bool glamor_composite_clipped_region(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - glamor_pixmap_private *source_pixmap_priv, - glamor_pixmap_private *mask_pixmap_priv, - glamor_pixmap_private *dest_pixmap_priv, - RegionPtr region, - int x_source, - int y_source, - int x_mask, - int y_mask, - int x_dest, - int y_dest) + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + glamor_pixmap_private * source_pixmap_priv, + glamor_pixmap_private * mask_pixmap_priv, + glamor_pixmap_private * dest_pixmap_priv, + RegionPtr region, + int x_source, + int y_source, + int x_mask, int y_mask, int x_dest, int y_dest) { - ScreenPtr screen = dest->pDrawable->pScreen; - PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; - PicturePtr temp_src = source, temp_mask = mask; - glamor_pixmap_private *temp_src_priv = source_pixmap_priv; - glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv; - int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; - BoxPtr extent; - glamor_composite_rect_t rect[10]; - glamor_composite_rect_t *prect = rect; - int prect_size = ARRAY_SIZE(rect); - int ok = FALSE; - int i; - int width; - int height; - BoxPtr box; - int nbox; - Bool two_pass_ca = FALSE; - - extent = RegionExtents(region); - box = RegionRects(region); - nbox = RegionNumRects(region); - width = extent->x2 - extent->x1; - height = extent->y2 - extent->y1; - - x_temp_src = x_source; - y_temp_src = y_source; - x_temp_mask = x_mask; - y_temp_mask = y_mask; - - DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n", - x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); - - if (source_pixmap_priv) - source_pixmap = source_pixmap_priv->base.pixmap; - - if (mask_pixmap_priv) - mask_pixmap = mask_pixmap_priv->base.pixmap; - - /* XXX is it possible source mask have non-zero drawable.x/y? */ - if (source - && ((!source->pDrawable - && (source->pSourcePict->type != SourcePictTypeSolidFill)) - || (source->pDrawable - && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) - && (source_pixmap->drawable.width != width - || source_pixmap->drawable.height != height)))) { - temp_src = - glamor_convert_gradient_picture(screen, source, - extent->x1 + x_source - x_dest, - extent->y1 + y_source - y_dest, - width, height); - if (!temp_src) { - temp_src = source; - goto out; - } - temp_src_priv = glamor_get_pixmap_private((PixmapPtr)(temp_src->pDrawable)); - x_temp_src = - extent->x1 + x_dest; - y_temp_src = - extent->y1 + y_dest; - } - - if (mask - && - ((!mask->pDrawable - && (mask->pSourcePict->type != SourcePictTypeSolidFill)) - || (mask->pDrawable - && !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv) - && (mask_pixmap->drawable.width != width - || mask_pixmap->drawable.height != height)))) { - /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity - * to do reduce one convertion. */ - temp_mask = - glamor_convert_gradient_picture(screen, mask, - extent->x1 + x_mask - x_dest, - extent->y1 + y_mask - y_dest, - width, height); - if (!temp_mask) { - temp_mask = mask; - goto out; - } - temp_mask_priv = glamor_get_pixmap_private((PixmapPtr)(temp_mask->pDrawable)); - x_temp_mask = - extent->x1 + x_dest; - y_temp_mask = - extent->y1 + y_dest; - } - /* Do two-pass PictOpOver componentAlpha, until we enable - * dual source color blending. - */ - - if (mask && mask->componentAlpha) { - if (op == PictOpOver) { - two_pass_ca = TRUE; - op = PictOpOutReverse; - } - } - - if (!mask && temp_src) { - if (glamor_composite_with_copy(op, temp_src, dest, - x_temp_src, y_temp_src, - x_dest, y_dest, region)) { - ok = TRUE; - goto out; - } - } - - /*XXXXX, self copy?*/ - - x_dest += dest->pDrawable->x; - y_dest += dest->pDrawable->y; - if (temp_src && temp_src->pDrawable) { - x_temp_src += temp_src->pDrawable->x; - y_temp_src += temp_src->pDrawable->y; - } - if (temp_mask && temp_mask->pDrawable) { - x_temp_mask += temp_mask->pDrawable->x; - y_temp_mask += temp_mask->pDrawable->y; - } - - if (nbox > ARRAY_SIZE(rect)) { - prect = calloc(nbox, sizeof(*prect)); - if (prect) - prect_size = nbox; - else { - prect = rect; - prect_size = ARRAY_SIZE(rect); - } - } - while(nbox) { - int box_cnt; - box_cnt = nbox > prect_size ? prect_size : nbox; - for (i = 0; i < box_cnt; i++) { - prect[i].x_src = box[i].x1 + x_temp_src - x_dest; - prect[i].y_src = box[i].y1 + y_temp_src - y_dest; - prect[i].x_mask = box[i].x1 + x_temp_mask - x_dest; - prect[i].y_mask = box[i].y1 + y_temp_mask - y_dest; - prect[i].x_dst = box[i].x1; - prect[i].y_dst = box[i].y1; - prect[i].width = box[i].x2 - box[i].x1; - prect[i].height = box[i].y2 - box[i].y1; - DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst); - } - ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest, - temp_src_priv, temp_mask_priv, - dest_pixmap_priv, - box_cnt, prect, two_pass_ca); - if (!ok) - break; - nbox -= box_cnt; - box += box_cnt; - } - - if (prect != rect) - free(prect); -out: - if (temp_src != source) - FreePicture(temp_src, 0); - if (temp_mask != mask) - FreePicture(temp_mask, 0); - - return ok; + ScreenPtr screen = dest->pDrawable->pScreen; + PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; + PicturePtr temp_src = source, temp_mask = mask; + glamor_pixmap_private *temp_src_priv = source_pixmap_priv; + glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv; + int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; + BoxPtr extent; + glamor_composite_rect_t rect[10]; + glamor_composite_rect_t *prect = rect; + int prect_size = ARRAY_SIZE(rect); + int ok = FALSE; + int i; + int width; + int height; + BoxPtr box; + int nbox; + Bool two_pass_ca = FALSE; + + extent = RegionExtents(region); + box = RegionRects(region); + nbox = RegionNumRects(region); + width = extent->x2 - extent->x1; + height = extent->y2 - extent->y1; + + x_temp_src = x_source; + y_temp_src = y_source; + x_temp_mask = x_mask; + y_temp_mask = y_mask; + + DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n", + x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); + + if (source_pixmap_priv) + source_pixmap = source_pixmap_priv->base.pixmap; + + if (mask_pixmap_priv) + mask_pixmap = mask_pixmap_priv->base.pixmap; + + /* XXX is it possible source mask have non-zero drawable.x/y? */ + if (source + && ((!source->pDrawable + && (source->pSourcePict->type != SourcePictTypeSolidFill)) + || (source->pDrawable + && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) + && (source_pixmap->drawable.width != width + || source_pixmap->drawable.height != height)))) { + temp_src = + glamor_convert_gradient_picture(screen, source, + extent->x1 + x_source - x_dest, + extent->y1 + y_source - y_dest, + width, height); + if (!temp_src) { + temp_src = source; + goto out; + } + temp_src_priv = + glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable)); + x_temp_src = -extent->x1 + x_dest; + y_temp_src = -extent->y1 + y_dest; + } + + if (mask + && + ((!mask->pDrawable + && (mask->pSourcePict->type != SourcePictTypeSolidFill)) + || (mask->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv) + && (mask_pixmap->drawable.width != width + || mask_pixmap->drawable.height != height)))) { + /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity + * to do reduce one convertion. */ + temp_mask = + glamor_convert_gradient_picture(screen, mask, + extent->x1 + x_mask - x_dest, + extent->y1 + y_mask - y_dest, + width, height); + if (!temp_mask) { + temp_mask = mask; + goto out; + } + temp_mask_priv = + glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable)); + x_temp_mask = -extent->x1 + x_dest; + y_temp_mask = -extent->y1 + y_dest; + } + /* Do two-pass PictOpOver componentAlpha, until we enable + * dual source color blending. + */ + + if (mask && mask->componentAlpha) { + if (op == PictOpOver) { + two_pass_ca = TRUE; + op = PictOpOutReverse; + } + } + + if (!mask && temp_src) { + if (glamor_composite_with_copy(op, temp_src, dest, + x_temp_src, y_temp_src, + x_dest, y_dest, region)) { + ok = TRUE; + goto out; + } + } + + /*XXXXX, self copy? */ + + x_dest += dest->pDrawable->x; + y_dest += dest->pDrawable->y; + if (temp_src && temp_src->pDrawable) { + x_temp_src += temp_src->pDrawable->x; + y_temp_src += temp_src->pDrawable->y; + } + if (temp_mask && temp_mask->pDrawable) { + x_temp_mask += temp_mask->pDrawable->x; + y_temp_mask += temp_mask->pDrawable->y; + } + + if (nbox > ARRAY_SIZE(rect)) { + prect = calloc(nbox, sizeof(*prect)); + if (prect) + prect_size = nbox; + else { + prect = rect; + prect_size = ARRAY_SIZE(rect); + } + } + while (nbox) { + int box_cnt; + + box_cnt = nbox > prect_size ? prect_size : nbox; + for (i = 0; i < box_cnt; i++) { + prect[i].x_src = box[i].x1 + x_temp_src - x_dest; + prect[i].y_src = box[i].y1 + y_temp_src - y_dest; + prect[i].x_mask = box[i].x1 + x_temp_mask - x_dest; + prect[i].y_mask = box[i].y1 + y_temp_mask - y_dest; + prect[i].x_dst = box[i].x1; + prect[i].y_dst = box[i].y1; + prect[i].width = box[i].x2 - box[i].x1; + prect[i].height = box[i].y2 - box[i].y1; + DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst); + } + ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest, + temp_src_priv, temp_mask_priv, + dest_pixmap_priv, + box_cnt, prect, two_pass_ca); + if (!ok) + break; + nbox -= box_cnt; + box += box_cnt; + } + + if (prect != rect) + free(prect); + out: + if (temp_src != source) + FreePicture(temp_src, 0); + if (temp_mask != mask) + FreePicture(temp_mask, 0); + + return ok; } static Bool _glamor_composite(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, INT16 y_dest, - CARD16 width, CARD16 height, Bool fallback) + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, + CARD16 width, CARD16 height, Bool fallback) { - ScreenPtr screen = dest->pDrawable->pScreen; - glamor_pixmap_private *dest_pixmap_priv; - glamor_pixmap_private *source_pixmap_priv = - NULL, *mask_pixmap_priv = NULL; - PixmapPtr dest_pixmap = - glamor_get_drawable_pixmap(dest->pDrawable); - PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - Bool ret = TRUE; - 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); - - if (source->pDrawable) { - source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); - source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); - if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY) - goto fail; - } - - if (mask && mask->pDrawable) { - mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); - mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); - if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY) - goto fail; - } - - DEBUGF("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n", - source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { - goto fail; - } - - if (op >= ARRAY_SIZE(composite_op_info)) - goto fail; - - if (mask && mask->componentAlpha) { - if (op == PictOpAtop - || op == PictOpAtopReverse - || op == PictOpXor - || op >= PictOpSaturate) { - glamor_fallback - ("glamor_composite(): component alpha op %x\n", op); - goto fail; - } - } - - if ((source && source->filter >= PictFilterConvolution) - || (mask && mask->filter >= PictFilterConvolution)) { - glamor_fallback("glamor_composite(): unsupported filter\n"); - goto fail; - } - - if (!miComputeCompositeRegion(®ion, - source, mask, dest, - x_source + (source_pixmap ? source->pDrawable->x : 0), - y_source + (source_pixmap ? source->pDrawable->y : 0), - x_mask + (mask_pixmap ? mask->pDrawable->x : 0), - y_mask + (mask_pixmap ? mask->pDrawable->y : 0), - x_dest + dest->pDrawable->x, - y_dest + dest->pDrawable->y, - width, - height)) { - ret = TRUE; - goto done; - } - - nbox = REGION_NUM_RECTS(®ion); - DEBUGF("first clipped when compositing.\n"); - DEBUGRegionPrint(®ion); - extent = RegionExtents(®ion); - if (nbox == 0) { - ret = TRUE; - goto done; - } - /* If destination is not a large pixmap, but the region is larger - * than texture size limitation, and source or mask is memory pixmap, - * then there may be need to load a large memory pixmap to a - * texture, and this is not permitted. Then we force to clip the - * destination and make sure latter will not upload a large memory - * pixmap. */ - if (!glamor_check_fbo_size(glamor_priv, - extent->x2 - extent->x1, extent->y2 - extent->y1) - && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) - && ((source_pixmap_priv - && (source_pixmap_priv->type == GLAMOR_MEMORY || source->repeatType == RepeatPad)) - || (mask_pixmap_priv - && (mask_pixmap_priv->type == GLAMOR_MEMORY || mask->repeatType == RepeatPad)) - || (!source_pixmap_priv - && (source->pSourcePict->type != SourcePictTypeSolidFill)) - || (!mask_pixmap_priv && mask - && mask->pSourcePict->type != SourcePictTypeSolidFill))) - force_clip = 1; - - if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE - || (source_pixmap_priv - && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) - || (mask_pixmap_priv - && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) - ok = glamor_composite_largepixmap_region(op, - source, mask, dest, - source_pixmap_priv, - mask_pixmap_priv, - dest_pixmap_priv, - ®ion, force_clip, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest, - width, height); - else - ok = glamor_composite_clipped_region(op, source, - mask, dest, - source_pixmap_priv, - mask_pixmap_priv, - dest_pixmap_priv, - ®ion, - x_source, y_source, - x_mask, y_mask, - x_dest, y_dest); - - REGION_UNINIT(dest->pDrawable->pScreen, ®ion); - - if (ok) - goto done; -fail: - - if (!fallback - && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable) - && (!source_pixmap - || glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable)) - && (!mask_pixmap - || glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) { - ret = FALSE; - goto done; - } - - glamor_fallback - ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c) to pict %p:%p %dx%d (%c)\n", - source, source->pDrawable, - source->pDrawable ? source->pDrawable->width : 0, - source->pDrawable ? source->pDrawable->height : 0, mask, - (!mask) ? NULL : mask->pDrawable, (!mask - || !mask->pDrawable) ? 0 : - mask->pDrawable->width, (!mask - || !mask-> - pDrawable) ? 0 : mask->pDrawable-> - height, glamor_get_picture_location(source), - glamor_get_picture_location(mask), dest, dest->pDrawable, - dest->pDrawable->width, dest->pDrawable->height, - glamor_get_picture_location(dest)); + ScreenPtr screen = dest->pDrawable->pScreen; + glamor_pixmap_private *dest_pixmap_priv; + glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL; + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); + PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + Bool ret = TRUE; + 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); + + if (source->pDrawable) { + source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY) + goto fail; + } + + if (mask && mask->pDrawable) { + mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); + mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); + if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY) + goto fail; + } + + DEBUGF + ("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n", + source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest, + width, height); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { + goto fail; + } + + if (op >= ARRAY_SIZE(composite_op_info)) + goto fail; + + if (mask && mask->componentAlpha) { + if (op == PictOpAtop + || op == PictOpAtopReverse + || op == PictOpXor || op >= PictOpSaturate) { + glamor_fallback("glamor_composite(): component alpha op %x\n", op); + goto fail; + } + } + + if ((source && source->filter >= PictFilterConvolution) + || (mask && mask->filter >= PictFilterConvolution)) { + glamor_fallback("glamor_composite(): unsupported filter\n"); + goto fail; + } + + if (!miComputeCompositeRegion(®ion, + source, mask, dest, + x_source + + (source_pixmap ? source->pDrawable->x : 0), + y_source + + (source_pixmap ? source->pDrawable->y : 0), + x_mask + + (mask_pixmap ? mask->pDrawable->x : 0), + y_mask + + (mask_pixmap ? mask->pDrawable->y : 0), + x_dest + dest->pDrawable->x, + y_dest + dest->pDrawable->y, width, height)) { + ret = TRUE; + goto done; + } + + nbox = REGION_NUM_RECTS(®ion); + DEBUGF("first clipped when compositing.\n"); + DEBUGRegionPrint(®ion); + extent = RegionExtents(®ion); + if (nbox == 0) { + ret = TRUE; + goto done; + } + /* If destination is not a large pixmap, but the region is larger + * than texture size limitation, and source or mask is memory pixmap, + * then there may be need to load a large memory pixmap to a + * texture, and this is not permitted. Then we force to clip the + * destination and make sure latter will not upload a large memory + * pixmap. */ + if (!glamor_check_fbo_size(glamor_priv, + extent->x2 - extent->x1, extent->y2 - extent->y1) + && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) + && ((source_pixmap_priv + && (source_pixmap_priv->type == GLAMOR_MEMORY || + source->repeatType == RepeatPad)) + || (mask_pixmap_priv && + (mask_pixmap_priv->type == GLAMOR_MEMORY || + mask->repeatType == RepeatPad)) + || (!source_pixmap_priv && + (source->pSourcePict->type != SourcePictTypeSolidFill)) + || (!mask_pixmap_priv && mask && + mask->pSourcePict->type != SourcePictTypeSolidFill))) + force_clip = 1; + + if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE + || (source_pixmap_priv + && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) + || (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) + ok = glamor_composite_largepixmap_region(op, + source, mask, dest, + source_pixmap_priv, + mask_pixmap_priv, + dest_pixmap_priv, + ®ion, force_clip, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest, width, height); + else + ok = glamor_composite_clipped_region(op, source, + mask, dest, + source_pixmap_priv, + mask_pixmap_priv, + dest_pixmap_priv, + ®ion, + x_source, y_source, + x_mask, y_mask, x_dest, y_dest); + + REGION_UNINIT(dest->pDrawable->pScreen, ®ion); + + if (ok) + goto done; + fail: + + if (!fallback && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable) + && (!source_pixmap + || glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable)) + && (!mask_pixmap + || glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) { + ret = FALSE; + goto done; + } + + glamor_fallback + ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c) to pict %p:%p %dx%d (%c)\n", + source, source->pDrawable, + source->pDrawable ? source->pDrawable->width : 0, + source->pDrawable ? source->pDrawable->height : 0, mask, + (!mask) ? NULL : mask->pDrawable, (!mask + || !mask->pDrawable) ? 0 : + mask->pDrawable->width, (!mask + || !mask->pDrawable) ? 0 : mask-> + pDrawable->height, glamor_get_picture_location(source), + glamor_get_picture_location(mask), dest, dest->pDrawable, + dest->pDrawable->width, dest->pDrawable->height, + glamor_get_picture_location(dest)); #define GET_SUB_PICTURE(p, access) do { \ glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap, \ @@ -1897,32 +1876,28 @@ fail: 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)) { - if (source_pixmap == dest_pixmap || glamor_prepare_access_picture - (source, GLAMOR_ACCESS_RO)) { - if (!mask - || glamor_prepare_access_picture(mask, - GLAMOR_ACCESS_RO)) - { - fbComposite(op, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, x_dest, - y_dest, width, height); - if (mask) - glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO); - } - if (source_pixmap != dest_pixmap) - glamor_finish_access_picture(source, GLAMOR_ACCESS_RO); - } - glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW); - } + 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)) { + if (source_pixmap == dest_pixmap || glamor_prepare_access_picture + (source, GLAMOR_ACCESS_RO)) { + if (!mask || glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) { + fbComposite(op, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, x_dest, y_dest, width, height); + if (mask) + glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO); + } + if (source_pixmap != dest_pixmap) + glamor_finish_access_picture(source, GLAMOR_ACCESS_RO); + } + glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW); + } #define PUT_SUB_PICTURE(p, access) do { \ if (sub_ ##p ##_pixmap != NULL) { \ @@ -1938,198 +1913,196 @@ fail: 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; + 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; } void glamor_composite(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, INT16 y_dest, - CARD16 width, CARD16 height) + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height) { - _glamor_composite(op, source, mask, dest, x_source, y_source, - x_mask, y_mask, x_dest, y_dest, width, height, - TRUE); + _glamor_composite(op, source, mask, dest, x_source, y_source, + x_mask, y_mask, x_dest, y_dest, width, height, TRUE); } Bool glamor_composite_nf(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, INT16 y_dest, - CARD16 width, CARD16 height) + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height) { - return _glamor_composite(op, source, mask, dest, x_source, y_source, - x_mask, y_mask, x_dest, y_dest, width, height, - FALSE); + return _glamor_composite(op, source, mask, dest, x_source, y_source, + x_mask, y_mask, x_dest, y_dest, width, height, + FALSE); } static void glamor_get_src_rect_extent(int nrect, - glamor_composite_rect_t *rects, - BoxPtr extent) + glamor_composite_rect_t * rects, BoxPtr extent) { - extent->x1 = MAXSHORT; - extent->y1 = MAXSHORT; - extent->x2 = MINSHORT; - extent->y2 = MINSHORT; - - while(nrect--) { - if (extent->x1 > rects->x_src) - extent->x1 = rects->x_src; - if (extent->y1 > rects->y_src) - extent->y1 = rects->y_src; - if (extent->x2 < rects->x_src + rects->width) - extent->x2 = rects->x_src + rects->width; - if (extent->y2 < rects->y_src + rects->height) - extent->y2 = rects->y_src + rects->height; - rects++; - } + extent->x1 = MAXSHORT; + extent->y1 = MAXSHORT; + extent->x2 = MINSHORT; + extent->y2 = MINSHORT; + + while (nrect--) { + if (extent->x1 > rects->x_src) + extent->x1 = rects->x_src; + if (extent->y1 > rects->y_src) + extent->y1 = rects->y_src; + if (extent->x2 < rects->x_src + rects->width) + extent->x2 = rects->x_src + rects->width; + if (extent->y2 < rects->y_src + rects->height) + extent->y2 = rects->y_src + rects->height; + rects++; + } } static void glamor_composite_src_rect_translate(int nrect, - glamor_composite_rect_t *rects, - int x, int y) + glamor_composite_rect_t * rects, + int x, int y) { - while(nrect--) { - rects->x_src += x; - rects->y_src += y; - rects++; - } + while (nrect--) { + rects->x_src += x; + rects->y_src += y; + rects++; + } } void glamor_composite_glyph_rects(CARD8 op, - PicturePtr src, PicturePtr mask, PicturePtr dst, - int nrect, glamor_composite_rect_t * rects) + PicturePtr src, PicturePtr mask, PicturePtr dst, + int nrect, glamor_composite_rect_t * rects) { - int n; - PicturePtr temp_src = NULL; - glamor_composite_rect_t *r; - - ValidatePicture(src); - ValidatePicture(dst); - if (!(glamor_is_large_picture(src) - || (mask && glamor_is_large_picture(mask)) - || glamor_is_large_picture(dst))) { - glamor_pixmap_private *src_pixmap_priv = NULL; - glamor_pixmap_private *mask_pixmap_priv = NULL; - glamor_pixmap_private *dst_pixmap_priv; - glamor_pixmap_private *temp_src_priv = NULL; - BoxRec src_extent; - - dst_pixmap_priv = glamor_get_pixmap_private - (glamor_get_drawable_pixmap(dst->pDrawable)); - - if (mask && mask->pDrawable) - mask_pixmap_priv = glamor_get_pixmap_private - (glamor_get_drawable_pixmap(mask->pDrawable)); - if (src->pDrawable) - src_pixmap_priv = glamor_get_pixmap_private - (glamor_get_drawable_pixmap(src->pDrawable)); - - if (!src->pDrawable - && (src->pSourcePict->type != SourcePictTypeSolidFill)) { - glamor_get_src_rect_extent(nrect, rects, &src_extent); - temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen, - src, - src_extent.x1, src_extent.y1, - src_extent.x2 - src_extent.x1, - src_extent.y2 - src_extent.y1); - if (!temp_src) - goto fallback; - - temp_src_priv = glamor_get_pixmap_private - ((PixmapPtr)(temp_src->pDrawable)); - glamor_composite_src_rect_translate(nrect, rects, - -src_extent.x1, -src_extent.y1); - } else { - temp_src = src; - temp_src_priv = src_pixmap_priv; - } - - if (mask && mask->componentAlpha) { - if (op == PictOpOver) { - if (glamor_composite_with_shader(PictOpOutReverse, - temp_src, mask, dst, temp_src_priv, - mask_pixmap_priv, dst_pixmap_priv, nrect, rects, - TRUE)) - goto done; - } - } else { - if (glamor_composite_with_shader(op, temp_src, mask, dst, temp_src_priv, - mask_pixmap_priv, dst_pixmap_priv, nrect, rects, FALSE)) - goto done; - } - } -fallback: - n = nrect; - r = rects; - - while (n--) { - CompositePicture(op, - temp_src ? temp_src : src, - mask, - dst, - r->x_src, r->y_src, - r->x_mask, r->y_mask, - r->x_dst, r->y_dst, r->width, r->height); - r++; - } - -done: - if (temp_src && temp_src != src) - FreePicture(temp_src, 0); + int n; + PicturePtr temp_src = NULL; + glamor_composite_rect_t *r; + + ValidatePicture(src); + ValidatePicture(dst); + if (!(glamor_is_large_picture(src) + || (mask && glamor_is_large_picture(mask)) + || glamor_is_large_picture(dst))) { + glamor_pixmap_private *src_pixmap_priv = NULL; + glamor_pixmap_private *mask_pixmap_priv = NULL; + glamor_pixmap_private *dst_pixmap_priv; + glamor_pixmap_private *temp_src_priv = NULL; + BoxRec src_extent; + + dst_pixmap_priv = glamor_get_pixmap_private + (glamor_get_drawable_pixmap(dst->pDrawable)); + + if (mask && mask->pDrawable) + mask_pixmap_priv = glamor_get_pixmap_private + (glamor_get_drawable_pixmap(mask->pDrawable)); + if (src->pDrawable) + src_pixmap_priv = glamor_get_pixmap_private + (glamor_get_drawable_pixmap(src->pDrawable)); + + if (!src->pDrawable + && (src->pSourcePict->type != SourcePictTypeSolidFill)) { + glamor_get_src_rect_extent(nrect, rects, &src_extent); + temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen, + src, + src_extent.x1, + src_extent.y1, + src_extent.x2 - + src_extent.x1, + src_extent.y2 - + src_extent.y1); + if (!temp_src) + goto fallback; + + temp_src_priv = glamor_get_pixmap_private + ((PixmapPtr) (temp_src->pDrawable)); + glamor_composite_src_rect_translate(nrect, rects, + -src_extent.x1, -src_extent.y1); + } + else { + temp_src = src; + temp_src_priv = src_pixmap_priv; + } + + if (mask && mask->componentAlpha) { + if (op == PictOpOver) { + if (glamor_composite_with_shader(PictOpOutReverse, + temp_src, mask, dst, + temp_src_priv, + mask_pixmap_priv, + dst_pixmap_priv, nrect, rects, + TRUE)) + goto done; + } + } + else { + if (glamor_composite_with_shader + (op, temp_src, mask, dst, temp_src_priv, mask_pixmap_priv, + dst_pixmap_priv, nrect, rects, FALSE)) + goto done; + } + } + fallback: + n = nrect; + r = rects; + + while (n--) { + CompositePicture(op, + temp_src ? temp_src : src, + mask, + dst, + r->x_src, r->y_src, + r->x_mask, r->y_mask, + r->x_dst, r->y_dst, r->width, r->height); + r++; + } + + done: + if (temp_src && temp_src != src) + FreePicture(temp_src, 0); } static Bool -_glamor_composite_rects (CARD8 op, - PicturePtr pDst, - xRenderColor *color, - int nRect, - xRectangle *rects, - Bool fallback) +_glamor_composite_rects(CARD8 op, + PicturePtr pDst, + xRenderColor * color, + int nRect, xRectangle *rects, Bool fallback) { - miCompositeRects(op, pDst, color, nRect, rects); - return TRUE; + miCompositeRects(op, pDst, color, nRect, rects); + return TRUE; } void -glamor_composite_rects (CARD8 op, - PicturePtr pDst, - xRenderColor *color, - int nRect, - xRectangle *rects) +glamor_composite_rects(CARD8 op, + PicturePtr pDst, + xRenderColor * color, int nRect, xRectangle *rects) { - _glamor_composite_rects(op, pDst, color, nRect, rects, TRUE); + _glamor_composite_rects(op, pDst, color, nRect, rects, TRUE); } Bool -glamor_composite_rects_nf (CARD8 op, - PicturePtr pDst, - xRenderColor *color, - int nRect, - xRectangle *rects) +glamor_composite_rects_nf(CARD8 op, + PicturePtr pDst, + xRenderColor * color, int nRect, xRectangle *rects) { - return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE); + return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE); } -#endif /* RENDER */ +#endif /* RENDER */ diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 3d447b6..22fe88c 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -30,82 +30,83 @@ static Bool _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, - DDXPointPtr points, int *widths, int numPoints, int sorted, - Bool fallback) + DDXPointPtr points, int *widths, int numPoints, int sorted, + Bool fallback) { - PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *dest_pixmap_priv; - int i; - uint8_t *drawpixels_src = (uint8_t *) src; - RegionPtr clip = fbGetCompositeClip(gc); - BoxRec *pbox; - int x_off, y_off; - Bool ret = FALSE; + PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *dest_pixmap_priv; + int i; + uint8_t *drawpixels_src = (uint8_t *) src; + RegionPtr clip = fbGetCompositeClip(gc); + BoxRec *pbox; + int x_off, y_off; + Bool ret = FALSE; - 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"); - goto fail; - } + 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"); + goto fail; + } - /* XXX Shall we set alu here? */ - if (!glamor_set_planemask(dest_pixmap, gc->planemask)) - goto fail; + /* XXX Shall we set alu here? */ + if (!glamor_set_planemask(dest_pixmap, gc->planemask)) + goto fail; - glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off); - for (i = 0; i < numPoints; i++) { + glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off); + for (i = 0; i < numPoints; i++) { - int n = REGION_NUM_RECTS(clip); - pbox = REGION_RECTS(clip); - while (n--) { - int x1 = points[i].x; - int x2 = x1 + widths[i]; - int y1 = points[i].y; + int n = REGION_NUM_RECTS(clip); - if (pbox->y1 > points[i].y || pbox->y2 < points[i].y) - break; - x1 = x1 > pbox->x1 ? x1 : pbox->x1; - x2 = x2 < pbox->x2 ? x2 : pbox->x2; - if (x1 >= x2) - continue; - glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off, y1 + y_off, x2 - x1, 1, - PixmapBytePad(widths[i], drawable->depth), - drawpixels_src, 0); - } - drawpixels_src += PixmapBytePad(widths[i], drawable->depth); - } - ret = TRUE; - goto done; + pbox = REGION_RECTS(clip); + while (n--) { + int x1 = points[i].x; + int x2 = x1 + widths[i]; + int y1 = points[i].y; -fail: - if (!fallback - && glamor_ddx_fallback_check_pixmap(drawable)) - goto done; + if (pbox->y1 > points[i].y || pbox->y2 < points[i].y) + break; + x1 = x1 > pbox->x1 ? x1 : pbox->x1; + x2 = x2 < pbox->x2 ? x2 : pbox->x2; + if (x1 >= x2) + continue; + glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off, + y1 + y_off, x2 - x1, 1, + PixmapBytePad(widths[i], + drawable->depth), + drawpixels_src, 0); + } + drawpixels_src += PixmapBytePad(widths[i], drawable->depth); + } + ret = TRUE; + 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, numPoints, sorted); - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); - } - ret = TRUE; + fail: + if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)) + goto done; -done: - return ret; + 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, numPoints, sorted); + glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + } + ret = TRUE; + + done: + return ret; } void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, - DDXPointPtr points, int *widths, int n, int sorted) + DDXPointPtr points, int *widths, int n, int sorted) { - _glamor_set_spans(drawable, gc, src, points, - widths, n, sorted, TRUE); + _glamor_set_spans(drawable, gc, src, points, widths, n, sorted, TRUE); } Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src, - DDXPointPtr points, int *widths, int n, int sorted) + DDXPointPtr points, int *widths, int n, int sorted) { - return _glamor_set_spans(drawable, gc, src, points, - widths, n, sorted, FALSE); + return _glamor_set_spans(drawable, gc, src, points, + widths, n, sorted, FALSE); } diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 60486cf..0012653 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -36,290 +36,274 @@ void glamor_init_tile_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - 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); - dispatch = glamor_get_dispatch(glamor_priv); - glamor_priv->tile_prog = dispatch->glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs); - fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - tile_fs); - dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog); - dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog); - - dispatch->glBindAttribLocation(glamor_priv->tile_prog, - GLAMOR_VERTEX_POS, "v_position"); - dispatch->glBindAttribLocation(glamor_priv->tile_prog, - GLAMOR_VERTEX_SOURCE, - "v_texcoord0"); - glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog); - - sampler_uniform_location = - dispatch->glGetUniformLocation(glamor_priv->tile_prog, - "sampler"); - dispatch->glUseProgram(glamor_priv->tile_prog); - dispatch->glUniform1i(sampler_uniform_location, 0); - - glamor_priv->tile_wh = - dispatch->glGetUniformLocation(glamor_priv->tile_prog, - "wh"); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + 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); + dispatch = glamor_get_dispatch(glamor_priv); + glamor_priv->tile_prog = dispatch->glCreateProgram(); + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs); + dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog); + dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog); + + dispatch->glBindAttribLocation(glamor_priv->tile_prog, + GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(glamor_priv->tile_prog, + GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog); + + sampler_uniform_location = + dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler"); + dispatch->glUseProgram(glamor_priv->tile_prog); + dispatch->glUniform1i(sampler_uniform_location, 0); + + glamor_priv->tile_wh = + dispatch->glGetUniformLocation(glamor_priv->tile_prog, "wh"); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); } void glamor_fini_tile_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glDeleteProgram(glamor_priv->tile_prog); - glamor_put_dispatch(glamor_priv); + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glDeleteProgram(glamor_priv->tile_prog); + glamor_put_dispatch(glamor_priv); } static void _glamor_tile(PixmapPtr pixmap, PixmapPtr tile, - int x, int y, int width, int height, - int tile_x, int tile_y) + 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); - glamor_gl_dispatch *dispatch; - 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); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glUseProgram(glamor_priv->tile_prog); - - glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv); - dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh); - dispatch->glActiveTexture(GL_TEXTURE0); - dispatch->glBindTexture(GL_TEXTURE_2D, - src_pixmap_priv->base.fbo->tex); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - GL_REPEAT); - dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_REPEAT); + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; + 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); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glUseProgram(glamor_priv->tile_prog); + + glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv); + dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); #ifndef GLAMOR_GLES2 - dispatch->glEnable(GL_TEXTURE_2D); + dispatch->glEnable(GL_TEXTURE_2D); #endif - 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); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, - GL_FLOAT, GL_FALSE, - 2 * sizeof(float), - source_texcoords); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - - glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale, - x1, y1, - x2, y2, - glamor_priv->yInverted, vertices); - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - vertices); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + 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); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, + GL_FLOAT, GL_FALSE, + 2 * sizeof(float), source_texcoords); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale, + x1, y1, + x2, y2, glamor_priv->yInverted, vertices); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), vertices); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); #ifndef GLAMOR_GLES2 - dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glDisable(GL_TEXTURE_2D); #endif - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); - glamor_priv->state = RENDER_STATE; - glamor_priv->render_idle_cnt = 0; + 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) + 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; - glamor_gl_dispatch *dispatch; - - 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; - } - - dispatch = glamor_get_dispatch(glamor_priv); - if (!glamor_set_alu(dispatch, alu)) { - glamor_fallback("unsupported alu %x\n", alu); - glamor_put_dispatch(glamor_priv); - 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(dispatch, GXcopy); - glamor_put_dispatch(glamor_priv); - return TRUE; -fail: - return FALSE; + 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; + glamor_gl_dispatch *dispatch; + + 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; + } + + dispatch = glamor_get_dispatch(glamor_priv); + if (!glamor_set_alu(dispatch, alu)) { + glamor_fallback("unsupported alu %x\n", alu); + glamor_put_dispatch(glamor_priv); + 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(dispatch, GXcopy); + glamor_put_dispatch(glamor_priv); + return TRUE; + fail: + return FALSE; } diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c index 76b3729..c7f7a62 100644 --- a/glamor/glamor_trapezoid.c +++ b/glamor/glamor_trapezoid.c @@ -37,25 +37,27 @@ #include "fbpict.h" static xFixed -_glamor_linefixedX (xLineFixed *l, xFixed y, Bool ceil) +_glamor_linefixedX(xLineFixed * l, xFixed y, Bool ceil) { - xFixed dx = l->p2.x - l->p1.x; - xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx; - xFixed dy = l->p2.y - l->p1.y; - if (ceil) - ex += (dy - 1); - return l->p1.x + (xFixed) (ex / dy); + xFixed dx = l->p2.x - l->p1.x; + xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx; + xFixed dy = l->p2.y - l->p1.y; + + if (ceil) + ex += (dy - 1); + return l->p1.x + (xFixed) (ex / dy); } static xFixed -_glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil) +_glamor_linefixedY(xLineFixed * l, xFixed x, Bool ceil) { - xFixed dy = l->p2.y - l->p1.y; - xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy; - xFixed dx = l->p2.x - l->p1.x; - if (ceil) - ey += (dx - 1); - return l->p1.y + (xFixed) (ey / dx); + xFixed dy = l->p2.y - l->p1.y; + xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy; + xFixed dx = l->p2.x - l->p1.x; + + if (ceil) + ey += (dx - 1); + return l->p1.y + (xFixed) (ey / dx); } #ifdef GLAMOR_TRAPEZOID_SHADER @@ -73,204 +75,206 @@ _glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil) && point[1] <= IntToxFixed(rect->y2)) static xFixed -_glamor_lines_crossfixedY (xLineFixed *l, xLineFixed *r) +_glamor_lines_crossfixedY(xLineFixed * l, xLineFixed * r) { - xFixed dx1 = l->p2.x - l->p1.x; - xFixed dx2 = r->p2.x - r->p1.x; - xFixed dy1 = l->p2.y - l->p1.y; - xFixed dy2 = r->p2.y - r->p1.y; - xFixed_32_32 tmp = (xFixed_32_32) dy2 * dy1; - xFixed_32_32 dividend1 = (tmp >> 32) * (l->p1.x - r->p1.x); - xFixed_32_32 dividend2; - xFixed_32_32 dividend3; - xFixed_32_32 divisor; - - tmp = (xFixed_32_32) dx1 * dy2; - dividend2 = (tmp >> 32) * l->p1.y; - tmp = (xFixed_32_32) dy1 * dx2; - dividend3 = (tmp >> 32) * r->p1.y; - divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2 - - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32; - - if (divisor) - return (xFixed)((dividend2 - dividend1 - dividend3) / divisor); - - return 0xFFFFFFFF; -} + xFixed dx1 = l->p2.x - l->p1.x; + xFixed dx2 = r->p2.x - r->p1.x; + xFixed dy1 = l->p2.y - l->p1.y; + xFixed dy2 = r->p2.y - r->p1.y; + xFixed_32_32 tmp = (xFixed_32_32) dy2 * dy1; + xFixed_32_32 dividend1 = (tmp >> 32) * (l->p1.x - r->p1.x); + xFixed_32_32 dividend2; + xFixed_32_32 dividend3; + xFixed_32_32 divisor; -static Bool -point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y) -{ - int ret = TRUE; - int tmp; - if (point[1] > trap->bottom) { - ret = FALSE; - if (DEBUG_CLIP_VTX) { - ErrorF("Out of Trap bottom, point[1] = %d(0x%x)), " - "bottom = %d(0x%x)\n", - (unsigned int)xFixedToInt(point[1]), point[1], - (unsigned int)xFixedToInt(trap->bottom), - (unsigned int)trap->bottom); - } - - return ret; - } + tmp = (xFixed_32_32) dx1 *dy2; - if (point[1] < trap->top) { - ret = FALSE; - if (DEBUG_CLIP_VTX) { - ErrorF("Out of Trap top, point[1] = %d(0x%x)), " - "top = %d(0x%x)\n", - (unsigned int)xFixedToInt(point[1]), point[1], - (unsigned int)xFixedToInt(trap->top), - (unsigned int)trap->top); - } - - return ret; - } + dividend2 = (tmp >> 32) * l->p1.y; + tmp = (xFixed_32_32) dy1 *dx2; - tmp = _glamor_linefixedX (&trap->left, point[1], FALSE); - if (point[0] < tmp) { - ret = FALSE; - - if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e && - abs(point[1] - trap->top) < pixman_fixed_1_minus_e && - tmp - point[0] < pixman_fixed_1_minus_e) { - ret = TRUE; - } else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e && - point[1] - trap->bottom < pixman_fixed_1_minus_e && - tmp - point[0] < pixman_fixed_1_minus_e) { - ret = TRUE; - } - - if (DEBUG_CLIP_VTX && !ret) { - ErrorF("Out of Trap left, point[0] = %d(0x%x)), " - "left = %d(0x%x)\n", - (unsigned int)xFixedToInt(point[0]), point[0], - (unsigned int)xFixedToInt(tmp), (unsigned int)tmp); - } - - if (!ret) - return ret; - } + dividend3 = (tmp >> 32) * r->p1.y; + divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2 + - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32; - tmp = _glamor_linefixedX (&trap->right, point[1], TRUE); - if (point[0] > tmp) { - ret = FALSE; - - if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e && - abs(point[1] - trap->top) < pixman_fixed_1_minus_e && - point[0] - tmp < pixman_fixed_1_minus_e) { - ret = TRUE; - } else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e && - abs(point[1] - trap->bottom) < pixman_fixed_1_minus_e && - point[0] - tmp < pixman_fixed_1_minus_e) { - ret = TRUE; - } - - if (DEBUG_CLIP_VTX && !ret) { - ErrorF("Out of Trap right, point[0] = %d(0x%x)), " - "right = %d(0x%x)\n", - (unsigned int)xFixedToInt(point[0]), point[0], - (unsigned int)xFixedToInt(tmp), (unsigned int)tmp); - } - - if (!ret) - return ret; - } + if (divisor) + return (xFixed) ((dividend2 - dividend1 - dividend3) / divisor); - return ret; + return 0xFFFFFFFF; +} + +static Bool +point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y) +{ + int ret = TRUE; + int tmp; + + if (point[1] > trap->bottom) { + ret = FALSE; + if (DEBUG_CLIP_VTX) { + ErrorF("Out of Trap bottom, point[1] = %d(0x%x)), " + "bottom = %d(0x%x)\n", + (unsigned int) xFixedToInt(point[1]), point[1], + (unsigned int) xFixedToInt(trap->bottom), + (unsigned int) trap->bottom); + } + + return ret; + } + + if (point[1] < trap->top) { + ret = FALSE; + if (DEBUG_CLIP_VTX) { + ErrorF("Out of Trap top, point[1] = %d(0x%x)), " + "top = %d(0x%x)\n", + (unsigned int) xFixedToInt(point[1]), point[1], + (unsigned int) xFixedToInt(trap->top), + (unsigned int) trap->top); + } + + return ret; + } + + tmp = _glamor_linefixedX(&trap->left, point[1], FALSE); + if (point[0] < tmp) { + ret = FALSE; + + if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e && + abs(point[1] - trap->top) < pixman_fixed_1_minus_e && + tmp - point[0] < pixman_fixed_1_minus_e) { + ret = TRUE; + } + else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e && + point[1] - trap->bottom < pixman_fixed_1_minus_e && + tmp - point[0] < pixman_fixed_1_minus_e) { + ret = TRUE; + } + + if (DEBUG_CLIP_VTX && !ret) { + ErrorF("Out of Trap left, point[0] = %d(0x%x)), " + "left = %d(0x%x)\n", + (unsigned int) xFixedToInt(point[0]), point[0], + (unsigned int) xFixedToInt(tmp), (unsigned int) tmp); + } + + if (!ret) + return ret; + } + + tmp = _glamor_linefixedX(&trap->right, point[1], TRUE); + if (point[0] > tmp) { + ret = FALSE; + + if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e && + abs(point[1] - trap->top) < pixman_fixed_1_minus_e && + point[0] - tmp < pixman_fixed_1_minus_e) { + ret = TRUE; + } + else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e && + abs(point[1] - trap->bottom) < pixman_fixed_1_minus_e && + point[0] - tmp < pixman_fixed_1_minus_e) { + ret = TRUE; + } + + if (DEBUG_CLIP_VTX && !ret) { + ErrorF("Out of Trap right, point[0] = %d(0x%x)), " + "right = %d(0x%x)\n", + (unsigned int) xFixedToInt(point[0]), point[0], + (unsigned int) xFixedToInt(tmp), (unsigned int) tmp); + } + + if (!ret) + return ret; + } + + return ret; } static void glamor_emit_composite_triangle(ScreenPtr screen, - const float *src_coords, - const float *mask_coords, - const float *dst_coords) + const float *src_coords, + const float *mask_coords, + const float *dst_coords) { - glamor_emit_composite_vert(screen, src_coords, mask_coords, - dst_coords, 0); - glamor_emit_composite_vert(screen, src_coords, mask_coords, - dst_coords, 1); - glamor_emit_composite_vert(screen, src_coords, mask_coords, - dst_coords, 2); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1); + glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2); } static void glamor_flush_composite_triangles(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch; - - dispatch = glamor_get_dispatch(glamor_priv); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); - else { - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - glamor_priv->vb, GL_DYNAMIC_DRAW); - } + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; + + dispatch = glamor_get_dispatch(glamor_priv); + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); + else { - if (!glamor_priv->render_nr_verts) - return; + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + dispatch->glBufferData(GL_ARRAY_BUFFER, + glamor_priv->vbo_offset, + glamor_priv->vb, GL_DYNAMIC_DRAW); + } - dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts); - glamor_put_dispatch(glamor_priv); + if (!glamor_priv->render_nr_verts) + return; + + dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts); + glamor_put_dispatch(glamor_priv); } static Bool _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox, - int vertex[6], int *num) + int vertex[6], int *num) { - xFixed edge_cross_y = 0xFFFFFFFF; - int tl[2]; - int bl[2]; - int tr[2]; - int br[2]; - int left_cut_top[2]; - int left_cut_left[2]; - int left_cut_right[2]; - int left_cut_bottom[2]; - int right_cut_top[2]; - int right_cut_left[2]; - int right_cut_right[2]; - int right_cut_bottom[2]; - int tmp[2]; - int tmp_vtx[20*2]; - float tmp_vtx_slope[20]; - BoxRec trap_bound; - int i = 0; - int vertex_num = 0; - - if (DEBUG_CLIP_VTX) { - ErrorF("The parameter of xTrapezoid is:\ntop: %d 0x%x\tbottom: %d 0x%x\n" - "left: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n" - "right: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n", - xFixedToInt(trap->top), (unsigned int)trap->top, - xFixedToInt(trap->bottom), (unsigned int)trap->bottom, - xFixedToInt(trap->left.p1.x), (unsigned int)trap->left.p1.x, - xFixedToInt(trap->left.p1.y), (unsigned int)trap->left.p1.y, - xFixedToInt(trap->left.p2.x), (unsigned int)trap->left.p2.x, - xFixedToInt(trap->left.p2.y), (unsigned int)trap->left.p2.y, - xFixedToInt(trap->right.p1.x), (unsigned int)trap->right.p1.x, - xFixedToInt(trap->right.p1.y), (unsigned int)trap->right.p1.y, - xFixedToInt(trap->right.p2.x), (unsigned int)trap->right.p2.x, - xFixedToInt(trap->right.p2.y), (unsigned int)trap->right.p2.y); - } - - miTrapezoidBounds(1, trap, &trap_bound); - if (DEBUG_CLIP_VTX) - ErrorF("The bounds for this traps is: bounds.x1 = %d, bounds.x2 = %d, " - "bounds.y1 = %d, bounds.y2 = %d\n", trap_bound.x1, trap_bound.x2, - trap_bound.y1, trap_bound.y2); - - if (trap_bound.x1 > pbox->x2 || trap_bound.x2 < pbox->x1) - return FALSE; - if (trap_bound.y1 > pbox->y2 || trap_bound.y2 < pbox->y1) - return FALSE; + xFixed edge_cross_y = 0xFFFFFFFF; + int tl[2]; + int bl[2]; + int tr[2]; + int br[2]; + int left_cut_top[2]; + int left_cut_left[2]; + int left_cut_right[2]; + int left_cut_bottom[2]; + int right_cut_top[2]; + int right_cut_left[2]; + int right_cut_right[2]; + int right_cut_bottom[2]; + int tmp[2]; + int tmp_vtx[20 * 2]; + float tmp_vtx_slope[20]; + BoxRec trap_bound; + int i = 0; + int vertex_num = 0; + + if (DEBUG_CLIP_VTX) { + ErrorF + ("The parameter of xTrapezoid is:\ntop: %d 0x%x\tbottom: %d 0x%x\n" + "left: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n" + "right: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n", + xFixedToInt(trap->top), (unsigned int) trap->top, + xFixedToInt(trap->bottom), (unsigned int) trap->bottom, + xFixedToInt(trap->left.p1.x), (unsigned int) trap->left.p1.x, + xFixedToInt(trap->left.p1.y), (unsigned int) trap->left.p1.y, + xFixedToInt(trap->left.p2.x), (unsigned int) trap->left.p2.x, + xFixedToInt(trap->left.p2.y), (unsigned int) trap->left.p2.y, + xFixedToInt(trap->right.p1.x), (unsigned int) trap->right.p1.x, + xFixedToInt(trap->right.p1.y), (unsigned int) trap->right.p1.y, + xFixedToInt(trap->right.p2.x), (unsigned int) trap->right.p2.x, + xFixedToInt(trap->right.p2.y), (unsigned int) trap->right.p2.y); + } + + miTrapezoidBounds(1, trap, &trap_bound); + if (DEBUG_CLIP_VTX) + ErrorF("The bounds for this traps is: bounds.x1 = %d, bounds.x2 = %d, " + "bounds.y1 = %d, bounds.y2 = %d\n", trap_bound.x1, trap_bound.x2, + trap_bound.y1, trap_bound.y2); + + if (trap_bound.x1 > pbox->x2 || trap_bound.x2 < pbox->x1) + return FALSE; + if (trap_bound.y1 > pbox->y2 || trap_bound.y2 < pbox->y1) + return FALSE; #define IS_TRAP_EDGE_VERTICAL(edge) \ (edge->p1.x == edge->p2.x) @@ -334,1319 +338,1347 @@ _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox, "the Rect\n"); \ } - /*Trap's right edge cut right edge. */ - if((!IS_TRAP_EDGE_VERTICAL((&trap->left))) || - (!IS_TRAP_EDGE_VERTICAL((&trap->right)))) { - edge_cross_y = _glamor_lines_crossfixedY((&trap->left), (&trap->right)); - if (DEBUG_CLIP_VTX) { - ErrorF("Trap's left edge cut right edge at %d(0x%x), " - "trap_top = %x, trap_bottom = %x\n", - xFixedToInt(edge_cross_y), edge_cross_y, - (unsigned int)trap->top, (unsigned int)trap->bottom); - } - } - - /*Trap's TopLeft, BottomLeft, TopRight and BottomRight. */ - CACULATE_CUT_VERTEX(tl, 1, FALSE, trap->top, (&trap->left)); - CACULATE_CUT_VERTEX(bl, 1, FALSE, trap->bottom, (&trap->left)); - CACULATE_CUT_VERTEX(tr, 1, TRUE, trap->top, (&trap->right)); - CACULATE_CUT_VERTEX(br, 1, TRUE, trap->bottom, (&trap->right)); - - if (DEBUG_CLIP_VTX) - ErrorF("Trap's TopLeft, BottomLeft, TopRight and BottomRight\n"); - if (DEBUG_CLIP_VTX) - ErrorF("Caculate the vertex of trapezoid:\n" - " (%3d, %3d)-------------------------(%3d, %3d)\n" - " / \\ \n" - " / \\ \n" - " / \\ \n" - " (%3d, %3d)---------------------------------(%3d, %3d)\n" - "Clip with rect:\n" - " (%3d, %3d)------------------------(%3d, %3d) \n" - " | | \n" - " | | \n" - " | | \n" - " (%3d, %3d)------------------------(%3d, %3d) \n", - xFixedToInt(tl[0]), xFixedToInt(tl[1]), xFixedToInt(tr[0]), - xFixedToInt(tr[1]), xFixedToInt(bl[0]), xFixedToInt(bl[1]), - xFixedToInt(br[0]), xFixedToInt(br[1]), - pbox->x1, pbox->y1, pbox->x2, pbox->y1, pbox->x1, pbox->y2, - pbox->x2, pbox->y2); - - ADD_VERTEX_IF_INSIDE(tl); - ADD_VERTEX_IF_INSIDE(bl); - ADD_VERTEX_IF_INSIDE(tr); - ADD_VERTEX_IF_INSIDE(br); - - /*Trap's left edge cut Rect. */ - if (DEBUG_CLIP_VTX) - ErrorF("Trap's left edge cut Rect\n"); - CACULATE_CUT_VERTEX(left_cut_top, 1, FALSE, IntToxFixed(pbox->y1), (&trap->left)); - ADD_VERTEX_IF_INSIDE(left_cut_top); - if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) { - CACULATE_CUT_VERTEX(left_cut_left, 0, FALSE, IntToxFixed(pbox->x1), (&trap->left)); - ADD_VERTEX_IF_INSIDE(left_cut_left); - } - CACULATE_CUT_VERTEX(left_cut_bottom, 1, FALSE, IntToxFixed(pbox->y2), (&trap->left)); - ADD_VERTEX_IF_INSIDE(left_cut_bottom); - if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) { - CACULATE_CUT_VERTEX(left_cut_right, 0, FALSE, IntToxFixed(pbox->x2), (&trap->left)); - ADD_VERTEX_IF_INSIDE(left_cut_right); - } - - /*Trap's right edge cut Rect. */ - if (DEBUG_CLIP_VTX) - ErrorF("Trap's right edge cut Rect\n"); - CACULATE_CUT_VERTEX(right_cut_top, 1, TRUE, IntToxFixed(pbox->y1), (&trap->right)); - ADD_VERTEX_IF_INSIDE(right_cut_top); - if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) { - CACULATE_CUT_VERTEX(right_cut_left, 0, TRUE, IntToxFixed(pbox->x1), (&trap->right)); - ADD_VERTEX_IF_INSIDE(right_cut_left); - } - CACULATE_CUT_VERTEX(right_cut_bottom, 1, TRUE, IntToxFixed(pbox->y2), (&trap->right)); - ADD_VERTEX_IF_INSIDE(right_cut_bottom); - if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) { - CACULATE_CUT_VERTEX(right_cut_right, 0, TRUE, IntToxFixed(pbox->x2), (&trap->right)); - ADD_VERTEX_IF_INSIDE(right_cut_right); - } - - /* Trap's top cut Left and Right of rect. */ - if (DEBUG_CLIP_VTX) - ErrorF("Trap's top cut Left and Right of rect\n"); - tmp[0] = IntToxFixed(pbox->x1); - tmp[1] = trap->top; - ADD_VERTEX_IF_INSIDE(tmp); - tmp[0] = IntToxFixed(pbox->x2); - tmp[1] = trap->top; - ADD_VERTEX_IF_INSIDE(tmp); - - /* Trap's bottom cut Left and Right of rect. */ - if (DEBUG_CLIP_VTX) - ErrorF("Trap's bottom cut Left and Right of rect\n"); - tmp[0] = IntToxFixed(pbox->x1); - tmp[1] = trap->bottom; - ADD_VERTEX_IF_INSIDE(tmp); - tmp[0] = IntToxFixed(pbox->x2); - tmp[1] = trap->bottom; - ADD_VERTEX_IF_INSIDE(tmp); - - /* The orginal 4 vertex of rect. */ - if (DEBUG_CLIP_VTX) - ErrorF("The orginal 4 vertex of rect\n"); - tmp[0] = IntToxFixed(pbox->x1); - tmp[1] = IntToxFixed(pbox->y1); - ADD_VERTEX_IF_INSIDE(tmp); - tmp[0] = IntToxFixed(pbox->x1); - tmp[1] = IntToxFixed(pbox->y2); - ADD_VERTEX_IF_INSIDE(tmp); - tmp[0] = IntToxFixed(pbox->x2); - tmp[1] = IntToxFixed(pbox->y2); - ADD_VERTEX_IF_INSIDE(tmp); - tmp[0] = IntToxFixed(pbox->x2); - tmp[1] = IntToxFixed(pbox->y1); - ADD_VERTEX_IF_INSIDE(tmp); - - if (DEBUG_CLIP_VTX) { - ErrorF("\nThe candidate vertex number is %d\n", vertex_num / 2); - for (i = 0; i < vertex_num / 2; i++) { - ErrorF("(%d, %d) ", tmp_vtx[2*i], tmp_vtx[2*i + 1]); - } - ErrorF("\n"); - } - - /* Sort the vertex by X and then Y. */ - for (i = 0; i < vertex_num / 2; i++) { - int j; - for (j = 0; j < vertex_num / 2 - i - 1; j++) { - if (tmp_vtx[2*j] > tmp_vtx[2*(j+1)] - || (tmp_vtx[2*j] == tmp_vtx[2*(j+1)] - && tmp_vtx[2*j + 1] > tmp_vtx[2*(j+1) + 1])) { - tmp[0] = tmp_vtx[2*j]; - tmp[1] = tmp_vtx[2*j + 1]; - tmp_vtx[2*j] = tmp_vtx[2*(j+1)]; - tmp_vtx[2*j + 1] = tmp_vtx[2*(j+1) + 1]; - tmp_vtx[2*(j+1)] = tmp[0]; - tmp_vtx[2*(j+1) + 1] = tmp[1]; - } - } - - } - - if (DEBUG_CLIP_VTX) { - ErrorF("\nAfter sort vertex number is:\n"); - for (i = 0; i < vertex_num / 2; i++) { - ErrorF("(%d, %d) ", tmp_vtx[2*i], tmp_vtx[2*i + 1]); - } - ErrorF("\n"); - } - - memset(vertex, -1, 2*6); - *num = 0; - - for (i = 0; i < vertex_num / 2; i++) { - if (*num > 0 && vertex[2*(*num - 1)] == tmp_vtx[2*i] - && vertex[2*(*num - 1) + 1] == tmp_vtx[2*i + 1]) { - /*same vertex.*/ - if (DEBUG_CLIP_VTX) - ErrorF("X Point:(%d, %d) discard\n", - tmp_vtx[2*i], tmp_vtx[2*i + 1]); - continue; - } - - (*num)++; - if (*num > 6) { - if (DEBUG_CLIP_VTX) - FatalError("Trapezoid clip with Rect can never have vtx" - "number bigger than 6\n"); - else { - ErrorF("Trapezoid clip with Rect can never have vtx" - "number bigger than 6\n"); - *num = 6; - break; - } - } - - vertex[2*(*num - 1)] = tmp_vtx[2*i]; - vertex[2*(*num - 1) + 1] = tmp_vtx[2*i + 1]; - if (DEBUG_CLIP_VTX) - ErrorF("@ Point:(%d, %d) select, num now is %d\n", - tmp_vtx[2*i], tmp_vtx[2*i + 1], *num); - } - - /* Now we need to arrange the vtx in the polygon's counter-clockwise - order. We first select the left and top point as the start point and - sort every vtx by the slope from vtx to the start vtx. */ - for (i = 1; i < *num; i++) { - tmp_vtx_slope[i] = (vertex[2*i] != vertex[0] ? - (float)(vertex[2*i + 1] - vertex[1]) / (float)(vertex[2*i] - vertex[0]) - : (float)INT_MAX); - } - - if (DEBUG_CLIP_VTX) { - ErrorF("\nvtx number: %d, VTX and slope:\n", *num); - for (i = 0; i < *num; i++) { - ErrorF("(%d, %d):%f ", - vertex[2*i], vertex[2*i + 1], - tmp_vtx_slope[i]); - } - ErrorF("\n"); - } - - /* Sort the vertex by slope. */ - for (i = 0; i < *num - 1; i++) { - int j; - float tmp_slope; - for (j = 1; j < *num - i - 1; j++) { - if (tmp_vtx_slope[j] < tmp_vtx_slope[j + 1]) { - tmp_slope = tmp_vtx_slope[j]; - tmp_vtx_slope[j] = tmp_vtx_slope[j + 1]; - tmp_vtx_slope[j + 1] = tmp_slope; - tmp[0] = vertex[2*j]; - tmp[1] = vertex[2*j + 1]; - vertex[2*j] = vertex[2*(j+1)]; - vertex[2*j + 1] = vertex[2*(j+1) + 1]; - vertex[2*(j+1)] = tmp[0]; - vertex[2*(j+1) + 1] = tmp[1]; - } - } - } - - if (DEBUG_CLIP_VTX) { - ErrorF("\nBefore return, vtx number: %d, VTX and slope:\n", *num); - for (i = 0; i < *num; i++) { - ErrorF("(%d, %d):%f ", - vertex[2*i], vertex[2*i + 1], - tmp_vtx_slope[i]); - } - ErrorF("\n"); - } - - return TRUE; + /*Trap's right edge cut right edge. */ + if ((!IS_TRAP_EDGE_VERTICAL((&trap->left))) || + (!IS_TRAP_EDGE_VERTICAL((&trap->right)))) { + edge_cross_y = _glamor_lines_crossfixedY((&trap->left), (&trap->right)); + if (DEBUG_CLIP_VTX) { + ErrorF("Trap's left edge cut right edge at %d(0x%x), " + "trap_top = %x, trap_bottom = %x\n", + xFixedToInt(edge_cross_y), edge_cross_y, + (unsigned int) trap->top, (unsigned int) trap->bottom); + } + } + + /*Trap's TopLeft, BottomLeft, TopRight and BottomRight. */ + CACULATE_CUT_VERTEX(tl, 1, FALSE, trap->top, (&trap->left)); + CACULATE_CUT_VERTEX(bl, 1, FALSE, trap->bottom, (&trap->left)); + CACULATE_CUT_VERTEX(tr, 1, TRUE, trap->top, (&trap->right)); + CACULATE_CUT_VERTEX(br, 1, TRUE, trap->bottom, (&trap->right)); + + if (DEBUG_CLIP_VTX) + ErrorF("Trap's TopLeft, BottomLeft, TopRight and BottomRight\n"); + if (DEBUG_CLIP_VTX) + ErrorF("Caculate the vertex of trapezoid:\n" + " (%3d, %3d)-------------------------(%3d, %3d)\n" + " / \\ \n" + " / \\ \n" + " / \\ \n" + " (%3d, %3d)---------------------------------(%3d, %3d)\n" + "Clip with rect:\n" + " (%3d, %3d)------------------------(%3d, %3d) \n" + " | | \n" + " | | \n" + " | | \n" + " (%3d, %3d)------------------------(%3d, %3d) \n", + xFixedToInt(tl[0]), xFixedToInt(tl[1]), xFixedToInt(tr[0]), + xFixedToInt(tr[1]), xFixedToInt(bl[0]), xFixedToInt(bl[1]), + xFixedToInt(br[0]), xFixedToInt(br[1]), + pbox->x1, pbox->y1, pbox->x2, pbox->y1, pbox->x1, pbox->y2, + pbox->x2, pbox->y2); + + ADD_VERTEX_IF_INSIDE(tl); + ADD_VERTEX_IF_INSIDE(bl); + ADD_VERTEX_IF_INSIDE(tr); + ADD_VERTEX_IF_INSIDE(br); + + /*Trap's left edge cut Rect. */ + if (DEBUG_CLIP_VTX) + ErrorF("Trap's left edge cut Rect\n"); + CACULATE_CUT_VERTEX(left_cut_top, 1, FALSE, IntToxFixed(pbox->y1), + (&trap->left)); + ADD_VERTEX_IF_INSIDE(left_cut_top); + if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) { + CACULATE_CUT_VERTEX(left_cut_left, 0, FALSE, IntToxFixed(pbox->x1), + (&trap->left)); + ADD_VERTEX_IF_INSIDE(left_cut_left); + } + CACULATE_CUT_VERTEX(left_cut_bottom, 1, FALSE, IntToxFixed(pbox->y2), + (&trap->left)); + ADD_VERTEX_IF_INSIDE(left_cut_bottom); + if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) { + CACULATE_CUT_VERTEX(left_cut_right, 0, FALSE, IntToxFixed(pbox->x2), + (&trap->left)); + ADD_VERTEX_IF_INSIDE(left_cut_right); + } + + /*Trap's right edge cut Rect. */ + if (DEBUG_CLIP_VTX) + ErrorF("Trap's right edge cut Rect\n"); + CACULATE_CUT_VERTEX(right_cut_top, 1, TRUE, IntToxFixed(pbox->y1), + (&trap->right)); + ADD_VERTEX_IF_INSIDE(right_cut_top); + if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) { + CACULATE_CUT_VERTEX(right_cut_left, 0, TRUE, IntToxFixed(pbox->x1), + (&trap->right)); + ADD_VERTEX_IF_INSIDE(right_cut_left); + } + CACULATE_CUT_VERTEX(right_cut_bottom, 1, TRUE, IntToxFixed(pbox->y2), + (&trap->right)); + ADD_VERTEX_IF_INSIDE(right_cut_bottom); + if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) { + CACULATE_CUT_VERTEX(right_cut_right, 0, TRUE, IntToxFixed(pbox->x2), + (&trap->right)); + ADD_VERTEX_IF_INSIDE(right_cut_right); + } + + /* Trap's top cut Left and Right of rect. */ + if (DEBUG_CLIP_VTX) + ErrorF("Trap's top cut Left and Right of rect\n"); + tmp[0] = IntToxFixed(pbox->x1); + tmp[1] = trap->top; + ADD_VERTEX_IF_INSIDE(tmp); + tmp[0] = IntToxFixed(pbox->x2); + tmp[1] = trap->top; + ADD_VERTEX_IF_INSIDE(tmp); + + /* Trap's bottom cut Left and Right of rect. */ + if (DEBUG_CLIP_VTX) + ErrorF("Trap's bottom cut Left and Right of rect\n"); + tmp[0] = IntToxFixed(pbox->x1); + tmp[1] = trap->bottom; + ADD_VERTEX_IF_INSIDE(tmp); + tmp[0] = IntToxFixed(pbox->x2); + tmp[1] = trap->bottom; + ADD_VERTEX_IF_INSIDE(tmp); + + /* The orginal 4 vertex of rect. */ + if (DEBUG_CLIP_VTX) + ErrorF("The orginal 4 vertex of rect\n"); + tmp[0] = IntToxFixed(pbox->x1); + tmp[1] = IntToxFixed(pbox->y1); + ADD_VERTEX_IF_INSIDE(tmp); + tmp[0] = IntToxFixed(pbox->x1); + tmp[1] = IntToxFixed(pbox->y2); + ADD_VERTEX_IF_INSIDE(tmp); + tmp[0] = IntToxFixed(pbox->x2); + tmp[1] = IntToxFixed(pbox->y2); + ADD_VERTEX_IF_INSIDE(tmp); + tmp[0] = IntToxFixed(pbox->x2); + tmp[1] = IntToxFixed(pbox->y1); + ADD_VERTEX_IF_INSIDE(tmp); + + if (DEBUG_CLIP_VTX) { + ErrorF("\nThe candidate vertex number is %d\n", vertex_num / 2); + for (i = 0; i < vertex_num / 2; i++) { + ErrorF("(%d, %d) ", tmp_vtx[2 * i], tmp_vtx[2 * i + 1]); + } + ErrorF("\n"); + } + + /* Sort the vertex by X and then Y. */ + for (i = 0; i < vertex_num / 2; i++) { + int j; + + for (j = 0; j < vertex_num / 2 - i - 1; j++) { + if (tmp_vtx[2 * j] > tmp_vtx[2 * (j + 1)] + || (tmp_vtx[2 * j] == tmp_vtx[2 * (j + 1)] + && tmp_vtx[2 * j + 1] > tmp_vtx[2 * (j + 1) + 1])) { + tmp[0] = tmp_vtx[2 * j]; + tmp[1] = tmp_vtx[2 * j + 1]; + tmp_vtx[2 * j] = tmp_vtx[2 * (j + 1)]; + tmp_vtx[2 * j + 1] = tmp_vtx[2 * (j + 1) + 1]; + tmp_vtx[2 * (j + 1)] = tmp[0]; + tmp_vtx[2 * (j + 1) + 1] = tmp[1]; + } + } + + } + + if (DEBUG_CLIP_VTX) { + ErrorF("\nAfter sort vertex number is:\n"); + for (i = 0; i < vertex_num / 2; i++) { + ErrorF("(%d, %d) ", tmp_vtx[2 * i], tmp_vtx[2 * i + 1]); + } + ErrorF("\n"); + } + + memset(vertex, -1, 2 * 6); + *num = 0; + + for (i = 0; i < vertex_num / 2; i++) { + if (*num > 0 && vertex[2 * (*num - 1)] == tmp_vtx[2 * i] + && vertex[2 * (*num - 1) + 1] == tmp_vtx[2 * i + 1]) { + /*same vertex. */ + if (DEBUG_CLIP_VTX) + ErrorF("X Point:(%d, %d) discard\n", + tmp_vtx[2 * i], tmp_vtx[2 * i + 1]); + continue; + } + + (*num)++; + if (*num > 6) { + if (DEBUG_CLIP_VTX) + FatalError("Trapezoid clip with Rect can never have vtx" + "number bigger than 6\n"); + else { + ErrorF("Trapezoid clip with Rect can never have vtx" + "number bigger than 6\n"); + *num = 6; + break; + } + } + + vertex[2 * (*num - 1)] = tmp_vtx[2 * i]; + vertex[2 * (*num - 1) + 1] = tmp_vtx[2 * i + 1]; + if (DEBUG_CLIP_VTX) + ErrorF("@ Point:(%d, %d) select, num now is %d\n", + tmp_vtx[2 * i], tmp_vtx[2 * i + 1], *num); + } + + /* Now we need to arrange the vtx in the polygon's counter-clockwise + order. We first select the left and top point as the start point and + sort every vtx by the slope from vtx to the start vtx. */ + for (i = 1; i < *num; i++) { + tmp_vtx_slope[i] = (vertex[2 * i] != vertex[0] ? + (float) (vertex[2 * i + 1] - + vertex[1]) / (float) (vertex[2 * i] - + vertex[0]) + : (float) INT_MAX); + } + + if (DEBUG_CLIP_VTX) { + ErrorF("\nvtx number: %d, VTX and slope:\n", *num); + for (i = 0; i < *num; i++) { + ErrorF("(%d, %d):%f ", + vertex[2 * i], vertex[2 * i + 1], tmp_vtx_slope[i]); + } + ErrorF("\n"); + } + + /* Sort the vertex by slope. */ + for (i = 0; i < *num - 1; i++) { + int j; + float tmp_slope; + + for (j = 1; j < *num - i - 1; j++) { + if (tmp_vtx_slope[j] < tmp_vtx_slope[j + 1]) { + tmp_slope = tmp_vtx_slope[j]; + tmp_vtx_slope[j] = tmp_vtx_slope[j + 1]; + tmp_vtx_slope[j + 1] = tmp_slope; + tmp[0] = vertex[2 * j]; + tmp[1] = vertex[2 * j + 1]; + vertex[2 * j] = vertex[2 * (j + 1)]; + vertex[2 * j + 1] = vertex[2 * (j + 1) + 1]; + vertex[2 * (j + 1)] = tmp[0]; + vertex[2 * (j + 1) + 1] = tmp[1]; + } + } + } + + if (DEBUG_CLIP_VTX) { + ErrorF("\nBefore return, vtx number: %d, VTX and slope:\n", *num); + for (i = 0; i < *num; i++) { + ErrorF("(%d, %d):%f ", + vertex[2 * i], vertex[2 * i + 1], tmp_vtx_slope[i]); + } + ErrorF("\n"); + } + + return TRUE; } static void glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch; - int stride; - int vert_size; - - glamor_priv->render_nr_verts = 0; - - /* For GLAMOR_VERTEX_POS */ - glamor_priv->vb_stride = 2 * sizeof(float); - - /* For GLAMOR_GLAMOR_VERTEX_SOURCE */ - glamor_priv->vb_stride += 2 * sizeof(float); - - /* For GLAMOR_VERTEX_TOP_BOTTOM */ - glamor_priv->vb_stride += 2 * sizeof(float); - - /* For GLAMOR_VERTEX_LEFT_PARAM */ - glamor_priv->vb_stride += 4 * sizeof(float); - - /* For GLAMOR_VERTEX_RIGHT_PARAM */ - glamor_priv->vb_stride += 4 * sizeof(float); - - vert_size = n_verts * glamor_priv->vb_stride; - - dispatch = glamor_get_dispatch(glamor_priv); - - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) { - glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * - glamor_priv->vb_stride; - glamor_priv->vbo_offset = 0; - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_size, - NULL, GL_STREAM_DRAW); - } - - glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - vert_size, - GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); - - assert(glamor_priv->vb != NULL); - glamor_priv->vb -= glamor_priv->vbo_offset; - } else { - glamor_priv->vbo_offset = 0; - } - - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); - - /* Set the vertex pointer. */ - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset)); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); - stride = 2; - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - stride += 2; - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); - stride += 2; - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); - stride += 4; - - dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT, - GL_FALSE, glamor_priv->vb_stride, - (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float))); - dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); - - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_gl_dispatch *dispatch; + int stride; + int vert_size; + + glamor_priv->render_nr_verts = 0; + + /* For GLAMOR_VERTEX_POS */ + glamor_priv->vb_stride = 2 * sizeof(float); + + /* For GLAMOR_GLAMOR_VERTEX_SOURCE */ + glamor_priv->vb_stride += 2 * sizeof(float); + + /* For GLAMOR_VERTEX_TOP_BOTTOM */ + glamor_priv->vb_stride += 2 * sizeof(float); + + /* For GLAMOR_VERTEX_LEFT_PARAM */ + glamor_priv->vb_stride += 4 * sizeof(float); + + /* For GLAMOR_VERTEX_RIGHT_PARAM */ + glamor_priv->vb_stride += 4 * sizeof(float); + + vert_size = n_verts * glamor_priv->vb_stride; + + dispatch = glamor_get_dispatch(glamor_priv); + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { + if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) { + glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * + glamor_priv->vb_stride; + glamor_priv->vbo_offset = 0; + dispatch->glBufferData(GL_ARRAY_BUFFER, + glamor_priv->vbo_size, NULL, GL_STREAM_DRAW); + } + + glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, + glamor_priv->vbo_offset, + vert_size, + GL_MAP_WRITE_BIT | + GL_MAP_UNSYNCHRONIZED_BIT); + + assert(glamor_priv->vb != NULL); + glamor_priv->vb -= glamor_priv->vbo_offset; + } + else { + glamor_priv->vbo_offset = 0; + } + + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); + + /* Set the vertex pointer. */ + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, glamor_priv->vb_stride, + (void *) ((long) glamor_priv->vbo_offset)); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + stride = 2; + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, + GL_FALSE, glamor_priv->vb_stride, + (void *) ((long) glamor_priv->vbo_offset + + stride * sizeof(float))); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + stride += 2; + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT, + GL_FALSE, glamor_priv->vb_stride, + (void *) ((long) glamor_priv->vbo_offset + + stride * sizeof(float))); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); + stride += 2; + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT, + GL_FALSE, glamor_priv->vb_stride, + (void *) ((long) glamor_priv->vbo_offset + + stride * sizeof(float))); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); + stride += 4; + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT, + GL_FALSE, glamor_priv->vb_stride, + (void *) ((long) glamor_priv->vbo_offset + + stride * sizeof(float))); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); + + glamor_put_dispatch(glamor_priv); } static Bool _glamor_trapezoids_with_shader(CARD8 op, - PicturePtr src, PicturePtr dst, - PictFormatPtr mask_format, INT16 x_src, INT16 y_src, - int ntrap, xTrapezoid * traps) + PicturePtr src, PicturePtr dst, + PictFormatPtr mask_format, INT16 x_src, + INT16 y_src, int ntrap, xTrapezoid * traps) { - ScreenPtr screen = dst->pDrawable->pScreen; - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - struct shader_key key; - glamor_composite_shader *shader = NULL; - struct blendinfo op_info; - PictFormatShort saved_source_format = 0; - PixmapPtr source_pixmap = NULL; - PixmapPtr dest_pixmap = NULL; - glamor_pixmap_private *source_pixmap_priv = NULL; - glamor_pixmap_private *dest_pixmap_priv = NULL; - glamor_pixmap_private *temp_src_priv = NULL; - int x_temp_src, y_temp_src; - int src_width, src_height; - int source_x_off, source_y_off; - GLfloat src_xscale = 1, src_yscale = 1; - int x_dst, y_dst; - int dest_x_off, dest_y_off; - GLfloat dst_xscale, dst_yscale; - BoxRec bounds; - PicturePtr temp_src = src; - glamor_gl_dispatch *dispatch = NULL; - int vert_stride = 3; - int ntriangle_per_loop; - int nclip_rect; - int mclip_rect; - int clip_processed; - int clipped_vtx[6*2]; - RegionRec region; - BoxPtr box = NULL; - BoxPtr pbox = NULL; - int traps_count = 0; - int traps_not_completed = 0; - xTrapezoid * ptrap = NULL; - int nbox; - float src_matrix[9]; - Bool ret = FALSE; - - /* If a mask format wasn't provided, we get to choose, but behavior should - * be as if there was no temporary mask the traps were accumulated into. - */ - if (!mask_format) { - if (dst->polyEdge == PolyEdgeSharp) - mask_format = PictureMatchFormat(screen, 1, PICT_a1); - else - mask_format = PictureMatchFormat(screen, 8, PICT_a8); - for (; ntrap; ntrap--, traps++) - glamor_trapezoids(op, src, dst, mask_format, x_src, - y_src, 1, traps); - return TRUE; - } - - miTrapezoidBounds(ntrap, traps, &bounds); - DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, " - "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2, - bounds.y1, bounds.y2); - - /* No area need to render. */ - if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) - return TRUE; - - dest_pixmap = glamor_get_drawable_pixmap(dst->pDrawable); - dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv) - || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { - /* Currently. Always fallback to cpu if destination is in CPU memory.*/ - ret = FALSE; - DEBUGF("dst pixmap has no FBO.\n"); - goto TRAPEZOID_OUT; - } - - if (src->pDrawable) { - source_pixmap = glamor_get_drawable_pixmap(src->pDrawable); - source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); - temp_src_priv = source_pixmap_priv; - if (source_pixmap_priv - && (source_pixmap_priv->type == GLAMOR_DRM_ONLY - || source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) { - ret = FALSE; - goto TRAPEZOID_OUT; - } - } - - x_dst = bounds.x1; - y_dst = bounds.y1; - - src_width = bounds.x2 - bounds.x1; - src_height = bounds.y2 - bounds.y1; - - x_temp_src = x_src + bounds.x1 - (traps[0].left.p1.x >> 16); - y_temp_src = y_src + bounds.y1 - (traps[0].left.p1.y >> 16); - - if ((!src->pDrawable && - (src->pSourcePict->type != SourcePictTypeSolidFill)) //1. The Gradient case. - /* 2. Has no fbo but can upload.*/ - || (src->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) - && ((src_width * src_height * 4 < - source_pixmap->drawable.width * source_pixmap->drawable.height) - || !glamor_check_fbo_size(glamor_priv, source_pixmap->drawable.width, - source_pixmap->drawable.height)))) { - - if (!glamor_check_fbo_size(glamor_priv, src_width, src_height)) { - ret = FALSE; - goto TRAPEZOID_OUT; - } - temp_src = glamor_convert_gradient_picture(screen, src, - x_src, y_src, - src_width, src_height); - if (!temp_src) { - temp_src = src; - ret = FALSE; - DEBUGF("Convert gradient picture failed\n"); - goto TRAPEZOID_OUT; - } - temp_src_priv = glamor_get_pixmap_private((PixmapPtr)temp_src->pDrawable); - x_temp_src = y_temp_src = 0; - } - - x_dst += dst->pDrawable->x; - y_dst += dst->pDrawable->y; - if (temp_src->pDrawable) { - x_temp_src += temp_src->pDrawable->x; - y_temp_src += temp_src->pDrawable->y; - } - - if (!miComputeCompositeRegion(®ion, - temp_src, NULL, dst, - x_temp_src, y_temp_src, - 0, 0, - x_dst, y_dst, - src_width, src_height)) { - DEBUGF("All the regions are clipped out, do nothing\n"); - goto TRAPEZOID_OUT; - } - - box = REGION_RECTS(®ion); - nbox = REGION_NUM_RECTS(®ion); - pbox = box; - - ret = glamor_composite_choose_shader(op, temp_src, NULL, dst, - temp_src_priv, NULL, dest_pixmap_priv, - &key, &shader, &op_info, &saved_source_format); - if (ret == FALSE) { - DEBUGF("can not set the shader program for composite\n"); - goto TRAPEZOID_RESET_GL; - } - glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); - glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info); - glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; - glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && - key.mask != SHADER_MASK_SOLID); - - dispatch = glamor_get_dispatch(glamor_priv); - - glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap, - &dest_x_off, &dest_y_off); - - pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale); - - if (glamor_priv->has_source_coords) { - source_pixmap = glamor_get_drawable_pixmap(temp_src->pDrawable); - source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); - glamor_get_drawable_deltas(temp_src->pDrawable, - source_pixmap, - &source_x_off, &source_y_off); - pixmap_priv_get_scale(source_pixmap_priv, - &src_xscale, &src_yscale); - glamor_picture_get_matrixf(temp_src, src_matrix); - vert_stride += 3; - } - - if (glamor_priv->has_mask_coords) { - DEBUGF("Should never have mask coords here!\n"); - ret = FALSE; - goto TRAPEZOID_RESET_GL; - } - - /* A trapezoid clip with a rectangle will at most generate a hexagon, - which can be devided into 4 triangles to render. */ - ntriangle_per_loop = (vert_stride * nbox * ntrap * 4) > GLAMOR_COMPOSITE_VBO_VERT_CNT ? - (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nbox * ntrap * 4; - ntriangle_per_loop = (ntriangle_per_loop / 4) * 4; - - nclip_rect = nbox; - while (nclip_rect) { - mclip_rect = (nclip_rect * ntrap * 4) > ntriangle_per_loop ? - (ntriangle_per_loop / (4 * ntrap)) : nclip_rect; - - if (!mclip_rect) {/* Maybe too many traps. */ - mclip_rect = 1; - ptrap = traps; - traps_count = ntriangle_per_loop / 4; - traps_not_completed = ntrap - traps_count; - } else { - traps_count = ntrap; - ptrap = traps; - traps_not_completed = 0; - } - -NTRAPS_LOOP_AGAIN: - - glamor_setup_composite_vbo(screen, mclip_rect * traps_count * 4 * vert_stride); - clip_processed = mclip_rect; - - - while (mclip_rect--) { - while (traps_count--) { - int vtx_num; - int i; - float vertices[3*2], source_texcoords[3*2]; - - DEBUGF("In loop of render trapezoid, nclip_rect = %d, mclip_rect = %d, " - "clip_processed = %d, traps_count = %d, traps_not_completed = %d\n", - nclip_rect, mclip_rect, clip_processed, traps_count, traps_not_completed); - - if (_glamor_clip_trapezoid_vertex(ptrap, pbox, clipped_vtx, &vtx_num)) { - for (i = 0; i < vtx_num - 2; i++) { - int clipped_vtx_tmp[3*2]; - - clipped_vtx_tmp[0] = clipped_vtx[0]; - clipped_vtx_tmp[1] = clipped_vtx[1]; - clipped_vtx_tmp[2] = clipped_vtx[(i+1)*2]; - clipped_vtx_tmp[3] = clipped_vtx[(i+1)*2 + 1]; - clipped_vtx_tmp[4] = clipped_vtx[(i+2)*2]; - 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], - vertices[2], vertices[3], vertices[4], vertices[5]); - - - if (key.source != SHADER_SOURCE_SOLID) { - if (src->transform) { - glamor_set_transformed_normalize_tri_tcoords( - source_pixmap_priv, - src_matrix, src_xscale, src_yscale, - clipped_vtx_tmp, - glamor_priv->yInverted, - source_texcoords); - } else { - glamor_set_normalize_tri_tcoords( - src_xscale, src_yscale, - clipped_vtx_tmp, - glamor_priv->yInverted, - source_texcoords); - } - - DEBUGF("source_texcoords of triangle: (%f X %f), " - "(%f X %f), (%f X %f)\n", - source_texcoords[0], source_texcoords[1], - source_texcoords[2], source_texcoords[3], - source_texcoords[4], source_texcoords[5]); - } - - glamor_emit_composite_triangle(screen, source_texcoords, - NULL, vertices); - } - } - - ptrap++; - } - - if (traps_not_completed) { /* one loop of ntraps not completed */ - mclip_rect = 1; - traps_count = traps_not_completed > (ntriangle_per_loop / 4) ? - (ntriangle_per_loop / 4) : traps_not_completed; - traps_not_completed -= traps_count; - glamor_flush_composite_triangles(screen); - goto NTRAPS_LOOP_AGAIN; - } else { - ptrap = traps; - traps_count = ntrap; - } - - pbox++; - } - - glamor_flush_composite_triangles(screen); - - nclip_rect -= clip_processed; - } - - ret = TRUE; - -TRAPEZOID_RESET_GL: - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); - dispatch->glDisable(GL_BLEND); + ScreenPtr screen = dst->pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + struct shader_key key; + glamor_composite_shader *shader = NULL; + struct blendinfo op_info; + PictFormatShort saved_source_format = 0; + PixmapPtr source_pixmap = NULL; + PixmapPtr dest_pixmap = NULL; + glamor_pixmap_private *source_pixmap_priv = NULL; + glamor_pixmap_private *dest_pixmap_priv = NULL; + glamor_pixmap_private *temp_src_priv = NULL; + int x_temp_src, y_temp_src; + int src_width, src_height; + int source_x_off, source_y_off; + GLfloat src_xscale = 1, src_yscale = 1; + int x_dst, y_dst; + int dest_x_off, dest_y_off; + GLfloat dst_xscale, dst_yscale; + BoxRec bounds; + PicturePtr temp_src = src; + glamor_gl_dispatch *dispatch = NULL; + int vert_stride = 3; + int ntriangle_per_loop; + int nclip_rect; + int mclip_rect; + int clip_processed; + int clipped_vtx[6 * 2]; + RegionRec region; + BoxPtr box = NULL; + BoxPtr pbox = NULL; + int traps_count = 0; + int traps_not_completed = 0; + xTrapezoid *ptrap = NULL; + int nbox; + float src_matrix[9]; + Bool ret = FALSE; + + /* If a mask format wasn't provided, we get to choose, but behavior should + * be as if there was no temporary mask the traps were accumulated into. + */ + if (!mask_format) { + if (dst->polyEdge == PolyEdgeSharp) + mask_format = PictureMatchFormat(screen, 1, PICT_a1); + else + mask_format = PictureMatchFormat(screen, 8, PICT_a8); + for (; ntrap; ntrap--, traps++) + glamor_trapezoids(op, src, dst, mask_format, x_src, + y_src, 1, traps); + return TRUE; + } + + miTrapezoidBounds(ntrap, traps, &bounds); + DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, " + "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2, + bounds.y1, bounds.y2); + + /* No area need to render. */ + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return TRUE; + + dest_pixmap = glamor_get_drawable_pixmap(dst->pDrawable); + dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv) + || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + /* Currently. Always fallback to cpu if destination is in CPU memory. */ + ret = FALSE; + DEBUGF("dst pixmap has no FBO.\n"); + goto TRAPEZOID_OUT; + } + + if (src->pDrawable) { + source_pixmap = glamor_get_drawable_pixmap(src->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + temp_src_priv = source_pixmap_priv; + if (source_pixmap_priv + && (source_pixmap_priv->type == GLAMOR_DRM_ONLY + || source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) { + ret = FALSE; + goto TRAPEZOID_OUT; + } + } + + x_dst = bounds.x1; + y_dst = bounds.y1; + + src_width = bounds.x2 - bounds.x1; + src_height = bounds.y2 - bounds.y1; + + x_temp_src = x_src + bounds.x1 - (traps[0].left.p1.x >> 16); + y_temp_src = y_src + bounds.y1 - (traps[0].left.p1.y >> 16); + + if ((!src->pDrawable && (src->pSourcePict->type != SourcePictTypeSolidFill)) //1. The Gradient case. + /* 2. Has no fbo but can upload. */ + || (src->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) + && ((src_width * src_height * 4 < + source_pixmap->drawable.width * source_pixmap->drawable.height) + || !glamor_check_fbo_size(glamor_priv, + source_pixmap->drawable.width, + source_pixmap->drawable.height)))) { + + if (!glamor_check_fbo_size(glamor_priv, src_width, src_height)) { + ret = FALSE; + goto TRAPEZOID_OUT; + } + temp_src = glamor_convert_gradient_picture(screen, src, + x_src, y_src, + src_width, src_height); + if (!temp_src) { + temp_src = src; + ret = FALSE; + DEBUGF("Convert gradient picture failed\n"); + goto TRAPEZOID_OUT; + } + temp_src_priv = + glamor_get_pixmap_private((PixmapPtr) temp_src->pDrawable); + x_temp_src = y_temp_src = 0; + } + + x_dst += dst->pDrawable->x; + y_dst += dst->pDrawable->y; + if (temp_src->pDrawable) { + x_temp_src += temp_src->pDrawable->x; + y_temp_src += temp_src->pDrawable->y; + } + + if (!miComputeCompositeRegion(®ion, + temp_src, NULL, dst, + x_temp_src, y_temp_src, + 0, 0, x_dst, y_dst, src_width, src_height)) { + DEBUGF("All the regions are clipped out, do nothing\n"); + goto TRAPEZOID_OUT; + } + + box = REGION_RECTS(®ion); + nbox = REGION_NUM_RECTS(®ion); + pbox = box; + + ret = glamor_composite_choose_shader(op, temp_src, NULL, dst, + temp_src_priv, NULL, dest_pixmap_priv, + &key, &shader, &op_info, + &saved_source_format); + if (ret == FALSE) { + DEBUGF("can not set the shader program for composite\n"); + goto TRAPEZOID_RESET_GL; + } + glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv); + glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info); + glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID; + glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE && + key.mask != SHADER_MASK_SOLID); + + dispatch = glamor_get_dispatch(glamor_priv); + + glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap, + &dest_x_off, &dest_y_off); + + pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale); + + if (glamor_priv->has_source_coords) { + source_pixmap = glamor_get_drawable_pixmap(temp_src->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + glamor_get_drawable_deltas(temp_src->pDrawable, + source_pixmap, &source_x_off, &source_y_off); + pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale); + glamor_picture_get_matrixf(temp_src, src_matrix); + vert_stride += 3; + } + + if (glamor_priv->has_mask_coords) { + DEBUGF("Should never have mask coords here!\n"); + ret = FALSE; + goto TRAPEZOID_RESET_GL; + } + + /* A trapezoid clip with a rectangle will at most generate a hexagon, + which can be devided into 4 triangles to render. */ + ntriangle_per_loop = + (vert_stride * nbox * ntrap * 4) > + GLAMOR_COMPOSITE_VBO_VERT_CNT ? (GLAMOR_COMPOSITE_VBO_VERT_CNT / + vert_stride) : nbox * ntrap * 4; + ntriangle_per_loop = (ntriangle_per_loop / 4) * 4; + + nclip_rect = nbox; + while (nclip_rect) { + mclip_rect = (nclip_rect * ntrap * 4) > ntriangle_per_loop ? + (ntriangle_per_loop / (4 * ntrap)) : nclip_rect; + + if (!mclip_rect) { /* Maybe too many traps. */ + mclip_rect = 1; + ptrap = traps; + traps_count = ntriangle_per_loop / 4; + traps_not_completed = ntrap - traps_count; + } + else { + traps_count = ntrap; + ptrap = traps; + traps_not_completed = 0; + } + + NTRAPS_LOOP_AGAIN: + + glamor_setup_composite_vbo(screen, + mclip_rect * traps_count * 4 * vert_stride); + clip_processed = mclip_rect; + + while (mclip_rect--) { + while (traps_count--) { + int vtx_num; + int i; + float vertices[3 * 2], source_texcoords[3 * 2]; + + DEBUGF + ("In loop of render trapezoid, nclip_rect = %d, mclip_rect = %d, " + "clip_processed = %d, traps_count = %d, traps_not_completed = %d\n", + nclip_rect, mclip_rect, clip_processed, traps_count, + traps_not_completed); + + if (_glamor_clip_trapezoid_vertex + (ptrap, pbox, clipped_vtx, &vtx_num)) { + for (i = 0; i < vtx_num - 2; i++) { + int clipped_vtx_tmp[3 * 2]; + + clipped_vtx_tmp[0] = clipped_vtx[0]; + clipped_vtx_tmp[1] = clipped_vtx[1]; + clipped_vtx_tmp[2] = clipped_vtx[(i + 1) * 2]; + clipped_vtx_tmp[3] = clipped_vtx[(i + 1) * 2 + 1]; + clipped_vtx_tmp[4] = clipped_vtx[(i + 2) * 2]; + 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], + vertices[2], vertices[3], vertices[4], + vertices[5]); + + if (key.source != SHADER_SOURCE_SOLID) { + if (src->transform) { + glamor_set_transformed_normalize_tri_tcoords + (source_pixmap_priv, src_matrix, src_xscale, + src_yscale, clipped_vtx_tmp, + glamor_priv->yInverted, source_texcoords); + } + else { + glamor_set_normalize_tri_tcoords(src_xscale, + src_yscale, + clipped_vtx_tmp, + glamor_priv-> + yInverted, + source_texcoords); + } + + DEBUGF("source_texcoords of triangle: (%f X %f), " + "(%f X %f), (%f X %f)\n", + source_texcoords[0], source_texcoords[1], + source_texcoords[2], source_texcoords[3], + source_texcoords[4], source_texcoords[5]); + } + + glamor_emit_composite_triangle(screen, source_texcoords, + NULL, vertices); + } + } + + ptrap++; + } + + if (traps_not_completed) { /* one loop of ntraps not completed */ + mclip_rect = 1; + traps_count = traps_not_completed > (ntriangle_per_loop / 4) ? + (ntriangle_per_loop / 4) : traps_not_completed; + traps_not_completed -= traps_count; + glamor_flush_composite_triangles(screen); + goto NTRAPS_LOOP_AGAIN; + } + else { + ptrap = traps; + traps_count = ntrap; + } + + pbox++; + } + + glamor_flush_composite_triangles(screen); + + nclip_rect -= clip_processed; + } + + ret = TRUE; + + TRAPEZOID_RESET_GL: + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); + dispatch->glDisable(GL_BLEND); #ifndef GLAMOR_GLES2 - dispatch->glActiveTexture(GL_TEXTURE0); - dispatch->glDisable(GL_TEXTURE_2D); - dispatch->glActiveTexture(GL_TEXTURE1); - dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glDisable(GL_TEXTURE_2D); + dispatch->glActiveTexture(GL_TEXTURE1); + dispatch->glDisable(GL_TEXTURE_2D); #endif - dispatch->glUseProgram(0); - -TRAPEZOID_OUT: - if (box) { - REGION_UNINIT(dst->pDrawable->pScreen, ®ion); - } - - if (temp_src != src) { - FreePicture(temp_src, 0); - } else { - if (saved_source_format) { - src->format = saved_source_format; - } - } - - if (dispatch) { - glamor_put_dispatch(glamor_priv); - } - - return ret; + dispatch->glUseProgram(0); + + TRAPEZOID_OUT: + if (box) { + REGION_UNINIT(dst->pDrawable->pScreen, ®ion); + } + + if (temp_src != src) { + FreePicture(temp_src, 0); + } + else { + if (saved_source_format) { + src->format = saved_source_format; + } + } + + if (dispatch) { + glamor_put_dispatch(glamor_priv); + } + + return ret; } void glamor_init_trapezoid_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - GLint fs_prog, vs_prog; - - const char *trapezoid_vs = - GLAMOR_DEFAULT_PRECISION - "attribute vec4 v_position;\n" - "attribute vec2 v_texcoord;\n" - /* v_top_bottom, v_left_param and v_right_param contain the - constant value for all the vertex of one rect. Using uniform - is more suitable but we need to reset the uniform variables - for every rect rendering and can not use the vbo, which causes - performance loss. So we set these attributes to same value - for every vertex of one rect and so it is also a constant in FS */ - "attribute vec2 v_top_bottom;\n" - "attribute vec4 v_left_param;\n" - "attribute vec4 v_right_param;\n" - "\n" - "varying vec2 source_texture;\n" - "varying float trap_top;\n" - "varying float trap_bottom;\n" - "varying float trap_left_x;\n" - "varying float trap_left_y;\n" - "varying float trap_left_slope;\n" - "varying float trap_left_vertical_f;\n" - "varying float trap_right_x;\n" - "varying float trap_right_y;\n" - "varying float trap_right_slope;\n" - "varying float trap_right_vertical_f;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = v_position;\n" - " source_texture = v_texcoord.xy;\n" - " trap_top = v_top_bottom.x;\n" - " trap_bottom = v_top_bottom.y;\n" - " \n" - " trap_left_x = v_left_param.x;\n" - " trap_left_y = v_left_param.y;\n" - " trap_left_slope = v_left_param.z;\n" - " trap_left_vertical_f = v_left_param.w;\n" - " \n" - " trap_right_x = v_right_param.x;\n" - " trap_right_y = v_right_param.y;\n" - " trap_right_slope = v_right_param.z;\n" - " trap_right_vertical_f = v_right_param.w;\n" - "}\n"; - - /* - * Because some GL fill function do not support the MultSample - * anti-alias, we need to do the MSAA here. This manner like - * pixman, will caculate the value of area in trapezoid dividing - * the totol area for each pixel, as follow: - | - ----+------------------------------------------------------> - | - | ------------- - | / \ - | / \ - | / \ - | / +----------------+ - | / |.....\ | - | / |......\ | - | / |.......\ | - | / |........\ | - | /-------------------+---------\ | - | | | - | | | - | +----------------+ - | - \|/ - - */ - const char *trapezoid_fs = - GLAMOR_DEFAULT_PRECISION - "varying vec2 source_texture; \n" - "varying float trap_top; \n" - "varying float trap_bottom; \n" - "varying float trap_left_x; \n" - "varying float trap_left_y; \n" - "varying float trap_left_slope; \n" - "varying float trap_left_vertical_f; \n" - "varying float trap_right_x; \n" - "varying float trap_right_y; \n" - "varying float trap_right_slope; \n" - "varying float trap_right_vertical_f; \n" - "float x_per_pix = 1.0;" - "float y_per_pix = 1.0;" - "\n" - "float get_alpha_val() \n" - "{ \n" - " float x_up_cut_left; \n" - " float x_bottom_cut_left; \n" - " float x_up_cut_right; \n" - " float x_bottom_cut_right; \n" - " bool trap_left_vertical;\n" - " bool trap_right_vertical;\n" - " if (abs(trap_left_vertical_f - 1.0) <= 0.0001)\n" - " trap_left_vertical = true;\n" - " else\n" - " trap_left_vertical = false;\n" - " if (abs(trap_right_vertical_f - 1.0) <= 0.0001)\n" - " trap_right_vertical = true;\n" - " else\n" - " trap_right_vertical = false;\n" - " \n" - " if(trap_left_vertical == true) { \n" - " x_up_cut_left = trap_left_x; \n" - " x_bottom_cut_left = trap_left_x; \n" - " } else { \n" - " x_up_cut_left = trap_left_x \n" - " + (source_texture.y - y_per_pix/2.0 - trap_left_y) \n" - " / trap_left_slope; \n" - " x_bottom_cut_left = trap_left_x \n" - " + (source_texture.y + y_per_pix/2.0 - trap_left_y) \n" - " / trap_left_slope; \n" - " } \n" - " \n" - " if(trap_right_vertical == true) { \n" - " x_up_cut_right = trap_right_x; \n" - " x_bottom_cut_right = trap_right_x; \n" - " } else { \n" - " x_up_cut_right = trap_right_x \n" - " + (source_texture.y - y_per_pix/2.0 - trap_right_y) \n" - " / trap_right_slope; \n" - " x_bottom_cut_right = trap_right_x \n" - " + (source_texture.y + y_per_pix/2.0 - trap_right_y) \n" - " / trap_right_slope; \n" - " } \n" - " \n" - " if((x_up_cut_left <= source_texture.x - x_per_pix/2.0) && \n" - " (x_bottom_cut_left <= source_texture.x - x_per_pix/2.0) && \n" - " (x_up_cut_right >= source_texture.x + x_per_pix/2.0) && \n" - " (x_bottom_cut_right >= source_texture.x + x_per_pix/2.0) && \n" - " (trap_top <= source_texture.y - y_per_pix/2.0) && \n" - " (trap_bottom >= source_texture.y + y_per_pix/2.0)) { \n" - // The complete inside case. - " return 1.0; \n" - " } else if((trap_top > source_texture.y + y_per_pix/2.0) || \n" - " (trap_bottom < source_texture.y - y_per_pix/2.0)) { \n" - // The complete outside. Above the top or Below the bottom. - " return 0.0; \n" - " } else { \n" - " if((x_up_cut_right < source_texture.x - x_per_pix/2.0 && \n" - " x_bottom_cut_right < source_texture.x - x_per_pix/2.0) \n" - " || (x_up_cut_left > source_texture.x + x_per_pix/2.0 && \n" - " x_bottom_cut_left > source_texture.x + x_per_pix/2.0)) { \n" - // The complete outside. At Left or Right of the trapezoide. - " return 0.0; \n" - " } \n" - " } \n" - // Get here, the pix is partly inside the trapezoid. - " { \n" - " float percent = 0.0; \n" - " float up = (source_texture.y - y_per_pix/2.0) >= trap_top ? \n" - " (source_texture.y - y_per_pix/2.0) : trap_top; \n" - " float bottom = (source_texture.y + y_per_pix/2.0) <= trap_bottom ? \n" - " (source_texture.y + y_per_pix/2.0) : trap_bottom; \n" - " float left = source_texture.x - x_per_pix/2.0; \n" - " float right = source_texture.x + x_per_pix/2.0; \n" - " \n" - " percent = (bottom - up) / y_per_pix; \n" - " \n" - " if(trap_left_vertical == true) { \n" - " if(trap_left_x > source_texture.x - x_per_pix/2.0 && \n" - " trap_left_x < source_texture.x + x_per_pix/2.0) \n" - " left = trap_left_x; \n" - " } \n" - " if(trap_right_vertical == true) { \n" - " if(trap_right_x > source_texture.x - x_per_pix/2.0 && \n" - " trap_right_x < source_texture.x + x_per_pix/2.0) \n" - " right = trap_right_x; \n" - " } \n" - " if((up >= bottom) || (left >= right)) \n" - " return 0.0; \n" - " \n" - " percent = percent * ((right - left)/x_per_pix); \n" - " if(trap_left_vertical == true && trap_right_vertical == true) \n" - " return percent; \n" - " \n" - " if(trap_left_vertical != true) { \n" - " float area; \n" - // the slope should never be 0.0 here - " float up_x = trap_left_x + (up - trap_left_y)/trap_left_slope; \n" - " float bottom_x = trap_left_x + (bottom - trap_left_y)/trap_left_slope; \n" - " if(trap_left_slope < 0.0 && up_x > left) { \n" - /* case 1 - | - ----+-------------------------------------> - | / - | / - | +---/--------+ - | | /.........| - | | /..........| - | |/...........| - | /............| - | /|............| - | +------------+ - | - \|/ - */ - " float left_y = trap_left_y + trap_left_slope*(left - trap_left_x); \n" - " if((up_x > left) && (left_y > up)) { \n" - " area = 0.5 * (up_x - left) * (left_y - up); \n" - " if(up_x > right) { \n" - " float right_y = trap_left_y \n" - " + trap_left_slope*(right - trap_left_x); \n" - " area = area - 0.5 * (up_x - right) * (right_y - up); \n" - " } \n" - " if(left_y > bottom) { \n" - " area = area - 0.5 * (bottom_x - left) * (left_y - bottom); \n" - " } \n" - " } else { \n" - " area = 0.0; \n" - " } \n" - " percent = percent * (1.0 - (area/((right-left)*(bottom-up)))); \n" - " } else if(trap_left_slope > 0.0 && bottom_x > left) { \n" - /* case 2 - | - ----+-------------------------------------> - | \ - | \ - | +\-----------+ - | | \..........| - | | \.........| - | | \........| - | | \.......| - | | \......| - | +------\-----+ - | \ - | \ - \|/ - */ - " float right_y = trap_left_y + trap_left_slope*(right - trap_left_x); \n" - " if((up_x < right) && (right_y > up)) { \n" - " area = 0.5 * (right - up_x) * (right_y - up); \n" - " if(up_x < left) { \n" - " float left_y = trap_left_y \n" - " + trap_left_slope*(left - trap_left_x); \n" - " area = area - 0.5 * (left - up_x) * (left_y - up); \n" - " } \n" - " if(right_y > bottom) { \n" - " area = area - 0.5 * (right - bottom_x) * (right_y - bottom); \n" - " } \n" - " } else { \n" - " area = 0.0; \n" - " } \n" - " percent = percent * (area/((right-left)*(bottom-up))); \n" - " } \n" - " } \n" - " \n" - " if(trap_right_vertical != true) { \n" - " float area; \n" - // the slope should never be 0.0 here - " float up_x = trap_right_x + (up - trap_right_y)/trap_right_slope; \n" - " float bottom_x = trap_right_x + (bottom - trap_right_y)/trap_right_slope; \n" - " if(trap_right_slope < 0.0 && bottom_x < right) { \n" - /* case 3 - | - ----+-------------------------------------> - | / - | +--------/---+ - | |......./ | - | |....../ | - | |...../ | - | |..../ | - | |.../ | - | +--/---------+ - | / - | - \|/ - */ - " float left_y = trap_right_y + trap_right_slope*(left - trap_right_x); \n" - " if((up_x > left) && (left_y > up)) { \n" - " area = 0.5 * (up_x - left) * (left_y - up); \n" - " if(up_x > right) { \n" - " float right_y = trap_right_y \n" - " + trap_right_slope*(right - trap_right_x); \n" - " area = area - 0.5 * (up_x - right) * (right_y - up); \n" - " } \n" - " if(left_y > bottom) { \n" - " area = area - 0.5 * (bottom_x - left) * (left_y - bottom); \n" - " } \n" - " } else { \n" - " area = 0.0; \n" - " } \n" - " percent = percent * (area/((right-left)*(bottom-up))); \n" - " } else if(trap_right_slope > 0.0 && up_x < right) { \n" - /* case 4 - | - ----+-------------------------------------> - | \ - | +--------\---+ - | |.........\ | - | |..........\ | - | |...........\| - | |............\ - | |............|\ - | +------------+ \ - | \ - | - \|/ - */ - " float right_y = trap_right_y + trap_right_slope*(right - trap_right_x); \n" - " if((up_x < right) && (right_y > up)) { \n" - " area = 0.5 * (right - up_x) * (right_y - up); \n" - " if(up_x < left) { \n" - " float left_y = trap_right_y \n" - " + trap_right_slope*(left - trap_right_x); \n" - " area = area - 0.5 * (left - up_x) * (left_y - up); \n" - " } \n" - " if(right_y > bottom) { \n" - " area = area - 0.5 * (right - bottom_x) * (right_y - bottom); \n" - " } \n" - " } else { \n" - " area = 0.0; \n" - " } \n" - " percent = percent * (1.0 - (area/((right-left)*(bottom-up)))); \n" - " } \n" - " } \n" - " \n" - " return percent; \n" - " } \n" - "} \n" - "\n" - "void main() \n" - "{ \n" - " float alpha_val = get_alpha_val(); \n" - " gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val); \n" - "}\n"; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - - glamor_priv->trapezoid_prog = dispatch->glCreateProgram(); - - vs_prog = glamor_compile_glsl_prog(dispatch, - GL_VERTEX_SHADER, trapezoid_vs); - fs_prog = glamor_compile_glsl_prog(dispatch, - GL_FRAGMENT_SHADER, trapezoid_fs); - - dispatch->glAttachShader(glamor_priv->trapezoid_prog, vs_prog); - dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog); - - dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, - GLAMOR_VERTEX_POS, "v_positionsition"); - dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, - GLAMOR_VERTEX_SOURCE, "v_texcoord"); - dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, - GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom"); - dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, - GLAMOR_VERTEX_LEFT_PARAM, "v_left_param"); - dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, - GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param"); - - glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog); - - dispatch->glUseProgram(0); - - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + GLint fs_prog, vs_prog; + + const char *trapezoid_vs = + GLAMOR_DEFAULT_PRECISION + "attribute vec4 v_position;\n" "attribute vec2 v_texcoord;\n" + /* v_top_bottom, v_left_param and v_right_param contain the + constant value for all the vertex of one rect. Using uniform + is more suitable but we need to reset the uniform variables + for every rect rendering and can not use the vbo, which causes + performance loss. So we set these attributes to same value + for every vertex of one rect and so it is also a constant in FS */ + "attribute vec2 v_top_bottom;\n" + "attribute vec4 v_left_param;\n" + "attribute vec4 v_right_param;\n" + "\n" + "varying vec2 source_texture;\n" + "varying float trap_top;\n" + "varying float trap_bottom;\n" + "varying float trap_left_x;\n" + "varying float trap_left_y;\n" + "varying float trap_left_slope;\n" + "varying float trap_left_vertical_f;\n" + "varying float trap_right_x;\n" + "varying float trap_right_y;\n" + "varying float trap_right_slope;\n" + "varying float trap_right_vertical_f;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = v_position;\n" + " source_texture = v_texcoord.xy;\n" + " trap_top = v_top_bottom.x;\n" + " trap_bottom = v_top_bottom.y;\n" + " \n" + " trap_left_x = v_left_param.x;\n" + " trap_left_y = v_left_param.y;\n" + " trap_left_slope = v_left_param.z;\n" + " trap_left_vertical_f = v_left_param.w;\n" + " \n" + " trap_right_x = v_right_param.x;\n" + " trap_right_y = v_right_param.y;\n" + " trap_right_slope = v_right_param.z;\n" + " trap_right_vertical_f = v_right_param.w;\n" "}\n"; + + /* + * Because some GL fill function do not support the MultSample + * anti-alias, we need to do the MSAA here. This manner like + * pixman, will caculate the value of area in trapezoid dividing + * the totol area for each pixel, as follow: + | + ----+------------------------------------------------------> + | + | ------------- + | / \ + | / \ + | / \ + | / +----------------+ + | / |.....\ | + | / |......\ | + | / |.......\ | + | / |........\ | + | /-------------------+---------\ | + | | | + | | | + | +----------------+ + | + \|/ + + */ + const char *trapezoid_fs = + GLAMOR_DEFAULT_PRECISION + "varying vec2 source_texture; \n" + "varying float trap_top; \n" + "varying float trap_bottom; \n" + "varying float trap_left_x; \n" + "varying float trap_left_y; \n" + "varying float trap_left_slope; \n" + "varying float trap_left_vertical_f; \n" + "varying float trap_right_x; \n" + "varying float trap_right_y; \n" + "varying float trap_right_slope; \n" + "varying float trap_right_vertical_f; \n" + "float x_per_pix = 1.0;" + "float y_per_pix = 1.0;" + "\n" + "float get_alpha_val() \n" + "{ \n" + " float x_up_cut_left; \n" + " float x_bottom_cut_left; \n" + " float x_up_cut_right; \n" + " float x_bottom_cut_right; \n" + " bool trap_left_vertical;\n" + " bool trap_right_vertical;\n" + " if (abs(trap_left_vertical_f - 1.0) <= 0.0001)\n" + " trap_left_vertical = true;\n" + " else\n" + " trap_left_vertical = false;\n" + " if (abs(trap_right_vertical_f - 1.0) <= 0.0001)\n" + " trap_right_vertical = true;\n" + " else\n" + " trap_right_vertical = false;\n" + " \n" + " if(trap_left_vertical == true) { \n" + " x_up_cut_left = trap_left_x; \n" + " x_bottom_cut_left = trap_left_x; \n" + " } else { \n" + " x_up_cut_left = trap_left_x \n" + " + (source_texture.y - y_per_pix/2.0 - trap_left_y) \n" + " / trap_left_slope; \n" + " x_bottom_cut_left = trap_left_x \n" + " + (source_texture.y + y_per_pix/2.0 - trap_left_y) \n" + " / trap_left_slope; \n" + " } \n" + " \n" + " if(trap_right_vertical == true) { \n" + " x_up_cut_right = trap_right_x; \n" + " x_bottom_cut_right = trap_right_x; \n" + " } else { \n" + " x_up_cut_right = trap_right_x \n" + " + (source_texture.y - y_per_pix/2.0 - trap_right_y) \n" + " / trap_right_slope; \n" + " x_bottom_cut_right = trap_right_x \n" + " + (source_texture.y + y_per_pix/2.0 - trap_right_y) \n" + " / trap_right_slope; \n" + " } \n" + " \n" + " if((x_up_cut_left <= source_texture.x - x_per_pix/2.0) && \n" + " (x_bottom_cut_left <= source_texture.x - x_per_pix/2.0) && \n" + " (x_up_cut_right >= source_texture.x + x_per_pix/2.0) && \n" + " (x_bottom_cut_right >= source_texture.x + x_per_pix/2.0) && \n" + " (trap_top <= source_texture.y - y_per_pix/2.0) && \n" + " (trap_bottom >= source_texture.y + y_per_pix/2.0)) { \n" + // The complete inside case. + " return 1.0; \n" + " } else if((trap_top > source_texture.y + y_per_pix/2.0) || \n" + " (trap_bottom < source_texture.y - y_per_pix/2.0)) { \n" + // The complete outside. Above the top or Below the bottom. + " return 0.0; \n" + " } else { \n" + " if((x_up_cut_right < source_texture.x - x_per_pix/2.0 && \n" + " x_bottom_cut_right < source_texture.x - x_per_pix/2.0) \n" + " || (x_up_cut_left > source_texture.x + x_per_pix/2.0 && \n" + " x_bottom_cut_left > source_texture.x + x_per_pix/2.0)) { \n" + // The complete outside. At Left or Right of the trapezoide. + " return 0.0; \n" " } \n" " } \n" + // Get here, the pix is partly inside the trapezoid. + " { \n" + " float percent = 0.0; \n" + " float up = (source_texture.y - y_per_pix/2.0) >= trap_top ? \n" + " (source_texture.y - y_per_pix/2.0) : trap_top; \n" + " float bottom = (source_texture.y + y_per_pix/2.0) <= trap_bottom ? \n" + " (source_texture.y + y_per_pix/2.0) : trap_bottom; \n" + " float left = source_texture.x - x_per_pix/2.0; \n" + " float right = source_texture.x + x_per_pix/2.0; \n" + " \n" + " percent = (bottom - up) / y_per_pix; \n" + " \n" + " if(trap_left_vertical == true) { \n" + " if(trap_left_x > source_texture.x - x_per_pix/2.0 && \n" + " trap_left_x < source_texture.x + x_per_pix/2.0) \n" + " left = trap_left_x; \n" + " } \n" + " if(trap_right_vertical == true) { \n" + " if(trap_right_x > source_texture.x - x_per_pix/2.0 && \n" + " trap_right_x < source_texture.x + x_per_pix/2.0) \n" + " right = trap_right_x; \n" + " } \n" + " if((up >= bottom) || (left >= right)) \n" + " return 0.0; \n" + " \n" + " percent = percent * ((right - left)/x_per_pix); \n" + " if(trap_left_vertical == true && trap_right_vertical == true) \n" + " return percent; \n" + " \n" + " if(trap_left_vertical != true) { \n" + " float area; \n" + // the slope should never be 0.0 here + " float up_x = trap_left_x + (up - trap_left_y)/trap_left_slope; \n" + " float bottom_x = trap_left_x + (bottom - trap_left_y)/trap_left_slope; \n" + " if(trap_left_slope < 0.0 && up_x > left) { \n" + /* case 1 + | + ----+-------------------------------------> + | / + | / + | +---/--------+ + | | /.........| + | | /..........| + | |/...........| + | /............| + | /|............| + | +------------+ + | + \|/ + */ + " float left_y = trap_left_y + trap_left_slope*(left - trap_left_x); \n" + " if((up_x > left) && (left_y > up)) { \n" + " area = 0.5 * (up_x - left) * (left_y - up); \n" + " if(up_x > right) { \n" + " float right_y = trap_left_y \n" + " + trap_left_slope*(right - trap_left_x); \n" + " area = area - 0.5 * (up_x - right) * (right_y - up); \n" + " } \n" + " if(left_y > bottom) { \n" + " area = area - 0.5 * (bottom_x - left) * (left_y - bottom); \n" + " } \n" + " } else { \n" + " area = 0.0; \n" + " } \n" + " percent = percent * (1.0 - (area/((right-left)*(bottom-up)))); \n" + " } else if(trap_left_slope > 0.0 && bottom_x > left) { \n" + /* case 2 + | + ----+-------------------------------------> + | \ + | \ + | +\-----------+ + | | \..........| + | | \.........| + | | \........| + | | \.......| + | | \......| + | +------\-----+ + | \ + | \ + \|/ + */ + " float right_y = trap_left_y + trap_left_slope*(right - trap_left_x); \n" + " if((up_x < right) && (right_y > up)) { \n" + " area = 0.5 * (right - up_x) * (right_y - up); \n" + " if(up_x < left) { \n" + " float left_y = trap_left_y \n" + " + trap_left_slope*(left - trap_left_x); \n" + " area = area - 0.5 * (left - up_x) * (left_y - up); \n" + " } \n" + " if(right_y > bottom) { \n" + " area = area - 0.5 * (right - bottom_x) * (right_y - bottom); \n" + " } \n" + " } else { \n" + " area = 0.0; \n" + " } \n" + " percent = percent * (area/((right-left)*(bottom-up))); \n" + " } \n" + " } \n" + " \n" + " if(trap_right_vertical != true) { \n" + " float area; \n" + // the slope should never be 0.0 here + " float up_x = trap_right_x + (up - trap_right_y)/trap_right_slope; \n" + " float bottom_x = trap_right_x + (bottom - trap_right_y)/trap_right_slope; \n" + " if(trap_right_slope < 0.0 && bottom_x < right) { \n" + /* case 3 + | + ----+-------------------------------------> + | / + | +--------/---+ + | |......./ | + | |....../ | + | |...../ | + | |..../ | + | |.../ | + | +--/---------+ + | / + | + \|/ + */ + " float left_y = trap_right_y + trap_right_slope*(left - trap_right_x); \n" + " if((up_x > left) && (left_y > up)) { \n" + " area = 0.5 * (up_x - left) * (left_y - up); \n" + " if(up_x > right) { \n" + " float right_y = trap_right_y \n" + " + trap_right_slope*(right - trap_right_x); \n" + " area = area - 0.5 * (up_x - right) * (right_y - up); \n" + " } \n" + " if(left_y > bottom) { \n" + " area = area - 0.5 * (bottom_x - left) * (left_y - bottom); \n" + " } \n" + " } else { \n" + " area = 0.0; \n" + " } \n" + " percent = percent * (area/((right-left)*(bottom-up))); \n" + " } else if(trap_right_slope > 0.0 && up_x < right) { \n" + /* case 4 + | + ----+-------------------------------------> + | \ + | +--------\---+ + | |.........\ | + | |..........\ | + | |...........\| + | |............\ + | |............|\ + | +------------+ \ + | \ + | + \|/ + */ + " float right_y = trap_right_y + trap_right_slope*(right - trap_right_x); \n" + " if((up_x < right) && (right_y > up)) { \n" + " area = 0.5 * (right - up_x) * (right_y - up); \n" + " if(up_x < left) { \n" + " float left_y = trap_right_y \n" + " + trap_right_slope*(left - trap_right_x); \n" + " area = area - 0.5 * (left - up_x) * (left_y - up); \n" + " } \n" + " if(right_y > bottom) { \n" + " area = area - 0.5 * (right - bottom_x) * (right_y - bottom); \n" + " } \n" + " } else { \n" + " area = 0.0; \n" + " } \n" + " percent = percent * (1.0 - (area/((right-left)*(bottom-up)))); \n" + " } \n" + " } \n" + " \n" + " return percent; \n" + " } \n" + "} \n" + "\n" + "void main() \n" + "{ \n" + " float alpha_val = get_alpha_val(); \n" + " gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val); \n" "}\n"; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + + glamor_priv->trapezoid_prog = dispatch->glCreateProgram(); + + vs_prog = glamor_compile_glsl_prog(dispatch, + GL_VERTEX_SHADER, trapezoid_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, + GL_FRAGMENT_SHADER, trapezoid_fs); + + dispatch->glAttachShader(glamor_priv->trapezoid_prog, vs_prog); + dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog); + + dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, + GLAMOR_VERTEX_POS, "v_positionsition"); + dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, + GLAMOR_VERTEX_SOURCE, "v_texcoord"); + dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, + GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom"); + dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, + GLAMOR_VERTEX_LEFT_PARAM, "v_left_param"); + dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, + GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param"); + + glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog); + + dispatch->glUseProgram(0); + + glamor_put_dispatch(glamor_priv); } void glamor_fini_trapezoid_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glDeleteProgram(glamor_priv->trapezoid_prog); - glamor_put_dispatch(glamor_priv); + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glDeleteProgram(glamor_priv->trapezoid_prog); + glamor_put_dispatch(glamor_priv); } static Bool _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, - xTrapezoid * traps, int ntrap, BoxRec *bounds) + xTrapezoid * traps, int ntrap, + BoxRec * bounds) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - glamor_pixmap_private *pixmap_priv; - PixmapPtr pixmap = NULL; - GLint trapezoid_prog; - GLfloat xscale, yscale; - float left_slope, right_slope; - xTrapezoid *ptrap; - BoxRec one_trap_bound; - int nrect_max; - int i, j; - float *vertices; - float params[4]; - - glamor_priv = glamor_get_screen_private(screen); - trapezoid_prog = glamor_priv->trapezoid_prog; - - pixmap = glamor_get_drawable_pixmap(picture->pDrawable); - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) - || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* should always have here. */ - DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n"); - return FALSE; - } - - /* 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; - } - - dispatch = glamor_get_dispatch(glamor_priv); - - glamor_set_destination_pixmap_priv_nc(pixmap_priv); - - pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale)); - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - /* Now draw the Trapezoid mask. */ - dispatch->glUseProgram(trapezoid_prog); - - dispatch->glEnable(GL_BLEND); - dispatch->glBlendFunc(GL_ONE, GL_ONE); - - nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM); - - for (i = 0; i < ntrap;) { - int mrect; - int stride; - - mrect = (ntrap - i) > nrect_max ? nrect_max : (ntrap - i); - glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect); - stride = glamor_priv->vb_stride / sizeof(float); - - for (j = 0; j < mrect; j++) { - ptrap = traps + i + j; - - DEBUGF("--- The parameter of xTrapezoid is:\ntop: %d 0x%x\tbottom: %d 0x%x\n" - "left: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n" - "right: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n", - xFixedToInt(ptrap->top), ptrap->top, - xFixedToInt(ptrap->bottom), ptrap->bottom, - xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x, - xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y, - xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x, - xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y, - xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x, - xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y, - xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x, - xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y); - - miTrapezoidBounds(1, ptrap, &one_trap_bound); - - vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset) + 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), - (one_trap_bound.x2), - (one_trap_bound.y2), - glamor_priv->yInverted, 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], - vertices[2*stride], vertices[2*stride + 1], - vertices[3*stride], vertices[3*stride + 1]); - - /* Need to rebase. */ - one_trap_bound.x1 -= bounds->x1; - one_trap_bound.x2 -= bounds->x1; - one_trap_bound.y1 -= bounds->y1; - one_trap_bound.y2 -= bounds->y1; - - vertices -= 2; - - glamor_set_normalize_vcoords_ext(pixmap_priv, xscale, yscale, - one_trap_bound.x1, one_trap_bound.y1, - one_trap_bound.x2, one_trap_bound.y2, - glamor_priv->yInverted, 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], - vertices[2*stride], vertices[2*stride + 1], - vertices[3*stride], vertices[3*stride + 1]); - vertices += 4; - - /* Set the top and bottom. */ - params[0] = ((float)ptrap->top) / 65536; - params[1] = ((float)ptrap->bottom) / 65536; - glamor_set_const_ext(params, 2, vertices, 4, stride); - vertices += 2; - - /* Set the left params. */ - params[0] = ((float)ptrap->left.p1.x) / 65536; - params[1] = ((float)ptrap->left.p1.y) / 65536; - - if (ptrap->left.p1.x == ptrap->left.p2.x) { - left_slope = 0.0; - params[3] = 1.0; - } else { - left_slope = ((float)(ptrap->left.p1.y - ptrap->left.p2.y)) - / ((float)(ptrap->left.p1.x - ptrap->left.p2.x)); - params[3] = 0.0; - } - params[2] = left_slope; - glamor_set_const_ext(params, 4, vertices, 4, stride); - vertices += 4; - - /* Set the left params. */ - params[0] = ((float)ptrap->right.p1.x) / 65536; - params[1] = ((float)ptrap->right.p1.y) / 65536; - - if (ptrap->right.p1.x == ptrap->right.p2.x) { - right_slope = 0.0; - params[3] = 1.0; - } else { - right_slope = ((float)(ptrap->right.p1.y - ptrap->right.p2.y)) - / ((float)(ptrap->right.p1.x - ptrap->right.p2.x)); - params[3] = 0.0; - } - params[2] = right_slope; - glamor_set_const_ext(params, 4, vertices, 4, stride); - - DEBUGF("trap_top = %f, trap_bottom = %f, " - "trap_left_x = %f, trap_left_y = %f, left_slope = %f, " - "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n", - ((float)ptrap->top) / 65536, ((float)ptrap->bottom) / 65536, - ((float)ptrap->left.p1.x) / 65536, ((float)ptrap->left.p1.y) / 65536, - left_slope, - ((float)ptrap->right.p1.x) / 65536, ((float)ptrap->right.p1.y) / 65536, - right_slope); - - glamor_priv->render_nr_verts += 4; - glamor_priv->vbo_offset += glamor_priv->vb_stride * 4; - } - - i += mrect; - - /* Now rendering. */ - if (!glamor_priv->render_nr_verts) - continue; - - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) - dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); - else { - dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); - dispatch->glBufferData(GL_ARRAY_BUFFER, - glamor_priv->vbo_offset, - glamor_priv->vb, GL_DYNAMIC_DRAW); - } + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + glamor_pixmap_private *pixmap_priv; + PixmapPtr pixmap = NULL; + GLint trapezoid_prog; + GLfloat xscale, yscale; + float left_slope, right_slope; + xTrapezoid *ptrap; + BoxRec one_trap_bound; + int nrect_max; + int i, j; + float *vertices; + float params[4]; + + glamor_priv = glamor_get_screen_private(screen); + trapezoid_prog = glamor_priv->trapezoid_prog; + + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) + || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* should always have here. */ + DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n"); + return FALSE; + } + + /* 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; + } + + dispatch = glamor_get_dispatch(glamor_priv); + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + + pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale)); + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + /* Now draw the Trapezoid mask. */ + dispatch->glUseProgram(trapezoid_prog); + + dispatch->glEnable(GL_BLEND); + dispatch->glBlendFunc(GL_ONE, GL_ONE); + + nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM); + + for (i = 0; i < ntrap;) { + int mrect; + int stride; + + mrect = (ntrap - i) > nrect_max ? nrect_max : (ntrap - i); + glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect); + stride = glamor_priv->vb_stride / sizeof(float); + + for (j = 0; j < mrect; j++) { + ptrap = traps + i + j; + + DEBUGF + ("--- The parameter of xTrapezoid is:\ntop: %d 0x%x\tbottom: %d 0x%x\n" + "left: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n" + "right: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n", + xFixedToInt(ptrap->top), ptrap->top, + xFixedToInt(ptrap->bottom), ptrap->bottom, + xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x, + xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y, + xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x, + xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y, + xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x, + xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y, + xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x, + xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y); + + miTrapezoidBounds(1, ptrap, &one_trap_bound); + + vertices = + (float *) (glamor_priv->vb + glamor_priv->vbo_offset) + 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), + (one_trap_bound.x2), (one_trap_bound.y2), + glamor_priv->yInverted, 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], + vertices[2 * stride], vertices[2 * stride + 1], + vertices[3 * stride], vertices[3 * stride + 1]); + + /* Need to rebase. */ + one_trap_bound.x1 -= bounds->x1; + one_trap_bound.x2 -= bounds->x1; + one_trap_bound.y1 -= bounds->y1; + one_trap_bound.y2 -= bounds->y1; + + vertices -= 2; + + glamor_set_normalize_vcoords_ext(pixmap_priv, xscale, yscale, + one_trap_bound.x1, + one_trap_bound.y1, + one_trap_bound.x2, + one_trap_bound.y2, + glamor_priv->yInverted, 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], + vertices[2 * stride], vertices[2 * stride + 1], + vertices[3 * stride], vertices[3 * stride + 1]); + vertices += 4; + + /* Set the top and bottom. */ + params[0] = ((float) ptrap->top) / 65536; + params[1] = ((float) ptrap->bottom) / 65536; + glamor_set_const_ext(params, 2, vertices, 4, stride); + vertices += 2; + + /* Set the left params. */ + params[0] = ((float) ptrap->left.p1.x) / 65536; + params[1] = ((float) ptrap->left.p1.y) / 65536; + + if (ptrap->left.p1.x == ptrap->left.p2.x) { + left_slope = 0.0; + params[3] = 1.0; + } + else { + left_slope = ((float) (ptrap->left.p1.y - ptrap->left.p2.y)) + / ((float) (ptrap->left.p1.x - ptrap->left.p2.x)); + params[3] = 0.0; + } + params[2] = left_slope; + glamor_set_const_ext(params, 4, vertices, 4, stride); + vertices += 4; + + /* Set the left params. */ + params[0] = ((float) ptrap->right.p1.x) / 65536; + params[1] = ((float) ptrap->right.p1.y) / 65536; + + if (ptrap->right.p1.x == ptrap->right.p2.x) { + right_slope = 0.0; + params[3] = 1.0; + } + else { + right_slope = ((float) (ptrap->right.p1.y - ptrap->right.p2.y)) + / ((float) (ptrap->right.p1.x - ptrap->right.p2.x)); + params[3] = 0.0; + } + params[2] = right_slope; + glamor_set_const_ext(params, 4, vertices, 4, stride); + + DEBUGF("trap_top = %f, trap_bottom = %f, " + "trap_left_x = %f, trap_left_y = %f, left_slope = %f, " + "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n", + ((float) ptrap->top) / 65536, + ((float) ptrap->bottom) / 65536, + ((float) ptrap->left.p1.x) / 65536, + ((float) ptrap->left.p1.y) / 65536, left_slope, + ((float) ptrap->right.p1.x) / 65536, + ((float) ptrap->right.p1.y) / 65536, right_slope); + + glamor_priv->render_nr_verts += 4; + glamor_priv->vbo_offset += glamor_priv->vb_stride * 4; + } + + i += mrect; + + /* Now rendering. */ + if (!glamor_priv->render_nr_verts) + continue; + + if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) + dispatch->glUnmapBuffer(GL_ARRAY_BUFFER); + else { + dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); + dispatch->glBufferData(GL_ARRAY_BUFFER, + glamor_priv->vbo_offset, + glamor_priv->vb, GL_DYNAMIC_DRAW); + } #ifndef GLAMOR_GLES2 - dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts, - (glamor_priv->render_nr_verts * 3) / 2, - GL_UNSIGNED_SHORT, NULL); + dispatch->glDrawRangeElements(GL_TRIANGLES, 0, + glamor_priv->render_nr_verts, + (glamor_priv->render_nr_verts * 3) / 2, + GL_UNSIGNED_SHORT, NULL); #else - dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2, - GL_UNSIGNED_SHORT, NULL); + dispatch->glDrawElements(GL_TRIANGLES, + (glamor_priv->render_nr_verts * 3) / 2, + GL_UNSIGNED_SHORT, NULL); #endif - } - - dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); - dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - dispatch->glBlendFunc(GL_ONE, GL_ZERO); - dispatch->glDisable(GL_BLEND); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); - dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); - dispatch->glUseProgram(0); - glamor_put_dispatch(glamor_priv); - return TRUE; + } + + dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); + dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + dispatch->glBlendFunc(GL_ONE, GL_ZERO); + dispatch->glDisable(GL_BLEND); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_priv); + return TRUE; } -#endif /*GLAMOR_TRAPEZOID_SHADER */ +#endif /*GLAMOR_TRAPEZOID_SHADER */ /** * Creates an appropriate picture for temp mask use. */ static PicturePtr glamor_create_mask_picture(ScreenPtr screen, - PicturePtr dst, - PictFormatPtr pict_format, - CARD16 width, CARD16 height, int gpu) + PicturePtr dst, + PictFormatPtr pict_format, + CARD16 width, CARD16 height, int gpu) { - PixmapPtr pixmap; - PicturePtr picture; - int error; - - if (!pict_format) { - if (dst->polyEdge == PolyEdgeSharp) - pict_format = - PictureMatchFormat(screen, 1, PICT_a1); - else - pict_format = - PictureMatchFormat(screen, 8, PICT_a8); - if (!pict_format) - return 0; - } - - if (gpu) { - pixmap = glamor_create_pixmap(screen, width, height, - pict_format->depth, 0); - } else { - pixmap = glamor_create_pixmap(screen, 0, 0, - pict_format->depth, - GLAMOR_CREATE_PIXMAP_CPU); - } - - if (!pixmap) - return 0; - picture = CreatePicture(0, &pixmap->drawable, pict_format, - 0, 0, serverClient, &error); - glamor_destroy_pixmap(pixmap); - return picture; + PixmapPtr pixmap; + PicturePtr picture; + int error; + + if (!pict_format) { + if (dst->polyEdge == PolyEdgeSharp) + pict_format = PictureMatchFormat(screen, 1, PICT_a1); + else + pict_format = PictureMatchFormat(screen, 8, PICT_a8); + if (!pict_format) + return 0; + } + + if (gpu) { + pixmap = glamor_create_pixmap(screen, width, height, + pict_format->depth, 0); + } + else { + pixmap = glamor_create_pixmap(screen, 0, 0, + pict_format->depth, + GLAMOR_CREATE_PIXMAP_CPU); + } + + if (!pixmap) + return 0; + picture = CreatePicture(0, &pixmap->drawable, pict_format, + 0, 0, serverClient, &error); + glamor_destroy_pixmap(pixmap); + return picture; } static int -_glamor_trapezoid_bounds (int ntrap, xTrapezoid *traps, BoxPtr box) +_glamor_trapezoid_bounds(int ntrap, xTrapezoid * traps, BoxPtr box) { - int has_large_trapezoid = 0; - box->y1 = MAXSHORT; - box->y2 = MINSHORT; - box->x1 = MAXSHORT; - box->x2 = MINSHORT; - - for (; ntrap; ntrap--, traps++) { - INT16 x1, y1, x2, y2; - - if (!xTrapezoidValid(traps)) - continue; - y1 = xFixedToInt (traps->top); - if (y1 < box->y1) - box->y1 = y1; - - y2 = xFixedToInt (xFixedCeil (traps->bottom)); - if (y2 > box->y2) - box->y2 = y2; - - x1 = xFixedToInt (min (_glamor_linefixedX (&traps->left, traps->top, FALSE), - _glamor_linefixedX (&traps->left, traps->bottom, FALSE))); - if (x1 < box->x1) - box->x1 = x1; - - x2 = xFixedToInt (xFixedCeil (max (_glamor_linefixedX (&traps->right, traps->top, TRUE), - _glamor_linefixedX (&traps->right, traps->bottom, TRUE)))); - if (x2 > box->x2) - box->x2 = x2; - - if (!has_large_trapezoid && (x2 - x1) > 256 && (y2 - y1) > 32) - has_large_trapezoid = 1; - } - - return has_large_trapezoid; + int has_large_trapezoid = 0; + + box->y1 = MAXSHORT; + box->y2 = MINSHORT; + box->x1 = MAXSHORT; + box->x2 = MINSHORT; + + for (; ntrap; ntrap--, traps++) { + INT16 x1, y1, x2, y2; + + if (!xTrapezoidValid(traps)) + continue; + y1 = xFixedToInt(traps->top); + if (y1 < box->y1) + box->y1 = y1; + + y2 = xFixedToInt(xFixedCeil(traps->bottom)); + if (y2 > box->y2) + box->y2 = y2; + + x1 = xFixedToInt(min + (_glamor_linefixedX(&traps->left, traps->top, FALSE), + _glamor_linefixedX(&traps->left, traps->bottom, + FALSE))); + if (x1 < box->x1) + box->x1 = x1; + + x2 = xFixedToInt(xFixedCeil + (max + (_glamor_linefixedX(&traps->right, traps->top, TRUE), + _glamor_linefixedX(&traps->right, traps->bottom, + TRUE)))); + if (x2 > box->x2) + box->x2 = x2; + + if (!has_large_trapezoid && (x2 - x1) > 256 && (y2 - y1) > 32) + has_large_trapezoid = 1; + } + + return has_large_trapezoid; } /** @@ -1660,135 +1692,137 @@ _glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps, Bool fallback) { - ScreenPtr screen = dst->pDrawable->pScreen; - BoxRec bounds; - PicturePtr picture; - INT16 x_dst, y_dst; - INT16 x_rel, y_rel; - int width, height, stride; - PixmapPtr pixmap; - pixman_image_t *image = NULL; - int ret = 0; - int has_large_trapezoid; - - /* If a mask format wasn't provided, we get to choose, but behavior should - * be as if there was no temporary mask the traps were accumulated into. - */ - if (!mask_format) { - if (dst->polyEdge == PolyEdgeSharp) - mask_format = - PictureMatchFormat(screen, 1, PICT_a1); - else - mask_format = - PictureMatchFormat(screen, 8, PICT_a8); - for (; ntrap; ntrap--, traps++) - glamor_trapezoids(op, src, dst, mask_format, x_src, - y_src, 1, traps); - return TRUE; - } - - has_large_trapezoid = _glamor_trapezoid_bounds(ntrap, traps, &bounds); - DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, " - "bounds.y1 = %d, bounds.y2 = %d, ---- ntrap = %d\n", bounds.x1, - bounds.x2, bounds.y1, bounds.y2, ntrap); - - if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) - return TRUE; - - x_dst = traps[0].left.p1.x >> 16; - y_dst = traps[0].left.p1.y >> 16; - - width = bounds.x2 - bounds.x1; - height = bounds.y2 - bounds.y1; - stride = PixmapBytePad(width, mask_format->depth); + ScreenPtr screen = dst->pDrawable->pScreen; + BoxRec bounds; + PicturePtr picture; + INT16 x_dst, y_dst; + INT16 x_rel, y_rel; + int width, height, stride; + PixmapPtr pixmap; + pixman_image_t *image = NULL; + int ret = 0; + int has_large_trapezoid; + + /* If a mask format wasn't provided, we get to choose, but behavior should + * be as if there was no temporary mask the traps were accumulated into. + */ + if (!mask_format) { + if (dst->polyEdge == PolyEdgeSharp) + mask_format = PictureMatchFormat(screen, 1, PICT_a1); + else + mask_format = PictureMatchFormat(screen, 8, PICT_a8); + for (; ntrap; ntrap--, traps++) + glamor_trapezoids(op, src, dst, mask_format, x_src, + y_src, 1, traps); + return TRUE; + } + + has_large_trapezoid = _glamor_trapezoid_bounds(ntrap, traps, &bounds); + DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, " + "bounds.y1 = %d, bounds.y2 = %d, ---- ntrap = %d\n", bounds.x1, + bounds.x2, bounds.y1, bounds.y2, ntrap); + + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return TRUE; + + x_dst = traps[0].left.p1.x >> 16; + y_dst = traps[0].left.p1.y >> 16; + + width = bounds.x2 - bounds.x1; + height = bounds.y2 - bounds.y1; + stride = PixmapBytePad(width, mask_format->depth); #ifdef GLAMOR_TRAPEZOID_SHADER - /* We seperate the render to two paths. - Some GL implemetation do not implement the Anti-Alias for triangles - and polygen's filling. So when the edge is not vertical or horizontal, - sawtooth will be obvious. The trapezoid is widely used to render wide - lines and circles. In these case, the line or circle will be divided - into a large number of small trapezoids to approximate it, so the sawtooth - at the edge will cause the result not be acceptable. - When the depth of the mask is 1, there is no Anti-Alias needed, so we - use the clip logic to generate the result directly(fast path). - When the depth is not 1, AA is needed and we use a shader to generate - a temp mask pixmap. - */ - if (mask_format->depth == 1) { - ret = _glamor_trapezoids_with_shader(op, src, dst, mask_format, - x_src, y_src, ntrap, traps); - if(ret) - return TRUE; - } else { - if (has_large_trapezoid || ntrap > 256) { - /* The shader speed is relative slower than pixman when generating big chunk - trapezoid mask. We fallback to pixman to improve the performance. */ - ; - } else if (dst->polyMode == PolyModeImprecise) { - /* The precise mode is that we sample the trapezoid on the centre points of - an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader - and we use inside area ratio to replace it if the polymode == Imprecise. */ - picture = glamor_create_mask_picture(screen, dst, mask_format, - width, height, 1); - if (!picture) - return TRUE; - - ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds); - - if (!ret) - FreePicture(picture, 0); - } - } + /* We seperate the render to two paths. + Some GL implemetation do not implement the Anti-Alias for triangles + and polygen's filling. So when the edge is not vertical or horizontal, + sawtooth will be obvious. The trapezoid is widely used to render wide + lines and circles. In these case, the line or circle will be divided + into a large number of small trapezoids to approximate it, so the sawtooth + at the edge will cause the result not be acceptable. + When the depth of the mask is 1, there is no Anti-Alias needed, so we + use the clip logic to generate the result directly(fast path). + When the depth is not 1, AA is needed and we use a shader to generate + a temp mask pixmap. + */ + if (mask_format->depth == 1) { + ret = _glamor_trapezoids_with_shader(op, src, dst, mask_format, + x_src, y_src, ntrap, traps); + if (ret) + return TRUE; + } + else { + if (has_large_trapezoid || ntrap > 256) { + /* The shader speed is relative slower than pixman when generating big chunk + trapezoid mask. We fallback to pixman to improve the performance. */ + ; + } + else if (dst->polyMode == PolyModeImprecise) { + /* The precise mode is that we sample the trapezoid on the centre points of + an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader + and we use inside area ratio to replace it if the polymode == Imprecise. */ + picture = glamor_create_mask_picture(screen, dst, mask_format, + width, height, 1); + if (!picture) + return TRUE; + + ret = + _glamor_generate_trapezoid_with_shader(screen, picture, traps, + ntrap, &bounds); + + if (!ret) + FreePicture(picture, 0); + } + } #endif - if (!ret) { - DEBUGF("Fallback to sw rasterize of trapezoid\n"); - - picture = glamor_create_mask_picture(screen, dst, mask_format, - width, height, 0); - if (!picture) - return TRUE; - - image = pixman_image_create_bits(picture->format, - width, height, NULL, stride); - if (!image) { - FreePicture(picture, 0); - return TRUE; - } - - for (; ntrap; ntrap--, traps++) - pixman_rasterize_trapezoid(image, - (pixman_trapezoid_t *) traps, - -bounds.x1, -bounds.y1); - - pixmap = glamor_get_drawable_pixmap(picture->pDrawable); - - screen->ModifyPixmapHeader(pixmap, width, height, - mask_format->depth, - BitsPerPixel(mask_format->depth), - PixmapBytePad(width, - mask_format->depth), - pixman_image_get_data(image)); - } - - x_rel = bounds.x1 + x_src - x_dst; - y_rel = bounds.y1 + y_src - y_dst; - DEBUGF("x_src = %d, y_src = %d, x_dst = %d, y_dst = %d, " - "x_rel = %d, y_rel = %d\n", x_src, y_src, x_dst, - y_dst, x_rel, y_rel); - - CompositePicture(op, src, picture, dst, - x_rel, y_rel, - 0, 0, - bounds.x1, bounds.y1, - bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); - - if (image) - pixman_image_unref(image); - - FreePicture(picture, 0); - return TRUE; + if (!ret) { + DEBUGF("Fallback to sw rasterize of trapezoid\n"); + + picture = glamor_create_mask_picture(screen, dst, mask_format, + width, height, 0); + if (!picture) + return TRUE; + + image = pixman_image_create_bits(picture->format, + width, height, NULL, stride); + if (!image) { + FreePicture(picture, 0); + return TRUE; + } + + for (; ntrap; ntrap--, traps++) + pixman_rasterize_trapezoid(image, + (pixman_trapezoid_t *) traps, + -bounds.x1, -bounds.y1); + + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + + screen->ModifyPixmapHeader(pixmap, width, height, + mask_format->depth, + BitsPerPixel(mask_format->depth), + PixmapBytePad(width, + mask_format->depth), + pixman_image_get_data(image)); + } + + x_rel = bounds.x1 + x_src - x_dst; + y_rel = bounds.y1 + y_src - y_dst; + DEBUGF("x_src = %d, y_src = %d, x_dst = %d, y_dst = %d, " + "x_rel = %d, y_rel = %d\n", x_src, y_src, x_dst, + y_dst, x_rel, y_rel); + + CompositePicture(op, src, picture, dst, + x_rel, y_rel, + 0, 0, + bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + + if (image) + pixman_image_unref(image); + + FreePicture(picture, 0); + return TRUE; } void @@ -1797,23 +1831,22 @@ glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps) { - DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap); + DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap); - _glamor_trapezoids(op, src, dst, mask_format, x_src, - y_src, ntrap, traps, TRUE); + _glamor_trapezoids(op, src, dst, mask_format, x_src, + y_src, ntrap, traps, TRUE); } Bool glamor_trapezoids_nf(CARD8 op, - PicturePtr src, PicturePtr dst, - PictFormatPtr mask_format, INT16 x_src, INT16 y_src, - int ntrap, xTrapezoid * traps) + PicturePtr src, PicturePtr dst, + PictFormatPtr mask_format, INT16 x_src, INT16 y_src, + int ntrap, xTrapezoid * traps) { - DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap); + DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap); - return _glamor_trapezoids(op, src, dst, mask_format, x_src, - y_src, ntrap, traps, FALSE); + return _glamor_trapezoids(op, src, dst, mask_format, x_src, + y_src, ntrap, traps, FALSE); } -#endif /* RENDER */ - +#endif /* RENDER */ diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c index e0f4a97..693eef1 100644 --- a/glamor/glamor_triangles.c +++ b/glamor/glamor_triangles.c @@ -30,51 +30,48 @@ static Bool _glamor_triangles(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris, Bool fallback) + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris, + Bool fallback) { - if (!fallback - && glamor_ddx_fallback_check_pixmap(pDst->pDrawable) - && (!pSrc->pDrawable - || glamor_ddx_fallback_check_pixmap(pSrc->pDrawable))) - return FALSE; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDst->pDrawable) + && (!pSrc->pDrawable + || glamor_ddx_fallback_check_pixmap(pSrc->pDrawable))) + return FALSE; - if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_picture(pSrc, - GLAMOR_ACCESS_RO)) { + if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) { - fbTriangles(op, pSrc, pDst, maskFormat, xSrc, - ySrc, ntris, tris); + fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris); - glamor_finish_access_picture(pSrc, GLAMOR_ACCESS_RO); - } + glamor_finish_access_picture(pSrc, GLAMOR_ACCESS_RO); + } - glamor_finish_access_picture(pDst, GLAMOR_ACCESS_RW); - } - return TRUE; + glamor_finish_access_picture(pDst, GLAMOR_ACCESS_RW); + } + return TRUE; } void glamor_triangles(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris) + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris) { - _glamor_triangles(op, pSrc, pDst, maskFormat, - xSrc, ySrc, ntris, tris, TRUE); + _glamor_triangles(op, pSrc, pDst, maskFormat, + xSrc, ySrc, ntris, tris, TRUE); } Bool glamor_triangles_nf(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris) + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris) { - return _glamor_triangles(op, pSrc, pDst, maskFormat, - xSrc, ySrc, ntris, tris, FALSE); + return _glamor_triangles(op, pSrc, pDst, maskFormat, + xSrc, ySrc, ntris, tris, FALSE); } - diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index d307838..b27c56c 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -254,7 +254,6 @@ } \ } while(0) - /* _x1_ ... _y2_ may has fractional. */ #define glamor_get_repeat_transform_coords(priv, repeat_type, tx1, \ ty1, _x1_, _y1_) \ @@ -402,8 +401,6 @@ 2); \ } while (0) - - #define glamor_set_normalize_tri_tcoords(xscale, \ yscale, \ vtx, \ @@ -475,7 +472,6 @@ } \ } while (0) - #define glamor_set_repeat_transformed_normalize_tcoords( priv, \ repeat_type, \ matrix, \ @@ -541,7 +537,6 @@ x2, y2, yInverted, vertices, stride);\ } while(0) - #define glamor_set_normalize_tcoords(priv, xscale, yscale, \ x1, y1, x2, y2, \ yInverted, vertices) \ @@ -577,7 +572,6 @@ stride); \ } while(0) - #define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ @@ -721,7 +715,6 @@ (vertices)[3 * stride + 1] = _t5_; \ } while(0) - #define glamor_set_normalize_vcoords(priv, xscale, yscale, \ x1, y1, x2, y2, \ yInverted, vertices) \ @@ -786,44 +779,46 @@ inline static void glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox) { - int x_min, y_min; - int x_max, y_max; - int i; - x_min = y_min = MAXSHORT; - x_max = y_max = MINSHORT; - for (i = 0; i < nbox; i++) { - if (x_min > boxes[i].x1) - x_min = boxes[i].x1; - if (y_min > boxes[i].y1) - y_min = boxes[i].y1; - - if (x_max < boxes[i].x2) - x_max = boxes[i].x2; - if (y_max < boxes[i].y2) - y_max = boxes[i].y2; - } - bound->x1 = x_min; - bound->y1 = y_min; - bound->x2 = x_max; - bound->y2 = y_max; + int x_min, y_min; + int x_max, y_max; + int i; + + x_min = y_min = MAXSHORT; + x_max = y_max = MINSHORT; + for (i = 0; i < nbox; i++) { + if (x_min > boxes[i].x1) + x_min = boxes[i].x1; + if (y_min > boxes[i].y1) + y_min = boxes[i].y1; + + if (x_max < boxes[i].x2) + x_max = boxes[i].x2; + if (y_max < boxes[i].y2) + y_max = boxes[i].y2; + } + bound->x1 = x_min; + bound->y1 = y_min; + bound->x2 = x_max; + bound->y2 = y_max; } inline static void glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy) { - int i; - for (i = 0; i < nbox; i++) { - boxes[i].x1 += dx; - boxes[i].y1 += dy; - boxes[i].x2 += dx; - boxes[i].y2 += dy; - } + int i; + + for (i = 0; i < nbox; i++) { + boxes[i].x1 += dx; + boxes[i].y1 += dy; + boxes[i].x2 += dx; + boxes[i].y2 += dy; + } } static inline Bool -region_is_empty(pixman_region16_t *region) +region_is_empty(pixman_region16_t * region) { - return region->data && region->data->numRects == 0; + return region->data && region->data->numRects == 0; } #ifndef ARRAY_SIZE @@ -857,58 +852,58 @@ region_is_empty(pixman_region16_t *region) static inline CARD32 format_for_depth(int depth) { - switch (depth) { - case 1: - return PICT_a1; - case 4: - return PICT_a4; - case 8: - return PICT_a8; - case 15: - return PICT_x1r5g5b5; - case 16: - return PICT_r5g6b5; - default: - case 24: - return PICT_x8r8g8b8; + switch (depth) { + case 1: + return PICT_a1; + case 4: + return PICT_a4; + case 8: + return PICT_a8; + case 15: + return PICT_x1r5g5b5; + case 16: + return PICT_r5g6b5; + default: + case 24: + return PICT_x8r8g8b8; #if XORG_VERSION_CURRENT >= 10699900 - case 30: - return PICT_x2r10g10b10; + case 30: + return PICT_x2r10g10b10; #endif - case 32: - return PICT_a8r8g8b8; - } + case 32: + return PICT_a8r8g8b8; + } } static inline void gl_iformat_for_depth(int depth, GLenum * format) { - switch (depth) { + switch (depth) { #ifndef GLAMOR_GLES2 - case 1: - case 8: - *format = GL_ALPHA; - break; + case 1: + case 8: + *format = GL_ALPHA; + break; #endif - default: - *format = GL_RGBA; - break; - } + default: + *format = GL_RGBA; + break; + } } static inline CARD32 format_for_pixmap(PixmapPtr pixmap) { - glamor_pixmap_private *pixmap_priv; - PictFormatShort pict_format; + glamor_pixmap_private *pixmap_priv; + PictFormatShort pict_format; - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) - pict_format = pixmap_priv->base.picture->format; - else - pict_format = format_for_depth(pixmap->drawable.depth); + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) + pict_format = pixmap_priv->base.picture->format; + else + pict_format = format_for_depth(pixmap->drawable.depth); - return pict_format; + return pict_format; } #define REVERT_NONE 0 @@ -939,114 +934,112 @@ format_for_pixmap(PixmapPtr pixmap) #ifndef GLAMOR_GLES2 static inline int glamor_get_tex_format_type_from_pictformat(PictFormatShort format, - GLenum * tex_format, - GLenum * tex_type, - int *no_alpha, - int *revert, - int *swap_rb, - int is_upload) - + GLenum * tex_format, + GLenum * tex_type, + int *no_alpha, + int *revert, + int *swap_rb, int is_upload) { - *no_alpha = 0; - *revert = REVERT_NONE; - *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; - switch (format) { - case PICT_a1: - *tex_format = GL_ALPHA; - *tex_type = GL_UNSIGNED_BYTE; - *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; - break; - case PICT_b8g8r8x8: - *no_alpha = 1; - case PICT_b8g8r8a8: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_INT_8_8_8_8; - break; - - case PICT_x8r8g8b8: - *no_alpha = 1; - case PICT_a8r8g8b8: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - case PICT_x8b8g8r8: - *no_alpha = 1; - case PICT_a8b8g8r8: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; - break; - case PICT_x2r10g10b10: - *no_alpha = 1; - case PICT_a2r10g10b10: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - case PICT_x2b10g10r10: - *no_alpha = 1; - case PICT_a2b10g10r10: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - - case PICT_r5g6b5: - *tex_format = GL_RGB; - *tex_type = GL_UNSIGNED_SHORT_5_6_5; - break; - case PICT_b5g6r5: - *tex_format = GL_RGB; - *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV; - break; - case PICT_x1b5g5r5: - *no_alpha = 1; - case PICT_a1b5g5r5: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - break; - - case PICT_x1r5g5b5: - *no_alpha = 1; - case PICT_a1r5g5b5: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - break; - case PICT_a8: - *tex_format = GL_ALPHA; - *tex_type = GL_UNSIGNED_BYTE; - break; - case PICT_x4r4g4b4: - *no_alpha = 1; - case PICT_a4r4g4b4: - *tex_format = GL_BGRA; - *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; - break; - - case PICT_x4b4g4r4: - *no_alpha = 1; - case PICT_a4b4g4r4: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; - break; - - default: - LogMessageVerb(X_INFO, 0, - "fail to get matched format for %x \n", - format); - return -1; - } - return 0; + *no_alpha = 0; + *revert = REVERT_NONE; + *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; + switch (format) { + case PICT_a1: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; + break; + case PICT_b8g8r8x8: + *no_alpha = 1; + case PICT_b8g8r8a8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8; + break; + + case PICT_x8r8g8b8: + *no_alpha = 1; + case PICT_a8r8g8b8: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case PICT_x8b8g8r8: + *no_alpha = 1; + case PICT_a8b8g8r8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case PICT_x2r10g10b10: + *no_alpha = 1; + case PICT_a2r10g10b10: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; + break; + case PICT_x2b10g10r10: + *no_alpha = 1; + case PICT_a2b10g10r10: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; + break; + + case PICT_r5g6b5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + break; + case PICT_b5g6r5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV; + break; + case PICT_x1b5g5r5: + *no_alpha = 1; + case PICT_a1b5g5r5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + + case PICT_x1r5g5b5: + *no_alpha = 1; + case PICT_a1r5g5b5: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case PICT_a8: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + break; + case PICT_x4r4g4b4: + *no_alpha = 1; + case PICT_a4r4g4b4: + *tex_format = GL_BGRA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + + case PICT_x4b4g4r4: + *no_alpha = 1; + case PICT_a4b4g4r4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + + default: + LogMessageVerb(X_INFO, 0, + "fail to get matched format for %x \n", format); + return -1; + } + return 0; } /* Currently, we use RGBA to represent all formats. */ -inline static int cache_format(GLenum format) +inline static int +cache_format(GLenum format) { - switch (format) { - case GL_ALPHA: - return 1; - case GL_RGBA: - return 0; - default: - return -1; - } + switch (format) { + case GL_ALPHA: + return 1; + case GL_RGBA: + return 0; + default: + return -1; + } } #else @@ -1054,779 +1047,819 @@ inline static int cache_format(GLenum format) static inline int glamor_get_tex_format_type_from_pictformat(PictFormatShort format, - GLenum * tex_format, - GLenum * tex_type, - int *no_alpha, - int *revert, - int *swap_rb, - int is_upload) + GLenum * tex_format, + GLenum * tex_type, + int *no_alpha, + int *revert, + int *swap_rb, int is_upload) { - int need_swap_rb = 0; - - *no_alpha = 0; - *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL; - - switch (format) { - case PICT_b8g8r8x8: - *no_alpha = 1; - case PICT_b8g8r8a8: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_BYTE; - need_swap_rb = 1; - *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; - break; - - case PICT_x8r8g8b8: - *no_alpha = 1; - case PICT_a8r8g8b8: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_BYTE; - need_swap_rb = 1; - break; - - case PICT_x8b8g8r8: - *no_alpha = 1; - case PICT_a8b8g8r8: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_BYTE; - break; - - case PICT_x2r10g10b10: - *no_alpha = 1; - case PICT_a2r10g10b10: - *tex_format = GL_RGBA; - /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2. - * we have to use GL_UNSIGNED_BYTE and do the conversion in - * shader latter.*/ - *tex_type = GL_UNSIGNED_BYTE; - if (is_upload == 1) { - if (!IS_LITTLE_ENDIAN) - *revert = REVERT_UPLOADING_10_10_10_2; - else - *revert = REVERT_UPLOADING_2_10_10_10; - } - else { - if (!IS_LITTLE_ENDIAN) { - *revert = REVERT_DOWNLOADING_10_10_10_2; - } - else { - *revert = REVERT_DOWNLOADING_2_10_10_10; - } - } - need_swap_rb = 1; - - break; - - case PICT_x2b10g10r10: - *no_alpha = 1; - case PICT_a2b10g10r10: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_BYTE; - if (is_upload == 1) { - if (!IS_LITTLE_ENDIAN) - *revert = REVERT_UPLOADING_10_10_10_2; - else - *revert = REVERT_UPLOADING_2_10_10_10; - } - else { - if (!IS_LITTLE_ENDIAN) { - *revert = REVERT_DOWNLOADING_10_10_10_2; - } - else { - *revert = REVERT_DOWNLOADING_2_10_10_10; - } - } - break; - - case PICT_r5g6b5: - *tex_format = GL_RGB; - *tex_type = GL_UNSIGNED_SHORT_5_6_5; - *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL; - - break; - - case PICT_b5g6r5: - *tex_format = GL_RGB; - *tex_type = GL_UNSIGNED_SHORT_5_6_5; - need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;; - break; - - case PICT_x1b5g5r5: - *no_alpha = 1; - case PICT_a1b5g5r5: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_5_5_5_1; - if (IS_LITTLE_ENDIAN) { - *revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5; - } else - *revert = REVERT_NONE; - break; - - case PICT_x1r5g5b5: - *no_alpha = 1; - case PICT_a1r5g5b5: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_5_5_5_1; - if (IS_LITTLE_ENDIAN) { - *revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5; - } else - *revert = REVERT_NONE; - need_swap_rb = 1; - break; - - case PICT_a1: - *tex_format = GL_ALPHA; - *tex_type = GL_UNSIGNED_BYTE; - *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; - break; - - case PICT_a8: - *tex_format = GL_ALPHA; - *tex_type = GL_UNSIGNED_BYTE; - *revert = REVERT_NONE; - break; - - case PICT_x4r4g4b4: - *no_alpha = 1; - case PICT_a4r4g4b4: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; - *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; - need_swap_rb = 1; - break; - - case PICT_x4b4g4r4: - *no_alpha = 1; - case PICT_a4b4g4r4: - *tex_format = GL_RGBA; - *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; - *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; - break; - - default: - LogMessageVerb(X_INFO, 0, - "fail to get matched format for %x \n", - format); - return -1; - } - - if (need_swap_rb) - *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING; - else - *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; - return 0; + int need_swap_rb = 0; + + *no_alpha = 0; + *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL; + + switch (format) { + case PICT_b8g8r8x8: + *no_alpha = 1; + case PICT_b8g8r8a8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + need_swap_rb = 1; + *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; + break; + + case PICT_x8r8g8b8: + *no_alpha = 1; + case PICT_a8r8g8b8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + need_swap_rb = 1; + break; + + case PICT_x8b8g8r8: + *no_alpha = 1; + case PICT_a8b8g8r8: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + break; + + case PICT_x2r10g10b10: + *no_alpha = 1; + case PICT_a2r10g10b10: + *tex_format = GL_RGBA; + /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2. + * we have to use GL_UNSIGNED_BYTE and do the conversion in + * shader latter.*/ + *tex_type = GL_UNSIGNED_BYTE; + if (is_upload == 1) { + if (!IS_LITTLE_ENDIAN) + *revert = REVERT_UPLOADING_10_10_10_2; + else + *revert = REVERT_UPLOADING_2_10_10_10; + } + else { + if (!IS_LITTLE_ENDIAN) { + *revert = REVERT_DOWNLOADING_10_10_10_2; + } + else { + *revert = REVERT_DOWNLOADING_2_10_10_10; + } + } + need_swap_rb = 1; + + break; + + case PICT_x2b10g10r10: + *no_alpha = 1; + case PICT_a2b10g10r10: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_BYTE; + if (is_upload == 1) { + if (!IS_LITTLE_ENDIAN) + *revert = REVERT_UPLOADING_10_10_10_2; + else + *revert = REVERT_UPLOADING_2_10_10_10; + } + else { + if (!IS_LITTLE_ENDIAN) { + *revert = REVERT_DOWNLOADING_10_10_10_2; + } + else { + *revert = REVERT_DOWNLOADING_2_10_10_10; + } + } + break; + + case PICT_r5g6b5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL; + + break; + + case PICT_b5g6r5: + *tex_format = GL_RGB; + *tex_type = GL_UNSIGNED_SHORT_5_6_5; + need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;; + break; + + case PICT_x1b5g5r5: + *no_alpha = 1; + case PICT_a1b5g5r5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_5_5_5_1; + if (IS_LITTLE_ENDIAN) { + *revert = + is_upload ? REVERT_UPLOADING_1_5_5_5 : + REVERT_DOWNLOADING_1_5_5_5; + } + else + *revert = REVERT_NONE; + break; + + case PICT_x1r5g5b5: + *no_alpha = 1; + case PICT_a1r5g5b5: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_5_5_5_1; + if (IS_LITTLE_ENDIAN) { + *revert = + is_upload ? REVERT_UPLOADING_1_5_5_5 : + REVERT_DOWNLOADING_1_5_5_5; + } + else + *revert = REVERT_NONE; + need_swap_rb = 1; + break; + + case PICT_a1: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; + break; + + case PICT_a8: + *tex_format = GL_ALPHA; + *tex_type = GL_UNSIGNED_BYTE; + *revert = REVERT_NONE; + break; + + case PICT_x4r4g4b4: + *no_alpha = 1; + case PICT_a4r4g4b4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; + *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; + need_swap_rb = 1; + break; + + case PICT_x4b4g4r4: + *no_alpha = 1; + case PICT_a4b4g4r4: + *tex_format = GL_RGBA; + *tex_type = GL_UNSIGNED_SHORT_4_4_4_4; + *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE; + break; + + default: + LogMessageVerb(X_INFO, 0, + "fail to get matched format for %x \n", format); + return -1; + } + + if (need_swap_rb) + *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING; + else + *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; + return 0; } -inline static int cache_format(GLenum format) +inline static int +cache_format(GLenum format) { - switch (format) { - case GL_ALPHA: - return 2; - case GL_RGB: - return 1; - case GL_RGBA: - return 0; - default: - return -1; - } + switch (format) { + case GL_ALPHA: + return 2; + case GL_RGB: + return 1; + case GL_RGBA: + return 0; + default: + return -1; + } } #endif - static inline int glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, - GLenum * format, - GLenum * type, - int *no_alpha, - int *revert, - int *swap_rb, - int is_upload) + GLenum * format, + GLenum * type, + int *no_alpha, + int *revert, int *swap_rb, int is_upload) { - glamor_pixmap_private *pixmap_priv; - PictFormatShort pict_format; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) - pict_format = pixmap_priv->base.picture->format; - else - pict_format = format_for_depth(pixmap->drawable.depth); - - return glamor_get_tex_format_type_from_pictformat(pict_format, - format, type, - no_alpha, - revert, - swap_rb, - is_upload); + glamor_pixmap_private *pixmap_priv; + PictFormatShort pict_format; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) + pict_format = pixmap_priv->base.picture->format; + else + pict_format = format_for_depth(pixmap->drawable.depth); + + return glamor_get_tex_format_type_from_pictformat(pict_format, + format, type, + no_alpha, + revert, + swap_rb, is_upload); } - /* borrowed from uxa */ static inline Bool glamor_get_rgba_from_pixel(CARD32 pixel, - float *red, - float *green, - float *blue, float *alpha, CARD32 format) + float *red, + float *green, + float *blue, float *alpha, CARD32 format) { - int rbits, bbits, gbits, abits; - int rshift, bshift, gshift, ashift; - - rbits = PICT_FORMAT_R(format); - gbits = PICT_FORMAT_G(format); - bbits = PICT_FORMAT_B(format); - abits = PICT_FORMAT_A(format); - - if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { - rshift = gshift = bshift = ashift = 0; - } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { - bshift = 0; - gshift = bbits; - rshift = gshift + gbits; - ashift = rshift + rbits; - } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { - rshift = 0; - gshift = rbits; - bshift = gshift + gbits; - ashift = bshift + bbits; + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { + rshift = gshift = bshift = ashift = 0; + } + else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } + else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; #if XORG_VERSION_CURRENT >= 10699900 - } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { - ashift = 0; - rshift = abits; - if (abits == 0) - rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + - bbits); - gshift = rshift + rbits; - bshift = gshift + gbits; + } + else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { + ashift = 0; + rshift = abits; + if (abits == 0) + rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + bbits); + gshift = rshift + rbits; + bshift = gshift + gbits; #endif - } else { - return FALSE; - } + } + else { + return FALSE; + } #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \ *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \ / (float)((1<<(_bits_)) - 1) - if (rbits) - COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits); - else - *red = 0; + if (rbits) + COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits); + else + *red = 0; - if (gbits) - COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits); - else - *green = 0; + if (gbits) + COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits); + else + *green = 0; - if (bbits) - COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits); - else - *blue = 0; + if (bbits) + COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits); + else + *blue = 0; - if (abits) - COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits); - else - *alpha = 1; + if (abits) + COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits); + else + *alpha = 1; - return TRUE; + return TRUE; } -inline static Bool glamor_pict_format_is_compatible(PictFormatShort pict_format, int depth) +inline static Bool +glamor_pict_format_is_compatible(PictFormatShort pict_format, int depth) { - GLenum iformat; - - gl_iformat_for_depth(depth, &iformat); - switch (iformat) { - case GL_RGBA: - return (pict_format == PICT_a8r8g8b8 || pict_format == PICT_x8r8g8b8); - case GL_ALPHA: - return (pict_format == PICT_a8); - default: - return FALSE; - } + GLenum iformat; + + gl_iformat_for_depth(depth, &iformat); + switch (iformat) { + case GL_RGBA: + return (pict_format == PICT_a8r8g8b8 || pict_format == PICT_x8r8g8b8); + case GL_ALPHA: + return (pict_format == PICT_a8); + default: + return FALSE; + } } /* return TRUE if we can access this pixmap at DDX driver. */ -inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable) +inline static Bool +glamor_ddx_fallback_check_pixmap(DrawablePtr drawable) { - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - return (!pixmap_priv - || (pixmap_priv->type == GLAMOR_TEXTURE_DRM - || pixmap_priv->type == GLAMOR_MEMORY - || pixmap_priv->type == GLAMOR_DRM_ONLY)); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + return (!pixmap_priv + || (pixmap_priv->type == GLAMOR_TEXTURE_DRM + || pixmap_priv->type == GLAMOR_MEMORY + || pixmap_priv->type == GLAMOR_DRM_ONLY)); } -inline static Bool glamor_ddx_fallback_check_gc(GCPtr gc) +inline static Bool +glamor_ddx_fallback_check_gc(GCPtr gc) { - PixmapPtr pixmap; - if (!gc) - return TRUE; - switch (gc->fillStyle) { - case FillStippled: - case FillOpaqueStippled: - pixmap = gc->stipple; - break; - case FillTiled: - pixmap = gc->tile.pixmap; - break; - default: - pixmap = NULL; - } - return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable)); + PixmapPtr pixmap; + + if (!gc) + return TRUE; + switch (gc->fillStyle) { + case FillStippled: + case FillOpaqueStippled: + pixmap = gc->stipple; + break; + case FillTiled: + pixmap = gc->tile.pixmap; + break; + default: + pixmap = NULL; + } + return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable)); } -inline static Bool glamor_is_large_pixmap(PixmapPtr pixmap) + +inline static Bool +glamor_is_large_pixmap(PixmapPtr pixmap) { - glamor_pixmap_private *priv; + glamor_pixmap_private *priv; - priv = glamor_get_pixmap_private(pixmap); - return (priv->type == GLAMOR_TEXTURE_LARGE); + priv = glamor_get_pixmap_private(pixmap); + return (priv->type == GLAMOR_TEXTURE_LARGE); } -inline static Bool glamor_is_large_picture(PicturePtr picture) +inline static Bool +glamor_is_large_picture(PicturePtr picture) { - PixmapPtr pixmap; + PixmapPtr pixmap; - if (picture->pDrawable) { - pixmap = glamor_get_drawable_pixmap(picture->pDrawable); - return glamor_is_large_pixmap(pixmap); - } - return FALSE; + if (picture->pDrawable) { + pixmap = glamor_get_drawable_pixmap(picture->pDrawable); + return glamor_is_large_pixmap(pixmap); + } + return FALSE; } -inline static Bool glamor_tex_format_is_readable(GLenum format) +inline static Bool +glamor_tex_format_is_readable(GLenum format) { - return ((format == GL_RGBA || format == GL_RGB || format == GL_ALPHA)); + return ((format == GL_RGBA || format == GL_RGB || format == GL_ALPHA)); } -static inline void _glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h) +static inline void +_glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h) { - int i,j; - unsigned char * p = pixmap->devPrivate.ptr; - int stride = pixmap->devKind; - - p = p + y * stride + x; - - for (i = 0; i < h; i++) - { - ErrorF("line %3d: ", i); - for(j = 0; j < w; j++) - ErrorF("%2d ", (p[j/8] & (1 << (j%8)))>>(j%8)); - p += stride; - ErrorF("\n"); - } + int i, j; + unsigned char *p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) { + ErrorF("line %3d: ", i); + for (j = 0; j < w; j++) + ErrorF("%2d ", (p[j / 8] & (1 << (j % 8))) >> (j % 8)); + p += stride; + ErrorF("\n"); + } } -static inline void _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h) +static inline void +_glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h) { - int i,j; - unsigned char * p = pixmap->devPrivate.ptr; - int stride = pixmap->devKind; - - p = p + y * stride + x; - - for (i = 0; i < h; i++) - { - ErrorF("line %3d: ", i); - for(j = 0; j < w; j++) - ErrorF("%2x ", p[j]); - p += stride; - ErrorF("\n"); - } + int i, j; + unsigned char *p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) { + ErrorF("line %3d: ", i); + for (j = 0; j < w; j++) + ErrorF("%2x ", p[j]); + p += stride; + ErrorF("\n"); + } } -static inline void _glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h) +static inline void +_glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h) { - int i,j; - unsigned short * p = pixmap->devPrivate.ptr; - int stride = pixmap->devKind / 2; - - p = p + y * stride + x; - - for (i = 0; i < h; i++) - { - ErrorF("line %3d: ", i); - for(j = 0; j < w; j++) - ErrorF("%2x ", p[j]); - p += stride; - ErrorF("\n"); - } + int i, j; + unsigned short *p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind / 2; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) { + ErrorF("line %3d: ", i); + for (j = 0; j < w; j++) + ErrorF("%2x ", p[j]); + p += stride; + ErrorF("\n"); + } } -static inline void _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h) +static inline void +_glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h) { - int i,j; - unsigned int * p = pixmap->devPrivate.ptr; - int stride = pixmap->devKind / 4; - - p = p + y * stride + x; - - for (i = 0; i < h; i++) - { - ErrorF("line %3d: ", i); - for(j = 0; j < w; j++) - ErrorF("%2x ", p[j]); - p += stride; - ErrorF("\n"); - } + int i, j; + unsigned int *p = pixmap->devPrivate.ptr; + int stride = pixmap->devKind / 4; + + p = p + y * stride + x; + + for (i = 0; i < h; i++) { + ErrorF("line %3d: ", i); + for (j = 0; j < w; j++) + ErrorF("%2x ", p[j]); + p += stride; + ErrorF("\n"); + } } -static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h) +static inline void +glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h) { - w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w; - h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h; - - glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO); - switch (pixmap->drawable.depth) { - case 8: - _glamor_dump_pixmap_byte(pixmap, x, y, w, h); - break; - case 15: - case 16: - _glamor_dump_pixmap_sword(pixmap, x, y, w, h); - break; - - case 24: - case 32: - _glamor_dump_pixmap_word(pixmap, x, y, w, h); - break; - case 1: - _glamor_dump_pixmap_bits(pixmap, x, y, w, h); - break; - default: - ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth); - } - glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); + w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w; + h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h; + + glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO); + switch (pixmap->drawable.depth) { + case 8: + _glamor_dump_pixmap_byte(pixmap, x, y, w, h); + break; + case 15: + case 16: + _glamor_dump_pixmap_sword(pixmap, x, y, w, h); + break; + + case 24: + case 32: + _glamor_dump_pixmap_word(pixmap, x, y, w, h); + break; + case 1: + _glamor_dump_pixmap_bits(pixmap, x, y, w, h); + break; + default: + ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth); + } + glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); } -static inline void _glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, - int x, int y, int w, int h, - PictFormatShort short_format, - int all, int diffs) +static inline void +_glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, + int x, int y, int w, int h, + PictFormatShort short_format, int all, int diffs) { - int i, j; - unsigned char * p1 = pixmap1->devPrivate.ptr; - unsigned char * p2 = pixmap2->devPrivate.ptr; - int line_need_printed = 0; - int test_code = 0xAABBCCDD; - int little_endian = 0; - unsigned char *p_test; - int bpp = pixmap1->drawable.depth == 8 ? 1 : 4; - int stride = pixmap1->devKind; - - assert(pixmap1->devKind == pixmap2->devKind); - - ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h); - - p1 = p1 + y * stride + x; - p2 = p2 + y * stride + x; - - if (all) { - for (i = 0; i < h; i++) { - ErrorF("line %3d: ", i); - - for (j = 0; j < stride; j++) { - if (j % bpp == 0) - ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); - else - ErrorF("%2x:%2x ", p1[j], p2[j]); - } - - p1 += stride; - p2 += stride; - ErrorF("\n"); - } - } else { - if (short_format == PICT_a8r8g8b8) { - p_test = (unsigned char *) & test_code; - little_endian = (*p_test == 0xDD); - bpp = 4; - - for (i = 0; i < h; i++) { - line_need_printed = 0; - - for (j = 0; j < stride; j++) { - if (p1[j] != p2[j] && (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) { - if (line_need_printed) { - if (little_endian) { - switch (j % 4) { - case 2: - ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - case 1: - ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - case 0: - ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - case 3: - ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - } - } else { - switch (j % 4) { - case 1: - ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - case 2: - ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - case 3: - ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - case 0: - ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]); - break; - } - } - } else { - line_need_printed = 1; - j = -1; - ErrorF("line %3d: ", i); - continue; - } - } - } - - p1 += stride; - p2 += stride; - ErrorF("\n"); - } - } //more format can be added here. - else { // the default format, just print. - for (i = 0; i < h; i++) { - line_need_printed = 0; - - for (j = 0; j < stride; j++) { - if (p1[j] != p2[j]) { - if (line_need_printed) { - ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); - } else { - line_need_printed = 1; - j = -1; - ErrorF("line %3d: ", i); - continue; - } - } - } - - p1 += stride; - p2 += stride; - ErrorF("\n"); - } - } - } + int i, j; + unsigned char *p1 = pixmap1->devPrivate.ptr; + unsigned char *p2 = pixmap2->devPrivate.ptr; + int line_need_printed = 0; + int test_code = 0xAABBCCDD; + int little_endian = 0; + unsigned char *p_test; + int bpp = pixmap1->drawable.depth == 8 ? 1 : 4; + int stride = pixmap1->devKind; + + assert(pixmap1->devKind == pixmap2->devKind); + + ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h); + + p1 = p1 + y * stride + x; + p2 = p2 + y * stride + x; + + if (all) { + for (i = 0; i < h; i++) { + ErrorF("line %3d: ", i); + + for (j = 0; j < stride; j++) { + if (j % bpp == 0) + ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); + else + ErrorF("%2x:%2x ", p1[j], p2[j]); + } + + p1 += stride; + p2 += stride; + ErrorF("\n"); + } + } + else { + if (short_format == PICT_a8r8g8b8) { + p_test = (unsigned char *) &test_code; + little_endian = (*p_test == 0xDD); + bpp = 4; + + for (i = 0; i < h; i++) { + line_need_printed = 0; + + for (j = 0; j < stride; j++) { + if (p1[j] != p2[j] && + (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) { + if (line_need_printed) { + if (little_endian) { + switch (j % 4) { + case 2: + ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + case 1: + ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + case 0: + ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + case 3: + ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + } + } + else { + switch (j % 4) { + case 1: + ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + case 2: + ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + case 3: + ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + case 0: + ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], + p2[j]); + break; + } + } + } + else { + line_need_printed = 1; + j = -1; + ErrorF("line %3d: ", i); + continue; + } + } + } + + p1 += stride; + p2 += stride; + ErrorF("\n"); + } + } //more format can be added here. + else { // the default format, just print. + for (i = 0; i < h; i++) { + line_need_printed = 0; + + for (j = 0; j < stride; j++) { + if (p1[j] != p2[j]) { + if (line_need_printed) { + ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); + } + else { + line_need_printed = 1; + j = -1; + ErrorF("line %3d: ", i); + continue; + } + } + } + + p1 += stride; + p2 += stride; + ErrorF("\n"); + } + } + } } -static inline void glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, - int x, int y, int w, int h, int all, int diffs) +static inline void +glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, + int x, int y, int w, int h, int all, int diffs) { - assert(pixmap1->drawable.depth == pixmap2->drawable.depth); + assert(pixmap1->drawable.depth == pixmap2->drawable.depth); - glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); - glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); + glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); + glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); - _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs); + _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs); - glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); - glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); } /* This function is used to compare two pictures. If the picture has no drawable, we use fb functions to generate it. */ -static inline void glamor_compare_pictures( ScreenPtr screen, - PicturePtr fst_picture, - PicturePtr snd_picture, - int x_source, int y_source, - int width, int height, - int all, int diffs) +static inline void +glamor_compare_pictures(ScreenPtr screen, + PicturePtr fst_picture, + PicturePtr snd_picture, + int x_source, int y_source, + int width, int height, int all, int diffs) { - PixmapPtr fst_pixmap; - PixmapPtr snd_pixmap; - int fst_generated, snd_generated; - int error; - int fst_type = -1; - int snd_type = -1; // -1 represent has drawable. - - if (fst_picture->format != snd_picture->format) { - ErrorF("Different picture format can not compare!\n"); - return; - } - - if (!fst_picture->pDrawable) { - fst_type = fst_picture->pSourcePict->type; - } - - if (!snd_picture->pDrawable) { - snd_type = snd_picture->pSourcePict->type; - } - - if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) { - ErrorF("Different picture type will never be same!\n"); - return; - } - - fst_generated = snd_generated = 0; - - if (!fst_picture->pDrawable) { - PicturePtr pixman_pic; - PixmapPtr pixmap = NULL; - PictFormatShort format; - - format = fst_picture->format; - - pixmap = glamor_create_pixmap(screen, - width, height, - PIXMAN_FORMAT_DEPTH(format), - GLAMOR_CREATE_PIXMAP_CPU); - - pixman_pic = CreatePicture(0, - &pixmap->drawable, - PictureMatchFormat(screen, - PIXMAN_FORMAT_DEPTH(format), format), - 0, 0, serverClient, &error); - - fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic, - x_source, y_source, - 0, 0, - 0, 0, - width, height); - - glamor_destroy_pixmap(pixmap); - - fst_picture = pixman_pic; - fst_generated = 1; - } - - if (!snd_picture->pDrawable) { - PicturePtr pixman_pic; - PixmapPtr pixmap = NULL; - PictFormatShort format; - - format = snd_picture->format; - - pixmap = glamor_create_pixmap(screen, - width, height, - PIXMAN_FORMAT_DEPTH(format), - GLAMOR_CREATE_PIXMAP_CPU); - - pixman_pic = CreatePicture(0, - &pixmap->drawable, - PictureMatchFormat(screen, - PIXMAN_FORMAT_DEPTH(format), format), - 0, 0, serverClient, &error); - - fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic, - x_source, y_source, - 0, 0, - 0, 0, - width, height); - - glamor_destroy_pixmap(pixmap); - - snd_picture = pixman_pic; - snd_generated = 1; - } - - fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable); - snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable); - - if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) { - if (fst_generated) - glamor_destroy_picture(fst_picture); - if (snd_generated) - glamor_destroy_picture(snd_picture); - - ErrorF("Different pixmap depth can not compare!\n"); - return; - } - - glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); - glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); - - if ((fst_type == SourcePictTypeLinear) || - (fst_type == SourcePictTypeRadial) || - (fst_type == SourcePictTypeConical) || - (snd_type == SourcePictTypeLinear) || - (snd_type == SourcePictTypeRadial) || - (snd_type == SourcePictTypeConical)) { - x_source = y_source = 0; - } - - _glamor_compare_pixmaps(fst_pixmap, snd_pixmap, - x_source, y_source, - width, height, - fst_picture->format, all, diffs); - - glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); - glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); - - if (fst_generated) - glamor_destroy_picture(fst_picture); - if (snd_generated) - glamor_destroy_picture(snd_picture); - - return; + PixmapPtr fst_pixmap; + PixmapPtr snd_pixmap; + int fst_generated, snd_generated; + int error; + int fst_type = -1; + int snd_type = -1; // -1 represent has drawable. + + if (fst_picture->format != snd_picture->format) { + ErrorF("Different picture format can not compare!\n"); + return; + } + + if (!fst_picture->pDrawable) { + fst_type = fst_picture->pSourcePict->type; + } + + if (!snd_picture->pDrawable) { + snd_type = snd_picture->pSourcePict->type; + } + + if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) { + ErrorF("Different picture type will never be same!\n"); + return; + } + + fst_generated = snd_generated = 0; + + if (!fst_picture->pDrawable) { + PicturePtr pixman_pic; + PixmapPtr pixmap = NULL; + PictFormatShort format; + + format = fst_picture->format; + + pixmap = glamor_create_pixmap(screen, + width, height, + PIXMAN_FORMAT_DEPTH(format), + GLAMOR_CREATE_PIXMAP_CPU); + + pixman_pic = CreatePicture(0, + &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH + (format), format), 0, 0, + serverClient, &error); + + fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic, + x_source, y_source, 0, 0, 0, 0, width, height); + + glamor_destroy_pixmap(pixmap); + + fst_picture = pixman_pic; + fst_generated = 1; + } + + if (!snd_picture->pDrawable) { + PicturePtr pixman_pic; + PixmapPtr pixmap = NULL; + PictFormatShort format; + + format = snd_picture->format; + + pixmap = glamor_create_pixmap(screen, + width, height, + PIXMAN_FORMAT_DEPTH(format), + GLAMOR_CREATE_PIXMAP_CPU); + + pixman_pic = CreatePicture(0, + &pixmap->drawable, + PictureMatchFormat(screen, + PIXMAN_FORMAT_DEPTH + (format), format), 0, 0, + serverClient, &error); + + fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic, + x_source, y_source, 0, 0, 0, 0, width, height); + + glamor_destroy_pixmap(pixmap); + + snd_picture = pixman_pic; + snd_generated = 1; + } + + fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable); + snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable); + + if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) { + if (fst_generated) + glamor_destroy_picture(fst_picture); + if (snd_generated) + glamor_destroy_picture(snd_picture); + + ErrorF("Different pixmap depth can not compare!\n"); + return; + } + + glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); + glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); + + if ((fst_type == SourcePictTypeLinear) || + (fst_type == SourcePictTypeRadial) || + (fst_type == SourcePictTypeConical) || + (snd_type == SourcePictTypeLinear) || + (snd_type == SourcePictTypeRadial) || + (snd_type == SourcePictTypeConical)) { + x_source = y_source = 0; + } + + _glamor_compare_pixmaps(fst_pixmap, snd_pixmap, + x_source, y_source, + width, height, fst_picture->format, all, diffs); + + glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); + + if (fst_generated) + glamor_destroy_picture(fst_picture); + if (snd_generated) + glamor_destroy_picture(snd_picture); + + return; } #ifdef __i386__ -static inline unsigned long __fls(unsigned long x) +static inline unsigned long +__fls(unsigned long x) { - asm("bsr %1,%0" - : "=r" (x) - : "rm" (x)); - return x; + asm("bsr %1,%0":"=r"(x) + : "rm"(x)); + return x; } #else -static inline unsigned long __fls(unsigned long x) +static inline unsigned long +__fls(unsigned long x) { - int n; - - if (x == 0) return(0); - n = 0; - if (x <= 0x0000FFFF) {n = n +16; x = x <<16;} - if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;} - if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;} - if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;} - if (x <= 0x7FFFFFFF) {n = n + 1;} - return 31 - n; + int n; + + if (x == 0) + return (0); + n = 0; + if (x <= 0x0000FFFF) { + n = n + 16; + x = x << 16; + } + if (x <= 0x00FFFFFF) { + n = n + 8; + x = x << 8; + } + if (x <= 0x0FFFFFFF) { + n = n + 4; + x = x << 4; + } + if (x <= 0x3FFFFFFF) { + n = n + 2; + x = x << 2; + } + if (x <= 0x7FFFFFFF) { + n = n + 1; + } + return 31 - n; } #endif -static inline void glamor_make_current(ScreenPtr screen) +static inline void +glamor_make_current(ScreenPtr screen) { - glamor_egl_make_current(screen); + glamor_egl_make_current(screen); } -static inline void glamor_restore_current(ScreenPtr screen) +static inline void +glamor_restore_current(ScreenPtr screen) { - glamor_egl_restore_context(screen); + glamor_egl_restore_context(screen); } #ifdef GLX_USE_SHARED_DISPATCH static inline glamor_gl_dispatch * -glamor_get_dispatch(glamor_screen_private *glamor_priv) +glamor_get_dispatch(glamor_screen_private * glamor_priv) { - if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) - glamor_make_current(glamor_priv->screen); + if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) + glamor_make_current(glamor_priv->screen); - return &glamor_priv->_dispatch; + return &glamor_priv->_dispatch; } static inline void -glamor_put_dispatch(glamor_screen_private *glamor_priv) +glamor_put_dispatch(glamor_screen_private * glamor_priv) { - if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) - glamor_restore_current(glamor_priv->screen); + if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) + glamor_restore_current(glamor_priv->screen); } #else #warning "Indirect GLX may be broken, need to implement context switch." static inline glamor_gl_dispatch * -glamor_get_dispatch(glamor_screen_private *glamor_priv) +glamor_get_dispatch(glamor_screen_private * glamor_priv) { - return &glamor_priv->_dispatch; + return &glamor_priv->_dispatch; } static inline void -glamor_put_dispatch(glamor_screen_private *glamor_priv) +glamor_put_dispatch(glamor_screen_private * glamor_priv) { } diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c index b67c728..60647bf 100644 --- a/glamor/glamor_window.c +++ b/glamor/glamor_window.c @@ -28,76 +28,72 @@ * Screen Change Window Attribute implementation. */ - static void -glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr * ppPixmap) +glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap) { - PixmapPtr pPixmap = *ppPixmap; - glamor_pixmap_private *pixmap_priv; + PixmapPtr pPixmap = *ppPixmap; + glamor_pixmap_private *pixmap_priv; - if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { - pixmap_priv = glamor_get_pixmap_private(pPixmap); - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { - glamor_fallback("pixmap %p has no fbo\n", pPixmap); - goto fail; - } - glamor_debug_output(GLAMOR_DEBUG_UNIMPL, - "To be implemented.\n"); - } - return; + if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { + pixmap_priv = glamor_get_pixmap_private(pPixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { + glamor_fallback("pixmap %p has no fbo\n", pPixmap); + goto fail; + } + glamor_debug_output(GLAMOR_DEBUG_UNIMPL, "To be implemented.\n"); + } + return; - fail: - GLAMOR_PANIC - (" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile" - " is broken for glamor. \n"); + fail: + GLAMOR_PANIC + (" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile" + " is broken for glamor. \n"); } Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask) { - if (mask & CWBackPixmap) { - if (pWin->backgroundState == BackgroundPixmap) - glamor_fixup_window_pixmap(&pWin->drawable, - &pWin-> - background.pixmap); - } + if (mask & CWBackPixmap) { + if (pWin->backgroundState == BackgroundPixmap) + glamor_fixup_window_pixmap(&pWin->drawable, + &pWin->background.pixmap); + } - if (mask & CWBorderPixmap) { - if (pWin->borderIsPixel == FALSE) - glamor_fixup_window_pixmap(&pWin->drawable, - &pWin->border.pixmap); - } - return TRUE; + if (mask & CWBorderPixmap) { + if (pWin->borderIsPixel == FALSE) + glamor_fixup_window_pixmap(&pWin->drawable, &pWin->border.pixmap); + } + return TRUE; } void glamor_set_window_pixmap(WindowPtr win, PixmapPtr pPixmap) { - ScreenPtr screen = win->drawable.pScreen; - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - PixmapPtr old = screen->GetWindowPixmap(win); + ScreenPtr screen = win->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr old = screen->GetWindowPixmap(win); - if (pPixmap != old) { - glamor_pixmap_private *pixmap_priv; - PicturePtr pic = NULL; + if (pPixmap != old) { + glamor_pixmap_private *pixmap_priv; + PicturePtr pic = NULL; - pixmap_priv = glamor_get_pixmap_private(old); - if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) && pixmap_priv->base.picture->pDrawable == (DrawablePtr)win) { - pic = pixmap_priv->base.picture; - pixmap_priv->base.is_picture = 0; - pixmap_priv->base.picture = NULL; - } + pixmap_priv = glamor_get_pixmap_private(old); + if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) && + pixmap_priv->base.picture->pDrawable == (DrawablePtr) win) { + pic = pixmap_priv->base.picture; + pixmap_priv->base.is_picture = 0; + pixmap_priv->base.picture = NULL; + } - pixmap_priv = glamor_get_pixmap_private(pPixmap); - if (pixmap_priv) { - pixmap_priv->base.is_picture = !!pic; - pixmap_priv->base.picture = pic; - } - } + pixmap_priv = glamor_get_pixmap_private(pPixmap); + if (pixmap_priv) { + pixmap_priv->base.is_picture = ! !pic; + pixmap_priv->base.picture = pic; + } + } - screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap; - (screen->SetWindowPixmap)(win, pPixmap); - glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap; - screen->SetWindowPixmap = glamor_set_window_pixmap; + screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap; + (screen->SetWindowPixmap) (win, pPixmap); + glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap; + screen->SetWindowPixmap = glamor_set_window_pixmap; } diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index a89b4cd..237a272 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -39,15 +39,14 @@ #include #include "fourcc.h" /* Reference color space transform data */ -typedef struct tagREF_TRANSFORM -{ - float RefLuma; - float RefRCb; - float RefRCr; - float RefGCb; - float RefGCr; - float RefBCb; - float RefBCr; +typedef struct tagREF_TRANSFORM { + float RefLuma; + float RefRCb; + float RefRCr; + float RefGCb; + float RefGCr; + float RefBCb; + float RefBCr; } REF_TRANSFORM; #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0) @@ -56,590 +55,575 @@ typedef struct tagREF_TRANSFORM #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) #define RTFHue(a) (((a)*3.1416)/1000.0) -static const char *xv_vs= "attribute vec4 v_position;\n" - "attribute vec4 v_texcoord0;\n" - "varying vec2 tcs;\n" - "void main()\n" "{\n" " gl_Position = v_position;\n" - "tcs = v_texcoord0.xy;\n" - "}\n"; +static const char *xv_vs = "attribute vec4 v_position;\n" + "attribute vec4 v_texcoord0;\n" + "varying vec2 tcs;\n" + "void main()\n" "{\n" " gl_Position = v_position;\n" + "tcs = v_texcoord0.xy;\n" "}\n"; static const char *xv_ps = GLAMOR_DEFAULT_PRECISION - "uniform sampler2D y_sampler;\n" - "uniform sampler2D u_sampler;\n" - "uniform sampler2D v_sampler;\n" - "uniform vec4 offsetyco;\n" - "uniform vec4 ucogamma;\n" - "uniform vec4 vco;\n" - "varying vec2 tcs;\n" - "float sample;\n" - "vec4 temp1;\n" - "void main()\n" "{\n" - "sample = texture2D(y_sampler, tcs).w;\n" - "temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n" - "sample = texture2D(u_sampler, tcs).w;\n" - "temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n" - "sample = texture2D(v_sampler, tcs).w;\n" - "temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n" - "temp1.w = 1.0;\n" - "gl_FragColor = temp1;\n" - "}\n"; + "uniform sampler2D y_sampler;\n" + "uniform sampler2D u_sampler;\n" + "uniform sampler2D v_sampler;\n" + "uniform vec4 offsetyco;\n" + "uniform vec4 ucogamma;\n" + "uniform vec4 vco;\n" + "varying vec2 tcs;\n" + "float sample;\n" + "vec4 temp1;\n" + "void main()\n" "{\n" + "sample = texture2D(y_sampler, tcs).w;\n" + "temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n" + "sample = texture2D(u_sampler, tcs).w;\n" + "temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n" + "sample = texture2D(v_sampler, tcs).w;\n" + "temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n" + "temp1.w = 1.0;\n" "gl_FragColor = temp1;\n" "}\n"; void glamor_init_xv_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; - GLint fs_prog, vs_prog; - - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); - glamor_priv->xv_prog = dispatch->glCreateProgram(); - - vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, xv_vs); - fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, xv_ps); - dispatch->glAttachShader(glamor_priv->xv_prog, vs_prog); - dispatch->glAttachShader(glamor_priv->xv_prog, fs_prog); - - dispatch->glBindAttribLocation(glamor_priv->xv_prog, - GLAMOR_VERTEX_POS, "v_position"); - dispatch->glBindAttribLocation(glamor_priv->xv_prog, - GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(dispatch, glamor_priv->xv_prog); - - glamor_put_dispatch(glamor_priv); + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + GLint fs_prog, vs_prog; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); + glamor_priv->xv_prog = dispatch->glCreateProgram(); + + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, xv_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, xv_ps); + dispatch->glAttachShader(glamor_priv->xv_prog, vs_prog); + dispatch->glAttachShader(glamor_priv->xv_prog, fs_prog); + + dispatch->glBindAttribLocation(glamor_priv->xv_prog, + GLAMOR_VERTEX_POS, "v_position"); + dispatch->glBindAttribLocation(glamor_priv->xv_prog, + GLAMOR_VERTEX_SOURCE, "v_texcoord0"); + glamor_link_glsl_prog(dispatch, glamor_priv->xv_prog); + + glamor_put_dispatch(glamor_priv); } void glamor_fini_xv_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv; - glamor_gl_dispatch *dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; - glamor_priv = glamor_get_screen_private(screen); - dispatch = glamor_get_dispatch(glamor_priv); + glamor_priv = glamor_get_screen_private(screen); + dispatch = glamor_get_dispatch(glamor_priv); - dispatch->glDeleteProgram(glamor_priv->xv_prog); - glamor_put_dispatch(glamor_priv); + dispatch->glDeleteProgram(glamor_priv->xv_prog); + glamor_put_dispatch(glamor_priv); } #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; +static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace, + xvGamma; #define NUM_ATTRIBUTES 5 -static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES+1] = -{ +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] = -{ +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 XF86ImageRec Images[NUM_IMAGES] = { + XVIMAGE_YV12, + XVIMAGE_I420, +}; static void glamor_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup) { -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]); -port_priv->src_pix[i] = NULL; -} -} + 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]); + port_priv->src_pix[i] = NULL; + } + } } static int -glamor_xv_set_port_attribute(ScrnInfoPtr pScrn, - Atom attribute, - INT32 value, - pointer data) +glamor_xv_set_port_attribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 value, pointer data) { -glamor_port_private *port_priv = (glamor_port_private *)data; -if (attribute == xvBrightness) - port_priv->brightness = ClipValue(value, -1000, 1000); -else if (attribute == xvHue) - port_priv->hue = ClipValue(value, -1000, 1000); -else if (attribute == xvContrast) - port_priv->contrast = ClipValue(value, -1000, 1000); -else if (attribute == xvSaturation) - port_priv->saturation = ClipValue(value, -1000, 1000); -else if (attribute == xvGamma) - port_priv->gamma = ClipValue (value, 100, 10000); -else if(attribute == xvColorspace) - port_priv->transform_index = ClipValue (value, 0, 1); -else - return BadMatch; -return Success; + glamor_port_private *port_priv = (glamor_port_private *) data; + + if (attribute == xvBrightness) + port_priv->brightness = ClipValue(value, -1000, 1000); + else if (attribute == xvHue) + port_priv->hue = ClipValue(value, -1000, 1000); + else if (attribute == xvContrast) + port_priv->contrast = ClipValue(value, -1000, 1000); + else if (attribute == xvSaturation) + port_priv->saturation = ClipValue(value, -1000, 1000); + else if (attribute == xvGamma) + port_priv->gamma = ClipValue(value, 100, 10000); + else if (attribute == xvColorspace) + 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, - pointer data) +glamor_xv_get_port_attribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 *value, pointer data) { -glamor_port_private *port_priv = (glamor_port_private *)data; -if (attribute == xvBrightness) - *value = port_priv->brightness; -else if (attribute == xvHue) - *value = port_priv->hue; -else if (attribute == xvContrast) - *value = port_priv->contrast; -else if (attribute == xvSaturation) - *value = port_priv->saturation; -else if (attribute == xvGamma) - *value = port_priv->gamma; -else if(attribute == xvColorspace) - *value = port_priv->transform_index; -else - return BadMatch; - -return Success; + glamor_port_private *port_priv = (glamor_port_private *) data; + + if (attribute == xvBrightness) + *value = port_priv->brightness; + else if (attribute == xvHue) + *value = port_priv->hue; + else if (attribute == xvContrast) + *value = port_priv->contrast; + else if (attribute == xvSaturation) + *value = port_priv->saturation; + else if (attribute == xvGamma) + *value = port_priv->gamma; + else if (attribute == xvColorspace) + *value = port_priv->transform_index; + else + return BadMatch; + + 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, - pointer data) + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, pointer data) { -*p_w = drw_w; -*p_h = drw_h; + *p_w = drw_w; + *p_h = drw_h; } static int glamor_xv_query_image_attributes(ScrnInfoPtr pScrn, - int id, - unsigned short *w, unsigned short *h, - int *pitches, int *offsets) + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) { -int size = 0, tmp; - -if (offsets) offsets[0] = 0; -switch (id) { -case FOURCC_YV12: -case FOURCC_I420: -*h = *h; -*w = *w; -size = *w; -if (pitches) pitches[0] = size; -size *= *h; -if (offsets) offsets[1] = size; -tmp = *w >> 1; -if (pitches) pitches[1] = pitches[2] = tmp; -tmp *= (*h >> 1); -size += tmp; -if (offsets) offsets[2] = size; -size += tmp; -break; -} -return size; + int size = 0, tmp; + + if (offsets) + offsets[0] = 0; + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + *h = *h; + *w = *w; + size = *w; + if (pitches) + pitches[0] = size; + size *= *h; + if (offsets) + offsets[1] = size; + tmp = *w >> 1; + if (pitches) + pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if (offsets) + offsets[2] = size; + size += tmp; + break; + } + return size; } + /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces note the difference to the parameters used in overlay are due to 10bit vs. float calcs */ -static REF_TRANSFORM trans[2] = -{ - {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */ - {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */ - }; +static REF_TRANSFORM trans[2] = { + {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */ + {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) +glamor_display_textured_video(glamor_port_private * port_priv) { -ScreenPtr screen = port_priv->pPixmap->drawable.pScreen; -glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); -glamor_pixmap_private *pixmap_priv = - glamor_get_pixmap_private(port_priv->pPixmap); -glamor_pixmap_private *src_pixmap_priv[3]; -glamor_gl_dispatch *dispatch; -float vertices[32], texcoords[8]; -BoxPtr box = REGION_RECTS(&port_priv->clip); -int nBox = REGION_NUM_RECTS(&port_priv->clip); -int dst_x_off, dst_y_off; -GLfloat dst_xscale, dst_yscale; -GLfloat src_xscale[3], src_yscale[3]; -int i; -const float Loff = -0.0627; -const float Coff = -0.502; -float uvcosf, uvsinf; -float yco; -float uco[3], vco[3], off[3]; -float bright, cont, gamma; -int ref = port_priv->transform_index; -GLint uloc, sampler_loc; - -cont = RTFContrast(port_priv->contrast); -bright = RTFBrightness(port_priv->brightness); -gamma = (float)port_priv->gamma / 1000.0; -uvcosf = RTFSaturation(port_priv->saturation) * cos(RTFHue(port_priv->hue)); -uvsinf = RTFSaturation(port_priv->saturation) * sin(RTFHue(port_priv->hue)); + ScreenPtr screen = port_priv->pPixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *pixmap_priv = + glamor_get_pixmap_private(port_priv->pPixmap); + glamor_pixmap_private *src_pixmap_priv[3]; + glamor_gl_dispatch *dispatch; + float vertices[32], texcoords[8]; + BoxPtr box = REGION_RECTS(&port_priv->clip); + int nBox = REGION_NUM_RECTS(&port_priv->clip); + int dst_x_off, dst_y_off; + GLfloat dst_xscale, dst_yscale; + GLfloat src_xscale[3], src_yscale[3]; + int i; + const float Loff = -0.0627; + const float Coff = -0.502; + float uvcosf, uvsinf; + float yco; + float uco[3], vco[3], off[3]; + float bright, cont, gamma; + int ref = port_priv->transform_index; + GLint uloc, sampler_loc; + + cont = RTFContrast(port_priv->contrast); + bright = RTFBrightness(port_priv->brightness); + gamma = (float) port_priv->gamma / 1000.0; + uvcosf = RTFSaturation(port_priv->saturation) * cos(RTFHue(port_priv->hue)); + uvsinf = RTFSaturation(port_priv->saturation) * sin(RTFHue(port_priv->hue)); /* overlay video also does pre-gamma contrast/sat adjust, should we? */ -yco = trans[ref].RefLuma * cont; -uco[0] = -trans[ref].RefRCr * uvsinf; -uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf; -uco[2] = trans[ref].RefBCb * uvcosf; -vco[0] = trans[ref].RefRCr * uvcosf; -vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf; -vco[2] = trans[ref].RefBCb * uvsinf; -off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright; -off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright; -off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; -gamma = 1.0; - -pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale); -glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off, - &dst_y_off); -glamor_set_destination_pixmap_priv_nc(pixmap_priv); - -for (i = 0; i < 3; i++) { -if (port_priv->src_pix[i]) { -src_pixmap_priv[i] = glamor_get_pixmap_private(port_priv->src_pix[i]); -pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i], &src_yscale[i]); -} -} -dispatch = glamor_get_dispatch(glamor_priv); -dispatch->glUseProgram(glamor_priv->xv_prog); - -uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "offsetyco"); -dispatch->glUniform4f(uloc, off[0], off[1], off[2], yco); -uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "ucogamma"); -dispatch->glUniform4f(uloc, uco[0], uco[1], uco[2], gamma); -uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "vco"); -dispatch->glUniform4f(uloc, vco[0], vco[1], vco[2], 0); - -dispatch->glActiveTexture(GL_TEXTURE0); -dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_LINEAR); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE); - -dispatch->glActiveTexture(GL_TEXTURE1); -dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_LINEAR); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE); - -dispatch->glActiveTexture(GL_TEXTURE2); -dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_MAG_FILTER, - GL_LINEAR); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE); -dispatch->glTexParameteri(GL_TEXTURE_2D, - GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE); - -sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "y_sampler"); -dispatch->glUniform1i(sampler_loc, 0); -sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "u_sampler"); -dispatch->glUniform1i(sampler_loc, 1); -sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "v_sampler"); -dispatch->glUniform1i(sampler_loc, 2); - -dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, - GL_FLOAT, GL_FALSE, - 2 * sizeof(float), - texcoords); -dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - -dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), - vertices); - -dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); -for (i = 0; i < nBox; i++) { -float off_x = box[i].x1 - port_priv->drw_x; -float off_y = box[i].y1 - port_priv->drw_y; -float diff_x = (float)port_priv->src_w / (float)port_priv->dst_w; -float diff_y = (float)port_priv->src_h / (float)port_priv->dst_h; -float srcx, srcy, srcw, srch; -int dstx, dsty, dstw, dsth; - - -dstx = box[i].x1 + dst_x_off; -dsty = box[i].y1 + dst_y_off; -dstw = box[i].x2 - box[i].x1; -dsth = box[i].y2 - box[i].y1; - -srcx = port_priv->src_x + off_x * diff_x; -srcy = port_priv->src_y + off_y * diff_y; -srcw = (port_priv->src_w * dstw) / (float)port_priv->dst_w; -srch = (port_priv->src_h * dsth) / (float)port_priv->dst_h; - -glamor_set_normalize_vcoords(pixmap_priv, - dst_xscale, dst_yscale, - dstx, - dsty, - dstx + dstw, - dsty + dsth, - glamor_priv->yInverted, - vertices); - -glamor_set_normalize_tcoords(src_pixmap_priv[0], - src_xscale[0], - src_yscale[0], - srcx, - srcy, - srcx + srcw, - srcy + srch, - glamor_priv->yInverted, - texcoords); - -dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -} - -dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); -dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - -dispatch->glUseProgram(0); -glamor_put_dispatch(glamor_priv); -DamageDamageRegion(port_priv->pDraw, &port_priv->clip); + yco = trans[ref].RefLuma * cont; + uco[0] = -trans[ref].RefRCr * uvsinf; + uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf; + uco[2] = trans[ref].RefBCb * uvcosf; + vco[0] = trans[ref].RefRCr * uvcosf; + vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf; + vco[2] = trans[ref].RefBCb * uvsinf; + off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright; + off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright; + off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright; + gamma = 1.0; + + pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale); + glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off, + &dst_y_off); + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + + for (i = 0; i < 3; i++) { + if (port_priv->src_pix[i]) { + src_pixmap_priv[i] = + glamor_get_pixmap_private(port_priv->src_pix[i]); + pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i], + &src_yscale[i]); + } + } + dispatch = glamor_get_dispatch(glamor_priv); + dispatch->glUseProgram(glamor_priv->xv_prog); + + uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "offsetyco"); + dispatch->glUniform4f(uloc, off[0], off[1], off[2], yco); + uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "ucogamma"); + dispatch->glUniform4f(uloc, uco[0], uco[1], uco[2], gamma); + uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "vco"); + dispatch->glUniform4f(uloc, vco[0], vco[1], vco[2], 0); + + dispatch->glActiveTexture(GL_TEXTURE0); + dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + dispatch->glActiveTexture(GL_TEXTURE1); + dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + dispatch->glActiveTexture(GL_TEXTURE2); + dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + sampler_loc = + dispatch->glGetUniformLocation(glamor_priv->xv_prog, "y_sampler"); + dispatch->glUniform1i(sampler_loc, 0); + sampler_loc = + dispatch->glGetUniformLocation(glamor_priv->xv_prog, "u_sampler"); + dispatch->glUniform1i(sampler_loc, 1); + sampler_loc = + dispatch->glGetUniformLocation(glamor_priv->xv_prog, "v_sampler"); + dispatch->glUniform1i(sampler_loc, 2); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, + GL_FLOAT, GL_FALSE, + 2 * sizeof(float), texcoords); + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), vertices); + + dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + for (i = 0; i < nBox; i++) { + float off_x = box[i].x1 - port_priv->drw_x; + float off_y = box[i].y1 - port_priv->drw_y; + float diff_x = (float) port_priv->src_w / (float) port_priv->dst_w; + float diff_y = (float) port_priv->src_h / (float) port_priv->dst_h; + float srcx, srcy, srcw, srch; + int dstx, dsty, dstw, dsth; + + dstx = box[i].x1 + dst_x_off; + dsty = box[i].y1 + dst_y_off; + dstw = box[i].x2 - box[i].x1; + dsth = box[i].y2 - box[i].y1; + + srcx = port_priv->src_x + off_x * diff_x; + srcy = port_priv->src_y + off_y * diff_y; + srcw = (port_priv->src_w * dstw) / (float) port_priv->dst_w; + srch = (port_priv->src_h * dsth) / (float) port_priv->dst_h; + + glamor_set_normalize_vcoords(pixmap_priv, + dst_xscale, dst_yscale, + dstx, + dsty, + dstx + dstw, + dsty + dsth, + glamor_priv->yInverted, vertices); + + glamor_set_normalize_tcoords(src_pixmap_priv[0], + src_xscale[0], + src_yscale[0], + srcx, + srcy, + srcx + srcw, + srcy + srch, + glamor_priv->yInverted, texcoords); + + dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + + dispatch->glUseProgram(0); + glamor_put_dispatch(glamor_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, - pointer data, - DrawablePtr pDrawable) +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, pointer data, DrawablePtr pDrawable) { - ScreenPtr screen = xf86ScrnToScreen(pScrn); - 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_display_textured_video(port_priv); - return Success; + ScreenPtr screen = xf86ScrnToScreen(pScrn); + 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_display_textured_video(port_priv); + return Success; } -static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = -{ - { - 0, - "XV_IMAGE", - 8192, 8192, - {1, 1} - } +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; - - 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 = (pointer)(pPriv); - } - return adapt; + glamor_port_private *port_priv; + XF86VideoAdaptorPtr adapt; + int i; + + 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 = (pointer) (pPriv); + } + return adapt; } #else XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr screen, int num_texture_ports) { - return NULL; + return NULL; } #endif diff --git a/glamor/glapi.h b/glamor/glapi.h index d510dac..481e4ba 100644 --- a/glamor/glapi.h +++ b/glamor/glapi.h @@ -22,7 +22,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - /** * \mainpage Mesa GL API Module * @@ -63,59 +62,55 @@ #define _glapi_Context _mglapi_Context #endif -typedef void (*_glapi_proc)(void); +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 struct _glapi_table *_glapi_tls_Dispatch + __attribute__ ((tls_model("initial-exec"))); -extern __thread void * _glapi_tls_Context - __attribute__((tls_model("initial-exec"))); +extern __thread void *_glapi_tls_Context + __attribute__ ((tls_model("initial-exec"))); extern const struct _glapi_table *_glapi_Dispatch; extern const void *_glapi_Context; -# define GET_DISPATCH() _glapi_tls_Dispatch -# define GET_CURRENT_CONTEXT(C) C = (typeof(C)) _glapi_tls_Context -# define SET_CURRENT_CONTEXT(C) _glapi_tls_Context = (void*)C +#define GET_DISPATCH() _glapi_tls_Dispatch +#define GET_CURRENT_CONTEXT(C) C = (typeof(C)) _glapi_tls_Context +#define SET_CURRENT_CONTEXT(C) _glapi_tls_Context = (void*)C #else extern struct _glapi_table *_glapi_Dispatch; extern void *_glapi_Context; -# ifdef THREADS +#ifdef THREADS -# define GET_DISPATCH() \ +#define GET_DISPATCH() \ (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch()) -# define GET_CURRENT_CONTEXT(C) C = (typeof(C)) \ +#define GET_CURRENT_CONTEXT(C) C = (typeof(C)) \ (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context()) - -# define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context)) \ +#define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context)) \ _glapi_Context = (void*)C; \ else \ _glapi_set_context(C); } while(0) -# else - -# define GET_DISPATCH() _glapi_Dispatch -# define GET_CURRENT_CONTEXT(C) C = (typeof(C)) _glapi_Context -# define SET_CURRENT_CONTEXT(C) _glapi_Context = (void*)C +#else -# endif +#define GET_DISPATCH() _glapi_Dispatch +#define GET_CURRENT_CONTEXT(C) C = (typeof(C)) _glapi_Context +#define SET_CURRENT_CONTEXT(C) _glapi_Context = (void*)C -#endif /* defined (GLX_USE_TLS) */ +#endif +#endif /* defined (GLX_USE_TLS) */ extern void -_glapi_set_context(void *context); + _glapi_set_context(void *context); -extern void * -_glapi_get_context(void); +extern void *_glapi_get_context(void); #endif -- 2.7.4