glamor_image.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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_transfer.h"
  24. #include "glamor_transform.h"
  25. /*
  26. * PutImage. Only does ZPixmap right now as other formats are quite a bit harder
  27. */
  28. static Bool
  29. glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
  30. int w, int h, int leftPad, int format, char *bits)
  31. {
  32. ScreenPtr screen = drawable->pScreen;
  33. glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
  34. PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
  35. glamor_pixmap_private *pixmap_priv;
  36. uint32_t byte_stride = PixmapBytePad(w, drawable->depth);
  37. RegionRec region;
  38. BoxRec box;
  39. int off_x, off_y;
  40. pixmap_priv = glamor_get_pixmap_private(pixmap);
  41. if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
  42. return FALSE;
  43. if (gc->alu != GXcopy)
  44. goto bail;
  45. if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
  46. goto bail;
  47. if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
  48. format = ZPixmap;
  49. if (format != ZPixmap)
  50. goto bail;
  51. x += drawable->x;
  52. y += drawable->y;
  53. box.x1 = x;
  54. box.y1 = y;
  55. box.x2 = box.x1 + w;
  56. box.y2 = box.y1 + h;
  57. RegionInit(&region, &box, 1);
  58. RegionIntersect(&region, &region, gc->pCompositeClip);
  59. glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
  60. if (off_x || off_y) {
  61. x += off_x;
  62. y += off_y;
  63. RegionTranslate(&region, off_x, off_y);
  64. }
  65. glamor_make_current(glamor_priv);
  66. glamor_upload_region(pixmap, &region, x, y, (uint8_t *) bits, byte_stride);
  67. RegionUninit(&region);
  68. return TRUE;
  69. bail:
  70. return FALSE;
  71. }
  72. static void
  73. glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
  74. int w, int h, int leftPad, int format, char *bits)
  75. {
  76. if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW))
  77. fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
  78. glamor_finish_access(drawable);
  79. }
  80. void
  81. glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
  82. int w, int h, int leftPad, int format, char *bits)
  83. {
  84. if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
  85. return;
  86. glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
  87. }
  88. Bool
  89. glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
  90. int w, int h, int leftPad, int format, char *bits)
  91. {
  92. if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
  93. return TRUE;
  94. if (glamor_ddx_fallback_check_pixmap(drawable) &&
  95. glamor_ddx_fallback_check_gc(gc))
  96. return FALSE;
  97. glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
  98. return TRUE;
  99. }
  100. static Bool
  101. glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
  102. unsigned int format, unsigned long plane_mask, char *d)
  103. {
  104. PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
  105. glamor_pixmap_private *pixmap_priv;
  106. uint32_t byte_stride = PixmapBytePad(w, drawable->depth);
  107. BoxRec box;
  108. int off_x, off_y;
  109. pixmap_priv = glamor_get_pixmap_private(pixmap);
  110. if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
  111. goto bail;
  112. if (format != ZPixmap || !glamor_pm_is_solid(drawable, plane_mask))
  113. goto bail;
  114. glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
  115. box.x1 = x;
  116. box.x2 = x + w;
  117. box.y1 = y;
  118. box.y2 = y + h;
  119. glamor_download_boxes(pixmap, &box, 1,
  120. drawable->x + off_x, drawable->y + off_y,
  121. -x, -y,
  122. (uint8_t *) d, byte_stride);
  123. return TRUE;
  124. bail:
  125. return FALSE;
  126. }
  127. static void
  128. glamor_get_image_bail(DrawablePtr drawable, int x, int y, int w, int h,
  129. unsigned int format, unsigned long plane_mask, char *d)
  130. {
  131. if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO))
  132. fbGetImage(drawable, x, y, w, h, format, plane_mask, d);
  133. glamor_finish_access(drawable);
  134. }
  135. void
  136. glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
  137. unsigned int format, unsigned long plane_mask, char *d)
  138. {
  139. if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d))
  140. return;
  141. glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
  142. }
  143. Bool
  144. glamor_get_image_nf(DrawablePtr drawable, int x, int y, int w, int h,
  145. unsigned int format, unsigned long plane_mask, char *d)
  146. {
  147. if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d))
  148. return TRUE;
  149. if (glamor_ddx_fallback_check_pixmap(drawable))
  150. return FALSE;
  151. glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
  152. return TRUE;
  153. }