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
This commit is contained in:
parent
01b88ccc55
commit
8a3285b6c5
@ -247,15 +247,22 @@ class TransformLayer extends ContainerLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PaintLayer extends ContainerLayer {
|
class OpacityLayer extends ContainerLayer {
|
||||||
PaintLayer({ Offset offset: Offset.zero, this.bounds, this.paintSettings }) : super(offset: offset);
|
OpacityLayer({ Offset offset: Offset.zero, this.bounds, this.alpha }) : super(offset: offset);
|
||||||
|
|
||||||
// bounds is _not_ affected by given offset
|
// bounds is _not_ affected by given offset
|
||||||
Rect bounds;
|
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) {
|
void paint(sky.Canvas canvas) {
|
||||||
canvas.saveLayer(bounds, paintSettings);
|
canvas.saveLayer(bounds, paintForAlpha(alpha));
|
||||||
canvas.translate(offset.dx, offset.dy);
|
canvas.translate(offset.dx, offset.dy);
|
||||||
paintChildren(canvas);
|
paintChildren(canvas);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
@ -265,20 +272,24 @@ class PaintLayer extends ContainerLayer {
|
|||||||
class ColorFilterLayer extends ContainerLayer {
|
class ColorFilterLayer extends ContainerLayer {
|
||||||
ColorFilterLayer({
|
ColorFilterLayer({
|
||||||
Offset offset: Offset.zero,
|
Offset offset: Offset.zero,
|
||||||
this.size,
|
this.bounds,
|
||||||
this.color,
|
this.color,
|
||||||
this.transferMode
|
this.transferMode
|
||||||
}) : super(offset: offset);
|
}) : super(offset: offset);
|
||||||
|
|
||||||
Size size;
|
// bounds is _not_ affected by given offset
|
||||||
|
Rect bounds;
|
||||||
Color color;
|
Color color;
|
||||||
sky.TransferMode transferMode;
|
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) {
|
void paint(sky.Canvas canvas) {
|
||||||
Paint paint = new Paint()
|
canvas.saveLayer(bounds, paintForColorFilter(color, transferMode));
|
||||||
..color = color
|
|
||||||
..setTransferMode(transferMode);
|
|
||||||
canvas.saveLayer(offset & size, paint);
|
|
||||||
canvas.translate(offset.dx, offset.dy);
|
canvas.translate(offset.dx, offset.dy);
|
||||||
paintChildren(canvas);
|
paintChildren(canvas);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
@ -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));
|
assert(debugCanPaintChild(child));
|
||||||
final Offset childOffset = childPosition.toOffset();
|
final Offset childOffset = childPosition.toOffset();
|
||||||
if (!child.needsCompositing) {
|
if (!child.needsCompositing) {
|
||||||
canvas.saveLayer(bounds, paint);
|
canvas.saveLayer(bounds, OpacityLayer.paintForAlpha(alpha));
|
||||||
canvas.translate(childOffset.dx, childOffset.dy);
|
canvas.translate(childOffset.dx, childOffset.dy);
|
||||||
insertChild(child, Offset.zero);
|
insertChild(child, Offset.zero);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
} else {
|
} 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);
|
_containerLayer.add(paintLayer);
|
||||||
compositeChild(child, parentLayer: paintLayer);
|
compositeChild(child, parentLayer: paintLayer);
|
||||||
}
|
}
|
||||||
|
@ -275,23 +275,11 @@ class RenderOpacity extends RenderProxyBox {
|
|||||||
if (_opacity == value)
|
if (_opacity == value)
|
||||||
return;
|
return;
|
||||||
_opacity = value;
|
_opacity = value;
|
||||||
_cachedPaint = null;
|
|
||||||
markNeedsPaint();
|
markNeedsPaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
int get _alpha => (_opacity * 255).round();
|
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) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
int a = _alpha;
|
int a = _alpha;
|
||||||
@ -300,7 +288,7 @@ class RenderOpacity extends RenderProxyBox {
|
|||||||
if (a == 255)
|
if (a == 255)
|
||||||
context.paintChild(child, offset.toPoint());
|
context.paintChild(child, offset.toPoint());
|
||||||
else
|
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)
|
if (_color == value)
|
||||||
return;
|
return;
|
||||||
_color = value;
|
_color = value;
|
||||||
_cachedPaint = null;
|
|
||||||
markNeedsPaint();
|
markNeedsPaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,23 +315,12 @@ class RenderColorFilter extends RenderProxyBox {
|
|||||||
if (_transferMode == value)
|
if (_transferMode == value)
|
||||||
return;
|
return;
|
||||||
_transferMode = value;
|
_transferMode = value;
|
||||||
_cachedPaint = null;
|
|
||||||
markNeedsPaint();
|
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) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
if (child != null)
|
if (child != null)
|
||||||
context.paintChildWithPaint(child, offset.toPoint(), offset & size, _paint);
|
context.paintChildWithColorFilter(child, offset.toPoint(), offset & size, _color, _transferMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user