qemu-pixman.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  3. * See the COPYING file in the top-level directory.
  4. */
  5. #include "qemu-common.h"
  6. #include "ui/console.h"
  7. PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format)
  8. {
  9. PixelFormat pf;
  10. uint8_t bpp;
  11. bpp = pf.bits_per_pixel = PIXMAN_FORMAT_BPP(format);
  12. pf.bytes_per_pixel = PIXMAN_FORMAT_BPP(format) / 8;
  13. pf.depth = PIXMAN_FORMAT_DEPTH(format);
  14. pf.abits = PIXMAN_FORMAT_A(format);
  15. pf.rbits = PIXMAN_FORMAT_R(format);
  16. pf.gbits = PIXMAN_FORMAT_G(format);
  17. pf.bbits = PIXMAN_FORMAT_B(format);
  18. switch (PIXMAN_FORMAT_TYPE(format)) {
  19. case PIXMAN_TYPE_ARGB:
  20. pf.ashift = pf.bbits + pf.gbits + pf.rbits;
  21. pf.rshift = pf.bbits + pf.gbits;
  22. pf.gshift = pf.bbits;
  23. pf.bshift = 0;
  24. break;
  25. case PIXMAN_TYPE_ABGR:
  26. pf.ashift = pf.rbits + pf.gbits + pf.bbits;
  27. pf.bshift = pf.rbits + pf.gbits;
  28. pf.gshift = pf.rbits;
  29. pf.rshift = 0;
  30. break;
  31. case PIXMAN_TYPE_BGRA:
  32. pf.bshift = bpp - pf.bbits;
  33. pf.gshift = bpp - (pf.bbits + pf.gbits);
  34. pf.rshift = bpp - (pf.bbits + pf.gbits + pf.rbits);
  35. pf.ashift = 0;
  36. break;
  37. case PIXMAN_TYPE_RGBA:
  38. pf.rshift = bpp - pf.rbits;
  39. pf.gshift = bpp - (pf.rbits + pf.gbits);
  40. pf.bshift = bpp - (pf.rbits + pf.gbits + pf.bbits);
  41. pf.ashift = 0;
  42. break;
  43. default:
  44. g_assert_not_reached();
  45. break;
  46. }
  47. pf.amax = (1 << pf.abits) - 1;
  48. pf.rmax = (1 << pf.rbits) - 1;
  49. pf.gmax = (1 << pf.gbits) - 1;
  50. pf.bmax = (1 << pf.bbits) - 1;
  51. pf.amask = pf.amax << pf.ashift;
  52. pf.rmask = pf.rmax << pf.rshift;
  53. pf.gmask = pf.gmax << pf.gshift;
  54. pf.bmask = pf.bmax << pf.bshift;
  55. return pf;
  56. }
  57. pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)
  58. {
  59. if (native_endian) {
  60. switch (bpp) {
  61. case 15:
  62. return PIXMAN_x1r5g5b5;
  63. case 16:
  64. return PIXMAN_r5g6b5;
  65. case 24:
  66. return PIXMAN_r8g8b8;
  67. case 32:
  68. return PIXMAN_x8r8g8b8;
  69. }
  70. } else {
  71. switch (bpp) {
  72. case 24:
  73. return PIXMAN_b8g8r8;
  74. case 32:
  75. return PIXMAN_b8g8r8x8;
  76. break;
  77. }
  78. }
  79. g_assert_not_reached();
  80. }
  81. int qemu_pixman_get_type(int rshift, int gshift, int bshift)
  82. {
  83. int type = PIXMAN_TYPE_OTHER;
  84. if (rshift > gshift && gshift > bshift) {
  85. if (bshift == 0) {
  86. type = PIXMAN_TYPE_ARGB;
  87. } else {
  88. #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 21, 8)
  89. type = PIXMAN_TYPE_RGBA;
  90. #endif
  91. }
  92. } else if (rshift < gshift && gshift < bshift) {
  93. if (rshift == 0) {
  94. type = PIXMAN_TYPE_ABGR;
  95. } else {
  96. #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 16, 0)
  97. type = PIXMAN_TYPE_BGRA;
  98. #endif
  99. }
  100. }
  101. return type;
  102. }
  103. pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf)
  104. {
  105. pixman_format_code_t format;
  106. int type;
  107. type = qemu_pixman_get_type(pf->rshift, pf->gshift, pf->bshift);
  108. format = PIXMAN_FORMAT(pf->bits_per_pixel, type,
  109. pf->abits, pf->rbits, pf->gbits, pf->bbits);
  110. if (!pixman_format_supported_source(format)) {
  111. return 0;
  112. }
  113. return format;
  114. }
  115. pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
  116. int width)
  117. {
  118. pixman_image_t *image = pixman_image_create_bits(format, width, 1, NULL, 0);
  119. assert(image != NULL);
  120. return image;
  121. }
  122. /* fill linebuf from framebuffer */
  123. void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
  124. int width, int x, int y)
  125. {
  126. pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf,
  127. x, y, 0, 0, 0, 0, width, 1);
  128. }
  129. /* copy linebuf to framebuffer */
  130. void qemu_pixman_linebuf_copy(pixman_image_t *fb, int width, int x, int y,
  131. pixman_image_t *linebuf)
  132. {
  133. pixman_image_composite(PIXMAN_OP_SRC, linebuf, NULL, fb,
  134. 0, 0, 0, 0, x, y, width, 1);
  135. }
  136. pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
  137. pixman_image_t *image)
  138. {
  139. pixman_image_t *mirror;
  140. mirror = pixman_image_create_bits(format,
  141. pixman_image_get_width(image),
  142. pixman_image_get_height(image),
  143. NULL,
  144. pixman_image_get_stride(image));
  145. return mirror;
  146. }
  147. void qemu_pixman_image_unref(pixman_image_t *image)
  148. {
  149. if (image == NULL) {
  150. return;
  151. }
  152. pixman_image_unref(image);
  153. }
  154. pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color)
  155. {
  156. pixman_color_t c;
  157. c.red = ((color & pf->rmask) >> pf->rshift) << (16 - pf->rbits);
  158. c.green = ((color & pf->gmask) >> pf->gshift) << (16 - pf->gbits);
  159. c.blue = ((color & pf->bmask) >> pf->bshift) << (16 - pf->bbits);
  160. c.alpha = ((color & pf->amask) >> pf->ashift) << (16 - pf->abits);
  161. return c;
  162. }
  163. pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font,
  164. unsigned int ch)
  165. {
  166. pixman_image_t *glyph;
  167. uint8_t *data;
  168. bool bit;
  169. int x, y;
  170. glyph = pixman_image_create_bits(PIXMAN_a8, 8, height,
  171. NULL, 0);
  172. data = (uint8_t *)pixman_image_get_data(glyph);
  173. font += height * ch;
  174. for (y = 0; y < height; y++, font++) {
  175. for (x = 0; x < 8; x++, data++) {
  176. bit = (*font) & (1 << (7-x));
  177. *data = bit ? 0xff : 0x00;
  178. }
  179. }
  180. return glyph;
  181. }
  182. void qemu_pixman_glyph_render(pixman_image_t *glyph,
  183. pixman_image_t *surface,
  184. pixman_color_t *fgcol,
  185. pixman_color_t *bgcol,
  186. int x, int y, int cw, int ch)
  187. {
  188. pixman_image_t *ifg = pixman_image_create_solid_fill(fgcol);
  189. pixman_image_t *ibg = pixman_image_create_solid_fill(bgcol);
  190. pixman_image_composite(PIXMAN_OP_SRC, ibg, NULL, surface,
  191. 0, 0, 0, 0,
  192. cw * x, ch * y,
  193. cw, ch);
  194. pixman_image_composite(PIXMAN_OP_OVER, ifg, glyph, surface,
  195. 0, 0, 0, 0,
  196. cw * x, ch * y,
  197. cw, ch);
  198. pixman_image_unref(ifg);
  199. pixman_image_unref(ibg);
  200. }