Commit 91b1a076 authored by Jason Simmons's avatar Jason Simmons Committed by GitHub

Framework support for checkerboardOffscreenLayers (#10054)

See https://github.com/flutter/flutter/issues/9473
parent b4e0e541
...@@ -36,6 +36,7 @@ class GalleryApp extends StatefulWidget { ...@@ -36,6 +36,7 @@ class GalleryApp extends StatefulWidget {
this.updateUrlFetcher, this.updateUrlFetcher,
this.enablePerformanceOverlay: true, this.enablePerformanceOverlay: true,
this.checkerboardRasterCacheImages: true, this.checkerboardRasterCacheImages: true,
this.checkerboardOffscreenLayers: true,
this.onSendFeedback, this.onSendFeedback,
Key key} Key key}
) : super(key: key); ) : super(key: key);
...@@ -46,6 +47,8 @@ class GalleryApp extends StatefulWidget { ...@@ -46,6 +47,8 @@ class GalleryApp extends StatefulWidget {
final bool checkerboardRasterCacheImages; final bool checkerboardRasterCacheImages;
final bool checkerboardOffscreenLayers;
final VoidCallback onSendFeedback; final VoidCallback onSendFeedback;
@override @override
...@@ -56,6 +59,7 @@ class GalleryAppState extends State<GalleryApp> { ...@@ -56,6 +59,7 @@ class GalleryAppState extends State<GalleryApp> {
bool _useLightTheme = true; bool _useLightTheme = true;
bool _showPerformanceOverlay = false; bool _showPerformanceOverlay = false;
bool _checkerboardRasterCacheImages = false; bool _checkerboardRasterCacheImages = false;
bool _checkerboardOffscreenLayers = false;
double _timeDilation = 1.0; double _timeDilation = 1.0;
TargetPlatform _platform; TargetPlatform _platform;
...@@ -95,6 +99,12 @@ class GalleryAppState extends State<GalleryApp> { ...@@ -95,6 +99,12 @@ class GalleryAppState extends State<GalleryApp> {
_checkerboardRasterCacheImages = value; _checkerboardRasterCacheImages = value;
}); });
} : null, } : null,
checkerboardOffscreenLayers: _checkerboardOffscreenLayers,
onCheckerboardOffscreenLayersChanged: widget.checkerboardOffscreenLayers ? (bool value) {
setState(() {
_checkerboardOffscreenLayers = value;
});
} : null,
onPlatformChanged: (TargetPlatform value) { onPlatformChanged: (TargetPlatform value) {
setState(() { setState(() {
_platform = value == defaultTargetPlatform ? null : value; _platform = value == defaultTargetPlatform ? null : value;
...@@ -134,6 +144,7 @@ class GalleryAppState extends State<GalleryApp> { ...@@ -134,6 +144,7 @@ class GalleryAppState extends State<GalleryApp> {
theme: (_useLightTheme ? _kGalleryLightTheme : _kGalleryDarkTheme).copyWith(platform: _platform ?? defaultTargetPlatform), theme: (_useLightTheme ? _kGalleryLightTheme : _kGalleryDarkTheme).copyWith(platform: _platform ?? defaultTargetPlatform),
showPerformanceOverlay: _showPerformanceOverlay, showPerformanceOverlay: _showPerformanceOverlay,
checkerboardRasterCacheImages: _checkerboardRasterCacheImages, checkerboardRasterCacheImages: _checkerboardRasterCacheImages,
checkerboardOffscreenLayers: _checkerboardOffscreenLayers,
routes: _kRoutes, routes: _kRoutes,
home: home, home: home,
); );
......
...@@ -98,6 +98,8 @@ class GalleryDrawer extends StatelessWidget { ...@@ -98,6 +98,8 @@ class GalleryDrawer extends StatelessWidget {
this.onShowPerformanceOverlayChanged, this.onShowPerformanceOverlayChanged,
this.checkerboardRasterCacheImages, this.checkerboardRasterCacheImages,
this.onCheckerboardRasterCacheImagesChanged, this.onCheckerboardRasterCacheImagesChanged,
this.checkerboardOffscreenLayers,
this.onCheckerboardOffscreenLayersChanged,
this.onPlatformChanged, this.onPlatformChanged,
this.onSendFeedback, this.onSendFeedback,
}) : super(key: key) { }) : super(key: key) {
...@@ -117,6 +119,9 @@ class GalleryDrawer extends StatelessWidget { ...@@ -117,6 +119,9 @@ class GalleryDrawer extends StatelessWidget {
final bool checkerboardRasterCacheImages; final bool checkerboardRasterCacheImages;
final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged; final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged;
final bool checkerboardOffscreenLayers;
final ValueChanged<bool> onCheckerboardOffscreenLayersChanged;
final ValueChanged<TargetPlatform> onPlatformChanged; final ValueChanged<TargetPlatform> onPlatformChanged;
final VoidCallback onSendFeedback; final VoidCallback onSendFeedback;
...@@ -299,6 +304,23 @@ class GalleryDrawer extends StatelessWidget { ...@@ -299,6 +304,23 @@ class GalleryDrawer extends StatelessWidget {
)); ));
} }
if (onCheckerboardOffscreenLayersChanged != null) {
allDrawerItems.insert(8, new ListTile(
leading: const Icon(Icons.assessment),
title: const Text('Checkerboard Offscreen Layers'),
trailing: new Checkbox(
value: checkerboardOffscreenLayers,
onChanged: (bool value) {
onCheckerboardOffscreenLayersChanged(!checkerboardOffscreenLayers);
},
),
selected: checkerboardOffscreenLayers,
onTap: () {
onCheckerboardOffscreenLayersChanged(!checkerboardOffscreenLayers);
},
));
}
return new Drawer(child: new ListView(primary: false, children: allDrawerItems)); return new Drawer(child: new ListView(primary: false, children: allDrawerItems));
} }
} }
...@@ -76,6 +76,8 @@ class GalleryHome extends StatefulWidget { ...@@ -76,6 +76,8 @@ class GalleryHome extends StatefulWidget {
this.onShowPerformanceOverlayChanged, this.onShowPerformanceOverlayChanged,
this.checkerboardRasterCacheImages, this.checkerboardRasterCacheImages,
this.onCheckerboardRasterCacheImagesChanged, this.onCheckerboardRasterCacheImagesChanged,
this.checkerboardOffscreenLayers,
this.onCheckerboardOffscreenLayersChanged,
this.onPlatformChanged, this.onPlatformChanged,
this.onSendFeedback, this.onSendFeedback,
}) : super(key: key) { }) : super(key: key) {
...@@ -95,6 +97,9 @@ class GalleryHome extends StatefulWidget { ...@@ -95,6 +97,9 @@ class GalleryHome extends StatefulWidget {
final bool checkerboardRasterCacheImages; final bool checkerboardRasterCacheImages;
final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged; final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged;
final bool checkerboardOffscreenLayers;
final ValueChanged<bool> onCheckerboardOffscreenLayersChanged;
final ValueChanged<TargetPlatform> onPlatformChanged; final ValueChanged<TargetPlatform> onPlatformChanged;
final VoidCallback onSendFeedback; final VoidCallback onSendFeedback;
...@@ -161,6 +166,8 @@ class GalleryHomeState extends State<GalleryHome> with SingleTickerProviderState ...@@ -161,6 +166,8 @@ class GalleryHomeState extends State<GalleryHome> with SingleTickerProviderState
onShowPerformanceOverlayChanged: widget.onShowPerformanceOverlayChanged, onShowPerformanceOverlayChanged: widget.onShowPerformanceOverlayChanged,
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages, checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
onCheckerboardRasterCacheImagesChanged: widget.onCheckerboardRasterCacheImagesChanged, onCheckerboardRasterCacheImagesChanged: widget.onCheckerboardRasterCacheImagesChanged,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
onCheckerboardOffscreenLayersChanged: widget.onCheckerboardOffscreenLayersChanged,
onPlatformChanged: widget.onPlatformChanged, onPlatformChanged: widget.onPlatformChanged,
onSendFeedback: widget.onSendFeedback, onSendFeedback: widget.onSendFeedback,
), ),
......
...@@ -60,6 +60,7 @@ class MaterialApp extends StatefulWidget { ...@@ -60,6 +60,7 @@ class MaterialApp extends StatefulWidget {
this.debugShowMaterialGrid: false, this.debugShowMaterialGrid: false,
this.showPerformanceOverlay: false, this.showPerformanceOverlay: false,
this.checkerboardRasterCacheImages: false, this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false,
this.showSemanticsDebugger: false, this.showSemanticsDebugger: false,
this.debugShowCheckedModeBanner: true this.debugShowCheckedModeBanner: true
}) : super(key: key) { }) : super(key: key) {
...@@ -135,6 +136,9 @@ class MaterialApp extends StatefulWidget { ...@@ -135,6 +136,9 @@ class MaterialApp extends StatefulWidget {
/// Turns on checkerboarding of raster cache images. /// Turns on checkerboarding of raster cache images.
final bool checkerboardRasterCacheImages; final bool checkerboardRasterCacheImages;
/// Turns on checkerboarding of layers rendered to offscreen bitmaps.
final bool checkerboardOffscreenLayers;
/// Turns on an overlay that shows the accessibility information /// Turns on an overlay that shows the accessibility information
/// reported by the framework. /// reported by the framework.
final bool showSemanticsDebugger; final bool showSemanticsDebugger;
...@@ -240,6 +244,7 @@ class _MaterialAppState extends State<MaterialApp> { ...@@ -240,6 +244,7 @@ class _MaterialAppState extends State<MaterialApp> {
onLocaleChanged: widget.onLocaleChanged, onLocaleChanged: widget.onLocaleChanged,
showPerformanceOverlay: widget.showPerformanceOverlay, showPerformanceOverlay: widget.showPerformanceOverlay,
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages, checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
showSemanticsDebugger: widget.showSemanticsDebugger, showSemanticsDebugger: widget.showSemanticsDebugger,
debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner
) )
......
...@@ -163,6 +163,7 @@ class PerformanceOverlayLayer extends Layer { ...@@ -163,6 +163,7 @@ class PerformanceOverlayLayer extends Layer {
@required this.optionsMask, @required this.optionsMask,
@required this.rasterizerThreshold, @required this.rasterizerThreshold,
@required this.checkerboardRasterCacheImages, @required this.checkerboardRasterCacheImages,
@required this.checkerboardOffscreenLayers,
}); });
/// The rectangle in this layer's coordinate system that the overlay should occupy. /// The rectangle in this layer's coordinate system that the overlay should occupy.
...@@ -193,12 +194,23 @@ class PerformanceOverlayLayer extends Layer { ...@@ -193,12 +194,23 @@ class PerformanceOverlayLayer extends Layer {
/// that aid it in making better decisions about caching. /// that aid it in making better decisions about caching.
final bool checkerboardRasterCacheImages; final bool checkerboardRasterCacheImages;
/// Whether the compositor should checkerboard layers that are rendered to offscreen
/// bitmaps. This can be useful for debugging rendering performance.
///
/// Render target switches are caused by using opacity layers (via a [FadeTransition] or
/// [Opacity] widget), clips, shader mask layers, etc. Selecting a new render target
/// and merging it with the rest of the scene has a performance cost. This can sometimes
/// be avoided by using equivalent widgets that do not require these layers (for example,
/// replacing an [Opacity] widget with an [widgets.Image] using a [BlendMode]).
final bool checkerboardOffscreenLayers;
@override @override
void addToScene(ui.SceneBuilder builder, Offset layerOffset) { void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
assert(optionsMask != null); assert(optionsMask != null);
builder.addPerformanceOverlay(optionsMask, overlayRect.shift(layerOffset)); builder.addPerformanceOverlay(optionsMask, overlayRect.shift(layerOffset));
builder.setRasterizerTracingThreshold(rasterizerThreshold); builder.setRasterizerTracingThreshold(rasterizerThreshold);
builder.setCheckerboardRasterCacheImages(checkerboardRasterCacheImages); builder.setCheckerboardRasterCacheImages(checkerboardRasterCacheImages);
builder.setCheckerboardOffscreenLayers(checkerboardOffscreenLayers);
} }
} }
......
...@@ -59,18 +59,21 @@ enum PerformanceOverlayOption { ...@@ -59,18 +59,21 @@ enum PerformanceOverlayOption {
class RenderPerformanceOverlay extends RenderBox { class RenderPerformanceOverlay extends RenderBox {
/// Creates a performance overlay render object. /// Creates a performance overlay render object.
/// ///
/// The [optionsMask], [rasterizerThreshold] and [checkerboardRasterCacheImages] /// The [optionsMask], [rasterizerThreshold], [checkerboardRasterCacheImages],
/// arguments must not be null. /// and [checkerboardOffscreenLayers] arguments must not be null.
RenderPerformanceOverlay({ RenderPerformanceOverlay({
int optionsMask: 0, int optionsMask: 0,
int rasterizerThreshold: 0, int rasterizerThreshold: 0,
bool checkerboardRasterCacheImages: false, bool checkerboardRasterCacheImages: false,
bool checkerboardOffscreenLayers: false,
}) : _optionsMask = optionsMask, }) : _optionsMask = optionsMask,
_rasterizerThreshold = rasterizerThreshold, _rasterizerThreshold = rasterizerThreshold,
_checkerboardRasterCacheImages = checkerboardRasterCacheImages { _checkerboardRasterCacheImages = checkerboardRasterCacheImages,
_checkerboardOffscreenLayers = checkerboardOffscreenLayers {
assert(optionsMask != null); assert(optionsMask != null);
assert(rasterizerThreshold != null); assert(rasterizerThreshold != null);
assert(checkerboardRasterCacheImages != null); assert(checkerboardRasterCacheImages != null);
assert(checkerboardOffscreenLayers != null);
} }
/// The mask is created by shifting 1 by the index of the specific /// The mask is created by shifting 1 by the index of the specific
...@@ -109,6 +112,17 @@ class RenderPerformanceOverlay extends RenderBox { ...@@ -109,6 +112,17 @@ class RenderPerformanceOverlay extends RenderBox {
markNeedsPaint(); markNeedsPaint();
} }
/// Whether the compositor should checkerboard layers rendered to offscreen bitmaps.
bool get checkerboardOffscreenLayers => _checkerboardOffscreenLayers;
bool _checkerboardOffscreenLayers;
set checkerboardOffscreenLayers(bool value) {
assert(value != null);
if (value == _checkerboardOffscreenLayers)
return;
_checkerboardOffscreenLayers = value;
markNeedsPaint();
}
@override @override
bool get sizedByParent => true; bool get sizedByParent => true;
...@@ -160,6 +174,7 @@ class RenderPerformanceOverlay extends RenderBox { ...@@ -160,6 +174,7 @@ class RenderPerformanceOverlay extends RenderBox {
optionsMask: optionsMask, optionsMask: optionsMask,
rasterizerThreshold: rasterizerThreshold, rasterizerThreshold: rasterizerThreshold,
checkerboardRasterCacheImages: checkerboardRasterCacheImages, checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
)); ));
} }
} }
...@@ -49,12 +49,14 @@ class WidgetsApp extends StatefulWidget { ...@@ -49,12 +49,14 @@ class WidgetsApp extends StatefulWidget {
this.onLocaleChanged, this.onLocaleChanged,
this.showPerformanceOverlay: false, this.showPerformanceOverlay: false,
this.checkerboardRasterCacheImages: false, this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false,
this.showSemanticsDebugger: false, this.showSemanticsDebugger: false,
this.debugShowCheckedModeBanner: true this.debugShowCheckedModeBanner: true
}) : assert(color != null), }) : assert(color != null),
assert(onGenerateRoute != null), assert(onGenerateRoute != null),
assert(showPerformanceOverlay != null), assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null), assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null), assert(showSemanticsDebugger != null),
super(key: key); super(key: key);
...@@ -89,8 +91,15 @@ class WidgetsApp extends StatefulWidget { ...@@ -89,8 +91,15 @@ class WidgetsApp extends StatefulWidget {
final bool showPerformanceOverlay; final bool showPerformanceOverlay;
/// Checkerboards raster cache images. /// Checkerboards raster cache images.
///
/// See [PerformanceOverlay.checkerboardRasterCacheImages].
final bool checkerboardRasterCacheImages; final bool checkerboardRasterCacheImages;
/// Checkerboards layers rendered to offscreen bitmaps.
///
/// See [PerformanceOverlay.checkerboardOffscreenLayers].
final bool checkerboardOffscreenLayers;
/// Turns on an overlay that shows the accessibility information /// Turns on an overlay that shows the accessibility information
/// reported by the framework. /// reported by the framework.
final bool showSemanticsDebugger; final bool showSemanticsDebugger;
...@@ -220,9 +229,14 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv ...@@ -220,9 +229,14 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
// options are set. // options are set.
if (widget.showPerformanceOverlay || WidgetsApp.showPerformanceOverlayOverride) { if (widget.showPerformanceOverlay || WidgetsApp.showPerformanceOverlayOverride) {
performanceOverlay = new PerformanceOverlay.allEnabled( performanceOverlay = new PerformanceOverlay.allEnabled(
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages); checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
} else if (widget.checkerboardRasterCacheImages) { checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
performanceOverlay = const PerformanceOverlay(checkerboardRasterCacheImages: true); );
} else if (widget.checkerboardRasterCacheImages || widget.checkerboardOffscreenLayers) {
performanceOverlay = new PerformanceOverlay(
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
);
} }
if (performanceOverlay != null) { if (performanceOverlay != null) {
......
...@@ -31,13 +31,15 @@ class PerformanceOverlay extends LeafRenderObjectWidget { ...@@ -31,13 +31,15 @@ class PerformanceOverlay extends LeafRenderObjectWidget {
Key key, Key key,
this.optionsMask: 0, this.optionsMask: 0,
this.rasterizerThreshold: 0, this.rasterizerThreshold: 0,
this.checkerboardRasterCacheImages: false this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false,
}) : super(key: key); }) : super(key: key);
/// Create a performance overlay that displays all available statistics /// Create a performance overlay that displays all available statistics
PerformanceOverlay.allEnabled({ Key key, PerformanceOverlay.allEnabled({ Key key,
this.rasterizerThreshold: 0, this.rasterizerThreshold: 0,
this.checkerboardRasterCacheImages: false }) this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false })
: optionsMask = ( : optionsMask = (
1 << PerformanceOverlayOption.displayRasterizerStatistics.index | 1 << PerformanceOverlayOption.displayRasterizerStatistics.index |
1 << PerformanceOverlayOption.visualizeRasterizerStatistics.index | 1 << PerformanceOverlayOption.visualizeRasterizerStatistics.index |
...@@ -91,11 +93,22 @@ class PerformanceOverlay extends LeafRenderObjectWidget { ...@@ -91,11 +93,22 @@ class PerformanceOverlay extends LeafRenderObjectWidget {
/// that aid it in making better decisions about caching. /// that aid it in making better decisions about caching.
final bool checkerboardRasterCacheImages; final bool checkerboardRasterCacheImages;
/// Whether the compositor should checkerboard layers that are rendered to offscreen
/// bitmaps. This can be useful for debugging rendering performance.
///
/// Render target switches are caused by using opacity layers (via a [FadeTransition] or
/// [Opacity] widget), clips, shader mask layers, etc. Selecting a new render target
/// and merging it with the rest of the scene has a performance cost. This can sometimes
/// be avoided by using equivalent widgets that do not require these layers (for example,
/// replacing an [Opacity] widget with an [widgets.Image] using a [BlendMode]).
final bool checkerboardOffscreenLayers;
@override @override
RenderPerformanceOverlay createRenderObject(BuildContext context) => new RenderPerformanceOverlay( RenderPerformanceOverlay createRenderObject(BuildContext context) => new RenderPerformanceOverlay(
optionsMask: optionsMask, optionsMask: optionsMask,
rasterizerThreshold: rasterizerThreshold, rasterizerThreshold: rasterizerThreshold,
checkerboardRasterCacheImages: checkerboardRasterCacheImages checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
); );
@override @override
......
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