Unverified Commit 11ff938a authored by zljj0818's avatar zljj0818 Committed by GitHub

Added a filterQuality parameter to texture (#59966)

parent 33aa4576
...@@ -581,11 +581,12 @@ class PictureLayer extends Layer { ...@@ -581,11 +581,12 @@ class PictureLayer extends Layer {
class TextureLayer extends Layer { class TextureLayer extends Layer {
/// Creates a texture layer bounded by [rect] and with backend texture /// Creates a texture layer bounded by [rect] and with backend texture
/// identified by [textureId], if [freeze] is true new texture frames will not be /// identified by [textureId], if [freeze] is true new texture frames will not be
/// populated to the texture. /// populated to the texture, and use [filterQuality] to set layer's [FilterQuality].
TextureLayer({ TextureLayer({
@required this.rect, @required this.rect,
@required this.textureId, @required this.textureId,
this.freeze = false, this.freeze = false,
this.filterQuality = ui.FilterQuality.low,
}) : assert(rect != null), }) : assert(rect != null),
assert(textureId != null); assert(textureId != null);
...@@ -604,6 +605,9 @@ class TextureLayer extends Layer { ...@@ -604,6 +605,9 @@ class TextureLayer extends Layer {
/// un-freezes it when it is certain that a frame with the new size is ready. /// un-freezes it when it is certain that a frame with the new size is ready.
final bool freeze; final bool freeze;
/// {@macro FilterQuality}
final ui.FilterQuality filterQuality;
@override @override
void addToScene(ui.SceneBuilder builder, [ Offset layerOffset = Offset.zero ]) { void addToScene(ui.SceneBuilder builder, [ Offset layerOffset = Offset.zero ]) {
final Rect shiftedRect = layerOffset == Offset.zero ? rect : rect.shift(layerOffset); final Rect shiftedRect = layerOffset == Offset.zero ? rect : rect.shift(layerOffset);
...@@ -613,6 +617,7 @@ class TextureLayer extends Layer { ...@@ -613,6 +617,7 @@ class TextureLayer extends Layer {
width: shiftedRect.width, width: shiftedRect.width,
height: shiftedRect.height, height: shiftedRect.height,
freeze: freeze, freeze: freeze,
filterQuality: filterQuality,
); );
} }
......
...@@ -37,10 +37,14 @@ import 'object.dart'; ...@@ -37,10 +37,14 @@ import 'object.dart';
/// * <https://api.flutter.dev/objcdoc/Protocols/FlutterTextureRegistry.html> /// * <https://api.flutter.dev/objcdoc/Protocols/FlutterTextureRegistry.html>
/// for how to create and manage backend textures on iOS. /// for how to create and manage backend textures on iOS.
class TextureBox extends RenderBox { class TextureBox extends RenderBox {
/// Creates a box backed by the texture identified by [textureId]. /// Creates a box backed by the texture identified by [textureId], and use
TextureBox({ @required int textureId }) /// [filterQuality] to set texture's [FilterQuality].
: assert(textureId != null), TextureBox({
_textureId = textureId; @required int textureId,
FilterQuality filterQuality = FilterQuality.low,
}) : assert(textureId != null),
_textureId = textureId,
_filterQuality = filterQuality;
/// The identity of the backend texture. /// The identity of the backend texture.
int get textureId => _textureId; int get textureId => _textureId;
...@@ -53,6 +57,17 @@ class TextureBox extends RenderBox { ...@@ -53,6 +57,17 @@ class TextureBox extends RenderBox {
} }
} }
/// {@macro FilterQuality}
FilterQuality get filterQuality => _filterQuality;
FilterQuality _filterQuality;
set filterQuality(FilterQuality value) {
assert(value != null);
if (value == _filterQuality)
return;
_filterQuality = value;
markNeedsPaint();
}
@override @override
bool get sizedByParent => true; bool get sizedByParent => true;
...@@ -77,6 +92,7 @@ class TextureBox extends RenderBox { ...@@ -77,6 +92,7 @@ class TextureBox extends RenderBox {
context.addLayer(TextureLayer( context.addLayer(TextureLayer(
rect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height), rect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height),
textureId: _textureId, textureId: _textureId,
filterQuality: _filterQuality,
)); ));
} }
} }
...@@ -35,21 +35,34 @@ import 'framework.dart'; ...@@ -35,21 +35,34 @@ import 'framework.dart';
/// * <https://api.flutter.dev/objcdoc/Protocols/FlutterTextureRegistry.html> /// * <https://api.flutter.dev/objcdoc/Protocols/FlutterTextureRegistry.html>
/// for how to create and manage backend textures on iOS. /// for how to create and manage backend textures on iOS.
class Texture extends LeafRenderObjectWidget { class Texture extends LeafRenderObjectWidget {
/// Creates a widget backed by the texture identified by [textureId]. /// Creates a widget backed by the texture identified by [textureId], and use
/// [filterQuality] to set texture's [FilterQuality].
const Texture({ const Texture({
Key key, Key key,
@required this.textureId, @required this.textureId,
this.filterQuality = FilterQuality.low,
}) : assert(textureId != null), }) : assert(textureId != null),
super(key: key); super(key: key);
/// The identity of the backend texture. /// The identity of the backend texture.
final int textureId; final int textureId;
/// {@template FilterQuality}
/// The quality of sampling the texture and rendering it on screen.
///
/// When the texture is scaled, a default [FilterQuality.low] is used for a higher quality but slower
/// interpolation (typically bilinear). It can be changed to [FilterQuality.none] for a lower quality but
/// faster interpolation (typically nearest-neighbor). See also [FilterQuality.medium] and
/// [FilterQuality.high] for more options.
/// {@endtemplate}
final FilterQuality filterQuality;
@override @override
TextureBox createRenderObject(BuildContext context) => TextureBox(textureId: textureId); TextureBox createRenderObject(BuildContext context) => TextureBox(textureId: textureId, filterQuality: filterQuality);
@override @override
void updateRenderObject(BuildContext context, TextureBox renderObject) { void updateRenderObject(BuildContext context, TextureBox renderObject) {
renderObject.textureId = textureId; renderObject.textureId = textureId;
renderObject.filterQuality = filterQuality;
} }
} }
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
void main() {
testWidgets('Texture with default FilterQuality', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(child: Texture(textureId: 1,))
);
final Texture texture = tester.firstWidget(find.byType(Texture));
expect(texture, isNotNull);
expect(texture.textureId, 1);
expect(texture.filterQuality, FilterQuality.low);
final RenderObject renderObject = tester.firstRenderObject(find.byType(Texture));
expect(renderObject, isNotNull);
final TextureBox textureBox = renderObject as TextureBox;
expect(textureBox, isNotNull);
expect(textureBox.textureId, 1);
expect(textureBox.filterQuality, FilterQuality.low);
final ContainerLayer containerLayer = ContainerLayer();
final PaintingContext paintingContext = PaintingContext(containerLayer, Rect.zero);
textureBox.paint(paintingContext, Offset.zero);
final Layer layer = containerLayer.lastChild;
expect(layer, isNotNull);
final TextureLayer textureLayer = layer as TextureLayer;
expect(textureLayer, isNotNull);
expect(textureLayer.textureId, 1);
expect(textureLayer.filterQuality, FilterQuality.low);
});
testWidgets('Texture with FilterQuality.none', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(child: Texture(textureId: 1, filterQuality: FilterQuality.none))
);
final Texture texture = tester.firstWidget(find.byType(Texture));
expect(texture, isNotNull);
expect(texture.textureId, 1);
expect(texture.filterQuality, FilterQuality.none);
final RenderObject renderObject = tester.firstRenderObject(find.byType(Texture));
expect(renderObject, isNotNull);
final TextureBox textureBox = renderObject as TextureBox;
expect(textureBox, isNotNull);
expect(textureBox.textureId, 1);
expect(textureBox.filterQuality, FilterQuality.none);
final ContainerLayer containerLayer = ContainerLayer();
final PaintingContext paintingContext = PaintingContext(containerLayer, Rect.zero);
textureBox.paint(paintingContext, Offset.zero);
final Layer layer = containerLayer.lastChild;
expect(layer, isNotNull);
final TextureLayer textureLayer = layer as TextureLayer;
expect(textureLayer, isNotNull);
expect(textureLayer.textureId, 1);
expect(textureLayer.filterQuality, FilterQuality.none);
});
testWidgets('Texture with FilterQuality.low', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(child: Texture(textureId: 1, filterQuality: FilterQuality.low))
);
final Texture texture = tester.firstWidget(find.byType(Texture));
expect(texture, isNotNull);
expect(texture.textureId, 1);
expect(texture.filterQuality, FilterQuality.low);
final RenderObject renderObject = tester.firstRenderObject(find.byType(Texture));
expect(renderObject, isNotNull);
final TextureBox textureBox = renderObject as TextureBox;
expect(textureBox, isNotNull);
expect(textureBox.textureId, 1);
expect(textureBox.filterQuality, FilterQuality.low);
final ContainerLayer containerLayer = ContainerLayer();
final PaintingContext paintingContext = PaintingContext(containerLayer, Rect.zero);
textureBox.paint(paintingContext, Offset.zero);
final Layer layer = containerLayer.lastChild;
expect(layer, isNotNull);
final TextureLayer textureLayer = layer as TextureLayer;
expect(textureLayer, isNotNull);
expect(textureLayer.textureId, 1);
expect(textureLayer.filterQuality, FilterQuality.low);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment