Closed Bug 1016558 Opened 12 years ago Closed 12 years ago

Use the right critical display port when painting a layer with a 2D integer-translation CSS transform

Categories

(Core :: Panning and Zooming, defect)

32 Branch
All
Gonk (Firefox OS)
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla32

People

(Reporter: kats, Assigned: kats)

References

Details

Attachments

(3 files, 4 obsolete files)

As a result of the problem described in the comment at [1], layers which have a 2D integer-translation css transform end up getting tiled, but use incorrect values for their displayport properties. This results in low-res content possibly getting painted instead of high-res content. [1] http://mxr.mozilla.org/mozilla-central/source/gfx/layers/client/ClientTiledThebesLayer.cpp?rev=bd59c5ef0677#78
Attachment #8429507 - Attachment description: 2-github-reftest-ac0ad4f → Part 1 - Log critical displayport
Attachment #8429507 - Attachment is patch: true
Attachment #8429507 - Flags: review?(chrislord.net)
This code is not easy to exercise locally so I did a try push to catch any obvious problems. https://tbpl.mozilla.org/?tree=Try&rev=908d83eb186e
Comment on attachment 8429507 [details] [diff] [review] Part 1 - Log critical displayport Review of attachment 8429507 [details] [diff] [review]: ----------------------------------------------------------------- LGTM.
Attachment #8429507 - Flags: review?(chrislord.net) → review+
The try in comment 4 looks fine, but that push has low-res disabled. I also did a full try run with low-res/progressive enabled, it is at https://tbpl.mozilla.org/?tree=Try&rev=06d71a0ef764. It shows some new failures, presumably caused by the WIPs above. I'll repro them locally and see if I can figure out what's going on.
Had a small bug in the previous version, should be fixed now. Did another try run, waiting on results before flagging for review.
Attachment #8429512 - Attachment is obsolete: true
This part should be ready for review.
Attachment #8429511 - Attachment is obsolete: true
Attachment #8430389 - Flags: review?(chrislord.net)
Attachment #8430389 - Flags: review?(botond)
Comment on attachment 8430389 [details] [diff] [review] Part 2 - Rename a bunch of stuff and update comments Review of attachment 8430389 [details] [diff] [review]: ----------------------------------------------------------------- ::: gfx/layers/client/ClientTiledThebesLayer.cpp @@ +148,5 @@ > // Calculate the transform required to convert ParentLayer space of our > // display port parent to LayoutDevice space of this layer. > + gfx::Matrix4x4 transform = scrollAncestor->GetTransform(); > + ContainerLayer* displayPortAncestorParent = displayPortAncestor->GetParent() ? > + displayPortAncestor->GetParent()->GetParent() : nullptr; Technically, this would be a displayPortAncestorGrandparent ;)
Attachment #8430389 - Flags: review?(botond) → review+
(In reply to Botond Ballo [:botond] from comment #9) > Technically, this would be a displayPortAncestorGrandparent ;) True. Part 3 actually gets rid of this by refactoring it, and does end up using the parent instead of the grandparent. I don't even know why it was using the grandparent here.
Comment on attachment 8430389 [details] [diff] [review] Part 2 - Rename a bunch of stuff and update comments Review of attachment 8430389 [details] [diff] [review]: ----------------------------------------------------------------- Looks good, I think some of the comments could use some tweaking (see below), but it's definitely better than what was there before. ::: gfx/layers/client/ClientTiledThebesLayer.cpp @@ +114,5 @@ > > // Get the metrics of the nearest scrollable layer and the nearest layer > // with a displayport. > + ContainerLayer* displayPortAncestor = nullptr; > + ContainerLayer* scrollAncestor = nullptr; nit: It's verging on ocd, but it'd be nicer if these two were declared the other way round (scrollAncestor first) to match the comment, and to get a nice line-length progression :) Not sure why I didn't do this in the first place... @@ +139,5 @@ > return; > } > > // Note, not handling transformed layers lets us assume that LayoutDevice > // space of the scroll parent layer is the same as LayoutDevice space of 'of the scroll ancestor layer' @@ +147,3 @@ > > // Calculate the transform required to convert ParentLayer space of our > // display port parent to LayoutDevice space of this layer. 'display port ancestor' @@ +148,5 @@ > // Calculate the transform required to convert ParentLayer space of our > // display port parent to LayoutDevice space of this layer. > + gfx::Matrix4x4 transform = scrollAncestor->GetTransform(); > + ContainerLayer* displayPortAncestorParent = displayPortAncestor->GetParent() ? > + displayPortAncestor->GetParent()->GetParent() : nullptr; Botond is right, but I think it's actually worth renaming this to reflect that - displayPortAncestorGrandParent or ParentParent would do... Or displayPortAncestorContainerParent, perhaps? @@ +150,5 @@ > + gfx::Matrix4x4 transform = scrollAncestor->GetTransform(); > + ContainerLayer* displayPortAncestorParent = displayPortAncestor->GetParent() ? > + displayPortAncestor->GetParent()->GetParent() : nullptr; > + for (ContainerLayer* ancestor = scrollAncestor->GetParent(); > + ancestor != displayPortAncestorParent; Alternatively, we could just use the actual displayPortAncestorParent and reformat this loop into a do { ... } while (ancestor != displayPortAncestorParent); ? @@ +173,3 @@ > criticalDisplayPort))); > > + // Compute the viewport that applies to this layer in the LayoutDevice This comment has been changed, is this correct? Should it not read 'Compute the viewport that applies to the displayport ancestor layer in the LayoutDevice space of this layer' ? @@ +182,2 @@ > > + // Store the resolution from the displayport layer. Because this is Gecko-side, nit: 'displayport ancestor layer', for consistency? ::: gfx/layers/client/TiledContentClient.cpp @@ +892,2 @@ > { > // Transform the current composition bounds into ParentLayer coordinates Maybe modify this comment to read 'into the same space as the displayport ancestor of this layer' ? @@ +967,5 @@ > } > } > > // Transform the composition bounds, which is in the ParentLayer coordinates > // of the nearest ContainerLayer with a valid displayport to LayoutDevice and same modification here (which is already saying that, but is wordier than it needs to be now).
Attachment #8430389 - Flags: review?(chrislord.net) → review+
Updated to address review comments, carrying r+. Unless noted below I fixed it as per the review comment. (In reply to Chris Lord [:cwiiis] from comment #11) > @@ +150,5 @@ > > + gfx::Matrix4x4 transform = scrollAncestor->GetTransform(); > > + ContainerLayer* displayPortAncestorParent = displayPortAncestor->GetParent() ? > > + displayPortAncestor->GetParent()->GetParent() : nullptr; > > + for (ContainerLayer* ancestor = scrollAncestor->GetParent(); > > + ancestor != displayPortAncestorParent; > > Alternatively, we could just use the actual displayPortAncestorParent and > reformat this loop into a do { ... } while (ancestor != > displayPortAncestorParent); ? I do something like this in part 3. For part 2 I'll just rename it to displayPortAncestorGrandParent > @@ +173,3 @@ > > criticalDisplayPort))); > > > > + // Compute the viewport that applies to this layer in the LayoutDevice > > This comment has been changed, is this correct? Should it not read 'Compute > the viewport that applies to the displayport ancestor layer in the > LayoutDevice space of this layer' ? Except we don't really care if the viewport applies to the displayport ancestor layer. The reason we're converting it to the LayoutDevice space of *this* layer is because we care about *this* layer, and that viewport is the closest ancestor viewport that is useful. That's why I updated the comment to read the way it does. The relevance of the viewport is that it applies to *this* layer. > ::: gfx/layers/client/TiledContentClient.cpp > @@ +892,2 @@ > > { > > // Transform the current composition bounds into ParentLayer coordinates > > Maybe modify this comment to read 'into the same space as the displayport > ancestor of this layer' ? > > @@ +967,5 @@ > > } > > } > > > > // Transform the composition bounds, which is in the ParentLayer coordinates > > // of the nearest ContainerLayer with a valid displayport to LayoutDevice > > and same modification here (which is already saying that, but is wordier > than it needs to be now). I merged the two comments into and clarified it a bit. I didn't see the point of having two comments that basically the same thing, given that one is inside a helper function and the other was at the only callsite.
Attachment #8430389 - Attachment is obsolete: true
Attachment #8430781 - Flags: review+
My previous green reftest run with these patches is at https://tbpl.mozilla.org/?tree=Try&rev=d046a9fca42f and I just did an all push at https://tbpl.mozilla.org/?tree=Try&rev=1bea98312267
Comment on attachment 8430782 [details] [diff] [review] Part 3 - Stop special-casing the scroll offset and deal with transforms more generically Review of attachment 8430782 [details] [diff] [review]: ----------------------------------------------------------------- This looks sound, but it's hard to wrap your head around things like this. Do we still not have a way of testing these functions? Let's at least file a bug (if there isn't already one) to get some tests in for this. I'm sure it works now, but I can see it being broken...
Attachment #8430782 - Flags: review?(chrislord.net) → review+
Filed bug 1017632 for testing that code.
Comment on attachment 8430782 [details] [diff] [review] Part 3 - Stop special-casing the scroll offset and deal with transforms more generically Review of attachment 8430782 [details] [diff] [review]: ----------------------------------------------------------------- Does this patch resolve the FIXME near the beginning of BeginPaint()? If so, we should remove it. ::: gfx/layers/client/ClientTiledThebesLayer.cpp @@ +61,5 @@ > +static gfx3DMatrix > +GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor) > +{ > + gfx::Matrix4x4 transform; > + Layer* aAncestorParent = aAncestor->GetParent(); s/aAncestorParent/ancestorParent @@ +157,5 @@ > > // Calculate the transform required to convert ParentLayer space of our > + // display port ancestor to the LayoutDevice space of this layer. > + gfx3DMatrix layoutDeviceToDisplayPort = > + GetTransformToAncestorsParentLayer(this, displayPortAncestor); It looks like, compared to the previous code, we are excluding the transform of the ancestor-parent itself. Is this intentional? @@ +168,5 @@ > // Compute the critical display port that applies to this layer in the > // LayoutDevice space of this layer. > ParentLayerRect criticalDisplayPort = > + (displayportMetrics.mCriticalDisplayPort * displayportMetrics.GetZoomToParent()) > + + displayportMetrics.mCompositionBounds.TopLeft(); Is the change of coordinate system here (i.e. not adding the scroll offset) related to the other changes in this patch?
(In reply to Botond Ballo [:botond] from comment #17) > Does this patch resolve the FIXME near the beginning of BeginPaint()? If so, > we should remove it. In fact, does it remove the need for the entire "if (!GetBaseTransform().Is2DIntegerTranslation())" block?
(In reply to Botond Ballo [:botond] from comment #17) > Does this patch resolve the FIXME near the beginning of BeginPaint()? If so, > we should remove it. I believe that it resolves it partially. We should now be able to deal with any 2d translation and scale transforms. I'd rather adjust that in a follow-up bug because it might flush out more bugs. Ok I file a follow-up for it? We might also be able to get rid of the fennec special-casing there. > ::: gfx/layers/client/ClientTiledThebesLayer.cpp > @@ +61,5 @@ > > +static gfx3DMatrix > > +GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor) > > +{ > > + gfx::Matrix4x4 transform; > > + Layer* aAncestorParent = aAncestor->GetParent(); > > s/aAncestorParent/ancestorParent Oops, good catch. Will fix. > @@ +157,5 @@ > > > > // Calculate the transform required to convert ParentLayer space of our > > + // display port ancestor to the LayoutDevice space of this layer. > > + gfx3DMatrix layoutDeviceToDisplayPort = > > + GetTransformToAncestorsParentLayer(this, displayPortAncestor); > > It looks like, compared to the previous code, we are excluding the transform > of the ancestor-parent itself. Is this intentional? Yes. I see no reason to include that transform (i.e. I don't know why it was going up to the grandparent before), and the new code doesn't seem to break any cases that I could find. > @@ +168,5 @@ > > // Compute the critical display port that applies to this layer in the > > // LayoutDevice space of this layer. > > ParentLayerRect criticalDisplayPort = > > + (displayportMetrics.mCriticalDisplayPort * displayportMetrics.GetZoomToParent()) > > + + displayportMetrics.mCompositionBounds.TopLeft(); > > Is the change of coordinate system here (i.e. not adding the scroll offset) > related to the other changes in this patch? Yes. Because the transform on the layer is related to the scroll offset, I removed the scroll offset and started using the transform instead. That handles the more general case so we don't need special code for detecting "scroll" vs "CSS transform". Adding the composition bounds is still needed because if you ignore the scroll offset, then the critical displayport is relative to the composition bounds and we need to convert it to be relative to the layer origin.
(In reply to Kartikaya Gupta (email:kats@mozilla.com) from comment #19) > I believe that it resolves it partially. We should now be able to deal with > any 2d translation and scale transforms. I'd rather adjust that in a > follow-up bug because it might flush out more bugs. Ok I file a follow-up > for it? We might also be able to get rid of the fennec special-casing there. Note in particular I suspect it will require a bunch of tests to be fuzzed because more code will be going through this transformation stuff which likely introduces rounding errors.
Comment on attachment 8430782 [details] [diff] [review] Part 3 - Stop special-casing the scroll offset and deal with transforms more generically Review of attachment 8430782 [details] [diff] [review]: ----------------------------------------------------------------- Thanks for the explanations! A follow-up for removing the FIXME and such is fine.
Attachment #8430782 - Flags: review?(botond) → review+
Thanks. I filed bug 1017680 for the FIXME.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: