Skip empty platform view overlays.#11427
Conversation
This change sets up a "spying canvas" to try and detect empty canvases. When using platform views with a custom embedder, if a platform view overlay canvas is known to be empty we skip creating a compositor layer for that overlay.
d67d1fd to
fb66d03
Compare
chinmaygarde
left a comment
There was a problem hiding this comment.
Other than a test to make sure we don't ask the embedder for a backing store unnecessarily, everything else looks good. All other comments are nits.
| // This is used to determine whether anything was drawn into | ||
| // a canvas so it is possible to implement optimizations that | ||
| // are specific to empty canvases. | ||
| class CanvasSpy { |
There was a problem hiding this comment.
The comments won't end up in doxygen generated docs. See shell.h for a prototype.
Ditto for all other comment blocks.
shell/common/canvas_spy_unittests.cc
Outdated
| SkPixmap actual; | ||
| SkPixmap expected; | ||
|
|
||
| actual_surface->peekPixels(&actual); |
There was a problem hiding this comment.
These calls can fail. ASSERT_TRUE on the result.
| actual_surface->peekPixels(&actual); | ||
| expected_surface->peekPixels(&expected); | ||
|
|
||
| const auto size = actual.rowBytes() * actual.height(); |
There was a problem hiding this comment.
ASSERT_NE(size, 0) to make sure earlier failures on the peek don't result in this test passing.
shell/common/canvas_spy.cc
Outdated
| return n_way_canvas_.get(); | ||
| } | ||
|
|
||
| DidDrawCanvas::DidDrawCanvas(int width, int height) : INHERITED(width, height) { |
There was a problem hiding this comment.
We don't use Skia's internal non-namespaced macros or the typedef pattern. Please use the superclass name directly instead of using INHERITED.
shell/common/canvas_spy.cc
Outdated
| } | ||
|
|
||
| DidDrawCanvas::DidDrawCanvas(int width, int height) : INHERITED(width, height) { | ||
| did_draw_ = false; |
There was a problem hiding this comment.
Nit: Prefer defaulting this to false in the header and get rid of this. That way, if/when we add more ctors, we don't have to remember to default all scalars.
shell/common/canvas_spy.h
Outdated
| ~DidDrawCanvas() override; | ||
| bool DidDrawIntoCanvas(); | ||
|
|
||
| protected: |
There was a problem hiding this comment.
We are not going to subclass this further. Please make this private and mark the class final. This will also make it a compiler error if the base class adds new pure virtual methods that we haven't overriden.
| bool onDoSaveBehind(const SkRect*) override; | ||
| void willRestore() override; | ||
|
|
||
| void didConcat(const SkMatrix&) override; |
There was a problem hiding this comment.
We mention the class/interface that defines the method being overriden. So, // | SkCanvasVirtualEnforcer<SkNoDrawCanvas>| here and in the implementation for all overrides.
| presented_layers.push_back( | ||
| MakeLayer(params, presented_platform_views.at(view_id))); | ||
|
|
||
| if (!pending_canvas_spies_[view_id]->DidDrawIntoCanvas()) { |
There was a problem hiding this comment.
Use .at() instead of .[] when you know you don't want to insert a default constructed map element. We know this is safe because of the DCHECK added above.
| if (!pending_canvas_spies_[view_id]->DidDrawIntoCanvas()) { | ||
| // Nothing was drawn into the overlay canvas, we don't need to composite | ||
| // it. | ||
| continue; |
There was a problem hiding this comment.
Test this continue. We should upgrade the embedder test compositor to make sure we track the number of backing stores being requested of the the embedder. Then assert that we don't ask for extra backing stores. If we forgot or later moved this continue, no test would fail.
There was a problem hiding this comment.
Added an assertion for the number of backing stores in the test.
Side note that EmbedderTest.CompositorMustBeAbleToRenderWithPlatformLayerOnBottom would have failed if we removed this continue.
shell/common/canvas_spy.cc
Outdated
| return n_way_canvas_.get(); | ||
| } | ||
|
|
||
| DidDrawCanvas::DidDrawCanvas(int width, int height) : INHERITED(width, height) { |
shell/common/canvas_spy.cc
Outdated
| } | ||
|
|
||
| DidDrawCanvas::DidDrawCanvas(int width, int height) : INHERITED(width, height) { | ||
| did_draw_ = false; |
| // This is used to determine whether anything was drawn into | ||
| // a canvas so it is possible to implement optimizations that | ||
| // are specific to empty canvases. | ||
| class CanvasSpy { |
shell/common/canvas_spy.h
Outdated
| ~DidDrawCanvas() override; | ||
| bool DidDrawIntoCanvas(); | ||
|
|
||
| protected: |
| bool onDoSaveBehind(const SkRect*) override; | ||
| void willRestore() override; | ||
|
|
||
| void didConcat(const SkMatrix&) override; |
shell/common/canvas_spy_unittests.cc
Outdated
| SkPixmap actual; | ||
| SkPixmap expected; | ||
|
|
||
| actual_surface->peekPixels(&actual); |
| actual_surface->peekPixels(&actual); | ||
| expected_surface->peekPixels(&expected); | ||
|
|
||
| const auto size = actual.rowBytes() * actual.height(); |
| presented_layers.push_back( | ||
| MakeLayer(params, presented_platform_views.at(view_id))); | ||
|
|
||
| if (!pending_canvas_spies_[view_id]->DidDrawIntoCanvas()) { |
| if (!pending_canvas_spies_[view_id]->DidDrawIntoCanvas()) { | ||
| // Nothing was drawn into the overlay canvas, we don't need to composite | ||
| // it. | ||
| continue; |
There was a problem hiding this comment.
Added an assertion for the number of backing stores in the test.
Side note that EmbedderTest.CompositorMustBeAbleToRenderWithPlatformLayerOnBottom would have failed if we removed this continue.
|
I am going to close b/139737705. |
[email protected]:flutter/engine.git/compare/11e3ade157db...ba1a303 git log 11e3ade..ba1a303 --no-merges --oneline 2019-08-26 [email protected] Patch buttons for chromebook touchpad (flutter/engine#11420) 2019-08-26 [email protected] Skip empty platform view overlays. (flutter/engine#11427) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected] on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md
|
@amirh : this looks like a performance optimization. Is there a known benchmark that covers this performance? Or is there a manual performance test process that's documented somewhere? |
|
This optimization is guaranteed by the engine and made available to the embedder. This is tested in the the CanvasSpyUnittests Amir added in this patch and enabled in |
This change sets up a "spying canvas" to try and detect empty canvases.
When using platform views with a custom embedder, if a platform view
overlay canvas is known to be empty we skip creating a compositor layer
for that overlay.