WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
117067
[BlackBerry] Accelerated compositing layers that intersect the image plane are incorrectly transformed
https://bugs.webkit.org/show_bug.cgi?id=117067
Summary
[BlackBerry] Accelerated compositing layers that intersect the image plane ar...
Arvid Nilsson
Reported
2013-05-31 03:55:25 PDT
The BlackBerry port mathematically projects each corner of each layer bounds rectangle, which gives the wrong results when the layer intersects the image plane. For display lists, we still get the correct appearance of the layer contents, since the display list results in geometry that's transformed in the vertex shader, on the GPU. However, the transformed bounds are used for drawing the debug border, performing visibility calculations on the CPU and drawing of WebGL, masks/reflections and filters. Using the mathematical projection of points that lie behind the image plane gives the wrong results. The easiest way to visualise the error is to just enable the debug border and make some layers intersect the image plane, e.g. the clouds on
https://developer.mozilla.org/en-US/demos/detail/the-box/launch
. The most important consequence of this bug is that the wrong area of the layer will be considered visible, so a tiled layer will not populate the right tiles (or sometimes, any tiles at all). However, this is reasonably easy to fix - the recipe can be found in section 6.2 of
http://www.w3.org/TR/css3-transforms
.
Attachments
Some clouds with matching bounding boxes
(752.19 KB, image/png)
2013-05-31 03:57 PDT
,
Arvid Nilsson
no flags
Details
Some clouds with broken bounding boxes, visualising the bug
(749.54 KB, image/png)
2013-05-31 03:57 PDT
,
Arvid Nilsson
no flags
Details
Patch
(36.14 KB, patch)
2013-05-31 04:08 PDT
,
Arvid Nilsson
no flags
Details
Formatted Diff
Diff
Patch
(36.22 KB, patch)
2013-06-12 12:40 PDT
,
Arvid Nilsson
no flags
Details
Formatted Diff
Diff
Patch
(63.10 KB, patch)
2013-06-14 03:35 PDT
,
Arvid Nilsson
no flags
Details
Formatted Diff
Diff
Patch
(36.43 KB, patch)
2013-06-14 03:36 PDT
,
Arvid Nilsson
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Arvid Nilsson
Comment 1
2013-05-31 03:57:18 PDT
Created
attachment 203430
[details]
Some clouds with matching bounding boxes
Arvid Nilsson
Comment 2
2013-05-31 03:57:49 PDT
Created
attachment 203431
[details]
Some clouds with broken bounding boxes, visualising the bug
Arvid Nilsson
Comment 3
2013-05-31 04:08:32 PDT
Created
attachment 203433
[details]
Patch
Arvid Nilsson
Comment 4
2013-06-04 14:43:11 PDT
Andrew just added a setting in the browser GUI to enable the AC layer debug borders, so this bug is now much easier to reproduce and the fix easier to verify.
Jakob Petsovits
Comment 5
2013-06-07 08:14:00 PDT
Comment on
attachment 203433
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=203433&action=review
Slightly complex, but looks alright to me. Informal r+ and bonus kudos for writing clear code to tackle a not-so-straightforward problem.
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:207 > + static FloatPoint data[4] = { FloatPoint(0, 1), FloatPoint(1, 1), FloatPoint(1, 0), FloatPoint(0, 0) }; > + static Vector<FloatPoint>* coordinates = 0;
For a moment I was wondering whether this will always return the same coordinates even when called with a different value for upsideDown, because it's initialized only when coordinates is 0. Then I realized that data and coordinates only exist in this scope (within "if (upsideDown)") and therefore they are two distinct pairs of static variables, even though they bear the same name. Putting different prefixes on the variable names would help avoid this confusion, imho.
Arvid Nilsson
Comment 6
2013-06-12 12:40:15 PDT
Created
attachment 204500
[details]
Patch
Carlos Garcia Campos
Comment 7
2013-06-13 04:01:48 PDT
Comment on
attachment 204500
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=204500&action=review
> Source/WebCore/platform/graphics/blackberry/EGLImageLayerCompositingThreadClient.cpp:58 > + glVertexAttribPointer(program.texCoordLocation(), 2, GL_FLOAT, GL_FALSE, 0, layer->textureCoordinates(true /*upsideDown*/).data());
You could use an enum instead of a bool and you don't need a comment to make the code readable :-)
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:157 > + polygon = intersect(quad, LayerClipPlane(FloatPoint3D(matrix.m14(), matrix.m24(), matrix.m34()), matrix.m44() - epsilon));
Could this be Vector<FloatPoint3D, 4> polygon = ...?
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:159 > + // Compute the clipped texture coordinates
Nit: finish comment with a period.
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:172 > + p = multVecMatrix(matrix, p, w);
This looks a bit weird to me because p is a reference, maybe we could do: FloatPoint3D p = multVecMatrix(matrix, polygon[i], w);
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:176 > + p.setX(p.x() / w); > + p.setY(p.y() / w); > + p.setZ(p.z() / w);
This could be p.scale(1 / w); Why not reusing the existing TransformationMatrix::multVecMatrix()?
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:207 > + static FloatPoint data[4] = { FloatPoint(0, 1), FloatPoint(1, 1), FloatPoint(1, 0), FloatPoint(0, 0) }; > + static Vector<FloatPoint>* upsideDownCoordinates = 0;
I'm not sure making data static is a good idea, since the points are going to be copied to the vector and the vector is static, we will keep two copies always in memory, no?
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:216 > + static FloatPoint data[4] = { FloatPoint(0, 0), FloatPoint(1, 0), FloatPoint(1, 1), FloatPoint(0, 1) }; > + static Vector<FloatPoint>* coordinates = 0;
Ditto.
Arvid Nilsson
Comment 8
2013-06-14 02:55:59 PDT
Comment on
attachment 204500
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=204500&action=review
>> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:176 >> + p.setZ(p.z() / w); > > This could be p.scale(1 / w); Why not reusing the existing TransformationMatrix::multVecMatrix()?
The reason I did it like this, is I want the improved numeric stability of dividing p.x() with w instead of multiplying by 1/w. I thought 1/w would lose precision, but perhaps a floating point math expert can tell me otherwise. The reason I can't use the existing TransformationMatrix::multVecMatrix() is because it discards the w:s, and we need those in the next patch to perform unprojection.
>> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:207 >> + static Vector<FloatPoint>* upsideDownCoordinates = 0; > > I'm not sure making data static is a good idea, since the points are going to be copied to the vector and the vector is static, we will keep two copies always in memory, no?
Unfortunately, there's no way to make the Vector be the only copy of the data... And it's important that the common cases of full-rect texturing should use static data instead of being allocated on each call. I agree this code is a bit clunky, but this was the only way I could find of having the cake (static full-rect texture coordinate data) and eating it too (being able to return non-full-rect coordinate data in case of clipping).
Arvid Nilsson
Comment 9
2013-06-14 03:35:12 PDT
Created
attachment 204691
[details]
Patch
Arvid Nilsson
Comment 10
2013-06-14 03:35:44 PDT
Comment on
attachment 204691
[details]
Patch Wrong again
Arvid Nilsson
Comment 11
2013-06-14 03:36:19 PDT
Created
attachment 204692
[details]
Patch
Carlos Garcia Campos
Comment 12
2013-06-14 05:38:45 PDT
Comment on
attachment 204692
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=204692&action=review
> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:170 > + if (w != 1) {
You should probably also check w != 0 to a void a zero divison.
Arvid Nilsson
Comment 13
2013-06-14 06:18:50 PDT
Comment on
attachment 204692
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=204692&action=review
>> Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp:170 >> + if (w != 1) { > > You should probably also check w != 0 to a void a zero divison.
Thanks for the review =) Due to the construction above, where any point with w < epsilon is clipped to w = epsilon, w can never be 0 here.
WebKit Commit Bot
Comment 14
2013-06-14 07:04:35 PDT
Comment on
attachment 204692
[details]
Patch Clearing flags on attachment: 204692 Committed
r151591
: <
http://trac.webkit.org/changeset/151591
>
WebKit Commit Bot
Comment 15
2013-06-14 07:04:38 PDT
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug