glamor: Switch to software fb for too large pixmap.

If pixmap's size exceeds the limitation of the MESA library, the
rendering will fail. So we switch to software fb if it is the case.
Add one new element for pixmap private structure to indicate whehter
we are a software fb type or a opengl type.
This commit is contained in:
Zhigang Gong 2011-05-19 11:40:38 +08:00
parent 74ca45e7d0
commit f871d174a8
2 changed files with 35 additions and 9 deletions

View File

@ -95,12 +95,24 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
PixmapPtr pixmap;
GLenum format;
GLuint tex;
glamor_pixmap_private *pixmap_priv;
int type = GLAMOR_GL;
if (w > 32767 || h > 32767)
return NullPixmap;
pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
if (w > MAX_WIDTH || h > MAX_HEIGHT) {
/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
If we exceed such limitation, we have to use framebuffer.*/
type = GLAMOR_FB;
pixmap = fbCreatePixmap (screen, w, h, depth, usage);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
(((w * pixmap->drawable.bitsPerPixel +
7) / 8) + 3) & ~3,
NULL);
ErrorF("fallback to software fb for pixmap %p , %d x %d \n", pixmap, w, h);
} else
pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
fbDestroyPixmap(pixmap);
@ -108,8 +120,12 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
return NullPixmap;
}
if (w == 0 || h == 0)
if (w == 0 || h == 0 || type != GLAMOR_GL)
return pixmap;
pixmap_priv = glamor_get_pixmap_private(pixmap);
pixmap_priv->type = type;
/* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
* FBOs, which EXT_fbo forgot to do.
*/
@ -122,7 +138,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
break;
}
/* Create the texture used to store the pixmap's data. */
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
@ -132,7 +147,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
format, GL_UNSIGNED_BYTE, NULL);
glamor_set_pixmap_texture(pixmap, w, h, tex);
return pixmap;
}
@ -141,7 +155,6 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
{
if (pixmap->refcnt == 1) {
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
glDeleteTextures(1, &pixmap_priv->tex);
}
@ -285,7 +298,6 @@ glamor_close_screen(int idx, ScreenPtr screen)
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
#endif
glamor_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_close_screen;
screen->CreateGC = glamor_priv->saved_create_gc;

View File

@ -39,6 +39,14 @@
#include "glyphstr.h"
#endif
#ifndef MAX_WIDTH
#define MAX_WIDTH 4096
#endif
#ifndef MAX_HEIGHT
#define MAX_HEIGHT 4096
#endif
typedef enum glamor_access {
GLAMOR_ACCESS_RO,
GLAMOR_ACCESS_RW,
@ -175,10 +183,16 @@ typedef struct glamor_screen_private {
glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
} glamor_screen_private;
enum glamor_pixmap_type {
GLAMOR_GL,
GLAMOR_FB
};
typedef struct glamor_pixmap_private {
GLuint tex;
GLuint fb;
GLuint pbo;
enum glamor_pixmap_type type;
} glamor_pixmap_private;
extern DevPrivateKey glamor_screen_private_key;
@ -250,8 +264,8 @@ glamor_report_delayed_fallbacks(ScreenPtr screen)
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
if (glamor_priv->delayed_fallback_string) {
LogMessageVerb(X_INFO, 0, "fallback: %s",
glamor_priv->delayed_fallback_string);
// LogMessageVerb(X_INFO, 0, "fallback: %s",
// glamor_priv->delayed_fallback_string);
glamor_clear_delayed_fallbacks(screen);
}
}