From c89d7516b8c650c59cde83e9ca90307214343f60 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 20 Aug 2015 10:28:23 -0700 Subject: [PATCH] Split up paintChildWithPaint into paintChildWithOpacity and paintChildWithColorFilter The compositor backends we're planning to use can't handle a general-purpose paint layer and instead need lower-level operations. Fixes #707 --- sky/packages/sky/lib/rendering/layer.dart | 31 ++++++++++------ sky/packages/sky/lib/rendering/object.dart | 35 +++++++++++++++++-- sky/packages/sky/lib/rendering/proxy_box.dart | 28 ++------------- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/sky/packages/sky/lib/rendering/layer.dart b/sky/packages/sky/lib/rendering/layer.dart index f4b9994406326..634dd41496e8f 100644 --- a/sky/packages/sky/lib/rendering/layer.dart +++ b/sky/packages/sky/lib/rendering/layer.dart @@ -247,15 +247,22 @@ class TransformLayer extends ContainerLayer { } } -class PaintLayer extends ContainerLayer { - PaintLayer({ Offset offset: Offset.zero, this.bounds, this.paintSettings }) : super(offset: offset); +class OpacityLayer extends ContainerLayer { + OpacityLayer({ Offset offset: Offset.zero, this.bounds, this.alpha }) : super(offset: offset); // bounds is _not_ affected by given offset Rect bounds; - Paint paintSettings; // TODO(ianh): rename this to 'paint' once paint() is gone + int alpha; + + static Paint paintForAlpha(int alpha) { + return new Paint() + ..color = new Color.fromARGB(alpha, 0, 0, 0) + ..setTransferMode(sky.TransferMode.srcOver) + ..isAntiAlias = false; + } void paint(sky.Canvas canvas) { - canvas.saveLayer(bounds, paintSettings); + canvas.saveLayer(bounds, paintForAlpha(alpha)); canvas.translate(offset.dx, offset.dy); paintChildren(canvas); canvas.restore(); @@ -265,20 +272,24 @@ class PaintLayer extends ContainerLayer { class ColorFilterLayer extends ContainerLayer { ColorFilterLayer({ Offset offset: Offset.zero, - this.size, + this.bounds, this.color, this.transferMode }) : super(offset: offset); - Size size; + // bounds is _not_ affected by given offset + Rect bounds; Color color; sky.TransferMode transferMode; + static paintForColorFilter(Color color, sky.TransferMode transferMode) { + new Paint() + ..setColorFilter(new sky.ColorFilter.mode(color, transferMode)) + ..isAntiAlias = false; + } + void paint(sky.Canvas canvas) { - Paint paint = new Paint() - ..color = color - ..setTransferMode(transferMode); - canvas.saveLayer(offset & size, paint); + canvas.saveLayer(bounds, paintForColorFilter(color, transferMode)); canvas.translate(offset.dx, offset.dy); paintChildren(canvas); canvas.restore(); diff --git a/sky/packages/sky/lib/rendering/object.dart b/sky/packages/sky/lib/rendering/object.dart index f39a8e350b9a9..7cd6e94a13250 100644 --- a/sky/packages/sky/lib/rendering/object.dart +++ b/sky/packages/sky/lib/rendering/object.dart @@ -188,16 +188,45 @@ class PaintingContext { } } - void paintChildWithPaint(RenderObject child, Point childPosition, Rect bounds, Paint paint) { + void paintChildWithOpacity(RenderObject child, + Point childPosition, + Rect bounds, + int alpha) { assert(debugCanPaintChild(child)); final Offset childOffset = childPosition.toOffset(); if (!child.needsCompositing) { - canvas.saveLayer(bounds, paint); + canvas.saveLayer(bounds, OpacityLayer.paintForAlpha(alpha)); canvas.translate(childOffset.dx, childOffset.dy); insertChild(child, Offset.zero); canvas.restore(); } else { - PaintLayer paintLayer = new PaintLayer(offset: childOffset, bounds: bounds, paintSettings: paint); + OpacityLayer paintLayer = new OpacityLayer( + offset: childOffset, + bounds: bounds, + alpha: alpha); + _containerLayer.add(paintLayer); + compositeChild(child, parentLayer: paintLayer); + } + } + + void paintChildWithColorFilter(RenderObject child, + Point childPosition, + Rect bounds, + Color color, + sky.TransferMode transferMode) { + assert(debugCanPaintChild(child)); + final Offset childOffset = childPosition.toOffset(); + if (!child.needsCompositing) { + canvas.saveLayer(bounds, ColorFilterLayer.paintForColorFilter(color, transferMode)); + canvas.translate(childOffset.dx, childOffset.dy); + insertChild(child, Offset.zero); + canvas.restore(); + } else { + ColorFilterLayer paintLayer = new ColorFilterLayer( + offset: childOffset, + bounds: bounds, + color: color, + transferMode: transferMode); _containerLayer.add(paintLayer); compositeChild(child, parentLayer: paintLayer); } diff --git a/sky/packages/sky/lib/rendering/proxy_box.dart b/sky/packages/sky/lib/rendering/proxy_box.dart index 4031b7b401617..bf27c891826a7 100644 --- a/sky/packages/sky/lib/rendering/proxy_box.dart +++ b/sky/packages/sky/lib/rendering/proxy_box.dart @@ -275,23 +275,11 @@ class RenderOpacity extends RenderProxyBox { if (_opacity == value) return; _opacity = value; - _cachedPaint = null; markNeedsPaint(); } int get _alpha => (_opacity * 255).round(); - Paint _cachedPaint; - Paint get _paint { - if (_cachedPaint == null) { - _cachedPaint = new Paint() - ..color = new Color.fromARGB(_alpha, 0, 0, 0) - ..setTransferMode(sky.TransferMode.srcOver) - ..isAntiAlias = false; - } - return _cachedPaint; - } - void paint(PaintingContext context, Offset offset) { if (child != null) { int a = _alpha; @@ -300,7 +288,7 @@ class RenderOpacity extends RenderProxyBox { if (a == 255) context.paintChild(child, offset.toPoint()); else - context.paintChildWithPaint(child, offset.toPoint(), null, _paint); + context.paintChildWithOpacity(child, offset.toPoint(), null, a); } } } @@ -317,7 +305,6 @@ class RenderColorFilter extends RenderProxyBox { if (_color == value) return; _color = value; - _cachedPaint = null; markNeedsPaint(); } @@ -328,23 +315,12 @@ class RenderColorFilter extends RenderProxyBox { if (_transferMode == value) return; _transferMode = value; - _cachedPaint = null; markNeedsPaint(); } - Paint _cachedPaint; - Paint get _paint { - if (_cachedPaint == null) { - _cachedPaint = new Paint() - ..setColorFilter(new sky.ColorFilter.mode(_color, _transferMode)) - ..isAntiAlias = false; - } - return _cachedPaint; - } - void paint(PaintingContext context, Offset offset) { if (child != null) - context.paintChildWithPaint(child, offset.toPoint(), offset & size, _paint); + context.paintChildWithColorFilter(child, offset.toPoint(), offset & size, _color, _transferMode); } }