Chromium Code Reviews| Index: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| index b67e4a6ca84ce244d459c1346e967d5601da75c9..2a2364ae6b33317c9d6fff34a6b1d5de408a348b 100644 |
| --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| @@ -4051,50 +4051,93 @@ PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer(PassRefPtr<Imag |
| return buf->newImageSnapshot(); |
| } |
| -void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| - GLsizei width, GLsizei height, GLint border, |
| - GLenum format, GLenum type, DOMArrayBufferView* pixels) |
| +void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView(const char* funcType, GLenum target, GLint level, GLint internalformat, |
| + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei depth, |
| + GLint xoffset, GLint yoffset, GLint zoffset, DOMArrayBufferView* pixels) |
| { |
| if (isContextLost()) |
| return; |
| - if (!validateTexture2DBinding("texImage2D", target)) |
| + if ((!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D")) && !validateTexture2DBinding(funcType, target)) |
| return; |
| - if (!validateTexFunc("texImage2D", TexImage, SourceArrayBufferView, target, level, internalformat, width, height, 1, border, format, type, 0, 0, 0)) |
| + if ((!strcmp(funcType, "texImage3D") || !strcmp(funcType, "texSubImage3D")) && !validateTexture3DBinding(funcType, target)) |
|
xidachen
2016/05/31 02:11:41
Yes, the error is because validateTexture3DBinding
|
| return; |
| - if (!validateTexFuncData("texImage2D", Tex2D, level, width, height, 1, format, type, pixels, NullAllowed)) |
| + TexImageFunctionType functionType; |
| + if (!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texImage3D")) |
| + functionType = TexImage; |
| + else |
| + functionType = TexSubImage; |
| + if (!validateTexFunc(funcType, functionType, SourceArrayBufferView, target, level, internalformat, width, height, depth, border, format, type, xoffset, yoffset, zoffset)) |
| + return; |
| + TexImageDimension sourceType; |
| + if (!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D")) |
| + sourceType = Tex2D; |
| + else |
| + sourceType = Tex3D; |
| + if (!validateTexFuncData(funcType, sourceType, level, width, height, depth, format, type, pixels, NullAllowed)) |
| return; |
| void* data = pixels ? pixels->baseAddress() : 0; |
| Vector<uint8_t> tempData; |
| bool changeUnpackAlignment = false; |
| if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) { |
| - if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData)) |
| - return; |
| - data = tempData.data(); |
| + if (!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D")) { |
| + if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData)) |
| + return; |
| + data = tempData.data(); |
| + } else { |
| + NOTIMPLEMENTED(); |
| + if (!strcmp(funcType, "texImage3D")) |
| + return; |
| + } |
| changeUnpackAlignment = true; |
| } |
| + if (!strcmp(funcType, "texImage3D")) { |
| + contextGL()->TexImage3D(target, level, convertTexInternalFormat(internalformat, type), width, height, depth, border, format, type, data); |
| + return; |
| + } |
| + |
| if (changeUnpackAlignment) |
| resetUnpackParameters(); |
| - texImage2DBase(target, level, internalformat, width, height, border, format, type, data); |
| + if (!strcmp(funcType, "texImage2D")) |
| + texImage2DBase(target, level, internalformat, width, height, border, format, type, data); |
| + else if (!strcmp(funcType, "texSubImage2D")) |
| + contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data); |
| + else |
| + contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data); |
| if (changeUnpackAlignment) |
| restoreUnpackParameters(); |
| } |
| void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| - GLenum format, GLenum type, ImageData* pixels) |
| + GLsizei width, GLsizei height, GLint border, |
| + GLenum format, GLenum type, DOMArrayBufferView* pixels) |
| +{ |
| + texImageHelperDOMArrayBufferView("texImage2D", target, level, internalformat, width, height, border, format, type, 1, 0, 0, 0, pixels); |
| +} |
| + |
| +void WebGLRenderingContextBase::texImageHelperImageData(const char* funcType, GLenum target, GLint level, GLint internalformat, |
| + GLint border, GLenum format, GLenum type, GLsizei depth, |
| + GLint xoffset, GLint yoffset, GLint zoffset, ImageData* pixels) |
| { |
| if (isContextLost()) |
| return; |
| if (!pixels) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "no image data"); |
| + synthesizeGLError(GL_INVALID_VALUE, funcType, "no image data"); |
| return; |
| } |
| if (pixels->data()->bufferBase()->isNeutered()) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "The source data has been neutered."); |
| + synthesizeGLError(GL_INVALID_VALUE, funcType, "The source data has been neutered."); |
| return; |
| } |
| - if (!validateTexture2DBinding("texImage2D", target)) |
| + if ((!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D")) && !validateTexture2DBinding(funcType, target)) |
| + return; |
| + if (!strcmp(funcType, "texSubImage3D") && !validateTexture3DBinding(funcType, target)) |
| return; |
| - if (!validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 1, 0, format, type, 0, 0, 0)) |
| + TexImageFunctionType functionType; |
| + if (!strcmp(funcType, "texImage2D")) |
| + functionType = TexImage; |
| + else |
| + functionType = TexSubImage; |
| + if (!validateTexFunc(funcType, functionType, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), depth, border, format, type, xoffset, yoffset, zoffset)) |
| return; |
| Vector<uint8_t> data; |
| bool needConversion = true; |
| @@ -4108,37 +4151,67 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int |
| type = GL_FLOAT; |
| } |
| if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data"); |
| + synthesizeGLError(GL_INVALID_VALUE, funcType, "bad image data"); |
| return; |
| } |
| } |
| resetUnpackParameters(); |
| - texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data()); |
| + if (!strcmp(funcType, "texImage2D")) |
| + texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), border, format, type, needConversion ? data.data() : pixels->data()->data()); |
| + else if (!strcmp(funcType, "texSubImage2D")) |
| + contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data()); |
| + else // must be "texSubImage3D" |
| + contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, pixels->width(), pixels->height(), depth, format, type, needConversion ? data.data() : pixels->data()->data()); |
| restoreUnpackParameters(); |
| } |
| void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| - GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState) |
| + GLenum format, GLenum type, ImageData* pixels) |
| +{ |
| + texImageHelperImageData("texImage2D", target, level, internalformat, 0, format, type, 1, 0, 0, 0, pixels); |
| +} |
| + |
| +bool WebGLRenderingContextBase::texImageHelperHTMLImageElement(const char* funcType, GLenum target, GLint level, GLint internalformat, |
| + GLenum format, GLenum type, GLint xoffset, GLint yoffset, GLint zoffset, HTMLImageElement* image, ExceptionState& exceptionState) |
| { |
| if (isContextLost()) |
| - return; |
| - if (!validateHTMLImageElement("texImage2D", image, exceptionState)) |
| - return; |
| - if (!validateTexture2DBinding("texImage2D", target)) |
| - return; |
| + return false; |
| + if (!validateHTMLImageElement(funcType, image, exceptionState)) |
| + return false; |
| + if ((!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D")) && !validateTexture2DBinding(funcType, target)) |
| + return false; |
| + if (!strcmp(funcType, "texSubImage3D") && !validateTexture3DBinding(funcType, target)) |
| + return false; |
| + if (!strcmp(funcType, "texSubImage3D")) |
| + return true; |
| RefPtr<Image> imageForRender = image->cachedImage()->getImage(); |
| if (imageForRender && imageForRender->isSVGImage()) |
| - imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), "texImage2D"); |
| + imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), funcType); |
| - if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 1, 0, format, type, 0, 0, 0)) |
| - return; |
| + TexImageFunctionType functionType; |
| + if (!strcmp(funcType, "texImage2D")) |
| + functionType = TexImage; |
| + else |
| + functionType = TexSubImage; |
| + if (!imageForRender || !validateTexFunc(funcType, functionType, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) |
| + return false; |
| if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| type = GL_FLOAT; |
| } |
| - texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha); |
| + if (!strcmp(funcType, "texImage2D")) |
| + texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha); |
| + else if (!strcmp(funcType, "texSubImage2D")) |
| + texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha); |
| + return true; |
| +} |
| + |
| +void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| + GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState) |
| +{ |
| + texImageHelperHTMLImageElement("texImage2D", target, level, internalformat, format, type, 0, 0, 0, image, exceptionState); |
| } |
| bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) |
| @@ -4212,19 +4285,36 @@ void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy |
| } |
| } |
| +WebGLTexture* WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(const char* funcType, GLenum target, GLint level, GLint internalformat, |
| + GLenum format, GLenum type, GLint xoffset, GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exceptionState) |
| +{ |
| + if (isContextLost()) |
| + return nullptr; |
| + if (!validateHTMLCanvasElement(funcType, canvas, exceptionState)) |
| + return nullptr; |
| + WebGLTexture* texture = nullptr; |
| + if (!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D") |
| + texture = validateTexture2DBinding(funcType, target); |
| + else |
| + texture = validateTexture3DBinding(funcType, target); |
| + if (!texture) |
| + return nullptr; |
| + TexImageFunctionType functionType; |
| + if (!strcmp(funcType, "texImage2D")) |
| + functionType = TexImage; |
| + else |
| + functionType = TexSubImage; |
| + if (!validateTexFunc(funcType, functionType, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) |
| + return nullptr; |
| + return texture; |
| +} |
| + |
| void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!validateHTMLCanvasElement("texImage2D", canvas, exceptionState)) |
| - return; |
| - WebGLTexture* texture = validateTexture2DBinding("texImage2D", target); |
| + WebGLTexture* texture = texImageHelperHTMLCanvasElement("texImage2D", target, level, internalformat, format, type, 0, 0, 0, canvas, exceptionState); |
| if (!texture) |
| return; |
| - if (!validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0)) |
| - return; |
| - |
| // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support float/integer/sRGB internal format. |
| // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. |
| if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated() || !canUseTexImageCanvasByGPU(internalformat, type)) { |
| @@ -4251,19 +4341,36 @@ PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* |
| return buf->newImageSnapshot(); |
| } |
| +WebGLTexture* WebGLRenderingContextBase::texImageHelperHTMLVideoElement(const char* funcType, GLenum target, GLint level, GLint internalformat, |
| + GLenum format, GLenum type, GLint xoffset, GLint yoffset, GLint zoffset, HTMLVideoElement* video, ExceptionState& exceptionState) |
| +{ |
| + if (isContextLost()) |
| + return nullptr; |
| + if (!validateHTMLVideoElement(funcType, video, exceptionState)) |
| + return nullptr; |
| + WebGLTexture* texture = nullptr; |
| + if (!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D") |
| + texture = validateTexture2DBinding(funcType, target); |
| + else |
| + texture = validateTexture3DBinding(funcType, target); |
| + if (!texture) |
| + return nullptr; |
| + TexImageFunctionType functionType; |
| + if (!strcmp(funcType, "texImage2D")) |
| + functionType = TexImage; |
| + else |
| + functionType = TexSubImage; |
| + if (!validateTexFunc(funcType, functionType, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, zoffset)) |
| + return nullptr; |
| + return texture; |
| +} |
| + |
| void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!validateHTMLVideoElement("texImage2D", video, exceptionState)) |
| - return; |
| - WebGLTexture* texture = validateTexture2DBinding("texImage2D", target); |
| + WebGLTexture* texture = texImageHelperHTMLVideoElement("texImage2D", target, level, internalformat, format, type, 0, 0, 0, video, exceptionState); |
| if (!texture) |
| return; |
| - if (!validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, 0, 0, 0)) |
| - return; |
| - |
| // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible. |
| // Otherwise, it will fall back to the normal SW path. |
| if (GL_TEXTURE_2D == target) { |
| @@ -4298,16 +4405,23 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int |
| texImage2DImpl(target, level, internalformat, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); |
| } |
| -void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| - GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionState) |
| +void WebGLRenderingContextBase::texImageHelperImageBitmap(const char* funcType, GLenum target, GLint level, GLint internalformat, |
| + GLenum format, GLenum type, GLint xoffset, GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exceptionState) |
| { |
| if (isContextLost()) |
| return; |
| - if (!validateImageBitmap("texImage2D", bitmap, exceptionState)) |
| + if (!validateImageBitmap(funcType, bitmap, exceptionState)) |
| return; |
| - if (!validateTexture2DBinding("texImage2D", target)) |
| + if ((!strcmp(funcType, "texImage2D") || !strcmp(funcType, "texSubImage2D")) && !validateTexture2DBinding(funcType, target)) |
| return; |
| - if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, level, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0)) |
| + if (!strcmp(funcType, "texSubImage3D") && !validateTexture3DBinding(funcType, target)) |
| + return; |
| + TexImageFunctionType functionType; |
| + if (!strcmp(funcType, "texImage2D")) |
| + functionType = TexImage; |
| + else |
| + functionType = TexSubImage; |
| + if (!validateTexFunc(funcType, functionType, SourceImageBitmap, target, level, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) |
| return; |
| ASSERT(bitmap->bitmapImage()); |
| RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); |
| @@ -4338,15 +4452,26 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int |
| bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType); |
| if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) |
| || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), format, type, false, false, data))) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data"); |
| + synthesizeGLError(GL_INVALID_VALUE, funcType, "bad image data"); |
| return; |
| } |
| } |
| resetUnpackParameters(); |
| - texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->height(), 0, format, type, needConversion ? data.data() : pixelDataPtr); |
| + if (!strcmp(funcType, "texImage2D")) |
| + texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->height(), 0, format, type, needConversion ? data.data() : pixelDataPtr); |
| + else if (!strcmp(funcType, "texSubImage2D")) |
| + contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr); |
| + else // must be "texSubImage3D" |
| + contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, bitmap->width(), bitmap->height(), 1, format, type, needConversion ? data.data() : pixelDataPtr); |
| restoreUnpackParameters(); |
| } |
| +void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat, |
| + GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionState) |
| +{ |
| + texImageHelperImageBitmap("texImage2D", target, level, internalformat, format, type, 0, 0, 0, bitmap, exceptionState); |
| +} |
| + |
| void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloat paramf, GLint parami, bool isFloat) |
| { |
| if (isContextLost()) |
| @@ -4445,105 +4570,27 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint |
| GLsizei width, GLsizei height, |
| GLenum format, GLenum type, DOMArrayBufferView* pixels) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!validateTexture2DBinding("texSubImage2D", target)) |
| - return; |
| - if (!validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, 0, width, height, 1, 0, format, type, xoffset, yoffset, 0)) |
| - return; |
| - if (!validateTexFuncData("texSubImage2D", Tex2D, level, width, height, 1, format, type, pixels, NullNotAllowed)) |
| - return; |
| - void* data = pixels->baseAddress(); |
| - Vector<uint8_t> tempData; |
| - bool changeUnpackAlignment = false; |
| - if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) { |
| - if (!WebGLImageConversion::extractTextureData(width, height, format, type, |
| - m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData)) |
| - return; |
| - data = tempData.data(); |
| - changeUnpackAlignment = true; |
| - } |
| - if (changeUnpackAlignment) |
| - resetUnpackParameters(); |
| - contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data); |
| - if (changeUnpackAlignment) |
| - restoreUnpackParameters(); |
| + texImageHelperDOMArrayBufferView("texSubImage2D", target, level, 0, width, height, 0, format, type, 1, xoffset, yoffset, 0, pixels); |
| } |
| void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
| GLenum format, GLenum type, ImageData* pixels) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!pixels) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "no image data"); |
| - return; |
| - } |
| - if (pixels->data()->bufferBase()->isNeutered()) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "The source data has been neutered."); |
| - return; |
| - } |
| - if (!validateTexture2DBinding("texSubImage2D", target)) |
| - return; |
| - if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, 0, pixels->width(), pixels->height(), 1, 0, format, type, xoffset, yoffset, 0)) |
| - return; |
| - if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| - // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| - type = GL_FLOAT; |
| - } |
| - Vector<uint8_t> data; |
| - bool needConversion = true; |
| - // The data from ImageData is always of format RGBA8. |
| - // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required. |
| - if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha) { |
| - needConversion = false; |
| - } else { |
| - if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data"); |
| - return; |
| - } |
| - } |
| - resetUnpackParameters(); |
| - contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data()); |
| - restoreUnpackParameters(); |
| + texImageHelperImageData("texSubImage2D", target, level, 0, 0, format, type, 1, xoffset, yoffset, 0, pixels); |
| } |
| void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
| GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!validateHTMLImageElement("texSubImage2D", image, exceptionState)) |
| - return; |
| - if (!validateTexture2DBinding("texSubImage2D", target)) |
| - return; |
| - |
| - RefPtr<Image> imageForRender = image->cachedImage()->getImage(); |
| - if (imageForRender && imageForRender->isSVGImage()) |
| - imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), "texSubImage2D"); |
| - |
| - if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, 0, imageForRender->width(), imageForRender->height(), 1, 0, format, type, xoffset, yoffset, 0)) |
| - return; |
| - |
| - if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| - // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| - type = GL_FLOAT; |
| - } |
| - texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha); |
| + texImageHelperHTMLImageElement("texSubImage2D", target, level, 0, format, type, xoffset, yoffset, 0, image, exceptionState); |
| } |
| void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
| GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)) |
| - return; |
| - WebGLTexture* texture = validateTexture2DBinding("texSubImage2D", target); |
| + WebGLTexture* texture = texImageHelperHTMLCanvasElement("texSubImage2D", target, level, 0, format, type, xoffset, yoffset, 0, canvas, exceptionState); |
| if (!texture) |
| return; |
| - if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, 0)) |
| - return; |
| // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats. |
| bool useReadBackPath = isWebGL2OrHigher() |
| @@ -4565,13 +4612,8 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint |
| void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
| GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!validateHTMLVideoElement("texSubImage2D", video, exceptionState)) |
| - return; |
| - if (!validateTexture2DBinding("texSubImage2D", target)) |
| - return; |
| - if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, 0, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, 0)) |
| + WebGLTexture* texture = texImageHelperHTMLVideoElement("texSubImage2D", target, level, 0, format, type, xoffset, yoffset, 0, video, exceptionState); |
| + if (!texture) |
| return; |
| RefPtr<Image> image = videoFrameToImage(video); |
| @@ -4583,48 +4625,7 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint |
| void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
| GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionState) |
| { |
| - if (isContextLost()) |
| - return; |
| - if (!validateImageBitmap("texSubImage2D", bitmap, exceptionState)) |
| - return; |
| - if (!validateTexture2DBinding("texSubImage2D", target)) |
| - return; |
| - if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target, level, 0, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0)) |
| - return; |
| - if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| - // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| - type = GL_FLOAT; |
| - } |
| - ASSERT(bitmap->bitmapImage()); |
| - RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); |
| - SkPixmap pixmap; |
| - OwnPtr<uint8_t[]> pixelData; |
| - uint8_t* pixelDataPtr = nullptr; |
| - bool peekSucceed = skImage->peekPixels(&pixmap); |
| - if (peekSucceed) { |
| - pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr()); |
| - } else if (skImage->isTextureBacked()) { |
| - pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); |
| - pixelDataPtr = pixelData.get(); |
| - } |
| - Vector<uint8_t> data; |
| - bool needConversion = true; |
| - bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::kRGBA_8888_SkColorType); |
| - bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed); |
| - if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { |
| - needConversion = false; |
| - } else { |
| - // In the case of ImageBitmap, we do not need to apply flipY or premultiplyAlpha. |
| - bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType); |
| - if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) |
| - || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), format, type, false, false, data))) { |
| - synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data"); |
| - return; |
| - } |
| - } |
| - resetUnpackParameters(); |
| - contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr); |
| - restoreUnpackParameters(); |
| + texImageHelperImageBitmap("texSubImage2D", target, level, 0, format, type, xoffset, yoffset, 0, bitmap, exceptionState); |
| } |
| void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) |