Advertisement
Guest User

Untitled

a guest
Jun 25th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.10 KB | None | 0 0
  1. From 043c2e4599b5d800daff04116ff703f0724251a2 Mon Sep 17 00:00:00 2001
  2. From: Robert Bragg <robert@linux.intel.com>
  3. Date: Mon, 1 Nov 2010 18:33:17 +0000
  4. Subject: [PATCH] _multitexture_quad_single_primitive: avoid wrap overrides
  5.  
  6. This avoids using the wrap mode overrides mechanism to implement
  7. _cogl_multitexture_quad_single_primitive which requires memsetting a
  8. fairly large array. This updates it to use cogl_pipeline_foreach_layer()
  9. and we now derive an override_material to handle changes to the wrap
  10. modes instead of using the CoglPipelineWrapModeOverrides.
  11. ---
  12. clutter/cogl/cogl/cogl-primitives.c | 259 +++++++++++++++++++----------------
  13. 1 files changed, 143 insertions(+), 116 deletions(-)
  14.  
  15. diff --git a/clutter/cogl/cogl/cogl-primitives.c b/clutter/cogl/cogl/cogl-primitives.c
  16. index 466402a..782df9d 100644
  17. --- a/clutter/cogl/cogl/cogl-primitives.c
  18. +++ b/clutter/cogl/cogl/cogl-primitives.c
  19. @@ -331,6 +331,133 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle,
  20. &state);
  21. }
  22.  
  23. +typedef struct _ValidateTexCoordsState
  24. +{
  25. + int i;
  26. + int n_layers;
  27. + const float *user_tex_coords;
  28. + int user_tex_coords_len;
  29. + float *final_tex_coords;
  30. + CoglPipeline *override_pipeline;
  31. +} ValidateTexCoordsState;
  32. +
  33. +/*
  34. + * Validate the texture coordinates for this rectangle.
  35. + */
  36. +static gboolean
  37. +validate_tex_coords_cb (CoglPipeline *pipeline,
  38. + int layer_index,
  39. + void *user_data)
  40. +{
  41. + ValidateTexCoordsState *state = user_data;
  42. + CoglHandle texture;
  43. + const float *in_tex_coords;
  44. + float *out_tex_coords;
  45. + float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0};
  46. + CoglTransformResult transform_result;
  47. +
  48. + state->i++;
  49. +
  50. + texture = _cogl_pipeline_get_layer_texture (pipeline, layer_index);
  51. +
  52. + /* NB: NULL textures are handled by _cogl_pipeline_flush_gl_state */
  53. + if (!texture)
  54. + return TRUE;
  55. +
  56. + /* FIXME: we should be able to avoid this copying when no
  57. + * transform is required by the texture backend and the user
  58. + * has supplied enough coordinates for all the layers.
  59. + */
  60. +
  61. + /* If the user didn't supply texture coordinates for this layer
  62. + then use the default coords */
  63. + if (state->i >= state->user_tex_coords_len / 4)
  64. + in_tex_coords = default_tex_coords;
  65. + else
  66. + in_tex_coords = &state->user_tex_coords[state->i * 4];
  67. +
  68. + out_tex_coords = &state->final_tex_coords[state->i * 4];
  69. +
  70. + memcpy (out_tex_coords, in_tex_coords, sizeof (float) * 4);
  71. +
  72. + /* Convert the texture coordinates to GL.
  73. + */
  74. + transform_result =
  75. + _cogl_texture_transform_quad_coords_to_gl (texture,
  76. + out_tex_coords);
  77. + /* If the texture has waste or we are using GL_TEXTURE_RECT we
  78. + * can't handle texture repeating so we can't use the layer if
  79. + * repeating is required.
  80. + *
  81. + * NB: We already know that no texture matrix is being used if the
  82. + * texture doesn't support hardware repeat.
  83. + */
  84. + if (transform_result == COGL_TRANSFORM_SOFTWARE_REPEAT)
  85. + {
  86. + if (state->i == 0)
  87. + {
  88. + if (state->n_layers > 1)
  89. + {
  90. + static gboolean warning_seen = FALSE;
  91. + if (!warning_seen)
  92. + g_warning ("Skipping layers 1..n of your material since "
  93. + "the first layer doesn't support hardware "
  94. + "repeat (e.g. because of waste or use of "
  95. + "GL_TEXTURE_RECTANGLE_ARB) and you supplied "
  96. + "texture coordinates outside the range [0,1]."
  97. + "Falling back to software repeat assuming "
  98. + "layer 0 is the most important one keep");
  99. + warning_seen = TRUE;
  100. + }
  101. + return FALSE;
  102. + }
  103. + else
  104. + {
  105. + static gboolean warning_seen = FALSE;
  106. + if (!warning_seen)
  107. + g_warning ("Skipping layer %d of your material "
  108. + "since you have supplied texture coords "
  109. + "outside the range [0,1] but the texture "
  110. + "doesn't support hardware repeat (e.g. "
  111. + "because of waste or use of "
  112. + "GL_TEXTURE_RECTANGLE_ARB). This isn't "
  113. + "supported with multi-texturing.", state->i);
  114. + warning_seen = TRUE;
  115. +
  116. + cogl_pipeline_set_layer_texture (texture, layer_index, NULL);
  117. + }
  118. + }
  119. +
  120. + /* By default WRAP_MODE_AUTOMATIC becomes to CLAMP_TO_EDGE. If
  121. + the texture coordinates need repeating then we'll override
  122. + this to GL_REPEAT. Otherwise we'll leave it at CLAMP_TO_EDGE
  123. + so that it won't blend in pixels from the opposite side when
  124. + the full texture is drawn with GL_LINEAR filter mode */
  125. + if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT)
  126. + {
  127. + if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) ==
  128. + COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
  129. + {
  130. + if (!state->override_pipeline)
  131. + state->override_pipeline = cogl_pipeline_copy (pipeline);
  132. + cogl_pipeline_set_layer_wrap_mode_s (state->override_pipeline,
  133. + layer_index,
  134. + COGL_PIPELINE_WRAP_MODE_REPEAT);
  135. + }
  136. + if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) ==
  137. + COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
  138. + {
  139. + if (!state->override_pipeline)
  140. + state->override_pipeline = cogl_pipeline_copy (pipeline);
  141. + cogl_pipeline_set_layer_wrap_mode_t (state->override_pipeline,
  142. + layer_index,
  143. + COGL_PIPELINE_WRAP_MODE_REPEAT);
  144. + }
  145. + }
  146. +
  147. + return TRUE;
  148. +}
  149. +
  150. /* This path supports multitexturing but only when each of the layers is
  151. * handled with a single GL texture. Also if repeating is necessary then
  152. * _cogl_texture_can_hardware_repeat() must return TRUE.
  153. @@ -354,131 +481,31 @@ _cogl_multitexture_quad_single_primitive (const float *position,
  154. const float *user_tex_coords,
  155. int user_tex_coords_len)
  156. {
  157. - int n_layers = cogl_pipeline_get_n_layers (pipeline);
  158. - float *final_tex_coords = alloca (sizeof (float) * 4 * n_layers);
  159. - const GList *layers;
  160. - GList *tmp;
  161. - int i;
  162. - CoglPipelineWrapModeOverrides wrap_mode_overrides;
  163. - /* This will be set to point to wrap_mode_overrides when an override
  164. - is needed */
  165. - CoglPipelineWrapModeOverrides *wrap_mode_overrides_p = NULL;
  166. + int n_layers = cogl_pipeline_get_n_layers (pipeline);
  167. + ValidateTexCoordsState state;
  168. + float *final_tex_coords = alloca (sizeof (float) * 4 * n_layers);
  169.  
  170. _COGL_GET_CONTEXT (ctx, FALSE);
  171.  
  172. - memset (&wrap_mode_overrides, 0, sizeof (wrap_mode_overrides));
  173. -
  174. - /*
  175. - * Validate the texture coordinates for this rectangle.
  176. - */
  177. - layers = _cogl_pipeline_get_layers (pipeline);
  178. - for (tmp = (GList *)layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
  179. - {
  180. - CoglHandle layer = (CoglHandle)tmp->data;
  181. - CoglHandle tex_handle;
  182. - const float *in_tex_coords;
  183. - float *out_tex_coords;
  184. - float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0};
  185. - CoglTransformResult transform_result;
  186. -
  187. - tex_handle = _cogl_pipeline_layer_get_texture (layer);
  188. -
  189. - /* COGL_INVALID_HANDLE textures are handled by
  190. - * _cogl_pipeline_flush_gl_state */
  191. - if (tex_handle == COGL_INVALID_HANDLE)
  192. - continue;
  193. -
  194. - /* If the user didn't supply texture coordinates for this layer
  195. - then use the default coords */
  196. - if (i >= user_tex_coords_len / 4)
  197. - in_tex_coords = default_tex_coords;
  198. - else
  199. - in_tex_coords = &user_tex_coords[i * 4];
  200. -
  201. - out_tex_coords = &final_tex_coords[i * 4];
  202. -
  203. - memcpy (out_tex_coords, in_tex_coords, sizeof (GLfloat) * 4);
  204. -
  205. - /* Convert the texture coordinates to GL.
  206. - */
  207. - transform_result =
  208. - _cogl_texture_transform_quad_coords_to_gl (tex_handle,
  209. - out_tex_coords);
  210. - /* If the texture has waste or we are using GL_TEXTURE_RECT we
  211. - * can't handle texture repeating so we can't use the layer if
  212. - * repeating is required.
  213. - *
  214. - * NB: We already know that no texture matrix is being used if the
  215. - * texture doesn't support hardware repeat.
  216. - */
  217. - if (transform_result == COGL_TRANSFORM_SOFTWARE_REPEAT)
  218. - {
  219. - if (i == 0)
  220. - {
  221. - if (n_layers > 1)
  222. - {
  223. - static gboolean warning_seen = FALSE;
  224. - if (!warning_seen)
  225. - g_warning ("Skipping layers 1..n of your material since "
  226. - "the first layer doesn't support hardware "
  227. - "repeat (e.g. because of waste or use of "
  228. - "GL_TEXTURE_RECTANGLE_ARB) and you supplied "
  229. - "texture coordinates outside the range [0,1]."
  230. - "Falling back to software repeat assuming "
  231. - "layer 0 is the most important one keep");
  232. - warning_seen = TRUE;
  233. - }
  234. - return FALSE;
  235. - }
  236. - else
  237. - {
  238. - static gboolean warning_seen = FALSE;
  239. - if (!warning_seen)
  240. - g_warning ("Skipping layer %d of your material "
  241. - "since you have supplied texture coords "
  242. - "outside the range [0,1] but the texture "
  243. - "doesn't support hardware repeat (e.g. "
  244. - "because of waste or use of "
  245. - "GL_TEXTURE_RECTANGLE_ARB). This isn't "
  246. - "supported with multi-texturing.", i);
  247. - warning_seen = TRUE;
  248. -
  249. - /* NB: marking for fallback will replace the layer with
  250. - * a default transparent texture */
  251. - fallback_layers |= (1 << i);
  252. - }
  253. - }
  254. + state.i = -1;
  255. + state.n_layers = n_layers;
  256. + state.user_tex_coords = user_tex_coords;
  257. + state.user_tex_coords_len = user_tex_coords_len;
  258. + state.final_tex_coords = final_tex_coords;
  259. + state.override_pipeline = NULL;
  260.  
  261. - /* By default WRAP_MODE_AUTOMATIC becomes to CLAMP_TO_EDGE. If
  262. - the texture coordinates need repeating then we'll override
  263. - this to GL_REPEAT. Otherwise we'll leave it at CLAMP_TO_EDGE
  264. - so that it won't blend in pixels from the opposite side when
  265. - the full texture is drawn with GL_LINEAR filter mode */
  266. - if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT)
  267. - {
  268. - if (_cogl_pipeline_layer_get_wrap_mode_s (layer) ==
  269. - COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
  270. - {
  271. - wrap_mode_overrides.values[i].s
  272. - = COGL_PIPELINE_WRAP_MODE_OVERRIDE_REPEAT;
  273. - wrap_mode_overrides_p = &wrap_mode_overrides;
  274. - }
  275. - if (_cogl_pipeline_layer_get_wrap_mode_t (layer) ==
  276. - COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
  277. - {
  278. - wrap_mode_overrides.values[i].t
  279. - = COGL_PIPELINE_WRAP_MODE_OVERRIDE_REPEAT;
  280. - wrap_mode_overrides_p = &wrap_mode_overrides;
  281. - }
  282. - }
  283. - }
  284. + cogl_pipeline_foreach_layer (pipeline,
  285. + validate_tex_coords_cb,
  286. + &state);
  287. + if (state.override_pipeline)
  288. + pipeline = state.override_pipeline;
  289.  
  290. _cogl_journal_log_quad (position,
  291. pipeline,
  292. n_layers,
  293. - fallback_layers,
  294. + 0, /* we don't need fallback layers */
  295. 0, /* don't replace the layer0 texture */
  296. - wrap_mode_overrides_p,
  297. + NULL, /* we never use wrap mode overrides */
  298. final_tex_coords,
  299. n_layers * 4);
  300.  
  301. --
  302. 1.7.0.4
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement