Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/render/render_opengl.c')
-rw-r--r--source/blender/editors/render/render_opengl.c78
1 files changed, 52 insertions, 26 deletions
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 55c07140216..1133b5f79d1 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -38,7 +38,6 @@
#include "BLI_math_color_blend.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_jitter.h"
#include "BLI_threads.h"
#include "BLI_task.h"
@@ -257,10 +256,8 @@ static void screen_opengl_views_setup(OGLRender *oglrender)
}
}
- BLI_lock_thread(LOCK_DRAW_IMAGE);
if (!(is_multiview && BKE_scene_multiview_is_stereo3d(rd)))
oglrender->iuser.flag &= ~IMA_SHOW_STEREO;
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
/* will only work for non multiview correctly */
if (v3d) {
@@ -315,7 +312,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
RE_render_result_rect_from_ibuf(rr, &scene->r, out, oglrender->view_id);
IMB_freeImBuf(out);
}
- else if (gpd){
+ else if (gpd) {
/* If there are no strips, Grease Pencil still needs a buffer to draw on */
ImBuf *out = IMB_allocImBuf(oglrender->sizex, oglrender->sizey, 32, IB_rect);
RE_render_result_rect_from_ibuf(rr, &scene->r, out, oglrender->view_id);
@@ -356,11 +353,15 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
ImBuf *ibuf_view;
const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
+ unsigned int draw_flags = V3D_OFSDRAW_NONE;
+ draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0;
+
if (view_context) {
+ draw_flags |= (draw_bgpic) ? V3D_OFSDRAW_USE_BACKGROUND : 0;
+
ibuf_view = ED_view3d_draw_offscreen_imbuf(
scene, v3d, ar, sizex, sizey,
- IB_rect, draw_bgpic,
- alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname,
+ IB_rect, draw_flags, alpha_mode, oglrender->ofs_samples, viewname,
oglrender->fx, oglrender->ofs, err_out);
/* for stamp only */
@@ -369,10 +370,11 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
}
}
else {
+ draw_flags |= (V3D_OFSDRAW_USE_GPENCIL | V3D_OFSDRAW_USE_BACKGROUND);
ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(
scene, scene->camera, oglrender->sizex, oglrender->sizey,
- IB_rect, OB_SOLID, false, true, true,
- alpha_mode, oglrender->ofs_samples, oglrender->ofs_full_samples, viewname,
+ IB_rect, draw_flags, OB_SOLID,
+ alpha_mode, oglrender->ofs_samples, viewname,
oglrender->fx, oglrender->ofs, err_out);
camera = scene->camera;
}
@@ -682,9 +684,18 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->fx = GPU_fx_compositor_create();
}
}
+ else if (is_sequencer) {
+ /* NOTE: We allow animation of DoF setting for flexibility in edits, so
+ * we can't check in advance whether we need FX compositor or not.
+ * We just always allocated it and make sure it doesn't add extra
+ * overhead rather than memory allocation here if it's not really
+ * needed.
+ */
+ oglrender->fx = GPU_fx_compositor_create();
+ }
/* create render */
- oglrender->re = RE_NewRender(scene->id.name);
+ oglrender->re = RE_NewSceneRender(scene);
/* create image and image user */
oglrender->ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
@@ -715,7 +726,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->task_scheduler = task_scheduler;
oglrender->task_pool = BLI_task_pool_create_background(task_scheduler,
oglrender);
- BLI_pool_set_num_threads(oglrender->task_pool, 1);
}
else {
oglrender->task_scheduler = NULL;
@@ -747,6 +757,23 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
int i;
if (oglrender->is_animation) {
+ /* Trickery part for movie output:
+ *
+ * We MUST write frames in an exact order, so we only let background
+ * thread to work on that, and main thread is simply waits for that
+ * thread to do all the dirty work.
+ *
+ * After this loop is done work_and_wait() will have nothing to do,
+ * so we don't run into wrong order of frames written to the stream.
+ */
+ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
+ BLI_mutex_lock(&oglrender->task_mutex);
+ while (oglrender->num_scheduled_frames > 0) {
+ BLI_condition_wait(&oglrender->task_condition,
+ &oglrender->task_mutex);
+ }
+ BLI_mutex_unlock(&oglrender->task_mutex);
+ }
BLI_task_pool_work_and_wait(oglrender->task_pool);
BLI_task_pool_free(oglrender->task_pool);
/* Depending on various things we might or might not use global scheduler. */
@@ -858,7 +885,7 @@ static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
typedef struct WriteTaskData {
RenderResult *rr;
- int cfra;
+ Scene tmp_scene;
} WriteTaskData;
static void write_result_func(TaskPool * __restrict pool,
@@ -867,10 +894,10 @@ static void write_result_func(TaskPool * __restrict pool,
{
OGLRender *oglrender = (OGLRender *) BLI_task_pool_userdata(pool);
WriteTaskData *task_data = (WriteTaskData *) task_data_v;
- Scene *scene = oglrender->scene;
+ Scene *scene = &task_data->tmp_scene;
RenderResult *rr = task_data->rr;
const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
- const int cfra = task_data->cfra;
+ const int cfra = scene->r.cfra;
bool ok;
/* Don't attempt to write if we've got an error. */
if (!oglrender->pool_ok) {
@@ -886,18 +913,17 @@ static void write_result_func(TaskPool * __restrict pool,
*/
ReportList reports;
BKE_reports_init(&reports, oglrender->reports->flag & ~RPT_PRINT);
- /* Do actual save logic here, depending on the file format. */
- Scene tmp_scene = *scene;
- tmp_scene.r.cfra = cfra;
+ /* Do actual save logic here, depending on the file format.
+ *
+ * NOTE: We have to construct temporary scene with proper scene->r.cfra.
+ * This is because underlying calls do not use r.cfra but use scene
+ * for that.
+ */
if (is_movie) {
- /* We have to construct temporary scene with proper scene->r.cfra.
- * This is because underlying calls do not use r.cfra but use scene
- * for that.
- */
ok = RE_WriteRenderViewsMovie(&reports,
rr,
- &tmp_scene,
- &tmp_scene.r,
+ scene,
+ &scene->r,
oglrender->mh,
oglrender->movie_ctx_arr,
oglrender->totvideos,
@@ -917,8 +943,8 @@ static void write_result_func(TaskPool * __restrict pool,
true,
NULL);
- BKE_render_result_stamp_info(&tmp_scene, tmp_scene.camera, rr, false);
- ok = RE_WriteRenderViewsImage(NULL, rr, &tmp_scene, true, name);
+ BKE_render_result_stamp_info(scene, scene->camera, rr, false);
+ ok = RE_WriteRenderViewsImage(NULL, rr, scene, true, name);
if (!ok) {
BKE_reportf(&reports,
RPT_ERROR,
@@ -957,7 +983,7 @@ static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr)
Scene *scene = oglrender->scene;
WriteTaskData *task_data = MEM_mallocN(sizeof(WriteTaskData), "write task data");
task_data->rr = rr;
- task_data->cfra = scene->r.cfra;
+ task_data->tmp_scene = *scene;
BLI_mutex_lock(&oglrender->task_mutex);
oglrender->num_scheduled_frames++;
if (oglrender->num_scheduled_frames > MAX_SCHEDULED_FRAMES) {
@@ -1071,7 +1097,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
/* render frame? */
if (oglrender->timer == event->customdata)
break;
- /* fall-through */
+ ATTR_FALLTHROUGH;
default:
/* nothing to do */
return OPERATOR_RUNNING_MODAL;