| Index: Source/core/html/canvas/WebGLRenderingContextBase.cpp
|
| diff --git a/Source/core/html/canvas/WebGLRenderingContextBase.cpp b/Source/core/html/canvas/WebGLRenderingContextBase.cpp
|
| index efeab45ec32ed47ca0f9f0bfc08d92ad83c60ee4..9bfe64069d998ef6c4c77938d4f1ac6ceffb1388 100644
|
| --- a/Source/core/html/canvas/WebGLRenderingContextBase.cpp
|
| +++ b/Source/core/html/canvas/WebGLRenderingContextBase.cpp
|
| @@ -3457,7 +3457,7 @@ void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLenu
|
| webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
|
| }
|
|
|
| -bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset)
|
| +bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexImageFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset)
|
| {
|
| if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
|
| return false;
|
| @@ -3593,6 +3593,72 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
|
| texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
|
| }
|
|
|
| +void WebGLRenderingContextBase::texImage2DCanvasByGPU(TexImageFunctionType functionType, WebGLTexture* texture, GLenum target,
|
| + GLint level, GLenum internalformat, GLenum type, GLint xoffset, GLint yoffset, HTMLCanvasElement* canvas)
|
| +{
|
| + ScopedTexture2DRestorer restorer(this);
|
| +
|
| + Platform3DObject targetTexture = texture->object();
|
| + GLenum targetType = type;
|
| + GLenum targetInternalformat = internalformat;
|
| + GLint targetLevel = level;
|
| + bool possibleDirectCopy = false;
|
| + if (functionType == NotTexSubImage2D) {
|
| + possibleDirectCopy = GL_TEXTURE_2D == target && Extensions3DUtil::canUseCopyTextureCHROMIUM(internalformat, type, level);
|
| + } else if (functionType == TexSubImage2D) {
|
| + possibleDirectCopy = false;
|
| + }
|
| + // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture.
|
| + if (!possibleDirectCopy) {
|
| + targetLevel = 0;
|
| + targetInternalformat = GL_RGBA;
|
| + targetType = GL_UNSIGNED_BYTE;
|
| + targetTexture = webContext()->createTexture();
|
| + webContext()->bindTexture(GL_TEXTURE_2D, targetTexture);
|
| + webContext()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| + webContext()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| + webContext()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| + webContext()->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| + webContext()->texImage2D(GL_TEXTURE_2D, 0, targetInternalformat, canvas->width(),
|
| + canvas->height(), 0, GL_RGBA, targetType, 0);
|
| + }
|
| +
|
| + if (!canvas->is3D()) {
|
| + ImageBuffer* buffer = canvas->buffer();
|
| + if (!buffer)
|
| + return;
|
| + if (!buffer->copyToPlatformTexture(webContext(), targetTexture, targetInternalformat, targetType,
|
| + targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
|
| + ASSERT_NOT_REACHED();
|
| + }
|
| + } else {
|
| + WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
|
| + if (!gl)
|
| + return;
|
| + ScopedTexture2DRestorer restorer(gl);
|
| + if (!gl->drawingBuffer()->copyToPlatformTexture(webContext(), targetTexture, targetInternalformat, targetType,
|
| + targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
|
| + ASSERT_NOT_REACHED();
|
| + }
|
| + }
|
| +
|
| + if (!possibleDirectCopy) {
|
| + WebGLId tmpFBO = webContext()->createFramebuffer();
|
| + webContext()->bindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
|
| + webContext()->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0);
|
| + webContext()->bindTexture(texture->getTarget(), texture->object());
|
| + if (functionType == NotTexSubImage2D) {
|
| + webContext()->copyTexImage2D(target, level, internalformat, 0, 0, canvas->width(), canvas->height(), 0);
|
| + } else if (functionType == TexSubImage2D) {
|
| + webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, 0, 0, canvas->width(), canvas->height());
|
| + }
|
| + webContext()->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
| + restoreCurrentFramebuffer();
|
| + webContext()->deleteFramebuffer(tmpFBO);
|
| + webContext()->deleteTexture(targetTexture);
|
| + }
|
| +}
|
| +
|
| void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
|
| GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
|
| {
|
| @@ -3600,31 +3666,17 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
|
| return;
|
|
|
| WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
|
| + ASSERT(texture);
|
|
|
| - // If possible, copy from the canvas element directly to the texture
|
| - // via the GPU, without a read-back to system memory.
|
| - if (GL_TEXTURE_2D == target && texture) {
|
| - ScopedTexture2DRestorer restorer(this);
|
| -
|
| - if (!canvas->is3D()) {
|
| - ImageBuffer* buffer = canvas->buffer();
|
| - if (buffer && buffer->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
|
| - level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
|
| - texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
|
| - return;
|
| - }
|
| - } else {
|
| - WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
|
| - ScopedTexture2DRestorer restorer(gl);
|
| - if (gl && gl->drawingBuffer()->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
|
| - level, m_unpackPremultiplyAlpha, !m_unpackFlipY, BackBuffer)) {
|
| - texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
|
| - return;
|
| - }
|
| - }
|
| + if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated()) {
|
| + ASSERT(!canvas->renderingContext() || canvas->renderingContext()->is2d());
|
| + texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(),
|
| + WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
|
| + return;
|
| }
|
|
|
| - texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(BackBuffer), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
|
| + texImage2DCanvasByGPU(NotTexSubImage2D, texture, target, level, internalformat, type, 0, 0, canvas);
|
| + texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
|
| }
|
|
|
| PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
|
| @@ -3858,7 +3910,17 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint
|
| || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
|
| return;
|
|
|
| - texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(BackBuffer), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
|
| + WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
|
| + ASSERT(texture);
|
| +
|
| + if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated()) {
|
| + ASSERT(!canvas->renderingContext() || canvas->renderingContext()->is2d());
|
| + texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(),
|
| + WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
|
| + return;
|
| + }
|
| +
|
| + texImage2DCanvasByGPU(TexSubImage2D, texture, target, level, GL_RGBA, type, xoffset, yoffset, canvas);
|
| }
|
|
|
| void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
| @@ -4819,7 +4881,7 @@ bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, G
|
| return true;
|
| }
|
|
|
| -bool WebGLRenderingContextBase::validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType functionType,
|
| +bool WebGLRenderingContextBase::validateTexFuncDimensions(const char* functionName, TexImageFunctionType functionType,
|
| GLenum target, GLint level, GLsizei width, GLsizei height)
|
| {
|
| if (width < 0 || height < 0) {
|
| @@ -4858,7 +4920,7 @@ bool WebGLRenderingContextBase::validateTexFuncDimensions(const char* functionNa
|
| return true;
|
| }
|
|
|
| -bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target,
|
| +bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName, TexImageFunctionType functionType, GLenum target,
|
| GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type)
|
| {
|
| // We absolutely have to validate the format and type combination.
|
| @@ -5031,7 +5093,7 @@ bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functi
|
| return true;
|
| }
|
|
|
| -bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format)
|
| +bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, TexImageFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format)
|
| {
|
| if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
|
| return false;
|
|
|