glamor: Create FBOs for pixmaps.
This commit is contained in:
parent
f92d1478e9
commit
519103565c
|
@ -40,6 +40,8 @@
|
||||||
|
|
||||||
static int glamor_screen_private_key_index;
|
static int glamor_screen_private_key_index;
|
||||||
DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
|
DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
|
||||||
|
static int glamor_pixmap_private_key_index;
|
||||||
|
DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
|
* glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
|
||||||
|
@ -63,9 +65,57 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
|
||||||
|
|
||||||
static PixmapPtr
|
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_hint)
|
unsigned int usage)
|
||||||
{
|
{
|
||||||
return fbCreatePixmap(screen, w, h, depth, usage_hint);
|
PixmapPtr pixmap;
|
||||||
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
GLenum format;
|
||||||
|
|
||||||
|
if (w > 32767 || h > 32767)
|
||||||
|
return NullPixmap;
|
||||||
|
|
||||||
|
pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
|
||||||
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
|
if (w == 0 || h == 0)
|
||||||
|
return pixmap;
|
||||||
|
|
||||||
|
/* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
|
||||||
|
* FBOs, which EXT_fbo forgot to do.
|
||||||
|
*/
|
||||||
|
switch (depth) {
|
||||||
|
case 24:
|
||||||
|
format = GL_RGB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
format = GL_RGBA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the texture used to store the pixmap's data. */
|
||||||
|
glGenTextures(1, &pixmap_priv->tex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
|
||||||
|
format, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
|
/* Create a framebuffer object wrapping the texture so that we can render
|
||||||
|
* to it.
|
||||||
|
*/
|
||||||
|
glGenFramebuffersEXT(1, &pixmap_priv->fb);
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
|
||||||
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_COLOR_ATTACHMENT0_EXT,
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
pixmap_priv->tex,
|
||||||
|
0);
|
||||||
|
|
||||||
|
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
|
||||||
|
(w * pixmap->drawable.bitsPerPixel + 7) / 8,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
@ -96,9 +146,19 @@ glamor_init(ScreenPtr screen)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
|
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
|
||||||
|
if (!dixRequestPrivate(glamor_pixmap_private_key,
|
||||||
|
sizeof(glamor_pixmap_private))) {
|
||||||
|
LogMessage(X_WARNING,
|
||||||
|
"glamor%d: Failed to allocate pixmap private\n",
|
||||||
|
screen->myNum);
|
||||||
|
}
|
||||||
|
|
||||||
glewInit();
|
glewInit();
|
||||||
|
|
||||||
|
if (!GLEW_EXT_framebuffer_object) {
|
||||||
|
ErrorF("GL_EXT_framebuffer_object required\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
if (!GLEW_ARB_shader_objects) {
|
if (!GLEW_ARB_shader_objects) {
|
||||||
ErrorF("GL_ARB_shader_objects required\n");
|
ErrorF("GL_ARB_shader_objects required\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -42,17 +42,28 @@
|
||||||
Bool
|
Bool
|
||||||
glamor_set_destination_pixmap(PixmapPtr pixmap)
|
glamor_set_destination_pixmap(PixmapPtr pixmap)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
|
||||||
|
|
||||||
if (pixmap != screen_pixmap) {
|
if (pixmap_priv == NULL) {
|
||||||
ErrorF("stubbed drawing to non-screen pixmap\n");
|
ErrorF("no pixmap priv?");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pixmap_priv->fb == 0) {
|
||||||
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
||||||
|
|
||||||
|
if (pixmap != screen_pixmap) {
|
||||||
|
ErrorF("No FBO\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
|
||||||
|
|
||||||
glViewport(0, 0,
|
glViewport(0, 0,
|
||||||
screen_pixmap->drawable.width,
|
pixmap->drawable.width,
|
||||||
screen_pixmap->drawable.height);
|
pixmap->drawable.height);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -75,10 +86,18 @@ void
|
||||||
glamor_set_transform_for_pixmap(PixmapPtr pixmap,
|
glamor_set_transform_for_pixmap(PixmapPtr pixmap,
|
||||||
glamor_transform_uniforms *uniform_locations)
|
glamor_transform_uniforms *uniform_locations)
|
||||||
{
|
{
|
||||||
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
||||||
|
|
||||||
glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
|
glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
|
||||||
glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
|
glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
|
||||||
glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
|
glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
|
||||||
glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
|
if (pixmap == screen_pixmap)
|
||||||
|
glUniform1fARB(uniform_locations->y_scale,
|
||||||
|
-2.0f / pixmap->drawable.height);
|
||||||
|
else
|
||||||
|
glUniform1fARB(uniform_locations->y_scale,
|
||||||
|
2.0f / pixmap->drawable.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint
|
GLint
|
||||||
|
@ -176,53 +195,38 @@ static 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)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = drawable->pScreen;
|
ErrorF("stub put_image\n");
|
||||||
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
|
||||||
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
|
|
||||||
|
|
||||||
if (screen_pixmap != dest_pixmap) {
|
|
||||||
fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
|
|
||||||
} else {
|
|
||||||
ErrorF("stub put_image\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static 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)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = drawable->pScreen;
|
|
||||||
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
|
||||||
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
|
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
GLenum format, type;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (screen_pixmap != dest_pixmap) {
|
switch (drawable->depth) {
|
||||||
fbSetSpans(drawable, gc, src, points, widths, n, sorted);
|
case 24:
|
||||||
} else {
|
case 32:
|
||||||
GLenum format, type;
|
format = GL_BGRA;
|
||||||
int i;
|
type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ErrorF("Unknown setspans depth %d\n", drawable->depth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (drawable->depth) {
|
if (!glamor_set_destination_pixmap(dest_pixmap))
|
||||||
case 24:
|
return;
|
||||||
case 32:
|
for (i = 0; i < n; i++) {
|
||||||
format = GL_BGRA;
|
glRasterPos2i(points[i].x - dest_pixmap->screen_x,
|
||||||
type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
points[i].y - dest_pixmap->screen_y);
|
||||||
break;
|
glDrawPixels(widths[i],
|
||||||
default:
|
1,
|
||||||
ErrorF("Unknown setspans depth %d\n", drawable->depth);
|
format, type,
|
||||||
return;
|
src);
|
||||||
}
|
src += PixmapBytePad(widths[i], drawable->depth);
|
||||||
|
|
||||||
if (!glamor_set_destination_pixmap(dest_pixmap))
|
|
||||||
return;
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
glRasterPos2i(points[i].x - dest_pixmap->screen_x,
|
|
||||||
points[i].y - dest_pixmap->screen_y);
|
|
||||||
glDrawPixels(widths[i],
|
|
||||||
1,
|
|
||||||
format, type,
|
|
||||||
src);
|
|
||||||
src += PixmapBytePad(widths[i], drawable->depth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,9 +239,6 @@ static 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)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = drawable->pScreen;
|
|
||||||
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
|
||||||
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
|
|
||||||
xRectangle *rects;
|
xRectangle *rects;
|
||||||
int x1, x2, y1, y2;
|
int x1, x2, y1, y2;
|
||||||
int i;
|
int i;
|
||||||
|
@ -245,10 +246,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
||||||
/* 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 || gc->lineStyle != LineSolid ||
|
if (gc->lineWidth != 0 || gc->lineStyle != LineSolid ||
|
||||||
gc->fillStyle != FillSolid) {
|
gc->fillStyle != FillSolid) {
|
||||||
if (dest_pixmap != screen_pixmap)
|
ErrorF("stub poly_line\n");
|
||||||
fbPolyLine(drawable, gc, mode, n, points);
|
|
||||||
else
|
|
||||||
ErrorF("stub poly_line\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,10 +265,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
||||||
|
|
||||||
if (x1 != x2 && y1 != y2) {
|
if (x1 != x2 && y1 != y2) {
|
||||||
xfree(rects);
|
xfree(rects);
|
||||||
if (dest_pixmap != screen_pixmap)
|
ErrorF("stub poly_line\n");
|
||||||
fbPolyLine(drawable, gc, mode, n, points);
|
|
||||||
else
|
|
||||||
ErrorF("stub poly_line\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,14 +44,6 @@ glamor_fill_spans(DrawablePtr drawable,
|
||||||
int extentX1, extentX2, extentY1, extentY2;
|
int extentX1, extentX2, extentY1, extentY2;
|
||||||
int fullX1, fullX2, fullY1;
|
int fullX1, fullX2, fullY1;
|
||||||
int partX1, partX2;
|
int partX1, partX2;
|
||||||
ScreenPtr screen = drawable->pScreen;
|
|
||||||
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
|
||||||
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
|
|
||||||
|
|
||||||
if (dest_pixmap != screen_pixmap) {
|
|
||||||
fbFillSpans(drawable, gc, n, points, widths, sorted);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extents = REGION_EXTENTS(gc->pScreen, clip);
|
extents = REGION_EXTENTS(gc->pScreen, clip);
|
||||||
extentX1 = extents->x1;
|
extentX1 = extents->x1;
|
||||||
|
|
|
@ -39,36 +39,33 @@ glamor_get_spans(DrawablePtr drawable,
|
||||||
int count,
|
int count,
|
||||||
char *dst)
|
char *dst)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = drawable->pScreen;
|
|
||||||
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
|
||||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
GLenum format, type;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (screen_pixmap != pixmap) {
|
switch (drawable->depth) {
|
||||||
|
case 24:
|
||||||
|
case 32:
|
||||||
|
format = GL_BGRA;
|
||||||
|
type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ErrorF("Unknown getspans depth %d\n", drawable->depth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!glamor_set_destination_pixmap(pixmap)) {
|
||||||
fbGetSpans(drawable, wmax, points, widths, count, dst);
|
fbGetSpans(drawable, wmax, points, widths, count, dst);
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
GLenum format, type;
|
|
||||||
int i;
|
for (i = 0; i < count; i++) {
|
||||||
switch (drawable->depth) {
|
glReadPixels(points[i].x - pixmap->screen_x,
|
||||||
case 24:
|
points[i].y - pixmap->screen_y,
|
||||||
case 32:
|
widths[i],
|
||||||
format = GL_BGRA;
|
1,
|
||||||
type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
format, type,
|
||||||
break;
|
dst);
|
||||||
default:
|
dst += PixmapBytePad(widths[i], drawable->depth);
|
||||||
ErrorF("Unknown getspans depth %d\n", drawable->depth);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!glamor_set_destination_pixmap(pixmap))
|
|
||||||
return;
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
glReadPixels(points[i].x - pixmap->screen_x,
|
|
||||||
points[i].y - pixmap->screen_y,
|
|
||||||
widths[i],
|
|
||||||
1,
|
|
||||||
format, type,
|
|
||||||
dst);
|
|
||||||
dst += PixmapBytePad(widths[i], drawable->depth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,13 +50,24 @@ typedef struct glamor_screen_private {
|
||||||
glamor_transform_uniforms solid_transform;
|
glamor_transform_uniforms solid_transform;
|
||||||
} glamor_screen_private;
|
} glamor_screen_private;
|
||||||
|
|
||||||
|
typedef struct glamor_pixmap_private {
|
||||||
|
GLuint tex;
|
||||||
|
GLuint fb;
|
||||||
|
} glamor_pixmap_private;
|
||||||
|
|
||||||
extern DevPrivateKey glamor_screen_private_key;
|
extern DevPrivateKey glamor_screen_private_key;
|
||||||
|
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 *)dixLookupPrivate(&screen->devPrivates,
|
||||||
glamor_screen_private_key);
|
glamor_screen_private_key);
|
||||||
}
|
}
|
||||||
|
static inline glamor_pixmap_private *
|
||||||
|
glamor_get_pixmap_private(PixmapPtr pixmap)
|
||||||
|
{
|
||||||
|
return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
|
||||||
|
}
|
||||||
|
|
||||||
/* glamor.c */
|
/* glamor.c */
|
||||||
PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
|
PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
|
||||||
|
|
Loading…
Reference in New Issue