Changeset 106815 in webkit


Ignore:
Timestamp:
Feb 6, 2012 9:49:59 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Initial implementation of GraphicsContext3DOpenGLES.cpp
https://bugs.webkit.org/show_bug.cgi?id=76248

Patch by ChangSeok Oh <ChangSeok Oh> on 2012-02-06
Reviewed by Martin Robinson.

Implemented APIs in GraphicsContext3DOpenGLES.cpp according to the GLES spec. roughly.
But no way to run these codes right now, because they need an extra port
specific implementation to work. I plan to add these extra codes for the GTK port
in the next patch. And also this patch doesn't support anti-aliasing yet. Another bug
will deal with it.
Moved some APIs in GraphicsContext3DOpenGLES.cpp to GraphicsContext3DCommon.cpp.
It looks it could be shared between gl and gles.
Two helper functions are added to avoid code duplication in GraphicsContext3D.
Added a missing period at the end of comment lines.

No new tests required.
We'll be able to verify this patch by using the existing webgl test cases.

  • platform/graphics/GraphicsContext3D.h: Add build flag to access stencilBuffer & depthBuffer for gles.

(WebCore):

  • platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:

(WebCore::GraphicsContext3D::reshapeFBOs): Helper function extracted from GC3D::reshape to resize regular & multisampled FBOs.
(WebCore::GraphicsContext3D::resolveMultisamplingIfNecessary): Helper function to resolve multisampling.

  • platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:

(WebCore::GraphicsContext3D::validateAttributes): Add condition to disable antialiasing & packedDepthStencilExtension for GLES.
(WebCore::GraphicsContext3D::paintRenderingResultsToCanvas):
(WebCore::GraphicsContext3D::paintRenderingResultsToImageData):

Following APIs looked shareable so that moved into GC3DOpenGLCommon.cpp.
(WebCore::GraphicsContext3D::prepareTexture):
(WebCore):
(WebCore::GraphicsContext3D::readRenderingResults):
(WebCore::GraphicsContext3D::reshape):
(WebCore::GraphicsContext3D::bindFramebuffer):
(WebCore::GraphicsContext3D::copyTexImage2D):
(WebCore::GraphicsContext3D::copyTexSubImage2D):
(WebCore::GraphicsContext3D::getActiveUniform):
(WebCore::GraphicsContext3D::readPixels):

Added a missing period at the end of comment line.
(WebCore::GraphicsContext3D::compileShader):
(WebCore::GraphicsContext3D::getActiveAttrib):
(WebCore::GraphicsContext3D::uniform2fv):
(WebCore::GraphicsContext3D::uniform3fv):
(WebCore::GraphicsContext3D::uniform4fv):
(WebCore::GraphicsContext3D::uniform2iv):
(WebCore::GraphicsContext3D::uniform3iv):
(WebCore::GraphicsContext3D::uniform4iv):
(WebCore::GraphicsContext3D::uniformMatrix2fv):
(WebCore::GraphicsContext3D::uniformMatrix3fv):
(WebCore::GraphicsContext3D::uniformMatrix4fv):
(WebCore::GraphicsContext3D::texSubImage2D):

  • platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp:

(WebCore::GraphicsContext3D::reshapeFBOs): Same with the above.
(WebCore::GraphicsContext3D::resolveMultisamplingIfNecessary): Same with the above.

Brief explanation about what the differences are between gl and gles.
(WebCore::GraphicsContext3D::renderbufferStorage): Removed codes for converting GLES parameter to GL parameter.
(WebCore::GraphicsContext3D::getIntegerv): Removed codes that emulate GLES.
(WebCore::GraphicsContext3D::texImage2D): Removed codes for converting GLES parameter to GL parameter.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r106811 r106815  
     12012-02-06  ChangSeok Oh  <shivamidow@gmail.com>
     2
     3        Initial implementation of GraphicsContext3DOpenGLES.cpp
     4        https://bugs.webkit.org/show_bug.cgi?id=76248
     5
     6        Reviewed by Martin Robinson.
     7
     8        Implemented APIs in GraphicsContext3DOpenGLES.cpp according to the GLES spec. roughly.
     9        But no way to run these codes right now, because they need an extra port
     10        specific implementation to work. I plan to add these extra codes for the GTK port
     11        in the next patch. And also this patch doesn't support anti-aliasing yet. Another bug
     12        will deal with it.
     13        Moved some APIs in GraphicsContext3DOpenGLES.cpp to GraphicsContext3DCommon.cpp.
     14        It looks it could be shared between gl and gles.
     15        Two helper functions are added to avoid code duplication in GraphicsContext3D.
     16        Added a missing period at the end of comment lines.
     17
     18        No new tests required.
     19        We'll be able to verify this patch by using the existing webgl test cases.
     20
     21        * platform/graphics/GraphicsContext3D.h: Add build flag to access stencilBuffer & depthBuffer for gles.
     22        (WebCore):
     23        * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
     24        (WebCore::GraphicsContext3D::reshapeFBOs): Helper function extracted from GC3D::reshape to resize regular & multisampled FBOs.
     25        (WebCore::GraphicsContext3D::resolveMultisamplingIfNecessary): Helper function to resolve multisampling.
     26        * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
     27        (WebCore::GraphicsContext3D::validateAttributes): Add condition to disable antialiasing & packedDepthStencilExtension for GLES.
     28        (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas):
     29        (WebCore::GraphicsContext3D::paintRenderingResultsToImageData):
     30
     31        Following APIs looked shareable so that moved into GC3DOpenGLCommon.cpp.
     32        (WebCore::GraphicsContext3D::prepareTexture):
     33        (WebCore):
     34        (WebCore::GraphicsContext3D::readRenderingResults):
     35        (WebCore::GraphicsContext3D::reshape):
     36        (WebCore::GraphicsContext3D::bindFramebuffer):
     37        (WebCore::GraphicsContext3D::copyTexImage2D):
     38        (WebCore::GraphicsContext3D::copyTexSubImage2D):
     39        (WebCore::GraphicsContext3D::getActiveUniform):
     40        (WebCore::GraphicsContext3D::readPixels):
     41
     42        Added a missing period at the end of comment line.
     43        (WebCore::GraphicsContext3D::compileShader):
     44        (WebCore::GraphicsContext3D::getActiveAttrib):
     45        (WebCore::GraphicsContext3D::uniform2fv):
     46        (WebCore::GraphicsContext3D::uniform3fv):
     47        (WebCore::GraphicsContext3D::uniform4fv):
     48        (WebCore::GraphicsContext3D::uniform2iv):
     49        (WebCore::GraphicsContext3D::uniform3iv):
     50        (WebCore::GraphicsContext3D::uniform4iv):
     51        (WebCore::GraphicsContext3D::uniformMatrix2fv):
     52        (WebCore::GraphicsContext3D::uniformMatrix3fv):
     53        (WebCore::GraphicsContext3D::uniformMatrix4fv):
     54        (WebCore::GraphicsContext3D::texSubImage2D):
     55
     56        * platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp:
     57        (WebCore::GraphicsContext3D::reshapeFBOs): Same with the above.
     58        (WebCore::GraphicsContext3D::resolveMultisamplingIfNecessary): Same with the above.
     59
     60        Brief explanation about what the differences are between gl and gles.
     61        (WebCore::GraphicsContext3D::renderbufferStorage): Removed codes for converting GLES parameter to GL parameter.
     62        (WebCore::GraphicsContext3D::getIntegerv): Removed codes that emulate GLES.
     63        (WebCore::GraphicsContext3D::texImage2D): Removed codes for converting GLES parameter to GL parameter.
     64
    1652012-02-06  Alexander Pavlov  <apavlov@chromium.org>
    266
  • trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h

    r106772 r106815  
    2727#define GraphicsContext3D_h
    2828
    29 #include "IntSize.h"
    3029#include "GraphicsLayer.h"
    3130#include "GraphicsTypes3D.h"
     
    9493class ImageBuffer;
    9594class ImageData;
     95class IntRect;
     96class IntSize;
    9697#if USE(CAIRO)
    9798class PlatformContextCairo;
     
    909910#endif
    910911
     912    bool reshapeFBOs(const IntSize&);
     913    void resolveMultisamplingIfNecessary(const IntRect&);
     914
    911915    int m_currentWidth, m_currentHeight;
    912916    bool isResourceSafe();
     
    943947    GC3Duint m_stencilBuffer;
    944948#else
     949#if USE(OPENGL_ES_2)
     950    GC3Duint m_depthBuffer;
     951    GC3Duint m_stencilBuffer;
     952#endif
    945953    GC3Duint m_depthStencilBuffer;
    946954#endif
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp

    r106772 r106815  
    3131
    3232#include "Extensions3DOpenGL.h"
     33#include "IntRect.h"
     34#include "IntSize.h"
    3335#include "NotImplemented.h"
    3436
     
    4446namespace WebCore {
    4547
    46 void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize)
    47 {
    48     if (pixelsSize < m_currentWidth * m_currentHeight * 4)
    49         return;
    50 
    51     makeContextCurrent();
    52 
    53     bool mustRestoreFBO = false;
    54     if (m_attrs.antialias) {
    55         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
    56         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
    57         ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    58         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    59         mustRestoreFBO = true;
    60     } else {
    61         if (m_boundFBO != m_fbo) {
    62             mustRestoreFBO = true;
    63             ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    64         }
    65     }
    66 
    67     GLint packAlignment = 4;
    68     bool mustRestorePackAlignment = false;
    69     ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
    70     if (packAlignment > 4) {
    71         ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
    72         mustRestorePackAlignment = true;
    73     }
    74 
    75     ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
    76 
    77     if (mustRestorePackAlignment)
    78         ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
    79 
    80     if (mustRestoreFBO)
    81         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
    82 }
    83 
    84 void GraphicsContext3D::reshape(int width, int height)
    85 {
    86     if (!platformGraphicsContext3D())
    87         return;
    88 
    89     if (width == m_currentWidth && height == m_currentHeight)
    90         return;
    91    
    92     m_currentWidth = width;
    93     m_currentHeight = height;
    94    
    95     makeContextCurrent();
    96     validateAttributes();
    97 
     48bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
     49{
     50    const int width = size.width();
     51    const int height = size.height();
    9852    GLuint colorFormat, internalDepthStencilFormat = 0;
    9953    if (m_attrs.alpha) {
     
    10963
    11064        Extensions3D* extensions = getExtensions();
    111         // Use a 24 bit depth buffer where we know we have it
     65        // Use a 24 bit depth buffer where we know we have it.
    11266        if (extensions->supports("GL_EXT_packed_depth_stencil"))
    11367            internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
     
    11872    bool mustRestoreFBO = false;
    11973
    120     // resize multisample FBO
     74    // Resize multisample FBO.
    12175    if (m_attrs.antialias) {
    12276        GLint maxSampleCount;
     
    178132    }
    179133
    180     // Initialize renderbuffers to 0.
    181     GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0;
    182     GLint clearStencil = 0;
    183     GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE;
    184     GLuint stencilMask = 0xffffffff;
    185     GLboolean isScissorEnabled = GL_FALSE;
    186     GLboolean isDitherEnabled = GL_FALSE;
    187     GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
    188     ::glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
    189     ::glClearColor(0, 0, 0, 0);
    190     ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
    191     ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    192     if (m_attrs.depth) {
    193         ::glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
    194         ::glClearDepth(1);
    195         ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
    196         ::glDepthMask(GL_TRUE);
    197         clearMask |= GL_DEPTH_BUFFER_BIT;
    198     }
    199     if (m_attrs.stencil) {
    200         ::glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil);
    201         ::glClearStencil(0);
    202         ::glGetIntegerv(GL_STENCIL_WRITEMASK, reinterpret_cast<GLint*>(&stencilMask));
    203         ::glStencilMaskSeparate(GL_FRONT, 0xffffffff);
    204         clearMask |= GL_STENCIL_BUFFER_BIT;
    205     }
    206     isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST);
    207     ::glDisable(GL_SCISSOR_TEST);
    208     isDitherEnabled = ::glIsEnabled(GL_DITHER);
    209     ::glDisable(GL_DITHER);
    210 
    211     ::glClear(clearMask);
    212 
    213     ::glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
    214     ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
    215     if (m_attrs.depth) {
    216         ::glClearDepth(clearDepth);
    217         ::glDepthMask(depthMask);
    218     }
    219     if (m_attrs.stencil) {
    220         ::glClearStencil(clearStencil);
    221         ::glStencilMaskSeparate(GL_FRONT, stencilMask);
    222     }
    223     if (isScissorEnabled)
    224         ::glEnable(GL_SCISSOR_TEST);
    225     else
    226         ::glDisable(GL_SCISSOR_TEST);
    227     if (isDitherEnabled)
    228         ::glEnable(GL_DITHER);
    229     else
    230         ::glDisable(GL_DITHER);
    231 
    232     if (mustRestoreFBO)
    233         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
    234 
    235     ::glFlush();
    236 }
    237 
    238 void GraphicsContext3D::prepareTexture()
    239 {
    240     if (m_layerComposited)
    241         return;
    242     makeContextCurrent();
    243     if (m_attrs.antialias) {
    244         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
    245         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
    246         ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    247     }
    248     ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    249     ::glActiveTexture(GL_TEXTURE0);
    250     ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
    251     ::glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, 0, 0, m_currentWidth, m_currentHeight, 0);
    252     ::glBindTexture(GL_TEXTURE_2D, m_boundTexture0);
    253     ::glActiveTexture(m_activeTexture);
    254     ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
    255     ::glFinish();
    256     m_layerComposited = true;
    257 }
    258 
    259 void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
    260 {
    261     makeContextCurrent();
    262     GLuint fbo;
    263     if (buffer)
    264         fbo = buffer;
    265     else
    266         fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
    267     if (fbo != m_boundFBO) {
    268         ::glBindFramebufferEXT(target, fbo);
    269         m_boundFBO = fbo;
    270     }
    271 }
    272 
    273 void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
    274 {
    275     makeContextCurrent();
    276     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
    277         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
    278         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
    279         ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    280         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    281     }
    282     ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
    283     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
    284         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
    285 }
    286 
    287 void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
    288 {
    289     makeContextCurrent();
    290     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
    291         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
    292         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
    293         ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    294         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    295     }
    296     ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
    297     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
    298         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
    299 }
    300 
    301 bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
    302 {
    303     if (!program) {
    304         synthesizeGLError(INVALID_VALUE);
    305         return false;
    306     }
    307     makeContextCurrent();
    308     GLint maxUniformSize = 0;
    309     ::glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
    310     GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination
    311     GLsizei nameLength = 0;
    312     GLint size = 0;
    313     GLenum type = 0;
    314     ::glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name);
    315     if (!nameLength)
    316         return false;
    317     info.name = String(name, nameLength);
    318     info.type = type;
    319     info.size = size;
    320     return true;
    321 }
    322 
    323 
    324 void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
    325 {
    326     // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
    327     // all previous rendering calls should be done before reading pixels.
    328     makeContextCurrent();
    329     ::glFlush();
    330     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
    331         ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
    332         ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
    333         ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    334         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    335         ::glFlush();
    336     }
    337     ::glReadPixels(x, y, width, height, format, type, data);
    338     if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
    339         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     134    return mustRestoreFBO;
     135}
     136
     137void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect)
     138{
     139    ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
     140    ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
     141    ::glBlitFramebufferEXT(rect.x(), rect.y(), rect.maxX(), rect.maxY(), rect.x(), rect.y(), rect.maxX(), rect.maxY(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
    340142}
    341143
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp

    r106772 r106815  
    11/*
    22 * Copyright (C) 2010 Apple Inc. All rights reserved.
     3 * Copyright (C) 2012 ChangSeok Oh <shivamidow@gmail.com>
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    3637#include "ImageBuffer.h"
    3738#include "ImageData.h"
     39#include "IntRect.h"
     40#include "IntSize.h"
    3841#include "NotImplemented.h"
    3942#include "WebGLObject.h"
     
    6265    Extensions3D* extensions = getExtensions();
    6366    if (m_attrs.stencil) {
    64         if (extensions->supports("GL_EXT_packed_depth_stencil")) {
    65             extensions->ensureEnabled("GL_EXT_packed_depth_stencil");
     67        const char* packedDepthStencilExtension = isGLES2Compliant() ? "GL_OES_packed_depth_stencil" : "GL_EXT_packed_depth_stencil";
     68        if (extensions->supports(packedDepthStencilExtension)) {
     69            extensions->ensureEnabled(packedDepthStencilExtension);
    6670            // Force depth if stencil is true.
    6771            m_attrs.depth = true;
     
    7579        if (!std::strstr(vendor, "NVIDIA"))
    7680            isValidVendor = false;
    77         if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample"))
     81        if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
    7882            m_attrs.antialias = false;
    7983        else
     
    104108    if (!m_attrs.premultipliedAlpha) {
    105109        for (int i = 0; i < totalBytes; i += 4) {
    106             // Premultiply alpha
     110            // Premultiply alpha.
    107111            pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
    108112            pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
     
    125129{
    126130    // Reading premultiplied alpha would involve unpremultiplying, which is
    127     // lossy
     131    // lossy.
    128132    if (m_attrs.premultipliedAlpha)
    129133        return 0;
     
    135139    readRenderingResults(pixels, totalBytes);
    136140
    137     // Convert to RGBA
     141    // Convert to RGBA.
    138142    for (int i = 0; i < totalBytes; i += 4)
    139143        std::swap(pixels[i], pixels[i + 2]);
     
    142146}
    143147
     148void GraphicsContext3D::prepareTexture()
     149{
     150    if (m_layerComposited)
     151        return;
     152
     153    makeContextCurrent();
     154    if (m_attrs.antialias)
     155        resolveMultisamplingIfNecessary(IntRect(0, 0, m_currentWidth, m_currentHeight));
     156
     157    ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     158    ::glActiveTexture(GL_TEXTURE0);
     159    ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
     160    ::glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, 0, 0, m_currentWidth, m_currentHeight, 0);
     161    ::glBindTexture(GL_TEXTURE_2D, m_boundTexture0);
     162    ::glActiveTexture(m_activeTexture);
     163    ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     164    ::glFinish();
     165    m_layerComposited = true;
     166}
     167
     168void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize)
     169{
     170    int totalBytes = m_currentWidth * m_currentHeight * 4;
     171    if (pixelsSize < totalBytes)
     172        return;
     173
     174    makeContextCurrent();
     175
     176    bool mustRestoreFBO = false;
     177    if (m_attrs.antialias) {
     178        resolveMultisamplingIfNecessary(IntRect(0, 0, m_currentWidth, m_currentHeight));
     179        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     180        mustRestoreFBO = true;
     181    } else {
     182        if (m_boundFBO != m_fbo) {
     183            mustRestoreFBO = true;
     184            ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     185        }
     186    }
     187
     188    GLint packAlignment = 4;
     189    bool mustRestorePackAlignment = false;
     190    ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
     191    if (packAlignment > 4) {
     192        ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
     193        mustRestorePackAlignment = true;
     194    }
     195
     196    ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
     197    if (isGLES2Compliant()) {
     198        for (int i = 0; i < totalBytes; i += 4)
     199            std::swap(pixels[i], pixels[i + 2]); // Convert to BGRA.
     200    }
     201
     202    if (mustRestorePackAlignment)
     203        ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
     204
     205    if (mustRestoreFBO)
     206        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     207}
     208
     209void GraphicsContext3D::reshape(int width, int height)
     210{
     211    if (!platformGraphicsContext3D())
     212        return;
     213
     214    if (width == m_currentWidth && height == m_currentHeight)
     215        return;
     216
     217    m_currentWidth = width;
     218    m_currentHeight = height;
     219
     220    makeContextCurrent();
     221    validateAttributes();
     222
     223    bool mustRestoreFBO = reshapeFBOs(IntSize(width, height));
     224
     225    // Initialize renderbuffers to 0.
     226    GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0;
     227    GLint clearStencil = 0;
     228    GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE;
     229    GLuint stencilMask = 0xffffffff;
     230    GLboolean isScissorEnabled = GL_FALSE;
     231    GLboolean isDitherEnabled = GL_FALSE;
     232    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
     233    ::glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
     234    ::glClearColor(0, 0, 0, 0);
     235    ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
     236    ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
     237    if (m_attrs.depth) {
     238        ::glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
     239        ::glClearDepth(1);
     240        ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
     241        ::glDepthMask(GL_TRUE);
     242        clearMask |= GL_DEPTH_BUFFER_BIT;
     243    }
     244    if (m_attrs.stencil) {
     245        ::glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil);
     246        ::glClearStencil(0);
     247        ::glGetIntegerv(GL_STENCIL_WRITEMASK, reinterpret_cast<GLint*>(&stencilMask));
     248        ::glStencilMaskSeparate(GL_FRONT, 0xffffffff);
     249        clearMask |= GL_STENCIL_BUFFER_BIT;
     250    }
     251    isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST);
     252    ::glDisable(GL_SCISSOR_TEST);
     253    isDitherEnabled = ::glIsEnabled(GL_DITHER);
     254    ::glDisable(GL_DITHER);
     255
     256    ::glClear(clearMask);
     257
     258    ::glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
     259    ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
     260    if (m_attrs.depth) {
     261        ::glClearDepth(clearDepth);
     262        ::glDepthMask(depthMask);
     263    }
     264    if (m_attrs.stencil) {
     265        ::glClearStencil(clearStencil);
     266        ::glStencilMaskSeparate(GL_FRONT, stencilMask);
     267    }
     268    if (isScissorEnabled)
     269        ::glEnable(GL_SCISSOR_TEST);
     270    else
     271        ::glDisable(GL_SCISSOR_TEST);
     272    if (isDitherEnabled)
     273        ::glEnable(GL_DITHER);
     274    else
     275        ::glDisable(GL_DITHER);
     276
     277    if (mustRestoreFBO)
     278        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
     279
     280    ::glFlush();
     281}
     282
    144283IntSize GraphicsContext3D::getInternalFramebufferSize() const
    145284{
     
    173312    makeContextCurrent();
    174313    ::glBindBuffer(target, buffer);
     314}
     315
     316void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
     317{
     318    makeContextCurrent();
     319    GLuint fbo;
     320    if (buffer)
     321        fbo = buffer;
     322    else
     323        fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
     324    if (fbo != m_boundFBO) {
     325        ::glBindFramebufferEXT(target, fbo);
     326        m_boundFBO = fbo;
     327    }
    175328}
    176329
     
    308461
    309462    if (!isValid)
    310         return; // Shader didn't validate, don't move forward with compiling translated source   
     463        return; // Shader didn't validate, don't move forward with compiling translated source.
    311464
    312465    int translatedShaderLength = translatedShaderSource.length();
     
    323476    ::glGetShaderiv(shader, COMPILE_STATUS, &GLCompileSuccess);
    324477   
    325     // ASSERT that ANGLE generated GLSL will be accepted by OpenGL
     478    // ASSERT that ANGLE generated GLSL will be accepted by OpenGL.
    326479    ASSERT(GLCompileSuccess == GL_TRUE);
     480}
     481
     482void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
     483{
     484    makeContextCurrent();
     485    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
     486        resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
     487        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     488    }
     489    ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
     490    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
     491        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     492}
     493
     494void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
     495{
     496    makeContextCurrent();
     497    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
     498        resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
     499        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     500    }
     501    ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
     502    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
     503        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
    327504}
    328505
     
    440617    GLint maxAttributeSize = 0;
    441618    ::glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
    442     GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination
     619    GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination.
    443620    GLsizei nameLength = 0;
    444621    GLint size = 0;
     
    452629    return true;
    453630}
     631
     632bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
     633{
     634    if (!program) {
     635        synthesizeGLError(INVALID_VALUE);
     636        return false;
     637    }
     638
     639    makeContextCurrent();
     640    GLint maxUniformSize = 0;
     641    ::glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
     642
     643    OwnArrayPtr<GLchar> name = adoptArrayPtr(new GLchar[maxUniformSize]); // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination.
     644    GLsizei nameLength = 0;
     645    GLint size = 0;
     646    GLenum type = 0;
     647    ::glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name.get());
     648    if (!nameLength)
     649        return false;
     650
     651    info.name = String(name.get(), nameLength);
     652    info.type = type;
     653    info.size = size;
     654
     655    return true;
     656}
    454657   
    455658void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders)
     
    587790}
    588791
     792void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
     793{
     794    // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
     795    // all previous rendering calls should be done before reading pixels.
     796    makeContextCurrent();
     797    ::glFlush();
     798    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
     799        resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
     800        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     801        ::glFlush();
     802    }
     803    ::glReadPixels(x, y, width, height, format, type, data);
     804    if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
     805        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
     806}
     807
    589808void GraphicsContext3D::releaseShaderCompiler()
    590809{
     
    687906void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dfloat* array, GC3Dsizei size)
    688907{
    689     // FIXME: length needs to be a multiple of 2
     908    // FIXME: length needs to be a multiple of 2.
    690909    makeContextCurrent();
    691910    ::glUniform2fv(location, size, array);
     
    700919void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dfloat* array, GC3Dsizei size)
    701920{
    702     // FIXME: length needs to be a multiple of 3
     921    // FIXME: length needs to be a multiple of 3.
    703922    makeContextCurrent();
    704923    ::glUniform3fv(location, size, array);
     
    713932void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dfloat* array, GC3Dsizei size)
    714933{
    715     // FIXME: length needs to be a multiple of 4
     934    // FIXME: length needs to be a multiple of 4.
    716935    makeContextCurrent();
    717936    ::glUniform4fv(location, size, array);
     
    738957void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dint* array, GC3Dsizei size)
    739958{
    740     // FIXME: length needs to be a multiple of 2
     959    // FIXME: length needs to be a multiple of 2.
    741960    makeContextCurrent();
    742961    ::glUniform2iv(location, size, array);
     
    751970void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dint* array, GC3Dsizei size)
    752971{
    753     // FIXME: length needs to be a multiple of 3
     972    // FIXME: length needs to be a multiple of 3.
    754973    makeContextCurrent();
    755974    ::glUniform3iv(location, size, array);
     
    764983void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dint* array, GC3Dsizei size)
    765984{
    766     // FIXME: length needs to be a multiple of 4
     985    // FIXME: length needs to be a multiple of 4.
    767986    makeContextCurrent();
    768987    ::glUniform4iv(location, size, array);
     
    771990void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* array, GC3Dsizei size)
    772991{
    773     // FIXME: length needs to be a multiple of 4
     992    // FIXME: length needs to be a multiple of 4.
    774993    makeContextCurrent();
    775994    ::glUniformMatrix2fv(location, size, transpose, array);
     
    778997void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* array, GC3Dsizei size)
    779998{
    780     // FIXME: length needs to be a multiple of 9
     999    // FIXME: length needs to be a multiple of 9.
    7811000    makeContextCurrent();
    7821001    ::glUniformMatrix3fv(location, size, transpose, array);
     
    7851004void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dboolean transpose, GC3Dfloat* array, GC3Dsizei size)
    7861005{
    787     // FIXME: length needs to be a multiple of 16
     1006    // FIXME: length needs to be a multiple of 16.
    7881007    makeContextCurrent();
    7891008    ::glUniformMatrix4fv(location, size, transpose, array);
     
    10511270    makeContextCurrent();
    10521271
    1053     // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
     1272    // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size.
    10541273    ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
    10551274}
  • trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp

    r104896 r106815  
    3131#include "GraphicsContext3D.h"
    3232
     33#include "IntRect.h"
     34#include "IntSize.h"
    3335#include "NotImplemented.h"
    3436
     
    3941namespace WebCore {
    4042
    41 void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize)
     43bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
    4244{
    43     notImplemented();
     45    const int width = size.width();
     46    const int height = size.height();
     47    GLuint colorFormat = 0, pixelDataType = 0;
     48    if (m_attrs.alpha) {
     49        m_internalColorFormat = GL_RGBA;
     50        colorFormat = GL_RGBA;
     51        pixelDataType = GL_UNSIGNED_BYTE;
     52    } else {
     53        m_internalColorFormat = GL_RGB;
     54        colorFormat = GL_RGB;
     55        pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
     56    }
     57
     58    // We don't allow the logic where stencil is required and depth is not.
     59    // See GraphicsContext3D::validateAttributes.
     60    bool supportPackedDepthStencilBuffer = (m_attrs.stencil || m_attrs.depth) && getExtensions()->supports("GL_OES_packed_depth_stencil");
     61
     62    // Resize regular FBO.
     63    bool mustRestoreFBO = false;
     64    if (m_boundFBO != m_fbo) {
     65        mustRestoreFBO = true;
     66        ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
     67    }
     68
     69    ::glBindTexture(GL_TEXTURE_2D, m_texture);
     70    ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, pixelDataType, 0);
     71    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
     72
     73    ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
     74    ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
     75    ::glBindTexture(GL_TEXTURE_2D, 0);
     76
     77    // We don't support antialiasing yet. See GraphicsContext3D::validateAttributes.
     78    ASSERT(!m_attrs.antialias);
     79
     80    if (m_attrs.stencil || m_attrs.depth) {
     81        // Use a 24 bit depth buffer where we know we have it.
     82        if (supportPackedDepthStencilBuffer) {
     83            ::glBindTexture(GL_TEXTURE_2D, m_depthStencilBuffr);
     84            ::glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_OES, width, height, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, 0);
     85            if (m_attrs.stencil)
     86                ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_depthStencilBuffer, 0);
     87            if (m_attrs.depth)
     88                ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthStencilBuffer, 0);
     89            ::glBindTexture(GL_TEXTURE_2D, 0);
     90        } else {
     91            if (m_attributes.stencil) {
     92                ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_stencilBuffer);
     93                ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8, width, height);
     94                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencilBuffer);
     95            }
     96            if (m_attributes.depth) {
     97                ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
     98                ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, width, height);
     99                ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
     100            }
     101            ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
     102        }
     103    }
     104    if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
     105        // FIXME: cleanup
     106        notImplemented();
     107    }
     108
     109    return mustRestoreFBO;
    44110}
    45111
    46 void GraphicsContext3D::reshape(int width, int height)
     112void GraphicsContext3D::resolveMultisamplingIfNecessary(IntRect& rect)
    47113{
    48     notImplemented();
    49 }
    50 
    51 void GraphicsContext3D::prepareTexture()
    52 {
    53     notImplemented();
    54 }
    55 
    56 void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
    57 {
    58     notImplemented();
    59 }
    60 
    61 void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
    62 {
    63     notImplemented();
    64 }
    65 
    66 void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
    67 {
    68     notImplemented();
    69 }
    70 
    71 bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
    72 {
    73     notImplemented();
    74 }
    75 
    76 
    77 void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
    78 {
     114    // FIXME: We don't support antialiasing yet.
    79115    notImplemented();
    80116}
     
    82118void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
    83119{
    84     notImplemented();
     120    makeContextCurrent();
     121    ::glRenderbufferStorageEXT(target, internalformat, width, height);
    85122}
    86123
    87124void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
    88125{
    89     notImplemented();
     126    makeContextCurrent();
     127    ::glGetIntegerv(pname, value);
    90128}
    91129
    92130bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
    93131{
    94     notImplemented();
    95     return false;
    96 }
    97 
     132    if (width && height && !pixels) {
     133        synthesizeGLError(INVALID_VALUE);
     134        return false;
     135    }
     136    makeContextCurrent();
     137    ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
     138    return true;
    98139}
    99140
Note: See TracChangeset for help on using the changeset viewer.