Merge remote-tracking branch 'anholt/glamor-next'
This commit is contained in:
commit
5c2e9fa3d6
|
@ -7,20 +7,21 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
|
|||
libglamor_la_SOURCES = \
|
||||
glamor.c \
|
||||
glamor_context.h \
|
||||
glamor_copyarea.c \
|
||||
glamor_copywindow.c \
|
||||
glamor_copy.c \
|
||||
glamor_core.c \
|
||||
glamor_dash.c \
|
||||
glamor_debug.h \
|
||||
glamor_fill.c \
|
||||
glamor_font.c \
|
||||
glamor_font.h \
|
||||
glamor_glx.c \
|
||||
glamor_glyphs.c \
|
||||
glamor_polylines.c \
|
||||
glamor_segment.c \
|
||||
glamor_image.c \
|
||||
glamor_lines.c \
|
||||
glamor_segs.c \
|
||||
glamor_render.c \
|
||||
glamor_gradient.c \
|
||||
glamor_prepare.c \
|
||||
glamor_prepare.h \
|
||||
glamor_program.c \
|
||||
glamor_program.h \
|
||||
glamor_rects.c \
|
||||
|
@ -31,10 +32,8 @@ libglamor_la_SOURCES = \
|
|||
glamor_transform.c \
|
||||
glamor_transform.h \
|
||||
glamor_trapezoid.c \
|
||||
glamor_tile.c \
|
||||
glamor_triangles.c\
|
||||
glamor_addtraps.c\
|
||||
glamor_copyplane.c\
|
||||
glamor_glyphblt.c\
|
||||
glamor_points.c\
|
||||
glamor_priv.h\
|
||||
|
@ -45,7 +44,9 @@ libglamor_la_SOURCES = \
|
|||
glamor_window.c\
|
||||
glamor_fbo.c\
|
||||
glamor_compositerects.c\
|
||||
glamor_utils.c\
|
||||
glamor_utils.h\
|
||||
glamor_xv.c \
|
||||
glamor.h
|
||||
|
||||
libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
|
||||
|
|
|
@ -35,10 +35,9 @@
|
|||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
static DevPrivateKeyRec glamor_screen_private_key_index;
|
||||
DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
|
||||
static DevPrivateKeyRec glamor_pixmap_private_key_index;
|
||||
DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
|
||||
DevPrivateKeyRec glamor_screen_private_key;
|
||||
DevPrivateKeyRec glamor_pixmap_private_key;
|
||||
DevPrivateKeyRec glamor_gc_private_key;
|
||||
|
||||
/**
|
||||
* glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
|
||||
|
@ -68,7 +67,7 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
|
|||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
|
||||
pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
|
||||
glamor_pixmap_private_key);
|
||||
&glamor_pixmap_private_key);
|
||||
if (pixmap_priv == NULL) {
|
||||
pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
|
||||
glamor_set_pixmap_private(pixmap, pixmap_priv);
|
||||
|
@ -251,11 +250,6 @@ glamor_block_handler(ScreenPtr screen)
|
|||
glamor_priv->tick++;
|
||||
glFlush();
|
||||
glamor_fbo_expire(glamor_priv);
|
||||
if (glamor_priv->state == RENDER_STATE
|
||||
&& glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
|
||||
glamor_priv->state = IDLE_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -330,13 +324,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
return FALSE;
|
||||
|
||||
glamor_priv->flags = flags;
|
||||
if (flags & GLAMOR_INVERTED_Y_AXIS) {
|
||||
glamor_priv->yInverted = TRUE;
|
||||
}
|
||||
else
|
||||
glamor_priv->yInverted = FALSE;
|
||||
|
||||
if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
|
||||
if (!dixRegisterPrivateKey(&glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
|
||||
LogMessage(X_WARNING,
|
||||
"glamor%d: Failed to allocate screen private\n",
|
||||
screen->myNum);
|
||||
|
@ -345,11 +334,19 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
|
||||
glamor_set_screen_private(screen, glamor_priv);
|
||||
|
||||
if (!dixRegisterPrivateKey(glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
|
||||
if (!dixRegisterPrivateKey(&glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
|
||||
LogMessage(X_WARNING,
|
||||
"glamor%d: Failed to allocate pixmap private\n",
|
||||
screen->myNum);
|
||||
goto fail;;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!dixRegisterPrivateKey(&glamor_gc_private_key, PRIVATE_GC,
|
||||
sizeof (glamor_gc_private))) {
|
||||
LogMessage(X_WARNING,
|
||||
"glamor%d: Failed to allocate gc private\n",
|
||||
screen->myNum);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (epoxy_is_desktop_gl())
|
||||
|
@ -398,6 +395,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
}
|
||||
}
|
||||
|
||||
glamor_priv->has_rw_pbo = FALSE;
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
||||
glamor_priv->has_rw_pbo = TRUE;
|
||||
|
||||
glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug");
|
||||
glamor_priv->has_pack_invert =
|
||||
epoxy_has_gl_extension("GL_MESA_pack_invert");
|
||||
|
@ -407,6 +408,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
epoxy_has_gl_extension("GL_ARB_map_buffer_range");
|
||||
glamor_priv->has_buffer_storage =
|
||||
epoxy_has_gl_extension("GL_ARB_buffer_storage");
|
||||
glamor_priv->has_nv_texture_barrier =
|
||||
epoxy_has_gl_extension("GL_NV_texture_barrier");
|
||||
|
||||
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size);
|
||||
glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]);
|
||||
|
@ -505,8 +510,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
|
||||
glamor_init_vbo(screen);
|
||||
glamor_init_pixmap_fbo(screen);
|
||||
glamor_init_solid_shader(screen);
|
||||
glamor_init_tile_shader(screen);
|
||||
#ifdef GLAMOR_TRAPEZOID_SHADER
|
||||
glamor_init_trapezoid_shader(screen);
|
||||
#endif
|
||||
|
@ -538,8 +541,6 @@ glamor_release_screen_priv(ScreenPtr screen)
|
|||
#endif
|
||||
glamor_fini_vbo(screen);
|
||||
glamor_fini_pixmap_fbo(screen);
|
||||
glamor_fini_solid_shader(screen);
|
||||
glamor_fini_tile_shader(screen);
|
||||
#ifdef GLAMOR_TRAPEZOID_SHADER
|
||||
glamor_fini_trapezoid_shader(screen);
|
||||
#endif
|
||||
|
@ -559,7 +560,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
|
|||
glamor_pixmap_private *old_priv;
|
||||
glamor_pixmap_fbo *fbo;
|
||||
|
||||
old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
|
||||
old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
|
||||
|
||||
if (priv) {
|
||||
assert(old_priv == NULL);
|
||||
|
@ -572,7 +573,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
|
|||
free(old_priv);
|
||||
}
|
||||
|
||||
dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv);
|
||||
dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key, priv);
|
||||
}
|
||||
|
||||
Bool
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef enum glamor_pixmap_type {
|
|||
} glamor_pixmap_type_t;
|
||||
|
||||
#define GLAMOR_EGL_EXTERNAL_BUFFER 3
|
||||
#define GLAMOR_INVERTED_Y_AXIS 1
|
||||
#define GLAMOR_INVERTED_Y_AXIS 1 /* compat stub */
|
||||
#define GLAMOR_USE_SCREEN (1 << 1)
|
||||
#define GLAMOR_USE_PICTURE_SCREEN (1 << 2)
|
||||
#define GLAMOR_USE_EGL_SCREEN (1 << 3)
|
||||
|
@ -79,12 +79,6 @@ typedef enum glamor_pixmap_type {
|
|||
* @screen: Current screen pointer.
|
||||
* @flags: Please refer the flags description above.
|
||||
*
|
||||
* @GLAMOR_INVERTED_Y_AXIS:
|
||||
* set 1 means the GL env's origin (0,0) is at top-left.
|
||||
* EGL/DRM platform is an example need to set this bit.
|
||||
* glx platform's origin is at bottom-left thus need to
|
||||
* clear this bit.
|
||||
*
|
||||
* @GLAMOR_USE_SCREEN:
|
||||
* If running in an pre-existing X environment, and the
|
||||
* gl context is GLX, then you should set this bit and
|
||||
|
@ -321,6 +315,10 @@ extern _X_EXPORT int glamor_create_gc(GCPtr gc);
|
|||
extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes,
|
||||
DrawablePtr drawable);
|
||||
|
||||
extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
|
||||
|
||||
#define HAS_GLAMOR_DESTROY_GC 1
|
||||
|
||||
extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
|
||||
extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
|
||||
|
||||
|
@ -354,6 +352,17 @@ extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
|
|||
Bool upsidedown, Pixel bitplane,
|
||||
void *closure);
|
||||
|
||||
extern _X_EXPORT Bool glamor_copy_nf(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown, Pixel bitplane,
|
||||
void *closure);
|
||||
|
||||
extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
|
||||
PicturePtr source,
|
||||
PicturePtr mask,
|
||||
|
|
693
glamor/glamor_copy.c
Normal file
693
glamor/glamor_copy.c
Normal file
|
@ -0,0 +1,693 @@
|
|||
/*
|
||||
* Copyright © 2014 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
#include "glamor_transfer.h"
|
||||
#include "glamor_prepare.h"
|
||||
#include "glamor_transform.h"
|
||||
|
||||
struct copy_args {
|
||||
PixmapPtr src_pixmap;
|
||||
glamor_pixmap_fbo *src;
|
||||
uint32_t bitplane;
|
||||
int dx, dy;
|
||||
};
|
||||
|
||||
static Bool
|
||||
use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
|
||||
{
|
||||
struct copy_args *args = arg;
|
||||
glamor_pixmap_fbo *src = args->src;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, src->tex);
|
||||
|
||||
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
|
||||
glUniform2f(prog->fill_size_uniform, src->width, src->height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const glamor_facet glamor_facet_copyarea = {
|
||||
"copy_area",
|
||||
.vs_vars = "attribute vec2 primitive;\n",
|
||||
.vs_exec = (GLAMOR_POS(gl_Position, primitive.xy)
|
||||
" fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
|
||||
.fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
|
||||
.locations = glamor_program_location_fill,
|
||||
.use = use_copyarea,
|
||||
};
|
||||
|
||||
/*
|
||||
* Configure the copy plane program for the current operation
|
||||
*/
|
||||
|
||||
static Bool
|
||||
use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
|
||||
{
|
||||
struct copy_args *args = arg;
|
||||
glamor_pixmap_fbo *src = args->src;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, src->tex);
|
||||
|
||||
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
|
||||
glUniform2f(prog->fill_size_uniform, src->width, src->height);
|
||||
|
||||
glamor_set_color(dst, gc->fgPixel, prog->fg_uniform);
|
||||
glamor_set_color(dst, gc->bgPixel, prog->bg_uniform);
|
||||
|
||||
/* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */
|
||||
switch (args->src_pixmap->drawable.depth) {
|
||||
case 24:
|
||||
glUniform4ui(prog->bitplane_uniform,
|
||||
(args->bitplane >> 16) & 0xff,
|
||||
(args->bitplane >> 8) & 0xff,
|
||||
(args->bitplane ) & 0xff,
|
||||
0);
|
||||
|
||||
glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0);
|
||||
break;
|
||||
case 32:
|
||||
glUniform4ui(prog->bitplane_uniform,
|
||||
(args->bitplane >> 16) & 0xff,
|
||||
(args->bitplane >> 8) & 0xff,
|
||||
(args->bitplane ) & 0xff,
|
||||
(args->bitplane >> 24) & 0xff);
|
||||
|
||||
glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0xff);
|
||||
break;
|
||||
case 16:
|
||||
glUniform4ui(prog->bitplane_uniform,
|
||||
(args->bitplane >> 11) & 0x1f,
|
||||
(args->bitplane >> 5) & 0x3f,
|
||||
(args->bitplane ) & 0x1f,
|
||||
0);
|
||||
|
||||
glUniform4f(prog->bitmul_uniform, 0x1f, 0x3f, 0x1f, 0);
|
||||
break;
|
||||
case 15:
|
||||
glUniform4ui(prog->bitplane_uniform,
|
||||
(args->bitplane >> 10) & 0x1f,
|
||||
(args->bitplane >> 5) & 0x1f,
|
||||
(args->bitplane ) & 0x1f,
|
||||
0);
|
||||
|
||||
glUniform4f(prog->bitmul_uniform, 0x1f, 0x1f, 0x1f, 0);
|
||||
break;
|
||||
case 8:
|
||||
glUniform4ui(prog->bitplane_uniform,
|
||||
0, 0, 0, args->bitplane);
|
||||
glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff);
|
||||
break;
|
||||
case 1:
|
||||
glUniform4ui(prog->bitplane_uniform,
|
||||
0, 0, 0, args->bitplane);
|
||||
glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const glamor_facet glamor_facet_copyplane = {
|
||||
"copy_plane",
|
||||
.version = 130,
|
||||
.vs_vars = "attribute vec2 primitive;\n",
|
||||
.vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy))
|
||||
" fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
|
||||
.fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n"
|
||||
" if ((bits & bitplane) != uvec4(0,0,0,0))\n"
|
||||
" gl_FragColor = fg;\n"
|
||||
" else\n"
|
||||
" gl_FragColor = bg;\n"),
|
||||
.locations = glamor_program_location_fill|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
|
||||
.use = use_copyplane,
|
||||
};
|
||||
|
||||
/*
|
||||
* When all else fails, pull the bits out of the GPU and do the
|
||||
* operation with fb
|
||||
*/
|
||||
|
||||
static void
|
||||
glamor_copy_bail(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
|
||||
if (bitplane) {
|
||||
if (src->bitsPerPixel > 1)
|
||||
fbCopyNto1(src, dst, gc, box, nbox, dx, dy,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
else
|
||||
fbCopy1toN(src, dst, gc, box, nbox, dx, dy,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
} else {
|
||||
fbCopyNtoN(src, dst, gc, box, nbox, dx, dy,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
}
|
||||
}
|
||||
glamor_finish_access(dst);
|
||||
glamor_finish_access(src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements CopyPlane and CopyArea from the GPU to the GPU by using
|
||||
* the source as a texture and painting that into the destination.
|
||||
*
|
||||
* This requires that source and dest are different textures, or that
|
||||
* (if the copy area doesn't overlap), GL_NV_texture_barrier is used
|
||||
* to ensure that the caches are flushed at the right times.
|
||||
*/
|
||||
static Bool
|
||||
glamor_copy_cpu_fbo(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
FbBits *src_bits;
|
||||
FbStride src_stride;
|
||||
int src_bpp;
|
||||
int src_xoff, src_yoff;
|
||||
int dst_xoff, dst_yoff;
|
||||
|
||||
if (gc && gc->alu != GXcopy)
|
||||
goto bail;
|
||||
|
||||
if (gc && !glamor_pm_is_solid(dst, gc->planemask))
|
||||
goto bail;
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
glamor_prepare_access(src, GLAMOR_ACCESS_RO);
|
||||
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff);
|
||||
|
||||
fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff);
|
||||
|
||||
glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy,
|
||||
dst_xoff, dst_yoff,
|
||||
(uint8_t *) src_bits, src_stride * sizeof (FbBits));
|
||||
glamor_finish_access(src);
|
||||
|
||||
return TRUE;
|
||||
|
||||
bail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy from GPU to GPU by using the source
|
||||
* as a texture and painting that into the destination
|
||||
*/
|
||||
|
||||
static Bool
|
||||
glamor_copy_fbo_fbo_draw(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
int src_box_x, src_box_y, dst_box_x, dst_box_y;
|
||||
int dst_off_x, dst_off_y;
|
||||
int src_off_x, src_off_y;
|
||||
GLshort *v;
|
||||
char *vbo_offset;
|
||||
struct copy_args args;
|
||||
glamor_program *prog;
|
||||
const glamor_facet *copy_facet;
|
||||
Bool set_scissor;
|
||||
int n;
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
|
||||
goto bail_ctx;
|
||||
|
||||
if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
|
||||
goto bail_ctx;
|
||||
|
||||
if (bitplane) {
|
||||
prog = &glamor_priv->copy_plane_prog;
|
||||
copy_facet = &glamor_facet_copyplane;
|
||||
} else {
|
||||
prog = &glamor_priv->copy_area_prog;
|
||||
copy_facet = &glamor_facet_copyarea;
|
||||
}
|
||||
|
||||
if (prog->failed)
|
||||
goto bail_ctx;
|
||||
|
||||
if (!prog->prog) {
|
||||
if (!glamor_build_program(screen, prog,
|
||||
copy_facet, NULL))
|
||||
goto bail_ctx;
|
||||
}
|
||||
|
||||
args.src_pixmap = src_pixmap;
|
||||
args.bitplane = bitplane;
|
||||
|
||||
/* Set up the vertex buffers for the points */
|
||||
|
||||
v = glamor_get_vbo_space(dst->pScreen, nbox * 8 * sizeof (int16_t), &vbo_offset);
|
||||
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
|
||||
2 * sizeof (GLshort), vbo_offset);
|
||||
|
||||
for (n = 0; n < nbox; n++) {
|
||||
v[0] = box->x1; v[1] = box->y1;
|
||||
v[2] = box->x1; v[3] = box->y2;
|
||||
v[4] = box->x2; v[5] = box->y2;
|
||||
v[6] = box->x2; v[7] = box->y1;
|
||||
v += 8;
|
||||
box++;
|
||||
}
|
||||
|
||||
glamor_put_vbo_space(screen);
|
||||
|
||||
glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
|
||||
|
||||
set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE;
|
||||
if (set_scissor)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
glamor_pixmap_loop(src_priv, src_box_x, src_box_y) {
|
||||
BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y);
|
||||
|
||||
args.dx = dx + src_off_x - src_box->x1;
|
||||
args.dy = dy + src_off_y - src_box->y1;
|
||||
args.src = glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y);
|
||||
|
||||
if (!glamor_use_program(dst_pixmap, gc, prog, &args))
|
||||
goto bail_ctx;
|
||||
|
||||
glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) {
|
||||
glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE,
|
||||
prog->matrix_uniform, &dst_off_x, &dst_off_y);
|
||||
|
||||
if (set_scissor)
|
||||
glScissor(dst_off_x - args.dx,
|
||||
dst_off_y - args.dy,
|
||||
src_box->x2 - src_box->x1,
|
||||
src_box->y2 - src_box->y1);
|
||||
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
||||
glDrawArrays(GL_QUADS, 0, nbox * 4);
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < nbox; i++)
|
||||
glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (set_scissor)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
return TRUE;
|
||||
|
||||
bail_ctx:
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies from the GPU to the GPU using a temporary pixmap in between,
|
||||
* to correctly handle overlapping copies.
|
||||
*/
|
||||
|
||||
static Bool
|
||||
glamor_copy_fbo_fbo_temp(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
PixmapPtr tmp_pixmap;
|
||||
BoxRec bounds;
|
||||
int n;
|
||||
BoxPtr tmp_box;
|
||||
|
||||
if (nbox == 0)
|
||||
return TRUE;
|
||||
|
||||
/* Sanity check state to avoid getting halfway through and bailing
|
||||
* at the last second. Might be nice to have checks that didn't
|
||||
* involve setting state.
|
||||
*/
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
|
||||
goto bail_ctx;
|
||||
|
||||
if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
|
||||
goto bail_ctx;
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
|
||||
/* Find the size of the area to copy
|
||||
*/
|
||||
bounds = box[0];
|
||||
for (n = 1; n < nbox; n++) {
|
||||
bounds.x1 = min(bounds.x1, box[n].x1);
|
||||
bounds.x2 = max(bounds.x2, box[n].x2);
|
||||
bounds.y1 = min(bounds.y1, box[n].y1);
|
||||
bounds.y2 = max(bounds.y2, box[n].y2);
|
||||
}
|
||||
|
||||
/* Allocate a suitable temporary pixmap
|
||||
*/
|
||||
tmp_pixmap = glamor_create_pixmap(screen,
|
||||
bounds.x2 - bounds.x1,
|
||||
bounds.y2 - bounds.y1,
|
||||
src->depth, 0);
|
||||
if (!tmp_pixmap)
|
||||
goto bail;
|
||||
|
||||
tmp_box = calloc(nbox, sizeof (BoxRec));
|
||||
if (!tmp_box)
|
||||
goto bail_pixmap;
|
||||
|
||||
/* Convert destination boxes into tmp pixmap boxes
|
||||
*/
|
||||
for (n = 0; n < nbox; n++) {
|
||||
tmp_box[n].x1 = box[n].x1 - bounds.x1;
|
||||
tmp_box[n].x2 = box[n].x2 - bounds.x1;
|
||||
tmp_box[n].y1 = box[n].y1 - bounds.y1;
|
||||
tmp_box[n].y2 = box[n].y2 - bounds.y1;
|
||||
}
|
||||
|
||||
if (!glamor_copy_fbo_fbo_draw(src,
|
||||
&tmp_pixmap->drawable,
|
||||
NULL,
|
||||
tmp_box,
|
||||
nbox,
|
||||
dx + bounds.x1,
|
||||
dy + bounds.y1,
|
||||
FALSE, FALSE,
|
||||
0, NULL))
|
||||
goto bail_box;
|
||||
|
||||
if (!glamor_copy_fbo_fbo_draw(&tmp_pixmap->drawable,
|
||||
dst,
|
||||
gc,
|
||||
box,
|
||||
nbox,
|
||||
-bounds.x1,
|
||||
-bounds.y1,
|
||||
FALSE, FALSE,
|
||||
bitplane, closure))
|
||||
goto bail_box;
|
||||
|
||||
free(tmp_box);
|
||||
|
||||
glamor_destroy_pixmap(tmp_pixmap);
|
||||
|
||||
return TRUE;
|
||||
bail_box:
|
||||
free(tmp_box);
|
||||
bail_pixmap:
|
||||
glamor_destroy_pixmap(tmp_pixmap);
|
||||
bail:
|
||||
return FALSE;
|
||||
|
||||
bail_ctx:
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the copy has to be implemented with
|
||||
* glamor_copy_fbo_fbo_temp() instead of glamor_copy_fbo_fbo().
|
||||
*
|
||||
* If the src and dst are in the same pixmap, then glamor_copy_fbo_fbo()'s
|
||||
* sampling would give undefined results (since the same texture would be
|
||||
* bound as an FBO destination and as a texture source). However, if we
|
||||
* have GL_NV_texture_barrier, we can take advantage of the exception it
|
||||
* added:
|
||||
*
|
||||
* "- If a texel has been written, then in order to safely read the result
|
||||
* a texel fetch must be in a subsequent Draw separated by the command
|
||||
*
|
||||
* void TextureBarrierNV(void);
|
||||
*
|
||||
* TextureBarrierNV() will guarantee that writes have completed and caches
|
||||
* have been invalidated before subsequent Draws are executed."
|
||||
*/
|
||||
static Bool
|
||||
glamor_copy_needs_temp(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
int n;
|
||||
int dst_off_x, dst_off_y;
|
||||
int src_off_x, src_off_y;
|
||||
BoxRec bounds;
|
||||
|
||||
if (src_pixmap != dst_pixmap)
|
||||
return FALSE;
|
||||
|
||||
if (nbox == 0)
|
||||
return FALSE;
|
||||
|
||||
if (!glamor_priv->has_nv_texture_barrier)
|
||||
return TRUE;
|
||||
|
||||
glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y);
|
||||
|
||||
bounds = box[0];
|
||||
for (n = 1; n < nbox; n++) {
|
||||
bounds.x1 = min(bounds.x1, box[n].x1);
|
||||
bounds.y1 = min(bounds.y1, box[n].y1);
|
||||
|
||||
bounds.x2 = max(bounds.x2, box[n].x2);
|
||||
bounds.y2 = max(bounds.y2, box[n].y2);
|
||||
}
|
||||
|
||||
/* Check to see if the pixmap-relative boxes overlap in both X and Y,
|
||||
* in which case we can't rely on NV_texture_barrier and must
|
||||
* make a temporary copy
|
||||
*
|
||||
* dst.x1 < src.x2 &&
|
||||
* src.x1 < dst.x2 &&
|
||||
*
|
||||
* dst.y1 < src.y2 &&
|
||||
* src.y1 < dst.y2
|
||||
*/
|
||||
if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x &&
|
||||
bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x &&
|
||||
|
||||
bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y &&
|
||||
bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
glTextureBarrierNV();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
glamor_copy_gl(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
|
||||
if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv)) {
|
||||
if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv)) {
|
||||
if (glamor_copy_needs_temp(src, dst, box, nbox, dx, dy))
|
||||
return glamor_copy_fbo_fbo_temp(src, dst, gc, box, nbox, dx, dy,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
else
|
||||
return glamor_copy_fbo_fbo_draw(src, dst, gc, box, nbox, dx, dy,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
}
|
||||
if (bitplane == 0)
|
||||
return glamor_copy_cpu_fbo(src, dst, gc, box, nbox, dx, dy,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_copy(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure))
|
||||
return;
|
||||
glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int width, int height, int dstx, int dsty)
|
||||
{
|
||||
return miDoCopy(src, dst, gc,
|
||||
srcx, srcy, width, height,
|
||||
dstx, dsty, glamor_copy, 0, NULL);
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int width, int height, int dstx, int dsty,
|
||||
unsigned long bitplane)
|
||||
{
|
||||
if ((bitplane & FbFullMask(src->depth)) == 0)
|
||||
return miHandleExposures(src, dst, gc,
|
||||
srcx, srcy, width, height, dstx, dsty,
|
||||
bitplane);
|
||||
return miDoCopy(src, dst, gc,
|
||||
srcx, srcy, width, height,
|
||||
dstx, dsty, glamor_copy, bitplane, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region)
|
||||
{
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(&window->drawable);
|
||||
DrawablePtr drawable = &pixmap->drawable;
|
||||
RegionRec dst_region;
|
||||
int dx, dy;
|
||||
|
||||
dx = old_origin.x - window->drawable.x;
|
||||
dy = old_origin.y - window->drawable.y;
|
||||
RegionTranslate(src_region, -dx, -dy);
|
||||
|
||||
RegionNull(&dst_region);
|
||||
|
||||
RegionIntersect(&dst_region, &window->borderClip, src_region);
|
||||
|
||||
#ifdef COMPOSITE
|
||||
if (pixmap->screen_x || pixmap->screen_y)
|
||||
RegionTranslate(&dst_region, -pixmap->screen_x, -pixmap->screen_y);
|
||||
#endif
|
||||
|
||||
miCopyRegion(drawable, drawable,
|
||||
0, &dst_region, dx, dy, glamor_copy, 0, 0);
|
||||
|
||||
RegionUninit(&dst_region);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_copy_n_to_n_nf(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown, Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure))
|
||||
return TRUE;
|
||||
if (glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst))
|
||||
return FALSE;
|
||||
glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_copy_plane_nf(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||
unsigned long bitplane, RegionPtr *region)
|
||||
{
|
||||
if (glamor_ddx_fallback_check_pixmap(src) &&
|
||||
glamor_ddx_fallback_check_pixmap(dst) &&
|
||||
glamor_ddx_fallback_check_gc(gc))
|
||||
return FALSE;
|
||||
|
||||
*region = glamor_copy_plane(src, dst, gc,
|
||||
srcx, srcy, w, h, dstx, dsty,
|
||||
bitplane);
|
||||
return TRUE;
|
||||
}
|
|
@ -1,626 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Anholt <eric@anholt.net>
|
||||
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
/** @file glamor_copyarea.c
|
||||
*
|
||||
* GC CopyArea implementation
|
||||
*/
|
||||
static Bool
|
||||
glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
|
||||
{
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
|
||||
int fbo_x_off, fbo_y_off;
|
||||
int src_fbo_x_off, src_fbo_y_off;
|
||||
|
||||
if (!glamor_priv->has_fbo_blit) {
|
||||
glamor_delayed_fallback(screen, "no EXT_framebuffer_blit\n");
|
||||
return FALSE;
|
||||
}
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
|
||||
if (gc) {
|
||||
if (gc->alu != GXcopy) {
|
||||
glamor_delayed_fallback(screen, "non-copy ALU\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
||||
glamor_delayed_fallback(screen, "no src fbo\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (glamor_set_destination_pixmap(dst_pixmap))
|
||||
return FALSE;
|
||||
|
||||
pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
|
||||
pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->base.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, &src_y_off);
|
||||
dst_x_off += fbo_x_off;
|
||||
dst_y_off += fbo_y_off;
|
||||
src_y_off += dy + src_fbo_y_off;
|
||||
src_x_off += src_fbo_x_off;
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
if (glamor_priv->yInverted) {
|
||||
glBlitFramebuffer(box[i].x1 + dx + src_x_off,
|
||||
box[i].y1 + src_y_off,
|
||||
box[i].x2 + dx + src_x_off,
|
||||
box[i].y2 + src_y_off,
|
||||
box[i].x1 + dst_x_off,
|
||||
box[i].y1 + dst_y_off,
|
||||
box[i].x2 + dst_x_off,
|
||||
box[i].y2 + dst_y_off,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
else {
|
||||
int flip_dst_y1 =
|
||||
dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
|
||||
int flip_dst_y2 =
|
||||
dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
|
||||
int flip_src_y1 =
|
||||
src_pixmap->drawable.height - (box[i].y2 + src_y_off);
|
||||
int flip_src_y2 =
|
||||
src_pixmap->drawable.height - (box[i].y1 + src_y_off);
|
||||
|
||||
glBlitFramebuffer(box[i].x1 + dx + src_x_off,
|
||||
flip_src_y1,
|
||||
box[i].x2 + dx + src_x_off,
|
||||
flip_src_y2,
|
||||
box[i].x1 + dst_x_off,
|
||||
flip_dst_y1,
|
||||
box[i].x2 + dst_x_off,
|
||||
flip_dst_y2,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
glamor_priv->state = BLIT_STATE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
|
||||
{
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(dst->pScreen);
|
||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
int i;
|
||||
float vertices[8], texcoords[8];
|
||||
glamor_pixmap_private *src_pixmap_priv;
|
||||
glamor_pixmap_private *dst_pixmap_priv;
|
||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
||||
enum glamor_pixmap_status src_status = GLAMOR_NONE;
|
||||
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
||||
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
|
||||
if (src_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
|
||||
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
||||
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
|
||||
return FALSE;
|
||||
#else
|
||||
src_status = glamor_upload_pixmap_to_texture(src_pixmap);
|
||||
if (src_status != GLAMOR_UPLOAD_DONE)
|
||||
return FALSE;
|
||||
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
#endif
|
||||
}
|
||||
|
||||
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
||||
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||
GL_FALSE, 2 * sizeof(float), vertices);
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
||||
dx += src_x_off;
|
||||
dy += src_y_off;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), texcoords);
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||
glUseProgram(glamor_priv->finish_access_prog[0]);
|
||||
glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE);
|
||||
glUniform1i(glamor_priv->finish_access_swap_rb[0], SWAP_NONE_UPLOADING);
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
|
||||
glamor_set_normalize_vcoords(dst_pixmap_priv,
|
||||
dst_xscale, dst_yscale,
|
||||
box[i].x1 + dst_x_off,
|
||||
box[i].y1 + dst_y_off,
|
||||
box[i].x2 + dst_x_off,
|
||||
box[i].y2 + dst_y_off,
|
||||
glamor_priv->yInverted, vertices);
|
||||
|
||||
glamor_set_normalize_tcoords(src_pixmap_priv,
|
||||
src_xscale,
|
||||
src_yscale,
|
||||
box[i].x1 + dx,
|
||||
box[i].y1 + dy,
|
||||
box[i].x2 + dx,
|
||||
box[i].y2 + dy,
|
||||
glamor_priv->yInverted, texcoords);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||
/* The source texture is bound to a fbo, we have to flush it here. */
|
||||
glamor_priv->state = RENDER_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
__glamor_copy_n_to_n(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
|
||||
DrawablePtr temp_src = src;
|
||||
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
||||
glamor_screen_private *glamor_priv;
|
||||
BoxRec bound;
|
||||
ScreenPtr screen;
|
||||
int temp_dx = dx;
|
||||
int temp_dy = dy;
|
||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
||||
int i;
|
||||
int overlaped = 0;
|
||||
Bool ret = FALSE;
|
||||
|
||||
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
screen = dst_pixmap->drawable.pScreen;
|
||||
glamor_priv = glamor_get_screen_private(dst->pScreen);
|
||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
||||
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
||||
|
||||
if (src_pixmap_priv->base.fbo
|
||||
&& src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.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++) {
|
||||
if (x_shift < abs(box[i].x2 - box[i].x1)
|
||||
&& y_shift < abs(box[i].y2 - box[i].y1)) {
|
||||
overlaped = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
|
||||
box[0].x1, box[0].y1,
|
||||
box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
|
||||
dx, dy, src_pixmap, dst_pixmap);
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
|
||||
!overlaped &&
|
||||
(glamor_priv->state != RENDER_STATE
|
||||
|| !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
|
||||
&& glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
}
|
||||
glamor_calculate_boxes_bound(&bound, box, nbox);
|
||||
|
||||
/* Overlaped indicate the src and dst are the same pixmap. */
|
||||
if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
|
||||
&& (((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
|
||||
* 4 >
|
||||
src_pixmap->drawable.width *
|
||||
src_pixmap->drawable.height)
|
||||
|| !(glamor_check_fbo_size(glamor_priv,
|
||||
src_pixmap->drawable.width,
|
||||
src_pixmap->drawable.
|
||||
height))))) {
|
||||
|
||||
temp_pixmap = glamor_create_pixmap(screen,
|
||||
bound.x2 - bound.x1,
|
||||
bound.y2 - bound.y1,
|
||||
src_pixmap->drawable.depth,
|
||||
overlaped ? 0 :
|
||||
GLAMOR_CREATE_PIXMAP_CPU);
|
||||
assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size);
|
||||
assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size);
|
||||
if (!temp_pixmap)
|
||||
goto done;
|
||||
glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1);
|
||||
temp_src = &temp_pixmap->drawable;
|
||||
|
||||
if (overlaped)
|
||||
glamor_copy_n_to_n_textured(src, temp_src, gc, box,
|
||||
nbox,
|
||||
temp_dx + bound.x1, temp_dy + bound.y1);
|
||||
else
|
||||
fbCopyNtoN(src, temp_src, gc, box, nbox,
|
||||
temp_dx + bound.x1, temp_dy + bound.y1,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
glamor_translate_boxes(box, nbox, bound.x1, bound.y1);
|
||||
temp_dx = -bound.x1;
|
||||
temp_dy = -bound.y1;
|
||||
}
|
||||
else {
|
||||
temp_dx = dx;
|
||||
temp_dy = dy;
|
||||
temp_src = src;
|
||||
}
|
||||
|
||||
if (glamor_copy_n_to_n_textured
|
||||
(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
|
||||
ret = TRUE;
|
||||
}
|
||||
done:
|
||||
if (temp_src != src)
|
||||
glamor_destroy_pixmap(temp_pixmap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Bool
|
||||
_glamor_copy_n_to_n(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown, Pixel bitplane,
|
||||
void *closure, Bool fallback)
|
||||
{
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
PixmapPtr dst_pixmap, src_pixmap;
|
||||
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
||||
glamor_screen_private *glamor_priv;
|
||||
BoxPtr extent;
|
||||
RegionRec region;
|
||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
||||
Bool ok = FALSE;
|
||||
int force_clip = 0;
|
||||
|
||||
if (nbox == 0)
|
||||
return TRUE;
|
||||
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
|
||||
glamor_priv = glamor_get_screen_private(screen);
|
||||
|
||||
DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
|
||||
box[0].x1, box[0].y1,
|
||||
box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
|
||||
dx, dy, src_pixmap, dst_pixmap);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
|
||||
goto fall_back;
|
||||
|
||||
if (gc) {
|
||||
if (!glamor_set_planemask(dst_pixmap, gc->planemask))
|
||||
goto fall_back;
|
||||
glamor_make_current(glamor_priv);
|
||||
if (!glamor_set_alu(screen, gc->alu)) {
|
||||
goto fail_noregion;
|
||||
}
|
||||
}
|
||||
|
||||
if (!src_pixmap_priv) {
|
||||
glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
}
|
||||
|
||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
||||
|
||||
RegionInitBoxes(®ion, box, nbox);
|
||||
extent = RegionExtents(®ion);
|
||||
|
||||
if (!glamor_check_fbo_size(glamor_priv,
|
||||
extent->x2 - extent->x1, extent->y2 - extent->y1)
|
||||
&& (src_pixmap_priv->type == GLAMOR_MEMORY
|
||||
|| (src_pixmap_priv == dst_pixmap_priv))) {
|
||||
force_clip = 1;
|
||||
}
|
||||
|
||||
if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
||||
|| src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||
glamor_pixmap_clipped_regions *clipped_dst_regions;
|
||||
int n_dst_region, i, j;
|
||||
PixmapPtr temp_source_pixmap;
|
||||
glamor_pixmap_private *temp_source_priv = NULL;
|
||||
|
||||
RegionTranslate(®ion, dst_x_off, dst_y_off);
|
||||
if (!force_clip)
|
||||
clipped_dst_regions =
|
||||
glamor_compute_clipped_regions(dst_pixmap_priv, ®ion,
|
||||
&n_dst_region, 0, reverse,
|
||||
upsidedown);
|
||||
else
|
||||
clipped_dst_regions =
|
||||
glamor_compute_clipped_regions_ext(dst_pixmap_priv, ®ion,
|
||||
&n_dst_region,
|
||||
glamor_priv->max_fbo_size,
|
||||
glamor_priv->max_fbo_size,
|
||||
reverse, upsidedown);
|
||||
for (i = 0; i < n_dst_region; i++) {
|
||||
int n_src_region;
|
||||
glamor_pixmap_clipped_regions *clipped_src_regions;
|
||||
BoxPtr current_boxes;
|
||||
int n_current_boxes;
|
||||
|
||||
SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv,
|
||||
clipped_dst_regions[i].block_idx);
|
||||
|
||||
temp_source_pixmap = NULL;
|
||||
if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||
RegionTranslate(clipped_dst_regions[i].region,
|
||||
-dst_x_off + src_x_off + dx,
|
||||
-dst_y_off + src_y_off + dy);
|
||||
clipped_src_regions =
|
||||
glamor_compute_clipped_regions(src_pixmap_priv,
|
||||
clipped_dst_regions[i].
|
||||
region, &n_src_region, 0,
|
||||
reverse, upsidedown);
|
||||
DEBUGF("Source is large pixmap.\n");
|
||||
for (j = 0; j < n_src_region; j++) {
|
||||
if (src_pixmap_priv != dst_pixmap_priv)
|
||||
SET_PIXMAP_FBO_CURRENT(src_pixmap_priv,
|
||||
clipped_src_regions[j].
|
||||
block_idx);
|
||||
else if (src_pixmap_priv == dst_pixmap_priv &&
|
||||
clipped_src_regions[j].block_idx !=
|
||||
clipped_dst_regions[i].block_idx) {
|
||||
/* source and the dest are the same, but need different block_idx.
|
||||
* we create a empty pixmap and fill the required source fbo and box to
|
||||
* it. It's a little hacky, but avoid extra copy. */
|
||||
temp_source_pixmap =
|
||||
glamor_create_pixmap(src->pScreen, 0, 0, src->depth,
|
||||
0);
|
||||
if (!temp_source_pixmap) {
|
||||
ok = FALSE;
|
||||
goto fail;
|
||||
}
|
||||
src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
|
||||
src_pixmap->drawable.
|
||||
width,
|
||||
src_pixmap->drawable.
|
||||
height, 0, 0,
|
||||
src_pixmap->devKind,
|
||||
NULL);
|
||||
temp_source_priv =
|
||||
glamor_get_pixmap_private(temp_source_pixmap);
|
||||
*temp_source_priv = *src_pixmap_priv;
|
||||
temp_source_priv->large.box =
|
||||
src_pixmap_priv->large.
|
||||
box_array[clipped_src_regions[j].block_idx];
|
||||
temp_source_priv->base.fbo =
|
||||
src_pixmap_priv->large.
|
||||
fbo_array[clipped_src_regions[j].block_idx];
|
||||
temp_source_priv->base.pixmap = temp_source_pixmap;
|
||||
}
|
||||
assert(temp_source_pixmap ||
|
||||
!(src_pixmap_priv == dst_pixmap_priv &&
|
||||
(clipped_src_regions[j].block_idx !=
|
||||
clipped_dst_regions[i].block_idx)));
|
||||
|
||||
RegionTranslate(clipped_src_regions[j].region,
|
||||
-src_x_off - dx, -src_y_off - dy);
|
||||
current_boxes = RegionRects(clipped_src_regions[j].region);
|
||||
n_current_boxes =
|
||||
RegionNumRects(clipped_src_regions[j].region);
|
||||
DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n",
|
||||
clipped_dst_regions[i].block_idx,
|
||||
clipped_src_regions[j].block_idx);
|
||||
DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
|
||||
current_boxes[0].x1, current_boxes[0].y1,
|
||||
current_boxes[0].x2, current_boxes[0].y2, dx, dy,
|
||||
src_pixmap, dst_pixmap);
|
||||
if (!temp_source_pixmap)
|
||||
ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
|
||||
n_current_boxes, dx, dy,
|
||||
reverse, upsidedown, bitplane,
|
||||
closure);
|
||||
else {
|
||||
ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable,
|
||||
dst, gc, current_boxes,
|
||||
n_current_boxes, dx, dy,
|
||||
reverse, upsidedown, bitplane,
|
||||
closure);
|
||||
temp_source_priv->type = GLAMOR_MEMORY;
|
||||
temp_source_priv->base.fbo = NULL;
|
||||
glamor_destroy_pixmap(temp_source_pixmap);
|
||||
temp_source_pixmap = NULL;
|
||||
}
|
||||
|
||||
RegionDestroy(clipped_src_regions[j].region);
|
||||
if (!ok) {
|
||||
assert(0);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_src_region == 0)
|
||||
ok = TRUE;
|
||||
free(clipped_src_regions);
|
||||
}
|
||||
else {
|
||||
RegionTranslate(clipped_dst_regions[i].region,
|
||||
-dst_x_off, -dst_y_off);
|
||||
current_boxes = RegionRects(clipped_dst_regions[i].region);
|
||||
n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
|
||||
|
||||
DEBUGF("dest pixmap fbo idx %d \n",
|
||||
clipped_dst_regions[i].block_idx);
|
||||
DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
|
||||
current_boxes[0].x1, current_boxes[0].y1,
|
||||
current_boxes[0].x2, current_boxes[0].y2,
|
||||
dx, dy, src_pixmap, dst_pixmap);
|
||||
|
||||
ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
|
||||
n_current_boxes, dx, dy, reverse,
|
||||
upsidedown, bitplane, closure);
|
||||
|
||||
}
|
||||
RegionDestroy(clipped_dst_regions[i].region);
|
||||
}
|
||||
if (n_dst_region == 0)
|
||||
ok = TRUE;
|
||||
free(clipped_dst_regions);
|
||||
}
|
||||
else {
|
||||
ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
|
||||
reverse, upsidedown, bitplane, closure);
|
||||
}
|
||||
|
||||
fail:
|
||||
RegionUninit(®ion);
|
||||
fail_noregion:
|
||||
glamor_make_current(glamor_priv);
|
||||
glamor_set_alu(screen, GXcopy);
|
||||
|
||||
if (ok)
|
||||
return TRUE;
|
||||
fall_back:
|
||||
if (!fallback && glamor_ddx_fallback_check_pixmap(src)
|
||||
&& glamor_ddx_fallback_check_pixmap(dst))
|
||||
goto done;
|
||||
|
||||
if (src_pixmap_priv->type == GLAMOR_DRM_ONLY
|
||||
|| dst_pixmap_priv->type == GLAMOR_DRM_ONLY) {
|
||||
LogMessage(X_WARNING,
|
||||
"Access a DRM only pixmap is not allowed within glamor.\n");
|
||||
return TRUE;
|
||||
}
|
||||
glamor_report_delayed_fallbacks(src->pScreen);
|
||||
glamor_report_delayed_fallbacks(dst->pScreen);
|
||||
|
||||
glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
|
||||
glamor_get_drawable_location(src),
|
||||
glamor_get_drawable_location(dst));
|
||||
|
||||
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) &&
|
||||
glamor_prepare_access(src, GLAMOR_ACCESS_RO) &&
|
||||
glamor_prepare_access_gc(gc)) {
|
||||
fbCopyNtoN(src, dst, gc, box, nbox,
|
||||
dx, dy, reverse, upsidedown, bitplane, closure);
|
||||
}
|
||||
glamor_finish_access_gc(gc);
|
||||
glamor_finish_access(src);
|
||||
glamor_finish_access(dst);
|
||||
ok = TRUE;
|
||||
|
||||
done:
|
||||
glamor_clear_delayed_fallbacks(src->pScreen);
|
||||
glamor_clear_delayed_fallbacks(dst->pScreen);
|
||||
return ok;
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int width, int height, int dstx, int dsty)
|
||||
{
|
||||
RegionPtr region;
|
||||
|
||||
region = miDoCopy(src, dst, gc,
|
||||
srcx, srcy, width, height,
|
||||
dstx, dsty, glamor_copy_n_to_n, 0, NULL);
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_copy_n_to_n(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
_glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
|
||||
dy, reverse, upsidedown, bitplane, closure, TRUE);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_copy_n_to_n_nf(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
|
||||
dy, reverse, upsidedown, bitplane, closure,
|
||||
FALSE);
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* 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
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Zhigang Gong <zhigang.gong@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
static Bool
|
||||
_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||
unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
|
||||
{
|
||||
if (!fallback && glamor_ddx_fallback_check_gc(pGC)
|
||||
&& glamor_ddx_fallback_check_pixmap(pSrc)
|
||||
&& glamor_ddx_fallback_check_pixmap(pDst))
|
||||
goto fail;
|
||||
|
||||
if (glamor_prepare_access(pDst, GLAMOR_ACCESS_RW) &&
|
||||
glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO) &&
|
||||
glamor_prepare_access_gc(pGC)) {
|
||||
*pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
|
||||
dstx, dsty, bitPlane);
|
||||
}
|
||||
glamor_finish_access_gc(pGC);
|
||||
glamor_finish_access(pSrc);
|
||||
glamor_finish_access(pDst);
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||
unsigned long bitPlane)
|
||||
{
|
||||
RegionPtr ret;
|
||||
|
||||
_glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
|
||||
dstx, dsty, bitPlane, &ret, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||
unsigned long bitPlane, RegionPtr *pRegion)
|
||||
{
|
||||
return _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
|
||||
dstx, dsty, bitPlane, pRegion, FALSE);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
/** @file glamor_copywindow.c
|
||||
*
|
||||
* Screen CopyWindow implementation.
|
||||
*/
|
||||
|
||||
void
|
||||
glamor_copy_window(WindowPtr win, DDXPointRec old_origin, RegionPtr src_region)
|
||||
{
|
||||
RegionRec dst_region;
|
||||
int dx, dy;
|
||||
PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
|
||||
|
||||
dx = old_origin.x - win->drawable.x;
|
||||
dy = old_origin.y - win->drawable.y;
|
||||
REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
|
||||
|
||||
REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
|
||||
|
||||
REGION_INTERSECT(win->drawable.pScreen, &dst_region,
|
||||
&win->borderClip, src_region);
|
||||
#ifdef COMPOSITE
|
||||
if (pixmap->screen_x || pixmap->screen_y)
|
||||
REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
|
||||
-pixmap->screen_x, -pixmap->screen_y);
|
||||
#endif
|
||||
|
||||
miCopyRegion(&pixmap->drawable, &pixmap->drawable,
|
||||
NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL);
|
||||
|
||||
REGION_UNINIT(win->drawable.pScreen, &dst_region);
|
||||
}
|
|
@ -114,27 +114,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
|
|||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
|
||||
{
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (pixmap->devPrivate.ptr) {
|
||||
/* Already mapped, nothing needs to be done. Note that we
|
||||
* aren't allowing promotion from RO to RW, because it would
|
||||
* require re-mapping the PBO.
|
||||
*/
|
||||
assert(!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) ||
|
||||
access == GLAMOR_ACCESS_RO ||
|
||||
pixmap_priv->base.map_access == GLAMOR_ACCESS_RW);
|
||||
return TRUE;
|
||||
}
|
||||
pixmap_priv->base.map_access = access;
|
||||
|
||||
return glamor_download_pixmap_to_cpu(pixmap, access);
|
||||
}
|
||||
|
||||
/*
|
||||
* When downloading a unsupported color format to CPU memory,
|
||||
we need to shuffle the color elements and then use a supported
|
||||
|
@ -313,102 +292,6 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
|
|||
glDeleteProgram(glamor_priv->finish_access_prog[1]);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_finish_access(DrawablePtr drawable)
|
||||
{
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(drawable->pScreen);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
|
||||
return;
|
||||
|
||||
/* If we are doing a series of unmaps from a nested map, we're
|
||||
* done. None of the callers do any rendering to maps after
|
||||
* starting an unmap sequence, so we don't need to delay until the
|
||||
* last nested unmap.
|
||||
*/
|
||||
if (!pixmap->devPrivate.ptr)
|
||||
return;
|
||||
|
||||
if (pixmap_priv->base.map_access == GLAMOR_ACCESS_RW) {
|
||||
glamor_restore_pixmap_to_texture(pixmap);
|
||||
}
|
||||
|
||||
if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
|
||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
|
||||
|
||||
pixmap_priv->base.fbo->pbo_valid = FALSE;
|
||||
pixmap_priv->base.fbo->pbo = 0;
|
||||
}
|
||||
else {
|
||||
free(pixmap->devPrivate.ptr);
|
||||
}
|
||||
|
||||
if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
|
||||
pixmap->devKind = pixmap_priv->base.drm_stride;
|
||||
|
||||
if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)
|
||||
pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
|
||||
|
||||
pixmap->devPrivate.ptr = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
|
||||
* current fill style.
|
||||
*
|
||||
* Solid doesn't use an extra pixmap source, so we don't worry about them.
|
||||
* Stippled/OpaqueStippled are 1bpp and can be in fb, so we should worry
|
||||
* about them.
|
||||
*/
|
||||
Bool
|
||||
glamor_prepare_access_gc(GCPtr gc)
|
||||
{
|
||||
if (gc->stipple) {
|
||||
if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
|
||||
return FALSE;
|
||||
}
|
||||
if (gc->fillStyle == FillTiled) {
|
||||
if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
|
||||
GLAMOR_ACCESS_RO)) {
|
||||
if (gc->stipple)
|
||||
glamor_finish_access(&gc->stipple->drawable);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes access to the tile in the GC, if used.
|
||||
*/
|
||||
void
|
||||
glamor_finish_access_gc(GCPtr gc)
|
||||
{
|
||||
if (gc->fillStyle == FillTiled)
|
||||
glamor_finish_access(&gc->tile.pixmap->drawable);
|
||||
if (gc->stipple)
|
||||
glamor_finish_access(&gc->stipple->drawable);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
|
||||
int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
unsigned long fg_pixel, unsigned long bg_pixel,
|
||||
int stipple_x, int stipple_y)
|
||||
{
|
||||
glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GCOps glamor_gc_ops = {
|
||||
.FillSpans = glamor_fill_spans,
|
||||
.SetSpans = glamor_set_spans,
|
||||
|
@ -432,6 +315,58 @@ GCOps glamor_gc_ops = {
|
|||
.PushPixels = glamor_push_pixels,
|
||||
};
|
||||
|
||||
/*
|
||||
* When the stipple is changed or drawn to, invalidate any
|
||||
* cached copy
|
||||
*/
|
||||
static void
|
||||
glamor_invalidate_stipple(GCPtr gc)
|
||||
{
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
|
||||
if (gc_priv->stipple) {
|
||||
if (gc_priv->stipple_damage)
|
||||
DamageUnregister(gc_priv->stipple_damage);
|
||||
glamor_destroy_pixmap(gc_priv->stipple);
|
||||
gc_priv->stipple = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
glamor_stipple_damage_report(DamagePtr damage, RegionPtr region,
|
||||
void *closure)
|
||||
{
|
||||
GCPtr gc = closure;
|
||||
|
||||
glamor_invalidate_stipple(gc);
|
||||
}
|
||||
|
||||
static void
|
||||
glamor_stipple_damage_destroy(DamagePtr damage, void *closure)
|
||||
{
|
||||
GCPtr gc = closure;
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
|
||||
gc_priv->stipple_damage = NULL;
|
||||
glamor_invalidate_stipple(gc);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_track_stipple(GCPtr gc)
|
||||
{
|
||||
if (gc->stipple) {
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
|
||||
if (!gc_priv->stipple_damage)
|
||||
gc_priv->stipple_damage = DamageCreate(glamor_stipple_damage_report,
|
||||
glamor_stipple_damage_destroy,
|
||||
DamageReportNonEmpty,
|
||||
TRUE, gc->pScreen, gc);
|
||||
if (gc_priv->stipple_damage)
|
||||
DamageRegister(&gc->stipple->drawable, gc_priv->stipple_damage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* uxa_validate_gc() sets the ops to glamor's implementations, which may be
|
||||
* accelerated or may sync the card and fall back to fb.
|
||||
|
@ -502,6 +437,9 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
|
|||
changes &= ~GCTile;
|
||||
}
|
||||
|
||||
if (changes & GCStipple)
|
||||
glamor_invalidate_stipple(gc);
|
||||
|
||||
if (changes & GCStipple && gc->stipple) {
|
||||
/* We can't inline stipple handling like we do for GCTile because
|
||||
* it sets fbgc privates.
|
||||
|
@ -515,14 +453,38 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
|
|||
fbValidateGC(gc, changes, drawable);
|
||||
}
|
||||
|
||||
if (changes & GCDashList) {
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
|
||||
if (gc_priv->dash) {
|
||||
glamor_destroy_pixmap(gc_priv->dash);
|
||||
gc_priv->dash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gc->ops = &glamor_gc_ops;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_destroy_gc(GCPtr gc)
|
||||
{
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
|
||||
if (gc_priv->dash) {
|
||||
glamor_destroy_pixmap(gc_priv->dash);
|
||||
gc_priv->dash = NULL;
|
||||
}
|
||||
glamor_invalidate_stipple(gc);
|
||||
if (gc_priv->stipple_damage)
|
||||
DamageDestroy(gc_priv->stipple_damage);
|
||||
miDestroyGC(gc);
|
||||
}
|
||||
|
||||
static GCFuncs glamor_gc_funcs = {
|
||||
glamor_validate_gc,
|
||||
miChangeGC,
|
||||
miCopyGC,
|
||||
miDestroyGC,
|
||||
glamor_destroy_gc,
|
||||
miChangeClip,
|
||||
miDestroyClip,
|
||||
miCopyClip
|
||||
|
@ -535,6 +497,10 @@ static GCFuncs glamor_gc_funcs = {
|
|||
int
|
||||
glamor_create_gc(GCPtr gc)
|
||||
{
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
|
||||
gc_priv->dash = NULL;
|
||||
gc_priv->stipple = NULL;
|
||||
if (!fbCreateGC(gc))
|
||||
return FALSE;
|
||||
|
||||
|
|
370
glamor/glamor_dash.c
Normal file
370
glamor/glamor_dash.c
Normal file
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* Copyright © 2014 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
#include "glamor_program.h"
|
||||
#include "glamor_transform.h"
|
||||
#include "glamor_transfer.h"
|
||||
#include "glamor_prepare.h"
|
||||
|
||||
static const char dash_vs_vars[] =
|
||||
"attribute vec3 primitive;\n"
|
||||
"varying float dash_offset;\n";
|
||||
|
||||
static const char dash_vs_exec[] =
|
||||
" dash_offset = primitive.z / dash_length;\n"
|
||||
GLAMOR_POS(gl_Position, primitive.xy);
|
||||
|
||||
static const char dash_fs_vars[] =
|
||||
"varying float dash_offset;\n";
|
||||
|
||||
static const char on_off_fs_exec[] =
|
||||
" float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
|
||||
" if (pattern == 0.0)\n"
|
||||
" discard;\n";
|
||||
|
||||
/* XXX deal with stippled double dashed lines once we have stippling support */
|
||||
static const char double_fs_exec[] =
|
||||
" float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
|
||||
" if (pattern == 0.0)\n"
|
||||
" gl_FragColor = bg;\n"
|
||||
" else\n"
|
||||
" gl_FragColor = fg;\n";
|
||||
|
||||
|
||||
static const glamor_facet glamor_facet_on_off_dash_lines = {
|
||||
.version = 130,
|
||||
.name = "poly_lines_on_off_dash",
|
||||
.vs_vars = dash_vs_vars,
|
||||
.vs_exec = dash_vs_exec,
|
||||
.fs_vars = dash_fs_vars,
|
||||
.fs_exec = on_off_fs_exec,
|
||||
.locations = glamor_program_location_dash,
|
||||
};
|
||||
|
||||
static const glamor_facet glamor_facet_double_dash_lines = {
|
||||
.version = 130,
|
||||
.name = "poly_lines_double_dash",
|
||||
.vs_vars = dash_vs_vars,
|
||||
.vs_exec = dash_vs_exec,
|
||||
.fs_vars = dash_fs_vars,
|
||||
.fs_exec = double_fs_exec,
|
||||
.locations = (glamor_program_location_dash|
|
||||
glamor_program_location_fg|
|
||||
glamor_program_location_bg),
|
||||
};
|
||||
|
||||
static PixmapPtr
|
||||
glamor_get_dash_pixmap(GCPtr gc)
|
||||
{
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
ScreenPtr screen = gc->pScreen;
|
||||
PixmapPtr pixmap;
|
||||
int offset;
|
||||
int d;
|
||||
uint32_t pixel;
|
||||
GCPtr scratch_gc;
|
||||
|
||||
if (gc_priv->dash)
|
||||
return gc_priv->dash;
|
||||
|
||||
offset = 0;
|
||||
for (d = 0; d < gc->numInDashList; d++)
|
||||
offset += gc->dash[d];
|
||||
|
||||
pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0);
|
||||
if (!pixmap)
|
||||
goto bail;
|
||||
|
||||
scratch_gc = GetScratchGC(8, screen);
|
||||
if (!scratch_gc)
|
||||
goto bail_pixmap;
|
||||
|
||||
pixel = 0xffffffff;
|
||||
offset = 0;
|
||||
for (d = 0; d < gc->numInDashList; d++) {
|
||||
xRectangle rect;
|
||||
ChangeGCVal changes;
|
||||
|
||||
changes.val = pixel;
|
||||
(void) ChangeGC(NullClient, scratch_gc,
|
||||
GCForeground, &changes);
|
||||
ValidateGC(&pixmap->drawable, scratch_gc);
|
||||
rect.x = offset;
|
||||
rect.y = 0;
|
||||
rect.width = gc->dash[d];
|
||||
rect.height = 1;
|
||||
scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect);
|
||||
offset += gc->dash[d];
|
||||
pixel = ~pixel;
|
||||
}
|
||||
FreeScratchGC(scratch_gc);
|
||||
|
||||
gc_priv->dash = pixmap;
|
||||
return pixmap;
|
||||
|
||||
bail_pixmap:
|
||||
glamor_destroy_pixmap(pixmap);
|
||||
bail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static glamor_program *
|
||||
glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
|
||||
{
|
||||
ScreenPtr screen = drawable->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
PixmapPtr dash_pixmap;
|
||||
glamor_pixmap_private *dash_priv;
|
||||
glamor_program *prog;
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
goto bail;
|
||||
|
||||
if (gc->lineWidth != 0)
|
||||
goto bail;
|
||||
|
||||
dash_pixmap = glamor_get_dash_pixmap(gc);
|
||||
dash_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dash_priv))
|
||||
goto bail;
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
switch (gc->lineStyle) {
|
||||
case LineOnOffDash:
|
||||
prog = glamor_use_program_fill(pixmap, gc,
|
||||
&glamor_priv->on_off_dash_line_progs,
|
||||
&glamor_facet_on_off_dash_lines);
|
||||
if (!prog)
|
||||
goto bail_ctx;
|
||||
break;
|
||||
case LineDoubleDash:
|
||||
if (gc->fillStyle != FillSolid)
|
||||
goto bail_ctx;
|
||||
|
||||
prog = &glamor_priv->double_dash_line_prog;
|
||||
|
||||
if (!prog->prog) {
|
||||
if (!glamor_build_program(screen, prog,
|
||||
&glamor_facet_double_dash_lines,
|
||||
NULL))
|
||||
goto bail_ctx;
|
||||
}
|
||||
|
||||
if (!glamor_use_program(pixmap, gc, prog, NULL))
|
||||
goto bail_ctx;
|
||||
|
||||
glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform);
|
||||
glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto bail_ctx;
|
||||
}
|
||||
|
||||
|
||||
/* Set the dash pattern as texture 1 */
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex);
|
||||
glUniform1i(prog->dash_uniform, 1);
|
||||
glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width);
|
||||
|
||||
return prog;
|
||||
|
||||
bail_ctx:
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
bail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog,
|
||||
int n, GLenum mode)
|
||||
{
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
int box_x, box_y;
|
||||
int off_x, off_y;
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||
int nbox = RegionNumRects(gc->pCompositeClip);
|
||||
BoxPtr box = RegionRects(gc->pCompositeClip);
|
||||
|
||||
glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
|
||||
prog->matrix_uniform, &off_x, &off_y);
|
||||
|
||||
while (nbox--) {
|
||||
glScissor(box->x1 + off_x,
|
||||
box->y1 + off_y,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1);
|
||||
box++;
|
||||
glDrawArrays(mode, 0, n);
|
||||
}
|
||||
}
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_line_length(short x1, short y1, short x2, short y2)
|
||||
{
|
||||
return max(abs(x2 - x1), abs(y2 - y1));
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points)
|
||||
{
|
||||
ScreenPtr screen = drawable->pScreen;
|
||||
glamor_program *prog;
|
||||
short *v;
|
||||
char *vbo_offset;
|
||||
int add_last;
|
||||
int dash_pos;
|
||||
int prev_x, prev_y;
|
||||
int i;
|
||||
|
||||
if (n < 2)
|
||||
return TRUE;
|
||||
|
||||
if (!(prog = glamor_dash_setup(drawable, gc)))
|
||||
return FALSE;
|
||||
|
||||
add_last = 0;
|
||||
if (gc->capStyle != CapNotLast)
|
||||
add_last = 1;
|
||||
|
||||
/* Set up the vertex buffers for the points */
|
||||
|
||||
v = glamor_get_vbo_space(drawable->pScreen,
|
||||
(n + add_last) * 3 * sizeof (short),
|
||||
&vbo_offset);
|
||||
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
|
||||
3 * sizeof (short), vbo_offset);
|
||||
|
||||
dash_pos = gc->dashOffset;
|
||||
prev_x = prev_y = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
int this_x = points[i].x;
|
||||
int this_y = points[i].y;
|
||||
if (i) {
|
||||
if (mode == CoordModePrevious) {
|
||||
this_x += prev_x;
|
||||
this_y += prev_y;
|
||||
}
|
||||
dash_pos += glamor_line_length(prev_x, prev_y,
|
||||
this_x, this_y);
|
||||
}
|
||||
v[0] = prev_x = this_x;
|
||||
v[1] = prev_y = this_y;
|
||||
v[2] = dash_pos;
|
||||
v += 3;
|
||||
}
|
||||
|
||||
if (add_last) {
|
||||
v[0] = prev_x + 1;
|
||||
v[1] = prev_y;
|
||||
v[2] = dash_pos + 1;
|
||||
}
|
||||
|
||||
glamor_put_vbo_space(screen);
|
||||
|
||||
glamor_dash_loop(drawable, gc, prog, n + add_last, GL_LINE_STRIP);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static short *
|
||||
glamor_add_segment(short *v, short x1, short y1, short x2, short y2,
|
||||
int dash_start, int dash_end)
|
||||
{
|
||||
v[0] = x1;
|
||||
v[1] = y1;
|
||||
v[2] = dash_start;
|
||||
|
||||
v[3] = x2;
|
||||
v[4] = y2;
|
||||
v[5] = dash_end;
|
||||
return v + 6;
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs)
|
||||
{
|
||||
ScreenPtr screen = drawable->pScreen;
|
||||
glamor_program *prog;
|
||||
short *v;
|
||||
char *vbo_offset;
|
||||
int dash_start = gc->dashOffset;
|
||||
int add_last;
|
||||
int i;
|
||||
|
||||
if (!(prog = glamor_dash_setup(drawable, gc)))
|
||||
return FALSE;
|
||||
|
||||
add_last = 0;
|
||||
if (gc->capStyle != CapNotLast)
|
||||
add_last = 1;
|
||||
|
||||
/* Set up the vertex buffers for the points */
|
||||
|
||||
v = glamor_get_vbo_space(drawable->pScreen,
|
||||
(nseg<<add_last) * 6 * sizeof (short),
|
||||
&vbo_offset);
|
||||
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
|
||||
3 * sizeof (short), vbo_offset);
|
||||
|
||||
for (i = 0; i < nseg; i++) {
|
||||
int dash_end = dash_start + glamor_line_length(segs[i].x1, segs[i].y1,
|
||||
segs[i].x2, segs[i].y2);
|
||||
v = glamor_add_segment(v,
|
||||
segs[i].x1, segs[i].y1,
|
||||
segs[i].x2, segs[i].y2,
|
||||
dash_start, dash_end);
|
||||
if (add_last)
|
||||
v = glamor_add_segment(v,
|
||||
segs[i].x2, segs[i].y2,
|
||||
segs[i].x2 + 1, segs[i].y2,
|
||||
dash_end, dash_end + 1);
|
||||
}
|
||||
|
||||
glamor_put_vbo_space(screen);
|
||||
|
||||
glamor_dash_loop(drawable, gc, prog, nseg << (1 + add_last), GL_LINES);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1,356 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Anholt <eric@anholt.net>
|
||||
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
/** @file glamor_fill.c
|
||||
*
|
||||
* GC fill implementation, based loosely on fb_fill.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fills the given rectangle of a drawable with the GC's fill style.
|
||||
*/
|
||||
Bool
|
||||
glamor_fill(DrawablePtr drawable,
|
||||
GCPtr gc, int x, int y, int width, int height, Bool fallback)
|
||||
{
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
int off_x, off_y;
|
||||
PixmapPtr sub_pixmap = NULL;
|
||||
glamor_access_t sub_pixmap_access;
|
||||
DrawablePtr saved_drawable = NULL;
|
||||
int saved_x = x, saved_y = y;
|
||||
|
||||
glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
|
||||
|
||||
switch (gc->fillStyle) {
|
||||
case FillSolid:
|
||||
if (!glamor_solid(dst_pixmap,
|
||||
x + off_x,
|
||||
y + off_y,
|
||||
width, height, gc->alu, gc->planemask, gc->fgPixel))
|
||||
goto fail;
|
||||
break;
|
||||
case FillStippled:
|
||||
case FillOpaqueStippled:
|
||||
if (!glamor_stipple(dst_pixmap,
|
||||
gc->stipple,
|
||||
x + off_x,
|
||||
y + off_y,
|
||||
width,
|
||||
height,
|
||||
gc->alu,
|
||||
gc->planemask,
|
||||
gc->fgPixel,
|
||||
gc->bgPixel, gc->patOrg.x, gc->patOrg.y))
|
||||
goto fail;
|
||||
break;
|
||||
case FillTiled:
|
||||
if (!glamor_tile(dst_pixmap,
|
||||
gc->tile.pixmap,
|
||||
x + off_x,
|
||||
y + off_y,
|
||||
width,
|
||||
height,
|
||||
gc->alu,
|
||||
gc->planemask,
|
||||
x - drawable->x - gc->patOrg.x,
|
||||
y - drawable->y - gc->patOrg.y))
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (!fallback) {
|
||||
if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable)
|
||||
&& glamor_ddx_fallback_check_gc(gc))
|
||||
return FALSE;
|
||||
}
|
||||
/* Is it possible to set the access as WO? */
|
||||
|
||||
sub_pixmap_access = GLAMOR_ACCESS_RW;
|
||||
|
||||
sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x,
|
||||
y + off_y, width, height,
|
||||
sub_pixmap_access);
|
||||
|
||||
if (sub_pixmap != NULL) {
|
||||
if (gc->fillStyle != FillSolid) {
|
||||
gc->patOrg.x += (drawable->x - x);
|
||||
gc->patOrg.y += (drawable->y - y);
|
||||
}
|
||||
saved_drawable = drawable;
|
||||
drawable = &sub_pixmap->drawable;
|
||||
saved_x = x;
|
||||
saved_y = y;
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
|
||||
glamor_prepare_access_gc(gc)) {
|
||||
fbFill(drawable, gc, x, y, width, height);
|
||||
}
|
||||
glamor_finish_access_gc(gc);
|
||||
glamor_finish_access(drawable);
|
||||
|
||||
if (sub_pixmap != NULL) {
|
||||
if (gc->fillStyle != FillSolid) {
|
||||
gc->patOrg.x -= (saved_drawable->x - saved_x);
|
||||
gc->patOrg.y -= (saved_drawable->y - saved_y);
|
||||
}
|
||||
|
||||
x = saved_x;
|
||||
y = saved_y;
|
||||
|
||||
glamor_put_sub_pixmap(sub_pixmap, dst_pixmap,
|
||||
x + off_x, y + off_y,
|
||||
width, height, sub_pixmap_access);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_init_solid_shader(ScreenPtr screen)
|
||||
{
|
||||
glamor_screen_private *glamor_priv;
|
||||
const char *solid_vs =
|
||||
"attribute vec4 v_position;"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = v_position;\n"
|
||||
"}\n";
|
||||
const char *solid_fs =
|
||||
GLAMOR_DEFAULT_PRECISION
|
||||
"uniform vec4 color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = color;\n"
|
||||
"}\n";
|
||||
GLint fs_prog, vs_prog;
|
||||
|
||||
glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_make_current(glamor_priv);
|
||||
glamor_priv->solid_prog = glCreateProgram();
|
||||
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
|
||||
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
|
||||
glAttachShader(glamor_priv->solid_prog, vs_prog);
|
||||
glAttachShader(glamor_priv->solid_prog, fs_prog);
|
||||
|
||||
glBindAttribLocation(glamor_priv->solid_prog,
|
||||
GLAMOR_VERTEX_POS, "v_position");
|
||||
glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid");
|
||||
|
||||
glamor_priv->solid_color_uniform_location =
|
||||
glGetUniformLocation(glamor_priv->solid_prog, "color");
|
||||
}
|
||||
|
||||
void
|
||||
glamor_fini_solid_shader(ScreenPtr screen)
|
||||
{
|
||||
glamor_screen_private *glamor_priv;
|
||||
|
||||
glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_make_current(glamor_priv);
|
||||
glDeleteProgram(glamor_priv->solid_prog);
|
||||
}
|
||||
|
||||
static void
|
||||
_glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
GLfloat xscale, yscale;
|
||||
float stack_vertices[32];
|
||||
float *vertices = stack_vertices;
|
||||
int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2);
|
||||
|
||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
glUseProgram(glamor_priv->solid_prog);
|
||||
|
||||
glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
|
||||
|
||||
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
|
||||
|
||||
if (nbox > valid_nbox) {
|
||||
int allocated_nbox;
|
||||
float *new_vertices;
|
||||
|
||||
if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6)
|
||||
allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
|
||||
else
|
||||
allocated_nbox = nbox;
|
||||
new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float));
|
||||
if (new_vertices) {
|
||||
vertices = new_vertices;
|
||||
valid_nbox = allocated_nbox;
|
||||
}
|
||||
}
|
||||
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||
GL_FALSE, 2 * sizeof(float), vertices);
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
while (nbox) {
|
||||
int box_cnt, i;
|
||||
float *next_box;
|
||||
|
||||
next_box = vertices;
|
||||
box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
|
||||
for (i = 0; i < box_cnt; i++) {
|
||||
glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
|
||||
box[i].x1, box[i].y1,
|
||||
box[i].x2, box[i].y2,
|
||||
glamor_priv->yInverted,
|
||||
next_box);
|
||||
next_box += 4 * 2;
|
||||
}
|
||||
if (box_cnt == 1)
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
|
||||
else {
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||
glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6,
|
||||
GL_UNSIGNED_SHORT, NULL);
|
||||
} else {
|
||||
glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
nbox -= box_cnt;
|
||||
box += box_cnt;
|
||||
}
|
||||
|
||||
if (vertices != stack_vertices)
|
||||
free(vertices);
|
||||
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glamor_priv->state = RENDER_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the given rectangles of pixmap with an X pixel value.
|
||||
*
|
||||
* This is a helper used by other code after clipping and translation
|
||||
* of coordinates to a glamor backing pixmap.
|
||||
*/
|
||||
Bool
|
||||
glamor_solid_boxes(PixmapPtr pixmap,
|
||||
BoxPtr box, int nbox, unsigned long fg_pixel)
|
||||
{
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
GLfloat color[4];
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
return FALSE;
|
||||
|
||||
glamor_get_rgba_from_pixel(fg_pixel,
|
||||
&color[0],
|
||||
&color[1],
|
||||
&color[2], &color[3], format_for_pixmap(pixmap));
|
||||
|
||||
if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||
RegionRec region;
|
||||
int n_region;
|
||||
glamor_pixmap_clipped_regions *clipped_regions;
|
||||
int i;
|
||||
|
||||
RegionInitBoxes(®ion, box, nbox);
|
||||
clipped_regions =
|
||||
glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0,
|
||||
0, 0);
|
||||
for (i = 0; i < n_region; i++) {
|
||||
BoxPtr inner_box;
|
||||
int inner_nbox;
|
||||
|
||||
SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
|
||||
|
||||
inner_box = RegionRects(clipped_regions[i].region);
|
||||
inner_nbox = RegionNumRects(clipped_regions[i].region);
|
||||
_glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
|
||||
RegionDestroy(clipped_regions[i].region);
|
||||
}
|
||||
free(clipped_regions);
|
||||
RegionUninit(®ion);
|
||||
}
|
||||
else
|
||||
_glamor_solid_boxes(pixmap, box, nbox, color);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a rectangle of a pixmap with an X pixel value.
|
||||
*
|
||||
* This is a helper used by other glamor code mostly for clearing of
|
||||
* buffers to 0.
|
||||
*/
|
||||
Bool
|
||||
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
BoxRec box;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
return FALSE;
|
||||
|
||||
if (!glamor_set_planemask(pixmap, planemask)) {
|
||||
glamor_fallback("Failedto set planemask in glamor_solid.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
if (!glamor_set_alu(screen, alu)) {
|
||||
if (alu == GXclear)
|
||||
fg_pixel = 0;
|
||||
else {
|
||||
glamor_fallback("unsupported alu %x\n", alu);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
box.x1 = x;
|
||||
box.y1 = y;
|
||||
box.x2 = x + width;
|
||||
box.y2 = y + height;
|
||||
glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
|
||||
|
||||
glamor_set_alu(screen, GXcopy);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -56,7 +56,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
|
|||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs,
|
||||
prog = glamor_use_program_fill(pixmap, gc,
|
||||
&glamor_priv->poly_glyph_blt_progs,
|
||||
&glamor_facet_poly_glyph_blt);
|
||||
if (!prog)
|
||||
goto bail_ctx;
|
||||
|
@ -74,7 +75,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
|
|||
int off_x, off_y;
|
||||
char *vbo_offset;
|
||||
|
||||
glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y);
|
||||
glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE,
|
||||
prog->matrix_uniform, &off_x, &off_y);
|
||||
|
||||
max_points = 500;
|
||||
num_points = 0;
|
||||
|
@ -105,10 +107,12 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
|
|||
|
||||
if (!num_points) {
|
||||
points = glamor_get_vbo_space(screen,
|
||||
max_points * (2 * sizeof (INT16)),
|
||||
max_points *
|
||||
(2 * sizeof (INT16)),
|
||||
&vbo_offset);
|
||||
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT,
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS,
|
||||
2, GL_SHORT,
|
||||
GL_FALSE, 0, vbo_offset);
|
||||
}
|
||||
|
||||
|
@ -149,7 +153,8 @@ glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc,
|
|||
int start_x, int y, unsigned int nglyph,
|
||||
CharInfoPtr *ppci, void *pglyph_base)
|
||||
{
|
||||
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base))
|
||||
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci,
|
||||
pglyph_base))
|
||||
return;
|
||||
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
|
||||
ppci, pglyph_base);
|
||||
|
@ -160,10 +165,13 @@ glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
|
|||
int start_x, int y, unsigned int nglyph,
|
||||
CharInfoPtr *ppci, void *pglyph_base)
|
||||
{
|
||||
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base))
|
||||
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci,
|
||||
pglyph_base))
|
||||
return TRUE;
|
||||
if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
|
||||
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||
glamor_ddx_fallback_check_gc(gc)) {
|
||||
return FALSE;
|
||||
}
|
||||
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
|
||||
ppci, pglyph_base);
|
||||
return TRUE;
|
||||
|
@ -179,8 +187,8 @@ glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
|
|||
}
|
||||
|
||||
static Bool
|
||||
glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
|
||||
DrawablePtr drawable, int w, int h, int x, int y)
|
||||
glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
|
||||
DrawablePtr drawable, int w, int h, int x, int y)
|
||||
{
|
||||
ScreenPtr screen = drawable->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
|
@ -188,65 +196,40 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
|
|||
glamor_pixmap_private *pixmap_priv;
|
||||
uint8_t *bitmap_data = bitmap->devPrivate.ptr;
|
||||
int bitmap_stride = bitmap->devKind;
|
||||
int off_x, off_y;
|
||||
glamor_program *prog;
|
||||
RegionPtr clip = gc->pCompositeClip;
|
||||
int box_x, box_y;
|
||||
int yy, xx;
|
||||
GLfloat xscale, yscale;
|
||||
float color[4];
|
||||
unsigned long fg_pixel = gc->fgPixel;
|
||||
float *points, *next_point;
|
||||
int num_points = 0;
|
||||
int num_points;
|
||||
INT16 *points = NULL;
|
||||
char *vbo_offset;
|
||||
RegionPtr clip;
|
||||
|
||||
if (w * h > MAXINT / (2 * sizeof(float)))
|
||||
return FALSE;
|
||||
|
||||
if (gc->fillStyle != FillSolid) {
|
||||
glamor_fallback("gc fillstyle not solid\n");
|
||||
return FALSE;
|
||||
}
|
||||
goto bail;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
return FALSE;
|
||||
goto bail;
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
if (!glamor_set_alu(screen, gc->alu)) {
|
||||
if (gc->alu == GXclear)
|
||||
fg_pixel = 0;
|
||||
else {
|
||||
glamor_fallback("unsupported alu %x\n", gc->alu);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!glamor_set_planemask(pixmap, gc->planemask)) {
|
||||
glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__);
|
||||
return FALSE;
|
||||
}
|
||||
prog = glamor_use_program_fill(pixmap, gc,
|
||||
&glamor_priv->poly_glyph_blt_progs,
|
||||
&glamor_facet_poly_glyph_blt);
|
||||
if (!prog)
|
||||
goto bail_ctx;
|
||||
|
||||
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
|
||||
|
||||
glUseProgram(glamor_priv->solid_prog);
|
||||
|
||||
glamor_get_rgba_from_pixel(fg_pixel,
|
||||
&color[0], &color[1], &color[2], &color[3],
|
||||
format_for_pixmap(pixmap));
|
||||
glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
|
||||
|
||||
points = glamor_get_vbo_space(screen, w * h * sizeof(float) * 2,
|
||||
points = glamor_get_vbo_space(screen, w * h * sizeof(INT16) * 2,
|
||||
&vbo_offset);
|
||||
next_point = points;
|
||||
|
||||
clip = fbGetCompositeClip(gc);
|
||||
num_points = 0;
|
||||
|
||||
/* Note that because fb sets miTranslate in the GC, our incoming X
|
||||
* and Y are in screen coordinate space (same for spans, but not
|
||||
* other operations).
|
||||
*/
|
||||
|
||||
for (yy = 0; yy < h; yy++) {
|
||||
uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride;
|
||||
for (xx = 0; xx < w; xx++) {
|
||||
|
@ -255,63 +238,58 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
|
|||
x + xx,
|
||||
y + yy,
|
||||
NULL)) {
|
||||
next_point[0] = v_from_x_coord_x(xscale, x + xx + off_x + 0.5);
|
||||
if (glamor_priv->yInverted)
|
||||
next_point[1] = v_from_x_coord_y_inverted(yscale, y + yy + off_y + 0.5);
|
||||
else
|
||||
next_point[1] = v_from_x_coord_y(yscale, y + yy + off_y + 0.5);
|
||||
|
||||
next_point += 2;
|
||||
*points++ = x + xx;
|
||||
*points++ = y + yy;
|
||||
num_points++;
|
||||
}
|
||||
}
|
||||
}
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||
GL_FALSE, 2 * sizeof(float),
|
||||
vbo_offset);
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT,
|
||||
GL_FALSE, 0, vbo_offset);
|
||||
|
||||
glamor_put_vbo_space(screen);
|
||||
|
||||
glDrawArrays(GL_POINTS, 0, num_points);
|
||||
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||
glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE,
|
||||
prog->matrix_uniform, NULL, NULL);
|
||||
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
|
||||
DrawablePtr pDrawable, int w, int h, int x, int y,
|
||||
Bool fallback)
|
||||
{
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
|
||||
if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
|
||||
&& glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
|
||||
&& glamor_ddx_fallback_check_gc(pGC))
|
||||
return FALSE;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pBitmap);
|
||||
if (pixmap_priv->type == GLAMOR_MEMORY) {
|
||||
if (glamor_push_pixels_points(pGC, pBitmap, pDrawable, w, h, x, y))
|
||||
return TRUE;
|
||||
glDrawArrays(GL_POINTS, 0, num_points);
|
||||
}
|
||||
|
||||
miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
return TRUE;
|
||||
|
||||
bail_ctx:
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
bail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
|
||||
DrawablePtr pDrawable, int w, int h, int x, int y)
|
||||
{
|
||||
_glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE);
|
||||
if (glamor_push_pixels_gl(pGC, pBitmap, pDrawable, w, h, x, y))
|
||||
return;
|
||||
|
||||
miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
|
||||
DrawablePtr pDrawable, int w, int h, int x, int y)
|
||||
glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap,
|
||||
DrawablePtr drawable, int w, int h, int x, int y)
|
||||
{
|
||||
return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE);
|
||||
if (glamor_push_pixels_gl(gc, bitmap, drawable, w, h, x, y))
|
||||
return TRUE;
|
||||
|
||||
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||
glamor_ddx_fallback_check_pixmap(&bitmap->drawable) &&
|
||||
glamor_ddx_fallback_check_gc(gc))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
miPushPixels(gc, bitmap, drawable, w, h, x, y);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ clear_mask_cache(struct glamor_glyph_mask_cache *maskcache)
|
|||
struct glamor_glyph_mask_cache_entry *mce;
|
||||
|
||||
glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
|
||||
MASK_CACHE_MAX_SIZE, GXcopy, 0xFFFFFFFF, 0);
|
||||
MASK_CACHE_MAX_SIZE, 0);
|
||||
mce = &maskcache->mcache[0];
|
||||
while (cnt--) {
|
||||
mce->width = 0;
|
||||
|
@ -448,9 +448,9 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
|
|||
box.y1 = y;
|
||||
box.x2 = x + glyph->info.width;
|
||||
box.y2 = y + glyph->info.height;
|
||||
glamor_copy_n_to_n_nf(&scratch->drawable,
|
||||
&pCachePixmap->drawable, NULL,
|
||||
&box, 1, -x, -y, FALSE, FALSE, 0, NULL);
|
||||
glamor_copy(&scratch->drawable,
|
||||
&pCachePixmap->drawable, NULL,
|
||||
&box, 1, -x, -y, FALSE, FALSE, 0, NULL);
|
||||
if (scratch != pGlyphPixmap)
|
||||
screen->DestroyPixmap(scratch);
|
||||
|
||||
|
@ -1433,7 +1433,7 @@ glamor_glyphs_via_mask(CARD8 op,
|
|||
glamor_destroy_pixmap(mask_pixmap);
|
||||
return;
|
||||
}
|
||||
glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0);
|
||||
glamor_solid(mask_pixmap, 0, 0, width, height, 0);
|
||||
component_alpha = NeedsComponent(mask_format->format);
|
||||
mask = CreatePicture(0, &mask_pixmap->drawable,
|
||||
mask_format, CPComponentAlpha,
|
||||
|
|
|
@ -699,7 +699,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
|
|||
width),
|
||||
(INT16) (dst_picture->pDrawable->
|
||||
height),
|
||||
glamor_priv->yInverted, vertices);
|
||||
vertices);
|
||||
|
||||
if (tex_normalize) {
|
||||
glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
|
||||
|
@ -710,17 +710,14 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
|
|||
(INT16) (dst_picture->
|
||||
pDrawable->height +
|
||||
y_source),
|
||||
glamor_priv->yInverted,
|
||||
tex_vertices);
|
||||
}
|
||||
else {
|
||||
glamor_set_tcoords_tri_strip((INT16) (dst_picture->pDrawable->width),
|
||||
(INT16) (dst_picture->pDrawable->height),
|
||||
x_source, y_source,
|
||||
glamor_set_tcoords_tri_strip(x_source, y_source,
|
||||
(INT16) (dst_picture->pDrawable->width) +
|
||||
x_source,
|
||||
(INT16) (dst_picture->pDrawable->height) +
|
||||
y_source, glamor_priv->yInverted,
|
||||
y_source,
|
||||
tex_vertices);
|
||||
}
|
||||
|
||||
|
@ -1084,13 +1081,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
|
|||
r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.
|
||||
radius);
|
||||
|
||||
glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted,
|
||||
cxy);
|
||||
glamor_set_circle_centre(width, height, c1x, c1y, cxy);
|
||||
glUniform2fv(c1_uniform_location, 1, cxy);
|
||||
glUniform1f(r1_uniform_location, r1);
|
||||
|
||||
glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted,
|
||||
cxy);
|
||||
glamor_set_circle_centre(width, height, c2x, c2y, cxy);
|
||||
glUniform2fv(c2_uniform_location, 1, cxy);
|
||||
glUniform1f(r2_uniform_location, r2);
|
||||
|
||||
|
@ -1322,7 +1317,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
|
|||
linear.p1.x),
|
||||
pixman_fixed_to_double(src_picture->pSourcePict->
|
||||
linear.p1.y),
|
||||
glamor_priv->yInverted, pt1);
|
||||
pt1);
|
||||
DEBUGF("pt1:(%f, %f) ---> (%f %f)\n",
|
||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
|
||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y),
|
||||
|
@ -1333,7 +1328,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
|
|||
linear.p2.x),
|
||||
pixman_fixed_to_double(src_picture->pSourcePict->
|
||||
linear.p2.y),
|
||||
glamor_priv->yInverted, pt2);
|
||||
pt2);
|
||||
DEBUGF("pt2:(%f, %f) ---> (%f %f)\n",
|
||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
|
||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y),
|
||||
|
|
|
@ -797,9 +797,9 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
|||
copy_box.y2 = temp_extent->y2 - temp_extent->y1;
|
||||
dx = temp_extent->x1;
|
||||
dy = temp_extent->y1;
|
||||
glamor_copy_n_to_n(&priv->base.pixmap->drawable,
|
||||
&temp_pixmap->drawable,
|
||||
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
||||
glamor_copy(&priv->base.pixmap->drawable,
|
||||
&temp_pixmap->drawable,
|
||||
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
||||
// glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
|
||||
// temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00);
|
||||
}
|
||||
|
@ -829,9 +829,10 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
|||
copy_box.x1, copy_box.y1, copy_box.x2,
|
||||
copy_box.y2, dx, dy);
|
||||
|
||||
glamor_copy_n_to_n(&priv->base.pixmap->drawable,
|
||||
&temp_pixmap->drawable,
|
||||
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
||||
glamor_copy(&priv->base.pixmap->drawable,
|
||||
&temp_pixmap->drawable,
|
||||
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
||||
|
||||
box++;
|
||||
}
|
||||
}
|
||||
|
|
187
glamor/glamor_lines.c
Normal file
187
glamor/glamor_lines.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright © 2014 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
#include "glamor_program.h"
|
||||
#include "glamor_transform.h"
|
||||
#include "glamor_prepare.h"
|
||||
|
||||
static const glamor_facet glamor_facet_poly_lines = {
|
||||
.name = "poly_lines",
|
||||
.vs_vars = "attribute vec2 primitive;\n",
|
||||
.vs_exec = (" vec2 pos = vec2(0.0,0.0);\n"
|
||||
GLAMOR_POS(gl_Position, primitive.xy)),
|
||||
};
|
||||
|
||||
static Bool
|
||||
glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points)
|
||||
{
|
||||
ScreenPtr screen = drawable->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
glamor_program *prog;
|
||||
int off_x, off_y;
|
||||
DDXPointPtr v;
|
||||
char *vbo_offset;
|
||||
int box_x, box_y;
|
||||
int add_last;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
goto bail;
|
||||
|
||||
add_last = 0;
|
||||
if (gc->capStyle != CapNotLast)
|
||||
add_last = 1;
|
||||
|
||||
if (n < 2)
|
||||
return TRUE;
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
prog = glamor_use_program_fill(pixmap, gc,
|
||||
&glamor_priv->poly_line_program,
|
||||
&glamor_facet_poly_lines);
|
||||
|
||||
if (!prog)
|
||||
goto bail_ctx;
|
||||
|
||||
/* Set up the vertex buffers for the points */
|
||||
|
||||
v = glamor_get_vbo_space(drawable->pScreen,
|
||||
(n + add_last) * sizeof (DDXPointRec),
|
||||
&vbo_offset);
|
||||
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
|
||||
sizeof (DDXPointRec), vbo_offset);
|
||||
|
||||
if (mode == CoordModePrevious) {
|
||||
int i;
|
||||
DDXPointRec here = { 0, 0 };
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
here.x += points[i].x;
|
||||
here.y += points[i].y;
|
||||
v[i] = here;
|
||||
}
|
||||
} else {
|
||||
memcpy(v, points, n * sizeof (DDXPointRec));
|
||||
}
|
||||
|
||||
if (add_last) {
|
||||
v[n].x = v[n-1].x + 1;
|
||||
v[n].y = v[n-1].y;
|
||||
}
|
||||
|
||||
glamor_put_vbo_space(screen);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||
int nbox = RegionNumRects(gc->pCompositeClip);
|
||||
BoxPtr box = RegionRects(gc->pCompositeClip);
|
||||
|
||||
glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
|
||||
prog->matrix_uniform, &off_x, &off_y);
|
||||
|
||||
while (nbox--) {
|
||||
glScissor(box->x1 + off_x,
|
||||
box->y1 + off_y,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1);
|
||||
box++;
|
||||
glDrawArrays(GL_LINE_STRIP, 0, n + add_last);
|
||||
}
|
||||
}
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
return TRUE;
|
||||
bail_ctx:
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
bail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points)
|
||||
{
|
||||
if (gc->lineWidth != 0)
|
||||
return FALSE;
|
||||
|
||||
switch (gc->lineStyle) {
|
||||
case LineSolid:
|
||||
return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points);
|
||||
case LineOnOffDash:
|
||||
return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points);
|
||||
case LineDoubleDash:
|
||||
if (gc->fillStyle == FillTiled)
|
||||
return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points);
|
||||
else
|
||||
return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
glamor_poly_lines_bail(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points)
|
||||
{
|
||||
glamor_fallback("to %p (%c)\n", drawable,
|
||||
glamor_get_drawable_location(drawable));
|
||||
|
||||
miPolylines(drawable, gc, mode, n, points);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points)
|
||||
{
|
||||
if (glamor_poly_lines_gl(drawable, gc, mode, n, points))
|
||||
return;
|
||||
glamor_poly_lines_bail(drawable, gc, mode, n, points);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points)
|
||||
{
|
||||
if (glamor_poly_lines_gl(drawable, gc, mode, n, points))
|
||||
return TRUE;
|
||||
|
||||
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||
glamor_ddx_fallback_check_gc(gc))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glamor_poly_lines_bail(drawable, gc, mode, n, points);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -45,24 +45,6 @@ glamor_upload_picture_to_texture(PicturePtr picture)
|
|||
return glamor_upload_pixmap_to_texture(pixmap);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
|
||||
{
|
||||
if (!picture || !picture->pDrawable)
|
||||
return TRUE;
|
||||
|
||||
return glamor_prepare_access(picture->pDrawable, access);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_finish_access_picture(PicturePtr picture)
|
||||
{
|
||||
if (!picture || !picture->pDrawable)
|
||||
return;
|
||||
|
||||
glamor_finish_access(picture->pDrawable);
|
||||
}
|
||||
|
||||
/*
|
||||
* We should already have drawable attached to it, if it has one.
|
||||
* Then set the attached pixmap to is_picture format, and set
|
||||
|
|
|
@ -747,11 +747,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
|||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
static float vertices[8];
|
||||
|
||||
static float texcoords[8] = { 0, 1,
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0
|
||||
};
|
||||
static float texcoords_inv[8] = { 0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
|
@ -760,11 +755,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
|||
float *ptexcoords;
|
||||
float dst_xscale, dst_yscale;
|
||||
GLuint tex = 0;
|
||||
int need_flip;
|
||||
int need_free_bits = 0;
|
||||
|
||||
need_flip = !glamor_priv->yInverted;
|
||||
|
||||
if (bits == NULL)
|
||||
goto ready_to_upload;
|
||||
|
||||
|
@ -798,7 +790,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
|||
/* 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 && !need_flip
|
||||
&& revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING
|
||||
#ifdef WALKAROUND_LARGE_TEXTURE_MAP
|
||||
&& pixmap_priv->type != GLAMOR_TEXTURE_LARGE
|
||||
#endif
|
||||
|
@ -818,17 +810,14 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (need_flip)
|
||||
ptexcoords = texcoords;
|
||||
else
|
||||
ptexcoords = texcoords_inv;
|
||||
ptexcoords = texcoords_inv;
|
||||
|
||||
pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
|
||||
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
|
||||
dst_yscale,
|
||||
x, y,
|
||||
x + w, y + h,
|
||||
glamor_priv->yInverted, vertices);
|
||||
vertices);
|
||||
/* Slow path, we need to flip y or wire alpha to 1. */
|
||||
glamor_make_current(glamor_priv);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||
|
@ -865,10 +854,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
|||
/*
|
||||
* Prepare to upload a pixmap to texture memory.
|
||||
* no_alpha equals 1 means the format needs to wire alpha to 1.
|
||||
* Two condtion need to setup a fbo for a pixmap
|
||||
* 1. !yInverted, we need to do flip if we are not yInverted.
|
||||
* 2. no_alpha != 0, we need to wire the alpha.
|
||||
* */
|
||||
*/
|
||||
static int
|
||||
glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
|
||||
int revert, int swap_rb)
|
||||
|
@ -896,8 +882,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
|
|||
return 0;
|
||||
|
||||
if (!(no_alpha || (revert == REVERT_NORMAL)
|
||||
|| (swap_rb != SWAP_NONE_UPLOADING)
|
||||
|| !glamor_priv->yInverted)) {
|
||||
|| (swap_rb != SWAP_NONE_UPLOADING))) {
|
||||
/* We don't need a fbo, a simple texture uploading should work. */
|
||||
|
||||
flag = GLAMOR_CREATE_FBO_NO_FBO;
|
||||
|
@ -939,26 +924,6 @@ glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* download sub region from a large region.
|
||||
*/
|
||||
static void
|
||||
glamor_get_bits(char *dst_bits, int dst_stride, char *src_bits,
|
||||
int src_stride, int bpp, int x, int y, int w, int h)
|
||||
{
|
||||
int j;
|
||||
int byte_per_pixel;
|
||||
|
||||
byte_per_pixel = bpp / 8;
|
||||
dst_bits += y * dst_stride + x * byte_per_pixel;
|
||||
|
||||
for (j = y; j < y + h; j++) {
|
||||
memcpy(dst_bits, src_bits, w * byte_per_pixel);
|
||||
src_bits += src_stride;
|
||||
dst_bits += dst_stride;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
|
||||
int h, int stride, void *bits, int pbo)
|
||||
|
@ -1100,13 +1065,6 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
|
||||
{
|
||||
if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
|
||||
LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* as gles2 only support a very small set of color format and
|
||||
* type when do glReadPixel,
|
||||
|
@ -1142,7 +1100,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
|
|||
|
||||
glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
|
||||
temp_xscale, temp_yscale, 0, 0, w, h,
|
||||
glamor_priv->yInverted, vertices);
|
||||
vertices);
|
||||
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), vertices);
|
||||
|
@ -1153,7 +1111,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
|
|||
source_yscale,
|
||||
x, y,
|
||||
x + w, y + h,
|
||||
glamor_priv->yInverted, texcoords);
|
||||
texcoords);
|
||||
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), texcoords);
|
||||
|
@ -1176,330 +1134,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
|
|||
return temp_fbo;
|
||||
}
|
||||
|
||||
/*
|
||||
* Download a sub region of pixmap to a specified memory region.
|
||||
* The pixmap must have a valid FBO, otherwise return a NULL.
|
||||
* */
|
||||
|
||||
static void *
|
||||
_glamor_download_sub_pixmap_to_cpu(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, int pbo,
|
||||
glamor_access_t access)
|
||||
{
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
GLenum gl_access = 0, gl_usage = 0;
|
||||
void *data, *read;
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
glamor_pixmap_fbo *temp_fbo = NULL;
|
||||
int need_post_conversion = 0;
|
||||
int need_free_data = 0;
|
||||
int fbo_x_off, fbo_y_off;
|
||||
|
||||
data = bits;
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
return NULL;
|
||||
|
||||
switch (access) {
|
||||
case GLAMOR_ACCESS_RO:
|
||||
gl_access = GL_READ_ONLY;
|
||||
gl_usage = GL_STREAM_READ;
|
||||
break;
|
||||
case GLAMOR_ACCESS_RW:
|
||||
gl_access = GL_READ_WRITE;
|
||||
gl_usage = GL_DYNAMIC_DRAW;
|
||||
break;
|
||||
default:
|
||||
ErrorF("Glamor: Invalid access code. %d\n", access);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||
|
||||
need_post_conversion = (revert > REVERT_NORMAL);
|
||||
if (need_post_conversion) {
|
||||
if (pixmap->drawable.depth == 1) {
|
||||
int temp_stride;
|
||||
|
||||
temp_stride = (((w * 8 + 7) / 8) + 3) & ~3;
|
||||
data = malloc(temp_stride * h);
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
need_free_data = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
|
||||
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
||||
&& !need_post_conversion
|
||||
&& (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
|
||||
if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
|
||||
format, type, no_alpha,
|
||||
revert, swap_rb))) {
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
x = 0;
|
||||
y = 0;
|
||||
fbo_x_off = 0;
|
||||
fbo_y_off = 0;
|
||||
}
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
|
||||
if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
|
||||
|
||||
if (!glamor_priv->yInverted) {
|
||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
||||
glPixelStorei(GL_PACK_INVERT_MESA, 1);
|
||||
}
|
||||
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
|
||||
assert(pbo > 0);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, gl_usage);
|
||||
}
|
||||
|
||||
glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data);
|
||||
|
||||
if (!glamor_priv->yInverted) {
|
||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
||||
glPixelStorei(GL_PACK_INVERT_MESA, 0);
|
||||
}
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
|
||||
bits = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned int temp_pbo;
|
||||
int yy;
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
glGenBuffers(1, &temp_pbo);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, GL_STREAM_READ);
|
||||
glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, 0);
|
||||
read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
||||
for (yy = 0; yy < pixmap->drawable.height; yy++)
|
||||
memcpy((char *) data + yy * stride,
|
||||
(char *) read + (h - yy - 1) * stride, stride);
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
glDeleteBuffers(1, &temp_pbo);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (need_post_conversion) {
|
||||
/* As OpenGL desktop version never enters here.
|
||||
* Don't need to consider if the pbo is valid.*/
|
||||
bits = glamor_color_convert_to_bits(data, bits,
|
||||
w, h,
|
||||
stride, no_alpha, revert, swap_rb);
|
||||
}
|
||||
|
||||
if (temp_fbo != NULL)
|
||||
glamor_destroy_fbo(temp_fbo);
|
||||
if (need_free_data)
|
||||
free(data);
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
void *
|
||||
glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||
int stride, void *bits, int pbo,
|
||||
glamor_access_t access)
|
||||
{
|
||||
GLenum format, type;
|
||||
int no_alpha, revert, swap_rb;
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
Bool force_clip;
|
||||
|
||||
if (glamor_get_tex_format_type_from_pixmap(pixmap,
|
||||
&format,
|
||||
&type,
|
||||
&no_alpha,
|
||||
&revert, &swap_rb, 0)) {
|
||||
glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
return NULL;
|
||||
|
||||
force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
|
||||
&& !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
|
||||
|
||||
if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
|
||||
|
||||
RegionRec region;
|
||||
BoxRec box;
|
||||
int n_region;
|
||||
glamor_pixmap_clipped_regions *clipped_regions;
|
||||
void *sub_bits;
|
||||
int i, j;
|
||||
|
||||
sub_bits = malloc(h * stride);
|
||||
if (sub_bits == NULL)
|
||||
return FALSE;
|
||||
box.x1 = x;
|
||||
box.y1 = y;
|
||||
box.x2 = x + w;
|
||||
box.y2 = y + h;
|
||||
RegionInitBoxes(®ion, &box, 1);
|
||||
|
||||
if (!force_clip)
|
||||
clipped_regions =
|
||||
glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region,
|
||||
0, 0, 0);
|
||||
else
|
||||
clipped_regions =
|
||||
glamor_compute_clipped_regions_ext(pixmap_priv, ®ion,
|
||||
&n_region,
|
||||
pixmap_priv->large.block_w,
|
||||
pixmap_priv->large.block_h,
|
||||
0,
|
||||
0);
|
||||
|
||||
DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
|
||||
for (i = 0; i < n_region; i++) {
|
||||
BoxPtr boxes;
|
||||
int nbox;
|
||||
int temp_stride;
|
||||
void *temp_bits;
|
||||
|
||||
assert(pbo == 0);
|
||||
SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
|
||||
|
||||
boxes = RegionRects(clipped_regions[i].region);
|
||||
nbox = RegionNumRects(clipped_regions[i].region);
|
||||
for (j = 0; j < nbox; j++) {
|
||||
temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
|
||||
pixmap->drawable.depth);
|
||||
|
||||
if (boxes[j].x1 == x && temp_stride == stride) {
|
||||
temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
|
||||
}
|
||||
else {
|
||||
temp_bits = sub_bits;
|
||||
}
|
||||
DEBUGF("download x %d y %d w %d h %d temp stride %d \n",
|
||||
boxes[j].x1, boxes[j].y1,
|
||||
boxes[j].x2 - boxes[j].x1,
|
||||
boxes[j].y2 - boxes[j].y1, temp_stride);
|
||||
|
||||
/* For large pixmap, we don't support pbo currently. */
|
||||
assert(pbo == 0);
|
||||
if (_glamor_download_sub_pixmap_to_cpu
|
||||
(pixmap, format, type, no_alpha, revert, swap_rb,
|
||||
boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
|
||||
boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits, pbo,
|
||||
access) == FALSE) {
|
||||
RegionUninit(®ion);
|
||||
free(sub_bits);
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
if (boxes[j].x1 != x || temp_stride != stride)
|
||||
glamor_get_bits(bits, stride, temp_bits, temp_stride,
|
||||
pixmap->drawable.bitsPerPixel,
|
||||
boxes[j].x1 - x, boxes[j].y1 - y,
|
||||
boxes[j].x2 - boxes[j].x1,
|
||||
boxes[j].y2 - boxes[j].y1);
|
||||
}
|
||||
|
||||
RegionDestroy(clipped_regions[i].region);
|
||||
}
|
||||
free(sub_bits);
|
||||
free(clipped_regions);
|
||||
RegionUninit(®ion);
|
||||
return bits;
|
||||
}
|
||||
else
|
||||
return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type,
|
||||
no_alpha, revert, swap_rb, x,
|
||||
y, w, h, stride, bits, pbo,
|
||||
access);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a pixmap to CPU memory.
|
||||
* The input data is the pixmap's fbo.
|
||||
* The output data is at pixmap->devPrivate.ptr. We always use pbo
|
||||
* to read the fbo and then map it to va. If possible, we will use
|
||||
* it directly as devPrivate.ptr.
|
||||
* If successfully download a fbo to cpu then return TRUE.
|
||||
* Otherwise return FALSE.
|
||||
**/
|
||||
Bool
|
||||
glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
||||
{
|
||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
unsigned int stride;
|
||||
void *data = NULL, *dst;
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
int pbo = 0;
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
return TRUE;
|
||||
|
||||
glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
|
||||
"Downloading pixmap %p %dx%d depth%d\n",
|
||||
pixmap,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height, pixmap->drawable.depth);
|
||||
|
||||
stride = pixmap->devKind;
|
||||
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
||||
|| (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
|
||||
|| pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||
data = malloc(stride * pixmap->drawable.height);
|
||||
}
|
||||
else {
|
||||
glamor_make_current(glamor_priv);
|
||||
if (pixmap_priv->base.fbo->pbo == 0)
|
||||
glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
|
||||
pbo = pixmap_priv->base.fbo->pbo;
|
||||
}
|
||||
|
||||
if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
|
||||
stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
|
||||
pixmap_priv->base.drm_stride = pixmap->devKind;
|
||||
pixmap->devKind = stride;
|
||||
}
|
||||
|
||||
dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
|
||||
pixmap->drawable.width,
|
||||
pixmap->drawable.height,
|
||||
pixmap->devKind, data, pbo, access);
|
||||
|
||||
if (!dst) {
|
||||
if (data)
|
||||
free(data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pbo != 0)
|
||||
pixmap_priv->base.fbo->pbo_valid = 1;
|
||||
|
||||
pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
|
||||
|
||||
pixmap->devPrivate.ptr = dst;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* fixup a fbo to the exact size as the pixmap. */
|
||||
/* XXX LARGE pixmap? */
|
||||
Bool
|
||||
|
@ -1558,132 +1192,3 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We may use this function to reduce a large pixmap to a small sub
|
||||
* pixmap. Two scenarios currently:
|
||||
* 1. When fallback a large textured pixmap to CPU but we do need to
|
||||
* do rendering within a small sub region, then we can just get a
|
||||
* sub region.
|
||||
*
|
||||
* 2. When uploading a large pixmap to texture but we only need to
|
||||
* use part of the source/mask picture. As glTexImage2D will be more
|
||||
* efficient to upload a contingent region rather than a sub block
|
||||
* in a large buffer. We use this function to gather the sub region
|
||||
* to a contingent sub pixmap.
|
||||
*
|
||||
* The sub-pixmap must have the same format as the source pixmap.
|
||||
*
|
||||
* */
|
||||
PixmapPtr
|
||||
glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||
glamor_access_t access)
|
||||
{
|
||||
glamor_screen_private *glamor_priv;
|
||||
PixmapPtr sub_pixmap;
|
||||
glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv;
|
||||
void *data;
|
||||
int pbo;
|
||||
int flag;
|
||||
|
||||
if (x < 0 || y < 0)
|
||||
return NULL;
|
||||
w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
|
||||
h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
|
||||
|
||||
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
return NULL;
|
||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 ||
|
||||
pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
|
||||
flag = GLAMOR_CREATE_PIXMAP_CPU;
|
||||
else
|
||||
flag = GLAMOR_CREATE_PIXMAP_MAP;
|
||||
|
||||
sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
||||
pixmap->drawable.depth, flag);
|
||||
|
||||
if (sub_pixmap == NULL)
|
||||
return NULL;
|
||||
|
||||
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
||||
pbo =
|
||||
sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.
|
||||
fbo->pbo : 0) : 0;
|
||||
|
||||
if (pixmap_priv->base.is_picture) {
|
||||
sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
|
||||
sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
|
||||
}
|
||||
|
||||
if (pbo)
|
||||
data = NULL;
|
||||
else
|
||||
data = sub_pixmap->devPrivate.ptr;
|
||||
|
||||
data =
|
||||
glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h,
|
||||
sub_pixmap->devKind, data, pbo,
|
||||
access);
|
||||
if (data == NULL) {
|
||||
fbDestroyPixmap(sub_pixmap);
|
||||
return NULL;
|
||||
}
|
||||
if (pbo) {
|
||||
assert(sub_pixmap->devPrivate.ptr == NULL);
|
||||
sub_pixmap->devPrivate.ptr = data;
|
||||
sub_pixmap_priv->base.fbo->pbo_valid = 1;
|
||||
}
|
||||
#if 0
|
||||
struct pixman_box16 box;
|
||||
PixmapPtr new_sub_pixmap;
|
||||
int dx, dy;
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = w;
|
||||
box.y2 = h;
|
||||
|
||||
dx = x;
|
||||
dy = y;
|
||||
|
||||
new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
||||
pixmap->drawable.depth,
|
||||
GLAMOR_CREATE_PIXMAP_CPU);
|
||||
glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box,
|
||||
1, dx, dy, 0, 0, 0, NULL);
|
||||
glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
|
||||
#endif
|
||||
|
||||
return sub_pixmap;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
|
||||
int w, int h, glamor_access_t access)
|
||||
{
|
||||
void *bits;
|
||||
int pbo;
|
||||
glamor_pixmap_private *sub_pixmap_priv;
|
||||
|
||||
if (access != GLAMOR_ACCESS_RO) {
|
||||
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
||||
if (sub_pixmap_priv->base.fbo && sub_pixmap_priv->base.fbo->pbo_valid) {
|
||||
bits = NULL;
|
||||
pbo = sub_pixmap_priv->base.fbo->pbo;
|
||||
}
|
||||
else {
|
||||
bits = sub_pixmap->devPrivate.ptr;
|
||||
pbo = 0;
|
||||
}
|
||||
|
||||
assert(x >= 0 && y >= 0);
|
||||
w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w;
|
||||
h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h;
|
||||
glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h,
|
||||
sub_pixmap->devKind, bits, pbo);
|
||||
}
|
||||
glamor_destroy_pixmap(sub_pixmap);
|
||||
}
|
||||
|
|
|
@ -105,9 +105,6 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
|
|||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
glamor_priv->state = RENDER_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
|
||||
return TRUE;
|
||||
|
||||
bail_ctx:
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* 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
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Anholt <eric@anholt.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
/** @file glamor_polylines.c
|
||||
*
|
||||
* GC PolyFillRect implementation, taken straight from fb_fill.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* glamor_poly_lines() checks if it can accelerate the lines as a group of
|
||||
* horizontal or vertical lines (rectangles), and uses existing rectangle fill
|
||||
* acceleration if so.
|
||||
*/
|
||||
static Bool
|
||||
_glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
||||
DDXPointPtr points, Bool fallback)
|
||||
{
|
||||
xRectangle *rects;
|
||||
int x1, x2, y1, y2;
|
||||
int i;
|
||||
|
||||
/* Don't try to do wide lines or non-solid fill style. */
|
||||
if (gc->lineWidth != 0) {
|
||||
/* This ends up in miSetSpans, which is accelerated as well as we
|
||||
* can hope X wide lines will be.
|
||||
*/
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (gc->lineStyle != LineSolid) {
|
||||
glamor_fallback("non-solid fill line style %d\n", gc->lineStyle);
|
||||
goto fail;
|
||||
}
|
||||
rects = malloc(sizeof(xRectangle) * (n - 1));
|
||||
x1 = points[0].x;
|
||||
y1 = points[0].y;
|
||||
/* If we have any non-horizontal/vertical, fall back. */
|
||||
for (i = 0; i < n - 1; i++) {
|
||||
if (mode == CoordModePrevious) {
|
||||
x2 = x1 + points[i + 1].x;
|
||||
y2 = y1 + points[i + 1].y;
|
||||
}
|
||||
else {
|
||||
x2 = points[i + 1].x;
|
||||
y2 = points[i + 1].y;
|
||||
}
|
||||
if (x1 != x2 && y1 != y2) {
|
||||
free(rects);
|
||||
glamor_fallback("stub diagonal poly_line\n");
|
||||
goto fail;
|
||||
}
|
||||
if (x1 < x2) {
|
||||
rects[i].x = x1;
|
||||
rects[i].width = x2 - x1 + 1;
|
||||
}
|
||||
else {
|
||||
rects[i].x = x2;
|
||||
rects[i].width = x1 - x2 + 1;
|
||||
}
|
||||
if (y1 < y2) {
|
||||
rects[i].y = y1;
|
||||
rects[i].height = y2 - y1 + 1;
|
||||
}
|
||||
else {
|
||||
rects[i].y = y2;
|
||||
rects[i].height = y1 - y2 + 1;
|
||||
}
|
||||
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
|
||||
free(rects);
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)
|
||||
&& glamor_ddx_fallback_check_gc(gc))
|
||||
return FALSE;
|
||||
|
||||
switch (gc->lineStyle) {
|
||||
case LineSolid:
|
||||
if (gc->lineWidth == 0)
|
||||
miZeroLine(drawable, gc, mode, n, points);
|
||||
else
|
||||
miWideLine(drawable, gc, mode, n, points);
|
||||
break;
|
||||
case LineOnOffDash:
|
||||
case LineDoubleDash:
|
||||
miWideDash(drawable, gc, mode, n, points);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
||||
DDXPointPtr points)
|
||||
{
|
||||
_glamor_poly_lines(drawable, gc, mode, n, points, TRUE);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
||||
DDXPointPtr points)
|
||||
{
|
||||
return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE);
|
||||
}
|
274
glamor/glamor_prepare.c
Normal file
274
glamor/glamor_prepare.c
Normal file
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
* Copyright © 2014 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
#include "glamor_prepare.h"
|
||||
#include "glamor_transfer.h"
|
||||
|
||||
/*
|
||||
* Make a pixmap ready to draw with fb by
|
||||
* creating a PBO large enough for the whole object
|
||||
* and downloading all of the FBOs into it.
|
||||
*/
|
||||
|
||||
static Bool
|
||||
glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
||||
int gl_access, gl_usage;
|
||||
RegionRec region;
|
||||
|
||||
if (priv->type == GLAMOR_DRM_ONLY)
|
||||
return FALSE;
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
|
||||
return TRUE;
|
||||
|
||||
RegionInit(®ion, box, 1);
|
||||
|
||||
/* See if it's already mapped */
|
||||
if (pixmap->devPrivate.ptr) {
|
||||
/*
|
||||
* Someone else has mapped this pixmap;
|
||||
* we'll assume that it's directly mapped
|
||||
* by a lower level driver
|
||||
*/
|
||||
if (!priv->base.prepared)
|
||||
return TRUE;
|
||||
|
||||
/* In X, multiple Drawables can be stored in the same Pixmap (such as
|
||||
* each individual window in a non-composited screen pixmap, or the
|
||||
* reparented window contents inside the window-manager-decorated window
|
||||
* pixmap on a composited screen).
|
||||
*
|
||||
* As a result, when doing a series of mappings for a fallback, we may
|
||||
* need to add more boxes to the set of data we've downloaded, as we go.
|
||||
*/
|
||||
RegionSubtract(®ion, ®ion, &priv->base.prepare_region);
|
||||
if (!RegionNotEmpty(®ion))
|
||||
return TRUE;
|
||||
|
||||
if (access == GLAMOR_ACCESS_RW)
|
||||
FatalError("attempt to remap buffer as writable");
|
||||
|
||||
if (priv->base.pbo) {
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
pixmap->devPrivate.ptr = NULL;
|
||||
}
|
||||
} else {
|
||||
RegionInit(&priv->base.prepare_region, box, 1);
|
||||
|
||||
if (glamor_priv->has_rw_pbo) {
|
||||
if (priv->base.pbo == 0)
|
||||
glGenBuffers(1, &priv->base.pbo);
|
||||
|
||||
if (access == GLAMOR_ACCESS_RW)
|
||||
gl_usage = GL_DYNAMIC_DRAW;
|
||||
else
|
||||
gl_usage = GL_STREAM_READ;
|
||||
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER,
|
||||
pixmap->devKind * pixmap->drawable.height, NULL,
|
||||
gl_usage);
|
||||
} else {
|
||||
pixmap->devPrivate.ptr = malloc(pixmap->devKind *
|
||||
pixmap->drawable.height);
|
||||
if (!pixmap->devPrivate.ptr)
|
||||
return FALSE;
|
||||
}
|
||||
priv->base.map_access = access;
|
||||
}
|
||||
|
||||
glamor_download_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion),
|
||||
0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
|
||||
|
||||
RegionUninit(®ion);
|
||||
|
||||
if (glamor_priv->has_rw_pbo) {
|
||||
if (priv->base.map_access == GLAMOR_ACCESS_RW)
|
||||
gl_access = GL_READ_WRITE;
|
||||
else
|
||||
gl_access = GL_READ_ONLY;
|
||||
|
||||
pixmap->devPrivate.ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
priv->base.prepared = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we're done with the drawable, unmap the PBO, reupload
|
||||
* if we were writing to it and then unbind it to release the memory
|
||||
*/
|
||||
|
||||
static void
|
||||
glamor_fini_pixmap(PixmapPtr pixmap)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
|
||||
return;
|
||||
|
||||
if (!priv->base.prepared)
|
||||
return;
|
||||
|
||||
if (glamor_priv->has_rw_pbo) {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo);
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
pixmap->devPrivate.ptr = NULL;
|
||||
}
|
||||
|
||||
if (priv->base.map_access == GLAMOR_ACCESS_RW) {
|
||||
glamor_upload_boxes(pixmap,
|
||||
RegionRects(&priv->base.prepare_region),
|
||||
RegionNumRects(&priv->base.prepare_region),
|
||||
0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
|
||||
}
|
||||
|
||||
RegionUninit(&priv->base.prepare_region);
|
||||
|
||||
if (glamor_priv->has_rw_pbo) {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
glDeleteBuffers(1, &priv->base.pbo);
|
||||
priv->base.pbo = 0;
|
||||
} else {
|
||||
free(pixmap->devPrivate.ptr);
|
||||
pixmap->devPrivate.ptr = NULL;
|
||||
}
|
||||
|
||||
priv->base.prepared = FALSE;
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
|
||||
{
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
BoxRec box;
|
||||
int off_x, off_y;
|
||||
|
||||
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
||||
|
||||
box.x1 = drawable->x + off_x;
|
||||
box.x2 = box.x1 + drawable->width;
|
||||
box.y1 = drawable->y + off_y;
|
||||
box.y2 = box.y1 + drawable->height;
|
||||
return glamor_prep_pixmap_box(pixmap, access, &box);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
BoxRec box;
|
||||
int off_x, off_y;
|
||||
|
||||
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
||||
box.x1 = drawable->x + x + off_x;
|
||||
box.x2 = box.x1 + w;
|
||||
box.y1 = drawable->y + y + off_y;
|
||||
box.y2 = box.y1 + h;
|
||||
return glamor_prep_pixmap_box(pixmap, access, &box);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_finish_access(DrawablePtr drawable)
|
||||
{
|
||||
glamor_fini_pixmap(glamor_get_drawable_pixmap(drawable));
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a picture ready to use with fb.
|
||||
*/
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
|
||||
{
|
||||
if (!picture || !picture->pDrawable)
|
||||
return TRUE;
|
||||
|
||||
return glamor_prepare_access(picture->pDrawable, access);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
if (!picture || !picture->pDrawable)
|
||||
return TRUE;
|
||||
return glamor_prepare_access_box(picture->pDrawable, access,
|
||||
x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_finish_access_picture(PicturePtr picture)
|
||||
{
|
||||
if (!picture || !picture->pDrawable)
|
||||
return;
|
||||
|
||||
glamor_finish_access(picture->pDrawable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a GC ready to use with fb. This just
|
||||
* means making sure the appropriate fill pixmap is
|
||||
* in CPU memory again
|
||||
*/
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_gc(GCPtr gc)
|
||||
{
|
||||
switch (gc->fillStyle) {
|
||||
case FillTiled:
|
||||
return glamor_prepare_access(&gc->tile.pixmap->drawable,
|
||||
GLAMOR_ACCESS_RO);
|
||||
case FillStippled:
|
||||
case FillOpaqueStippled:
|
||||
return glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free any temporary CPU pixmaps for the GC
|
||||
*/
|
||||
void
|
||||
glamor_finish_access_gc(GCPtr gc)
|
||||
{
|
||||
switch (gc->fillStyle) {
|
||||
case FillTiled:
|
||||
glamor_finish_access(&gc->tile.pixmap->drawable);
|
||||
break;
|
||||
case FillStippled:
|
||||
case FillOpaqueStippled:
|
||||
glamor_finish_access(&gc->stipple->drawable);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -20,25 +20,33 @@
|
|||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
#ifndef _GLAMOR_PREPARE_H_
|
||||
#define _GLAMOR_PREPARE_H_
|
||||
|
||||
Bool
|
||||
glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, int nseg,
|
||||
xSegment *seg)
|
||||
{
|
||||
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||
glamor_ddx_fallback_check_gc(gc)) {
|
||||
return FALSE;
|
||||
}
|
||||
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
|
||||
|
||||
miPolySegment(drawable, gc, nseg, seg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
Bool
|
||||
glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
void
|
||||
glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg,
|
||||
xSegment *seg)
|
||||
{
|
||||
miPolySegment(drawable, gc, nseg, seg);
|
||||
}
|
||||
glamor_finish_access(DrawablePtr drawable);
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
void
|
||||
glamor_finish_access_picture(PicturePtr picture);
|
||||
|
||||
Bool
|
||||
glamor_prepare_access_gc(GCPtr gc);
|
||||
|
||||
void
|
||||
glamor_finish_access_gc(GCPtr gc);
|
||||
|
||||
#endif /* _GLAMOR_PREPARE_H_ */
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <xorg-server.h>
|
||||
#include "glamor.h"
|
||||
#include "xvdix.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#if GLAMOR_HAS_GBM
|
||||
|
@ -193,13 +194,7 @@ struct glamor_saved_procs {
|
|||
#define GLAMOR_TICK_AFTER(t0, t1) \
|
||||
(((int)(t1) - (int)(t0)) < 0)
|
||||
|
||||
#define IDLE_STATE 0
|
||||
#define RENDER_STATE 1
|
||||
#define BLIT_STATE 2
|
||||
#define RENDER_IDEL_MAX 32
|
||||
|
||||
typedef struct glamor_screen_private {
|
||||
Bool yInverted;
|
||||
unsigned int tick;
|
||||
enum glamor_gl_flavor gl_flavor;
|
||||
int glsl_version;
|
||||
|
@ -208,16 +203,14 @@ typedef struct glamor_screen_private {
|
|||
int has_map_buffer_range;
|
||||
int has_buffer_storage;
|
||||
int has_khr_debug;
|
||||
int has_nv_texture_barrier;
|
||||
int max_fbo_size;
|
||||
int has_rw_pbo;
|
||||
|
||||
struct xorg_list
|
||||
fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
|
||||
unsigned long fbo_cache_watermark;
|
||||
|
||||
/* glamor_solid */
|
||||
GLint solid_prog;
|
||||
GLint solid_color_uniform_location;
|
||||
|
||||
/* glamor point shader */
|
||||
glamor_program point_prog;
|
||||
|
||||
|
@ -235,6 +228,20 @@ typedef struct glamor_screen_private {
|
|||
glamor_program te_text_prog;
|
||||
glamor_program image_text_prog;
|
||||
|
||||
/* glamor copy shaders */
|
||||
glamor_program copy_area_prog;
|
||||
glamor_program copy_plane_prog;
|
||||
|
||||
/* glamor line shader */
|
||||
glamor_program_fill poly_line_program;
|
||||
|
||||
/* glamor segment shaders */
|
||||
glamor_program_fill poly_segment_program;
|
||||
|
||||
/* glamor dash line shader */
|
||||
glamor_program_fill on_off_dash_line_progs;
|
||||
glamor_program double_dash_line_prog;
|
||||
|
||||
/* vertext/elment_index buffer object for render */
|
||||
GLuint vbo, ebo;
|
||||
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
|
||||
|
@ -261,10 +268,6 @@ typedef struct glamor_screen_private {
|
|||
GLint finish_access_revert[2];
|
||||
GLint finish_access_swap_rb[2];
|
||||
|
||||
/* glamor_tile */
|
||||
GLint tile_prog;
|
||||
GLint tile_wh;
|
||||
|
||||
/* glamor gradient, 0 for small nstops, 1 for
|
||||
large nstops and 2 for dynamic generate. */
|
||||
GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
|
||||
|
@ -280,8 +283,6 @@ typedef struct glamor_screen_private {
|
|||
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
|
||||
int delayed_fallback_pending;
|
||||
int flags;
|
||||
int state;
|
||||
unsigned int render_idle_cnt;
|
||||
ScreenPtr screen;
|
||||
int dri3_enabled;
|
||||
|
||||
|
@ -430,6 +431,9 @@ typedef struct glamor_pixmap_private_base {
|
|||
int drm_stride;
|
||||
glamor_screen_private *glamor_priv;
|
||||
PicturePtr picture;
|
||||
GLuint pbo;
|
||||
RegionRec prepare_region;
|
||||
Bool prepared;
|
||||
#if GLAMOR_HAS_GBM
|
||||
EGLImageKHR image;
|
||||
#endif
|
||||
|
@ -528,7 +532,7 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv)
|
|||
for (y = 0; y < glamor_pixmap_hcnt(priv); y++) \
|
||||
for (x = 0; x < glamor_pixmap_wcnt(priv); x++)
|
||||
|
||||
/*
|
||||
/*
|
||||
* Pixmap dynamic status, used by dynamic upload feature.
|
||||
*
|
||||
* GLAMOR_NONE: initial status, don't need to do anything.
|
||||
|
@ -544,19 +548,29 @@ typedef enum glamor_pixmap_status {
|
|||
GLAMOR_UPLOAD_FAILED
|
||||
} glamor_pixmap_status_t;
|
||||
|
||||
extern DevPrivateKey glamor_screen_private_key;
|
||||
extern DevPrivateKey glamor_pixmap_private_key;
|
||||
/* GC private structure. Currently holds only any computed dash pixmap */
|
||||
|
||||
typedef struct {
|
||||
PixmapPtr dash;
|
||||
PixmapPtr stipple;
|
||||
DamagePtr stipple_damage;
|
||||
} glamor_gc_private;
|
||||
|
||||
extern DevPrivateKeyRec glamor_gc_private_key;
|
||||
extern DevPrivateKeyRec glamor_screen_private_key;
|
||||
extern DevPrivateKeyRec glamor_pixmap_private_key;
|
||||
|
||||
static inline glamor_screen_private *
|
||||
glamor_get_screen_private(ScreenPtr screen)
|
||||
{
|
||||
return (glamor_screen_private *)
|
||||
dixLookupPrivate(&screen->devPrivates, glamor_screen_private_key);
|
||||
dixLookupPrivate(&screen->devPrivates, &glamor_screen_private_key);
|
||||
}
|
||||
|
||||
static inline void
|
||||
glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
|
||||
{
|
||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, priv);
|
||||
dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv);
|
||||
}
|
||||
|
||||
static inline glamor_pixmap_private *
|
||||
|
@ -564,17 +578,23 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
|
|||
{
|
||||
glamor_pixmap_private *priv;
|
||||
|
||||
priv = dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
|
||||
priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
|
||||
if (!priv) {
|
||||
glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
|
||||
priv = dixLookupPrivate(&pixmap->devPrivates,
|
||||
glamor_pixmap_private_key);
|
||||
&glamor_pixmap_private_key);
|
||||
}
|
||||
return priv;
|
||||
}
|
||||
|
||||
void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
|
||||
|
||||
static inline glamor_gc_private *
|
||||
glamor_get_gc_private(GCPtr gc)
|
||||
{
|
||||
return dixLookupPrivate(&gc->devPrivates, &glamor_gc_private_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the given planemask covers all the significant bits in the
|
||||
* pixel values for pDrawable.
|
||||
|
@ -614,32 +634,13 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
|
|||
int flag, int block_w, int block_h,
|
||||
glamor_pixmap_private *);
|
||||
|
||||
/* glamor_copyarea.c */
|
||||
RegionPtr
|
||||
|
||||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int width, int height, int dstx, int dsty);
|
||||
void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
BoxPtr box, int nbox, int dx, int dy, Bool reverse,
|
||||
Bool upsidedown, Pixel bitplane, void *closure);
|
||||
|
||||
/* glamor_core.c */
|
||||
Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
|
||||
void glamor_finish_access(DrawablePtr drawable);
|
||||
Bool glamor_prepare_access_window(WindowPtr window);
|
||||
void glamor_finish_access_window(WindowPtr window);
|
||||
Bool glamor_prepare_access_gc(GCPtr gc);
|
||||
void glamor_finish_access_gc(GCPtr gc);
|
||||
void glamor_init_finish_access_shaders(ScreenPtr screen);
|
||||
void glamor_fini_finish_access_shaders(ScreenPtr screen);
|
||||
|
||||
const Bool glamor_get_drawable_location(const DrawablePtr drawable);
|
||||
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
|
||||
int *x, int *y);
|
||||
Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
|
||||
int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
unsigned long fg_pixel, unsigned long bg_pixel,
|
||||
int stipple_x, int stipple_y);
|
||||
GLint glamor_compile_glsl_prog(GLenum type, const char *source);
|
||||
void glamor_link_glsl_prog(ScreenPtr screen, GLint prog,
|
||||
const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
|
||||
|
@ -651,7 +652,7 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
|
|||
void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
|
||||
|
||||
/* nc means no check. caller must ensure this pixmap has valid fbo.
|
||||
* usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
|
||||
* usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
|
||||
* */
|
||||
void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
|
||||
|
||||
|
@ -665,17 +666,8 @@ Bool glamor_set_alu(ScreenPtr screen, unsigned char alu);
|
|||
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
|
||||
RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
|
||||
|
||||
/* glamor_fill.c */
|
||||
Bool glamor_fill(DrawablePtr drawable,
|
||||
GCPtr gc, int x, int y, int width, int height, Bool fallback);
|
||||
Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
unsigned long fg_pixel);
|
||||
Bool glamor_solid_boxes(PixmapPtr pixmap,
|
||||
BoxPtr box, int nbox, unsigned long fg_pixel);
|
||||
|
||||
void glamor_init_solid_shader(ScreenPtr screen);
|
||||
void glamor_fini_solid_shader(ScreenPtr screen);
|
||||
void
|
||||
glamor_track_stipple(GCPtr gc);
|
||||
|
||||
/* glamor_glyphs.c */
|
||||
Bool glamor_realize_glyph_caches(ScreenPtr screen);
|
||||
|
@ -687,10 +679,6 @@ void glamor_glyphs(CARD8 op,
|
|||
INT16 xSrc,
|
||||
INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
|
||||
|
||||
/* glamor_polylines.c */
|
||||
void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
||||
DDXPointPtr points);
|
||||
|
||||
/* glamor_render.c */
|
||||
Bool glamor_composite_clipped_region(CARD8 op,
|
||||
PicturePtr source,
|
||||
|
@ -756,14 +744,6 @@ void glamor_trapezoids(CARD8 op,
|
|||
PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
|
||||
int ntrap, xTrapezoid *traps);
|
||||
|
||||
/* glamor_tile.c */
|
||||
Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||
int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
int tile_x, int tile_y);
|
||||
void glamor_init_tile_shader(ScreenPtr screen);
|
||||
void glamor_fini_tile_shader(ScreenPtr screen);
|
||||
|
||||
/* glamor_gradient.c */
|
||||
void glamor_init_gradient_shader(ScreenPtr screen);
|
||||
void glamor_fini_gradient_shader(ScreenPtr screen);
|
||||
|
@ -801,31 +781,6 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset);
|
|||
void
|
||||
glamor_put_vbo_space(ScreenPtr screen);
|
||||
|
||||
/**
|
||||
* Download a pixmap's texture to cpu memory. If success,
|
||||
* One copy of current pixmap's texture will be put into
|
||||
* the pixmap->devPrivate.ptr. Will use pbo to map to
|
||||
* the pointer if possible.
|
||||
* The pixmap must be a gl texture pixmap. gl_fbo must be GLAMOR_FBO_NORMAL and
|
||||
* gl_tex must be 1. Used by glamor_prepare_access.
|
||||
*
|
||||
*/
|
||||
Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
|
||||
|
||||
void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w,
|
||||
int h, int stride, void *bits, int pbo,
|
||||
glamor_access_t access);
|
||||
|
||||
/**
|
||||
* Restore a pixmap's data which is downloaded by
|
||||
* glamor_download_pixmap_to_cpu to its original
|
||||
* gl texture. Used by glamor_finish_access.
|
||||
*
|
||||
* The pixmap must originally be a texture -- gl_fbo must be
|
||||
* GLAMOR_FBO_NORMAL.
|
||||
**/
|
||||
void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
|
||||
|
||||
/**
|
||||
* According to the flag,
|
||||
* if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure
|
||||
|
@ -846,11 +801,6 @@ Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
|
|||
int h, int stride, void *bits,
|
||||
int pbo);
|
||||
|
||||
PixmapPtr glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
|
||||
int w, int h, glamor_access_t access);
|
||||
void glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
|
||||
int w, int h, glamor_access_t access);
|
||||
|
||||
glamor_pixmap_clipped_regions *
|
||||
glamor_compute_clipped_regions(glamor_pixmap_private *priv,
|
||||
RegionPtr region, int *clipped_nbox,
|
||||
|
@ -909,20 +859,10 @@ Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
|||
GLenum type, int no_alpha, int revert,
|
||||
int swap_rb, void *bits);
|
||||
|
||||
/**
|
||||
* Destroy all the resources allocated on the uploading
|
||||
* phase, includs the tex and fbo.
|
||||
**/
|
||||
void glamor_destroy_upload_pixmap(PixmapPtr pixmap);
|
||||
|
||||
int glamor_create_picture(PicturePtr picture);
|
||||
|
||||
void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
|
||||
|
||||
Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
|
||||
|
||||
void glamor_finish_access_picture(PicturePtr picture);
|
||||
|
||||
void glamor_destroy_picture(PicturePtr picture);
|
||||
|
||||
/* fixup a fbo to the exact size as the pixmap. */
|
||||
|
@ -935,11 +875,6 @@ void glamor_picture_format_fixup(PicturePtr picture,
|
|||
void glamor_add_traps(PicturePtr pPicture,
|
||||
INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
|
||||
|
||||
RegionPtr glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||
int srcx, int srcy, int w, int h,
|
||||
int dstx, int dsty,
|
||||
unsigned long bitPlane);
|
||||
|
||||
/* glamor_text.c */
|
||||
int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, int count, char *chars);
|
||||
|
@ -981,6 +916,48 @@ void
|
|||
glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
|
||||
unsigned int format, unsigned long planeMask, char *d);
|
||||
|
||||
/* glamor_dash.c */
|
||||
Bool
|
||||
glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points);
|
||||
|
||||
Bool
|
||||
glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs);
|
||||
|
||||
/* glamor_lines.c */
|
||||
void
|
||||
glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
|
||||
int mode, int n, DDXPointPtr points);
|
||||
|
||||
/* glamor_segs.c */
|
||||
void
|
||||
glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs);
|
||||
|
||||
/* glamor_copy.c */
|
||||
void
|
||||
glamor_copy(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse,
|
||||
Bool upsidedown,
|
||||
Pixel bitplane,
|
||||
void *closure);
|
||||
|
||||
RegionPtr
|
||||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int width, int height, int dstx, int dsty);
|
||||
|
||||
RegionPtr
|
||||
glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int width, int height, int dstx, int dsty,
|
||||
unsigned long bitplane);
|
||||
|
||||
/* glamor_glyphblt.c */
|
||||
void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
|
||||
int x, int y, unsigned int nglyph,
|
||||
|
@ -996,17 +973,21 @@ void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
|
|||
void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
||||
DDXPointPtr ppt);
|
||||
|
||||
void glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
|
||||
xSegment *pSeg);
|
||||
|
||||
void glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
||||
DDXPointPtr ppt);
|
||||
|
||||
void glamor_composite_rectangles(CARD8 op,
|
||||
PicturePtr dst,
|
||||
xRenderColor *color,
|
||||
int num_rects, xRectangle *rects);
|
||||
|
||||
/* glamor_util.c */
|
||||
void
|
||||
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned long fg_pixel);
|
||||
|
||||
void
|
||||
glamor_solid_boxes(PixmapPtr pixmap,
|
||||
BoxPtr box, int nbox, unsigned long fg_pixel);
|
||||
|
||||
|
||||
/* glamor_xv */
|
||||
typedef struct {
|
||||
uint32_t transform_index;
|
||||
|
@ -1028,15 +1009,41 @@ typedef struct {
|
|||
int src_pix_w, src_pix_h;
|
||||
} glamor_port_private;
|
||||
|
||||
void glamor_init_xv_shader(ScreenPtr screen);
|
||||
void glamor_fini_xv_shader(ScreenPtr screen);
|
||||
extern XvAttributeRec glamor_xv_attributes[];
|
||||
extern int glamor_xv_num_attributes;
|
||||
extern XvImageRec glamor_xv_images[];
|
||||
extern int glamor_xv_num_images;
|
||||
|
||||
void glamor_xv_init_port(glamor_port_private *port_priv);
|
||||
void glamor_xv_stop_video(glamor_port_private *port_priv);
|
||||
int glamor_xv_set_port_attribute(glamor_port_private *port_priv,
|
||||
Atom attribute, INT32 value);
|
||||
int glamor_xv_get_port_attribute(glamor_port_private *port_priv,
|
||||
Atom attribute, INT32 *value);
|
||||
int glamor_xv_query_image_attributes(int id,
|
||||
unsigned short *w, unsigned short *h,
|
||||
int *pitches, int *offsets);
|
||||
int glamor_xv_put_image(glamor_port_private *port_priv,
|
||||
DrawablePtr pDrawable,
|
||||
short src_x, short src_y,
|
||||
short drw_x, short drw_y,
|
||||
short src_w, short src_h,
|
||||
short drw_w, short drw_h,
|
||||
int id,
|
||||
unsigned char *buf,
|
||||
short width,
|
||||
short height,
|
||||
Bool sync,
|
||||
RegionPtr clipBoxes);
|
||||
void glamor_xv_core_init(ScreenPtr screen);
|
||||
void glamor_xv_render(glamor_port_private *port_priv);
|
||||
|
||||
#include"glamor_utils.h"
|
||||
|
||||
/* Dynamic pixmap upload to texture if needed.
|
||||
/* Dynamic pixmap upload to texture if needed.
|
||||
* Sometimes, the target is a gl texture pixmap/picture,
|
||||
* but the source or mask is in cpu memory. In that case,
|
||||
* upload the source/mask to gl texture and then avoid
|
||||
* upload the source/mask to gl texture and then avoid
|
||||
* fallback the whole process to cpu. Most of the time,
|
||||
* this will increase performance obviously. */
|
||||
|
||||
|
|
|
@ -51,42 +51,51 @@ static const glamor_facet glamor_fill_tile = {
|
|||
.use = use_tile,
|
||||
};
|
||||
|
||||
#if 0
|
||||
static Bool
|
||||
use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog)
|
||||
use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
|
||||
{
|
||||
return glamor_set_stippled(pixmap, gc, prog->fg_uniform, prog->fill_offset_uniform, prog->fill_size_uniform);
|
||||
return glamor_set_stippled(pixmap, gc, prog->fg_uniform,
|
||||
prog->fill_offset_uniform,
|
||||
prog->fill_size_uniform);
|
||||
}
|
||||
|
||||
static const glamor_facet glamor_fill_stipple = {
|
||||
.name = "stipple",
|
||||
.version = 130,
|
||||
.vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
|
||||
.fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
|
||||
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
|
||||
.fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
|
||||
" if (a == 0.0)\n"
|
||||
" discard;\n"
|
||||
" gl_FragColor = fg;\n")
|
||||
.locations = glamor_program_location_fg | glamor_program_location_fill
|
||||
" gl_FragColor = fg;\n"),
|
||||
.locations = glamor_program_location_fg | glamor_program_location_fill,
|
||||
.use = use_stipple,
|
||||
};
|
||||
|
||||
static Bool
|
||||
use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
|
||||
{
|
||||
if (!use_stipple(pixmap, gc, prog, arg))
|
||||
return FALSE;
|
||||
glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const glamor_facet glamor_fill_opaque_stipple = {
|
||||
.name = "opaque_stipple",
|
||||
.version = 130,
|
||||
.vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
|
||||
.fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
|
||||
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
|
||||
.fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
|
||||
" if (a == 0.0)\n"
|
||||
" gl_FragColor = bg;\n"
|
||||
" else\n"
|
||||
" gl_FragColor = fg;\n"),
|
||||
.locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill
|
||||
.locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill,
|
||||
.use = use_opaque_stipple
|
||||
};
|
||||
#endif
|
||||
|
||||
static const glamor_facet *glamor_facet_fill[4] = {
|
||||
&glamor_fill_solid,
|
||||
&glamor_fill_tile,
|
||||
NULL,
|
||||
NULL,
|
||||
&glamor_fill_stipple,
|
||||
&glamor_fill_opaque_stipple,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -117,6 +126,16 @@ static glamor_location_var location_vars[] = {
|
|||
.location = glamor_program_location_font,
|
||||
.fs_vars = "uniform usampler2D font;\n",
|
||||
},
|
||||
{
|
||||
.location = glamor_program_location_bitplane,
|
||||
.fs_vars = ("uniform uvec4 bitplane;\n"
|
||||
"uniform vec4 bitmul;\n"),
|
||||
},
|
||||
{
|
||||
.location = glamor_program_location_dash,
|
||||
.vs_vars = "uniform float dash_length;\n",
|
||||
.fs_vars = "uniform sampler2D dash;\n",
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0])
|
||||
|
@ -196,6 +215,8 @@ static const glamor_facet facet_null_fill = {
|
|||
.name = ""
|
||||
};
|
||||
|
||||
#define DBG 0
|
||||
|
||||
static GLint
|
||||
glamor_get_uniform(glamor_program *prog,
|
||||
glamor_program_location location,
|
||||
|
@ -281,7 +302,6 @@ glamor_build_program(ScreenPtr screen,
|
|||
if (!vs_prog_string || !fs_prog_string)
|
||||
goto fail;
|
||||
|
||||
#define DBG 0
|
||||
#if DBG
|
||||
ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s",
|
||||
prim->name, fill->name, vs_prog_string, fs_prog_string);
|
||||
|
@ -318,6 +338,10 @@ glamor_build_program(ScreenPtr screen,
|
|||
prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
|
||||
prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size");
|
||||
prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
|
||||
prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane");
|
||||
prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
|
||||
prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash");
|
||||
prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length");
|
||||
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
goto fail;
|
||||
|
|
|
@ -29,6 +29,8 @@ typedef enum {
|
|||
glamor_program_location_bg = 2,
|
||||
glamor_program_location_fill = 4,
|
||||
glamor_program_location_font = 8,
|
||||
glamor_program_location_bitplane = 16,
|
||||
glamor_program_location_dash = 32,
|
||||
} glamor_program_location;
|
||||
|
||||
typedef enum {
|
||||
|
@ -61,6 +63,10 @@ struct _glamor_program {
|
|||
GLint fill_size_uniform;
|
||||
GLint fill_offset_uniform;
|
||||
GLint font_uniform;
|
||||
GLint bitplane_uniform;
|
||||
GLint bitmul_uniform;
|
||||
GLint dash_uniform;
|
||||
GLint dash_length_uniform;
|
||||
glamor_program_location locations;
|
||||
glamor_program_flag flags;
|
||||
glamor_use prim_use;
|
||||
|
|
|
@ -651,11 +651,12 @@ glamor_composite_with_copy(CARD8 op,
|
|||
if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
|
||||
goto cleanup_region;
|
||||
}
|
||||
ret = glamor_copy_n_to_n_nf(source->pDrawable,
|
||||
dest->pDrawable, NULL,
|
||||
RegionRects(region), RegionNumRects(region),
|
||||
x_source - x_dest, y_source - y_dest,
|
||||
FALSE, FALSE, 0, NULL);
|
||||
glamor_copy(source->pDrawable,
|
||||
dest->pDrawable, NULL,
|
||||
RegionRects(region), RegionNumRects(region),
|
||||
x_source - x_dest, y_source - y_dest,
|
||||
FALSE, FALSE, 0, NULL);
|
||||
ret = TRUE;
|
||||
cleanup_region:
|
||||
return ret;
|
||||
}
|
||||
|
@ -792,30 +793,29 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
|
|||
float *matrix,
|
||||
float xscale, float yscale,
|
||||
int x1, int y1, int x2, int y2,
|
||||
int yInverted, float *texcoords,
|
||||
float *texcoords,
|
||||
int stride)
|
||||
{
|
||||
if (!matrix && repeat_type == RepeatNone)
|
||||
glamor_set_normalize_tcoords_ext(priv, xscale, yscale,
|
||||
x1, y1,
|
||||
x2, y2, yInverted, texcoords, stride);
|
||||
x2, y2, texcoords, stride);
|
||||
else if (matrix && repeat_type == RepeatNone)
|
||||
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,
|
||||
yscale, x1, y1,
|
||||
x2, y2,
|
||||
yInverted,
|
||||
texcoords, stride);
|
||||
else if (!matrix && repeat_type != RepeatNone)
|
||||
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
|
||||
xscale, yscale,
|
||||
x1, y1,
|
||||
x2, y2,
|
||||
yInverted, texcoords, stride);
|
||||
texcoords, stride);
|
||||
else if (matrix && repeat_type != RepeatNone)
|
||||
glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
|
||||
matrix, xscale,
|
||||
yscale, x1, y1, x2,
|
||||
y2, yInverted,
|
||||
y2,
|
||||
texcoords, stride);
|
||||
}
|
||||
|
||||
|
@ -1265,7 +1265,7 @@ glamor_composite_with_shader(CARD8 op,
|
|||
glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
|
||||
dst_yscale, x_dest, y_dest,
|
||||
x_dest + width, y_dest + height,
|
||||
glamor_priv->yInverted, vertices,
|
||||
vertices,
|
||||
vb_stride);
|
||||
vertices += 2;
|
||||
if (key.source != SHADER_SOURCE_SOLID) {
|
||||
|
@ -1275,7 +1275,6 @@ glamor_composite_with_shader(CARD8 op,
|
|||
src_yscale, x_source,
|
||||
y_source, x_source + width,
|
||||
y_source + height,
|
||||
glamor_priv->yInverted,
|
||||
vertices, vb_stride);
|
||||
vertices += 2;
|
||||
}
|
||||
|
@ -1287,7 +1286,6 @@ glamor_composite_with_shader(CARD8 op,
|
|||
mask_yscale, x_mask,
|
||||
y_mask, x_mask + width,
|
||||
y_mask + height,
|
||||
glamor_priv->yInverted,
|
||||
vertices, vb_stride);
|
||||
vertices += 2;
|
||||
}
|
||||
|
@ -1315,8 +1313,6 @@ glamor_composite_with_shader(CARD8 op,
|
|||
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
|
||||
glDisable(GL_BLEND);
|
||||
DEBUGF("finish rendering.\n");
|
||||
glamor_priv->state = RENDER_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
if (saved_source_format)
|
||||
source->format = saved_source_format;
|
||||
|
||||
|
@ -1586,15 +1582,6 @@ _glamor_composite(CARD8 op,
|
|||
RegionRec region;
|
||||
BoxPtr extent;
|
||||
int nbox, ok = FALSE;
|
||||
PixmapPtr sub_dest_pixmap = NULL;
|
||||
PixmapPtr sub_source_pixmap = NULL;
|
||||
PixmapPtr sub_mask_pixmap = NULL;
|
||||
int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
|
||||
int source_x_off, source_y_off, saved_source_x, saved_source_y;
|
||||
int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
|
||||
DrawablePtr saved_dest_drawable;
|
||||
DrawablePtr saved_source_drawable;
|
||||
DrawablePtr saved_mask_drawable;
|
||||
int force_clip = 0;
|
||||
|
||||
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
|
||||
|
@ -1737,34 +1724,13 @@ _glamor_composite(CARD8 op,
|
|||
dest->pDrawable->width, dest->pDrawable->height,
|
||||
glamor_get_picture_location(dest));
|
||||
|
||||
#define GET_SUB_PICTURE(p, access) do { \
|
||||
glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap, \
|
||||
& p ##_x_off, & p ##_y_off); \
|
||||
sub_ ##p ##_pixmap = glamor_get_sub_pixmap(p ##_pixmap, \
|
||||
x_ ##p + p ##_x_off + p->pDrawable->x, \
|
||||
y_ ##p + p ##_y_off + p->pDrawable->y, \
|
||||
width, height, access); \
|
||||
if (sub_ ##p ##_pixmap != NULL) { \
|
||||
saved_ ##p ##_drawable = p->pDrawable; \
|
||||
saved_ ##p ##_x = x_ ##p; \
|
||||
saved_ ##p ##_y = y_ ##p; \
|
||||
if (p->pCompositeClip) \
|
||||
pixman_region_translate (p->pCompositeClip, \
|
||||
-p->pDrawable->x - x_ ##p, \
|
||||
-p->pDrawable->y - y_ ##p); \
|
||||
p->pDrawable = &sub_ ##p ##_pixmap->drawable; \
|
||||
x_ ##p = 0; \
|
||||
y_ ##p = 0; \
|
||||
} } while(0)
|
||||
GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
||||
if (source->pDrawable && !source->transform)
|
||||
GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
||||
if (mask && mask->pDrawable && !mask->transform)
|
||||
GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
|
||||
|
||||
if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW) &&
|
||||
glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO) &&
|
||||
glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) {
|
||||
if (glamor_prepare_access_picture_box(dest, GLAMOR_ACCESS_RW,
|
||||
x_dest, y_dest, width, height) &&
|
||||
glamor_prepare_access_picture_box(source, GLAMOR_ACCESS_RO,
|
||||
x_source, y_source, width, height) &&
|
||||
glamor_prepare_access_picture_box(mask, GLAMOR_ACCESS_RO,
|
||||
x_mask, y_mask, width, height))
|
||||
{
|
||||
fbComposite(op,
|
||||
source, mask, dest,
|
||||
x_source, y_source,
|
||||
|
@ -1774,25 +1740,6 @@ _glamor_composite(CARD8 op,
|
|||
glamor_finish_access_picture(source);
|
||||
glamor_finish_access_picture(dest);
|
||||
|
||||
#define PUT_SUB_PICTURE(p, access) do { \
|
||||
if (sub_ ##p ##_pixmap != NULL) { \
|
||||
x_ ##p = saved_ ##p ##_x; \
|
||||
y_ ##p = saved_ ##p ##_y; \
|
||||
p->pDrawable = saved_ ##p ##_drawable; \
|
||||
if (p->pCompositeClip) \
|
||||
pixman_region_translate (p->pCompositeClip, \
|
||||
p->pDrawable->x + x_ ##p, \
|
||||
p->pDrawable->y + y_ ##p); \
|
||||
glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap, \
|
||||
x_ ##p + p ##_x_off + p->pDrawable->x, \
|
||||
y_ ##p + p ##_y_off + p->pDrawable->y, \
|
||||
width, height, access); \
|
||||
}} while(0)
|
||||
if (mask && mask->pDrawable)
|
||||
PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
|
||||
if (source->pDrawable)
|
||||
PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
||||
PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
|
188
glamor/glamor_segs.c
Normal file
188
glamor/glamor_segs.c
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* Copyright © 2014 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
#include "glamor_program.h"
|
||||
#include "glamor_transform.h"
|
||||
#include "glamor_prepare.h"
|
||||
|
||||
static const glamor_facet glamor_facet_poly_segment = {
|
||||
.name = "poly_segment",
|
||||
.vs_vars = "attribute vec2 primitive;\n",
|
||||
.vs_exec = (" vec2 pos = vec2(0.0,0.0);\n"
|
||||
GLAMOR_POS(gl_Position, primitive.xy)),
|
||||
};
|
||||
|
||||
static Bool
|
||||
glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs)
|
||||
{
|
||||
ScreenPtr screen = drawable->pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
glamor_program *prog;
|
||||
int off_x, off_y;
|
||||
xSegment *v;
|
||||
char *vbo_offset;
|
||||
int box_x, box_y;
|
||||
int add_last;
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||
goto bail;
|
||||
|
||||
add_last = 0;
|
||||
if (gc->capStyle != CapNotLast)
|
||||
add_last = 1;
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
prog = glamor_use_program_fill(pixmap, gc,
|
||||
&glamor_priv->poly_segment_program,
|
||||
&glamor_facet_poly_segment);
|
||||
|
||||
if (!prog)
|
||||
goto bail_ctx;
|
||||
|
||||
/* Set up the vertex buffers for the points */
|
||||
|
||||
v = glamor_get_vbo_space(drawable->pScreen,
|
||||
(nseg << add_last) * sizeof (xSegment),
|
||||
&vbo_offset);
|
||||
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
|
||||
sizeof(DDXPointRec), vbo_offset);
|
||||
|
||||
if (add_last) {
|
||||
int i, j;
|
||||
for (i = 0, j=0; i < nseg; i++) {
|
||||
v[j++] = segs[i];
|
||||
v[j].x1 = segs[i].x2;
|
||||
v[j].y1 = segs[i].y2;
|
||||
v[j].x2 = segs[i].x2+1;
|
||||
v[j].y2 = segs[i].y2;
|
||||
j++;
|
||||
}
|
||||
} else
|
||||
memcpy(v, segs, nseg * sizeof (xSegment));
|
||||
|
||||
glamor_put_vbo_space(screen);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||
int nbox = RegionNumRects(gc->pCompositeClip);
|
||||
BoxPtr box = RegionRects(gc->pCompositeClip);
|
||||
|
||||
glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
|
||||
prog->matrix_uniform, &off_x, &off_y);
|
||||
|
||||
while (nbox--) {
|
||||
glScissor(box->x1 + off_x,
|
||||
box->y1 + off_y,
|
||||
box->x2 - box->x1,
|
||||
box->y2 - box->y1);
|
||||
box++;
|
||||
glDrawArrays(GL_LINES, 0, nseg << (1 + add_last));
|
||||
}
|
||||
}
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
return TRUE;
|
||||
bail_ctx:
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
bail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs)
|
||||
{
|
||||
if (gc->lineWidth != 0)
|
||||
return FALSE;
|
||||
|
||||
switch (gc->lineStyle) {
|
||||
case LineSolid:
|
||||
return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs);
|
||||
case LineOnOffDash:
|
||||
return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs);
|
||||
case LineDoubleDash:
|
||||
if (gc->fillStyle == FillTiled)
|
||||
return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs);
|
||||
else
|
||||
return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs)
|
||||
{
|
||||
glamor_fallback("to %p (%c)\n", drawable,
|
||||
glamor_get_drawable_location(drawable));
|
||||
|
||||
if (gc->lineWidth == 0) {
|
||||
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
|
||||
glamor_prepare_access_gc(gc)) {
|
||||
fbPolySegment(drawable, gc, nseg, segs);
|
||||
}
|
||||
glamor_finish_access_gc(gc);
|
||||
glamor_finish_access(drawable);
|
||||
} else
|
||||
miPolySegment(drawable, gc, nseg, segs);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs)
|
||||
{
|
||||
if (glamor_poly_segment_gl(drawable, gc, nseg, segs))
|
||||
return;
|
||||
|
||||
glamor_poly_segment_bail(drawable, gc, nseg, segs);
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc,
|
||||
int nseg, xSegment *segs)
|
||||
{
|
||||
if (glamor_poly_segment_gl(drawable, gc, nseg, segs))
|
||||
return TRUE;
|
||||
|
||||
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||
glamor_ddx_fallback_check_gc(gc))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glamor_poly_segment_bail(drawable, gc, nseg, segs);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -326,9 +326,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
|
|||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
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_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||
|
|
|
@ -293,9 +293,6 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
|
|||
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
|
||||
glamor_priv->state = RENDER_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
|
||||
*final_pos = x;
|
||||
return TRUE;
|
||||
|
||||
|
@ -493,9 +490,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
|
|||
(void) glamor_text(drawable, gc, glamor_font, prog,
|
||||
x, y, count, chars, charinfo, sixteen);
|
||||
|
||||
glamor_priv->state = RENDER_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
|
||||
return TRUE;
|
||||
|
||||
bail:
|
||||
|
|
|
@ -1,293 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* 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
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Anholt <eric@anholt.net>
|
||||
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
/** @file glamor_tile.c
|
||||
*
|
||||
* Implements the basic fill-with-a-tile support used by multiple GC ops.
|
||||
*/
|
||||
|
||||
void
|
||||
glamor_init_tile_shader(ScreenPtr screen)
|
||||
{
|
||||
glamor_screen_private *glamor_priv;
|
||||
const char *tile_vs =
|
||||
"attribute vec4 v_position;\n"
|
||||
"attribute vec4 v_texcoord0;\n"
|
||||
"varying vec2 tile_texture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = v_position;\n"
|
||||
" tile_texture = v_texcoord0.xy;\n"
|
||||
"}\n";
|
||||
const char *tile_fs =
|
||||
GLAMOR_DEFAULT_PRECISION
|
||||
"varying vec2 tile_texture;\n"
|
||||
"uniform sampler2D sampler;\n"
|
||||
"uniform vec2 wh;"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 rel_tex;"
|
||||
" rel_tex = tile_texture * wh; \n"
|
||||
" rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
|
||||
" gl_FragColor = texture2D(sampler, rel_tex);\n"
|
||||
"}\n";
|
||||
GLint fs_prog, vs_prog;
|
||||
GLint sampler_uniform_location;
|
||||
|
||||
glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_make_current(glamor_priv);
|
||||
glamor_priv->tile_prog = glCreateProgram();
|
||||
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
|
||||
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
|
||||
glAttachShader(glamor_priv->tile_prog, vs_prog);
|
||||
glAttachShader(glamor_priv->tile_prog, fs_prog);
|
||||
|
||||
glBindAttribLocation(glamor_priv->tile_prog,
|
||||
GLAMOR_VERTEX_POS, "v_position");
|
||||
glBindAttribLocation(glamor_priv->tile_prog,
|
||||
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
|
||||
glamor_link_glsl_prog(screen, glamor_priv->tile_prog, "tile");
|
||||
|
||||
sampler_uniform_location =
|
||||
glGetUniformLocation(glamor_priv->tile_prog, "sampler");
|
||||
glUseProgram(glamor_priv->tile_prog);
|
||||
glUniform1i(sampler_uniform_location, 0);
|
||||
|
||||
glamor_priv->tile_wh =
|
||||
glGetUniformLocation(glamor_priv->tile_prog, "wh");
|
||||
}
|
||||
|
||||
void
|
||||
glamor_fini_tile_shader(ScreenPtr screen)
|
||||
{
|
||||
glamor_screen_private *glamor_priv;
|
||||
|
||||
glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_make_current(glamor_priv);
|
||||
glDeleteProgram(glamor_priv->tile_prog);
|
||||
}
|
||||
|
||||
static void
|
||||
_glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||
int x, int y, int width, int height, int tile_x, int tile_y)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
int x1 = x;
|
||||
int x2 = x + width;
|
||||
int y1 = y;
|
||||
int y2 = y + height;
|
||||
int tile_x1 = tile_x;
|
||||
int tile_x2 = tile_x + width;
|
||||
int tile_y1 = tile_y;
|
||||
int tile_y2 = tile_y + height;
|
||||
float vertices[8];
|
||||
float source_texcoords[8];
|
||||
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
||||
glamor_pixmap_private *src_pixmap_priv;
|
||||
glamor_pixmap_private *dst_pixmap_priv;
|
||||
float wh[4];
|
||||
|
||||
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
|
||||
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
||||
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
||||
glamor_make_current(glamor_priv);
|
||||
glUseProgram(glamor_priv->tile_prog);
|
||||
|
||||
glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
|
||||
glUniform2fv(glamor_priv->tile_wh, 1, wh);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glamor_set_repeat_normalize_tcoords
|
||||
(src_pixmap_priv, RepeatNormal,
|
||||
src_xscale, src_yscale,
|
||||
tile_x1, tile_y1,
|
||||
tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords);
|
||||
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), source_texcoords);
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||
|
||||
glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
|
||||
x1, y1,
|
||||
x2, y2, glamor_priv->yInverted, vertices);
|
||||
|
||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), vertices);
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
glamor_priv->state = RENDER_STATE;
|
||||
glamor_priv->render_idle_cnt = 0;
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||
int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask, int tile_x, int tile_y)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
glamor_pixmap_private *dst_pixmap_priv;
|
||||
glamor_pixmap_private *src_pixmap_priv;
|
||||
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
|
||||
return FALSE;
|
||||
|
||||
if (glamor_priv->tile_prog == 0) {
|
||||
glamor_fallback("Tiling unsupported\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
||||
/* XXX dynamic uploading candidate. */
|
||||
glamor_fallback("Non-texture tile pixmap\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!glamor_set_planemask(pixmap, planemask)) {
|
||||
glamor_fallback("unsupported planemask %lx\n", planemask);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
if (!glamor_set_alu(screen, alu)) {
|
||||
glamor_fallback("unsupported alu %x\n", alu);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
||||
|| src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||
glamor_pixmap_clipped_regions *clipped_dst_regions;
|
||||
int n_dst_region, i, j, k;
|
||||
BoxRec box;
|
||||
RegionRec region;
|
||||
|
||||
box.x1 = x;
|
||||
box.y1 = y;
|
||||
box.x2 = x + width;
|
||||
box.y2 = y + height;
|
||||
RegionInitBoxes(®ion, &box, 1);
|
||||
clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
|
||||
®ion,
|
||||
&n_dst_region, 0,
|
||||
0, 0);
|
||||
for (i = 0; i < n_dst_region; i++) {
|
||||
int n_src_region;
|
||||
glamor_pixmap_clipped_regions *clipped_src_regions;
|
||||
BoxPtr current_boxes;
|
||||
int n_current_boxes;
|
||||
|
||||
SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv,
|
||||
clipped_dst_regions[i].block_idx);
|
||||
|
||||
if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||
RegionTranslate(clipped_dst_regions[i].region,
|
||||
tile_x - x, tile_y - y);
|
||||
DEBUGF("tiled a large src pixmap. %dx%d \n",
|
||||
tile->drawable.width, tile->drawable.height);
|
||||
clipped_src_regions =
|
||||
glamor_compute_clipped_regions(src_pixmap_priv,
|
||||
clipped_dst_regions[i].
|
||||
region, &n_src_region, 1, 0,
|
||||
0);
|
||||
DEBUGF("got %d src regions %d \n", n_src_region);
|
||||
for (j = 0; j < n_src_region; j++) {
|
||||
|
||||
SET_PIXMAP_FBO_CURRENT(src_pixmap_priv,
|
||||
clipped_src_regions[j].block_idx);
|
||||
|
||||
RegionTranslate(clipped_src_regions[j].region,
|
||||
x - tile_x, y - tile_y);
|
||||
current_boxes = RegionRects(clipped_src_regions[j].region);
|
||||
n_current_boxes =
|
||||
RegionNumRects(clipped_src_regions[j].region);
|
||||
for (k = 0; k < n_current_boxes; k++) {
|
||||
DEBUGF
|
||||
("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n",
|
||||
current_boxes[k].x1, current_boxes[k].y1,
|
||||
current_boxes[k].x2 - current_boxes[k].x1,
|
||||
current_boxes[k].y2 - current_boxes[k].y1,
|
||||
clipped_dst_regions[i].block_idx,
|
||||
clipped_src_regions[j].block_idx,
|
||||
(tile_x + (current_boxes[k].x1 - x)),
|
||||
tile_y + (current_boxes[k].y1 - y));
|
||||
|
||||
_glamor_tile(pixmap, tile,
|
||||
current_boxes[k].x1, current_boxes[k].y1,
|
||||
current_boxes[k].x2 - current_boxes[k].x1,
|
||||
current_boxes[k].y2 - current_boxes[k].y1,
|
||||
(tile_x + (current_boxes[k].x1 - x)),
|
||||
(tile_y + (current_boxes[k].y1 - y)));
|
||||
}
|
||||
|
||||
RegionDestroy(clipped_src_regions[j].region);
|
||||
}
|
||||
free(clipped_src_regions);
|
||||
}
|
||||
else {
|
||||
current_boxes = RegionRects(clipped_dst_regions[i].region);
|
||||
n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
|
||||
for (k = 0; k < n_current_boxes; k++) {
|
||||
_glamor_tile(pixmap, tile,
|
||||
current_boxes[k].x1, current_boxes[k].y1,
|
||||
current_boxes[k].x2 - current_boxes[k].x1,
|
||||
current_boxes[k].y2 - current_boxes[k].y1,
|
||||
(tile_x + (current_boxes[k].x1 - x)),
|
||||
(tile_y + (current_boxes[k].y1 - y)));
|
||||
}
|
||||
}
|
||||
RegionDestroy(clipped_dst_regions[i].region);
|
||||
}
|
||||
free(clipped_dst_regions);
|
||||
RegionUninit(®ion);
|
||||
}
|
||||
else
|
||||
_glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
|
||||
|
||||
glamor_set_alu(screen, GXcopy);
|
||||
return TRUE;
|
||||
fail:
|
||||
return FALSE;
|
||||
|
||||
}
|
|
@ -72,9 +72,6 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
|||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
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);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
|
||||
|
||||
|
@ -90,27 +87,14 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
|||
while (nbox--) {
|
||||
|
||||
/* compute drawable coordinates */
|
||||
int x1 = boxes->x1 + dx_dst;
|
||||
int x2 = boxes->x2 + dx_dst;
|
||||
int y1 = boxes->y1 + dy_dst;
|
||||
int y2 = boxes->y2 + dy_dst;
|
||||
int x1 = MAX(boxes->x1 + dx_dst, box->x1);
|
||||
int x2 = MIN(boxes->x2 + dx_dst, box->x2);
|
||||
int y1 = MAX(boxes->y1 + dy_dst, box->y1);
|
||||
int y2 = MIN(boxes->y2 + dy_dst, box->y2);
|
||||
|
||||
boxes++;
|
||||
|
||||
if (x1 < box->x1)
|
||||
x1 = box->x1;
|
||||
if (box->x2 < x2)
|
||||
x2 = box->x2;
|
||||
|
||||
if (x2 <= x1)
|
||||
continue;
|
||||
|
||||
if (y1 < box->y1)
|
||||
y1 = box->y1;
|
||||
if (box->y2 < y2)
|
||||
y2 = box->y2;
|
||||
|
||||
if (y2 <= y1)
|
||||
if (x2 <= x1 || y2 <= y1)
|
||||
continue;
|
||||
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src);
|
||||
|
@ -195,26 +179,14 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
|||
while (nbox--) {
|
||||
|
||||
/* compute drawable coordinates */
|
||||
int x1 = boxes->x1 + dx_src;
|
||||
int x2 = boxes->x2 + dx_src;
|
||||
int y1 = boxes->y1 + dy_src;
|
||||
int y2 = boxes->y2 + dy_src;
|
||||
int x1 = MAX(boxes->x1 + dx_src, box->x1);
|
||||
int x2 = MIN(boxes->x2 + dx_src, box->x2);
|
||||
int y1 = MAX(boxes->y1 + dy_src, box->y1);
|
||||
int y2 = MIN(boxes->y2 + dy_src, box->y2);
|
||||
|
||||
boxes++;
|
||||
|
||||
if (x1 < box->x1)
|
||||
x1 = box->x1;
|
||||
if (box->x2 < x2)
|
||||
x2 = box->x2;
|
||||
|
||||
if (y1 < box->y1)
|
||||
y1 = box->y1;
|
||||
if (box->y2 < y2)
|
||||
y2 = box->y2;
|
||||
|
||||
if (x2 <= x1)
|
||||
continue;
|
||||
if (y2 <= y1)
|
||||
if (x2 <= x1 || y2 <= y1)
|
||||
continue;
|
||||
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
|
||||
|
|
|
@ -198,6 +198,64 @@ glamor_set_tiled(PixmapPtr pixmap,
|
|||
size_uniform);
|
||||
}
|
||||
|
||||
static PixmapPtr
|
||||
glamor_get_stipple_pixmap(GCPtr gc)
|
||||
{
|
||||
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||
ScreenPtr screen = gc->pScreen;
|
||||
PixmapPtr bitmap;
|
||||
PixmapPtr pixmap;
|
||||
GCPtr scratch_gc;
|
||||
ChangeGCVal changes[2];
|
||||
|
||||
if (gc_priv->stipple)
|
||||
return gc_priv->stipple;
|
||||
|
||||
bitmap = gc->stipple;
|
||||
if (!bitmap)
|
||||
goto bail;
|
||||
|
||||
pixmap = glamor_create_pixmap(screen,
|
||||
bitmap->drawable.width,
|
||||
bitmap->drawable.height,
|
||||
8, GLAMOR_CREATE_NO_LARGE);
|
||||
if (!pixmap)
|
||||
goto bail;
|
||||
|
||||
scratch_gc = GetScratchGC(8, screen);
|
||||
if (!scratch_gc)
|
||||
goto bail_pixmap;
|
||||
|
||||
changes[0].val = 0xff;
|
||||
changes[1].val = 0x00;
|
||||
if (ChangeGC(NullClient, scratch_gc,
|
||||
GCForeground|GCBackground, changes) != Success)
|
||||
goto bail_gc;
|
||||
ValidateGC(&pixmap->drawable, scratch_gc);
|
||||
|
||||
(*scratch_gc->ops->CopyPlane)(&bitmap->drawable,
|
||||
&pixmap->drawable,
|
||||
scratch_gc,
|
||||
0, 0,
|
||||
bitmap->drawable.width,
|
||||
bitmap->drawable.height,
|
||||
0, 0, 0x1);
|
||||
|
||||
FreeScratchGC(scratch_gc);
|
||||
gc_priv->stipple = pixmap;
|
||||
|
||||
glamor_track_stipple(gc);
|
||||
|
||||
return pixmap;
|
||||
|
||||
bail_gc:
|
||||
FreeScratchGC(scratch_gc);
|
||||
bail_pixmap:
|
||||
glamor_destroy_pixmap(pixmap);
|
||||
bail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_set_stippled(PixmapPtr pixmap,
|
||||
GCPtr gc,
|
||||
|
@ -205,11 +263,19 @@ glamor_set_stippled(PixmapPtr pixmap,
|
|||
GLint offset_uniform,
|
||||
GLint size_uniform)
|
||||
{
|
||||
PixmapPtr stipple;
|
||||
|
||||
stipple = glamor_get_stipple_pixmap(gc);
|
||||
if (!stipple)
|
||||
return FALSE;
|
||||
|
||||
if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
|
||||
return FALSE;
|
||||
|
||||
if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return glamor_set_texture(pixmap,
|
||||
stipple,
|
||||
-gc->patOrg.x,
|
||||
-gc->patOrg.y,
|
||||
offset_uniform,
|
||||
size_uniform);
|
||||
}
|
||||
|
|
|
@ -908,7 +908,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
|
|||
clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1];
|
||||
glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale,
|
||||
clipped_vtx_tmp,
|
||||
glamor_priv->yInverted,
|
||||
vertices);
|
||||
DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
|
||||
"(%f X %f)\n", vertices[0], vertices[1],
|
||||
|
@ -920,14 +919,12 @@ _glamor_trapezoids_with_shader(CARD8 op,
|
|||
glamor_set_transformed_normalize_tri_tcoords
|
||||
(source_pixmap_priv, src_matrix, src_xscale,
|
||||
src_yscale, clipped_vtx_tmp,
|
||||
glamor_priv->yInverted, source_texcoords);
|
||||
source_texcoords);
|
||||
}
|
||||
else {
|
||||
glamor_set_normalize_tri_tcoords(src_xscale,
|
||||
src_yscale,
|
||||
clipped_vtx_tmp,
|
||||
glamor_priv->
|
||||
yInverted,
|
||||
source_texcoords);
|
||||
}
|
||||
|
||||
|
@ -1392,12 +1389,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
|||
}
|
||||
|
||||
/* First, clear all to zero */
|
||||
if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
|
||||
pixmap_priv->base.pixmap->drawable.height,
|
||||
GXclear, 0xFFFFFFFF, 0)) {
|
||||
DEBUGF("glamor_solid failed, fallback\n");
|
||||
return FALSE;
|
||||
}
|
||||
glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
|
||||
pixmap_priv->base.pixmap->drawable.height, 0);
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
|
@ -1443,11 +1436,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
|||
miTrapezoidBounds(1, ptrap, &one_trap_bound);
|
||||
|
||||
vertices += 2;
|
||||
glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
|
||||
(pixmap_priv->base.pixmap->drawable.height),
|
||||
(one_trap_bound.x1), (one_trap_bound.y1),
|
||||
glamor_set_tcoords_ext((one_trap_bound.x1), (one_trap_bound.y1),
|
||||
(one_trap_bound.x2), (one_trap_bound.y2),
|
||||
glamor_priv->yInverted, vertices, stride);
|
||||
vertices, stride);
|
||||
DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
|
||||
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
|
||||
vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
|
||||
|
@ -1467,8 +1458,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
|||
one_trap_bound.y1,
|
||||
one_trap_bound.x2,
|
||||
one_trap_bound.y2,
|
||||
glamor_priv->yInverted, vertices,
|
||||
stride);
|
||||
vertices, stride);
|
||||
DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
|
||||
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
|
||||
vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
|
||||
|
|
79
glamor/glamor_utils.c
Normal file
79
glamor/glamor_utils.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright © 2014 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
void
|
||||
glamor_solid_boxes(PixmapPtr pixmap,
|
||||
BoxPtr box, int nbox, unsigned long fg_pixel)
|
||||
{
|
||||
DrawablePtr drawable = &pixmap->drawable;
|
||||
GCPtr gc;
|
||||
xRectangle *rect;
|
||||
int n;
|
||||
|
||||
rect = malloc(nbox * sizeof (xRectangle));
|
||||
if (!rect)
|
||||
return;
|
||||
for (n = 0; n < nbox; n++) {
|
||||
rect[n].x = box[n].x1;
|
||||
rect[n].y = box[n].y1;
|
||||
rect[n].width = box[n].x2 - box[n].x1;
|
||||
rect[n].height = box[n].y2 - box[n].y1;
|
||||
}
|
||||
|
||||
gc = GetScratchGC(drawable->depth, drawable->pScreen);
|
||||
if (gc) {
|
||||
ChangeGCVal vals[1];
|
||||
|
||||
vals[0].val = fg_pixel;
|
||||
ChangeGC(NullClient, gc, GCForeground, vals);
|
||||
ValidateGC(drawable, gc);
|
||||
gc->ops->PolyFillRect(drawable, gc, nbox, rect);
|
||||
FreeScratchGC(gc);
|
||||
}
|
||||
free(rect);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned long fg_pixel)
|
||||
{
|
||||
DrawablePtr drawable = &pixmap->drawable;
|
||||
GCPtr gc;
|
||||
ChangeGCVal vals[1];
|
||||
xRectangle rect;
|
||||
|
||||
vals[0].val = fg_pixel;
|
||||
gc = GetScratchGC(drawable->depth, drawable->pScreen);
|
||||
if (!gc)
|
||||
return;
|
||||
ChangeGC(NullClient, gc, GCForeground, vals);
|
||||
ValidateGC(drawable, gc);
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
gc->ops->PolyFillRect(drawable, gc, 1, &rect);
|
||||
FreeScratchGC(gc);
|
||||
}
|
||||
|
|
@ -32,6 +32,8 @@
|
|||
#ifndef __GLAMOR_UTILS_H__
|
||||
#define __GLAMOR_UTILS_H__
|
||||
|
||||
#include "glamor_prepare.h"
|
||||
|
||||
#define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0)
|
||||
#define v_from_x_coord_y(_yscale_, _y_) (-2 * (_y_) * (_yscale_) + 1.0)
|
||||
#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
|
||||
|
@ -311,21 +313,17 @@
|
|||
} while(0)
|
||||
|
||||
#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \
|
||||
texcoord, yInverted) \
|
||||
texcoord) \
|
||||
do { \
|
||||
(texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \
|
||||
if (_X_LIKELY(yInverted)) \
|
||||
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\
|
||||
else \
|
||||
(texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \
|
||||
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \
|
||||
DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \
|
||||
(texcoord)[1]); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_transformed_point(priv, matrix, xscale, \
|
||||
yscale, texcoord, \
|
||||
x, y, \
|
||||
yInverted) \
|
||||
x, y) \
|
||||
do { \
|
||||
float tx, ty; \
|
||||
int fbo_x_off, fbo_y_off; \
|
||||
|
@ -337,10 +335,7 @@
|
|||
tx += fbo_x_off; \
|
||||
ty += fbo_y_off; \
|
||||
(texcoord)[0] = t_from_x_coord_x(xscale, tx); \
|
||||
if (_X_LIKELY(yInverted)) \
|
||||
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
|
||||
else \
|
||||
(texcoord)[1] = t_from_x_coord_y(yscale, ty); \
|
||||
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
|
||||
DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \
|
||||
} while(0)
|
||||
|
||||
|
@ -349,18 +344,14 @@
|
|||
xscale, \
|
||||
yscale, \
|
||||
vtx, \
|
||||
yInverted, \
|
||||
texcoords) \
|
||||
do { \
|
||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||
texcoords, (vtx)[0], (vtx)[1], \
|
||||
yInverted); \
|
||||
texcoords, (vtx)[0], (vtx)[1]); \
|
||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||
texcoords+2, (vtx)[2], (vtx)[3], \
|
||||
yInverted); \
|
||||
texcoords+2, (vtx)[2], (vtx)[3]); \
|
||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||
texcoords+4, (vtx)[4], (vtx)[5], \
|
||||
yInverted); \
|
||||
texcoords+4, (vtx)[4], (vtx)[5]); \
|
||||
} while (0)
|
||||
|
||||
#define glamor_set_transformed_normalize_tcoords_ext( priv, \
|
||||
|
@ -368,21 +359,17 @@
|
|||
xscale, \
|
||||
yscale, \
|
||||
tx1, ty1, tx2, ty2, \
|
||||
yInverted, texcoords, \
|
||||
texcoords, \
|
||||
stride) \
|
||||
do { \
|
||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||
texcoords, tx1, ty1, \
|
||||
yInverted); \
|
||||
texcoords, tx1, ty1); \
|
||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||
texcoords + 1 * stride, tx2, ty1, \
|
||||
yInverted); \
|
||||
texcoords + 1 * stride, tx2, ty1); \
|
||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||
texcoords + 2 * stride, tx2, ty2, \
|
||||
yInverted); \
|
||||
texcoords + 2 * stride, tx2, ty2); \
|
||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||
texcoords + 3 * stride, tx1, ty2, \
|
||||
yInverted); \
|
||||
texcoords + 3 * stride, tx1, ty2); \
|
||||
} while (0)
|
||||
|
||||
#define glamor_set_transformed_normalize_tcoords( priv, \
|
||||
|
@ -390,35 +377,31 @@
|
|||
xscale, \
|
||||
yscale, \
|
||||
tx1, ty1, tx2, ty2, \
|
||||
yInverted, texcoords) \
|
||||
texcoords) \
|
||||
do { \
|
||||
glamor_set_transformed_normalize_tcoords_ext( priv, \
|
||||
matrix, \
|
||||
xscale, \
|
||||
yscale, \
|
||||
tx1, ty1, tx2, ty2, \
|
||||
yInverted, texcoords, \
|
||||
texcoords, \
|
||||
2); \
|
||||
} while (0)
|
||||
|
||||
#define glamor_set_normalize_tri_tcoords(xscale, \
|
||||
yscale, \
|
||||
vtx, \
|
||||
yInverted, \
|
||||
texcoords) \
|
||||
do { \
|
||||
_glamor_set_normalize_tpoint(xscale, yscale, \
|
||||
(vtx)[0], (vtx)[1], \
|
||||
texcoords, \
|
||||
yInverted); \
|
||||
texcoords); \
|
||||
_glamor_set_normalize_tpoint(xscale, yscale, \
|
||||
(vtx)[2], (vtx)[3], \
|
||||
texcoords+2, \
|
||||
yInverted); \
|
||||
texcoords+2); \
|
||||
_glamor_set_normalize_tpoint(xscale, yscale, \
|
||||
(vtx)[4], (vtx)[5], \
|
||||
texcoords+4, \
|
||||
yInverted); \
|
||||
texcoords+4); \
|
||||
} while (0)
|
||||
|
||||
#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
|
||||
|
@ -428,14 +411,13 @@
|
|||
yscale, \
|
||||
_x1_, _y1_, \
|
||||
_x2_, _y2_, \
|
||||
yInverted, \
|
||||
texcoords, \
|
||||
stride) \
|
||||
do { \
|
||||
if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \
|
||||
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \
|
||||
yscale, _x1_, _y1_, \
|
||||
_x2_, _y2_, yInverted, \
|
||||
_x2_, _y2_, \
|
||||
texcoords, stride); \
|
||||
} else { \
|
||||
float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \
|
||||
|
@ -462,13 +444,13 @@
|
|||
DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \
|
||||
ttx2, tty2, ttx3, tty3, ttx4, tty4); \
|
||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \
|
||||
texcoords, yInverted); \
|
||||
texcoords); \
|
||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \
|
||||
texcoords + 1 * stride, yInverted); \
|
||||
texcoords + 1 * stride); \
|
||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \
|
||||
texcoords + 2 * stride, yInverted); \
|
||||
texcoords + 2 * stride); \
|
||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \
|
||||
texcoords + 3 * stride, yInverted); \
|
||||
texcoords + 3 * stride); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -479,7 +461,6 @@
|
|||
yscale, \
|
||||
_x1_, _y1_, \
|
||||
_x2_, _y2_, \
|
||||
yInverted, \
|
||||
texcoords) \
|
||||
do { \
|
||||
glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
|
||||
|
@ -489,14 +470,13 @@
|
|||
yscale, \
|
||||
_x1_, _y1_, \
|
||||
_x2_, _y2_, \
|
||||
yInverted, \
|
||||
texcoords, \
|
||||
2); \
|
||||
} while (0)
|
||||
|
||||
#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
|
||||
ty1, tx2, ty2, \
|
||||
yInverted, vertices, stride) \
|
||||
vertices, stride) \
|
||||
do { \
|
||||
/* vertices may be write-only, so we use following \
|
||||
* temporary variable. */ \
|
||||
|
@ -505,21 +485,15 @@
|
|||
(vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \
|
||||
(vertices)[2 * stride] = _t2_; \
|
||||
(vertices)[3 * stride] = _t0_; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \
|
||||
(vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\
|
||||
} \
|
||||
else { \
|
||||
(vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \
|
||||
(vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);\
|
||||
} \
|
||||
(vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \
|
||||
(vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \
|
||||
(vertices)[1 * stride + 1] = _t1_; \
|
||||
(vertices)[3 * stride + 1] = _t5_; \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices, stride) \
|
||||
vertices, stride) \
|
||||
do { \
|
||||
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
|
||||
float tx1, tx2, ty1, ty2; \
|
||||
|
@ -530,26 +504,26 @@
|
|||
ty1 = y1 + fbo_y_off; \
|
||||
ty2 = y2 + fbo_y_off; \
|
||||
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
||||
tx2, ty2, yInverted, vertices, \
|
||||
tx2, ty2, vertices, \
|
||||
stride); \
|
||||
} else \
|
||||
_glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \
|
||||
x2, y2, yInverted, vertices, stride);\
|
||||
x2, y2, vertices, stride); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_tcoords(priv, xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices) \
|
||||
vertices) \
|
||||
do { \
|
||||
glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices, 2); \
|
||||
vertices, 2); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
|
||||
xscale, yscale, \
|
||||
_x1_, _y1_, _x2_, _y2_, \
|
||||
yInverted, vertices, stride)\
|
||||
vertices, stride) \
|
||||
do { \
|
||||
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
|
||||
float tx1, tx2, ty1, ty2; \
|
||||
|
@ -564,130 +538,99 @@
|
|||
_x1_, _y1_, _x2_, _y2_); \
|
||||
} \
|
||||
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
||||
tx2, ty2, yInverted, vertices, \
|
||||
tx2, ty2, vertices, \
|
||||
stride); \
|
||||
} else \
|
||||
_glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \
|
||||
_x2_, _y2_, yInverted, vertices, \
|
||||
_x2_, _y2_, vertices, \
|
||||
stride); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
|
||||
xscale, yscale, \
|
||||
_x1_, _y1_, _x2_, _y2_, \
|
||||
yInverted, vertices) \
|
||||
vertices) \
|
||||
do { \
|
||||
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
|
||||
xscale, yscale, \
|
||||
_x1_, _y1_, _x2_, _y2_, \
|
||||
yInverted, vertices, 2); \
|
||||
vertices, 2); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices) \
|
||||
vertices) \
|
||||
do { \
|
||||
(vertices)[0] = t_from_x_coord_x(xscale, x1); \
|
||||
(vertices)[2] = t_from_x_coord_x(xscale, x2); \
|
||||
(vertices)[6] = (vertices)[2]; \
|
||||
(vertices)[4] = (vertices)[0]; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
|
||||
(vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \
|
||||
} \
|
||||
else { \
|
||||
(vertices)[1] = t_from_x_coord_y(yscale, y1); \
|
||||
(vertices)[7] = t_from_x_coord_y(yscale, y2); \
|
||||
} \
|
||||
(vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
|
||||
(vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \
|
||||
(vertices)[3] = (vertices)[1]; \
|
||||
(vertices)[5] = (vertices)[7]; \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \
|
||||
yInverted, vertices) \
|
||||
#define glamor_set_tcoords(x1, y1, x2, y2, vertices) \
|
||||
do { \
|
||||
(vertices)[0] = (x1); \
|
||||
(vertices)[2] = (x2); \
|
||||
(vertices)[4] = (vertices)[2]; \
|
||||
(vertices)[6] = (vertices)[0]; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = (y1); \
|
||||
(vertices)[5] = (y2); \
|
||||
} \
|
||||
else { \
|
||||
(vertices)[1] = height - (y2); \
|
||||
(vertices)[5] = height - (y1); \
|
||||
} \
|
||||
(vertices)[1] = (y1); \
|
||||
(vertices)[5] = (y2); \
|
||||
(vertices)[3] = (vertices)[1]; \
|
||||
(vertices)[7] = (vertices)[5]; \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_tcoords_ext(width, height, x1, y1, x2, y2, \
|
||||
yInverted, vertices, stride) \
|
||||
#define glamor_set_tcoords_ext(x1, y1, x2, y2, vertices, stride) \
|
||||
do { \
|
||||
(vertices)[0] = (x1); \
|
||||
(vertices)[1*stride] = (x2); \
|
||||
(vertices)[2*stride] = (vertices)[1*stride]; \
|
||||
(vertices)[3*stride] = (vertices)[0]; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = (y1); \
|
||||
(vertices)[2*stride + 1] = (y2); \
|
||||
} \
|
||||
else { \
|
||||
(vertices)[1] = height - (y2); \
|
||||
(vertices)[2*stride + 1] = height - (y1); \
|
||||
} \
|
||||
(vertices)[1] = (y1); \
|
||||
(vertices)[2*stride + 1] = (y2); \
|
||||
(vertices)[1*stride + 1] = (vertices)[1]; \
|
||||
(vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \
|
||||
yInverted, vertices) \
|
||||
vertices) \
|
||||
do { \
|
||||
(vertices)[0] = v_from_x_coord_x(xscale, x); \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
|
||||
} else { \
|
||||
(vertices)[1] = v_from_x_coord_y(yscale, y); \
|
||||
} \
|
||||
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \
|
||||
yInverted, vertices) \
|
||||
vertices) \
|
||||
do { \
|
||||
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
||||
(vtx)[0], (vtx)[1], \
|
||||
yInverted, vertices); \
|
||||
vertices); \
|
||||
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
||||
(vtx)[2], (vtx)[3], \
|
||||
yInverted, vertices+2); \
|
||||
vertices+2); \
|
||||
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
||||
(vtx)[4], (vtx)[5], \
|
||||
yInverted, vertices+4); \
|
||||
vertices+4); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2, \
|
||||
yInverted, vertices) \
|
||||
#define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \
|
||||
do { \
|
||||
(vertices)[0] = (x1); \
|
||||
(vertices)[2] = (x2); \
|
||||
(vertices)[6] = (vertices)[2]; \
|
||||
(vertices)[4] = (vertices)[0]; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = (y1); \
|
||||
(vertices)[7] = (y2); \
|
||||
} \
|
||||
else { \
|
||||
(vertices)[1] = height - (y2); \
|
||||
(vertices)[7] = height - (y1); \
|
||||
} \
|
||||
(vertices)[1] = (y1); \
|
||||
(vertices)[7] = (y2); \
|
||||
(vertices)[3] = (vertices)[1]; \
|
||||
(vertices)[5] = (vertices)[7]; \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices, stride) \
|
||||
vertices, stride) \
|
||||
do { \
|
||||
int fbo_x_off, fbo_y_off; \
|
||||
/* vertices may be write-only, so we use following \
|
||||
|
@ -699,29 +642,22 @@
|
|||
x2 + fbo_x_off); \
|
||||
(vertices)[2 * stride] = _t2_; \
|
||||
(vertices)[3 * stride] = _t0_; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \
|
||||
y1 + fbo_y_off); \
|
||||
(vertices)[2 * stride + 1] = _t5_ = \
|
||||
v_from_x_coord_y_inverted(yscale, \
|
||||
y2 + fbo_y_off); \
|
||||
} \
|
||||
else { \
|
||||
(vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \
|
||||
(vertices)[2 * stride + 1] = _t5_ = v_from_x_coord_y(yscale, \
|
||||
y2 + fbo_y_off); \
|
||||
} \
|
||||
(vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \
|
||||
y1 + fbo_y_off); \
|
||||
(vertices)[2 * stride + 1] = _t5_ = \
|
||||
v_from_x_coord_y_inverted(yscale, \
|
||||
y2 + fbo_y_off); \
|
||||
(vertices)[1 * stride + 1] = _t1_; \
|
||||
(vertices)[3 * stride + 1] = _t5_; \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_vcoords(priv, xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices) \
|
||||
vertices) \
|
||||
do { \
|
||||
glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices, 2); \
|
||||
vertices, 2); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \
|
||||
|
@ -736,44 +672,30 @@
|
|||
|
||||
#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \
|
||||
x1, y1, x2, y2, \
|
||||
yInverted, vertices) \
|
||||
vertices) \
|
||||
do { \
|
||||
(vertices)[0] = v_from_x_coord_x(xscale, x1); \
|
||||
(vertices)[2] = v_from_x_coord_x(xscale, x2); \
|
||||
(vertices)[6] = (vertices)[2]; \
|
||||
(vertices)[4] = (vertices)[0]; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
|
||||
(vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \
|
||||
} \
|
||||
else { \
|
||||
(vertices)[1] = v_from_x_coord_y(yscale, y1); \
|
||||
(vertices)[7] = v_from_x_coord_y(yscale, y2); \
|
||||
} \
|
||||
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
|
||||
(vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \
|
||||
(vertices)[3] = (vertices)[1]; \
|
||||
(vertices)[5] = (vertices)[7]; \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_normalize_pt(xscale, yscale, x, y, \
|
||||
yInverted, pt) \
|
||||
pt) \
|
||||
do { \
|
||||
(pt)[0] = t_from_x_coord_x(xscale, x); \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
|
||||
} else { \
|
||||
(pt)[1] = t_from_x_coord_y(yscale, y); \
|
||||
} \
|
||||
(pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
|
||||
} while(0)
|
||||
|
||||
#define glamor_set_circle_centre(width, height, x, y, \
|
||||
yInverted, c) \
|
||||
c) \
|
||||
do { \
|
||||
(c)[0] = (float)x; \
|
||||
if (_X_LIKELY(yInverted)) { \
|
||||
(c)[1] = (float)y; \
|
||||
} else { \
|
||||
(c)[1] = (float)height - (float)y; \
|
||||
} \
|
||||
(c)[1] = (float)y; \
|
||||
} while(0)
|
||||
|
||||
inline static void
|
||||
|
|
|
@ -36,12 +36,10 @@
|
|||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "xf86xv.h"
|
||||
#define GLAMOR_FOR_XORG
|
||||
#include "glamor_priv.h"
|
||||
|
||||
#include <X11/extensions/Xv.h>
|
||||
#include "fourcc.h"
|
||||
#include "../hw/xfree86/common/fourcc.h"
|
||||
/* Reference color space transform data */
|
||||
typedef struct tagREF_TRANSFORM {
|
||||
float RefLuma;
|
||||
|
@ -90,7 +88,28 @@ static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
|
|||
"gl_FragColor = temp1;\n"
|
||||
"}\n";
|
||||
|
||||
void
|
||||
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
|
||||
|
||||
XvAttributeRec glamor_xv_attributes[] = {
|
||||
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_BRIGHTNESS"},
|
||||
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_CONTRAST"},
|
||||
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_SATURATION"},
|
||||
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_HUE"},
|
||||
{XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE"},
|
||||
{0, 0, 0, NULL}
|
||||
};
|
||||
int glamor_xv_num_attributes = ARRAY_SIZE(glamor_xv_attributes) - 1;
|
||||
|
||||
Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue,
|
||||
glamorColorspace, glamorGamma;
|
||||
|
||||
XvImageRec glamor_xv_images[] = {
|
||||
XVIMAGE_YV12,
|
||||
XVIMAGE_I420,
|
||||
};
|
||||
int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
|
||||
|
||||
static void
|
||||
glamor_init_xv_shader(ScreenPtr screen)
|
||||
{
|
||||
glamor_screen_private *glamor_priv;
|
||||
|
@ -113,43 +132,12 @@ glamor_init_xv_shader(ScreenPtr screen)
|
|||
}
|
||||
|
||||
#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
|
||||
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
|
||||
|
||||
static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace,
|
||||
xvGamma;
|
||||
|
||||
#define NUM_ATTRIBUTES 5
|
||||
static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES + 1] = {
|
||||
{XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
|
||||
{XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
|
||||
{XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
|
||||
{XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
|
||||
{XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
|
||||
{0, 0, 0, NULL}
|
||||
};
|
||||
|
||||
#define NUM_FORMATS 3
|
||||
|
||||
static XF86VideoFormatRec Formats[NUM_FORMATS] = {
|
||||
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
|
||||
};
|
||||
|
||||
#define NUM_IMAGES 2
|
||||
|
||||
static XF86ImageRec Images[NUM_IMAGES] = {
|
||||
XVIMAGE_YV12,
|
||||
XVIMAGE_I420,
|
||||
};
|
||||
|
||||
static void
|
||||
glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
|
||||
void
|
||||
glamor_xv_stop_video(glamor_port_private *port_priv)
|
||||
{
|
||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
||||
int i;
|
||||
|
||||
if (!cleanup)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (port_priv->src_pix[i]) {
|
||||
glamor_destroy_pixmap(port_priv->src_pix[i]);
|
||||
|
@ -158,46 +146,42 @@ glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xv_set_port_attribute(ScrnInfoPtr pScrn,
|
||||
Atom attribute, INT32 value, void *data)
|
||||
int
|
||||
glamor_xv_set_port_attribute(glamor_port_private *port_priv,
|
||||
Atom attribute, INT32 value)
|
||||
{
|
||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
||||
|
||||
if (attribute == xvBrightness)
|
||||
if (attribute == glamorBrightness)
|
||||
port_priv->brightness = ClipValue(value, -1000, 1000);
|
||||
else if (attribute == xvHue)
|
||||
else if (attribute == glamorHue)
|
||||
port_priv->hue = ClipValue(value, -1000, 1000);
|
||||
else if (attribute == xvContrast)
|
||||
else if (attribute == glamorContrast)
|
||||
port_priv->contrast = ClipValue(value, -1000, 1000);
|
||||
else if (attribute == xvSaturation)
|
||||
else if (attribute == glamorSaturation)
|
||||
port_priv->saturation = ClipValue(value, -1000, 1000);
|
||||
else if (attribute == xvGamma)
|
||||
else if (attribute == glamorGamma)
|
||||
port_priv->gamma = ClipValue(value, 100, 10000);
|
||||
else if (attribute == xvColorspace)
|
||||
else if (attribute == glamorColorspace)
|
||||
port_priv->transform_index = ClipValue(value, 0, 1);
|
||||
else
|
||||
return BadMatch;
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
|
||||
Atom attribute, INT32 *value, void *data)
|
||||
int
|
||||
glamor_xv_get_port_attribute(glamor_port_private *port_priv,
|
||||
Atom attribute, INT32 *value)
|
||||
{
|
||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
||||
|
||||
if (attribute == xvBrightness)
|
||||
if (attribute == glamorBrightness)
|
||||
*value = port_priv->brightness;
|
||||
else if (attribute == xvHue)
|
||||
else if (attribute == glamorHue)
|
||||
*value = port_priv->hue;
|
||||
else if (attribute == xvContrast)
|
||||
else if (attribute == glamorContrast)
|
||||
*value = port_priv->contrast;
|
||||
else if (attribute == xvSaturation)
|
||||
else if (attribute == glamorSaturation)
|
||||
*value = port_priv->saturation;
|
||||
else if (attribute == xvGamma)
|
||||
else if (attribute == glamorGamma)
|
||||
*value = port_priv->gamma;
|
||||
else if (attribute == xvColorspace)
|
||||
else if (attribute == glamorColorspace)
|
||||
*value = port_priv->transform_index;
|
||||
else
|
||||
return BadMatch;
|
||||
|
@ -205,20 +189,8 @@ glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
|
|||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
glamor_xv_query_best_size(ScrnInfoPtr pScrn,
|
||||
Bool motion,
|
||||
short vid_w, short vid_h,
|
||||
short drw_w, short drw_h,
|
||||
unsigned int *p_w, unsigned int *p_h, void *data)
|
||||
{
|
||||
*p_w = drw_w;
|
||||
*p_h = drw_h;
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xv_query_image_attributes(ScrnInfoPtr pScrn,
|
||||
int id,
|
||||
int
|
||||
glamor_xv_query_image_attributes(int id,
|
||||
unsigned short *w, unsigned short *h,
|
||||
int *pitches, int *offsets)
|
||||
{
|
||||
|
@ -258,8 +230,8 @@ static REF_TRANSFORM trans[2] = {
|
|||
{1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */
|
||||
};
|
||||
|
||||
static void
|
||||
glamor_display_textured_video(glamor_port_private *port_priv)
|
||||
void
|
||||
glamor_xv_render(glamor_port_private *port_priv)
|
||||
{
|
||||
ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
|
@ -282,6 +254,9 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
|||
int ref = port_priv->transform_index;
|
||||
GLint uloc, sampler_loc;
|
||||
|
||||
if (!glamor_priv->xv_prog)
|
||||
glamor_init_xv_shader(screen);
|
||||
|
||||
cont = RTFContrast(port_priv->contrast);
|
||||
bright = RTFBrightness(port_priv->brightness);
|
||||
gamma = (float) port_priv->gamma / 1000.0;
|
||||
|
@ -385,7 +360,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
|||
dsty,
|
||||
dstx + dstw,
|
||||
dsty + dsth,
|
||||
glamor_priv->yInverted, vertices);
|
||||
vertices);
|
||||
|
||||
glamor_set_normalize_tcoords(src_pixmap_priv[0],
|
||||
src_xscale[0],
|
||||
|
@ -394,7 +369,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
|||
srcy,
|
||||
srcx + srcw,
|
||||
srcy + srch,
|
||||
glamor_priv->yInverted, texcoords);
|
||||
texcoords);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
@ -405,8 +380,9 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
|||
DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xv_put_image(ScrnInfoPtr pScrn,
|
||||
int
|
||||
glamor_xv_put_image(glamor_port_private *port_priv,
|
||||
DrawablePtr pDrawable,
|
||||
short src_x, short src_y,
|
||||
short drw_x, short drw_y,
|
||||
short src_w, short src_h,
|
||||
|
@ -416,35 +392,15 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
|||
short width,
|
||||
short height,
|
||||
Bool sync,
|
||||
RegionPtr clipBoxes, void *data, DrawablePtr pDrawable)
|
||||
RegionPtr clipBoxes)
|
||||
{
|
||||
ScreenPtr screen = pDrawable->pScreen;
|
||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
||||
INT32 x1, x2, y1, y2;
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
int srcPitch, srcPitch2;
|
||||
BoxRec dstBox;
|
||||
int top, nlines;
|
||||
int s2offset, s3offset, tmp;
|
||||
|
||||
s2offset = s3offset = srcPitch2 = 0;
|
||||
|
||||
/* Clip */
|
||||
x1 = src_x;
|
||||
x2 = src_x + src_w;
|
||||
y1 = src_y;
|
||||
y2 = src_y + src_h;
|
||||
|
||||
dstBox.x1 = drw_x;
|
||||
dstBox.x2 = drw_x + drw_w;
|
||||
dstBox.y1 = drw_y;
|
||||
dstBox.y2 = drw_y + drw_h;
|
||||
if (!xf86XVClipVideoHelper
|
||||
(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
|
||||
return Success;
|
||||
|
||||
if ((x1 >= x2) || (y1 >= y2))
|
||||
return Success;
|
||||
|
||||
srcPitch = width;
|
||||
srcPitch2 = width >> 1;
|
||||
|
||||
|
@ -457,11 +413,11 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
|||
glamor_destroy_pixmap(port_priv->src_pix[i]);
|
||||
|
||||
port_priv->src_pix[0] =
|
||||
glamor_create_pixmap(screen, width, height, 8, 0);
|
||||
glamor_create_pixmap(pScreen, width, height, 8, 0);
|
||||
port_priv->src_pix[1] =
|
||||
glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
|
||||
glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0);
|
||||
port_priv->src_pix[2] =
|
||||
glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
|
||||
glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0);
|
||||
port_priv->src_pix_w = width;
|
||||
port_priv->src_pix_h = height;
|
||||
|
||||
|
@ -470,8 +426,8 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
|||
return BadAlloc;
|
||||
}
|
||||
|
||||
top = (y1 >> 16) & ~1;
|
||||
nlines = ((y2 + 0xffff) >> 16) - top;
|
||||
top = (src_y) & ~1;
|
||||
nlines = (src_y + height) - top;
|
||||
|
||||
switch (id) {
|
||||
case FOURCC_YV12:
|
||||
|
@ -505,7 +461,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
|||
}
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW)
|
||||
port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable);
|
||||
port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable);
|
||||
else
|
||||
port_priv->pPixmap = (PixmapPtr) pDrawable;
|
||||
|
||||
|
@ -524,83 +480,30 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
|||
port_priv->w = width;
|
||||
port_priv->h = height;
|
||||
port_priv->pDraw = pDrawable;
|
||||
glamor_display_textured_video(port_priv);
|
||||
glamor_xv_render(port_priv);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
|
||||
{
|
||||
0,
|
||||
"XV_IMAGE",
|
||||
8192, 8192,
|
||||
{1, 1}
|
||||
}
|
||||
};
|
||||
|
||||
XF86VideoAdaptorPtr
|
||||
glamor_xv_init(ScreenPtr screen, int num_texture_ports)
|
||||
void
|
||||
glamor_xv_init_port(glamor_port_private *port_priv)
|
||||
{
|
||||
glamor_port_private *port_priv;
|
||||
XF86VideoAdaptorPtr adapt;
|
||||
int i;
|
||||
port_priv->brightness = 0;
|
||||
port_priv->contrast = 0;
|
||||
port_priv->saturation = 0;
|
||||
port_priv->hue = 0;
|
||||
port_priv->gamma = 1000;
|
||||
port_priv->transform_index = 0;
|
||||
|
||||
glamor_init_xv_shader(screen);
|
||||
|
||||
adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
|
||||
(sizeof(glamor_port_private) + sizeof(DevUnion)));
|
||||
if (adapt == NULL)
|
||||
return NULL;
|
||||
|
||||
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
|
||||
xvContrast = MAKE_ATOM("XV_CONTRAST");
|
||||
xvSaturation = MAKE_ATOM("XV_SATURATION");
|
||||
xvHue = MAKE_ATOM("XV_HUE");
|
||||
xvGamma = MAKE_ATOM("XV_GAMMA");
|
||||
xvColorspace = MAKE_ATOM("XV_COLORSPACE");
|
||||
|
||||
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
|
||||
adapt->flags = 0;
|
||||
adapt->name = "GLAMOR Textured Video";
|
||||
adapt->nEncodings = 1;
|
||||
adapt->pEncodings = DummyEncodingGLAMOR;
|
||||
|
||||
adapt->nFormats = NUM_FORMATS;
|
||||
adapt->pFormats = Formats;
|
||||
adapt->nPorts = num_texture_ports;
|
||||
adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
|
||||
|
||||
adapt->pAttributes = Attributes_glamor;
|
||||
adapt->nAttributes = NUM_ATTRIBUTES;
|
||||
|
||||
port_priv =
|
||||
(glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]);
|
||||
adapt->pImages = Images;
|
||||
adapt->nImages = NUM_IMAGES;
|
||||
adapt->PutVideo = NULL;
|
||||
adapt->PutStill = NULL;
|
||||
adapt->GetVideo = NULL;
|
||||
adapt->GetStill = NULL;
|
||||
adapt->StopVideo = glamor_xv_stop_video;
|
||||
adapt->SetPortAttribute = glamor_xv_set_port_attribute;
|
||||
adapt->GetPortAttribute = glamor_xv_get_port_attribute;
|
||||
adapt->QueryBestSize = glamor_xv_query_best_size;
|
||||
adapt->PutImage = glamor_xv_put_image;
|
||||
adapt->ReputImage = NULL;
|
||||
adapt->QueryImageAttributes = glamor_xv_query_image_attributes;
|
||||
|
||||
for (i = 0; i < num_texture_ports; i++) {
|
||||
glamor_port_private *pPriv = &port_priv[i];
|
||||
|
||||
pPriv->brightness = 0;
|
||||
pPriv->contrast = 0;
|
||||
pPriv->saturation = 0;
|
||||
pPriv->hue = 0;
|
||||
pPriv->gamma = 1000;
|
||||
pPriv->transform_index = 0;
|
||||
|
||||
REGION_NULL(pScreen, &pPriv->clip);
|
||||
|
||||
adapt->pPortPrivates[i].ptr = (void *) (pPriv);
|
||||
}
|
||||
return adapt;
|
||||
REGION_NULL(pScreen, &port_priv->clip);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_xv_core_init(ScreenPtr screen)
|
||||
{
|
||||
glamorBrightness = MAKE_ATOM("XV_BRIGHTNESS");
|
||||
glamorContrast = MAKE_ATOM("XV_CONTRAST");
|
||||
glamorSaturation = MAKE_ATOM("XV_SATURATION");
|
||||
glamorHue = MAKE_ATOM("XV_HUE");
|
||||
glamorGamma = MAKE_ATOM("XV_GAMMA");
|
||||
glamorColorspace = MAKE_ATOM("XV_COLORSPACE");
|
||||
}
|
||||
|
|
|
@ -35,9 +35,14 @@ XV_SRCS = ephyrvideo.c
|
|||
endif
|
||||
|
||||
if GLAMOR
|
||||
if XV
|
||||
GLAMOR_XV_SRCS = ephyr_glamor_xv.c
|
||||
endif
|
||||
|
||||
GLAMOR_SRCS = \
|
||||
ephyr_glamor_glx.c \
|
||||
ephyr_glamor_glx.h \
|
||||
$(GLAMOR_XV_SRCS) \
|
||||
$()
|
||||
endif
|
||||
|
||||
|
|
|
@ -650,7 +650,9 @@ ephyrInitScreen(ScreenPtr pScreen)
|
|||
|
||||
#ifdef XV
|
||||
if (!ephyrNoXV) {
|
||||
if (!ephyrInitVideo(pScreen)) {
|
||||
if (ephyr_glamor)
|
||||
ephyr_glamor_xv_init(pScreen);
|
||||
else if (!ephyrInitVideo(pScreen)) {
|
||||
EPHYR_LOG_ERROR("failed to initialize xvideo\n");
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -224,4 +224,14 @@ void ephyr_glamor_host_paint_rect(ScreenPtr pScreen);
|
|||
|
||||
Bool ephyrInitVideo(ScreenPtr pScreen);
|
||||
|
||||
/* ephyr_glamor_xv.c */
|
||||
#ifdef GLAMOR
|
||||
void ephyr_glamor_xv_init(ScreenPtr screen);
|
||||
#else /* !GLAMOR */
|
||||
static inline void
|
||||
ephyr_glamor_xv_init(ScreenPtr screen)
|
||||
{
|
||||
}
|
||||
#endif /* !GLAMOR */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
static Display *dpy;
|
||||
static XVisualInfo *visual_info;
|
||||
static GLXFBConfig fb_config;
|
||||
Bool ephyr_glamor_gles2;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -145,6 +146,10 @@ ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor)
|
|||
"}\n";
|
||||
|
||||
const char *fs_source =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision mediump float;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"varying vec2 t;\n"
|
||||
"uniform sampler2D s; /* initially 0 */\n"
|
||||
"\n"
|
||||
|
@ -276,7 +281,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
|
|||
|
||||
glx_win = glXCreateWindow(dpy, fb_config, win, NULL);
|
||||
|
||||
ctx = glXCreateContext(dpy, visual_info, NULL, True);
|
||||
if (ephyr_glamor_gles2) {
|
||||
static const int context_attribs[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT,
|
||||
0,
|
||||
};
|
||||
if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy),
|
||||
"GLX_EXT_create_context_es2_profile")) {
|
||||
ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
|
||||
context_attribs);
|
||||
} else {
|
||||
FatalError("Xephyr -glamor_gles2 rquires "
|
||||
"GLX_EXT_create_context_es2_profile\n");
|
||||
}
|
||||
} else {
|
||||
ctx = glXCreateContext(dpy, visual_info, NULL, True);
|
||||
}
|
||||
if (ctx == NULL)
|
||||
FatalError("glXCreateContext failed\n");
|
||||
|
||||
|
|
161
hw/kdrive/ephyr/ephyr_glamor_xv.c
Normal file
161
hw/kdrive/ephyr/ephyr_glamor_xv.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* 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
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
#include "kdrive.h"
|
||||
#include "kxv.h"
|
||||
#include "ephyr.h"
|
||||
#include "glamor_priv.h"
|
||||
|
||||
#include <X11/extensions/Xv.h>
|
||||
#include "fourcc.h"
|
||||
|
||||
#define NUM_FORMATS 3
|
||||
|
||||
static KdVideoFormatRec Formats[NUM_FORMATS] = {
|
||||
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
|
||||
};
|
||||
|
||||
static void
|
||||
ephyr_glamor_xv_stop_video(KdScreenInfo *screen, void *data, Bool cleanup)
|
||||
{
|
||||
if (!cleanup)
|
||||
return;
|
||||
|
||||
glamor_xv_stop_video(data);
|
||||
}
|
||||
|
||||
static int
|
||||
ephyr_glamor_xv_set_port_attribute(KdScreenInfo *screen,
|
||||
Atom attribute, INT32 value, void *data)
|
||||
{
|
||||
return glamor_xv_set_port_attribute(data, attribute, value);
|
||||
}
|
||||
|
||||
static int
|
||||
ephyr_glamor_xv_get_port_attribute(KdScreenInfo *screen,
|
||||
Atom attribute, INT32 *value, void *data)
|
||||
{
|
||||
return glamor_xv_get_port_attribute(data, attribute, value);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyr_glamor_xv_query_best_size(KdScreenInfo *screen,
|
||||
Bool motion,
|
||||
short vid_w, short vid_h,
|
||||
short drw_w, short drw_h,
|
||||
unsigned int *p_w, unsigned int *p_h,
|
||||
void *data)
|
||||
{
|
||||
*p_w = drw_w;
|
||||
*p_h = drw_h;
|
||||
}
|
||||
|
||||
static int
|
||||
ephyr_glamor_xv_query_image_attributes(KdScreenInfo *screen,
|
||||
int id,
|
||||
unsigned short *w, unsigned short *h,
|
||||
int *pitches, int *offsets)
|
||||
{
|
||||
return glamor_xv_query_image_attributes(id, w, h, pitches, offsets);
|
||||
}
|
||||
|
||||
static int
|
||||
ephyr_glamor_xv_put_image(KdScreenInfo *screen,
|
||||
DrawablePtr pDrawable,
|
||||
short src_x, short src_y,
|
||||
short drw_x, short drw_y,
|
||||
short src_w, short src_h,
|
||||
short drw_w, short drw_h,
|
||||
int id,
|
||||
unsigned char *buf,
|
||||
short width,
|
||||
short height,
|
||||
Bool sync,
|
||||
RegionPtr clipBoxes, void *data)
|
||||
{
|
||||
return glamor_xv_put_image(data, pDrawable,
|
||||
src_x, src_y,
|
||||
drw_x, drw_y,
|
||||
src_w, src_h,
|
||||
drw_w, drw_h,
|
||||
id, buf, width, height, sync, clipBoxes);
|
||||
}
|
||||
|
||||
void
|
||||
ephyr_glamor_xv_init(ScreenPtr screen)
|
||||
{
|
||||
KdVideoAdaptorRec *adaptor;
|
||||
glamor_port_private *port_privates;
|
||||
KdVideoEncodingRec encoding = {
|
||||
0,
|
||||
"XV_IMAGE",
|
||||
/* These sizes should probably be GL_MAX_TEXTURE_SIZE instead
|
||||
* of 2048, but our context isn't set up yet.
|
||||
*/
|
||||
2048, 2048,
|
||||
{1, 1}
|
||||
};
|
||||
int i;
|
||||
|
||||
glamor_xv_core_init(screen);
|
||||
|
||||
adaptor = xnfcalloc(1, sizeof(*adaptor));
|
||||
|
||||
adaptor->name = "glamor textured video";
|
||||
adaptor->type = XvWindowMask | XvInputMask | XvImageMask;
|
||||
adaptor->flags = 0;
|
||||
adaptor->nEncodings = 1;
|
||||
adaptor->pEncodings = &encoding;
|
||||
|
||||
adaptor->pFormats = Formats;
|
||||
adaptor->nFormats = NUM_FORMATS;
|
||||
|
||||
adaptor->nPorts = 16; /* Some absurd number */
|
||||
port_privates = xnfcalloc(adaptor->nPorts,
|
||||
sizeof(glamor_port_private));
|
||||
adaptor->pPortPrivates = xnfcalloc(adaptor->nPorts,
|
||||
sizeof(glamor_port_private *));
|
||||
for (i = 0; i < adaptor->nPorts; i++) {
|
||||
adaptor->pPortPrivates[i].ptr = &port_privates[i];
|
||||
glamor_xv_init_port(&port_privates[i]);
|
||||
}
|
||||
|
||||
adaptor->pAttributes = glamor_xv_attributes;
|
||||
adaptor->nAttributes = glamor_xv_num_attributes;
|
||||
|
||||
adaptor->pImages = glamor_xv_images;
|
||||
adaptor->nImages = glamor_xv_num_images;
|
||||
|
||||
adaptor->StopVideo = ephyr_glamor_xv_stop_video;
|
||||
adaptor->SetPortAttribute = ephyr_glamor_xv_set_port_attribute;
|
||||
adaptor->GetPortAttribute = ephyr_glamor_xv_get_port_attribute;
|
||||
adaptor->QueryBestSize = ephyr_glamor_xv_query_best_size;
|
||||
adaptor->PutImage = ephyr_glamor_xv_put_image;
|
||||
adaptor->QueryImageAttributes = ephyr_glamor_xv_query_image_attributes;
|
||||
|
||||
KdXVScreenInit(screen, adaptor, 1);
|
||||
}
|
|
@ -35,7 +35,7 @@ extern Bool EphyrWantGrayScale;
|
|||
extern Bool EphyrWantResize;
|
||||
extern Bool kdHasPointer;
|
||||
extern Bool kdHasKbd;
|
||||
extern Bool ephyr_glamor;
|
||||
extern Bool ephyr_glamor, ephyr_glamor_gles2;
|
||||
|
||||
#ifdef GLXEXT
|
||||
extern Bool ephyrNoDRI;
|
||||
|
@ -138,6 +138,7 @@ ddxUseMsg(void)
|
|||
ErrorF("-resizeable Make Xephyr windows resizeable\n");
|
||||
#ifdef GLAMOR
|
||||
ErrorF("-glamor Enable 2D acceleration using glamor\n");
|
||||
ErrorF("-glamor_gles2 Enable 2D acceleration using glamor (with GLES2 only)\n");
|
||||
#endif
|
||||
ErrorF
|
||||
("-fakexa Simulate acceleration using software rendering\n");
|
||||
|
@ -251,6 +252,15 @@ ddxProcessArgument(int argc, char **argv, int i)
|
|||
ephyrFuncs.finiAccel = ephyr_glamor_fini;
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp (argv[i], "-glamor_gles2")) {
|
||||
ephyr_glamor = TRUE;
|
||||
ephyr_glamor_gles2 = TRUE;
|
||||
ephyrFuncs.initAccel = ephyr_glamor_init;
|
||||
ephyrFuncs.enableAccel = ephyr_glamor_enable;
|
||||
ephyrFuncs.disableAccel = ephyr_glamor_disable;
|
||||
ephyrFuncs.finiAccel = ephyr_glamor_fini;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp(argv[i], "-fakexa")) {
|
||||
ephyrFuncs.initAccel = ephyrDrawInit;
|
||||
|
|
|
@ -69,7 +69,7 @@ static Bool ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this);
|
|||
static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this,
|
||||
ScreenPtr a_screen);
|
||||
|
||||
static Bool ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs,
|
||||
static Bool ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs,
|
||||
int a_attrs_len,
|
||||
const char *a_attr_name,
|
||||
int a_attr_value, Bool *a_is_valid);
|
||||
|
@ -363,7 +363,7 @@ translate_xv_attributes(KdVideoAdaptorPtr adaptor,
|
|||
|
||||
it = xcb_xv_query_port_attributes_attributes_iterator(reply);
|
||||
for (i = 0; i < reply->num_attributes; i++) {
|
||||
KdAttributePtr attribute = &adaptor->pAttributes[i];
|
||||
XvAttributePtr attribute = &adaptor->pAttributes[i];
|
||||
|
||||
attribute->flags = it.data->flags;
|
||||
attribute->min_value = it.data->min;
|
||||
|
@ -397,7 +397,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor,
|
|||
return FALSE;
|
||||
|
||||
adaptor->nImages = reply->num_formats;
|
||||
adaptor->pImages = calloc(reply->num_formats, sizeof(KdImageRec));
|
||||
adaptor->pImages = calloc(reply->num_formats, sizeof(XvImageRec));
|
||||
if (!adaptor->pImages) {
|
||||
free(reply);
|
||||
return FALSE;
|
||||
|
@ -405,7 +405,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor,
|
|||
|
||||
formats = xcb_xv_list_image_formats_format(reply);
|
||||
for (i = 0; i < reply->num_formats; i++) {
|
||||
KdImagePtr image = &adaptor->pImages[i];
|
||||
XvImagePtr image = &adaptor->pImages[i];
|
||||
|
||||
image->id = formats[i].id;
|
||||
image->type = formats[i].type;
|
||||
|
@ -612,11 +612,7 @@ ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this)
|
|||
static Bool
|
||||
ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen)
|
||||
{
|
||||
KdScreenPriv(a_screen);
|
||||
KdScreenInfo *screen = pScreenPriv->screen;
|
||||
Bool is_ok = FALSE;
|
||||
KdVideoAdaptorPtr *adaptors = NULL, *registered_adaptors = NULL;
|
||||
int num_registered_adaptors = 0, i = 0, num_adaptors = 0;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_screen, FALSE);
|
||||
|
||||
|
@ -624,38 +620,22 @@ ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen)
|
|||
|
||||
if (!a_this->num_adaptors)
|
||||
goto out;
|
||||
num_registered_adaptors =
|
||||
KdXVListGenericAdaptors(screen, ®istered_adaptors);
|
||||
|
||||
num_adaptors = num_registered_adaptors + a_this->num_adaptors;
|
||||
adaptors = calloc(num_adaptors, sizeof(KdVideoAdaptorPtr));
|
||||
if (!adaptors) {
|
||||
EPHYR_LOG_ERROR("failed to allocate adaptors tab\n");
|
||||
goto out;
|
||||
}
|
||||
memmove(adaptors, registered_adaptors, num_registered_adaptors);
|
||||
for (i = 0; i < a_this->num_adaptors; i++) {
|
||||
*(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i];
|
||||
}
|
||||
if (!KdXVScreenInit(a_screen, adaptors, num_adaptors)) {
|
||||
if (!KdXVScreenInit(a_screen, a_this->adaptors, a_this->num_adaptors)) {
|
||||
EPHYR_LOG_ERROR("failed to register adaptors\n");
|
||||
goto out;
|
||||
}
|
||||
EPHYR_LOG("there are %d registered adaptors\n", num_adaptors);
|
||||
EPHYR_LOG("there are %d registered adaptors\n", a_this->num_adaptors);
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
free(registered_adaptors);
|
||||
registered_adaptors = NULL;
|
||||
free(adaptors);
|
||||
adaptors = NULL;
|
||||
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
static Bool
|
||||
ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs,
|
||||
ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs,
|
||||
int a_attrs_len,
|
||||
const char *a_attr_name,
|
||||
int a_attr_value, Bool *a_is_valid)
|
||||
|
|
|
@ -287,7 +287,8 @@ hostx_set_title(char *title)
|
|||
int
|
||||
hostx_init(void)
|
||||
{
|
||||
uint32_t attr;
|
||||
uint32_t attrs[2];
|
||||
uint32_t attr_mask = 0;
|
||||
xcb_cursor_t empty_cursor;
|
||||
xcb_pixmap_t cursor_pxm;
|
||||
uint16_t red, green, blue;
|
||||
|
@ -299,7 +300,7 @@ hostx_init(void)
|
|||
const xcb_query_extension_reply_t *shm_rep;
|
||||
xcb_screen_t *xscreen;
|
||||
|
||||
attr =
|
||||
attrs[0] =
|
||||
XCB_EVENT_MASK_BUTTON_PRESS
|
||||
| XCB_EVENT_MASK_BUTTON_RELEASE
|
||||
| XCB_EVENT_MASK_POINTER_MOTION
|
||||
|
@ -307,6 +308,7 @@ hostx_init(void)
|
|||
| XCB_EVENT_MASK_KEY_RELEASE
|
||||
| XCB_EVENT_MASK_EXPOSURE
|
||||
| XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||
attr_mask |= XCB_CW_EVENT_MASK;
|
||||
|
||||
EPHYR_DBG("mark");
|
||||
#ifdef GLAMOR
|
||||
|
@ -325,9 +327,18 @@ hostx_init(void)
|
|||
HostX.gc = xcb_generate_id(HostX.conn);
|
||||
HostX.depth = xscreen->root_depth;
|
||||
#ifdef GLAMOR
|
||||
if (ephyr_glamor)
|
||||
if (ephyr_glamor) {
|
||||
HostX.visual = ephyr_glamor_get_visual();
|
||||
else
|
||||
if (HostX.visual->visual_id != xscreen->root_visual) {
|
||||
attrs[1] = xcb_generate_id(HostX.conn);
|
||||
attr_mask |= XCB_CW_COLORMAP;
|
||||
xcb_create_colormap(HostX.conn,
|
||||
XCB_COLORMAP_ALLOC_NONE,
|
||||
attrs[1],
|
||||
HostX.winroot,
|
||||
HostX.visual->visual_id);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual);
|
||||
|
||||
|
@ -379,9 +390,9 @@ hostx_init(void)
|
|||
scrpriv->win_height,
|
||||
0,
|
||||
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
XCB_CW_EVENT_MASK,
|
||||
&attr);
|
||||
HostX.visual->visual_id,
|
||||
attr_mask,
|
||||
attrs);
|
||||
}
|
||||
else {
|
||||
xcb_create_window(HostX.conn,
|
||||
|
@ -391,9 +402,9 @@ hostx_init(void)
|
|||
0,0,100,100, /* will resize */
|
||||
0,
|
||||
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
XCB_CW_EVENT_MASK,
|
||||
&attr);
|
||||
HostX.visual->visual_id,
|
||||
attr_mask,
|
||||
attrs);
|
||||
|
||||
hostx_set_win_title(screen,
|
||||
"(ctrl+shift grabs mouse and keyboard)");
|
||||
|
@ -1234,8 +1245,7 @@ ephyr_glamor_init(ScreenPtr screen)
|
|||
|
||||
glamor_init(screen,
|
||||
GLAMOR_USE_SCREEN |
|
||||
GLAMOR_USE_PICTURE_SCREEN |
|
||||
GLAMOR_INVERTED_Y_AXIS);
|
||||
GLAMOR_USE_PICTURE_SCREEN);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
|
|||
static void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
|
||||
|
||||
/* misc */
|
||||
static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr *, int);
|
||||
static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr, int);
|
||||
|
||||
static DevPrivateKeyRec KdXVWindowKeyRec;
|
||||
|
||||
|
@ -116,49 +116,6 @@ static unsigned long PortResource = 0;
|
|||
#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
|
||||
dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
|
||||
|
||||
static KdXVInitGenericAdaptorPtr *GenDrivers = NULL;
|
||||
static int NumGenDrivers = 0;
|
||||
|
||||
int
|
||||
KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc)
|
||||
{
|
||||
KdXVInitGenericAdaptorPtr *newdrivers;
|
||||
|
||||
/* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */
|
||||
|
||||
newdrivers = realloc(GenDrivers, sizeof(KdXVInitGenericAdaptorPtr) *
|
||||
(1 + NumGenDrivers));
|
||||
if (!newdrivers)
|
||||
return 0;
|
||||
GenDrivers = newdrivers;
|
||||
|
||||
GenDrivers[NumGenDrivers++] = InitFunc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
KdXVListGenericAdaptors(KdScreenInfo * screen, KdVideoAdaptorPtr ** adaptors)
|
||||
{
|
||||
int i, j, n, num;
|
||||
KdVideoAdaptorPtr *DrivAdap, *new;
|
||||
|
||||
num = 0;
|
||||
*adaptors = NULL;
|
||||
for (i = 0; i < NumGenDrivers; i++) {
|
||||
n = GenDrivers[i] (screen, &DrivAdap);
|
||||
if (0 == n)
|
||||
continue;
|
||||
new = realloc(*adaptors, sizeof(KdVideoAdaptorPtr) * (num + n));
|
||||
if (NULL == new)
|
||||
continue;
|
||||
*adaptors = new;
|
||||
for (j = 0; j < n; j++, num++)
|
||||
(*adaptors)[num] = DrivAdap[j];
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
KdVideoAdaptorPtr
|
||||
KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen)
|
||||
{
|
||||
|
@ -172,7 +129,7 @@ KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr)
|
|||
}
|
||||
|
||||
Bool
|
||||
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * adaptors, int num)
|
||||
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr adaptors, int num)
|
||||
{
|
||||
KdXVScreenPtr ScreenPriv;
|
||||
XvScreenPtr pxvs;
|
||||
|
@ -282,7 +239,7 @@ KdXVFreeAdaptor(XvAdaptorPtr pAdaptor)
|
|||
}
|
||||
|
||||
static Bool
|
||||
KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
||||
KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number)
|
||||
{
|
||||
KdScreenPriv(pScreen);
|
||||
KdScreenInfo *screen = pScreenPriv->screen;
|
||||
|
@ -295,15 +252,11 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
|||
XvPortRecPrivatePtr portPriv;
|
||||
XvPortPtr pPort, pp;
|
||||
int numPort;
|
||||
KdAttributePtr attributePtr;
|
||||
XvAttributePtr pAttribute, pat;
|
||||
KdVideoFormatPtr formatPtr;
|
||||
XvFormatPtr pFormat, pf;
|
||||
int numFormat, totFormat;
|
||||
KdVideoEncodingPtr encodingPtr;
|
||||
XvEncodingPtr pEncode, pe;
|
||||
KdImagePtr imagePtr;
|
||||
XvImagePtr pImage, pi;
|
||||
int numVisuals;
|
||||
VisualPtr pVisual;
|
||||
int i;
|
||||
|
@ -315,7 +268,7 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
|||
return FALSE;
|
||||
|
||||
for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
|
||||
adaptorPtr = infoPtr[na];
|
||||
adaptorPtr = &infoPtr[na];
|
||||
|
||||
if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
|
||||
!adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
|
||||
|
@ -381,26 +334,24 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
|||
}
|
||||
|
||||
if (adaptorPtr->nImages &&
|
||||
(pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
||||
|
||||
for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
|
||||
i < adaptorPtr->nImages; i++, pi++, imagePtr++) {
|
||||
memcpy(pi, imagePtr, sizeof(*pi));
|
||||
}
|
||||
(pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
||||
memcpy(pa->pImages, adaptorPtr->pImages,
|
||||
adaptorPtr->nImages * sizeof(XvImageRec));
|
||||
pa->nImages = adaptorPtr->nImages;
|
||||
pa->pImages = pImage;
|
||||
}
|
||||
|
||||
if (adaptorPtr->nAttributes &&
|
||||
(pAttribute =
|
||||
calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) {
|
||||
for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i =
|
||||
0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) {
|
||||
memcpy(pat, attributePtr, sizeof(*pat));
|
||||
pat->name = strdup(attributePtr->name);
|
||||
(pa->pAttributes = calloc(adaptorPtr->nAttributes,
|
||||
sizeof(XvAttributeRec)))) {
|
||||
memcpy(pa->pAttributes, adaptorPtr->pAttributes,
|
||||
adaptorPtr->nAttributes * sizeof(XvAttributeRec));
|
||||
|
||||
for (i = 0; i < adaptorPtr->nAttributes; i++) {
|
||||
pa->pAttributes[i].name =
|
||||
strdup(adaptorPtr->pAttributes[i].name);
|
||||
}
|
||||
|
||||
pa->nAttributes = adaptorPtr->nAttributes;
|
||||
pa->pAttributes = pAttribute;
|
||||
}
|
||||
|
||||
totFormat = adaptorPtr->nFormats;
|
||||
|
|
|
@ -56,8 +56,6 @@ of the copyright holder.
|
|||
#define VIDEO_OVERLAID_STILLS 0x00000008
|
||||
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
|
||||
|
||||
typedef XvImageRec KdImageRec, *KdImagePtr;
|
||||
|
||||
typedef struct {
|
||||
KdScreenInfo *screen;
|
||||
int id;
|
||||
|
@ -121,7 +119,7 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
int id;
|
||||
char *name;
|
||||
const char *name;
|
||||
unsigned short width, height;
|
||||
XvRationalRec rate;
|
||||
} KdVideoEncodingRec, *KdVideoEncodingPtr;
|
||||
|
@ -131,12 +129,10 @@ typedef struct {
|
|||
short class;
|
||||
} KdVideoFormatRec, *KdVideoFormatPtr;
|
||||
|
||||
typedef XvAttributeRec KdAttributeRec, *KdAttributePtr;
|
||||
|
||||
typedef struct {
|
||||
unsigned int type;
|
||||
int flags;
|
||||
char *name;
|
||||
const char *name;
|
||||
int nEncodings;
|
||||
KdVideoEncodingPtr pEncodings;
|
||||
int nFormats;
|
||||
|
@ -144,9 +140,9 @@ typedef struct {
|
|||
int nPorts;
|
||||
DevUnion *pPortPrivates;
|
||||
int nAttributes;
|
||||
KdAttributePtr pAttributes;
|
||||
XvAttributePtr pAttributes;
|
||||
int nImages;
|
||||
KdImagePtr pImages;
|
||||
XvImagePtr pImages;
|
||||
PutVideoFuncPtr PutVideo;
|
||||
PutStillFuncPtr PutStill;
|
||||
GetVideoFuncPtr GetVideo;
|
||||
|
@ -161,16 +157,7 @@ typedef struct {
|
|||
} KdVideoAdaptorRec, *KdVideoAdaptorPtr;
|
||||
|
||||
Bool
|
||||
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * Adaptors, int num);
|
||||
|
||||
typedef int (*KdXVInitGenericAdaptorPtr) (KdScreenInfo * screen,
|
||||
KdVideoAdaptorPtr ** Adaptors);
|
||||
|
||||
int
|
||||
KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc);
|
||||
|
||||
int
|
||||
KdXVListGenericAdaptors(KdScreenInfo * screen, KdVideoAdaptorPtr ** Adaptors);
|
||||
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr Adaptors, int num);
|
||||
|
||||
void
|
||||
|
||||
|
|
|
@ -359,15 +359,11 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
|
|||
XvPortRecPrivatePtr portPriv;
|
||||
XvPortPtr pPort, pp;
|
||||
int numPort;
|
||||
XF86AttributePtr attributePtr;
|
||||
XvAttributePtr pAttribute, pat;
|
||||
XF86VideoFormatPtr formatPtr;
|
||||
XvFormatPtr pFormat, pf;
|
||||
int numFormat, totFormat;
|
||||
XF86VideoEncodingPtr encodingPtr;
|
||||
XvEncodingPtr pEncode, pe;
|
||||
XF86ImagePtr imagePtr;
|
||||
XvImagePtr pImage, pi;
|
||||
int numVisuals;
|
||||
VisualPtr pVisual;
|
||||
int i;
|
||||
|
@ -445,49 +441,24 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
|
|||
}
|
||||
|
||||
if (adaptorPtr->nImages &&
|
||||
(pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
||||
|
||||
for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
|
||||
i < adaptorPtr->nImages; i++, pi++, imagePtr++) {
|
||||
pi->id = imagePtr->id;
|
||||
pi->type = imagePtr->type;
|
||||
pi->byte_order = imagePtr->byte_order;
|
||||
memcpy(pi->guid, imagePtr->guid, 16);
|
||||
pi->bits_per_pixel = imagePtr->bits_per_pixel;
|
||||
pi->format = imagePtr->format;
|
||||
pi->num_planes = imagePtr->num_planes;
|
||||
pi->depth = imagePtr->depth;
|
||||
pi->red_mask = imagePtr->red_mask;
|
||||
pi->green_mask = imagePtr->green_mask;
|
||||
pi->blue_mask = imagePtr->blue_mask;
|
||||
pi->y_sample_bits = imagePtr->y_sample_bits;
|
||||
pi->u_sample_bits = imagePtr->u_sample_bits;
|
||||
pi->v_sample_bits = imagePtr->v_sample_bits;
|
||||
pi->horz_y_period = imagePtr->horz_y_period;
|
||||
pi->horz_u_period = imagePtr->horz_u_period;
|
||||
pi->horz_v_period = imagePtr->horz_v_period;
|
||||
pi->vert_y_period = imagePtr->vert_y_period;
|
||||
pi->vert_u_period = imagePtr->vert_u_period;
|
||||
pi->vert_v_period = imagePtr->vert_v_period;
|
||||
memcpy(pi->component_order, imagePtr->component_order, 32);
|
||||
pi->scanline_order = imagePtr->scanline_order;
|
||||
}
|
||||
(pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
||||
memcpy(pa->pImages, adaptorPtr->pImages,
|
||||
adaptorPtr->nImages * sizeof(XvImageRec));
|
||||
pa->nImages = adaptorPtr->nImages;
|
||||
pa->pImages = pImage;
|
||||
}
|
||||
|
||||
if (adaptorPtr->nAttributes &&
|
||||
(pAttribute =
|
||||
calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) {
|
||||
for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i =
|
||||
0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) {
|
||||
pat->flags = attributePtr->flags;
|
||||
pat->min_value = attributePtr->min_value;
|
||||
pat->max_value = attributePtr->max_value;
|
||||
pat->name = strdup(attributePtr->name);
|
||||
(pa->pAttributes = calloc(adaptorPtr->nAttributes,
|
||||
sizeof(XvAttributeRec)))) {
|
||||
memcpy(pa->pAttributes, adaptorPtr->pAttributes,
|
||||
adaptorPtr->nAttributes * sizeof(XvAttributeRec));
|
||||
|
||||
for (i = 0; i < adaptorPtr->nAttributes; i++) {
|
||||
pa->pAttributes[i].name =
|
||||
strdup(adaptorPtr->pAttributes[i].name);
|
||||
}
|
||||
|
||||
pa->nAttributes = adaptorPtr->nAttributes;
|
||||
pa->pAttributes = pAttribute;
|
||||
}
|
||||
|
||||
totFormat = adaptorPtr->nFormats;
|
||||
|
|
|
@ -42,34 +42,7 @@
|
|||
*/
|
||||
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
int type;
|
||||
int byte_order;
|
||||
unsigned char guid[16];
|
||||
int bits_per_pixel;
|
||||
int format;
|
||||
int num_planes;
|
||||
|
||||
/* for RGB formats only */
|
||||
int depth;
|
||||
unsigned int red_mask;
|
||||
unsigned int green_mask;
|
||||
unsigned int blue_mask;
|
||||
|
||||
/* for YUV formats only */
|
||||
unsigned int y_sample_bits;
|
||||
unsigned int u_sample_bits;
|
||||
unsigned int v_sample_bits;
|
||||
unsigned int horz_y_period;
|
||||
unsigned int horz_u_period;
|
||||
unsigned int horz_v_period;
|
||||
unsigned int vert_y_period;
|
||||
unsigned int vert_u_period;
|
||||
unsigned int vert_v_period;
|
||||
char component_order[32];
|
||||
int scanline_order;
|
||||
} XF86ImageRec, *XF86ImagePtr;
|
||||
typedef XvImageRec XF86ImageRec, *XF86ImagePtr;
|
||||
|
||||
typedef struct {
|
||||
ScrnInfoPtr pScrn;
|
||||
|
@ -147,12 +120,7 @@ typedef struct {
|
|||
short class;
|
||||
} XF86VideoFormatRec, *XF86VideoFormatPtr;
|
||||
|
||||
typedef struct {
|
||||
int flags;
|
||||
int min_value;
|
||||
int max_value;
|
||||
const char *name;
|
||||
} XF86AttributeRec, *XF86AttributePtr;
|
||||
typedef XvAttributeRec XF86AttributeRec, *XF86AttributePtr;
|
||||
|
||||
typedef struct {
|
||||
unsigned int type;
|
||||
|
|
|
@ -24,7 +24,7 @@ module_LTLIBRARIES = libglamoregl.la
|
|||
libglamoregl_la_SOURCES = \
|
||||
$(top_srcdir)/glamor/glamor_egl.c \
|
||||
$(top_srcdir)/glamor/glamor_eglmodule.c \
|
||||
$(top_srcdir)/glamor/glamor_xv.c \
|
||||
glamor_xf86_xv.c \
|
||||
$()
|
||||
|
||||
libglamoregl_la_LDFLAGS = \
|
||||
|
@ -38,6 +38,7 @@ libglamoregl_la_LIBADD = \
|
|||
|
||||
AM_CPPFLAGS = $(XORG_INCS) \
|
||||
-I$(top_srcdir)/dri3 \
|
||||
-I$(top_srcdir)/glamor \
|
||||
$()
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
|
||||
|
|
185
hw/xfree86/glamor_egl/glamor_xf86_xv.c
Normal file
185
hw/xfree86/glamor_egl/glamor_xf86_xv.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* 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
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Dave Airlie <airlied@redhat.com>
|
||||
*
|
||||
* some code is derived from the xf86-video-ati radeon driver, mainly
|
||||
* the calculations.
|
||||
*/
|
||||
|
||||
/** @file glamor_xf86_xv.c
|
||||
*
|
||||
* This implements the XF86 XV interface, and calls into glamor core
|
||||
* for its support of the suspiciously similar XF86 and Kdrive
|
||||
* device-dependent XV interfaces.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#define GLAMOR_FOR_XORG
|
||||
#include "glamor_priv.h"
|
||||
|
||||
#include <X11/extensions/Xv.h>
|
||||
#include "fourcc.h"
|
||||
|
||||
#define NUM_FORMATS 3
|
||||
|
||||
static XF86VideoFormatRec Formats[NUM_FORMATS] = {
|
||||
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
|
||||
};
|
||||
|
||||
static void
|
||||
glamor_xf86_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
|
||||
{
|
||||
if (!cleanup)
|
||||
return;
|
||||
|
||||
glamor_xv_stop_video(data);
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xf86_xv_set_port_attribute(ScrnInfoPtr pScrn,
|
||||
Atom attribute, INT32 value, void *data)
|
||||
{
|
||||
return glamor_xv_set_port_attribute(data, attribute, value);
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xf86_xv_get_port_attribute(ScrnInfoPtr pScrn,
|
||||
Atom attribute, INT32 *value, void *data)
|
||||
{
|
||||
return glamor_xv_get_port_attribute(data, attribute, value);
|
||||
}
|
||||
|
||||
static void
|
||||
glamor_xf86_xv_query_best_size(ScrnInfoPtr pScrn,
|
||||
Bool motion,
|
||||
short vid_w, short vid_h,
|
||||
short drw_w, short drw_h,
|
||||
unsigned int *p_w, unsigned int *p_h, void *data)
|
||||
{
|
||||
*p_w = drw_w;
|
||||
*p_h = drw_h;
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xf86_xv_query_image_attributes(ScrnInfoPtr pScrn,
|
||||
int id,
|
||||
unsigned short *w, unsigned short *h,
|
||||
int *pitches, int *offsets)
|
||||
{
|
||||
return glamor_xv_query_image_attributes(id, w, h, pitches, offsets);
|
||||
}
|
||||
|
||||
static int
|
||||
glamor_xf86_xv_put_image(ScrnInfoPtr pScrn,
|
||||
short src_x, short src_y,
|
||||
short drw_x, short drw_y,
|
||||
short src_w, short src_h,
|
||||
short drw_w, short drw_h,
|
||||
int id,
|
||||
unsigned char *buf,
|
||||
short width,
|
||||
short height,
|
||||
Bool sync,
|
||||
RegionPtr clipBoxes, void *data, DrawablePtr pDrawable)
|
||||
{
|
||||
return glamor_xv_put_image(data, pDrawable,
|
||||
src_x, src_y,
|
||||
drw_x, drw_y,
|
||||
src_w, src_h,
|
||||
drw_w, drw_h,
|
||||
id, buf, width, height, sync, clipBoxes);
|
||||
}
|
||||
|
||||
static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
|
||||
{
|
||||
0,
|
||||
"XV_IMAGE",
|
||||
8192, 8192,
|
||||
{1, 1}
|
||||
}
|
||||
};
|
||||
|
||||
XF86VideoAdaptorPtr
|
||||
glamor_xv_init(ScreenPtr screen, int num_texture_ports)
|
||||
{
|
||||
glamor_port_private *port_priv;
|
||||
XF86VideoAdaptorPtr adapt;
|
||||
int i;
|
||||
|
||||
glamor_xv_core_init(screen);
|
||||
|
||||
adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
|
||||
(sizeof(glamor_port_private) + sizeof(DevUnion)));
|
||||
if (adapt == NULL)
|
||||
return NULL;
|
||||
|
||||
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
|
||||
adapt->flags = 0;
|
||||
adapt->name = "GLAMOR Textured Video";
|
||||
adapt->nEncodings = 1;
|
||||
adapt->pEncodings = DummyEncodingGLAMOR;
|
||||
|
||||
adapt->nFormats = NUM_FORMATS;
|
||||
adapt->pFormats = Formats;
|
||||
adapt->nPorts = num_texture_ports;
|
||||
adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
|
||||
|
||||
adapt->pAttributes = glamor_xv_attributes;
|
||||
adapt->nAttributes = glamor_xv_num_attributes;
|
||||
|
||||
port_priv =
|
||||
(glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]);
|
||||
adapt->pImages = glamor_xv_images;
|
||||
adapt->nImages = glamor_xv_num_images;
|
||||
adapt->PutVideo = NULL;
|
||||
adapt->PutStill = NULL;
|
||||
adapt->GetVideo = NULL;
|
||||
adapt->GetStill = NULL;
|
||||
adapt->StopVideo = glamor_xf86_xv_stop_video;
|
||||
adapt->SetPortAttribute = glamor_xf86_xv_set_port_attribute;
|
||||
adapt->GetPortAttribute = glamor_xf86_xv_get_port_attribute;
|
||||
adapt->QueryBestSize = glamor_xf86_xv_query_best_size;
|
||||
adapt->PutImage = glamor_xf86_xv_put_image;
|
||||
adapt->ReputImage = NULL;
|
||||
adapt->QueryImageAttributes = glamor_xf86_xv_query_image_attributes;
|
||||
|
||||
for (i = 0; i < num_texture_ports; i++) {
|
||||
glamor_port_private *pPriv = &port_priv[i];
|
||||
|
||||
pPriv->brightness = 0;
|
||||
pPriv->contrast = 0;
|
||||
pPriv->saturation = 0;
|
||||
pPriv->hue = 0;
|
||||
pPriv->gamma = 1000;
|
||||
pPriv->transform_index = 0;
|
||||
|
||||
REGION_NULL(pScreen, &pPriv->clip);
|
||||
|
||||
adapt->pPortPrivates[i].ptr = (void *) (pPriv);
|
||||
}
|
||||
return adapt;
|
||||
}
|
11
mi/mi.h
11
mi/mi.h
|
@ -67,6 +67,11 @@ typedef struct _miDash *miDashPtr;
|
|||
|
||||
/* miarc.c */
|
||||
|
||||
extern _X_EXPORT void miWideArc(DrawablePtr pDraw,
|
||||
GCPtr pGC,
|
||||
int narcs,
|
||||
xArc * parcs);
|
||||
|
||||
extern _X_EXPORT void miPolyArc(DrawablePtr /*pDraw */ ,
|
||||
GCPtr /*pGC */ ,
|
||||
int /*narcs */ ,
|
||||
|
@ -452,6 +457,12 @@ extern _X_EXPORT void miWideDash(DrawablePtr /*pDrawable */ ,
|
|||
DDXPointPtr /*pPts */
|
||||
);
|
||||
|
||||
extern _X_EXPORT void miPolylines(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int mode,
|
||||
int npt,
|
||||
DDXPointPtr pPts);
|
||||
|
||||
/* miwindow.c */
|
||||
|
||||
extern _X_EXPORT void miClearToBackground(WindowPtr /*pWin */ ,
|
||||
|
|
11
mi/miarc.c
11
mi/miarc.c
|
@ -886,7 +886,7 @@ miFillWideEllipse(DrawablePtr pDraw, GCPtr pGC, xArc * parc)
|
|||
*/
|
||||
|
||||
void
|
||||
miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||
miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||
{
|
||||
int i;
|
||||
xArc *parc;
|
||||
|
@ -3396,3 +3396,12 @@ drawQuadrant(struct arc_def *def,
|
|||
y--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||
{
|
||||
if (pGC->lineWidth == 0)
|
||||
miZeroPolyArc(pDraw, pGC, narcs, parcs);
|
||||
else
|
||||
miWideArc(pDraw, pGC, narcs, parcs);
|
||||
}
|
||||
|
|
144
mi/mifillarc.c
144
mi/mifillarc.c
|
@ -476,26 +476,16 @@ miFillArcSliceSetup(xArc * arc, miArcSliceRec * slice, GCPtr pGC)
|
|||
*wids++ = slw; \
|
||||
}
|
||||
|
||||
static void
|
||||
miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||
static int
|
||||
miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||
{
|
||||
int x, y, e;
|
||||
int yk, xk, ym, xm, dx, dy, xorg, yorg;
|
||||
int slw;
|
||||
miFillArcRec info;
|
||||
DDXPointPtr points;
|
||||
DDXPointPtr pts;
|
||||
int *widths;
|
||||
int *wids;
|
||||
|
||||
points = malloc(sizeof(DDXPointRec) * arc->height);
|
||||
if (!points)
|
||||
return;
|
||||
widths = malloc(sizeof(int) * arc->height);
|
||||
if (!widths) {
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
miFillArcSetup(arc, &info);
|
||||
MIFILLARCSETUP();
|
||||
if (pGC->miTranslate) {
|
||||
|
@ -508,31 +498,19 @@ miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
MIFILLARCSTEP(slw);
|
||||
ADDSPANS();
|
||||
}
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
return pts - points;
|
||||
}
|
||||
|
||||
static void
|
||||
miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||
static int
|
||||
miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||
{
|
||||
int x, y;
|
||||
int xorg, yorg, dx, dy, slw;
|
||||
double e, yk, xk, ym, xm;
|
||||
miFillArcDRec info;
|
||||
DDXPointPtr points;
|
||||
DDXPointPtr pts;
|
||||
int *widths;
|
||||
int *wids;
|
||||
|
||||
points = malloc(sizeof(DDXPointRec) * arc->height);
|
||||
if (!points)
|
||||
return;
|
||||
widths = malloc(sizeof(int) * arc->height);
|
||||
if (!widths) {
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
miFillArcDSetup(arc, &info);
|
||||
MIFILLARCSETUP();
|
||||
if (pGC->miTranslate) {
|
||||
|
@ -545,9 +523,7 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
MIFILLARCSTEP(slw);
|
||||
ADDSPANS();
|
||||
}
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
return pts - points;
|
||||
}
|
||||
|
||||
#define ADDSPAN(l,r) \
|
||||
|
@ -572,17 +548,15 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
ADDSPAN(xl, xc); \
|
||||
}
|
||||
|
||||
static void
|
||||
miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||
static int
|
||||
miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||
{
|
||||
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
|
||||
int x, y, e;
|
||||
miFillArcRec info;
|
||||
miArcSliceRec slice;
|
||||
int ya, xl, xr, xc;
|
||||
DDXPointPtr points;
|
||||
DDXPointPtr pts;
|
||||
int *widths;
|
||||
int *wids;
|
||||
|
||||
miFillArcSetup(arc, &info);
|
||||
|
@ -591,14 +565,6 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
slw = arc->height;
|
||||
if (slice.flip_top || slice.flip_bot)
|
||||
slw += (arc->height >> 1) + 1;
|
||||
points = malloc(sizeof(DDXPointRec) * slw);
|
||||
if (!points)
|
||||
return;
|
||||
widths = malloc(sizeof(int) * slw);
|
||||
if (!widths) {
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
if (pGC->miTranslate) {
|
||||
xorg += pDraw->x;
|
||||
yorg += pDraw->y;
|
||||
|
@ -622,13 +588,11 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
ADDSLICESPANS(slice.flip_bot);
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
return pts - points;
|
||||
}
|
||||
|
||||
static void
|
||||
miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||
static int
|
||||
miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||
{
|
||||
int x, y;
|
||||
int dx, dy, xorg, yorg, slw;
|
||||
|
@ -636,9 +600,7 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
miFillArcDRec info;
|
||||
miArcSliceRec slice;
|
||||
int ya, xl, xr, xc;
|
||||
DDXPointPtr points;
|
||||
DDXPointPtr pts;
|
||||
int *widths;
|
||||
int *wids;
|
||||
|
||||
miFillArcDSetup(arc, &info);
|
||||
|
@ -647,14 +609,6 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
slw = arc->height;
|
||||
if (slice.flip_top || slice.flip_bot)
|
||||
slw += (arc->height >> 1) + 1;
|
||||
points = malloc(sizeof(DDXPointRec) * slw);
|
||||
if (!points)
|
||||
return;
|
||||
widths = malloc(sizeof(int) * slw);
|
||||
if (!widths) {
|
||||
free(points);
|
||||
return;
|
||||
}
|
||||
if (pGC->miTranslate) {
|
||||
xorg += pDraw->x;
|
||||
yorg += pDraw->y;
|
||||
|
@ -678,35 +632,69 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
|||
ADDSLICESPANS(slice.flip_bot);
|
||||
}
|
||||
}
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
||||
free(widths);
|
||||
free(points);
|
||||
return pts - points;
|
||||
}
|
||||
|
||||
/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
|
||||
* Since we don't have to worry about overlapping segments, we can just
|
||||
* fill each arc as it comes.
|
||||
*/
|
||||
void
|
||||
miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||
{
|
||||
int i;
|
||||
xArc *arc;
|
||||
|
||||
for (i = narcs, arc = parcs; --i >= 0; arc++) {
|
||||
if (miFillArcEmpty(arc))
|
||||
continue;
|
||||
if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE)) {
|
||||
if (miCanFillArc(arc))
|
||||
miFillEllipseI(pDraw, pGC, arc);
|
||||
else
|
||||
miFillEllipseD(pDraw, pGC, arc);
|
||||
/* Limit the number of spans in a single draw request to avoid integer
|
||||
* overflow in the computation of the span buffer size.
|
||||
*/
|
||||
#define MAX_SPANS_PER_LOOP (4 * 1024 * 1024)
|
||||
|
||||
void
|
||||
miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, xArc * parcs)
|
||||
{
|
||||
while (narcs_all > 0) {
|
||||
int narcs;
|
||||
int i;
|
||||
xArc *arc;
|
||||
int nspans = 0;
|
||||
DDXPointPtr pts, points;
|
||||
int *wids, *widths;
|
||||
int n;
|
||||
|
||||
for (narcs = 0, arc = parcs; narcs < narcs_all; narcs++, arc++) {
|
||||
if (narcs && nspans + arc->height > MAX_SPANS_PER_LOOP)
|
||||
break;
|
||||
nspans += arc->height;
|
||||
}
|
||||
else {
|
||||
if (miCanFillArc(arc))
|
||||
miFillArcSliceI(pDraw, pGC, arc);
|
||||
else
|
||||
miFillArcSliceD(pDraw, pGC, arc);
|
||||
|
||||
pts = points = malloc (sizeof (DDXPointRec) * nspans +
|
||||
sizeof(int) * nspans);
|
||||
if (points) {
|
||||
wids = widths = (int *) (points + nspans);
|
||||
|
||||
for (i = 0, arc = parcs; i < narcs; arc++, i++) {
|
||||
if (miFillArcEmpty(arc))
|
||||
continue;
|
||||
if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
|
||||
{
|
||||
if (miCanFillArc(arc))
|
||||
n = miFillEllipseI(pDraw, pGC, arc, pts, wids);
|
||||
else
|
||||
n = miFillEllipseD(pDraw, pGC, arc, pts, wids);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (miCanFillArc(arc))
|
||||
n = miFillArcSliceI(pDraw, pGC, arc, pts, wids);
|
||||
else
|
||||
n = miFillArcSliceD(pDraw, pGC, arc, pts, wids);
|
||||
}
|
||||
pts += n;
|
||||
wids += n;
|
||||
}
|
||||
nspans = pts - points;
|
||||
if (nspans)
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, nspans, points,
|
||||
widths, FALSE);
|
||||
free (points);
|
||||
}
|
||||
parcs += narcs;
|
||||
narcs_all -= narcs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1979,3 +1979,23 @@ miWideDash(DrawablePtr pDrawable, GCPtr pGC,
|
|||
if (spanData)
|
||||
miCleanupSpanData(pDrawable, pGC, spanData);
|
||||
}
|
||||
|
||||
void
|
||||
miPolylines(DrawablePtr drawable,
|
||||
GCPtr gc,
|
||||
int mode,
|
||||
int n,
|
||||
DDXPointPtr points)
|
||||
{
|
||||
if (gc->lineWidth == 0) {
|
||||
if (gc->lineStyle == LineSolid)
|
||||
miZeroLine(drawable, gc, mode, n, points);
|
||||
else
|
||||
miZeroDashLine(drawable, gc, mode, n, points);
|
||||
} else {
|
||||
if (gc->lineStyle == LineSolid)
|
||||
miWideLine(drawable, gc, mode, n, points);
|
||||
else
|
||||
miWideDash(drawable, gc, mode, n, points);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -656,7 +656,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
|||
|
||||
for (arc = parcs, i = narcs; --i >= 0; arc++) {
|
||||
if (!miCanZeroArc(arc))
|
||||
miPolyArc(pDraw, pGC, 1, arc);
|
||||
miWideArc(pDraw, pGC, 1, arc);
|
||||
else {
|
||||
if (arc->width > arc->height)
|
||||
n = arc->width + (arc->height >> 1);
|
||||
|
|
|
@ -179,14 +179,6 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */
|
|||
MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
|
||||
|
||||
while (--npt > 0) {
|
||||
if (Nspans > 0)
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit,
|
||||
pwidthInit, FALSE);
|
||||
Nspans = 0;
|
||||
new_span = TRUE;
|
||||
spans = pspanInit - 1;
|
||||
widths = pwidthInit - 1;
|
||||
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
oc1 = oc2;
|
||||
|
@ -208,6 +200,14 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */
|
|||
|
||||
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
|
||||
|
||||
if (ady + 1 > (list_len - Nspans)) {
|
||||
(*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit,
|
||||
pwidthInit, FALSE);
|
||||
Nspans = 0;
|
||||
spans = pspanInit - 1;
|
||||
widths = pwidthInit - 1;
|
||||
}
|
||||
new_span = TRUE;
|
||||
if (adx > ady) {
|
||||
e1 = ady << 1;
|
||||
e2 = e1 - (adx << 1);
|
||||
|
|
Loading…
Reference in New Issue
Block a user