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:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-05-06 12:48:07 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-05-06 12:49:09 +0300
commitef0c02cb4dbd5f74fd0cb7c7ef119e4ca1936249 (patch)
tree1000d42908297b93b1f767209438bc88ef3f5f18 /source/blender/imbuf
parent204f55c189d7e7a7b7808b6730a285326e7ac38a (diff)
Speedup of regular 2D painting
Yet another commit which makes painting aware of multi-threaded systems.
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/IMB_imbuf.h17
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c81
-rw-r--r--source/blender/imbuf/intern/rectop.c63
3 files changed, 125 insertions, 36 deletions
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 383a5f19c4a..93d2b3e0cd0 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -130,7 +130,18 @@ void IMB_freeImBuf(struct ImBuf *ibuf);
* \attention Defined in allocimbuf.c
*/
struct ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y,
- unsigned char d, unsigned int flags);
+ unsigned char planes, unsigned int flags);
+
+/**
+ * Initialize given ImBuf.
+ *
+ * Use in cases when temporary image buffer is allocated on stack.
+ *
+ * \attention Defined in allocimbuf.c
+ */
+bool IMB_initImBuf(struct ImBuf *ibuf,
+ unsigned int x, unsigned int y,
+ unsigned char planes, unsigned int flags);
/**
* Create a copy of a pixel buffer and wrap it to a new ImBuf
@@ -213,6 +224,10 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *obuf, struct ImBuf *sbuf,
unsigned short *dmask, unsigned short *curvemask, unsigned short *mmask, float mask_max,
int destx, int desty, int origx, int origy, int srcx, int srcy,
int width, int height, IMB_BlendMode mode, bool accumulate);
+void IMB_rectblend_threaded(struct ImBuf *dbuf, struct ImBuf *obuf, struct ImBuf *sbuf,
+ unsigned short *dmask, unsigned short *curvemask, unsigned short *mmask, float mask_max,
+ int destx, int desty, int origx, int origy, int srcx, int srcy,
+ int width, int height, IMB_BlendMode mode, bool accumulate);
/**
*
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 988f43ff9fa..ef3743d9c8a 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -446,49 +446,60 @@ ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int
{
ImBuf *ibuf;
- ibuf = MEM_callocN(sizeof(ImBuf), "ImBuf_struct");
+ ibuf = MEM_mallocN(sizeof(ImBuf), "ImBuf_struct");
if (ibuf) {
- ibuf->x = x;
- ibuf->y = y;
- ibuf->planes = planes;
- ibuf->ftype = IMB_FTYPE_PNG;
- ibuf->foptions.quality = 15; /* the 15 means, set compression to low ratio but not time consuming */
- ibuf->channels = 4; /* float option, is set to other values when buffers get assigned */
- ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
-
- if (flags & IB_rect) {
- if (imb_addrectImBuf(ibuf) == false) {
- IMB_freeImBuf(ibuf);
- return NULL;
- }
+ if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
+ IMB_freeImBuf(ibuf);
+ return NULL;
}
-
- if (flags & IB_rectfloat) {
- if (imb_addrectfloatImBuf(ibuf) == false) {
- IMB_freeImBuf(ibuf);
- return NULL;
- }
+ }
+
+ return (ibuf);
+}
+
+bool IMB_initImBuf(struct ImBuf *ibuf,
+ unsigned int x, unsigned int y,
+ unsigned char planes, unsigned int flags)
+{
+ memset(ibuf, 0, sizeof(ImBuf));
+
+ ibuf->x = x;
+ ibuf->y = y;
+ ibuf->planes = planes;
+ ibuf->ftype = IMB_FTYPE_PNG;
+ ibuf->foptions.quality = 15; /* the 15 means, set compression to low ratio but not time consuming */
+ ibuf->channels = 4; /* float option, is set to other values when buffers get assigned */
+ ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
+
+ if (flags & IB_rect) {
+ if (imb_addrectImBuf(ibuf) == false) {
+ return false;
}
-
- if (flags & IB_zbuf) {
- if (addzbufImBuf(ibuf) == false) {
- IMB_freeImBuf(ibuf);
- return NULL;
- }
+ }
+
+ if (flags & IB_rectfloat) {
+ if (imb_addrectfloatImBuf(ibuf) == false) {
+ return false;
}
-
- if (flags & IB_zbuffloat) {
- if (addzbuffloatImBuf(ibuf) == false) {
- IMB_freeImBuf(ibuf);
- return NULL;
- }
+ }
+
+ if (flags & IB_zbuf) {
+ if (addzbufImBuf(ibuf) == false) {
+ return false;
}
+ }
- /* assign default spaces */
- colormanage_imbuf_set_default_spaces(ibuf);
+ if (flags & IB_zbuffloat) {
+ if (addzbuffloatImBuf(ibuf) == false) {
+ return false;
+ }
}
- return (ibuf);
+
+ /* assign default spaces */
+ colormanage_imbuf_set_default_spaces(ibuf);
+
+ return true;
}
/* does no zbuffers? */
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index c7b347cb20c..3360fd7548e 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -693,6 +693,69 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
}
}
+typedef struct RectBlendThreadData {
+ ImBuf *dbuf, *obuf, *sbuf;
+ unsigned short *dmask, *curvemask, *texmask;
+ float mask_max;
+ int destx, desty, origx, origy;
+ int srcx, srcy, width;
+ IMB_BlendMode mode;
+ bool accumulate;
+} RectBlendThreadData;
+
+static void rectblend_thread_do(void *data_v,
+ int start_scanline,
+ int num_scanlines)
+{
+ RectBlendThreadData *data = (RectBlendThreadData *)data_v;
+ IMB_rectblend(data->dbuf, data->obuf, data->sbuf,
+ data->dmask, data->curvemask, data->texmask,
+ data->mask_max,
+ data->destx,
+ data->desty + start_scanline,
+ data->origx,
+ data->origy + start_scanline,
+ data->srcx,
+ data->srcy + start_scanline,
+ data->width, num_scanlines,
+ data->mode, data->accumulate);
+}
+
+void IMB_rectblend_threaded(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf,
+ unsigned short *dmask, unsigned short *curvemask,
+ unsigned short *texmask, float mask_max,
+ int destx, int desty, int origx, int origy,
+ int srcx, int srcy, int width, int height,
+ IMB_BlendMode mode, bool accumulate)
+{
+ if (((size_t)width) * height < 64 * 64) {
+ IMB_rectblend(dbuf, obuf, sbuf, dmask, curvemask, texmask,
+ mask_max, destx, desty, origx, origy,
+ srcx, srcy, width, height, mode, accumulate);
+ }
+ else {
+ RectBlendThreadData data;
+ data.dbuf = dbuf;
+ data.obuf = obuf;
+ data.sbuf = sbuf;
+ data.dmask = dmask;
+ data.curvemask = curvemask;
+ data.texmask = texmask;
+ data.mask_max = mask_max;
+ data.destx = destx;
+ data.desty = desty;
+ data.origx = origx;
+ data.origy = origy;
+ data.srcx = srcx;
+ data.srcy = srcy;
+ data.width = width;
+ data.mode = mode;
+ data.accumulate = accumulate;
+ IMB_processor_apply_threaded_scanlines(
+ height, rectblend_thread_do, &data);
+ }
+}
+
/* fill */
void IMB_rectfill(ImBuf *drect, const float col[4])