Changeset 56872 in webkit


Ignore:
Timestamp:
Mar 31, 2010 3:15:03 PM (14 years ago)
Author:
eric@webkit.org
Message:

2010-03-31 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.

2010-03-31 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. (WebCore::V8HTMLCanvasElement::getContextCallback):
  • 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. (-[Canvas3DLayer drawInCGLContext:pixelFormat:forLayerTime:displayTime:]):
  • platform/graphics/mac/GraphicsContext3DMac.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Mac. (WebCore::GraphicsContext3D::GraphicsContext3D): (WebCore::GraphicsContext3D::~GraphicsContext3D): (WebCore::GraphicsContext3D::validateAttributes): (WebCore::GraphicsContext3D::reshape): (WebCore::GraphicsContext3D::prepareTexture): (WebCore::GraphicsContext3D::bindFramebuffer): (WebCore::GraphicsContext3D::readPixels):
  • platform/graphics/mac/GraphicsLayerCA.mm: Adjust to modified Canvas3DLayer init call. (WebCore::GraphicsLayerCA::setContentsToGraphicsContext3D):

2010-03-31 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

  • src/WebGraphicsContext3DDefaultImpl.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Chrome. (WebKit::WebGraphicsContext3DDefaultImpl::WebGraphicsContext3DDefaultImpl): (WebKit::WebGraphicsContext3DDefaultImpl::~WebGraphicsContext3DDefaultImpl): (WebKit::WebGraphicsContext3DDefaultImpl::initialize): (WebKit::WebGraphicsContext3DDefaultImpl::validateAttributes): (WebKit::WebGraphicsContext3DDefaultImpl::reshape): (WebKit::WebGraphicsContext3DDefaultImpl::readBackFramebuffer): (WebKit::WebGraphicsContext3DDefaultImpl::bindFramebuffer): (WebKit::WebGraphicsContext3DDefaultImpl::readPixels): Deal with wrong returned alpha values in Mac.
  • src/WebGraphicsContext3DDefaultImpl.h: Add a function.
Location:
trunk
Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r56865 r56872  
     12010-03-31  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-31  Qi Zhang  <qi.2.zhang@nokia.com>
    216
  • trunk/LayoutTests/fast/canvas/webgl/context-attributes-expected.txt

    r56127 r56872  
    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 == true || attribs.antialias == false 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, antialias: false }) 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 false
     28PASS attribs.premultipliedAlpha is true
     29Test customized values
     30PASS context = create3DContext({ premultipliedAlpha: false, antialias: 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 false
     36PASS attribs.premultipliedAlpha is true
    2137PASS successfullyParsed is true
    2238
  • trunk/LayoutTests/fast/canvas/webgl/context-attributes.html

    r56127 r56872  
    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");
     22// Antialias is requested by default, but might or might not be supported.
     23shouldBe("attribs.antialias == true || attribs.antialias == false", "true");
    2424shouldBe("attribs.premultipliedAlpha", "true");
    2525
     
    3333shouldBe("attribs.premultipliedAlpha", "true");
    3434
     35debug("Test customized values");
     36// (stencil == true && depth == false) is not supported, default depth to true
     37shouldBeNonNull("context = create3DContext({ depth: false, stencil: true, antialias: false })");
     38shouldBeNonNull("attribs = context.getContextAttributes()");
     39shouldBe("attribs.depth", "true");
     40shouldBe("attribs.alpha", "true");
     41shouldBe("attribs.stencil", "true");
     42shouldBe("attribs.antialias", "false");
     43shouldBe("attribs.premultipliedAlpha", "true");
     44
     45debug("Test customized values");
     46// (premultipliedAlpha == false) is not supported, default to true
     47shouldBeNonNull("context = create3DContext({ premultipliedAlpha: false, antialias: false })");
     48shouldBeNonNull("attribs = context.getContextAttributes()");
     49shouldBe("attribs.depth", "true");
     50shouldBe("attribs.alpha", "true");
     51shouldBe("attribs.stencil", "true");
     52shouldBe("attribs.antialias", "false");
     53shouldBe("attribs.premultipliedAlpha", "true");
     54
    3555successfullyParsed = true;
    3656</script>
  • trunk/LayoutTests/fast/canvas/webgl/gl-get-calls-expected.txt

    r56127 r56872  
    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

    r56127 r56872  
    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

    r56869 r56872  
     12010-03-31  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        (WebCore::V8HTMLCanvasElement::getContextCallback):
     12        * platform/graphics/GraphicsContext3D.h: Add members/functions for multisampling/stencil buffer purpose.
     13        * platform/graphics/mac/Canvas3DLayer.h: Add GraphicsContext3D as a member of Canvas3DLayer.
     14        * platform/graphics/mac/Canvas3DLayer.mm: Add multisampling support.
     15        (-[Canvas3DLayer drawInCGLContext:pixelFormat:forLayerTime:displayTime:]):
     16        * platform/graphics/mac/GraphicsContext3DMac.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Mac.
     17        (WebCore::GraphicsContext3D::GraphicsContext3D):
     18        (WebCore::GraphicsContext3D::~GraphicsContext3D):
     19        (WebCore::GraphicsContext3D::validateAttributes):
     20        (WebCore::GraphicsContext3D::reshape):
     21        (WebCore::GraphicsContext3D::prepareTexture):
     22        (WebCore::GraphicsContext3D::bindFramebuffer):
     23        (WebCore::GraphicsContext3D::readPixels):
     24        * platform/graphics/mac/GraphicsLayerCA.mm: Adjust to modified Canvas3DLayer init call.
     25        (WebCore::GraphicsLayerCA::setContentsToGraphicsContext3D):
     26
    1272010-03-31  Jian Li  <jianli@chromium.org>
    228
  • trunk/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp

    r56127 r56872  
    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

    r56127 r56872  
    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.
     
    709714                          unsigned int* format);
    710715
     716#if PLATFORM(MAC)
     717        // Take into account the user's requested context creation attributes,
     718        // in particular stencil and antialias, and determine which could or
     719        // could not be honored based on the capabilities of the OpenGL
     720        // implementation.
     721        void validateAttributes();
     722#endif
     723
    711724        int m_currentWidth, m_currentHeight;
    712725       
     
    718731        GLuint m_texture;
    719732        GLuint m_fbo;
    720         GLuint m_depthBuffer;
     733        GLuint m_depthStencilBuffer;
     734
     735        // For tracking which FBO is bound
     736        GLuint m_boundFBO;
     737
     738        // For multisampling
     739        GLuint m_multisampleFBO;
     740        GLuint m_multisampleDepthStencilBuffer;
     741        GLuint m_multisampleColorBuffer;
     742
    721743        // Errors raised by synthesizeGLError().
    722744        ListHashSet<unsigned long> m_syntheticErrors;
  • trunk/WebCore/platform/graphics/mac/Canvas3DLayer.h

    r56127 r56872  
    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

    r56127 r56872  
    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

    r56825 r56872  
    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;
    99     m_attrs.premultipliedAlpha = true;
    100 
     89    , m_depthStencilBuffer(0)
     90    , m_boundFBO(0)
     91    , m_multisampleFBO(0)
     92    , m_multisampleDepthStencilBuffer(0)
     93    , m_multisampleColorBuffer(0)
     94{
    10195    Vector<CGLPixelFormatAttribute> attribs;
    10296    CGLPixelFormatObj pixelFormatObj = 0;
     
    146140    CGLSetCurrentContext(m_contextObj);
    147141   
     142    validateAttributes();
     143
    148144    // create a texture to render into
    149145    ::glGenTextures(1, &m_texture);
     
    153149    ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    154150    ::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);
    156151    ::glBindTexture(GL_TEXTURE_2D, 0);
    157152   
     
    160155    ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    161156   
    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);
     157    m_boundFBO = m_fbo;
     158    if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
     159        ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
     160
     161    // create an multisample FBO
     162    if (m_attrs.antialias) {
     163        ::glGenFramebuffersEXT(1, &m_multisampleFBO);
     164        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     165        m_boundFBO = m_multisampleFBO;
     166        ::glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
     167        if (m_attrs.stencil || m_attrs.depth)
     168            ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     169    }
    169170   
    170171    ::glClearColor(0, 0, 0, 0);
     
    175176    if (m_contextObj) {
    176177        CGLSetCurrentContext(m_contextObj);
    177         ::glDeleteRenderbuffersEXT(1, & m_depthBuffer);
    178178        ::glDeleteTextures(1, &m_texture);
     179        if (m_attrs.antialias) {
     180            ::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
     181            if (m_attrs.stencil || m_attrs.depth)
     182                ::glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     183            ::glDeleteFramebuffersEXT(1, &m_multisampleFBO);
     184        } else {
     185            if (m_attrs.stencil || m_attrs.depth)
     186                ::glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
     187        }
    179188        ::glDeleteFramebuffersEXT(1, &m_fbo);
    180189        CGLSetCurrentContext(0);
     
    183192}
    184193
     194void GraphicsContext3D::validateAttributes()
     195{
     196    const char* extensions = reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS));
     197    if (m_attrs.stencil) {
     198        if (std::strstr(extensions, "GL_EXT_packed_depth_stencil")) {
     199            if (!m_attrs.depth)
     200                m_attrs.depth = true;
     201        } else
     202            m_attrs.stencil = false;
     203    }
     204    if (m_attrs.antialias) {
     205        bool isValidVendor = true;
     206        // Currently in Mac we only turn on antialias if vendor is NVIDIA.
     207        const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
     208        if (!std::strstr(vendor, "NVIDIA"))
     209            isValidVendor = false;
     210        if (!isValidVendor || !std::strstr(extensions, "GL_EXT_framebuffer_multisample"))
     211            m_attrs.antialias = false;
     212    }
     213    // FIXME: instead of enforcing premultipliedAlpha = true, implement the
     214    // correct behavior when premultipliedAlpha = false is requested.
     215    m_attrs.premultipliedAlpha = true;
     216}
     217
    185218void GraphicsContext3D::makeContextCurrent()
    186219{
     
    207240    CGLSetCurrentContext(m_contextObj);
    208241   
     242    GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
     243    if (m_attrs.alpha) {
     244        internalColorFormat = GL_RGBA8;
     245        colorFormat = GL_RGBA;
     246    } else {
     247        internalColorFormat = GL_RGB8;
     248        colorFormat = GL_RGB;
     249    }
     250    if (m_attrs.stencil || m_attrs.depth) {
     251        // We don't allow the logic where stencil is required and depth is not.
     252        // See GraphicsContext3D constructor.
     253        if (m_attrs.stencil && m_attrs.depth)
     254            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
     255        else
     256            internalDepthStencilFormat = GL_DEPTH_COMPONENT;
     257    }
     258
     259    bool mustRestoreFBO = false;
     260
     261    // resize multisample FBO
     262    if (m_attrs.antialias) {
     263        GLint maxSampleCount;
     264        ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
     265        GLint sampleCount = std::min(8, maxSampleCount);
     266        if (sampleCount > maxSampleCount)
     267            sampleCount = maxSampleCount;
     268        if (m_boundFBO != m_multisampleFBO) {
     269            ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     270            mustRestoreFBO = true;
     271        }
     272        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     273        ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
     274        ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     275        if (m_attrs.stencil || m_attrs.depth) {
     276            ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     277            ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
     278            if (m_attrs.stencil)
     279                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     280            if (m_attrs.depth)
     281                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     282        }
     283        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     284        if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
     285            // FIXME: cleanup.
     286            notImplemented();
     287        }
     288    }
     289
     290    // resize regular FBO
     291    if (m_boundFBO != m_fbo) {
     292        mustRestoreFBO = true;
     293        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     294    }
    209295    ::glBindTexture(GL_TEXTURE_2D, m_texture);
    210     ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
     296    ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
     297    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
    211298    ::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) {
     299    if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
     300        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     301        ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
     302        if (m_attrs.stencil)
     303            ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     304        if (m_attrs.depth)
     305            ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     306        ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     307    }
     308    if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
    222309        // FIXME: cleanup
    223310        notImplemented();
    224311    }
    225312
    226     ::glClear(GL_COLOR_BUFFER_BIT);
     313    if (mustRestoreFBO)
     314        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     315
     316    GLenum clearMask = GL_COLOR_BUFFER_BIT;
     317    if (m_attrs.depth)
     318        clearMask |= GL_DEPTH_BUFFER_BIT;
     319    if (m_attrs.stencil)
     320        clearMask |= GL_STENCIL_BUFFER_BIT;
     321    ::glClear(clearMask);
    227322    ::glFlush();
    228323}
     
    238333}
    239334
     335void GraphicsContext3D::prepareTexture()
     336{
     337    if (m_attrs.antialias) {
     338        ensureContext(m_contextObj);
     339        ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     340        ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     341        ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     342        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     343        ::glFinish();
     344    }
     345}
     346
    240347void GraphicsContext3D::activeTexture(unsigned long texture)
    241348{
     
    269376{
    270377    ensureContext(m_contextObj);
    271     ::glBindFramebufferEXT(target, (buffer && buffer->object()) ? (GLuint) buffer->object() : m_fbo);
     378    GLuint fbo;
     379    if (buffer && buffer->object())
     380        fbo = (GLuint)buffer->object();
     381    else
     382        fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
     383    if (fbo != m_boundFBO) {
     384        ::glBindFramebufferEXT(target, fbo);
     385        m_boundFBO = fbo;
     386    }
    272387}
    273388
     
    677792        return 0;
    678793       
     794    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
     795        ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     796        ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     797        ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     798        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     799    }
    679800    RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);
    680801    ::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data());
     802    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
     803        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     804    if (!m_attrs.alpha) {
     805        // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.
     806        // This is a hack until ::glReadPixels fixes its behavior.
     807        GLubyte* data = reinterpret_cast<GLubyte*>(array->data());
     808        unsigned byteLength = array->byteLength();
     809        for (unsigned i = 3; i < byteLength; i += 4)
     810            data[i] = 255;
     811    }
    681812    return array;   
    682813}
  • trunk/WebCore/platform/graphics/mac/GraphicsLayerCA.mm

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

    r56853 r56872  
     12010-03-31  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        * src/WebGraphicsContext3DDefaultImpl.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Chrome.
     9        (WebKit::WebGraphicsContext3DDefaultImpl::WebGraphicsContext3DDefaultImpl):
     10        (WebKit::WebGraphicsContext3DDefaultImpl::~WebGraphicsContext3DDefaultImpl):
     11        (WebKit::WebGraphicsContext3DDefaultImpl::initialize):
     12        (WebKit::WebGraphicsContext3DDefaultImpl::validateAttributes):
     13        (WebKit::WebGraphicsContext3DDefaultImpl::reshape):
     14        (WebKit::WebGraphicsContext3DDefaultImpl::readBackFramebuffer):
     15        (WebKit::WebGraphicsContext3DDefaultImpl::bindFramebuffer):
     16        (WebKit::WebGraphicsContext3DDefaultImpl::readPixels): Deal with wrong returned alpha values in Mac.
     17        * src/WebGraphicsContext3DDefaultImpl.h: Add a function.
     18
    1192010-03-31  Darin Fisher  <darin@chromium.org>
    220
  • trunk/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp

    r56426 r56872  
    125125    , m_texture(0)
    126126    , m_fbo(0)
    127     , m_depthBuffer(0)
     127    , m_depthStencilBuffer(0)
     128    , m_multisampleFBO(0)
     129    , m_multisampleDepthStencilBuffer(0)
     130    , m_multisampleColorBuffer(0)
    128131    , m_boundFBO(0)
    129132#ifdef FLIP_FRAMEBUFFER_VERTICALLY
     
    153156        makeContextCurrent();
    154157#ifndef RENDER_TO_DEBUGGING_WINDOW
    155         glDeleteRenderbuffersEXT(1, &m_depthBuffer);
     158        if (m_attributes.antialias) {
     159            glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
     160            if (m_attributes.depth || m_attributes.stencil)
     161                glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     162            glDeleteFramebuffersEXT(1, &m_multisampleFBO);
     163        } else {
     164            if (m_attributes.depth || m_attributes.stencil)
     165                glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
     166        }
    156167        glDeleteTextures(1, &m_texture);
    157168#ifdef FLIP_FRAMEBUFFER_VERTICALLY
     
    185196bool WebGraphicsContext3DDefaultImpl::initialize(WebGraphicsContext3D::Attributes attributes)
    186197{
    187     // FIXME: we need to take into account the user's requested
    188     // context creation attributes, in particular stencil and
    189     // antialias, and determine which could and could not be honored
    190     // based on the capabilities of the OpenGL implementation.
    191     m_attributes.alpha = true;
    192     m_attributes.depth = true;
    193     m_attributes.stencil = false;
    194     m_attributes.antialias = false;
    195     m_attributes.premultipliedAlpha = true;
    196 
    197198#if OS(WINDOWS)
    198199    WNDCLASS wc;
     
    377378    }
    378379
     380    m_attributes = attributes;
     381    validateAttributes();
     382
    379383    m_initialized = true;
    380384    return true;
     385}
     386
     387void WebGraphicsContext3DDefaultImpl::validateAttributes()
     388{
     389    const char* extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
     390
     391    if (m_attributes.stencil) {
     392        if (std::strstr(extensions, "GL_EXT_packed_depth_stencil")) {
     393            if (!m_attributes.depth)
     394                m_attributes.depth = true;
     395        } else
     396            m_attributes.stencil = false;
     397    }
     398    if (m_attributes.antialias) {
     399        bool isValidVendor = true;
     400#if PLATFORM(CG)
     401        // Currently in Mac we only turn on antialias if vendor is NVIDIA.
     402        const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
     403        if (!std::strstr(vendor, "NVIDIA"))
     404            isValidVendor = false;
     405#endif
     406        if (!isValidVendor || !std::strstr(extensions, "GL_EXT_framebuffer_multisample"))
     407            m_attributes.antialias = false;
     408    }
     409    // FIXME: instead of enforcing premultipliedAlpha = true, implement the
     410    // correct behavior when premultipliedAlpha = false is requested.
     411    m_attributes.premultipliedAlpha = true;
    381412}
    382413
     
    466497        // Generate the framebuffer object
    467498        glGenFramebuffersEXT(1, &m_fbo);
    468         // Generate the depth buffer
    469         glGenRenderbuffersEXT(1, &m_depthBuffer);
    470     }
    471 
    472     // Reallocate the color and depth buffers
     499        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     500        m_boundFBO = m_fbo;
     501        if (m_attributes.depth || m_attributes.stencil)
     502            glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
     503        // Generate the multisample framebuffer object
     504        if (m_attributes.antialias) {
     505            glGenFramebuffersEXT(1, &m_multisampleFBO);
     506            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     507            m_boundFBO = m_multisampleFBO;
     508            glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
     509            if (m_attributes.depth || m_attributes.stencil)
     510                glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
     511        }
     512    }
     513
     514    GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
     515    if (m_attributes.alpha) {
     516        internalColorFormat = GL_RGBA8;
     517        colorFormat = GL_RGBA;
     518    } else {
     519        internalColorFormat = GL_RGB8;
     520        colorFormat = GL_RGB;
     521    }
     522    if (m_attributes.stencil || m_attributes.depth) {
     523        // We don't allow the logic where stencil is required and depth is not.
     524        // See GraphicsContext3DInternal constructor.
     525        if (m_attributes.stencil && m_attributes.depth)
     526            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
     527        else
     528            internalDepthStencilFormat = GL_DEPTH_COMPONENT;
     529    }
     530
     531    bool mustRestoreFBO = false;
     532
     533    // Resize multisampling FBO
     534    if (m_attributes.antialias) {
     535        GLint maxSampleCount;
     536        glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
     537        GLint sampleCount = std::min(8, maxSampleCount);
     538        if (m_boundFBO != m_multisampleFBO) {
     539            mustRestoreFBO = true;
     540            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     541        }
     542        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     543        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
     544        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
     545        if (m_attributes.stencil || m_attributes.depth) {
     546            glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     547            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
     548            if (m_attributes.stencil)
     549                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     550            if (m_attributes.depth)
     551                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
     552        }
     553        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     554        GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
     555        if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
     556            printf("GraphicsContext3D: multisampling framebuffer was incomplete\n");
     557
     558            // FIXME: cleanup.
     559            notImplemented();
     560        }
     561    }
     562
     563    // Resize regular FBO
     564    if (m_boundFBO != m_fbo) {
     565        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     566        mustRestoreFBO = true;
     567    }
    473568    glBindTexture(target, m_texture);
    474     glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
     569    glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
     570    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
    475571    glBindTexture(target, 0);
    476 
    477     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    478     m_boundFBO = m_fbo;
    479     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
    480     glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
    481     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    482 
    483     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
    484     glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
     572    if (!m_attributes.antialias && (m_attributes.stencil || m_attributes.depth)) {
     573        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     574        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
     575        if (m_attributes.stencil)
     576            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     577        if (m_attributes.depth)
     578            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
     579        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     580    }
    485581    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    486582    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
     
    490586        notImplemented();
    491587    }
     588
     589    if (mustRestoreFBO)
     590        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
    492591#endif // RENDER_TO_DEBUGGING_WINDOW
    493592
     
    500599#endif // FLIP_FRAMEBUFFER_VERTICALLY
    501600
    502     glClear(GL_COLOR_BUFFER_BIT);
    503 
     601    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
     602    if (m_attributes.stencil)
     603        clearMask |= GL_STENCIL_BUFFER_BIT;
     604    if (m_attributes.depth)
     605        clearMask |= GL_DEPTH_BUFFER_BIT;
     606    glClear(clearMask);
    504607}
    505608
     
    545648    // is fully GPU composited, it wasn't worth the complexity.
    546649
    547     bool mustRestoreFBO = (m_boundFBO != m_fbo);
    548     if (mustRestoreFBO)
     650    bool mustRestoreFBO;
     651    if (m_attributes.antialias) {
     652        glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     653        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     654        glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    549655        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     656        mustRestoreFBO = true;
     657    } else {
     658        if (m_boundFBO != m_fbo) {
     659            mustRestoreFBO = true;
     660            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     661        }
     662    }
    550663#if PLATFORM(SKIA)
    551664    glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
     
    686799    makeContextCurrent();
    687800    if (!framebuffer)
    688         framebuffer = m_fbo;
    689     glBindFramebufferEXT(target, framebuffer);
    690     m_boundFBO = framebuffer;
     801        framebuffer = (m_attributes.antialias ? m_multisampleFBO : m_fbo);
     802    if (framebuffer != m_boundFBO) {
     803        glBindFramebufferEXT(target, framebuffer);
     804        m_boundFBO = framebuffer;
     805    }
    691806}
    692807
     
    9851100DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, double, double)
    9861101
    987 DELEGATE_TO_GL_7(readPixels, ReadPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, void*)
     1102void WebGraphicsContext3DDefaultImpl::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels)
     1103{
     1104#ifndef RENDER_TO_DEBUGGING_WINDOW
     1105    if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) {
     1106        glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     1107        glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     1108        glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     1109        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     1110    }
     1111#endif
     1112    glReadPixels(x, y, width, height, format, type, pixels);
     1113#if PLATFORM(CG)
     1114    if (!m_attributes.alpha) {
     1115        // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.
     1116        // This is a hack until glReadPixels fixes its behavior.
     1117        // Pixels are stored in WebGLUnsignedByteArray, which is unsigned char array.
     1118        unsigned char* data = reinterpret_cast<unsigned char*>(pixels);
     1119        // FIXME: take into account pack alignment.
     1120        unsigned long byteLength = width * height * 4 * sizeof(unsigned char);
     1121        for (unsigned long i = 3; i < byteLength; i += 4)
     1122            data[i] = 255;
     1123    }
     1124#endif
     1125#ifndef RENDER_TO_DEBUGGING_WINDOW
     1126    if (m_attributes.antialias && m_boundFBO == m_multisampleFBO)
     1127        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     1128#endif
     1129}
    9881130
    9891131void WebGraphicsContext3DDefaultImpl::releaseShaderCompiler()
  • trunk/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h

    r56381 r56872  
    265265    unsigned int m_texture;
    266266    unsigned int m_fbo;
    267     unsigned int m_depthBuffer;
     267    unsigned int m_depthStencilBuffer;
    268268    unsigned int m_cachedWidth, m_cachedHeight;
     269
     270    // For multisampling
     271    unsigned int m_multisampleFBO;
     272    unsigned int m_multisampleDepthStencilBuffer;
     273    unsigned int m_multisampleColorBuffer;
    269274
    270275    // For tracking which FBO is bound
     
    277282                        unsigned int height);
    278283#endif
     284
     285    // Take into account the user's requested context creation attributes, in
     286    // particular stencil and antialias, and determine which could or could
     287    // not be honored based on the capabilities of the OpenGL implementation.
     288    void validateAttributes();
    279289
    280290    // Note: we aren't currently using this information, but we will
Note: See TracChangeset for help on using the changeset viewer.