Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/render/render_preview.c
| Show First 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_texture.h" | #include "BKE_texture.h" | ||||
| #include "BKE_world.h" | #include "BKE_world.h" | ||||
| #include "IMB_imbuf.h" | #include "IMB_imbuf.h" | ||||
| #include "IMB_imbuf_types.h" | #include "IMB_imbuf_types.h" | ||||
| #include "IMB_thumbs.h" | |||||
| #include "BIF_gl.h" | #include "BIF_gl.h" | ||||
| #include "BIF_glutil.h" | #include "BIF_glutil.h" | ||||
| #include "RE_pipeline.h" | #include "RE_pipeline.h" | ||||
| #include "RE_engine.h" | #include "RE_engine.h" | ||||
| Show All 32 Lines | if (brush->flag & BRUSH_CUSTOM_ICON) { | ||||
| if (path[0]) { | if (path[0]) { | ||||
| /* use fefault color spaces */ | /* use fefault color spaces */ | ||||
| brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); | brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); | ||||
| } | } | ||||
| } | } | ||||
| if (brush->icon_imbuf) | if (brush->icon_imbuf) | ||||
| BKE_icon_changed(BKE_icon_getid(&brush->id)); | BKE_icon_changed(BKE_icon_id_ensure(&brush->id)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!(brush->icon_imbuf)) | if (!(brush->icon_imbuf)) | ||||
| brush->id.icon_id = 0; | brush->id.icon_id = 0; | ||||
| return brush->icon_imbuf; | return brush->icon_imbuf; | ||||
| ▲ Show 20 Lines • Show All 790 Lines • ▼ Show 20 Lines | static void set_alpha(char *cp, int sizex, int sizey, char alpha) | ||||
| for (a = 0; a < size; a++, cp += 4) | for (a = 0; a < size; a++, cp += 4) | ||||
| cp[3] = alpha; | cp[3] = alpha; | ||||
| } | } | ||||
| static void icon_preview_startjob(void *customdata, short *stop, short *do_update) | static void icon_preview_startjob(void *customdata, short *stop, short *do_update) | ||||
| { | { | ||||
| ShaderPreview *sp = customdata; | ShaderPreview *sp = customdata; | ||||
| if (sp->pr_method == PR_ICON_DEFERRED) { | |||||
| PreviewImage *prv = sp->owner; | |||||
| ImBuf *thumb; | |||||
| char *deferred_data = PRV_DEFERRED_DATA(prv); | |||||
| int source = deferred_data[0]; | |||||
| char *path = &deferred_data[1]; | |||||
| // printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path); | |||||
| thumb = IMB_thumb_manage(path, THB_LARGE, source); | |||||
| if (thumb) { | |||||
| /* PreviewImage assumes premultiplied alhpa... */ | |||||
| IMB_premultiply_alpha(thumb); | |||||
| icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect); | |||||
| IMB_freeImBuf(thumb); | |||||
| } | |||||
| } | |||||
| else { | |||||
| ID *id = sp->id; | ID *id = sp->id; | ||||
| short idtype = GS(id->name); | short idtype = GS(id->name); | ||||
| if (idtype == ID_IM) { | if (idtype == ID_IM) { | ||||
| Image *ima = (Image *)id; | Image *ima = (Image *)id; | ||||
| ImBuf *ibuf = NULL; | ImBuf *ibuf = NULL; | ||||
| ImageUser iuser = {NULL}; | ImageUser iuser = {NULL}; | ||||
| /* ima->ok is zero when Image cannot load */ | /* ima->ok is zero when Image cannot load */ | ||||
| if (ima == NULL || ima->ok == 0) | if (ima == NULL || ima->ok == 0) | ||||
| return; | return; | ||||
| /* setup dummy image user */ | /* setup dummy image user */ | ||||
| iuser.ok = iuser.framenr = 1; | iuser.ok = iuser.framenr = 1; | ||||
| iuser.scene = sp->scene; | iuser.scene = sp->scene; | ||||
| /* elubie: this needs to be changed: here image is always loaded if not | /* elubie: this needs to be changed: here image is always loaded if not | ||||
| * already there. Very expensive for large images. Need to find a way to | * already there. Very expensive for large images. Need to find a way to | ||||
| * only get existing ibuf */ | * only get existing ibuf */ | ||||
| ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); | ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); | ||||
| if (ibuf == NULL || ibuf->rect == NULL) { | if (ibuf == NULL || ibuf->rect == NULL) { | ||||
| BKE_image_release_ibuf(ima, ibuf, NULL); | BKE_image_release_ibuf(ima, ibuf, NULL); | ||||
| return; | return; | ||||
| } | } | ||||
| icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect); | icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect); | ||||
| *do_update = true; | *do_update = true; | ||||
| BKE_image_release_ibuf(ima, ibuf, NULL); | BKE_image_release_ibuf(ima, ibuf, NULL); | ||||
| } | } | ||||
| else if (idtype == ID_BR) { | else if (idtype == ID_BR) { | ||||
| Brush *br = (Brush *)id; | Brush *br = (Brush *)id; | ||||
| br->icon_imbuf = get_brush_icon(br); | br->icon_imbuf = get_brush_icon(br); | ||||
| memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int)); | memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int)); | ||||
| if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) | if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) | ||||
| return; | return; | ||||
| icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect); | icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect); | ||||
| *do_update = true; | *do_update = true; | ||||
| } | } | ||||
| else { | else { | ||||
| /* re-use shader job */ | /* re-use shader job */ | ||||
| shader_preview_startjob(customdata, stop, do_update); | shader_preview_startjob(customdata, stop, do_update); | ||||
| /* world is rendered with alpha=0, so it wasn't displayed | /* world is rendered with alpha=0, so it wasn't displayed | ||||
| * this could be render option for sky to, for later */ | * this could be render option for sky to, for later */ | ||||
| if (idtype == ID_WO) { | if (idtype == ID_WO) { | ||||
| set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); | set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); | ||||
| } | } | ||||
| else if (idtype == ID_MA) { | else if (idtype == ID_MA) { | ||||
| Material *ma = (Material *)id; | Material *ma = (Material *)id; | ||||
| if (ma->material_type == MA_TYPE_HALO) | if (ma->material_type == MA_TYPE_HALO) | ||||
| set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); | set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| /* use same function for icon & shader, so the job manager | /* use same function for icon & shader, so the job manager | ||||
| * does not run two of them at the same time. */ | * does not run two of them at the same time. */ | ||||
| static void common_preview_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress)) | static void common_preview_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress)) | ||||
| { | { | ||||
| ShaderPreview *sp = customdata; | ShaderPreview *sp = customdata; | ||||
| if (sp->pr_method == PR_ICON_RENDER) | if (ELEM(sp->pr_method, PR_ICON_RENDER, PR_ICON_DEFERRED)) | ||||
| icon_preview_startjob(customdata, stop, do_update); | icon_preview_startjob(customdata, stop, do_update); | ||||
| else | else | ||||
| shader_preview_startjob(customdata, stop, do_update); | shader_preview_startjob(customdata, stop, do_update); | ||||
| } | } | ||||
| /* exported functions */ | /* exported functions */ | ||||
| static void icon_preview_add_size(IconPreview *ip, unsigned int *rect, int sizex, int sizey) | static void icon_preview_add_size(IconPreview *ip, unsigned int *rect, int sizex, int sizey) | ||||
| Show All 19 Lines | |||||
| static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, float *progress) | static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, float *progress) | ||||
| { | { | ||||
| IconPreview *ip = (IconPreview *)customdata; | IconPreview *ip = (IconPreview *)customdata; | ||||
| IconPreviewSize *cur_size = ip->sizes.first; | IconPreviewSize *cur_size = ip->sizes.first; | ||||
| const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene); | const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene); | ||||
| while (cur_size) { | while (cur_size) { | ||||
| PreviewImage *prv = ip->owner; | |||||
| ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); | ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); | ||||
| const bool is_render = !prv->use_deferred; | |||||
| /* construct shader preview from image size and previewcustomdata */ | /* construct shader preview from image size and previewcustomdata */ | ||||
| sp->scene = ip->scene; | sp->scene = ip->scene; | ||||
| sp->owner = ip->owner; | sp->owner = ip->owner; | ||||
| sp->sizex = cur_size->sizex; | sp->sizex = cur_size->sizex; | ||||
| sp->sizey = cur_size->sizey; | sp->sizey = cur_size->sizey; | ||||
| sp->pr_method = PR_ICON_RENDER; | sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED; | ||||
| sp->pr_rect = cur_size->rect; | sp->pr_rect = cur_size->rect; | ||||
| sp->id = ip->id; | sp->id = ip->id; | ||||
| if (is_render) { | |||||
| BLI_assert(ip->id); | |||||
| if (use_new_shading) { | if (use_new_shading) { | ||||
| /* texture icon rendering is hardcoded to use BI, | /* texture icon rendering is hardcoded to use BI, | ||||
| * so don't even think of using cycle's bmain for | * so don't even think of using cycle's bmain for | ||||
| * texture icons | * texture icons | ||||
| */ | */ | ||||
| if (GS(ip->id->name) != ID_TE) | if (GS(ip->id->name) != ID_TE) | ||||
| sp->pr_main = G_pr_main_cycles; | sp->pr_main = G_pr_main_cycles; | ||||
| else | else | ||||
| sp->pr_main = G_pr_main; | sp->pr_main = G_pr_main; | ||||
| } | } | ||||
| else { | else { | ||||
| sp->pr_main = G_pr_main; | sp->pr_main = G_pr_main; | ||||
| } | } | ||||
| } | |||||
| common_preview_startjob(sp, stop, do_update, progress); | common_preview_startjob(sp, stop, do_update, progress); | ||||
| shader_preview_free(sp); | shader_preview_free(sp); | ||||
| cur_size = cur_size->next; | cur_size = cur_size->next; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey) | ||||
| /* render all resolutions from suspended job too */ | /* render all resolutions from suspended job too */ | ||||
| old_ip = WM_jobs_customdata_get(wm_job); | old_ip = WM_jobs_customdata_get(wm_job); | ||||
| if (old_ip) | if (old_ip) | ||||
| BLI_movelisttolist(&ip->sizes, &old_ip->sizes); | BLI_movelisttolist(&ip->sizes, &old_ip->sizes); | ||||
| /* customdata for preview thread */ | /* customdata for preview thread */ | ||||
| ip->scene = CTX_data_scene(C); | ip->scene = CTX_data_scene(C); | ||||
| ip->owner = id; | ip->owner = owner; | ||||
| ip->id = id; | ip->id = id; | ||||
| icon_preview_add_size(ip, rect, sizex, sizey); | icon_preview_add_size(ip, rect, sizex, sizey); | ||||
| /* setup job */ | /* setup job */ | ||||
| WM_jobs_customdata_set(wm_job, ip, icon_preview_free); | WM_jobs_customdata_set(wm_job, ip, icon_preview_free); | ||||
| WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL); | WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL); | ||||
| WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob); | WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob); | ||||
| ▲ Show 20 Lines • Show All 60 Lines • Show Last 20 Lines | |||||