Framework support for checkerboardOffscreenLayers (#10054)

See https://github.com/flutter/flutter/issues/9473
This commit is contained in:
Jason Simmons 2017-05-12 14:41:07 -07:00 committed by GitHub
parent b4e0e541ec
commit 91b1a07656
8 changed files with 108 additions and 9 deletions

View file

@ -36,6 +36,7 @@ class GalleryApp extends StatefulWidget {
this.updateUrlFetcher,
this.enablePerformanceOverlay: true,
this.checkerboardRasterCacheImages: true,
this.checkerboardOffscreenLayers: true,
this.onSendFeedback,
Key key}
) : super(key: key);
@ -46,6 +47,8 @@ class GalleryApp extends StatefulWidget {
final bool checkerboardRasterCacheImages;
final bool checkerboardOffscreenLayers;
final VoidCallback onSendFeedback;
@override
@ -56,6 +59,7 @@ class GalleryAppState extends State<GalleryApp> {
bool _useLightTheme = true;
bool _showPerformanceOverlay = false;
bool _checkerboardRasterCacheImages = false;
bool _checkerboardOffscreenLayers = false;
double _timeDilation = 1.0;
TargetPlatform _platform;
@ -95,6 +99,12 @@ class GalleryAppState extends State<GalleryApp> {
_checkerboardRasterCacheImages = value;
});
} : null,
checkerboardOffscreenLayers: _checkerboardOffscreenLayers,
onCheckerboardOffscreenLayersChanged: widget.checkerboardOffscreenLayers ? (bool value) {
setState(() {
_checkerboardOffscreenLayers = value;
});
} : null,
onPlatformChanged: (TargetPlatform value) {
setState(() {
_platform = value == defaultTargetPlatform ? null : value;
@ -134,6 +144,7 @@ class GalleryAppState extends State<GalleryApp> {
theme: (_useLightTheme ? _kGalleryLightTheme : _kGalleryDarkTheme).copyWith(platform: _platform ?? defaultTargetPlatform),
showPerformanceOverlay: _showPerformanceOverlay,
checkerboardRasterCacheImages: _checkerboardRasterCacheImages,
checkerboardOffscreenLayers: _checkerboardOffscreenLayers,
routes: _kRoutes,
home: home,
);

View file

@ -98,6 +98,8 @@ class GalleryDrawer extends StatelessWidget {
this.onShowPerformanceOverlayChanged,
this.checkerboardRasterCacheImages,
this.onCheckerboardRasterCacheImagesChanged,
this.checkerboardOffscreenLayers,
this.onCheckerboardOffscreenLayersChanged,
this.onPlatformChanged,
this.onSendFeedback,
}) : super(key: key) {
@ -117,6 +119,9 @@ class GalleryDrawer extends StatelessWidget {
final bool checkerboardRasterCacheImages;
final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged;
final bool checkerboardOffscreenLayers;
final ValueChanged<bool> onCheckerboardOffscreenLayersChanged;
final ValueChanged<TargetPlatform> onPlatformChanged;
final VoidCallback onSendFeedback;
@ -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));
}
}

View file

@ -76,6 +76,8 @@ class GalleryHome extends StatefulWidget {
this.onShowPerformanceOverlayChanged,
this.checkerboardRasterCacheImages,
this.onCheckerboardRasterCacheImagesChanged,
this.checkerboardOffscreenLayers,
this.onCheckerboardOffscreenLayersChanged,
this.onPlatformChanged,
this.onSendFeedback,
}) : super(key: key) {
@ -95,6 +97,9 @@ class GalleryHome extends StatefulWidget {
final bool checkerboardRasterCacheImages;
final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged;
final bool checkerboardOffscreenLayers;
final ValueChanged<bool> onCheckerboardOffscreenLayersChanged;
final ValueChanged<TargetPlatform> onPlatformChanged;
final VoidCallback onSendFeedback;
@ -161,6 +166,8 @@ class GalleryHomeState extends State<GalleryHome> with SingleTickerProviderState
onShowPerformanceOverlayChanged: widget.onShowPerformanceOverlayChanged,
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
onCheckerboardRasterCacheImagesChanged: widget.onCheckerboardRasterCacheImagesChanged,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
onCheckerboardOffscreenLayersChanged: widget.onCheckerboardOffscreenLayersChanged,
onPlatformChanged: widget.onPlatformChanged,
onSendFeedback: widget.onSendFeedback,
),

View file

@ -60,6 +60,7 @@ class MaterialApp extends StatefulWidget {
this.debugShowMaterialGrid: false,
this.showPerformanceOverlay: false,
this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false,
this.showSemanticsDebugger: false,
this.debugShowCheckedModeBanner: true
}) : super(key: key) {
@ -135,6 +136,9 @@ class MaterialApp extends StatefulWidget {
/// Turns on checkerboarding of raster cache images.
final bool checkerboardRasterCacheImages;
/// Turns on checkerboarding of layers rendered to offscreen bitmaps.
final bool checkerboardOffscreenLayers;
/// Turns on an overlay that shows the accessibility information
/// reported by the framework.
final bool showSemanticsDebugger;
@ -240,6 +244,7 @@ class _MaterialAppState extends State<MaterialApp> {
onLocaleChanged: widget.onLocaleChanged,
showPerformanceOverlay: widget.showPerformanceOverlay,
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
showSemanticsDebugger: widget.showSemanticsDebugger,
debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner
)

View file

@ -163,6 +163,7 @@ class PerformanceOverlayLayer extends Layer {
@required this.optionsMask,
@required this.rasterizerThreshold,
@required this.checkerboardRasterCacheImages,
@required this.checkerboardOffscreenLayers,
});
/// The rectangle in this layer's coordinate system that the overlay should occupy.
@ -193,12 +194,23 @@ class PerformanceOverlayLayer extends Layer {
/// that aid it in making better decisions about caching.
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
void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
assert(optionsMask != null);
builder.addPerformanceOverlay(optionsMask, overlayRect.shift(layerOffset));
builder.setRasterizerTracingThreshold(rasterizerThreshold);
builder.setCheckerboardRasterCacheImages(checkerboardRasterCacheImages);
builder.setCheckerboardOffscreenLayers(checkerboardOffscreenLayers);
}
}

View file

@ -59,18 +59,21 @@ enum PerformanceOverlayOption {
class RenderPerformanceOverlay extends RenderBox {
/// Creates a performance overlay render object.
///
/// The [optionsMask], [rasterizerThreshold] and [checkerboardRasterCacheImages]
/// arguments must not be null.
/// The [optionsMask], [rasterizerThreshold], [checkerboardRasterCacheImages],
/// and [checkerboardOffscreenLayers] arguments must not be null.
RenderPerformanceOverlay({
int optionsMask: 0,
int rasterizerThreshold: 0,
bool checkerboardRasterCacheImages: false,
bool checkerboardOffscreenLayers: false,
}) : _optionsMask = optionsMask,
_rasterizerThreshold = rasterizerThreshold,
_checkerboardRasterCacheImages = checkerboardRasterCacheImages {
_checkerboardRasterCacheImages = checkerboardRasterCacheImages,
_checkerboardOffscreenLayers = checkerboardOffscreenLayers {
assert(optionsMask != null);
assert(rasterizerThreshold != null);
assert(checkerboardRasterCacheImages != null);
assert(checkerboardOffscreenLayers != null);
}
/// The mask is created by shifting 1 by the index of the specific
@ -109,6 +112,17 @@ class RenderPerformanceOverlay extends RenderBox {
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
bool get sizedByParent => true;
@ -160,6 +174,7 @@ class RenderPerformanceOverlay extends RenderBox {
optionsMask: optionsMask,
rasterizerThreshold: rasterizerThreshold,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
));
}
}

View file

@ -49,12 +49,14 @@ class WidgetsApp extends StatefulWidget {
this.onLocaleChanged,
this.showPerformanceOverlay: false,
this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false,
this.showSemanticsDebugger: false,
this.debugShowCheckedModeBanner: true
}) : assert(color != null),
assert(onGenerateRoute != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
super(key: key);
@ -89,8 +91,15 @@ class WidgetsApp extends StatefulWidget {
final bool showPerformanceOverlay;
/// Checkerboards raster cache images.
///
/// See [PerformanceOverlay.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
/// reported by the framework.
final bool showSemanticsDebugger;
@ -220,9 +229,14 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
// options are set.
if (widget.showPerformanceOverlay || WidgetsApp.showPerformanceOverlayOverride) {
performanceOverlay = new PerformanceOverlay.allEnabled(
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages);
} else if (widget.checkerboardRasterCacheImages) {
performanceOverlay = const PerformanceOverlay(checkerboardRasterCacheImages: true);
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
);
} else if (widget.checkerboardRasterCacheImages || widget.checkerboardOffscreenLayers) {
performanceOverlay = new PerformanceOverlay(
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
);
}
if (performanceOverlay != null) {

View file

@ -31,13 +31,15 @@ class PerformanceOverlay extends LeafRenderObjectWidget {
Key key,
this.optionsMask: 0,
this.rasterizerThreshold: 0,
this.checkerboardRasterCacheImages: false
this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false,
}) : super(key: key);
/// Create a performance overlay that displays all available statistics
PerformanceOverlay.allEnabled({ Key key,
this.rasterizerThreshold: 0,
this.checkerboardRasterCacheImages: false })
this.checkerboardRasterCacheImages: false,
this.checkerboardOffscreenLayers: false })
: optionsMask = (
1 << PerformanceOverlayOption.displayRasterizerStatistics.index |
1 << PerformanceOverlayOption.visualizeRasterizerStatistics.index |
@ -91,11 +93,22 @@ class PerformanceOverlay extends LeafRenderObjectWidget {
/// that aid it in making better decisions about caching.
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
RenderPerformanceOverlay createRenderObject(BuildContext context) => new RenderPerformanceOverlay(
optionsMask: optionsMask,
rasterizerThreshold: rasterizerThreshold,
checkerboardRasterCacheImages: checkerboardRasterCacheImages
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
);
@override