Files
CodenameEngine/source/openfl/display/DisplayObjectRenderer.hx
T
2024-03-19 21:51:00 +01:00

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