Small artifacts appear then disappear with hardware acceleration

RESOLVED FIXED in mozilla2.0

Status

()

defect
RESOLVED FIXED
8 years ago
4 years ago

People

(Reporter: zpao, Assigned: roc)

Tracking

(Blocks 1 bug)

unspecified
mozilla2.0
x86
All
Points:
---
Dependency tree / graph
Bug Flags:
in-testsuite +

Firefox Tracking Flags

(blocking2.0 .x+)

Details

()

Attachments

(10 attachments, 2 obsolete attachments)

476 bytes, text/html
Details
476 bytes, text/html
Details
5.08 KB, patch
roc
: review-
Details | Diff | Splinter Review
542 bytes, text/html
Details
6.23 KB, patch
Details | Diff | Splinter Review
13.53 KB, patch
bas.schouten
: review+
beltzner
: approval2.0-
Details | Diff | Splinter Review
1.23 KB, patch
dbaron
: review+
Details | Diff | Splinter Review
16.44 KB, patch
cjones
: review+
beltzner
: approval2.0+
Details | Diff | Splinter Review
29.30 KB, patch
mattwoodrow
: review+
beltzner
: approval2.0-
Details | Diff | Splinter Review
6.69 KB, patch
bas.schouten
: review+
Details | Diff | Splinter Review
+++ This bug was initially created as a clone of Bug #634784 +++

Just like bug 634784, I was using the demo at http://shakenandstirredweb.com/playground/blur/. This time just small black artifacts, not the big black areas from before.

You can see them in action in the video I attached previously: attachment #512978 [details].

Demoting to blocking? since I'm not sure how bad this really is.

Still OS X, still same graphics card situation as before.
Same for me (but I'm on Win 7 x32).
OS: Mac OS X → All
No longer blocks: 635275
Matt Woodrow wrote:
> I think these are due to scaling the texture and rounding causing sampling to
> read from the opposite side of the texture. We fixed this on container layers
> by disabling wrapping, but on thebes layers the texture boundary can be in the
> middle of a physical texture. I'm not sure how we can fix this other than
> disabling the texture rotation code, which probably shouldn't be done for this
> release.

I'm not sure why wrapping would cause black pixels though. Also this happens on Windows which isn't using the texture rotation.
This is cross-platform. For now, I'm going to give this to Rob; me or Matt or Jeff or Bas could easily take it on, though.

This is ugly, but I wouldn't pull an RC off the wire for it, so it softblocks. This probably doesn't require beta coverage either.
Assignee: nobody → roc
blocking2.0: ? → final+
Whiteboard: [softblocker]
> I'm not sure why wrapping would cause black pixels though. Also this happens on
> Windows which isn't using the texture rotation.

Bug 622585 included a fix for a similar looking problem by disabling texture wrapping. We were occasionally sampling from outside the texture bounds when scaled and getting pixel data from the opposite side of the texture.

Since this happens on platforms without texture rotation, I take my conclusion back
Posted file Simple testcase
Hover over the browser window to trigger rotation.

The testcase passes with BasicLayers and fails with D3D9 and D3D10, but only when the <article> layer is using component alpha. Interestingly it passes with OpenGL and component alpha!

The testcase seems to show that the artifacts appear at the boundaries of our text drawing that are inside the rectangular bounds of the layer, which is weird since the layer system doesn't really know about that. The only thing I can think of is that the visible region contains two rectangles, which don't fill the whole bounding rectangle of the ThebesLayer, and that's triggering it somehow.
This testcase shows that if we don't use a component alpha layer, the bug does not occur, even if the visible region isn't filling its bounding rectangle.
Posted patch D3D9 fix? (obsolete) — Splinter Review
This seems to fix it for D3D9. I have to confess I don't fully understand what the problem it fixes is.

We're not doing any GPU-based antialiasing, right? So the same set of pixels should be updated on each pass of the component alpha rendering, and we shouldn't be getting burned by partial coverage. So I still don't know what's actually causing those artifacts, or in particular why they only appear in the interior of the texture rect. There's clearly nothing wrong with the texture data itself, since the artifacts are completely dependent on the current transform.

Is it possible that the blend modes we're setting are actually affecting which pixels are being updated by the primitive? Or some other hidden state is affecting that? Help me, Obi-Bas!
Attachment #513926 - Flags: review?(bas.schouten)
Hmm. I suppose that when we resample due to a transform we could be sampling pixels outside the visible region but inside the texture bounds, so clamping to texture bounds doesn't help. For RGBA textures those pixels would normally be transparent so they won't hurt (much), but we probably still shouldn't do that. For component-alpha textures, we only fill the buffers with white and black in the visible region, so when we sample outside that region we mix some transparent black with both the on-white and on-black values, which will definitely cause problems.

I don't know why this isn't affecting GL.

If this analysis is correct, then I think the correct solution is to apply the patch in comment #7 but for all layer modes (opaque, RGBA, component-alpha), so that whenever the effective transform is going to cause resampling, the entire mTextureRect is valid and we don't risk sampling pixels in a dubious state.
Note that the simplified testcase exposes some other issues that we should fix ASAP, possibly even for Firefox 4 since they're technically regressions. Namely, we render subpixel-AA text to a buffer and then transform the buffer. That is bogus! If we know a layer buffer is going to be transformed (by something other than an integer translation) we need to disable subpixel AA for everything that renders into that buffer. And conveniently, that means the buffer will not need component alpha! I need to file a new bug on this.
(In reply to comment #5)
> Created attachment 513923 [details]
> Simple testcase
> 
> Hover over the browser window to trigger rotation.
> 
> The testcase passes with BasicLayers and fails with D3D9 and D3D10, but only
> when the <article> layer is using component alpha. Interestingly it passes with
> OpenGL and component alpha!
> 
> The testcase seems to show that the artifacts appear at the boundaries of our
> text drawing that are inside the rectangular bounds of the layer, which is
> weird since the layer system doesn't really know about that. The only thing I
> can think of is that the visible region contains two rectangles, which don't
> fill the whole bounding rectangle of the ThebesLayer, and that's triggering it
> somehow.

WFM. Latest nightly; Win7 x32; graph. card is hd3850; d2d, dw are on.
(In reply to comment #8)
> Hmm. I suppose that when we resample due to a transform we could be sampling
> pixels outside the visible region but inside the texture bounds, so clamping to
> texture bounds doesn't help. For RGBA textures those pixels would normally be
> transparent so they won't hurt (much), but we probably still shouldn't do that.
> For component-alpha textures, we only fill the buffers with white and black in
> the visible region, so when we sample outside that region we mix some
> transparent black with both the on-white and on-black values, which will
> definitely cause problems.

This was going to be my theory, the fix I'm suggesting is slightly different, we should take the visible region, but extend each rect in the region by a certain amount of pixels (bounded by the texture rect of course). The amount of pixels depends on the level of scaling in the transforms (i.e. how far away pixels can be sampled).

I should note there is some cases where if we simply take the bounds of the visible region as visible region as the visible region layout will not draw the correct content there. See bug 593860.
Comment on attachment 513926 [details] [diff] [review]
D3D9 fix?

This should be okay if we only do it for component alpha surfaces.
Attachment #513926 - Flags: review?(bas.schouten) → review+
(In reply to comment #11)
> This was going to be my theory, the fix I'm suggesting is slightly different,
> we should take the visible region, but extend each rect in the region by a
> certain amount of pixels (bounded by the texture rect of course). The amount of
> pixels depends on the level of scaling in the transforms (i.e. how far away
> pixels can be sampled).

We could do that, but it adds complexity, and maybe that complexity is not needed in practice. I suspect it would only matter if we have a transformed object where the visible region is much smaller than its bounds (e.g. two very disconnected pieces).

> I should note there is some cases where if we simply take the bounds of the
> visible region as visible region as the visible region layout will not draw the
> correct content there. See bug 593860.

My patch won't cause problems like that because I extend the visible region before we compute the drawRegion, so we'll actually fill and draw the full bounds.
I think we need to do this for all texture types. Also, this version of the patch avoids modifying mVisibleRegion, which is a good thing since the visible region should be entirely under layout's control.
Attachment #513926 - Attachment is obsolete: true
Attachment #514069 - Flags: review?(bas.schouten)
Whiteboard: [softblocker] → [softblocker][needs review]
This static testcase shows the bug occurring in a ThebesLayer that is marked opaqueContent.
Comment on attachment 514069 [details] [diff] [review]
better fix for D3D9 and D3D10

This patch isn't correct because for opaque ThebesLayers, we can't rely on layout drawing opaque stuff outside the visible region (the opaque flag only guarantees opaque drawing in the visible region), so we'll draw bad stuff or nothing at all there (perhaps leaving it black or garbage).

When we need to draw in the bounds of the visible region, we should also convert opaque ThebesLayers to RGBA format to avoid this problem.
Attachment #514069 - Flags: review?(bas.schouten) → review-
Posted patch testsSplinter Review
These tests test compositing of a transformed, resampled ThebesLayer with complex visible region. There is one test for each of opaque, RGBA and component alpha ThebesLayers.
These patches pass those tests. BasicLayers also passes. OpenGL does not, there are some visual artifacts if you zoom in.
Attachment #514129 - Flags: review?(bas.schouten)
Comment on attachment 514129 [details] [diff] [review]
D3D9 and D3D10 fix

>diff --git a/gfx/layers/d3d10/ThebesLayerD3D10.cpp b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
>--- a/gfx/layers/d3d10/ThebesLayerD3D10.cpp
>+++ b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
> ThebesLayerD3D10::Validate(ReadbackProcessor *aReadback)
> {
>   if (mVisibleRegion.IsEmpty()) {
>     return;
>   }
> 
>+  nsIntRect newTextureRect = mVisibleRegion.GetBounds();
>+
>   SurfaceMode mode = GetSurfaceMode();
>   if (mode == SURFACE_COMPONENT_ALPHA &&
>       (!mParent || !mParent->SupportsComponentAlphaChildren())) {
>     mode = SURFACE_SINGLE_CHANNEL_ALPHA;
>   }

Nit: I'd like some whitespace here.

>+  // If we have a transform that requires resampling of our texture, then
>+  // we need to make sure we don't sample pixels that haven't been drawn.
>+  // We clamp sample coordinates to the texture rect, but when the visible region
>+  // doesn't fill the entire texture rect we need to make sure we draw all the
>+  // pixels in the texture rect anyway in case they get sampled.
>+  nsIntRegion neededRegion = mVisibleRegion;
>+  if (neededRegion.GetBounds() != newTextureRect ||
>+      neededRegion.GetNumRects() > 1) {
>+    gfxMatrix transform2d;
>+    if (!GetEffectiveTransform().Is2D(&transform2d) ||

>diff --git a/gfx/layers/d3d9/ThebesLayerD3D9.cpp b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
>--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp
>+++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
>@@ -203,21 +203,44 @@ ThebesLayerD3D9::RenderVisibleRegion()
> 
> void
> ThebesLayerD3D9::RenderThebesLayer(ReadbackProcessor* aReadback)
> {
>   if (mVisibleRegion.IsEmpty()) {
>     return;
>   }
> 
>+  nsIntRect newTextureRect = mVisibleRegion.GetBounds();
>+
>   SurfaceMode mode = GetSurfaceMode();
>   if (mode == SURFACE_COMPONENT_ALPHA &&
>       (!mParent || !mParent->SupportsComponentAlphaChildren())) {
>     mode = SURFACE_SINGLE_CHANNEL_ALPHA;
>   }

Nit: And here.
>+  // If we have a transform that requires resampling of our texture, then
>+  // we need to make sure we don't sample pixels that haven't been drawn.
>+  // We clamp sample coordinates to the texture rect, but when the visible region
>+  // doesn't fill the entire texture rect we need to make sure we draw all the
>+  // pixels in the texture rect anyway in case they get sampled.
>+  nsIntRegion neededRegion = mVisibleRegion;
>+  if (neededRegion.GetBounds() != newTextureRect ||
>+      neededRegion.GetNumRects() > 1) {
>+    gfxMatrix transform2d;
>+    if (!GetEffectiveTransform().Is2D(&transform2d) ||
>+        transform2d.HasNonIntegerTranslation()) {
>+      neededRegion = newTextureRect;
>+      if (mode == SURFACE_OPAQUE) {
>+        // We're going to paint outside the visible region, but layout hasn't
>+        // promised that it will paint opaquely there, so we'll have to
>+        // treat this layer as transparent.
>+        mode = SURFACE_SINGLE_CHANNEL_ALPHA;
>+      }
>+    }
>+  }
>+
Attachment #514129 - Flags: review?(bas.schouten) → review+
(In reply to comment #19)
> Nit: I'd like some whitespace here.

Hmm, where exactly? There is whitespace there :-)
Posted patch GL fix (obsolete) — Splinter Review
This doesn't completely fix GL. With these patches, the first test fails because the antialiasing along the edges of the visible region that are inside its bounding rect is slightly different in the test and reference. It's possible there's nothing we can do about that. Visually it looks fine.
Attachment #514156 - Flags: review?(matt.woodrow+bugzilla)
Comment on attachment 514156 [details] [diff] [review]
GL fix


> 
>+static const int ALLOW_REPEAT = 0x01;
>+
> // BindAndDrawQuadWithTextureRect can work with either GL_REPEAT (preferred)
> // or GL_CLAMP_TO_EDGE textures.  We select based on whether REPEAT is
> // valid for non-power-of-two textures -- if we have NPOT support we use it,
> // otherwise we stick with CLAMP_TO_EDGE and decompose.
> static already_AddRefed<TextureImage>
> CreateClampOrRepeatTextureImage(GLContext *aGl,
>                                 const nsIntSize& aSize,
>-                                TextureImage::ContentType aContentType)
>+                                TextureImage::ContentType aContentType,
>+                                PRUint32 aFlags)

Probably should update the comment here.

> 
>-  if (visibleBounds.Size() <= mBufferRect.Size()) {
>+  if (neededBounds.Size() <= mBufferRect.Size() &&
>+      mTexImage &&
>+      (mTexImage->GetWrapMode() == LOCAL_GL_CLAMP_TO_EDGE || mEnableRotationOptimization)) {
>     NS_ASSERTION(curXRes == aXResolution && curYRes == aYResolution,
>                  "resolution changes must clear the buffer!");
>     // The current buffer is big enough to hold the visible area.

This one too, this condition isn't overly clear what it's testing.


>   gfxMatrix transform2d;
>   gfxSize scale(1.0, 1.0);
>+  float paintXRes = 1.0;
>+  float paintYRes = 1.0;
>+  bool willResample;
>   if (transform.Is2D(&transform2d)) {
>     scale = transform2d.ScaleFactors(PR_TRUE);
>+    paintXRes = gfxUtils::ClampToScaleFactor(scale.width);
>+    paintYRes = gfxUtils::ClampToScaleFactor(scale.height);
>+    transform2d.Scale(1.0/paintXRes, 1.0/paintYRes);
>+    willResample = transform2d.HasNonIntegerTranslation();
>+  } else {
>+    willResample = true;
>   }

In the case where the translation is only a scale and integer translation, and paint*Res matches scale willResample could probably be false too. I doubt this will ever matter in practice, simplicity is probably better.
Attachment #514156 - Flags: review?(matt.woodrow+bugzilla) → review+
Whiteboard: [softblocker][needs review] → [softblocker][needs landing]
Comment on attachment 514449 [details] [diff] [review]
Add layersOpenGL to the reftest harness

r=dbaron

(though I think all of the null-checking of gWindowUtils can go...)
Attachment #514449 - Flags: review?(dbaron) → review+
Attachment #514449 - Flags: superreview?(joe) → superreview+
A fix for BasicLayers is needed as well; the problems are less visible but show up with the reftests. Working on it.
Blocks: 634397
Blocks: 634759
tracking-fennec: --- → ?
I updated this quite a lot on top of the BasicLayers fix.
Attachment #514156 - Attachment is obsolete: true
Attachment #514974 - Flags: review?(matt.woodrow+bugzilla)
Comment on attachment 514973 [details] [diff] [review]
BasicLayers fix

I like this patch more than the previous one.

>+  NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || destBufferRect == neededRegion.GetBounds(),
>+               "If we're resampling, we need to validate the entire buffer");
> 

I'd appreciate an
|assert(BufferSizeOkFor(ScaledSize(destBufferRect.Size() ...))| here.

>+  enum {
>+    PAINT_WILL_RESAMPLE = 0x01
>+  };

I'd prefer a name more like PAINT_ALLOW_RESAMPLE or SUPPORT_RESAMPLE
or ASSUME_RESAMPLE, because in the shadow-layer case the buffer might
or might not be resampled.

>   /**
>    * Start a drawing operation. This returns a PaintState describing what
>    * needs to be drawn to bring the buffer up to date in the visible region.
>    * This queries aLayer to get the currently valid and visible regions.
>    * The returned mContext may be null if mRegionToDraw is empty.
>    * Otherwise it must not be null.
>    * mRegionToInvalidate will contain mRegionToDraw.
>+   * @param aFlags when PAINT_WILL_RESAMPLE is passed, this indicates that

"passing PAINT_WILL_RESAMPLE indicates .."

>   BasicThebesLayerBuffer(BasicThebesLayer* aLayer)
>     : Base(ContainsVisibleBounds)
>     , mLayer(aLayer)
>-  {}
>+  {
>+  }

?

>+    PRUint32 flags = 0;
>+    gfxMatrix transform;
>+    if (!GetEffectiveTransform().Is2D(&transform) ||
>+        transform.HasNonIntegerTranslation()) {
>+      flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
>+    }

We also need this flag for shadowable layers with shadows.
MustRetainContent() already exists and makes enough sense here, so I'd
be fine with reusing it.

r=me with the shadow-layer fix.  Yeah, it's broken already, but no need to
make it worse. ;)
Attachment #514973 - Flags: review?(jones.chris.g) → review+
(In reply to comment #28)
> >+  NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || destBufferRect == neededRegion.GetBounds(),
> >+               "If we're resampling, we need to validate the entire buffer");
> > 
> 
> I'd appreciate an
> |assert(BufferSizeOkFor(ScaledSize(destBufferRect.Size() ...))| here.

Will do.

> >+  enum {
> >+    PAINT_WILL_RESAMPLE = 0x01
> >+  };
> 
> I'd prefer a name more like PAINT_ALLOW_RESAMPLE or SUPPORT_RESAMPLE
> or ASSUME_RESAMPLE, because in the shadow-layer case the buffer might
> or might not be resampled.

Sure.

> >   BasicThebesLayerBuffer(BasicThebesLayer* aLayer)
> >     : Base(ContainsVisibleBounds)
> >     , mLayer(aLayer)
> >-  {}
> >+  {
> >+  }
> 
> ?

Will remove.

> >+    PRUint32 flags = 0;
> >+    gfxMatrix transform;
> >+    if (!GetEffectiveTransform().Is2D(&transform) ||
> >+        transform.HasNonIntegerTranslation()) {
> >+      flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
> >+    }
> 
> We also need this flag for shadowable layers with shadows.
> MustRetainContent() already exists and makes enough sense here, so I'd
> be fine with reusing it.

OK. This means we'll disable rotation for shadowlayers as soon as this lands. I hope that's OK!
Tragically, my new reftests fail on BasicLayers and GL layers because of small, not visually relevant differences. I'll probably just mark them as failing and go ahead.
Oops, I wasn't CC'd here :/.

(In reply to comment #29)
> OK. This means we'll disable rotation for shadowlayers as soon as this lands. I
> hope that's OK!

Yep.  For a variety of reasons, fennec basically never ends up using rotation.
Attachment #514974 - Flags: review?(matt.woodrow+bugzilla) → review+
Comment on attachment 514129 [details] [diff] [review]
D3D9 and D3D10 fix

Fixes visible artifacts with CSS transforms
Attachment #514129 - Flags: approval2.0?
Comment on attachment 514973 [details] [diff] [review]
BasicLayers fix

Fixes visible artifacts with CSS transforms
Attachment #514973 - Flags: approval2.0?
Comment on attachment 514974 [details] [diff] [review]
Updated GL patch

Fixes visible artifacts with CSS transforms
Attachment #514974 - Flags: approval2.0?
The BasicLayers fix may also be a hardblocker for Fennec.
I don't think we want to take this at this time; the current state is not great, but livable. We'll fix this in Firefox 5.

If the BasicLayers fix is a hard blocker for Fennec, they should mark as such.
Attachment #514129 - Flags: approval2.0? → approval2.0-
Attachment #514973 - Flags: approval2.0? → approval2.0-
Attachment #514974 - Flags: approval2.0? → approval2.0-
This should hard block Fennec because of bug 634397. We need the displayport to draw correctly so we can make invalidate only a portion of it and make it fast.
(In reply to comment #35)
> The BasicLayers fix may also be a hardblocker for Fennec.

Fennec does want to block on this, but first, I'd like to know if there are technical issues or risks with landing this for FF4?
If I understand correctly, it should also block Fennec because we spend a lot of time rendering stuff at non-identity resolutions, unlike Firefox.
This fixes rendering issues in Fennec
tracking-fennec: ? → 2.0+
There is some risk because we're changing core ThebesLayer code. However, the code is tested by reftests and this is a bad bug, not just for Fennec but for any pages using CSS transforms on desktop Firefox.
Comment on attachment 514973 [details] [diff] [review]
BasicLayers fix

Renominating based on Fennec needs.
Attachment #514973 - Flags: approval2.0- → approval2.0?
Comment on attachment 514973 [details] [diff] [review]
BasicLayers fix

a=beltzner
Attachment #514973 - Flags: approval2.0? → approval2.0+

Updated

8 years ago
Status: NEW → RESOLVED
Last Resolved: 8 years ago
Resolution: --- → FIXED
Whiteboard: [softblocker][needs landing] → [softblocker]
Target Milestone: --- → mozilla2.0

Comment 45

8 years ago
Landing of this bug and bug 632423 caused Windows reftest failures such as <http://tinderbox.mozilla.org/showlog.cgi?log=Firefox/1299024306.1299027792.9789.gz>.

I landed the following two changesets to deal with the failures:

http://hg.mozilla.org/mozilla-central/rev/f0a5657c643c
http://hg.mozilla.org/mozilla-central/rev/3436b367b4a4
This is not fully fixed. There are D3D and GL patches to land (post-FF4).
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Clearing blocking-fennec because the remaining patches do not block Fennec 4.
tracking-fennec: 2.0+ → ---
Whiteboard: [softblocker] → [softblocker][approved-patches-landed]
** PRODUCT DRIVERS PLEASE NOTE **

This bug is one of 7 automatically changed from blocking2.0:final+ to blocking2.0:.x during the endgame of Firefox 4 for the following reasons:

 - it was marked as a soft blocking issue without a requirement for beta coverage
blocking2.0: final+ → .x+
(In reply to comment #29)

None of these comments were addressed.  I'll fix PAINT_WILL_RESAMPLE for shadow layers in bug 635035.  (It's the only actual bug.)
I just landed what was in this bug, roc may have had a different patch in his queue.
No longer blocks: 634397
My tests fail on OpenGL and D3D9 because in the test files we draw the #d ThebesLayer as two quads, so the GPU makes a binary decision about which pixels to touch on the inside edges of the quads (the inside of the 'L'). In the reference files, we draw the #d ThebesLayer as a single quad with an L-shaped image in it, so the inside edge is antialiased by the bilinear filter when the ThebesLayer is resampled.

I don't know how to fix this. We can't ignore these edge pixels because they're exactly where we want to test for artifacts. I can improve the situation by noting when this bug fix is active --- i.e., because we're resampling we're ensuring the entire texture is filled with valid pixels --- and in that case, drawing the entire texture as one quad so our interior edges are antialised by resampling. However, for D3D9 at least, we still have off-by-one errors along the edge ... it seems that resampling and compositing an edge between rgb(200,200,200) and rgba(0,0,0,0) over a white background can give slightly different results to resampling an edge between rgb(200,200,200) and rgb(255,255,255).
OK, I got the tests passing with D3D9 by making the reference use a background image so that there are transparent pixels in its transformed ThebesLayer along the inside of the 'L'.
This is needed for the tests to pass with D3D9.

You could argue that this is sacrificing some performance for a barely-perceptible improvement in quality, but I think it doesn't really matter and it helps for testing.
Attachment #522336 - Flags: review?(bas.schouten)
Comment on attachment 522336 [details] [diff] [review]
draw layer in a single quad when resampling

I think this is fine perf wise. I doubt we're going to be fillrate bound very often.

However this still leaves the outer edges non-anti-aliased right? Of course we knew this when we did layers this way, but we're okay with that?
Attachment #522336 - Flags: review?(bas.schouten) → review+
(In reply to comment #56)
> I think this is fine perf wise. I doubt we're going to be fillrate bound very
> often.
> 
> However this still leaves the outer edges non-anti-aliased right? Of course we
> knew this when we did layers this way, but we're okay with that?

Yes, that's right. I think that's OK for now.
Whiteboard: [softblocker][approved-patches-landed] → [softblocker][approved-patches-landed][not-ready-for-cedar]
Comment on attachment 514128 [details] [diff] [review]
tests

>+#d {
>+	position:absolute;
>+	top:200px;
>+	left:200px;
>+    font-size:30px;
>+    transform:rotate(30deg);
>+    -moz-transform:rotate(30deg);
>+    background:white;
>+}

What's up with the tabs?
Depends on: 647315
Depends on: 647642
Depends on: 662154
Interestingly, I get an unexpected pass in a xvfb:
REFTEST TEST-UNEXPECTED-PASS | file:///tmp/build/layout/reftests/bugs/635373-3.html | image comparison (==)

Should I file a separate bug?
Corresponding image:
data:image/png;base64,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c0yp1Wpl06ZN5XOf+1zZvXv3kgKk1WpVPT0AgCUTILBMxsfHZwTDC1/4wlKr1XrjhS98YbnpppsWFR+23QUAjhYCBJbB9PT0rIXnp59+ei8+Nm3aVGq1Wnn+85+/qG9COp1O1VMEAFgWAgSWwejo6KxoeOtb39oLkG9+85vls5/9bLnxxhsXHB+jo6NVTw8AYNkIEFiiTqczZzi8973v7QXIF77whTmf85GPfKR8+ctfLo899ticj/f399t2FwA4qggQWKJmszlnPFx++eW9APnkJz856/Hf/va3Zf369aVWq5VTTjml3HbbbbbdBQCOegIElqDVah30p1PXXXddL0De9773zfmcG264oTz3uc/tPe/tb397ue+++0pfX18ZGBioenoAAMtOgMASNBqNgwbIt771rRlhMddzHnzwwfLhD394xm5ZGzduLB/5yEfK97///aqnBwCw7AQILNKB2+4eOH784x/3ouKMM86Y8dg999xTLrjggrJx48bec17+8peXc889t6xbt673t9e97nXlgQceqHqqAADLRoDAIsy17e6B41e/+lUvJE4++eTS19dXbr/99vLmN7+5Fxnr1q0rZ599dvnJT37SO+5nP/tZOffcc8szn/nM3h3VP/ShD5V6vV71tAEAlkyAwCKMjIyU/v7+QwbIn//8516AHHvsseWVr3zljJ9ZXXDBBeWee+6ZddzevXtLKf/v5137/zRr8+bN5frrry/tdrvi2QMALJ4AgQVqt9u9WKjX6wcNkd27d8/4OVWtVitbtmwpH//4x8tDDz005zGNRqN0u93ea+3/E61942tf+1qFswcAWBoBAgs017a7/f39M0Lk1ltvLW94wxtmhMOVV15ZHnnkkUN+azIxMTHjtZ71rGf1jv/ud79bzj777DI5OVnRzAEAlk6AwAJMTk4eNB4effTRcsMNN5RTTz111rcWtVqt3H777YeMj8HBwVmvd/LJJ/eO//vf/17BjAEAlpcAgQWYa9vdXbt2lc9//vMz7ufx7Gc/u1x11VXlta99be9v3/ve9w4ZIFNTU7Ne71WvelXv+Hvvvfeg76vdbpcbb7zRXdMBgCOeAIF5euCBB8rnPve5smfPnt4i88suu6wcd9xxvUh48YtfXLZv3152795d6vV6ec973tN77Mtf/vJB42NkZGTO13zjG9/YO/6uu+466Hv76le/Wmq1WjnttNPKr3/965U6BQAASyZAYB6mp6d7azpOPvnkcv7555cNGzbMuM/HTTfdVB5//PEZYXHZZZf1nvPpT396zvjo7+8/6DcX5513Xu/4H/3oRwd9f7fddlt5wQte0HvuO9/5zvLwww+v1OkAAFg0AQLzMDw8XG666aZy0kknzVjX8epXv7rceeedB/1m47Of/Wzvufvu5XHgc8bGxg76uu9///t7x3/nO9855HvcsWNH2bJlS+/5T3rSk8pVV111yP8fACBNgMBhTE1Nzdha95prrilPe9rTSq1WKxs2bCgXX3xx2bVr15wB8vWvf70XBFu3bu1943GwbXcP9LGPfax3/LZt2+Z8zgMPPFDOO++83pa/GzduLGeeeWZZt25d2bJlSxkYGFipUwMAsGACBA5jYGBgVlg8+OCD5V3veldZv359Of7448vOnTvnDJCbb765FxCve93rZt0/5HBb6u7/DcrVV18947EdO3aUc845p/f4k5/85HLppZeWPXv2lFJK+f3vf19uueWWUkopl1xySfngBz/obuoAQOUECBzCxMTEIXeuuuuuu8qNN9540MfvvPPOXiC87GUvm/V4s9k85J3Nt2/f3jv+0ksvLaWUcs8995S3vOUtvb8/5SlPKZ/4xCfK448/Puf/8Ze//KUcc8wxpVarleOOO65s27Ztzh23AAASBAgcRLfbnXPb3fmMHTt2lPvvv7/84Q9/mLE171zPrdfrZWRkZM6fYn3ve9+bsdB9/12xNm3aVD796U+X/v7+Q85j3+L5/bcJftGLXlR++tOfrtSpAwA4KAECB7F3795FxUdfX18566yzysaNG8vFF1/c+9C/YcOGQx7T399fxsfHZ4TID3/4w1k3NNy8eXO55ppr5rxx4YFuvfXWUqvVemtBfv7zn5eXvOQlvf/rzW9+c/nrX/+6kqcRAGAGAQJz6HQ6i46P//znP2Xr1q1z3g39H//4x2GPHxgYKK1Wq5RSyllnndU79vjjjy/XXXddGR4envc8vv/975fNmzeXr3/9672/TU1Nla985Stl8+bNvTD66Ec/WprN5rKfRwCAAwkQmMPw8PCiA2TfuOOOO8ppp502I0BuvvnmeR//gx/8oHfcE57whPLggw8uai6NRqN0Op1Zf+/v7y8XXnhhb33IM57xjPKNb3xjzucCACwXAQIHaLVaS46PfePxxx8v27dvLyeccEKp1Wpl3bp15fzzzy+PPPLIYb9Fed7zntcLkEsuuWTF5vunP/2pnHnmmb3XOvXUU8uvfvWrFXs9AGBtEyBwgLm23V3q2LVrV7n00kvLE5/4xHL66acf9vlXXnllLwie/vSnl507d5bx8fEVnffVV18949uarVu3ln/9618r+poAwNojQGA/4+Pjyx4f+4977723/O53v5v19/3XhvzpT38qxx57bC8EvvCFL8xYH3KobXsX49577y3nnHNO70aG+8b69evLL37xi2V9LQAAAQL/1e12S71eX9EAmWvs2LGjPPWpTy0XXnhh2blzZ3nHO97Ri4CXvvSl5dFHH511zPDwcJmenl7SfH/zm9+Us88+e9ZC+WOOOaZccMEF5W9/+9synVkAgP9PgMB/jY6OxuOjr6+vbNu2raxfv773c6v9v4m45ZZbDnpcvV4vY2Njc94/5FDuvvvuGWs+9t8m+AMf+ED55z//uUJnGABAgEApZWnb7i7H+OUvf1le85rXzAiCM844Y17HNhqNMjk5edg53nHHHbNeo1arlY0bN5aLLrqoPPzww4EzDQCsdQIESinNZrPSANk3vv3tb8+4Y/nb3va2ct99983r2GazWaampmbMq9vtlltvvbW84hWvmBUeT3rSk8oll1xSdu/eXdFZBwDWIgHCmrec2+4ux/j3v/9drrjiit5C9BNPPLHs2bNn3sePjIyUdrtdbr755nLKKafMCo9jjz22fOxjHyuPPfZY1aceAFiDBAhrXqPRqDw65hp//OMfy3nnnVe++MUvzvuYPXv2lO3bt5eTTjppVng87WlPK5/61KdKvV6v+pQDAGuYAGFNGxsbqzw0lmPs3r27fOlLX5px88J947jjjitXX311GRgYqPp0AwAIENauqrbdXc7xyCOPlOuuu66ceOKJs8Jj8+bN5Yorrig7d+4szWazdDqdqk85AIAAYe0aHh6uPCCWMq6//vryzGc+c1Z4HH/88eUzn/lM2bVr16xjRkdHF7xtLwDAchIgrEntdrvygFjK2L17d3nxi188Izy2bNlSrr322vLwww8f8tj+/v4yPj5e9SUAANYoAcKaNDg4WHlELEeEXHvttWXTpk29GwledNFFZefOnfM6fnBwsLRaraovBQCwxggQ1pzJycnK42E5x0MPPVTe/e539+6mfvzxx5dt27aVxx57bF7HDw0NWR8CAMQIENac/v7+yqNhJcaBd1M/5ZRTym233TavY+v1uvUhAECEAGFN2bt3b+WhsNLjhhtumHE39XPOOafcf//9M56zc+fO8q53vWvW3/v7+8vExETVlwkAOIoJENaMTqez6rfdne848G7qGzduLJdffnn517/+Vfr6+spFF11UarVaef3rXz/n8QMDA6Xdbld9yQCAo5AAYc0YGhqqPAzS449//GPZunVrWbduXanVauU5z3lOufbaa8uGDRvK+vXry913333I40dGRsr09HTVlw4AOIoIENaE6enpNfPtx1zjjjvuKKeddtqMbXvf/e53z+vYer1exsbGqr6EAMBRQoCwZnQ6nTX5Lci+8fjjj5ft27eXE044oWzatKk8+OCDCzq+0WiUycnJqi8jALDKCRDWnFarVQYGBioPgqrGrl27yk9+8pNFH99sNq0PAQAWTYCwJnW73TI+Pn7Ubsm70qNer1sfAgAsigBhTet2u2VkZGRNrw9ZaoiMj4+7fwgAMG8CBEop7Xa7NJvNyj/Qr9YxMDBQWq1W1ZcRAFgFBAjsp9VqlUajUfkH+tU6ms1m6XQ6VV9GAOAIJkBgDmNjY36WtYQxOjrqZ1kAwJwECBzE9PR0GR4ervzD/God/f39ZWJiourLCAAcYQQIHMbU1FQZHBys/AP9ah2Dg4Nlamqq6ssIABwhBAjM08TEhPUhSxjDw8PWhwAAAgQWotvtlr1791ofsshRr9fL3r17rQ8BgDVMgMAidDod60OWMBqNhvUhALBGCRBYgna7bX3IEsbAwID1IQCwxggQWAYTExOlv7+/8g/0q3UMDw+X6enpqi8jABAgQGCZdLvdMjo6WvmH+dU66vV6GRsbq/oyAgArTIDAMut0OmVoaKjyD/SrcdTrdd+EAMBRToDACmm1WmVgYKDyD/WraYyPj1d92QCAFSZAYAV1u90yPj5ufcg8RqPRqPpyAQABAgQCpqeny8jIiPuHHGK0Wq2qLxMAECBAIKjdbpdms1n5h/0jbTSbzaovDQAQIkCgApOTk6XRaFT+wf9IGZ1Op+pLAgCECBCo0NjY2Jr/Wdbo6GjVlwEACBIgULHp6ekyPDxceQhUMWy7CwBrjwCBI0S73V5z2/badhcA1h4BAkeYiYmJNbE+ZHBwsOpTDQBUQIDAEajb7ZbR0dGjen3I1NRU1acZAKiAAIEjWKfTOSrXhwwNDVV9agGAiggQWAVarVYZHBysPByWY9TrddvuAsAaJkBgFZmYmFj1P8vau3dv1acRAKiQAIFVZt/6kKpDYjGj0WiUbrdb9SkEACokQGCV6nQ6ZWhoqPKoWMiYmJio+rQBABUTILDKtVqtVXH/ENvuAgClCBA4KnS73TI2NnZErw+x7S4AUIoAgaPK9PR0GRkZOeJCZGRkpOpTAwAcIQQIHIXa7XZpNpuVh0dfX1/p7+8v09PTVZ8SAOAIIUDgKDY5OVkajUalAWLbXQBgfwIEjnJVrg+x7S4AcCABAmvE9PR0GR4ejgbI5ORk1dMGAI4wAgTWmHa7Hdm2t9lsVj1VAOAIJEBgjZqcnCz9/f0rEh/1er202+2qpwgAHIEECKxh3W63jI6OLvv6ENvuAgAHI0CAMj09XYaGhpYlPmy7CwAcigABelqtVhkcHFxSgIyNjVU9DQDgCCZAgFnGx8cXtT5kYGDAtrsAwCEJEGBO+9aHLCRAWq1W1W8bADjCCRDgkNrtdmk2m4eNj6GhoarfKgCwCggQYF5arVZpNBoH3Xa30+lU/RYBgFVAgAALMjY2Nmvb3tHR0arfFgCwSggQYMGmp6fL8PCwbXcBgAUTIMCiTU1NWXgOACyIAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECE39mo0AAAWfSURBVAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADECBAAACBGgAAAADECBAAAiBEgAABAjAABAABiBAgAABAjQAAAgBgBAgAAxAgQAAAgRoAAAAAxAgQAAIgRIAAAQIwAAQAAYgQIAAAQI0AAAIAYAQIAAMQIEAAAIEaAAAAAMQIEAACIESAAAECMAAEAAGIECAAAECNAAACAGAECAADE/B/mXiiqhkAYogAAAABJRU5ErkJggg==
You need to log in before you can comment on or make changes to this bug.