static void draw_image_buffer_repeated(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy) { const double time_current = PIL_check_seconds_timer(); const int xmax = ceil(ar->v2d.cur.xmax); const int ymax = ceil(ar->v2d.cur.ymax); const int xmin = floor(ar->v2d.cur.xmin); const int ymin = floor(ar->v2d.cur.ymin); int x; for (x = xmin; x < xmax; x++) { int y; for (y = ymin; y < ymax; y++) { if (ima && (ima->tpageflag & IMA_TILES)) draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy); else draw_image_buffer(C, sima, ar, scene, ibuf, x, y, zoomx, zoomy); /* only draw until running out of time */ if ((PIL_check_seconds_timer() - time_current) > 0.25) return; } } }
/* * Bake Dynamic Paint image sequence surface */ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) { DynamicPaintModifierData *pmd = NULL; DynamicPaintCanvasSettings *canvas; Object *ob = ED_object_context(C); int status = 0; double timer = PIL_check_seconds_timer(); DynamicPaintSurface *surface; /* * Get modifier data */ pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); if (!pmd) { BKE_report(op->reports, RPT_ERROR, "Bake failed: no Dynamic Paint modifier found"); return 0; } /* Make sure we're dealing with a canvas */ canvas = pmd->canvas; if (!canvas) { BKE_report(op->reports, RPT_ERROR, "Bake failed: invalid canvas"); return 0; } surface = get_activeSurface(canvas); /* Set state to baking and init surface */ canvas->error[0] = '\0'; canvas->flags |= MOD_DPAINT_BAKING; G.is_break = FALSE; /* reset blender_test_break*/ /* Bake Dynamic Paint */ status = dynamicPaint_bakeImageSequence(C, surface, ob); /* Clear bake */ canvas->flags &= ~MOD_DPAINT_BAKING; WM_cursor_restore(CTX_wm_window(C)); dynamicPaint_freeSurfaceData(surface); /* Bake was successful: * Report for ended bake and how long it took */ if (status) { /* Format time string */ char time_str[30]; double time = PIL_check_seconds_timer() - timer; BLI_timestr(time, time_str); /* Show bake info */ BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%s)", time_str); } else { if (strlen(canvas->error)) { /* If an error occurred */ BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error); } else { /* User canceled the bake */ BKE_report(op->reports, RPT_WARNING, "Baking canceled!"); } } return status; }
void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms) { double t; void *work = NULL; struct timespec timeout; t = PIL_check_seconds_timer(); wait_timeout(&timeout, ms); /* wait until there is work */ pthread_mutex_lock(&queue->mutex); while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) { if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) break; else if (PIL_check_seconds_timer() - t >= ms * 0.001) break; } /* if we have something, pop it */ if (!BLI_gsqueue_is_empty(queue->queue)) { BLI_gsqueue_pop(queue->queue, &work); if (BLI_gsqueue_is_empty(queue->queue)) pthread_cond_broadcast(&queue->finish_cond); } pthread_mutex_unlock(&queue->mutex); return work; }
/* context should be used but not now because it causes some bugs */ void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate) { py_call_level--; if (gilstate) PyGILState_Release(*gilstate); if (py_call_level < 0) { fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n"); } else if (py_call_level == 0) { /* XXX - Calling classes currently wont store the context :\, * cant set NULL because of this. but this is very flakey still. */ #if 0 BPy_SetContext(NULL); bpy_import_main_set(NULL); #endif #ifdef TIME_PY_RUN bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run; bpy_timer_count++; #endif } }
static void scene_update_objects(EvaluationContext *eval_ctx, Scene *scene, Scene *scene_parent) { TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; ThreadedObjectUpdateState state; state.eval_ctx = eval_ctx; state.scene = scene; state.scene_parent = scene_parent; memset(state.statistics, 0, sizeof(state.statistics)); state.has_updated_objects = false; state.base_time = PIL_check_seconds_timer(); #ifdef MBALL_SINGLETHREAD_HACK state.has_mballs = false; #endif task_pool = BLI_task_pool_create(task_scheduler, &state); DAG_threaded_update_begin(scene, scene_update_object_add_task, task_pool); BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); if (G.debug & G_DEBUG) { print_threads_statistics(&state); } #ifdef MBALL_SINGLETHREAD_HACK if (state.has_mballs) { scene_update_all_bases(eval_ctx, scene, scene_parent); } #endif }
static void dpaint_bake_endjob(void *customdata) { DynamicPaintBakeJob *job = customdata; DynamicPaintCanvasSettings *canvas = job->canvas; canvas->flags &= ~MOD_DPAINT_BAKING; dynamicPaint_freeSurfaceData(job->surface); G.is_rendering = false; BKE_spacedata_draw_locks(false); WM_set_locked_interface(G.main->wm.first, false); /* Bake was successful: * Report for ended bake and how long it took */ if (job->success) { /* Show bake info */ WM_reportf(RPT_INFO, "DynamicPaint: Bake complete! (%.2f)", PIL_check_seconds_timer() - job->start); } else { if (strlen(canvas->error)) { /* If an error occurred */ WM_reportf(RPT_ERROR, "DynamicPaint: Bake failed: %s", canvas->error); } else { /* User canceled the bake */ WM_report(RPT_WARNING, "Baking canceled!"); } } }
PartDeflect *object_add_collision_fields(int type) { PartDeflect *pd; pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect"); pd->forcefield = type; pd->pdef_sbdamp = 0.1f; pd->pdef_sbift = 0.2f; pd->pdef_sboft = 0.02f; pd->seed = ((unsigned int)(ceil(PIL_check_seconds_timer()))+1) % 128; pd->f_strength = 1.0f; pd->f_damp = 1.0f; /* set sensible defaults based on type */ switch (type) { case PFIELD_VORTEX: pd->shape = PFIELD_SHAPE_PLANE; break; case PFIELD_WIND: pd->shape = PFIELD_SHAPE_PLANE; pd->f_flow = 1.0f; /* realistic wind behavior */ break; case PFIELD_TEXTURE: pd->f_size = 1.0f; break; case PFIELD_SMOKEFLOW: pd->f_flow = 1.0f; break; } pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION; return pd; }
void applySnapping(TransInfo *t, float *vec) { /* project is not applied this way */ if (t->tsnap.project) return; if (t->tsnap.status & SNAP_FORCED) { t->tsnap.targetSnap(t); t->tsnap.applySnap(t, vec); } else if (!ELEM(t->tsnap.mode, SCE_SNAP_MODE_INCREMENT, SCE_SNAP_MODE_GRID) && activeSnap(t)) { double current = PIL_check_seconds_timer(); // Time base quirky code to go around findnearest slowness /* !TODO! add exception for object mode, no need to slow it down then */ if (current - t->tsnap.last >= 0.01) { t->tsnap.calcSnap(t, vec); t->tsnap.targetSnap(t); t->tsnap.last = current; } if (validSnap(t)) { t->tsnap.applySnap(t, vec); } } }
void KX_LibLoadStatus::Finish() { m_finished = true; m_progress = 1.f; m_endtime = PIL_check_seconds_timer(); RunFinishCallback(); RunProgressCallback(); }
static int pupdate_time(void) { static double ltime; double time; time = PIL_check_seconds_timer(); ptottime += (time - ltime); ltime = time; return (ptottime < 0); }
void BPY_python_end(void) { // fprintf(stderr, "Ending Python!\n"); PyGILState_STATE gilstate; /* finalizing, no need to grab the state, except when we are a module */ gilstate = PyGILState_Ensure(); /* free other python data. */ pyrna_free_types(); /* clear all python data from structs */ bpy_intern_string_exit(); /* bpy.app modules that need cleanup */ BPY_app_translations_end(); /* Release copy of clear sys modules dictionary */ BPy_end_modules(); #ifndef WITH_PYTHON_MODULE BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */ Py_Finalize(); (void)gilstate; #else PyGILState_Release(gilstate); #endif #ifdef TIME_PY_RUN /* measure time since py started */ bpy_timer = PIL_check_seconds_timer() - bpy_timer; printf("*bpy stats* - "); printf("tot exec: %d, ", bpy_timer_count); printf("tot run: %.4fsec, ", bpy_timer_run_tot); if (bpy_timer_count > 0) printf("average run: %.6fsec, ", (bpy_timer_run_tot / bpy_timer_count)); if (bpy_timer > 0.0) printf("tot usage %.4f%%", (bpy_timer_run_tot / bpy_timer) * 100.0); printf("\n"); // fprintf(stderr, "Ending Python Done!\n"); #endif }
void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) { py_call_level++; if (gilstate) *gilstate = PyGILState_Ensure(); if (py_call_level == 1) { BPY_context_update(C); #ifdef TIME_PY_RUN if (bpy_timer_count == 0) { /* record time from the beginning */ bpy_timer = PIL_check_seconds_timer(); bpy_timer_run = bpy_timer_run_tot = 0.0; } bpy_timer_run = PIL_check_seconds_timer(); bpy_timer_count++; #endif } }
// set actual position void VideoFFmpeg::setPositions (void) { // set video start time m_startTime = PIL_check_seconds_timer(); // if file is played and actual position is before end position if (!m_eof && m_lastFrame >= 0 && (!m_isFile || m_lastFrame < m_range[1] * actFrameRate())) // continue from actual position m_startTime -= double(m_lastFrame) / actFrameRate(); else { m_startTime -= m_range[0]; // start from beginning, stop cache just in case stopCache(); } }
wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep) { wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer"); wt->event_type = event_type; wt->ltime = PIL_check_seconds_timer(); wt->ntime = wt->ltime + timestep; wt->stime = wt->ltime; wt->timestep = timestep; wt->win = win; BLI_addtail(&wm->timers, wt); return wt; }
wmTimer *WM_event_add_timer_notifier(wmWindowManager *wm, wmWindow *win, unsigned int type, double timestep) { wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer"); wt->event_type = TIMERNOTIFIER; wt->ltime = PIL_check_seconds_timer(); wt->ntime = wt->ltime + timestep; wt->stime = wt->ltime; wt->timestep = timestep; wt->win = win; wt->customdata = SET_UINT_IN_POINTER(type); BLI_addtail(&wm->timers, wt); return wt; }
void MovieDistortionOperation::deinitExecution() { this->m_inputOperation = NULL; this->m_movieClip = NULL; while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) { double minTime = PIL_check_seconds_timer(); vector<DistortionCache*>::iterator minTimeIterator = s_cache.begin(); for (vector<DistortionCache*>::iterator it = s_cache.begin(); it < s_cache.end(); it ++) { DistortionCache * cache = *it; if (cache->getTimeLastUsage() < minTime) { minTime = cache->getTimeLastUsage(); minTimeIterator = it; } } s_cache.erase(minTimeIterator); } }
/* exported as handle callback to bke blender.c */ void wm_window_testbreak(void) { static double ltime = 0; double curtime = PIL_check_seconds_timer(); /* only check for breaks every 50 milliseconds * if we get called more often. */ if ((curtime - ltime) > 0.05) { int hasevent = GHOST_ProcessEvents(g_system, 0); /* 0 is no wait */ if (hasevent) GHOST_DispatchEvents(g_system); ltime = curtime; } }
void UI_pie_menu_end(bContext *C, uiPieMenu *pie) { wmWindow *window = CTX_wm_window(C); uiPopupBlockHandle *menu; menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PIE, pie); menu->popup = true; menu->towardstime = PIL_check_seconds_timer(); UI_popup_handlers_add( C, &window->modalhandlers, menu, WM_HANDLER_ACCEPT_DBL_CLICK); WM_event_add_mousemove(C); menu->can_refresh = false; MEM_freeN(pie); }
/* if different owner starts existing startjob, it suspends itself */ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) { if (wm_job->running) { /* signal job to end and restart */ wm_job->stop = TRUE; // printf("job started a running job, ending... %s\n", wm_job->name); } else { if (wm_job->customdata && wm_job->startjob) { wm_jobs_test_suspend_stop(wm, wm_job); if (wm_job->suspended == FALSE) { /* copy to ensure proper free in end */ wm_job->run_customdata = wm_job->customdata; wm_job->run_free = wm_job->free; wm_job->free = NULL; wm_job->customdata = NULL; wm_job->running = TRUE; if (wm_job->initjob) wm_job->initjob(wm_job->run_customdata); wm_job->stop = FALSE; wm_job->ready = FALSE; wm_job->progress = 0.0; // printf("job started: %s\n", wm_job->name); BLI_init_threads(&wm_job->threads, do_job_thread, 1); BLI_insert_thread(&wm_job->threads, wm_job); } /* restarted job has timer already */ if (wm_job->wt == NULL) wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, wm_job->timestep); if (G.debug & G_DEBUG_JOBS) wm_job->start_time = PIL_check_seconds_timer(); } else { printf("job fails, not initialized\n"); } } }
/** * This timer system only gives maximum 1 timer event per redraw cycle, * to prevent queues to get overloaded. * Timer handlers should check for delta to decide if they just update, or follow real time. * Timer handlers can also set duration to match frames passed */ static int wm_window_timer(const bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmTimer *wt, *wtnext; wmWindow *win; double time = PIL_check_seconds_timer(); int retval = 0; for (wt = wm->timers.first; wt; wt = wtnext) { wtnext = wt->next; /* in case timer gets removed */ win = wt->win; if (wt->sleep == 0) { if (time > wt->ntime) { wt->delta = time - wt->ltime; wt->duration += wt->delta; wt->ltime = time; wt->ntime = wt->stime + wt->timestep * ceil(wt->duration / wt->timestep); if (wt->event_type == TIMERJOBS) wm_jobs_timer(C, wm, wt); else if (wt->event_type == TIMERAUTOSAVE) wm_autosave_timer(C, wm, wt); else if (wt->event_type == TIMERNOTIFIER) WM_main_add_notifier(GET_UINT_FROM_POINTER(wt->customdata), NULL); else if (win) { wmEvent event; wm_event_init_from_window(win, &event); event.type = wt->event_type; event.val = KM_NOTHING; event.keymodifier = 0; event.custom = EVT_DATA_TIMER; event.customdata = wt; wm_event_add(win, &event); retval = 1; } } } } return retval; }
KX_LibLoadStatus::KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter, class KX_KetsjiEngine* kx_engine, class KX_Scene* merge_scene, const char *path) : m_converter(kx_converter), m_engine(kx_engine), m_mergescene(merge_scene), m_data(NULL), m_libname(path), m_progress(0.0f), m_finished(false) #ifdef WITH_PYTHON , m_finish_cb(NULL), m_progress_cb(NULL) #endif { m_endtime = m_starttime = PIL_check_seconds_timer(); }
static void view_zoom_apply(bContext *C, ViewZoomData *vpd, wmOperator *op, const wmEvent *event) { float factor; if (U.viewzoom == USER_ZOOM_CONT) { SpaceClip *sclip = CTX_wm_space_clip(C); double time = PIL_check_seconds_timer(); float time_step = (float)(time - vpd->timer_lastdraw); float fac; float zfac; if (U.uiflag & USER_ZOOM_HORIZ) { fac = (float)(event->x - vpd->x); } else { fac = (float)(event->y - vpd->y); } if (U.uiflag & USER_ZOOM_INVERT) { fac = -fac; } zfac = 1.0f + ((fac / 20.0f) * time_step); vpd->timer_lastdraw = time; factor = (sclip->zoom * zfac) / vpd->zoom; } else { float delta = event->x - vpd->x + event->y - vpd->y; if (U.uiflag & USER_ZOOM_INVERT) { delta *= -1; } factor = 1.0f + delta / 300.0f; } RNA_float_set(op->ptr, "factor", factor); sclip_zoom_set(C, vpd->zoom * factor, vpd->location); ED_region_tag_redraw(CTX_wm_region(C)); }
void BPY_python_end(void) { // fprintf(stderr, "Ending Python!\n"); PyGILState_Ensure(); /* finalizing, no need to grab the state */ // free other python data. pyrna_free_types(); /* clear all python data from structs */ bpy_intern_string_exit(); #ifndef WITH_PYTHON_MODULE BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */ #endif Py_Finalize(); #ifdef TIME_PY_RUN // measure time since py started bpy_timer = PIL_check_seconds_timer() - bpy_timer; printf("*bpy stats* - "); printf("tot exec: %d, ", bpy_timer_count); printf("tot run: %.4fsec, ", bpy_timer_run_tot); if (bpy_timer_count > 0) printf("average run: %.6fsec, ", (bpy_timer_run_tot / bpy_timer_count)); if (bpy_timer > 0.0) printf("tot usage %.4f%%", (bpy_timer_run_tot / bpy_timer) * 100.0); printf("\n"); // fprintf(stderr, "Ending Python Done!\n"); #endif }
static void ui_do_animate(const bContext *C, Panel *panel) { uiHandlePanelData *data= panel->activedata; ScrArea *sa= CTX_wm_area(C); ARegion *ar= CTX_wm_region(C); float fac; fac= (PIL_check_seconds_timer()-data->starttime)/ANIMATION_TIME; fac= sqrt(fac); fac= MIN2(fac, 1.0f); /* for max 1 second, interpolate positions */ if(uiAlignPanelStep(sa, ar, fac, 0)) ED_region_tag_redraw(ar); else fac= 1.0f; if(fac >= 1.0f) { panel_activate_state(C, panel, PANEL_STATE_EXIT); return; } }
/* This timer system only gives maximum 1 timer event per redraw cycle, * to prevent queues to get overloaded. * Timer handlers should check for delta to decide if they just * update, or follow real time. * Timer handlers can also set duration to match frames passed */ static int wm_window_timer(const bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmTimer *wt, *wtnext; wmWindow *win; double time = PIL_check_seconds_timer(); int retval = 0; for (wt = wm->timers.first; wt; wt = wtnext) { wtnext = wt->next; /* in case timer gets removed */ win = wt->win; if (wt->sleep == 0) { if (time > wt->ntime) { wt->delta = time - wt->ltime; wt->duration += wt->delta; wt->ltime = time; wt->ntime = wt->stime + wt->timestep *ceil(wt->duration / wt->timestep); if (wt->event_type == TIMERJOBS) wm_jobs_timer(C, wm, wt); else if (wt->event_type == TIMERAUTOSAVE) wm_autosave_timer(C, wm, wt); else if (win) { wmEvent event = *(win->eventstate); event.type = wt->event_type; event.custom = EVT_DATA_TIMER; event.customdata = wt; wm_event_add(win, &event); retval = 1; } } } } return retval; }
static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update, float *progress) { DynamicPaintBakeJob *job = customdata; job->stop = stop; job->do_update = do_update; job->progress = progress; job->start = PIL_check_seconds_timer(); job->success = 1; G.is_break = false; /* reset BKE_blender_test_break*/ /* XXX annoying hack: needed to prevent data corruption when changing * scene frame in separate threads */ G.is_rendering = true; BKE_spacedata_draw_locks(true); dynamicPaint_bakeImageSequence(job); *do_update = true; *stop = 0; }
static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); ViewZoomData *vpd; op->customdata = vpd = MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData"); WM_cursor_modal_set(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR); if (U.viewzoom == USER_ZOOM_CONT) { /* needs a timer to continue redrawing */ vpd->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); vpd->timer_lastdraw = PIL_check_seconds_timer(); } vpd->x = event->x; vpd->y = event->y; vpd->zoom = sc->zoom; vpd->event_type = event->type; ED_clip_mouse_pos(sc, ar, event->mval, vpd->location); WM_event_add_modal_handler(C, op); }
/* str is IMA_MAX_RENDER_TEXT in size */ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) { char info_time_str[32]; // used to be extern to header_info.c uintptr_t mem_in_use, mmap_in_use, peak_memory; float megs_used_memory, mmap_used_memory, megs_peak_memory; char *spos = str; mem_in_use = MEM_get_memory_in_use(); mmap_in_use = MEM_get_mapped_memory_in_use(); peak_memory = MEM_get_peak_memory(); megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0); mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0); megs_peak_memory = (peak_memory) / (1024.0 * 1024.0); /* local view */ if (rs->localview) spos += sprintf(spos, "%s | ", IFACE_("Local View")); /* frame number */ spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra)); /* previous and elapsed time */ BLI_timestr(rs->lastframetime, info_time_str, sizeof(info_time_str)); if (rs->infostr && rs->infostr[0]) { if (rs->lastframetime != 0.0) spos += sprintf(spos, IFACE_("| Last:%s "), info_time_str); else spos += sprintf(spos, "| "); BLI_timestr(PIL_check_seconds_timer() - rs->starttime, info_time_str, sizeof(info_time_str)); } else spos += sprintf(spos, "| "); spos += sprintf(spos, IFACE_("Time:%s "), info_time_str); /* statistics */ if (rs->statstr) { if (rs->statstr[0]) { spos += sprintf(spos, "| %s ", rs->statstr); } } else { if (rs->totvert || rs->totface || rs->tothalo || rs->totstrand || rs->totlamp) spos += sprintf(spos, "| "); if (rs->totvert) spos += sprintf(spos, IFACE_("Ve:%d "), rs->totvert); if (rs->totface) spos += sprintf(spos, IFACE_("Fa:%d "), rs->totface); if (rs->tothalo) spos += sprintf(spos, IFACE_("Ha:%d "), rs->tothalo); if (rs->totstrand) spos += sprintf(spos, IFACE_("St:%d "), rs->totstrand); if (rs->totlamp) spos += sprintf(spos, IFACE_("La:%d "), rs->totlamp); if (rs->mem_peak == 0.0f) spos += sprintf(spos, IFACE_("| Mem:%.2fM (%.2fM, Peak %.2fM) "), megs_used_memory, mmap_used_memory, megs_peak_memory); else spos += sprintf(spos, IFACE_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak); if (rs->curfield) spos += sprintf(spos, IFACE_("Field %d "), rs->curfield); if (rs->curblur) spos += sprintf(spos, IFACE_("Blur %d "), rs->curblur); } /* full sample */ if (rs->curfsa) spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa); /* extra info */ if (rs->infostr && rs->infostr[0]) spos += sprintf(spos, "| %s ", rs->infostr); /* very weak... but 512 characters is quite safe */ if (spos >= str + IMA_MAX_RENDER_TEXT) if (G.debug & G_DEBUG) printf("WARNING! renderwin text beyond limit\n"); }
/** * this method is called for the top execution groups. containing the compositor node or the preview node or the viewer node) */ void ExecutionGroup::execute(ExecutionSystem *graph) { const CompositorContext &context = graph->getContext(); const bNodeTree *bTree = context.getbNodeTree(); if (this->m_width == 0 || this->m_height == 0) {return; } /// @note: break out... no pixels to calculate. if (bTree->test_break && bTree->test_break(bTree->tbh)) {return; } /// @note: early break out for blur and preview nodes if (this->m_numberOfChunks == 0) {return; } /// @note: early break out unsigned int chunkNumber; this->m_executionStartTime = PIL_check_seconds_timer(); this->m_chunksFinished = 0; this->m_bTree = bTree; unsigned int index; unsigned int *chunkOrder = (unsigned int *)MEM_mallocN(sizeof(unsigned int) * this->m_numberOfChunks, __func__); for (chunkNumber = 0; chunkNumber < this->m_numberOfChunks; chunkNumber++) { chunkOrder[chunkNumber] = chunkNumber; } NodeOperation *operation = this->getOutputOperation(); float centerX = 0.5; float centerY = 0.5; OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT; if (operation->isViewerOperation()) { ViewerOperation *viewer = (ViewerOperation *)operation; centerX = viewer->getCenterX(); centerY = viewer->getCenterY(); chunkorder = viewer->getChunkOrder(); } const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); switch (chunkorder) { case COM_TO_RANDOM: for (index = 0; index < 2 * this->m_numberOfChunks; index++) { int index1 = rand() % this->m_numberOfChunks; int index2 = rand() % this->m_numberOfChunks; int s = chunkOrder[index1]; chunkOrder[index1] = chunkOrder[index2]; chunkOrder[index2] = s; } break; case COM_TO_CENTER_OUT: { ChunkOrderHotspot *hotspots[1]; hotspots[0] = new ChunkOrderHotspot(border_width * centerX, border_height * centerY, 0.0f); rcti rect; ChunkOrder *chunkOrders = (ChunkOrder *)MEM_mallocN(sizeof(ChunkOrder) * this->m_numberOfChunks, __func__); for (index = 0; index < this->m_numberOfChunks; index++) { determineChunkRect(&rect, index); chunkOrders[index].setChunkNumber(index); chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin); chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin); chunkOrders[index].determineDistance(hotspots, 1); } std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks - 1]); for (index = 0; index < this->m_numberOfChunks; index++) { chunkOrder[index] = chunkOrders[index].getChunkNumber(); } delete hotspots[0]; MEM_freeN(chunkOrders); break; } case COM_TO_RULE_OF_THIRDS: { ChunkOrderHotspot *hotspots[9]; unsigned int tx = border_width / 6; unsigned int ty = border_height / 6; unsigned int mx = border_width / 2; unsigned int my = border_height / 2; unsigned int bx = mx + 2 * tx; unsigned int by = my + 2 * ty; float addition = this->m_numberOfChunks / COM_RULE_OF_THIRDS_DIVIDER; hotspots[0] = new ChunkOrderHotspot(mx, my, addition * 0); hotspots[1] = new ChunkOrderHotspot(tx, my, addition * 1); hotspots[2] = new ChunkOrderHotspot(bx, my, addition * 2); hotspots[3] = new ChunkOrderHotspot(bx, by, addition * 3); hotspots[4] = new ChunkOrderHotspot(tx, ty, addition * 4); hotspots[5] = new ChunkOrderHotspot(bx, ty, addition * 5); hotspots[6] = new ChunkOrderHotspot(tx, by, addition * 6); hotspots[7] = new ChunkOrderHotspot(mx, ty, addition * 7); hotspots[8] = new ChunkOrderHotspot(mx, by, addition * 8); rcti rect; ChunkOrder *chunkOrders = (ChunkOrder *)MEM_mallocN(sizeof(ChunkOrder) * this->m_numberOfChunks, __func__); for (index = 0; index < this->m_numberOfChunks; index++) { determineChunkRect(&rect, index); chunkOrders[index].setChunkNumber(index); chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin); chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin); chunkOrders[index].determineDistance(hotspots, 9); } std::sort(&chunkOrders[0], &chunkOrders[this->m_numberOfChunks]); for (index = 0; index < this->m_numberOfChunks; index++) { chunkOrder[index] = chunkOrders[index].getChunkNumber(); } delete hotspots[0]; delete hotspots[1]; delete hotspots[2]; delete hotspots[3]; delete hotspots[4]; delete hotspots[5]; delete hotspots[6]; delete hotspots[7]; delete hotspots[8]; MEM_freeN(chunkOrders); break; } case COM_TO_TOP_DOWN: default: break; } DebugInfo::execution_group_started(this); DebugInfo::graphviz(graph); bool breaked = false; bool finished = false; unsigned int startIndex = 0; const int maxNumberEvaluated = BLI_system_thread_count() * 2; while (!finished && !breaked) { bool startEvaluated = false; finished = true; int numberEvaluated = 0; for (index = startIndex; index < this->m_numberOfChunks && numberEvaluated < maxNumberEvaluated; index++) { chunkNumber = chunkOrder[index]; int yChunk = chunkNumber / this->m_numberOfXChunks; int xChunk = chunkNumber - (yChunk * this->m_numberOfXChunks); const ChunkExecutionState state = this->m_chunkExecutionStates[chunkNumber]; if (state == COM_ES_NOT_SCHEDULED) { scheduleChunkWhenPossible(graph, xChunk, yChunk); finished = false; startEvaluated = true; numberEvaluated++; if (bTree->update_draw) bTree->update_draw(bTree->udh); } else if (state == COM_ES_SCHEDULED) { finished = false; startEvaluated = true; numberEvaluated++; } else if (state == COM_ES_EXECUTED && !startEvaluated) { startIndex = index + 1; } } WorkScheduler::finish(); if (bTree->test_break && bTree->test_break(bTree->tbh)) { breaked = true; } } DebugInfo::execution_group_finished(this); DebugInfo::graphviz(graph); MEM_freeN(chunkOrder); }
/* hardcoded to event TIMERJOBS */ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) { wmJob *wm_job, *wm_jobnext; float total_progress = 0.f; float jobs_progress = 0; for (wm_job = wm->jobs.first; wm_job; wm_job = wm_jobnext) { wm_jobnext = wm_job->next; if (wm_job->wt == wt) { /* running threads */ if (wm_job->threads.first) { /* let threads get temporary lock over main thread if needed */ wm_job_main_thread_yield(wm_job); /* always call note and update when ready */ if (wm_job->do_update || wm_job->ready) { if (wm_job->update) wm_job->update(wm_job->run_customdata); if (wm_job->note) WM_event_add_notifier(C, wm_job->note, NULL); if (wm_job->flag & WM_JOB_PROGRESS) WM_event_add_notifier(C, NC_WM | ND_JOB, NULL); wm_job->do_update = false; } if (wm_job->ready) { if (wm_job->endjob) wm_job->endjob(wm_job->run_customdata); /* free own data */ wm_job->run_free(wm_job->run_customdata); wm_job->run_customdata = NULL; wm_job->run_free = NULL; // if (wm_job->stop) printf("job ready but stopped %s\n", wm_job->name); // else printf("job finished %s\n", wm_job->name); if (G.debug & G_DEBUG_JOBS) { printf("Job '%s' finished in %f seconds\n", wm_job->name, PIL_check_seconds_timer() - wm_job->start_time); } wm_job->running = false; WM_job_main_thread_lock_release(wm_job); BLI_threadpool_end(&wm_job->threads); WM_job_main_thread_lock_acquire(wm_job); if (wm_job->endnote) WM_event_add_notifier(C, wm_job->endnote, NULL); WM_event_add_notifier(C, NC_WM | ND_JOB, NULL); /* new job added for wm_job? */ if (wm_job->customdata) { // printf("job restarted with new data %s\n", wm_job->name); WM_jobs_start(wm, wm_job); } else { WM_event_remove_timer(wm, wm_job->win, wm_job->wt); wm_job->wt = NULL; /* remove wm_job */ wm_job_free(wm, wm_job); } } else if (wm_job->flag & WM_JOB_PROGRESS) { /* accumulate global progress for running jobs */ jobs_progress++; total_progress += wm_job->progress; } } else if (wm_job->suspended) { WM_jobs_start(wm, wm_job); } } else if (wm_job->threads.first && !wm_job->ready) { if (wm_job->flag & WM_JOB_PROGRESS) { /* accumulate global progress for running jobs */ jobs_progress++; total_progress += wm_job->progress; } } } /* if there are running jobs, set the global progress indicator */ if (jobs_progress > 0) { wmWindow *win; float progress = total_progress / (float)jobs_progress; for (win = wm->windows.first; win; win = win->next) WM_progress_set(win, progress); } else { wmWindow *win; for (win = wm->windows.first; win; win = win->next) WM_progress_clear(win); } }