From 23f7134fd4987bb8a2558ecd7301166b8c96360d Mon Sep 17 00:00:00 2001 From: treeform Date: Fri, 20 Nov 2020 20:08:57 -0800 Subject: [PATCH] Bench: inplace draw vs copy draw. --- src/pixie/images.nim | 57 ++++++++++++++++++++++++----------- tests/benchmark_images.nim | 40 ++++++++++++++++++++++++ tests/images/copyDraw.bmp | Bin 0 -> 40122 bytes tests/images/inplaceDraw.bmp | Bin 0 -> 40122 bytes 4 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 tests/benchmark_images.nim create mode 100644 tests/images/copyDraw.bmp create mode 100644 tests/images/inplaceDraw.bmp diff --git a/src/pixie/images.nim b/src/pixie/images.nim index 0adbc21..5492cc7 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -238,6 +238,21 @@ proc hasEffect*(blendMode: BlendMode, rgba: ColorRGBA): bool = else: rgba.a > 0 +proc drawBlendIntegerPos*( + destImage, srcImage: Image, pos = vec2(0, 0), blendMode = Normal, +) = + ## Fast draw of dest + fill using offset with color blending. + for y in 0 ..< srcImage.height: + for x in 0 ..< srcImage.width: + let + srcRgba = srcImage.getRgbaUnsafe(x, y) + if blendMode.hasEffect(srcRgba): + let + destRgba = destImage.getRgbaUnsafe(x + pos.x.int, y + pos.y.int) + rgba = blendMode.mix(destRgba, srcRgba) + # TODO: Make unsafe + destImage[x + pos.x.int, y + pos.y.int] = rgba + proc draw*(destImage: Image, srcImage: Image, mat: Mat4, blendMode = Normal) = ## Draws one image onto another using matrix with color blending. var srcImage = srcImage @@ -280,28 +295,34 @@ proc draw*(destImage: Image, srcImage: Image, mat: Mat4, blendMode = Normal) = for y in yStart ..< yEnd: for x in xStart ..< xEnd: let srcV = start + stepX * float32(x) + stepY * float32(y) - if srcImage.inside(int srcV.x, int srcV.y): + if srcImage.inside(int srcV.x.floor, int srcV.y.floor): let srcRgba = srcImage.getRgbaSmooth(srcV.x - 0.5, srcV.y - 0.5) - let - destRgba = destImage.getRgbaUnsafe(x, y) - color = blendMode.mix(destRgba.color, srcRgba.color) - destImage.setRgbaUnsafe(x, y, color.rgba) + if blendMode.hasEffect(srcRgba): + let + destRgba = destImage.getRgbaUnsafe(x, y) + color = blendMode.mix(destRgba, srcRgba) + destImage.setRgbaUnsafe(x, y, color) -proc draw*( - destImage, srcImage: Image, pos = vec2(0, 0), blendMode = Normal, -) = - ## Fast draw of dest + fill using offset with color blending. - for y in 0 ..< srcImage.height: - for x in 0 ..< srcImage.width: - let - srcRgba = srcImage.getRgbaUnsafe(x, y) +proc gpuDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = Normal): Image = + ## Draws one image onto another using matrix with color blending. + result = newImage(destImage.width, destImage.height) + for y in 0 .. result.width: + for x in 0 .. result.height: + let srcPos = mat * vec2(x.float32, y.float32) + var destRgba = destImage.getRgbaUnsafe(x, y) + var srcRgba = rgba(0, 0, 0, 0) + if srcImage.inside(srcPos.x.floor.int, srcPos.y.floor.int): + srcRgba = srcImage.getRgbaSmooth(srcPos.x - 0.5, srcPos.y - 0.5) if blendMode.hasEffect(srcRgba): - let - destRgba = destImage.getRgbaUnsafe(x + pos.x.int, y + pos.y.int) - rgba = blendMode.mix(destRgba, srcRgba) - # TODO: Make unsafe - destImage[x + pos.x.int, y + pos.y.int] = rgba + destRgba = blendMode.mix(destRgba, srcRgba) + result.setRgbaUnsafe(x, y, destRgba) + +proc draw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal) = + destImage.draw(srcImage, translate(vec3(pos.x, pos.y, 0)), blendMode) + +proc gpuDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal): Image = + destImage.gpuDraw(srcImage, translate(-pos), blendMode) ## Thoughts ## single draw function that takes a matrix diff --git a/tests/benchmark_images.nim b/tests/benchmark_images.nim new file mode 100644 index 0000000..cc69961 --- /dev/null +++ b/tests/benchmark_images.nim @@ -0,0 +1,40 @@ +import pixie, chroma, vmath, fidget/opengl/perf, pixie/fileformats/bmp + +block: + var a = newImage(100, 100) + a.fill(rgba(255, 0, 0, 255)) + var b = newImage(100, 100) + b.fill(rgba(0, 255, 0, 255)) + a.draw(b, pos=vec2(25, 25)) + writeFile("tests/images/inplaceDraw.bmp", a.encodeBmp()) + +block: + var a = newImage(100, 100) + a.fill(rgba(255, 0, 0, 255)) + var b = newImage(100, 100) + b.fill(rgba(0, 255, 0, 255)) + var c = a.gpuDraw(b, pos=vec2(25, 25)) + writeFile("tests/images/copyDraw.bmp", c.encodeBmp()) + + +timeIt "inplaceDraw": + var tmp = 0 + for i in 0 ..< 1000: + var a = newImage(100, 100) + a.fill(rgba(255, 0, 0, 255)) + var b = newImage(100, 100) + b.fill(rgba(0, 255, 0, 255)) + a.draw(b, pos=vec2(25, 25)) + tmp += a.width * a.height + echo tmp + +timeIt "copyDraw": + var tmp = 0 + for i in 0 ..< 1000: + var a = newImage(100, 100) + a.fill(rgba(255, 0, 0, 255)) + var b = newImage(100, 100) + b.fill(rgba(0, 255, 0, 255)) + var c = a.gpuDraw(b, pos=vec2(25, 25)) + tmp += c.width * c.height + echo tmp diff --git a/tests/images/copyDraw.bmp b/tests/images/copyDraw.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bed31be741a0047d5f0cf9687aa4c742429414f0 GIT binary patch literal 40122 zcmeI5v5mq&00fN)KcoTILQeb*e1e21fLf@8=J>-95DtMSVX)4!#KNMP&DkGr*J*iO z#{D$T-|K9qdD@QWd7RzP^Nh#kb${I7ZokL#yu9(jZG8N`_8Gsi3ldn{#pCfJ`BpdBOjcVk<5odnRn!avoezTFevkmd~jAq zG9LzI-jNT^%1GwJpv*h+!C4u}d>E8@M?N?!Bbg6_GVjO-XJsVwVNm8B`QWUKWIhba zydxi+m66PcL78{tgR?S{`7kK+j(l)dMlv4;W!{kw&dNyU!=TJN^1)dd$$S`;c}G4t zD-95DtMSVX)4!#KNMP&DkGr*J*iO z#{D$T-|K9qdD@QWd7RzP^Nh#kb${I7ZokL#yu9(jZG8N`_8Gsi3ldn{#pCfJ`BpdBOjcVk<5odnRn!avoezTFevkmd~jAq zG9LzI-jNT^%1GwJpv*h+!C4u}d>E8@M?N?!Bbg6_GVjO-XJsVwVNm8B`QWUKWIhba zydxi+m66PcL78{tgR?S{`7kK+j(l)dMlv4;W!{kw&dNyU!=TJN^1)dd$$S`;c}G4t zD