-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] Use the new DisplayList depth info in the experimental canvas prototype #52214
[Impeller] Use the new DisplayList depth info in the experimental canvas prototype #52214
Conversation
Not exactly the most thorough stress test, but this flutter app with a bunch of save/restored clips now restores the clip state correctly with this patch... main.dart
|
When I run this on flutter gallery (dev/integration_tests/new_gallery) without the experimental canvas patch I'm getting a warning about an unresolved depth value: E/flutter (14094): [ERROR:flutter/impeller/base/validation.cc(59)] Break on 'ImpellerValidationBreak' to inspect point of failure: EntityPass (Depth=1) contains one or more clips with an unresolved depth value. |
This also crashes on gallery with the new canvas enabled:
|
This is happening while drawing a shadow:
|
It looks like the call to save in drawShadow is missing the depth value? |
Here is my diff that I think fixes it at least for the gallery case: diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc
index 6c86ea3b5c..4feb71ee1f 100644
--- a/impeller/aiks/canvas.cc
+++ b/impeller/aiks/canvas.cc
@@ -21,6 +21,7 @@
#include "impeller/entity/contents/text_contents.h"
#include "impeller/entity/contents/texture_contents.h"
#include "impeller/entity/contents/vertices_contents.h"
+#include "impeller/entity/entity_pass.h"
#include "impeller/entity/geometry/geometry.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/constants.h"
@@ -411,13 +412,13 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
// Defer the alpha, blend mode, and image filter to a separate layer.
SaveLayer({.color = Color::White().WithAlpha(rrect_color.alpha),
.blend_mode = paint.blend_mode,
- .image_filter = paint.image_filter});
+ .image_filter = paint.image_filter}, /*bounds=*/std::nullopt, nullptr, ContentBoundsPromise::kContainsContents, 1); // TODO bounds + promise.
rrect_paint.color = rrect_color.WithAlpha(1);
} else {
rrect_paint.color = rrect_color;
rrect_paint.blend_mode = paint.blend_mode;
rrect_paint.image_filter = paint.image_filter;
- Save();
+ Save(1);
}
auto draw_blurred_rrect = [this, &rect, &corner_radii, &rrect_paint]() {
diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc
index ab07ebdd9a..51a70068ca 100644
--- a/impeller/display_list/dl_dispatcher.cc
+++ b/impeller/display_list/dl_dispatcher.cc
@@ -1152,7 +1152,7 @@ void DlDispatcherBase::drawShadow(const CacheablePath& cache,
GetCanvas().GetCurrentTransform().GetScale().y},
};
- GetCanvas().Save();
+ GetCanvas().Save(1); // Only a single draw.
GetCanvas().PreConcat(
Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y)));
diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc
index e85ed212f9..e502834b38 100644
--- a/shell/gpu/gpu_surface_vulkan_impeller.cc
+++ b/shell/gpu/gpu_surface_vulkan_impeller.cc |
I think the correct bounds for that SaveLayer is probably just the RRect bounds |
There is also an error on the existing canvas when an image filter is applied, this can be seen when the stretch overscroll effect on the gallery runs - same error about unresolved depth value. |
impeller/aiks/canvas.cc
Outdated
@@ -407,13 +411,14 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect, | |||
// Defer the alpha, blend mode, and image filter to a separate layer. | |||
SaveLayer({.color = Color::White().WithAlpha(rrect_color.alpha), | |||
.blend_mode = paint.blend_mode, | |||
.image_filter = paint.image_filter}); | |||
.image_filter = paint.image_filter}, | |||
rect, nullptr, ContentBoundsPromise::kContainsContents, 1u); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually since this is for the rrect blur we need to expand the coverage size up to some threshold. Doesn't need to be done now I'd just note it so we don't forget.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
err not rrect blur, the slow gaussian blur path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bounds for a SaveLayer are the content bounds, not for the filtered bounds, so it should not include any expansion by the image_filter in the SaveLayer paint...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, are you saying that the contents of this SaveLayer will be the expanded blurred rrect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh right, if its the content bounds its just the rect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
loweing as in replacing things like drawShadow
with saveLayer/blur drawShape restore
. It would be specific to this renderer but that is good IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, as we progress along with the experimental canvas we might start relying less on calling one method from another with depth implications and just insert the associated rendering structures more directly. Then we'll have more immediate control over the allocation of depths from each operation. Currently, the things that you suggest will have automatic allocations of depth implicit in calling "that other rendering operation". We could create a new layer, draw the blurred thing to it, and then render it back to the original render target all without needing to bump the depth more than the implicitly assigned single depth value. For now there are just a lot of side effects to each implementation because we're trying to leverage the regular canvas ops.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to adjust for this by just having the DL allocate 2 depths per rendering op when there is a MaskFilter in effect. It's kind of Impeller-specific logic, but it's abstracted a bit to keep the object encapsulation intact. In reality, DL could always allocate 5 or 20 depths to each rendering op and we'd still never really run out of room in the depth buffer. Then we won't care how efficient or multi-staged the Impeller implementations are. For now, I'm trying to keep it mostly stingy with occasional conservative over-allocations...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latest commit adjusts for this additional SaveLayer.
In the latest commit I've added EXPERIMENTAL support for the playground... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…mental canvas prototype (flutter/engine#52214)
…147085) flutter/engine@5083af6...0902c41 2024-04-19 flar@google.com [Impeller] Use the new DisplayList depth info in the experimental canvas prototype (flutter/engine#52214) 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 jsimmons@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…lutter#147085) flutter/engine@5083af6...0902c41 2024-04-19 flar@google.com [Impeller] Use the new DisplayList depth info in the experimental canvas prototype (flutter/engine#52214) 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 jsimmons@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Plumbing the new DL depth data into the experimental direct rendering Impeller canvas prototype.