Changeset 81886 in webkit


Ignore:
Timestamp:
Mar 24, 2011 12:34:51 PM (13 years ago)
Author:
benjamin.poulain@nokia.com
Message:

2011-03-24 Benjamin Poulain <benjamin.poulain@nokia.com>

Reviewed by Kenneth Rohde Christiansen.

[Qt] When we render WebGL offscreen, color conversion cost a lot of CPU cycles
https://bugs.webkit.org/show_bug.cgi?id=40884

The software fallback is now only needed for corner cases like a manual rendering
of the page to QImage.

Keeping the image with the last pixel values is no longer needed. Removing it reduce the
performance for real-time rendering on software surface, but this case should no longer be
supported.

The conversion from OpenGL color space and coordinates is done manually for performance. This
also fix the bug of the inverted X axis due to the transformation.

The tests and benchmarks are done through Qt API tests.

  • platform/graphics/qt/GraphicsContext3DQt.cpp: (WebCore::swapBgrToRgb): (WebCore::GraphicsContext3DInternal::paint): (WebCore::GraphicsContext3D::reshape):

2011-03-24 Benjamin Poulain <benjamin.poulain@nokia.com>

Reviewed by Kenneth Rohde Christiansen.

[Qt] When we render WebGL offscreen, color conversion cost a lot of CPU cycles
https://bugs.webkit.org/show_bug.cgi?id=40884

Add tests and benchmarks for the software fallback of WebGL.

  • tests/benchmarks/webgl/10000_triangles.html: Added.
  • tests/benchmarks/webgl/tst_webgl.cpp: Added. (GraphicsView::GraphicsView): (GraphicsView::resizeEvent): (tst_WebGlPerformance::init): (tst_WebGlPerformance::cleanup): (tst_WebGlPerformance::benchSoftwareFallbackRgb16): (tst_WebGlPerformance::benchSoftwareFallbackRgb32): (tst_WebGlPerformance::benchSoftwareFallbackArgb32): (tst_WebGlPerformance::benchSoftwareFallbackArgb32Premultiplied): (tst_WebGlPerformance::benchmarkFrameRenderingOnImage):
  • tests/benchmarks/webgl/tst_webgl.qrc: Added.
  • tests/benchmarks/webgl/webgl.pro: Added.
  • tests/qgraphicswebview/qgraphicswebview.pro:
  • tests/qgraphicswebview/resources/pointing_right.html: Added.
  • tests/qgraphicswebview/resources/pointing_up.html: Added.
  • tests/qgraphicswebview/tst_qgraphicswebview.cpp: (compareImagesFuzzyPixelCount): (GraphicsView::GraphicsView): (tst_QGraphicsWebView::webglSoftwareFallbackVerticalOrientation): (tst_QGraphicsWebView::webglSoftwareFallbackHorizontalOrientation): (tst_QGraphicsWebView::compareCanvasToImage):
  • tests/qgraphicswebview/tst_qgraphicswebview.qrc:
  • tests/tests.pro:
Location:
trunk/Source
Files:
7 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r81884 r81886  
     12011-03-24  Benjamin Poulain  <benjamin.poulain@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Qt] When we render WebGL offscreen, color conversion cost a lot of CPU cycles
     6        https://bugs.webkit.org/show_bug.cgi?id=40884
     7
     8        The software fallback is now only needed for corner cases like a manual rendering
     9        of the page to QImage.
     10
     11        Keeping the image with the last pixel values is no longer needed. Removing it reduce the
     12        performance for real-time rendering on software surface, but this case should no longer be
     13        supported.
     14
     15        The conversion from OpenGL color space and coordinates is done manually for performance. This
     16        also fix the bug of the inverted X axis due to the transformation.
     17
     18        The tests and benchmarks are done through Qt API tests.
     19
     20        * platform/graphics/qt/GraphicsContext3DQt.cpp:
     21        (WebCore::swapBgrToRgb):
     22        (WebCore::GraphicsContext3DInternal::paint):
     23        (WebCore::GraphicsContext3D::reshape):
     24
    1252011-03-24  Nat Duca  <nduca@chromium.org>
    226
  • trunk/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp

    r81740 r81886  
    264264    GLuint m_currentFbo;
    265265    GLuint m_depthBuffer;
    266     QImage m_pixels;
    267266    bool m_layerComposited;
    268267    ListHashSet<unsigned int> m_syntheticErrors;
     
    482481}
    483482
     483static inline quint32 swapBgrToRgb(quint32 pixel)
     484{
     485    return ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
     486}
     487
    484488void GraphicsContext3DInternal::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
    485489{
     
    497501
    498502    // Alternatively read pixels to a memory buffer.
     503    QImage offscreenImage(rect.width(), rect.height(), QImage::Format_ARGB32);
     504    quint32* imagePixels = reinterpret_cast<quint32*>(offscreenImage.bits());
     505
    499506    m_glWidget->makeCurrent();
    500507    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_mainFbo);
    501     glReadPixels(/* x */ 0, /* y */ 0, rect.width(), rect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, m_pixels.bits());
    502     painter->drawImage(/* x */ 0, /* y */ 0, m_pixels.rgbSwapped().transformed(QMatrix().rotate(180)));
     508    glReadPixels(/* x */ 0, /* y */ 0, rect.width(), rect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, imagePixels);
     509
    503510    bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_currentFbo);
     511
     512    // OpenGL gives us ABGR on 32 bits, and with the origin at the bottom left
     513    // We need RGB32 or ARGB32_PM, with the origin at the top left.
     514    quint32* pixelsSrc = imagePixels;
     515    const int height = static_cast<int>(rect.height());
     516    const int width = static_cast<int>(rect.width());
     517    const int halfHeight = height / 2;
     518    for (int row = 0; row < halfHeight; ++row) {
     519        const int targetIdx = (height - 1 - row) * width;
     520        quint32* pixelsDst = imagePixels + targetIdx;
     521        for (int column = 0; column < width; ++column) {
     522            quint32 tempPixel = *pixelsSrc;
     523            *pixelsSrc = swapBgrToRgb(*pixelsDst);
     524            *pixelsDst = swapBgrToRgb(tempPixel);
     525            ++pixelsSrc;
     526            ++pixelsDst;
     527        }
     528    }
     529    if (static_cast<int>(height) % 2) {
     530        for (int column = 0; column < width; ++column) {
     531            *pixelsSrc = swapBgrToRgb(*pixelsSrc);
     532            ++pixelsSrc;
     533        }
     534    }
     535    painter->drawImage(/* x */ 0, /* y */ 0, offscreenImage);
    504536}
    505537
     
    591623
    592624    m_internal->m_boundingRect = QRectF(QPointF(0, 0), QSizeF(width, height));
    593     m_internal->m_pixels = QImage(m_currentWidth, m_currentHeight, QImage::Format_ARGB32);
    594625
    595626    m_internal->m_glWidget->makeCurrent();
  • trunk/Source/WebKit/qt/ChangeLog

    r81876 r81886  
     12011-03-24  Benjamin Poulain  <benjamin.poulain@nokia.com>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Qt] When we render WebGL offscreen, color conversion cost a lot of CPU cycles
     6        https://bugs.webkit.org/show_bug.cgi?id=40884
     7
     8        Add tests and benchmarks for the software fallback of WebGL.
     9
     10        * tests/benchmarks/webgl/10000_triangles.html: Added.
     11        * tests/benchmarks/webgl/tst_webgl.cpp: Added.
     12        (GraphicsView::GraphicsView):
     13        (GraphicsView::resizeEvent):
     14        (tst_WebGlPerformance::init):
     15        (tst_WebGlPerformance::cleanup):
     16        (tst_WebGlPerformance::benchSoftwareFallbackRgb16):
     17        (tst_WebGlPerformance::benchSoftwareFallbackRgb32):
     18        (tst_WebGlPerformance::benchSoftwareFallbackArgb32):
     19        (tst_WebGlPerformance::benchSoftwareFallbackArgb32Premultiplied):
     20        (tst_WebGlPerformance::benchmarkFrameRenderingOnImage):
     21        * tests/benchmarks/webgl/tst_webgl.qrc: Added.
     22        * tests/benchmarks/webgl/webgl.pro: Added.
     23        * tests/qgraphicswebview/qgraphicswebview.pro:
     24        * tests/qgraphicswebview/resources/pointing_right.html: Added.
     25        * tests/qgraphicswebview/resources/pointing_up.html: Added.
     26        * tests/qgraphicswebview/tst_qgraphicswebview.cpp:
     27        (compareImagesFuzzyPixelCount):
     28        (GraphicsView::GraphicsView):
     29        (tst_QGraphicsWebView::webglSoftwareFallbackVerticalOrientation):
     30        (tst_QGraphicsWebView::webglSoftwareFallbackHorizontalOrientation):
     31        (tst_QGraphicsWebView::compareCanvasToImage):
     32        * tests/qgraphicswebview/tst_qgraphicswebview.qrc:
     33        * tests/tests.pro:
     34
    1352011-03-24  Kristian Amlie  <kristian.amlie@nokia.com>
    236
  • trunk/Source/WebKit/qt/tests/qgraphicswebview/qgraphicswebview.pro

    r58096 r81886  
    22include(../tests.pri)
    33exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
     4contains(DEFINES, ENABLE_WEBGL=1) {
     5    QT += opengl
     6}
  • trunk/Source/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp

    r81393 r81886  
    2525#include <qwebpage.h>
    2626#include <qwebframe.h>
     27
     28#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
     29#include <QGLWidget>
     30#endif
    2731
    2832class tst_QGraphicsWebView : public QObject
     
    4044    void setPalette();
    4145    void renderHints();
     46
     47#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
     48    void webglSoftwareFallbackVerticalOrientation();
     49    void webglSoftwareFallbackHorizontalOrientation();
     50
     51private:
     52    void compareCanvasToImage(const QUrl&, const QImage&);
     53#endif
    4254};
    4355
     
    445457}
    446458
     459class GraphicsView : public QGraphicsView {
     460public:
     461    GraphicsView();
     462    QGraphicsWebView* m_webView;
     463};
     464
     465#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
     466bool compareImagesFuzzyPixelCount(const QImage& image1, const QImage& image2, qreal tolerance = 0.05)
     467{
     468    if (image1.size() != image2.size())
     469        return false;
     470
     471    unsigned diffPixelCount = 0;
     472    for (int row = 0; row < image1.size().width(); ++row) {
     473        for (int column = 0; column < image1.size().height(); ++column)
     474            if (image1.pixel(row, column) != image2.pixel(row, column))
     475                ++diffPixelCount;
     476    }
     477
     478    if (diffPixelCount > (image1.size().width() * image1.size().height()) * tolerance)
     479        return false;
     480
     481    return true;
     482}
     483
     484GraphicsView::GraphicsView()
     485{
     486    QGraphicsScene* const scene = new QGraphicsScene(this);
     487    setScene(scene);
     488
     489    m_webView = new QGraphicsWebView;
     490    scene->addItem(m_webView);
     491
     492    m_webView->page()->settings()->setAttribute(QWebSettings::WebGLEnabled, true);
     493    m_webView->setResizesToContents(true);
     494
     495    setFrameShape(QFrame::NoFrame);
     496    setViewport(new QGLWidget);
     497}
     498
     499void tst_QGraphicsWebView::webglSoftwareFallbackVerticalOrientation()
     500{
     501    QSize canvasSize(100, 100);
     502    QImage reference(canvasSize, QImage::Format_ARGB32);
     503    reference.fill(0xFF00FF00);
     504    { // Reference.
     505        QPainter painter(&reference);
     506        QPolygonF triangleUp;
     507        triangleUp << QPointF(0, canvasSize.height())
     508                   << QPointF(canvasSize.width(), canvasSize.height())
     509                   << QPointF(canvasSize.width() / 2.0, canvasSize.height() / 2.0);
     510        painter.setPen(Qt::NoPen);
     511        painter.setBrush(Qt::red);
     512        painter.drawPolygon(triangleUp);
     513    }
     514
     515    compareCanvasToImage(QUrl(QLatin1String("qrc:///resources/pointing_up.html")), reference);
     516}
     517
     518void tst_QGraphicsWebView::webglSoftwareFallbackHorizontalOrientation()
     519{
     520    QSize canvasSize(100, 100);
     521    QImage reference(canvasSize, QImage::Format_ARGB32);
     522    reference.fill(0xFF00FF00);
     523    { // Reference.
     524        QPainter painter(&reference);
     525        QPolygonF triangleUp;
     526        triangleUp << QPointF(0, 0)
     527                   << QPointF(0, canvasSize.height())
     528                   << QPointF(canvasSize.width() / 2.0, canvasSize.height() / 2.0);
     529        painter.setPen(Qt::NoPen);
     530        painter.setBrush(Qt::red);
     531        painter.drawPolygon(triangleUp);
     532    }
     533
     534    compareCanvasToImage(QUrl(QLatin1String("qrc:///resources/pointing_right.html")), reference);
     535}
     536
     537void tst_QGraphicsWebView::compareCanvasToImage(const QUrl& url, const QImage& reference)
     538{
     539    GraphicsView view;
     540    view.show();
     541    QTest::qWaitForWindowShown(&view);
     542
     543    QGraphicsWebView* const graphicsWebView = view.m_webView;
     544    graphicsWebView->load(url);
     545    QVERIFY(waitForSignal(graphicsWebView, SIGNAL(loadFinished(bool))));
     546    { // Force a render, to create the accelerated compositing tree.
     547        QPixmap pixmap(view.size());
     548        QPainter painter(&pixmap);
     549        view.render(&painter);
     550    }
     551    QApplication::syncX();
     552
     553    const QSize imageSize = reference.size();
     554
     555    QImage target(imageSize, QImage::Format_ARGB32);
     556    { // Web page content.
     557        QPainter painter(&target);
     558        QRectF renderRect(0, 0, imageSize.width(), imageSize.height());
     559        view.scene()->render(&painter, renderRect, renderRect);
     560    }
     561    QVERIFY(compareImagesFuzzyPixelCount(target, reference, 0.01));
     562}
     563#endif
     564
    447565QTEST_MAIN(tst_QGraphicsWebView)
    448566
  • trunk/Source/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.qrc

    r60958 r81886  
    1 <!DOCTYPE RCC><RCC version="1.0">
    2 <qresource>
    3     <file>resources/input_types.html</file>
    4 </qresource>
     1<RCC>
     2    <qresource prefix="/">
     3        <file>resources/input_types.html</file>
     4        <file>resources/pointing_right.html</file>
     5        <file>resources/pointing_up.html</file>
     6    </qresource>
    57</RCC>
    6 
  • trunk/Source/WebKit/qt/tests/tests.pro

    r79678 r81886  
    44contains(QT_CONFIG, declarative): SUBDIRS += qdeclarativewebview
    55SUBDIRS += benchmarks/painting benchmarks/loading
     6contains(DEFINES, ENABLE_WEBGL=1) {
     7    SUBDIRS += benchmarks/webgl
     8}
Note: See TracChangeset for help on using the changeset viewer.