LCOV - code coverage report
Current view: top level - compositor - visual_manager.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 101 150 67.3 %
Date: 2021-04-29 23:48:07 Functions: 7 8 87.5 %

          Line data    Source code
       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             : #include "visual_manager.h"
      27             : #include "nodes_stacks.h"
      28             : #include <gpac/nodes_mpeg4.h>
      29             : #ifndef GPAC_DISABLE_SVG
      30             : #include <gpac/nodes_svg.h>
      31             : #endif
      32             : 
      33           0 : static Bool visual_draw_bitmap_stub(GF_VisualManager *visual, GF_TraverseState *tr_state, struct _drawable_context *ctx)
      34             : {
      35           0 :         return 0;
      36             : }
      37             : 
      38             : 
      39         652 : GF_VisualManager *visual_new(GF_Compositor *compositor)
      40             : {
      41             :         GF_VisualManager *tmp;
      42         652 :         GF_SAFEALLOC(tmp, GF_VisualManager);
      43         652 :         if (!tmp) {
      44           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to allocate new visual\n"));
      45             :                 return NULL;
      46             :         }
      47             : 
      48         652 :         tmp->center_coords = 1;
      49         652 :         tmp->compositor = compositor;
      50         652 :         ra_init(&tmp->to_redraw);
      51             : #ifndef GPAC_DISABLE_VRML
      52         652 :         tmp->back_stack = gf_list_new();
      53         652 :         tmp->view_stack = gf_list_new();
      54             : #endif
      55             : 
      56         652 :         tmp->raster_brush = gf_evg_stencil_new(GF_STENCIL_SOLID);
      57             : 
      58         652 :         tmp->DrawBitmap = visual_draw_bitmap_stub;
      59         652 :         tmp->ClearSurface = visual_2d_clear_surface;
      60             : 
      61             : #ifdef GPAC_ENABLE_COVERAGE
      62         652 :         if (gf_sys_is_cov_mode()) {
      63             :                 visual_draw_bitmap_stub(tmp, NULL, NULL);
      64             :                 visual_reset_graphics(NULL);
      65             :         }
      66             : #endif
      67             : 
      68             : #ifndef GPAC_DISABLE_3D
      69             : 
      70             : #ifndef GPAC_DISABLE_VRML
      71         652 :         tmp->navigation_stack = gf_list_new();
      72         652 :         tmp->fog_stack = gf_list_new();
      73             : #endif /*GPAC_DISABLE_VRML*/
      74         652 :         tmp->alpha_nodes_to_draw = gf_list_new();
      75         652 :         tmp->compiled_programs = gf_list_new();
      76             : #endif
      77             : 
      78         652 :         return tmp;
      79             : }
      80             : 
      81         651 : void visual_del(GF_VisualManager *visual)
      82             : {
      83         651 :         ra_del(&visual->to_redraw);
      84             : 
      85         651 :         if (visual->raster_surface) gf_evg_surface_delete(visual->raster_surface);
      86         651 :         visual->raster_surface = NULL;
      87         651 :         if (visual->raster_brush) gf_evg_stencil_delete(visual->raster_brush);
      88         651 :         visual->raster_brush = NULL;
      89             : 
      90        6841 :         while (visual->context) {
      91             :                 DrawableContext *ctx = visual->context;
      92        5539 :                 visual->context = ctx->next;
      93        5539 :                 DeleteDrawableContext(ctx);
      94             :         }
      95         651 :         while (visual->prev_nodes) {
      96             :                 struct _drawable_store *cur = visual->prev_nodes;
      97           0 :                 visual->prev_nodes = cur->next;
      98           0 :                 gf_free(cur);
      99             :         }
     100             : 
     101             : #ifndef GPAC_DISABLE_VRML
     102         651 :         if (visual->back_stack) BindableStackDelete(visual->back_stack);
     103         651 :         if (visual->view_stack) BindableStackDelete(visual->view_stack);
     104             : #endif /*GPAC_DISABLE_VRML*/
     105             : 
     106             : #ifndef GPAC_DISABLE_3D
     107         651 :         visual_3d_reset_graphics(visual);
     108         651 :         ra_del(&visual->hybgl_drawn);
     109             : 
     110             : #ifndef GPAC_DISABLE_VRML
     111         651 :         if (visual->navigation_stack) BindableStackDelete(visual->navigation_stack);
     112         651 :         if (visual->fog_stack) BindableStackDelete(visual->fog_stack);
     113             : #endif /*GPAC_DISABLE_VRML*/
     114             : 
     115         651 :         gf_list_del(visual->alpha_nodes_to_draw);
     116         651 :         gf_list_del(visual->compiled_programs);
     117             : #endif
     118         651 :         gf_free(visual);
     119         651 : }
     120             : 
     121        5422 : Bool visual_get_size_info(GF_TraverseState *tr_state, Fixed *surf_width, Fixed *surf_height)
     122             : {
     123             :         Fixed w, h;
     124             : //      w = tr_state->visual->width;
     125             : //      h = tr_state->visual->height;
     126        5422 :         w = tr_state->vp_size.x;
     127        5422 :         h = tr_state->vp_size.y;
     128             :         /*no size info, use main compositor output size*/
     129        5422 :         if (!w || !h) {
     130           6 :                 w = INT2FIX(tr_state->visual->compositor->vp_width);
     131           6 :                 h = INT2FIX(tr_state->visual->compositor->vp_height);
     132             :         }
     133        5422 :         if (tr_state->pixel_metrics) {
     134        5422 :                 *surf_width = w;
     135        5422 :                 *surf_height = h;
     136        5422 :                 return 1;
     137             :         }
     138           0 :         if (tr_state->min_hsize) {
     139           0 :                 *surf_width = gf_divfix(w, tr_state->min_hsize);
     140           0 :                 *surf_height = gf_divfix(h, tr_state->min_hsize);
     141           0 :                 return 0;
     142             :         }
     143           0 :         if (h > w) {
     144           0 :                 *surf_width = 2*FIX_ONE;
     145           0 :                 *surf_height = gf_divfix(2*h, w);
     146             :         } else {
     147           0 :                 *surf_width = gf_divfix(2*w, h);
     148           0 :                 *surf_height = 2*FIX_ONE;
     149             :         }
     150             :         return 0;
     151             : }
     152             : 
     153       28429 : void visual_clean_contexts(GF_VisualManager *visual)
     154             : {
     155             :         u32 i, count;
     156       28429 :         Bool is_root_visual = (visual->compositor->visual==visual) ? 1 : 0;
     157       28429 :         DrawableContext *ctx = visual->context;
     158      193060 :         while (ctx && ctx->drawable) {
     159             :                 /*remove visual registration flag*/
     160      136202 :                 ctx->drawable->flags &= ~DRAWABLE_REGISTERED_WITH_VISUAL;
     161      136202 :                 if (is_root_visual && (ctx->flags & CTX_HAS_APPEARANCE))
     162      110803 :                         gf_node_dirty_reset(ctx->appear, 0);
     163             : 
     164             : #ifndef GPAC_DISABLE_3D
     165             :                 /*this may happen when switching a visual from 2D to 3D - discard context*/
     166      136202 :                 if (visual->type_3d) ctx->drawable=NULL;
     167             : #endif
     168      136202 :                 ctx = ctx->next;
     169             :         }
     170             : 
     171             :         /*composite visual, cannot reset flags until root is done*/
     172       28429 :         if (!is_root_visual) return;
     173             : 
     174             :         /*reset all flags of all appearance nodes registered on all visuals but main one (done above)
     175             :         this must be done once all visuals have been drawn, otherwise we won't detect the changes
     176             :         for nodes drawn on several visuals*/
     177       26361 :         count = gf_list_count(visual->compositor->visuals);
     178       28690 :         for (i=1; i<count; i++) {
     179        2329 :                 GF_VisualManager *a_vis = gf_list_get(visual->compositor->visuals, i);
     180        2329 :                 ctx = a_vis->context;
     181        7247 :                 while (ctx && ctx->drawable) {
     182        2589 :                         if (ctx->flags & CTX_HAS_APPEARANCE)
     183        2542 :                                 gf_node_dirty_reset(ctx->appear, 0);
     184             : 
     185        2589 :                         ctx->drawable = NULL;
     186        2589 :                         ctx = ctx->next;
     187             :                 }
     188             :         }
     189             : }
     190             : 
     191       28429 : Bool visual_draw_frame(GF_VisualManager *visual, GF_Node *root, GF_TraverseState *tr_state, Bool is_root_visual)
     192             : {
     193             : #ifndef GPAC_DISABLE_3D
     194       28429 :         if (visual->type_3d) {
     195        6963 :                 Bool res = visual_3d_draw_frame(visual, root, tr_state, is_root_visual);
     196        6963 :                 visual_clean_contexts(visual);
     197        6963 :                 return res;
     198             :         }
     199       21466 :         if (visual->compositor->hybrid_opengl)
     200        1907 :                 visual_3d_clean_state(visual);
     201             : #endif
     202       21466 :         return visual_2d_draw_frame(visual, root, tr_state, is_root_visual);
     203             : }
     204             : 
     205         102 : void gf_sc_get_nodes_bounds(GF_Node *self, GF_ChildNodeItem *children, GF_TraverseState *tr_state, s32 *child_idx)
     206             : {
     207             :         u32 i;
     208             :         SFVec2f size;
     209             :         GF_Rect rc;
     210             :         GF_Matrix2D cur_mx;
     211             : 
     212         102 :         if (tr_state->abort_bounds_traverse) {
     213           0 :                 if (self == tr_state->for_node) {
     214           0 :                         gf_mx2d_pre_multiply(&tr_state->mx_at_node, &tr_state->transform);
     215             :                 }
     216           0 :                 tr_state->abort_bounds_traverse=0;
     217           0 :                 gf_sc_get_nodes_bounds(self, children, tr_state, child_idx);
     218           0 :                 tr_state->abort_bounds_traverse=1;
     219          19 :                 return;
     220             :         }
     221         102 :         if (!children) return;
     222             : 
     223             :         size.x = size.y = -FIX_ONE;
     224             : #ifndef GPAC_DISABLE_VRML
     225          83 :         switch (gf_node_get_tag(self)) {
     226           0 :         case TAG_MPEG4_Layer2D:
     227           0 :                 size = ((M_Layer2D *)self)->size;
     228           0 :                 break;
     229           0 :         case TAG_MPEG4_Layer3D:
     230           0 :                 size = ((M_Layer3D *)self)->size;
     231           0 :                 break;
     232           0 :         case TAG_MPEG4_Form:
     233           0 :                 size = ((M_Form *)self)->size;
     234           0 :                 break;
     235             :         }
     236             : #endif
     237          83 :         if ((size.x>=0) && (size.y>=0)) {
     238           0 :                 tr_state->bounds = gf_rect_center(size.x, size.y);
     239           0 :                 return;
     240             :         }
     241             : 
     242          83 :         gf_mx2d_copy(cur_mx, tr_state->transform);
     243          83 :         rc = gf_rect_center(0,0);
     244             : 
     245             :         i = 0;
     246         427 :         while (children) {
     247         261 :                 if (child_idx && (i != (u32) *child_idx)) {
     248           0 :                         children = children->next;
     249           0 :                         continue;
     250             :                 }
     251         261 :                 gf_mx2d_init(tr_state->transform);
     252         261 :                 tr_state->bounds = gf_rect_center(0,0);
     253             : 
     254             :                 /*we hit the target node*/
     255         261 :                 if (children->node == tr_state->for_node)
     256           0 :                         tr_state->abort_bounds_traverse = 1;
     257             : 
     258         261 :                 gf_node_traverse(children->node, tr_state);
     259             : 
     260         261 :                 if (tr_state->abort_bounds_traverse) {
     261           0 :                         gf_mx2d_add_matrix(&tr_state->mx_at_node, &cur_mx);
     262           0 :                         return;
     263             :                 }
     264             : 
     265         261 :                 gf_mx2d_apply_rect(&tr_state->transform, &tr_state->bounds);
     266         261 :                 gf_rect_union(&rc, &tr_state->bounds);
     267         261 :                 children = children->next;
     268         261 :                 if (child_idx)
     269             :                         break;
     270             :         }
     271             : 
     272             : #ifndef GPAC_DISABLE_SVG
     273          83 :         if (gf_node_get_tag(self)==TAG_SVG_use) {
     274             :                 GF_FieldInfo info;
     275           0 :                 if (gf_node_get_attribute_by_tag(self, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) {
     276           0 :                         GF_Node *iri = ((XMLRI*)info.far_ptr)->target;
     277           0 :                         if (iri) {
     278           0 :                                 gf_mx2d_init(tr_state->transform);
     279           0 :                                 tr_state->bounds = gf_rect_center(0,0);
     280             : 
     281             :                                 /*we hit the target node*/
     282           0 :                                 if (iri == tr_state->for_node)
     283           0 :                                         tr_state->abort_bounds_traverse = 1;
     284             : 
     285           0 :                                 gf_node_traverse(iri, tr_state);
     286             : 
     287           0 :                                 if (tr_state->abort_bounds_traverse) {
     288           0 :                                         gf_mx2d_pre_multiply(&tr_state->mx_at_node, &cur_mx);
     289           0 :                                         return;
     290             :                                 }
     291             : 
     292           0 :                                 gf_mx2d_apply_rect(&tr_state->transform, &tr_state->bounds);
     293           0 :                                 gf_rect_union(&rc, &tr_state->bounds);
     294             :                         }
     295             :                 }
     296             :         }
     297             : #endif
     298             : 
     299             :         gf_mx2d_copy(tr_state->transform, cur_mx);
     300          83 :         if (self != tr_state->for_node) {
     301          83 :                 gf_mx2d_apply_rect(&tr_state->transform, &rc);
     302             :         }
     303          83 :         tr_state->bounds = rc;
     304             : }
     305             : 
     306           1 : void visual_reset_graphics(GF_VisualManager *visual)
     307             : {
     308           1 :         if (!visual) return;
     309             : #ifndef GPAC_DISABLE_3D
     310           1 :         if (visual->type_3d) {
     311           0 :                 visual_3d_reset_graphics(visual);
     312             :         }
     313           1 :         compositor_2d_reset_gl_auto(visual->compositor);
     314             : #endif
     315             : }
     316             : 

Generated by: LCOV version 1.13