Пример #1
0
_X_EXPORT void
glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
{
    ScreenPtr screen = pixmap->drawable.pScreen;
    glamor_pixmap_private *pixmap_priv;
    glamor_screen_private *glamor_priv;
    glamor_pixmap_fbo *fbo;
    GLenum format;

    glamor_priv = glamor_get_screen_private(screen);
    pixmap_priv = glamor_get_pixmap_private(pixmap);

    if (pixmap_priv->base.fbo) {
        fbo = glamor_pixmap_detach_fbo(pixmap_priv);
        glamor_destroy_fbo(fbo);
    }

    format = gl_iformat_for_pixmap(pixmap);
    fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
                                     pixmap->drawable.height, format, tex, 0);

    if (fbo == NULL) {
        ErrorF("XXX fail to create fbo.\n");
        return;
    }

    glamor_pixmap_attach_fbo(pixmap, fbo);
}
/**
 * Upload pixmap to a specified texture.
 * This texture may not be the one attached to it.
 **/
static Bool
__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
                                  GLenum format,
                                  GLenum type,
                                  int x, int y, int w, int h,
                                  void *bits, int pbo)
{
    glamor_screen_private *glamor_priv =
        glamor_get_screen_private(pixmap->drawable.pScreen);
    int non_sub = 0;
    unsigned int iformat = 0;

    glamor_make_current(glamor_priv);
    if (*tex == 0) {
        glGenTextures(1, tex);
        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
            iformat = gl_iformat_for_pixmap(pixmap);
        else
            iformat = format;
        non_sub = 1;
        assert(x == 0 && y == 0);
    }

    glBindTexture(GL_TEXTURE_2D, *tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    assert(pbo || bits != 0);
    if (bits == NULL) {
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
        glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    }
    glamor_priv->suppress_gl_out_of_memory_logging = true;
    if (non_sub)
        glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
    else
        glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
    glamor_priv->suppress_gl_out_of_memory_logging = false;
    if (glGetError() == GL_OUT_OF_MEMORY) {
        if (non_sub) {
            glDeleteTextures(1, tex);
            *tex = 0;
        }
        return FALSE;
    }

    if (bits == NULL)
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

    return TRUE;
}
Пример #3
0
/*
 * Prepare to upload a pixmap to texture memory.
 * no_alpha equals 1 means the format needs to wire alpha to 1.
 */
static int
glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
                             int revert, int swap_rb)
{
    int flag = 0;
    glamor_pixmap_private *pixmap_priv;
    glamor_screen_private *glamor_priv;
    glamor_pixmap_fbo *fbo;
    GLenum iformat;

    pixmap_priv = glamor_get_pixmap_private(pixmap);
    glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);

    if (pixmap_priv->base.gl_fbo != GLAMOR_FBO_UNATTACHED)
        return 0;

    if (pixmap_priv->base.fbo
        && (pixmap_priv->base.fbo->width < pixmap->drawable.width
            || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
        fbo = glamor_pixmap_detach_fbo(pixmap_priv);
        glamor_destroy_fbo(fbo);
    }

    if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
        return 0;

    if (!(no_alpha || (revert == REVERT_NORMAL)
          || (swap_rb != SWAP_NONE_UPLOADING))) {
        /* We don't need a fbo, a simple texture uploading should work. */

        flag = GLAMOR_CREATE_FBO_NO_FBO;
    }

    if ((flag == GLAMOR_CREATE_FBO_NO_FBO
         && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
        || (flag == 0 && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
        return 0;

    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
        iformat = gl_iformat_for_pixmap(pixmap);
    else
        iformat = format;

    if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
        return -1;

    return 0;
}
Пример #4
0
PixmapPtr
glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                     unsigned int usage)
{
    PixmapPtr pixmap;
    glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
    glamor_pixmap_private *pixmap_priv;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    glamor_pixmap_fbo *fbo = NULL;
    int pitch;
    GLenum format;

    if (w > 32767 || h > 32767)
        return NullPixmap;

    if ((usage == GLAMOR_CREATE_PIXMAP_CPU
         || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64)
         || (w == 0 && h == 0)
         || !glamor_check_pixmap_fbo_depth(depth))
        || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
            !glamor_check_fbo_size(glamor_priv, w, h)))
        return fbCreatePixmap(screen, w, h, depth, usage);
    else
        pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);

    pixmap_priv = calloc(1, sizeof(*pixmap_priv));

    if (!pixmap_priv) {
        fbDestroyPixmap(pixmap);
        return fbCreatePixmap(screen, w, h, depth, usage);
    }
    glamor_set_pixmap_private(pixmap, pixmap_priv);

    if (usage == GLAMOR_CREATE_PIXMAP_MAP)
        type = GLAMOR_MEMORY_MAP;

    pixmap_priv->base.pixmap = pixmap;
    pixmap_priv->base.glamor_priv = glamor_priv;

    format = gl_iformat_for_pixmap(pixmap);

    pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);

    if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
        pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
        pixmap_priv->base.box.x1 = 0;
        pixmap_priv->base.box.y1 = 0;
        pixmap_priv->base.box.x2 = w;
        pixmap_priv->base.box.y2 = h;
        return pixmap;
    }
    else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
        glamor_check_fbo_size(glamor_priv, w, h))
    {
        pixmap_priv->type = type;
        pixmap_priv->base.box.x1 = 0;
        pixmap_priv->base.box.y1 = 0;
        pixmap_priv->base.box.x2 = w;
        pixmap_priv->base.box.y2 = h;
        fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
    } else {
        int tile_size = glamor_priv->max_fbo_size;
        DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size);
        pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
        fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
                                      tile_size, tile_size, pixmap_priv);
    }

    if (fbo == NULL) {
        fbDestroyPixmap(pixmap);
        free(pixmap_priv);
        return fbCreatePixmap(screen, w, h, depth, usage);
    }

    glamor_pixmap_attach_fbo(pixmap, fbo);

    return pixmap;
}