xorg-server-1.16.0-upstream_glamor_fix-1.patch 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
  2. Date: 2014-08-18
  3. Initial Package Version: 1.16.0
  4. Upstream Status: Applied
  5. Origin: Upstream
  6. Description: Fixes bug in glamor.
  7. From 3c0431b8911241552a15a43e4279c50658b50a18 Mon Sep 17 00:00:00 2001
  8. From: Keith Packard <keithp@keithp.com>
  9. Date: Wed, 16 Jul 2014 16:03:23 -0700
  10. Subject: glamor: Fix temp picture coordinates in
  11. glamor_composite_clipped_region
  12. To understand this patch, let's start at the protocol interface where
  13. the relationship between the coordinate spaces is documented:
  14. static Bool
  15. _glamor_composite(CARD8 op,
  16. PicturePtr source,
  17. PicturePtr mask,
  18. PicturePtr dest,
  19. INT16 x_source,
  20. INT16 y_source,
  21. INT16 x_mask,
  22. INT16 y_mask,
  23. INT16 x_dest, INT16 y_dest,
  24. CARD16 width, CARD16 height, Bool fallback)
  25. The coordinates are passed to this function directly off the wire and
  26. are all relative to their respective drawables. For Windows, this means
  27. that they are relative to the upper left corner of the window, in
  28. whatever pixmap that window is getting drawn to.
  29. _glamor_composite calls miComputeCompositeRegion to construct a clipped
  30. region to actually render to. In reality, miComputeCompositeRegion clips
  31. only to the destination these days; source clip region based clipping
  32. would have to respect the transform, which isn't really possible. The
  33. returned region is relative to the screen in which dest lives; offset by
  34. dest->drawable.x and dest->drawable.y.
  35. What is important to realize here is that, because of clipping, the
  36. composite region may not have the same position within the destination
  37. drawable as x_dest, y_dest. The protocol coordinates now exist solely to
  38. 'pin' the three objects together.
  39. extents->x1,y1 Screen origin of clipped operation
  40. width,height Extents of the clipped operation
  41. x_dest,y_dest Unclipped destination-relative operation coordinate
  42. x_source,y_source Unclipped source-relative operation coordinate
  43. x_mask,y_mask Unclipped mask-relative operation coordinate
  44. One thing we want to know is what the offset is from the original
  45. operation origin to the clipped origin
  46. Destination drawable relative coordinates of the clipped operation:
  47. x_dest_clipped = extents->x1 - dest->drawable.x
  48. y_dest_clipped = extents->y1 - dest->drawable.y
  49. Offset from the original operation origin:
  50. x_off_clipped = x_dest_clipped - x_dest
  51. y_off_clipped = y_dest_clipped - y_dest
  52. Source drawable relative coordinates of the clipped operation:
  53. x_source_clipped = x_source + x_off_clipped;
  54. y_source_clipped = y_source + y_off_clipped;
  55. Mask drawable relative coordinates of the clipped operation:
  56. x_mask_clipped = x_source + x_off_clipped;
  57. y_mask_clipped = y_source + y_off_clipped;
  58. This is where the original code fails -- it doesn't subtract the
  59. destination drawable location when computing the distance that the
  60. operation has been moved by clipping. Here's what it does when
  61. constructing a temporary source picture:
  62. temp_src =
  63. glamor_convert_gradient_picture(screen, source,
  64. extent->x1 + x_source - x_dest,
  65. extent->y1 + y_source - y_dest,
  66. width, height);
  67. ...
  68. x_temp_src = -extent->x1 + x_dest;
  69. y_temp_src = -extent->y1 + y_dest;
  70. glamor_convert_gradient_picture needs source drawable relative
  71. coordinates, but that is not what it's getting; it's getting
  72. screen-relative coordinates for the destination, adjusted by the
  73. distance between the provided source and destination operation
  74. coordinates. We want x_source_clipped and y_source_clipped:
  75. x_source_clipped = x_source + x_off_clipped
  76. = x_source + x_dest_clipped - x_dest
  77. = x_source + extents->x1 - dest->drawable.x - x_dest
  78. x_temp_src/y_temp_src are supposed to be the coordinates of the original
  79. operation translated to the temporary picture:
  80. x_temp_src = x_source - x_source_clipped;
  81. y_temp_src = y_source - y_source_clipped;
  82. Note that x_source_clipped/y_source_clipped will never be less than
  83. x_source/y_source because all we're doing is clipping. This means that
  84. x_temp_src/y_temp_src will always be non-positive; the original source
  85. coordinate can never be strictly *inside* the temporary image or we
  86. could have made the temporary image smaller.
  87. x_temp_src = x_source - x_source_clipped
  88. = x_source - (x_source + x_off_clipped)
  89. = -x_off_clipped
  90. = x_dest - x_dest_clipped
  91. = x_dest - (extents->x1 - dest->drawable.x)
  92. Again, this is off by the destination origin within the screen
  93. coordinate space.
  94. The code should look like:
  95. temp_src =
  96. glamor_convert_gradient_picture(screen, source,
  97. extent->x1 + x_source - x_dest - dest->pDrawable->x,
  98. extent->y1 + y_source - y_dest - dest->pDrawable->y,
  99. width, height);
  100. x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x;
  101. y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y;
  102. Signed-off-by: Keith Packard <keithp@keithp.com>
  103. Reviewed-by: Markus Wick <markus@selfnet.de>
  104. (cherry picked from commit 55f5bfb578e934319d1308cbb56c900c5ac7cfa7)
  105. Signed-off-by: Julien Cristau <jcristau@debian.org>
  106. diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
  107. index 14ab738..e5d5d2c 100644
  108. --- a/glamor/glamor_render.c
  109. +++ b/glamor/glamor_render.c
  110. @@ -1450,8 +1450,8 @@ glamor_composite_clipped_region(CARD8 op,
  111. || source_pixmap->drawable.height != height)))) {
  112. temp_src =
  113. glamor_convert_gradient_picture(screen, source,
  114. - extent->x1 + x_source - x_dest,
  115. - extent->y1 + y_source - y_dest,
  116. + extent->x1 + x_source - x_dest - dest->pDrawable->x,
  117. + extent->y1 + y_source - y_dest - dest->pDrawable->y,
  118. width, height);
  119. if (!temp_src) {
  120. temp_src = source;
  121. @@ -1459,8 +1459,8 @@ glamor_composite_clipped_region(CARD8 op,
  122. }
  123. temp_src_priv =
  124. glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable));
  125. - x_temp_src = -extent->x1 + x_dest;
  126. - y_temp_src = -extent->y1 + y_dest;
  127. + x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x;
  128. + y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y;
  129. }
  130. if (mask
  131. @@ -1474,8 +1474,8 @@ glamor_composite_clipped_region(CARD8 op,
  132. * to do reduce one convertion. */
  133. temp_mask =
  134. glamor_convert_gradient_picture(screen, mask,
  135. - extent->x1 + x_mask - x_dest,
  136. - extent->y1 + y_mask - y_dest,
  137. + extent->x1 + x_mask - x_dest - dest->pDrawable->x,
  138. + extent->y1 + y_mask - y_dest - dest->pDrawable->y,
  139. width, height);
  140. if (!temp_mask) {
  141. temp_mask = mask;
  142. @@ -1483,8 +1483,8 @@ glamor_composite_clipped_region(CARD8 op,
  143. }
  144. temp_mask_priv =
  145. glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable));
  146. - x_temp_mask = -extent->x1 + x_dest;
  147. - y_temp_mask = -extent->y1 + y_dest;
  148. + x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x;
  149. + y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y;
  150. }
  151. /* Do two-pass PictOpOver componentAlpha, until we enable
  152. * dual source color blending.
  153. --
  154. cgit v0.10.2