In the past, this rectangle was relative to the intermediate surface of the
closest ancestor container layer with intermediate surface, or in root layer
coordinates if there was no such ancestor layer.
After this patch, the rectangle no longer relative to the intermediate surface;
it is now in the same space as the surface rectangle. The surface origin is no
longer used as an offset for the clip rect.
Example: Container layer with intermediate surface has visible region
(100, 200, 400, 300) and the clip covers the entire surface.
In the past, aClipRect would be (0, 0, 400, 300).
After this patch, the clip rect is (100, 200, 400, 300).
Background:
Before this patch, Compositor::DrawGeometry was called with aClipRect in
relative-to-intermediate-surface-or-root-layer space. All compositor
implementations were treating the aClipRect coordinates as relative to the
current render target, i.e. relative to the current render target's origin.
This worked fine when you were actually rendering to an intermediate surface.
But when rendering to the initial render target, the two spaces are not
necessarily equivalent: Root layer coordinates are not necessarily relative to
the initial render target, because the root layer space has its origin in the
top left corner of the window, whereas the initial render target does not
necessarily have to have its origin in the top left corner of the window.
To be fair, in CompositorOGL and CompositorD3D11, the initial render target
actually does have its origin in the top left corner of the window.
The notable exception is BasicCompositor when BasicCompositor uses a back
buffer: The back buffer only covers the invalid rect, so the render target
around the back buffer has its origin in the top left corner of the invalid
rect, which can be anywhere within the window.
As a result, when drawing into the back buffer render target (as opposed to an
intermediate surface), BasicCompositor::DrawGeometry's aClipRect was not
relative to the render target. So how did BasicCompositor know to clip the back
buffer in the right place? It would need to offset aClipRect by rt->GetOffset()
only for the initial render target, but not for render targets that were
created for intermediate surfaces, because for those render targets the
coordinates would already be correct.
The key difference was the back buffer DrawTarget's transform:
CreateRenderTargetForWindow was setting the transform on the initial render
target's DrawTarget to Translation(-rt->GetOrigin()).
And CreateRenderTarget, which creates render targets for intermediate surfaces,
was not setting a transform on the DrawTargets it creates.
So BasicCompositor::DrawGeometry was using the current render target's transform
only to correct aClipRect's offset, and for nothing else. Directly after
applying the clip, it would overwrite the render target's transform with a new
transform which included the GetOrigin() offset in all types of render targets.
I was rather surprised when I found out about this.
If I wanted to make CompositorOGL behave similarly when drawing to a native
layer which is not located at (0, 0) in the window, I would have to add a
similar annotation on the render target for the native layer that says: "Here's
an extra offset that you need to apply only to clip rects and to nothing else
when rendering to this render target, because Layer::CalculateScissorRect
predicts the wrong surface location for the initial render target".
I'm not a fan of special offsets that only apply in special cases.
So instead of predicting an incorrect offset and then correcting for the
misprediction afterwards, this patch makes us no longer subtract the
intermediate surface offset in CalculateScissorRect(). So then DrawGeometry just
always needs to offset the clip rect by mCurrentRenderTarget->GetOrigin() (which
is the correct offset, known in the correct place) in order to translate the
clip rect into physical render target coordinates.
Since this removes a difference in treatment between BasicCompositor's initial
render target and intermediate render targets, I'm also removing the code that
sets a transform on the initial render target in CreateRenderTargetForWindow.
Depends on D42422
Description
•