void DenoisingTask::setup_denoising_buffer() { /* Expand filter_area by radius pixels and clamp the result to the extent of the neighboring tiles */ rect = rect_from_shape(filter_area.x, filter_area.y, filter_area.z, filter_area.w); rect = rect_expand(rect, radius); rect = rect_clip(rect, make_int4(tile_info->x[0], tile_info->y[0], tile_info->x[3], tile_info->y[3])); buffer.passes = 14; buffer.width = rect.z - rect.x; buffer.stride = align_up(buffer.width, 4); buffer.h = rect.w - rect.y; int alignment_floats = divide_up(device->mem_sub_ptr_alignment(), sizeof(float)); buffer.pass_stride = align_up(buffer.stride * buffer.h, alignment_floats); /* Pad the total size by four floats since the SIMD kernels might go a bit over the end. */ int mem_size = align_up(buffer.pass_stride * buffer.passes + 4, alignment_floats); buffer.mem.alloc_to_device(mem_size, false); /* CPUs process shifts sequentially while GPUs process them in parallel. */ int num_layers; if(buffer.gpu_temporary_mem) { /* Shadowing prefiltering uses a radius of 6, so allocate at least that much. */ int max_radius = max(radius, 6); int num_shifts = (2*max_radius + 1) * (2*max_radius + 1); num_layers = 2*num_shifts + 1; } else { num_layers = 3; } /* Allocate two layers per shift as well as one for the weight accumulation. */ buffer.temporary_mem.alloc_to_device(num_layers * buffer.pass_stride); }
static void damagerect(VTermScreen *screen, VTermRect rect) { VTermRect emit; switch(screen->damage_merge) { case VTERM_DAMAGE_CELL: /* Always emit damage event */ emit = rect; break; case VTERM_DAMAGE_ROW: /* Emit damage longer than one row. Try to merge with existing damage in * the same row */ if(rect.end_row > rect.start_row + 1) { /* Bigger than 1 line - flush existing, emit this */ vterm_screen_flush_damage(screen); emit = rect; } else if(screen->damaged.start_row == -1) { /* None stored yet */ screen->damaged = rect; return; } else if(rect.start_row == screen->damaged.start_row) { /* Merge with the stored line */ if(screen->damaged.start_col > rect.start_col) screen->damaged.start_col = rect.start_col; if(screen->damaged.end_col < rect.end_col) screen->damaged.end_col = rect.end_col; return; } else { /* Emit the currently stored line, store a new one */ emit = screen->damaged; screen->damaged = rect; } break; case VTERM_DAMAGE_SCREEN: case VTERM_DAMAGE_SCROLL: /* Never emit damage event */ if(screen->damaged.start_row == -1) screen->damaged = rect; else { rect_expand(&screen->damaged, &rect); } return; default: DEBUG_LOG1("TODO: Maybe merge damage for level %d\n", screen->damage_merge); return; } if(screen->callbacks && screen->callbacks->damage) (*screen->callbacks->damage)(emit, screen->cbdata); }