Changeset 207719 in webkit


Ignore:
Timestamp:
Oct 22, 2016, 4:28:39 PM (9 years ago)
Author:
Chris Dumez
Message:

WebGLRenderingContextBase.texImage2D() should use a union instead of overloading
https://bugs.webkit.org/show_bug.cgi?id=163856

Reviewed by Darin Adler.

WebGLRenderingContextBase.texImage2D() should use a union instead of overloading:

  • html/canvas/WebGLRenderingContextBase.cpp:

(WebCore::WebGLRenderingContextBase::texImage2D):

  • html/canvas/WebGLRenderingContextBase.h:
  • html/canvas/WebGLRenderingContextBase.idl:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r207717 r207719  
     12016-10-22  Chris Dumez  <cdumez@apple.com>
     2
     3        WebGLRenderingContextBase.texImage2D() should use a union instead of overloading
     4        https://bugs.webkit.org/show_bug.cgi?id=163856
     5
     6        Reviewed by Darin Adler.
     7
     8        WebGLRenderingContextBase.texImage2D() should use a union instead of overloading:
     9        - https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14
     10
     11        * html/canvas/WebGLRenderingContextBase.cpp:
     12        (WebCore::WebGLRenderingContextBase::texImage2D):
     13        * html/canvas/WebGLRenderingContextBase.h:
     14        * html/canvas/WebGLRenderingContextBase.idl:
     15
    1162016-10-22  Antti Koivisto  <antti@apple.com>
    217
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

    r207715 r207719  
    31093109}
    31103110
    3111 void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    3112                                        GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
    3113 {
    3114     ec = 0;
    3115     if (isContextLostOrPending() || !pixels || !validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
    3116         return;
    3117     Vector<uint8_t> data;
    3118     bool needConversion = true;
    3119     // The data from ImageData is always of format RGBA8.
    3120     // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
    3121     if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE)
    3122         needConversion = false;
    3123     else {
    3124         if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
    3125             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
     3111void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Optional<TexImageSource> source, ExceptionCode& ec)
     3112{
     3113    if (!source) {
     3114        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "source is null");
     3115        return;
     3116    }
     3117
     3118    auto visitor = WTF::makeVisitor([&](const RefPtr<ImageData>& pixels) {
     3119        ec = 0;
     3120        if (isContextLostOrPending() || !validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
    31263121            return;
    3127         }
    3128     }
    3129     if (m_unpackAlignment != 1)
    3130         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
    3131     texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
    3132     if (m_unpackAlignment != 1)
    3133         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
     3122        Vector<uint8_t> data;
     3123        bool needConversion = true;
     3124        // The data from ImageData is always of format RGBA8.
     3125        // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
     3126        if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE)
     3127            needConversion = false;
     3128        else {
     3129            if (!m_context->extractImageData(pixels.get(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
     3130                synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
     3131                return;
     3132            }
     3133        }
     3134        if (m_unpackAlignment != 1)
     3135            m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
     3136        texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
     3137        if (m_unpackAlignment != 1)
     3138            m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
     3139    }, [&](const RefPtr<HTMLImageElement>& image) {
     3140        ec = 0;
     3141        if (isContextLostOrPending() || !validateHTMLImageElement("texImage2D", image.get(), ec))
     3142            return;
     3143
     3144        RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
     3145        if (!imageForRender)
     3146            return;
     3147
     3148        if (imageForRender->isSVGImage())
     3149            imageForRender = drawImageIntoBuffer(*imageForRender, image->width(), image->height(), 1);
     3150
     3151        if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
     3152            return;
     3153
     3154        texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
     3155
     3156    }, [&](const RefPtr<HTMLCanvasElement>& canvas) {
     3157        ec = 0;
     3158        if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas.get(), ec) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
     3159            return;
     3160
     3161        WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
     3162        // If possible, copy from the canvas element directly to the texture
     3163        // via the GPU, without a read-back to system memory.
     3164        //
     3165        // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE should be lifted when
     3166        // ImageBuffer::copyToPlatformTexture implementations are fully functional.
     3167        if (texture
     3168            && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
     3169            && type == GraphicsContext3D::UNSIGNED_BYTE
     3170            && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))) {
     3171            ImageBuffer* buffer = canvas->buffer();
     3172            if (buffer && buffer->copyToPlatformTexture(*m_context.get(), target, texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
     3173                texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
     3174                return;
     3175            }
     3176        }
     3177
     3178        RefPtr<ImageData> imageData = canvas->getImageData();
     3179        if (imageData)
     3180            texImage2D(target, level, internalformat, format, type, TexImageSource(imageData.get()), ec);
     3181        else
     3182            texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
     3183    }, [&](const RefPtr<HTMLVideoElement>& video) {
     3184        ec = 0;
     3185        if (isContextLostOrPending() || !validateHTMLVideoElement("texImage2D", video.get(), ec)
     3186            || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
     3187            return;
     3188
     3189        // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
     3190        // Otherwise, it will fall back to the normal SW path.
     3191        // FIXME: The current restrictions require that format shoud be RGB or RGBA,
     3192        // type should be UNSIGNED_BYTE and level should be 0. It may be lifted in the future.
     3193        WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
     3194        if (GraphicsContext3D::TEXTURE_2D == target && texture
     3195            && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
     3196            && type == GraphicsContext3D::UNSIGNED_BYTE
     3197            && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))
     3198            && !level) {
     3199            if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), target, level, internalformat, format, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
     3200                texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
     3201                return;
     3202            }
     3203        }
     3204
     3205        // Normal pure SW path.
     3206        RefPtr<Image> image = videoFrameToImage(video.get(), ImageBuffer::fastCopyImageMode());
     3207        if (!image)
     3208            return;
     3209        texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
     3210    });
     3211
     3212    WTF::visit(visitor, source.value());
    31343213}
    31353214
     
    31503229}
    31513230
    3152 void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    3153                                        GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
    3154 {
    3155     ec = 0;
    3156     if (isContextLostOrPending() || !validateHTMLImageElement("texImage2D", image, ec))
    3157         return;
    3158 
    3159     RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
    3160     if (!imageForRender)
    3161         return;
    3162 
    3163     if (imageForRender->isSVGImage())
    3164         imageForRender = drawImageIntoBuffer(*imageForRender, image->width(), image->height(), 1);
    3165 
    3166     if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
    3167         return;
    3168 
    3169     texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
    3170 }
    3171 
    3172 void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    3173                                        GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
    3174 {
    3175     ec = 0;
    3176     if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
    3177         return;
    3178 
    3179     WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
    3180     // If possible, copy from the canvas element directly to the texture
    3181     // via the GPU, without a read-back to system memory.
    3182     //
    3183     // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE should be lifted when
    3184     // ImageBuffer::copyToPlatformTexture implementations are fully functional.
    3185     if (texture
    3186         && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
    3187         && type == GraphicsContext3D::UNSIGNED_BYTE
    3188         && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))) {
    3189         ImageBuffer* buffer = canvas->buffer();
    3190         if (buffer && buffer->copyToPlatformTexture(*m_context.get(), target, texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
    3191             texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
    3192             return;
    3193         }
    3194     }
    3195 
    3196     RefPtr<ImageData> imageData = canvas->getImageData();
    3197     if (imageData)
    3198         texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
    3199     else
    3200         texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
    3201 }
    3202 
    32033231#if ENABLE(VIDEO)
     3232
    32043233RefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
    32053234{
     
    32163245}
    32173246
    3218 void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    3219                                        GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
    3220 {
    3221     ec = 0;
    3222     if (isContextLostOrPending() || !validateHTMLVideoElement("texImage2D", video, ec)
    3223         || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
    3224         return;
    3225 
    3226     // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
    3227     // Otherwise, it will fall back to the normal SW path.
    3228     // FIXME: The current restrictions require that format shoud be RGB or RGBA,
    3229     // type should be UNSIGNED_BYTE and level should be 0. It may be lifted in the future.
    3230     WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
    3231     if (GraphicsContext3D::TEXTURE_2D == target && texture
    3232         && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
    3233         && type == GraphicsContext3D::UNSIGNED_BYTE
    3234         && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))
    3235         && !level) {
    3236         if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), target, level, internalformat, format, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
    3237             texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
    3238             return;
    3239         }
    3240     }
    3241 
    3242     // Normal pure SW path.
    3243     RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
    3244     if (!image)
    3245         return;
    3246     texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
    3247 }
    32483247#endif
    32493248
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h

    r207715 r207719  
    244244    void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
    245245
    246     void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    247                     GC3Dsizei width, GC3Dsizei height, GC3Dint border,
    248                     GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&&, ExceptionCode&);
    249     void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    250                     GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);
    251     void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    252                     GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);
    253     void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    254                     GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);
    255 #if ENABLE(VIDEO)
    256     void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
    257                     GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);
    258 #endif
     246    void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&&, ExceptionCode&);
     247
     248    using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
     249    void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Optional<TexImageSource>, ExceptionCode&);
    259250
    260251    void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
  • trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl

    r207715 r207719  
    3939typedef unrestricted float GLclampf;
    4040typedef (ArrayBuffer or ArrayBufferView) BufferDataSource;
     41
     42// FIXME: Should allow ImageBitmap too.
     43typedef (ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
    4144
    4245[
     
    613616
    614617    // Supported forms:
    615     [MayThrowLegacyException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
    616   GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
    617     [MayThrowLegacyException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
    618   GLenum format, GLenum type, ImageData? pixels);
    619     [MayThrowLegacyException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
    620   GLenum format, GLenum type, HTMLImageElement? image);
    621     [MayThrowLegacyException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
    622   GLenum format, GLenum type, HTMLCanvasElement? canvas);
    623 #if defined(ENABLE_VIDEO) && ENABLE_VIDEO
    624     [MayThrowLegacyException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
    625   GLenum format, GLenum type, HTMLVideoElement? video);
    626 #endif
     618    [MayThrowLegacyException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
     619    [MayThrowLegacyException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, TexImageSource? source);
    627620
    628621    [MayThrowLegacyException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
Note: See TracChangeset for help on using the changeset viewer.