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:
authorBastien Montagne <montagne29@wanadoo.fr>2016-01-17 19:16:57 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-01-17 19:17:28 +0300
commita5c419f4ccb19b0c01f3cbf5929f8a43bc503eff (patch)
tree7653bffbe098f561f3ecfc9fe73b4d850b713c37
parent5a20df6336afffc0aeb41fdc2464a11baf55c9f3 (diff)
paint_cursor: OMP -> BLI_task.
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c290
1 files changed, 151 insertions, 139 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index f57255aff61..8dc266750ed 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -32,6 +32,7 @@
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BLI_task.h"
#include "BLI_utildefines.h"
#include "DNA_brush_types.h"
@@ -139,6 +140,112 @@ static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
snap->winy = vc->ar->winy;
}
+typedef struct LoadTexData {
+ Brush *br;
+ ViewContext *vc;
+
+ MTex *mtex;
+ GLubyte *buffer;
+ bool col;
+
+ struct ImagePool *pool;
+ int size;
+ float rotation;
+ float radius;
+} LoadTexData;
+
+static void load_tex_task_cb_ex(void *userdata, void *UNUSED(userdata_chunck), const int j, const int thread_id)
+{
+ LoadTexData *data = userdata;
+ Brush *br = data->br;
+ ViewContext *vc = data->vc;
+
+ MTex *mtex = data->mtex;
+ GLubyte *buffer = data->buffer;
+ const bool col = data->col;
+
+ struct ImagePool *pool = data->pool;
+ const int size = data->size;
+ const float rotation = data->rotation;
+ const float radius = data->radius;
+
+ bool convert_to_linear = false;
+ struct ColorSpace *colorspace = NULL;
+
+ if (mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
+ ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
+ /* For consistency, sampling always returns color in linear space */
+ if (tex_ibuf && tex_ibuf->rect_float == NULL) {
+ convert_to_linear = true;
+ colorspace = tex_ibuf->rect_colorspace;
+ }
+ BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
+ }
+
+ for (int i = 0; i < size; i++) {
+ // largely duplicated from tex_strength
+
+ int index = j * size + i;
+
+ float x = (float)i / size;
+ float y = (float)j / size;
+ float len;
+
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
+ x *= vc->ar->winx / radius;
+ y *= vc->ar->winy / radius;
+ }
+ else {
+ x = (x - 0.5f) * 2.0f;
+ y = (y - 0.5f) * 2.0f;
+ }
+
+ len = sqrtf(x * x + y * y);
+
+ if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1.0f) {
+ /* it is probably worth optimizing for those cases where the texture is not rotated by skipping the calls to
+ * atan2, sqrtf, sin, and cos. */
+ if (mtex->tex && (rotation > 0.001f || rotation < -0.001f)) {
+ const float angle = atan2f(y, x) + rotation;
+
+ x = len * cosf(angle);
+ y = len * sinf(angle);
+ }
+
+ if (col) {
+ float rgba[4];
+
+ paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_id, convert_to_linear, colorspace);
+
+ buffer[index * 4] = rgba[0] * 255;
+ buffer[index * 4 + 1] = rgba[1] * 255;
+ buffer[index * 4 + 2] = rgba[2] * 255;
+ buffer[index * 4 + 3] = rgba[3] * 255;
+ }
+ else {
+ float avg = paint_get_tex_pixel(mtex, x, y, pool, thread_id);
+
+ avg += br->texture_sample_bias;
+
+ /* clamp to avoid precision overflow */
+ CLAMP(avg, 0.0f, 1.0f);
+ buffer[index] = 255 - (GLubyte)(255 * avg);
+ }
+ }
+ else {
+ if (col) {
+ buffer[index * 4] = 0;
+ buffer[index * 4 + 1] = 0;
+ buffer[index * 4 + 2] = 0;
+ buffer[index * 4 + 3] = 0;
+ }
+ else {
+ buffer[index] = 0;
+ }
+ }
+ }
+}
+
static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
{
bool init;
@@ -149,10 +256,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
GLubyte *buffer = NULL;
int size;
- int j;
- int refresh;
+ bool refresh;
OverlayControlFlags invalid = (primary) ? (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY) :
- (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY);
+ (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY);
target = (primary) ? &primary_snap : &secondary_snap;
@@ -165,13 +271,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
if (refresh) {
struct ImagePool *pool = NULL;
- bool convert_to_linear = false;
- struct ColorSpace *colorspace;
/* stencil is rotated later */
- const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
- -mtex->rot : 0;
-
- float radius = BKE_brush_size_get(vc->scene, br) * zoom;
+ const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ? -mtex->rot : 0.0f;
+ const float radius = BKE_brush_size_get(vc->scene, br) * zoom;
make_tex_snap(target, vc, zoom);
@@ -190,8 +292,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
if (size < target->old_size)
size = target->old_size;
}
- else
+ else {
size = 512;
+ }
if (target->old_size != size) {
if (target->overlay_texture) {
@@ -213,98 +316,12 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
if (mtex->tex && mtex->tex->nodetree)
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
-#pragma omp parallel for schedule(static)
- for (j = 0; j < size; j++) {
- int i;
- float y;
- float len;
- int thread_num;
-
-#ifdef _OPENMP
- thread_num = omp_get_thread_num();
-#else
- thread_num = 0;
-#endif
-
- if (mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
- ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
- /* For consistency, sampling always returns color in linear space */
- if (tex_ibuf && tex_ibuf->rect_float == NULL) {
- convert_to_linear = true;
- colorspace = tex_ibuf->rect_colorspace;
- }
- BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
- }
-
+ LoadTexData data = {
+ .br = br, .vc = vc, .mtex = mtex, .buffer = buffer, .col = col,
+ .pool = pool, .size = size, .rotation = rotation, .radius = radius,
+ };
- for (i = 0; i < size; i++) {
-
- // largely duplicated from tex_strength
-
- int index = j * size + i;
- float x;
-
- x = (float)i / size;
- y = (float)j / size;
-
- if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
- x *= vc->ar->winx / radius;
- y *= vc->ar->winy / radius;
- }
- else {
- x -= 0.5f;
- y -= 0.5f;
-
- x *= 2;
- y *= 2;
- }
-
- len = sqrtf(x * x + y * y);
-
- if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1) {
- /* it is probably worth optimizing for those cases where
- * the texture is not rotated by skipping the calls to
- * atan2, sqrtf, sin, and cos. */
- if (mtex->tex && (rotation > 0.001f || rotation < -0.001f)) {
- const float angle = atan2f(y, x) + rotation;
-
- x = len * cosf(angle);
- y = len * sinf(angle);
- }
-
- if (col) {
- float rgba[4];
-
- paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_num, convert_to_linear, colorspace);
-
- buffer[index * 4] = rgba[0] * 255;
- buffer[index * 4 + 1] = rgba[1] * 255;
- buffer[index * 4 + 2] = rgba[2] * 255;
- buffer[index * 4 + 3] = rgba[3] * 255;
- }
- else {
- float avg = paint_get_tex_pixel(mtex, x, y, pool, thread_num);
-
- avg += br->texture_sample_bias;
-
- /* clamp to avoid precision overflow */
- CLAMP(avg, 0.0f, 1.0f);
- buffer[index] = 255 - (GLubyte)(255 * avg);
- }
- }
- else {
- if (col) {
- buffer[index * 4] = 0;
- buffer[index * 4 + 1] = 0;
- buffer[index * 4 + 2] = 0;
- buffer[index * 4 + 3] = 0;
- }
- else {
- buffer[index] = 0;
- }
- }
- }
- }
+ BLI_task_parallel_range_ex(0, size, &data, NULL, 0, load_tex_task_cb_ex, true, false);
if (mtex->tex && mtex->tex->nodetree)
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
@@ -353,6 +370,34 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
return 1;
}
+static void load_tex_cursor_task_cb(void *userdata, const int j)
+{
+ LoadTexData *data = userdata;
+ Brush *br = data->br;
+
+ GLubyte *buffer = data->buffer;
+
+ const int size = data->size;
+
+ for (int i = 0; i < size; i++) {
+ // largely duplicated from tex_strength
+
+ const int index = j * size + i;
+ const float x = (((float)i / size) - 0.5f) * 2.0f;
+ const float y = (((float)j / size) - 0.5f) * 2.0f;
+ const float len = sqrtf(x * x + y * y);
+
+ if (len <= 1.0f) {
+ float avg = BKE_brush_curve_strength_clamped(br, len, 1.0f); /* Falloff curve */
+
+ buffer[index] = 255 - (GLubyte)(255 * avg);
+ }
+ else {
+ buffer[index] = 0;
+ }
+ }
+}
+
static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
{
bool init;
@@ -361,10 +406,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
GLubyte *buffer = NULL;
int size;
- int j;
- int refresh;
-
- refresh =
+ const bool refresh =
!cursor_snap.overlay_texture ||
(overlay_flags & PAINT_INVALID_OVERLAY_CURVE) ||
cursor_snap.zoom != zoom;
@@ -404,41 +446,11 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
curvemapping_initialize(br->curve);
-#pragma omp parallel for schedule(static)
- for (j = 0; j < size; j++) {
- int i;
- float y;
- float len;
-
- for (i = 0; i < size; i++) {
-
- // largely duplicated from tex_strength
+ LoadTexData data = {
+ .br = br, .buffer = buffer, .size = size,
+ };
- int index = j * size + i;
- float x;
-
- x = (float)i / size;
- y = (float)j / size;
-
- x -= 0.5f;
- y -= 0.5f;
-
- x *= 2;
- y *= 2;
-
- len = sqrtf(x * x + y * y);
-
- if (len <= 1) {
- float avg = BKE_brush_curve_strength_clamped(br, len, 1.0f); /* Falloff curve */
-
- buffer[index] = 255 - (GLubyte)(255 * avg);
-
- }
- else {
- buffer[index] = 0;
- }
- }
- }
+ BLI_task_parallel_range(0, size, &data, load_tex_cursor_task_cb, true);
if (!cursor_snap.overlay_texture)
glGenTextures(1, &cursor_snap.overlay_texture);