glamor: Replace "finish access" shader with texture swizzling.
For pictures without alpha, and for most other formats for GLES2, we would make a temporary FBO, make another temporary texture, upload our GLAMOR_MEMORY pixmap to the texture, then run the "finish access" shader across it to swizzle its values around into the temporary FBO (which we would use for a single Render operation and then throw away). We can simplify everything by using GL_ARB_texture_swizzle (or its GLES3 counterpart). It's just not worth the complexity to try to improve the performance of this already low-performance path (SHM pixmaps + Render) on GLES2. Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
b0cc04992c
commit
0b4c0c75d0
|
@ -605,9 +605,15 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
glamor_priv->max_fbo_size = MAX_FBO_SIZE;
|
glamor_priv->max_fbo_size = MAX_FBO_SIZE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glamor_priv->has_texture_swizzle =
|
||||||
|
(epoxy_has_gl_extension("GL_ARB_texture_swizzle") ||
|
||||||
|
(glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && gl_version >= 30));
|
||||||
|
|
||||||
glamor_priv->one_channel_format = GL_ALPHA;
|
glamor_priv->one_channel_format = GL_ALPHA;
|
||||||
if (epoxy_has_gl_extension("GL_ARB_texture_rg") && epoxy_has_gl_extension("GL_ARB_texture_swizzle"))
|
if (epoxy_has_gl_extension("GL_ARB_texture_rg") &&
|
||||||
|
glamor_priv->has_texture_swizzle) {
|
||||||
glamor_priv->one_channel_format = GL_RED;
|
glamor_priv->one_channel_format = GL_RED;
|
||||||
|
}
|
||||||
|
|
||||||
glamor_set_debug_level(&glamor_debug_level);
|
glamor_set_debug_level(&glamor_debug_level);
|
||||||
|
|
||||||
|
@ -668,7 +674,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
|
|
||||||
glamor_init_vbo(screen);
|
glamor_init_vbo(screen);
|
||||||
glamor_init_pixmap_fbo(screen);
|
glamor_init_pixmap_fbo(screen);
|
||||||
glamor_init_finish_access_shaders(screen);
|
|
||||||
|
|
||||||
#ifdef GLAMOR_GRADIENT_SHADER
|
#ifdef GLAMOR_GRADIENT_SHADER
|
||||||
glamor_init_gradient_shader(screen);
|
glamor_init_gradient_shader(screen);
|
||||||
|
|
|
@ -113,164 +113,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* When downloading a unsupported color format to CPU memory,
|
|
||||||
we need to shuffle the color elements and then use a supported
|
|
||||||
color format to read it back to CPU memory.
|
|
||||||
|
|
||||||
For an example, the picture's format is PICT_b8g8r8a8,
|
|
||||||
Then the expecting color layout is as below (little endian):
|
|
||||||
0 1 2 3 : address
|
|
||||||
a r g b
|
|
||||||
|
|
||||||
Now the in GLES2 the supported color format is GL_RGBA, type is
|
|
||||||
GL_UNSIGNED_TYPE, then we need to shuffle the fragment
|
|
||||||
color as :
|
|
||||||
frag_color = sample(texture).argb;
|
|
||||||
before we use glReadPixel to get it back.
|
|
||||||
|
|
||||||
For the uploading process, the shuffle is a revert shuffle.
|
|
||||||
We still use GL_RGBA, GL_UNSIGNED_BYTE to upload the color
|
|
||||||
to a texture, then let's see
|
|
||||||
0 1 2 3 : address
|
|
||||||
a r g b : correct colors
|
|
||||||
R G B A : GL_RGBA with GL_UNSIGNED_BYTE
|
|
||||||
|
|
||||||
Now we need to shuffle again, the mapping rule is
|
|
||||||
r = G, g = B, b = A, a = R. Then the uploading shuffle is as
|
|
||||||
below:
|
|
||||||
frag_color = sample(texture).gbar;
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_init_finish_access_shaders(ScreenPtr screen)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
const char *vs_source =
|
|
||||||
"attribute vec4 v_position;\n"
|
|
||||||
"attribute vec4 v_texcoord0;\n"
|
|
||||||
"varying vec2 source_texture;\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" gl_Position = v_position;\n"
|
|
||||||
" source_texture = v_texcoord0.xy;\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
const char *common_source =
|
|
||||||
GLAMOR_DEFAULT_PRECISION
|
|
||||||
"varying vec2 source_texture;\n"
|
|
||||||
"uniform sampler2D sampler;\n"
|
|
||||||
"uniform int revert;\n"
|
|
||||||
"uniform int swap_rb;\n"
|
|
||||||
"#define REVERT_NONE 0\n"
|
|
||||||
"#define REVERT_NORMAL 1\n"
|
|
||||||
"#define SWAP_UPLOADING 2\n"
|
|
||||||
"#define SWAP_NONE_UPLOADING 3\n";
|
|
||||||
|
|
||||||
const char *fs_source =
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 color = texture2D(sampler, source_texture);\n"
|
|
||||||
" if (revert == REVERT_NONE) \n"
|
|
||||||
" { \n"
|
|
||||||
" if ((swap_rb != SWAP_NONE_UPLOADING)) \n"
|
|
||||||
" gl_FragColor = color.bgra;\n"
|
|
||||||
" else \n"
|
|
||||||
" gl_FragColor = color.rgba;\n"
|
|
||||||
" } \n"
|
|
||||||
" else \n"
|
|
||||||
" { \n"
|
|
||||||
" if (swap_rb == SWAP_UPLOADING)\n"
|
|
||||||
" gl_FragColor = color.gbar;\n"
|
|
||||||
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
|
|
||||||
" gl_FragColor = color.abgr;\n"
|
|
||||||
" } \n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
const char *set_alpha_source =
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 color = texture2D(sampler, source_texture);\n"
|
|
||||||
" if (revert == REVERT_NONE) \n"
|
|
||||||
" { \n"
|
|
||||||
" if (swap_rb != SWAP_NONE_UPLOADING) \n"
|
|
||||||
" gl_FragColor = vec4(color.bgr, 1);\n"
|
|
||||||
" else \n"
|
|
||||||
" gl_FragColor = vec4(color.rgb, 1);\n"
|
|
||||||
" } \n"
|
|
||||||
" else \n"
|
|
||||||
" { \n"
|
|
||||||
" if (swap_rb == SWAP_UPLOADING)\n"
|
|
||||||
" gl_FragColor = vec4(color.gba, 1);\n"
|
|
||||||
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
|
|
||||||
" gl_FragColor = vec4(color.abg, 1);\n"
|
|
||||||
" } \n"
|
|
||||||
"}\n";
|
|
||||||
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
|
|
||||||
GLint sampler_uniform_location;
|
|
||||||
char *source;
|
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(screen);
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glamor_priv->finish_access_prog[0] = glCreateProgram();
|
|
||||||
glamor_priv->finish_access_prog[1] = glCreateProgram();
|
|
||||||
|
|
||||||
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
|
|
||||||
|
|
||||||
XNFasprintf(&source, "%s%s", common_source, fs_source);
|
|
||||||
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
|
|
||||||
free(source);
|
|
||||||
|
|
||||||
glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
|
|
||||||
glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
|
|
||||||
|
|
||||||
avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
|
|
||||||
|
|
||||||
XNFasprintf(&source, "%s%s", common_source, set_alpha_source);
|
|
||||||
set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER,
|
|
||||||
source);
|
|
||||||
free(source);
|
|
||||||
|
|
||||||
glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
|
|
||||||
glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
|
|
||||||
|
|
||||||
glBindAttribLocation(glamor_priv->finish_access_prog[0],
|
|
||||||
GLAMOR_VERTEX_POS, "v_position");
|
|
||||||
glBindAttribLocation(glamor_priv->finish_access_prog[0],
|
|
||||||
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
|
|
||||||
glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[0],
|
|
||||||
"finish access 0");
|
|
||||||
|
|
||||||
glBindAttribLocation(glamor_priv->finish_access_prog[1],
|
|
||||||
GLAMOR_VERTEX_POS, "v_position");
|
|
||||||
glBindAttribLocation(glamor_priv->finish_access_prog[1],
|
|
||||||
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
|
|
||||||
glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[1],
|
|
||||||
"finish access 1");
|
|
||||||
|
|
||||||
glamor_priv->finish_access_revert[0] =
|
|
||||||
glGetUniformLocation(glamor_priv->finish_access_prog[0], "revert");
|
|
||||||
|
|
||||||
glamor_priv->finish_access_swap_rb[0] =
|
|
||||||
glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
|
|
||||||
sampler_uniform_location =
|
|
||||||
glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
|
|
||||||
glUseProgram(glamor_priv->finish_access_prog[0]);
|
|
||||||
glUniform1i(sampler_uniform_location, 0);
|
|
||||||
glUniform1i(glamor_priv->finish_access_revert[0], 0);
|
|
||||||
glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
|
|
||||||
|
|
||||||
glamor_priv->finish_access_revert[1] =
|
|
||||||
glGetUniformLocation(glamor_priv->finish_access_prog[1], "revert");
|
|
||||||
glamor_priv->finish_access_swap_rb[1] =
|
|
||||||
glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
|
|
||||||
sampler_uniform_location =
|
|
||||||
glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
|
|
||||||
glUseProgram(glamor_priv->finish_access_prog[1]);
|
|
||||||
glUniform1i(glamor_priv->finish_access_revert[1], 0);
|
|
||||||
glUniform1i(sampler_uniform_location, 0);
|
|
||||||
glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GCOps glamor_gc_ops = {
|
static GCOps glamor_gc_ops = {
|
||||||
.FillSpans = glamor_fill_spans,
|
.FillSpans = glamor_fill_spans,
|
||||||
|
|
|
@ -170,6 +170,17 @@ glamor_pixmap_fbo_cache_put(glamor_screen_private *glamor_priv,
|
||||||
("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n",
|
("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n",
|
||||||
fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
|
fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
|
||||||
|
|
||||||
|
/* Reset the texture swizzle that may have been set by
|
||||||
|
* glamor_picture.c. Don't reset GL_RED -> GL_ALPHA swizzle, though
|
||||||
|
*/
|
||||||
|
if (glamor_priv->has_texture_swizzle && n_format != 2) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, fbo->tex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
|
||||||
|
}
|
||||||
|
|
||||||
glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
|
glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
|
||||||
xorg_list_add(&fbo->list, cache);
|
xorg_list_add(&fbo->list, cache);
|
||||||
fbo->expire = glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
|
fbo->expire = glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright © 2016 Broadcom
|
||||||
* Copyright © 2009 Intel Corporation
|
* Copyright © 2009 Intel Corporation
|
||||||
* Copyright © 1998 Keith Packard
|
* Copyright © 1998 Keith Packard
|
||||||
*
|
*
|
||||||
|
@ -20,10 +21,19 @@
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file glamor_picture.c
|
||||||
*
|
*
|
||||||
* Authors:
|
* Implements temporary uploads of GL_MEMORY Pixmaps to a texture that
|
||||||
* Zhigang Gong <zhigang.gong@gmail.com>
|
* is swizzled appropriately for a given Render picture format.
|
||||||
|
* laid *
|
||||||
*
|
*
|
||||||
|
* This is important because GTK likes to use SHM Pixmaps for Render
|
||||||
|
* blending operations, and we don't want a blend operation to fall
|
||||||
|
* back to software (readback is more expensive than the upload we do
|
||||||
|
* here, and you'd have to re-upload the fallback output anyway).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -31,40 +41,54 @@
|
||||||
#include "glamor_priv.h"
|
#include "glamor_priv.h"
|
||||||
#include "mipict.h"
|
#include "mipict.h"
|
||||||
|
|
||||||
/*
|
static void byte_swap_swizzle(GLenum *swizzle)
|
||||||
* Map picture's format to the correct gl texture format and type.
|
{
|
||||||
* no_alpha is used to indicate whehter we need to wire alpha to 1.
|
GLenum temp;
|
||||||
|
|
||||||
|
temp = swizzle[0];
|
||||||
|
swizzle[0] = swizzle[3];
|
||||||
|
swizzle[3] = temp;
|
||||||
|
|
||||||
|
temp = swizzle[1];
|
||||||
|
swizzle[1] = swizzle[2];
|
||||||
|
swizzle[2] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GL format and type for uploading our bits to a given PictFormat.
|
||||||
*
|
*
|
||||||
* Although opengl support A1/GL_BITMAP, we still don't use it
|
* We may need to tell the caller to translate the bits to another
|
||||||
* here, it seems that mesa has bugs when uploading a A1 bitmap.
|
* format, as in PICT_a1 (which GL doesn't support). We may also need
|
||||||
*
|
* to tell the GL to swizzle the texture on sampling, because GLES3
|
||||||
* Return 0 if find a matched texture type. Otherwise return -1.
|
* doesn't support the GL_UNSIGNED_INT_8_8_8_8{,_REV} types, so we
|
||||||
**/
|
* don't have enough channel reordering options at upload time without
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
static Bool
|
static Bool
|
||||||
glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
PictFormatShort format,
|
PictFormatShort format,
|
||||||
|
PictFormatShort *temp_format,
|
||||||
GLenum *tex_format,
|
GLenum *tex_format,
|
||||||
GLenum *tex_type,
|
GLenum *tex_type,
|
||||||
int *no_alpha,
|
GLenum *swizzle)
|
||||||
int *revert,
|
|
||||||
int *swap_rb)
|
|
||||||
{
|
{
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
|
||||||
Bool is_little_endian = IMAGE_BYTE_ORDER == LSBFirst;
|
Bool is_little_endian = IMAGE_BYTE_ORDER == LSBFirst;
|
||||||
|
|
||||||
*no_alpha = 0;
|
*temp_format = format;
|
||||||
*revert = REVERT_NONE;
|
swizzle[0] = GL_RED;
|
||||||
*swap_rb = SWAP_NONE_UPLOADING;
|
swizzle[1] = GL_GREEN;
|
||||||
|
swizzle[2] = GL_BLUE;
|
||||||
|
swizzle[3] = GL_ALPHA;
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case PICT_a1:
|
case PICT_a1:
|
||||||
*tex_format = glamor_priv->one_channel_format;
|
*tex_format = glamor_priv->one_channel_format;
|
||||||
*tex_type = GL_UNSIGNED_BYTE;
|
*tex_type = GL_UNSIGNED_BYTE;
|
||||||
*revert = REVERT_UPLOADING_A1;
|
*temp_format = PICT_a8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_b8g8r8x8:
|
case PICT_b8g8r8x8:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_b8g8r8a8:
|
case PICT_b8g8r8a8:
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_format = GL_BGRA;
|
*tex_format = GL_BGRA;
|
||||||
|
@ -72,13 +96,18 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
} else {
|
} else {
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
*tex_type = GL_UNSIGNED_BYTE;
|
*tex_type = GL_UNSIGNED_BYTE;
|
||||||
*swap_rb = SWAP_UPLOADING;
|
|
||||||
*revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
|
swizzle[0] = GL_GREEN;
|
||||||
|
swizzle[1] = GL_BLUE;
|
||||||
|
swizzle[2] = GL_ALPHA;
|
||||||
|
swizzle[3] = GL_RED;
|
||||||
|
|
||||||
|
if (!is_little_endian)
|
||||||
|
byte_swap_swizzle(swizzle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x8r8g8b8:
|
case PICT_x8r8g8b8:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a8r8g8b8:
|
case PICT_a8r8g8b8:
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_format = GL_BGRA;
|
*tex_format = GL_BGRA;
|
||||||
|
@ -86,26 +115,31 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
} else {
|
} else {
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
*tex_type = GL_UNSIGNED_BYTE;
|
*tex_type = GL_UNSIGNED_BYTE;
|
||||||
*swap_rb = SWAP_UPLOADING;
|
|
||||||
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
|
swizzle[0] = GL_BLUE;
|
||||||
|
swizzle[2] = GL_RED;
|
||||||
|
|
||||||
|
if (!is_little_endian)
|
||||||
|
byte_swap_swizzle(swizzle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x8b8g8r8:
|
case PICT_x8b8g8r8:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a8b8g8r8:
|
case PICT_a8b8g8r8:
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
} else {
|
} else {
|
||||||
|
*tex_format = GL_RGBA;
|
||||||
*tex_type = GL_UNSIGNED_BYTE;
|
*tex_type = GL_UNSIGNED_BYTE;
|
||||||
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
|
|
||||||
|
if (!is_little_endian)
|
||||||
|
byte_swap_swizzle(swizzle);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x2r10g10b10:
|
case PICT_x2r10g10b10:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a2r10g10b10:
|
case PICT_a2r10g10b10:
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_format = GL_BGRA;
|
*tex_format = GL_BGRA;
|
||||||
|
@ -116,7 +150,6 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x2b10g10r10:
|
case PICT_x2b10g10r10:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a2b10g10r10:
|
case PICT_a2b10g10r10:
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
|
@ -129,8 +162,6 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
case PICT_r5g6b5:
|
case PICT_r5g6b5:
|
||||||
*tex_format = GL_RGB;
|
*tex_format = GL_RGB;
|
||||||
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
|
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
|
||||||
if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP)
|
|
||||||
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
|
|
||||||
break;
|
break;
|
||||||
case PICT_b5g6r5:
|
case PICT_b5g6r5:
|
||||||
*tex_format = GL_RGB;
|
*tex_format = GL_RGB;
|
||||||
|
@ -138,14 +169,12 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
*tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
|
*tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
|
||||||
} else {
|
} else {
|
||||||
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
|
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
|
||||||
if (is_little_endian)
|
swizzle[0] = GL_BLUE;
|
||||||
*swap_rb = SWAP_UPLOADING;
|
swizzle[2] = GL_RED;
|
||||||
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x1b5g5r5:
|
case PICT_x1b5g5r5:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a1b5g5r5:
|
case PICT_a1b5g5r5:
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
|
@ -156,7 +185,6 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x1r5g5b5:
|
case PICT_x1r5g5b5:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a1r5g5b5:
|
case PICT_a1r5g5b5:
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_format = GL_BGRA;
|
*tex_format = GL_BGRA;
|
||||||
|
@ -172,35 +200,36 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x4r4g4b4:
|
case PICT_x4r4g4b4:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a4r4g4b4:
|
case PICT_a4r4g4b4:
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_format = GL_BGRA;
|
*tex_format = GL_BGRA;
|
||||||
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
||||||
} else {
|
} else {
|
||||||
|
/* XXX */
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
|
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||||
*revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
|
|
||||||
*swap_rb = SWAP_UPLOADING;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_x4b4g4r4:
|
case PICT_x4b4g4r4:
|
||||||
*no_alpha = 1;
|
|
||||||
case PICT_a4b4g4r4:
|
case PICT_a4b4g4r4:
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
||||||
} else {
|
} else {
|
||||||
|
/* XXX */
|
||||||
*tex_format = GL_RGBA;
|
*tex_format = GL_RGBA;
|
||||||
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
|
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||||
*revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!PICT_FORMAT_A(format))
|
||||||
|
swizzle[3] = GL_ONE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,194 +266,6 @@ glamor_get_converted_image(PictFormatShort dst_format,
|
||||||
return dst_image;
|
return dst_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
_glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
|
||||||
GLenum type, int no_alpha, int revert,
|
|
||||||
int swap_rb, int x, int y, int w, int h,
|
|
||||||
int stride, void *bits)
|
|
||||||
{
|
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
glamor_screen_private *glamor_priv =
|
|
||||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
|
||||||
float dst_xscale, dst_yscale;
|
|
||||||
GLuint tex = 0;
|
|
||||||
pixman_image_t *converted_image = NULL;
|
|
||||||
|
|
||||||
if (revert == REVERT_UPLOADING_A1) {
|
|
||||||
converted_image = glamor_get_converted_image(PICT_a8,
|
|
||||||
PICT_a1,
|
|
||||||
bits,
|
|
||||||
PixmapBytePad(w, 1),
|
|
||||||
w, h);
|
|
||||||
if (!converted_image)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
bits = pixman_image_get_data(converted_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try fast path firstly, upload the pixmap to the texture attached
|
|
||||||
* to the fbo directly. */
|
|
||||||
if (no_alpha == 0
|
|
||||||
&& revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING) {
|
|
||||||
int fbo_x_off, fbo_y_off;
|
|
||||||
|
|
||||||
assert(pixmap_priv->fbo->tex);
|
|
||||||
pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
|
|
||||||
|
|
||||||
assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
|
|
||||||
assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
|
|
||||||
assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
|
|
||||||
if (!__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
|
|
||||||
format, type,
|
|
||||||
x + fbo_x_off, y + fbo_y_off,
|
|
||||||
w, h,
|
|
||||||
bits)) {
|
|
||||||
if (converted_image)
|
|
||||||
pixman_image_unref(bits);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
static const float texcoords_inv[8] = { 0, 0,
|
|
||||||
1, 0,
|
|
||||||
1, 1,
|
|
||||||
0, 1
|
|
||||||
};
|
|
||||||
GLfloat *v;
|
|
||||||
char *vbo_offset;
|
|
||||||
|
|
||||||
v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset);
|
|
||||||
|
|
||||||
pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
|
|
||||||
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
|
|
||||||
dst_yscale,
|
|
||||||
x, y,
|
|
||||||
x + w, y + h,
|
|
||||||
v);
|
|
||||||
/* Slow path, we need to flip y or wire alpha to 1. */
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
|
|
||||||
if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
|
|
||||||
format, type, 0, 0, w, h, bits)) {
|
|
||||||
if (converted_image)
|
|
||||||
pixman_image_unref(bits);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&v[8], texcoords_inv, 8 * sizeof(GLfloat));
|
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
|
||||||
GL_FALSE, 2 * sizeof(float), vbo_offset);
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
|
|
||||||
GL_FALSE, 2 * sizeof(float), vbo_offset + 8 * sizeof(GLfloat));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
|
||||||
|
|
||||||
glamor_put_vbo_space(screen);
|
|
||||||
glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
|
|
||||||
glamor_set_alu(screen, GXcopy);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
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);
|
|
||||||
glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
|
|
||||||
glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
|
|
||||||
glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
|
||||||
glDeleteTextures(1, &tex);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (converted_image)
|
|
||||||
pixman_image_unref(bits);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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_screen_private *glamor_priv =
|
|
||||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
|
||||||
GLenum iformat;
|
|
||||||
|
|
||||||
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 (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads a picture based on a GLAMOR_MEMORY pixmap to a texture in a
|
* Uploads a picture based on a GLAMOR_MEMORY pixmap to a texture in a
|
||||||
* temporary FBO.
|
* temporary FBO.
|
||||||
|
@ -433,17 +274,24 @@ Bool
|
||||||
glamor_upload_picture_to_texture(PicturePtr picture)
|
glamor_upload_picture_to_texture(PicturePtr picture)
|
||||||
{
|
{
|
||||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
|
||||||
void *bits = pixmap->devPrivate.ptr;
|
|
||||||
int stride = pixmap->devKind;
|
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
GLenum format, type;
|
|
||||||
int no_alpha, revert, swap_rb;
|
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
PictFormatShort converted_format;
|
||||||
|
void *bits = pixmap->devPrivate.ptr;
|
||||||
|
int stride = pixmap->devKind;
|
||||||
|
GLenum format, type;
|
||||||
|
GLenum swizzle[4];
|
||||||
|
GLenum iformat;
|
||||||
|
Bool ret = TRUE;
|
||||||
|
Bool needs_swizzle;
|
||||||
|
pixman_image_t *converted_image = NULL;
|
||||||
|
|
||||||
assert(glamor_pixmap_is_memory(pixmap));
|
assert(glamor_pixmap_is_memory(pixmap));
|
||||||
assert(!pixmap_priv->fbo);
|
assert(!pixmap_priv->fbo);
|
||||||
|
|
||||||
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
/* No handling of large pixmap pictures here (would need to make
|
/* No handling of large pixmap pictures here (would need to make
|
||||||
* an FBO array and split the uploads across it).
|
* an FBO array and split the uploads across it).
|
||||||
*/
|
*/
|
||||||
|
@ -455,20 +303,73 @@ glamor_upload_picture_to_texture(PicturePtr picture)
|
||||||
|
|
||||||
if (!glamor_get_tex_format_type_from_pictformat(screen,
|
if (!glamor_get_tex_format_type_from_pictformat(screen,
|
||||||
picture->format,
|
picture->format,
|
||||||
|
&converted_format,
|
||||||
&format,
|
&format,
|
||||||
&type,
|
&type,
|
||||||
&no_alpha,
|
swizzle)) {
|
||||||
&revert, &swap_rb)) {
|
|
||||||
glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
|
glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
|
needs_swizzle = (swizzle[0] != GL_RED ||
|
||||||
no_alpha, revert, swap_rb,
|
swizzle[1] != GL_GREEN ||
|
||||||
0, 0,
|
swizzle[2] != GL_BLUE ||
|
||||||
pixmap->drawable.width,
|
swizzle[3] != GL_ALPHA);
|
||||||
pixmap->drawable.height,
|
|
||||||
stride, bits);
|
if (!glamor_priv->has_texture_swizzle && needs_swizzle) {
|
||||||
|
glamor_fallback("Couldn't upload temporary picture due to missing "
|
||||||
|
"GL_ARB_texture_swizzle.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (converted_format != picture->format) {
|
||||||
|
converted_image = glamor_get_converted_image(converted_format,
|
||||||
|
picture->format,
|
||||||
|
bits, stride,
|
||||||
|
pixmap->drawable.width,
|
||||||
|
pixmap->drawable.height);
|
||||||
|
if (!converted_image)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
bits = pixman_image_get_data(converted_image);
|
||||||
|
stride = pixman_image_get_stride(converted_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
||||||
|
iformat = gl_iformat_for_pixmap(pixmap);
|
||||||
|
else
|
||||||
|
iformat = format;
|
||||||
|
|
||||||
|
if (!glamor_pixmap_ensure_fbo(pixmap, iformat, GLAMOR_CREATE_FBO_NO_FBO))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
|
||||||
|
glamor_priv->suppress_gl_out_of_memory_logging = true;
|
||||||
|
|
||||||
|
/* We can't use glamor_pixmap_loop() because GLAMOR_MEMORY pixmaps
|
||||||
|
* don't have initialized boxes.
|
||||||
|
*/
|
||||||
|
glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, iformat,
|
||||||
|
pixmap->drawable.width, pixmap->drawable.height, 0,
|
||||||
|
format, type, bits);
|
||||||
|
|
||||||
|
if (needs_swizzle) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, swizzle[0]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, swizzle[1]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, swizzle[2]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, swizzle[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_priv->suppress_gl_out_of_memory_logging = false;
|
||||||
|
if (glGetError() == GL_OUT_OF_MEMORY) {
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (converted_image)
|
||||||
|
pixman_image_unref(converted_image);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,7 @@ typedef struct glamor_screen_private {
|
||||||
Bool use_quads;
|
Bool use_quads;
|
||||||
Bool has_vertex_array_object;
|
Bool has_vertex_array_object;
|
||||||
Bool has_dual_blend;
|
Bool has_dual_blend;
|
||||||
|
Bool has_texture_swizzle;
|
||||||
Bool is_core_profile;
|
Bool is_core_profile;
|
||||||
int max_fbo_size;
|
int max_fbo_size;
|
||||||
|
|
||||||
|
@ -286,11 +287,6 @@ typedef struct glamor_screen_private {
|
||||||
[glamor_program_alpha_count]
|
[glamor_program_alpha_count]
|
||||||
[SHADER_DEST_SWIZZLE_COUNT];
|
[SHADER_DEST_SWIZZLE_COUNT];
|
||||||
|
|
||||||
/* shaders to restore a texture to another texture. */
|
|
||||||
GLint finish_access_prog[2];
|
|
||||||
GLint finish_access_revert[2];
|
|
||||||
GLint finish_access_swap_rb[2];
|
|
||||||
|
|
||||||
/* glamor gradient, 0 for small nstops, 1 for
|
/* glamor gradient, 0 for small nstops, 1 for
|
||||||
large nstops and 2 for dynamic generate. */
|
large nstops and 2 for dynamic generate. */
|
||||||
GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
|
GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
|
||||||
|
@ -586,8 +582,6 @@ void glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
|
||||||
unsigned count);
|
unsigned count);
|
||||||
|
|
||||||
/* glamor_core.c */
|
/* glamor_core.c */
|
||||||
void glamor_init_finish_access_shaders(ScreenPtr screen);
|
|
||||||
|
|
||||||
Bool glamor_get_drawable_location(const DrawablePtr drawable);
|
Bool glamor_get_drawable_location(const DrawablePtr drawable);
|
||||||
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
|
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
|
||||||
int *x, int *y);
|
int *x, int *y);
|
||||||
|
|
Loading…
Reference in New Issue