Changeset 56074 in webkit


Ignore:
Timestamp:
Mar 16, 2010 11:53:34 AM (14 years ago)
Author:
kbr@google.com
Message:

2010-03-16 Zhenyao Mo <zmo@google.com>

Reviewed by Darin Fisher.

Hook up WebGLContextAttributes to OpenGL context creation code
https://bugs.webkit.org/show_bug.cgi?id=33416

Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html

  • src/GraphicsContext3D.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Windows.

2010-03-16 Zhenyao Mo <zmo@google.com>

Reviewed by Darin Fisher.

Hook up WebGLContextAttributes to OpenGL context creation code
https://bugs.webkit.org/show_bug.cgi?id=33416

Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html

  • bindings/v8/custom/V8HTMLCanvasElementCustom.cpp: Fix an index bug.
  • platform/graphics/GraphicsContext3D.h: Add members/functions for multisampling/stencil buffer purpose.
  • platform/graphics/mac/Canvas3DLayer.h: Add GraphicsContext3D as a member of Canvas3DLayer.
  • platform/graphics/mac/Canvas3DLayer.mm: Add multisampling support.
  • platform/graphics/mac/GraphicsContext3DMac.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Mac.
  • platform/graphics/mac/GraphicsLayerCA.mm: Adjust to modified Canvas3DLayer init call.

2010-03-16 Zhenyao Mo <zmo@google.com>

Reviewed by Darin Fisher.

Hook up WebGLContextAttributes to OpenGL context creation code
https://bugs.webkit.org/show_bug.cgi?id=33416

  • fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-expected.txt: Added.
  • fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html: Added.
  • fast/canvas/webgl/context-attributes-expected.txt: WebGL context attributes behavior changed with this fix.
  • fast/canvas/webgl/context-attributes.html: Ditto.
  • fast/canvas/webgl/gl-get-calls-expected.txt: Stencil buffer is enabled, thus Stencil Bits is no longer 0.
  • fast/canvas/webgl/gl-get-calls.html: Ditto.
Location:
trunk
Files:
2 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r56073 r56074  
     12010-03-16  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Darin Fisher.
     4
     5        Hook up WebGLContextAttributes to OpenGL context creation code
     6        https://bugs.webkit.org/show_bug.cgi?id=33416
     7
     8        * fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-expected.txt: Added.
     9        * fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html: Added.
     10        * fast/canvas/webgl/context-attributes-expected.txt: WebGL context attributes behavior changed with this fix.
     11        * fast/canvas/webgl/context-attributes.html: Ditto.
     12        * fast/canvas/webgl/gl-get-calls-expected.txt: Stencil buffer is enabled, thus Stencil Bits is no longer 0.
     13        * fast/canvas/webgl/gl-get-calls.html: Ditto.
     14
    1152010-03-16  Joanmarie Diggs  <joanmarie.diggs@gmail.com>
    216
  • trunk/LayoutTests/fast/canvas/webgl/context-attributes-expected.txt

    r53238 r56074  
    88PASS attribs.depth is true
    99PASS attribs.alpha is true
    10 PASS (attribs.stencil == true || attribs.stencil == false) is true
    11 PASS (attribs.antialias == true || attribs.antialias == false) is true
     10PASS attribs.stencil is true
     11PASS attribs.antialias is true
    1212PASS attribs.premultipliedAlpha is true
    1313Test customized values
     
    1919PASS attribs.antialias is false
    2020PASS attribs.premultipliedAlpha is true
     21Test customized values
     22PASS context = create3DContext({ depth: false, stencil: true }) is non-null.
     23PASS attribs = context.getContextAttributes() is non-null.
     24PASS attribs.depth is true
     25PASS attribs.alpha is true
     26PASS attribs.stencil is true
     27PASS attribs.antialias is true
     28PASS attribs.premultipliedAlpha is true
     29Test customized values
     30PASS context = create3DContext({ premultipliedAlpha: false }) is non-null.
     31PASS attribs = context.getContextAttributes() is non-null.
     32PASS attribs.depth is true
     33PASS attribs.alpha is true
     34PASS attribs.stencil is true
     35PASS attribs.antialias is true
     36PASS attribs.premultipliedAlpha is true
    2137PASS successfullyParsed is true
    2238
  • trunk/LayoutTests/fast/canvas/webgl/context-attributes.html

    r53238 r56074  
    1919shouldBe("attribs.depth", "true");
    2020shouldBe("attribs.alpha", "true");
    21 // The following two depend on whether the implementation actually supports them
    22 shouldBe("(attribs.stencil == true || attribs.stencil == false)", "true");
    23 shouldBe("(attribs.antialias == true || attribs.antialias == false)", "true");
     21shouldBe("attribs.stencil", "true");
     22shouldBe("attribs.antialias", "true");
    2423shouldBe("attribs.premultipliedAlpha", "true");
    2524
     
    3332shouldBe("attribs.premultipliedAlpha", "true");
    3433
     34debug("Test customized values");
     35// (stencil == true && depth == false) is not supported, default depth to true
     36shouldBeNonNull("context = create3DContext({ depth: false, stencil: true })");
     37shouldBeNonNull("attribs = context.getContextAttributes()");
     38shouldBe("attribs.depth", "true");
     39shouldBe("attribs.alpha", "true");
     40shouldBe("attribs.stencil", "true");
     41shouldBe("attribs.antialias", "true");
     42shouldBe("attribs.premultipliedAlpha", "true");
     43
     44debug("Test customized values");
     45// (premultipliedAlpha == false) is not supported, default to true
     46shouldBeNonNull("context = create3DContext({ premultipliedAlpha: false })");
     47shouldBeNonNull("attribs = context.getContextAttributes()");
     48shouldBe("attribs.depth", "true");
     49shouldBe("attribs.alpha", "true");
     50shouldBe("attribs.stencil", "true");
     51shouldBe("attribs.antialias", "true");
     52shouldBe("attribs.premultipliedAlpha", "true");
     53
    3554successfullyParsed = true;
    3655</script>
  • trunk/LayoutTests/fast/canvas/webgl/gl-get-calls-expected.txt

    r55282 r56074  
    5454PASS context.getParameter(context.STENCIL_BACK_PASS_DEPTH_PASS) is context.KEEP
    5555PASS context.getParameter(context.STENCIL_BACK_REF) is 0
    56 PASS context.getParameter(context.STENCIL_BITS) is 0
     56PASS context.getParameter(context.STENCIL_BITS) > 0 is true
    5757PASS context.getParameter(context.STENCIL_CLEAR_VALUE) is 0
    5858PASS context.getParameter(context.STENCIL_FAIL) is context.KEEP
  • trunk/LayoutTests/fast/canvas/webgl/gl-get-calls.html

    r55282 r56074  
    8383    //shouldBe('context.getParameter(context.STENCIL_BACK_VALUE_MASK)', '0xFFFFFFFF');
    8484    //shouldBe('context.getParameter(context.STENCIL_BACK_WRITEMASK)', '0xFFFFFFFF');
    85     shouldBe('context.getParameter(context.STENCIL_BITS)', '0');
     85    shouldBe('context.getParameter(context.STENCIL_BITS) > 0', 'true');
    8686    shouldBe('context.getParameter(context.STENCIL_CLEAR_VALUE)', '0');
    8787    shouldBe('context.getParameter(context.STENCIL_FAIL)', 'context.KEEP');
  • trunk/WebCore/ChangeLog

    r56073 r56074  
     12010-03-16  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Darin Fisher.
     4
     5        Hook up WebGLContextAttributes to OpenGL context creation code
     6        https://bugs.webkit.org/show_bug.cgi?id=33416
     7
     8        Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
     9
     10        * bindings/v8/custom/V8HTMLCanvasElementCustom.cpp: Fix an index bug.
     11        * platform/graphics/GraphicsContext3D.h: Add members/functions for multisampling/stencil buffer purpose.
     12        * platform/graphics/mac/Canvas3DLayer.h: Add GraphicsContext3D as a member of Canvas3DLayer.
     13        * platform/graphics/mac/Canvas3DLayer.mm: Add multisampling support.
     14        * platform/graphics/mac/GraphicsContext3DMac.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Mac.
     15        * platform/graphics/mac/GraphicsLayerCA.mm: Adjust to modified Canvas3DLayer init call.
     16
    1172010-03-16  Joanmarie Diggs  <joanmarie.diggs@gmail.com>
    218
  • trunk/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp

    r55854 r56074  
    5757        attrs = WebGLContextAttributes::create();
    5858        WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get());
    59         if (args.Length() > 1 && args[0]->IsObject()) {
     59        if (args.Length() > 1 && args[1]->IsObject()) {
    6060            v8::Handle<v8::Object> jsAttrs = args[1]->ToObject();
    6161            v8::Handle<v8::String> alpha = v8::String::New("alpha");
  • trunk/WebCore/platform/graphics/GraphicsContext3D.h

    r55283 r56074  
    426426#endif
    427427        void makeContextCurrent();
    428        
     428
     429#if PLATFORM(MAC)
     430        // With multisampling on, blit from multisampleFBO to regular FBO.
     431        void prepareTexture();
     432#endif
     433
    429434        // Helper to return the size in bytes of OpenGL data types
    430435        // like GL_FLOAT, GL_INT, etc.
     
    718723        GLuint m_texture;
    719724        GLuint m_fbo;
    720         GLuint m_depthBuffer;
     725        GLuint m_depthStencilBuffer;
     726
     727        // For tracking which FBO is bound
     728        GLuint m_boundFBO;
     729
     730        // For multisampling
     731        GLuint m_multisampleFBO;
     732        GLuint m_multisampleDepthStencilBuffer;
     733        GLuint m_multisampleColorBuffer;
     734
    721735        // Errors raised by synthesizeGLError().
    722736        ListHashSet<unsigned long> m_syntheticErrors;
  • trunk/WebCore/platform/graphics/mac/Canvas3DLayer.h

    r50067 r56074  
    3333namespace WebCore {
    3434    class GraphicsLayer;
     35    class GraphicsContext3D;
    3536}
    3637
     
    3839{
    3940    WebCore::GraphicsLayer* m_layerOwner;
     41    WebCore::GraphicsContext3D* m_context;
    4042    CGLContextObj m_contextObj;
    4143    GLuint m_texture;
    4244}
    4345
    44 - (id)initWithContext:(CGLContextObj)context texture:(GLuint)texture;
     46- (id)initWithContext:(WebCore::GraphicsContext3D*)context;
    4547
    4648- (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
  • trunk/WebCore/platform/graphics/mac/Canvas3DLayer.mm

    r53510 r56074  
    4242@implementation Canvas3DLayer
    4343
    44 -(id)initWithContext:(CGLContextObj)context texture:(GLuint)texture
     44-(id)initWithContext:(GraphicsContext3D*)context
    4545{
    46     m_contextObj = context;
    47     m_texture = texture;
     46    m_context = context;
     47    m_contextObj = static_cast<CGLContextObj>(context->platformGraphicsContext3D());
     48    m_texture = static_cast<GLuint>(context->platformTexture());
    4849    self = [super init];
    4950    return self;
     
    7172-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
    7273{
    73     CGLSetCurrentContext(m_contextObj);
    74     glFinish();
     74    m_context->prepareTexture();
     75
    7576    CGLSetCurrentContext(glContext);
    7677
  • trunk/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp

    r54907 r56074  
    8787    , m_texture(0)
    8888    , m_fbo(0)
    89     , m_depthBuffer(0)
    90 {
    91     // FIXME: we need to take into account the user's requested
    92     // context creation attributes, in particular stencil and
    93     // antialias, and determine which could and could not be honored
    94     // based on the capabilities of the OpenGL implementation.
    95     m_attrs.alpha = true;
    96     m_attrs.depth = true;
    97     m_attrs.stencil = false;
    98     m_attrs.antialias = false;
     89    , m_depthStencilBuffer(0)
     90    , m_boundFBO(0)
     91    , m_multisampleFBO(0)
     92    , m_multisampleDepthStencilBuffer(0)
     93    , m_multisampleColorBuffer(0)
     94{
     95    // Take into account the user's requested context creation attributes, in
     96    // particular stencil and antialias, and determine which could and could
     97    // not be honored based on the capabilities of the OpenGL implementation.
     98    if (m_attrs.stencil && !m_attrs.depth)
     99        m_attrs.depth = true;
     100    // FIXME: instead of enforcing premultipliedAlpha = true, implement the
     101    // correct behavior when premultipliedAlpha = false is requested.
    99102    m_attrs.premultipliedAlpha = true;
    100103
     
    153156    ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    154157    ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    155     ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    156158    ::glBindTexture(GL_TEXTURE_2D, 0);
    157    
     159
    158160    // create an FBO
    159161    ::glGenFramebuffersEXT(1, &m_fbo);
    160162    ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    161    
    162     ::glGenRenderbuffersEXT(1, &m_depthBuffer);
    163     ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
    164     ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 1, 1);
    165     ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    166    
    167     ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
    168     ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
    169    
     163    m_boundFBO = m_fbo;
     164    if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
     165        ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
     166
     167    // create an multisample FBO
     168    if (m_attrs.antialias) {
     169        ::glGenFramebuffersEXT(1, &m_multisampleFBO);
     170        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     171        m_boundFBO = m_multisampleFBO;
     172        ::glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
     173        if (m_attrs.stencil || m_attrs.depth)
     174            ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     175    }
     176
    170177    ::glClearColor(0, 0, 0, 0);
    171178}
     
    175182    if (m_contextObj) {
    176183        CGLSetCurrentContext(m_contextObj);
    177         ::glDeleteRenderbuffersEXT(1, & m_depthBuffer);
    178184        ::glDeleteTextures(1, &m_texture);
     185        if (m_attrs.antialias) {
     186            ::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
     187            if (m_attrs.stencil || m_attrs.depth)
     188                ::glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     189            ::glDeleteFramebuffersEXT(1, &m_multisampleFBO);
     190        } else {
     191            if (m_attrs.stencil || m_attrs.depth)
     192                ::glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
     193        }
    179194        ::glDeleteFramebuffersEXT(1, &m_fbo);
    180195        CGLSetCurrentContext(0);
     
    206221   
    207222    CGLSetCurrentContext(m_contextObj);
    208    
     223
     224    GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
     225    if (m_attrs.alpha) {
     226        internalColorFormat = GL_RGBA8;
     227        colorFormat = GL_RGBA;
     228    } else {
     229        internalColorFormat = GL_RGB8;
     230        colorFormat = GL_RGB;
     231    }
     232    if (m_attrs.stencil || m_attrs.depth) {
     233        // We don't allow the logic where stencil is required and depth is not.
     234        // See GraphicsContext3D constructor.
     235        if (m_attrs.stencil && m_attrs.depth)
     236            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
     237        else
     238            internalDepthStencilFormat = GL_DEPTH_COMPONENT;
     239    }
     240
     241    bool mustRestoreFBO = false;
     242
     243    // resize multisample FBO
     244    if (m_attrs.antialias) {
     245        GLint maxSampleCount;
     246        ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
     247        GLint sampleCount = std::min(8, maxSampleCount);
     248        if (sampleCount > maxSampleCount)
     249            sampleCount = maxSampleCount;
     250        if (m_boundFBO != m_multisampleFBO) {
     251            ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     252            mustRestoreFBO = true;
     253        }
     254        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     255        ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
     256        ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     257        if (m_attrs.stencil || m_attrs.depth) {
     258            ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     259            ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
     260            if (m_attrs.stencil)
     261                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     262            if (m_attrs.depth)
     263                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     264        }
     265        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     266        if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
     267            // FIXME: cleanup.
     268            notImplemented();
     269        }
     270    }
     271
     272    // resize regular FBO
     273    if (m_boundFBO != m_fbo) {
     274        mustRestoreFBO = true;
     275        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     276    }
    209277    ::glBindTexture(GL_TEXTURE_2D, m_texture);
    210     ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
     278    ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
     279    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
    211280    ::glBindTexture(GL_TEXTURE_2D, 0);
    212    
    213     ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    214     ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
    215     ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
    216     ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    217    
    218     ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
    219     ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
    220     GLenum status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    221     if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
    222         // FIXME: cleanup
     281    if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
     282        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     283        ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
     284        if (m_attrs.stencil)
     285            ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     286        if (m_attrs.depth)
     287            ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     288        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     289    }
     290    if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
     291        // FIXME: cleanup.
    223292        notImplemented();
    224293    }
    225294
    226     ::glClear(GL_COLOR_BUFFER_BIT);
     295    if (mustRestoreFBO)
     296        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     297
     298    GLenum clearMask = GL_COLOR_BUFFER_BIT;
     299    if (m_attrs.depth)
     300        clearMask |= GL_DEPTH_BUFFER_BIT;
     301    if (m_attrs.stencil)
     302        clearMask |= GL_STENCIL_BUFFER_BIT;
     303    ::glClear(clearMask);
    227304    ::glFlush();
    228305}
     
    244321}
    245322
     323void GraphicsContext3D::prepareTexture()
     324{
     325    if (m_attrs.antialias) {
     326        ensureContext(m_contextObj);
     327        ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     328        ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     329        ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     330        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     331        ::glFinish();
     332    }
     333}
     334
    246335void GraphicsContext3D::attachShader(WebGLProgram* program, WebGLShader* shader)
    247336{
     
    269358{
    270359    ensureContext(m_contextObj);
    271     ::glBindFramebufferEXT(target, (buffer && buffer->object()) ? (GLuint) buffer->object() : m_fbo);
     360    GLuint fbo;
     361    if (buffer && buffer->object())
     362        fbo = (GLuint)buffer->object();
     363    else
     364        fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
     365    if (fbo != m_boundFBO) {
     366        ::glBindFramebufferEXT(target, fbo);
     367        m_boundFBO = fbo;
     368    }
    272369}
    273370
     
    676773    if (type != GL_UNSIGNED_BYTE || format != GL_RGBA)
    677774        return 0;
    678        
     775
     776    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
     777        ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     778        ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     779        ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     780        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     781    }
    679782    RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);
    680783    ::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data());
     784    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
     785        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     786    if (!m_attrs.alpha) {
     787        // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.
     788        // This is a hack until ::glReadPixels fixes its behavior.
     789        GLubyte* data = reinterpret_cast<GLubyte*>(array->data());
     790        unsigned byteLength = array->byteLength();
     791        for (unsigned i = 3; i < byteLength; i += 4)
     792            data[i] = 255;
     793    }
    681794    return array;   
    682795}
  • trunk/WebCore/platform/graphics/mac/GraphicsLayerCA.mm

    r55601 r56074  
    17171717    if (m_platformGraphicsContext3D != NullPlatformGraphicsContext3D && m_platformTexture != NullPlatform3DObject) {
    17181718        // create the inner 3d layer
    1719         m_contentsLayer.adoptNS([[Canvas3DLayer alloc] initWithContext:static_cast<CGLContextObj>(m_platformGraphicsContext3D) texture:static_cast<GLuint>(m_platformTexture)]);
     1719        m_contentsLayer.adoptNS([[Canvas3DLayer alloc] initWithContext:const_cast<GraphicsContext3D*>(graphicsContext3D)]);
    17201720#ifndef NDEBUG
    17211721        [m_contentsLayer.get() setName:@"3D Layer"];
  • trunk/WebKit/chromium/ChangeLog

    r56070 r56074  
     12010-03-16  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Darin Fisher.
     4
     5        Hook up WebGLContextAttributes to OpenGL context creation code
     6        https://bugs.webkit.org/show_bug.cgi?id=33416
     7
     8        Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
     9
     10        * src/GraphicsContext3D.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Windows.
     11
    1122010-03-16  Yury Semikhatsky  <yurys@chromium.org>
    213
  • trunk/WebKit/chromium/src/GraphicsContext3D.cpp

    r54907 r56074  
    125125    void viewportImpl(long x, long y, unsigned long width, unsigned long height);
    126126
     127    void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* buffer);
     128
    127129    void synthesizeGLError(unsigned long error);
    128130
    129131private:
    130132    GraphicsContext3D::Attributes m_attrs;
    131 
     133   
    132134    unsigned int m_texture;
    133135    unsigned int m_fbo;
    134     unsigned int m_depthBuffer;
     136    unsigned int m_depthStencilBuffer;
    135137    unsigned int m_cachedWidth, m_cachedHeight;
     138
     139    // For multisampling
     140    unsigned int m_multisampleFBO;
     141    unsigned int m_multisampleDepthStencilBuffer;
     142    unsigned int m_multisampleColorBuffer;
    136143
    137144    // For tracking which FBO is bound
     
    352359    , m_texture(0)
    353360    , m_fbo(0)
    354     , m_depthBuffer(0)
     361    , m_depthStencilBuffer(0)
     362    , m_multisampleFBO(0)
     363    , m_multisampleDepthStencilBuffer(0)
     364    , m_multisampleColorBuffer(0)
    355365    , m_boundFBO(0)
    356366#ifdef FLIP_FRAMEBUFFER_VERTICALLY
     
    376386#endif
    377387{
    378     // FIXME: we need to take into account the user's requested
    379     // context creation attributes, in particular stencil and
    380     // antialias, and determine which could and could not be honored
    381     // based on the capabilities of the OpenGL implementation.
    382     m_attrs.alpha = true;
    383     m_attrs.depth = true;
    384     m_attrs.stencil = false;
    385     m_attrs.antialias = false;
     388    // Take into account the user's requested context creation attributes, in
     389    // particular stencil and antialias, and determine which could and could
     390    // not be honored based on the capabilities of the OpenGL implementation.
     391    if (m_attrs.stencil) {
     392        if (GLEW_EXT_packed_depth_stencil) {
     393            if (!m_attrs.depth)
     394                m_attrs.depth = true;
     395        } else {
     396            m_attrs.stencil = false;
     397        }
     398    }
     399    if (m_attrs.antialias && !GLEW_EXT_framebuffer_multisample)
     400        m_attrs.antialias = false;
     401    // FIXME: instead of enforcing premultipliedAlpha = true, implement the
     402    // correct behavior when premultipliedAlpha = false is requested.
    386403    m_attrs.premultipliedAlpha = true;
    387404
     
    573590    makeContextCurrent();
    574591#ifndef RENDER_TO_DEBUGGING_WINDOW
    575     glDeleteRenderbuffersEXT(1, &m_depthBuffer);
     592    if (m_attrs.antialias) {
     593        glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
     594        if (m_attrs.depth || m_attrs.stencil)
     595            glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     596        glDeleteFramebuffersEXT(1, &m_multisampleFBO);
     597    } else {
     598        if (m_attrs.depth || m_attrs.stencil)
     599            glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
     600    }
    576601    glDeleteTextures(1, &m_texture);
    577602#ifdef FLIP_FRAMEBUFFER_VERTICALLY
     
    670695        // Generate the framebuffer object
    671696        glGenFramebuffersEXT(1, &m_fbo);
    672         // Generate the depth buffer
    673         glGenRenderbuffersEXT(1, &m_depthBuffer);
    674     }
    675 
    676     // Reallocate the color and depth buffers
     697        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     698        m_boundFBO = m_fbo;
     699        if (m_attrs.depth || m_attrs.stencil)
     700            glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
     701        // Generate the multisample framebuffer object
     702        if (m_attrs.antialias) {
     703            glGenFramebuffersEXT(1, &m_multisampleFBO);
     704            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     705            m_boundFBO = m_multisampleFBO;
     706            glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
     707            if (m_attrs.depth || m_attrs.stencil)
     708                glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     709        }
     710    }
     711
     712    GLint internalColorFormat, colorFormat, internalDepthStencilFormat;
     713    if (m_attrs.alpha) {
     714        internalColorFormat = GL_RGBA8;
     715        colorFormat = GL_RGBA;
     716    } else {
     717        internalColorFormat = GL_RGB8;
     718        colorFormat = GL_RGB;
     719    }
     720    if (m_attrs.stencil || m_attrs.depth) {
     721        // We don't allow the logic where stencil is required and depth is not.
     722        // See GraphicsContext3DInternal constructor.
     723        if (m_attrs.stencil && m_attrs.depth)
     724            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
     725        else
     726            internalDepthStencilFormat = GL_DEPTH_COMPONENT;
     727    }
     728
     729    bool mustRestoreFBO = false;
     730
     731    // Resize multisampling FBO
     732    if (m_attrs.antialias) {
     733        GLint maxSampleCount;
     734        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
     735        GLint sampleCount = std::min(8, maxSampleCount);
     736        if (m_boundFBO != m_multisampleFBO) {
     737            mustRestoreFBO = true;
     738            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     739        }
     740        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     741        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
     742        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     743        if (m_attrs.stencil || m_attrs.depth) {
     744            glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     745            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
     746            if (m_attrs.stencil)
     747                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     748            if (m_attrs.depth)
     749                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     750        }
     751        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     752        GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
     753        if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
     754            printf("GraphicsContext3D: multisampling framebuffer was incomplete\n");
     755
     756            // FIXME: cleanup.
     757            notImplemented();
     758        }
     759    }
     760
     761    // Resize regular FBO
     762    if (m_boundFBO != m_fbo) {
     763        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     764        mustRestoreFBO = true;
     765    }
    677766    glBindTexture(target, m_texture);
    678     glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
     767    glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
     768    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
    679769    glBindTexture(target, 0);
    680 
    681     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    682     m_boundFBO = m_fbo;
    683     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
    684     glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
    685     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    686 
    687     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
    688     glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
     770    if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
     771        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     772        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
     773        if (m_attrs.stencil)
     774            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     775        if (m_attrs.depth)
     776            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     777        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     778    }
    689779    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    690780    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
     
    694784        notImplemented();
    695785    }
     786
     787    if (mustRestoreFBO)
     788        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
    696789#endif  // RENDER_TO_DEBUGGING_WINDOW
    697790
     
    704797#endif  // FLIP_FRAMEBUFFER_VERTICALLY
    705798
    706     glClear(GL_COLOR_BUFFER_BIT);
     799    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
     800    if (m_attrs.stencil)
     801        clearMask |= GL_STENCIL_BUFFER_BIT;
     802    if (m_attrs.depth)
     803        clearMask |= GL_DEPTH_BUFFER_BIT;
     804    glClear(clearMask);
    707805
    708806#if PLATFORM(CG)
     
    759857    ImageBuffer* imageBuffer = canvas->buffer();
    760858    unsigned char* pixels = 0;
    761     bool mustRestoreFBO = (m_boundFBO != m_fbo);
    762     if (mustRestoreFBO)
     859    bool mustRestoreFBO;
     860    if (m_attrs.antialias) {
     861        glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     862        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     863        glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    763864        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     865        mustRestoreFBO = true;
     866    } else {
     867        if (m_boundFBO != m_fbo) {
     868            mustRestoreFBO = true;
     869            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     870        }
     871    }
    764872#if PLATFORM(SKIA)
    765873    const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap();
     
    866974}
    867975
     976void GraphicsContext3DInternal::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* buffer)
     977{
     978#ifndef RENDER_TO_DEBUGGING_WINDOW
     979    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
     980        glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     981        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     982        glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     983        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     984    }
     985#endif
     986    glReadPixels(x, y, width, height, format, type, buffer);
     987#ifndef RENDER_TO_DEBUGGING_WINDOW
     988    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
     989        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     990#endif
     991}
     992
    868993void GraphicsContext3DInternal::activeTexture(unsigned long texture)
    869994{
     
    8931018    GLuint id = EXTRACT(framebuffer);
    8941019    if (!id)
    895         id = m_fbo;
    896     glBindFramebufferEXT(target, id);
    897     m_boundFBO = id;
     1020        id = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
     1021    if (id != m_boundFBO) {
     1022        glBindFramebufferEXT(target, id);
     1023        m_boundFBO = id;
     1024    }
    8981025}
    8991026
     
    18101937    // FIXME: take into account pack alignment.
    18111938    RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);
    1812     glReadPixels(x, y, width, height, format, type, array->baseAddress());
     1939    m_internal->readPixels(x, y, width, height, format, type, array->baseAddress());
     1940#if OS(DARWIN)
     1941    GraphicsContext3D::Attributes attrs = m_internal->getContextAttributes();
     1942    if (!attrs.alpha) {
     1943        // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.
     1944        // This is a hack until ::glReadPixels fixes its behavior.
     1945        GLubyte* data = reinterpret_cast<GLubyte*>(array->baseAddress());
     1946        unsigned byteLength = array->byteLength();
     1947        for (unsigned i = 3; i < byteLength; i += 4)
     1948            data[i] = 255;
     1949    }
     1950#endif
    18131951    return array;
    18141952}
Note: See TracChangeset for help on using the changeset viewer.