1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/foundation.dart';
6
7import 'box.dart';
8import 'layer.dart';
9import 'object.dart';
10
11/// A rectangle upon which a backend texture is mapped.
12///
13/// Backend textures are images that can be applied (mapped) to an area of the
14/// Flutter view. They are created, managed, and updated using a
15/// platform-specific texture registry. This is typically done by a plugin
16/// that integrates with host platform video player, camera, or OpenGL APIs,
17/// or similar image sources.
18///
19/// A texture box refers to its backend texture using an integer ID. Texture
20/// IDs are obtained from the texture registry and are scoped to the Flutter
21/// view. Texture IDs may be reused after deregistration, at the discretion
22/// of the registry. The use of texture IDs currently unknown to the registry
23/// will silently result in a blank rectangle.
24///
25/// Texture boxes are repainted autonomously as dictated by the backend (e.g. on
26/// arrival of a video frame). Such repainting generally does not involve
27/// executing Dart code.
28///
29/// The size of the rectangle is determined by the parent, and the texture is
30/// automatically scaled to fit.
31///
32/// See also:
33///
34/// * [TextureRegistry](/javadoc/io/flutter/view/TextureRegistry.html)
35/// for how to create and manage backend textures on Android.
36/// * [TextureRegistry Protocol](/ios-embedder/protocol_flutter_texture_registry-p.html)
37/// for how to create and manage backend textures on iOS.
38class TextureBox extends RenderBox {
39 /// Creates a box backed by the texture identified by [textureId], and use
40 /// [filterQuality] to set texture's [FilterQuality].
41 TextureBox({
42 required int textureId,
43 bool freeze = false,
44 FilterQuality filterQuality = FilterQuality.low,
45 }) : _textureId = textureId,
46 _freeze = freeze,
47 _filterQuality = filterQuality;
48
49 /// The identity of the backend texture.
50 int get textureId => _textureId;
51 int _textureId;
52 set textureId(int value) {
53 if (value != _textureId) {
54 _textureId = value;
55 markNeedsPaint();
56 }
57 }
58
59 /// When true the texture will not be updated with new frames.
60 bool get freeze => _freeze;
61 bool _freeze;
62 set freeze(bool value) {
63 if (value != _freeze) {
64 _freeze = value;
65 markNeedsPaint();
66 }
67 }
68
69 /// {@macro flutter.widgets.Texture.filterQuality}
70 FilterQuality get filterQuality => _filterQuality;
71 FilterQuality _filterQuality;
72 set filterQuality(FilterQuality value) {
73 if (value != _filterQuality) {
74 _filterQuality = value;
75 markNeedsPaint();
76 }
77 }
78
79 @override
80 bool get sizedByParent => true;
81
82 @override
83 bool get alwaysNeedsCompositing => true;
84
85 @override
86 bool get isRepaintBoundary => true;
87
88 @override
89 @protected
90 Size computeDryLayout(covariant BoxConstraints constraints) {
91 return constraints.biggest;
92 }
93
94 @override
95 bool hitTestSelf(Offset position) => true;
96
97 @override
98 void paint(PaintingContext context, Offset offset) {
99 context.addLayer(TextureLayer(
100 rect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height),
101 textureId: _textureId,
102 freeze: freeze,
103 filterQuality: _filterQuality,
104 ));
105 }
106}
107