Changeset 78923 in webkit


Ignore:
Timestamp:
Feb 17, 2011 3:49:53 PM (13 years ago)
Author:
kbr@google.com
Message:

2011-02-17 Kenneth Russell <kbr@google.com>

Reviewed by James Robinson.

Add support for GPU accelerated path rendering
https://bugs.webkit.org/show_bug.cgi?id=44729

Incorporates the Loop and Blinn path rendering algorithm as an
option to the GPU-accelerated canvas code, currently only compiled
in to the Chromium port. Currently it's toggled by changing a
hardcoded constant in
SharedGraphicsContext3D::useLoopBlinnForPathRendering() and is
disabled by default. This mechanism can be improved once we've
gained more confidence in the implementation. There are some known
bugs that need to be fixed first.

No new tests; ran some 2D Canvas tests manually with the new flag
both enabled and disabled.

  • WebCore.gypi:
  • platform/graphics/chromium/GLES2Canvas.cpp: (WebCore::GLES2Canvas::GLES2Canvas): (WebCore::GLES2Canvas::fillPath):
  • platform/graphics/chromium/GLES2Canvas.h:
  • platform/graphics/gpu/LoopBlinnClassifier.h:
  • platform/graphics/gpu/LoopBlinnLocalTriangulator.h:
  • platform/graphics/gpu/SharedGraphicsContext3D.cpp: (WebCore::SharedGraphicsContext3D::create): (WebCore::SharedGraphicsContext3D::SharedGraphicsContext3D): (WebCore::SharedGraphicsContext3D::createBuffer): (WebCore::SharedGraphicsContext3D::bindBuffer): (WebCore::SharedGraphicsContext3D::bufferData): (WebCore::SharedGraphicsContext3D::bufferSubData): (WebCore::SharedGraphicsContext3D::useLoopBlinnForPathRendering): (WebCore::SharedGraphicsContext3D::useLoopBlinnInteriorProgram): (WebCore::SharedGraphicsContext3D::useLoopBlinnExteriorProgram):
  • platform/graphics/gpu/SharedGraphicsContext3D.h:
  • platform/graphics/skia/GraphicsContextSkia.cpp: (WebCore::GraphicsContext::fillPath):
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r78922 r78923  
     12011-02-17  Kenneth Russell  <kbr@google.com>
     2
     3        Reviewed by James Robinson.
     4
     5        Add support for GPU accelerated path rendering
     6        https://bugs.webkit.org/show_bug.cgi?id=44729
     7
     8        Incorporates the Loop and Blinn path rendering algorithm as an
     9        option to the GPU-accelerated canvas code, currently only compiled
     10        in to the Chromium port. Currently it's toggled by changing a
     11        hardcoded constant in
     12        SharedGraphicsContext3D::useLoopBlinnForPathRendering() and is
     13        disabled by default. This mechanism can be improved once we've
     14        gained more confidence in the implementation. There are some known
     15        bugs that need to be fixed first.
     16
     17        No new tests; ran some 2D Canvas tests manually with the new flag
     18        both enabled and disabled.
     19
     20        * WebCore.gypi:
     21        * platform/graphics/chromium/GLES2Canvas.cpp:
     22        (WebCore::GLES2Canvas::GLES2Canvas):
     23        (WebCore::GLES2Canvas::fillPath):
     24        * platform/graphics/chromium/GLES2Canvas.h:
     25        * platform/graphics/gpu/LoopBlinnClassifier.h:
     26        * platform/graphics/gpu/LoopBlinnLocalTriangulator.h:
     27        * platform/graphics/gpu/SharedGraphicsContext3D.cpp:
     28        (WebCore::SharedGraphicsContext3D::create):
     29        (WebCore::SharedGraphicsContext3D::SharedGraphicsContext3D):
     30        (WebCore::SharedGraphicsContext3D::createBuffer):
     31        (WebCore::SharedGraphicsContext3D::bindBuffer):
     32        (WebCore::SharedGraphicsContext3D::bufferData):
     33        (WebCore::SharedGraphicsContext3D::bufferSubData):
     34        (WebCore::SharedGraphicsContext3D::useLoopBlinnForPathRendering):
     35        (WebCore::SharedGraphicsContext3D::useLoopBlinnInteriorProgram):
     36        (WebCore::SharedGraphicsContext3D::useLoopBlinnExteriorProgram):
     37        * platform/graphics/gpu/SharedGraphicsContext3D.h:
     38        * platform/graphics/skia/GraphicsContextSkia.cpp:
     39        (WebCore::GraphicsContext::fillPath):
     40
    1412011-02-16  Stephen White  <senorblanco@chromium.org>
    242
  • trunk/Source/WebCore/WebCore.gypi

    r78914 r78923  
    26872687            'platform/graphics/gpu/DrawingBuffer.cpp',
    26882688            'platform/graphics/gpu/DrawingBuffer.h',
     2689            'platform/graphics/gpu/LoopBlinnClassifier.cpp',
     2690            'platform/graphics/gpu/LoopBlinnClassifier.h',
     2691            'platform/graphics/gpu/LoopBlinnConstants.h',
     2692            'platform/graphics/gpu/LoopBlinnLocalTriangulator.cpp',
     2693            'platform/graphics/gpu/LoopBLinnLocalTriangulator.h',
     2694            'platform/graphics/gpu/LoopBlinnMathUtils.cpp',
     2695            'platform/graphics/gpu/LoopBlinnMathUtils.h',
     2696            'platform/graphics/gpu/LoopBlinnPathCache.cpp',
     2697            'platform/graphics/gpu/LoopBlinnPathCache.h',
     2698            'platform/graphics/gpu/LoopBlinnPathProcessor.cpp',
     2699            'platform/graphics/gpu/LoopBlinnPathProcessor.h',
     2700            'platform/graphics/gpu/LoopBlinnShader.cpp',
     2701            'platform/graphics/gpu/LoopBlinnShader.h',
     2702            'platform/graphics/gpu/LoopBlinnSolidFillShader.cpp',
     2703            'platform/graphics/gpu/LoopBlinnSolidFillShader.h',
     2704            'platform/graphics/gpu/LoopBlinnTextureCoords.cpp',
     2705            'platform/graphics/gpu/LoopBlinnTextureCoords.h',
    26892706            'platform/graphics/gpu/PODArena.h',
    26902707            'platform/graphics/gpu/PODInterval.h',
  • trunk/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp

    r78704 r78923  
    3939#include "internal_glu.h"
    4040#include "IntRect.h"
     41#include "LoopBlinnPathProcessor.h"
     42#include "LoopBlinnSolidFillShader.h"
    4143#include "Path.h"
    4244#include "PlatformString.h"
     
    171173    , m_drawingBuffer(drawingBuffer)
    172174    , m_state(0)
     175    , m_pathVertexBuffer(0)
    173176{
    174177    m_flipMatrix.translate(-1.0f, 1.0f);
     
    554557void GLES2Canvas::fillPath(const Path& path, const Color& color)
    555558{
    556     int count;
    557     unsigned vertexBuffer, indexBuffer;
    558     createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
    559     m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer);
    560     checkGLError("bindBuffer");
    561     m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer);
    562     checkGLError("bindBuffer");
    563 
    564     AffineTransform matrix(m_flipMatrix);
    565     matrix *= m_state->m_ctm;
    566 
    567     m_context->useFillSolidProgram(matrix, color);
    568     checkGLError("useFillSolidProgram");
    569 
    570     m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
    571     checkGLError("drawArrays");
    572 
    573     m_context->graphicsContext3D()->deleteBuffer(vertexBuffer);
    574     checkGLError("deleteBuffer");
    575 
    576     m_context->graphicsContext3D()->deleteBuffer(indexBuffer);
    577     checkGLError("deleteBuffer");
     559    if (SharedGraphicsContext3D::useLoopBlinnForPathRendering()) {
     560        bindFramebuffer();
     561        m_context->applyCompositeOperator(m_state->m_compositeOp);
     562
     563        m_pathCache.clear();
     564        LoopBlinnPathProcessor processor;
     565        processor.process(path, m_pathCache);
     566        if (!m_pathVertexBuffer)
     567            m_pathVertexBuffer = m_context->createBuffer();
     568        m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_pathVertexBuffer);
     569        int byteSizeOfVertices = 2 * m_pathCache.numberOfVertices() * sizeof(float);
     570        int byteSizeOfTexCoords = 3 * m_pathCache.numberOfVertices() * sizeof(float);
     571        int byteSizeOfInteriorVertices = 2 * m_pathCache.numberOfInteriorVertices() * sizeof(float);
     572        m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER,
     573                              byteSizeOfVertices + byteSizeOfTexCoords + byteSizeOfInteriorVertices,
     574                              GraphicsContext3D::STATIC_DRAW);
     575        m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, byteSizeOfVertices, m_pathCache.vertices());
     576        m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices, byteSizeOfTexCoords, m_pathCache.texcoords());
     577        m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices + byteSizeOfTexCoords, byteSizeOfInteriorVertices, m_pathCache.interiorVertices());
     578
     579        AffineTransform matrix(m_flipMatrix);
     580        matrix *= m_state->m_ctm;
     581
     582        // Draw the exterior
     583        m_context->useLoopBlinnExteriorProgram(0, byteSizeOfVertices, matrix, color);
     584        m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfVertices());
     585
     586        // Draw the interior
     587        m_context->useLoopBlinnInteriorProgram(byteSizeOfVertices + byteSizeOfTexCoords, matrix, color);
     588        m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfInteriorVertices());
     589    } else {
     590        int count;
     591        unsigned vertexBuffer, indexBuffer;
     592        createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
     593        m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer);
     594        checkGLError("bindBuffer");
     595        m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer);
     596        checkGLError("bindBuffer");
     597
     598        AffineTransform matrix(m_flipMatrix);
     599        matrix *= m_state->m_ctm;
     600
     601        m_context->useFillSolidProgram(matrix, color);
     602        checkGLError("useFillSolidProgram");
     603
     604        bindFramebuffer();
     605        m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
     606        checkGLError("drawArrays");
     607
     608        m_context->graphicsContext3D()->deleteBuffer(vertexBuffer);
     609        checkGLError("deleteBuffer");
     610
     611        m_context->graphicsContext3D()->deleteBuffer(indexBuffer);
     612        checkGLError("deleteBuffer");
     613    }
    578614}
    579615
  • trunk/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h

    r78704 r78923  
    3737#include "GraphicsTypes.h"
    3838#include "ImageSource.h"
     39#include "LoopBlinnPathCache.h"
    3940#include "Texture.h"
    4041
     
    115116    State* m_state;
    116117    AffineTransform m_flipMatrix;
     118
     119    // Members for GPU-accelerated path rendering.
     120    LoopBlinnPathCache m_pathCache;
     121    unsigned m_pathVertexBuffer;
    117122};
    118123
  • trunk/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h

    r76248 r78923  
    3131#define LoopBlinnClassifier_h
    3232
     33#include <wtf/Noncopyable.h>
    3334
    3435namespace WebCore {
  • trunk/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h

    r76248 r78923  
    3131#include "LoopBlinnConstants.h"
    3232#include <wtf/Assertions.h>
     33#include <wtf/Noncopyable.h>
    3334
    3435namespace WebCore {
  • trunk/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp

    r78625 r78923  
    4040#include "FloatRect.h"
    4141#include "IntSize.h"
     42#include "LoopBlinnSolidFillShader.h"
    4243#include "SolidFillShader.h"
    4344#include "TexShader.h"
     
    5455    attr.depth = false;
    5556    attr.stencil = true;
    56     attr.antialias = false;
     57    attr.antialias = useLoopBlinnForPathRendering();
    5758    attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts.
    5859    RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow);
     
    7475    , m_solidFillShader(solidFillShader)
    7576    , m_texShader(texShader)
     77    , m_oesStandardDerivativesSupported(false)
    7678{
    7779    allContexts()->add(this);
     
    8284        extensions->ensureEnabled("GL_EXT_read_format_bgra");
    8385    }
     86    m_oesStandardDerivativesSupported = extensions->supports("GL_OES_standard_derivatives");
     87    if (m_oesStandardDerivativesSupported)
     88        extensions->ensureEnabled("GL_OES_standard_derivatives");
    8489}
    8590
     
    140145{
    141146    m_context->flush();
     147}
     148
     149Platform3DObject SharedGraphicsContext3D::createBuffer()
     150{
     151    return m_context->createBuffer();
    142152}
    143153
     
    325335}
    326336
     337void SharedGraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
     338{
     339    m_context->bindBuffer(target, buffer);
     340}
     341
    327342void SharedGraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
    328343{
     
    330345}
    331346
     347void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
     348{
     349    m_context->bufferData(target, size, usage);
     350}
     351
     352void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
     353{
     354    m_context->bufferData(target, size, data, usage);
     355}
     356
     357void SharedGraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
     358{
     359    m_context->bufferSubData(target, offset, size, data);
     360}
     361
    332362void SharedGraphicsContext3D::useFillSolidProgram(const AffineTransform& transform, const Color& color)
    333363{
     
    355385}
    356386
     387bool SharedGraphicsContext3D::useLoopBlinnForPathRendering()
     388{
     389    return false;
     390}
     391
     392void SharedGraphicsContext3D::useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform& transform, const Color& color)
     393{
     394    if (!m_loopBlinnInteriorShader) {
     395        m_loopBlinnInteriorShader = LoopBlinnSolidFillShader::create(m_context.get(),
     396                                                                     LoopBlinnShader::Interior,
     397                                                                     Shader::NotAntialiased);
     398    }
     399    ASSERT(m_loopBlinnInteriorShader);
     400    m_loopBlinnInteriorShader->use(vertexOffset, 0, transform, color);
     401}
     402
     403void SharedGraphicsContext3D::useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform& transform, const Color& color)
     404{
     405    if (!m_loopBlinnExteriorShader) {
     406        m_loopBlinnExteriorShader = LoopBlinnSolidFillShader::create(m_context.get(),
     407                                                                     LoopBlinnShader::Exterior,
     408                                                                     m_oesStandardDerivativesSupported ? Shader::Antialiased : Shader::NotAntialiased);
     409    }
     410    ASSERT(m_loopBlinnExteriorShader);
     411    m_loopBlinnExteriorShader->use(vertexOffset, klmOffset, transform, color);
     412}
     413
    357414} // namespace WebCore
    358415
  • trunk/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h

    r78625 r78923  
    5050class HostWindow;
    5151class IntSize;
     52class LoopBlinnSolidFillShader;
    5253class SolidFillShader;
    5354class TexShader;
     
    6263    // Functions that delegate directly to GraphicsContext3D, with caching
    6364    void makeContextCurrent();
     65    void bindBuffer(GC3Denum target, Platform3DObject);
    6466    void bindFramebuffer(Platform3DObject framebuffer);
     67    void bufferData(GC3Denum target, GC3Dsizeiptr, GC3Denum usage);
     68    void bufferData(GC3Denum target, GC3Dsizeiptr, const void* data, GC3Denum usage);
     69    void bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr, const void* data);
    6570    void setViewport(const IntSize&);
    6671    void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
     
    7479    void flush();
    7580
     81    Platform3DObject createBuffer();
    7682    Platform3DObject createFramebuffer();
    7783    Platform3DObject createTexture();
     
    118124    GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
    119125
     126    // Members for GPU-accelerated path rendering.
     127    static bool useLoopBlinnForPathRendering();
     128    void useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform&, const Color&);
     129    void useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform&, const Color&);
     130
    120131private:
    121132    SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D>, PassOwnPtr<SolidFillShader>, PassOwnPtr<TexShader>);
     
    134145
    135146    TextureHashMap m_textures;
     147
     148    // Members for GPU-accelerated path rendering.
     149    // FIXME: support more kinds of fill types for paths.
     150    OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnInteriorShader;
     151    OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnExteriorShader;
     152    bool m_oesStandardDerivativesSupported;
    136153};
    137154
  • trunk/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp

    r78846 r78923  
    732732        return;
    733733
     734    // FIXME: add support to GLES2Canvas for more than just solid fills.
    734735    if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
    735736        platformContext()->prepareForHardwareDraw();
Note: See TracChangeset for help on using the changeset viewer.