Index: source/blender/blenkernel/intern/colortools.c =================================================================== --- source/blender/blenkernel/intern/colortools.c (révision 28136) +++ source/blender/blenkernel/intern/colortools.c (copie de travail) @@ -935,6 +935,34 @@ } } +void scopes_update_buffers(Scopes *scopes, ImBuf *ibuf) +{ + int tot = scopes->waveform_tot; + if (scopes->ok == 1 ) return; + + /* convert to number of lines with logarithmic scale */ + scopes->sample_lines = (scopes->accuracy*0.01) * (scopes->accuracy*0.01) * ibuf->y; + if (scopes->sample_full) + scopes->sample_lines = ibuf->y; + + scopes->waveform_tot = ibuf->x*scopes->sample_lines; + if (tot != scopes->waveform_tot) { + if (scopes->waveform_1) + MEM_freeN(scopes->waveform_1); + if (scopes->waveform_2) + MEM_freeN(scopes->waveform_2); + if (scopes->waveform_3) + MEM_freeN(scopes->waveform_3); + if (scopes->vecscope) + MEM_freeN(scopes->vecscope); + + scopes->waveform_1= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1"); + scopes->waveform_2= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2"); + scopes->waveform_3= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3"); + scopes->vecscope= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel"); + } +} + void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) { int x, y, c, n, nl; @@ -943,13 +971,11 @@ unsigned char *rc; unsigned int *bin_r, *bin_g, *bin_b, *bin_lum; int savedlines, saveline; - float rgb[3], ycc[3]; + float rgb[3], ycc[3], minmax[3][2]; int ycc_mode; if (scopes->ok == 1 ) return; - if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f; - /* hmmmm */ if (!(ELEM(ibuf->channels, 3, 4))) return; scopes->hist.channels = 3; @@ -977,35 +1003,14 @@ bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins"); - /* convert to number of lines with logarithmic scale */ - scopes->sample_lines = (scopes->accuracy*0.01) * (scopes->accuracy*0.01) * ibuf->y; - - if (scopes->sample_full) - scopes->sample_lines = ibuf->y; /* scan the image */ savedlines=0; for (c=0; c<3; c++) { - scopes->minmax[c][0]=25500.0f; - scopes->minmax[c][1]=-25500.0f; + minmax[c][0]=25500.0f; + minmax[c][1]=-25500.0f; } - - scopes->waveform_tot = ibuf->x*scopes->sample_lines; - - if (scopes->waveform_1) - MEM_freeN(scopes->waveform_1); - if (scopes->waveform_2) - MEM_freeN(scopes->waveform_2); - if (scopes->waveform_3) - MEM_freeN(scopes->waveform_3); - if (scopes->vecscope) - MEM_freeN(scopes->vecscope); - - scopes->waveform_1= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1"); - scopes->waveform_2= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2"); - scopes->waveform_3= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3"); - scopes->vecscope= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel"); - + if (ibuf->rect_float) rf = ibuf->rect_float; else if (ibuf->rect) @@ -1030,16 +1035,16 @@ /* check for min max */ if(ycc_mode == -1 ) { for (c=0; c<3; c++) { - if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c]; - if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c]; + if (rgb[c] < minmax[c][0]) minmax[c][0] = rgb[c]; + if (rgb[c] > minmax[c][1]) minmax[c][1] = rgb[c]; } } else { rgb_to_ycc(rgb[0],rgb[1],rgb[2],&ycc[0],&ycc[1],&ycc[2], ycc_mode); for (c=0; c<3; c++) { ycc[c] *=INV_255; - if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c]; - if (ycc[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = ycc[c]; + if (ycc[c] < minmax[c][0]) minmax[c][0] = ycc[c]; + if (ycc[c] > minmax[c][1]) minmax[c][1] = ycc[c]; } } /* increment count for histo*/ @@ -1062,6 +1067,12 @@ savedlines +=1; } + /* set min max now to avoid flickering if redraw while update */ + for (c=0; c<3; c++) { + scopes->minmax[c][0] = minmax[c][0]; + scopes->minmax[c][1] = minmax[c][1]; + } + /* convert hist data to float (proportional to max count) */ n=0; nl=0; Index: source/blender/blenkernel/BKE_colortools.h =================================================================== --- source/blender/blenkernel/BKE_colortools.h (révision 28136) +++ source/blender/blenkernel/BKE_colortools.h (copie de travail) @@ -75,6 +75,7 @@ void colorcorrection_do_ibuf(struct ImBuf *ibuf, const char *profile); void scopes_update(struct Scopes *scopes, struct ImBuf *ibuf, int use_color_management); +void scopes_update_buffers(struct Scopes *scopes, struct ImBuf *ibuf); void scopes_free(struct Scopes *scopes); #endif Index: source/blender/editors/space_image/space_image.c =================================================================== --- source/blender/editors/space_image/space_image.c (révision 28136) +++ source/blender/editors/space_image/space_image.c (copie de travail) @@ -408,7 +408,9 @@ simage->scopes.wavefrm_alpha=0.3; simage->scopes.vecscope_alpha=0.3; simage->scopes.wavefrm_height= 100; + simage->scopes.vecscope_height= 150; simage->scopes.hist.height= 100; + simage->sample_line_hist.height=100; /* main area */ ar= MEM_callocN(sizeof(ARegion), "main area for image"); @@ -620,7 +622,8 @@ break; case NC_SPACE: if(wmn->data == ND_SPACE_IMAGE) { - image_scopes_tag_refresh(sa); + if(wmn->action != NA_EDITED) + image_scopes_tag_refresh(sa); ED_area_tag_redraw(sa); } break; @@ -830,6 +833,74 @@ /* *********************** scopes region ************************ */ +/* scope job manager */ +typedef struct ScopeJob { + SpaceImage *sima; + Scene *scene; +} ScopeJob; + +static void scope_freejob(void *sjv) +{ + ScopeJob *sj= sjv; + MEM_freeN(sj); +} + +static void scope_initjob(void *sjv) +{ + ScopeJob *sj= sjv; + SpaceImage *sima= sj->sima; + void *lock; + + ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock); + if(ibuf) { + scopes_update_buffers(&sima->scopes, ibuf); + } + ED_space_image_release_buffer(sima, lock); +} + +/* only this runs inside thread */ +static void scope_startjob(void *sjv, short *stop, short *do_update) +{ + ScopeJob *sj= sjv; + SpaceImage *sima= sj->sima; + Scene *scene = sj->scene; + void *lock; + + ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock); + if(ibuf) { + scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT ); + } + ED_space_image_release_buffer(sima, lock); + + /* to prevent looping when no image opened */ + sima->scopes.ok= 1; +} + +/* setup and start the scope job */ +void image_scope_job(const bContext *C, ARegion *ar) +{ + SpaceImage *sima= CTX_wm_space_image(C); + wmJob *steve; + ScopeJob *sj; + + /* do not start job if scope is up to date to avoid looping */ + if (sima->scopes.ok==1) return; + + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sima, 0); + sj= MEM_callocN(sizeof(ScopeJob), "scope job"); + + /* customdata for scope thread */ + sj->sima= sima; + sj->scene= CTX_data_scene(C); + + /* setup job */ + WM_jobs_customdata(steve, sj, scope_freejob); + WM_jobs_timer(steve, 0.1, 0, NC_SPACE|ND_SPACE_IMAGE|NA_EDITED); + WM_jobs_callbacks(steve, scope_startjob, scope_initjob, NULL); + + WM_jobs_start(CTX_wm_manager(C), steve); +} + /* add handlers, stuff you only do once or on area/region changes */ static void image_scope_area_init(wmWindowManager *wm, ARegion *ar) { @@ -843,14 +914,8 @@ static void image_scope_area_draw(const bContext *C, ARegion *ar) { - SpaceImage *sima= CTX_wm_space_image(C); - Scene *scene= CTX_data_scene(C); - void *lock; - ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock); - if(ibuf) { - scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT ); - } - ED_space_image_release_buffer(sima, lock); + /* end of job will trigger a redraw */ + image_scope_job(C, ar); ED_region_panels(C, ar, 1, NULL, -1); } Index: source/blender/editors/interface/interface_draw.c =================================================================== --- source/blender/editors/interface/interface_draw.c (révision 28136) +++ source/blender/editors/interface/interface_draw.c (copie de travail) @@ -764,6 +764,8 @@ rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2; rect.ymax = (float)recti->ymax-1; + if (hist->ymax == 0.f) hist->ymax = 1.f; + w = rect.xmax - rect.xmin; h = (rect.ymax - rect.ymin) * hist->ymax; Index: source/blender/editors/interface/interface_templates.c =================================================================== --- source/blender/editors/interface/interface_templates.c (révision 28136) +++ source/blender/editors/interface/interface_templates.c (copie de travail) @@ -1599,7 +1599,7 @@ hist = (Histogram *)cptr.data; - hist->height= (hist->height<=0)?100:hist->height; + hist->height= (hist->height<=30)?30:hist->height; bt= uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, hist->height, hist, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); @@ -1636,7 +1636,7 @@ block= uiLayoutAbsoluteBlock(layout); - scopes->wavefrm_height= (scopes->wavefrm_height<=0)?100:scopes->wavefrm_height; + scopes->wavefrm_height= (scopes->wavefrm_height<=30)?30:scopes->wavefrm_height; bt= uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->wavefrm_height, scopes, 0, 0, 0, 0, ""); @@ -1672,7 +1672,7 @@ block= uiLayoutAbsoluteBlock(layout); - scopes->vecscope_height= (scopes->vecscope_height<=0)?100:scopes->vecscope_height; + scopes->vecscope_height= (scopes->vecscope_height<=30)?30:scopes->vecscope_height; bt= uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);