-
Notifications
You must be signed in to change notification settings - Fork 28.9k
[DisplayList] implement shadow bounds without relying on Skia utilities #172572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DisplayList] implement shadow bounds without relying on Skia utilities #172572
Conversation
|
||
} // namespace | ||
|
||
TEST(DlSkCanvas, ShadowBoundsCompatibilityTranslateScale) { |
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.
Note: These tests make sure we return the same answers as the previous code, but they will be deleted summarily when we delete the Skia backend (this entire directory will be deleted in whole).
So, there are also some additional tests in dl_canvas_unittests.cc
that test the raw answers without comparing to Skia and those will live on at that point...
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.
@gaaclarke here are the droi...tests you were looking for...
// need -B for the final quadratic equation computations anyway.) | ||
double negB = a2 + d2; | ||
double C = a2 * d2 - b2 * c2; | ||
double B2minus4AC = negB * negB - 4 * 1.0f * C; |
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.
Here and elsewhere, use underscore_case
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.
That gets tricky for these values that represent known variables in a common formula, so these would need to have capital A,B,C in them - but otherwise I can make them snake case.
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.
How about the new names?
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 assuming we have a lot of existing test coverage in the existing goldens, right?
EXPECT_FLOAT_EQ(shadow_bounds.GetLeft(), 96.333336f); | ||
EXPECT_FLOAT_EQ(shadow_bounds.GetTop(), 97.761909f); | ||
EXPECT_FLOAT_EQ(shadow_bounds.GetRight(), 203.66667f); | ||
EXPECT_FLOAT_EQ(shadow_bounds.GetBottom(), 205.09525f); |
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.
Can we compare this with the skia output since the intention is to replace it?
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.
That is done in the other file that will get deleted when the Skia source dependencies are deleted...
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.
(see display_list/skia/dl_sk_canvas_unittests.cc
)
The shadow bounds get used to compute bounds for DLs and we do have some tests that make sure that DL bounds are reasonable (by comparing to Skia and by ensuring that we don't overdraw them in the rendertests). See
The only direct use of the method I see in the existing unit tests is
|
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.
This looks good to me. I think the only thing it needs is a docstring for GetLocalBounds.
-zRatio * params.light_position.y); | ||
} | ||
|
||
DlRect GetLocalBounds(DlRect ambient_bounds, |
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.
Can you add a docstring here. It's not immediately easy to understand what this is doing. Here is the one for skia: https://github.com/google/skia/blob/d43c7d1ea21a80982b926be4f72f48b64fa4bfa6/include/utils/SkShadowUtils.h#L66
The name isn't quite obvious like the skia version either IMO since it's laking the "shadow" context.
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.
Well, that's the implementation function which never has a doc string. The doc string should be in the header file and that didn't change so it isn't in the diffs.
But, if you go look there you'll notice that it is also missing a doc comment, so the point is still valid. ;)
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.
None of the methods in DlCanvas are documented as they are assumed to be just duplicates of the SkCanvas methods, but we need to fix that at some point. For now, I'm also adding a doc comment to DrawShadow as well as the ComputeBounds function to help fully document what we mean by shadows (ComputeBounds refers to DrawShadow as "I'm the bounds for that guy" so it helps to nail down what "that guy" does). The rest of the methods in DlCanvas should be documented later as a low priority task in the de-skiafication mini-project.
/// @brief Return the smaller of the two non-negative scales that will | ||
/// be applied to 2D coordinates by this matrix. If the matrix | ||
/// has perspective components or the value cannot be computed, | ||
/// the method will return -1. |
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.
Why not use std::optional? It seems like accidentally using -1 isn't going to give the results you want, right?
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.
Technically this method would not be involved in any computation inside a perspective coordinate system, so this method shouldn't even be called on one. Any code that called this without knowing up front that the result would be successful would be considered poorly written (most likely didn't bother to have a plan for what to do when the matrix is perspective) and this method would not likely be called until well after the perspective condition was noted and branched away.
But there is no good way to "enforce" that with our API, so while using optional is more of a nuisance than informative for well-written code, its use would raise the visibility of the inappropriateness of using these methods with a perspective transform. Hopefully someone modifying code in Impeller to use this method would be motivated to think more about how their code should work in a perspective situation.
@@ -358,6 +360,76 @@ std::optional<MatrixDecomposition> Matrix::Decompose() const { | |||
return result; | |||
} | |||
|
|||
std::optional<std::pair<Scalar, Scalar>> Matrix::GetScales2D() const { |
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.
Couldn't you just transform 2 unit vectors to calculate this?
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.
No, this isn't the scale factor for the unit vectors - that's what the basis methods return. This is the expansion factor in any direction. For skewed transforms, the unit axis vectors are not scaled, but the 45-degree unit vector is scaled by more than 1, and the perpendicular to that vector is scaled by less than 1.
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 creating a doc comment for the GetMaxBasis method to clarify its limitation.
I note that there is a GetScale()
method also, which doesn't return a true scale and is only used in one location:
GetCanvas().GetCurrentTransform().GetScale().y}, |
I'll file a bug for the latter and leave it for now. See #172611
I assume that I'll have to merge with the post-license-cpp revert and do the appropriate manual licensing stuff, but the code itself should be in a hopefully final form. |
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, thanks
Right now DisplayList defers to Skia to compute the bounds of shadow operations, but we really need to own this code now that we are doing our own rendering so I ported it over and simplified it to just deal with the cases we care about.
Eliminates a bullet item in #161456