glamor_transform.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright © 2014 Keith Packard
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that copyright
  7. * notice and this permission notice appear in supporting documentation, and
  8. * that the name of the copyright holders not be used in advertising or
  9. * publicity pertaining to distribution of the software without specific,
  10. * written prior permission. The copyright holders make no representations
  11. * about the suitability of this software for any purpose. It is provided "as
  12. * is" without express or implied warranty.
  13. *
  14. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20. * OF THIS SOFTWARE.
  21. */
  22. #include "glamor_priv.h"
  23. #include "glamor_transform.h"
  24. /*
  25. * Set up rendering to target the specified drawable, computing an
  26. * appropriate transform for the vertex shader to convert
  27. * drawable-relative coordinates into pixmap-relative coordinates. If
  28. * requested, the offset from pixmap origin coordinates back to window
  29. * system coordinates will be returned in *p_off_x, *p_off_y so that
  30. * clipping computations can be adjusted as appropriate
  31. */
  32. void
  33. glamor_set_destination_drawable(DrawablePtr drawable,
  34. int box_x,
  35. int box_y,
  36. Bool do_drawable_translate,
  37. Bool center_offset,
  38. GLint matrix_uniform_location,
  39. int *p_off_x,
  40. int *p_off_y)
  41. {
  42. PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
  43. glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
  44. int off_x, off_y;
  45. BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
  46. int w = box->x2 - box->x1;
  47. int h = box->y2 - box->y1;
  48. float scale_x = 2.0f / (float) w;
  49. float scale_y = 2.0f / (float) h;
  50. float center_adjust = 0.0f;
  51. glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
  52. off_x -= box->x1;
  53. off_y -= box->y1;
  54. if (p_off_x) {
  55. *p_off_x = off_x;
  56. *p_off_y = off_y;
  57. }
  58. /* A tricky computation to find the right value for the two linear functions
  59. * that transform rendering coordinates to pixmap coordinates
  60. *
  61. * pixmap_x = render_x + drawable->x + off_x
  62. * pixmap_y = render_y + drawable->y + off_y
  63. *
  64. * gl_x = pixmap_x * 2 / width - 1
  65. * gl_y = pixmap_y * 2 / height - 1
  66. *
  67. * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1
  68. *
  69. * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1
  70. *
  71. * I'll think about yInverted later, when I have some way to test
  72. */
  73. if (do_drawable_translate) {
  74. off_x += drawable->x;
  75. off_y += drawable->y;
  76. }
  77. /*
  78. * To get GL_POINTS drawn in the right spot, we need to adjust the
  79. * coordinates by 1/2 a pixel.
  80. */
  81. if (center_offset)
  82. center_adjust = 0.5f;
  83. glUniform4f(matrix_uniform_location,
  84. scale_x, (off_x + center_adjust) * scale_x - 1.0f,
  85. scale_y, (off_y + center_adjust) * scale_y - 1.0f);
  86. glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
  87. 0, 0, w, h);
  88. }
  89. /*
  90. * Set up for solid rendering to the specified pixmap using alu, fg and planemask
  91. * from the specified GC. Load the target color into the specified uniform
  92. */
  93. void
  94. glamor_set_color(PixmapPtr pixmap,
  95. CARD32 pixel,
  96. GLint uniform)
  97. {
  98. float color[4];
  99. glamor_get_rgba_from_pixel(pixel,
  100. &color[0], &color[1], &color[2], &color[3],
  101. format_for_pixmap(pixmap));
  102. glUniform4fv(uniform, 1, color);
  103. }
  104. Bool
  105. glamor_set_solid(PixmapPtr pixmap,
  106. GCPtr gc,
  107. Bool use_alu,
  108. GLint uniform)
  109. {
  110. CARD32 pixel;
  111. int alu = use_alu ? gc->alu : GXcopy;
  112. if (!glamor_set_planemask(pixmap, gc->planemask))
  113. return FALSE;
  114. pixel = gc->fgPixel;
  115. if (!glamor_set_alu(pixmap->drawable.pScreen, alu)) {
  116. switch (gc->alu) {
  117. case GXclear:
  118. pixel = 0;
  119. break;
  120. case GXcopyInverted:
  121. pixel = ~pixel;
  122. break;
  123. case GXset:
  124. pixel = ~0 & gc->planemask;
  125. break;
  126. default:
  127. return FALSE;
  128. }
  129. }
  130. glamor_set_color(pixmap, gc->fgPixel, uniform);
  131. return TRUE;
  132. }
  133. Bool
  134. glamor_set_texture(PixmapPtr pixmap,
  135. PixmapPtr texture,
  136. int off_x,
  137. int off_y,
  138. GLint offset_uniform,
  139. GLint size_uniform)
  140. {
  141. glamor_pixmap_private *texture_priv;
  142. texture_priv = glamor_get_pixmap_private(texture);
  143. if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv))
  144. return FALSE;
  145. if (texture_priv->type == GLAMOR_TEXTURE_LARGE)
  146. return FALSE;
  147. glActiveTexture(GL_TEXTURE0);
  148. glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex);
  149. glUniform2f(offset_uniform, off_x, off_y);
  150. glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height);
  151. return TRUE;
  152. }
  153. Bool
  154. glamor_set_tiled(PixmapPtr pixmap,
  155. GCPtr gc,
  156. GLint offset_uniform,
  157. GLint size_uniform)
  158. {
  159. if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
  160. return FALSE;
  161. if (!glamor_set_planemask(pixmap, gc->planemask))
  162. return FALSE;
  163. return glamor_set_texture(pixmap,
  164. gc->tile.pixmap,
  165. -gc->patOrg.x,
  166. -gc->patOrg.y,
  167. offset_uniform,
  168. size_uniform);
  169. }
  170. Bool
  171. glamor_set_stippled(PixmapPtr pixmap,
  172. GCPtr gc,
  173. GLint fg_uniform,
  174. GLint offset_uniform,
  175. GLint size_uniform)
  176. {
  177. if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
  178. return FALSE;
  179. if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform))
  180. return FALSE;
  181. return TRUE;
  182. }