You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

273 lines
9.2 KiB

  1. /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
  2. /*
  3. * Utilities for use with Cogl
  4. *
  5. * Copyright 2010 Red Hat, Inc.
  6. * Copyright 2010 Intel Corporation
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA
  21. * 02110-1335, USA.
  22. */
  23. #if HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26. #include "cogl-utils.h"
  27. #include <gdk/gdk.h>
  28. /**
  29. * meta_create_color_texture_4ub:
  30. * @red:
  31. * @green:
  32. * @blue:
  33. * @alpha:
  34. * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE;
  35. * %COGL_TEXTURE_NO_SLICING is useful if the texture will be
  36. * repeated to create a constant color fill, since hardware
  37. * repeat can't be used for a sliced texture.
  38. *
  39. * Creates a texture that is a single pixel with the specified
  40. * unpremultiplied color components.
  41. *
  42. * Return value: (transfer full): a newly created Cogl texture
  43. */
  44. LOCAL_SYMBOL CoglHandle
  45. meta_create_color_texture_4ub (guint8 red,
  46. guint8 green,
  47. guint8 blue,
  48. guint8 alpha,
  49. CoglTextureFlags flags)
  50. {
  51. CoglColor color;
  52. guint8 pixel[4];
  53. cogl_color_set_from_4ub (&color, red, green, blue, alpha);
  54. cogl_color_premultiply (&color);
  55. pixel[0] = cogl_color_get_red_byte (&color);
  56. pixel[1] = cogl_color_get_green_byte (&color);
  57. pixel[2] = cogl_color_get_blue_byte (&color);
  58. pixel[3] = cogl_color_get_alpha_byte (&color);
  59. return cogl_texture_new_from_data (1, 1,
  60. flags,
  61. COGL_PIXEL_FORMAT_RGBA_8888_PRE,
  62. COGL_PIXEL_FORMAT_ANY,
  63. 4, pixel);
  64. }
  65. /* Based on gnome-shell/src/st/st-private.c:_st_create_texture_material.c */
  66. /**
  67. * meta_create_texture_material:
  68. * @src_texture: (allow-none): texture to use initially for the layer
  69. *
  70. * Creates a material with a single layer. Using a common template
  71. * allows sharing a shader for different uses in Muffin. To share the same
  72. * shader with all other materials that are just texture plus opacity
  73. * would require Cogl fixes.
  74. * (See http://bugzilla.clutter-project.org/show_bug.cgi?id=2425)
  75. *
  76. * Return value: (transfer full): a newly created Cogl material
  77. */
  78. LOCAL_SYMBOL CoglHandle
  79. meta_create_texture_material (CoglHandle src_texture)
  80. {
  81. static CoglHandle texture_material_template = COGL_INVALID_HANDLE;
  82. CoglHandle material;
  83. /* We use a material that has a dummy texture as a base for all
  84. texture materials. The idea is that only the Cogl texture object
  85. would be different in the children so it is likely that Cogl will
  86. be able to share GL programs between all the textures. */
  87. if (G_UNLIKELY (texture_material_template == COGL_INVALID_HANDLE))
  88. {
  89. CoglHandle dummy_texture;
  90. dummy_texture = meta_create_color_texture_4ub (0xff, 0xff, 0xff, 0xff,
  91. COGL_TEXTURE_NONE);
  92. texture_material_template = cogl_material_new ();
  93. cogl_material_set_layer (texture_material_template, 0, dummy_texture);
  94. cogl_handle_unref (dummy_texture);
  95. }
  96. material = cogl_material_copy (texture_material_template);
  97. if (src_texture != COGL_INVALID_HANDLE)
  98. cogl_material_set_layer (material, 0, src_texture);
  99. return material;
  100. }
  101. /********************************************************************************************/
  102. /********************************* CoglTexture2d wrapper ************************************/
  103. static CoglContext *cogl_context = NULL;
  104. static gboolean supports_npot = FALSE;
  105. static gint screen_width = 0;
  106. static gint screen_height = 0;
  107. inline static gboolean
  108. hardware_supports_npot_sizes (void)
  109. {
  110. if (cogl_context != NULL)
  111. return supports_npot;
  112. ClutterBackend *backend = clutter_get_default_backend ();
  113. cogl_context = clutter_backend_get_cogl_context (backend);
  114. supports_npot = cogl_has_feature (cogl_context, COGL_FEATURE_ID_TEXTURE_NPOT);
  115. return supports_npot;
  116. }
  117. inline static void
  118. clamp_sizes (gint *width,
  119. gint *height)
  120. {
  121. if (screen_width == 0)
  122. {
  123. GdkScreen *screen = gdk_screen_get_default ();
  124. screen_width = gdk_screen_get_width (screen);
  125. screen_height = gdk_screen_get_height (screen);
  126. }
  127. *width = MIN (*width, screen_width * 2);
  128. *height = MIN (*height, screen_height * 2);
  129. }
  130. /**
  131. * meta_cogl_texture_new_from_data_wrapper: (skip)
  132. *
  133. * Decides whether to use the newer (apparently safer)
  134. * cogl_texture_2d_new_from_data or the older cogl_texture_new_from_data
  135. * depending on if the GPU supports it.
  136. */
  137. CoglTexture *
  138. meta_cogl_texture_new_from_data_wrapper (int width,
  139. int height,
  140. CoglTextureFlags flags,
  141. CoglPixelFormat format,
  142. CoglPixelFormat internal_format,
  143. int rowstride,
  144. const uint8_t *data)
  145. {
  146. CoglTexture *texture = NULL;
  147. clamp_sizes (&width, &height);
  148. if (hardware_supports_npot_sizes ())
  149. {
  150. texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (cogl_context, width, height,
  151. format,
  152. #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0)
  153. COGL_PIXEL_FORMAT_ANY,
  154. #endif
  155. rowstride,
  156. data,
  157. NULL));
  158. }
  159. else
  160. {
  161. texture = cogl_texture_new_from_data (width,
  162. height,
  163. flags,
  164. format,
  165. internal_format,
  166. rowstride,
  167. data);
  168. }
  169. return texture;
  170. }
  171. /**
  172. * meta_cogl_texture_new_from_file_wrapper: (skip)
  173. *
  174. * Decides whether to use the newer (apparently safer)
  175. * cogl_texture_2d_new_from_file or the older cogl_texture_new_from_file
  176. * depending on if the GPU supports it.
  177. */
  178. CoglTexture *
  179. meta_cogl_texture_new_from_file_wrapper (const char *filename,
  180. CoglTextureFlags flags,
  181. CoglPixelFormat internal_format)
  182. {
  183. CoglTexture *texture = NULL;
  184. if (hardware_supports_npot_sizes ())
  185. {
  186. texture = COGL_TEXTURE (cogl_texture_2d_new_from_file (cogl_context,
  187. filename,
  188. #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0)
  189. COGL_PIXEL_FORMAT_ANY,
  190. #endif
  191. NULL));
  192. }
  193. else
  194. {
  195. texture = cogl_texture_new_from_file (filename,
  196. flags,
  197. internal_format,
  198. NULL);
  199. }
  200. return texture;
  201. }
  202. /**
  203. * meta_cogl_texture_new_with_size_wrapper: (skip)
  204. *
  205. * Decides whether to use the newer (apparently safer)
  206. * cogl_texture_2d_new_with_size or the older cogl_texture_new_with_size
  207. * depending on if the GPU supports it.
  208. */
  209. CoglTexture *
  210. meta_cogl_texture_new_with_size_wrapper (int width,
  211. int height,
  212. CoglTextureFlags flags,
  213. CoglPixelFormat internal_format)
  214. {
  215. CoglTexture *texture = NULL;
  216. clamp_sizes (&width, &height);
  217. if (hardware_supports_npot_sizes ())
  218. {
  219. texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context,
  220. width,
  221. height
  222. #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0)
  223. ,CLUTTER_CAIRO_FORMAT_ARGB32
  224. #endif
  225. ));
  226. }
  227. else
  228. {
  229. texture = cogl_texture_new_with_size (width, height,
  230. flags,
  231. internal_format);
  232. }
  233. return texture;
  234. }