1 /* 2 * GPAC - Multimedia Framework C SDK 3 * 4 * Authors: Jean Le Feuvre 5 * Copyright (c) Telecom ParisTech 2000-2012 6 * All rights reserved 7 * 8 * This file is part of GPAC / Scene Compositor sub-project 9 * 10 * GPAC is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * GPAC is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; see the file COPYING. If not, write to 22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 */ 25 26 27 #ifndef DRAWABLE_H 28 #define DRAWABLE_H 29 30 #include <gpac/internal/compositor_dev.h> 31 32 33 typedef struct _drawable Drawable; 34 typedef struct _drawable_context DrawableContext; 35 36 typedef struct _bound_info 37 { 38 /*cliped bounds in pixels - needed to track static objects with animated cliping*/ 39 GF_IRect clip; 40 /*uncliped bounds - needed to track moving objects fully contained in visual and for image bliting*/ 41 GF_Rect unclip; 42 /* extra_check: 43 for MPEG-4: pointer to appearance node (due to DEF/USE) in order to detect same bounds and appearance node change 44 for SVG: currently not used, should be needed for <use> 45 */ 46 void *extra_check; 47 48 /**/ 49 struct _bound_info *next; 50 } BoundInfo; 51 52 typedef struct _dirty_rect_info 53 { 54 /*the visual manager for which we're storing the bounds of this node*/ 55 GF_VisualManager *visual; 56 /*the current location of the node on the visual manager collected during traverse step*/ 57 struct _bound_info *current_bounds; 58 /*the location of the node on the visual manager at the previous frame*/ 59 struct _bound_info *previous_bounds; 60 61 /**/ 62 struct _dirty_rect_info *next; 63 } DRInfo; 64 65 enum { 66 /*user defined flags*/ 67 68 /*if flag set, the node callback function will be used to draw the node. Otherwise, 69 high-level draw operations on the drawable & drawable context will be used*/ 70 DRAWABLE_USE_TRAVERSE_DRAW = 1, 71 72 /*bounds tracker flags, INTERNAL TO RENDERER */ 73 74 /*flag set by drawable_mark_modified during a TRAVERSE_SORT pass when geometry's node has been modified. This forces clearing of the node 75 and skips bounds checking. 76 Flag is cleared by the compositor*/ 77 DRAWABLE_HAS_CHANGED = 1<<1, 78 /*same flag as above except set when picking/getting bounds out of the main scene traversal routine (user event, script)*/ 79 DRAWABLE_HAS_CHANGED_IN_LAST_TRAVERSE = 1<<2, 80 81 /*flag set if node has been drawn for the current visual manager*/ 82 DRAWABLE_DRAWN_ON_VISUAL = 1<<3, 83 /*set if node is registered in previous node drawn list of the current visual manager 84 the flag is only set during a visual_draw_frame pass*/ 85 DRAWABLE_REGISTERED_WITH_VISUAL = 1<<4, 86 87 /*drawable is an overlay surface*/ 88 DRAWABLE_IS_OVERLAY = 1<<5, 89 90 /*drawable has a cache texture*/ 91 DRAWABLE_IS_CACHED = 1<<6, 92 93 /*drawable has been initialized for hybrid GL mode - used to perform the initial clear of the overlay graphics*/ 94 DRAWABLE_HYBGL_INIT = 1<<7, 95 }; 96 97 struct _drawable 98 { 99 #ifndef GPAC_DISABLE_3D 100 /*3D object for drawable if needed - NOT ALLOCATED BY DEFAULT 101 DO NOT CHANGE THE LOCATION IN THE STRUCTURE, IT SHALL BE FIRST TO BE TYPECASTED TO 102 A Drawable3D when drawing OpenGL*/ 103 GF_Mesh *mesh; 104 #endif 105 /*set of drawable flags*/ 106 u32 flags; 107 108 /*node owning the drawable*/ 109 GF_Node *node; 110 111 /*bounds collector*/ 112 struct _dirty_rect_info *dri; 113 114 /*graphic path - !! CREATED BY DEFAULT !! */ 115 GF_Path *path; 116 /*cached outlines*/ 117 struct _strikeinfo2d *outline; 118 }; 119 120 /*construction destruction*/ 121 Drawable *drawable_new(); 122 void drawable_del(Drawable *dr); 123 void drawable_del_ex(Drawable *dr, GF_Compositor *compositor); 124 125 /*cleans up the drawable attached to the node*/ 126 void drawable_node_del(GF_Node *node); 127 128 129 /* 130 decide whether drawing is needed or not based on visual settings and parent node - must be called 131 at the end of each TRAVERSE_SORT of drawable nodes 132 if orig_bounds is NULL, function uses the bounds of the drawable's path 133 */ 134 void drawable_finalize_sort(DrawableContext *ctx, GF_TraverseState *tr_state, GF_Rect *orig_bounds); 135 /*same as drawable_finalize_sort but skips focus check*/ 136 void drawable_finalize_sort_ex(DrawableContext *ctx, GF_TraverseState *tr_state, GF_Rect *orig_bounds, Bool skip_focus); 137 138 /*base constructor for geometry objects that work without overloading the drawable stuff*/ 139 Drawable *drawable_stack_new(GF_Compositor *compositor, GF_Node *node); 140 /*reset all paths (main path and any outline) of the stack*/ 141 void drawable_reset_path(Drawable *st); 142 /*reset all paths outlines (only) of the stack*/ 143 void drawable_reset_path_outline(Drawable *st); 144 145 /*mark the drawable as modified - this shall be caleed whenever the node geometry is rebuilt 146 in order to signal this change to the bounds tracker algorithm*/ 147 void drawable_mark_modified(Drawable *st, GF_TraverseState *tr_state); 148 149 /*checks if the current object is the focused one, and insert the focus drawable at the current pos*/ 150 void drawable_check_focus_highlight(GF_Node *node, GF_TraverseState *tr_state, GF_Rect *orig_bounds); 151 152 /*reset the highlight state (bounds) if associated with the current node. This is automatically called 153 whenever reseting a drawable but must be called when a grouping node is modified*/ 154 void drawable_reset_group_highlight(GF_TraverseState *tr_state, GF_Node *n); 155 156 /*move current bounds to previous bounds for given target visual manager - called BEFORE updating the visual manager 157 returns 1 if nod was draw last frame on this visual manager, 0 otherwise*/ 158 Bool drawable_flush_bounds(Drawable *node, GF_VisualManager *on_visual, u32 mode2d); 159 160 /* 161 return 1 if same bound is found in previous list (and remove it from the list) 162 return 0 otherwise 163 */ 164 Bool drawable_has_same_bounds(DrawableContext *ctx, GF_VisualManager *visual); 165 166 /* 167 return any previous bounds related to the same visual manager in @rc if any 168 if nothing found return 0 169 */ 170 Bool drawable_get_previous_bound(Drawable *node, GF_IRect *rc, GF_VisualManager *visual); 171 172 /*reset bounds array (current and previous) on the given visual manager*/ 173 void drawable_reset_bounds(Drawable *dr, GF_VisualManager *visual); 174 /*setup clip/uncli pointers for the drawable context*/ 175 void drawable_check_bounds(DrawableContext *ctx, GF_VisualManager *visual); 176 177 /*the focus drawable routine of the focus object*/ 178 void drawable_traverse_focus(GF_Node *node, void *rs, Bool is_destroy); 179 180 struct _draw_aspect_2d 181 { 182 /*including alpha*/ 183 GF_Color fill_color, line_color; 184 Fixed line_scale; 185 GF_PenSettings pen_props; 186 /*texture fill handler*/ 187 struct _gf_sc_texture_handler *fill_texture; 188 /*texture stroke handler*/ 189 struct _gf_sc_texture_handler *line_texture; 190 }; 191 192 /*fills the 2D drawing properties according to the traversing state - MPEG4/X3D only*/ 193 u32 drawable_get_aspect_2d_mpeg4(GF_Node *node, DrawAspect2D *asp, GF_TraverseState *tr_state); 194 /*fills the 2D drawing properties according to the traversing state - SVG only*/ 195 Bool drawable_get_aspect_2d_svg(GF_Node *node, DrawAspect2D *asp, GF_TraverseState *tr_state); 196 197 198 enum 199 { 200 /*set whenever appearance changed*/ 201 CTX_APP_DIRTY = 1, 202 /*set whenever texture data changed*/ 203 CTX_TEXTURE_DIRTY = 1<<1, 204 205 /*set when context is an MPEG-4/VRML node*/ 206 CTX_HAS_APPEARANCE = 1<<2, 207 /*set if node completely fits its bounds (flat rect and bitmap) then non transparent*/ 208 CTX_IS_TRANSPARENT = 1<<3, 209 /*set if node is text data*/ 210 CTX_IS_TEXT = 1<<4, 211 /*set if node is background*/ 212 CTX_IS_BACKGROUND = 1<<5, 213 /*turn antialiasing off when drawing*/ 214 CTX_NO_ANTIALIAS = 1<<6, 215 /*indicates path has been textured, in which case FILL is skiped*/ 216 CTX_PATH_FILLED = 1<<7, 217 /*indicates path outline has been textured, in which case STRIKE is skiped*/ 218 CTX_PATH_STROKE = 1<<8, 219 /*indicates SVG path outline geometry has been modified*/ 220 CTX_SVG_OUTLINE_GEOMETRY_DIRTY = 1<<9, 221 /*indicates the context is in a flip coord state (used for image and text flip)*/ 222 CTX_FLIPED_COORDS = 1<<10, 223 //flag set in opengl auto mode to indicate that the corresponding area should not be cleared but still redrawn (this means an opaque texture is used) 224 CTX_HYBOGL_NO_CLEAR = 1<<11, 225 //flag set in opengl auto mode to indicate that the corresponding area should not be cleared but still redrawn (this means an opaque texture is used) 226 CTX_BACKROUND_NOT_LAYER = 1<<12, 227 CTX_BACKROUND_NO_CLEAR= 1<<13, 228 }; 229 230 #define CTX_3DTYPE_MASK 0x7800 231 232 #define CTX_REDRAW_MASK 0x00000003 233 234 struct _drawable_context 235 { 236 /*next context allocated, or NULL*/ 237 struct _drawable_context *next; 238 239 /*any of the above flags*/ 240 u16 flags; 241 /*only used by text when splitting strings into chars / substrings*/ 242 s16 sub_path_index; 243 244 /*drawable using this context*/ 245 Drawable *drawable; 246 247 /*pointer to clipped and uncliped (for sensors) rect in pixels.*/ 248 BoundInfo *bi; 249 250 /*draw info*/ 251 DrawAspect2D aspect; 252 /*transform matrix from top*/ 253 GF_Matrix2D transform; 254 /*color matrix, NULL if none/identity*/ 255 GF_ColorMatrix *col_mat; 256 257 /* extra check data for bounds matching 258 for MPEG-4: appearance node 259 for SVG: parent <use> node if any 260 */ 261 GF_Node *appear; 262 263 #ifdef GF_SR_USE_DEPTH 264 //local gain and offset 265 Fixed depth_gain, depth_offset; 266 #endif 267 268 }; 269 270 DrawableContext *NewDrawableContext(); 271 void DeleteDrawableContext(DrawableContext *); 272 void drawctx_reset(DrawableContext *ctx); 273 void drawctx_update_info(DrawableContext *ctx, GF_VisualManager *visual); 274 275 #ifndef GPAC_DISABLE_VRML 276 /*inits context - may return NULL if the node doesn't have to be drawn*/ 277 DrawableContext *drawable_init_context_mpeg4(Drawable *node, GF_TraverseState *tr_state); 278 #endif 279 280 /*inits context for SVG - may return NULL if the node doesn't have to be drawn*/ 281 DrawableContext *drawable_init_context_svg(Drawable *drawable, GF_TraverseState *tr_state); 282 283 /*base draw function for 2D objects (texturing, fill and strike) 284 in 2D, the current context is passed in the traversing state 285 */ 286 void drawable_draw(Drawable *drawable, GF_TraverseState *tr_state); 287 288 /*picking function for VRML-based scene graphs*/ 289 void vrml_drawable_pick(Drawable *drawable, GF_TraverseState *tr_state); 290 291 /*SVG picking function (uses SVG pointrer events)*/ 292 void svg_drawable_pick(GF_Node *node, Drawable *drawable, GF_TraverseState *tr_state); 293 294 /*stored at compositor level and in each drawable node*/ 295 typedef struct _strikeinfo2d 296 { 297 struct _strikeinfo2d *next; 298 /*vectorial outline*/ 299 GF_Path *outline; 300 /*drawable using this outline*/ 301 Drawable *drawable; 302 /*lineprops used to build outline (MPEG-4 only)*/ 303 GF_Node *lineProps; 304 /*user+world->local scaling for non-scalable outlines*/ 305 Fixed line_scale; 306 /*SVG path length*/ 307 Fixed path_length; 308 /*set only for text, indicates sub-path outline*/ 309 GF_Path *original; 310 311 312 #ifndef GPAC_DISABLE_3D 313 /*3D drawing*/ 314 Bool is_vectorial; 315 GF_Mesh *mesh_outline; 316 #endif 317 } StrikeInfo2D; 318 319 void delete_strikeinfo2d(StrikeInfo2D *info); 320 /*get strike and manage any scale change&co. This avoids recomputing outline at each frame...*/ 321 StrikeInfo2D *drawable_get_strikeinfo(GF_Compositor *compositor, Drawable *drawable, DrawAspect2D *asp, GF_Node *appear, GF_Path *path, u32 svg_flags, GF_TraverseState *tr_state); 322 323 324 void drawable_compute_line_scale(GF_TraverseState *tr_state, DrawAspect2D *asp); 325 326 Bool svg_drawable_is_over(Drawable *drawable, Fixed x, Fixed y, DrawAspect2D *asp, GF_TraverseState *tr_state, GF_Rect *glyph_rc); 327 328 void drawable_check_texture_dirty(DrawableContext *ctx, Drawable *drawable, GF_TraverseState *tr_state); 329 #endif 330