865 lines
29 KiB
Haxe
865 lines
29 KiB
Haxe
package openfl.display;
|
|
|
|
#if !flash
|
|
import openfl.display._internal.Context3DGraphics;
|
|
import openfl.display.Bitmap;
|
|
import openfl.display.DisplayObject;
|
|
import openfl.display.Tilemap;
|
|
import openfl.events.EventDispatcher;
|
|
import openfl.events.RenderEvent;
|
|
import openfl.geom.ColorTransform;
|
|
import openfl.geom.Matrix;
|
|
import openfl.geom.Point;
|
|
import openfl.geom.Rectangle;
|
|
import openfl.text.TextField;
|
|
#if lime
|
|
import lime._internal.graphics.ImageCanvasUtil; // TODO
|
|
import lime.graphics.cairo.Cairo;
|
|
import lime.graphics.RenderContext;
|
|
import lime.graphics.RenderContextType;
|
|
#end
|
|
|
|
#if !openfl_debug
|
|
@:fileXml('tags="haxe,release"')
|
|
@:noDebug
|
|
#end
|
|
@:access(openfl.display._internal.Context3DGraphics)
|
|
@:access(lime.graphics.ImageBuffer)
|
|
@:access(openfl.display.Bitmap)
|
|
@:access(openfl.display.BitmapData)
|
|
@:access(openfl.display.DisplayObject)
|
|
@:access(openfl.display.Graphics)
|
|
@:access(openfl.display.Tilemap)
|
|
@:access(openfl.display3D.Context3D)
|
|
@:access(openfl.events.RenderEvent)
|
|
@:access(openfl.filters.BitmapFilter)
|
|
@:access(openfl.geom.ColorTransform)
|
|
@:access(openfl.geom.Rectangle)
|
|
@:access(openfl.geom.Transform)
|
|
@:access(openfl.text.TextField)
|
|
@:allow(openfl.display._internal)
|
|
@:allow(openfl.display)
|
|
@:allow(openfl.text)
|
|
class DisplayObjectRenderer extends EventDispatcher
|
|
{
|
|
@:noCompletion private var __allowSmoothing:Bool;
|
|
@:noCompletion private var __blendMode:BlendMode;
|
|
@:noCompletion private var __cleared:Bool;
|
|
@SuppressWarnings("checkstyle:Dynamic") @:noCompletion private var __context:#if lime RenderContext #else Dynamic #end;
|
|
@:noCompletion private var __overrideBlendMode:BlendMode;
|
|
@:noCompletion private var __pixelRatio:Float;
|
|
@:noCompletion private var __roundPixels:Bool;
|
|
@:noCompletion private var __stage:Stage;
|
|
@:noCompletion private var __tempColorTransform:ColorTransform;
|
|
@:noCompletion private var __transparent:Bool;
|
|
@SuppressWarnings("checkstyle:Dynamic") @:noCompletion private var __type:#if lime RenderContextType #else Dynamic #end;
|
|
@:noCompletion private var __worldAlpha:Float;
|
|
@:noCompletion private var __worldColorTransform:ColorTransform;
|
|
@:noCompletion private var __worldTransform:Matrix;
|
|
|
|
@:noCompletion private function new()
|
|
{
|
|
super();
|
|
|
|
__allowSmoothing = true;
|
|
__pixelRatio = 1;
|
|
__tempColorTransform = new ColorTransform();
|
|
__worldAlpha = 1;
|
|
}
|
|
|
|
@:noCompletion private function __clear():Void {}
|
|
|
|
@:noCompletion private function __getAlpha(value:Float):Float
|
|
{
|
|
return value * __worldAlpha;
|
|
}
|
|
|
|
@:noCompletion private function __getColorTransform(value:ColorTransform):ColorTransform
|
|
{
|
|
if (__worldColorTransform != null)
|
|
{
|
|
__tempColorTransform.__copyFrom(__worldColorTransform);
|
|
__tempColorTransform.__combine(value);
|
|
return __tempColorTransform;
|
|
}
|
|
else
|
|
{
|
|
return value;
|
|
}
|
|
}
|
|
|
|
@:noCompletion private function __popMask():Void {}
|
|
|
|
@:noCompletion private function __popMaskObject(object:DisplayObject, handleScrollRect:Bool = true):Void {}
|
|
|
|
@:noCompletion private function __popMaskRect():Void {}
|
|
|
|
@:noCompletion private function __pushMask(mask:DisplayObject):Void {}
|
|
|
|
@:noCompletion private function __pushMaskObject(object:DisplayObject, handleScrollRect:Bool = true):Void {}
|
|
|
|
@:noCompletion private function __pushMaskRect(rect:Rectangle, transform:Matrix):Void {}
|
|
|
|
@:noCompletion private function __render(object:IBitmapDrawable):Void {}
|
|
|
|
@:noCompletion private function __renderEvent(displayObject:DisplayObject):Void
|
|
{
|
|
var renderer = this;
|
|
#if lime
|
|
if (displayObject.__customRenderEvent != null && displayObject.__renderable)
|
|
{
|
|
displayObject.__customRenderEvent.allowSmoothing = renderer.__allowSmoothing;
|
|
displayObject.__customRenderEvent.objectMatrix.copyFrom(displayObject.__renderTransform);
|
|
displayObject.__customRenderEvent.objectColorTransform.__copyFrom(displayObject.__worldColorTransform);
|
|
displayObject.__customRenderEvent.renderer = renderer;
|
|
|
|
switch (renderer.__type)
|
|
{
|
|
case OPENGL:
|
|
if (!renderer.__cleared) renderer.__clear();
|
|
|
|
var renderer:OpenGLRenderer = cast renderer;
|
|
renderer.setShader(displayObject.__worldShader);
|
|
renderer.__context3D.__flushGL();
|
|
|
|
displayObject.__customRenderEvent.type = RenderEvent.RENDER_OPENGL;
|
|
|
|
case CAIRO:
|
|
displayObject.__customRenderEvent.type = RenderEvent.RENDER_CAIRO;
|
|
|
|
case DOM:
|
|
if (displayObject.stage != null && displayObject.__worldVisible)
|
|
{
|
|
displayObject.__customRenderEvent.type = RenderEvent.RENDER_DOM;
|
|
}
|
|
else
|
|
{
|
|
displayObject.__customRenderEvent.type = RenderEvent.CLEAR_DOM;
|
|
}
|
|
|
|
case CANVAS:
|
|
displayObject.__customRenderEvent.type = RenderEvent.RENDER_CANVAS;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
renderer.__setBlendMode(displayObject.__worldBlendMode);
|
|
renderer.__pushMaskObject(displayObject);
|
|
|
|
displayObject.dispatchEvent(displayObject.__customRenderEvent);
|
|
|
|
renderer.__popMaskObject(displayObject);
|
|
|
|
if (renderer.__type == OPENGL)
|
|
{
|
|
var renderer:OpenGLRenderer = cast renderer;
|
|
renderer.setViewport();
|
|
}
|
|
}
|
|
#end
|
|
}
|
|
|
|
@:noCompletion private function __resize(width:Int, height:Int):Void {}
|
|
|
|
@:noCompletion private function __setBlendMode(value:BlendMode):Void {}
|
|
|
|
@:noCompletion private function __shouldCacheHardware(displayObject:DisplayObject, value:Null<Bool>):Null<Bool>
|
|
{
|
|
if (displayObject == null) return null;
|
|
|
|
switch (displayObject.__drawableType)
|
|
{
|
|
case SPRITE, STAGE:
|
|
if (value == true) return true;
|
|
value = __shouldCacheHardware_DisplayObject(displayObject, value);
|
|
if (value == true) return true;
|
|
|
|
if (displayObject.__children != null)
|
|
{
|
|
for (child in displayObject.__children)
|
|
{
|
|
value = __shouldCacheHardware_DisplayObject(child, value);
|
|
if (value == true) return true;
|
|
}
|
|
}
|
|
|
|
return value;
|
|
|
|
case TEXT_FIELD:
|
|
return value == true ? true : false;
|
|
|
|
case TILEMAP:
|
|
return true;
|
|
|
|
default:
|
|
return __shouldCacheHardware_DisplayObject(displayObject, value);
|
|
}
|
|
}
|
|
|
|
@:noCompletion private function __shouldCacheHardware_DisplayObject(displayObject:DisplayObject, value:Null<Bool>):Null<Bool>
|
|
{
|
|
if (value == true || displayObject.__filters != null) return true;
|
|
|
|
if (value == false || (displayObject.__graphics != null && !Context3DGraphics.isCompatible(displayObject.__graphics)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@:noCompletion private function __updateCacheBitmap(displayObject:DisplayObject, force:Bool):Bool
|
|
{
|
|
if (displayObject == null) return false;
|
|
var renderer = this;
|
|
|
|
switch (displayObject.__drawableType)
|
|
{
|
|
case BITMAP:
|
|
var bitmap:Bitmap = cast displayObject;
|
|
// TODO: Handle filters without an intermediate draw
|
|
if (bitmap.__bitmapData == null
|
|
|| (bitmap.__filters == null #if lime && renderer.__type == OPENGL #end && bitmap.__cacheBitmap == null)) return false;
|
|
force = (bitmap.__bitmapData.image != null && bitmap.__bitmapData.image.version != bitmap.__imageVersion);
|
|
|
|
case TEXT_FIELD:
|
|
var textField:TextField = cast displayObject;
|
|
if (textField.__filters == null #if lime && renderer.__type == OPENGL #end && textField.__cacheBitmap == null
|
|
&& !textField.__domRender) return false;
|
|
if (force) textField.__renderDirty = true;
|
|
force = force || textField.__dirty;
|
|
|
|
case TILEMAP:
|
|
var tilemap:Tilemap = cast displayObject;
|
|
if (tilemap.__filters == null #if lime && renderer.__type == OPENGL #end && tilemap.__cacheBitmap == null) return false;
|
|
|
|
default:
|
|
}
|
|
|
|
#if lime
|
|
if (displayObject.__isCacheBitmapRender) return false;
|
|
#if openfl_disable_cacheasbitmap
|
|
return false;
|
|
#end
|
|
|
|
var colorTransform = ColorTransform.__pool.get();
|
|
colorTransform.__copyFrom(displayObject.__worldColorTransform);
|
|
if (renderer.__worldColorTransform != null) colorTransform.__combine(renderer.__worldColorTransform);
|
|
var updated = false;
|
|
|
|
// TODO: Do not force cacheAsBitmap on OpenGL once Scale-9 is properly supported in Context3DShape
|
|
if (displayObject.cacheAsBitmap
|
|
|| (renderer.__type != OPENGL && !colorTransform.__isDefault(true))
|
|
|| (renderer.__type == OPENGL && displayObject.scale9Grid != null))
|
|
{
|
|
var rect = null;
|
|
|
|
var needRender = (displayObject.__cacheBitmap == null
|
|
|| (displayObject.__renderDirty && (force || (displayObject.__children != null && displayObject.__children.length > 0)))
|
|
|| displayObject.opaqueBackground != displayObject.__cacheBitmapBackground);
|
|
var softwareDirty = needRender
|
|
|| (displayObject.__graphics != null && displayObject.__graphics.__softwareDirty)
|
|
|| !displayObject.__cacheBitmapColorTransform.__equals(colorTransform, true);
|
|
var hardwareDirty = needRender || (displayObject.__graphics != null && displayObject.__graphics.__hardwareDirty);
|
|
|
|
var renderType = renderer.__type;
|
|
|
|
if (softwareDirty || hardwareDirty)
|
|
{
|
|
#if !openfl_force_gl_cacheasbitmap
|
|
if (renderType == OPENGL)
|
|
{
|
|
if (#if !openfl_disable_gl_cacheasbitmap __shouldCacheHardware(displayObject, null) == false #else true #end)
|
|
{
|
|
#if (js && html5)
|
|
renderType = CANVAS;
|
|
#else
|
|
renderType = CAIRO;
|
|
#end
|
|
}
|
|
}
|
|
#end
|
|
|
|
if (softwareDirty && (renderType == CANVAS || renderType == CAIRO)) needRender = true;
|
|
if (hardwareDirty && renderType == OPENGL) needRender = true;
|
|
}
|
|
|
|
var updateTransform = (needRender || !displayObject.__cacheBitmap.__worldTransform.equals(displayObject.__worldTransform));
|
|
var hasFilters = #if !openfl_disable_filters displayObject.__filters != null #else false #end;
|
|
|
|
#if !openfl_enable_cacheasbitmap
|
|
if (renderer.__type == DOM && !hasFilters)
|
|
{
|
|
return false;
|
|
}
|
|
#end
|
|
|
|
if (hasFilters && !needRender)
|
|
{
|
|
for (filter in displayObject.__filters)
|
|
{
|
|
if (filter.__renderDirty)
|
|
{
|
|
needRender = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (displayObject.__cacheBitmapMatrix == null)
|
|
{
|
|
displayObject.__cacheBitmapMatrix = new Matrix();
|
|
}
|
|
|
|
var bitmapMatrix = (displayObject.__cacheAsBitmapMatrix != null ? displayObject.__cacheAsBitmapMatrix : displayObject.__renderTransform);
|
|
|
|
if (!needRender
|
|
&& (bitmapMatrix.a != displayObject.__cacheBitmapMatrix.a
|
|
|| bitmapMatrix.b != displayObject.__cacheBitmapMatrix.b
|
|
|| bitmapMatrix.c != displayObject.__cacheBitmapMatrix.c
|
|
|| bitmapMatrix.d != displayObject.__cacheBitmapMatrix.d))
|
|
{
|
|
needRender = true;
|
|
}
|
|
|
|
if (!needRender
|
|
&& renderer.__type != OPENGL
|
|
&& displayObject.__cacheBitmapData != null
|
|
&& displayObject.__cacheBitmapData.image != null
|
|
&& displayObject.__cacheBitmapData.image.version < displayObject.__cacheBitmapData.__textureVersion)
|
|
{
|
|
needRender = true;
|
|
}
|
|
|
|
// Ensure that cached bitmap is updated after changes to scrollRect
|
|
if (!needRender)
|
|
{
|
|
var current = displayObject;
|
|
while (current != null)
|
|
{
|
|
if (current.scrollRect != null)
|
|
{
|
|
// TODO: do we need to update transform if scroll rects haven't changed?
|
|
updateTransform = true;
|
|
break;
|
|
}
|
|
current = current.parent;
|
|
}
|
|
}
|
|
|
|
displayObject.__cacheBitmapMatrix.copyFrom(bitmapMatrix);
|
|
displayObject.__cacheBitmapMatrix.tx = 0;
|
|
displayObject.__cacheBitmapMatrix.ty = 0;
|
|
|
|
// TODO: Handle dimensions better if object has a scrollRect?
|
|
|
|
var bitmapWidth = 0, bitmapHeight = 0;
|
|
var filterWidth = 0, filterHeight = 0;
|
|
var offsetX = 0., offsetY = 0.;
|
|
|
|
#if (openfl_disable_hdpi || openfl_disable_hdpi_cacheasbitmap)
|
|
var pixelRatio = 1;
|
|
#else
|
|
var pixelRatio = __pixelRatio;
|
|
#end
|
|
|
|
if (updateTransform || needRender)
|
|
{
|
|
rect = Rectangle.__pool.get();
|
|
|
|
displayObject.__getFilterBounds(rect, displayObject.__cacheBitmapMatrix);
|
|
|
|
filterWidth = rect.width > 0 ? Math.floor(rect.width * pixelRatio) : 0;
|
|
filterHeight = rect.height > 0 ? Math.floor(rect.height * pixelRatio) : 0;
|
|
|
|
offsetX = rect.x > 0 ? Math.ceil(rect.x) : Math.floor(rect.x);
|
|
offsetY = rect.y > 0 ? Math.ceil(rect.y) : Math.floor(rect.y);
|
|
|
|
if (displayObject.__cacheBitmapData != null)
|
|
{
|
|
if (filterWidth > displayObject.__cacheBitmapData.width || filterHeight > displayObject.__cacheBitmapData.height)
|
|
{
|
|
bitmapWidth = Math.ceil(Math.max(filterWidth * 1.25, displayObject.__cacheBitmapData.width));
|
|
bitmapHeight = Math.ceil(Math.max(filterHeight * 1.25, displayObject.__cacheBitmapData.height));
|
|
needRender = true;
|
|
}
|
|
else
|
|
{
|
|
bitmapWidth = displayObject.__cacheBitmapData.width;
|
|
bitmapHeight = displayObject.__cacheBitmapData.height;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bitmapWidth = filterWidth;
|
|
bitmapHeight = filterHeight;
|
|
}
|
|
}
|
|
|
|
if (needRender)
|
|
{
|
|
updateTransform = true;
|
|
displayObject.__cacheBitmapBackground = displayObject.opaqueBackground;
|
|
|
|
if (filterWidth >= 0.5 && filterHeight >= 0.5)
|
|
{
|
|
var needsFill = (displayObject.opaqueBackground != null
|
|
&& (bitmapWidth != filterWidth || bitmapHeight != filterHeight));
|
|
var fillColor = displayObject.opaqueBackground != null ? (0xFF << 24) | displayObject.opaqueBackground : 0;
|
|
var bitmapColor = needsFill ? 0 : fillColor;
|
|
var allowFramebuffer = (renderer.__type == OPENGL);
|
|
|
|
if (displayObject.__cacheBitmapData == null
|
|
|| bitmapWidth > displayObject.__cacheBitmapData.width
|
|
|| bitmapHeight > displayObject.__cacheBitmapData.height)
|
|
{
|
|
displayObject.__cacheBitmapData = new BitmapData(bitmapWidth, bitmapHeight, true, bitmapColor);
|
|
|
|
if (displayObject.__cacheBitmap == null) displayObject.__cacheBitmap = new Bitmap();
|
|
displayObject.__cacheBitmap.__bitmapData = displayObject.__cacheBitmapData;
|
|
displayObject.__cacheBitmapRenderer = null;
|
|
}
|
|
else
|
|
{
|
|
displayObject.__cacheBitmapData.__fillRect(displayObject.__cacheBitmapData.rect, bitmapColor, allowFramebuffer);
|
|
}
|
|
|
|
if (needsFill)
|
|
{
|
|
rect.setTo(0, 0, filterWidth, filterHeight);
|
|
displayObject.__cacheBitmapData.__fillRect(rect, fillColor, allowFramebuffer);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ColorTransform.__pool.release(colorTransform);
|
|
|
|
displayObject.__cacheBitmap = null;
|
|
displayObject.__cacheBitmapData = null;
|
|
displayObject.__cacheBitmapData2 = null;
|
|
displayObject.__cacheBitmapData3 = null;
|
|
displayObject.__cacheBitmapRenderer = null;
|
|
|
|
if (displayObject.__drawableType == TEXT_FIELD)
|
|
{
|
|
var textField:TextField = cast displayObject;
|
|
if (textField.__cacheBitmap != null)
|
|
{
|
|
textField.__cacheBitmap.__renderTransform.tx -= textField.__offsetX * pixelRatio;
|
|
textField.__cacheBitmap.__renderTransform.ty -= textField.__offsetY * pixelRatio;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Should we retain these longer?
|
|
|
|
displayObject.__cacheBitmapData = displayObject.__cacheBitmap.bitmapData;
|
|
displayObject.__cacheBitmapData2 = null;
|
|
displayObject.__cacheBitmapData3 = null;
|
|
}
|
|
|
|
if (updateTransform || needRender)
|
|
{
|
|
displayObject.__cacheBitmap.__worldTransform.copyFrom(displayObject.__worldTransform);
|
|
|
|
if (bitmapMatrix == displayObject.__renderTransform)
|
|
{
|
|
displayObject.__cacheBitmap.__renderTransform.identity();
|
|
displayObject.__cacheBitmap.__renderTransform.scale(1 / pixelRatio, 1 / pixelRatio);
|
|
displayObject.__cacheBitmap.__renderTransform.tx = displayObject.__renderTransform.tx + offsetX;
|
|
displayObject.__cacheBitmap.__renderTransform.ty = displayObject.__renderTransform.ty + offsetY;
|
|
}
|
|
else
|
|
{
|
|
displayObject.__cacheBitmap.__renderTransform.copyFrom(displayObject.__cacheBitmapMatrix);
|
|
displayObject.__cacheBitmap.__renderTransform.invert();
|
|
displayObject.__cacheBitmap.__renderTransform.concat(displayObject.__renderTransform);
|
|
displayObject.__cacheBitmap.__renderTransform.a *= 1 / pixelRatio;
|
|
displayObject.__cacheBitmap.__renderTransform.d *= 1 / pixelRatio;
|
|
displayObject.__cacheBitmap.__renderTransform.tx += offsetX;
|
|
displayObject.__cacheBitmap.__renderTransform.ty += offsetY;
|
|
}
|
|
}
|
|
|
|
displayObject.__cacheBitmap.smoothing = renderer.__allowSmoothing;
|
|
displayObject.__cacheBitmap.__renderable = displayObject.__renderable;
|
|
displayObject.__cacheBitmap.__worldAlpha = displayObject.__worldAlpha;
|
|
displayObject.__cacheBitmap.__worldBlendMode = displayObject.__worldBlendMode;
|
|
displayObject.__cacheBitmap.__worldShader = displayObject.__worldShader;
|
|
// displayObject.__cacheBitmap.__scrollRect = displayObject.__scrollRect;
|
|
// displayObject.__cacheBitmap.filters = displayObject.filters;
|
|
displayObject.__cacheBitmap.mask = displayObject.__mask;
|
|
|
|
if (needRender)
|
|
{
|
|
#if lime
|
|
if (displayObject.__cacheBitmapRenderer == null || renderType != displayObject.__cacheBitmapRenderer.__type)
|
|
{
|
|
if (renderType == OPENGL)
|
|
{
|
|
displayObject.__cacheBitmapRenderer = new OpenGLRenderer(cast(renderer, OpenGLRenderer).__context3D, displayObject.__cacheBitmapData);
|
|
}
|
|
else
|
|
{
|
|
if (displayObject.__cacheBitmapData.image == null)
|
|
{
|
|
var color = displayObject.opaqueBackground != null ? (0xFF << 24) | displayObject.opaqueBackground : 0;
|
|
displayObject.__cacheBitmapData = new BitmapData(bitmapWidth, bitmapHeight, true, color);
|
|
displayObject.__cacheBitmap.__bitmapData = displayObject.__cacheBitmapData;
|
|
}
|
|
|
|
#if (js && html5)
|
|
ImageCanvasUtil.convertToCanvas(displayObject.__cacheBitmapData.image);
|
|
displayObject.__cacheBitmapRenderer = new CanvasRenderer(displayObject.__cacheBitmapData.image.buffer.__srcContext);
|
|
#else
|
|
displayObject.__cacheBitmapRenderer = new CairoRenderer(new Cairo(displayObject.__cacheBitmapData.getSurface()));
|
|
#end
|
|
}
|
|
|
|
displayObject.__cacheBitmapRenderer.__worldTransform = new Matrix();
|
|
displayObject.__cacheBitmapRenderer.__worldColorTransform = new ColorTransform();
|
|
}
|
|
#else
|
|
return false;
|
|
#end
|
|
|
|
if (displayObject.__cacheBitmapColorTransform == null) displayObject.__cacheBitmapColorTransform = new ColorTransform();
|
|
|
|
displayObject.__cacheBitmapRenderer.__stage = displayObject.stage;
|
|
|
|
displayObject.__cacheBitmapRenderer.__allowSmoothing = renderer.__allowSmoothing;
|
|
displayObject.__cacheBitmapRenderer.__setBlendMode(NORMAL);
|
|
displayObject.__cacheBitmapRenderer.__worldAlpha = 1 / displayObject.__worldAlpha;
|
|
|
|
displayObject.__cacheBitmapRenderer.__worldTransform.copyFrom(displayObject.__renderTransform);
|
|
displayObject.__cacheBitmapRenderer.__worldTransform.invert();
|
|
displayObject.__cacheBitmapRenderer.__worldTransform.concat(displayObject.__cacheBitmapMatrix);
|
|
displayObject.__cacheBitmapRenderer.__worldTransform.tx -= offsetX;
|
|
displayObject.__cacheBitmapRenderer.__worldTransform.ty -= offsetY;
|
|
displayObject.__cacheBitmapRenderer.__worldTransform.scale(pixelRatio, pixelRatio);
|
|
|
|
displayObject.__cacheBitmapRenderer.__pixelRatio = pixelRatio;
|
|
|
|
displayObject.__cacheBitmapRenderer.__worldColorTransform.__copyFrom(colorTransform);
|
|
displayObject.__cacheBitmapRenderer.__worldColorTransform.__invert();
|
|
|
|
displayObject.__isCacheBitmapRender = true;
|
|
|
|
if (displayObject.__cacheBitmapRenderer.__type == OPENGL)
|
|
{
|
|
var parentRenderer:OpenGLRenderer = cast renderer;
|
|
var childRenderer:OpenGLRenderer = cast displayObject.__cacheBitmapRenderer;
|
|
|
|
var context = childRenderer.__context3D;
|
|
|
|
var cacheRTT = context.__state.renderToTexture;
|
|
var cacheRTTDepthStencil = context.__state.renderToTextureDepthStencil;
|
|
var cacheRTTAntiAlias = context.__state.renderToTextureAntiAlias;
|
|
var cacheRTTSurfaceSelector = context.__state.renderToTextureSurfaceSelector;
|
|
|
|
// var cacheFramebuffer = context.__contextState.__currentGLFramebuffer;
|
|
|
|
var cacheBlendMode = parentRenderer.__blendMode;
|
|
parentRenderer.__suspendClipAndMask();
|
|
childRenderer.__copyShader(parentRenderer);
|
|
// childRenderer.__copyState (parentRenderer);
|
|
|
|
displayObject.__cacheBitmapData.__setUVRect(context, 0, 0, filterWidth, filterHeight);
|
|
childRenderer.__setRenderTarget(displayObject.__cacheBitmapData);
|
|
if (displayObject.__cacheBitmapData.image != null)
|
|
displayObject.__cacheBitmapData.__textureVersion = displayObject.__cacheBitmapData.image.version
|
|
+ 1;
|
|
|
|
displayObject.__cacheBitmapData.__drawGL(displayObject, childRenderer);
|
|
|
|
if (hasFilters)
|
|
{
|
|
var needSecondBitmapData = true;
|
|
var needCopyOfOriginal = false;
|
|
|
|
for (filter in displayObject.__filters)
|
|
{
|
|
// if (filter.__needSecondBitmapData) {
|
|
// needSecondBitmapData = true;
|
|
// }
|
|
if (filter.__preserveObject)
|
|
{
|
|
needCopyOfOriginal = true;
|
|
}
|
|
}
|
|
|
|
var bitmap = displayObject.__cacheBitmapData;
|
|
var bitmap2 = null;
|
|
var bitmap3 = null;
|
|
|
|
// if (needSecondBitmapData) {
|
|
if (displayObject.__cacheBitmapData2 == null
|
|
|| bitmapWidth > displayObject.__cacheBitmapData2.width
|
|
|| bitmapHeight > displayObject.__cacheBitmapData2.height)
|
|
{
|
|
displayObject.__cacheBitmapData2 = new BitmapData(bitmapWidth, bitmapHeight, true, 0);
|
|
}
|
|
else
|
|
{
|
|
displayObject.__cacheBitmapData2.fillRect(displayObject.__cacheBitmapData2.rect, 0);
|
|
if (displayObject.__cacheBitmapData2.image != null)
|
|
{
|
|
displayObject.__cacheBitmapData2.__textureVersion = displayObject.__cacheBitmapData2.image.version + 1;
|
|
}
|
|
}
|
|
displayObject.__cacheBitmapData2.__setUVRect(context, 0, 0, filterWidth, filterHeight);
|
|
bitmap2 = displayObject.__cacheBitmapData2;
|
|
// } else {
|
|
// bitmap2 = bitmapData;
|
|
// }
|
|
|
|
if (needCopyOfOriginal)
|
|
{
|
|
if (displayObject.__cacheBitmapData3 == null
|
|
|| bitmapWidth > displayObject.__cacheBitmapData3.width
|
|
|| bitmapHeight > displayObject.__cacheBitmapData3.height)
|
|
{
|
|
displayObject.__cacheBitmapData3 = new BitmapData(bitmapWidth, bitmapHeight, true, 0);
|
|
}
|
|
else
|
|
{
|
|
displayObject.__cacheBitmapData3.fillRect(displayObject.__cacheBitmapData3.rect, 0);
|
|
if (displayObject.__cacheBitmapData3.image != null)
|
|
{
|
|
displayObject.__cacheBitmapData3.__textureVersion = displayObject.__cacheBitmapData3.image.version + 1;
|
|
}
|
|
}
|
|
displayObject.__cacheBitmapData3.__setUVRect(context, 0, 0, filterWidth, filterHeight);
|
|
bitmap3 = displayObject.__cacheBitmapData3;
|
|
}
|
|
|
|
childRenderer.__setBlendMode(NORMAL);
|
|
childRenderer.__worldAlpha = 1;
|
|
childRenderer.__worldTransform.identity();
|
|
childRenderer.__worldColorTransform.__identity();
|
|
|
|
// var sourceRect = bitmap.rect;
|
|
// if (__tempPoint == null) __tempPoint = new Point ();
|
|
// var destPoint = __tempPoint;
|
|
var shader, cacheBitmap;
|
|
|
|
for (filter in displayObject.__filters)
|
|
{
|
|
if (filter.__preserveObject)
|
|
{
|
|
childRenderer.__setRenderTarget(bitmap3);
|
|
childRenderer.__renderFilterPass(bitmap, childRenderer.__defaultDisplayShader, filter.__smooth);
|
|
}
|
|
|
|
for (i in 0...filter.__numShaderPasses)
|
|
{
|
|
shader = filter.__initShader(childRenderer, i, filter.__preserveObject ? bitmap3 : null);
|
|
childRenderer.__setBlendMode(filter.__shaderBlendMode);
|
|
childRenderer.__setRenderTarget(bitmap2);
|
|
childRenderer.__renderFilterPass(bitmap, shader, filter.__smooth);
|
|
|
|
cacheBitmap = bitmap;
|
|
bitmap = bitmap2;
|
|
bitmap2 = cacheBitmap;
|
|
}
|
|
|
|
filter.__renderDirty = false;
|
|
}
|
|
|
|
displayObject.__cacheBitmap.__bitmapData = bitmap;
|
|
}
|
|
|
|
parentRenderer.__blendMode = NORMAL;
|
|
parentRenderer.__setBlendMode(cacheBlendMode);
|
|
parentRenderer.__copyShader(childRenderer);
|
|
|
|
if (cacheRTT != null)
|
|
{
|
|
context.setRenderToTexture(cacheRTT, cacheRTTDepthStencil, cacheRTTAntiAlias, cacheRTTSurfaceSelector);
|
|
}
|
|
else
|
|
{
|
|
context.setRenderToBackBuffer();
|
|
}
|
|
|
|
// context.__bindGLFramebuffer (cacheFramebuffer);
|
|
|
|
// parentRenderer.__restoreState (childRenderer);
|
|
parentRenderer.__resumeClipAndMask(childRenderer);
|
|
parentRenderer.setViewport();
|
|
|
|
displayObject.__cacheBitmapColorTransform.__copyFrom(colorTransform);
|
|
}
|
|
else
|
|
{
|
|
#if (js && html5)
|
|
displayObject.__cacheBitmapData.__drawCanvas(displayObject, cast displayObject.__cacheBitmapRenderer);
|
|
#else
|
|
displayObject.__cacheBitmapData.__drawCairo(displayObject, cast displayObject.__cacheBitmapRenderer);
|
|
#end
|
|
|
|
if (hasFilters)
|
|
{
|
|
var needSecondBitmapData = false;
|
|
var needCopyOfOriginal = false;
|
|
|
|
for (filter in displayObject.__filters)
|
|
{
|
|
if (filter.__needSecondBitmapData)
|
|
{
|
|
needSecondBitmapData = true;
|
|
}
|
|
if (filter.__preserveObject)
|
|
{
|
|
needCopyOfOriginal = true;
|
|
}
|
|
}
|
|
|
|
var bitmap = displayObject.__cacheBitmapData;
|
|
var bitmap2 = null;
|
|
var bitmap3 = null;
|
|
|
|
if (needSecondBitmapData)
|
|
{
|
|
if (displayObject.__cacheBitmapData2 == null
|
|
|| displayObject.__cacheBitmapData2.image == null
|
|
|| bitmapWidth > displayObject.__cacheBitmapData2.width
|
|
|| bitmapHeight > displayObject.__cacheBitmapData2.height)
|
|
{
|
|
displayObject.__cacheBitmapData2 = new BitmapData(bitmapWidth, bitmapHeight, true, 0);
|
|
}
|
|
else
|
|
{
|
|
displayObject.__cacheBitmapData2.fillRect(displayObject.__cacheBitmapData2.rect, 0);
|
|
}
|
|
bitmap2 = displayObject.__cacheBitmapData2;
|
|
}
|
|
else
|
|
{
|
|
bitmap2 = bitmap;
|
|
}
|
|
|
|
if (needCopyOfOriginal)
|
|
{
|
|
if (displayObject.__cacheBitmapData3 == null
|
|
|| displayObject.__cacheBitmapData3.image == null
|
|
|| bitmapWidth > displayObject.__cacheBitmapData3.width
|
|
|| bitmapHeight > displayObject.__cacheBitmapData3.height)
|
|
{
|
|
displayObject.__cacheBitmapData3 = new BitmapData(bitmapWidth, bitmapHeight, true, 0);
|
|
}
|
|
else
|
|
{
|
|
displayObject.__cacheBitmapData3.fillRect(displayObject.__cacheBitmapData3.rect, 0);
|
|
}
|
|
bitmap3 = displayObject.__cacheBitmapData3;
|
|
}
|
|
|
|
if (displayObject.__tempPoint == null) displayObject.__tempPoint = new Point();
|
|
var destPoint = displayObject.__tempPoint;
|
|
var cacheBitmap, lastBitmap;
|
|
|
|
for (filter in displayObject.__filters)
|
|
{
|
|
if (filter.__preserveObject)
|
|
{
|
|
bitmap3.copyPixels(bitmap, bitmap.rect, destPoint);
|
|
}
|
|
|
|
lastBitmap = filter.__applyFilter(bitmap2, bitmap, bitmap.rect, destPoint);
|
|
|
|
if (filter.__preserveObject)
|
|
{
|
|
lastBitmap.draw(bitmap3, null,
|
|
displayObject.__objectTransform != null ? displayObject.__objectTransform.__colorTransform : null);
|
|
}
|
|
filter.__renderDirty = false;
|
|
|
|
if (needSecondBitmapData && lastBitmap == bitmap2)
|
|
{
|
|
cacheBitmap = bitmap;
|
|
bitmap = bitmap2;
|
|
bitmap2 = cacheBitmap;
|
|
}
|
|
}
|
|
|
|
if (displayObject.__cacheBitmapData != bitmap)
|
|
{
|
|
// TODO: Fix issue with swapping __cacheBitmap.__bitmapData
|
|
// __cacheBitmapData.copyPixels (bitmap, bitmap.rect, destPoint);
|
|
|
|
// Adding __cacheBitmapRenderer = null; makes this work
|
|
cacheBitmap = displayObject.__cacheBitmapData;
|
|
displayObject.__cacheBitmapData = bitmap;
|
|
displayObject.__cacheBitmapData2 = cacheBitmap;
|
|
displayObject.__cacheBitmap.__bitmapData = displayObject.__cacheBitmapData;
|
|
displayObject.__cacheBitmapRenderer = null;
|
|
}
|
|
|
|
displayObject.__cacheBitmap.__imageVersion = displayObject.__cacheBitmapData.__textureVersion;
|
|
}
|
|
|
|
displayObject.__cacheBitmapColorTransform.__copyFrom(colorTransform);
|
|
|
|
if (!displayObject.__cacheBitmapColorTransform.__isDefault(true))
|
|
{
|
|
displayObject.__cacheBitmapColorTransform.alphaMultiplier = 1;
|
|
displayObject.__cacheBitmapData.colorTransform(displayObject.__cacheBitmapData.rect, displayObject.__cacheBitmapColorTransform);
|
|
}
|
|
}
|
|
|
|
displayObject.__isCacheBitmapRender = false;
|
|
}
|
|
|
|
if (updateTransform || needRender)
|
|
{
|
|
Rectangle.__pool.release(rect);
|
|
}
|
|
|
|
updated = updateTransform;
|
|
}
|
|
else if (displayObject.__cacheBitmap != null)
|
|
{
|
|
if (renderer.__type == DOM)
|
|
{
|
|
var domRenderer:DOMRenderer = cast renderer;
|
|
domRenderer.__renderDrawableClear(displayObject.__cacheBitmap);
|
|
}
|
|
|
|
displayObject.__cacheBitmap = null;
|
|
displayObject.__cacheBitmapData = null;
|
|
displayObject.__cacheBitmapData2 = null;
|
|
displayObject.__cacheBitmapData3 = null;
|
|
displayObject.__cacheBitmapColorTransform = null;
|
|
displayObject.__cacheBitmapRenderer = null;
|
|
|
|
updated = true;
|
|
}
|
|
|
|
ColorTransform.__pool.release(colorTransform);
|
|
|
|
if (updated && displayObject.__drawableType == TEXT_FIELD)
|
|
{
|
|
var textField:TextField = cast displayObject;
|
|
if (textField.__cacheBitmap != null)
|
|
{
|
|
textField.__cacheBitmap.__renderTransform.tx -= textField.__offsetX;
|
|
textField.__cacheBitmap.__renderTransform.ty -= textField.__offsetY;
|
|
}
|
|
}
|
|
|
|
return updated;
|
|
#else
|
|
return false;
|
|
#end
|
|
}
|
|
}
|
|
#else
|
|
typedef DisplayObjectRenderer = Dynamic;
|
|
#end
|