From 7009358d2556c9d38b9c1851db0e7aa4f33e7783 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Thu, 12 May 2016 23:15:24 -0700 Subject: [PATCH] Progress on better WebGL support in Image --- lime/graphics/Image.hx | 25 ++--- lime/graphics/utils/ImageCanvasUtil.hx | 129 +++++++++++++++++-------- lime/graphics/utils/ImageDataUtil.hx | 24 +++++ 3 files changed, 128 insertions(+), 50 deletions(-) diff --git a/lime/graphics/Image.hx b/lime/graphics/Image.hx index f587a63ea..31ff47de8 100644 --- a/lime/graphics/Image.hx +++ b/lime/graphics/Image.hx @@ -80,6 +80,7 @@ class Image { public var src (get, set):Dynamic; public var transparent (get, set):Bool; public var type:ImageType; + public var version:Int; public var width:Int; public var x:Float; public var y:Float; @@ -92,6 +93,8 @@ class Image { this.width = width; this.height = height; + version = 0; + if (type == null) { if (Application.current != null && Application.current.renderer != null) { @@ -169,15 +172,13 @@ class Image { if (buffer != null) { - if (type == CANVAS && buffer.__srcImage == null) { - - ImageCanvasUtil.convertToCanvas (this); - ImageCanvasUtil.sync (this, true); - - } + #if (js && html5) + ImageCanvasUtil.sync (this, true); + #end var image = new Image (buffer.clone (), offsetX, offsetY, width, height, null, type); image.dirty = dirty; + image.version = version; return image; } else { @@ -496,7 +497,9 @@ class Image { if (canvas == null) return null; var buffer = new ImageBuffer (null, canvas.width, canvas.height); buffer.src = canvas; - return new Image (buffer); + var image = new Image (buffer); + image.type = CANVAS; + return image; } @@ -519,7 +522,9 @@ class Image { if (image == null) return null; var buffer = new ImageBuffer (null, image.width, image.height); buffer.src = image; - return new Image (buffer); + var _image = new Image (buffer); + _image.type = CANVAS; + return _image; } @@ -1399,9 +1404,7 @@ class Image { #if (js && html5) - ImageCanvasUtil.convertToCanvas (this); - ImageCanvasUtil.sync (this, false); - ImageCanvasUtil.createImageData (this); + ImageCanvasUtil.convertToData (this); #elseif flash diff --git a/lime/graphics/utils/ImageCanvasUtil.hx b/lime/graphics/utils/ImageCanvasUtil.hx index 448c8dfbb..e4743cd94 100644 --- a/lime/graphics/utils/ImageCanvasUtil.hx +++ b/lime/graphics/utils/ImageCanvasUtil.hx @@ -23,8 +23,7 @@ class ImageCanvasUtil { public static function colorTransform (image:Image, rect:Rectangle, colorMatrix:ColorMatrix):Void { - convertToCanvas (image); - createImageData (image); + convertToData (image); ImageDataUtil.colorTransform (image, rect, colorMatrix); @@ -48,15 +47,30 @@ class ImageCanvasUtil { } else if (buffer.data != null && buffer.__srcCanvas == null) { + image.transparent = true; createCanvas (image, buffer.width, buffer.height); createImageData (image); + buffer.__srcContext.putImageData (buffer.__srcImageData, 0, 0); + } else if (buffer.data == null && buffer.__srcImageData != null) { buffer.data = cast buffer.__srcImageData.data; } + if (image.type == CANVAS) { + + image.dirty = false; + + } else { + + image.type = CANVAS; + + sync (image, false); + + } + } @@ -66,13 +80,16 @@ class ImageCanvasUtil { if (image.buffer.data == null) { convertToCanvas (image); - sync (image, false); - createImageData (image); + image.type = DATA; + image.dirty = true; - image.buffer.__srcCanvas = null; - image.buffer.__srcContext = null; + } else if (image.type == DATA) { + + image.dirty = false; } + + sync (image, false); #end } @@ -80,10 +97,8 @@ class ImageCanvasUtil { public static function copyChannel (image:Image, sourceImage:Image, sourceRect:Rectangle, destPoint:Vector2, sourceChannel:ImageChannel, destChannel:ImageChannel):Void { - convertToCanvas (sourceImage); - createImageData (sourceImage); - convertToCanvas (image); - createImageData (image); + convertToData (sourceImage); + convertToData (image); ImageDataUtil.copyChannel (image, sourceImage, sourceRect, destPoint, sourceChannel, destChannel); @@ -130,6 +145,9 @@ class ImageCanvasUtil { } + image.dirty = true; + image.version++; + } @@ -231,13 +249,15 @@ class ImageCanvasUtil { image.buffer.__srcContext.fillStyle = 'rgba(' + r + ', ' + g + ', ' + b + ', ' + (a / 255) + ')'; image.buffer.__srcContext.fillRect (rect.x + image.offsetX, rect.y + image.offsetY, rect.width + image.offsetX, rect.height + image.offsetY); + image.dirty = true; + image.version++; + } public static function floodFill (image:Image, x:Int, y:Int, color:Int, format:PixelFormat):Void { - convertToCanvas (image); - createImageData (image); + convertToData (image); ImageDataUtil.floodFill (image, x, y, color, format); @@ -246,8 +266,7 @@ class ImageCanvasUtil { public static function getPixel (image:Image, x:Int, y:Int, format:PixelFormat):Int { - convertToCanvas (image); - createImageData (image); + convertToData (image); return ImageDataUtil.getPixel (image, x, y, format); @@ -256,8 +275,7 @@ class ImageCanvasUtil { public static function getPixel32 (image:Image, x:Int, y:Int, format:PixelFormat):Int { - convertToCanvas (image); - createImageData (image); + convertToData (image); return ImageDataUtil.getPixel32 (image, x, y, format); @@ -266,8 +284,7 @@ class ImageCanvasUtil { public static function getPixels (image:Image, rect:Rectangle, format:PixelFormat):Bytes { - convertToCanvas (image); - createImageData (image); + convertToData (image); return ImageDataUtil.getPixels (image, rect, format); @@ -276,10 +293,8 @@ class ImageCanvasUtil { public static function merge (image:Image, sourceImage:Image, sourceRect:Rectangle, destPoint:Vector2, redMultiplier:Int, greenMultiplier:Int, blueMultiplier:Int, alphaMultiplier:Int):Void { - convertToCanvas (sourceImage); - createImageData (sourceImage); - convertToCanvas (image); - createImageData (image); + convertToData (sourceImage); + convertToData (image); ImageDataUtil.merge (image, sourceImage, sourceRect, destPoint, redMultiplier, greenMultiplier, blueMultiplier, alphaMultiplier); @@ -305,6 +320,12 @@ class ImageCanvasUtil { } + buffer.__srcImageData = null; + buffer.data = null; + + image.dirty = true; + image.version++; + } @@ -318,13 +339,15 @@ class ImageCanvasUtil { image.buffer.__srcContext.clearRect (x, y, image.width, image.height); image.buffer.__srcContext.drawImage (image.buffer.__srcCanvas, x, y); + image.dirty = true; + image.version++; + } public static function setPixel (image:Image, x:Int, y:Int, color:Int, format:PixelFormat):Void { - convertToCanvas (image); - createImageData (image); + convertToData (image); ImageDataUtil.setPixel (image, x, y, color, format); @@ -333,8 +356,7 @@ class ImageCanvasUtil { public static function setPixel32 (image:Image, x:Int, y:Int, color:Int, format:PixelFormat):Void { - convertToCanvas (image); - createImageData (image); + convertToData (image); ImageDataUtil.setPixel32 (image, x, y, color, format); @@ -343,8 +365,7 @@ class ImageCanvasUtil { public static function setPixels (image:Image, rect:Rectangle, bytes:Bytes, format:PixelFormat):Void { - convertToCanvas (image); - createImageData (image); + convertToData (image); ImageDataUtil.setPixels (image, rect, bytes, format); @@ -354,23 +375,53 @@ class ImageCanvasUtil { public static function sync (image:Image, clear:Bool):Void { #if (js && html5) - if (image.dirty && image.buffer.__srcImageData != null && image.type != DATA) { + if (image.dirty) { + + var buffer = image.buffer; + + if (buffer.__srcImageData != null && image.type != DATA) { + + buffer.__srcContext.putImageData (buffer.__srcImageData, 0, 0); + buffer.data = null; + image.dirty = false; + + image.type = CANVAS; + + if (clear) { + + buffer.__srcImageData = null; + buffer.data = null; + + } + + } else if (buffer.__srcContext != null && image.type == DATA) { + + if (buffer.__srcImageData == null) { + + createImageData (image); + + } else { + + buffer.__srcImageData = buffer.__srcContext.getImageData (0, 0, buffer.width, buffer.height); + buffer.data = new UInt8Array (cast buffer.__srcImageData.data.buffer); + + } + + if (clear) { + + buffer.__srcCanvas = null; + buffer.__srcContext = null; + + } + + } - image.buffer.__srcContext.putImageData (image.buffer.__srcImageData, 0, 0); - image.buffer.data = null; image.dirty = false; - } - - if (clear) { - - image.buffer.__srcImageData = null; - image.buffer.data = null; - } #end } -} +} \ No newline at end of file diff --git a/lime/graphics/utils/ImageDataUtil.hx b/lime/graphics/utils/ImageDataUtil.hx index 6772e6e0b..8698c5e4b 100644 --- a/lime/graphics/utils/ImageDataUtil.hx +++ b/lime/graphics/utils/ImageDataUtil.hx @@ -20,6 +20,7 @@ import lime.utils.UInt8Array; @:build(lime.system.CFFI.build()) #end +@:access(lime.graphics.ImageBuffer) @:access(lime.math.color.RGBA) @@ -67,6 +68,7 @@ class ImageDataUtil { } image.dirty = true; + image.version++; } @@ -151,6 +153,7 @@ class ImageDataUtil { } image.dirty = true; + image.version++; } @@ -297,6 +300,7 @@ class ImageDataUtil { } image.dirty = true; + image.version++; } @@ -348,6 +352,7 @@ class ImageDataUtil { } image.dirty = true; + image.version++; } @@ -430,6 +435,7 @@ class ImageDataUtil { } image.dirty = true; + image.version++; } @@ -738,6 +744,7 @@ class ImageDataUtil { } image.dirty = true; + image.version++; } @@ -767,6 +774,7 @@ class ImageDataUtil { image.buffer.premultiplied = true; image.dirty = true; + image.version++; } @@ -841,6 +849,16 @@ class ImageDataUtil { buffer.width = newWidth; buffer.height = newHeight; + #if (js && html5) + buffer.__srcImage = null; + buffer.__srcImageData = null; + buffer.__srcCanvas = null; + buffer.__srcContext = null; + #end + + image.dirty = true; + image.version++; + } @@ -959,6 +977,7 @@ class ImageDataUtil { image.buffer.format = format; image.dirty = true; + image.version++; } @@ -984,6 +1003,7 @@ class ImageDataUtil { pixel.writeUInt8 (image.buffer.data, (4 * (y + image.offsetY) * image.buffer.width + (x + image.offsetX) * 4), image.buffer.format, image.buffer.premultiplied); image.dirty = true; + image.version++; } @@ -1004,6 +1024,7 @@ class ImageDataUtil { pixel.writeUInt8 (image.buffer.data, (4 * (y + image.offsetY) * image.buffer.width + (x + image.offsetX) * 4), image.buffer.format, image.buffer.premultiplied); image.dirty = true; + image.version++; } @@ -1053,6 +1074,7 @@ class ImageDataUtil { } image.dirty = true; + image.version++; } @@ -1167,6 +1189,7 @@ class ImageDataUtil { if (hits > 0) { image.dirty = true; + image.version++; } @@ -1200,6 +1223,7 @@ class ImageDataUtil { image.buffer.premultiplied = false; image.dirty = true; + image.version++; }