Revision: 17442 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17442 Author: campbellbarton Date: 2008-11-13 14:17:04 +0100 (Thu, 13 Nov 2008)
Log Message: ----------- simple workaround slowdown with painting onto multiple parts of an image at once, just use a grid of boundboxes per image. was also running undo calls when it shouldnt, Modified Paths: -------------- branches/projection-paint/source/blender/src/imagepaint.c Modified: branches/projection-paint/source/blender/src/imagepaint.c =================================================================== --- branches/projection-paint/source/blender/src/imagepaint.c 2008-11-13 11:30:34 UTC (rev 17441) +++ branches/projection-paint/source/blender/src/imagepaint.c 2008-11-13 13:17:04 UTC (rev 17442) @@ -141,6 +141,8 @@ /* testing options */ #define PROJ_BUCKET_DIV 128 /* TODO - test other values, this is a guess, seems ok */ +#define PROJ_BOUNDBOX_DIV 6 /* TODO - test other values, this is a guess, seems ok */ +#define PROJ_BOUNDBOX_SQUARED (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV) //#define PROJ_DEBUG_PAINT 1 #define PROJ_DEBUG_NOSCANLINE 1 @@ -200,7 +202,7 @@ Image **projectImages; /* array of images we are painting onto while, use so we can tag for updates */ ImBuf **projectImBufs; /* array of imbufs we are painting onto while, use so we can get the rect and rect_float quickly */ - ImagePaintPartialRedraw *projectPartialRedraws; /* array of partial redraws */ + ImagePaintPartialRedraw *projectPartialRedraws[PROJ_BOUNDBOX_SQUARED]; /* array of partial redraws */ int projectImageTotal; /* size of projectImages array */ @@ -245,7 +247,7 @@ short x_px, y_px; void *pixel; short image_index; /* if anyone wants to paint onto more then 32000 images they can bite me */ - short flag; + short bb_cell_index; } ProjectPixel; typedef struct ProjectPixelClone { @@ -281,6 +283,19 @@ static UndoElem *curundo = NULL; static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0}; + +static int BLI_linklist_index(struct LinkNode *list, void *ptr) +{ + int index; + + for (index = 0; list; list= list->next, index++) { + if (list->link == ptr) + return index; + } + + return -1; +} + /* UNDO */ /* internal functions */ @@ -1333,6 +1348,12 @@ projPixel->x_px = x; projPixel->y_px = y; + /* which bounding box cell are we in? */ + //projPixel->x_bb = (char) ; + //projPixel->y_bb = (char) (((float)y/(float)ibuf->y) * PROJ_BOUNDBOX_DIV); + + projPixel->bb_cell_index = ((int)((((float)x)/((float)ibuf->x)) * PROJ_BOUNDBOX_DIV)) + ((int)((((float)y)/((float)ibuf->y)) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV ; + /* done with view3d_project_float inline */ if (ps->tool==PAINT_TOOL_CLONE) { float co[2]; @@ -2248,7 +2269,11 @@ /* build an array of images we use*/ ps->projectImages = BLI_memarena_alloc( ps->projectArena, sizeof(Image *) * ps->projectImageTotal); ps->projectImBufs = BLI_memarena_alloc( ps->projectArena, sizeof(ImBuf *) * ps->projectImageTotal); - ps->projectPartialRedraws = BLI_memarena_alloc( ps->projectArena, sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal); + *(ps->projectPartialRedraws) = BLI_memarena_alloc( ps->projectArena, sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal * PROJ_BOUNDBOX_SQUARED); + + for (a=1; a< ps->projectImageTotal; a++) { + ps->projectPartialRedraws[a] = *(ps->projectPartialRedraws) + (a * PROJ_BOUNDBOX_SQUARED); + } // calloced - memset(ps->projectPartialRedraws, 0, sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal); for (node= image_LinkList, i=0; node; node= node->next, i++) { @@ -2397,6 +2422,7 @@ if(texpaint || G.sima->lock) { int w = imapaintpartial.x2 - imapaintpartial.x1; int h = imapaintpartial.y2 - imapaintpartial.y1; + // printf("%d, %d, \n", w, h); GPU_paint_update_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h); } } @@ -2806,27 +2832,35 @@ /* Loop over all images on this mesh and update any we have touched */ static int imapaint_refresh_tagged(ProjectPaintState *ps) { - ImagePaintPartialRedraw *pr = ps->projectPartialRedraws; - int a; + ImagePaintPartialRedraw *pr; + int a,i; int redraw = 0; - - for (a=0; a < ps->projectImageTotal; a++, pr++) { + for (a=0; a < ps->projectImageTotal; a++) { Image *ima = ps->projectImages[a]; if (ima->id.flag & LIB_DOIT) { - if(U.uiflag & USER_GLOBALUNDO) { - // Dont need to set "imapaintpartial" This is updated from imapaint_dirty_region args. - imapaint_dirty_region(ima, ps->projectImBufs[a], pr->x1, pr->y1, pr->x2 - pr->x1, pr->y2 - pr->y1); - } else { - imapaintpartial = ps->projectPartialRedraws[a]; - + /* look over each bound cell */ + for (i=0; i<PROJ_BOUNDBOX_SQUARED; i++) { + pr = &(ps->projectPartialRedraws[a][i]); + if (pr->x2 != -1) { /* TODO - use 'enabled' ? */ + /* + if(U.uiflag & USER_GLOBALUNDO) { + // Dont need to set "imapaintpartial" This is updated from imapaint_dirty_region args. + imapaint_dirty_region(ima, ps->projectImBufs[a], pr->x1, pr->y1, pr->x2 - pr->x1, pr->y2 - pr->y1); + } else { + */ + imapaintpartial = *pr; + /* + } + */ + + imapaint_image_update(ima, ps->projectImBufs[a], 1 /*texpaint*/ ); + + redraw = 1; + } } - imapaint_image_update(ima, ps->projectImBufs[a], 1 /*texpaint*/ ); - - redraw = 1; - ima->id.flag &= ~LIB_DOIT; /* clear for reuse */ } } @@ -2901,7 +2935,7 @@ short mval[2], double time, float pressure, - ImagePaintPartialRedraw *projectPartialRedraws, + ImagePaintPartialRedraw *projectPartialRedraws[PROJ_BOUNDBOX_SQUARED], int thread_index) { LinkNode *node; @@ -2911,6 +2945,7 @@ int last_index = -1; ImagePaintPartialRedraw *last_partial_redraw; + ImagePaintPartialRedraw *last_partial_redraw_cell; float rgba[4], alpha, dist, dist_nosqrt; char rgba_ub[4]; @@ -2986,19 +3021,19 @@ if (last_index != projPixel->image_index) { last_index = projPixel->image_index; - last_partial_redraw = &projectPartialRedraws[last_index]; + last_partial_redraw = projectPartialRedraws[last_index]; ps->projectImages[last_index]->id.flag |= LIB_DOIT; /* halgrind complains this is not threadsafe but probably ok? - we are only setting this flag anyway */ is_floatbuf = ps->projectImBufs[last_index]->rect_float ? 1 : 0; } + last_partial_redraw_cell = last_partial_redraw + projPixel->bb_cell_index; + last_partial_redraw_cell->x1 = MIN2( last_partial_redraw_cell->x1, projPixel->x_px ); + last_partial_redraw_cell->y1 = MIN2( last_partial_redraw_cell->y1, projPixel->y_px ); - last_partial_redraw->x1 = MIN2( last_partial_redraw->x1, projPixel->x_px ); - last_partial_redraw->y1 = MIN2( last_partial_redraw->y1, projPixel->y_px ); + last_partial_redraw_cell->x2 = MAX2( last_partial_redraw_cell->x2, projPixel->x_px+1 ); + last_partial_redraw_cell->y2 = MAX2( last_partial_redraw_cell->y2, projPixel->y_px+1 ); - last_partial_redraw->x2 = MAX2( last_partial_redraw->x2, projPixel->x_px ); - last_partial_redraw->y2 = MAX2( last_partial_redraw->y2, projPixel->y_px ); - dist = (float)sqrt(dist_nosqrt); switch(ps->tool) { @@ -3128,7 +3163,7 @@ float pressure; /* annoying but we need to have image bounds per thread, then merge into ps->projectPartialRedraws */ - ImagePaintPartialRedraw *projectPartialRedraws; /* array of partial redraws */ + ImagePaintPartialRedraw *projectPartialRedraws[PROJ_BOUNDBOX_SQUARED]; /* array of partial redraws */ /* thread settings */ int thread_tot; @@ -3178,6 +3213,8 @@ /* get the threads running */ for(a=0; a < ps->thread_tot; a++) { + int i; + #ifdef PROJ_DEBUG_PRINT_THREADS printf("INIT THREAD %d\n", a); #endif @@ -3196,10 +3233,14 @@ handles[a].thread_index = a; handles[a].ready = 0; + *(handles[a].projectPartialRedraws) = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->projectArena, ps->projectImageTotal * sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); + /* image bounds */ - handles[a].projectPartialRedraws = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->projectArena, ps->projectImageTotal * sizeof(ImagePaintPartialRedraw)); + for (i=1; i< ps->projectImageTotal; i++) { + handles[a].projectPartialRedraws[i] = *(handles[a].projectPartialRedraws) + (i * PROJ_BOUNDBOX_SQUARED); + } - memcpy(handles[a].projectPartialRedraws, ps->projectPartialRedraws, ps->projectImageTotal * sizeof(ImagePaintPartialRedraw) ); + memcpy(*(handles[a].projectPartialRedraws), *(ps->projectPartialRedraws), ps->projectImageTotal * sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED ); BLI_insert_thread(&threads, &handles[a]); } @@ -3218,7 +3259,7 @@ /* move threaded bounds back into ps->projectPartialRedraws */ for(a=0; a < ps->thread_tot; a++) { - partial_redraw_array_merge(ps->projectPartialRedraws, handles[a].projectPartialRedraws, ps->projectImageTotal); + partial_redraw_array_merge(*(ps->projectPartialRedraws), *(handles[a].projectPartialRedraws), ps->projectImageTotal * PROJ_BOUNDBOX_SQUARED); } return imapaint_refresh_tagged(ps); @@ -3310,7 +3351,7 @@ { int redraw_flag = 0; - partial_redraw_array_init(ps->projectPartialRedraws, ps->projectImageTotal); + partial_redraw_array_init(*ps->projectPartialRedraws, ps->projectImageTotal * PROJ_BOUNDBOX_SQUARED); /* TODO - support more brush operations, airbrush etc */ if (ps->thread_tot > 1) { @@ -3534,7 +3575,7 @@ time= PIL_check_seconds_timer(); if (project) { /* Projection Painting */ - if ( ((s.brush->flag & BRUSH_AIRBRUSH) || init) || (cmp_brush_spacing(mval, prevmval, ps.brush->size/10.0 * ps.brush->spacing )) ) { + if ( ((s.brush->flag & BRUSH_AIRBRUSH) || init) || (cmp_brush_spacing(mval, prevmval, ps.brush->size/100.0 * ps.brush->spacing )) ) { imapaint_paint_stroke_project(&ps, painter, prevmval, mval, stroke_gp ? 0 : 1, time, pressure); prevmval[0]= mval[0]; prevmval[1]= mval[1]; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs