glamor_fbo: Introduce glamor fbo to manage all the fb/tex.
This is the first patch to implement a fbo/tex pool mechanism which is like the sna's BO cache list. We firstly need to decopule the fbo/tex from each pixmap. The new glamor_pixmap_fbo data structure is for that purpose. It's somehow independent to each pixmap and can be reused latter by other pixmaps once it's detached from the current pixmap. And this commit also slightly change the way to create a memory pixmap. We will not create a pixmap private data structure by default, instead we will crete that structure when a memory pixmap is attaching a fbo to it. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
ca2ddd33a1
commit
2ff4100849
|
@ -44,6 +44,7 @@ libglamor_la_SOURCES = \
|
|||
glamor_picture.c\
|
||||
glamor_window.c\
|
||||
glamor_gl_dispatch.c\
|
||||
glamor_fbo.c\
|
||||
glamor.h
|
||||
|
||||
sdk_HEADERS = glamor.h
|
||||
|
|
111
glamor/glamor.c
111
glamor/glamor.c
|
@ -85,52 +85,41 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
|
|||
glamor_pixmap_private *pixmap_priv;
|
||||
glamor_screen_private *glamor_priv;
|
||||
glamor_gl_dispatch *dispatch;
|
||||
glamor_pixmap_fbo *fbo;
|
||||
|
||||
glamor_priv = glamor_get_screen_private(screen);
|
||||
dispatch = &glamor_priv->dispatch;
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (pixmap_priv == NULL) {
|
||||
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;
|
||||
if (pixmap_priv->fbo) {
|
||||
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
|
||||
glamor_destroy_fbo(fbo);
|
||||
}
|
||||
|
||||
if (pixmap_priv->fb)
|
||||
dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
|
||||
fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
pixmap->drawable.depth, tex, 0);
|
||||
|
||||
if (pixmap_priv->tex)
|
||||
dispatch->glDeleteTextures(1, &pixmap_priv->tex);
|
||||
|
||||
pixmap_priv->tex = tex;
|
||||
|
||||
/* Create a framebuffer object wrapping the texture so that we can render
|
||||
* to it.
|
||||
*/
|
||||
pixmap_priv->gl_fbo = 1;
|
||||
if (tex != 0) {
|
||||
glamor_pixmap_ensure_fb(pixmap);
|
||||
pixmap_priv->gl_tex = 1;
|
||||
} else {
|
||||
pixmap_priv->fb = 0;
|
||||
pixmap_priv->gl_tex = 0;
|
||||
if (fbo == NULL) {
|
||||
ErrorF("XXX fail to create fbo.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pixmap->devPrivate.ptr = NULL;
|
||||
glamor_pixmap_attach_fbo(pixmap, fbo);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_set_screen_pixmap(PixmapPtr screen_pixmap)
|
||||
{
|
||||
ScreenPtr screen = screen_pixmap->drawable.pScreen;
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
glamor_screen_private *glamor_priv;
|
||||
|
||||
glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
|
||||
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
|
||||
glamor_priv->screen_fbo = pixmap_priv->fb;
|
||||
glamor_priv->screen_fbo = pixmap_priv->fbo->fb;
|
||||
|
||||
pixmap_priv->fbo->width = screen_pixmap->drawable.width;
|
||||
pixmap_priv->fbo->height = screen_pixmap->drawable.height;
|
||||
}
|
||||
|
||||
PixmapPtr
|
||||
|
@ -138,13 +127,15 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
|||
unsigned int usage)
|
||||
{
|
||||
PixmapPtr pixmap;
|
||||
GLenum format;
|
||||
GLuint tex;
|
||||
glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(screen);
|
||||
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
|
||||
glamor_pixmap_fbo *fbo;
|
||||
int pitch;
|
||||
int flag;
|
||||
|
||||
if (w > 32767 || h > 32767)
|
||||
return NullPixmap;
|
||||
|
||||
|
@ -153,62 +144,53 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
|||
|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
|
||||
/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
|
||||
If we exceed such limitation, we have to use framebuffer. */
|
||||
type = GLAMOR_MEMORY;
|
||||
pixmap = fbCreatePixmap(screen, w, h, depth, usage);
|
||||
return fbCreatePixmap(screen, w, h, depth, usage);
|
||||
} else
|
||||
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
|
||||
|
||||
pixmap_priv = calloc(1, sizeof(*pixmap_priv));
|
||||
dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key,
|
||||
|
||||
if (!pixmap_priv)
|
||||
return fbCreatePixmap(screen, w, h, depth, usage);
|
||||
|
||||
dixSetPrivate(&pixmap->devPrivates,
|
||||
glamor_pixmap_private_key,
|
||||
pixmap_priv);
|
||||
|
||||
pixmap_priv->container = pixmap;
|
||||
pixmap_priv->glamor_priv = glamor_priv;
|
||||
|
||||
pixmap_priv->type = type;
|
||||
if (w == 0 || h == 0 || type == GLAMOR_MEMORY)
|
||||
|
||||
if (w == 0 || h == 0)
|
||||
return pixmap;
|
||||
|
||||
gl_iformat_for_depth(depth, &format);
|
||||
/* 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);
|
||||
fbo = glamor_create_fbo(glamor_priv, w, h, depth, 0);
|
||||
|
||||
glamor_set_pixmap_texture(pixmap, tex);
|
||||
if (fbo == NULL) {
|
||||
fbDestroyPixmap(pixmap);
|
||||
free(pixmap_priv);
|
||||
return fbCreatePixmap(screen, w, h, depth, usage);
|
||||
}
|
||||
|
||||
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
|
||||
(((w *
|
||||
pixmap->drawable.
|
||||
bitsPerPixel + 7) / 8) +
|
||||
3) & ~3, NULL);
|
||||
glamor_pixmap_attach_fbo(pixmap, fbo);
|
||||
|
||||
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
|
||||
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_destroy_textured_pixmap(PixmapPtr pixmap)
|
||||
{
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
|
||||
if (pixmap->refcnt == 1) {
|
||||
glamor_pixmap_private *pixmap_priv =
|
||||
glamor_get_pixmap_private(pixmap);
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
if (pixmap_priv != NULL) {
|
||||
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);
|
||||
glamor_pixmap_fbo *fbo;
|
||||
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
|
||||
if (fbo)
|
||||
glamor_destroy_fbo(fbo);
|
||||
free(pixmap_priv);
|
||||
}
|
||||
}
|
||||
|
@ -238,6 +220,7 @@ _glamor_block_handler(void *data, OSTimePtr timeout,
|
|||
{
|
||||
glamor_gl_dispatch *dispatch = data;
|
||||
dispatch->glFlush();
|
||||
dispatch->glFinish();
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -79,7 +79,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
|||
glamor_validate_pixmap(dst_pixmap);
|
||||
|
||||
dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
|
||||
src_pixmap_priv->fb);
|
||||
src_pixmap_priv->fbo->fb);
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
|
||||
&dst_y_off);
|
||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
|
||||
|
@ -167,7 +167,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!src_pixmap_priv->gl_fbo) {
|
||||
if (!src_pixmap_priv || !src_pixmap_priv->gl_fbo) {
|
||||
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
||||
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
|
||||
goto fail;
|
||||
|
@ -175,6 +175,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
src_status = glamor_upload_pixmap_to_texture(src_pixmap);
|
||||
if (src_status != GLAMOR_UPLOAD_DONE)
|
||||
goto fail;
|
||||
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
#endif
|
||||
} else
|
||||
flush_needed = 1;
|
||||
|
@ -199,8 +201,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
|
||||
&dst_y_off);
|
||||
|
||||
|
||||
|
||||
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||
GL_FALSE, 2 * sizeof(float),
|
||||
vertices);
|
||||
|
@ -216,7 +216,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
|
||||
dispatch->glActiveTexture(GL_TEXTURE0);
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D,
|
||||
src_pixmap_priv->tex);
|
||||
src_pixmap_priv->fbo->tex);
|
||||
#ifndef GLAMOR_GLES2
|
||||
dispatch->glEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
|
@ -333,7 +333,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
|||
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->fbo && src_pixmap_priv->fbo->fb == dst_pixmap_priv->fbo->fb) {
|
||||
int x_shift = abs(src_x_off - dx - dst_x_off);
|
||||
int y_shift = abs(src_y_off - dy - dst_y_off);
|
||||
for (i = 0; i < nbox; i++) {
|
||||
|
|
|
@ -49,7 +49,7 @@ glamor_get_drawable_location(const DrawablePtr drawable)
|
|||
glamor_get_screen_private(drawable->pScreen);
|
||||
if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
|
||||
return 'm';
|
||||
if (pixmap_priv->fb == glamor_priv->screen_fbo)
|
||||
if (pixmap_priv->fbo->fb == glamor_priv->screen_fbo)
|
||||
return 's';
|
||||
else
|
||||
return 'f';
|
||||
|
@ -271,13 +271,13 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
|
|||
glamor_restore_pixmap_to_texture(pixmap);
|
||||
}
|
||||
|
||||
if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
|
||||
if (pixmap_priv->fbo->pbo != 0 && pixmap_priv->fbo->pbo_valid) {
|
||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
||||
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
pixmap_priv->pbo_valid = FALSE;
|
||||
dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
|
||||
pixmap_priv->pbo = 0;
|
||||
pixmap_priv->fbo->pbo_valid = FALSE;
|
||||
dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
|
||||
pixmap_priv->fbo->pbo = 0;
|
||||
} else {
|
||||
free(pixmap->devPrivate.ptr);
|
||||
}
|
||||
|
|
|
@ -79,5 +79,8 @@ AbortServer(void)
|
|||
_glamor_priv_->delayed_fallback_string); \
|
||||
_glamor_priv_->delayed_fallback_pending = 0; } } while(0)
|
||||
|
||||
#define DEBUGF(str, ...)
|
||||
//#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
132
glamor/glamor_fbo.c
Normal file
132
glamor/glamor_fbo.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
glamor_pixmap_fbo *
|
||||
glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
|
||||
int w, int h, int depth, GLint tex, int flag)
|
||||
{
|
||||
glamor_gl_dispatch *dispatch;
|
||||
glamor_pixmap_fbo *fbo;
|
||||
GLenum format;
|
||||
|
||||
fbo = calloc(1, sizeof(*fbo));
|
||||
if (fbo == NULL)
|
||||
return NULL;
|
||||
|
||||
gl_iformat_for_depth(depth, &format);
|
||||
|
||||
fbo->tex = tex;
|
||||
fbo->width = w;
|
||||
fbo->height = h;
|
||||
fbo->format = format;
|
||||
fbo->glamor_priv = glamor_priv;
|
||||
|
||||
glamor_pixmap_ensure_fb(fbo);
|
||||
|
||||
return fbo;
|
||||
}
|
||||
|
||||
/* Make sure already detached from any pixmap. */
|
||||
void
|
||||
glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
|
||||
{
|
||||
glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
|
||||
|
||||
DEBUGF("Destroy fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb);
|
||||
if (fbo->fb)
|
||||
dispatch->glDeleteFramebuffers(1, &fbo->fb);
|
||||
if (fbo->tex)
|
||||
dispatch->glDeleteTextures(1, &fbo->tex);
|
||||
if (fbo->pbo)
|
||||
dispatch->glDeleteBuffers(1, &fbo->pbo);
|
||||
|
||||
free(fbo);
|
||||
}
|
||||
|
||||
glamor_pixmap_fbo *
|
||||
glamor_create_fbo(glamor_screen_private *glamor_priv,
|
||||
int w, int h, int depth, int flag)
|
||||
{
|
||||
glamor_gl_dispatch *dispatch;
|
||||
glamor_pixmap_fbo *fbo;
|
||||
GLenum format;
|
||||
GLint tex;
|
||||
|
||||
gl_iformat_for_depth(depth, &format);
|
||||
dispatch = &glamor_priv->dispatch;
|
||||
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);
|
||||
|
||||
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
|
||||
DEBUGF("Creat fbo %p tex %d width %d height %d \n", fbo, tex, w, h);
|
||||
|
||||
return fbo;
|
||||
}
|
||||
|
||||
glamor_pixmap_fbo *
|
||||
glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
|
||||
{
|
||||
glamor_pixmap_fbo *fbo;
|
||||
|
||||
if (pixmap_priv == NULL)
|
||||
return NULL;
|
||||
|
||||
fbo = pixmap_priv->fbo;
|
||||
if (fbo == NULL)
|
||||
return NULL;
|
||||
|
||||
pixmap_priv->fbo = NULL;
|
||||
return fbo;
|
||||
}
|
||||
|
||||
/* The pixmap must not be attached to another fbo. */
|
||||
void
|
||||
glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
|
||||
{
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (pixmap_priv == NULL) {
|
||||
glamor_screen_private *glamor_priv;
|
||||
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
pixmap_priv = calloc(1, sizeof(*pixmap_priv));
|
||||
dixSetPrivate(&pixmap->devPrivates,
|
||||
glamor_pixmap_private_key, pixmap_priv);
|
||||
pixmap_priv->container = pixmap;
|
||||
pixmap_priv->glamor_priv = glamor_priv;
|
||||
pixmap_priv->type = GLAMOR_MEMORY;
|
||||
}
|
||||
|
||||
if (pixmap_priv->fbo)
|
||||
return;
|
||||
|
||||
pixmap_priv->fbo = fbo;
|
||||
|
||||
switch (pixmap_priv->type) {
|
||||
case GLAMOR_TEXTURE_ONLY:
|
||||
case GLAMOR_TEXTURE_DRM:
|
||||
pixmap_priv->gl_fbo = 1;
|
||||
if (fbo->tex != 0)
|
||||
pixmap_priv->gl_tex = 1;
|
||||
else {
|
||||
/* XXX For the Xephyr only, may be broken now.*/
|
||||
pixmap_priv->gl_tex = 0;
|
||||
}
|
||||
pixmap->devPrivate.ptr = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -89,7 +89,7 @@ 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);
|
||||
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fbo->fb);
|
||||
#ifndef GLAMOR_GLES2
|
||||
dispatch->glMatrixMode(GL_PROJECTION);
|
||||
dispatch->glLoadIdentity();
|
||||
|
@ -97,8 +97,8 @@ glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
|
|||
dispatch->glLoadIdentity();
|
||||
#endif
|
||||
dispatch->glViewport(0, 0,
|
||||
pixmap_priv->container->drawable.width,
|
||||
pixmap_priv->container->drawable.height);
|
||||
pixmap_priv->fbo->width,
|
||||
pixmap_priv->fbo->height);
|
||||
|
||||
}
|
||||
|
||||
|
@ -242,10 +242,10 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
|
|||
dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
}
|
||||
|
||||
if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
|
||||
if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid) {
|
||||
texels = NULL;
|
||||
dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
|
||||
pixmap_priv->pbo);
|
||||
pixmap_priv->fbo->pbo);
|
||||
} else
|
||||
texels = pixmap->devPrivate.ptr;
|
||||
|
||||
|
@ -309,7 +309,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
|
|||
* to the fbo directly. */
|
||||
if (no_alpha == 0 && no_revert == 1 && !need_flip) {
|
||||
__glamor_upload_pixmap_to_texture(pixmap, format, type,
|
||||
pixmap_priv->tex);
|
||||
pixmap_priv->fbo->tex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -363,19 +363,18 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
|
|||
}
|
||||
|
||||
void
|
||||
glamor_pixmap_ensure_fb(PixmapPtr pixmap)
|
||||
glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
|
||||
{
|
||||
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);
|
||||
glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
|
||||
|
||||
if (fbo->fb == 0)
|
||||
dispatch->glGenFramebuffers(1, &fbo->fb);
|
||||
assert(fbo->tex != 0);
|
||||
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
|
||||
dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, pixmap_priv->tex,
|
||||
GL_TEXTURE_2D, fbo->tex,
|
||||
0);
|
||||
status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
|
@ -422,11 +421,13 @@ 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;
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
glamor_screen_private *glamor_priv;
|
||||
GLenum format;
|
||||
glamor_pixmap_fbo *fbo;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
|
||||
if (!glamor_check_fbo_size
|
||||
(glamor_priv, pixmap->drawable.width, pixmap->drawable.height)
|
||||
|
@ -441,28 +442,14 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
|
|||
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;
|
||||
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
pixmap->drawable.depth,
|
||||
0);
|
||||
if (fbo == NULL)
|
||||
return -1;
|
||||
|
||||
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);
|
||||
}
|
||||
glamor_pixmap_attach_fbo(pixmap, fbo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -575,7 +562,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
|
|||
|
||||
temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
|
||||
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
|
||||
dispatch->glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
GL_NEAREST);
|
||||
|
@ -599,7 +586,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
|
|||
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||
|
||||
dispatch->glActiveTexture(GL_TEXTURE0);
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->fbo->tex);
|
||||
dispatch->glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
GL_NEAREST);
|
||||
|
@ -726,11 +713,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
|||
}
|
||||
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||
if (pixmap_priv->pbo == 0)
|
||||
if (pixmap_priv->fbo->pbo == 0)
|
||||
dispatch->glGenBuffers(1,
|
||||
&pixmap_priv->pbo);
|
||||
&pixmap_priv->fbo->pbo);
|
||||
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
|
||||
pixmap_priv->pbo);
|
||||
pixmap_priv->fbo->pbo);
|
||||
dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
|
||||
stride *
|
||||
pixmap->drawable.height,
|
||||
|
@ -740,7 +727,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
|||
format, type, 0);
|
||||
data = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
|
||||
gl_access);
|
||||
pixmap_priv->pbo_valid = TRUE;
|
||||
pixmap_priv->fbo->pbo_valid = TRUE;
|
||||
|
||||
if (!glamor_priv->yInverted) {
|
||||
assert(glamor_priv->gl_flavor ==
|
||||
|
@ -762,11 +749,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
|||
data = malloc(stride * pixmap->drawable.height);
|
||||
assert(data);
|
||||
if (access != GLAMOR_ACCESS_WO) {
|
||||
if (pixmap_priv->pbo == 0)
|
||||
if (pixmap_priv->fbo->pbo == 0)
|
||||
dispatch->glGenBuffers(1,
|
||||
&pixmap_priv->pbo);
|
||||
&pixmap_priv->fbo->pbo);
|
||||
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
|
||||
pixmap_priv->pbo);
|
||||
pixmap_priv->fbo->pbo);
|
||||
dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
|
||||
stride *
|
||||
pixmap->drawable.height,
|
||||
|
@ -783,9 +770,9 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
|||
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;
|
||||
pixmap_priv->fbo->pbo_valid = FALSE;
|
||||
dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
|
||||
pixmap_priv->fbo->pbo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,29 +785,3 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
|
||||
#include "glamor_debug.h"
|
||||
|
||||
#include <list.h>
|
||||
|
||||
typedef struct glamor_composite_shader {
|
||||
GLuint prog;
|
||||
GLint dest_to_dest_uniform_location;
|
||||
|
@ -123,6 +125,7 @@ enum glamor_gl_flavor {
|
|||
};
|
||||
|
||||
#define GLAMOR_CREATE_PIXMAP_CPU 0x100
|
||||
#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101
|
||||
|
||||
#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
|
||||
|
||||
|
@ -156,6 +159,10 @@ struct glamor_saved_procs {
|
|||
UnrealizeGlyphProcPtr unrealize_glyph;
|
||||
};
|
||||
|
||||
#define CACHE_FORMAT_COUNT 2
|
||||
#define CACHE_BUCKET_WCOUNT 16
|
||||
#define CACHE_BUCKET_HCOUNT 16
|
||||
|
||||
typedef struct glamor_screen_private {
|
||||
struct glamor_gl_dispatch dispatch;
|
||||
int yInverted;
|
||||
|
@ -238,15 +245,25 @@ typedef union _glamor_pending_op {
|
|||
* @container: The corresponding pixmap's pointer.
|
||||
**/
|
||||
|
||||
typedef struct glamor_pixmap_private {
|
||||
glamor_pixmap_type_t type;
|
||||
unsigned char gl_fbo:1;
|
||||
unsigned char gl_tex:1;
|
||||
unsigned char pbo_valid:1;
|
||||
unsigned char is_picture:1;
|
||||
typedef struct glamor_pixmap_fbo {
|
||||
unsigned char pbo_valid;
|
||||
GLuint tex;
|
||||
GLuint fb;
|
||||
GLuint pbo;
|
||||
int width;
|
||||
int height;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
glamor_screen_private *glamor_priv;
|
||||
} glamor_pixmap_fbo;
|
||||
|
||||
|
||||
typedef struct glamor_pixmap_private {
|
||||
unsigned char gl_fbo:1;
|
||||
unsigned char is_picture:1;
|
||||
unsigned char gl_tex:1;
|
||||
glamor_pixmap_type_t type;
|
||||
glamor_pixmap_fbo *fbo;
|
||||
PictFormatShort pict_format;
|
||||
glamor_pending_op pending_op;
|
||||
PixmapPtr container;
|
||||
|
@ -311,6 +328,23 @@ PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
|||
|
||||
Bool glamor_destroy_pixmap(PixmapPtr pixmap);
|
||||
|
||||
glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv);
|
||||
void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
|
||||
glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
|
||||
int w, int h, int depth, GLint tex, int flag);
|
||||
glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
|
||||
int w, int h, int depth, int flag);
|
||||
void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
|
||||
|
||||
Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
|
||||
|
||||
Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
|
||||
|
||||
#define GLAMOR_CACHE_GET_DEFAULT 0
|
||||
#define GLAMOR_CACHE_GET_EAXCT_SIZE 1
|
||||
#define GLAMOR_CACHE_GET_UPLOAD 2
|
||||
|
||||
|
||||
/* glamor_copyarea.c */
|
||||
RegionPtr
|
||||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
|
@ -503,14 +537,14 @@ Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap,
|
|||
**/
|
||||
void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
|
||||
/**
|
||||
* Ensure to have a fbo attached to the pixmap.
|
||||
* If the pixmap already has one fbo then do nothing.
|
||||
* Otherwise, it will generate a new fbo, and bind
|
||||
* the pixmap's texture to the fbo.
|
||||
* The pixmap must has a valid texture before call this
|
||||
* Ensure to have a fbo has a valid/complete glfbo.
|
||||
* If the fbo already has a valid glfbo then do nothing.
|
||||
* Otherwise, it will generate a new glfbo, and bind
|
||||
* the fbo's texture to the glfbo.
|
||||
* The fbo must has a valid texture before call this
|
||||
* API, othersie, it will trigger a assert.
|
||||
*/
|
||||
void glamor_pixmap_ensure_fb(PixmapPtr pixmap);
|
||||
void glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo);
|
||||
|
||||
/**
|
||||
* Upload a pixmap to gl texture. Used by dynamic pixmap
|
||||
|
|
|
@ -388,7 +388,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
|
|||
glamor_get_screen_private(screen);
|
||||
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
|
||||
dispatch->glActiveTexture(GL_TEXTURE0 + unit);
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
|
||||
switch (picture->repeatType) {
|
||||
case RepeatNone:
|
||||
#ifndef GLAMOR_GLES2
|
||||
|
@ -923,18 +923,16 @@ glamor_composite_with_shader(CARD8 op,
|
|||
|
||||
mask_status = GLAMOR_NONE;
|
||||
}
|
||||
source_status = glamor_upload_picture_to_texture(source);
|
||||
|
||||
source_status = glamor_upload_picture_to_texture(source);
|
||||
if (source_status != GLAMOR_UPLOAD_DONE) {
|
||||
glamor_fallback
|
||||
("Failed to upload source texture.\n");
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (source_status == GLAMOR_UPLOAD_PENDING) {
|
||||
source_status =
|
||||
glamor_upload_picture_to_texture(source);
|
||||
source_status = glamor_upload_picture_to_texture(source);
|
||||
if (source_status != GLAMOR_UPLOAD_DONE) {
|
||||
glamor_fallback
|
||||
("Failed to upload source texture.\n");
|
||||
|
@ -943,9 +941,7 @@ glamor_composite_with_shader(CARD8 op,
|
|||
}
|
||||
|
||||
if (mask_status == GLAMOR_UPLOAD_PENDING) {
|
||||
mask_status =
|
||||
glamor_upload_picture_to_texture(mask);
|
||||
|
||||
mask_status = glamor_upload_picture_to_texture(mask);
|
||||
if (mask_status != GLAMOR_UPLOAD_DONE) {
|
||||
glamor_fallback
|
||||
("Failed to upload mask texture.\n");
|
||||
|
@ -1208,22 +1204,14 @@ _glamor_composite(CARD8 op,
|
|||
if (source->pDrawable) {
|
||||
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
|
||||
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
|
||||
if (!source_pixmap_priv) {
|
||||
glamor_set_pixmap_type(source_pixmap, GLAMOR_MEMORY);
|
||||
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
|
||||
}
|
||||
if (source_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
||||
if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (mask && mask->pDrawable) {
|
||||
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
|
||||
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
|
||||
if (!mask_pixmap_priv) {
|
||||
glamor_set_pixmap_type(mask_pixmap, GLAMOR_MEMORY);
|
||||
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
|
||||
}
|
||||
if (mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
||||
if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
||||
goto fail;
|
||||
}
|
||||
if ((!source->pDrawable
|
||||
|
|
|
@ -156,7 +156,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
|||
|
||||
dispatch->glActiveTexture(GL_TEXTURE0);
|
||||
dispatch->glBindTexture(GL_TEXTURE_2D,
|
||||
src_pixmap_priv->tex);
|
||||
src_pixmap_priv->fbo->tex);
|
||||
dispatch->glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
GL_NEAREST);
|
||||
|
|
|
@ -13,12 +13,11 @@
|
|||
#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
|
||||
|
||||
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
||||
do { \
|
||||
*(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width; \
|
||||
*(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height; \
|
||||
do { \
|
||||
*(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width; \
|
||||
*(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height; \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \
|
||||
+ ((float)xFixedFrac(_val_) / 65536.0))
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user