int RenderEngine::arm_command(TransportCommand *command, int ¤t_vchannel, int ¤t_achannel) { // Prevent this renderengine from accepting another command until finished. // Since the renderengine is often deleted after the input_lock command it must // be locked here as well as in the calling routine. input_lock->lock("RenderEngine::arm_command"); this->command->copy_from(command); // Fix background rendering asset to use current dimensions and ignore // headers. preferences->brender_asset->frame_rate = command->get_edl()->session->frame_rate; preferences->brender_asset->width = command->get_edl()->session->output_w; preferences->brender_asset->height = command->get_edl()->session->output_h; preferences->brender_asset->use_header = 0; preferences->brender_asset->layers = 1; preferences->brender_asset->video_data = 1; done = 0; interrupted = 0; // Retool configuration for this node this->config->copy_from(command->get_edl()->session->playback_config); VideoOutConfig *vconfig = this->config->vconfig; AudioOutConfig *aconfig = this->config->aconfig; if(command->realtime) { if(command->single_frame() && vconfig->driver != PLAYBACK_X11_GL) { vconfig->driver = PLAYBACK_X11; } } else { vconfig->driver = PLAYBACK_X11; } get_duty(); if(do_audio) { fragment_len = aconfig->fragment_size; // Larger of audio_module_fragment and fragment length adjusted for speed // Extra memory must be allocated for rendering slow motion. adjusted_fragment_len = (int64_t)((float)aconfig->fragment_size / command->get_speed() + 0.5); if(adjusted_fragment_len < aconfig->fragment_size) adjusted_fragment_len = aconfig->fragment_size; } // Set lock so audio doesn't start until video has started. if(do_video) { while(first_frame_lock->get_value() > 0) first_frame_lock->lock("RenderEngine::arm_command"); } else // Set lock so audio doesn't wait for video which is never to come. { while(first_frame_lock->get_value() <= 0) first_frame_lock->unlock(); } open_output(); create_render_threads(); arm_render_threads(); return 0; }
/* * Check the scene to determine whether or not any parameters that affect * the thread pool, the persistent message passing primitives, or other * infrastructure needs to be reconfigured before rendering commences. */ void rendercheck(scenedef * scene) { flt runtime; rt_timerhandle stth; /* setup time timer handle */ if (scene->verbosemode && scene->mynode == 0) { char msgtxt[1024]; int i, totalcpus; flt totalspeed; rt_ui_message(MSG_0, "CPU Information:"); totalspeed = 0.0; totalcpus = 0; for (i=0; i<scene->nodes; i++) { sprintf(msgtxt, " Node %4d: %2d CPUs, CPU Speed %4.2f, Node Speed %6.2f Name: %s", i, scene->cpuinfo[i].numcpus, scene->cpuinfo[i].cpuspeed, scene->cpuinfo[i].nodespeed, scene->cpuinfo[i].machname); rt_ui_message(MSG_0, msgtxt); totalcpus += scene->cpuinfo[i].numcpus; totalspeed += scene->cpuinfo[i].nodespeed; } sprintf(msgtxt, " Total CPUs: %d", totalcpus); rt_ui_message(MSG_0, msgtxt); sprintf(msgtxt, " Total Speed: %f\n", totalspeed); rt_ui_message(MSG_0, msgtxt); } rt_barrier_sync(); /* synchronize all nodes at this point */ stth=rt_timer_create(); rt_timer_start(stth); /* Time the preprocessing of the scene database */ rt_autoshader(scene); /* Adapt to the shading features needed at runtime */ /* Hierarchical grid ray tracing acceleration scheme */ if (scene->boundmode == RT_BOUNDING_ENABLED) engrid_scene(scene, scene->boundthresh); /* if any clipping groups exist, we have to use appropriate */ /* intersection testing logic */ if (scene->cliplist != NULL) { scene->flags |= RT_SHADE_CLIPPING; } /* if there was a preexisting image, free it before continuing */ if (scene->imginternal && (scene->img != NULL)) { free(scene->img); scene->img = NULL; } /* Allocate a new image buffer if necessary */ if (scene->img == NULL) { scene->imginternal = 1; if (scene->verbosemode && scene->mynode == 0) { rt_ui_message(MSG_0, "Allocating Image Buffer."); } /* allocate the image buffer accordinate to pixel format */ if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) { scene->img = malloc(scene->hres * scene->vres * 3); } else if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB96F) { scene->img = malloc(sizeof(float) * scene->hres * scene->vres * 3); } else { rt_ui_message(MSG_0, "Illegal image buffer format specifier!"); } if (scene->img == NULL) { scene->imginternal = 0; rt_ui_message(MSG_0, "Warning: Failed To Allocate Image Buffer!"); } } /* if any threads are leftover from a previous scene, and the */ /* scene has changed significantly, we have to collect, and */ /* respawn the worker threads, since lots of things may have */ /* changed which would affect them. */ destroy_render_threads(scene); create_render_threads(scene); /* allocate and initialize persistent scanline receive buffers */ /* which are used by the parallel message passing code. */ scene->parbuf = rt_init_scanlinereceives(scene); /* the scene has been successfully prepared for rendering */ /* unless it gets modified in certain ways, we don't need to */ /* pre-process it ever again. */ scene->scenecheck = 0; rt_timer_stop(stth); /* Preprocessing is finished, stop timing */ runtime=rt_timer_time(stth); rt_timer_destroy(stth); /* Print out relevent timing info */ if (scene->mynode == 0) { char msgtxt[256]; sprintf(msgtxt, "Preprocessing Time: %10.4f seconds",runtime); rt_ui_message(MSG_0, msgtxt); } }