aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fontconfig/src/fcatomic.h18
-rw-r--r--libX11/specs/libX11/CH01.xml2
-rw-r--r--libX11/specs/libX11/CH14.xml2
-rw-r--r--libX11/src/Iconify.c26
-rw-r--r--libX11/src/ReconfWM.c37
-rw-r--r--libX11/src/Withdraw.c22
-rw-r--r--libX11/src/xkb/XKB.c11
-rw-r--r--libX11/src/xkb/XKBMAlloc.c2
-rw-r--r--libxcb/doc/tutorial/index.html24
-rw-r--r--mesalib/configure.ac7
-rw-r--r--mesalib/docs/GL3.txt8
-rw-r--r--mesalib/docs/index.html6
-rw-r--r--mesalib/docs/relnotes.html1
-rw-r--r--mesalib/docs/relnotes/10.2.4.html127
-rw-r--r--mesalib/docs/relnotes/10.3.html4
-rw-r--r--mesalib/src/glsl/ast_function.cpp35
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp87
-rw-r--r--mesalib/src/glsl/builtin_functions.cpp67
-rw-r--r--mesalib/src/glsl/glsl_parser.yy8
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp2
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h5
-rw-r--r--mesalib/src/glsl/ir.cpp6
-rw-r--r--mesalib/src/glsl/ir.h33
-rw-r--r--mesalib/src/glsl/ir_builder.cpp18
-rw-r--r--mesalib/src/glsl/ir_builder.h4
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp2
-rw-r--r--mesalib/src/glsl/ir_hierarchical_visitor.cpp158
-rw-r--r--mesalib/src/glsl/ir_hierarchical_visitor.h29
-rw-r--r--mesalib/src/glsl/ir_reader.cpp7
-rw-r--r--mesalib/src/glsl/ir_validate.cpp30
-rw-r--r--mesalib/src/glsl/list.h40
-rw-r--r--mesalib/src/glsl/opt_function_inlining.cpp7
-rw-r--r--mesalib/src/glsl/opt_rebalance_tree.cpp23
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_gentable.py4
-rw-r--r--mesalib/src/mesa/drivers/dri/Makefile.am3
-rw-r--r--mesalib/src/mesa/drivers/dri/common/drirc20
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h5
-rw-r--r--mesalib/src/mesa/main/arrayobj.c15
-rw-r--r--mesalib/src/mesa/main/format_pack.c2
-rw-r--r--mesalib/src/mesa/main/mtypes.h19
-rw-r--r--mesalib/src/mesa/main/pack.c16
-rw-r--r--mesalib/src/mesa/main/texparam.c22
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp8
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp11
-rw-r--r--mesalib/src/mesa/vbo/vbo_context.h22
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec.c15
-rw-r--r--tools/plink/putty.h1
-rw-r--r--tools/plink/settings.c2
-rw-r--r--tools/plink/ssh.c51
-rw-r--r--tools/plink/winhelp.h1
-rw-r--r--xorg-server/config/config.c129
-rw-r--r--xorg-server/config/udev.c10
-rw-r--r--xorg-server/configure.ac6
-rw-r--r--xorg-server/dix/getevents.c80
-rw-r--r--xorg-server/glamor/Makefile.am16
-rw-r--r--xorg-server/glamor/glamor.c51
-rw-r--r--xorg-server/glamor/glamor.h23
-rw-r--r--xorg-server/glamor/glamor_copy.c693
-rw-r--r--xorg-server/glamor/glamor_copyarea.c626
-rw-r--r--xorg-server/glamor/glamor_copyplane.c75
-rw-r--r--xorg-server/glamor/glamor_copywindow.c56
-rw-r--r--xorg-server/glamor/glamor_core.c202
-rw-r--r--xorg-server/glamor/glamor_dash.c370
-rw-r--r--xorg-server/glamor/glamor_fill.c356
-rw-r--r--xorg-server/glamor/glamor_glyphblt.c154
-rw-r--r--xorg-server/glamor/glamor_glyphs.c10
-rw-r--r--xorg-server/glamor/glamor_gradient.c19
-rw-r--r--xorg-server/glamor/glamor_largepixmap.c13
-rw-r--r--xorg-server/glamor/glamor_lines.c187
-rw-r--r--xorg-server/glamor/glamor_picture.c18
-rw-r--r--xorg-server/glamor/glamor_pixmap.c509
-rw-r--r--xorg-server/glamor/glamor_points.c3
-rw-r--r--xorg-server/glamor/glamor_polylines.c136
-rw-r--r--xorg-server/glamor/glamor_prepare.c274
-rw-r--r--xorg-server/glamor/glamor_prepare.h (renamed from xorg-server/glamor/glamor_segment.c)40
-rw-r--r--xorg-server/glamor/glamor_priv.h266
-rw-r--r--xorg-server/glamor/glamor_program.c56
-rw-r--r--xorg-server/glamor/glamor_program.h6
-rw-r--r--xorg-server/glamor/glamor_render.c105
-rw-r--r--xorg-server/glamor/glamor_segs.c188
-rw-r--r--xorg-server/glamor/glamor_spans.c3
-rw-r--r--xorg-server/glamor/glamor_sync.c117
-rw-r--r--xorg-server/glamor/glamor_text.c6
-rw-r--r--xorg-server/glamor/glamor_tile.c293
-rw-r--r--xorg-server/glamor/glamor_transfer.c48
-rw-r--r--xorg-server/glamor/glamor_transform.c72
-rw-r--r--xorg-server/glamor/glamor_trapezoid.c22
-rw-r--r--xorg-server/glamor/glamor_utils.c79
-rw-r--r--xorg-server/glamor/glamor_utils.h218
-rw-r--r--xorg-server/glamor/glamor_xv.c265
-rw-r--r--xorg-server/hw/kdrive/ephyr/Makefile.am5
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c10
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.h13
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c24
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_glamor_xv.c161
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrinit.c14
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrvideo.c34
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.c34
-rw-r--r--xorg-server/hw/kdrive/src/kdrive.c4
-rw-r--r--xorg-server/hw/kdrive/src/kdrive.h1
-rw-r--r--xorg-server/hw/kdrive/src/kxv.c81
-rw-r--r--xorg-server/hw/kdrive/src/kxv.h23
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86DPMS.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h10
-rw-r--r--xorg-server/hw/xfree86/common/xf86platformBus.c58
-rw-r--r--xorg-server/hw/xfree86/common/xf86platformBus.h104
-rw-r--r--xorg-server/hw/xfree86/common/xf86xv.c53
-rw-r--r--xorg-server/hw/xfree86/common/xf86xv.h36
-rw-r--r--xorg-server/hw/xfree86/glamor_egl/Makefile.am3
-rw-r--r--xorg-server/hw/xfree86/glamor_egl/glamor_xf86_xv.c185
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Rotate.c18
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_platform.c52
-rw-r--r--xorg-server/include/callback.h18
-rw-r--r--xorg-server/include/colormap.h16
-rw-r--r--xorg-server/include/cursor.h4
-rw-r--r--xorg-server/include/dix.h69
-rw-r--r--xorg-server/include/dixfont.h10
-rw-r--r--xorg-server/include/dixgrabs.h4
-rw-r--r--xorg-server/include/gc.h4
-rw-r--r--xorg-server/include/gcstruct.h38
-rw-r--r--xorg-server/include/hotplug.h69
-rw-r--r--xorg-server/include/input.h8
-rw-r--r--xorg-server/include/os.h52
-rw-r--r--xorg-server/include/pixmap.h14
-rw-r--r--xorg-server/include/property.h36
-rw-r--r--xorg-server/include/resource.h74
-rw-r--r--xorg-server/include/scrnintstr.h116
-rw-r--r--xorg-server/include/window.h20
-rw-r--r--xorg-server/include/xkbsrv.h18
-rw-r--r--xorg-server/mi/mi.h85
-rw-r--r--xorg-server/mi/miarc.c11
-rw-r--r--xorg-server/mi/mifillarc.c146
-rw-r--r--xorg-server/mi/misprite.c4
-rw-r--r--xorg-server/mi/miwideline.c20
-rw-r--r--xorg-server/mi/mizerarc.c2
-rw-r--r--xorg-server/mi/mizerline.c16
-rw-r--r--xorg-server/os/access.c6
-rw-r--r--xorg-server/os/log.c2
140 files changed, 4591 insertions, 4076 deletions
diff --git a/fontconfig/src/fcatomic.h b/fontconfig/src/fcatomic.h
index 362e52164..cc28a883c 100644
--- a/fontconfig/src/fcatomic.h
+++ b/fontconfig/src/fcatomic.h
@@ -48,22 +48,22 @@
#include "fcwindows.h"
-/* mingw32 does not have MemoryBarrier.
- * MemoryBarrier may be defined as a macro or a function.
- * Just make a failsafe version for ourselves. */
-#ifdef MemoryBarrier
-#define HBMemoryBarrier MemoryBarrier
-#else
-static inline void HBMemoryBarrier (void) {
+/* MinGW has a convoluted history of supporting MemoryBarrier
+ * properly. As such, define a function to wrap the whole
+ * thing. */
+static inline void _FCMemoryBarrier (void) {
+#if !defined(MemoryBarrier)
long dummy = 0;
InterlockedExchange (&dummy, 1);
-}
+#else
+ MemoryBarrier ();
#endif
+}
typedef LONG fc_atomic_int_t;
#define fc_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
-#define fc_atomic_ptr_get(P) (HBMemoryBarrier (), (void *) *(P))
+#define fc_atomic_ptr_get(P) (_FCMemoryBarrier (), (void *) *(P))
#define fc_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
diff --git a/libX11/specs/libX11/CH01.xml b/libX11/specs/libX11/CH01.xml
index 67744cfa2..26009f2fa 100644
--- a/libX11/specs/libX11/CH01.xml
+++ b/libX11/specs/libX11/CH01.xml
@@ -678,7 +678,7 @@ store.
</listitem>
<listitem>
<para>
-The user should have control of his screen real estate.
+The user should have control of their screen real estate.
Therefore, you should write your applications to react to window management
rather than presume control of the entire screen.
What you do inside of your top-level window, however,
diff --git a/libX11/specs/libX11/CH14.xml b/libX11/specs/libX11/CH14.xml
index 678f979c4..c1a2704e9 100644
--- a/libX11/specs/libX11/CH14.xml
+++ b/libX11/specs/libX11/CH14.xml
@@ -2094,7 +2094,7 @@ The definitions for the initial_state flag are:
<literallayout class="monospaced">
#define WithdrawnState 0
#define NormalState 1 /* most applications start this way */
-#define IconicState 2 /* application wants to start as an icon */
+#define IconicState 3 /* application wants to start as an icon */
</literallayout>
<para>
diff --git a/libX11/src/Iconify.c b/libX11/src/Iconify.c
index 3a969d741..9da416596 100644
--- a/libX11/src/Iconify.c
+++ b/libX11/src/Iconify.c
@@ -67,19 +67,23 @@ Status XIconifyWindow (
Window w,
int screen)
{
- XClientMessageEvent ev;
- Window root = RootWindow (dpy, screen);
Atom prop;
prop = XInternAtom (dpy, "WM_CHANGE_STATE", False);
- if (prop == None) return False;
+ if (prop == None)
+ return False;
+ else {
+ XClientMessageEvent ev = {
+ .type = ClientMessage,
+ .window = w,
+ .message_type = prop,
+ .format = 32,
+ .data.l[0] = IconicState
+ };
+ Window root = RootWindow (dpy, screen);
- ev.type = ClientMessage;
- ev.window = w;
- ev.message_type = prop;
- ev.format = 32;
- ev.data.l[0] = IconicState;
- return (XSendEvent (dpy, root, False,
- SubstructureRedirectMask|SubstructureNotifyMask,
- (XEvent *)&ev));
+ return (XSendEvent (dpy, root, False,
+ SubstructureRedirectMask|SubstructureNotifyMask,
+ (XEvent *)&ev));
+ }
}
diff --git a/libX11/src/ReconfWM.c b/libX11/src/ReconfWM.c
index 1776f2e15..8dc3534e0 100644
--- a/libX11/src/ReconfWM.c
+++ b/libX11/src/ReconfWM.c
@@ -41,7 +41,6 @@ Status XReconfigureWMWindow (
unsigned int mask,
XWindowChanges *changes)
{
- XConfigureRequestEvent ev;
Window root = RootWindow (dpy, screen);
_XAsyncHandler async;
_XAsyncErrorState async_state;
@@ -120,20 +119,24 @@ Status XReconfigureWMWindow (
/*
* If the request succeeded, then everything is okay; otherwise, send event
*/
- if (!async_state.error_count) return True;
-
- ev.type = ConfigureRequest;
- ev.window = w;
- ev.parent = root;
- ev.value_mask = (mask & AllMaskBits);
- ev.x = changes->x;
- ev.y = changes->y;
- ev.width = changes->width;
- ev.height = changes->height;
- ev.border_width = changes->border_width;
- ev.above = changes->sibling;
- ev.detail = changes->stack_mode;
- return (XSendEvent (dpy, root, False,
- SubstructureRedirectMask|SubstructureNotifyMask,
- (XEvent *)&ev));
+ if (!async_state.error_count)
+ return True;
+ else {
+ XConfigureRequestEvent ev = {
+ .type = ConfigureRequest,
+ .window = w,
+ .parent = root,
+ .value_mask = (mask & AllMaskBits),
+ .x = changes->x,
+ .y = changes->y,
+ .width = changes->width,
+ .height = changes->height,
+ .border_width = changes->border_width,
+ .above = changes->sibling,
+ .detail = changes->stack_mode,
+ };
+ return (XSendEvent (dpy, root, False,
+ SubstructureRedirectMask|SubstructureNotifyMask,
+ (XEvent *)&ev));
+ }
}
diff --git a/libX11/src/Withdraw.c b/libX11/src/Withdraw.c
index ac15ddc92..1015f5b86 100644
--- a/libX11/src/Withdraw.c
+++ b/libX11/src/Withdraw.c
@@ -67,16 +67,18 @@ Status XWithdrawWindow (
Window w,
int screen)
{
- XUnmapEvent ev;
- Window root = RootWindow (dpy, screen);
-
XUnmapWindow (dpy, w);
- ev.type = UnmapNotify;
- ev.event = root;
- ev.window = w;
- ev.from_configure = False;
- return (XSendEvent (dpy, root, False,
- SubstructureRedirectMask|SubstructureNotifyMask,
- (XEvent *)&ev));
+ {
+ Window root = RootWindow (dpy, screen);
+ XUnmapEvent ev = {
+ .type = UnmapNotify,
+ .event = root,
+ .window = w,
+ .from_configure = False
+ };
+ return (XSendEvent (dpy, root, False,
+ SubstructureRedirectMask|SubstructureNotifyMask,
+ (XEvent *)&ev));
+ }
}
diff --git a/libX11/src/xkb/XKB.c b/libX11/src/xkb/XKB.c
index 6413ba274..03a89d07d 100644
--- a/libX11/src/xkb/XKB.c
+++ b/libX11/src/xkb/XKB.c
@@ -696,9 +696,7 @@ XkbGetPerClientControls(Display *dpy, unsigned *ctrls)
if ((dpy->flags & XlibDisplayNoXkb) ||
(!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) ||
- (*ctrls & ~(XkbPCF_GrabsUseXKBStateMask |
- XkbPCF_LookupStateWhenGrabbed |
- XkbPCF_SendEventUsesXKBState)))
+ (ctrls == NULL))
return False;
LockDisplay(dpy);
xkbi = dpy->xkb_info;
@@ -716,10 +714,9 @@ XkbGetPerClientControls(Display *dpy, unsigned *ctrls)
}
UnlockDisplay(dpy);
SyncHandle();
- if (ctrls)
- *ctrls = (rep.value & (XkbPCF_GrabsUseXKBStateMask |
- XkbPCF_LookupStateWhenGrabbed |
- XkbPCF_SendEventUsesXKBState));
+ *ctrls = (rep.value & (XkbPCF_GrabsUseXKBStateMask |
+ XkbPCF_LookupStateWhenGrabbed |
+ XkbPCF_SendEventUsesXKBState));
return (True);
}
diff --git a/libX11/src/xkb/XKBMAlloc.c b/libX11/src/xkb/XKBMAlloc.c
index 0b86aa1d5..2e39634a7 100644
--- a/libX11/src/xkb/XKBMAlloc.c
+++ b/libX11/src/xkb/XKBMAlloc.c
@@ -300,7 +300,7 @@ XkbAddKeyType(XkbDescPtr xkb,
}
}
}
- if ((!map) || (!map->types) || (!map->num_types < XkbNumRequiredTypes)) {
+ if ((!map) || (!map->types) || (map->num_types < XkbNumRequiredTypes)) {
tmp = XkbNumRequiredTypes + 1;
if (XkbAllocClientMap(xkb, XkbKeyTypesMask, tmp) != Success)
return NULL;
diff --git a/libxcb/doc/tutorial/index.html b/libxcb/doc/tutorial/index.html
index adec0acd3..ea0833745 100644
--- a/libxcb/doc/tutorial/index.html
+++ b/libxcb/doc/tutorial/index.html
@@ -150,7 +150,7 @@
<li><a class="subsection" href="#DoesBackingStore">DoesBackingStore</a>
<li><a class="subsection" href="#EventMaskOfScreen">EventMaskOfScreen</a>
</ol>
- <li><a class="subsection" href="#misc">Miscellaneaous macros</a>
+ <li><a class="subsection" href="#misc">Miscellaneous macros</a>
<ol>
<li><a class="subsection" href="#DisplayOfScreen">DisplayOfScreen</a>
<li><a class="subsection" href="#DisplayCells">DisplayCells / CellsOfScreen</a>
@@ -1331,7 +1331,7 @@ main ()
/* We draw the polygonal line */
xcb_poly_line (c, XCB_COORD_MODE_PREVIOUS, win, foreground, 4, polyline);
- /* We draw the segements */
+ /* We draw the segments */
xcb_poly_segment (c, win, foreground, 2, segments);
/* We draw the rectangles */
@@ -1470,10 +1470,10 @@ xcb_change_window_attributes (c, win, XCB_CW_EVENT_MASK, values);
</pre>
<div class="emph">
<p>
- Note: A common bug programmers do is adding code to handle new
+ Note: A common bug programmers have is adding code to handle new
event types in their program, while forgetting to add the
masks for these events in the creation of the window. Such a
- programmer then should sit down for hours debugging his
+ programmer would then sit there for hours debugging their
program, wondering "Why doesn't my program notice that I
released the button?", only to find that they registered for
button press events but not for button release events.
@@ -1830,7 +1830,7 @@ typedef xcb_enter_notify_event_t xcb_leave_notify_event_t;
keyboard focus using the window manager (often by clicking
on the title bar of the desired window). Once our window
has the keyboard focus, every key press or key release will
- cause an event to be sent to our program (if it regsitered
+ cause an event to be sent to our program (if it registered
for these event types...).
</p>
<li class="subsubtitle"><a name="keypress">Keyboard press and release events</a>
@@ -2090,7 +2090,7 @@ xcb_void_cookie_t xcb_open_font (xcb_connection_t *c,
Once a font is opened, you have to create a Graphic Context
that will contain the informations about the color of the
foreground and the background used when you draw a text in a
- Drawable. Here is an exemple of a Graphic Context that will
+ Drawable. Here is an example of a Graphic Context that will
allow us to draw an opened font with a black foreground and a
white background:
</p>
@@ -2404,7 +2404,7 @@ xcb_void_cookie_t xcb_change_property (xcb_connection_t *c, /* Connection
const void *data); /* Data */
</pre>
<p>
- The <span class="code">mode</span> parameter coud be one of
+ The <span class="code">mode</span> parameter could be one of
the following values (defined in enumeration xcb_prop_mode_t in
the xproto.h header file):
</p>
@@ -2939,7 +2939,7 @@ xcb_get_window_attributes_reply_t *xcb_get_window_attributes_reply (xcb_connecti
latter case, each time the mouse moves onto your window, the
screen color map will be replaced by your window's color map,
and you'll see all the other windows on screen change their
- colors into something quite bizzare. In fact, this is the
+ colors into something quite bizarre. In fact, this is the
effect you get with X applications that use the "-install"
command line option.
</p>
@@ -3302,10 +3302,10 @@ xcb_void_cookie_t xcb_free_pixmap (xcb_connection_t *c, /* Pointer to the
<li class="title"><a name="mousecursor">Messing with the mouse cursor</a>
<p>
It it possible to modify the shape of the mouse pointer (also
- called the X pointer) when in certain states, as we otfen see in
+ called the X pointer) when in certain states, as we often see in
programs. For example, a busy application would often display
- the sand clock over its main window, to give the user a visual
- hint that he should wait. Let's see how we can change the mouse
+ the hourglass cursor over its main window, to give the user a visual
+ hint that they should wait. Let's see how we can change the mouse
cursor of our windows.
</p>
<ol>
@@ -3341,7 +3341,7 @@ xcb_void_cookie_t xcb_create_glyph_cursor (xcb_connection_t *c,
</p>
<p>
So we first open that font (see <a href="#loadfont">Loading a Font</a>)
- and create the new cursor. As for every X ressource, we have to
+ and create the new cursor. As for every X resource, we have to
ask for an X id with <span class="code">xcb_generate_id</span>
first:
</p>
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 48f5f815e..744e55ce3 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -1881,9 +1881,10 @@ radeon_llvm_check() {
AC_MSG_ERROR([--enable-gallium-llvm is required when building $1])
fi
LLVM_REQUIRED_VERSION_MAJOR="3"
- LLVM_REQUIRED_VERSION_MINOR="3"
- if test "$LLVM_VERSION_INT" -lt "${LLVM_REQUIRED_VERSION_MAJOR}0${LLVM_REQUIRED_VERSION_MINOR}"; then
- AC_MSG_ERROR([LLVM $LLVM_REQUIRED_VERSION_MAJOR.$LLVM_REQUIRED_VERSION_MINOR or newer is required for $1])
+ LLVM_REQUIRED_VERSION_MINOR="4"
+ LLVM_REQUIRED_VERSION_PATCH="2"
+ if test "${LLVM_VERSION_INT}${LLVM_VERSION_PATCH}" -lt "${LLVM_REQUIRED_VERSION_MAJOR}0${LLVM_REQUIRED_VERSION_MINOR}${LLVM_REQUIRED_VERSION_PATCH}"; then
+ AC_MSG_ERROR([LLVM $LLVM_REQUIRED_VERSION_MAJOR.$LLVM_REQUIRED_VERSION_MINOR.$LLVM_REQUIRED_VERSION_PATCH or newer is required for $1])
fi
if test true && $LLVM_CONFIG --targets-built | grep -qvw 'R600' ; then
AC_MSG_ERROR([LLVM R600 Target not enabled. You can enable it when building the LLVM
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt
index 296e14cdf..0f37da410 100644
--- a/mesalib/docs/GL3.txt
+++ b/mesalib/docs/GL3.txt
@@ -98,7 +98,7 @@ GL 4.0:
GLSL 4.0 not started
GL_ARB_draw_buffers_blend DONE (i965, nv50, nvc0, r600, radeonsi, softpipe)
- GL_ARB_draw_indirect DONE (i965)
+ GL_ARB_draw_indirect DONE (i965, nvc0, radeonsi, softpipe, llvmpipe)
GL_ARB_gpu_shader5 started
- 'precise' qualifier DONE
- Dynamically uniform sampler array indices started (Chris)
@@ -110,7 +110,7 @@ GL 4.0:
- Geometry shader instancing DONE (i965, nvc0)
- Geometry shader multiple streams DONE (i965, nvc0)
- Enhanced per-sample shading DONE (i965)
- - Interpolation functions started (Chris)
+ - Interpolation functions DONE (i965)
- New overload resolution rules DONE
GL_ARB_gpu_shader_fp64 started (Dave)
GL_ARB_sample_shading DONE (i965, nv50, nvc0, radeonsi)
@@ -118,7 +118,7 @@ GL 4.0:
GL_ARB_tessellation_shader started (Fabian)
GL_ARB_texture_buffer_object_rgb32 DONE (i965, nvc0, r600, radeonsi, softpipe)
GL_ARB_texture_cube_map_array DONE (i965, nv50, nvc0, r600, radeonsi, softpipe)
- GL_ARB_texture_gather DONE (i965, nv50, nvc0, radeonsi)
+ GL_ARB_texture_gather DONE (i965, nv50, nvc0, radeonsi, r600)
GL_ARB_texture_query_lod DONE (i965, nv50, nvc0, radeonsi)
GL_ARB_transform_feedback2 DONE (i965, nv50, nvc0, r600, radeonsi)
GL_ARB_transform_feedback3 DONE (i965, nv50, nvc0, r600, radeonsi)
@@ -165,7 +165,7 @@ GL 4.3:
GL_ARB_framebuffer_no_attachments not started
GL_ARB_internalformat_query2 not started
GL_ARB_invalidate_subdata DONE (all drivers)
- GL_ARB_multi_draw_indirect DONE (i965)
+ GL_ARB_multi_draw_indirect DONE (i965, nvc0, radeonsi, softpipe, llvmpipe)
GL_ARB_program_interface_query not started
GL_ARB_robust_buffer_access_behavior not started
GL_ARB_shader_image_size not started
diff --git a/mesalib/docs/index.html b/mesalib/docs/index.html
index d3882f063..8aef51a18 100644
--- a/mesalib/docs/index.html
+++ b/mesalib/docs/index.html
@@ -16,6 +16,12 @@
<h1>News</h1>
+<h2>July 78, 2014</h2>
+<p>
+<a href="relnotes/10.2.4.html">Mesa 10.2.4</a> is released.
+This is a bug-fix release.
+</p>
+
<h2>July 7, 2014</h2>
<p>
<a href="relnotes/10.2.3.html">Mesa 10.2.3</a> is released.
diff --git a/mesalib/docs/relnotes.html b/mesalib/docs/relnotes.html
index ba88d1a26..ca008830a 100644
--- a/mesalib/docs/relnotes.html
+++ b/mesalib/docs/relnotes.html
@@ -21,6 +21,7 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<ul>
+<li><a href="relnotes/10.2.4.html">10.2.4 release notes</a>
<li><a href="relnotes/10.2.3.html">10.2.3 release notes</a>
<li><a href="relnotes/10.2.2.html">10.2.2 release notes</a>
<li><a href="relnotes/10.2.1.html">10.2.1 release notes</a>
diff --git a/mesalib/docs/relnotes/10.2.4.html b/mesalib/docs/relnotes/10.2.4.html
new file mode 100644
index 000000000..9ded82983
--- /dev/null
+++ b/mesalib/docs/relnotes/10.2.4.html
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Mesa Release Notes</title>
+ <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+ <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.2.4 Release Notes / July 18, 2014</h1>
+
+<p>
+Mesa 10.2.4 is a bug fix release which fixes bugs found since the 10.2.3 release.
+</p>
+<p>
+Mesa 10.2.4 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3. OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+06a2341244eb85c283f59f70161e06ded106f835ed9b6be1ef0243bd9344811a MesaLib-10.2.4.tar.bz2
+33e3c8b4343503e7d7d17416c670438860a2fd99ec93ea3327f73c3abe33b5e4 MesaLib-10.2.4.tar.gz
+e26791a4a62a61b82e506e6ba031812d09697d1a831e8239af67e5722a8ee538 MesaLib-10.2.4.zip
+</pre>
+
+<h2>New features</h2>
+<p>None</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81157">Bug 81157</a> - [BDW]Piglit some spec_glsl-1.50_execution_built-in-functions* cases fail</li>
+
+</ul>
+
+<h2>Changes</h2>
+
+<p>Abdiel Janulgue (3):</p>
+<ul>
+ <li>i965/fs: Refactor check for potential copy propagated instructions.</li>
+ <li>i965/fs: skip copy-propate for logical instructions with negated src entries</li>
+ <li>i965/vec4: skip copy-propate for logical instructions with negated src entries</li>
+</ul>
+
+<p>Brian Paul (3):</p>
+<ul>
+ <li>mesa: fix geometry shader memory leaks</li>
+ <li>st/mesa: fix geometry shader memory leak</li>
+ <li>gallium/u_blitter: fix some shader memory leaks</li>
+</ul>
+
+<p>Carl Worth (2):</p>
+<ul>
+ <li>docs: Add sha256 checksums for the 10.2.3 release</li>
+ <li>Update VERSION to 10.2.4</li>
+</ul>
+
+<p>Eric Anholt (1):</p>
+<ul>
+ <li>i965: Generalize the pixel_x/y workaround for all UW types.</li>
+</ul>
+
+<p>Ilia Mirkin (4):</p>
+<ul>
+ <li>nv50/ir: retrieve shadow compare from first arg</li>
+ <li>nv50/ir: ignore bias for samplerCubeShadow on nv50</li>
+ <li>nvc0/ir: do quadops on the right texture coordinates for TXD</li>
+ <li>nvc0/ir: use manual TXD when offsets are involved</li>
+</ul>
+
+<p>Jordan Justen (1):</p>
+<ul>
+ <li>i965: Add auxiliary surface field #defines for Broadwell.</li>
+</ul>
+
+<p>Kenneth Graunke (9):</p>
+<ul>
+ <li>i965: Don't copy propagate abs into Broadwell logic instructions.</li>
+ <li>i965: Set execution size to 8 for instructions with force_sechalf set.</li>
+ <li>i965/fs: Set force_uncompressed and force_sechalf on samplepos setup.</li>
+ <li>i965/fs: Use WE_all for gl_SampleID header register munging.</li>
+ <li>i965: Add plumbing for Broadwell's auxiliary surface support.</li>
+ <li>i965: Drop SINT workaround for CMS layout on Broadwell.</li>
+ <li>i965: Hook up the MCS buffers in SURFACE_STATE on Broadwell.</li>
+ <li>i965: Add 2x MSAA support to the MCS allocation function.</li>
+ <li>i965: Enable compressed multisample support (CMS) on Broadwell.</li>
+</ul>
+
+<p>Marek Olšák (4):</p>
+<ul>
+ <li>gallium: fix u_default_transfer_inline_write for textures</li>
+ <li>st/mesa: fix samplerCubeShadow with bias</li>
+ <li>radeonsi: fix samplerCubeShadow with bias</li>
+ <li>radeonsi: add support for TXB2</li>
+</ul>
+
+<p>Matt Turner (8):</p>
+<ul>
+ <li>i965/vec4: Don't return void from a void function.</li>
+ <li>i965/vec4: Don't fix_math_operand() on Gen &gt;= 8.</li>
+ <li>i965/fs: Don't fix_math_operand() on Gen &gt;= 8.</li>
+ <li>i965/fs: Make try_constant_propagate() static.</li>
+ <li>i965/fs: Constant propagate into 2-src math instructions on Gen8.</li>
+ <li>i965/vec4: Constant propagate into 2-src math instructions on Gen8.</li>
+ <li>i965/fs: Don't use brw_imm_* unnecessarily.</li>
+ <li>i965/fs: Set correct number of regs_written for MCS fetches.</li>
+</ul>
+
+</div>
+</body>
+</html>
diff --git a/mesalib/docs/relnotes/10.3.html b/mesalib/docs/relnotes/10.3.html
index 2e718fc8a..90247c09c 100644
--- a/mesalib/docs/relnotes/10.3.html
+++ b/mesalib/docs/relnotes/10.3.html
@@ -45,11 +45,13 @@ Note: some of the new features are only available with certain drivers.
<ul>
<li>GL_ARB_compressed_texture_pixel_storage on all drivers</li>
+<li>GL_ARB_draw_indirect on nvc0, radeonsi</li>
<li>GL_ARB_explicit_uniform_location (all drivers that support GLSL)</li>
+<li>GL_ARB_multi_draw_indirect on nvc0, radeonsi</li>
<li>GL_ARB_sample_shading on radeonsi</li>
<li>GL_ARB_stencil_texturing on nv50, nvc0, r600, and radeonsi</li>
<li>GL_ARB_texture_cube_map_array on radeonsi</li>
-<li>GL_ARB_texture_gather on radeonsi</li>
+<li>GL_ARB_texture_gather on radeonsi, r600</li>
<li>GL_ARB_texture_query_levels on nv50, nvc0, llvmpipe, r600, radeonsi, softpipe</li>
<li>GL_ARB_texture_query_lod on radeonsi</li>
<li>GL_ARB_viewport_array on nvc0</li>
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index cdb34cc69..4981fe174 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -178,6 +178,24 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
return false;
}
+ /* Verify that shader_in parameters are shader inputs */
+ if (formal->data.must_be_shader_input) {
+ ir_variable *var = actual->variable_referenced();
+ if (var && var->data.mode != ir_var_shader_in) {
+ _mesa_glsl_error(&loc, state,
+ "parameter `%s` must be a shader input",
+ formal->name);
+ return false;
+ }
+
+ if (actual->ir_type == ir_type_swizzle) {
+ _mesa_glsl_error(&loc, state,
+ "parameter `%s` must not be swizzled",
+ formal->name);
+ return false;
+ }
+ }
+
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
if (formal->data.mode == ir_var_function_out
|| formal->data.mode == ir_var_function_inout) {
@@ -742,11 +760,22 @@ process_vec_mat_constructor(exec_list *instructions,
instructions->push_tail(var);
int i = 0;
+
foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
- ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
- new(ctx) ir_constant(i));
+ ir_instruction *assignment = NULL;
+
+ if (var->type->is_matrix()) {
+ ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
+ new(ctx) ir_constant(i));
+ assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
+ } else {
+ /* use writemask rather than index for vector */
+ assert(var->type->is_vector());
+ assert(i < 4);
+ ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
+ assignment = new(ctx) ir_assignment(lhs, rhs, NULL, (unsigned)(1 << i));
+ }
- ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
instructions->push_tail(assignment);
i++;
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 885bee547..328cd1b1b 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -4513,6 +4513,12 @@ ast_switch_statement::hir(exec_list *instructions,
instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var,
is_break_val));
+ state->switch_state.run_default =
+ new(ctx) ir_variable(glsl_type::bool_type,
+ "run_default_tmp",
+ ir_var_temporary);
+ instructions->push_tail(state->switch_state.run_default);
+
/* Cache test expression.
*/
test_to_hir(instructions, state);
@@ -4567,8 +4573,71 @@ ir_rvalue *
ast_case_statement_list::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
- foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases)
- case_stmt->hir(instructions, state);
+ exec_list default_case, after_default, tmp;
+
+ foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) {
+ case_stmt->hir(&tmp, state);
+
+ /* Default case. */
+ if (state->switch_state.previous_default && default_case.is_empty()) {
+ default_case.append_list(&tmp);
+ continue;
+ }
+
+ /* If default case found, append 'after_default' list. */
+ if (!default_case.is_empty())
+ after_default.append_list(&tmp);
+ else
+ instructions->append_list(&tmp);
+ }
+
+ /* Handle the default case. This is done here because default might not be
+ * the last case. We need to add checks against following cases first to see
+ * if default should be chosen or not.
+ */
+ if (!default_case.is_empty()) {
+
+ /* Default case was the last one, no checks required. */
+ if (after_default.is_empty()) {
+ instructions->append_list(&default_case);
+ return NULL;
+ }
+
+ ir_rvalue *const true_val = new (state) ir_constant(true);
+ ir_dereference_variable *deref_run_default_var =
+ new(state) ir_dereference_variable(state->switch_state.run_default);
+
+ /* Choose to run default case initially, following conditional
+ * assignments might change this.
+ */
+ ir_assignment *const init_var =
+ new(state) ir_assignment(deref_run_default_var, true_val);
+ instructions->push_tail(init_var);
+
+ foreach_in_list(ir_instruction, ir, &after_default) {
+ ir_assignment *assign = ir->as_assignment();
+
+ if (!assign)
+ continue;
+
+ /* Clone the check between case label and init expression. */
+ ir_expression *exp = (ir_expression*) assign->condition;
+ ir_expression *clone = exp->clone(state, NULL);
+
+ ir_dereference_variable *deref_var =
+ new(state) ir_dereference_variable(state->switch_state.run_default);
+ ir_rvalue *const false_val = new (state) ir_constant(false);
+
+ ir_assignment *const set_false =
+ new(state) ir_assignment(deref_var, false_val, clone);
+
+ instructions->push_tail(set_false);
+ }
+
+ /* Append default case and all cases after it. */
+ instructions->append_list(&default_case);
+ instructions->append_list(&after_default);
+ }
/* Case statements do not have r-values. */
return NULL;
@@ -4728,9 +4797,17 @@ ast_case_label::hir(exec_list *instructions,
}
state->switch_state.previous_default = this;
+ /* Set fallthru condition on 'run_default' bool. */
+ ir_dereference_variable *deref_run_default =
+ new(ctx) ir_dereference_variable(state->switch_state.run_default);
+ ir_rvalue *const cond_true = new(ctx) ir_constant(true);
+ ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
+ cond_true,
+ deref_run_default);
+
/* Set falltrhu state. */
ir_assignment *set_fallthru =
- new(ctx) ir_assignment(deref_fallthru_var, true_val);
+ new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
instructions->push_tail(set_fallthru);
}
@@ -5007,9 +5084,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
* 'declarations' list in each of the elements.
*/
foreach_list_typed (ast_declarator_list, decl_list, link, declarations) {
- foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) {
- decl_count++;
- }
+ decl_count += decl_list->declarations.length();
}
/* Allocate storage for the fields and process the field
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
index 258b83142..e01742c4d 100644
--- a/mesalib/src/glsl/builtin_functions.cpp
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -226,6 +226,14 @@ shader_packing_or_gpu_shader5(const _mesa_glsl_parse_state *state)
}
static bool
+fs_gpu_shader5(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT &&
+ (state->is_version(400, 0) || state->ARB_gpu_shader5_enable);
+}
+
+
+static bool
texture_array_lod(const _mesa_glsl_parse_state *state)
{
return lod_exists_in_stage(state) &&
@@ -627,6 +635,9 @@ private:
B1(uaddCarry)
B1(usubBorrow)
B1(mulExtended)
+ B1(interpolateAtCentroid)
+ B1(interpolateAtOffset)
+ B1(interpolateAtSample)
ir_function_signature *_atomic_intrinsic(builtin_available_predicate avail);
ir_function_signature *_atomic_op(const char *intrinsic,
@@ -2186,6 +2197,24 @@ builtin_builder::create_builtins()
_mulExtended(glsl_type::uvec3_type),
_mulExtended(glsl_type::uvec4_type),
NULL);
+ add_function("interpolateAtCentroid",
+ _interpolateAtCentroid(glsl_type::float_type),
+ _interpolateAtCentroid(glsl_type::vec2_type),
+ _interpolateAtCentroid(glsl_type::vec3_type),
+ _interpolateAtCentroid(glsl_type::vec4_type),
+ NULL);
+ add_function("interpolateAtOffset",
+ _interpolateAtOffset(glsl_type::float_type),
+ _interpolateAtOffset(glsl_type::vec2_type),
+ _interpolateAtOffset(glsl_type::vec3_type),
+ _interpolateAtOffset(glsl_type::vec4_type),
+ NULL);
+ add_function("interpolateAtSample",
+ _interpolateAtSample(glsl_type::float_type),
+ _interpolateAtSample(glsl_type::vec2_type),
+ _interpolateAtSample(glsl_type::vec3_type),
+ _interpolateAtSample(glsl_type::vec4_type),
+ NULL);
add_function("atomicCounter",
_atomic_op("__intrinsic_atomic_read",
@@ -4260,6 +4289,44 @@ builtin_builder::_mulExtended(const glsl_type *type)
}
ir_function_signature *
+builtin_builder::_interpolateAtCentroid(const glsl_type *type)
+{
+ ir_variable *interpolant = in_var(type, "interpolant");
+ interpolant->data.must_be_shader_input = 1;
+ MAKE_SIG(type, fs_gpu_shader5, 1, interpolant);
+
+ body.emit(ret(interpolate_at_centroid(interpolant)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_interpolateAtOffset(const glsl_type *type)
+{
+ ir_variable *interpolant = in_var(type, "interpolant");
+ interpolant->data.must_be_shader_input = 1;
+ ir_variable *offset = in_var(glsl_type::vec2_type, "offset");
+ MAKE_SIG(type, fs_gpu_shader5, 2, interpolant, offset);
+
+ body.emit(ret(interpolate_at_offset(interpolant, offset)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_interpolateAtSample(const glsl_type *type)
+{
+ ir_variable *interpolant = in_var(type, "interpolant");
+ interpolant->data.must_be_shader_input = 1;
+ ir_variable *sample_num = in_var(glsl_type::int_type, "sample_num");
+ MAKE_SIG(type, fs_gpu_shader5, 2, interpolant, sample_num);
+
+ body.emit(ret(interpolate_at_sample(interpolant, sample_num)));
+
+ return sig;
+}
+
+ir_function_signature *
builtin_builder::_atomic_intrinsic(builtin_available_predicate avail)
{
ir_variable *counter = in_var(glsl_type::atomic_uint_type, "counter");
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index b9897498f..4c871633f 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -376,6 +376,14 @@ external_declaration_list:
if ($2 != NULL)
state->translation_unit.push_tail(& $2->link);
}
+ | external_declaration_list extension_statement {
+ if (!state->allow_extension_directive_midshader) {
+ _mesa_glsl_error(& @2, state,
+ "#extension directive is not allowed "
+ "in the middle of a shader");
+ YYERROR;
+ }
+ }
;
variable_identifier:
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index b327c2b43..890123ad1 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -210,6 +210,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->early_fragment_tests = false;
memset(this->atomic_counter_offsets, 0,
sizeof(this->atomic_counter_offsets));
+ this->allow_extension_directive_midshader =
+ ctx->Const.AllowGLSLExtensionDirectiveMidShader;
}
/**
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 17918163e..ce66e2fa4 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -43,6 +43,9 @@ struct glsl_switch_state {
ir_variable *is_break_var;
class ast_switch_statement *switch_nesting_ast;
+ /** Used to set condition if 'default' label should be chosen. */
+ ir_variable *run_default;
+
/** Table of constant values already used in case labels */
struct hash_table *labels_ht;
class ast_case_label *previous_default;
@@ -490,6 +493,8 @@ struct _mesa_glsl_parse_state {
/** Atomic counter offsets by binding */
unsigned atomic_counter_offsets[MAX_COMBINED_ATOMIC_BUFFERS];
+
+ bool allow_extension_directive_midshader;
};
# define YYLLOC_DEFAULT(Current, Rhs, N) \
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 1d8bb6e7b..28fd94b95 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -250,6 +250,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
case ir_unop_dFdx:
case ir_unop_dFdy:
case ir_unop_bitfield_reverse:
+ case ir_unop_interpolate_at_centroid:
this->type = op0->type;
break;
@@ -403,6 +404,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
case ir_binop_rshift:
case ir_binop_bfm:
case ir_binop_ldexp:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
this->type = op0->type;
break;
@@ -524,6 +527,7 @@ static const char *const operator_strs[] = {
"find_msb",
"find_lsb",
"noise",
+ "interpolate_at_centroid",
"+",
"-",
"*",
@@ -557,6 +561,8 @@ static const char *const operator_strs[] = {
"ubo_load",
"ldexp",
"vector_extract",
+ "interpolate_at_offset",
+ "interpolate_at_sample",
"fma",
"lrp",
"csel",
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index d5239d4de..ea19924ab 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -678,6 +678,12 @@ public:
unsigned from_named_ifc_block_array:1;
/**
+ * Non-zero if the variable must be a shader input. This is useful for
+ * constraints on function parameters.
+ */
+ unsigned must_be_shader_input:1;
+
+ /**
* \brief Layout qualifier for gl_FragDepth.
*
* This is not equal to \c ir_depth_layout_none if and only if this
@@ -1234,9 +1240,16 @@ enum ir_expression_operation {
ir_unop_noise,
/**
+ * Interpolate fs input at centroid
+ *
+ * operand0 is the fs input.
+ */
+ ir_unop_interpolate_at_centroid,
+
+ /**
* A sentinel marking the last of the unary operations.
*/
- ir_last_unop = ir_unop_noise,
+ ir_last_unop = ir_unop_interpolate_at_centroid,
ir_binop_add,
ir_binop_sub,
@@ -1355,9 +1368,25 @@ enum ir_expression_operation {
ir_binop_vector_extract,
/**
+ * Interpolate fs input at offset
+ *
+ * operand0 is the fs input
+ * operand1 is the offset from the pixel center
+ */
+ ir_binop_interpolate_at_offset,
+
+ /**
+ * Interpolate fs input at sample position
+ *
+ * operand0 is the fs input
+ * operand1 is the sample ID
+ */
+ ir_binop_interpolate_at_sample,
+
+ /**
* A sentinel marking the last of the binary operations.
*/
- ir_last_binop = ir_binop_vector_extract,
+ ir_last_binop = ir_binop_interpolate_at_sample,
/**
* \name Fused floating-point multiply-add, part of ARB_gpu_shader5.
diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp
index f4a1c6efa..f03941443 100644
--- a/mesalib/src/glsl/ir_builder.cpp
+++ b/mesalib/src/glsl/ir_builder.cpp
@@ -501,6 +501,24 @@ b2f(operand a)
}
ir_expression *
+interpolate_at_centroid(operand a)
+{
+ return expr(ir_unop_interpolate_at_centroid, a);
+}
+
+ir_expression *
+interpolate_at_offset(operand a, operand b)
+{
+ return expr(ir_binop_interpolate_at_offset, a, b);
+}
+
+ir_expression *
+interpolate_at_sample(operand a, operand b)
+{
+ return expr(ir_binop_interpolate_at_sample, a, b);
+}
+
+ir_expression *
fma(operand a, operand b, operand c)
{
return expr(ir_triop_fma, a, b, c);
diff --git a/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h
index 108b53a5e..573596cf1 100644
--- a/mesalib/src/glsl/ir_builder.h
+++ b/mesalib/src/glsl/ir_builder.h
@@ -186,6 +186,10 @@ ir_expression *b2f(operand a);
ir_expression *min2(operand a, operand b);
ir_expression *max2(operand a, operand b);
+ir_expression *interpolate_at_centroid(operand a);
+ir_expression *interpolate_at_offset(operand a, operand b);
+ir_expression *interpolate_at_sample(operand a, operand b);
+
ir_expression *fma(operand a, operand b, operand c);
ir_expression *lrp(operand x, operand y, operand a);
ir_expression *csel(operand a, operand b, operand c);
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index 7f83eb134..5570ed46f 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -510,6 +510,8 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
case ir_binop_lshift:
case ir_binop_rshift:
case ir_binop_ldexp:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
case ir_binop_vector_extract:
case ir_triop_csel:
case ir_triop_bitfield_extract:
diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.cpp b/mesalib/src/glsl/ir_hierarchical_visitor.cpp
index d3c00ecdb..adb629414 100644
--- a/mesalib/src/glsl/ir_hierarchical_visitor.cpp
+++ b/mesalib/src/glsl/ir_hierarchical_visitor.cpp
@@ -27,16 +27,18 @@
ir_hierarchical_visitor::ir_hierarchical_visitor()
{
this->base_ir = NULL;
- this->callback = NULL;
- this->data = NULL;
+ this->callback_enter = NULL;
+ this->callback_leave = NULL;
+ this->data_enter = NULL;
+ this->data_leave = NULL;
this->in_assignee = false;
}
ir_visitor_status
ir_hierarchical_visitor::visit(ir_rvalue *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -44,8 +46,8 @@ ir_hierarchical_visitor::visit(ir_rvalue *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_variable *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -53,8 +55,8 @@ ir_hierarchical_visitor::visit(ir_variable *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_constant *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -62,8 +64,8 @@ ir_hierarchical_visitor::visit(ir_constant *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_loop_jump *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -71,8 +73,8 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir)
ir_visitor_status
ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -80,8 +82,8 @@ ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_loop *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -89,15 +91,17 @@ ir_hierarchical_visitor::visit_enter(ir_loop *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_loop *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -105,15 +109,17 @@ ir_hierarchical_visitor::visit_enter(ir_function_signature *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_function_signature *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_function *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -121,15 +127,17 @@ ir_hierarchical_visitor::visit_enter(ir_function *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_function *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_expression *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -137,15 +145,17 @@ ir_hierarchical_visitor::visit_enter(ir_expression *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_expression *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_texture *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -153,15 +163,17 @@ ir_hierarchical_visitor::visit_enter(ir_texture *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_texture *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -169,15 +181,17 @@ ir_hierarchical_visitor::visit_enter(ir_swizzle *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_swizzle *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -185,15 +199,17 @@ ir_hierarchical_visitor::visit_enter(ir_dereference_array *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_dereference_array *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -201,15 +217,17 @@ ir_hierarchical_visitor::visit_enter(ir_dereference_record *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_dereference_record *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -217,15 +235,17 @@ ir_hierarchical_visitor::visit_enter(ir_assignment *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_assignment *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_call *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -233,15 +253,17 @@ ir_hierarchical_visitor::visit_enter(ir_call *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_call *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_return *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -249,15 +271,17 @@ ir_hierarchical_visitor::visit_enter(ir_return *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_return *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_discard *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -265,15 +289,17 @@ ir_hierarchical_visitor::visit_enter(ir_discard *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_discard *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_if *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -281,15 +307,17 @@ ir_hierarchical_visitor::visit_enter(ir_if *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_if *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_emit_vertex *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -297,15 +325,17 @@ ir_hierarchical_visitor::visit_enter(ir_emit_vertex *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_emit_vertex *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
ir_visitor_status
ir_hierarchical_visitor::visit_enter(ir_end_primitive *ir)
{
- if (this->callback != NULL)
- this->callback(ir, this->data);
+ if (this->callback_enter != NULL)
+ this->callback_enter(ir, this->data_enter);
return visit_continue;
}
@@ -313,7 +343,9 @@ ir_hierarchical_visitor::visit_enter(ir_end_primitive *ir)
ir_visitor_status
ir_hierarchical_visitor::visit_leave(ir_end_primitive *ir)
{
- (void) ir;
+ if (this->callback_leave != NULL)
+ this->callback_leave(ir, this->data_leave);
+
return visit_continue;
}
@@ -326,13 +358,17 @@ ir_hierarchical_visitor::run(exec_list *instructions)
void
visit_tree(ir_instruction *ir,
- void (*callback)(class ir_instruction *ir, void *data),
- void *data)
+ void (*callback_enter)(class ir_instruction *ir, void *data),
+ void *data_enter,
+ void (*callback_leave)(class ir_instruction *ir, void *data),
+ void *data_leave)
{
ir_hierarchical_visitor v;
- v.callback = callback;
- v.data = data;
+ v.callback_enter = callback_enter;
+ v.callback_leave = callback_leave;
+ v.data_enter = data_enter;
+ v.data_leave = data_leave;
ir->accept(&v);
}
diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.h b/mesalib/src/glsl/ir_hierarchical_visitor.h
index bc89a04d8..faa52fd79 100644
--- a/mesalib/src/glsl/ir_hierarchical_visitor.h
+++ b/mesalib/src/glsl/ir_hierarchical_visitor.h
@@ -163,14 +163,29 @@ public:
* \warning
* Visitor classes derived from \c ir_hierarchical_visitor \b may \b not
* invoke this function. This can be used, for example, to cause the
- * callback to be invoked on every node type execpt one.
+ * callback to be invoked on every node type except one.
*/
- void (*callback)(class ir_instruction *ir, void *data);
+ void (*callback_enter)(class ir_instruction *ir, void *data);
/**
- * Extra data parameter passed to the per-node callback function
+ * Callback function that is invoked on exit of each node visited.
+ *
+ * \warning
+ * Visitor classes derived from \c ir_hierarchical_visitor \b may \b not
+ * invoke this function. This can be used, for example, to cause the
+ * callback to be invoked on every node type except one.
+ */
+ void (*callback_leave)(class ir_instruction *ir, void *data);
+
+ /**
+ * Extra data parameter passed to the per-node callback_enter function
+ */
+ void *data_enter;
+
+ /**
+ * Extra data parameter passed to the per-node callback_leave function
*/
- void *data;
+ void *data_leave;
/**
* Currently in the LHS of an assignment?
@@ -181,8 +196,10 @@ public:
};
void visit_tree(ir_instruction *ir,
- void (*callback)(class ir_instruction *ir, void *data),
- void *data);
+ void (*callback_enter)(class ir_instruction *ir, void *data),
+ void *data_enter,
+ void (*callback_leave)(class ir_instruction *ir, void *data) = NULL,
+ void *data_leave = NULL);
ir_visitor_status visit_list_elements(ir_hierarchical_visitor *v, exec_list *l,
bool statement_list = true);
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 4017bdd73..e3566e1d6 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -723,10 +723,9 @@ ir_reader::read_expression(s_expression *expr)
ir_read_error(expr, "invalid operator: %s", s_op->value());
return NULL;
}
-
- int num_operands = -3; /* skip "expression" <type> <operation> */
- foreach_in_list(s_expression, e, &((s_list *) expr)->subexpressions)
- ++num_operands;
+
+ /* Skip "expression" <type> <operation> by subtracting 3. */
+ int num_operands = (int) ((s_list *) expr)->subexpressions.length() - 3;
int expected_operands = ir_expression::get_num_operands(op);
if (num_operands != expected_operands) {
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 271dbe096..37e1ce33e 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -49,8 +49,8 @@ public:
this->current_function = NULL;
- this->callback = ir_validate::validate_ir;
- this->data = ht;
+ this->callback_enter = ir_validate::validate_ir;
+ this->data_enter = ht;
}
~ir_validate()
@@ -100,7 +100,7 @@ ir_validate::visit(ir_dereference_variable *ir)
abort();
}
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
return visit_continue;
}
@@ -167,7 +167,7 @@ ir_validate::visit_enter(ir_function *ir)
*/
this->current_function = ir;
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
/* Verify that all of the things stored in the list of signatures are,
* in fact, function signatures.
@@ -211,7 +211,7 @@ ir_validate::visit_enter(ir_function_signature *ir)
abort();
}
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
return visit_continue;
}
@@ -371,6 +371,11 @@ ir_validate::visit_leave(ir_expression *ir)
/* XXX what can we assert here? */
break;
+ case ir_unop_interpolate_at_centroid:
+ assert(ir->operands[0]->type == ir->type);
+ assert(ir->operands[0]->type->is_float());
+ break;
+
case ir_binop_add:
case ir_binop_sub:
case ir_binop_mul:
@@ -510,6 +515,19 @@ ir_validate::visit_leave(ir_expression *ir)
&& ir->operands[1]->type->is_integer());
break;
+ case ir_binop_interpolate_at_offset:
+ assert(ir->operands[0]->type == ir->type);
+ assert(ir->operands[0]->type->is_float());
+ assert(ir->operands[1]->type->components() == 2);
+ assert(ir->operands[1]->type->is_float());
+ break;
+
+ case ir_binop_interpolate_at_sample:
+ assert(ir->operands[0]->type == ir->type);
+ assert(ir->operands[0]->type->is_float());
+ assert(ir->operands[1]->type == glsl_type::int_type);
+ break;
+
case ir_triop_fma:
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
assert(ir->type == ir->operands[0]->type);
@@ -708,7 +726,7 @@ ir_validate::visit_enter(ir_assignment *ir)
}
}
- this->validate_ir(ir, this->data);
+ this->validate_ir(ir, this->data_enter);
return visit_continue;
}
diff --git a/mesalib/src/glsl/list.h b/mesalib/src/glsl/list.h
index a4444bda9..3ee6cdaa9 100644
--- a/mesalib/src/glsl/list.h
+++ b/mesalib/src/glsl/list.h
@@ -325,6 +325,8 @@ struct exec_list {
const exec_node *get_tail() const;
exec_node *get_tail();
+ unsigned length() const;
+
void push_head(exec_node *n);
void push_tail(exec_node *n);
void push_degenerate_list_at_head(exec_node *n);
@@ -345,9 +347,15 @@ struct exec_list {
void move_nodes_to(exec_list *target);
/**
- * Append all nodes from the source list to the target list
+ * Append all nodes from the source list to the end of the target list
*/
void append_list(exec_list *source);
+
+ /**
+ * Prepend all nodes from the source list to the beginning of the target
+ * list
+ */
+ void prepend_list(exec_list *source);
#endif
};
@@ -399,6 +407,19 @@ exec_list_get_tail(struct exec_list *list)
return !exec_list_is_empty(list) ? list->tail_pred : NULL;
}
+static inline unsigned
+exec_list_length(const struct exec_list *list)
+{
+ unsigned size = 0;
+ struct exec_node *node;
+
+ for (node = list->head; node->next != NULL; node = node->next) {
+ size++;
+ }
+
+ return size;
+}
+
static inline void
exec_list_push_head(struct exec_list *list, struct exec_node *n)
{
@@ -479,6 +500,13 @@ exec_list_append(struct exec_list *list, struct exec_list *source)
}
static inline void
+exec_list_prepend(struct exec_list *list, struct exec_list *source)
+{
+ exec_list_append(source, list);
+ exec_list_move_nodes_to(source, list);
+}
+
+static inline void
exec_node_insert_list_before(struct exec_node *n, struct exec_list *before)
{
if (exec_list_is_empty(before))
@@ -524,6 +552,11 @@ inline exec_node *exec_list::get_tail()
return exec_list_get_tail(this);
}
+inline unsigned exec_list::length() const
+{
+ return exec_list_length(this);
+}
+
inline void exec_list::push_head(exec_node *n)
{
exec_list_push_head(this, n);
@@ -554,6 +587,11 @@ inline void exec_list::append_list(exec_list *source)
exec_list_append(this, source);
}
+inline void exec_list::prepend_list(exec_list *source)
+{
+ exec_list_prepend(this, source);
+}
+
inline void exec_node::insert_before(exec_list *before)
{
exec_node_insert_list_before(this, before);
diff --git a/mesalib/src/glsl/opt_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp
index b84bb8e11..64b4907ba 100644
--- a/mesalib/src/glsl/opt_function_inlining.cpp
+++ b/mesalib/src/glsl/opt_function_inlining.cpp
@@ -100,16 +100,13 @@ ir_call::generate_inline(ir_instruction *next_ir)
{
void *ctx = ralloc_parent(this);
ir_variable **parameters;
- int num_parameters;
+ unsigned num_parameters;
int i;
struct hash_table *ht;
ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare);
- num_parameters = 0;
- foreach_in_list(ir_rvalue, param, &this->callee->parameters)
- num_parameters++;
-
+ num_parameters = this->callee->parameters.length();
parameters = new ir_variable *[num_parameters];
/* Generate the declarations for the parameters to our inlined code,
diff --git a/mesalib/src/glsl/opt_rebalance_tree.cpp b/mesalib/src/glsl/opt_rebalance_tree.cpp
index 773aab3f6..095f2d7d2 100644
--- a/mesalib/src/glsl/opt_rebalance_tree.cpp
+++ b/mesalib/src/glsl/opt_rebalance_tree.cpp
@@ -60,6 +60,7 @@
#include "ir_visitor.h"
#include "ir_rvalue_visitor.h"
#include "ir_optimization.h"
+#include "main/macros.h" /* for MAX2 */
/* The DSW algorithm generates a degenerate tree (really, a linked list) in
* tree_to_vine(). We'd rather not leave a binary expression with only one
@@ -216,7 +217,9 @@ is_reduction(ir_instruction *ir, void *data)
* constant fold once split up. Handling matrices will need some more
* work.
*/
- if (expr->type->is_matrix()) {
+ if (expr->type->is_matrix() ||
+ expr->operands[0]->type->is_matrix() ||
+ (expr->operands[1] && expr->operands[1]->type->is_matrix())) {
ird->is_reduction = false;
return;
}
@@ -261,6 +264,22 @@ handle_expression(ir_expression *expr)
return expr;
}
+static void
+update_types(ir_instruction *ir, void *)
+{
+ ir_expression *expr = ir->as_expression();
+ if (!expr)
+ return;
+
+ const glsl_type *const new_type =
+ glsl_type::get_instance(expr->type->base_type,
+ MAX2(expr->operands[0]->type->vector_elements,
+ expr->operands[1]->type->vector_elements),
+ 1);
+ assert(new_type != glsl_type::error_type);
+ expr->type = new_type;
+}
+
void
ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
{
@@ -285,6 +304,8 @@ ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
if (new_rvalue == *rvalue)
return;
+ visit_tree(new_rvalue, NULL, NULL, update_types);
+
*rvalue = new_rvalue;
this->progress = true;
}
diff --git a/mesalib/src/mapi/glapi/gen/gl_gentable.py b/mesalib/src/mapi/glapi/gen/gl_gentable.py
index d45a5e0ff..9db6a773a 100644
--- a/mesalib/src/mapi/glapi/gen/gl_gentable.py
+++ b/mesalib/src/mapi/glapi/gen/gl_gentable.py
@@ -134,7 +134,11 @@ body_template = """
if(!disp->%(name)s) {
void ** procp = (void **) &disp->%(name)s;
snprintf(symboln, sizeof(symboln), "%%s%(entry_point)s", symbol_prefix);
+#ifdef _WIN32
+ *procp = GetProcAddress(handle, symboln);
+#else
*procp = dlsym(handle, symboln);
+#endif
}
"""
diff --git a/mesalib/src/mesa/drivers/dri/Makefile.am b/mesalib/src/mesa/drivers/dri/Makefile.am
index 70039f9ad..2009da921 100644
--- a/mesalib/src/mesa/drivers/dri/Makefile.am
+++ b/mesalib/src/mesa/drivers/dri/Makefile.am
@@ -85,7 +85,6 @@ install-data-hook:
ln -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so \
$(DESTDIR)$(dridir)/$$i; \
done;
- $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so
- $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.la
+ $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.*
endif
diff --git a/mesalib/src/mesa/drivers/dri/common/drirc b/mesalib/src/mesa/drivers/dri/common/drirc
index ebc04cd9b..4b9841bd2 100644
--- a/mesalib/src/mesa/drivers/dri/common/drirc
+++ b/mesalib/src/mesa/drivers/dri/common/drirc
@@ -11,17 +11,21 @@ Application bugs worked around in this file:
is still 1.10.
* Unigine Heaven 3.0 with ARB_texture_multisample uses a "ivec4 * vec4"
- expression, which fails to compile with GLSL 1.10.
+ expression, which is illegal in GLSL 1.10.
Adding "#version 130" fixes this.
* Unigine Heaven 3.0 with ARB_shader_bit_encoding uses the uint keyword, which
- fails to compile with GLSL 1.10.
+ is illegal in GLSL 1.10.
Adding "#version 130" fixes this.
* Unigine Heaven 3.0 with ARB_shader_bit_encoding uses a "uint & int"
- expression, which fails (and should fail) to compile with any GLSL version.
+ expression, which is illegal in any GLSL version.
Disabling ARB_shader_bit_encoding fixes this.
+* If ARB_sample_shading is supported, Unigine Heaven 4.0 and Valley 1.0 uses
+ an #extension directive in the middle of its shaders, which is illegal
+ in GLSL.
+
TODO: document the other workarounds.
-->
@@ -45,6 +49,7 @@ TODO: document the other workarounds.
<option name="disable_blend_func_extended" value="true" />
<option name="force_glsl_version" value="130" />
<option name="disable_shader_bit_encoding" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
</application>
<application name="Unigine Heaven (64-bit)" executable="heaven_x64">
@@ -52,6 +57,15 @@ TODO: document the other workarounds.
<option name="disable_blend_func_extended" value="true" />
<option name="force_glsl_version" value="130" />
<option name="disable_shader_bit_encoding" value="true" />
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Unigine Valley (32-bit)" executable="valley_x86">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
+ </application>
+
+ <application name="Unigine Valley (64-bit)" executable="valley_x64">
+ <option name="allow_glsl_extension_directive_midshader" value="true" />
</application>
<application name="Unigine OilRush (32-bit)" executable="OilRush_x86">
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
index fc9e10461..b73a6620c 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
+++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
@@ -105,6 +105,11 @@ DRI_CONF_OPT_BEGIN_V(force_glsl_version, int, def, "0:999") \
DRI_CONF_DESC(en,gettext("Force a default GLSL version for shaders that lack an explicit #version line")) \
DRI_CONF_OPT_END
+#define DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER(def) \
+DRI_CONF_OPT_BEGIN_B(allow_glsl_extension_directive_midshader, def) \
+ DRI_CONF_DESC(en,gettext("Allow GLSL #extension directives in the middle of shaders")) \
+DRI_CONF_OPT_END
+
/**
diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c
index efb993012..1ea319a74 100644
--- a/mesalib/src/mesa/main/arrayobj.c
+++ b/mesalib/src/mesa/main/arrayobj.c
@@ -427,6 +427,21 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
}
}
+ if (ctx->Array.DrawMethod == DRAW_ARRAYS) {
+ /* The _DrawArrays pointer is pointing at the VAO being unbound and
+ * that VAO may be in the process of being deleted. If it's not going
+ * to be deleted, this will have no effect, because the pointer needs
+ * to be updated by the VBO module anyway.
+ *
+ * Before the VBO module can update the pointer, we have to set it
+ * to NULL for drivers not to set up arrays which are not bound,
+ * or to prevent a crash if the VAO being unbound is going to be
+ * deleted.
+ */
+ ctx->Array._DrawArrays = NULL;
+ ctx->Array.DrawMethod = DRAW_NONE;
+ }
+
ctx->NewState |= _NEW_ARRAY;
_mesa_reference_vao(ctx, &ctx->Array.VAO, newObj);
diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c
index 6b28592a6..c97c05297 100644
--- a/mesalib/src/mesa/main/format_pack.c
+++ b/mesalib/src/mesa/main/format_pack.c
@@ -888,7 +888,7 @@ pack_float_R_UNORM8(const GLfloat src[4], void *dst)
static void
pack_ubyte_R8G8_UNORM(const GLubyte src[4], void *dst)
{
- GLubyte *d = ((GLubyte *) dst);
+ GLushort *d = ((GLushort *) dst);
*d = PACK_COLOR_88(src[GCOMP], src[RCOMP]);
}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index a7126fd55..91d9172f9 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1640,6 +1640,17 @@ struct gl_vertex_array_object
};
+/** Used to signal when transitioning from one kind of drawing method
+ * to another.
+ */
+typedef enum {
+ DRAW_NONE, /**< Initial value only */
+ DRAW_BEGIN_END,
+ DRAW_DISPLAY_LIST,
+ DRAW_ARRAYS
+} gl_draw_method;
+
+
/**
* Vertex array state
*/
@@ -1679,6 +1690,9 @@ struct gl_array_attrib
* The array pointer is set up only by the VBO module.
*/
const struct gl_client_array **_DrawArrays; /**< 0..VERT_ATTRIB_MAX-1 */
+
+ /** One of the DRAW_xxx flags, not consumed by drivers */
+ gl_draw_method DrawMethod;
};
@@ -3349,6 +3363,11 @@ struct gl_constants
GLuint ForceGLSLVersion;
/**
+ * Allow GLSL #extension directives in the middle of shaders.
+ */
+ GLboolean AllowGLSLExtensionDirectiveMidShader;
+
+ /**
* Does the driver support real 32-bit integers? (Otherwise, integers are
* simulated via floats.)
*/
diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c
index 5ebaaf6e5..649a74cce 100644
--- a/mesalib/src/mesa/main/pack.c
+++ b/mesalib/src/mesa/main/pack.c
@@ -3183,10 +3183,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
PROCESS(aSrc, ACOMP, 1.0F, 255, GLubyte, UBYTE_TO_FLOAT);
break;
case GL_BYTE:
- PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ);
- PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ);
- PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOATZ);
- PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOATZ);
+ PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX);
+ PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX);
+ PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX);
+ PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOAT_TEX);
break;
case GL_UNSIGNED_SHORT:
PROCESS(rSrc, RCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT);
@@ -3195,10 +3195,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
PROCESS(aSrc, ACOMP, 1.0F, 0xffff, GLushort, USHORT_TO_FLOAT);
break;
case GL_SHORT:
- PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ);
- PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ);
- PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOATZ);
- PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOATZ);
+ PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX);
+ PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX);
+ PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX);
+ PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOAT_TEX);
break;
case GL_UNSIGNED_INT:
PROCESS(rSrc, RCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT);
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index dc17ea584..30dd0b9b3 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -1051,6 +1051,7 @@ get_tex_level_parameter_image(struct gl_context *ctx,
GLenum pname, GLint *params)
{
const struct gl_texture_image *img = NULL;
+ struct gl_texture_image dummy_image;
mesa_format texFormat;
img = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -1062,12 +1063,12 @@ get_tex_level_parameter_image(struct gl_context *ctx,
* instead of 1. TEXTURE_COMPONENTS is deprecated; always
* use TEXTURE_INTERNAL_FORMAT."
*/
+ memset(&dummy_image, 0, sizeof(dummy_image));
+ dummy_image.TexFormat = MESA_FORMAT_NONE;
+ dummy_image.InternalFormat = GL_RGBA;
+ dummy_image._BaseFormat = GL_NONE;
- if (pname == GL_TEXTURE_INTERNAL_FORMAT)
- *params = GL_RGBA;
- else
- *params = 0;
- return;
+ img = &dummy_image;
}
texFormat = img->TexFormat;
@@ -1107,6 +1108,8 @@ get_tex_level_parameter_image(struct gl_context *ctx,
}
break;
case GL_TEXTURE_BORDER:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
*params = img->Border;
break;
case GL_TEXTURE_RED_SIZE:
@@ -1120,6 +1123,8 @@ get_tex_level_parameter_image(struct gl_context *ctx,
break;
case GL_TEXTURE_INTENSITY_SIZE:
case GL_TEXTURE_LUMINANCE_SIZE:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
*params = _mesa_get_format_bits(texFormat, pname);
if (*params == 0) {
@@ -1166,12 +1171,15 @@ get_tex_level_parameter_image(struct gl_context *ctx,
break;
/* GL_ARB_texture_float */
+ case GL_TEXTURE_LUMINANCE_TYPE_ARB:
+ case GL_TEXTURE_INTENSITY_TYPE_ARB:
+ if (ctx->API != API_OPENGL_COMPAT)
+ goto invalid_pname;
+ /* FALLTHROUGH */
case GL_TEXTURE_RED_TYPE_ARB:
case GL_TEXTURE_GREEN_TYPE_ARB:
case GL_TEXTURE_BLUE_TYPE_ARB:
case GL_TEXTURE_ALPHA_TYPE_ARB:
- case GL_TEXTURE_LUMINANCE_TYPE_ARB:
- case GL_TEXTURE_INTENSITY_TYPE_ARB:
case GL_TEXTURE_DEPTH_TYPE_ARB:
if (!ctx->Extensions.ARB_texture_float)
goto invalid_pname;
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 1109051e9..2a82e9d9d 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -1456,6 +1456,9 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
case ir_binop_carry:
case ir_binop_borrow:
case ir_binop_imul_high:
+ case ir_unop_interpolate_at_centroid:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
assert(!"not supported");
break;
@@ -2814,10 +2817,7 @@ get_mesa_program(struct gl_context *ctx,
prog->NumTemporaries = v.next_temp;
- int num_instructions = 0;
- foreach_in_list(ir_instruction, node, &v.instructions) {
- num_instructions++;
- }
+ unsigned num_instructions = v.instructions.length();
mesa_instructions =
(struct prog_instruction *)calloc(num_instructions,
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 4207cb64a..aa59fbfa9 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -772,6 +772,9 @@ void st_init_extensions(struct st_context *st)
if (st->options.disable_glsl_line_continuations)
ctx->Const.DisableGLSLLineContinuations = 1;
+ if (st->options.allow_glsl_extension_directive_midshader)
+ ctx->Const.AllowGLSLExtensionDirectiveMidShader = GL_TRUE;
+
ctx->Const.MinMapBufferAlignment =
screen->get_param(screen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT);
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index f47cd7d53..5c51e63d9 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2049,6 +2049,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
case ir_binop_ldexp:
case ir_binop_carry:
case ir_binop_borrow:
+ case ir_unop_interpolate_at_centroid:
+ case ir_binop_interpolate_at_offset:
+ case ir_binop_interpolate_at_sample:
/* This operation is not supported, or should have already been handled.
*/
assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");
@@ -2820,7 +2823,13 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
}
break;
case ir_txb:
- opcode = is_cube_array ? TGSI_OPCODE_TXB2 : TGSI_OPCODE_TXB;
+ if (is_cube_array ||
+ sampler_type == glsl_type::samplerCubeShadow_type) {
+ opcode = TGSI_OPCODE_TXB2;
+ }
+ else {
+ opcode = TGSI_OPCODE_TXB;
+ }
ir->lod_info.bias->accept(this);
lod_info = this->result;
if (ir->offset) {
diff --git a/mesalib/src/mesa/vbo/vbo_context.h b/mesalib/src/mesa/vbo/vbo_context.h
index 1680e23dc..e22451305 100644
--- a/mesalib/src/mesa/vbo/vbo_context.h
+++ b/mesalib/src/mesa/vbo/vbo_context.h
@@ -57,18 +57,6 @@
#include "vbo_save.h"
-/** Used to signal when transitioning from one kind of drawing method
- * to another.
- */
-enum draw_method
-{
- DRAW_NONE, /**< Initial value only */
- DRAW_BEGIN_END,
- DRAW_DISPLAY_LIST,
- DRAW_ARRAYS
-};
-
-
struct vbo_context {
struct gl_client_array currval[VBO_ATTRIB_MAX];
@@ -83,8 +71,6 @@ struct vbo_context {
* is responsible for initiating any fallback actions required:
*/
vbo_draw_func draw_prims;
-
- enum draw_method last_draw_method;
};
@@ -122,11 +108,11 @@ get_program_mode( struct gl_context *ctx )
* that arrays may be changing.
*/
static inline void
-vbo_draw_method(struct vbo_context *vbo, enum draw_method method)
+vbo_draw_method(struct vbo_context *vbo, gl_draw_method method)
{
- if (vbo->last_draw_method != method) {
- struct gl_context *ctx = vbo->exec.ctx;
+ struct gl_context *ctx = vbo->exec.ctx;
+ if (ctx->Array.DrawMethod != method) {
switch (method) {
case DRAW_ARRAYS:
ctx->Array._DrawArrays = vbo->exec.array.inputs;
@@ -142,7 +128,7 @@ vbo_draw_method(struct vbo_context *vbo, enum draw_method method)
}
ctx->NewDriverState |= ctx->DriverFlags.NewArray;
- vbo->last_draw_method = method;
+ ctx->Array.DrawMethod = method;
}
}
diff --git a/mesalib/src/mesa/vbo/vbo_exec.c b/mesalib/src/mesa/vbo/vbo_exec.c
index bd2b1b1a9..eb9035043 100644
--- a/mesalib/src/mesa/vbo/vbo_exec.c
+++ b/mesalib/src/mesa/vbo/vbo_exec.c
@@ -82,21 +82,6 @@ void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state )
if (!exec->validating && new_state & (_NEW_PROGRAM|_NEW_ARRAY)) {
exec->array.recalculate_inputs = GL_TRUE;
-
- /* If we ended up here because a VAO was deleted, the _DrawArrays
- * pointer which pointed to the VAO might be invalid now, so set it
- * to NULL. This prevents crashes in driver functions like Clear
- * where driver state validation might occur, but the vbo module is
- * still in an invalid state.
- *
- * Drivers should skip vertex array state validation if _DrawArrays
- * is NULL. It also has no effect on performance, because attrib
- * bindings will be recalculated anyway.
- */
- if (vbo->last_draw_method == DRAW_ARRAYS) {
- ctx->Array._DrawArrays = NULL;
- vbo->last_draw_method = DRAW_NONE;
- }
}
if (new_state & _NEW_EVAL)
diff --git a/tools/plink/putty.h b/tools/plink/putty.h
index f97c723b0..a6578ae0c 100644
--- a/tools/plink/putty.h
+++ b/tools/plink/putty.h
@@ -838,6 +838,7 @@ void cleanup_exit(int);
X(INT, NONE, sshbug_maxpkt2) \
X(INT, NONE, sshbug_ignore2) \
X(INT, NONE, sshbug_winadj) \
+ X(INT, NONE, sshbug_chanreq) \
/* \
* ssh_simple means that we promise never to open any channel \
* other than the main one, which means it can safely use a very \
diff --git a/tools/plink/settings.c b/tools/plink/settings.c
index a82a388bf..e949df95f 100644
--- a/tools/plink/settings.c
+++ b/tools/plink/settings.c
@@ -626,6 +626,7 @@ void save_open_settings(void *sesskey, Conf *conf)
write_setting_i(sesskey, "BugRekey2", 2-conf_get_int(conf, CONF_sshbug_rekey2));
write_setting_i(sesskey, "BugMaxPkt2", 2-conf_get_int(conf, CONF_sshbug_maxpkt2));
write_setting_i(sesskey, "BugWinadj", 2-conf_get_int(conf, CONF_sshbug_winadj));
+ write_setting_i(sesskey, "BugChanReq", 2-conf_get_int(conf, CONF_sshbug_chanreq));
write_setting_i(sesskey, "StampUtmp", conf_get_int(conf, CONF_stamp_utmp));
write_setting_i(sesskey, "LoginShell", conf_get_int(conf, CONF_login_shell));
write_setting_i(sesskey, "ScrollbarOnLeft", conf_get_int(conf, CONF_scrollbar_on_left));
@@ -970,6 +971,7 @@ void load_open_settings(void *sesskey, Conf *conf)
i = gppi_raw(sesskey, "BugRekey2", 0); conf_set_int(conf, CONF_sshbug_rekey2, 2-i);
i = gppi_raw(sesskey, "BugMaxPkt2", 0); conf_set_int(conf, CONF_sshbug_maxpkt2, 2-i);
i = gppi_raw(sesskey, "BugWinadj", 0); conf_set_int(conf, CONF_sshbug_winadj, 2-i);
+ i = gppi_raw(sesskey, "BugChanReq", 0); conf_set_int(conf, CONF_sshbug_chanreq, 2-i);
conf_set_int(conf, CONF_ssh_simple, FALSE);
gppi(sesskey, "StampUtmp", 1, conf, CONF_stamp_utmp);
gppi(sesskey, "LoginShell", 1, conf, CONF_login_shell);
diff --git a/tools/plink/ssh.c b/tools/plink/ssh.c
index 4eb84f899..7e63b4e0b 100644
--- a/tools/plink/ssh.c
+++ b/tools/plink/ssh.c
@@ -75,6 +75,7 @@ static const char *const ssh2_disconnect_reasons[] = {
#define BUG_SSH2_MAXPKT 256
#define BUG_CHOKES_ON_SSH2_IGNORE 512
#define BUG_CHOKES_ON_WINADJ 1024
+#define BUG_SENDS_LATE_REQUEST_REPLY 2048
/*
* Codes for terminal modes.
@@ -2812,6 +2813,19 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
ssh->remote_bugs |= BUG_CHOKES_ON_WINADJ;
logevent("We believe remote version has winadj bug");
}
+
+ if (conf_get_int(ssh->conf, CONF_sshbug_chanreq) == FORCE_ON ||
+ (conf_get_int(ssh->conf, CONF_sshbug_chanreq) == AUTO &&
+ (wc_match("OpenSSH_[2-5].*", imp) ||
+ wc_match("OpenSSH_6.[0-6]*", imp)))) {
+ /*
+ * These versions have the SSH-2 channel request bug. 6.7 and
+ * above do not:
+ * https://bugzilla.mindrot.org/show_bug.cgi?id=1818
+ */
+ ssh->remote_bugs |= BUG_SENDS_LATE_REQUEST_REPLY;
+ logevent("We believe remote version has SSH-2 channel request bug");
+ }
}
/*
@@ -7119,10 +7133,11 @@ static void ssh2_queue_chanreq_handler(struct ssh_channel *c,
* request-specific data added and be sent. Note that if a handler is
* provided, it's essential that the request actually be sent.
*
- * The handler will usually be passed the response packet in pktin.
- * If pktin is NULL, this means that no reply will ever be forthcoming
- * (e.g. because the entire connection is being destroyed) and the
- * handler should free any storage it's holding.
+ * The handler will usually be passed the response packet in pktin. If
+ * pktin is NULL, this means that no reply will ever be forthcoming
+ * (e.g. because the entire connection is being destroyed, or because
+ * the server initiated channel closure before we saw the response)
+ * and the handler should free any storage it's holding.
*/
static struct Packet *ssh2_chanreq_init(struct ssh_channel *c, char *type,
cchandler_fn_t handler, void *ctx)
@@ -7612,6 +7627,21 @@ static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
*/
ssh2_channel_got_eof(c);
+ if (!(ssh->remote_bugs & BUG_SENDS_LATE_REQUEST_REPLY)) {
+ /*
+ * It also means we stop expecting to see replies to any
+ * outstanding channel requests, so clean those up too.
+ * (ssh_chanreq_init will enforce by assertion that we don't
+ * subsequently put anything back on this list.)
+ */
+ while (c->v.v2.chanreq_head) {
+ struct outstanding_channel_request *ocr = c->v.v2.chanreq_head;
+ ocr->handler(c, NULL, ocr->ctx);
+ c->v.v2.chanreq_head = ocr->next;
+ sfree(ocr);
+ }
+ }
+
/*
* And we also send an outgoing EOF, if we haven't already, on the
* assumption that CLOSE is a pretty forceful announcement that
@@ -7787,6 +7817,16 @@ static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
ssh_pkt_getstring(pktin, &type, &typelen);
want_reply = ssh2_pkt_getbool(pktin);
+ if (c->closes & CLOSES_SENT_CLOSE) {
+ /*
+ * We don't reply to channel requests after we've sent
+ * CHANNEL_CLOSE for the channel, because our reply might
+ * cross in the network with the other side's CHANNEL_CLOSE
+ * and arrive after they have wound the channel up completely.
+ */
+ want_reply = FALSE;
+ }
+
/*
* Having got the channel number, we now look at
* the request type string to see if it's something
@@ -8416,7 +8456,8 @@ static void ssh2_msg_authconn(Ssh ssh, struct Packet *pktin)
static void ssh2_response_authconn(struct ssh_channel *c, struct Packet *pktin,
void *ctx)
{
- do_ssh2_authconn(c->ssh, NULL, 0, pktin);
+ if (pktin)
+ do_ssh2_authconn(c->ssh, NULL, 0, pktin);
}
static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
diff --git a/tools/plink/winhelp.h b/tools/plink/winhelp.h
index 14b588600..dabd8b825 100644
--- a/tools/plink/winhelp.h
+++ b/tools/plink/winhelp.h
@@ -146,6 +146,7 @@
#define WINHELP_CTX_ssh_bugs_rekey2 "ssh.bugs.rekey2:config-ssh-bug-rekey"
#define WINHELP_CTX_ssh_bugs_maxpkt2 "ssh.bugs.maxpkt2:config-ssh-bug-maxpkt2"
#define WINHELP_CTX_ssh_bugs_winadj "ssh.bugs.winadj:config-ssh-bug-winadj"
+#define WINHELP_CTX_ssh_bugs_chanreq "ssh.bugs.winadj:config-ssh-bug-chanreq"
#define WINHELP_CTX_serial_line "serial.line:config-serial-line"
#define WINHELP_CTX_serial_speed "serial.speed:config-serial-speed"
#define WINHELP_CTX_serial_databits "serial.databits:config-serial-databits"
diff --git a/xorg-server/config/config.c b/xorg-server/config/config.c
index 551451623..b5d634b87 100644
--- a/xorg-server/config/config.c
+++ b/xorg-server/config/config.c
@@ -128,128 +128,21 @@ device_is_duplicate(const char *config_info)
}
struct OdevAttributes *
-config_odev_allocate_attribute_list(void)
+config_odev_allocate_attributes(void)
{
- struct OdevAttributes *attriblist;
-
- attriblist = XNFalloc(sizeof(struct OdevAttributes));
- xorg_list_init(&attriblist->list);
- return attriblist;
-}
-
-void
-config_odev_free_attribute_list(struct OdevAttributes *attribs)
-{
- config_odev_free_attributes(attribs);
- free(attribs);
-}
-
-static struct OdevAttribute *
-config_odev_find_attribute(struct OdevAttributes *attribs, int attrib_id)
-{
- struct OdevAttribute *oa;
-
- xorg_list_for_each_entry(oa, &attribs->list, member) {
- if (oa->attrib_id == attrib_id)
- return oa;
- }
- return NULL;
-}
-
-static struct OdevAttribute *
-config_odev_find_or_add_attribute(struct OdevAttributes *attribs, int attrib)
-{
- struct OdevAttribute *oa;
-
- oa = config_odev_find_attribute(attribs, attrib);
- if (oa)
- return oa;
-
- oa = XNFcalloc(sizeof(struct OdevAttribute));
- oa->attrib_id = attrib;
- xorg_list_append(&oa->member, &attribs->list);
-
- return oa;
-}
-
-Bool
-config_odev_add_attribute(struct OdevAttributes *attribs, int attrib,
- const char *attrib_name)
-{
- struct OdevAttribute *oa;
-
- oa = config_odev_find_or_add_attribute(attribs, attrib);
- free(oa->attrib_name);
- oa->attrib_name = XNFstrdup(attrib_name);
- oa->attrib_type = ODEV_ATTRIB_STRING;
- return TRUE;
-}
-
-Bool
-config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib,
- int attrib_value)
-{
- struct OdevAttribute *oa;
-
- oa = config_odev_find_or_add_attribute(attribs, attrib);
- oa->attrib_value = attrib_value;
- oa->attrib_type = ODEV_ATTRIB_INT;
- return TRUE;
-}
-
-char *
-config_odev_get_attribute(struct OdevAttributes *attribs, int attrib_id)
-{
- struct OdevAttribute *oa;
-
- oa = config_odev_find_attribute(attribs, attrib_id);
- if (!oa)
- return NULL;
-
- if (oa->attrib_type != ODEV_ATTRIB_STRING) {
- LogMessage(X_ERROR, "Error %s called for non string attrib %d\n",
- __func__, attrib_id);
- return NULL;
- }
- return oa->attrib_name;
-}
-
-int
-config_odev_get_int_attribute(struct OdevAttributes *attribs, int attrib_id, int def)
-{
- struct OdevAttribute *oa;
-
- oa = config_odev_find_attribute(attribs, attrib_id);
- if (!oa)
- return def;
-
- if (oa->attrib_type != ODEV_ATTRIB_INT) {
- LogMessage(X_ERROR, "Error %s called for non integer attrib %d\n",
- __func__, attrib_id);
- return def;
- }
-
- return oa->attrib_value;
+ struct OdevAttributes *attribs = XNFcalloc(sizeof (struct OdevAttributes));
+ attribs->fd = -1;
+ return attribs;
}
void
config_odev_free_attributes(struct OdevAttributes *attribs)
{
- struct OdevAttribute *iter, *safe;
- int major = 0, minor = 0, fd = -1;
-
- xorg_list_for_each_entry_safe(iter, safe, &attribs->list, member) {
- switch (iter->attrib_id) {
- case ODEV_ATTRIB_MAJOR: major = iter->attrib_value; break;
- case ODEV_ATTRIB_MINOR: minor = iter->attrib_value; break;
- case ODEV_ATTRIB_FD: fd = iter->attrib_value; break;
- }
- xorg_list_del(&iter->member);
- if (iter->attrib_type == ODEV_ATTRIB_STRING)
- free(iter->attrib_name);
- free(iter);
- }
-
- if (fd != -1)
- systemd_logind_release_fd(major, minor, fd);
+ if (attribs->fd != -1)
+ systemd_logind_release_fd(attribs->major, attribs->minor, attribs->fd);
+ free(attribs->path);
+ free(attribs->syspath);
+ free(attribs->busid);
+ free(attribs->driver);
+ free(attribs);
}
diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c
index a1b72c13b..1e4a9d7a6 100644
--- a/xorg-server/config/udev.c
+++ b/xorg-server/config/udev.c
@@ -462,12 +462,12 @@ config_udev_odev_setup_attribs(const char *path, const char *syspath,
int major, int minor,
config_odev_probe_proc_ptr probe_callback)
{
- struct OdevAttributes *attribs = config_odev_allocate_attribute_list();
+ struct OdevAttributes *attribs = config_odev_allocate_attributes();
- config_odev_add_attribute(attribs, ODEV_ATTRIB_PATH, path);
- config_odev_add_attribute(attribs, ODEV_ATTRIB_SYSPATH, syspath);
- config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MAJOR, major);
- config_odev_add_int_attribute(attribs, ODEV_ATTRIB_MINOR, minor);
+ attribs->path = XNFstrdup(path);
+ attribs->syspath = XNFstrdup(syspath);
+ attribs->major = major;
+ attribs->minor = minor;
/* ownership of attribs is passed to probe layer */
probe_callback(attribs);
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index c214638d3..4338dc551 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -26,9 +26,9 @@ dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.15.99.904, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2014-07-07"
-RELEASE_NAME="Netarts Bay Oysters"
+AC_INIT([xorg-server], 1.16.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2014-07-17"
+RELEASE_NAME="Baba Ghanouj"
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index d68fa96d7..ffa89fad2 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -770,65 +770,27 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
}
-/* FIXME: relative events from devices with absolute axis ranges is
- fundamentally broken. We map the device coordinate range into the screen
- range, but don't really account for device resolution in that.
-
- what we do here is a hack to make touchpads usable. for a given relative
- motion vector in device coordinates:
- 1. calculate physical movement on the device in metres
- 2. calculate pixel vector that is the same physical movement on the
- screen (times some magic number to provide sensible base speed)
- 3. calculate what percentage this vector is of the current screen
- width/height
- 4. calculate equivalent vector in % on the device's min/max axis range
- 5. Use that device vector as the actual motion vector
-
- e.g. 10/50mm on the device, 10/50mm on the screen are 30/100 pixels,
- 30/100 pixels are 1/3% of the width, 1/3% of the device is a vector of
- 20/80 -> use 20/80 as dx/dy.
-
- dx/dy is then applied to the current position in device coordinates,
- mapped to screen coordinates and thus the movement on the screen reflects
- the motion direction on the device.
- */
static void
scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask)
{
- double x, y;
+ double y;
ValuatorClassPtr v = dev->valuator;
int xrange = v->axes[0].max_value - v->axes[0].min_value + 1;
int yrange = v->axes[1].max_value - v->axes[1].min_value + 1;
- /* Assume 100 units/m for devices without resolution */
- int xres = 100000, yres = 100000;
-
- /* If we have multiple screens with different dpi, it gets complicated:
- we have to map which screen we're on and then take the dpi of that
- screen to be somewhat accurate. */
- const ScreenPtr s = screenInfo.screens[0];
- const double screen_res = 1000.0 * s->width/s->mmWidth; /* units/m */
+ double screen_ratio = 1.0 * screenInfo.width/screenInfo.height;
+ double device_ratio = 1.0 * xrange/yrange;
+ double resolution_ratio = 1.0;
+ double ratio;
- /* some magic multiplier, so unaccelerated movement of x mm on the
- device reflects x * magic mm on the screen */
- const double magic = 4;
+ if (!valuator_mask_fetch_double(mask, 1, &y))
+ return;
- if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0) {
- xres = v->axes[0].resolution;
- yres = v->axes[1].resolution;
- }
+ if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0)
+ resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution;
- if (valuator_mask_isset(mask, 0)) {
- x = valuator_mask_get_double(mask, 0);
- x = magic * x/xres * screen_res/screenInfo.width * xrange;
- valuator_mask_set_double(mask, 0, x);
- }
-
- if (valuator_mask_isset(mask, 1)) {
- y = valuator_mask_get_double(mask, 1);
- y = magic * y/yres * screen_res/screenInfo.height * yrange;
- valuator_mask_set_double(mask, 1, y);
- }
+ ratio = device_ratio/resolution_ratio/screen_ratio;
+ valuator_mask_set_double(mask, 1, y / ratio);
}
/**
@@ -842,6 +804,15 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
{
int i;
Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
+ ValuatorClassPtr v = dev->valuator;
+
+ /* for abs devices in relative mode, we've just scaled wrong, since we
+ mapped the device's shape into the screen shape. Undo this. */
+ if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 &&
+ v->axes[0].min_value < v->axes[0].max_value &&
+ v->axes[1].min_value < v->axes[1].max_value) {
+ scale_for_device_resolution(dev, mask);
+ }
/* calc other axes, clip, drop back into valuators */
for (i = 0; i < valuator_mask_size(mask); i++) {
@@ -1470,21 +1441,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
set_raw_valuators(raw, &mask, raw->valuators.data);
}
else {
- ValuatorClassPtr v = pDev->valuator;
-
transformRelative(pDev, &mask);
- /* for abs devices in relative mode, we've just scaled wrong, since we
- mapped the device's shape into the screen shape. Undo this. */
- if (v && v->numAxes > 1 &&
- v->axes[0].min_value < v->axes[0].max_value &&
- v->axes[1].min_value < v->axes[1].max_value) {
- scale_for_device_resolution(pDev, &mask);
- }
-
if (flags & POINTER_ACCELERATE)
accelPointer(pDev, &mask, ms);
-
if ((flags & POINTER_NORAW) == 0 && raw)
set_raw_valuators(raw, &mask, raw->valuators.data);
diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am
index bde58b632..db72cb11c 100644
--- a/xorg-server/glamor/Makefile.am
+++ b/xorg-server/glamor/Makefile.am
@@ -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,10 @@ libglamor_la_SOURCES = \
glamor_window.c\
glamor_fbo.c\
glamor_compositerects.c\
+ glamor_utils.c\
glamor_utils.h\
+ glamor_xv.c \
+ glamor_sync.c \
glamor.h
libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c
index 358890375..521bc25c8 100644
--- a/xorg-server/glamor/glamor.c
+++ b/xorg-server/glamor/glamor.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
@@ -516,6 +519,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
#endif
glamor_pixmap_init(screen);
glamor_glyphs_init(screen);
+ glamor_sync_init(screen);
glamor_priv->screen = screen;
@@ -538,8 +542,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 +561,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 +574,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
@@ -587,6 +589,7 @@ glamor_close_screen(ScreenPtr screen)
#endif
glamor_priv = glamor_get_screen_private(screen);
flags = glamor_priv->flags;
+ glamor_sync_close(screen);
glamor_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
screen->CreateScreenResources =
diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h
index b0f2212d9..405dbe8ed 100644
--- a/xorg-server/glamor/glamor.h
+++ b/xorg-server/glamor/glamor.h
@@ -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,
diff --git a/xorg-server/glamor/glamor_copy.c b/xorg-server/glamor/glamor_copy.c
new file mode 100644
index 000000000..bfcde43db
--- /dev/null
+++ b/xorg-server/glamor/glamor_copy.c
@@ -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;
+}
diff --git a/xorg-server/glamor/glamor_copyarea.c b/xorg-server/glamor/glamor_copyarea.c
deleted file mode 100644
index e1988225f..000000000
--- a/xorg-server/glamor/glamor_copyarea.c
+++ /dev/null
@@ -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(&region, box, nbox);
- extent = RegionExtents(&region);
-
- 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(&region, dst_x_off, dst_y_off);
- if (!force_clip)
- clipped_dst_regions =
- glamor_compute_clipped_regions(dst_pixmap_priv, &region,
- &n_dst_region, 0, reverse,
- upsidedown);
- else
- clipped_dst_regions =
- glamor_compute_clipped_regions_ext(dst_pixmap_priv, &region,
- &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(&region);
- 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);
-}
diff --git a/xorg-server/glamor/glamor_copyplane.c b/xorg-server/glamor/glamor_copyplane.c
deleted file mode 100644
index 2bd2de30d..000000000
--- a/xorg-server/glamor/glamor_copyplane.c
+++ /dev/null
@@ -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);
-}
diff --git a/xorg-server/glamor/glamor_copywindow.c b/xorg-server/glamor/glamor_copywindow.c
deleted file mode 100644
index 1ced4b336..000000000
--- a/xorg-server/glamor/glamor_copywindow.c
+++ /dev/null
@@ -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);
-}
diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c
index b34943761..737b2744b 100644
--- a/xorg-server/glamor/glamor_core.c
+++ b/xorg-server/glamor/glamor_core.c
@@ -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;
diff --git a/xorg-server/glamor/glamor_dash.c b/xorg-server/glamor/glamor_dash.c
new file mode 100644
index 000000000..e8f60fa10
--- /dev/null
+++ b/xorg-server/glamor/glamor_dash.c
@@ -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;
+}
diff --git a/xorg-server/glamor/glamor_fill.c b/xorg-server/glamor/glamor_fill.c
deleted file mode 100644
index 073904d2a..000000000
--- a/xorg-server/glamor/glamor_fill.c
+++ /dev/null
@@ -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(&region, box, nbox);
- clipped_regions =
- glamor_compute_clipped_regions(pixmap_priv, &region, &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(&region);
- }
- 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;
-}
diff --git a/xorg-server/glamor/glamor_glyphblt.c b/xorg-server/glamor/glamor_glyphblt.c
index 1c511ff2b..73b1df51e 100644
--- a/xorg-server/glamor/glamor_glyphblt.c
+++ b/xorg-server/glamor/glamor_glyphblt.c
@@ -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;
- }
-
- glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
-
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
- pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
- glUseProgram(glamor_priv->solid_prog);
+ 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_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);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- 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);
-
- 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;
+ 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);
- 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;
}
diff --git a/xorg-server/glamor/glamor_glyphs.c b/xorg-server/glamor/glamor_glyphs.c
index 42f5f65f6..f570d7519 100644
--- a/xorg-server/glamor/glamor_glyphs.c
+++ b/xorg-server/glamor/glamor_glyphs.c
@@ -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,
diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c
index 28d66917f..4ded89dcd 100644
--- a/xorg-server/glamor/glamor_gradient.c
+++ b/xorg-server/glamor/glamor_gradient.c
@@ -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),
diff --git a/xorg-server/glamor/glamor_largepixmap.c b/xorg-server/glamor/glamor_largepixmap.c
index b3a8d5d20..5a4bec571 100644
--- a/xorg-server/glamor/glamor_largepixmap.c
+++ b/xorg-server/glamor/glamor_largepixmap.c
@@ -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, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+ glamor_copy(&priv->base.pixmap->drawable,
+ &temp_pixmap->drawable,
+ NULL, &copy_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, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+ glamor_copy(&priv->base.pixmap->drawable,
+ &temp_pixmap->drawable,
+ NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+
box++;
}
}
diff --git a/xorg-server/glamor/glamor_lines.c b/xorg-server/glamor/glamor_lines.c
new file mode 100644
index 000000000..e9a619505
--- /dev/null
+++ b/xorg-server/glamor/glamor_lines.c
@@ -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;
+}
+
diff --git a/xorg-server/glamor/glamor_picture.c b/xorg-server/glamor/glamor_picture.c
index 5fdc5f9b0..cbbc19406 100644
--- a/xorg-server/glamor/glamor_picture.c
+++ b/xorg-server/glamor/glamor_picture.c
@@ -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
diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c
index 789d3772e..ccb49f3c6 100644
--- a/xorg-server/glamor/glamor_pixmap.c
+++ b/xorg-server/glamor/glamor_pixmap.c
@@ -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(&region, &box, 1);
-
- if (!force_clip)
- clipped_regions =
- glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
- 0, 0, 0);
- else
- clipped_regions =
- glamor_compute_clipped_regions_ext(pixmap_priv, &region,
- &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(&region);
- 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(&region);
- 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);
-}
diff --git a/xorg-server/glamor/glamor_points.c b/xorg-server/glamor/glamor_points.c
index d4525e294..84383d254 100644
--- a/xorg-server/glamor/glamor_points.c
+++ b/xorg-server/glamor/glamor_points.c
@@ -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:
diff --git a/xorg-server/glamor/glamor_polylines.c b/xorg-server/glamor/glamor_polylines.c
deleted file mode 100644
index 1adf45ddc..000000000
--- a/xorg-server/glamor/glamor_polylines.c
+++ /dev/null
@@ -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);
-}
diff --git a/xorg-server/glamor/glamor_prepare.c b/xorg-server/glamor/glamor_prepare.c
new file mode 100644
index 000000000..561c55d19
--- /dev/null
+++ b/xorg-server/glamor/glamor_prepare.c
@@ -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(&region, 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(&region, &region, &priv->base.prepare_region);
+ if (!RegionNotEmpty(&region))
+ 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(&region), RegionNumRects(&region),
+ 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
+
+ RegionUninit(&region);
+
+ 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;
+ }
+}
diff --git a/xorg-server/glamor/glamor_segment.c b/xorg-server/glamor/glamor_prepare.h
index 53f7da0cb..85fa79574 100644
--- a/xorg-server/glamor/glamor_segment.c
+++ b/xorg-server/glamor/glamor_prepare.h
@@ -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);
+Bool
+glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access,
+ int x, int y, int w, int h);
+
+void
+glamor_finish_access(DrawablePtr drawable);
- return TRUE;
-}
+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_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg,
- xSegment *seg)
-{
- miPolySegment(drawable, gc, nseg, seg);
-}
+glamor_finish_access_picture(PicturePtr picture);
+
+Bool
+glamor_prepare_access_gc(GCPtr gc);
+
+void
+glamor_finish_access_gc(GCPtr gc);
+
+#endif /* _GLAMOR_PREPARE_H_ */
diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h
index c56c55973..57a46873c 100644
--- a/xorg-server/glamor/glamor_priv.h
+++ b/xorg-server/glamor/glamor_priv.h
@@ -31,6 +31,12 @@
#include <xorg-server.h>
#include "glamor.h"
+#include "xvdix.h"
+
+#if XSYNC
+#include "misyncshm.h"
+#include "misyncstr.h"
+#endif
#include <epoxy/gl.h>
#if GLAMOR_HAS_GBM
@@ -183,6 +189,9 @@ struct glamor_saved_procs {
DestroyPictureProcPtr destroy_picture;
UnrealizeGlyphProcPtr unrealize_glyph;
SetWindowPixmapProcPtr set_window_pixmap;
+#if XSYNC
+ SyncScreenFuncsRec sync_screen_funcs;
+#endif
};
#define CACHE_FORMAT_COUNT 3
@@ -193,13 +202,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 +211,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 +236,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 +276,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 +291,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 +439,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 +540,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 +556,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 +586,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 +642,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 +660,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 +674,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 +687,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 +752,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 +789,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 +809,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 +867,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 +883,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 +924,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 +981,28 @@ 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_sync.c */
+Bool
+glamor_sync_init(ScreenPtr screen);
+
+void
+glamor_sync_close(ScreenPtr screen);
+
+/* 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 +1024,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. */
diff --git a/xorg-server/glamor/glamor_program.c b/xorg-server/glamor/glamor_program.c
index 0f4d0f06a..1d0328f2b 100644
--- a/xorg-server/glamor/glamor_program.c
+++ b/xorg-server/glamor/glamor_program.c
@@ -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;
diff --git a/xorg-server/glamor/glamor_program.h b/xorg-server/glamor/glamor_program.h
index 88efc3593..56ba03aa8 100644
--- a/xorg-server/glamor/glamor_program.h
+++ b/xorg-server/glamor/glamor_program.h
@@ -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;
diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c
index 14ab738eb..2386f2e2e 100644
--- a/xorg-server/glamor/glamor_render.c
+++ b/xorg-server/glamor/glamor_render.c
@@ -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;
@@ -1450,8 +1446,8 @@ glamor_composite_clipped_region(CARD8 op,
|| source_pixmap->drawable.height != height)))) {
temp_src =
glamor_convert_gradient_picture(screen, source,
- extent->x1 + x_source - x_dest,
- extent->y1 + y_source - y_dest,
+ extent->x1 + x_source - x_dest - dest->pDrawable->x,
+ extent->y1 + y_source - y_dest - dest->pDrawable->y,
width, height);
if (!temp_src) {
temp_src = source;
@@ -1459,8 +1455,8 @@ glamor_composite_clipped_region(CARD8 op,
}
temp_src_priv =
glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable));
- x_temp_src = -extent->x1 + x_dest;
- y_temp_src = -extent->y1 + y_dest;
+ x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x;
+ y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y;
}
if (mask
@@ -1474,8 +1470,8 @@ glamor_composite_clipped_region(CARD8 op,
* to do reduce one convertion. */
temp_mask =
glamor_convert_gradient_picture(screen, mask,
- extent->x1 + x_mask - x_dest,
- extent->y1 + y_mask - y_dest,
+ extent->x1 + x_mask - x_dest - dest->pDrawable->x,
+ extent->y1 + y_mask - y_dest - dest->pDrawable->y,
width, height);
if (!temp_mask) {
temp_mask = mask;
@@ -1483,8 +1479,8 @@ glamor_composite_clipped_region(CARD8 op,
}
temp_mask_priv =
glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable));
- x_temp_mask = -extent->x1 + x_dest;
- y_temp_mask = -extent->y1 + y_dest;
+ x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x;
+ y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y;
}
/* Do two-pass PictOpOver componentAlpha, until we enable
* dual source color blending.
@@ -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;
}
diff --git a/xorg-server/glamor/glamor_segs.c b/xorg-server/glamor/glamor_segs.c
new file mode 100644
index 000000000..ff0daef10
--- /dev/null
+++ b/xorg-server/glamor/glamor_segs.c
@@ -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;
+}
+
diff --git a/xorg-server/glamor/glamor_spans.c b/xorg-server/glamor/glamor_spans.c
index 46ba6c38f..582d11df3 100644
--- a/xorg-server/glamor/glamor_spans.c
+++ b/xorg-server/glamor/glamor_spans.c
@@ -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) {
diff --git a/xorg-server/glamor/glamor_sync.c b/xorg-server/glamor/glamor_sync.c
new file mode 100644
index 000000000..d3d64a925
--- /dev/null
+++ b/xorg-server/glamor/glamor_sync.c
@@ -0,0 +1,117 @@
+/*
+ * 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 "misyncshm.h"
+#include "misyncstr.h"
+
+#if XSYNC
+/*
+ * This whole file exists to wrap a sync fence trigger operation so
+ * that we can flush GL to provide serialization between the server
+ * and the shm fence client
+ */
+
+static DevPrivateKeyRec glamor_sync_fence_key;
+
+struct glamor_sync_fence {
+ SyncFenceSetTriggeredFunc set_triggered;
+};
+
+static inline struct glamor_sync_fence *
+glamor_get_sync_fence(SyncFence *fence)
+{
+ return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key);
+}
+
+static void
+glamor_sync_fence_set_triggered (SyncFence *fence)
+{
+ ScreenPtr screen = fence->pScreen;
+ glamor_screen_private *glamor = glamor_get_screen_private(screen);
+ struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
+
+ /* Flush pending rendering operations */
+ glamor_make_current(glamor);
+ glFinish();
+
+ fence->funcs.SetTriggered = glamor_fence->set_triggered;
+ fence->funcs.SetTriggered(fence);
+ glamor_fence->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
+}
+
+static void
+glamor_sync_create_fence(ScreenPtr screen,
+ SyncFence *fence,
+ Bool initially_triggered)
+{
+ glamor_screen_private *glamor = glamor_get_screen_private(screen);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+ struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
+
+ screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
+ screen_funcs->CreateFence(screen, fence, initially_triggered);
+ glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
+ screen_funcs->CreateFence = glamor_sync_create_fence;
+
+ glamor_fence->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
+}
+#endif
+
+Bool
+glamor_sync_init(ScreenPtr screen)
+{
+#if XSYNC
+ glamor_screen_private *glamor = glamor_get_screen_private(screen);
+ SyncScreenFuncsPtr screen_funcs;
+
+ if (!dixPrivateKeyRegistered(&glamor_sync_fence_key)) {
+ if (!dixRegisterPrivateKey(&glamor_sync_fence_key,
+ PRIVATE_SYNC_FENCE,
+ sizeof (struct glamor_sync_fence)))
+ return FALSE;
+ }
+
+ if (!miSyncShmScreenInit(screen))
+ return FALSE;
+
+ screen_funcs = miSyncGetScreenFuncs(screen);
+ glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
+ screen_funcs->CreateFence = glamor_sync_create_fence;
+#endif
+ return TRUE;
+}
+
+void
+glamor_sync_close(ScreenPtr screen)
+{
+#if XSYNC
+ glamor_screen_private *glamor = glamor_get_screen_private(screen);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+
+ if (screen_funcs)
+ screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
+#endif
+}
diff --git a/xorg-server/glamor/glamor_text.c b/xorg-server/glamor/glamor_text.c
index 6e02b9aa8..59cd0fdc8 100644
--- a/xorg-server/glamor/glamor_text.c
+++ b/xorg-server/glamor/glamor_text.c
@@ -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:
diff --git a/xorg-server/glamor/glamor_tile.c b/xorg-server/glamor/glamor_tile.c
deleted file mode 100644
index 4e479763e..000000000
--- a/xorg-server/glamor/glamor_tile.c
+++ /dev/null
@@ -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(&region, &box, 1);
- clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
- &region,
- &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(&region);
- }
- else
- _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
-
- glamor_set_alu(screen, GXcopy);
- return TRUE;
- fail:
- return FALSE;
-
-}
diff --git a/xorg-server/glamor/glamor_transfer.c b/xorg-server/glamor/glamor_transfer.c
index ad875c962..891415565 100644
--- a/xorg-server/glamor/glamor_transfer.c
+++ b/xorg-server/glamor/glamor_transfer.c
@@ -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);
diff --git a/xorg-server/glamor/glamor_transform.c b/xorg-server/glamor/glamor_transform.c
index d6ba56421..c1df56018 100644
--- a/xorg-server/glamor/glamor_transform.c
+++ b/xorg-server/glamor/glamor_transform.c
@@ -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)
{
- if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
+ PixmapPtr stipple;
+
+ stipple = glamor_get_stipple_pixmap(gc);
+ if (!stipple)
return FALSE;
- if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform))
+ if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
return FALSE;
- return TRUE;
+ return glamor_set_texture(pixmap,
+ stipple,
+ -gc->patOrg.x,
+ -gc->patOrg.y,
+ offset_uniform,
+ size_uniform);
}
diff --git a/xorg-server/glamor/glamor_trapezoid.c b/xorg-server/glamor/glamor_trapezoid.c
index 4aba469af..d61d11f79 100644
--- a/xorg-server/glamor/glamor_trapezoid.c
+++ b/xorg-server/glamor/glamor_trapezoid.c
@@ -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],
diff --git a/xorg-server/glamor/glamor_utils.c b/xorg-server/glamor/glamor_utils.c
new file mode 100644
index 000000000..f06896096
--- /dev/null
+++ b/xorg-server/glamor/glamor_utils.c
@@ -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);
+}
+
diff --git a/xorg-server/glamor/glamor_utils.h b/xorg-server/glamor/glamor_utils.h
index 4c1581ef5..c15d17ca3 100644
--- a/xorg-server/glamor/glamor_utils.h
+++ b/xorg-server/glamor/glamor_utils.h
@@ -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
diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c
index 369b02b61..68a06a413 100644
--- a/xorg-server/glamor/glamor_xv.c
+++ b/xorg-server/glamor/glamor_xv.c
@@ -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;
+
+ REGION_NULL(pScreen, &port_priv->clip);
+}
- 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;
+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");
}
diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.am b/xorg-server/hw/kdrive/ephyr/Makefile.am
index 00a53d0df..10c59174f 100644
--- a/xorg-server/hw/kdrive/ephyr/Makefile.am
+++ b/xorg-server/hw/kdrive/ephyr/Makefile.am
@@ -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
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
index def50d8d8..d57e9f33c 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -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 {
@@ -756,6 +758,12 @@ ephyrScreenFini(KdScreenInfo * screen)
}
}
+void
+ephyrCloseScreen(ScreenPtr pScreen)
+{
+ ephyrUnsetInternalDamage(pScreen);
+}
+
/*
* Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
* See https://bugs.freedesktop.org/show_bug.cgi?id=3030
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h
index 34ce4601b..dfd93c9bc 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.h
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.h
@@ -131,6 +131,9 @@ void
ephyrScreenFini(KdScreenInfo * screen);
void
+ephyrCloseScreen(ScreenPtr pScreen);
+
+void
ephyrCardFini(KdCardInfo * card);
void
@@ -221,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
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
index eaf565496..8fe751693 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -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");
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_xv.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_xv.c
new file mode 100644
index 000000000..b9c3464d8
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_xv.c
@@ -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);
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c
index fac84cd13..fc0001012 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c
@@ -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;
@@ -430,4 +440,6 @@ KdCardFuncs ephyrFuncs = {
ephyrGetColors, /* getColors */
ephyrPutColors, /* putColors */
+
+ ephyrCloseScreen, /* closeScreen */
};
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
index c6728351f..ab18c7afa 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
@@ -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, &registered_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)
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
index 435919e0a..1c759743d 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.c
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -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;
}
diff --git a/xorg-server/hw/kdrive/src/kdrive.c b/xorg-server/hw/kdrive/src/kdrive.c
index 9814fc66a..b5b91c0dd 100644
--- a/xorg-server/hw/kdrive/src/kdrive.c
+++ b/xorg-server/hw/kdrive/src/kdrive.c
@@ -621,8 +621,12 @@ KdCloseScreen(ScreenPtr pScreen)
KdCardInfo *card = pScreenPriv->card;
Bool ret;
+ if (card->cfuncs->closeScreen)
+ (*card->cfuncs->closeScreen)(pScreen);
+
pScreenPriv->closed = TRUE;
pScreen->CloseScreen = pScreenPriv->CloseScreen;
+
if (pScreen->CloseScreen)
ret = (*pScreen->CloseScreen) (pScreen);
else
diff --git a/xorg-server/hw/kdrive/src/kdrive.h b/xorg-server/hw/kdrive/src/kdrive.h
index bec75cb6f..08b1681ce 100644
--- a/xorg-server/hw/kdrive/src/kdrive.h
+++ b/xorg-server/hw/kdrive/src/kdrive.h
@@ -130,6 +130,7 @@ typedef struct _KdCardFuncs {
void (*getColors) (ScreenPtr, int, xColorItem *);
void (*putColors) (ScreenPtr, int, xColorItem *);
+ void (*closeScreen) (ScreenPtr); /* close ScreenRec */
} KdCardFuncs;
#define KD_MAX_PSEUDO_DEPTH 8
diff --git a/xorg-server/hw/kdrive/src/kxv.c b/xorg-server/hw/kdrive/src/kxv.c
index 9cc0edd8a..60a83458c 100644
--- a/xorg-server/hw/kdrive/src/kxv.c
+++ b/xorg-server/hw/kdrive/src/kxv.c
@@ -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;
diff --git a/xorg-server/hw/kdrive/src/kxv.h b/xorg-server/hw/kdrive/src/kxv.h
index 85a030ee9..3a49a659f 100644
--- a/xorg-server/hw/kdrive/src/kxv.h
+++ b/xorg-server/hw/kdrive/src/kxv.h
@@ -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
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index 481674de2..779ba6f7c 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -103,7 +103,7 @@
"/etc/X11/%X," "%C/X11/%X"
#endif
#ifndef SYS_CONFIGDIRPATH
-#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
+#define SYS_CONFIGDIRPATH "%D/X11/%X"
#endif
#ifndef PROJECTROOT
#define PROJECTROOT "/usr/X11R6"
diff --git a/xorg-server/hw/xfree86/common/xf86DPMS.c b/xorg-server/hw/xfree86/common/xf86DPMS.c
index 14d1f4545..2b5a3ed1e 100644
--- a/xorg-server/hw/xfree86/common/xf86DPMS.c
+++ b/xorg-server/hw/xfree86/common/xf86DPMS.c
@@ -166,7 +166,7 @@ DPMSSet(ClientPtr client, int level)
return rc;
}
} else if (!xf86IsUnblank(screenIsSaved)) {
- rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverReset);
+ rc = dixSaveScreens(client, SCREEN_SAVER_OFF, ScreenSaverReset);
if (rc != Success)
return rc;
}
diff --git a/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h b/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h
index ec21bc2f2..b832c9a5f 100644
--- a/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h
+++ b/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h
@@ -49,10 +49,14 @@
#define UNWRAP_SCREEN(x) pScreen->x = pScreenPriv->x
-#define SCREEN_PROLOG(x) pScreen->x = ((VGAarbiterScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey))->x
+#define SCREEN_PRIV() ((VGAarbiterScreenPtr) dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey))
-#define SCREEN_EPILOG(x,y) pScreen->x = y;
+#define SCREEN_PROLOG(x) (pScreen->x = SCREEN_PRIV()->x)
+
+#define SCREEN_EPILOG(x,y) do { \
+ SCREEN_PRIV()->x = pScreen->x; \
+ pScreen->x = y; \
+ } while (0)
#define WRAP_PICT(x,y) if (ps) {pScreenPriv->x = ps->x;\
ps->x = y;}
diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.c b/xorg-server/hw/xfree86/common/xf86platformBus.c
index eb1a3fb5d..22e4603e6 100644
--- a/xorg-server/hw/xfree86/common/xf86platformBus.c
+++ b/xorg-server/hw/xfree86/common/xf86platformBus.c
@@ -77,7 +77,7 @@ xf86_remove_platform_device(int dev_index)
{
int j;
- config_odev_free_attribute_list(xf86_platform_devices[dev_index].attribs);
+ config_odev_free_attributes(xf86_platform_devices[dev_index].attribs);
for (j = dev_index; j < xf86_num_platform_devices - 1; j++)
memcpy(&xf86_platform_devices[j], &xf86_platform_devices[j + 1], sizeof(struct xf86_platform_device));
@@ -86,44 +86,6 @@ xf86_remove_platform_device(int dev_index)
}
Bool
-xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_name)
-{
- struct xf86_platform_device *device = &xf86_platform_devices[index];
-
- return config_odev_add_attribute(device->attribs, attrib_id, attrib_name);
-}
-
-Bool
-xf86_add_platform_device_int_attrib(int index, int attrib_id, int attrib_value)
-{
- return config_odev_add_int_attribute(xf86_platform_devices[index].attribs, attrib_id, attrib_value);
-}
-
-char *
-xf86_get_platform_attrib(int index, int attrib_id)
-{
- return config_odev_get_attribute(xf86_platform_devices[index].attribs, attrib_id);
-}
-
-char *
-xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id)
-{
- return config_odev_get_attribute(device->attribs, attrib_id);
-}
-
-int
-xf86_get_platform_int_attrib(int index, int attrib_id, int def)
-{
- return config_odev_get_int_attribute(xf86_platform_devices[index].attribs, attrib_id, def);
-}
-
-int
-xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int attrib_id, int def)
-{
- return config_odev_get_int_attribute(device->attribs, attrib_id, def);
-}
-
-Bool
xf86_get_platform_device_unowned(int index)
{
return (xf86_platform_devices[index].flags & XF86_PDEV_UNOWNED) ?
@@ -136,8 +98,8 @@ xf86_find_platform_device_by_devnum(int major, int minor)
int i, attr_major, attr_minor;
for (i = 0; i < xf86_num_platform_devices; i++) {
- attr_major = xf86_get_platform_int_attrib(i, ODEV_ATTRIB_MAJOR, 0);
- attr_minor = xf86_get_platform_int_attrib(i, ODEV_ATTRIB_MINOR, 0);
+ attr_major = xf86_platform_odev_attributes(i)->major;
+ attr_minor = xf86_platform_odev_attributes(i)->minor;
if (attr_major == major && attr_minor == minor)
return &xf86_platform_devices[i];
}
@@ -240,7 +202,7 @@ MatchToken(const char *value, struct xorg_list *patterns,
static Bool
OutputClassMatches(const XF86ConfOutputClassPtr oclass, int index)
{
- char *driver = xf86_get_platform_attrib(index, ODEV_ATTRIB_DRIVER);
+ char *driver = xf86_platform_odev_attributes(index)->driver;
if (!MatchToken(driver, &oclass->match_driver, strcmp))
return FALSE;
@@ -259,7 +221,7 @@ xf86OutputClassDriverList(int index, char *matches[], int nmatches)
for (cl = xf86configptr->conf_outputclass_lst; cl; cl = cl->list.next) {
if (OutputClassMatches(cl, index)) {
- char *path = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH);
+ char *path = xf86_platform_odev_attributes(index)->path;
xf86Msg(X_INFO, "Applying OutputClass \"%s\" to %s\n",
cl->identifier, path);
@@ -324,7 +286,7 @@ xf86platformProbe(void)
}
for (i = 0; i < xf86_num_platform_devices; i++) {
- char *busid = xf86_get_platform_attrib(i, ODEV_ATTRIB_BUSID);
+ char *busid = xf86_platform_odev_attributes(i)->busid;
if (pci && (strncmp(busid, "pci:", 4) == 0)) {
platform_find_pci_info(&xf86_platform_devices[i], busid);
@@ -412,11 +374,11 @@ static Bool doPlatformProbe(struct xf86_platform_device *dev, DriverPtr drvp,
if (entity != -1) {
if ((dev->flags & XF86_PDEV_SERVER_FD) && (!drvp->driverFunc ||
!drvp->driverFunc(NULL, SUPPORTS_SERVER_FDS, NULL))) {
- fd = xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1);
- major = xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_MAJOR, 0);
- minor = xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_MINOR, 0);
+ fd = dev->attribs->fd;
+ major = dev->attribs->major;
+ minor = dev->attribs->minor;
systemd_logind_release_fd(major, minor, fd);
- config_odev_add_int_attribute(dev->attribs, ODEV_ATTRIB_FD, -1);
+ dev->attribs->fd = -1;
dev->flags &= ~XF86_PDEV_SERVER_FD;
}
diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.h b/xorg-server/hw/xfree86/common/xf86platformBus.h
index 5dee4e0e0..317dd24d5 100644
--- a/xorg-server/hw/xfree86/common/xf86platformBus.h
+++ b/xorg-server/hw/xfree86/common/xf86platformBus.h
@@ -45,31 +45,109 @@ int xf86platformProbeDev(DriverPtr drvp);
extern int xf86_num_platform_devices;
extern struct xf86_platform_device *xf86_platform_devices;
-extern char *
-xf86_get_platform_attrib(int index, int attrib_id);
-extern int
-xf86_get_platform_int_attrib(int index, int attrib_id, int def);
extern int
xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned);
extern int
xf86_remove_platform_device(int dev_index);
extern Bool
xf86_get_platform_device_unowned(int index);
-/* Note starting with xserver 1.16 these 2 functions never fail */
-extern Bool
-xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
-extern Bool
-xf86_add_platform_device_int_attrib(int index, int attrib_id, int attrib_value);
extern int
xf86platformAddDevice(int index);
extern void
xf86platformRemoveDevice(int index);
-extern _X_EXPORT char *
-xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id);
-extern _X_EXPORT int
-xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int attrib_id, int def);
+static inline struct OdevAttributes *
+xf86_platform_device_odev_attributes(struct xf86_platform_device *device)
+{
+ return device->attribs;
+}
+
+static inline struct OdevAttributes *
+xf86_platform_odev_attributes(int index)
+{
+ struct xf86_platform_device *device = &xf86_platform_devices[index];
+
+ return device->attribs;
+}
+
+#ifndef _XORG_CONFIG_H_
+/*
+ * Define the legacy API only for external builds
+ */
+
+/* path to kernel device node - Linux e.g. /dev/dri/card0 */
+#define ODEV_ATTRIB_PATH 1
+/* system device path - Linux e.g. /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1 */
+#define ODEV_ATTRIB_SYSPATH 2
+/* DRI-style bus id */
+#define ODEV_ATTRIB_BUSID 3
+/* Server managed FD */
+#define ODEV_ATTRIB_FD 4
+/* Major number of the device node pointed to by ODEV_ATTRIB_PATH */
+#define ODEV_ATTRIB_MAJOR 5
+/* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */
+#define ODEV_ATTRIB_MINOR 6
+/* kernel driver name */
+#define ODEV_ATTRIB_DRIVER 7
+
+/* Protect against a mismatch attribute type by generating a compiler
+ * error using a negative array size when an incorrect attribute is
+ * passed
+ */
+
+#define _ODEV_ATTRIB_IS_STRING(x) ((x) == ODEV_ATTRIB_PATH || \
+ (x) == ODEV_ATTRIB_SYSPATH || \
+ (x) == ODEV_ATTRIB_BUSID || \
+ (x) == ODEV_ATTRIB_DRIVER)
+
+#define _ODEV_ATTRIB_STRING_CHECK(x) ((int (*)[_ODEV_ATTRIB_IS_STRING(x)-1]) 0)
+
+static inline char *
+_xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib, int (*fake)[0])
+{
+ switch (attrib) {
+ case ODEV_ATTRIB_PATH:
+ return xf86_platform_device_odev_attributes(device)->path;
+ case ODEV_ATTRIB_SYSPATH:
+ return xf86_platform_device_odev_attributes(device)->syspath;
+ case ODEV_ATTRIB_BUSID:
+ return xf86_platform_device_odev_attributes(device)->busid;
+ case ODEV_ATTRIB_DRIVER:
+ return xf86_platform_device_odev_attributes(device)->driver;
+ default:
+ assert(FALSE);
+ return NULL;
+ }
+}
+
+#define xf86_get_platform_device_attrib(device, attrib) _xf86_get_platform_device_attrib(device,attrib,_ODEV_ATTRIB_STRING_CHECK(attrib))
+
+#define _ODEV_ATTRIB_IS_INT(x) ((x) == ODEV_ATTRIB_FD || (x) == ODEV_ATTRIB_MAJOR || (x) == ODEV_ATTRIB_MINOR)
+#define _ODEV_ATTRIB_INT_DEFAULT(x) ((x) == ODEV_ATTRIB_FD ? -1 : 0)
+#define _ODEV_ATTRIB_DEFAULT_CHECK(x,def) (_ODEV_ATTRIB_INT_DEFAULT(x) == (def))
+#define _ODEV_ATTRIB_INT_CHECK(x,def) ((int (*)[_ODEV_ATTRIB_IS_INT(x)*_ODEV_ATTRIB_DEFAULT_CHECK(x,def)-1]) 0)
+
+static inline int
+_xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int attrib, int (*fake)[0])
+{
+ switch (attrib) {
+ case ODEV_ATTRIB_FD:
+ return xf86_platform_device_odev_attributes(device)->fd;
+ case ODEV_ATTRIB_MAJOR:
+ return xf86_platform_device_odev_attributes(device)->major;
+ case ODEV_ATTRIB_MINOR:
+ return xf86_platform_device_odev_attributes(device)->minor;
+ default:
+ assert(FALSE);
+ return 0;
+ }
+}
+
+#define xf86_get_platform_device_int_attrib(device, attrib, def) _xf86_get_platform_device_int_attrib(device,attrib,_ODEV_ATTRIB_INT_CHECK(attrib,def))
+
+#endif
+
extern _X_EXPORT Bool
xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid);
diff --git a/xorg-server/hw/xfree86/common/xf86xv.c b/xorg-server/hw/xfree86/common/xf86xv.c
index b16cb5df3..e212a7387 100644
--- a/xorg-server/hw/xfree86/common/xf86xv.c
+++ b/xorg-server/hw/xfree86/common/xf86xv.c
@@ -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;
diff --git a/xorg-server/hw/xfree86/common/xf86xv.h b/xorg-server/hw/xfree86/common/xf86xv.h
index 8986e2e57..de17eb133 100644
--- a/xorg-server/hw/xfree86/common/xf86xv.h
+++ b/xorg-server/hw/xfree86/common/xf86xv.h
@@ -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;
diff --git a/xorg-server/hw/xfree86/glamor_egl/Makefile.am b/xorg-server/hw/xfree86/glamor_egl/Makefile.am
index 85e1c0c06..e697c8296 100644
--- a/xorg-server/hw/xfree86/glamor_egl/Makefile.am
+++ b/xorg-server/hw/xfree86/glamor_egl/Makefile.am
@@ -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)
diff --git a/xorg-server/hw/xfree86/glamor_egl/glamor_xf86_xv.c b/xorg-server/hw/xfree86/glamor_egl/glamor_xf86_xv.c
new file mode 100644
index 000000000..8535fa0c9
--- /dev/null
+++ b/xorg-server/hw/xfree86/glamor_egl/glamor_xf86_xv.c
@@ -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;
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86Rotate.c b/xorg-server/hw/xfree86/modes/xf86Rotate.c
index 0ddd8408e..1627e61dd 100644
--- a/xorg-server/hw/xfree86/modes/xf86Rotate.c
+++ b/xorg-server/hw/xfree86/modes/xf86Rotate.c
@@ -234,12 +234,22 @@ xf86RotateBlockHandler(ScreenPtr pScreen,
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86RotateRedisplay(pScreen);
+ /* Unwrap before redisplay in case the software
+ * cursor layer wants to add its block handler to the
+ * chain
+ */
pScreen->BlockHandler = xf86_config->BlockHandler;
+
+ xf86RotateRedisplay(pScreen);
+
(*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
- /* cannot avoid re-wrapping until all wrapping is audited */
- xf86_config->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xf86RotateBlockHandler;
+
+ /* Re-wrap if we still need this hook */
+ if (xf86_config->rotation_damage != NULL) {
+ xf86_config->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xf86RotateBlockHandler;
+ } else
+ xf86_config->BlockHandler = NULL;
}
void
diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
index d660761c5..1d145b362 100644
--- a/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_platform.c
@@ -30,8 +30,8 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
int err = 0;
Bool paused, server_fd = FALSE;
- major = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MAJOR, 0);
- minor = config_odev_get_int_attribute(attribs, ODEV_ATTRIB_MINOR, 0);
+ major = attribs->major;
+ minor = attribs->minor;
fd = systemd_logind_take_fd(major, minor, path, &paused);
if (fd != -1) {
@@ -41,7 +41,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
systemd_logind_release_fd(major, minor, -1);
return FALSE;
}
- config_odev_add_int_attribute(attribs, ODEV_ATTRIB_FD, fd);
+ attribs->fd = fd;
server_fd = TRUE;
}
@@ -73,8 +73,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD;
buf = drmGetBusid(fd);
- xf86_add_platform_device_attrib(delayed_index,
- ODEV_ATTRIB_BUSID, buf);
+ xf86_platform_odev_attributes(delayed_index)->busid = XNFstrdup(buf);
drmFreeBusid(buf);
v = drmGetVersion(fd);
@@ -83,8 +82,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
goto out;
}
- xf86_add_platform_device_attrib(delayed_index, ODEV_ATTRIB_DRIVER,
- v->name);
+ xf86_platform_odev_attributes(delayed_index)->driver = XNFstrdup(v->name);
drmFreeVersion(v);
out:
@@ -96,16 +94,9 @@ out:
Bool
xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid)
{
- struct OdevAttribute *attrib;
- const char *syspath = NULL;
+ const char *syspath = device->attribs->syspath;
BusType bustype;
const char *id;
- xorg_list_for_each_entry(attrib, &device->attribs->list, member) {
- if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
- syspath = attrib->attrib_name;
- break;
- }
- }
if (!syspath)
return FALSE;
@@ -138,8 +129,7 @@ void
xf86PlatformReprobeDevice(int index, struct OdevAttributes *attribs)
{
Bool ret;
- char *dpath;
- dpath = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH);
+ char *dpath = attribs->path;
ret = get_drm_info(attribs, dpath, index);
if (ret == FALSE) {
@@ -155,18 +145,16 @@ void
xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
{
int i;
- char *path = NULL;
+ char *path = attribs->path;
Bool ret;
- path = config_odev_get_attribute(attribs, ODEV_ATTRIB_PATH);
if (!path)
goto out_free;
for (i = 0; i < xf86_num_platform_devices; i++) {
- char *dpath;
- dpath = xf86_get_platform_attrib(i, ODEV_ATTRIB_PATH);
+ char *dpath = xf86_platform_odev_attributes(i)->path;
- if (!strcmp(path, dpath))
+ if (dpath && !strcmp(path, dpath))
break;
}
@@ -189,7 +177,7 @@ xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
return;
out_free:
- config_odev_free_attribute_list(attribs);
+ config_odev_free_attributes(attribs);
}
void NewGPUDeviceRequest(struct OdevAttributes *attribs)
@@ -214,21 +202,15 @@ void NewGPUDeviceRequest(struct OdevAttributes *attribs)
void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
{
- struct OdevAttribute *attrib;
int index;
- char *syspath = NULL;
+ char *syspath = attribs->syspath;
- xorg_list_for_each_entry(attrib, &attribs->list, member) {
- if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
- syspath = attrib->attrib_name;
- break;
- }
- }
+ if (!syspath)
+ goto out;
for (index = 0; index < xf86_num_platform_devices; index++) {
- char *dspath;
- dspath = xf86_get_platform_attrib(index, ODEV_ATTRIB_SYSPATH);
- if (!strcmp(syspath, dspath))
+ char *dspath = xf86_platform_odev_attributes(index)->syspath;
+ if (dspath && !strcmp(syspath, dspath))
break;
}
@@ -242,7 +224,7 @@ void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
else
xf86platformRemoveDevice(index);
out:
- config_odev_free_attribute_list(attribs);
+ config_odev_free_attributes(attribs);
}
#endif
diff --git a/xorg-server/include/callback.h b/xorg-server/include/callback.h
index df638c0d4..fe7015ee7 100644
--- a/xorg-server/include/callback.h
+++ b/xorg-server/include/callback.h
@@ -64,16 +64,16 @@ typedef struct _CallbackList *CallbackListPtr; /* also in misc.h */
typedef void (*CallbackProcPtr) (CallbackListPtr *, void *, void *);
-extern _X_EXPORT Bool AddCallback(CallbackListPtr * /*pcbl */ ,
- CallbackProcPtr /*callback */ ,
- void */*data */ );
+extern _X_EXPORT Bool AddCallback(CallbackListPtr *pcbl,
+ CallbackProcPtr callback,
+ void *data);
-extern _X_EXPORT Bool DeleteCallback(CallbackListPtr * /*pcbl */ ,
- CallbackProcPtr /*callback */ ,
- void */*data */ );
+extern _X_EXPORT Bool DeleteCallback(CallbackListPtr *pcbl,
+ CallbackProcPtr callback,
+ void *data);
-extern _X_EXPORT void _CallCallbacks(CallbackListPtr * /*pcbl */ ,
- void */*call_data */ );
+extern _X_EXPORT void _CallCallbacks(CallbackListPtr *pcbl,
+ void *call_data);
static inline void
CallCallbacks(CallbackListPtr *pcbl, void *call_data)
@@ -83,7 +83,7 @@ CallCallbacks(CallbackListPtr *pcbl, void *call_data)
_CallCallbacks(pcbl, call_data);
}
-extern _X_EXPORT void DeleteCallbackList(CallbackListPtr * /*pcbl */ );
+extern _X_EXPORT void DeleteCallbackList(CallbackListPtr *pcbl);
extern _X_EXPORT void InitCallbackManager(void);
extern _X_EXPORT void DeleteCallbackManager(void);
diff --git a/xorg-server/include/colormap.h b/xorg-server/include/colormap.h
index 22229ca84..b89bbe114 100644
--- a/xorg-server/include/colormap.h
+++ b/xorg-server/include/colormap.h
@@ -82,14 +82,14 @@ extern _X_EXPORT int CreateColormap(Colormap /*mid */ ,
int /*alloc */ ,
int /*client */ );
-extern _X_EXPORT int FreeColormap(void */*pmap */ ,
- XID /*mid */ );
+extern _X_EXPORT int FreeColormap(void *pmap,
+ XID mid);
-extern _X_EXPORT int TellLostMap(WindowPtr /*pwin */ ,
- void */* Colormap *pmid */ );
+extern _X_EXPORT int TellLostMap(WindowPtr pwin,
+ void *value);
-extern _X_EXPORT int TellGainedMap(WindowPtr /*pwin */ ,
- void */* Colormap *pmid */ );
+extern _X_EXPORT int TellGainedMap(WindowPtr pwin,
+ void *value);
extern _X_EXPORT int CopyColormapAndFree(Colormap /*mid */ ,
ColormapPtr /*pSrc */ ,
@@ -126,8 +126,8 @@ extern _X_EXPORT int QueryColors(ColormapPtr /*pmap */ ,
xrgb * /*prgbList */ ,
ClientPtr client);
-extern _X_EXPORT int FreeClientPixels(void */*pcr */ ,
- XID /*fakeid */ );
+extern _X_EXPORT int FreeClientPixels(void *pcr,
+ XID fakeid);
extern _X_EXPORT int AllocColorCells(int /*client */ ,
ColormapPtr /*pmap */ ,
diff --git a/xorg-server/include/cursor.h b/xorg-server/include/cursor.h
index 9da08affd..1e483ac40 100644
--- a/xorg-server/include/cursor.h
+++ b/xorg-server/include/cursor.h
@@ -68,8 +68,8 @@ extern _X_EXPORT DevScreenPrivateKeyRec cursorScreenDevPriv;
extern _X_EXPORT CursorPtr rootCursor;
-extern _X_EXPORT int FreeCursor(void */*pCurs */ ,
- XID /*cid */ );
+extern _X_EXPORT int FreeCursor(void *pCurs,
+ XID cid);
extern _X_EXPORT CursorPtr RefCursor(CursorPtr /* cursor */);
extern _X_EXPORT CursorPtr UnrefCursor(CursorPtr /* cursor */);
diff --git a/xorg-server/include/dix.h b/xorg-server/include/dix.h
index f42e23655..61ecc8df2 100644
--- a/xorg-server/include/dix.h
+++ b/xorg-server/include/dix.h
@@ -147,14 +147,14 @@ extern _X_EXPORT void UpdateCurrentTime(void);
extern _X_EXPORT void UpdateCurrentTimeIf(void);
-extern _X_EXPORT int dixDestroyPixmap(void */*value */ ,
- XID /*pid */ );
+extern _X_EXPORT int dixDestroyPixmap(void *value,
+ XID pid);
-extern _X_EXPORT void InitClient(ClientPtr /*client */ ,
- int /*i */ ,
- void */*ospriv */ );
+extern _X_EXPORT void InitClient(ClientPtr client,
+ int i,
+ void *ospriv);
-extern _X_EXPORT ClientPtr NextAvailableClient(void */*ospriv */ );
+extern _X_EXPORT ClientPtr NextAvailableClient(void *ospriv);
extern _X_EXPORT void SendErrorToClient(ClientPtr /*client */ ,
unsigned int /*majorCode */ ,
@@ -203,11 +203,11 @@ extern _X_EXPORT int AlterSaveSetForClient(ClientPtr /*client */ ,
extern _X_EXPORT void DeleteWindowFromAnySaveSet(WindowPtr /*pWin */ );
-extern _X_EXPORT void BlockHandler(void */*pTimeout */ ,
- void */*pReadmask */ );
+extern _X_EXPORT void BlockHandler(void *pTimeout,
+ void *pReadmask);
-extern _X_EXPORT void WakeupHandler(int /*result */ ,
- void */*pReadmask */ );
+extern _X_EXPORT void WakeupHandler(int result,
+ void *pReadmask);
void
EnableLimitedSchedulingLatency(void);
@@ -215,21 +215,17 @@ void
void
DisableLimitedSchedulingLatency(void);
-typedef void (*WakeupHandlerProcPtr) (void */* blockData */ ,
- int /* result */ ,
- void */* pReadmask */ );
+typedef void (*WakeupHandlerProcPtr) (void *blockData,
+ int result,
+ void *pReadmask);
-extern _X_EXPORT Bool RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr
- /*blockHandler */ ,
- WakeupHandlerProcPtr
- /*wakeupHandler */ ,
- void */*blockData */ );
+extern _X_EXPORT Bool RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,
+ WakeupHandlerProcPtr wakeupHandler,
+ void *blockData);
-extern _X_EXPORT void RemoveBlockAndWakeupHandlers(BlockHandlerProcPtr
- /*blockHandler */ ,
- WakeupHandlerProcPtr
- /*wakeupHandler */ ,
- void */*blockData */ );
+extern _X_EXPORT void RemoveBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,
+ WakeupHandlerProcPtr wakeupHandler,
+ void *blockData);
extern _X_EXPORT void InitBlockAndWakeupHandlers(void);
@@ -237,22 +233,17 @@ extern _X_EXPORT void ProcessWorkQueue(void);
extern _X_EXPORT void ProcessWorkQueueZombies(void);
-extern _X_EXPORT Bool QueueWorkProc(Bool (* /*function */ )(
- ClientPtr
- /*clientUnused */
- ,
- void *
- /*closure */ ),
- ClientPtr /*client */ ,
- void */*closure */
- );
+extern _X_EXPORT Bool QueueWorkProc(Bool (*function)(ClientPtr clientUnused,
+ void *closure),
+ ClientPtr client,
+ void *closure);
-typedef Bool (*ClientSleepProcPtr) (ClientPtr /*client */ ,
- void */*closure */ );
+typedef Bool (*ClientSleepProcPtr) (ClientPtr client,
+ void *closure);
-extern _X_EXPORT Bool ClientSleep(ClientPtr /*client */ ,
- ClientSleepProcPtr /* function */ ,
- void */*closure */ );
+extern _X_EXPORT Bool ClientSleep(ClientPtr client,
+ ClientSleepProcPtr function,
+ void *closure);
#ifndef ___CLIENTSIGNAL_DEFINED___
#define ___CLIENTSIGNAL_DEFINED___
@@ -444,8 +435,8 @@ extern void
RecalculateDeliverableEvents(WindowPtr /* pWin */ );
extern _X_EXPORT int
-OtherClientGone(void */* value */ ,
- XID /* id */ );
+OtherClientGone(void *value,
+ XID id);
extern void
DoFocusEvents(DeviceIntPtr /* dev */ ,
diff --git a/xorg-server/include/dixfont.h b/xorg-server/include/dixfont.h
index 40d80c141..48c630539 100644
--- a/xorg-server/include/dixfont.h
+++ b/xorg-server/include/dixfont.h
@@ -40,9 +40,9 @@ extern _X_EXPORT void QueueFontWakeup(FontPathElementPtr /*fpe */ );
extern _X_EXPORT void RemoveFontWakeup(FontPathElementPtr /*fpe */ );
-extern _X_EXPORT void FontWakeup(void */*data */ ,
- int /*count */ ,
- void */*LastSelectMask */ );
+extern _X_EXPORT void FontWakeup(void *data,
+ int count,
+ void *LastSelectMask);
extern _X_EXPORT int OpenFont(ClientPtr /*client */ ,
XID /*fid */ ,
@@ -50,8 +50,8 @@ extern _X_EXPORT int OpenFont(ClientPtr /*client */ ,
unsigned /*lenfname */ ,
const char * /*pfontname */ );
-extern _X_EXPORT int CloseFont(void */*pfont */ ,
- XID /*fid */ );
+extern _X_EXPORT int CloseFont(void *pfont,
+ XID fid);
typedef struct _xQueryFontReply *xQueryFontReplyPtr;
diff --git a/xorg-server/include/dixgrabs.h b/xorg-server/include/dixgrabs.h
index d78d8127b..3bd80132b 100644
--- a/xorg-server/include/dixgrabs.h
+++ b/xorg-server/include/dixgrabs.h
@@ -47,8 +47,8 @@ extern GrabPtr CreateGrab(int /* client */ ,
WindowPtr /* confineTo */ ,
CursorPtr /* cursor */ );
-extern _X_EXPORT int DeletePassiveGrab(void */* value */ ,
- XID /* id */ );
+extern _X_EXPORT int DeletePassiveGrab(void *value,
+ XID id);
extern _X_EXPORT Bool GrabMatchesSecond(GrabPtr /* pFirstGrab */ ,
GrabPtr /* pSecondGrab */ ,
diff --git a/xorg-server/include/gc.h b/xorg-server/include/gc.h
index ecaa257bb..eb0a5835e 100644
--- a/xorg-server/include/gc.h
+++ b/xorg-server/include/gc.h
@@ -112,8 +112,8 @@ extern _X_EXPORT int CopyGC(GCPtr /*pgcSrc */ ,
GCPtr /*pgcDst */ ,
BITS32 /*mask */ );
-extern _X_EXPORT int FreeGC(void */*pGC */ ,
- XID /*gid */ );
+extern _X_EXPORT int FreeGC(void *pGC,
+ XID gid);
extern _X_EXPORT void FreeGCperDepth(int /*screenNum */ );
diff --git a/xorg-server/include/gcstruct.h b/xorg-server/include/gcstruct.h
index c830ccde7..6358b8cb7 100644
--- a/xorg-server/include/gcstruct.h
+++ b/xorg-server/include/gcstruct.h
@@ -76,10 +76,10 @@ typedef struct _GCFuncs {
void (*DestroyGC) (GCPtr /*pGC */ );
- void (*ChangeClip) (GCPtr /*pGC */ ,
- int /*type */ ,
- void */*pvalue */ ,
- int /*nrects */ );
+ void (*ChangeClip) (GCPtr pGC,
+ int type,
+ void *pvalue,
+ int nrects);
void (*DestroyClip) (GCPtr /*pGC */ );
@@ -210,21 +210,21 @@ typedef struct _GCOps {
int /*count */ ,
unsigned short * /*chars */ );
- void (*ImageGlyphBlt) (DrawablePtr /*pDrawable */ ,
- GCPtr /*pGC */ ,
- int /*x */ ,
- int /*y */ ,
- unsigned int /*nglyph */ ,
- CharInfoPtr * /*ppci */ ,
- void */*pglyphBase */ );
-
- void (*PolyGlyphBlt) (DrawablePtr /*pDrawable */ ,
- GCPtr /*pGC */ ,
- int /*x */ ,
- int /*y */ ,
- unsigned int /*nglyph */ ,
- CharInfoPtr * /*ppci */ ,
- void */*pglyphBase */ );
+ void (*ImageGlyphBlt) (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void *pglyphBase);
+
+ void (*PolyGlyphBlt) (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void *pglyphBase);
void (*PushPixels) (GCPtr /*pGC */ ,
PixmapPtr /*pBitMap */ ,
diff --git a/xorg-server/include/hotplug.h b/xorg-server/include/hotplug.h
index c4268a0c4..6fe76c806 100644
--- a/xorg-server/include/hotplug.h
+++ b/xorg-server/include/hotplug.h
@@ -32,64 +32,41 @@ extern _X_EXPORT void config_pre_init(void);
extern _X_EXPORT void config_init(void);
extern _X_EXPORT void config_fini(void);
-enum { ODEV_ATTRIB_STRING, ODEV_ATTRIB_INT };
-
-struct OdevAttribute {
- struct xorg_list member;
- int attrib_id;
- union {
- char *attrib_name;
- int attrib_value;
- };
- int attrib_type;
-};
+/* Bump this each time you add something to the struct
+ * so that drivers can easily tell what is available
+ */
+#define ODEV_ATTRIBUTES_VERSION 1
struct OdevAttributes {
- struct xorg_list list;
-};
+ /* path to kernel device node - Linux e.g. /dev/dri/card0 */
+ char *path;
-/* Note starting with xserver 1.16 this function never fails */
-struct OdevAttributes *
-config_odev_allocate_attribute_list(void);
+ /* system device path - Linux e.g. /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1 */
+ char *syspath;
-void
-config_odev_free_attribute_list(struct OdevAttributes *attribs);
+ /* DRI-style bus id */
+ char *busid;
-/* Note starting with xserver 1.16 this function never fails */
-Bool
-config_odev_add_attribute(struct OdevAttributes *attribs, int attrib,
- const char *attrib_name);
+ /* Server managed FD */
+ int fd;
-char *
-config_odev_get_attribute(struct OdevAttributes *attribs, int attrib_id);
+ /* Major number of the device node pointed to by ODEV_ATTRIB_PATH */
+ int major;
-/* Note starting with xserver 1.16 this function never fails */
-Bool
-config_odev_add_int_attribute(struct OdevAttributes *attribs, int attrib,
- int attrib_value);
+ /* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */
+ int minor;
+
+ /* kernel driver name */
+ char *driver;
+};
-int
-config_odev_get_int_attribute(struct OdevAttributes *attribs, int attrib,
- int def);
+/* Note starting with xserver 1.16 this function never fails */
+struct OdevAttributes *
+config_odev_allocate_attributes(void);
void
config_odev_free_attributes(struct OdevAttributes *attribs);
-/* path to kernel device node - Linux e.g. /dev/dri/card0 */
-#define ODEV_ATTRIB_PATH 1
-/* system device path - Linux e.g. /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1 */
-#define ODEV_ATTRIB_SYSPATH 2
-/* DRI-style bus id */
-#define ODEV_ATTRIB_BUSID 3
-/* Server managed FD */
-#define ODEV_ATTRIB_FD 4
-/* Major number of the device node pointed to by ODEV_ATTRIB_PATH */
-#define ODEV_ATTRIB_MAJOR 5
-/* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */
-#define ODEV_ATTRIB_MINOR 6
-/* kernel driver name */
-#define ODEV_ATTRIB_DRIVER 4
-
typedef void (*config_odev_probe_proc_ptr)(struct OdevAttributes *attribs);
void config_odev_probe(config_odev_probe_proc_ptr probe_callback);
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index cbf949b53..1b2102fc1 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -314,10 +314,10 @@ extern _X_EXPORT Bool InitTouchClassDeviceStruct(DeviceIntPtr /*device */ ,
unsigned int /*mode */ ,
unsigned int /*numAxes */ );
-typedef void (*BellProcPtr) (int /*percent */ ,
- DeviceIntPtr /*device */ ,
- void */*ctrl */ ,
- int);
+typedef void (*BellProcPtr) (int percent,
+ DeviceIntPtr device,
+ void *ctrl,
+ int feedbackClass);
typedef void (*KbdCtrlProcPtr) (DeviceIntPtr /*device */ ,
KeybdCtrl * /*ctrl */ );
diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h
index d26e399b6..0cbb9288e 100644
--- a/xorg-server/include/os.h
+++ b/xorg-server/include/os.h
@@ -139,8 +139,8 @@ extern _X_EXPORT const char *ClientAuthorized(ClientPtr /*client */ ,
unsigned int /*string_n */ ,
char * /*auth_string */ );
-extern _X_EXPORT Bool EstablishNewConnections(ClientPtr /*clientUnused */ ,
- void */*closure */ );
+extern _X_EXPORT Bool EstablishNewConnections(ClientPtr clientUnused,
+ void *closure);
extern _X_EXPORT void CheckConnections(void);
@@ -173,14 +173,14 @@ extern _X_EXPORT Bool AddClientOnOpenFD(int /* fd */ );
extern _X_EXPORT CARD32 GetTimeInMillis(void);
extern _X_EXPORT CARD64 GetTimeInMicros(void);
-extern _X_EXPORT void AdjustWaitForDelay(void */*waitTime */ ,
- unsigned long /*newdelay */ );
+extern _X_EXPORT void AdjustWaitForDelay(void *waitTime,
+ unsigned long newdelay);
typedef struct _OsTimerRec *OsTimerPtr;
-typedef CARD32 (*OsTimerCallback) (OsTimerPtr /* timer */ ,
- CARD32 /* time */ ,
- void */* arg */ );
+typedef CARD32 (*OsTimerCallback) (OsTimerPtr timer,
+ CARD32 time,
+ void *arg);
extern _X_EXPORT void TimerInit(void);
@@ -189,11 +189,11 @@ extern _X_EXPORT Bool TimerForce(OsTimerPtr /* timer */ );
#define TimerAbsolute (1<<0)
#define TimerForceOld (1<<1)
-extern _X_EXPORT OsTimerPtr TimerSet(OsTimerPtr /* timer */ ,
- int /* flags */ ,
- CARD32 /* millis */ ,
- OsTimerCallback /* func */ ,
- void */* arg */ );
+extern _X_EXPORT OsTimerPtr TimerSet(OsTimerPtr timer,
+ int flags,
+ CARD32 millis,
+ OsTimerCallback func,
+ void *arg);
extern _X_EXPORT void TimerCheck(void);
extern _X_EXPORT void TimerCancel(OsTimerPtr /* pTimer */ );
@@ -210,9 +210,9 @@ extern _X_EXPORT void UseMsg(void);
extern _X_EXPORT void ProcessCommandLine(int /*argc */ , char * /*argv */ []);
-extern _X_EXPORT int set_font_authorizations(char ** /* authorizations */ ,
- int * /*authlen */ ,
- void */* client */ );
+extern _X_EXPORT int set_font_authorizations(char **authorizations,
+ int *authlen,
+ void *client);
#ifndef _HAVE_XALLOC_DECLS
#define _HAVE_XALLOC_DECLS
@@ -391,18 +391,18 @@ AddHost(ClientPtr /*client */ ,
const void * /*pAddr */ );
extern _X_EXPORT Bool
-ForEachHostInFamily(int /*family */ ,
- Bool (* /*func */ )(
- unsigned char * /* addr */ ,
- short /* len */ ,
- void */* closure */ ),
- void */*closure */ );
+ForEachHostInFamily(int family,
+ Bool (*func)(
+ unsigned char *addr,
+ short len,
+ void *closure),
+ void *closure);
extern _X_EXPORT int
-RemoveHost(ClientPtr /*client */ ,
- int /*family */ ,
- unsigned /*length */ ,
- void */*pAddr */ );
+RemoveHost(ClientPtr client,
+ int family,
+ unsigned length,
+ void *pAddr);
extern _X_EXPORT int
GetHosts(void ** /*data */ ,
@@ -464,7 +464,7 @@ DefineSelf(int /*fd */ );
#if XDMCP
extern _X_EXPORT void
-AugmentSelf(void */*from */ , int /*len */ );
+AugmentSelf(void *from, int len);
extern _X_EXPORT void
RegisterAuthorizations(void);
diff --git a/xorg-server/include/pixmap.h b/xorg-server/include/pixmap.h
index 46ec3f5a2..f3c2c60c0 100644
--- a/xorg-server/include/pixmap.h
+++ b/xorg-server/include/pixmap.h
@@ -93,13 +93,13 @@ typedef union _PixUnion {
#define WindowDrawable(type) \
((type == DRAWABLE_WINDOW) || (type == UNDRAWABLE_WINDOW))
-extern _X_EXPORT PixmapPtr GetScratchPixmapHeader(ScreenPtr /*pScreen */ ,
- int /*width */ ,
- int /*height */ ,
- int /*depth */ ,
- int /*bitsPerPixel */ ,
- int /*devKind */ ,
- void */*pPixData */ );
+extern _X_EXPORT PixmapPtr GetScratchPixmapHeader(ScreenPtr pScreen,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ void *pPixData);
extern _X_EXPORT void FreeScratchPixmapHeader(PixmapPtr /*pPixmap */ );
diff --git a/xorg-server/include/property.h b/xorg-server/include/property.h
index 3b8ea8b2d..cae44719b 100644
--- a/xorg-server/include/property.h
+++ b/xorg-server/include/property.h
@@ -57,24 +57,24 @@ extern _X_EXPORT int dixLookupProperty(PropertyPtr * /*result */ ,
ClientPtr /*pClient */ ,
Mask /*access_mode */ );
-extern _X_EXPORT int dixChangeWindowProperty(ClientPtr /*pClient */ ,
- WindowPtr /*pWin */ ,
- Atom /*property */ ,
- Atom /*type */ ,
- int /*format */ ,
- int /*mode */ ,
- unsigned long /*len */ ,
- void */*value */ ,
- Bool /*sendevent */ );
-
-extern _X_EXPORT int ChangeWindowProperty(WindowPtr /*pWin */ ,
- Atom /*property */ ,
- Atom /*type */ ,
- int /*format */ ,
- int /*mode */ ,
- unsigned long /*len */ ,
- void */*value */ ,
- Bool /*sendevent */ );
+extern _X_EXPORT int dixChangeWindowProperty(ClientPtr pClient,
+ WindowPtr pWin,
+ Atom property,
+ Atom type,
+ int format,
+ int mode,
+ unsigned long len,
+ void *value,
+ Bool sendevent);
+
+extern _X_EXPORT int ChangeWindowProperty(WindowPtr pWin,
+ Atom property,
+ Atom type,
+ int format,
+ int mode,
+ unsigned long len,
+ void *value,
+ Bool sendevent);
extern _X_EXPORT int DeleteProperty(ClientPtr /*client */ ,
WindowPtr /*pWin */ ,
diff --git a/xorg-server/include/resource.h b/xorg-server/include/resource.h
index db44aefad..fe56bb2a7 100644
--- a/xorg-server/include/resource.h
+++ b/xorg-server/include/resource.h
@@ -136,21 +136,21 @@ typedef struct {
void *value;
} ResourceStateInfoRec;
-typedef int (*DeleteType) (void */*value */ ,
- XID /*id */ );
+typedef int (*DeleteType) (void *value,
+ XID id);
-typedef void (*FindResType) (void */*value */ ,
- XID /*id */ ,
- void */*cdata */ );
+typedef void (*FindResType) (void *value,
+ XID id,
+ void *cdata);
-typedef void (*FindAllRes) (void */*value */ ,
- XID /*id */ ,
- RESTYPE /*type */ ,
- void */*cdata */ );
+typedef void (*FindAllRes) (void *value,
+ XID id,
+ RESTYPE type,
+ void *cdata);
-typedef Bool (*FindComplexResType) (void */*value */ ,
- XID /*id */ ,
- void */*cdata */ );
+typedef Bool (*FindComplexResType) (void *value,
+ XID id,
+ void *cdata);
/* Structure for estimating resource memory usage. Memory usage
* consists of space allocated for the resource itself and of
@@ -166,16 +166,16 @@ typedef struct {
unsigned long refCnt;
} ResourceSizeRec, *ResourceSizePtr;
-typedef void (*SizeType)(void */*value*/,
- XID /*id*/,
- ResourceSizePtr /*size*/);
+typedef void (*SizeType)(void *value,
+ XID id,
+ ResourceSizePtr size);
-extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType /*deleteFunc */ ,
- const char * /*name */ );
+extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType deleteFunc,
+ const char *name);
-typedef void (*FindTypeSubResources)(void */* value */,
- FindAllRes /* func */,
- void */* cdata */);
+typedef void (*FindTypeSubResources)(void *value,
+ FindAllRes func,
+ void *cdata);
extern _X_EXPORT SizeType GetResourceTypeSizeFunc(
RESTYPE /*type*/);
@@ -200,9 +200,9 @@ extern _X_EXPORT XID FakeClientID(int /*client */ );
#ifdef __APPLE__
#define AddResource Darwin_X_AddResource
#endif
-extern _X_EXPORT Bool AddResource(XID /*id */ ,
- RESTYPE /*type */ ,
- void */*value */ );
+extern _X_EXPORT Bool AddResource(XID id,
+ RESTYPE type,
+ void *value);
extern _X_EXPORT void FreeResource(XID /*id */ ,
RESTYPE /*skipDeleteFuncType */ );
@@ -211,27 +211,27 @@ extern _X_EXPORT void FreeResourceByType(XID /*id */ ,
RESTYPE /*type */ ,
Bool /*skipFree */ );
-extern _X_EXPORT Bool ChangeResourceValue(XID /*id */ ,
- RESTYPE /*rtype */ ,
- void */*value */ );
+extern _X_EXPORT Bool ChangeResourceValue(XID id,
+ RESTYPE rtype,
+ void *value);
-extern _X_EXPORT void FindClientResourcesByType(ClientPtr /*client */ ,
- RESTYPE /*type */ ,
- FindResType /*func */ ,
- void */*cdata */ );
+extern _X_EXPORT void FindClientResourcesByType(ClientPtr client,
+ RESTYPE type,
+ FindResType func,
+ void *cdata);
-extern _X_EXPORT void FindAllClientResources(ClientPtr /*client */ ,
- FindAllRes /*func */ ,
- void */*cdata */ );
+extern _X_EXPORT void FindAllClientResources(ClientPtr client,
+ FindAllRes func,
+ void *cdata);
/** @brief Iterate through all subresources of a resource.
@note The XID argument provided to the FindAllRes function
may be 0 for subresources that don't have an XID */
-extern _X_EXPORT void FindSubResources(void */*resource*/,
- RESTYPE /*type*/,
- FindAllRes /*func*/,
- void */*cdata*/);
+extern _X_EXPORT void FindSubResources(void *resource,
+ RESTYPE type,
+ FindAllRes func,
+ void *cdata);
extern _X_EXPORT void FreeClientNeverRetainResources(ClientPtr /*client */ );
diff --git a/xorg-server/include/scrnintstr.h b/xorg-server/include/scrnintstr.h
index 6acdadd7a..6955e77fd 100644
--- a/xorg-server/include/scrnintstr.h
+++ b/xorg-server/include/scrnintstr.h
@@ -259,23 +259,23 @@ typedef void (*SendGraphicsExposeProcPtr) (ClientPtr /*client */ ,
int /*major */ ,
int /*minor */ );
-typedef void (*ScreenBlockHandlerProcPtr) (ScreenPtr /*pScreen*/ ,
- void */*pTimeout */ ,
- void */*pReadmask */ );
+typedef void (*ScreenBlockHandlerProcPtr) (ScreenPtr pScreen,
+ void *pTimeout,
+ void *pReadmask);
-typedef void (*ScreenWakeupHandlerProcPtr) (ScreenPtr /*pScreen*/ ,
- unsigned long /*result */ ,
- void */*pReadMask */ );
+typedef void (*ScreenWakeupHandlerProcPtr) (ScreenPtr pScreen,
+ unsigned long result,
+ void *pReadMask);
typedef Bool (*CreateScreenResourcesProcPtr) (ScreenPtr /*pScreen */ );
-typedef Bool (*ModifyPixmapHeaderProcPtr) (PixmapPtr /*pPixmap */ ,
- int /*width */ ,
- int /*height */ ,
- int /*depth */ ,
- int /*bitsPerPixel */ ,
- int /*devKind */ ,
- void */*pPixData */ );
+typedef Bool (*ModifyPixmapHeaderProcPtr) (PixmapPtr pPixmap,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ void *pPixData);
typedef PixmapPtr (*GetWindowPixmapProcPtr) (WindowPtr /*pWin */ );
@@ -358,6 +358,96 @@ typedef WindowPtr (*XYToWindowProcPtr)(ScreenPtr pScreen,
typedef int (*NameWindowPixmapProcPtr)(WindowPtr, PixmapPtr, CARD32);
+/* Wrapping Screen procedures
+
+ There are a few modules in the X server which dynamically add and
+ remove themselves from various screen procedure call chains.
+
+ For example, the BlockHandler is dynamically modified by:
+
+ * xf86Rotate
+ * miSprite
+ * composite
+ * render (for animated cursors)
+
+ Correctly manipulating this chain is complicated by the fact that
+ the chain is constructed through a sequence of screen private
+ structures, each holding the next screen->proc pointer.
+
+ To add a module to a screen->proc chain is fairly simple; just save
+ the current screen->proc value in the module screen private
+ and store the module's function in the screen->proc location.
+
+ Removing a screen proc is a bit trickier. It seems like all you
+ need to do is set the screen->proc pointer back to the value saved
+ in your screen private. However, if some other module has come
+ along and wrapped on top of you, then the right place to store the
+ previous screen->proc value is actually in the wrapping module's
+ screen private structure(!). Of course, you have no idea what
+ other module may have wrapped on top, nor could you poke inside
+ its screen private in any case.
+
+ To make this work, we restrict the unwrapping process to happen
+ during the invocation of the screen proc itself, and then we
+ require the screen proc to take some care when manipulating the
+ screen proc functions pointers.
+
+ The requirements are:
+
+ 1) The screen proc must set the screen->proc pointer back to the
+ value saved in its screen private before calling outside its
+ module.
+
+ 2a) If the screen proc wants to be remove itself from the chain,
+ it must not manipulate screen->proc pointer again before
+ returning.
+
+ 2b) If the screen proc wants to remain in the chain, it must:
+
+ 2b.1) Re-fetch the screen->proc pointer and store that in
+ its screen private. This ensures that any changes
+ to the chain will be preserved.
+
+ 2b.2) Set screen->proc back to itself
+
+ One key requirement here is that these steps must wrap not just
+ any invocation of the nested screen->proc value, but must nest
+ essentially any calls outside the current module. This ensures
+ that other modules can reliably manipulate screen->proc wrapping
+ using these same rules.
+
+ For example, the animated cursor code in render has two macros,
+ Wrap and Unwrap.
+
+ #define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
+
+ Unwrap takes the screen private (as), the screen (s) and the
+ member name (elt), and restores screen->proc to that saved in the
+ screen private.
+
+ #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
+
+ Wrap takes the screen private (as), the screen (s), the member
+ name (elt) and the wrapping function (func). It saves the
+ current screen->proc value in the screen private, and then sets the
+ screen->proc to the local wrapping function.
+
+ Within each of these functions, there's a pretty simple pattern:
+
+ Unwrap(as, pScreen, UnrealizeCursor);
+
+ // Do local stuff, including possibly calling down through
+ // pScreen->UnrealizeCursor
+
+ Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
+
+ The wrapping block handler is a bit different; it does the Unwrap,
+ the local operations and then only re-Wraps if the hook is still
+ required. Unwrap occurrs at the top of each function, just after
+ entry, and Wrap occurrs at the bottom of each function, just
+ before returning.
+ */
+
typedef struct _Screen {
int myNum; /* index of this instance in Screens[] */
ATOM id;
diff --git a/xorg-server/include/window.h b/xorg-server/include/window.h
index b5a937eef..c123728f0 100644
--- a/xorg-server/include/window.h
+++ b/xorg-server/include/window.h
@@ -72,16 +72,16 @@ struct _Cursor;
typedef struct _BackingStore *BackingStorePtr;
typedef struct _Window *WindowPtr;
-typedef int (*VisitWindowProcPtr) (WindowPtr /*pWin */ ,
- void */*data */ );
+typedef int (*VisitWindowProcPtr) (WindowPtr pWin,
+ void *data);
-extern _X_EXPORT int TraverseTree(WindowPtr /*pWin */ ,
- VisitWindowProcPtr /*func */ ,
- void */*data */ );
+extern _X_EXPORT int TraverseTree(WindowPtr pWin,
+ VisitWindowProcPtr func,
+ void *data);
-extern _X_EXPORT int WalkTree(ScreenPtr /*pScreen */ ,
- VisitWindowProcPtr /*func */ ,
- void */*data */ );
+extern _X_EXPORT int WalkTree(ScreenPtr pScreen,
+ VisitWindowProcPtr func,
+ void *data);
extern _X_EXPORT Bool CreateRootWindow(ScreenPtr /*pScreen */ );
@@ -108,8 +108,8 @@ extern _X_EXPORT WindowPtr CreateWindow(Window /*wid */ ,
VisualID /*visual */ ,
int * /*error */ );
-extern _X_EXPORT int DeleteWindow(void */*pWin */ ,
- XID /*wid */ );
+extern _X_EXPORT int DeleteWindow(void *pWin,
+ XID wid);
extern _X_EXPORT int DestroySubwindows(WindowPtr /*pWin */ ,
ClientPtr /*client */ );
diff --git a/xorg-server/include/xkbsrv.h b/xorg-server/include/xkbsrv.h
index 229de2194..a4878fc9e 100644
--- a/xorg-server/include/xkbsrv.h
+++ b/xorg-server/include/xkbsrv.h
@@ -596,15 +596,15 @@ extern _X_EXPORT void XkbSendCompatMapNotify(DeviceIntPtr /* kbd */ ,
xkbCompatMapNotify * /* ev */
);
-extern _X_EXPORT void XkbHandleBell(BOOL /* force */ ,
- BOOL /* eventOnly */ ,
- DeviceIntPtr /* kbd */ ,
- CARD8 /* percent */ ,
- void */* ctrl */ ,
- CARD8 /* class */ ,
- Atom /* name */ ,
- WindowPtr /* pWin */ ,
- ClientPtr /* pClient */
+extern _X_EXPORT void XkbHandleBell(BOOL force,
+ BOOL eventOnly,
+ DeviceIntPtr kbd,
+ CARD8 percent,
+ void *ctrl,
+ CARD8 class,
+ Atom name,
+ WindowPtr pWin,
+ ClientPtr pClient
);
extern _X_EXPORT void XkbSendAccessXNotify(DeviceIntPtr /* kbd */ ,
diff --git a/xorg-server/mi/mi.h b/xorg-server/mi/mi.h
index 1209a16c4..feba5cb0c 100644
--- a/xorg-server/mi/mi.h
+++ b/xorg-server/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 */ ,
@@ -265,22 +270,22 @@ extern _X_EXPORT void miPolyFillRect(DrawablePtr /*pDrawable */ ,
/* miglblt.c */
-extern _X_EXPORT void miPolyGlyphBlt(DrawablePtr /*pDrawable */ ,
- GCPtr /*pGC */ ,
- int /*x */ ,
- int /*y */ ,
- unsigned int /*nglyph */ ,
- CharInfoPtr * /*ppci */ ,
- void */*pglyphBase */
+extern _X_EXPORT void miPolyGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void *pglyphBase
);
-extern _X_EXPORT void miImageGlyphBlt(DrawablePtr /*pDrawable */ ,
- GCPtr /*pGC */ ,
- int /*x */ ,
- int /*y */ ,
- unsigned int /*nglyph */ ,
- CharInfoPtr * /*ppci */ ,
- void */*pglyphBase */
+extern _X_EXPORT void miImageGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void *pglyphBase
);
/* mipoly.c */
@@ -381,36 +386,36 @@ extern _X_EXPORT void miPushPixels(GCPtr /*pGC */ ,
/* miscrinit.c */
-extern _X_EXPORT Bool miModifyPixmapHeader(PixmapPtr /*pPixmap */ ,
- int /*width */ ,
- int /*height */ ,
- int /*depth */ ,
- int /*bitsPerPixel */ ,
- int /*devKind */ ,
- void */*pPixData */
+extern _X_EXPORT Bool miModifyPixmapHeader(PixmapPtr pPixmap,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ void *pPixData
);
extern _X_EXPORT Bool miCreateScreenResources(ScreenPtr /*pScreen */
);
-extern _X_EXPORT Bool miScreenDevPrivateInit(ScreenPtr /*pScreen */ ,
- int /*width */ ,
- void */*pbits */
+extern _X_EXPORT Bool miScreenDevPrivateInit(ScreenPtr pScreen,
+ int width,
+ void *pbits
);
-extern _X_EXPORT Bool miScreenInit(ScreenPtr /*pScreen */ ,
- void */*pbits */ ,
- int /*xsize */ ,
- int /*ysize */ ,
- int /*dpix */ ,
- int /*dpiy */ ,
- int /*width */ ,
- int /*rootDepth */ ,
- int /*numDepths */ ,
- DepthPtr /*depths */ ,
- VisualID /*rootVisual */ ,
- int /*numVisuals */ ,
- VisualPtr /*visuals */
+extern _X_EXPORT Bool miScreenInit(ScreenPtr pScreen,
+ void *pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int rootDepth,
+ int numDepths,
+ DepthPtr depths,
+ VisualID rootVisual,
+ int numVisuals,
+ VisualPtr visuals
);
/* mivaltree.c */
@@ -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 */ ,
diff --git a/xorg-server/mi/miarc.c b/xorg-server/mi/miarc.c
index 0f56c7db3..e55108a44 100644
--- a/xorg-server/mi/miarc.c
+++ b/xorg-server/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);
+}
diff --git a/xorg-server/mi/mifillarc.c b/xorg-server/mi/mifillarc.c
index 337343dd1..08484d703 100644
--- a/xorg-server/mi/mifillarc.c
+++ b/xorg-server/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.
*/
+
+/* 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, xArc * parcs)
+miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, 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);
- }
- else {
- if (miCanFillArc(arc))
- miFillArcSliceI(pDraw, pGC, arc);
- else
- miFillArcSliceD(pDraw, pGC, arc);
- }
+ 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;
+ }
+
+ 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;
}
}
diff --git a/xorg-server/mi/misprite.c b/xorg-server/mi/misprite.c
index eea731a15..68a49be1e 100644
--- a/xorg-server/mi/misprite.c
+++ b/xorg-server/mi/misprite.c
@@ -520,6 +520,8 @@ miSpriteBlockHandler(ScreenPtr pScreen, void *pTimeout,
miCursorInfoPtr pCursorInfo;
Bool WorkToDo = FALSE;
+ SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler);
+
for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
if (DevHasCursor(pDev)) {
pCursorInfo = MISPRITE(pDev);
@@ -543,8 +545,6 @@ miSpriteBlockHandler(ScreenPtr pScreen, void *pTimeout,
}
}
- SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler);
-
(*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
if (WorkToDo)
diff --git a/xorg-server/mi/miwideline.c b/xorg-server/mi/miwideline.c
index b76e7a818..29ba12c69 100644
--- a/xorg-server/mi/miwideline.c
+++ b/xorg-server/mi/miwideline.c
@@ -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);
+ }
+}
diff --git a/xorg-server/mi/mizerarc.c b/xorg-server/mi/mizerarc.c
index 9dac180d1..b216cf43d 100644
--- a/xorg-server/mi/mizerarc.c
+++ b/xorg-server/mi/mizerarc.c
@@ -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);
diff --git a/xorg-server/mi/mizerline.c b/xorg-server/mi/mizerline.c
index 90798dbdf..f30e01239 100644
--- a/xorg-server/mi/mizerline.c
+++ b/xorg-server/mi/mizerline.c
@@ -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);
diff --git a/xorg-server/os/access.c b/xorg-server/os/access.c
index e8c0781f2..9fcf99a73 100644
--- a/xorg-server/os/access.c
+++ b/xorg-server/os/access.c
@@ -1217,9 +1217,9 @@ AddHost(ClientPtr client, int family, unsigned length, /* of bytes in pAddr */
}
Bool
-ForEachHostInFamily(int family, Bool (*func) (unsigned char * /* addr */ ,
- short /* len */ ,
- void */* closure */ ),
+ForEachHostInFamily(int family, Bool (*func) (unsigned char *addr,
+ short len,
+ void *closure),
void *closure)
{
HOST *host;
diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c
index a368569d0..2a721b948 100644
--- a/xorg-server/os/log.c
+++ b/xorg-server/os/log.c
@@ -697,7 +697,7 @@ LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list a
if (sizeof(buf) - len == 1)
buf[len - 1] = '\n';
- newline = (buf[len - 1] == '\n');
+ newline = (len > 0 && buf[len - 1] == '\n');
LogSWrite(verb, buf, len, newline);
}