Commit f871d174 authored by Zhigang Gong's avatar Zhigang Gong

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.
parent 74ca45e7
......@@ -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;
......
......@@ -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);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment