Initial version.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2011-11-02 13:44:50 +08:00 committed by Eric Anholt
parent 2dbbe25650
commit b861aad8e2
28 changed files with 6256 additions and 5011 deletions

View File

@ -1,29 +1,24 @@
noinst_LTLIBRARIES = libglamor.la inst_LTLIBRARIES = libglamor.la
# Override these since glamor doesn't need them and the needed files aren't # Override these since glamor doesn't need them and the needed files aren't
# built (in hw/xfree86/os-support/solaris) until after glamor is built # built (in hw/xfree86/os-support/solaris) until after glamor is built
SOLARIS_ASM_CFLAGS="" SOLARIS_ASM_CFLAGS=""
if XORG
sdk_HEADERS = glamor.h
endif
if GLAMOR_GLES2 if GLAMOR_GLES2
libglamor_la_LIBADD = $(GLESV2_LIBS) libglamor_la_LIBADD = $(GLESV2_LIBS)
else else
libglamor_la_LIBADD = $(GL_LIBS) libglamor_la_LIBADD = $(GL_LIBS)
endif endif
if XORG instdir = $(moduledir)
sdk_HEADERS = glamor.h
endif
INCLUDES = \ INCLUDES = \
$(XORG_INCS) $(XORG_INCS)
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS) AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
libglamor_la_LDFLAGS = -avoid-version
libglamor_la_SOURCES = \ libglamor_la_SOURCES = \
glamor.c \ glamor.c \
glamor_copyarea.c \ glamor_copyarea.c \
@ -45,3 +40,17 @@ libglamor_la_SOURCES = \
glamor_window.c\ glamor_window.c\
glamor_gl_dispatch.c\ glamor_gl_dispatch.c\
glamor.h glamor.h
sdk_HEADERS = glamor.h
if EGL
LIBGLAMOR_EGL = libglamor_egl.la
module_LTLIBRARIES = $(LIBGLAMOR_EGL)
libglamor_egl_la_DEPENDENCIES = libglamor.la
libglamor_egl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor
#libglamor_egl_la_LIBADD = $(top_builddir)/src/libglamor.la
libglamor_egl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
libglamor_egl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
endif

View File

@ -53,51 +53,65 @@ DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
PixmapPtr PixmapPtr
glamor_get_drawable_pixmap(DrawablePtr drawable) glamor_get_drawable_pixmap(DrawablePtr drawable)
{ {
if (drawable->type == DRAWABLE_WINDOW) if (drawable->type == DRAWABLE_WINDOW)
return drawable->pScreen->GetWindowPixmap((WindowPtr)drawable); return drawable->
else pScreen->GetWindowPixmap((WindowPtr) drawable);
return (PixmapPtr)drawable; else
return (PixmapPtr) drawable;
} }
void _X_EXPORT void
glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
{ {
ScreenPtr screen = pixmap->drawable.pScreen; ScreenPtr screen = pixmap->drawable.pScreen;
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv = glamor_get_pixmap_private(pixmap);
assert(pixmap_priv); if (pixmap_priv == NULL) {
pixmap_priv->tex = tex; pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
dixSetPrivate(&pixmap->devPrivates,
glamor_pixmap_private_key, pixmap_priv);
pixmap_priv->container = pixmap;
pixmap_priv->glamor_priv = glamor_priv;
}
/* Create a framebuffer object wrapping the texture so that we can render pixmap_priv->tex = tex;
* to it.
*/ /* Create a framebuffer object wrapping the texture so that we can render
pixmap_priv->gl_fbo = 1; * to it.
if (tex != 0) { */
glamor_pixmap_ensure_fb(pixmap); pixmap_priv->gl_fbo = 1;
pixmap_priv->gl_tex = 1; if (tex != 0) {
} glamor_pixmap_ensure_fb(pixmap);
else { pixmap_priv->gl_tex = 1;
pixmap_priv->fb = 0; } else {
pixmap_priv->gl_tex = 0; pixmap_priv->fb = 0;
} pixmap_priv->gl_tex = 0;
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, }
(((w * pixmap->drawable.bitsPerPixel +
7) / 8) + 3) & ~3, if (pixmap->devKind == 0)
NULL); screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
(((w *
pixmap->drawable.
bitsPerPixel + 7) / 8) +
3) & ~3, NULL);
} }
/* Set screen pixmap. If tex equal to 0, means it is called from ephyr. */ /* Set screen pixmap. If tex equal to 0, means it is called from ephyr. */
void void
glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex) glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h,
unsigned int tex)
{ {
PixmapPtr pixmap = screen->GetScreenPixmap(screen); PixmapPtr pixmap = screen->GetScreenPixmap(screen);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_set_pixmap_texture(pixmap, w, h, tex); glamor_set_pixmap_texture(pixmap, w, h, tex);
glamor_priv->screen_fbo = pixmap_priv->fb; pixmap_priv = glamor_get_pixmap_private(pixmap);
pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; glamor_priv->screen_fbo = pixmap_priv->fb;
} }
@ -111,113 +125,138 @@ static PixmapPtr
glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
unsigned int usage) unsigned int usage)
{ {
PixmapPtr pixmap; PixmapPtr pixmap;
GLenum format; GLenum format;
GLuint tex; GLuint tex;
int type = GLAMOR_PIXMAP_TEXTURE; int type = GLAMOR_PIXMAP_TEXTURE;
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(screen);
if (w > 32767 || h > 32767) glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
return NullPixmap; if (w > 32767 || h > 32767)
return NullPixmap;
if (!glamor_check_fbo_size(glamor_priv, w,h) if (!glamor_check_fbo_size(glamor_priv, w, h)
|| !glamor_check_fbo_depth(depth) || !glamor_check_fbo_depth(depth)
|| usage == GLAMOR_CREATE_PIXMAP_CPU) { || usage == GLAMOR_CREATE_PIXMAP_CPU) {
/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo. /* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
If we exceed such limitation, we have to use framebuffer.*/ If we exceed such limitation, we have to use framebuffer. */
type = GLAMOR_PIXMAP_MEMORY; type = GLAMOR_PIXMAP_MEMORY;
pixmap = fbCreatePixmap (screen, w, h, depth, usage); pixmap = fbCreatePixmap(screen, w, h, depth, usage);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
(((w * pixmap->drawable.bitsPerPixel + (((w *
7) / 8) + 3) & ~3, pixmap->
NULL); drawable.bitsPerPixel +
7) / 8) + 3) & ~3, NULL);
#if 0 #if 0
if (usage != GLAMOR_CREATE_PIXMAP_CPU) if (usage != GLAMOR_CREATE_PIXMAP_CPU)
glamor_fallback("choose cpu memory for pixmap %p ," glamor_fallback("choose cpu memory for pixmap %p ,"
" %d x %d depth %d\n", pixmap, w, h, depth); " %d x %d depth %d\n", pixmap, w,
h, depth);
#endif #endif
} else } else
pixmap = fbCreatePixmap (screen, 0, 0, depth, usage); pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) { pixmap_priv = calloc(1, sizeof(*pixmap_priv));
fbDestroyPixmap(pixmap); dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key,
ErrorF("Fail to allocate privates for PIXMAP.\n"); pixmap_priv);
return NullPixmap; pixmap_priv->container = pixmap;
} pixmap_priv->glamor_priv = glamor_priv;
pixmap_priv = glamor_get_pixmap_private(pixmap); if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
pixmap_priv->container = pixmap; return pixmap;
pixmap_priv->glamor_priv = glamor_priv;
if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY) switch (depth) {
#if 0
case 8:
format = GL_ALPHA;
break;
#endif
case 24:
format = GL_RGB;
break;
default:
format = GL_RGBA;
break;
}
/* Create the texture used to store the pixmap's data. */
dispatch->glGenTextures(1, &tex);
dispatch->glBindTexture(GL_TEXTURE_2D, tex);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
GL_UNSIGNED_BYTE, NULL);
glamor_set_pixmap_texture(pixmap, w, h, tex);
return pixmap; return pixmap;
}
switch (depth) { void
#if 0 glamor_destroy_textured_pixmap(PixmapPtr pixmap)
case 8: {
format = GL_ALPHA; glamor_screen_private *glamor_priv =
break; glamor_get_screen_private(pixmap->drawable.pScreen);
#endif glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
case 24: if (pixmap->refcnt == 1) {
format = GL_RGB; glamor_pixmap_private *pixmap_priv =
break; glamor_get_pixmap_private(pixmap);
default: if (pixmap_priv != NULL) {
format = GL_RGBA; if (pixmap_priv->fb)
break; dispatch->glDeleteFramebuffers(1,
} &pixmap_priv->fb);
if (pixmap_priv->tex)
/* Create the texture used to store the pixmap's data. */ dispatch->glDeleteTextures(1,
dispatch->glGenTextures(1, &tex); &pixmap_priv->tex);
dispatch->glBindTexture(GL_TEXTURE_2D, tex); if (pixmap_priv->pbo)
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glDeleteBuffers(1,
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); &pixmap_priv->pbo);
dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, free(pixmap_priv);
format, GL_UNSIGNED_BYTE, NULL); }
}
glamor_set_pixmap_texture(pixmap, w, h, tex);
return pixmap;
} }
static Bool static Bool
glamor_destroy_pixmap(PixmapPtr pixmap) glamor_destroy_pixmap(PixmapPtr pixmap)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); glamor_destroy_textured_pixmap(pixmap);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; return fbDestroyPixmap(pixmap);
if (pixmap->refcnt == 1) {
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv->fb)
dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
if (pixmap_priv->tex)
dispatch->glDeleteTextures(1, &pixmap_priv->tex);
if (pixmap_priv->pbo)
dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP);
}
return fbDestroyPixmap(pixmap);
} }
static void void
glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask) glamor_block_handler(ScreenPtr screen)
{ {
glamor_gl_dispatch *dispatch = data; glamor_screen_private *glamor_priv =
dispatch->glFlush(); glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
dispatch->glFlush();
} }
static void static void
glamor_wakeup_handler(void *data, int result, void *last_select_mask) _glamor_block_handler(void *data, OSTimePtr timeout,
void *last_select_mask)
{
glamor_gl_dispatch *dispatch = data;
dispatch->glFlush();
}
static void
_glamor_wakeup_handler(void *data, int result, void *last_select_mask)
{ {
} }
static void static void
glamor_set_debug_level(int *debug_level) glamor_set_debug_level(int *debug_level)
{ {
char *debug_level_string; char *debug_level_string;
debug_level_string = getenv("GLAMOR_DEBUG"); debug_level_string = getenv("GLAMOR_DEBUG");
if (debug_level_string && sscanf(debug_level_string, "%d", debug_level) == 1) if (debug_level_string
return; && sscanf(debug_level_string, "%d", debug_level) == 1)
*debug_level = 0; return;
*debug_level = 0;
} }
int glamor_debug_level; int glamor_debug_level;
@ -226,176 +265,198 @@ int glamor_debug_level;
Bool Bool
glamor_init(ScreenPtr screen, unsigned int flags) glamor_init(ScreenPtr screen, unsigned int flags)
{ {
glamor_screen_private *glamor_priv; glamor_screen_private *glamor_priv;
int gl_version; int gl_version;
#ifdef RENDER #ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen); PictureScreenPtr ps = GetPictureScreenIfSet(screen);
#endif #endif
if (flags & ~GLAMOR_VALID_FLAGS) { if (flags & ~GLAMOR_VALID_FLAGS) {
ErrorF("glamor_init: Invalid flags %x\n", flags); ErrorF("glamor_init: Invalid flags %x\n", flags);
return FALSE; return FALSE;
} }
glamor_priv = calloc(1, sizeof(*glamor_priv)); glamor_priv = calloc(1, sizeof(*glamor_priv));
if (glamor_priv == NULL) if (glamor_priv == NULL)
return FALSE; return FALSE;
if (flags & GLAMOR_INVERTED_Y_AXIS) { if (flags & GLAMOR_INVERTED_Y_AXIS) {
glamor_priv->yInverted = 1; glamor_priv->yInverted = 1;
} else } else
glamor_priv->yInverted = 0; glamor_priv->yInverted = 0;
if (!dixRegisterPrivateKey(glamor_screen_private_key,PRIVATE_SCREEN, if (!dixRegisterPrivateKey
0)) { (glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
LogMessage(X_WARNING, LogMessage(X_WARNING,
"glamor%d: Failed to allocate screen private\n", "glamor%d: Failed to allocate screen private\n",
screen->myNum); screen->myNum);
goto fail; goto fail;
} }
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv); dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
glamor_priv);
if (!dixRegisterPrivateKey(glamor_pixmap_private_key,PRIVATE_PIXMAP, if (!dixRegisterPrivateKey
sizeof(glamor_pixmap_private))) { (glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
LogMessage(X_WARNING, LogMessage(X_WARNING,
"glamor%d: Failed to allocate pixmap private\n", "glamor%d: Failed to allocate pixmap private\n",
screen->myNum); screen->myNum);
goto fail;; goto fail;;
} }
gl_version = glamor_gl_get_version(); gl_version = glamor_gl_get_version();
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
if (gl_version < GLAMOR_GL_VERSION_ENCODE(1,3)) { if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
ErrorF("Require OpenGL version 1.3 or latter.\n"); ErrorF("Require OpenGL version 1.3 or latter.\n");
goto fail; goto fail;
} }
#else #else
if (gl_version < GLAMOR_GL_VERSION_ENCODE(2,0)) { if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
ErrorF("Require Open GLES2.0 or latter.\n"); ErrorF("Require Open GLES2.0 or latter.\n");
goto fail; goto fail;
} }
#endif #endif
glamor_gl_dispatch_init(screen, &glamor_priv->dispatch, gl_version); glamor_gl_dispatch_init(screen, &glamor_priv->dispatch,
gl_version);
#ifdef GLAMOR_GLES2 #ifdef GLAMOR_GLES2
if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) { if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
ErrorF("GL_EXT_texture_format_BGRA8888 required\n"); ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
goto fail; goto fail;
} }
#endif #endif
glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert"); glamor_priv->has_pack_invert =
glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit"); glamor_gl_has_extension("GL_MESA_pack_invert");
glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); 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);
if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
glamor_wakeup_handler, _glamor_wakeup_handler,
(void*)&glamor_priv->dispatch)) { (void *)
goto fail; &glamor_priv->dispatch)) {
} goto fail;
}
glamor_set_debug_level(&glamor_debug_level); glamor_set_debug_level(&glamor_debug_level);
glamor_priv->saved_close_screen = screen->CloseScreen;
screen->CloseScreen = glamor_close_screen;
glamor_priv->saved_create_gc = screen->CreateGC; if (flags & GLAMOR_USE_SCREEN) {
screen->CreateGC = glamor_create_gc; glamor_priv->saved_close_screen = screen->CloseScreen;
screen->CloseScreen = glamor_close_screen;
glamor_priv->saved_create_pixmap = screen->CreatePixmap; glamor_priv->saved_create_gc = screen->CreateGC;
screen->CreatePixmap = glamor_create_pixmap; screen->CreateGC = glamor_create_gc;
glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap; glamor_priv->saved_create_pixmap = screen->CreatePixmap;
screen->DestroyPixmap = glamor_destroy_pixmap; screen->CreatePixmap = glamor_create_pixmap;
glamor_priv->saved_get_spans = screen->GetSpans; glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
screen->GetSpans = glamor_get_spans; screen->DestroyPixmap = glamor_destroy_pixmap;
glamor_priv->saved_get_image = screen->GetImage; glamor_priv->saved_get_spans = screen->GetSpans;
screen->GetImage = miGetImage; screen->GetSpans = glamor_get_spans;
glamor_priv->saved_change_window_attributes = screen->ChangeWindowAttributes; glamor_priv->saved_get_image = screen->GetImage;
screen->ChangeWindowAttributes = glamor_change_window_attributes; screen->GetImage = miGetImage;
glamor_priv->saved_copy_window = screen->CopyWindow; glamor_priv->saved_change_window_attributes =
screen->CopyWindow = glamor_copy_window; screen->ChangeWindowAttributes;
screen->ChangeWindowAttributes =
glamor_change_window_attributes;
glamor_priv->saved_bitmap_to_region = screen->BitmapToRegion; glamor_priv->saved_copy_window = screen->CopyWindow;
screen->BitmapToRegion = glamor_bitmap_to_region; screen->CopyWindow = glamor_copy_window;
glamor_priv->saved_bitmap_to_region =
screen->BitmapToRegion;
screen->BitmapToRegion = glamor_bitmap_to_region;
}
#ifdef RENDER #ifdef RENDER
glamor_priv->saved_composite = ps->Composite; if (flags & GLAMOR_USE_PICTURE_SCREEN) {
ps->Composite = glamor_composite; glamor_priv->saved_composite = ps->Composite;
glamor_priv->saved_trapezoids = ps->Trapezoids; ps->Composite = glamor_composite;
ps->Trapezoids = glamor_trapezoids;
glamor_priv->saved_glyphs = ps->Glyphs;
ps->Glyphs = glamor_glyphs;
glamor_priv->saved_triangles = ps->Triangles;
ps->Triangles = glamor_triangles;
glamor_init_composite_shaders(screen);
glamor_priv->saved_create_picture = ps->CreatePicture;
ps->CreatePicture = glamor_create_picture;
glamor_priv->saved_destroy_picture = ps->DestroyPicture;
ps->DestroyPicture = glamor_destroy_picture;
glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph; glamor_priv->saved_trapezoids = ps->Trapezoids;
ps->UnrealizeGlyph = glamor_glyph_unrealize; ps->Trapezoids = glamor_trapezoids;
glamor_priv->saved_glyphs = ps->Glyphs;
ps->Glyphs = glamor_glyphs;
glamor_priv->saved_triangles = ps->Triangles;
ps->Triangles = glamor_triangles;
glamor_priv->saved_create_picture = ps->CreatePicture;
ps->CreatePicture = glamor_create_picture;
glamor_priv->saved_destroy_picture = ps->DestroyPicture;
ps->DestroyPicture = glamor_destroy_picture;
glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph;
ps->UnrealizeGlyph = glamor_glyph_unrealize;
}
glamor_init_composite_shaders(screen);
#endif #endif
glamor_init_solid_shader(screen); glamor_init_solid_shader(screen);
glamor_init_tile_shader(screen); glamor_init_tile_shader(screen);
glamor_init_putimage_shaders(screen); glamor_init_putimage_shaders(screen);
glamor_init_finish_access_shaders(screen); glamor_init_finish_access_shaders(screen);
glamor_pixmap_init(screen); glamor_pixmap_init(screen);
#ifdef GLAMOR_GLES2 #ifdef GLAMOR_GLES2
glamor_priv->gl_flavor = GLAMOR_GL_ES2; glamor_priv->gl_flavor = GLAMOR_GL_ES2;
#else #else
glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP; glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
#endif #endif
return TRUE; return TRUE;
fail: fail:
free(glamor_priv); free(glamor_priv);
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL); dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
return FALSE; NULL);
return FALSE;
} }
Bool Bool
glamor_close_screen(int idx, ScreenPtr screen) glamor_close_screen(int idx, ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
#ifdef RENDER #ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen); PictureScreenPtr ps = GetPictureScreenIfSet(screen);
#endif #endif
glamor_glyphs_fini(screen); glamor_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_close_screen; screen->CloseScreen = glamor_priv->saved_close_screen;
screen->CreateGC = glamor_priv->saved_create_gc; screen->CreateGC = glamor_priv->saved_create_gc;
screen->CreatePixmap = glamor_priv->saved_create_pixmap; screen->CreatePixmap = glamor_priv->saved_create_pixmap;
screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap; screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
screen->GetSpans = glamor_priv->saved_get_spans; screen->GetSpans = glamor_priv->saved_get_spans;
screen->ChangeWindowAttributes = glamor_priv->saved_change_window_attributes; screen->ChangeWindowAttributes =
screen->CopyWindow = glamor_priv->saved_copy_window; glamor_priv->saved_change_window_attributes;
screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region; screen->CopyWindow = glamor_priv->saved_copy_window;
screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
#ifdef RENDER #ifdef RENDER
if (ps) { if (ps) {
ps->Composite = glamor_priv->saved_composite; ps->Composite = glamor_priv->saved_composite;
ps->Trapezoids = glamor_priv->saved_trapezoids; ps->Trapezoids = glamor_priv->saved_trapezoids;
ps->Glyphs = glamor_priv->saved_glyphs; ps->Glyphs = glamor_priv->saved_glyphs;
ps->Triangles = glamor_priv->saved_triangles; ps->Triangles = glamor_priv->saved_triangles;
ps->CreatePicture = glamor_priv->saved_create_picture; ps->CreatePicture = glamor_priv->saved_create_picture;
} }
#endif #endif
if (glamor_priv->vb) if (glamor_priv->vb)
free(glamor_priv->vb); free(glamor_priv->vb);
free(glamor_priv); free(glamor_priv);
return screen->CloseScreen(idx, screen); return screen->CloseScreen(idx, screen);
} }
void void
glamor_fini(ScreenPtr screen) glamor_fini(ScreenPtr screen)
{ {
/* Do nothing currently. */ /* Do nothing currently. */
} }

View File

@ -39,25 +39,43 @@
#include "fb.h" #include "fb.h"
#include "fbpict.h" #include "fbpict.h"
#endif /* GLAMOR_H */ #endif /* GLAMOR_H */
#define GLAMOR_INVERTED_Y_AXIS 1 #define GLAMOR_INVERTED_Y_AXIS 1
#define GLAMOR_HOSTX 2 #define GLAMOR_USE_SCREEN 2
#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX) #define GLAMOR_USE_PICTURE_SCREEN 4
#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \
| GLAMOR_USE_SCREEN \
| GLAMOR_USE_PICTURE_SCREEN)
#define GLAMOR_EGL_EXTERNAL_BUFFER 3 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
extern _X_EXPORT void glamor_fini(ScreenPtr screen); extern _X_EXPORT void glamor_fini(ScreenPtr screen);
extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen,
extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen); int w, int h,
void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex); unsigned int tex);
extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
unsigned int tex);
extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
#ifdef GLAMOR_FOR_XORG #ifdef GLAMOR_FOR_XORG
extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd); extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride); extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
extern _X_EXPORT Bool glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride); int handle,
extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen); int stride);
extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags); extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
int handle,
int stride);
extern _X_EXPORT Bool glamor_egl_close_screen(ScreenPtr screen);
extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
#endif #endif

View File

@ -35,367 +35,406 @@
static Bool static Bool
glamor_copy_n_to_n_fbo_blit(DrawablePtr src, glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
DrawablePtr dst, DrawablePtr dst,
GCPtr gc, GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
BoxPtr box,
int nbox,
int dx,
int dy)
{ {
ScreenPtr screen = dst->pScreen; ScreenPtr screen = dst->pScreen;
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *src_pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(screen);
int dst_x_off, dst_y_off, src_x_off, src_y_off, i; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
if (!glamor_priv->has_fbo_blit) { if (!glamor_priv->has_fbo_blit) {
glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n"); glamor_delayed_fallback(screen,
return FALSE; "no EXT_framebuffer_blit\n");
} return FALSE;
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL)
return FALSE;
if (gc) {
if (gc->alu != GXcopy) {
glamor_delayed_fallback(screen, "non-copy ALU\n");
return FALSE;
} }
if (!glamor_pm_is_solid(dst, gc->planemask)) { src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
glamor_delayed_fallback(screen, "non-solid planemask\n");
return FALSE; if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL)
return FALSE;
if (gc) {
if (gc->alu != GXcopy) {
glamor_delayed_fallback(screen, "non-copy ALU\n");
return FALSE;
}
if (!glamor_pm_is_solid(dst, gc->planemask)) {
glamor_delayed_fallback(screen,
"non-solid planemask\n");
return FALSE;
}
} }
}
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
glamor_delayed_fallback(screen, "no src fbo\n"); glamor_delayed_fallback(screen, "no src fbo\n");
return FALSE; return FALSE;
}
if (glamor_set_destination_pixmap(dst_pixmap)) {
return FALSE;
}
glamor_validate_pixmap(dst_pixmap);
dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
src_y_off += dy;
for (i = 0; i < nbox; i++) {
if(glamor_priv->yInverted) {
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);
} }
}
return TRUE; if (glamor_set_destination_pixmap(dst_pixmap)) {
return FALSE;
}
glamor_validate_pixmap(dst_pixmap);
dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
src_pixmap_priv->fb);
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
&dst_y_off);
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
&src_y_off);
src_y_off += dy;
for (i = 0; i < nbox; i++) {
if (glamor_priv->yInverted) {
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);
}
}
return TRUE;
} }
#endif #endif
static Bool static Bool
glamor_copy_n_to_n_textured(DrawablePtr src, glamor_copy_n_to_n_textured(DrawablePtr src,
DrawablePtr dst, DrawablePtr dst,
GCPtr gc, GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
BoxPtr box,
int nbox,
int dx,
int dy
)
{ {
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
glamor_get_screen_private(dst->pScreen); glamor_get_screen_private(dst->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
int i; int i;
float vertices[8], texcoords[8]; float vertices[8], texcoords[8];
glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *src_pixmap_priv;
glamor_pixmap_private *dst_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv;
int src_x_off, src_y_off, dst_x_off, dst_y_off; int src_x_off, src_y_off, dst_x_off, dst_y_off;
enum glamor_pixmap_status src_status = GLAMOR_NONE; enum glamor_pixmap_status src_status = GLAMOR_NONE;
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
int flush_needed = 0; int flush_needed = 0;
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n"); glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
goto fail; goto fail;
} }
if (!src_pixmap_priv->gl_fbo) { if (!src_pixmap_priv->gl_fbo) {
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
goto fail; goto fail;
#else #else
src_status = glamor_upload_pixmap_to_texture(src_pixmap); src_status = glamor_upload_pixmap_to_texture(src_pixmap);
if (src_status != GLAMOR_UPLOAD_DONE) if (src_status != GLAMOR_UPLOAD_DONE)
goto fail; goto fail;
#endif #endif
} } else
else flush_needed = 1;
flush_needed = 1;
if (gc) { if (gc) {
glamor_set_alu(dispatch, gc->alu); glamor_set_alu(dispatch, gc->alu);
if (!glamor_set_planemask(dst_pixmap, gc->planemask)) if (!glamor_set_planemask(dst_pixmap, gc->planemask))
goto fail; goto fail;
if (gc->alu != GXcopy) { if (gc->alu != GXcopy) {
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv); glamor_set_destination_pixmap_priv_nc
glamor_validate_pixmap(src_pixmap); (src_pixmap_priv);
} glamor_validate_pixmap(src_pixmap);
} }
}
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
glamor_validate_pixmap(dst_pixmap); glamor_validate_pixmap(dst_pixmap);
pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_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->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
2 * sizeof(float), GL_FALSE, 2 * sizeof(float),
vertices); vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
dx += src_x_off; &src_y_off);
dy += src_y_off; dx += src_x_off;
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); dy += src_y_off;
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
&src_yscale);
dispatch->glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); dispatch->glBindTexture(GL_TEXTURE_2D,
src_pixmap_priv->tex);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
dispatch->glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D,
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
2 * sizeof(float), GL_FLOAT, GL_FALSE,
texcoords); 2 * sizeof(float),
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); texcoords);
dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1); dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); dispatch->
glUniform1i(glamor_priv->finish_access_no_revert[0],
1);
dispatch->
glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
} } else {
else { GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv); src_pixmap_priv);
} }
for (i = 0; i < nbox; i++) { for (i = 0; i < nbox; i++) {
glamor_set_normalize_vcoords(dst_xscale, dst_yscale, glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
box[i].x1 + dst_x_off, box[i].x1 + dst_x_off,
box[i].y1 + dst_y_off, box[i].y1 + dst_y_off,
box[i].x2 + dst_x_off, box[i].x2 + dst_x_off,
box[i].y2 + dst_y_off, box[i].y2 + dst_y_off,
glamor_priv->yInverted, glamor_priv->yInverted,
vertices); vertices);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv))
glamor_set_normalize_tcoords(src_xscale, src_yscale, glamor_set_normalize_tcoords(src_xscale,
box[i].x1 + dx, box[i].y1 + dy, src_yscale,
box[i].x2 + dx, box[i].y2 + dy, box[i].x1 + dx,
glamor_priv->yInverted, box[i].y1 + dy,
texcoords); box[i].x2 + dx,
box[i].y2 + dy,
glamor_priv->yInverted,
texcoords);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
} }
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
dispatch->glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
} }
dispatch->glUseProgram(0); dispatch->glUseProgram(0);
/* The source texture is bound to a fbo, we have to flush it here. */ /* The source texture is bound to a fbo, we have to flush it here. */
if (flush_needed) if (flush_needed)
dispatch->glFlush(); dispatch->glFlush();
return TRUE; return TRUE;
fail: fail:
glamor_set_alu(dispatch, GXcopy); glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(dst_pixmap, ~0); glamor_set_planemask(dst_pixmap, ~0);
return FALSE; return FALSE;
} }
void void
glamor_copy_n_to_n(DrawablePtr src, glamor_copy_n_to_n(DrawablePtr src,
DrawablePtr dst, DrawablePtr dst,
GCPtr gc, GCPtr gc,
BoxPtr box, BoxPtr box,
int nbox, int nbox,
int dx, int dx,
int dy, int dy,
Bool reverse, Bool reverse,
Bool upsidedown, Bool upsidedown, Pixel bitplane, void *closure)
Pixel bitplane,
void *closure)
{ {
glamor_access_t dst_access; glamor_access_t dst_access;
PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL; PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
DrawablePtr temp_src = src; DrawablePtr temp_src = src;
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
BoxRec bound; BoxRec bound;
ScreenPtr screen; ScreenPtr screen;
int temp_dx = dx; int temp_dx = dx;
int temp_dy = dy; int temp_dy = dy;
int src_x_off, src_y_off, dst_x_off, dst_y_off; int src_x_off, src_y_off, dst_x_off, dst_y_off;
int i; int i;
int overlaped = 0; int overlaped = 0;
dst_pixmap = glamor_get_drawable_pixmap(dst); dst_pixmap = glamor_get_drawable_pixmap(dst);
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
src_pixmap = glamor_get_drawable_pixmap(src); src_pixmap = glamor_get_drawable_pixmap(src);
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
screen = dst_pixmap->drawable.pScreen; screen = dst_pixmap->drawable.pScreen;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
glamor_fallback("dest pixmap %p has no fbo. \n", dst_pixmap); glamor_fallback("dest pixmap %p has no fbo. \n",
goto fail; dst_pixmap);
} goto fail;
}
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); &src_y_off);
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
&dst_y_off);
if (src_pixmap_priv->fb == dst_pixmap_priv->fb) { if (src_pixmap_priv->fb == dst_pixmap_priv->fb) {
int x_shift = abs(src_x_off - dx - dst_x_off); int x_shift = abs(src_x_off - dx - dst_x_off);
int y_shift = abs(src_y_off - dy - dst_y_off); int y_shift = abs(src_y_off - dy - dst_y_off);
for ( i = 0; i < nbox; i++) for (i = 0; i < nbox; i++) {
{ if (x_shift < abs(box[i].x2 - box[i].x1)
if (x_shift < abs(box[i].x2 - box[i].x1) && y_shift < abs(box[i].y2 - box[i].y1)) {
&& y_shift < abs(box[i].y2 - box[i].y1)) { overlaped = 1;
overlaped = 1; break;
break; }
} }
} }
} /* XXX need revisit to handle overlapped area copying. */
/* XXX need revisit to handle overlapped area copying. */
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
if ((overlaped if ((overlaped
|| !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex ) || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex)
&& glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
goto done; dy)) {
return; goto done;
} return;
#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))) {
temp_pixmap = (*screen->CreatePixmap)(screen,
bound.x2 - bound.x1,
bound.y2 - bound.y1,
src_pixmap->drawable.depth,
overlaped ? 0 : GLAMOR_CREATE_PIXMAP_CPU);
if (!temp_pixmap)
goto fail;
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
temp_src = &temp_pixmap->drawable;
if (overlaped)
glamor_copy_n_to_n_textured(src, temp_src, gc, box, nbox,
temp_dx + bound.x1, temp_dy + bound.y1);
else
fbCopyNtoN(src, temp_src, gc, box, nbox,
temp_dx + bound.x1, temp_dy + bound.y1,
reverse, upsidedown, bitplane,
closure);
glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
temp_dx = -bound.x1;
temp_dy = -bound.y1;
}
else {
temp_dx = dx;
temp_dy = dy;
temp_src = src;
}
if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
goto done;
}
fail:
glamor_report_delayed_fallbacks(src->pScreen);
glamor_report_delayed_fallbacks(dst->pScreen);
glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
glamor_get_drawable_location(src),
glamor_get_drawable_location(dst));
if (gc && gc->alu != GXcopy)
dst_access = GLAMOR_ACCESS_RW;
else
dst_access = GLAMOR_ACCESS_WO;
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
if (dst == src
|| glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
fbCopyNtoN(src, dst, gc, box, nbox,
dx, dy, reverse, upsidedown, bitplane,
closure);
if (dst != src)
glamor_finish_access(src);
} }
glamor_finish_access(dst); #endif
} glamor_calculate_boxes_bound(&bound, box, nbox);
done: /* Overlaped indicate the src and dst are the same pixmap. */
glamor_clear_delayed_fallbacks(src->pScreen); if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
glamor_clear_delayed_fallbacks(dst->pScreen); && ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
if (temp_src != src) { * 4 >
(*screen->DestroyPixmap)(temp_pixmap); src_pixmap->drawable.width *
} src_pixmap->drawable.height))) {
temp_pixmap = (*screen->CreatePixmap) (screen,
bound.x2 - bound.x1,
bound.y2 - bound.y1,
src_pixmap->
drawable.depth,
overlaped ? 0 :
GLAMOR_CREATE_PIXMAP_CPU);
if (!temp_pixmap)
goto fail;
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
temp_src = &temp_pixmap->drawable;
if (overlaped)
glamor_copy_n_to_n_textured(src, temp_src, gc, box,
nbox,
temp_dx + bound.x1,
temp_dy + bound.y1);
else
fbCopyNtoN(src, temp_src, gc, box, nbox,
temp_dx + bound.x1, temp_dy + bound.y1,
reverse, upsidedown, bitplane, closure);
glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
temp_dx = -bound.x1;
temp_dy = -bound.y1;
} else {
temp_dx = dx;
temp_dy = dy;
temp_src = src;
}
if (glamor_copy_n_to_n_textured
(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
goto done;
}
fail:
glamor_report_delayed_fallbacks(src->pScreen);
glamor_report_delayed_fallbacks(dst->pScreen);
glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
glamor_get_drawable_location(src),
glamor_get_drawable_location(dst));
if (gc && gc->alu != GXcopy)
dst_access = GLAMOR_ACCESS_RW;
else
dst_access = GLAMOR_ACCESS_WO;
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
if (dst == src
|| glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
fbCopyNtoN(src, dst, gc, box, nbox,
dx, dy, reverse, upsidedown, bitplane,
closure);
if (dst != src)
glamor_finish_access(src);
}
glamor_finish_access(dst);
}
done:
glamor_clear_delayed_fallbacks(src->pScreen);
glamor_clear_delayed_fallbacks(dst->pScreen);
if (temp_src != src) {
(*screen->DestroyPixmap) (temp_pixmap);
}
} }
RegionPtr RegionPtr
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, 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; RegionPtr region;
region = miDoCopy(src, dst, gc, region = miDoCopy(src, dst, gc,
srcx, srcy, width, height, srcx, srcy, width, height,
dstx, dsty, glamor_copy_n_to_n, 0, NULL); dstx, dsty, glamor_copy_n_to_n, 0, NULL);
return region; return region;
} }

View File

@ -32,29 +32,31 @@
* Screen CopyWindow implementation. * Screen CopyWindow implementation.
*/ */
void glamor_copy_window(WindowPtr win, DDXPointRec old_origin, void
RegionPtr src_region) glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
RegionPtr src_region)
{ {
RegionRec dst_region; RegionRec dst_region;
int dx, dy; int dx, dy;
PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win); PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
dx = old_origin.x - win->drawable.x; dx = old_origin.x - win->drawable.x;
dy = old_origin.y - win->drawable.y; dy = old_origin.y - win->drawable.y;
REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy); 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, REGION_INTERSECT(win->drawable.pScreen, &dst_region,
src_region); &win->borderClip, src_region);
#ifdef COMPOSITE #ifdef COMPOSITE
if (pixmap->screen_x || pixmap->screen_y) if (pixmap->screen_x || pixmap->screen_y)
REGION_TRANSLATE(win->drawable.pScreen, &dst_region, REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
-pixmap->screen_x, -pixmap->screen_y); -pixmap->screen_x, -pixmap->screen_y);
#endif #endif
miCopyRegion(&pixmap->drawable, &pixmap->drawable, miCopyRegion(&pixmap->drawable, &pixmap->drawable,
NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL); 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);
} }

View File

@ -42,215 +42,247 @@
const Bool const Bool
glamor_get_drawable_location(const DrawablePtr drawable) glamor_get_drawable_location(const DrawablePtr drawable)
{ {
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv =
glamor_screen_private *glamor_priv = glamor_get_pixmap_private(pixmap);
glamor_get_screen_private(drawable->pScreen); glamor_screen_private *glamor_priv =
if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0) glamor_get_screen_private(drawable->pScreen);
return 'm'; if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
if (pixmap_priv->fb == glamor_priv->screen_fbo) return 'm';
return 's'; if (pixmap_priv->fb == glamor_priv->screen_fbo)
else return 's';
return 'f'; else
return 'f';
} }
GLint GLint
glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source) glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
const char *source)
{ {
GLint ok; GLint ok;
GLint prog; GLint prog;
prog = dispatch->glCreateShader(type); prog = dispatch->glCreateShader(type);
dispatch->glShaderSource(prog, 1, (const GLchar **)&source, NULL); dispatch->glShaderSource(prog, 1, (const GLchar **) &source, NULL);
dispatch->glCompileShader(prog); dispatch->glCompileShader(prog);
dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
if (!ok) { if (!ok) {
GLchar *info; GLchar *info;
GLint size; GLint size;
dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
info = malloc(size); info = malloc(size);
dispatch->glGetShaderInfoLog(prog, size, NULL, info); dispatch->glGetShaderInfoLog(prog, size, NULL, info);
ErrorF("Failed to compile %s: %s\n", ErrorF("Failed to compile %s: %s\n",
type == GL_FRAGMENT_SHADER ? "FS" : "VS", type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
info); ErrorF("Program source:\n%s", source);
ErrorF("Program source:\n%s", source); FatalError("GLSL compile failure\n");
FatalError("GLSL compile failure\n"); }
}
return prog; return prog;
} }
void void
glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog) glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog)
{ {
GLint ok; GLint ok;
dispatch->glLinkProgram(prog); dispatch->glLinkProgram(prog);
dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok); dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
if (!ok) { if (!ok) {
GLchar *info; GLchar *info;
GLint size; GLint size;
dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
info = malloc(size); info = malloc(size);
dispatch->glGetProgramInfoLog(prog, size, NULL, info); dispatch->glGetProgramInfoLog(prog, size, NULL, info);
ErrorF("Failed to link: %s\n", ErrorF("Failed to link: %s\n", info);
info); FatalError("GLSL link failure\n");
FatalError("GLSL link failure\n"); }
}
} }
Bool Bool
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
{ {
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
return glamor_download_pixmap_to_cpu(pixmap, access); return glamor_download_pixmap_to_cpu(pixmap, access);
} }
void void
glamor_init_finish_access_shaders(ScreenPtr screen) glamor_init_finish_access_shaders(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(screen);
const char *vs_source = glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
"attribute vec4 v_position;\n" const char *vs_source =
"attribute vec4 v_texcoord0;\n" "attribute vec4 v_position;\n"
"varying vec2 source_texture;\n" "attribute vec4 v_texcoord0;\n"
"void main()\n" "varying vec2 source_texture;\n"
"{\n" "void main()\n"
" gl_Position = v_position;\n" "{\n"
" source_texture = v_texcoord0.xy;\n" " gl_Position = v_position;\n"
"}\n"; " source_texture = v_texcoord0.xy;\n" "}\n";
const char *fs_source = const char *fs_source =
GLAMOR_DEFAULT_PRECISION GLAMOR_DEFAULT_PRECISION
"varying vec2 source_texture;\n" "varying vec2 source_texture;\n"
"uniform sampler2D sampler;\n" "uniform sampler2D sampler;\n"
"uniform int no_revert;\n" "uniform int no_revert;\n"
"uniform int swap_rb;\n" "uniform int swap_rb;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" if (no_revert == 1) \n" " if (no_revert == 1) \n"
" { \n" " { \n"
" if (swap_rb == 1) \n" " if (swap_rb == 1) \n"
" gl_FragColor = texture2D(sampler, source_texture).bgra;\n" " gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
" else \n" " else \n"
" gl_FragColor = texture2D(sampler, source_texture).rgba;\n" " gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
" } \n" " } \n"
" else \n" " else \n"
" { \n" " { \n"
" if (swap_rb == 1) \n" " if (swap_rb == 1) \n"
" gl_FragColor = texture2D(sampler, source_texture).argb;\n" " gl_FragColor = texture2D(sampler, source_texture).argb;\n"
" else \n" " else \n"
" gl_FragColor = texture2D(sampler, source_texture).abgr;\n" " gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
" } \n" " } \n" "}\n";
"}\n";
const char *set_alpha_source = const char *set_alpha_source =
GLAMOR_DEFAULT_PRECISION GLAMOR_DEFAULT_PRECISION
"varying vec2 source_texture;\n" "varying vec2 source_texture;\n"
"uniform sampler2D sampler;\n" "uniform sampler2D sampler;\n"
"uniform int no_revert;\n" "uniform int no_revert;\n"
"uniform int swap_rb;\n" "uniform int swap_rb;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" if (no_revert == 1) \n" " if (no_revert == 1) \n"
" { \n" " { \n"
" if (swap_rb == 1) \n" " if (swap_rb == 1) \n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n" " gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
" else \n" " else \n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n" " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
" } \n" " } \n"
" else \n" " else \n"
" { \n" " { \n"
" if (swap_rb == 1) \n" " if (swap_rb == 1) \n"
" gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n" " gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
" else \n" " else \n"
" gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n" " gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
" } \n" " } \n" "}\n";
"}\n"; GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; GLint sampler_uniform_location;
GLint sampler_uniform_location;
glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram(); glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram(); glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); vs_prog =
fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, fs_source); glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); vs_source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); fs_prog =
glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
fs_source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
vs_prog);
dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
fs_prog);
avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); avs_prog =
set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, set_alpha_source); glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); vs_source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog); set_alpha_prog =
glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
set_alpha_source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
avs_prog);
dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
set_alpha_prog);
dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position"); dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); GLAMOR_VERTEX_POS, "v_position");
glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[0]); 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],
dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); GLAMOR_VERTEX_POS, "v_position");
glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[1]); dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
GLAMOR_VERTEX_SOURCE,
"v_texcoord0");
glamor_link_glsl_prog(dispatch,
glamor_priv->finish_access_prog[1]);
glamor_priv->finish_access_no_revert[0] = glamor_priv->finish_access_no_revert[0] =
dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert"); dispatch->
glGetUniformLocation(glamor_priv->finish_access_prog[0],
"no_revert");
glamor_priv->finish_access_swap_rb[0] = glamor_priv->finish_access_swap_rb[0] =
dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb"); dispatch->
sampler_uniform_location = glGetUniformLocation(glamor_priv->finish_access_prog[0],
dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); "swap_rb");
dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); sampler_uniform_location =
dispatch->glUniform1i(sampler_uniform_location, 0); dispatch->
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0],1); glGetUniformLocation(glamor_priv->finish_access_prog[0],
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],0); "sampler");
dispatch->glUseProgram(0); dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
dispatch->glUniform1i(sampler_uniform_location, 0);
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
dispatch->glUseProgram(0);
glamor_priv->finish_access_no_revert[1] = glamor_priv->finish_access_no_revert[1] =
dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert"); dispatch->
glamor_priv->finish_access_swap_rb[1] = glGetUniformLocation(glamor_priv->finish_access_prog[1],
dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb"); "no_revert");
sampler_uniform_location = glamor_priv->finish_access_swap_rb[1] =
dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); dispatch->
dispatch->glUseProgram(glamor_priv->finish_access_prog[1]); glGetUniformLocation(glamor_priv->finish_access_prog[1],
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1],1); "swap_rb");
dispatch->glUniform1i(sampler_uniform_location, 0); sampler_uniform_location =
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1],0); dispatch->
dispatch->glUseProgram(0); glGetUniformLocation(glamor_priv->finish_access_prog[1],
"sampler");
dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1], 1);
dispatch->glUniform1i(sampler_uniform_location, 0);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
dispatch->glUseProgram(0);
} }
void void
glamor_finish_access(DrawablePtr drawable) glamor_finish_access(DrawablePtr drawable)
{ {
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv =
glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return; return;
if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) { if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
glamor_restore_pixmap_to_texture(pixmap); glamor_restore_pixmap_to_texture(pixmap);
} }
if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) { if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
dispatch->glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
pixmap_priv->pbo_valid = FALSE; pixmap_priv->pbo_valid = FALSE;
dispatch->glDeleteBuffers(1, &pixmap_priv->pbo); dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
pixmap_priv->pbo = 0; pixmap_priv->pbo = 0;
} else { } else {
free(pixmap->devPrivate.ptr); free(pixmap->devPrivate.ptr);
} }
pixmap->devPrivate.ptr = NULL; pixmap->devPrivate.ptr = NULL;
} }
@ -265,19 +297,21 @@ glamor_finish_access(DrawablePtr drawable)
Bool Bool
glamor_prepare_access_gc(GCPtr gc) glamor_prepare_access_gc(GCPtr gc)
{ {
if (gc->stipple) { if (gc->stipple) {
if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO)) if (!glamor_prepare_access
return FALSE; (&gc->stipple->drawable, GLAMOR_ACCESS_RO))
} return FALSE;
if (gc->fillStyle == FillTiled) { }
if (!glamor_prepare_access (&gc->tile.pixmap->drawable, if (gc->fillStyle == FillTiled) {
GLAMOR_ACCESS_RO)) { if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
if (gc->stipple) GLAMOR_ACCESS_RO)) {
glamor_finish_access(&gc->stipple->drawable); if (gc->stipple)
return FALSE; glamor_finish_access(&gc->
} stipple->drawable);
} return FALSE;
return TRUE; }
}
return TRUE;
} }
/** /**
@ -286,10 +320,10 @@ glamor_prepare_access_gc(GCPtr gc)
void void
glamor_finish_access_gc(GCPtr gc) glamor_finish_access_gc(GCPtr gc)
{ {
if (gc->fillStyle == FillTiled) if (gc->fillStyle == FillTiled)
glamor_finish_access(&gc->tile.pixmap->drawable); glamor_finish_access(&gc->tile.pixmap->drawable);
if (gc->stipple) if (gc->stipple)
glamor_finish_access(&gc->stipple->drawable); glamor_finish_access(&gc->stipple->drawable);
} }
Bool Bool
@ -299,31 +333,32 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
unsigned long fg_pixel, unsigned long bg_pixel, unsigned long fg_pixel, unsigned long bg_pixel,
int stipple_x, int stipple_y) int stipple_x, int stipple_y)
{ {
glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth); glamor_fallback("stubbed out stipple depth %d\n",
return FALSE; pixmap->drawable.depth);
return FALSE;
} }
GCOps glamor_gc_ops = { GCOps glamor_gc_ops = {
.FillSpans = glamor_fill_spans, .FillSpans = glamor_fill_spans,
.SetSpans = glamor_set_spans, .SetSpans = glamor_set_spans,
.PutImage = glamor_put_image, .PutImage = glamor_put_image,
.CopyArea = glamor_copy_area, .CopyArea = glamor_copy_area,
.CopyPlane = miCopyPlane, .CopyPlane = miCopyPlane,
.PolyPoint = miPolyPoint, .PolyPoint = miPolyPoint,
.Polylines = glamor_poly_lines, .Polylines = glamor_poly_lines,
.PolySegment = miPolySegment, .PolySegment = miPolySegment,
.PolyRectangle = miPolyRectangle, .PolyRectangle = miPolyRectangle,
.PolyArc = miPolyArc, .PolyArc = miPolyArc,
.FillPolygon = miFillPolygon, .FillPolygon = miFillPolygon,
.PolyFillRect = glamor_poly_fill_rect, .PolyFillRect = glamor_poly_fill_rect,
.PolyFillArc = miPolyFillArc, .PolyFillArc = miPolyFillArc,
.PolyText8 = miPolyText8, .PolyText8 = miPolyText8,
.PolyText16 = miPolyText16, .PolyText16 = miPolyText16,
.ImageText8 = miImageText8, .ImageText8 = miImageText8,
.ImageText16 = miImageText16, .ImageText16 = miImageText16,
.ImageGlyphBlt = miImageGlyphBlt, .ImageGlyphBlt = miImageGlyphBlt,
.PolyGlyphBlt = miPolyGlyphBlt, .PolyGlyphBlt = miPolyGlyphBlt,
.PushPixels = miPushPixels, .PushPixels = miPushPixels,
}; };
/** /**
@ -333,91 +368,104 @@ GCOps glamor_gc_ops = {
static void static void
glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
{ {
/* fbValidateGC will do direct access to pixmaps if the tiling has changed. /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
* Preempt fbValidateGC by doing its work and masking the change out, so * Preempt fbValidateGC by doing its work and masking the change out, so
* that we can do the Prepare/finish_access. * that we can do the Prepare/finish_access.
*/ */
#ifdef FB_24_32BIT #ifdef FB_24_32BIT
if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
fbGetRotatedPixmap(gc) = 0; fbGetRotatedPixmap(gc) = 0;
} }
if (gc->fillStyle == FillTiled) { if (gc->fillStyle == FillTiled) {
PixmapPtr old_tile, new_tile; PixmapPtr old_tile, new_tile;
old_tile = gc->tile.pixmap; old_tile = gc->tile.pixmap;
if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { if (old_tile->drawable.bitsPerPixel !=
new_tile = fbGetRotatedPixmap(gc); drawable->bitsPerPixel) {
if (!new_tile || new_tile = fbGetRotatedPixmap(gc);
new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel) if (!new_tile ||
{ new_tile->drawable.bitsPerPixel !=
if (new_tile) drawable->bitsPerPixel) {
gc->pScreen->DestroyPixmap(new_tile); if (new_tile)
/* fb24_32ReformatTile will do direct access of a newly- gc->pScreen->DestroyPixmap
* allocated pixmap. (new_tile);
*/ /* fb24_32ReformatTile will do direct access of a newly-
glamor_fallback("GC %p tile FB_24_32 transformat %p.\n", gc, old_tile); * allocated pixmap.
*/
if (glamor_prepare_access(&old_tile->drawable, glamor_fallback
GLAMOR_ACCESS_RO)) { ("GC %p tile FB_24_32 transformat %p.\n",
new_tile = fb24_32ReformatTile(old_tile, gc, old_tile);
drawable->bitsPerPixel);
glamor_finish_access(&old_tile->drawable); if (glamor_prepare_access
} (&old_tile->drawable,
GLAMOR_ACCESS_RO)) {
new_tile =
fb24_32ReformatTile
(old_tile,
drawable->bitsPerPixel);
glamor_finish_access
(&old_tile->drawable);
}
}
if (new_tile) {
fbGetRotatedPixmap(gc) = old_tile;
gc->tile.pixmap = new_tile;
changes |= GCTile;
}
}
} }
if (new_tile) {
fbGetRotatedPixmap(gc) = old_tile;
gc->tile.pixmap = new_tile;
changes |= GCTile;
}
}
}
#endif #endif
if (changes & GCTile) { if (changes & GCTile) {
if (!gc->tileIsPixel) { if (!gc->tileIsPixel) {
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(gc->tile.pixmap); glamor_pixmap_private *pixmap_priv =
if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) glamor_get_pixmap_private(gc->tile.pixmap);
&& FbEvenTile(gc->tile.pixmap->drawable.width * if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
drawable->bitsPerPixel)) && FbEvenTile(gc->tile.pixmap->drawable.width *
{ drawable->bitsPerPixel)) {
glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap); glamor_fallback
if (glamor_prepare_access(&gc->tile.pixmap->drawable, ("GC %p tile changed %p.\n", gc,
GLAMOR_ACCESS_RW)) { gc->tile.pixmap);
fbPadPixmap(gc->tile.pixmap); if (glamor_prepare_access
glamor_finish_access(&gc->tile.pixmap->drawable); (&gc->tile.pixmap->drawable,
} GLAMOR_ACCESS_RW)) {
} fbPadPixmap(gc->tile.pixmap);
} glamor_finish_access
/* Mask out the GCTile change notification, now that we've done FB's (&gc->tile.pixmap->drawable);
* job for it. }
*/ }
changes &= ~GCTile; }
} /* Mask out the GCTile change notification, now that we've done FB's
* job for it.
*/
changes &= ~GCTile;
}
if (changes & GCStipple && gc->stipple) { if (changes & GCStipple && gc->stipple) {
/* We can't inline stipple handling like we do for GCTile because /* We can't inline stipple handling like we do for GCTile because
* it sets fbgc privates. * it sets fbgc privates.
*/ */
if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access
fbValidateGC(gc, changes, drawable); (&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
glamor_finish_access(&gc->stipple->drawable); fbValidateGC(gc, changes, drawable);
} glamor_finish_access(&gc->stipple->drawable);
} else { }
fbValidateGC(gc, changes, drawable); } else {
} fbValidateGC(gc, changes, drawable);
}
gc->ops = &glamor_gc_ops; gc->ops = &glamor_gc_ops;
} }
static GCFuncs glamor_gc_funcs = { static GCFuncs glamor_gc_funcs = {
glamor_validate_gc, glamor_validate_gc,
miChangeGC, miChangeGC,
miCopyGC, miCopyGC,
miDestroyGC, miDestroyGC,
miChangeClip, miChangeClip,
miDestroyClip, miDestroyClip,
miCopyClip miCopyClip
}; };
/** /**
@ -427,69 +475,68 @@ static GCFuncs glamor_gc_funcs = {
int int
glamor_create_gc(GCPtr gc) glamor_create_gc(GCPtr gc)
{ {
if (!fbCreateGC(gc)) if (!fbCreateGC(gc))
return FALSE; return FALSE;
gc->funcs = &glamor_gc_funcs; gc->funcs = &glamor_gc_funcs;
return TRUE; return TRUE;
} }
RegionPtr RegionPtr
glamor_bitmap_to_region(PixmapPtr pixmap) glamor_bitmap_to_region(PixmapPtr pixmap)
{ {
RegionPtr ret; RegionPtr ret;
glamor_fallback("pixmap %p \n", pixmap); glamor_fallback("pixmap %p \n", pixmap);
if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
return NULL; return NULL;
ret = fbPixmapToRegion(pixmap); ret = fbPixmapToRegion(pixmap);
glamor_finish_access(&pixmap->drawable); glamor_finish_access(&pixmap->drawable);
return ret; return ret;
} }
/* Borrow from cairo. */ /* Borrow from cairo. */
Bool Bool
glamor_gl_has_extension(char *extension) glamor_gl_has_extension(char *extension)
{ {
const char *gl_extensions; const char *gl_extensions;
char *pext; char *pext;
int ext_len; int ext_len;
ext_len = strlen(extension); ext_len = strlen(extension);
gl_extensions = (const char*)glGetString(GL_EXTENSIONS); gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
pext = (char*)gl_extensions; pext = (char *) gl_extensions;
if (pext == NULL || extension == NULL) if (pext == NULL || extension == NULL)
return FALSE; return FALSE;
while((pext = strstr(pext, extension)) != NULL) { while ((pext = strstr(pext, extension)) != NULL) {
if (pext[ext_len] == ' ' || pext[ext_len] == '\0') if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
return TRUE; return TRUE;
pext += ext_len; pext += ext_len;
} }
return FALSE; return FALSE;
} }
int int
glamor_gl_get_version (void) glamor_gl_get_version(void)
{ {
int major, minor; int major, minor;
const char *version = (const char *) glGetString (GL_VERSION); const char *version = (const char *) glGetString(GL_VERSION);
const char *dot = version == NULL ? NULL : strchr (version, '.'); const char *dot = version == NULL ? NULL : strchr(version, '.');
const char *major_start = dot; const char *major_start = dot;
/* Sanity check */ /* Sanity check */
if (dot == NULL || dot == version || *(dot + 1) == '\0') { if (dot == NULL || dot == version || *(dot + 1) == '\0') {
major = 0; major = 0;
minor = 0; minor = 0;
} else { } else {
/* Find the start of the major version in the string */ /* Find the start of the major version in the string */
while (major_start > version && *major_start != ' ') while (major_start > version && *major_start != ' ')
--major_start; --major_start;
major = strtol (major_start, NULL, 10); major = strtol(major_start, NULL, 10);
minor = strtol (dot + 1, NULL, 10); minor = strtol(dot + 1, NULL, 10);
} }
return GLAMOR_GL_VERSION_ENCODE (major, minor); return GLAMOR_GL_VERSION_ENCODE(major, minor);
} }

View File

@ -11,7 +11,8 @@
#define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD 3 #define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD 3
extern void extern void
AbortServer(void) _X_NORETURN; AbortServer(void)
_X_NORETURN;
#define GLAMOR_PANIC(_format_, ...) \ #define GLAMOR_PANIC(_format_, ...) \
do { \ do { \
@ -19,7 +20,7 @@ AbortServer(void) _X_NORETURN;
" at %32s line %d: " _format_ "\n", \ " at %32s line %d: " _format_ "\n", \
__FUNCTION__, __LINE__, \ __FUNCTION__, __LINE__, \
##__VA_ARGS__ ); \ ##__VA_ARGS__ ); \
AbortServer(); \ exit(1); \
} while(0) } while(0)

View File

@ -64,10 +64,15 @@
static const char glamor_name[] = "glamor"; 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;
static void static void
glamor_identify(int flags) 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 { struct glamor_egl_screen_private {
@ -79,47 +84,52 @@ struct glamor_egl_screen_private {
CreateScreenResourcesProcPtr CreateScreenResources; CreateScreenResourcesProcPtr CreateScreenResources;
CloseScreenProcPtr CloseScreen; CloseScreenProcPtr CloseScreen;
int fd; int fd;
int front_buffer_handle; int front_buffer_handle;
int cpp; int cpp;
struct gbm_device *gbm; struct gbm_device *gbm;
PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
struct glamor_gl_dispatch *dispatch; struct glamor_gl_dispatch *dispatch;
}; };
int xf86GlamorEGLPrivateIndex = -1; int xf86GlamorEGLPrivateIndex = -1;
static struct glamor_egl_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn) 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;
} }
static EGLImageKHR static EGLImageKHR
_glamor_create_egl_image(struct glamor_egl_screen_private *glamor_egl, int width, int height, int stride, int name) _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
int width, int height, int stride, int name)
{ {
EGLImageKHR image; EGLImageKHR image;
EGLint attribs[] = { EGLint attribs[] = {
EGL_WIDTH, 0, EGL_WIDTH, 0,
EGL_HEIGHT, 0, EGL_HEIGHT, 0,
EGL_DRM_BUFFER_STRIDE_MESA, 0, EGL_DRM_BUFFER_STRIDE_MESA, 0,
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, EGL_DRM_BUFFER_FORMAT_MESA,
EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA | EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
EGL_DRM_BUFFER_USE_SCANOUT_MESA, EGL_DRM_BUFFER_USE_MESA,
EGL_DRM_BUFFER_USE_SHARE_MESA |
EGL_DRM_BUFFER_USE_SCANOUT_MESA,
EGL_NONE EGL_NONE
}; };
attribs[1] = width; attribs[1] = width;
attribs[3] = height; attribs[3] = height;
attribs[5] = stride / 4; attribs[5] = stride / 4;
image = glamor_egl->egl_create_image_khr (glamor_egl->display, image = glamor_egl->egl_create_image_khr(glamor_egl->display,
glamor_egl->context, glamor_egl->context,
EGL_DRM_BUFFER_MESA, EGL_DRM_BUFFER_MESA,
(void*)name, (void *) name, attribs);
attribs);
if (image == EGL_NO_IMAGE_KHR) if (image == EGL_NO_IMAGE_KHR)
return EGL_NO_IMAGE_KHR; return EGL_NO_IMAGE_KHR;
@ -130,162 +140,198 @@ _glamor_create_egl_image(struct glamor_egl_screen_private *glamor_egl, int width
static int static int
glamor_get_flink_name(int fd, int handle, int *name) glamor_get_flink_name(int fd, int handle, int *name)
{ {
struct drm_gem_flink flink; struct drm_gem_flink flink;
flink.handle = handle; flink.handle = handle;
if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0)
return FALSE; return FALSE;
*name = flink.name; *name = flink.name;
return TRUE; return TRUE;
} }
static Bool static Bool
glamor_create_texture_from_image(struct glamor_egl_screen_private *glamor_egl, EGLImageKHR image, GLuint *texture) glamor_create_texture_from_image(struct glamor_egl_screen_private
*glamor_egl,
EGLImageKHR image, GLuint * texture)
{ {
glamor_egl->dispatch->glGenTextures(1, texture); glamor_egl->dispatch->glGenTextures(1, texture);
glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *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,
glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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->egl_image_target_texture2d_oes) (GL_TEXTURE_2D,
return TRUE; image);
return TRUE;
} }
Bool Bool
glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride) glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
{ {
ScrnInfoPtr scrn = xf86Screens[screen->myNum]; ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
EGLImageKHR image; EGLImageKHR image;
GLuint texture; GLuint texture;
if (!glamor_get_flink_name(glamor_egl->fd, handle, &glamor_egl->front_buffer_handle)) { if (!glamor_get_flink_name
xf86DrvMsg(scrn->scrnIndex, X_ERROR, (glamor_egl->fd, handle, &glamor_egl->front_buffer_handle)) {
"Couldn't flink front buffer handle\n"); xf86DrvMsg(scrn->scrnIndex, X_ERROR,
return FALSE; "Couldn't flink front buffer handle\n");
} return FALSE;
}
if (glamor_egl->root) { if (glamor_egl->root) {
eglDestroyImageKHR(glamor_egl->display, glamor_egl->root); eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
glamor_egl->root = EGL_NO_IMAGE_KHR; glamor_egl->root = EGL_NO_IMAGE_KHR;
} }
image = _glamor_create_egl_image( glamor_egl, image = _glamor_egl_create_image(glamor_egl,
scrn->virtualX, scrn->virtualX,
scrn->virtualY, scrn->virtualY,
stride, stride,
glamor_egl->front_buffer_handle); glamor_egl->front_buffer_handle);
if (image == EGL_NO_IMAGE_KHR) if (image == EGL_NO_IMAGE_KHR)
return FALSE; return FALSE;
glamor_create_texture_from_image(glamor_egl, image, &texture); glamor_create_texture_from_image(glamor_egl, image, &texture);
glamor_set_screen_pixmap_texture(screen, scrn->virtualX, scrn->virtualY, texture); glamor_set_screen_pixmap_texture(screen, scrn->virtualX,
scrn->virtualY, texture);
glamor_egl->root = image; glamor_egl->root = image;
return TRUE; return TRUE;
} }
/* /*
* This function will be called from the dri buffer allocation. * This function will be called from the dri buffer allocation.
* It is somehow very familiar with the create screen image. * It is somehow very familiar with the create textured screen.
* XXX the egl image here is not stored at any data structure. * XXX the egl image here is not stored at any data structure.
* Does this cause a leak problem? * Does this cause a leak problem?
*/ */
Bool Bool
glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride) glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
{ {
ScreenPtr screen = pixmap->drawable.pScreen; ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86Screens[screen->myNum]; ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
EGLImageKHR image; EGLImageKHR image;
GLuint texture; GLuint texture;
int name; int name;
if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) { if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Couldn't flink pixmap handle\n"); "Couldn't flink pixmap handle\n");
return FALSE; return FALSE;
} }
image = _glamor_create_egl_image( glamor_egl,
pixmap->drawable.width,
pixmap->drawable.height,
stride,
name);
if (image == EGL_NO_IMAGE_KHR)
return FALSE;
glamor_create_texture_from_image(glamor_egl, image, &texture); image = _glamor_egl_create_image(glamor_egl,
glamor_set_pixmap_texture(pixmap, pixmap->drawable.width, pixmap->drawable.height, texture); pixmap->drawable.width,
return TRUE; pixmap->drawable.height, stride,
name);
if (image == EGL_NO_IMAGE_KHR) {
ErrorF("Failed to create khr image for bo handle %d.\n", handle);
return FALSE;
}
glamor_create_texture_from_image(glamor_egl, image, &texture);
glamor_set_pixmap_texture(pixmap, pixmap->drawable.width,
pixmap->drawable.height, texture);
dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
image);
return TRUE;
}
void
glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
{
EGLImageKHR image;
ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
if (pixmap->refcnt == 1) {
image = dixLookupPrivate(&pixmap->devPrivates,
glamor_egl_pixmap_private_key);
if (image != EGL_NO_IMAGE_KHR)
eglDestroyImageKHR(glamor_egl->display, image);
}
glamor_destroy_textured_pixmap(pixmap);
} }
Bool Bool
glamor_close_egl_screen(ScreenPtr screen) glamor_egl_close_screen(ScreenPtr screen)
{ {
ScrnInfoPtr scrn = xf86Screens[screen->myNum]; ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
glamor_fini(screen); glamor_fini(screen);
eglDestroyImageKHR(glamor_egl->display, glamor_egl->root); eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
glamor_egl->root = EGL_NO_IMAGE_KHR; glamor_egl->root = EGL_NO_IMAGE_KHR;
return TRUE; return TRUE;
} }
static Bool static Bool
glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, char *extension) glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
char *extension)
{ {
const char *egl_extensions; const char *egl_extensions;
char *pext; char *pext;
int ext_len; int ext_len;
ext_len = strlen(extension); ext_len = strlen(extension);
egl_extensions = (const char*)eglQueryString(glamor_egl->display, EGL_EXTENSIONS); egl_extensions =
pext = (char*)egl_extensions; (const char *) eglQueryString(glamor_egl->display,
EGL_EXTENSIONS);
pext = (char *) egl_extensions;
if (pext == NULL || extension == NULL) if (pext == NULL || extension == NULL)
return FALSE; return FALSE;
while((pext = strstr(pext, extension)) != NULL) { while ((pext = strstr(pext, extension)) != NULL) {
if (pext[ext_len] == ' ' || pext[ext_len] == '\0') if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
return TRUE; return TRUE;
pext += ext_len; pext += ext_len;
} }
return FALSE; return FALSE;
} }
Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) Bool
glamor_egl_init(ScrnInfoPtr scrn, int fd)
{ {
struct glamor_egl_screen_private *glamor_egl; struct glamor_egl_screen_private *glamor_egl;
const char *version; const char *version;
EGLint config_attribs[] = { EGLint config_attribs[] = {
#ifdef GLAMOR_GLES2 #ifdef GLAMOR_GLES2
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_CLIENT_VERSION, 2,
#endif #endif
EGL_NONE EGL_NONE
}; };
glamor_identify(0); glamor_identify(0);
glamor_egl = calloc(sizeof(*glamor_egl), 1); glamor_egl = calloc(sizeof(*glamor_egl), 1);
if (xf86GlamorEGLPrivateIndex == -1) if (xf86GlamorEGLPrivateIndex == -1)
xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); xf86GlamorEGLPrivateIndex =
xf86AllocateScrnInfoPrivateIndex();
scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl; scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
glamor_egl->fd = fd; glamor_egl->fd = fd;
glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd); glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd);
if (glamor_egl->display == EGL_NO_DISPLAY) { if (glamor_egl->display == EGL_NO_DISPLAY) {
glamor_egl->gbm = gbm_create_device(glamor_egl->fd); glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
if (glamor_egl->gbm == NULL) { if (glamor_egl->gbm == NULL) {
ErrorF("couldn't get display device\n"); ErrorF("couldn't get display device\n");
return FALSE; return FALSE;
} }
} }
glamor_egl->display = eglGetDisplay(glamor_egl->gbm); glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
@ -293,7 +339,9 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
#else #else
eglBindAPI(EGL_OPENGL_ES_API); eglBindAPI(EGL_OPENGL_ES_API);
#endif #endif
if (!eglInitialize(glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) { if (!eglInitialize
(glamor_egl->display, &glamor_egl->major, &glamor_egl->minor))
{
xf86DrvMsg(scrn->scrnIndex, X_ERROR, xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"eglInitialize() failed\n"); "eglInitialize() failed\n");
return FALSE; return FALSE;
@ -308,32 +356,34 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
return FALSE; \ return FALSE; \
} }
GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image); GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image); GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
#ifdef GLAMOR_GLES2 #ifdef GLAMOR_GLES2
GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2); GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2);
#else #else
GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl); GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
#endif #endif
glamor_egl->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA) glamor_egl->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)
eglGetProcAddress("eglExportDRMImageMESA"); eglGetProcAddress("eglExportDRMImageMESA");
glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC) glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
eglGetProcAddress("eglCreateImageKHR"); eglGetProcAddress("eglCreateImageKHR");
glamor_egl->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) glamor_egl->egl_image_target_texture2d_oes =
eglGetProcAddress("glEGLImageTargetTexture2DOES"); (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
eglGetProcAddress("glEGLImageTargetTexture2DOES");
if (!glamor_egl->egl_create_image_khr if (!glamor_egl->egl_create_image_khr
|| !glamor_egl->egl_export_drm_image_mesa || !glamor_egl->egl_export_drm_image_mesa
|| !glamor_egl->egl_image_target_texture2d_oes) { || !glamor_egl->egl_image_target_texture2d_oes) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"eglGetProcAddress() failed\n"); "eglGetProcAddress() failed\n");
return FALSE; return FALSE;
} }
glamor_egl->context = eglCreateContext(glamor_egl->display, glamor_egl->context = eglCreateContext(glamor_egl->display,
NULL, EGL_NO_CONTEXT, config_attribs); NULL, EGL_NO_CONTEXT,
config_attribs);
if (glamor_egl->context == EGL_NO_CONTEXT) { if (glamor_egl->context == EGL_NO_CONTEXT) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to create EGL context\n"); "Failed to create EGL context\n");
@ -341,44 +391,59 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
} }
if (!eglMakeCurrent(glamor_egl->display, if (!eglMakeCurrent(glamor_egl->display,
EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) { EGL_NO_SURFACE, EGL_NO_SURFACE,
glamor_egl->context)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to make EGL context current\n"); "Failed to make EGL context current\n");
return FALSE; return FALSE;
} }
return TRUE;
}
Bool
return TRUE; glamor_egl_init_textured_pixmap(ScreenPtr screen)
{
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;
}
return TRUE;
} }
void void
glamor_free_egl_screen(int scrnIndex, int flags) glamor_egl_free_screen(int scrnIndex, int flags)
{ {
ScrnInfoPtr scrn = xf86Screens[scrnIndex]; ScrnInfoPtr scrn = xf86Screens[scrnIndex];
struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
if (glamor_egl != NULL) if (glamor_egl != NULL) {
{ if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) {
if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) { eglMakeCurrent(glamor_egl->display,
eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); EGL_NO_CONTEXT);
eglTerminate(glamor_egl->display); eglTerminate(glamor_egl->display);
} }
free(glamor_egl); free(glamor_egl);
} }
} }
/* egl version. */
Bool Bool
glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version) glamor_gl_dispatch_init(ScreenPtr screen,
struct glamor_gl_dispatch *dispatch,
int gl_version)
{ {
ScrnInfoPtr scrn = xf86Screens[screen->myNum]; ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn); struct glamor_egl_screen_private *glamor_egl =
if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress)) glamor_egl_get_screen_private(scrn);
return FALSE; if (!glamor_gl_dispatch_init_impl
glamor_egl->dispatch = dispatch; (dispatch, gl_version, (get_proc_address_t)eglGetProcAddress))
return TRUE; return FALSE;
glamor_egl->dispatch = dispatch;
return TRUE;
} }

44
glamor/glamor_eglmodule.c Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the XFree86 Project shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization from the
* XFree86 Project.
*/
#include <xorg-server.h>
#include "xf86Module.h"
static XF86ModuleVersionInfo VersRec = {
"glamor_egl",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
1, 0, 0,
ABI_CLASS_ANSIC, /* Only need the ansic layer */
ABI_ANSIC_VERSION,
MOD_CLASS_NONE,
{0, 0, 0, 0} /* signature, to be patched into the file by a tool */
};
_X_EXPORT XF86ModuleData glamor_eglModuleData = { &VersRec, NULL, NULL };

View File

@ -32,174 +32,167 @@
* GC fill implementation, based loosely on fb_fill.c * GC fill implementation, based loosely on fb_fill.c
*/ */
void Bool
glamor_fill(DrawablePtr drawable, glamor_fill(DrawablePtr drawable,
GCPtr gc, GCPtr gc, int x, int y, int width, int height)
int x,
int y,
int width,
int height)
{ {
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
int off_x, off_y; int off_x, off_y;
glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y); glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
switch (gc->fillStyle) { switch (gc->fillStyle) {
case FillSolid: case FillSolid:
if (!glamor_solid(dst_pixmap, if (!glamor_solid(dst_pixmap,
x + off_x, x + off_x,
y + off_y, y + off_y,
width, width, height, gc->alu, gc->planemask,
height, gc->fgPixel))
gc->alu, goto fail;
gc->planemask, break;
gc->fgPixel)) case FillStippled:
goto fail; case FillOpaqueStippled:
break; if (!glamor_stipple(dst_pixmap,
case FillStippled: gc->stipple,
case FillOpaqueStippled: x + off_x,
if (!glamor_stipple(dst_pixmap, y + off_y,
gc->stipple, width,
x + off_x, height,
y + off_y, gc->alu,
width, gc->planemask,
height, gc->fgPixel,
gc->alu, gc->bgPixel, gc->patOrg.x,
gc->planemask, gc->patOrg.y))
gc->fgPixel, goto fail;
gc->bgPixel, break;
gc->patOrg.x, case FillTiled:
gc->patOrg.y)) if (!glamor_tile(dst_pixmap,
goto fail; gc->tile.pixmap,
return; x + off_x,
break; y + off_y,
case FillTiled: width,
if (!glamor_tile(dst_pixmap, height,
gc->tile.pixmap, gc->alu,
x + off_x, gc->planemask,
y + off_y, drawable->x + x + off_x - gc->patOrg.x,
width, drawable->y + y + off_y - gc->patOrg.y))
height, goto fail;
gc->alu, break;
gc->planemask,
drawable->x + x + off_x - gc->patOrg.x,
drawable->y + y + off_y - gc->patOrg.y))
goto fail;
break;
}
return;
fail:
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); return TRUE;
} fail:
return; 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);
}
return TRUE;
} }
void void
glamor_init_solid_shader(ScreenPtr screen) glamor_init_solid_shader(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(screen);
const char *solid_vs = glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
"attribute vec4 v_position;" const char *solid_vs =
"void main()\n" "attribute vec4 v_position;"
"{\n" "void main()\n" "{\n" " gl_Position = v_position;\n"
" gl_Position = v_position;\n" "}\n";
"}\n"; const char *solid_fs =
const char *solid_fs = GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n"
GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" " gl_FragColor = color;\n" "}\n";
"uniform vec4 color;\n" GLint fs_prog, vs_prog;
"void main()\n"
"{\n"
" gl_FragColor = color;\n"
"}\n";
GLint fs_prog, vs_prog;
glamor_priv->solid_prog = dispatch->glCreateProgram(); glamor_priv->solid_prog = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs); vs_prog =
fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs); glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog); fs_prog =
dispatch->glAttachShader(glamor_priv->solid_prog, 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"); dispatch->glBindAttribLocation(glamor_priv->solid_prog,
glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog); GLAMOR_VERTEX_POS, "v_position");
glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
glamor_priv->solid_color_uniform_location = glamor_priv->solid_color_uniform_location =
dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color"); dispatch->glGetUniformLocation(glamor_priv->solid_prog,
"color");
} }
Bool Bool
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, 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; ScreenPtr screen = pixmap->drawable.pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_pixmap_private *pixmap_priv =
int x1 = x; glamor_get_pixmap_private(pixmap);
int x2 = x + width; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int y1 = y; int x1 = x;
int y2 = y + height; int x2 = x + width;
GLfloat color[4]; int y1 = y;
float vertices[8]; int y2 = y + height;
GLfloat xscale, yscale; GLfloat color[4];
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { float vertices[8];
glamor_fallback("dest %p has no fbo.\n", pixmap); GLfloat xscale, yscale;
goto fail; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
} glamor_fallback("dest %p has no fbo.\n", pixmap);
glamor_set_alu(dispatch, alu); goto fail;
if (!glamor_set_planemask(pixmap, planemask)) { }
glamor_fallback("Failedto set planemask in glamor_solid.\n"); glamor_set_alu(dispatch, alu);
goto fail; if (!glamor_set_planemask(pixmap, planemask)) {
} glamor_fallback
("Failedto set planemask in glamor_solid.\n");
goto fail;
}
glamor_get_rgba_from_pixel(fg_pixel, glamor_get_rgba_from_pixel(fg_pixel,
&color[0], &color[0],
&color[1], &color[1],
&color[2], &color[2],
&color[3], &color[3], format_for_pixmap(pixmap));
format_for_pixmap(pixmap));
#ifdef GLAMOR_DELAYED_FILLING #ifdef GLAMOR_DELAYED_FILLING
if (x == 0 && y == 0 if (x == 0 && y == 0
&& width == pixmap->drawable.width && width == pixmap->drawable.width
&& height == pixmap->drawable.height && height == pixmap->drawable.height
&& pixmap_priv->fb != glamor_priv->screen_fbo ) { && pixmap_priv->fb != glamor_priv->screen_fbo) {
pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL; pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
memcpy(&pixmap_priv->pending_op.fill.color4fv, memcpy(&pixmap_priv->pending_op.fill.color4fv,
color, 4*sizeof(GLfloat)); color, 4 * sizeof(GLfloat));
pixmap_priv->pending_op.fill.colori = fg_pixel; pixmap_priv->pending_op.fill.colori = fg_pixel;
return TRUE; return TRUE;
} }
#endif #endif
glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap); glamor_validate_pixmap(pixmap);
dispatch->glUseProgram(glamor_priv->solid_prog); dispatch->glUseProgram(glamor_priv->solid_prog);
dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
1, color);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
2 * sizeof(float), vertices); GL_FALSE, 2 * sizeof(float),
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); vertices);
pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
glamor_priv->yInverted, glamor_priv->yInverted, vertices);
vertices); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glUseProgram(0);
dispatch->glUseProgram(0); return TRUE;
return TRUE; fail:
fail: glamor_set_alu(dispatch, GXcopy);
glamor_set_alu(dispatch, GXcopy); glamor_set_planemask(pixmap, ~0);
glamor_set_planemask(pixmap, ~0); return FALSE;
return FALSE;
} }

View File

@ -32,58 +32,54 @@
void void
glamor_fill_spans(DrawablePtr drawable, glamor_fill_spans(DrawablePtr drawable,
GCPtr gc, GCPtr gc,
int n, int n, DDXPointPtr points, int *widths, int sorted)
DDXPointPtr points,
int *widths,
int sorted)
{ {
DDXPointPtr ppt; DDXPointPtr ppt;
int nbox; int nbox;
BoxPtr pbox; BoxPtr pbox;
int x1, x2, y; int x1, x2, y;
RegionPtr pClip = fbGetCompositeClip(gc); RegionPtr pClip = fbGetCompositeClip(gc);
if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
goto fail; goto fail;
ppt = points; ppt = points;
while (n--) { while (n--) {
x1 = ppt->x; x1 = ppt->x;
y = ppt->y; y = ppt->y;
x2 = x1 + (int)*widths; x2 = x1 + (int) *widths;
ppt++; ppt++;
widths++; widths++;
nbox = REGION_NUM_RECTS(pClip); nbox = REGION_NUM_RECTS(pClip);
pbox = REGION_RECTS(pClip); pbox = REGION_RECTS(pClip);
while (nbox--) { while (nbox--) {
if (pbox->y1 > y || pbox->y2 <= y) if (pbox->y1 > y || pbox->y2 <= y)
continue; continue;
if (x1 < pbox->x1) if (x1 < pbox->x1)
x1 = pbox->x1; x1 = pbox->x1;
if (x2 > pbox->x2) if (x2 > pbox->x2)
x2 = pbox->x2; x2 = pbox->x2;
if (x2 <= x1) if (x2 <= x1)
continue; continue;
glamor_fill (drawable,gc, glamor_fill(drawable, gc, x1, y, x2 - x1, 1);
x1, y, pbox++;
x2 - x1 , 1); }
pbox++; }
} return;
} fail:
return; glamor_fallback("to %p (%c)\n", drawable,
fail: glamor_get_drawable_location(drawable));
glamor_fallback("to %p (%c)\n", drawable, if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
glamor_get_drawable_location(drawable)); if (glamor_prepare_access_gc(gc)) {
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbFillSpans(drawable, gc, n, points, widths,
if (glamor_prepare_access_gc(gc)) { sorted);
fbFillSpans(drawable, gc, n, points, widths, sorted); glamor_finish_access_gc(gc);
glamor_finish_access_gc(gc); }
glamor_finish_access(drawable);
} }
glamor_finish_access(drawable);
}
} }

View File

@ -34,77 +34,73 @@
void void
glamor_get_spans(DrawablePtr drawable, glamor_get_spans(DrawablePtr drawable,
int wmax, int wmax,
DDXPointPtr points, DDXPointPtr points, int *widths, int count, char *dst)
int *widths,
int count,
char *dst)
{ {
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
GLenum format, type; GLenum format, type;
int no_alpha, no_revert; int no_alpha, no_revert;
glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_screen_private *glamor_priv =
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_get_screen_private(drawable->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_pixmap_private *pixmap_priv =
PixmapPtr temp_pixmap = NULL; glamor_get_pixmap_private(pixmap);
int i; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
uint8_t *readpixels_dst = (uint8_t *)dst; PixmapPtr temp_pixmap = NULL;
int x_off, y_off; int i;
uint8_t *readpixels_dst = (uint8_t *) dst;
int x_off, y_off;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
glamor_fallback("pixmap has no fbo.\n"); glamor_fallback("pixmap has no fbo.\n");
goto fail; goto fail;
}
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type,
&no_alpha,
&no_revert
)) {
glamor_fallback("unknown depth. %d \n",
drawable->depth);
goto fail;
}
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
/* XXX prepare whole pixmap is not efficient. */
temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format,
&type, no_alpha, no_revert);
pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
}
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
for (i = 0; i < count; i++) {
if (glamor_priv->yInverted) {
dispatch->glReadPixels(points[i].x + x_off,
(points[i].y + y_off),
widths[i],
1,
format, type,
readpixels_dst);
} else {
dispatch->glReadPixels(points[i].x + x_off,
pixmap->drawable.height - 1 - (points[i].y + y_off),
widths[i],
1,
format, type,
readpixels_dst);
} }
readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
}
if (temp_pixmap)
pixmap->drawable.pScreen->DestroyPixmap(temp_pixmap);
return;
fail: if (glamor_get_tex_format_type_from_pixmap(pixmap,
glamor_fallback("from %p (%c)\n", drawable, &format,
glamor_get_drawable_location(drawable)); &type, &no_alpha,
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) { &no_revert)) {
fbGetSpans(drawable, wmax, points, widths, count, dst); glamor_fallback("unknown depth. %d \n", drawable->depth);
glamor_finish_access(drawable); goto fail;
} }
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
/* XXX prepare whole pixmap is not efficient. */
temp_pixmap =
glamor_es2_pixmap_read_prepare(pixmap, &format,
&type, no_alpha,
no_revert);
pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
}
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
for (i = 0; i < count; i++) {
if (glamor_priv->yInverted) {
dispatch->glReadPixels(points[i].x + x_off,
(points[i].y + y_off),
widths[i], 1, format,
type, readpixels_dst);
} else {
dispatch->glReadPixels(points[i].x + x_off,
pixmap->drawable.height -
1 - (points[i].y + y_off),
widths[i], 1, format,
type, readpixels_dst);
}
readpixels_dst +=
PixmapBytePad(widths[i], drawable->depth);
}
if (temp_pixmap)
pixmap->drawable.pScreen->DestroyPixmap(temp_pixmap);
return;
fail:
glamor_fallback("from %p (%c)\n", drawable,
glamor_get_drawable_location(drawable));
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
fbGetSpans(drawable, wmax, points, widths, count, dst);
glamor_finish_access(drawable);
}
} }

View File

@ -3,71 +3,71 @@
#define INIT_FUNC(dst,func_name,get) \ #define INIT_FUNC(dst,func_name,get) \
dst->func_name = get(#func_name); \ dst->func_name = get(#func_name); \
if (dst->func_name == NULL) \ if (dst->func_name == NULL) \
{ ErrorF("Failed to get fun %s", #func_name); \ { ErrorF("Failed to get function %s", #func_name); \
goto fail; } goto fail; }
Bool _X_EXPORT Bool
glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
int gl_version, int gl_version,
void *(*get_proc_address)(const char*)) void *(*get_proc_address) (const char *))
{ {
INIT_FUNC(dispatch, glMatrixMode, get_proc_address); INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
INIT_FUNC(dispatch, glLoadIdentity, get_proc_address); INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
INIT_FUNC(dispatch, glViewport, get_proc_address); INIT_FUNC(dispatch, glViewport, get_proc_address);
INIT_FUNC(dispatch, glRasterPos2i, get_proc_address); INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
INIT_FUNC(dispatch, glDrawArrays, get_proc_address); INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
INIT_FUNC(dispatch, glReadPixels, get_proc_address); INIT_FUNC(dispatch, glReadPixels, get_proc_address);
INIT_FUNC(dispatch, glDrawPixels, get_proc_address); INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
INIT_FUNC(dispatch, glPixelStorei, get_proc_address); INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
INIT_FUNC(dispatch, glTexParameteri, get_proc_address); INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
INIT_FUNC(dispatch, glTexImage2D, get_proc_address); INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
INIT_FUNC(dispatch, glGenTextures, get_proc_address); INIT_FUNC(dispatch, glGenTextures, get_proc_address);
INIT_FUNC(dispatch, glDeleteTextures, get_proc_address); INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
INIT_FUNC(dispatch, glBindTexture, get_proc_address); INIT_FUNC(dispatch, glBindTexture, get_proc_address);
INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address); INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
INIT_FUNC(dispatch, glFlush, get_proc_address); INIT_FUNC(dispatch, glFlush, get_proc_address);
INIT_FUNC(dispatch, glGetIntegerv, get_proc_address); INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
INIT_FUNC(dispatch, glGetString, get_proc_address); INIT_FUNC(dispatch, glGetString, get_proc_address);
INIT_FUNC(dispatch, glScissor, get_proc_address); INIT_FUNC(dispatch, glScissor, get_proc_address);
INIT_FUNC(dispatch, glEnable, get_proc_address); INIT_FUNC(dispatch, glEnable, get_proc_address);
INIT_FUNC(dispatch, glDisable, get_proc_address); INIT_FUNC(dispatch, glDisable, get_proc_address);
INIT_FUNC(dispatch, glBlendFunc, get_proc_address); INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
INIT_FUNC(dispatch, glLogicOp, get_proc_address); INIT_FUNC(dispatch, glLogicOp, get_proc_address);
INIT_FUNC(dispatch, glActiveTexture, get_proc_address); INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
INIT_FUNC(dispatch, glGenBuffers, get_proc_address); INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
INIT_FUNC(dispatch, glBufferData, get_proc_address); INIT_FUNC(dispatch, glBufferData, get_proc_address);
INIT_FUNC(dispatch, glMapBuffer, get_proc_address); INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address); INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
INIT_FUNC(dispatch, glBindBuffer, get_proc_address); INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address); INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address); INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address); INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address); INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address); INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address); INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address); INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address); INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address); INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address); INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address); INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
INIT_FUNC(dispatch, glLinkProgram, get_proc_address); INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
INIT_FUNC(dispatch, glShaderSource, get_proc_address); INIT_FUNC(dispatch, glShaderSource, get_proc_address);
INIT_FUNC(dispatch, glUseProgram, get_proc_address); INIT_FUNC(dispatch, glUseProgram, get_proc_address);
INIT_FUNC(dispatch, glUniform1i, get_proc_address); INIT_FUNC(dispatch, glUniform1i, get_proc_address);
INIT_FUNC(dispatch, glUniform4f, get_proc_address); INIT_FUNC(dispatch, glUniform4f, get_proc_address);
INIT_FUNC(dispatch, glUniform4fv, get_proc_address); INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
INIT_FUNC(dispatch, glCreateProgram, get_proc_address); INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
INIT_FUNC(dispatch, glCreateShader, get_proc_address); INIT_FUNC(dispatch, glCreateShader, get_proc_address);
INIT_FUNC(dispatch, glCompileShader, get_proc_address); INIT_FUNC(dispatch, glCompileShader, get_proc_address);
INIT_FUNC(dispatch, glAttachShader, get_proc_address); INIT_FUNC(dispatch, glAttachShader, get_proc_address);
INIT_FUNC(dispatch, glGetShaderiv, get_proc_address); INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address); INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
INIT_FUNC(dispatch, glGetProgramiv, get_proc_address); INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address); INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address); INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
return TRUE; return TRUE;
fail: fail:
return FALSE; return FALSE;
} }

View File

@ -1,101 +1,123 @@
typedef struct glamor_gl_dispatch { typedef struct glamor_gl_dispatch {
/* Transformation functions */ /* Transformation functions */
void (*glMatrixMode)(GLenum mode); void (*glMatrixMode) (GLenum mode);
void (*glLoadIdentity)(void); void (*glLoadIdentity) (void);
void (*glViewport)( GLint x, GLint y, void (*glViewport) (GLint x, GLint y, GLsizei width,
GLsizei width, GLsizei height ); GLsizei height);
/* Drawing functions */ /* Drawing functions */
void (*glRasterPos2i)( GLint x, GLint y ); void (*glRasterPos2i) (GLint x, GLint y);
/* Vertex Array */ /* Vertex Array */
void (*glDrawArrays)( GLenum mode, GLint first, GLsizei count ); void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count);
/* Raster functions */ /* Raster functions */
void (*glReadPixels)( GLint x, GLint y, void (*glReadPixels) (GLint x, GLint y,
GLsizei width, GLsizei height, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLenum format, GLenum type, GLvoid * pixels);
GLvoid *pixels );
void (*glDrawPixels)( GLsizei width, GLsizei height, void (*glDrawPixels) (GLsizei width, GLsizei height,
GLenum format, GLenum type, GLenum format, GLenum type,
const GLvoid *pixels ); const GLvoid * pixels);
void (*glPixelStorei)( GLenum pname, GLint param ); void (*glPixelStorei) (GLenum pname, GLint param);
/* Texture Mapping */ /* Texture Mapping */
void (*glTexParameteri)( GLenum target, GLenum pname, GLint param ); void (*glTexParameteri) (GLenum target, GLenum pname, GLint param);
void (*glTexImage2D)( GLenum target, GLint level, void (*glTexImage2D) (GLenum target, GLint level,
GLint internalFormat, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, GLint border, GLenum format, GLenum type,
const GLvoid *pixels ); const GLvoid * pixels);
/* 1.1 */ /* 1.1 */
void (*glGenTextures)( GLsizei n, GLuint *textures ); void (*glGenTextures) (GLsizei n, GLuint * textures);
void (*glDeleteTextures)( GLsizei n, const GLuint *textures); void (*glDeleteTextures) (GLsizei n, const GLuint * textures);
void (*glBindTexture)( GLenum target, GLuint texture ); void (*glBindTexture) (GLenum target, GLuint texture);
void (*glTexSubImage2D)( GLenum target, GLint level, void (*glTexSubImage2D) (GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLenum format, GLenum type,
const GLvoid *pixels ); const GLvoid * pixels);
/* MISC */ /* MISC */
void (*glFlush)( void ); void (*glFlush) (void);
void (*glGetIntegerv)( GLenum pname, GLint *params ); void (*glGetIntegerv) (GLenum pname, GLint * params);
const GLubyte * (*glGetString)( GLenum name ); const GLubyte *(*glGetString) (GLenum name);
void (*glScissor)( GLint x, GLint y, GLsizei width, GLsizei height); void (*glScissor) (GLint x, GLint y, GLsizei width,
void (*glEnable)( GLenum cap ); GLsizei height);
void (*glDisable)( GLenum cap ); void (*glEnable) (GLenum cap);
void (*glBlendFunc)( GLenum sfactor, GLenum dfactor ); void (*glDisable) (GLenum cap);
void (*glLogicOp)( GLenum opcode ); void (*glBlendFunc) (GLenum sfactor, GLenum dfactor);
void (*glLogicOp) (GLenum opcode);
/* 1.3 */ /* 1.3 */
void (*glActiveTexture)( GLenum texture ); void (*glActiveTexture) (GLenum texture);
/* GL Extentions */ /* GL Extentions */
void (*glGenBuffers) (GLsizei n, GLuint *buffers); void (*glGenBuffers) (GLsizei n, GLuint * buffers);
void (*glBufferData) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); void (*glBufferData) (GLenum target, GLsizeiptr size,
GLvoid* (*glMapBuffer) (GLenum target, GLenum access); const GLvoid * data, GLenum usage);
GLboolean (*glUnmapBuffer) (GLenum target); GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
void (*glBindBuffer) (GLenum target, GLuint buffer); GLboolean(*glUnmapBuffer) (GLenum target);
void (*glDeleteBuffers) (GLsizei n, const GLuint *buffers); 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 (*glFramebufferTexture2D) (GLenum target, GLenum attachment,
void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); GLenum textarget, GLuint texture,
void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers); GLint level);
void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers); void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
GLenum (*glCheckFramebufferStatus) (GLenum target); void (*glDeleteFramebuffers) (GLsizei n,
void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); 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 (*glVertexAttribPointer) (GLuint index, GLint size,
void (*glDisableVertexAttribArray) (GLuint index); GLenum type, GLboolean normalized,
void (*glEnableVertexAttribArray) (GLuint index); GLsizei stride,
void (*glBindAttribLocation) (GLuint program, GLuint index, const GLchar *name); 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 (*glLinkProgram) (GLuint program);
void (*glShaderSource) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); void (*glShaderSource) (GLuint shader, GLsizei count,
void (*glUseProgram) (GLuint program); const GLchar * *string,
void (*glUniform1i) (GLint location, GLint v0); const GLint * length);
void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); void (*glUseProgram) (GLuint program);
void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat *value); void (*glUniform1i) (GLint location, GLint v0);
GLuint (*glCreateProgram) (void); void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
GLuint (*glCreateShader) (GLenum type); GLfloat v2, GLfloat v3);
void (*glCompileShader) (GLuint shader); void (*glUniform4fv) (GLint location, GLsizei count,
void (*glAttachShader) (GLuint program, GLuint shader); const GLfloat * value);
void (*glGetShaderiv) (GLuint shader, GLenum pname, GLint *params); GLuint(*glCreateProgram) (void);
void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); GLuint(*glCreateShader) (GLenum type);
void (*glGetProgramiv) (GLuint program, GLenum pname, GLint *params); void (*glCompileShader) (GLuint shader);
void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); void (*glAttachShader) (GLuint program, GLuint shader);
GLint (*glGetUniformLocation) (GLuint program, const GLchar *name); 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; } glamor_gl_dispatch;
Bool
typedef void *(*get_proc_address_t) (const char *);
_X_EXPORT Bool
glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
int gl_version, int gl_version,
void *(*get_proc_address)(const char*)); get_proc_address_t get_proc_address);
Bool
glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version);
_X_EXPORT Bool
glamor_gl_dispatch_init(ScreenPtr screen,
struct glamor_gl_dispatch *dispatch,
int gl_version);

File diff suppressed because it is too large Load Diff

View File

@ -12,33 +12,33 @@
enum glamor_pixmap_status enum glamor_pixmap_status
glamor_upload_picture_to_texture(PicturePtr picture) glamor_upload_picture_to_texture(PicturePtr picture)
{ {
PixmapPtr pixmap; PixmapPtr pixmap;
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
assert(picture->pDrawable); assert(picture->pDrawable);
pixmap = glamor_get_drawable_pixmap(picture->pDrawable); pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv = glamor_get_pixmap_private(pixmap);
assert(GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) == 1); assert(GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) == 1);
return glamor_upload_pixmap_to_texture(pixmap); return glamor_upload_pixmap_to_texture(pixmap);
} }
Bool Bool
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
{ {
if (!picture || !picture->pDrawable) if (!picture || !picture->pDrawable)
return TRUE; return TRUE;
return glamor_prepare_access(picture->pDrawable, access); return glamor_prepare_access(picture->pDrawable, access);
} }
void void
glamor_finish_access_picture(PicturePtr picture) glamor_finish_access_picture(PicturePtr picture)
{ {
if (!picture || !picture->pDrawable) if (!picture || !picture->pDrawable)
return; return;
glamor_finish_access(picture->pDrawable); glamor_finish_access(picture->pDrawable);
} }
/* /*
@ -49,45 +49,48 @@ glamor_finish_access_picture(PicturePtr picture)
int int
glamor_create_picture(PicturePtr picture) glamor_create_picture(PicturePtr picture)
{ {
PixmapPtr pixmap; PixmapPtr pixmap;
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv; glamor_screen_private *glamor_priv;
if (!picture || !picture->pDrawable) if (!picture || !picture->pDrawable)
return 0; return 0;
glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen); glamor_priv =
pixmap = glamor_get_drawable_pixmap(picture->pDrawable); glamor_get_screen_private(picture->pDrawable->pScreen);
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
assert(pixmap_priv); pixmap_priv = glamor_get_pixmap_private(pixmap);
assert(pixmap_priv);
pixmap_priv->is_picture = 1; pixmap_priv->is_picture = 1;
pixmap_priv->pict_format = picture->format; pixmap_priv->pict_format = picture->format;
return glamor_priv->saved_create_picture(picture); return glamor_priv->saved_create_picture(picture);
} }
void void
glamor_destroy_picture(PicturePtr picture) glamor_destroy_picture(PicturePtr picture)
{ {
PixmapPtr pixmap; PixmapPtr pixmap;
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv; glamor_screen_private *glamor_priv;
if (!picture || !picture->pDrawable) if (!picture || !picture->pDrawable)
return; return;
glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen); glamor_priv =
pixmap = glamor_get_drawable_pixmap(picture->pDrawable); glamor_get_screen_private(picture->pDrawable->pScreen);
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
assert(pixmap_priv); pixmap_priv = glamor_get_pixmap_private(pixmap);
assert(pixmap_priv);
pixmap_priv->is_picture = 0; pixmap_priv->is_picture = 0;
pixmap_priv->pict_format = 0; pixmap_priv->pict_format = 0;
glamor_priv->saved_destroy_picture(picture); glamor_priv->saved_destroy_picture(picture);
} }
void glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv) void
glamor_picture_format_fixup(PicturePtr picture,
glamor_pixmap_private * pixmap_priv)
{ {
pixmap_priv->pict_format = picture->format; pixmap_priv->pict_format = picture->format;
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,821 @@
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdlib.h>
#include "glamor_priv.h"
/**
* Sets the offsets to add to coordinates to make them address the same bits in
* the backing drawable. These coordinates are nonzero only for redirected
* windows.
*/
void
glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
int *x, int *y)
{
#ifdef COMPOSITE
if (drawable->type == DRAWABLE_WINDOW) {
*x = -pixmap->screen_x;
*y = -pixmap->screen_y;
return;
}
#endif
*x = 0;
*y = 0;
}
static void
_glamor_pixmap_validate_filling(glamor_screen_private * glamor_priv,
glamor_pixmap_private * pixmap_priv)
{
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
GLfloat vertices[8];
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float),
vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glUseProgram(glamor_priv->solid_prog);
dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
1, pixmap_priv->pending_op.fill.color4fv);
vertices[0] = -1;
vertices[1] = -1;
vertices[2] = 1;
vertices[3] = -1;
vertices[4] = 1;
vertices[5] = 1;
vertices[6] = -1;
vertices[7] = 1;
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glUseProgram(0);
pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
}
glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
NULL,
_glamor_pixmap_validate_filling
};
void
glamor_pixmap_init(ScreenPtr screen)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
}
void
glamor_validate_pixmap(PixmapPtr pixmap)
{
glamor_pixmap_validate_function_t validate_op;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
validate_op =
glamor_priv->pixmap_validate_funcs[pixmap_priv->
pending_op.type];
if (validate_op) {
(*validate_op) (glamor_priv, pixmap_priv);
}
}
void
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
{
glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
#ifndef GLAMOR_GLES2
dispatch->glMatrixMode(GL_PROJECTION);
dispatch->glLoadIdentity();
dispatch->glMatrixMode(GL_MODELVIEW);
dispatch->glLoadIdentity();
#endif
dispatch->glViewport(0, 0,
pixmap_priv->container->drawable.width,
pixmap_priv->container->drawable.height);
}
int
glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv)
{
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return -1;
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
return 0;
}
int
glamor_set_destination_pixmap(PixmapPtr pixmap)
{
int err;
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
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;
}
glamor_fallback("unsupported planemask %lx\n", planemask);
return GL_FALSE;
}
void
glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
{
#ifndef GLAMOR_GLES2
if (alu == GXcopy) {
dispatch->glDisable(GL_COLOR_LOGIC_OP);
return;
}
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:
FatalError("unknown logic op\n");
}
#else
if (alu != GXcopy)
ErrorF("unsupported alu %x \n", alu);
#endif
}
/**
* Upload pixmap to a specified texture.
* This texture may not be the one attached to it.
**/
int in_restore = 0;
static void
__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
GLenum type, GLuint tex)
{
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
unsigned int stride, row_length;
void *texels;
GLenum iformat;
switch (pixmap->drawable.depth) {
#if 0
case 8:
iformat = GL_ALPHA;
break;
#endif
case 24:
iformat = GL_RGB;
break;
default:
iformat = GL_RGBA;
break;
}
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
iformat = format;
}
stride = pixmap->devKind;
row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
dispatch->glBindTexture(GL_TEXTURE_2D, tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
} else {
dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
texels = NULL;
dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
pixmap_priv->pbo);
} else
texels = pixmap->devPrivate.ptr;
dispatch->glTexImage2D(GL_TEXTURE_2D,
0,
iformat,
pixmap->drawable.width,
pixmap->drawable.height, 0, format, type,
texels);
}
/*
* Load texture from the pixmap's data pointer and then
* draw the texture to the fbo, and flip the y axis.
* */
static void
_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
GLenum type, int no_alpha, int no_revert,
int 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 = &glamor_priv->dispatch;
static float vertices[8] = { -1, -1,
1, -1,
1, 1,
-1, 1
};
static float texcoords[8] = { 0, 1,
1, 1,
1, 0,
0, 0
};
static float texcoords_inv[8] = { 0, 0,
1, 0,
1, 1,
0, 1
};
float *ptexcoords;
GLuint tex;
int need_flip;
need_flip = (flip && !glamor_priv->yInverted);
/* Try fast path firstly, upload the pixmap to the texture attached
* to the fbo directly. */
if (no_alpha == 0 && no_revert == 1 && !need_flip) {
__glamor_upload_pixmap_to_texture(pixmap, format, type,
pixmap_priv->tex);
return;
}
if (need_flip)
ptexcoords = texcoords;
else
ptexcoords = texcoords_inv;
/* Slow path, we need to flip y or wire alpha to 1. */
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);
dispatch->glGenTextures(1, &tex);
__glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
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);
#endif
dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
dispatch->glUniform1i(glamor_priv->
finish_access_no_revert[no_alpha],
no_revert);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
0);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
#ifndef GLAMOR_GLES2
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);
}
void
glamor_pixmap_ensure_fb(PixmapPtr pixmap)
{
int status;
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
if (pixmap_priv->fb == 0)
dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
assert(pixmap_priv->tex != 0);
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, pixmap_priv->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;
}
LogMessageVerb(X_INFO, 0,
"destination is framebuffer incomplete: %s [%#x]\n",
str, status);
assert(0);
}
}
/*
* Prepare to upload a pixmap to texture memory.
* no_alpha equals 1 means the format needs to wire alpha to 1.
* Two condtion need to setup a fbo for a pixmap
* 1. !yInverted, we need to do flip if we are not yInverted.
* 2. no_alpha != 0, we need to wire the alpha.
* */
static int
glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
{
int need_fbo;
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (!glamor_check_fbo_size
(glamor_priv, pixmap->drawable.width, pixmap->drawable.height)
|| !glamor_check_fbo_depth(pixmap->drawable.depth)) {
glamor_fallback
("upload failed reason: bad size or depth %d x %d @depth %d \n",
pixmap->drawable.width, pixmap->drawable.height,
pixmap->drawable.depth);
return -1;
}
if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return 0;
if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted)
need_fbo = 1;
else
need_fbo = 0;
if (pixmap_priv->tex == 0)
dispatch->glGenTextures(1, &pixmap_priv->tex);
if (need_fbo) {
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
pixmap->drawable.width,
pixmap->drawable.height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glamor_pixmap_ensure_fb(pixmap);
}
return 0;
}
enum glamor_pixmap_status
glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
{
GLenum format, type;
int no_alpha, no_revert;
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
glamor_fallback("Unknown pixmap depth %d.\n",
pixmap->drawable.depth);
return GLAMOR_UPLOAD_FAILED;
}
if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
return GLAMOR_UPLOAD_FAILED;
glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
"Uploading pixmap %p %dx%d depth%d.\n",
pixmap,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.depth);
_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
no_revert, 1);
return GLAMOR_UPLOAD_DONE;
}
#if 0
enum glamor_pixmap_status
glamor_upload_pixmap_to_texure_from_data(PixmapPtr pixmap, void *data)
{
enum glamor_pixmap_status upload_status;
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
assert(pixmap_priv->pbo_valid == 0);
assert(pixmap->devPrivate.ptr == NULL);
pixmap->devPrivate.ptr = data;
upload_status = glamor_upload_pixmap_to_texture(pixmap);
pixmap->devPrivate.ptr = NULL;
return upload_status;
}
#endif
void
glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
{
GLenum format, type;
int no_alpha, no_revert;
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
ErrorF("Unknown pixmap depth %d.\n",
pixmap->drawable.depth);
assert(0);
}
in_restore = 1;
_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
no_revert, 1);
in_restore = 0;
}
/*
* as gles2 only support a very small set of color format and
* type when do glReadPixel,
* Before we use glReadPixels to get back a textured pixmap,
* Use shader to convert it to a supported format and thus
* get a new temporary pixmap returned.
* */
PixmapPtr
glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
GLenum * type, int no_alpha, int no_revert)
{
glamor_pixmap_private *source_priv;
glamor_screen_private *glamor_priv;
ScreenPtr screen;
PixmapPtr temp_pixmap;
glamor_pixmap_private *temp_pixmap_priv;
glamor_gl_dispatch *dispatch;
static float vertices[8] = { -1, -1,
1, -1,
1, 1,
-1, 1
};
static float texcoords[8] = { 0, 0,
1, 0,
1, 1,
0, 1
};
int swap_rb = 0;
screen = source->drawable.pScreen;
glamor_priv = glamor_get_screen_private(screen);
source_priv = glamor_get_pixmap_private(source);
dispatch = &glamor_priv->dispatch;
if (*format == GL_BGRA) {
*format = GL_RGBA;
swap_rb = 1;
}
temp_pixmap = (*screen->CreatePixmap) (screen,
source->drawable.width,
source->drawable.height,
source->drawable.depth, 0);
temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
source->drawable.width,
source->drawable.height, 0, *format, *type,
NULL);
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),
texcoords);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
dispatch->glUniform1i(glamor_priv->
finish_access_no_revert[no_alpha],
no_revert);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
swap_rb);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUseProgram(0);
return temp_pixmap;
}
/**
* Move a pixmap to CPU memory.
* The input data is the pixmap's fbo.
* The output data is at pixmap->devPrivate.ptr. We always use pbo
* to read the fbo and then map it to va. If possible, we will use
* it directly as devPrivate.ptr.
* If successfully download a fbo to cpu then return TRUE.
* Otherwise return FALSE.
**/
Bool
glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
{
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
unsigned int stride, row_length, y;
GLenum format, type, gl_access, gl_usage;
int no_alpha, no_revert;
uint8_t *data = NULL, *read;
PixmapPtr temp_pixmap = NULL;
ScreenPtr screen;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
screen = pixmap->drawable.pScreen;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return TRUE;
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
ErrorF("Unknown pixmap depth %d.\n",
pixmap->drawable.depth);
assert(0); // Should never happen.
return FALSE;
}
pixmap_priv->access_mode = access;
glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
"Downloading pixmap %p %dx%d depth%d\n",
pixmap,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.depth);
stride = pixmap->devKind;
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
/* XXX we may don't need to validate it on GPU here,
* we can just validate it on CPU. */
glamor_validate_pixmap(pixmap);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
&&
((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA)
|| no_revert != 1)) {
temp_pixmap =
glamor_es2_pixmap_read_prepare(pixmap, &format,
&type, no_alpha,
no_revert);
}
switch (access) {
case GLAMOR_ACCESS_RO:
gl_access = GL_READ_ONLY;
gl_usage = GL_STREAM_READ;
break;
case GLAMOR_ACCESS_WO:
data = malloc(stride * pixmap->drawable.height);
goto done;
break;
case GLAMOR_ACCESS_RW:
gl_access = GL_READ_WRITE;
gl_usage = GL_DYNAMIC_DRAW;
break;
default:
ErrorF("Glamor: Invalid access code. %d\n", access);
assert(0);
}
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
data = malloc(stride * pixmap->drawable.height);
}
row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
} else {
dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
// dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
}
if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
if (!glamor_priv->yInverted) {
assert(glamor_priv->gl_flavor ==
GLAMOR_GL_DESKTOP);
dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
}
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
if (pixmap_priv->pbo == 0)
dispatch->glGenBuffers(1,
&pixmap_priv->pbo);
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
pixmap_priv->pbo);
dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
stride *
pixmap->drawable.height,
NULL, gl_usage);
dispatch->glReadPixels(0, 0, row_length,
pixmap->drawable.height,
format, type, 0);
data = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
gl_access);
pixmap_priv->pbo_valid = TRUE;
if (!glamor_priv->yInverted) {
assert(glamor_priv->gl_flavor ==
GLAMOR_GL_DESKTOP);
dispatch->glPixelStorei
(GL_PACK_INVERT_MESA, 0);
}
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
} else {
if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
type = GL_UNSIGNED_SHORT_5_5_5_1;
dispatch->glReadPixels(0, 0,
pixmap->drawable.width,
pixmap->drawable.height,
format, type, data);
}
} else {
data = malloc(stride * pixmap->drawable.height);
assert(data);
if (access != GLAMOR_ACCESS_WO) {
if (pixmap_priv->pbo == 0)
dispatch->glGenBuffers(1,
&pixmap_priv->pbo);
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
pixmap_priv->pbo);
dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
stride *
pixmap->drawable.height,
NULL, GL_STREAM_READ);
dispatch->glReadPixels(0, 0, row_length,
pixmap->drawable.height,
format, type, 0);
read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
GL_READ_ONLY);
for (y = 0; y < pixmap->drawable.height; y++)
memcpy(data + y * stride,
read + (pixmap->drawable.height -
y - 1) * stride, stride);
dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
pixmap_priv->pbo_valid = FALSE;
dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
pixmap_priv->pbo = 0;
}
}
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
done:
pixmap->devPrivate.ptr = data;
if (temp_pixmap) {
(*screen->DestroyPixmap) (temp_pixmap);
}
return TRUE;
}
static void
_glamor_destroy_upload_pixmap(PixmapPtr pixmap)
{
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
assert(pixmap_priv->gl_fbo == 0);
if (pixmap_priv->fb)
dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
if (pixmap_priv->tex)
dispatch->glDeleteTextures(1, &pixmap_priv->tex);
if (pixmap_priv->pbo)
dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
}
void
glamor_destroy_upload_pixmap(PixmapPtr pixmap)
{
_glamor_destroy_upload_pixmap(pixmap);
}

View File

@ -39,72 +39,69 @@
void void
glamor_poly_fill_rect(DrawablePtr drawable, glamor_poly_fill_rect(DrawablePtr drawable,
GCPtr gc, GCPtr gc, int nrect, xRectangle * prect)
int nrect,
xRectangle *prect)
{ {
int fullX1, fullX2, fullY1, fullY2; int fullX1, fullX2, fullY1, fullY2;
int xorg, yorg; int xorg, yorg;
int n; int n;
register BoxPtr pbox; register BoxPtr pbox;
RegionPtr pClip = fbGetCompositeClip(gc);
if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
goto fail;
}
xorg = drawable->x; RegionPtr pClip = fbGetCompositeClip(gc);
yorg = drawable->y; if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
goto fail;
while (nrect--) {
fullX1 = prect->x + xorg;
fullY1 = prect->y + yorg;
fullX2 = fullX1 + (int)prect->width;
fullY2 = fullY1 + (int)prect->height;
prect++;
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;
pbox++;
if (x1 >= x2 || y1 >= y2)
continue;
glamor_fill(drawable,
gc,
x1,
y1,
x2 - x1,
y2 - y1);
}
}
return;
fail:
glamor_fallback(" to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable));
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
if (glamor_prepare_access_gc(gc)) {
fbPolyFillRect(drawable, gc, nrect, prect );
glamor_finish_access_gc(gc);
} }
glamor_finish_access(drawable);
} 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;
prect++;
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;
pbox++;
if (x1 >= x2 || y1 >= y2)
continue;
if (!glamor_fill(drawable, gc, x1, y1, x2 - x1,
y2 - y1))
goto fail;
}
}
return;
fail:
glamor_fallback(" to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable));
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
if (glamor_prepare_access_gc(gc)) {
fbPolyFillRect(drawable, gc, nrect, prect);
glamor_finish_access_gc(gc);
}
glamor_finish_access(drawable);
}
return;
} }

View File

@ -46,134 +46,130 @@ void
glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
DDXPointPtr points) DDXPointPtr points)
{ {
xRectangle *rects; xRectangle *rects;
int x1, x2, y1, y2; int x1, x2, y1, y2;
int i; int i;
int x_min = MAXSHORT; int x_min = MAXSHORT;
int x_max = MINSHORT; int x_max = MINSHORT;
int y_min = MAXSHORT; int y_min = MAXSHORT;
int y_max = MINSHORT; int y_max = MINSHORT;
DrawablePtr temp_dest; DrawablePtr temp_dest;
PixmapPtr temp_pixmap; PixmapPtr temp_pixmap;
GCPtr temp_gc = NULL; GCPtr temp_gc = NULL;
/* Don't try to do wide lines or non-solid fill style. */ /* Don't try to do wide lines or non-solid fill style. */
if (gc->lineWidth != 0) { if (gc->lineWidth != 0) {
/* This ends up in miSetSpans, which is accelerated as well as we /* This ends up in miSetSpans, which is accelerated as well as we
* can hope X wide lines will be. * can hope X wide lines will be.
*/ */
goto fail; goto fail;
} }
if (gc->lineStyle != LineSolid || if (gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) {
gc->fillStyle != FillSolid) { glamor_fallback
glamor_fallback("non-solid fill line style %d, fill style %d\n", ("non-solid fill line style %d, fill style %d\n",
gc->lineStyle, gc->fillStyle); gc->lineStyle, gc->fillStyle);
goto fail; goto fail;
} }
rects = malloc(sizeof(xRectangle) * (n - 1)); rects = malloc(sizeof(xRectangle) * (n - 1));
x1 = points[0].x; x1 = points[0].x;
y1 = points[0].y; y1 = points[0].y;
/* If we have any non-horizontal/vertical, fall back. */ /* If we have any non-horizontal/vertical, fall back. */
for (i = 0; i < n - 1; i++) { for (i = 0; i < n - 1; i++) {
if (mode == CoordModePrevious) { if (mode == CoordModePrevious) {
x2 = x1 + points[i + 1].x; x2 = x1 + points[i + 1].x;
y2 = y1 + points[i + 1].y; 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;
fail:
for (i = 0; i < n; i++) {
if (x_min > points[i].x)
x_min = points[i].x;
if (x_max < points[i].x)
x_max = points[i].x;
if (y_min > points[i].y)
y_min = points[i].y;
if (y_max < points[i].y)
y_max = points[i].y;
}
temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen,
x_max - x_min + 1,
y_max - y_min + 1,
drawable->depth, 0);
if (temp_pixmap) {
temp_dest = &temp_pixmap->drawable;
temp_gc =
GetScratchGC(temp_dest->depth, temp_dest->pScreen);
ValidateGC(temp_dest, temp_gc);
for (i = 0; i < n; i++) {
points[i].x -= x_min;
points[i].y -= y_min;
}
(void) glamor_copy_area(drawable,
temp_dest,
temp_gc,
x_min, y_min,
x_max - x_min + 1,
y_max - y_min + 1, 0, 0);
} else
temp_dest = drawable;
if (gc->lineWidth == 0) {
if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) {
if (glamor_prepare_access_gc(gc)) {
fbPolyLine(temp_dest, gc, mode, n, points);
glamor_finish_access_gc(gc);
}
glamor_finish_access(temp_dest);
}
} else { } else {
x2 = points[i + 1].x; /* fb calls mi functions in the lineWidth != 0 case. */
y2 = points[i + 1].y; fbPolyLine(drawable, gc, mode, n, points);
} }
if (x1 != x2 && y1 != y2) { if (temp_dest != drawable) {
free(rects); (void) glamor_copy_area(temp_dest,
glamor_fallback("stub diagonal poly_line\n"); drawable,
goto fail; temp_gc,
0, 0,
x_max - x_min + 1,
y_max - y_min + 1, x_min, y_min);
drawable->pScreen->DestroyPixmap(temp_pixmap);
for (i = 0; i < n; i++) {
points[i].x += x_min;
points[i].y += y_min;
}
FreeScratchGC(temp_gc);
} }
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;
fail:
for(i = 0; i < n; i++)
{
if (x_min > points[i].x)
x_min = points[i].x;
if (x_max < points[i].x)
x_max = points[i].x;
if (y_min > points[i].y)
y_min = points[i].y;
if (y_max < points[i].y)
y_max = points[i].y;
}
temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen,
x_max - x_min + 1, y_max - y_min + 1,
drawable->depth,
0);
if (temp_pixmap) {
temp_dest = &temp_pixmap->drawable;
temp_gc = GetScratchGC(temp_dest->depth, temp_dest->pScreen);
ValidateGC(temp_dest, temp_gc);
for(i = 0; i < n; i++)
{
points[i].x -= x_min;
points[i].y -= y_min;
}
(void)glamor_copy_area(drawable,
temp_dest,
temp_gc,
x_min, y_min,
x_max - x_min + 1, y_max - y_min + 1,
0, 0);
}
else
temp_dest = drawable;
if (gc->lineWidth == 0) {
if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) {
if (glamor_prepare_access_gc(gc)) {
fbPolyLine(temp_dest, gc, mode, n, points);
glamor_finish_access_gc(gc);
}
glamor_finish_access(temp_dest);
}
}
else {
/* fb calls mi functions in the lineWidth != 0 case. */
fbPolyLine(drawable, gc, mode, n, points);
}
if (temp_dest != drawable) {
(void)glamor_copy_area(temp_dest,
drawable,
temp_gc,
0, 0,
x_max - x_min + 1, y_max - y_min + 1,
x_min, y_min);
drawable->pScreen->DestroyPixmap(temp_pixmap);
for(i = 0; i < n; i++)
{
points[i].x += x_min;
points[i].y += y_min;
}
FreeScratchGC(temp_gc);
}
} }

View File

@ -31,7 +31,7 @@
#include <dix-config.h> #include <dix-config.h>
#include <xorg-config.h> #include <xorg-config.h>
#endif #endif
#include <xorg-server.h>
#include "glamor.h" #include "glamor.h"
@ -56,63 +56,66 @@
#include "glamor_debug.h" #include "glamor_debug.h"
typedef struct glamor_composite_shader { typedef struct glamor_composite_shader {
GLuint prog; GLuint prog;
GLint dest_to_dest_uniform_location; GLint dest_to_dest_uniform_location;
GLint dest_to_source_uniform_location; GLint dest_to_source_uniform_location;
GLint dest_to_mask_uniform_location; GLint dest_to_mask_uniform_location;
GLint source_uniform_location; GLint source_uniform_location;
GLint mask_uniform_location; GLint mask_uniform_location;
} glamor_composite_shader; } glamor_composite_shader;
typedef struct { typedef struct {
INT16 x_src; INT16 x_src;
INT16 y_src; INT16 y_src;
INT16 x_mask; INT16 x_mask;
INT16 y_mask; INT16 y_mask;
INT16 x_dst; INT16 x_dst;
INT16 y_dst; INT16 y_dst;
INT16 width; INT16 width;
INT16 height; INT16 height;
} glamor_composite_rect_t; } glamor_composite_rect_t;
enum glamor_vertex_type { enum glamor_vertex_type {
GLAMOR_VERTEX_POS, GLAMOR_VERTEX_POS,
GLAMOR_VERTEX_SOURCE, GLAMOR_VERTEX_SOURCE,
GLAMOR_VERTEX_MASK GLAMOR_VERTEX_MASK
}; };
enum shader_source { enum shader_source {
SHADER_SOURCE_SOLID, SHADER_SOURCE_SOLID,
SHADER_SOURCE_TEXTURE, SHADER_SOURCE_TEXTURE,
SHADER_SOURCE_TEXTURE_ALPHA, SHADER_SOURCE_TEXTURE_ALPHA,
SHADER_SOURCE_COUNT, SHADER_SOURCE_COUNT,
}; };
enum shader_mask { enum shader_mask {
SHADER_MASK_NONE, SHADER_MASK_NONE,
SHADER_MASK_SOLID, SHADER_MASK_SOLID,
SHADER_MASK_TEXTURE, SHADER_MASK_TEXTURE,
SHADER_MASK_TEXTURE_ALPHA, SHADER_MASK_TEXTURE_ALPHA,
SHADER_MASK_COUNT, SHADER_MASK_COUNT,
}; };
enum shader_in { enum shader_in {
SHADER_IN_SOURCE_ONLY, SHADER_IN_SOURCE_ONLY,
SHADER_IN_NORMAL, SHADER_IN_NORMAL,
SHADER_IN_CA_SOURCE, SHADER_IN_CA_SOURCE,
SHADER_IN_CA_ALPHA, SHADER_IN_CA_ALPHA,
SHADER_IN_COUNT, SHADER_IN_COUNT,
}; };
struct glamor_screen_private; struct glamor_screen_private;
struct glamor_pixmap_private; struct glamor_pixmap_private;
typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, typedef void (*glamor_pixmap_validate_function_t) (struct
struct glamor_pixmap_private*); glamor_screen_private *,
struct
glamor_pixmap_private
*);
enum glamor_gl_flavor { enum glamor_gl_flavor {
GLAMOR_GL_DESKTOP, // OPENGL API GLAMOR_GL_DESKTOP, // OPENGL API
GLAMOR_GL_ES2 // OPENGL ES2.0 API GLAMOR_GL_ES2 // OPENGL ES2.0 API
}; };
#define GLAMOR_CREATE_PIXMAP_CPU 0x100 #define GLAMOR_CREATE_PIXMAP_CPU 0x100
@ -121,98 +124,97 @@ enum glamor_gl_flavor {
#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
typedef struct { typedef struct {
PicturePtr picture; /* Where the glyphs of the cache are stored */ PicturePtr picture; /* Where the glyphs of the cache are stored */
GlyphPtr *glyphs; GlyphPtr *glyphs;
uint16_t count; uint16_t count;
uint16_t evict; uint16_t evict;
} glamor_glyph_cache_t; } glamor_glyph_cache_t;
#include "glamor_gl_dispatch.h" #include "glamor_gl_dispatch.h"
typedef struct glamor_screen_private { typedef struct glamor_screen_private {
CloseScreenProcPtr saved_close_screen; CloseScreenProcPtr saved_close_screen;
CreateGCProcPtr saved_create_gc; CreateGCProcPtr saved_create_gc;
CreatePixmapProcPtr saved_create_pixmap; CreatePixmapProcPtr saved_create_pixmap;
DestroyPixmapProcPtr saved_destroy_pixmap; DestroyPixmapProcPtr saved_destroy_pixmap;
GetSpansProcPtr saved_get_spans; GetSpansProcPtr saved_get_spans;
GetImageProcPtr saved_get_image; GetImageProcPtr saved_get_image;
CompositeProcPtr saved_composite; CompositeProcPtr saved_composite;
TrapezoidsProcPtr saved_trapezoids; TrapezoidsProcPtr saved_trapezoids;
GlyphsProcPtr saved_glyphs; GlyphsProcPtr saved_glyphs;
ChangeWindowAttributesProcPtr saved_change_window_attributes; ChangeWindowAttributesProcPtr saved_change_window_attributes;
CopyWindowProcPtr saved_copy_window; CopyWindowProcPtr saved_copy_window;
BitmapToRegionProcPtr saved_bitmap_to_region; BitmapToRegionProcPtr saved_bitmap_to_region;
TrianglesProcPtr saved_triangles; TrianglesProcPtr saved_triangles;
CreatePictureProcPtr saved_create_picture; CreatePictureProcPtr saved_create_picture;
DestroyPictureProcPtr saved_destroy_picture; DestroyPictureProcPtr saved_destroy_picture;
UnrealizeGlyphProcPtr saved_unrealize_glyph; UnrealizeGlyphProcPtr saved_unrealize_glyph;
int yInverted; int yInverted;
int screen_fbo; int screen_fbo;
GLuint vbo; GLuint vbo;
int vbo_offset; int vbo_offset;
int vbo_size; int vbo_size;
char *vb; char *vb;
int vb_stride; int vb_stride;
enum glamor_gl_flavor gl_flavor; enum glamor_gl_flavor gl_flavor;
int has_pack_invert; int has_pack_invert;
int has_fbo_blit; int has_fbo_blit;
int max_fbo_size; int max_fbo_size;
/* glamor_finishaccess */ /* glamor_finishaccess */
GLint finish_access_prog[2]; GLint finish_access_prog[2];
GLint finish_access_no_revert[2]; GLint finish_access_no_revert[2];
GLint finish_access_swap_rb[2]; GLint finish_access_swap_rb[2];
/* glamor_solid */ /* glamor_solid */
GLint solid_prog; GLint solid_prog;
GLint solid_color_uniform_location; GLint solid_color_uniform_location;
/* glamor_tile */ /* glamor_tile */
GLint tile_prog; GLint tile_prog;
/* glamor_putimage */ /* glamor_putimage */
GLint put_image_xybitmap_prog; GLint put_image_xybitmap_prog;
GLint put_image_xybitmap_fg_uniform_location; GLint put_image_xybitmap_fg_uniform_location;
GLint put_image_xybitmap_bg_uniform_location; GLint put_image_xybitmap_bg_uniform_location;
/* glamor_composite */ /* glamor_composite */
glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
[SHADER_MASK_COUNT] [SHADER_MASK_COUNT][SHADER_IN_COUNT];
[SHADER_IN_COUNT]; Bool has_source_coords, has_mask_coords;
Bool has_source_coords, has_mask_coords; int render_nr_verts;
int render_nr_verts; glamor_pixmap_validate_function_t *pixmap_validate_funcs;
glamor_pixmap_validate_function_t *pixmap_validate_funcs; glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES]; char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; int delayed_fallback_pending;
int delayed_fallback_pending;
glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
Bool glyph_cache_initialized; Bool glyph_cache_initialized;
struct glamor_gl_dispatch dispatch; struct glamor_gl_dispatch dispatch;
} glamor_screen_private; } glamor_screen_private;
typedef enum glamor_access { typedef enum glamor_access {
GLAMOR_ACCESS_RO, GLAMOR_ACCESS_RO,
GLAMOR_ACCESS_RW, GLAMOR_ACCESS_RW,
GLAMOR_ACCESS_WO, GLAMOR_ACCESS_WO,
} glamor_access_t; } glamor_access_t;
enum _glamor_pending_op_type{ enum _glamor_pending_op_type {
GLAMOR_PENDING_NONE, GLAMOR_PENDING_NONE,
GLAMOR_PENDING_FILL GLAMOR_PENDING_FILL
}; };
typedef struct _glamor_pending_fill { typedef struct _glamor_pending_fill {
unsigned int type; unsigned int type;
GLfloat color4fv[4]; GLfloat color4fv[4];
CARD32 colori; CARD32 colori;
} glamor_pending_fill; } glamor_pending_fill;
typedef union _glamor_pending_op { typedef union _glamor_pending_op {
unsigned int type; unsigned int type;
glamor_pending_fill fill; glamor_pending_fill fill;
} glamor_pending_op; } glamor_pending_op;
/* /*
@ -231,18 +233,18 @@ typedef union _glamor_pending_op {
**/ **/
typedef struct glamor_pixmap_private { typedef struct glamor_pixmap_private {
unsigned char gl_fbo:1; unsigned char gl_fbo:1;
unsigned char gl_tex:1; unsigned char gl_tex:1;
unsigned char pbo_valid:1; unsigned char pbo_valid:1;
unsigned char is_picture:1; unsigned char is_picture:1;
GLuint tex; GLuint tex;
GLuint fb; GLuint fb;
GLuint pbo; GLuint pbo;
glamor_access_t access_mode; glamor_access_t access_mode;
PictFormatShort pict_format; PictFormatShort pict_format;
glamor_pending_op pending_op; glamor_pending_op pending_op;
PixmapPtr container; PixmapPtr container;
glamor_screen_private *glamor_priv; glamor_screen_private *glamor_priv;
} glamor_pixmap_private; } glamor_pixmap_private;
/* /*
@ -255,10 +257,10 @@ typedef struct glamor_pixmap_private {
* *
* */ * */
typedef enum glamor_pixmap_status { typedef enum glamor_pixmap_status {
GLAMOR_NONE, GLAMOR_NONE,
GLAMOR_UPLOAD_PENDING, GLAMOR_UPLOAD_PENDING,
GLAMOR_UPLOAD_DONE, GLAMOR_UPLOAD_DONE,
GLAMOR_UPLOAD_FAILED GLAMOR_UPLOAD_FAILED
} glamor_pixmap_status_t; } glamor_pixmap_status_t;
@ -267,13 +269,16 @@ extern DevPrivateKey glamor_pixmap_private_key;
static inline glamor_screen_private * static inline glamor_screen_private *
glamor_get_screen_private(ScreenPtr screen) glamor_get_screen_private(ScreenPtr screen)
{ {
return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates, return (glamor_screen_private *)
glamor_screen_private_key); dixLookupPrivate(&screen->devPrivates,
glamor_screen_private_key);
} }
static inline glamor_pixmap_private * static inline glamor_pixmap_private *
glamor_get_pixmap_private(PixmapPtr pixmap) glamor_get_pixmap_private(PixmapPtr pixmap)
{ {
return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key); return dixLookupPrivate(&pixmap->devPrivates,
glamor_pixmap_private_key);
} }
@ -284,8 +289,8 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
static inline Bool static inline Bool
glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
{ {
return (planemask & FbFullMask(drawable->depth)) == return (planemask & FbFullMask(drawable->depth)) ==
FbFullMask(drawable->depth); FbFullMask(drawable->depth);
} }
extern int glamor_debug_level; extern int glamor_debug_level;
@ -299,19 +304,11 @@ Bool glamor_close_screen(int idx, ScreenPtr screen);
/* glamor_copyarea.c */ /* glamor_copyarea.c */
RegionPtr RegionPtr
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, 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,
void int dsty);
glamor_copy_n_to_n(DrawablePtr src, void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc,
DrawablePtr dst, BoxPtr box, int nbox, int dx, int dy, Bool reverse,
GCPtr gc, 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 */ /* glamor_copywindow.c */
void glamor_copy_window(WindowPtr win, DDXPointRec old_origin, void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
@ -334,30 +331,35 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
unsigned char alu, unsigned long planemask, unsigned char alu, unsigned long planemask,
unsigned long fg_pixel, unsigned long bg_pixel, unsigned long fg_pixel, unsigned long bg_pixel,
int stipple_x, int stipple_y); int stipple_x, int stipple_y);
GLint glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source); GLint glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
void glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog); const char *source);
void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, void glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog);
GLfloat *color); void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
unsigned long fg_pixel,
GLfloat * color);
int glamor_set_destination_pixmap(PixmapPtr pixmap); 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);
/* nc means no check. caller must ensure this pixmap has valid fbo. /* nc means no check. caller must ensure this pixmap has valid fbo.
* usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
* */ * */
void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv); void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *
pixmap_priv);
PixmapPtr PixmapPtr
glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
GLenum *type, int no_alpha, int no_revert); GLenum * type, int no_alpha, int no_revert);
void glamor_set_alu(struct glamor_gl_dispatch * dispatch, unsigned char alu); void glamor_set_alu(struct glamor_gl_dispatch *dispatch,
unsigned char alu);
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask); Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
Bool glamor_gl_has_extension(char *extension); Bool glamor_gl_has_extension(char *extension);
int glamor_gl_get_version(void); int glamor_gl_get_version(void);
#define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \ #define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \
((major) * 256) \ ((major) * 256) \
@ -367,12 +369,8 @@ int glamor_gl_get_version(void);
/* glamor_fill.c */ /* glamor_fill.c */
void glamor_fill(DrawablePtr drawable, Bool glamor_fill(DrawablePtr drawable,
GCPtr gc, GCPtr gc, int x, int y, int width, int height);
int x,
int y,
int width,
int height);
Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask, unsigned char alu, unsigned long planemask,
unsigned long fg_pixel); unsigned long fg_pixel);
@ -381,22 +379,18 @@ void glamor_solid_fail_region(PixmapPtr pixmap,
/* glamor_fillspans.c */ /* glamor_fillspans.c */
void glamor_fill_spans(DrawablePtr drawable, void glamor_fill_spans(DrawablePtr drawable,
GCPtr gc, GCPtr gc,
int n, int n, DDXPointPtr points, int *widths, int sorted);
DDXPointPtr points,
int *widths,
int sorted);
void glamor_init_solid_shader(ScreenPtr screen); void glamor_init_solid_shader(ScreenPtr screen);
/* glamor_getspans.c */ /* glamor_getspans.c */
void void
glamor_get_spans(DrawablePtr drawable, glamor_get_spans(DrawablePtr drawable,
int wmax, int wmax,
DDXPointPtr points, DDXPointPtr points,
int *widths, int *widths, int nspans, char *dst_start);
int nspans,
char *dst_start);
/* glamor_glyphs.c */ /* glamor_glyphs.c */
void glamor_glyphs_fini(ScreenPtr screen); void glamor_glyphs_fini(ScreenPtr screen);
@ -405,10 +399,10 @@ void glamor_glyphs(CARD8 op,
PicturePtr pDst, PicturePtr pDst,
PictFormatPtr maskFormat, PictFormatPtr maskFormat,
INT16 xSrc, INT16 xSrc,
INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs); INT16 ySrc, int nlist, GlyphListPtr list,
GlyphPtr * glyphs);
void void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
glamor_glyph_unrealize (ScreenPtr screen, GlyphPtr glyph);
/* glamor_setspans.c */ /* glamor_setspans.c */
void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, 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);
@ -416,17 +410,17 @@ void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
/* glamor_polyfillrect.c */ /* glamor_polyfillrect.c */
void void
glamor_poly_fill_rect(DrawablePtr drawable, glamor_poly_fill_rect(DrawablePtr drawable,
GCPtr gc, GCPtr gc, int nrect, xRectangle * prect);
int nrect,
xRectangle *prect);
/* glamor_polylines.c */ /* glamor_polylines.c */
void void
glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
DDXPointPtr points); DDXPointPtr points);
/* glamor_putimage.c */ /* glamor_putimage.c */
void void
glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, 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_init_putimage_shaders(ScreenPtr screen);
@ -440,18 +434,16 @@ void glamor_composite(CARD8 op,
INT16 ySrc, INT16 ySrc,
INT16 xMask, INT16 xMask,
INT16 yMask, INT16 yMask,
INT16 xDst, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
INT16 yDst,
CARD16 width,
CARD16 height);
void glamor_trapezoids(CARD8 op, void glamor_trapezoids(CARD8 op,
PicturePtr src, PicturePtr dst, PicturePtr src, PicturePtr dst,
PictFormatPtr mask_format, INT16 x_src, INT16 y_src, PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
int ntrap, xTrapezoid *traps); int ntrap, xTrapezoid * traps);
void glamor_init_composite_shaders(ScreenPtr screen); void glamor_init_composite_shaders(ScreenPtr screen);
void glamor_composite_rects(CARD8 op, void glamor_composite_rects(CARD8 op,
PicturePtr src, PicturePtr mask, PicturePtr dst, PicturePtr src, PicturePtr mask,
int nrect, glamor_composite_rect_t *rects); PicturePtr dst, int nrect,
glamor_composite_rect_t * rects);
/* glamor_tile.c */ /* glamor_tile.c */
Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
@ -462,19 +454,16 @@ void glamor_init_tile_shader(ScreenPtr screen);
/* glamor_triangles.c */ /* glamor_triangles.c */
void void
glamor_triangles (CARD8 op,
PicturePtr pSrc, glamor_triangles(CARD8 op,
PicturePtr pDst, PicturePtr pSrc,
PictFormatPtr maskFormat, PicturePtr pDst,
INT16 xSrc, PictFormatPtr maskFormat,
INT16 ySrc, INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris);
int ntris,
xTriangle *tris);
/* glamor_pixmap.c */ /* glamor_pixmap.c */
void void glamor_pixmap_init(ScreenPtr screen);
glamor_pixmap_init(ScreenPtr screen);
/** /**
* Download a pixmap's texture to cpu memory. If success, * Download a pixmap's texture to cpu memory. If success,
* One copy of current pixmap's texture will be put into * One copy of current pixmap's texture will be put into
@ -484,8 +473,8 @@ glamor_pixmap_init(ScreenPtr screen);
* gl_tex must be 1. Used by glamor_prepare_access. * gl_tex must be 1. Used by glamor_prepare_access.
* *
*/ */
Bool Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap,
glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access); glamor_access_t access);
/** /**
* Restore a pixmap's data which is downloaded by * Restore a pixmap's data which is downloaded by
@ -496,8 +485,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
* in texture originally. In other word, the gl_fbo * in texture originally. In other word, the gl_fbo
* must be 1. * must be 1.
**/ **/
void void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
/** /**
* Ensure to have a fbo attached to the pixmap. * Ensure to have a fbo attached to the pixmap.
* If the pixmap already has one fbo then do nothing. * If the pixmap already has one fbo then do nothing.
@ -506,51 +494,47 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
* The pixmap must has a valid texture before call this * The pixmap must has a valid texture before call this
* API, othersie, it will trigger a assert. * API, othersie, it will trigger a assert.
*/ */
void void glamor_pixmap_ensure_fb(PixmapPtr pixmap);
glamor_pixmap_ensure_fb(PixmapPtr pixmap);
/** /**
* Upload a pixmap to gl texture. Used by dynamic pixmap * Upload a pixmap to gl texture. Used by dynamic pixmap
* uploading feature. The pixmap must be a software pixmap. * uploading feature. The pixmap must be a software pixmap.
* This function will change current FBO and current shaders. * This function will change current FBO and current shaders.
*/ */
enum glamor_pixmap_status enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr
glamor_upload_pixmap_to_texture(PixmapPtr pixmap); pixmap);
/** /**
* Upload a picture to gl texture. Similar to the * Upload a picture to gl texture. Similar to the
* glamor_upload_pixmap_to_texture. Used in rendering. * glamor_upload_pixmap_to_texture. Used in rendering.
**/ **/
enum glamor_pixmap_status enum glamor_pixmap_status
glamor_upload_picture_to_texture(PicturePtr picture); glamor_upload_picture_to_texture(PicturePtr picture);
/** /**
* Destroy all the resources allocated on the uploading * Destroy all the resources allocated on the uploading
* phase, includs the tex and fbo. * phase, includs the tex and fbo.
**/ **/
void void glamor_destroy_upload_pixmap(PixmapPtr pixmap);
glamor_destroy_upload_pixmap(PixmapPtr pixmap);
void void glamor_validate_pixmap(PixmapPtr pixmap);
glamor_validate_pixmap(PixmapPtr pixmap);
int int glamor_create_picture(PicturePtr picture);
glamor_create_picture(PicturePtr picture);
Bool Bool
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
void void glamor_finish_access_picture(PicturePtr picture);
glamor_finish_access_picture(PicturePtr picture);
void void glamor_destroy_picture(PicturePtr picture);
glamor_destroy_picture(PicturePtr picture);
enum glamor_pixmap_status enum glamor_pixmap_status
glamor_upload_picture_to_texture(PicturePtr picture); glamor_upload_picture_to_texture(PicturePtr picture);
void void
glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv);
glamor_picture_format_fixup(PicturePtr picture,
glamor_pixmap_private * pixmap_priv);
#include"glamor_utils.h" #include"glamor_utils.h"
@ -562,8 +546,8 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
* this will increase performance obviously. */ * this will increase performance obviously. */
#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
#define GLAMOR_DELAYED_FILLING //#define GLAMOR_DELAYED_FILLING
#endif /* GLAMOR_PRIV_H */ #endif /* GLAMOR_PRIV_H */

View File

@ -36,56 +36,50 @@ void
glamor_init_putimage_shaders(ScreenPtr screen) glamor_init_putimage_shaders(ScreenPtr screen)
{ {
#if 0 #if 0
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
const char *xybitmap_vs = glamor_get_screen_private(screen);
"uniform float x_bias;\n" const char *xybitmap_vs =
"uniform float x_scale;\n" "uniform float x_bias;\n" "uniform float x_scale;\n"
"uniform float y_bias;\n" "uniform float y_bias;\n" "uniform float y_scale;\n"
"uniform float y_scale;\n" "varying vec2 bitmap_coords;\n" "void main()\n" "{\n"
"varying vec2 bitmap_coords;\n" " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
"void main()\n" " (gl_Vertex.y + y_bias) * y_scale,\n"
"{\n" " 0,\n"
" gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" " 1);\n"
" (gl_Vertex.y + y_bias) * y_scale,\n" " bitmap_coords = gl_MultiTexCoord0.xy;\n" "}\n";
" 0,\n" const char *xybitmap_fs =
" 1);\n" "uniform vec4 fg, bg;\n" "varying vec2 bitmap_coords;\n"
" bitmap_coords = gl_MultiTexCoord0.xy;\n" "uniform sampler2D bitmap_sampler;\n" "void main()\n" "{\n"
"}\n"; " float bitmap_value = texture2D(bitmap_sampler,\n"
const char *xybitmap_fs = " bitmap_coords).x;\n"
"uniform vec4 fg, bg;\n" " gl_FragColor = mix(bg, fg, bitmap_value);\n" "}\n";
"varying vec2 bitmap_coords;\n" GLint fs_prog, vs_prog, prog;
"uniform sampler2D bitmap_sampler;\n" GLint sampler_uniform_location;
"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) if (!GLEW_ARB_fragment_shader)
return; return;
prog = dispatch->glCreateProgram(); prog = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs); vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs); fs_prog =
dispatch->glAttachShader(prog, vs_prog); glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
dispatch->glAttachShader(prog, fs_prog); dispatch->glAttachShader(prog, vs_prog);
glamor_link_glsl_prog(prog); dispatch->glAttachShader(prog, fs_prog);
glamor_link_glsl_prog(prog);
dispatch->glUseProgram(prog); dispatch->glUseProgram(prog);
sampler_uniform_location = dispatch->glGetUniformLocation(prog, "bitmap_sampler"); sampler_uniform_location =
dispatch->glUniform1i(sampler_uniform_location, 0); dispatch->glGetUniformLocation(prog, "bitmap_sampler");
dispatch->glUniform1i(sampler_uniform_location, 0);
glamor_priv->put_image_xybitmap_fg_uniform_location = glamor_priv->put_image_xybitmap_fg_uniform_location =
dispatch->glGetUniformLocation(prog, "fg"); dispatch->glGetUniformLocation(prog, "fg");
glamor_priv->put_image_xybitmap_bg_uniform_location = glamor_priv->put_image_xybitmap_bg_uniform_location =
dispatch->glGetUniformLocation(prog, "bg"); dispatch->glGetUniformLocation(prog, "bg");
glamor_get_transform_uniform_locations(prog, glamor_get_transform_uniform_locations(prog,
&glamor_priv->put_image_xybitmap_transform); &glamor_priv->put_image_xybitmap_transform);
glamor_priv->put_image_xybitmap_prog = prog; glamor_priv->put_image_xybitmap_prog = prog;
dispatch->glUseProgram(0); dispatch->glUseProgram(0);
#endif #endif
} }
@ -106,13 +100,13 @@ glamor_init_putimage_shaders(ScreenPtr screen)
static int static int
y_flip(PixmapPtr pixmap, int y) y_flip(PixmapPtr pixmap, int y)
{ {
ScreenPtr screen = pixmap->drawable.pScreen; ScreenPtr screen = pixmap->drawable.pScreen;
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
if (pixmap == screen_pixmap) if (pixmap == screen_pixmap)
return (pixmap->drawable.height - 1) - y; return (pixmap->drawable.height - 1) - y;
else else
return y; return y;
} }
@ -121,129 +115,127 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
int x, int y, int w, int h, int left_pad, int x, int y, int w, int h, int left_pad,
int image_format, char *bits) int image_format, char *bits)
{ {
ScreenPtr screen = drawable->pScreen; ScreenPtr screen = drawable->pScreen;
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
float fg[4], bg[4]; glamor_get_screen_private(screen);
GLuint tex; float fg[4], bg[4];
unsigned int stride = PixmapBytePad(1, w + left_pad); GLuint tex;
RegionPtr clip; unsigned int stride = PixmapBytePad(1, w + left_pad);
BoxPtr box; RegionPtr clip;
int nbox; BoxPtr box;
float dest_coords[8]; int nbox;
const float bitmap_coords[8] = { float dest_coords[8];
0.0, 0.0, const float bitmap_coords[8] = {
1.0, 0.0, 0.0, 0.0,
1.0, 1.0, 1.0, 0.0,
0.0, 1.0, 1.0, 1.0,
}; 0.0, 1.0,
GLfloat xscale, yscale; };
glamor_pixmap_private *pixmap_priv; GLfloat xscale, yscale;
glamor_pixmap_private *pixmap_priv;
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv = glamor_get_pixmap_private(pixmap);
pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
glamor_set_normalize_vcoords(xscale, yscale, glamor_set_normalize_vcoords(xscale, yscale,
x, y, x, y,
x + w, y + h, x + w, y + h,
glamor_priv->yInverted, glamor_priv->yInverted, dest_coords);
dest_coords);
glamor_fallback("glamor_put_image_xybitmap: disabled\n"); glamor_fallback("glamor_put_image_xybitmap: disabled\n");
goto fail;
if (glamor_priv->put_image_xybitmap_prog == 0) {
ErrorF("no program for xybitmap putimage\n");
goto fail;
}
glamor_set_alu(gc->alu);
if (!glamor_set_planemask(pixmap, gc->planemask))
goto fail; goto fail;
dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog); if (glamor_priv->put_image_xybitmap_prog == 0) {
ErrorF("no program for xybitmap putimage\n");
goto fail;
}
glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); glamor_set_alu(gc->alu);
dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, if (!glamor_set_planemask(pixmap, gc->planemask))
1, fg); goto fail;
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->glUseProgram(glamor_priv->put_image_xybitmap_prog);
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);
dispatch->glEnable(GL_TEXTURE_2D);
/* Now that we've set up our bitmap texture and the shader, shove glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
* the destination rectangle through the cliprects and run the dispatch->glUniform4fv
* shader on the resulting fragments. (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
*/ glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords); dispatch->glUniform4fv
dispatch->glEnableClientState(GL_VERTEX_ARRAY); (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);
dispatch->glClientActiveTexture(GL_TEXTURE0);
dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
dispatch->glEnable(GL_SCISSOR_TEST); dispatch->glGenTextures(1, &tex);
clip = fbGetCompositeClip(gc); dispatch->glActiveTexture(GL_TEXTURE0);
for (nbox = REGION_NUM_RECTS(clip), dispatch->glEnable(GL_TEXTURE_2D);
box = REGION_RECTS(clip); dispatch->glBindTexture(GL_TEXTURE_2D, tex);
nbox--; dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
box++) GL_NEAREST);
{ dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
int x1 = x; GL_NEAREST);
int y1 = y; dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
int x2 = x + w; dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
int y2 = y + h; 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);
dispatch->glEnable(GL_TEXTURE_2D);
if (x1 < box->x1) /* Now that we've set up our bitmap texture and the shader, shove
x1 = box->x1; * the destination rectangle through the cliprects and run the
if (y1 < box->y1) * shader on the resulting fragments.
y1 = box->y1; */
if (x2 > box->x2) dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
x2 = box->x2; dispatch->glEnableClientState(GL_VERTEX_ARRAY);
if (y2 > box->y2) dispatch->glClientActiveTexture(GL_TEXTURE0);
y2 = box->y2; dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
if (x1 >= x2 || y1 >= y2) dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
continue;
dispatch->glScissor(box->x1, dispatch->glEnable(GL_SCISSOR_TEST);
y_flip(pixmap, box->y1), clip = fbGetCompositeClip(gc);
box->x2 - box->x1, for (nbox = REGION_NUM_RECTS(clip),
box->y2 - box->y1); box = REGION_RECTS(clip); nbox--; box++) {
dispatch->glDrawArrays(GL_QUADS, 0, 4); int x1 = x;
} int y1 = y;
int x2 = x + w;
int y2 = y + h;
dispatch->glDisable(GL_SCISSOR_TEST); if (x1 < box->x1)
glamor_set_alu(GXcopy); x1 = box->x1;
glamor_set_planemask(pixmap, ~0); if (y1 < box->y1)
dispatch->glDeleteTextures(1, &tex); y1 = box->y1;
dispatch->glDisable(GL_TEXTURE_2D); if (x2 > box->x2)
dispatch->glDisableClientState(GL_VERTEX_ARRAY); x2 = box->x2;
dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (y2 > box->y2)
return; y2 = box->y2;
glamor_set_alu(GXcopy); if (x1 >= x2 || y1 >= y2)
glamor_set_planemask(pixmap, ~0); continue;
glamor_fallback(": to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable)); dispatch->glScissor(box->x1,
fail: y_flip(pixmap, box->y1),
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { box->x2 - box->x1, box->y2 - box->y1);
fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); dispatch->glDrawArrays(GL_QUADS, 0, 4);
glamor_finish_access(drawable); }
}
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);
}
} }
#endif #endif
@ -252,166 +244,162 @@ void
glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, 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_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen); glamor_get_screen_private(drawable->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv =
GLenum type, format, iformat; glamor_get_pixmap_private(pixmap);
RegionPtr clip; GLenum type, format, iformat;
BoxPtr pbox; RegionPtr clip;
int nbox; BoxPtr pbox;
int src_stride = PixmapBytePad(w, drawable->depth); int nbox;
int x_off, y_off; int src_stride = PixmapBytePad(w, drawable->depth);
float vertices[8], texcoords[8]; int x_off, y_off;
GLfloat xscale, yscale, txscale, tyscale; float vertices[8], texcoords[8];
GLuint tex; GLfloat xscale, yscale, txscale, tyscale;
int no_alpha, no_revert; GLuint tex;
if (image_format == XYBitmap) { int no_alpha, no_revert;
assert(depth == 1); if (image_format == XYBitmap) {
goto fail; assert(depth == 1);
return; goto fail;
} return;
}
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
glamor_fallback("has no fbo.\n"); glamor_fallback("has no fbo.\n");
goto fail; goto fail;
} }
if (image_format != ZPixmap) { if (image_format != ZPixmap) {
glamor_fallback("non-ZPixmap\n"); glamor_fallback("non-ZPixmap\n");
goto fail; goto fail;
} }
if (!glamor_set_planemask(pixmap, gc->planemask)) { if (!glamor_set_planemask(pixmap, gc->planemask)) {
goto fail; goto fail;
} }
glamor_set_alu(dispatch, gc->alu); glamor_set_alu(dispatch, gc->alu);
if (glamor_get_tex_format_type_from_pixmap(pixmap, if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format, &format,
&type, &type, &no_alpha,
&no_alpha, &no_revert)) {
&no_revert glamor_fallback("unknown depth. %d \n", drawable->depth);
)) { goto fail;
glamor_fallback("unknown depth. %d \n", }
drawable->depth);
goto fail;
}
/* XXX consider to reuse a function to do the following work. */ /* XXX consider to reuse a function to do the following work. */
glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap); glamor_validate_pixmap(pixmap);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
2 * sizeof(float), GL_FALSE, 2 * sizeof(float),
vertices); vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
2 * sizeof(float), GL_FALSE, 2 * sizeof(float),
texcoords); texcoords);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH,
pixmap->drawable.bitsPerPixel); src_stride * 8 /
} pixmap->drawable.bitsPerPixel);
else { } else {
dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
// dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} }
dispatch->glGenTextures(1, &tex); dispatch->glGenTextures(1, &tex);
dispatch->glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D, tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
iformat = format; iformat = format;
} } else {
else { iformat = GL_RGBA;
iformat = GL_RGBA; }
}
dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat, dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat,
w, h, 0, w, h, 0, format, type, bits);
format, type, bits);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); GL_NEAREST);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
dispatch->glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]); dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); dispatch->glUniform1i(glamor_priv->
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0); finish_access_no_revert[no_alpha],
no_revert);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
0);
x += drawable->x; x += drawable->x;
y += drawable->y; y += drawable->y;
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
clip = fbGetCompositeClip(gc); clip = fbGetCompositeClip(gc);
txscale = 1.0/w; txscale = 1.0 / w;
tyscale = 1.0/h; tyscale = 1.0 / h;
pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
for (nbox = REGION_NUM_RECTS(clip), for (nbox = REGION_NUM_RECTS(clip),
pbox = REGION_RECTS(clip); pbox = REGION_RECTS(clip); nbox--; pbox++) {
nbox--; int x1 = x;
pbox++) int y1 = y;
{ int x2 = x + w;
int x1 = x; int y2 = y + h;
int y1 = y;
int x2 = x + w;
int y2 = y + h;
if (x1 < pbox->x1) if (x1 < pbox->x1)
x1 = pbox->x1; x1 = pbox->x1;
if (y1 < pbox->y1) if (y1 < pbox->y1)
y1 = pbox->y1; y1 = pbox->y1;
if (x2 > pbox->x2) if (x2 > pbox->x2)
x2 = pbox->x2; x2 = pbox->x2;
if (y2 > pbox->y2) if (y2 > pbox->y2)
y2 = pbox->y2; y2 = pbox->y2;
if (x1 >= x2 || y1 >= y2) if (x1 >= x2 || y1 >= y2)
continue; continue;
glamor_set_normalize_tcoords( txscale, tyscale, glamor_set_normalize_tcoords(txscale, tyscale,
x1 - x, y1 - y, x1 - x, y1 - y,
x2 - x, y2 - y, x2 - x, y2 - y, 1, texcoords);
1,
texcoords);
glamor_set_normalize_vcoords( xscale, yscale, glamor_set_normalize_vcoords(xscale, yscale,
x1 + x_off, y1 + y_off, x1 + x_off, y1 + y_off,
x2 + x_off, y2 + y_off, x2 + x_off, y2 + y_off,
glamor_priv->yInverted, glamor_priv->yInverted,
vertices); vertices);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
} }
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
dispatch->glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
dispatch->glUseProgram(0); dispatch->glUseProgram(0);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glDeleteTextures(1, &tex); dispatch->glDeleteTextures(1, &tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glamor_set_alu(dispatch, GXcopy); glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
return; return;
fail: fail:
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
glamor_fallback("to %p (%c)\n", glamor_fallback("to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable)); drawable, glamor_get_drawable_location(drawable));
if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h, left_pad, image_format, fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h,
bits); left_pad, image_format, bits);
glamor_finish_access(&pixmap->drawable); glamor_finish_access(&pixmap->drawable);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -35,76 +35,72 @@ void
glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, 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)
{ {
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(drawable->pScreen);
GLenum format, type; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int no_alpha, no_revert, i; GLenum format, type;
uint8_t *drawpixels_src = (uint8_t *)src; int no_alpha, no_revert, i;
RegionPtr clip = fbGetCompositeClip(gc); uint8_t *drawpixels_src = (uint8_t *) src;
BoxRec *pbox; RegionPtr clip = fbGetCompositeClip(gc);
int x_off, y_off; BoxRec *pbox;
int x_off, y_off;
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
glamor_fallback("ES2 fallback.\n"); glamor_fallback("ES2 fallback.\n");
goto fail; goto fail;
}
if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
&format,
&type,
&no_alpha,
&no_revert
)) {
glamor_fallback("unknown depth. %d \n",
drawable->depth);
goto fail;
}
if (glamor_set_destination_pixmap(dest_pixmap))
goto fail;
glamor_validate_pixmap(dest_pixmap);
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail;
glamor_set_alu(dispatch, gc->alu);
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail;
glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
for (i = 0; i < n; i++) {
n = REGION_NUM_RECTS(clip);
pbox = REGION_RECTS(clip);
while (n--) {
if (pbox->y1 > points[i].y)
break;
dispatch->glScissor(pbox->x1,
points[i].y + y_off,
pbox->x2 - pbox->x1,
1);
dispatch->glEnable(GL_SCISSOR_TEST);
dispatch->glRasterPos2i(points[i].x + x_off,
points[i].y + y_off);
dispatch->glDrawPixels(widths[i],
1,
format, type,
drawpixels_src);
} }
drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
}
glamor_set_planemask(dest_pixmap, ~0);
glamor_set_alu(dispatch, GXcopy);
dispatch->glDisable(GL_SCISSOR_TEST);
return;
fail:
glamor_fallback("to %p (%c)\n", if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
drawable, glamor_get_drawable_location(drawable)); &format,
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { &type, &no_alpha,
fbSetSpans(drawable, gc, src, points, widths, n, sorted); &no_revert)) {
glamor_finish_access(drawable); glamor_fallback("unknown depth. %d \n", drawable->depth);
} goto fail;
}
if (glamor_set_destination_pixmap(dest_pixmap))
goto fail;
glamor_validate_pixmap(dest_pixmap);
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail;
glamor_set_alu(dispatch, gc->alu);
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail;
glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
for (i = 0; i < n; i++) {
n = REGION_NUM_RECTS(clip);
pbox = REGION_RECTS(clip);
while (n--) {
if (pbox->y1 > points[i].y)
break;
dispatch->glScissor(pbox->x1,
points[i].y + y_off,
pbox->x2 - pbox->x1, 1);
dispatch->glEnable(GL_SCISSOR_TEST);
dispatch->glRasterPos2i(points[i].x + x_off,
points[i].y + y_off);
dispatch->glDrawPixels(widths[i], 1, format,
type, drawpixels_src);
}
drawpixels_src +=
PixmapBytePad(widths[i], drawable->depth);
}
glamor_set_planemask(dest_pixmap, ~0);
glamor_set_alu(dispatch, GXcopy);
dispatch->glDisable(GL_SCISSOR_TEST);
return;
fail:
glamor_fallback("to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable));
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
fbSetSpans(drawable, gc, src, points, widths, n, sorted);
glamor_finish_access(drawable);
}
} }

View File

@ -39,43 +39,49 @@
void void
glamor_init_tile_shader(ScreenPtr screen) glamor_init_tile_shader(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(screen);
const char *tile_vs = glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
"attribute vec4 v_position;\n" const char *tile_vs =
"attribute vec4 v_texcoord0;\n" "attribute vec4 v_position;\n"
"varying vec2 tile_texture;\n" "attribute vec4 v_texcoord0;\n"
"void main()\n" "varying vec2 tile_texture;\n"
"{\n" "void main()\n"
" gl_Position = v_position;\n" "{\n"
" tile_texture = v_texcoord0.xy;\n" " gl_Position = v_position;\n"
"}\n"; " tile_texture = v_texcoord0.xy;\n" "}\n";
const char *tile_fs = const char *tile_fs =
GLAMOR_DEFAULT_PRECISION GLAMOR_DEFAULT_PRECISION
"varying vec2 tile_texture;\n" "varying vec2 tile_texture;\n"
"uniform sampler2D sampler;\n" "uniform sampler2D sampler;\n"
"void main()\n" "void main()\n"
"{\n" "{\n" " gl_FragColor = texture2D(sampler, tile_texture);\n"
" gl_FragColor = texture2D(sampler, tile_texture);\n" "}\n";
"}\n"; GLint fs_prog, vs_prog;
GLint fs_prog, vs_prog; GLint sampler_uniform_location;
GLint sampler_uniform_location;
glamor_priv->tile_prog = dispatch->glCreateProgram(); glamor_priv->tile_prog = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs); vs_prog =
fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs); glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog); fs_prog =
dispatch->glAttachShader(glamor_priv->tile_prog, 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,
dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); GLAMOR_VERTEX_POS, "v_position");
glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog); dispatch->glBindAttribLocation(glamor_priv->tile_prog,
GLAMOR_VERTEX_SOURCE,
"v_texcoord0");
glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
sampler_uniform_location = sampler_uniform_location =
dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler"); dispatch->glGetUniformLocation(glamor_priv->tile_prog,
dispatch->glUseProgram(glamor_priv->tile_prog); "sampler");
dispatch->glUniform1i(sampler_uniform_location, 0); dispatch->glUseProgram(glamor_priv->tile_prog);
dispatch->glUseProgram(0); dispatch->glUniform1i(sampler_uniform_location, 0);
dispatch->glUseProgram(0);
} }
Bool Bool
@ -84,111 +90,124 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
unsigned char alu, unsigned long planemask, unsigned char alu, unsigned long planemask,
int tile_x, int tile_y) int tile_x, int tile_y)
{ {
ScreenPtr screen = pixmap->drawable.pScreen; ScreenPtr screen = pixmap->drawable.pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(screen);
int x1 = x; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int x2 = x + width; int x1 = x;
int y1 = y; int x2 = x + width;
int y2 = y + height; int y1 = y;
int tile_x1 = tile_x; int y2 = y + height;
int tile_x2 = tile_x + width; int tile_x1 = tile_x;
int tile_y1 = tile_y; int tile_x2 = tile_x + width;
int tile_y2 = tile_y + height; int tile_y1 = tile_y;
float vertices[8]; int tile_y2 = tile_y + height;
float source_texcoords[8]; float vertices[8];
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; float source_texcoords[8];
glamor_pixmap_private *src_pixmap_priv; GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
glamor_pixmap_private *dst_pixmap_priv; glamor_pixmap_private *src_pixmap_priv;
glamor_pixmap_private *dst_pixmap_priv;
src_pixmap_priv = glamor_get_pixmap_private(tile); src_pixmap_priv = glamor_get_pixmap_private(tile);
dst_pixmap_priv = glamor_get_pixmap_private(pixmap); dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
if (((tile_x != 0) && (tile_x + width > tile->drawable.width)) if (src_pixmap_priv == NULL || dst_pixmap_priv == NULL)
|| ((tile_y != 0) && (tile_y + height > tile->drawable.height))) { goto fail;
ErrorF("tile_x = %d tile_y = %d \n", tile_x, tile_y);
goto fail;
}
if (glamor_priv->tile_prog == 0) {
glamor_fallback("Tiling unsupported\n");
goto fail;
}
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
glamor_fallback("dest has no fbo.\n"); || ((tile_y != 0)
goto fail; && (tile_y + height > tile->drawable.height))) {
} ErrorF("tile_x = %d tile_y = %d \n", tile_x, tile_y);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) { goto fail;
/* XXX dynamic uploading candidate. */ }
glamor_fallback("Non-texture tile pixmap\n"); if (glamor_priv->tile_prog == 0) {
goto fail; glamor_fallback("Tiling unsupported\n");
} goto fail;
}
if (!glamor_set_planemask(pixmap, planemask)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
glamor_fallback("unsupported planemask %lx\n", planemask); glamor_fallback("dest has no fbo.\n");
goto fail; goto fail;
} }
if (alu != GXcopy) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv); /* XXX dynamic uploading candidate. */
glamor_validate_pixmap(tile); glamor_fallback("Non-texture tile pixmap\n");
} goto fail;
}
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); if (!glamor_set_planemask(pixmap, planemask)) {
glamor_validate_pixmap(pixmap); glamor_fallback("unsupported planemask %lx\n", planemask);
pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); goto fail;
}
if (alu != GXcopy) {
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
glamor_validate_pixmap(tile);
}
glamor_set_alu(dispatch, alu); glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
glamor_validate_pixmap(pixmap);
pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { glamor_set_alu(dispatch, alu);
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
dispatch->glUseProgram(glamor_priv->tile_prog);
dispatch->glActiveTexture(GL_TEXTURE0); if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); &src_yscale);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glUseProgram(glamor_priv->tile_prog);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D,
src_pixmap_priv->tex);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_REPEAT);
dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_REPEAT);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
dispatch->glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
glamor_set_normalize_tcoords(src_xscale, src_yscale, glamor_set_normalize_tcoords(src_xscale, src_yscale,
tile_x1, tile_y1, tile_x1, tile_y1,
tile_x2, tile_y2, tile_x2, tile_y2,
glamor_priv->yInverted, glamor_priv->yInverted,
source_texcoords); source_texcoords);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
2 * sizeof(float), GL_FLOAT, GL_FALSE,
source_texcoords); 2 * sizeof(float),
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); source_texcoords);
} dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
else { } else {
GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv); GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
} src_pixmap_priv);
}
glamor_set_normalize_vcoords(dst_xscale, dst_yscale, glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
x1, y1,x2, y2, x1, y1, x2, y2,
glamor_priv->yInverted, glamor_priv->yInverted, vertices);
vertices);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
2 * sizeof(float), GL_FALSE, 2 * sizeof(float),
vertices); vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
dispatch->glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
} }
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glUseProgram(0); dispatch->glUseProgram(0);
glamor_set_alu(dispatch, GXcopy); glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
return TRUE; return TRUE;
fail: fail:
return FALSE; return FALSE;
} }

View File

@ -33,29 +33,24 @@
#include "glamor_priv.h" #include "glamor_priv.h"
void void
glamor_triangles (CARD8 op, glamor_triangles(CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
PicturePtr pDst, PicturePtr pDst,
PictFormatPtr maskFormat, PictFormatPtr maskFormat,
INT16 xSrc, INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
INT16 ySrc,
int ntris,
xTriangle *tris)
{ {
if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) {
if (pSrc->pDrawable == NULL || if (pSrc->pDrawable == NULL ||
glamor_prepare_access(pSrc->pDrawable, GLAMOR_ACCESS_RO)) glamor_prepare_access(pSrc->pDrawable,
{ GLAMOR_ACCESS_RO)) {
fbTriangles(op, fbTriangles(op, pSrc, pDst, maskFormat, xSrc,
pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris); ySrc, ntris, tris);
} }
if (pSrc->pDrawable != NULL) if (pSrc->pDrawable != NULL)
glamor_finish_access(pSrc->pDrawable); glamor_finish_access(pSrc->pDrawable);
glamor_finish_access(pDst->pDrawable); glamor_finish_access(pDst->pDrawable);
} }
} }

View File

@ -124,40 +124,38 @@
inline static void inline static void
glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox) glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
{ {
int x_min, y_min; int x_min, y_min;
int x_max, y_max; int x_max, y_max;
int i; int i;
x_min = y_min = MAXSHORT; x_min = y_min = MAXSHORT;
x_max = y_max = MINSHORT; x_max = y_max = MINSHORT;
for(i = 0; i < nbox; i++) for (i = 0; i < nbox; i++) {
{ if (x_min > boxes[i].x1)
if (x_min > boxes[i].x1) x_min = boxes[i].x1;
x_min = boxes[i].x1; if (y_min > boxes[i].y1)
if (y_min > boxes[i].y1) y_min = boxes[i].y1;
y_min = boxes[i].y1;
if (x_max < boxes[i].x2) if (x_max < boxes[i].x2)
x_max = boxes[i].x2; x_max = boxes[i].x2;
if (y_max < boxes[i].y2) if (y_max < boxes[i].y2)
y_max = boxes[i].y2; y_max = boxes[i].y2;
} }
bound->x1 = x_min; bound->x1 = x_min;
bound->y1 = y_min; bound->y1 = y_min;
bound->x2 = x_max; bound->x2 = x_max;
bound->y2 = y_max; bound->y2 = y_max;
} }
inline static void inline static void
glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy) glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
{ {
int i; int i;
for (i = 0; i < nbox; i++) for (i = 0; i < nbox; i++) {
{ boxes[i].x1 += dx;
boxes[i].x1 += dx; boxes[i].y1 += dy;
boxes[i].y1 += dy; boxes[i].x2 += dx;
boxes[i].x2 += dx; boxes[i].y2 += dy;
boxes[i].y2 += dy; }
}
} }
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@ -203,34 +201,42 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
static inline CARD32 static inline CARD32
format_for_depth(int depth) format_for_depth(int depth)
{ {
switch (depth) { switch (depth) {
case 1: return PICT_a1; case 1:
case 4: return PICT_a4; return PICT_a1;
case 8: return PICT_a8; case 4:
case 15: return PICT_x1r5g5b5; return PICT_a4;
case 16: return PICT_r5g6b5; case 8:
default: return PICT_a8;
case 24: return PICT_x8r8g8b8; case 15:
return PICT_x1r5g5b5;
case 16:
return PICT_r5g6b5;
default:
case 24:
return PICT_x8r8g8b8;
#if XORG_VERSION_CURRENT >= 10699900 #if XORG_VERSION_CURRENT >= 10699900
case 30: return PICT_x2r10g10b10; case 30:
return PICT_x2r10g10b10;
#endif #endif
case 32: return PICT_a8r8g8b8; case 32:
} return PICT_a8r8g8b8;
}
} }
static inline CARD32 static inline CARD32
format_for_pixmap(PixmapPtr pixmap) format_for_pixmap(PixmapPtr pixmap)
{ {
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
PictFormatShort pict_format; PictFormatShort pict_format;
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv = glamor_get_pixmap_private(pixmap);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
pict_format = pixmap_priv->pict_format; pict_format = pixmap_priv->pict_format;
else else
pict_format = format_for_depth(pixmap->drawable.depth); pict_format = format_for_depth(pixmap->drawable.depth);
return pict_format; return pict_format;
} }
/* /*
@ -242,202 +248,204 @@ format_for_pixmap(PixmapPtr pixmap)
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
static inline int static inline int
glamor_get_tex_format_type_from_pictformat(PictFormatShort format, glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
GLenum *tex_format, GLenum * tex_format,
GLenum *tex_type, GLenum * tex_type,
int *no_alpha, int *no_alpha, int *no_revert)
int *no_revert)
{ {
*no_alpha = 0; *no_alpha = 0;
*no_revert = 1; *no_revert = 1;
switch (format) { switch (format) {
case PICT_a1: case PICT_a1:
*tex_format = GL_COLOR_INDEX; *tex_format = GL_COLOR_INDEX;
*tex_type = GL_BITMAP; *tex_type = GL_BITMAP;
break; break;
case PICT_b8g8r8x8: case PICT_b8g8r8x8:
*no_alpha = 1; *no_alpha = 1;
case PICT_b8g8r8a8: case PICT_b8g8r8a8:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_8_8_8_8; *tex_type = GL_UNSIGNED_INT_8_8_8_8;
break; break;
case PICT_x8r8g8b8: case PICT_x8r8g8b8:
*no_alpha = 1; *no_alpha = 1;
case PICT_a8r8g8b8: case PICT_a8r8g8b8:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
break; break;
case PICT_x8b8g8r8: case PICT_x8b8g8r8:
*no_alpha = 1; *no_alpha = 1;
case PICT_a8b8g8r8: case PICT_a8b8g8r8:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV; *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
break; break;
case PICT_x2r10g10b10: case PICT_x2r10g10b10:
*no_alpha = 1; *no_alpha = 1;
case PICT_a2r10g10b10: case PICT_a2r10g10b10:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
break; break;
case PICT_x2b10g10r10: case PICT_x2b10g10r10:
*no_alpha = 1; *no_alpha = 1;
case PICT_a2b10g10r10: case PICT_a2b10g10r10:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV; *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
break; break;
case PICT_r5g6b5: case PICT_r5g6b5:
*tex_format = GL_RGB; *tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5; *tex_type = GL_UNSIGNED_SHORT_5_6_5;
break; break;
case PICT_b5g6r5: case PICT_b5g6r5:
*tex_format = GL_RGB; *tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5_REV; *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
break; break;
case PICT_x1b5g5r5: case PICT_x1b5g5r5:
*no_alpha = 1; *no_alpha = 1;
case PICT_a1b5g5r5: case PICT_a1b5g5r5:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break; break;
case PICT_x1r5g5b5: case PICT_x1r5g5b5:
*no_alpha = 1; *no_alpha = 1;
case PICT_a1r5g5b5: case PICT_a1r5g5b5:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break; break;
case PICT_a8: case PICT_a8:
*tex_format = GL_ALPHA; *tex_format = GL_ALPHA;
*tex_type = GL_UNSIGNED_BYTE; *tex_type = GL_UNSIGNED_BYTE;
break; break;
case PICT_x4r4g4b4: case PICT_x4r4g4b4:
*no_alpha = 1; *no_alpha = 1;
case PICT_a4r4g4b4: case PICT_a4r4g4b4:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
break; break;
case PICT_x4b4g4r4: case PICT_x4b4g4r4:
*no_alpha = 1; *no_alpha = 1;
case PICT_a4b4g4r4: case PICT_a4b4g4r4:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
break; break;
default: default:
LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format); LogMessageVerb(X_INFO, 0,
return -1; "fail to get matched format for %x \n",
} format);
return 0; return -1;
}
return 0;
} }
#else #else
#define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst) #define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst)
static inline int static inline int
glamor_get_tex_format_type_from_pictformat(PictFormatShort format, glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
GLenum *tex_format, GLenum * tex_format,
GLenum *tex_type, GLenum * tex_type,
int *no_alpha, int *no_alpha, int *no_revert)
int *no_revert)
{ {
*no_alpha = 0; *no_alpha = 0;
*no_revert = IS_LITTLE_ENDIAN; *no_revert = IS_LITTLE_ENDIAN;
switch (format) { switch (format) {
case PICT_b8g8r8x8: case PICT_b8g8r8x8:
*no_alpha = 1; *no_alpha = 1;
case PICT_b8g8r8a8: case PICT_b8g8r8a8:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_BYTE; *tex_type = GL_UNSIGNED_BYTE;
*no_revert = !IS_LITTLE_ENDIAN; *no_revert = !IS_LITTLE_ENDIAN;
break; break;
case PICT_x8r8g8b8: case PICT_x8r8g8b8:
*no_alpha = 1; *no_alpha = 1;
case PICT_a8r8g8b8: case PICT_a8r8g8b8:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_BYTE; *tex_type = GL_UNSIGNED_BYTE;
break; break;
case PICT_x8b8g8r8: case PICT_x8b8g8r8:
*no_alpha = 1; *no_alpha = 1;
case PICT_a8b8g8r8: case PICT_a8b8g8r8:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_BYTE; *tex_type = GL_UNSIGNED_BYTE;
break; break;
case PICT_x2r10g10b10: case PICT_x2r10g10b10:
*no_alpha = 1; *no_alpha = 1;
case PICT_a2r10g10b10: case PICT_a2r10g10b10:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_10_10_10_2; *tex_type = GL_UNSIGNED_INT_10_10_10_2;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
case PICT_x2b10g10r10: case PICT_x2b10g10r10:
*no_alpha = 1; *no_alpha = 1;
case PICT_a2b10g10r10: case PICT_a2b10g10r10:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_INT_10_10_10_2; *tex_type = GL_UNSIGNED_INT_10_10_10_2;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
case PICT_r5g6b5: case PICT_r5g6b5:
*tex_format = GL_RGB; *tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5; *tex_type = GL_UNSIGNED_SHORT_5_6_5;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
case PICT_b5g6r5: case PICT_b5g6r5:
*tex_format = GL_RGB; *tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5; *tex_type = GL_UNSIGNED_SHORT_5_6_5;
*no_revert = FALSE; *no_revert = FALSE;
break; break;
case PICT_x1b5g5r5: case PICT_x1b5g5r5:
*no_alpha = 1; *no_alpha = 1;
case PICT_a1b5g5r5: case PICT_a1b5g5r5:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
case PICT_x1r5g5b5: case PICT_x1r5g5b5:
*no_alpha = 1; *no_alpha = 1;
case PICT_a1r5g5b5: case PICT_a1r5g5b5:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
case PICT_a8: case PICT_a8:
*tex_format = GL_ALPHA; *tex_format = GL_ALPHA;
*tex_type = GL_UNSIGNED_BYTE; *tex_type = GL_UNSIGNED_BYTE;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
case PICT_x4r4g4b4: case PICT_x4r4g4b4:
*no_alpha = 1; *no_alpha = 1;
case PICT_a4r4g4b4: case PICT_a4r4g4b4:
*tex_format = GL_BGRA; *tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
case PICT_x4b4g4r4: case PICT_x4b4g4r4:
*no_alpha = 1; *no_alpha = 1;
case PICT_a4b4g4r4: case PICT_a4b4g4r4:
*tex_format = GL_RGBA; *tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV; *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
*no_revert = TRUE; *no_revert = TRUE;
break; break;
default: default:
LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format); LogMessageVerb(X_INFO, 0,
return -1; "fail to get matched format for %x \n",
} format);
return 0; return -1;
}
return 0;
} }
@ -446,92 +454,91 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
static inline int static inline int
glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
GLenum *format, GLenum * format,
GLenum *type, GLenum * type,
int *no_alpha, int *no_alpha, int *no_revert)
int *no_revert)
{ {
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
PictFormatShort pict_format; PictFormatShort pict_format;
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv = glamor_get_pixmap_private(pixmap);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
pict_format = pixmap_priv->pict_format; pict_format = pixmap_priv->pict_format;
else else
pict_format = format_for_depth(pixmap->drawable.depth); pict_format = format_for_depth(pixmap->drawable.depth);
return glamor_get_tex_format_type_from_pictformat(pict_format, return glamor_get_tex_format_type_from_pictformat(pict_format,
format, type, format, type,
no_alpha, no_revert); no_alpha,
no_revert);
} }
/* borrowed from uxa */ /* borrowed from uxa */
static inline Bool static inline Bool
glamor_get_rgba_from_pixel(CARD32 pixel, glamor_get_rgba_from_pixel(CARD32 pixel,
float * red, float *red,
float * green, float *green,
float * blue, float *blue, float *alpha, CARD32 format)
float * alpha,
CARD32 format)
{ {
int rbits, bbits, gbits, abits; int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift; int rshift, bshift, gshift, ashift;
rbits = PICT_FORMAT_R(format); rbits = PICT_FORMAT_R(format);
gbits = PICT_FORMAT_G(format); gbits = PICT_FORMAT_G(format);
bbits = PICT_FORMAT_B(format); bbits = PICT_FORMAT_B(format);
abits = PICT_FORMAT_A(format); abits = PICT_FORMAT_A(format);
if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
rshift = gshift = bshift = ashift = 0; rshift = gshift = bshift = ashift = 0;
} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
bshift = 0; bshift = 0;
gshift = bbits; gshift = bbits;
rshift = gshift + gbits; rshift = gshift + gbits;
ashift = rshift + rbits; ashift = rshift + rbits;
} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
rshift = 0; rshift = 0;
gshift = rbits; gshift = rbits;
bshift = gshift + gbits; bshift = gshift + gbits;
ashift = bshift + bbits; ashift = bshift + bbits;
#if XORG_VERSION_CURRENT >= 10699900 #if XORG_VERSION_CURRENT >= 10699900
} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
ashift = 0; ashift = 0;
rshift = abits; rshift = abits;
if (abits == 0) if (abits == 0)
rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits); rshift = PICT_FORMAT_BPP(format) - (rbits + gbits +
gshift = rshift + rbits; bbits);
bshift = gshift + gbits; gshift = rshift + rbits;
bshift = gshift + gbits;
#endif #endif
} else { } else {
return FALSE; return FALSE;
} }
#define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \ #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \
*_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \ *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \
/ (float)((1<<(_bits_)) - 1) / (float)((1<<(_bits_)) - 1)
if (rbits) if (rbits)
COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits); COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
else else
*red = 0; *red = 0;
if (gbits) if (gbits)
COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits); COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
else else
*green = 0; *green = 0;
if (bbits) if (bbits)
COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits); COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
else else
*blue = 0; *blue = 0;
if (abits) if (abits)
COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits); COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
else else
*alpha = 1; *alpha = 1;
return TRUE; return TRUE;
} }

View File

@ -34,41 +34,42 @@
static void static void
glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap) glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr * ppPixmap)
{ {
PixmapPtr pPixmap = *ppPixmap; PixmapPtr pPixmap = *ppPixmap;
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
{ pixmap_priv = glamor_get_pixmap_private(pPixmap);
pixmap_priv = glamor_get_pixmap_private(pPixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("pixmap %p has no fbo\n", pPixmap);
glamor_fallback("pixmap %p has no fbo\n", pPixmap); goto fail;
goto fail; }
} glamor_debug_output(GLAMOR_DEBUG_UNIMPL,
glamor_debug_output(GLAMOR_DEBUG_UNIMPL, "To be implemented.\n"); "To be implemented.\n");
} }
return; return;
fail: fail:
GLAMOR_PANIC(" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile" GLAMOR_PANIC
" is broken for glamor. \n"); (" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile"
" is broken for glamor. \n");
} }
Bool Bool
glamor_change_window_attributes(WindowPtr pWin, unsigned long mask) glamor_change_window_attributes(WindowPtr pWin, unsigned long mask)
{ {
if (mask & CWBackPixmap) { if (mask & CWBackPixmap) {
if (pWin->backgroundState == BackgroundPixmap) if (pWin->backgroundState == BackgroundPixmap)
glamor_fixup_window_pixmap(&pWin->drawable, &pWin->background.pixmap); glamor_fixup_window_pixmap(&pWin->drawable,
} &pWin->
background.pixmap);
}
if (mask & CWBorderPixmap) { if (mask & CWBorderPixmap) {
if (pWin->borderIsPixel == FALSE) if (pWin->borderIsPixel == FALSE)
glamor_fixup_window_pixmap(&pWin->drawable, &pWin->border.pixmap); glamor_fixup_window_pixmap(&pWin->drawable,
} &pWin->border.pixmap);
return TRUE; }
return TRUE;
} }