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:
-rw-r--r--source/blender/draw/engines/image/image_engine.c61
-rw-r--r--source/blender/editors/space_image/image_edit.c10
-rw-r--r--source/blender/render/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/engine.c11
-rw-r--r--source/blender/render/intern/pipeline.c1
-rw-r--r--source/blender/render/intern/render_result.c65
-rw-r--r--source/blender/render/intern/render_result.h2
7 files changed, 100 insertions, 52 deletions
diff --git a/source/blender/draw/engines/image/image_engine.c b/source/blender/draw/engines/image/image_engine.c
index 438c95118ef..b4c0ade380e 100644
--- a/source/blender/draw/engines/image/image_engine.c
+++ b/source/blender/draw/engines/image/image_engine.c
@@ -115,33 +115,48 @@ static void space_image_gpu_texture_get(Image *image,
BKE_image_multiview_index(image, &sima->iuser);
}
- if (ibuf) {
- const int sima_flag = sima->flag & ED_space_image_get_display_channel_mask(ibuf);
- if (sima_flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
- if (ibuf->zbuf) {
- BLI_assert_msg(0, "Integer based depth buffers not supported");
- }
- else if (ibuf->zbuf_float) {
- *r_gpu_texture = GPU_texture_create_2d(
- __func__, ibuf->x, ibuf->y, 0, GPU_R16F, ibuf->zbuf_float);
- *r_owns_texture = true;
- }
- else if (ibuf->rect_float && ibuf->channels == 1) {
- *r_gpu_texture = GPU_texture_create_2d(
- __func__, ibuf->x, ibuf->y, 0, GPU_R16F, ibuf->rect_float);
- *r_owns_texture = true;
- }
+ if (ibuf == NULL) {
+ return;
+ }
+
+ if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
+ /* This codepath is only supposed to happen when drawing a lazily-allocatable render result.
+ * In all the other cases the `ED_space_image_acquire_buffer()` is expected to return NULL as
+ * an image buffer when it has no pixels. */
+
+ BLI_assert(image->type == IMA_TYPE_R_RESULT);
+
+ float zero[4] = {0, 0, 0, 0};
+ *r_gpu_texture = GPU_texture_create_2d(__func__, 1, 1, 0, GPU_RGBA16F, zero);
+ *r_owns_texture = true;
+ return;
+ }
+
+ const int sima_flag = sima->flag & ED_space_image_get_display_channel_mask(ibuf);
+ if (sima_flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
+ if (ibuf->zbuf) {
+ BLI_assert_msg(0, "Integer based depth buffers not supported");
}
- else if (image->source == IMA_SRC_TILED) {
- *r_gpu_texture = BKE_image_get_gpu_tiles(image, iuser, ibuf);
- *r_tex_tile_data = BKE_image_get_gpu_tilemap(image, iuser, NULL);
- *r_owns_texture = false;
+ else if (ibuf->zbuf_float) {
+ *r_gpu_texture = GPU_texture_create_2d(
+ __func__, ibuf->x, ibuf->y, 0, GPU_R16F, ibuf->zbuf_float);
+ *r_owns_texture = true;
}
- else {
- *r_gpu_texture = BKE_image_get_gpu_texture(image, iuser, ibuf);
- *r_owns_texture = false;
+ else if (ibuf->rect_float && ibuf->channels == 1) {
+ *r_gpu_texture = GPU_texture_create_2d(
+ __func__, ibuf->x, ibuf->y, 0, GPU_R16F, ibuf->rect_float);
+ *r_owns_texture = true;
}
}
+ else if (image->source == IMA_SRC_TILED) {
+ *r_gpu_texture = BKE_image_get_gpu_tiles(image, iuser, ibuf);
+ *r_tex_tile_data = BKE_image_get_gpu_tilemap(image, iuser, NULL);
+ *r_owns_texture = false;
+ }
+ else {
+ *r_gpu_texture = BKE_image_get_gpu_texture(image, iuser, ibuf);
+ *r_owns_texture = false;
+ }
}
static void space_node_gpu_texture_get(Image *image,
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 169dafcb8d0..a95189a303f 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -139,8 +139,10 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **r_lock, int tile)
ImBuf *ibuf;
if (sima && sima->image) {
+ const Image *image = sima->image;
+
#if 0
- if (sima->image->type == IMA_TYPE_R_RESULT && BIF_show_render_spare()) {
+ if (image->type == IMA_TYPE_R_RESULT && BIF_show_render_spare()) {
return BIF_render_spare_imbuf();
}
else
@@ -152,6 +154,12 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **r_lock, int tile)
}
if (ibuf) {
+ if (image->type == IMA_TYPE_R_RESULT && ibuf->x != 0 && ibuf->y != 0) {
+ /* Render result might be lazily allocated. Return ibuf without buffers to indicate that
+ * there is image buffer but it has no data yet. */
+ return ibuf;
+ }
+
if (ibuf->rect || ibuf->rect_float) {
return ibuf;
}
diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h
index 4534c86f7f7..cd839385bfb 100644
--- a/source/blender/render/RE_pipeline.h
+++ b/source/blender/render/RE_pipeline.h
@@ -155,6 +155,8 @@ typedef struct RenderResult {
char *error;
struct StampData *stamp_data;
+
+ bool passes_allocated;
} RenderResult;
typedef struct RenderStats {
diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c
index 75b3f2db249..1510587502b 100644
--- a/source/blender/render/intern/engine.c
+++ b/source/blender/render/intern/engine.c
@@ -212,6 +212,8 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y,
RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA");
RenderPass *differential_pass = render_layer_add_pass(rr, rl, 4, "BakeDifferential", "", "RGBA");
+ render_result_passes_allocated_ensure(rr);
+
/* Fill render passes from bake pixel array, to be read by the render engine. */
for (int ty = 0; ty < h; ty++) {
size_t offset = ty * w * 4;
@@ -328,6 +330,7 @@ RenderResult *RE_engine_begin_result(
/* can be NULL if we CLAMP the width or height to 0 */
if (result) {
render_result_clone_passes(re, result, viewname);
+ render_result_passes_allocated_ensure(result);
RenderPart *pa;
@@ -400,6 +403,14 @@ void RE_engine_end_result(
return;
}
+ if (!re->result->passes_allocated) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ if (!re->result->passes_allocated) {
+ render_result_passes_allocated_ensure(re->result);
+ }
+ BLI_rw_mutex_unlock(&re->resultmutex);
+ }
+
/* merge. on break, don't merge in result for preview renders, looks nicer */
if (!highlight) {
/* for exr tile render, detect tiles that are done */
diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c
index 479ad9209f0..9ef52b4bf41 100644
--- a/source/blender/render/intern/pipeline.c
+++ b/source/blender/render/intern/pipeline.c
@@ -354,6 +354,7 @@ RenderResult *RE_AcquireResultWrite(Render *re)
{
if (re) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ render_result_passes_allocated_ensure(re->result);
return re->result;
}
diff --git a/source/blender/render/intern/render_result.c b/source/blender/render/intern/render_result.c
index 091f5964291..c29ab342ed7 100644
--- a/source/blender/render/intern/render_result.c
+++ b/source/blender/render/intern/render_result.c
@@ -222,7 +222,6 @@ RenderPass *render_layer_add_pass(RenderResult *rr,
{
const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
- size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels;
rpass->channels = channels;
rpass->rectx = rl->rectx;
@@ -249,33 +248,6 @@ RenderPass *render_layer_add_pass(RenderResult *rr,
}
}
- /* Always allocate combined for display, in case of save buffers
- * other passes are not allocated and only saved to the EXR file. */
- if (rl->exrhandle == NULL || STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
- float *rect;
- int x;
-
- rpass->rect = MEM_callocN(sizeof(float) * rectsize, name);
- if (rpass->rect == NULL) {
- MEM_freeN(rpass);
- return NULL;
- }
-
- if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
- /* initialize to max speed */
- rect = rpass->rect;
- for (x = rectsize - 1; x >= 0; x--) {
- rect[x] = PASS_VECTOR_MAX;
- }
- }
- else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
- rect = rpass->rect;
- for (x = rectsize - 1; x >= 0; x--) {
- rect[x] = 10e10;
- }
- }
- }
-
BLI_addtail(&rl->passes, rpass);
return rpass;
@@ -316,6 +288,8 @@ RenderResult *render_result_new(
rr->do_exr_tile = true;
}
+ rr->passes_allocated = false;
+
render_result_views_new(rr, &re->r);
/* check renderdata for amount of layers */
@@ -484,6 +458,40 @@ RenderResult *render_result_new(
return rr;
}
+void render_result_passes_allocated_ensure(RenderResult *rr)
+{
+ LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
+ LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) {
+ if (rl->exrhandle != NULL && !STREQ(rp->name, RE_PASSNAME_COMBINED)) {
+ continue;
+ }
+
+ if (rp->rect != NULL) {
+ continue;
+ }
+
+ const size_t rectsize = ((size_t)rr->rectx) * rr->recty * rp->channels;
+ rp->rect = MEM_callocN(sizeof(float) * rectsize, rp->name);
+
+ if (STREQ(rp->name, RE_PASSNAME_VECTOR)) {
+ /* initialize to max speed */
+ float *rect = rp->rect;
+ for (int x = rectsize - 1; x >= 0; x--) {
+ rect[x] = PASS_VECTOR_MAX;
+ }
+ }
+ else if (STREQ(rp->name, RE_PASSNAME_Z)) {
+ float *rect = rp->rect;
+ for (int x = rectsize - 1; x >= 0; x--) {
+ rect[x] = 10e10;
+ }
+ }
+ }
+ }
+
+ rr->passes_allocated = true;
+}
+
void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
{
RenderLayer *rl;
@@ -1243,6 +1251,7 @@ void render_result_exr_file_end(Render *re, RenderEngine *engine)
render_result_free_list(&re->fullresult, re->result);
re->result = render_result_new(re, &re->disprect, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
re->result->stamp_data = stamp_data;
+ render_result_passes_allocated_ensure(re->result);
BLI_rw_mutex_unlock(&re->resultmutex);
LISTBASE_FOREACH (RenderLayer *, rl, &re->result->layers) {
diff --git a/source/blender/render/intern/render_result.h b/source/blender/render/intern/render_result.h
index 7732c113700..1fc64a4ea97 100644
--- a/source/blender/render/intern/render_result.h
+++ b/source/blender/render/intern/render_result.h
@@ -55,6 +55,8 @@ struct RenderResult *render_result_new(struct Render *re,
const char *layername,
const char *viewname);
+void render_result_passes_allocated_ensure(struct RenderResult *rr);
+
struct RenderResult *render_result_new_from_exr(
void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty);