Changeset 150809 in webkit


Ignore:
Timestamp:
May 28, 2013 10:28:35 AM (11 years ago)
Author:
anilsson@rim.com
Message:

[BlackBerry] backface-visibility: hidden doesn't work properly with masks and filters
https://bugs.webkit.org/show_bug.cgi?id=116616

Reviewed by Carlos Garcia Campos.

The BlackBerry::Platform::Graphics::GraphicsContext generates geometry
with a different winding order than the accelerated compositing backend
of the BlackBerry port. So, when we switched from Skia to this new
rendering engine, we switched from glFrontFace(GL_CCW) to
glFrontFace(GL_CW), and all was well when drawing display lists.
However, we forgot to update the winding order of geometry generated
within the accelerated compositing backend, which is used for masks and
filters, so they were getting erroneously culled out when
backface-visibility: hidden was applied to them. Fixed by switching the
winding order of all geometry generated up here, which has the added
benefit of enabling us to use TransformationMatrix::mapQuad instead of
transforming point-by-point.

To further complicate matters, a right-side up transform is used when
drawing layers into surfaces, reversing the winding order and requiring
us to switch back to glFrontFace(GL_CCW) temporarily, when drawing
layers to surfaces, or the layers will get culled out inside the
surface.

Also fix spelling error, "drawed" should be "drawn".

No new tests, this is only detectable by pixel tests, which the
BlackBerry port currently doesn't support.

PR 341945.

  • platform/graphics/blackberry/EGLImageLayerCompositingThreadClient.cpp:

(WebCore::EGLImageLayerCompositingThreadClient::drawTextures):

  • platform/graphics/blackberry/LayerCompositingThread.cpp:

(WebCore::LayerCompositingThread::setDrawTransform):
(WebCore::getTransformedRect):
(WebCore::LayerCompositingThread::drawTextures):
(WebCore::LayerCompositingThread::drawSurface):

  • platform/graphics/blackberry/LayerCompositingThread.h:

(LayerCompositingThread):
(WebCore::LayerCompositingThread::origin):

  • platform/graphics/blackberry/LayerFilterRenderer.cpp:

(WebCore):

  • platform/graphics/blackberry/LayerRenderer.cpp:

(WebCore::LayerRenderer::compositeLayers):
(WebCore):
(WebCore::LayerRenderer::drawLayersOnSurfaces):

  • platform/graphics/blackberry/LayerRendererSurface.cpp:

(WebCore::LayerRendererSurface::drawRect):
(WebCore::LayerRendererSurface::transformedBounds):

  • platform/graphics/blackberry/LayerRendererSurface.h:

(WebCore::LayerRendererSurface::origin):
(LayerRendererSurface):

  • platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp:

(WebCore):
(WebCore::loadBufferingImageData):
(WebCore::MediaPlayerPrivate::drawBufferingAnimation):

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r150805 r150809  
     12013-05-28  Arvid Nilsson  <anilsson@rim.com>
     2
     3        [BlackBerry] backface-visibility: hidden doesn't work properly with masks and filters
     4        https://bugs.webkit.org/show_bug.cgi?id=116616
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        The BlackBerry::Platform::Graphics::GraphicsContext generates geometry
     9        with a different winding order than the accelerated compositing backend
     10        of the BlackBerry port. So, when we switched from Skia to this new
     11        rendering engine, we switched from glFrontFace(GL_CCW) to
     12        glFrontFace(GL_CW), and all was well when drawing display lists.
     13        However, we forgot to update the winding order of geometry generated
     14        within the accelerated compositing backend, which is used for masks and
     15        filters, so they were getting erroneously culled out when
     16        backface-visibility: hidden was applied to them. Fixed by switching the
     17        winding order of all geometry generated up here, which has the added
     18        benefit of enabling us to use TransformationMatrix::mapQuad instead of
     19        transforming point-by-point.
     20
     21        To further complicate matters, a right-side up transform is used when
     22        drawing layers into surfaces, reversing the winding order and requiring
     23        us to switch back to glFrontFace(GL_CCW) temporarily, when drawing
     24        layers to surfaces, or the layers will get culled out inside the
     25        surface.
     26
     27        Also fix spelling error, "drawed" should be "drawn".
     28
     29        No new tests, this is only detectable by pixel tests, which the
     30        BlackBerry port currently doesn't support.
     31
     32        PR 341945.
     33
     34        * platform/graphics/blackberry/EGLImageLayerCompositingThreadClient.cpp:
     35        (WebCore::EGLImageLayerCompositingThreadClient::drawTextures):
     36        * platform/graphics/blackberry/LayerCompositingThread.cpp:
     37        (WebCore::LayerCompositingThread::setDrawTransform):
     38        (WebCore::getTransformedRect):
     39        (WebCore::LayerCompositingThread::drawTextures):
     40        (WebCore::LayerCompositingThread::drawSurface):
     41        * platform/graphics/blackberry/LayerCompositingThread.h:
     42        (LayerCompositingThread):
     43        (WebCore::LayerCompositingThread::origin):
     44        * platform/graphics/blackberry/LayerFilterRenderer.cpp:
     45        (WebCore):
     46        * platform/graphics/blackberry/LayerRenderer.cpp:
     47        (WebCore::LayerRenderer::compositeLayers):
     48        (WebCore):
     49        (WebCore::LayerRenderer::drawLayersOnSurfaces):
     50        * platform/graphics/blackberry/LayerRendererSurface.cpp:
     51        (WebCore::LayerRendererSurface::drawRect):
     52        (WebCore::LayerRendererSurface::transformedBounds):
     53        * platform/graphics/blackberry/LayerRendererSurface.h:
     54        (WebCore::LayerRendererSurface::origin):
     55        (LayerRendererSurface):
     56        * platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp:
     57        (WebCore):
     58        (WebCore::loadBufferingImageData):
     59        (WebCore::MediaPlayerPrivate::drawBufferingAnimation):
     60
    1612013-05-28  Andreas Kling  <akling@apple.com>
    262
  • trunk/Source/WebCore/platform/graphics/blackberry/EGLImageLayerCompositingThreadClient.cpp

    r144465 r150809  
    4848void EGLImageLayerCompositingThreadClient::drawTextures(LayerCompositingThread* layer, double /*scale*/, const GLES2Program& program)
    4949{
    50     static float upsideDown[4 * 2] = { 0, 1,  0, 0,  1, 0,  1, 1 };
     50    static float upsideDown[4 * 2] = { 0, 1,  1, 1,  1, 0,  0, 0 };
    5151
    5252    if (!m_textureAccessor || !m_textureAccessor->textureID())
  • trunk/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp

    r148192 r150809  
    134134    m_drawTransform = matrix;
    135135
    136     float bx = m_bounds.width() / 2.0;
    137     float by = m_bounds.height() / 2.0;
    138 
    139     if (sizeIsScaleInvariant()) {
    140         bx /= scale;
    141         by /= scale;
    142     }
    143 
    144     m_transformedBounds.setP1(matrix.mapPoint(FloatPoint(-bx, -by)));
    145     m_transformedBounds.setP2(matrix.mapPoint(FloatPoint(-bx, by)));
    146     m_transformedBounds.setP3(matrix.mapPoint(FloatPoint(bx, by)));
    147     m_transformedBounds.setP4(matrix.mapPoint(FloatPoint(bx, -by)));
    148 
     136    FloatRect boundsRect(-origin(), bounds());
     137
     138    if (sizeIsScaleInvariant())
     139        boundsRect.scale(1 / scale);
     140
     141    m_transformedBounds = matrix.mapQuad(boundsRect);
    149142    m_drawRect = m_transformedBounds.boundingBox();
    150143}
     
    152145static FloatQuad getTransformedRect(const IntSize& bounds, const IntRect& rect, const TransformationMatrix& drawTransform)
    153146{
    154     float x = -bounds.width() / 2.0 + rect.x();
    155     float y = -bounds.height() / 2.0 + rect.y();
    156     float w = rect.width();
    157     float h = rect.height();
    158     FloatQuad result;
    159     result.setP1(drawTransform.mapPoint(FloatPoint(x, y)));
    160     result.setP2(drawTransform.mapPoint(FloatPoint(x, y + h)));
    161     result.setP3(drawTransform.mapPoint(FloatPoint(x + w, y + h)));
    162     result.setP4(drawTransform.mapPoint(FloatPoint(x + w, y)));
    163 
    164     return result;
     147    FloatPoint origin(bounds.width() / 2.0f, bounds.height() / 2.0f);
     148    FloatRect layerRect(rect);
     149    layerRect.moveBy(-origin);
     150    return drawTransform.mapQuad(layerRect);
    165151}
    166152
     
    214200void LayerCompositingThread::drawTextures(double scale, const GLES2Program& program, const FloatRect& visibleRect)
    215201{
    216     static float texcoords[4 * 2] = { 0, 0,  0, 1,  1, 1,  1, 0 };
     202    static float texcoords[4 * 2] = { 0, 0,  1, 0,  1, 1,  0, 1 };
    217203
    218204    if (m_pluginView) {
     
    304290        glVertexAttribPointer(program.positionLocation(), 2, GL_FLOAT, GL_FALSE, 0, &surfaceQuad);
    305291
    306         static float texcoords[4 * 2] = { 0, 0,  0, 1,  1, 1,  1, 0 };
     292        static float texcoords[4 * 2] = { 0, 0,  1, 0,  1, 1,  0, 1 };
    307293        glVertexAttribPointer(program.texCoordLocation(), 2, GL_FLOAT, GL_FALSE, 0, texcoords);
    308294        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  • trunk/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.h

    r149824 r150809  
    162162    void setLayerRenderer(LayerRenderer*);
    163163
     164    // The draw transform expects the origin to be located at the center of the layer.
     165    FloatPoint origin() const { return FloatPoint(m_bounds.width() / 2.0f, m_bounds.height() / 2.0f); }
     166
    164167    void setDrawTransform(double scale, const TransformationMatrix&);
    165168    const TransformationMatrix& drawTransform() const { return m_drawTransform; }
  • trunk/Source/WebCore/platform/graphics/blackberry/LayerFilterRenderer.cpp

    r149824 r150809  
    683683}
    684684
    685 static float texcoords[4 * 2] = { 0, 0,  0, 1,  1, 1,  1, 0 };
     685static float texcoords[4 * 2] = { 0, 0,  1, 0,  1, 1,  0, 1 };
    686686
    687687void LayerFilterRenderer::applyActions(unsigned& fbo, LayerCompositingThread* layer, Vector<RefPtr<LayerFilterRendererAction> > actions)
  • trunk/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp

    r149824 r150809  
    332332        return;
    333333
    334     // If some layers should be drawed on temporary surfaces, we should do it first.
    335     drawLayersOnSurfaces(surfaceLayers);
     334    // If some layers should be drawn on temporary surfaces, we should do it first.
     335    if (!surfaceLayers.isEmpty())
     336        drawLayersOnSurfaces(surfaceLayers);
    336337
    337338    // Don't render the root layer, the BlackBerry port uses the BackingStore to draw the
     
    373374}
    374375
    375 static float texcoords[4 * 2] = { 0, 0,  0, 1,  1, 1,  1, 0 };
     376static float texcoords[4 * 2] = { 0, 0,  1, 0,  1, 1,  0, 1 };
    376377
    377378void LayerRenderer::compositeBuffer(const TransformationMatrix& transform, const FloatRect& contents, BlackBerry::Platform::Graphics::Buffer* buffer, bool contentsOpaque, float opacity)
     
    466467void LayerRenderer::drawLayersOnSurfaces(const Vector<RefPtr<LayerCompositingThread> >& surfaceLayers)
    467468{
     469    // Normally, an upside-down transform is used, as is the GL custom. However, when drawing
     470    // layers to surfaces, a right-side-up transform is used, so we need to switch the winding order
     471    // for culling.
     472    glFrontFace(GL_CCW);
     473
    468474    for (int i = surfaceLayers.size() - 1; i >= 0; i--) {
    469475        LayerCompositingThread* layer = surfaceLayers[i].get();
     
    492498    }
    493499
    494     // If there are layers drawed on surfaces, we need to switch to default framebuffer.
     500    glFrontFace(GL_CW);
     501
     502    // If there are layers drawn on surfaces, we need to switch to default framebuffer.
    495503    // Otherwise, we just need to set viewport.
    496     if (surfaceLayers.size()) {
    497         useSurface(0);
    498         glEnable(GL_SCISSOR_TEST);
    499         glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height());
    500     }
     504    useSurface(0);
     505    glEnable(GL_SCISSOR_TEST);
     506    glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height());
    501507}
    502508
     
    935941    drawDebugBorder(layer);
    936942
    937     // The texture for the LayerRendererSurface can be released after the surface was drawed on another surface.
     943    // The texture for the LayerRendererSurface can be released after the surface was drawn on another surface.
    938944    if (layerAlreadyOnSurface(layer)) {
    939945        layer->layerRendererSurface()->releaseTexture();
  • trunk/Source/WebCore/platform/graphics/blackberry/LayerRendererSurface.cpp

    r148200 r150809  
    4848FloatRect LayerRendererSurface::drawRect() const
    4949{
    50     float bx = m_size.width() / 2.0;
    51     float by = m_size.height() / 2.0;
    52 
    5350    FloatRect rect = transformedBounds().boundingBox();
    5451
    55     if (m_ownerLayer->replicaLayer()) {
    56         FloatQuad bounds;
    57         bounds.setP1(m_replicaDrawTransform.mapPoint(FloatPoint(-bx, -by)));
    58         bounds.setP2(m_replicaDrawTransform.mapPoint(FloatPoint(-bx, by)));
    59         bounds.setP3(m_replicaDrawTransform.mapPoint(FloatPoint(bx, by)));
    60         bounds.setP4(m_replicaDrawTransform.mapPoint(FloatPoint(bx, -by)));
    61         rect.unite(bounds.boundingBox());
    62     }
     52    if (m_ownerLayer->replicaLayer())
     53        rect.unite(m_replicaDrawTransform.mapQuad(FloatRect(-origin(), size())).boundingBox());
    6354
    6455    return rect;
     
    6758FloatQuad LayerRendererSurface::transformedBounds() const
    6859{
    69     float bx = m_size.width() / 2.0;
    70     float by = m_size.height() / 2.0;
    71 
    72     FloatQuad bounds;
    73     bounds.setP1(m_drawTransform.mapPoint(FloatPoint(-bx, -by)));
    74     bounds.setP2(m_drawTransform.mapPoint(FloatPoint(-bx, by)));
    75     bounds.setP3(m_drawTransform.mapPoint(FloatPoint(bx, by)));
    76     bounds.setP4(m_drawTransform.mapPoint(FloatPoint(bx, -by)));
    77 
    78     return bounds;
     60    return m_drawTransform.mapQuad(FloatRect(-origin(), size()));
    7961}
    8062
  • trunk/Source/WebCore/platform/graphics/blackberry/LayerRendererSurface.h

    r148200 r150809  
    4646    void setClipRect(const FloatRect& rect) { m_clipRect = rect; }
    4747
     48    FloatPoint origin() const { return FloatPoint(m_size.width() / 2.0f, m_size.height() / 2.0f); }
     49
    4850    void setDrawTransform(const TransformationMatrix& matrix) { m_drawTransform = matrix; }
    4951    const TransformationMatrix& drawTransform() const { return m_drawTransform; }
  • trunk/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp

    r149824 r150809  
    877877static const double BufferingAnimationDelay = 1.0 / 24;
    878878static unsigned* s_bufferingImageData = 0;
    879 static int s_bufferingImageWidth = 0;
    880 static int s_bufferingImageHeight = 0;
     879static IntSize s_bufferingImageSize;
    881880
    882881PlatformMedia MediaPlayerPrivate::platformMedia() const
     
    906905
    907906        loaded = true;
    908         s_bufferingImageWidth = bufferingIcon->width();
    909         s_bufferingImageHeight = bufferingIcon->height();
     907        s_bufferingImageSize = bufferingIcon->size();
    910908        int bufSize = bufferingIcon->decodedSize();
    911909        s_bufferingImageData = static_cast<unsigned*>(malloc(bufSize));
    912910
    913         nativeImage->readPixels(s_bufferingImageData, s_bufferingImageWidth * s_bufferingImageHeight);
     911        nativeImage->readPixels(s_bufferingImageData, s_bufferingImageSize.width() * s_bufferingImageSize.height());
    914912
    915913        bufferingIcon->deref();
     
    973971        if (!initialized) {
    974972            initialized = true;
    975             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s_bufferingImageWidth, s_bufferingImageHeight,
     973            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s_bufferingImageSize.width(), s_bufferingImageSize.height(),
    976974                0, GL_RGBA, GL_UNSIGNED_BYTE, s_bufferingImageData);
    977975            free(s_bufferingImageData);
    978976        }
    979977
    980         float texcoords[] = { 0, 0,  0, 1,  1, 1,  1, 0 };
    981         FloatPoint vertices[4];
    982         float bx = s_bufferingImageWidth / 2.0;
    983         float by = s_bufferingImageHeight / 2.0;
    984         vertices[0] = renderMatrix.mapPoint(FloatPoint(-bx, -by));
    985         vertices[1] = renderMatrix.mapPoint(FloatPoint(-bx, by));
    986         vertices[2] = renderMatrix.mapPoint(FloatPoint(bx, by));
    987         vertices[3] = renderMatrix.mapPoint(FloatPoint(bx, -by));
     978        float texcoords[] = { 0, 0,  1, 0,  1, 1,  0, 1 };
     979        FloatRect bufferingImageRect(FloatPoint(-s_bufferingImageSize.width() / 2.0f, -s_bufferingImageSize.height() / 2.0f), s_bufferingImageSize);
     980        FloatQuad transformedQuad = renderMatrix.mapQuad(bufferingImageRect);
    988981
    989982        glEnable(GL_BLEND);
    990983        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    991984        glUniform1f(program.opacityLocation(), 1.0);
    992         glVertexAttribPointer(program.positionLocation(), 2, GL_FLOAT, GL_FALSE, 0, vertices);
     985        glVertexAttribPointer(program.positionLocation(), 2, GL_FLOAT, GL_FALSE, 0, &transformedQuad);
    993986        glVertexAttribPointer(program.texCoordLocation(), 2, GL_FLOAT, GL_FALSE, 0, texcoords);
    994987        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
Note: See TracChangeset for help on using the changeset viewer.