LCOV - code coverage report
Current view: top level - evg - surface.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 597 616 96.9 %
Date: 2021-04-29 23:48:07 Functions: 22 22 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2019
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / software 2D rasterizer module
       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             : 
      28             : #include "rast_soft.h"
      29             : 
      30      926468 : static void get_surface_world_matrix(GF_EVGSurface *surf, GF_Matrix2D *mat)
      31             : {
      32     1852936 :         gf_mx2d_init(*mat);
      33      926468 :         if (surf->center_coords) {
      34      631149 :                 gf_mx2d_add_scale(mat, FIX_ONE, -FIX_ONE);
      35      631149 :                 gf_mx2d_add_translation(mat, INT2FIX(surf->width / 2), INT2FIX(surf->height / 2));
      36             :         }
      37      926468 : }
      38             : 
      39             : GF_EXPORT
      40        1232 : GF_EVGSurface *gf_evg_surface_new(Bool center_coords)
      41             : {
      42             :         GF_EVGSurface *surf;
      43        1232 :         GF_SAFEALLOC(surf, GF_EVGSurface);
      44        1232 :         if (surf) {
      45        1232 :                 surf->center_coords = center_coords;
      46        1232 :                 surf->texture_filter = GF_TEXTURE_FILTER_DEFAULT;
      47        1232 :                 surf->raster = evg_raster_new();
      48        1232 :                 surf->yuv_prof=1;
      49             :         }
      50        1232 :         return surf;
      51             : }
      52             : 
      53             : EVG_Surface3DExt *evg_init_3d_surface(GF_EVGSurface *surf);
      54             : 
      55             : GF_EXPORT
      56          19 : GF_EVGSurface *gf_evg_surface3d_new()
      57             : {
      58             :         GF_EVGSurface *surf;
      59          19 :         GF_SAFEALLOC(surf, GF_EVGSurface);
      60          19 :         if (surf) {
      61          19 :                 surf->texture_filter = GF_TEXTURE_FILTER_DEFAULT;
      62          19 :                 surf->raster = evg_raster_new();
      63          19 :                 surf->yuv_prof=1;
      64             : 
      65          19 :                 surf->ext3d = evg_init_3d_surface(surf);
      66          19 :                 if (!surf->ext3d) {
      67           0 :                         gf_free(surf);
      68           0 :                         return NULL;
      69             :                 }
      70             :         }
      71             :         return surf;
      72             : }
      73             : 
      74             : GF_EXPORT
      75         106 : void gf_evg_surface_set_center_coords(GF_EVGSurface *surf, Bool center_coords)
      76             : {
      77         106 :         if (surf) surf->center_coords = center_coords;
      78         106 : }
      79             : 
      80             : GF_EXPORT
      81        1251 : void gf_evg_surface_delete(GF_EVGSurface *surf)
      82             : {
      83        1251 :         if (!surf)
      84             :                 return;
      85        1251 :         if (surf->stencil_pix_run) gf_free(surf->stencil_pix_run);
      86        1251 :         surf->stencil_pix_run = NULL;
      87        1251 :         if (surf->raster) evg_raster_del(surf->raster);
      88        1251 :         surf->raster = NULL;
      89        1251 :         if (surf->uv_alpha) gf_free(surf->uv_alpha);
      90             : 
      91        1251 :         if (surf->ext3d) {
      92          19 :                 if (surf->ext3d->pix_vals)
      93          19 :                         gf_free(surf->ext3d->pix_vals);
      94          19 :                 gf_free(surf->ext3d);
      95             :         }
      96        1251 :         gf_free(surf);
      97             : }
      98             : 
      99             : GF_EXPORT
     100      698471 : GF_Err gf_evg_surface_set_matrix(GF_EVGSurface *surf, GF_Matrix2D *mat)
     101             : {
     102             :         GF_Matrix2D tmp;
     103      698471 :         if (!surf) return GF_BAD_PARAM;
     104      698471 :         get_surface_world_matrix(surf, &surf->mat);
     105      698471 :         surf->is_3d_matrix = GF_FALSE;
     106      698471 :         if (!mat) return GF_OK;
     107             : 
     108      681056 :         gf_mx2d_init(tmp);
     109      681056 :         gf_mx2d_add_matrix(&tmp, mat);
     110      681056 :         gf_mx2d_add_matrix(&tmp, &surf->mat);
     111      681056 :         gf_mx2d_copy(surf->mat, tmp);
     112      681056 :         return GF_OK;
     113             : }
     114             : 
     115             : GF_EXPORT
     116           1 : GF_Err gf_evg_surface_set_matrix_3d(GF_EVGSurface *surf, GF_Matrix *mat)
     117             : {
     118           1 :         if (!surf) return GF_BAD_PARAM;
     119           1 :         get_surface_world_matrix(surf, &surf->mat);
     120           1 :         surf->is_3d_matrix = GF_FALSE;
     121           1 :         if (!mat) return GF_OK;
     122           1 :         gf_mx_copy(surf->mx3d, *mat);
     123           1 :         surf->is_3d_matrix = GF_TRUE;
     124           1 :         return GF_OK;
     125             : }
     126             : 
     127       17042 : static void evg_surface_set_components_idx(GF_EVGSurface *surf)
     128             : {
     129       17042 :         surf->idx_y1=surf->idx_u=surf->idx_v=0;
     130       17042 :         surf->idx_a=surf->idx_r=surf->idx_g=surf->idx_b=0;
     131       17042 :         switch (surf->pixelFormat) {
     132          12 :         case GF_PIXEL_YUYV:
     133             :                 surf->idx_y1=0;
     134          12 :                 surf->idx_u=1;
     135          12 :                 surf->idx_v=3;
     136          12 :                 break;
     137          12 :         case GF_PIXEL_YVYU:
     138             :                 surf->idx_y1=0;
     139          12 :                 surf->idx_u=3;
     140          12 :                 surf->idx_v=1;
     141          12 :                 break;
     142          12 :         case GF_PIXEL_UYVY:
     143          12 :                 surf->idx_y1=1;
     144             :                 surf->idx_u=0;
     145          12 :                 surf->idx_v=2;
     146          12 :                 break;
     147          12 :         case GF_PIXEL_VYUY:
     148          12 :                 surf->idx_y1=1;
     149          12 :                 surf->idx_u=2;
     150             :                 surf->idx_v=0;
     151          12 :                 break;
     152          13 :         case GF_PIXEL_ALPHAGREY:
     153             :                 surf->idx_a = 0;
     154          13 :                 surf->idx_g = 1;
     155          13 :                 break;
     156          13 :         case GF_PIXEL_GREYALPHA:
     157          13 :                 surf->idx_a = 1;
     158             :                 surf->idx_g = 0;
     159          13 :                 break;
     160          24 :         case GF_PIXEL_ARGB:
     161             :                 surf->idx_a=0;
     162          24 :                 surf->idx_r=1;
     163          24 :                 surf->idx_g=2;
     164          24 :                 surf->idx_b=3;
     165          24 :                 break;
     166        2664 :         case GF_PIXEL_RGBA:
     167        2664 :                 surf->idx_a=3;
     168             :                 surf->idx_r=0;
     169        2664 :                 surf->idx_g=1;
     170        2664 :                 surf->idx_b=2;
     171        2664 :                 break;
     172           9 :         case GF_PIXEL_BGRA:
     173           9 :                 surf->idx_a=3;
     174           9 :                 surf->idx_r=2;
     175           9 :                 surf->idx_g=1;
     176             :                 surf->idx_b=0;
     177           9 :                 break;
     178           7 :         case GF_PIXEL_ABGR:
     179             :                 surf->idx_a=0;
     180           7 :                 surf->idx_r=3;
     181           7 :                 surf->idx_g=2;
     182           7 :                 surf->idx_b=1;
     183           7 :                 break;
     184           9 :         case GF_PIXEL_RGBX:
     185             :                 surf->idx_r=0;
     186           9 :                 surf->idx_g=1;
     187           9 :                 surf->idx_b=2;
     188           9 :                 surf->idx_a=3;
     189           9 :                 break;
     190           9 :         case GF_PIXEL_BGRX:
     191           9 :                 surf->idx_r=2;
     192           9 :                 surf->idx_g=1;
     193             :                 surf->idx_b=0;
     194           9 :                 surf->idx_a=3;
     195           9 :                 break;
     196          12 :         case GF_PIXEL_XRGB:
     197             :                 surf->idx_a=0;
     198          12 :                 surf->idx_r=1;
     199          12 :                 surf->idx_g=2;
     200          12 :                 surf->idx_b=3;
     201          12 :                 break;
     202          12 :         case GF_PIXEL_XBGR:
     203             :                 surf->idx_a=0;
     204          12 :                 surf->idx_r=3;
     205          12 :                 surf->idx_g=2;
     206          12 :                 surf->idx_b=1;
     207          12 :                 break;
     208       13758 :         case GF_PIXEL_RGB:
     209             :                 surf->idx_r=0;
     210       13758 :                 surf->idx_g=1;
     211       13758 :                 surf->idx_b=2;
     212       13758 :                 break;
     213           9 :         case GF_PIXEL_BGR:
     214           9 :                 surf->idx_r=2;
     215           9 :                 surf->idx_g=1;
     216             :                 surf->idx_b=0;
     217           9 :                 break;
     218             :         }
     219       17042 : }
     220             : 
     221             : GF_Err evg_3d_resize(GF_EVGSurface *surf);
     222             : 
     223             : 
     224             : GF_EXPORT
     225       17042 : GF_Err gf_evg_surface_attach_to_buffer(GF_EVGSurface *surf, u8 *pixels, u32 width, u32 height, s32 pitch_x, s32 pitch_y, GF_PixelFormat pixelFormat)
     226             : {
     227             :         u32 BPP;
     228             :         Bool size_changed=GF_FALSE;
     229       17042 :         if (!surf || !pixels) return GF_BAD_PARAM;
     230             : 
     231       17042 :         surf->is_transparent = GF_FALSE;
     232       17042 :         surf->not_8bits = GF_FALSE;
     233       17042 :         switch (pixelFormat) {
     234             :         case GF_PIXEL_GREYSCALE:
     235             :                 BPP = 1;
     236             :                 break;
     237          26 :         case GF_PIXEL_ALPHAGREY:
     238             :         case GF_PIXEL_GREYALPHA:
     239             :                 BPP = 2;
     240          26 :                 surf->is_transparent = GF_TRUE;
     241          26 :                 break;
     242          31 :         case GF_PIXEL_RGB_444:
     243             :         case GF_PIXEL_RGB_555:
     244             :         case GF_PIXEL_RGB_565:
     245             :                 BPP = 2;
     246          31 :                 break;
     247        2704 :         case GF_PIXEL_ARGB:
     248             :         case GF_PIXEL_BGRA:
     249             :         case GF_PIXEL_RGBA:
     250             :         case GF_PIXEL_ABGR:
     251        2704 :                 surf->is_transparent = GF_TRUE;
     252             :         case GF_PIXEL_RGBX:
     253             :         case GF_PIXEL_BGRX:
     254             :         case GF_PIXEL_XRGB:
     255             :         case GF_PIXEL_XBGR:
     256             :                 BPP = 4;
     257             :                 break;
     258       13767 :         case GF_PIXEL_BGR:
     259             :         case GF_PIXEL_RGB:
     260             :                 BPP = 3;
     261       13767 :                 break;
     262             :         case GF_PIXEL_YUV:
     263             :         case GF_PIXEL_YVU:
     264             :         case GF_PIXEL_NV12:
     265             :         case GF_PIXEL_NV21:
     266             :         case GF_PIXEL_YUV422:
     267             :         case GF_PIXEL_YUV444:
     268             :         case GF_PIXEL_YUYV:
     269             :         case GF_PIXEL_YVYU:
     270             :         case GF_PIXEL_UYVY:
     271             :         case GF_PIXEL_VYUY:
     272             :                 BPP = 1;
     273             :                 break;
     274          61 :         case GF_PIXEL_YUV_10:
     275             :         case GF_PIXEL_NV12_10:
     276             :         case GF_PIXEL_NV21_10:
     277             :         case GF_PIXEL_YUV422_10:
     278             :         case GF_PIXEL_YUV444_10:
     279             :                 BPP = 2;
     280          61 :                 surf->not_8bits = GF_TRUE;
     281          61 :                 break;
     282             :         default:
     283             :                 return GF_NOT_SUPPORTED;
     284             :         }
     285       17042 :         if (!pitch_x) pitch_x = BPP;
     286       17042 :         surf->pitch_x = pitch_x;
     287       17042 :         surf->pitch_y = pitch_y;
     288       17042 :         if (!surf->stencil_pix_run || (surf->width != width)) {
     289        1210 :                 u32 run_size = sizeof(u32) * (width+2);
     290        1210 :                 if (surf->not_8bits) run_size *= 2;
     291        1210 :                 if (surf->stencil_pix_run) gf_free(surf->stencil_pix_run);
     292        1210 :                 surf->stencil_pix_run = (u32 *) gf_malloc(run_size);
     293             :         }
     294       17042 :         if (surf->width != width) {
     295        1210 :                 surf->width = width;
     296             :                 size_changed = GF_TRUE;
     297             :         }
     298       17042 :         if (surf->height != height) {
     299        1213 :                 surf->height = height;
     300             :                 size_changed = GF_TRUE;
     301             :         }
     302       17042 :         surf->pixels = (char*)pixels;
     303       17042 :         surf->pixelFormat = pixelFormat;
     304       17042 :         surf->BPP = BPP;
     305       17042 :         evg_surface_set_components_idx(surf);
     306       17042 :         gf_evg_surface_set_matrix(surf, NULL);
     307       17042 :         if (surf->ext3d && size_changed)
     308          19 :                 evg_3d_resize(surf);
     309             :         return GF_OK;
     310             : }
     311             : 
     312             : 
     313             : GF_EXPORT
     314        2352 : GF_Err gf_evg_surface_attach_to_texture(GF_EVGSurface *surf, GF_EVGStencil * sten)
     315             : {
     316             :         EVG_Texture *tx = (EVG_Texture *) sten;
     317        2352 :         if (!surf || (tx->type != GF_STENCIL_TEXTURE)) return GF_BAD_PARAM;
     318             : 
     319        2352 :         return gf_evg_surface_attach_to_buffer(surf, tx->pixels, tx->width, tx->height, 0, tx->stride, tx->pixel_format);
     320             : }
     321             : 
     322             : 
     323             : GF_EXPORT
     324        5304 : GF_Err gf_evg_surface_clear(GF_EVGSurface *surf, GF_IRect *rc, u32 color)
     325             : {
     326             :         GF_IRect clear;
     327        5304 :         if (!surf) return GF_BAD_PARAM;
     328             : 
     329        5304 :         if (rc) {
     330             :                 s32 _x, _y;
     331        4168 :                 if (surf->center_coords) {
     332        3338 :                         _x = rc->x + surf->width / 2;
     333        3338 :                         _y = surf->height / 2 - rc->y;
     334             :                 } else {
     335         830 :                         _x = rc->x;
     336         830 :                         _y = rc->y - rc->height;
     337             :                 }
     338             :                 /*clip is outside our bounds, ignore*/
     339        4168 :                 if ((_x>=(s32) surf->width) || (_x + rc->width < 0))
     340             :                         return GF_OK;
     341        4158 :                 if ((_y>= (s32) surf->height) || (_y + rc->height < 0))
     342             :                         return GF_OK;
     343             : 
     344             :                 clear.width = (u32) rc->width;
     345        4133 :                 if (_x>=0) {
     346             :                         clear.x = (u32) _x;
     347             :                 } else {
     348             :                         if ( (s32) clear.width + _x < 0) return GF_BAD_PARAM;
     349             :                         clear.width += _x;
     350             :                         clear.x = 0;
     351             :                 }
     352        4133 :                 if (clear.x + clear.width > (s32) surf->width)
     353           8 :                         clear.width = surf->width - clear.x;
     354             : 
     355        4133 :                 if (!clear.width)
     356             :                         return GF_OK;
     357             : 
     358             :                 clear.height = (u32) rc->height;
     359        4133 :                 if (_y>=0) {
     360             :                         clear.y = _y;
     361             :                 } else {
     362             :                         if ( (s32) clear.height + _y < 0) return GF_BAD_PARAM;
     363             :                         clear.height += _y;
     364             :                         clear.y = 0;
     365             :                 }
     366        4133 :                 if (clear.y + clear.height > (s32) surf->height)
     367           4 :                         clear.height = surf->height - clear.y;
     368             : 
     369        4133 :                 if (!clear.height)
     370             :                         return GF_OK;
     371             :         } else {
     372             :                 clear.x = clear.y = 0;
     373        1136 :                 clear.width = surf->width;
     374        1136 :                 clear.height = surf->height;
     375             :         }
     376             : 
     377        5268 :         switch (surf->pixelFormat) {
     378             :         /*RGB formats*/
     379           5 :         case GF_PIXEL_GREYSCALE:
     380           5 :                 return evg_surface_clear_grey(surf, clear, color);
     381          10 :         case GF_PIXEL_ALPHAGREY:
     382             :         case GF_PIXEL_GREYALPHA:
     383          10 :                 return evg_surface_clear_alphagrey(surf, clear, color);
     384        2386 :         case GF_PIXEL_ARGB:
     385             :         case GF_PIXEL_BGRA:
     386             :         case GF_PIXEL_RGBA:
     387             :         case GF_PIXEL_ABGR:
     388        2386 :                 return evg_surface_clear_argb(surf, clear, color);
     389             : 
     390          20 :         case GF_PIXEL_RGBX:
     391             :         case GF_PIXEL_BGRX:
     392             :         case GF_PIXEL_XRGB:
     393             :         case GF_PIXEL_XBGR:
     394          20 :                 return evg_surface_clear_rgbx(surf, clear, color);
     395             : 
     396        2744 :         case GF_PIXEL_RGB:
     397             :         case GF_PIXEL_BGR:
     398        2744 :                 return evg_surface_clear_rgb(surf, clear, color);
     399           5 :         case GF_PIXEL_RGB_444:
     400           5 :                 return evg_surface_clear_444(surf, clear, color);
     401           5 :         case GF_PIXEL_RGB_555:
     402           5 :                 return evg_surface_clear_555(surf, clear, color);
     403           5 :         case GF_PIXEL_RGB_565:
     404           5 :                 return evg_surface_clear_565(surf, clear, color);
     405             : 
     406             :         /*YUV formats*/
     407          26 :         case GF_PIXEL_YUV:
     408             :         case GF_PIXEL_YVU:
     409          26 :                 return evg_surface_clear_yuv420p(surf, clear, color);
     410           9 :         case GF_PIXEL_YUV422:
     411           9 :                 return evg_surface_clear_yuv422p(surf, clear, color);
     412           4 :         case GF_PIXEL_NV12:
     413           4 :                 return evg_surface_clear_nv12(surf, clear, color, GF_FALSE);
     414           4 :         case GF_PIXEL_NV21:
     415           4 :                 return evg_surface_clear_nv12(surf, clear, color, GF_TRUE);
     416           9 :         case GF_PIXEL_YUV444:
     417           9 :                 return evg_surface_clear_yuv444p(surf, clear, color);
     418          16 :         case GF_PIXEL_YUYV:
     419             :         case GF_PIXEL_YVYU:
     420             :         case GF_PIXEL_UYVY:
     421             :         case GF_PIXEL_VYUY:
     422          16 :                 return evg_surface_clear_yuyv(surf, clear, color);
     423           4 :         case GF_PIXEL_YUV_10:
     424           4 :                 return evg_surface_clear_yuv420p_10(surf, clear, color);
     425           4 :         case GF_PIXEL_NV12_10:
     426           4 :                 return evg_surface_clear_nv12_10(surf, clear, color, GF_FALSE);
     427           4 :         case GF_PIXEL_NV21_10:
     428           4 :                 return evg_surface_clear_nv12_10(surf, clear, color, GF_TRUE);
     429           4 :         case GF_PIXEL_YUV422_10:
     430           4 :                 return evg_surface_clear_yuv422p_10(surf, clear, color);
     431           4 :         case GF_PIXEL_YUV444_10:
     432           4 :                 return evg_surface_clear_yuv444p_10(surf, clear, color);
     433             :         default:
     434             :                 return GF_BAD_PARAM;
     435             :         }
     436             : }
     437             : 
     438             : GF_EXPORT
     439      674792 : GF_Err gf_evg_surface_set_raster_level(GF_EVGSurface *surf, GF_RasterQuality RasterSetting)
     440             : {
     441      674792 :         if (!surf) return GF_BAD_PARAM;
     442      674792 :         switch (RasterSetting) {
     443      660666 :         case GF_RASTER_HIGH_QUALITY:
     444      660666 :                 surf->texture_filter = GF_TEXTURE_FILTER_HIGH_QUALITY;
     445      660666 :                 break;
     446           0 :         case GF_RASTER_MID:
     447           0 :                 surf->texture_filter = GF_TEXTURE_FILTER_HIGH_QUALITY;
     448           0 :                 break;
     449       14126 :         case GF_RASTER_HIGH_SPEED:
     450             :         default:
     451       14126 :                 surf->texture_filter = GF_TEXTURE_FILTER_HIGH_SPEED;
     452       14126 :                 break;
     453             :         }
     454             :         return GF_OK;
     455             : }
     456             : 
     457             : 
     458             : GF_EXPORT
     459      254712 : GF_Err gf_evg_surface_set_clipper(GF_EVGSurface *surf , GF_IRect *rc)
     460             : {
     461      254712 :         if (!surf) return GF_BAD_PARAM;
     462      254712 :         if (rc) {
     463      254345 :                 surf->clipper = *rc;
     464      254345 :                 surf->useClipper = 1;
     465             :                 /*clipper was given in BIFS like coords, we work with bottom-min for rect, (0,0) top-left of surface*/
     466      254345 :                 if (surf->center_coords) {
     467      165742 :                         surf->clipper.x += surf->width / 2;
     468      165742 :                         surf->clipper.y = surf->height / 2 - rc->y;
     469             :                 } else {
     470       88603 :                         surf->clipper.y -= rc->height;
     471             :                 }
     472             : 
     473      254345 :                 if (surf->clipper.x <=0) {
     474        1705 :                         if (surf->clipper.x + (s32) surf->clipper.width < 0) return GF_BAD_PARAM;
     475        1705 :                         surf->clipper.width += surf->clipper.x;
     476        1705 :                         surf->clipper.x = 0;
     477             :                 }
     478      254345 :                 if (surf->clipper.y <=0) {
     479        1076 :                         if (surf->clipper.y + (s32) surf->clipper.height < 0) return GF_BAD_PARAM;
     480        1076 :                         surf->clipper.height += surf->clipper.y;
     481        1076 :                         surf->clipper.y = 0;
     482             :                 }
     483      254345 :                 if (surf->clipper.x + surf->clipper.width > (s32) surf->width) {
     484           0 :                         surf->clipper.width = surf->width - surf->clipper.x;
     485             :                 }
     486      254345 :                 if (surf->clipper.y + surf->clipper.height > (s32) surf->height) {
     487           0 :                         surf->clipper.height = surf->height - surf->clipper.y;
     488             :                 }
     489             :         } else {
     490         367 :                 surf->useClipper = 0;
     491             :         }
     492             :         return GF_OK;
     493             : }
     494             : 
     495             : 
     496      228322 : static Bool setup_grey_callback(GF_EVGSurface *surf, Bool for_3d)
     497             : {
     498             :         u32 a, uv_alpha_size=0;
     499             :         Bool use_const = GF_TRUE;
     500             : 
     501             :         //in 3D mode, we only write one pixel at a time except in YUV modes
     502      228322 :         if (for_3d) {
     503             :                 a = 1;
     504             :                 use_const = GF_TRUE;
     505             :         }
     506      227996 :         else if (surf->sten->type == GF_STENCIL_SOLID) {
     507      215155 :                 surf->fill_col = ((EVG_Brush *)surf->sten)->color;
     508      215155 :                 a = GF_COL_A(surf->fill_col);
     509             :         } else {
     510             :                 a = 0;
     511             :                 use_const = GF_FALSE;
     512             :         }
     513             : 
     514      228322 :         if (use_const && !a && !surf->is_transparent) return GF_FALSE;
     515             : 
     516      228322 :         surf->is_422 = GF_FALSE;
     517      228322 :         surf->yuv_type = 0;
     518      228322 :         surf->swap_uv = GF_FALSE;
     519      228322 :         surf->yuv_flush_uv = NULL;
     520             : 
     521      228322 :         if (surf->comp_mode) a=100;
     522      228322 :         else if (surf->get_alpha) a=100;
     523      228322 :         surf->fill_single = NULL;
     524      228322 :         surf->fill_single_a = NULL;
     525             :         
     526      228322 :         switch (surf->pixelFormat) {
     527          32 :         case GF_PIXEL_GREYSCALE:
     528          32 :                 if (use_const) {
     529          17 :                         if (a!=0xFF) {
     530           3 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_grey_fill_const_a;
     531             :                         } else {
     532          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_grey_fill_const;
     533             :                         }
     534             :                 } else {
     535          15 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_grey_fill_var;
     536             :                 }
     537          32 :                 if (surf->ext3d) {
     538           1 :                         surf->fill_single = evg_grey_fill_single;
     539           1 :                         surf->fill_single_a = evg_grey_fill_single_a;
     540             :                 }
     541             :                 break;
     542          64 :         case GF_PIXEL_ALPHAGREY:
     543             :         case GF_PIXEL_GREYALPHA:
     544          64 :                 if (use_const) {
     545          34 :                         if (a!=0xFF) {
     546           6 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_alphagrey_fill_const_a;
     547             :                         } else {
     548          28 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_alphagrey_fill_const;
     549             :                         }
     550             :                 } else {
     551          30 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_alphagrey_fill_var;
     552             :                 }
     553          64 :                 if (surf->ext3d) {
     554           2 :                         surf->fill_single = evg_alphagrey_fill_single;
     555           2 :                         surf->fill_single_a = evg_alphagrey_fill_single_a;
     556             :                 }
     557             :                 break;
     558       22551 :         case GF_PIXEL_ARGB:
     559             :         case GF_PIXEL_RGBA:
     560             :         case GF_PIXEL_BGRA:
     561             :         case GF_PIXEL_ABGR:
     562       22551 :                 if (use_const) {
     563       22228 :                         if (!a) {
     564         301 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_argb_fill_erase;
     565       21927 :                         } else if (a!=0xFF) {
     566         175 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_argb_fill_const_a;
     567             :                         } else {
     568       21752 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_argb_fill_const;
     569             :                         }
     570             :                 } else {
     571         323 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_argb_fill_var;
     572             :                 }
     573       22551 :                 if (surf->ext3d) {
     574           4 :                         surf->fill_single = evg_argb_fill_single;
     575           4 :                         surf->fill_single_a = evg_argb_fill_single_a;
     576             :                 }
     577             :                 break;
     578             : 
     579         118 :         case GF_PIXEL_RGBX:
     580             :         case GF_PIXEL_BGRX:
     581             :         case GF_PIXEL_XRGB:
     582             :         case GF_PIXEL_XBGR:
     583         118 :                 if (use_const) {
     584          68 :                         if (a!=0xFF) {
     585          12 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_rgbx_fill_const_a;
     586             :                         } else {
     587          56 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_rgbx_fill_const;
     588             :                         }
     589             :                 } else {
     590          50 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_rgbx_fill_var;
     591             :                 }
     592         118 :                 if (surf->ext3d) {
     593           4 :                         surf->fill_single = evg_rgbx_fill_single;
     594           4 :                         surf->fill_single_a = evg_rgbx_fill_single_a;
     595             :                 }
     596             :                 break;
     597             : 
     598      203657 :         case GF_PIXEL_RGB:
     599             :         case GF_PIXEL_BGR:
     600      203657 :                 if (use_const) {
     601      191673 :                         if (a!=0xFF) {
     602        3132 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_rgb_fill_const_a;
     603             :                         } else {
     604      188541 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_rgb_fill_const;
     605             :                         }
     606             :                 } else {
     607       11984 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_rgb_fill_var;
     608             :                 }
     609      203657 :                 if (surf->ext3d) {
     610         211 :                         surf->fill_single = evg_rgb_fill_single;
     611         211 :                         surf->fill_single_a = evg_rgb_fill_single_a;
     612             :                 }
     613             :                 break;
     614             : 
     615          28 :         case GF_PIXEL_RGB_565:
     616          28 :                 if (use_const) {
     617          17 :                         if (a!=0xFF) {
     618           3 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_565_fill_const_a;
     619             :                         } else {
     620          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_565_fill_const;
     621             :                         }
     622             :                 } else {
     623          11 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_565_fill_var;
     624             :                         assert(surf->sten->fill_run);
     625             :                 }
     626          28 :                 if (surf->ext3d) {
     627           1 :                         surf->fill_single = evg_565_fill_single;
     628           1 :                         surf->fill_single_a = evg_565_fill_single_a;
     629             :                 }
     630             :                 break;
     631          32 :         case GF_PIXEL_RGB_444:
     632          32 :                 if (use_const) {
     633          17 :                         if (a!=0xFF) {
     634           3 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_444_fill_const_a;
     635             :                         } else {
     636          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_444_fill_const;
     637             :                         }
     638             :                 } else {
     639          15 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_444_fill_var;
     640             :                 }
     641          32 :                 if (surf->ext3d) {
     642           1 :                         surf->fill_single = evg_444_fill_single;
     643           1 :                         surf->fill_single_a = evg_444_fill_single_a;
     644             :                 }
     645             :                 break;
     646          28 :         case GF_PIXEL_RGB_555:
     647          28 :                 if (use_const) {
     648          17 :                         if (a!=0xFF) {
     649           3 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_555_fill_const_a;
     650             :                         } else {
     651          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_555_fill_const;
     652             :                         }
     653             :                 } else {
     654          11 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_555_fill_var;
     655             :                 }
     656          28 :                 if (surf->ext3d) {
     657           1 :                         surf->fill_single = evg_555_fill_single;
     658           1 :                         surf->fill_single_a = evg_555_fill_single_a;
     659             :                 }
     660             :                 break;
     661           0 :         case GF_PIXEL_YVU:
     662           0 :                 surf->swap_uv = GF_TRUE;
     663        1379 :         case GF_PIXEL_YUV:
     664        1379 :                 surf->yuv_type = EVG_YUV;
     665        1379 :                 if (use_const && !for_3d) {
     666        1101 :                         surf->yuv_flush_uv = evg_yuv420p_flush_uv_const;
     667             : 
     668        1101 :                         if (a!=0xFF) {
     669           4 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_const_a;
     670             :                         } else {
     671        1097 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_const;
     672             :                         }
     673        1101 :                         uv_alpha_size=2*surf->width;
     674             :                 } else {
     675         278 :                         surf->yuv_flush_uv = evg_yuv420p_flush_uv_var;
     676         278 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_var;
     677         278 :                         uv_alpha_size = 2 * 3*surf->width;
     678         278 :                         if (for_3d)
     679         101 :                                 surf->sten = &surf->ext3d->yuv_sten;
     680             :                 }
     681             :                 break;
     682          31 :         case GF_PIXEL_NV21:
     683          31 :                 surf->swap_uv = GF_TRUE;
     684          62 :         case GF_PIXEL_NV12:
     685          62 :                 surf->yuv_type = EVG_YUV;
     686             : 
     687          62 :                 if (surf->swap_uv) {
     688          31 :                         surf->idx_u = 1;
     689          31 :                         surf->idx_v = 0;
     690             :                 } else {
     691          31 :                         surf->idx_u = 0;
     692          31 :                         surf->idx_v = 1;
     693             :                 }
     694             : 
     695          62 :                 if (use_const && !for_3d) {
     696          32 :                         surf->yuv_flush_uv = evg_nv12_flush_uv_const;
     697             : 
     698          32 :                         if (a!=0xFF) {
     699           4 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_const_a;
     700             :                         } else {
     701          28 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_const;
     702             :                         }
     703          32 :                         uv_alpha_size = 2*surf->width;
     704             :                 } else {
     705          30 :                         surf->yuv_flush_uv = evg_nv12_flush_uv_var;
     706          30 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_var;
     707          30 :                         uv_alpha_size = 2 * 3*surf->width;
     708             :                 }
     709             :                 break;
     710          42 :         case GF_PIXEL_YUV422:
     711          42 :                 surf->yuv_type = EVG_YUV;
     712          42 :                 surf->is_422 = GF_TRUE;
     713          42 :                 if (use_const && !for_3d) {
     714          16 :                         surf->yuv_flush_uv = evg_yuv422p_flush_uv_const;
     715             : 
     716          16 :                         if (a!=0xFF) {
     717           2 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_const_a;
     718             :                         } else {
     719          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_const;
     720             :                         }
     721          16 :                         uv_alpha_size = 2*surf->width;
     722             :                 } else {
     723          26 :                         surf->yuv_flush_uv = evg_yuv422p_flush_uv_var;
     724          26 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_fill_var;
     725          26 :                         uv_alpha_size = 2 * 3*surf->width;
     726             :                 }
     727             :                 break;
     728          42 :         case GF_PIXEL_YUV444:
     729          42 :                 surf->yuv_type = EVG_YUV_444;
     730          42 :                 if (use_const) {
     731          16 :                         if (a!=0xFF) {
     732           2 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv444p_fill_const_a;
     733             :                         } else {
     734          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv444p_fill_const;
     735             :                         }
     736             :                 } else {
     737          26 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv444p_fill_var;
     738             :                 }
     739             :                 break;
     740         124 :         case GF_PIXEL_YUYV:
     741             :         case GF_PIXEL_YVYU:
     742             :         case GF_PIXEL_UYVY:
     743             :         case GF_PIXEL_VYUY:
     744         124 :                 surf->yuv_type = EVG_YUV;
     745         124 :                 if (use_const && !for_3d) {
     746          64 :                         if (a!=0xFF) {
     747           8 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuyv_fill_const_a;
     748             :                         } else {
     749          56 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuyv_fill_const;
     750             :                         }
     751          64 :                         uv_alpha_size = 2*surf->width;
     752             :                 } else {
     753          60 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuyv_fill_var;
     754          60 :                         uv_alpha_size = 2 * 3*surf->width;
     755             :                 }
     756             :                 break;
     757             : 
     758          39 :         case GF_PIXEL_YUV_10:
     759          39 :                 surf->yuv_type = EVG_YUV;
     760          39 :                 if (use_const && !for_3d) {
     761          16 :                         surf->yuv_flush_uv = evg_yuv420p_10_flush_uv_const;
     762             : 
     763          16 :                         if (a!=0xFF) {
     764           2 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_const_a;
     765             :                         } else {
     766          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_const;
     767             :                         }
     768          16 :                         uv_alpha_size = 4*surf->width;
     769             :                 } else {
     770          23 :                         surf->yuv_flush_uv = evg_yuv420p_10_flush_uv_var;
     771          23 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_var;
     772          23 :                         uv_alpha_size = 4*3*surf->width;
     773             :                 }
     774             :                 break;
     775          31 :         case GF_PIXEL_NV21_10:
     776          31 :                 surf->swap_uv = GF_TRUE;
     777          62 :         case GF_PIXEL_NV12_10:
     778          62 :                 surf->yuv_type = EVG_YUV;
     779             : 
     780          62 :                 if (surf->swap_uv) {
     781          31 :                         surf->idx_u = 1;
     782          31 :                         surf->idx_v = 0;
     783             :                 } else {
     784          31 :                         surf->idx_u = 0;
     785          31 :                         surf->idx_v = 1;
     786             :                 }
     787             : 
     788          62 :                 if (use_const && !for_3d) {
     789          32 :                         surf->yuv_flush_uv = evg_nv12_10_flush_uv_const;
     790             : 
     791          32 :                         if (a!=0xFF) {
     792           4 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_const_a;
     793             :                         } else {
     794          28 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_const;
     795             :                         }
     796          32 :                         uv_alpha_size = 4*surf->width;
     797             :                 } else {
     798          30 :                         surf->yuv_flush_uv = evg_nv12_10_flush_uv_var;
     799          30 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_var;
     800          30 :                         uv_alpha_size = 4 * 3*surf->width;
     801             :                 }
     802             :                 break;
     803          31 :         case GF_PIXEL_YUV422_10:
     804          31 :                 surf->yuv_type = EVG_YUV;
     805          31 :                 surf->is_422 = GF_TRUE;
     806          31 :                 if (use_const && !for_3d) {
     807          16 :                         surf->yuv_flush_uv = evg_yuv422p_10_flush_uv_const;
     808             : 
     809          16 :                         if (a!=0xFF) {
     810           2 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_const_a;
     811             :                         } else {
     812          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_const;
     813             :                         }
     814          16 :                         uv_alpha_size = 4*surf->width;
     815             :                 } else {
     816          15 :                         surf->yuv_flush_uv = evg_yuv422p_10_flush_uv_var;
     817          15 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv420p_10_fill_var;
     818          15 :                         uv_alpha_size = 4 * 3*surf->width;
     819             :                 }
     820             :                 break;
     821          31 :         case GF_PIXEL_YUV444_10:
     822          31 :                 surf->yuv_type = EVG_YUV_444;
     823          31 :                 if (use_const) {
     824          16 :                         if (a!=0xFF) {
     825           2 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv444p_10_fill_const_a;
     826             :                         } else {
     827          14 :                                 surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv444p_10_fill_const;
     828             :                         }
     829             :                 } else {
     830          15 :                         surf->gray_spans = (EVG_Raster_Span_Func) evg_yuv444p_10_fill_var;
     831             :                 }
     832             :                 break;
     833             :         default:
     834             :                 return GF_FALSE;
     835             :         }
     836             : 
     837        1739 :         if (uv_alpha_size) {
     838        1739 :                 if (surf->uv_alpha_alloc < uv_alpha_size) {
     839          93 :                         surf->uv_alpha_alloc = uv_alpha_size;
     840          93 :                         surf->uv_alpha = gf_realloc(surf->uv_alpha, uv_alpha_size);
     841             :                         memset(surf->uv_alpha, 0, uv_alpha_size);
     842             :                 }
     843        1739 :                 memset(surf->uv_alpha, 0, sizeof(char)*surf->uv_alpha_alloc);
     844             :         }
     845      228322 :         if (surf->yuv_type && for_3d)
     846         101 :                 surf->sten = &surf->ext3d->yuv_sten;
     847             : 
     848      228322 :         if (use_const && surf->yuv_type) {
     849             :                 u8 y, cb, cr;
     850        1410 :                 gf_evg_rgb_to_yuv(surf, surf->fill_col, &y, &cb, &cr);
     851        1410 :                 if (surf->swap_uv) {
     852          32 :                         u8 t = cb;
     853          32 :                         cb = cr;
     854          32 :                         cr = (u8) t;
     855          32 :                         surf->swap_uv = GF_FALSE;
     856             :                 }
     857             : 
     858        1410 :                 surf->fill_col = GF_COL_ARGB(a, y, cb, cr);
     859        1410 :                 surf->fill_col_wide = evg_col_to_wide(surf->fill_col);
     860             :         }
     861             : 
     862             :         return GF_TRUE;
     863             : }
     864             : 
     865             : 
     866             : GF_EXPORT
     867     1338140 : GF_Err gf_evg_surface_set_path(GF_EVGSurface *surf, GF_Path *gp)
     868             : {
     869     1338140 :         if (!surf) return GF_BAD_PARAM;
     870     1338140 :         if (!gp || !gp->n_points) {
     871      728226 :                 surf->ftoutline.n_points = 0;
     872      728226 :                 surf->ftoutline.n_contours = 0;
     873      728226 :                 return GF_OK;
     874             :         }
     875      609914 :         gf_path_flatten(gp);
     876      609914 :         surf->ftoutline.n_points = gp->n_points;
     877      609914 :         surf->ftoutline.n_contours = gp->n_contours;
     878             : 
     879      609914 :         surf->ftoutline.tags = gp->tags;
     880      609914 :         surf->ftoutline.contours = (s32*) gp->contours;
     881             : 
     882             :         /*store path bounds for gradient/textures*/
     883      609914 :         gf_path_get_bounds(gp, &surf->path_bounds);
     884             :         /*invert Y (ft uses min Y)*/
     885      609914 :         surf->path_bounds.y -= surf->path_bounds.height;
     886             : 
     887      609914 :         surf->ftoutline.flags = 0;
     888      609914 :         if (gp->flags & GF_PATH_FILL_ZERO_NONZERO) surf->ftoutline.flags = GF_PATH_FILL_ZERO_NONZERO;
     889             : 
     890      609914 :         surf->ftoutline.n_points = gp->n_points;
     891      609914 :         surf->ftoutline.points = gp->points;
     892      609914 :         surf->mx = &surf->mat;
     893      609914 :         return GF_OK;
     894             : }
     895             : 
     896             : /* static void gray_spans_stub(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf){} */
     897             : 
     898             : GF_EXPORT
     899      255933 : GF_Err gf_evg_surface_fill(GF_EVGSurface *surf, GF_EVGStencil *sten)
     900             : {
     901             :         GF_Err e;
     902             :         GF_Rect rc;
     903             :         u32 max_gray;
     904             :         GF_Matrix2D mat, st_mat;
     905             :         Bool restore_filter;
     906      255933 :         if (!surf || !sten) return GF_BAD_PARAM;
     907      255933 :         if (!surf->ftoutline.n_points) return GF_OK;
     908      227996 :         surf->sten = sten;
     909             : 
     910             :         /*setup ft raster calllbacks*/
     911      227996 :         if (!setup_grey_callback(surf, GF_FALSE)) return GF_OK;
     912             : 
     913             :         /*      surf->gray_spans = gray_spans_stub; */
     914             : 
     915             :         /*TODO, check matrix with 3D transform*/
     916             : 
     917      227996 :         get_surface_world_matrix(surf, &mat);
     918             :         restore_filter = GF_FALSE;
     919             :         /*get path frame for texture convertion */
     920      227996 :         if (sten->type != GF_STENCIL_SOLID) {
     921       12841 :                 rc = surf->path_bounds;
     922       12841 :                 gf_mx2d_apply_rect(&mat, &rc);
     923       12841 :                 rc.x = rc.y = 0;
     924             :                 /*assign target frame and matrix*/
     925       12841 :                 sten->frame = rc;
     926       12841 :                 gf_mx2d_copy(sten->pmat, surf->mat);
     927       12841 :                 gf_mx2d_inverse(&sten->pmat);
     928             : 
     929       12841 :                 gf_mx2d_copy(st_mat, sten->smat);
     930       12841 :                 gf_mx2d_init(sten->smat);
     931             : 
     932       12841 :                 switch (sten->type) {
     933        4728 :                 case GF_STENCIL_TEXTURE:
     934        4728 :                         if ( ((EVG_Texture *)sten)->tx_callback) {
     935             : 
     936             :                         } else {
     937        4626 :                                 if (! ((EVG_Texture *)sten)->pixels) return GF_BAD_PARAM;
     938             :                         }
     939             : 
     940        4728 :                         if (((EVG_Texture *)sten)->mod & GF_TEXTURE_FLIP_Y) {
     941           0 :                                 if (!surf->center_coords) gf_mx2d_add_scale(&sten->smat, FIX_ONE, -FIX_ONE);
     942             :                         } else {
     943        4728 :                                 if (surf->center_coords) gf_mx2d_add_scale(&sten->smat, FIX_ONE, -FIX_ONE);
     944             :                         }
     945        4728 :                         gf_mx2d_add_matrix(&sten->smat, &st_mat);
     946        4728 :                         gf_mx2d_add_matrix(&sten->smat, &mat);
     947        4728 :                         gf_mx2d_inverse(&sten->smat);
     948             : 
     949        4728 :                         evg_texture_init(sten, surf);
     950        4728 :                         if (((EVG_Texture *)sten)->filter == GF_TEXTURE_FILTER_DEFAULT) {
     951             :                                 restore_filter = GF_TRUE;
     952        4728 :                                 ((EVG_Texture *)sten)->filter = surf->texture_filter;
     953             :                         }
     954             : 
     955             :                         break;
     956        1785 :                 case GF_STENCIL_LINEAR_GRADIENT:
     957             :                 {
     958             :                         EVG_LinearGradient *lin = (EVG_LinearGradient *)sten;
     959        1785 :                         gf_mx2d_add_matrix(&sten->smat, &st_mat);
     960        1785 :                         gf_mx2d_add_matrix(&sten->smat, &mat);
     961        1785 :                         gf_mx2d_inverse(&sten->smat);
     962             :                         /*and finalize matrix in gradient coord system*/
     963        1785 :                         gf_mx2d_add_matrix(&sten->smat, &lin->vecmat);
     964        1785 :                         gf_mx2d_add_scale(&sten->smat, INT2FIX(1<<EVGGRADIENTBITS), INT2FIX(1<<EVGGRADIENTBITS));
     965             : 
     966             :                         /*init*/
     967        1785 :                         evg_gradient_precompute((EVG_BaseGradient *)lin, surf);
     968             : 
     969             :                 }
     970        1785 :                 break;
     971        6328 :                 case GF_STENCIL_RADIAL_GRADIENT:
     972             :                 {
     973             :                         EVG_RadialGradient *rad = (EVG_RadialGradient*)sten;
     974             :                         gf_mx2d_copy(sten->smat, st_mat);
     975        6328 :                         gf_mx2d_add_matrix(&sten->smat, &mat);
     976        6328 :                         gf_mx2d_inverse(&sten->smat);
     977        6328 :                         gf_mx2d_add_translation(&sten->smat, -rad->center.x, -rad->center.y);
     978        6328 :                         gf_mx2d_add_scale(&sten->smat, gf_invfix(rad->radius.x), gf_invfix(rad->radius.y));
     979             : 
     980        6328 :                         rad->d_f.x = gf_divfix(rad->focus.x - rad->center.x, rad->radius.x);
     981        6328 :                         rad->d_f.y = gf_divfix(rad->focus.y - rad->center.y, rad->radius.y);
     982             :                         /*init*/
     983        6328 :                         evg_radial_init(rad);
     984        6328 :                         evg_gradient_precompute((EVG_BaseGradient *)rad, surf);
     985             :                 }
     986        6328 :                 break;
     987             :                 }
     988             :         }
     989      227996 :         max_gray = surf->raster->max_gray_spans;
     990             :         /*force complete line callback for YUV 420/422*/
     991      227996 :         if (surf->yuv_type==EVG_YUV)
     992        1638 :                 surf->raster->max_gray_spans = 0xFFFFFFFF;
     993             : 
     994      227996 :         if (surf->useClipper) {
     995      226608 :                 surf->clip_xMin = surf->clipper.x;
     996      226608 :                 surf->clip_yMin = surf->clipper.y;
     997      226608 :                 surf->clip_xMax = (surf->clipper.x + surf->clipper.width);
     998      226608 :                 surf->clip_yMax = (surf->clipper.y + surf->clipper.height);
     999             :         } else {
    1000        1388 :                 surf->clip_xMin = 0;
    1001        1388 :                 surf->clip_yMin = 0;
    1002        1388 :                 surf->clip_xMax = (surf->width);
    1003        1388 :                 surf->clip_yMax = (surf->height);
    1004             :         }
    1005             : 
    1006             :         /*and call the raster*/
    1007      227996 :         if (surf->is_3d_matrix)
    1008           1 :                 e = evg_raster_render_path_3d(surf);
    1009             :         else
    1010      227995 :                 e = evg_raster_render(surf);
    1011             : 
    1012      227996 :         surf->raster->max_gray_spans = max_gray;
    1013             : 
    1014             :         /*restore stencil matrix*/
    1015      227996 :         if (sten->type != GF_STENCIL_SOLID) {
    1016       12841 :                 gf_mx2d_copy(sten->smat, st_mat);
    1017       12841 :                 if (restore_filter) ((EVG_Texture *)sten)->filter = GF_TEXTURE_FILTER_DEFAULT;
    1018             :         }
    1019      227996 :         surf->sten = 0L;
    1020      227996 :         return e;
    1021             : }
    1022             : 
    1023             : 
    1024             : 
    1025           1 : void gf_evg_surface_set_composite_mode(GF_EVGSurface *surf, GF_EVGCompositeMode comp_mode)
    1026             : {
    1027           1 :         if (surf) surf->comp_mode = comp_mode;
    1028           1 : }
    1029             : 
    1030         101 : void gf_evg_surface_set_alpha_callback(GF_EVGSurface *surf, u8 (*get_alpha)(void *udta, u8 src_alpha, s32 x, s32 y), void *cbk)
    1031             : {
    1032         101 :         if (surf) {
    1033         101 :                 surf->get_alpha = get_alpha;
    1034         101 :                 surf->get_alpha_udta = cbk;
    1035             :         }
    1036         101 : }
    1037             : 
    1038         201 : GF_Err gf_evg_surface_set_projection(GF_EVGSurface *surf, GF_Matrix *mx)
    1039             : {
    1040         201 :         if (!surf || !surf->ext3d) return GF_BAD_PARAM;
    1041         201 :         gf_mx_copy(surf->ext3d->proj, *mx);
    1042         201 :         return GF_OK;
    1043             : }
    1044         201 : GF_Err gf_evg_surface_set_modelview(GF_EVGSurface *surf, GF_Matrix *mx)
    1045             : {
    1046         201 :         if (!surf || !surf->ext3d) return GF_BAD_PARAM;
    1047         201 :         gf_mx_copy(surf->ext3d->modelview, *mx);
    1048         201 :         return GF_OK;
    1049             : }
    1050             : 
    1051             : GF_Err evg_raster_render3d(GF_EVGSurface *surf, u32 *indices, u32 nb_idx, Float *vertices, u32 nb_vertices, u32 nb_comp, GF_EVGPrimitiveType prim_type);
    1052             : 
    1053         226 : GF_Err gf_evg_surface_draw_array(GF_EVGSurface *surf, u32 *indices, u32 nb_idx, Float *vertices, u32 nb_vertices, u32 nb_comp, GF_EVGPrimitiveType prim_type)
    1054             : {
    1055             :         GF_Err e;
    1056             :         u32 max_gray;
    1057         226 :         if (!surf || !surf->ext3d) return GF_BAD_PARAM;
    1058             : 
    1059             :         /*setup ft raster calllbacks*/
    1060         226 :         if (!setup_grey_callback(surf, GF_TRUE)) return GF_OK;
    1061             : 
    1062         226 :         if (surf->useClipper) {
    1063           0 :                 surf->clip_xMin = surf->clipper.x;
    1064           0 :                 surf->clip_yMin = surf->clipper.y;
    1065           0 :                 surf->clip_xMax = (surf->clipper.x + surf->clipper.width);
    1066           0 :                 surf->clip_yMax = (surf->clipper.y + surf->clipper.height);
    1067             :         } else {
    1068         226 :                 surf->clip_xMin = 0;
    1069         226 :                 surf->clip_yMin = 0;
    1070         226 :                 surf->clip_xMax = (surf->width);
    1071         226 :                 surf->clip_yMax = (surf->height);
    1072             :         }
    1073         226 :         max_gray = surf->raster->max_gray_spans;
    1074             :         /*force complete line callback for YUV 420/422*/
    1075         226 :         if (surf->yuv_type==EVG_YUV)
    1076         101 :                 surf->raster->max_gray_spans = 0xFFFFFFFF;
    1077             : 
    1078             :         /*and call the raster*/
    1079         226 :         e = evg_raster_render3d(surf, indices, nb_idx, vertices, nb_vertices, nb_comp, prim_type);
    1080         226 :         surf->raster->max_gray_spans =  max_gray;
    1081         226 :         return e;
    1082             : }
    1083             : 
    1084             : GF_Err evg_raster_render3d_path(GF_EVGSurface *surf, GF_Path *path, Float z);
    1085             : 
    1086         100 : GF_Err gf_evg_surface_draw_path(GF_EVGSurface *surf, GF_Path *path, Float z)
    1087             : {
    1088             :         GF_Err e;
    1089             :         u32 max_gray;
    1090         100 :         if (!surf || !surf->ext3d) return GF_BAD_PARAM;
    1091             : 
    1092             :         /*setup ft raster calllbacks*/
    1093         100 :         if (!setup_grey_callback(surf, GF_TRUE)) return GF_OK;
    1094             : 
    1095         100 :         if (surf->useClipper) {
    1096           0 :                 surf->clip_xMin = surf->clipper.x;
    1097           0 :                 surf->clip_yMin = surf->clipper.y;
    1098           0 :                 surf->clip_xMax = (surf->clipper.x + surf->clipper.width);
    1099           0 :                 surf->clip_yMax = (surf->clipper.y + surf->clipper.height);
    1100             :         } else {
    1101         100 :                 surf->clip_xMin = 0;
    1102         100 :                 surf->clip_yMin = 0;
    1103         100 :                 surf->clip_xMax = (surf->width);
    1104         100 :                 surf->clip_yMax = (surf->height);
    1105             :         }
    1106         100 :         max_gray = surf->raster->max_gray_spans;
    1107             :         /*force complete line callback for YUV 420/422*/
    1108         100 :         if (surf->yuv_type==EVG_YUV)
    1109           0 :                 surf->raster->max_gray_spans = 0xFFFFFFFF;
    1110             : 
    1111             :         /*and call the raster*/
    1112         100 :         e = evg_raster_render3d_path(surf, path, z);
    1113         100 :         surf->raster->max_gray_spans =  max_gray;
    1114         100 :         return e;
    1115             : }

Generated by: LCOV version 1.13