Exemplo n.º 1
0
/* ----------------------------------------------------
 * p_get_ffetch_gva_frames_to_keep_cached
 * ----------------------------------------------------
 */
static gint32
p_get_ffetch_gva_frames_to_keep_cached()
{
  static gint32 value = -1;
  static char *gimprc_key = GAP_FFETCH_GVA_FRAMES_TO_KEEP_CACHED_GIMPRC_KEY;
  
  if(value == -1)
  {
    if(gap_debug)
    {
      printf("get gimprc value for %s\n"
        , gimprc_key
        );
    }
    value = gap_base_get_gimprc_int_value (gimprc_key
        , GAP_FFETCH_GVA_FRAMES_TO_KEEP_CACHED /* default_value*/
        , 1                                 /* min_value */
        , 1000                              /* max_value */
        );
  }
  if(gap_debug)
  {
    printf("value for %s is:%d\n"
        , gimprc_key
        ,(int)value
        );
  }
  return (value);
}  /* end p_get_ffetch_gva_frames_to_keep_cached */
Exemplo n.º 2
0
/* ----------------------------------------------------
 * p_get_ffetch_max_gvc_cache_elements
 * ----------------------------------------------------
 */
static gint32
p_get_ffetch_max_gvc_cache_elements()
{
  static gint32 value = -1;
  static char *gimprc_key = GAP_FFETCH_MAX_GVC_CACHE_ELEMENTS_GIMPRC_KEY;
  
  if(value == -1)
  {
    if(gap_debug)
    {
      printf("get gimprc value for %s\n"
        , gimprc_key
        );
    }
    value = gap_base_get_gimprc_int_value (gimprc_key
        , GAP_FFETCH_MAX_GVC_CACHE_ELEMENTS /* default_value*/
        , 1                                 /* min_value */
        , 80                              /* max_value */
        );
  }
  if(gap_debug)
  {
    printf("value for %s is:%d\n"
        , gimprc_key
        ,(int)value
        );
  }
  return (value);
}  /* end p_get_ffetch_max_gvc_cache_elements */
Exemplo n.º 3
0
/* ---------------------------------
 * gap_base_get_numProcessors
 * ---------------------------------
 * get number of available processors.
 * This implementation uses the gimprc parameter of the gimp core application.
 * Therefore the returned number does not reflect hardware information, but
 * reprents the number of processors that are configured to be used by th gimp.
 */
gint
gap_base_get_numProcessors()
{
  gint      numProcessors;

  numProcessors = gap_base_get_gimprc_int_value("num-processors"
                               , 1  /* default */
                               , 1  /* min */
                               , 32 /* max */
                               );
  return (numProcessors);
}
Exemplo n.º 4
0
/* ----------------------------------------------------
 * GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer
 * ----------------------------------------------------
 * copy (or deinterlaced copy) the specified srcFrameData into the specified
 * rgbBuffer.
 * in case the specified numProcessors > 1 this procedure uses a thread pool
 * to spread the work to the given number of processors.
 *
 * calling this procedure with rgbBuffer == NULL triggers logging
 * of captured runtime statistic values per thread
 * (in case gimp-gap was comiled with runtime recording configuration)
 * (this is a debug feature for development and analyse purpose only)
 */
void
GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer(GVA_RgbPixelBuffer *rgbBuffer
                                                , guchar *srcFrameData
                                                , gint32 numProcessors)
{
  static GapMultiPocessorCopyOrDelaceData  memcpdArray[GVA_MAX_MEMCPD_THREADS];

  static GThreadPool  *threadPool = NULL;
  static gulong        usleepTime = 10;
  static gint          numThreadsMax         = 1;
  gboolean             isMultithreadEnabled;
  gint                 numThreads;
  gint                 colsPerCpu;
  gint                 rowsPerCpu;
  gint                 retry;
  gint                 startCol;
  gint                 colWidth;
  gint                 startRow;
  gint                 rowHeight;
  gint                 ii;
  GapMultiPocessorCopyOrDelaceData *memcpd;
  GError *error;

  static gint32 funcId = -1;
  static gint32 funcIdPush = -1;
  static gint32 funcIdSingle = -1;
  static gint32 funcIdMainWait = -1;

  GAP_TIMM_GET_FUNCTION_ID(funcId, "GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer");
  GAP_TIMM_GET_FUNCTION_ID(funcIdPush, "GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer.pushToReActivateThreads");
  GAP_TIMM_GET_FUNCTION_ID(funcIdSingle, "GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer.singlecall");
  GAP_TIMM_GET_FUNCTION_ID(funcIdMainWait, "GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer.main (Wait)");

  error = NULL;
  ii = 0;

  if(gap_debug)
  {
    printf("GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer START numProcessors:%d\n"
      ,(int)numProcessors
      );
  }
  
  /* rgbBuffer NULL pointer triggers a debug feature that logs the recorded runtime statistics to stdout.
   * (but only in gimp-gap was configured for runtime recording at compiletime)
   */
  if(rgbBuffer == NULL)
  {
    for(ii=0; ii < numThreadsMax; ii++)
    {
      GapMultiPocessorCopyOrDelaceData *memcpd;
      memcpd = &memcpdArray[ii];
      
      GAP_TIMM_PRINT_RECORD(&memcpd->memcpyStats,   "... Thrd GVA_fcache_to_drawable_multithread.memcpyStats");
      GAP_TIMM_PRINT_RECORD(&memcpd->delaceStats, "... Thrd GVA_fcache_to_drawable_multithread.delaceStats");
    }
    
    return;
  }
   

  GAP_TIMM_START_FUNCTION(funcId);

  numThreads = MIN(numProcessors, GVA_MAX_MEMCPD_THREADS);
  numThreadsMax = MAX(numThreadsMax, numThreads);
  
  colsPerCpu = (rgbBuffer->width + (numThreads -1)) / numThreads;
  rowsPerCpu = (rgbBuffer->height + (numThreads -1)) / numThreads;

  /* check and init thread system */
  if(numThreads > 1)
  {
    isMultithreadEnabled = gap_base_thread_init();
  }
  else
  {
    isMultithreadEnabled = FALSE;
  }
  
  if((isMultithreadEnabled != TRUE)
  || (colsPerCpu < 16)
  || (rowsPerCpu < 16))
  {
    GAP_TIMM_START_FUNCTION(funcIdSingle);
    /* singleproceesor variant calls the worker thread once with setup
     * to process full buffer in one synchron call
     * (no locks are set in this case and no condition will be sent)
     */
    memcpd = &memcpdArray[0];
    memcpd->src_data = srcFrameData;
    memcpd->rgbBuffer = rgbBuffer;
    
    memcpd->startCol        = 0;
    memcpd->colWidth        = rgbBuffer->width;
    memcpd->memRow          = 0;
    memcpd->memHeightInRows = rgbBuffer->height;
    memcpd->cpuId = ii;
    memcpd->isFinished = FALSE;
    
    p_memcpy_or_delace_WorkerThreadFunction(memcpd);
    
    GAP_TIMM_STOP_FUNCTION(funcIdSingle);
    GAP_TIMM_STOP_FUNCTION(funcId);
    return;
  }


    
  if (threadPool == NULL)
  {
    usleepTime = gap_base_get_gimprc_int_value("video-api-mp-copy-or-delace-usleep"
                  , 10
                  , 1
                  , 10000);
    
    /* init the treadPool at first multiprocessing call
     * (and keep the threads until end of main process..)
     */
    threadPool = g_thread_pool_new((GFunc) p_memcpy_or_delace_WorkerThreadFunction
                                         ,NULL        /* user data */
                                         ,GVA_MAX_MEMCPD_THREADS          /* max_threads */
                                         ,TRUE        /* exclusive */
                                         ,&error      /* GError **error */
                                         );

    for(ii=0; ii < GVA_MAX_MEMCPD_THREADS; ii++)
    {
      GapMultiPocessorCopyOrDelaceData *memcpd;
      memcpd = &memcpdArray[ii];
      
      GAP_TIMM_INIT_RECORD(&memcpd->memcpyStats);
      GAP_TIMM_INIT_RECORD(&memcpd->delaceStats);
    }
  }

  
  if(gap_debug)
  {
    printf("GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer size:%d x %d numThreads:%d colsPerCpu:%d rowsPerCpu:%d\n"
      ,(int)rgbBuffer->width
      ,(int)rgbBuffer->height
      ,(int)numThreads
      ,(int)colsPerCpu
      ,(int)rowsPerCpu
      );
  }

  startCol = 0;
  startRow = 0;
  colWidth = colsPerCpu;
  rowHeight = rowsPerCpu;
  

  GAP_TIMM_START_FUNCTION(funcIdPush);
 
  /* build work packet-stripes and re-start one thread per stripe */
  for(ii=0; ii < numThreads; ii++)
  {
    GapMultiPocessorCopyOrDelaceData *memcpd;

    if(gap_debug)
    {
      printf("GVA_copy_or_deinterlace.. Cpu[%d] startCol:%d colWidth:%d startRow:%d rowHeight:%d delace:%d\n"
        ,(int)ii
        ,(int)startCol
        ,(int)colWidth
        ,(int)startRow
        ,(int)rowHeight
        ,(int)rgbBuffer->deinterlace
        );
    }
    
    memcpd = &memcpdArray[ii];
    memcpd->src_data = srcFrameData;
    memcpd->rgbBuffer = rgbBuffer;
    
    memcpd->startCol        = startCol;
    memcpd->colWidth        = colWidth;
    memcpd->memRow          = startRow;
    memcpd->memHeightInRows = rowHeight;
    memcpd->cpuId = ii;
    memcpd->isFinished = FALSE;
    
    /* (re)activate next thread */
    g_thread_pool_push (threadPool
                       , memcpd    /* user Data for the worker thread*/
                       , &error
                       );
    startCol += colsPerCpu;
    if((startCol + colsPerCpu) >  rgbBuffer->width)
    {
      /* the last thread handles a vertical stripe with the remaining columns
       */
      colWidth = rgbBuffer->width - startCol;
    }
    startRow += rowsPerCpu;
    if((startRow + rowsPerCpu) >  rgbBuffer->height)
    {
      /* the last thread handles a horizontal stripe with the remaining rows
       */
      colWidth = rgbBuffer->height - startRow;
    }
  }

  GAP_TIMM_STOP_FUNCTION(funcIdPush);


  /* now wait until all worker threads have finished thier tasks */
  retry = 0;
  while(TRUE)
  {
    gboolean isAllWorkDone;

    if(gap_debug)
    {
      printf("GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer: WAIT retry :%d\n"
        ,(int)retry
        );
    }
  
    GAP_TIMM_START_FUNCTION(funcIdMainWait);

    /* sleep a very short time before next check
     * Note that longer sleep leaves more cpu resources for the prallel running threads
     * but increases the raster for overall performance time.
     * varaints using a mutex and wakeup cond did not perform better than this,
     * because the parallel running threads had additonal mutex locking overhead
     * (that is not necessary here where each tread operates on its own memory range
     * of the frame data)
     */
    g_usleep(usleepTime);
    
    GAP_TIMM_STOP_FUNCTION(funcIdMainWait);

    if(gap_debug)
    {
      printf("GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer: WAKE-UP retry :%d\n"
        , (int)retry
        );
    }


    /* assume all threads finished work (this may already be the case after the first retry) */
    isAllWorkDone = TRUE;
    
    for(ii=0; ii < numThreads; ii++)
    {
      memcpd = &memcpdArray[ii];
      if(gap_debug)
      {
        printf("GVA_fcache_to_drawable_multithread: STATUS Cpu[%d] retry :%d  isFinished:%d\n"
          ,(int)ii
          ,(int)retry
          ,(int)memcpd->isFinished
          );
      }
      if(memcpd->isFinished != TRUE)
      {
        isAllWorkDone = FALSE;
        break;
      }
    }

    if(isAllWorkDone == TRUE)
    {
      break;
    }

    retry++;
  }

  GAP_TIMM_STOP_FUNCTION(funcId);

  if(gap_debug)
  {
    printf("GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer: DONE retry :%d\n"
        , (int)retry
        );
  }
  
}  /* end GVA_copy_or_deinterlace_fcache_data_to_rgbBuffer */
Exemplo n.º 5
0
/* ------------------------------------------
 * gap_detail_exact_align_via_4point_path
 * ------------------------------------------
 *
 */
gint32
gap_detail_exact_align_via_4point_path(gint32 image_id, gint32 activeDrawableId
   , gint32 pointOrder, GimpRunMode runMode)
{
  AlingCoords  alingCoordinates;
  AlingCoords *alingCoords;
  gint         countVaildPoints;
  gint32       ret;
  AlignDialogVals         advals;
  
  alingCoords = &alingCoordinates;
  ret = -1;
  

  advals.runExactAlign = TRUE;
  advals.image_id = image_id;
  advals.activeDrawableId = activeDrawableId;

  if (runMode == GIMP_RUN_NONINTERACTIVE)
  {
    advals.pointOrder = pointOrder;
  }
  else
  {
    /* get last used value (or default) 
     * from gimprc settings
     */
    advals.pointOrder = gap_base_get_gimprc_int_value(GIMPRC_EXACT_ALIGN_PATH_POINT_ORDER
                                                    , POINT_ORDER_MODE_31_42 /* DEFAULT */
                                                    , POINT_ORDER_MODE_31_42 /* min */
                                                    , POINT_ORDER_MODE_21_43 /* max */
                                                    );
  }

  
  if (runMode == GIMP_RUN_INTERACTIVE)
  {
    p_align_dialog(&advals);
  }
  
  if (advals.runExactAlign != TRUE)
  {
    return (ret);
  }

  if (runMode == GIMP_RUN_INTERACTIVE)
  {
    /* store order flag when entered via userdialog
     * in gimprc (for next use in same or later gimp session)
     */
    p_save_gimprc_gint32_value(GIMPRC_EXACT_ALIGN_PATH_POINT_ORDER, advals.pointOrder);
  }
  
 
  gimp_image_undo_group_start (image_id);
  
  countVaildPoints = p_capture_4_vector_points(image_id, alingCoords, advals.pointOrder);
  if(countVaildPoints == 4)
  {
    ret = p_exact_align_drawable(activeDrawableId, alingCoords);

  }
  else if(countVaildPoints == 2)
  {
    /* force order 0213 
     *  (captures the 2 valid points into startCoords and currCoords)
     */
    countVaildPoints = p_capture_4_vector_points(image_id, alingCoords, POINT_ORDER_MODE_21_43);
    ret = p_set_drawable_offsets(activeDrawableId, alingCoords);
  }
  else
  {
    if (advals.pointOrder == POINT_ORDER_MODE_31_42)
    {
      g_message(_("This filter requires a current path with 4 points, "
                "where point 1 and 2 mark reference positions "
                "and point 3 and 4 mark positions in the target layer."
                "It transforms the target layer in a way that "
                "point3 is moved to point1 and point4 moves to point2."
                "(this may include rotate and scale transformation).\n"
                "A path with 2 points can be used to move point2 to point1."
                "(via simple move operation without rotate and scale)"));
    }
    else
    {
      g_message(_("This filter requires a current path with 4 points, "
                "where point 1 and 3 mark reference positions "
                "and point 2 and 4 mark positions in the target layer."
                "It transforms the target layer in a way that "
                "point2 is moved to point1 and point4 moves to point3."
                "(this may include rotate and scale transformation).\n"
                "A path with 2 points can be used to move point2 to point1."
                "(via simple move operation without rotate and scale)"));
    }
  }
 
  gimp_image_undo_group_end (image_id);
  
  return(ret);
  
  
}  /* end  gap_detail_exact_align_via_4point_path */