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 ceada6f99d70a5b970eecfcbca4b2276caba176c..b29e86724fa87451995d809bdf34e8926677388c 100644 |
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
@@ -819,13 +819,13 @@ sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshot( |
SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, |
imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr |
: &disableLCDProps); |
- GLuint textureId = skia::GrBackendObjectToGrGLTextureInfo( |
- surface->getTextureHandle( |
- SkSurface::kDiscardWrite_TextureHandleAccess)) |
- ->fID; |
+ const GrGLTextureInfo* textureInfo = skia::GrBackendObjectToGrGLTextureInfo( |
+ surface->getTextureHandle(SkSurface::kDiscardWrite_TextureHandleAccess)); |
+ GLuint textureId = textureInfo->fID; |
+ GLenum textureTarget = textureInfo->fTarget; |
drawingBuffer()->copyToPlatformTexture( |
- gl, textureId, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, IntPoint(0, 0), |
+ gl, textureTarget, textureId, true, false, IntPoint(0, 0), |
IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer); |
return surface->makeImageSnapshot(); |
} |
@@ -989,76 +989,6 @@ static const GLenum kSupportedTypesTexImageSourceES3[] = { |
GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, |
}; |
-bool isUnsignedIntegerFormat(GLenum internalformat) { |
- switch (internalformat) { |
- case GL_R8UI: |
- case GL_R16UI: |
- case GL_R32UI: |
- case GL_RG8UI: |
- case GL_RG16UI: |
- case GL_RG32UI: |
- case GL_RGB8UI: |
- case GL_RGB16UI: |
- case GL_RGB32UI: |
- case GL_RGBA8UI: |
- case GL_RGB10_A2UI: |
- case GL_RGBA16UI: |
- case GL_RGBA32UI: |
- return true; |
- default: |
- return false; |
- } |
-} |
- |
-bool isSignedIntegerFormat(GLenum internalformat) { |
- switch (internalformat) { |
- case GL_R8I: |
- case GL_R16I: |
- case GL_R32I: |
- case GL_RG8I: |
- case GL_RG16I: |
- case GL_RG32I: |
- case GL_RGB8I: |
- case GL_RGB16I: |
- case GL_RGB32I: |
- case GL_RGBA8I: |
- case GL_RGBA16I: |
- case GL_RGBA32I: |
- return true; |
- default: |
- return false; |
- } |
-} |
- |
-bool isIntegerFormat(GLenum internalformat) { |
- return (isUnsignedIntegerFormat(internalformat) || |
- isSignedIntegerFormat(internalformat)); |
-} |
- |
-bool isFloatType(GLenum type) { |
- switch (type) { |
- case GL_FLOAT: |
- case GL_HALF_FLOAT: |
- case GL_HALF_FLOAT_OES: |
- case GL_UNSIGNED_INT_10F_11F_11F_REV: |
- return true; |
- default: |
- return false; |
- } |
-} |
- |
-bool isSRGBFormat(GLenum internalformat) { |
- switch (internalformat) { |
- case GL_SRGB_EXT: |
- case GL_SRGB_ALPHA_EXT: |
- case GL_SRGB8: |
- case GL_SRGB8_ALPHA8: |
- return true; |
- default: |
- return false; |
- } |
-} |
- |
} // namespace |
WebGLRenderingContextBase::WebGLRenderingContextBase( |
@@ -4959,21 +4889,19 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, |
sentinelEmptyRect(), 1, 0, exceptionState); |
} |
-bool WebGLRenderingContextBase::canUseTexImageByGPU( |
- TexImageFunctionID functionID, |
- GLint internalformat, |
- GLenum type) { |
- if (functionID == TexImage2D && |
- (isFloatType(type) || isIntegerFormat(internalformat) || |
- isSRGBFormat(internalformat))) |
+bool WebGLRenderingContextBase::canUseTexImageByGPU(GLenum type) { |
+#if OS(MACOSX) |
+ // RGB5_A1 is not color-renderable on NVIDIA Mac, see crbug.com/676209. |
+ if (type == GL_UNSIGNED_SHORT_5_5_5_1) |
return false; |
- // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more |
- // internal formats. |
- if (functionID == TexSubImage2D && |
- (isWebGL2OrHigher() || extensionEnabled(OESTextureFloatName) || |
- extensionEnabled(OESTextureHalfFloatName) || |
- extensionEnabled(EXTsRGBName))) |
+#endif |
+ // OES_texture_half_float doesn't support HALF_FLOAT_OES type for |
+ // CopyTexImage/CopyTexSubImage. And OES_texture_half_float doesn't require |
+ // HALF_FLOAT_OES type texture to be renderable. So, HALF_FLOAT_OES type |
+ // texture cannot be copied to or drawn to by glCopyTextureCHROMIUM. |
+ if (type == GL_HALF_FLOAT_OES) |
return false; |
+ |
return true; |
} |
@@ -4996,10 +4924,8 @@ SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( |
void WebGLRenderingContextBase::texImageCanvasByGPU( |
TexImageFunctionID functionID, |
HTMLCanvasElement* canvas, |
+ GLenum target, |
GLuint targetTexture, |
- GLenum targetInternalformat, |
- GLenum targetType, |
- GLint targetLevel, |
GLint xoffset, |
GLint yoffset, |
const IntRect& sourceSubRectangle) { |
@@ -5007,10 +4933,9 @@ void WebGLRenderingContextBase::texImageCanvasByGPU( |
ImageBuffer* buffer = canvas->buffer(); |
if (buffer && |
!buffer->copyToPlatformTexture( |
- functionIDToSnapshotReason(functionID), contextGL(), targetTexture, |
- targetInternalformat, targetType, targetLevel, |
- m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(xoffset, yoffset), |
- sourceSubRectangle)) { |
+ functionIDToSnapshotReason(functionID), contextGL(), target, |
+ targetTexture, m_unpackPremultiplyAlpha, m_unpackFlipY, |
+ IntPoint(xoffset, yoffset), sourceSubRectangle)) { |
NOTREACHED(); |
} |
} else { |
@@ -5018,9 +4943,9 @@ void WebGLRenderingContextBase::texImageCanvasByGPU( |
toWebGLRenderingContextBase(canvas->renderingContext()); |
ScopedTexture2DRestorer restorer(gl); |
if (!gl->drawingBuffer()->copyToPlatformTexture( |
- contextGL(), targetTexture, targetInternalformat, targetType, |
- targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, |
- IntPoint(xoffset, yoffset), sourceSubRectangle, BackBuffer)) { |
+ contextGL(), target, targetTexture, m_unpackPremultiplyAlpha, |
+ !m_unpackFlipY, IntPoint(xoffset, yoffset), sourceSubRectangle, |
+ BackBuffer)) { |
NOTREACHED(); |
} |
} |
@@ -5031,8 +4956,6 @@ void WebGLRenderingContextBase::texImageByGPU( |
WebGLTexture* texture, |
GLenum target, |
GLint level, |
- GLint internalformat, |
- GLenum type, |
GLint xoffset, |
GLint yoffset, |
GLint zoffset, |
@@ -5045,24 +4968,18 @@ void WebGLRenderingContextBase::texImageByGPU( |
ScopedTexture2DRestorer restorer(this); |
GLuint targetTexture = texture->object(); |
- GLenum targetType = type; |
- GLenum targetInternalformat = internalformat; |
- GLint targetLevel = level; |
bool possibleDirectCopy = false; |
- if (functionID == TexImage2D) { |
- possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM( |
- target, internalformat, type, level); |
+ if (functionID == TexImage2D || functionID == TexSubImage2D) { |
+ possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target); |
} |
GLint copyXOffset = xoffset; |
GLint copyYOffset = yoffset; |
+ GLenum copyTarget = target; |
// 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; |
contextGL()->GenTextures(1, &targetTexture); |
contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); |
contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, |
@@ -5073,21 +4990,22 @@ void WebGLRenderingContextBase::texImageByGPU( |
GL_CLAMP_TO_EDGE); |
contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, |
GL_CLAMP_TO_EDGE); |
- contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, |
- height, 0, GL_RGBA, targetType, 0); |
+ contextGL()->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, |
+ GL_RGBA, GL_UNSIGNED_BYTE, 0); |
copyXOffset = 0; |
copyYOffset = 0; |
+ copyTarget = GL_TEXTURE_2D; |
} |
+ ScopedUnpackParametersResetRestore temporaryResetUnpack(this); |
if (image->isCanvasElement()) { |
texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), |
- targetTexture, targetInternalformat, targetType, |
- targetLevel, copyXOffset, copyYOffset, |
+ copyTarget, targetTexture, copyXOffset, copyYOffset, |
sourceSubRectangle); |
} else { |
- texImageBitmapByGPU(static_cast<ImageBitmap*>(image), targetTexture, |
- targetInternalformat, targetType, targetLevel, |
- !m_unpackFlipY); |
+ texImageBitmapByGPU(static_cast<ImageBitmap*>(image), copyTarget, |
+ targetTexture, !m_unpackFlipY, copyXOffset, copyYOffset, |
+ sourceSubRectangle); |
} |
if (!possibleDirectCopy) { |
@@ -5164,7 +5082,7 @@ void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement( |
// upgraded to handle more formats. |
if (!canvas->renderingContext() || |
!canvas->renderingContext()->isAccelerated() || |
- !canUseTexImageByGPU(functionID, internalformat, type)) { |
+ !canUseTexImageByGPU(type)) { |
// 2D canvas has only FrontBuffer. |
texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
zoffset, format, type, |
@@ -5187,11 +5105,11 @@ void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement( |
if (functionID == TexImage2D) { |
texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), |
sourceSubRectangle.height(), 0, format, type, 0); |
- texImageByGPU(functionID, texture, target, level, internalformat, type, 0, |
- 0, 0, canvas, adjustedSourceSubRectangle); |
+ texImageByGPU(functionID, texture, target, level, 0, 0, 0, canvas, |
+ adjustedSourceSubRectangle); |
} else { |
- texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, |
- yoffset, 0, canvas, adjustedSourceSubRectangle); |
+ texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
+ canvas, adjustedSourceSubRectangle); |
} |
} else { |
// 3D functions. |
@@ -5273,9 +5191,13 @@ void WebGLRenderingContextBase::texImageHelperHTMLVideoElement( |
sourceImageRect == sentinelEmptyRect() || |
sourceImageRect == |
IntRect(0, 0, video->videoWidth(), video->videoHeight()); |
- if (functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && |
- GL_TEXTURE_2D == target && Extensions3DUtil::canUseCopyTextureCHROMIUM( |
- target, internalformat, type, level)) { |
+ const bool useCopyTextureCHROMIUM = |
+ functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && |
+ GL_TEXTURE_2D == target && canUseTexImageByGPU(type); |
+ // Format of source video may be 16-bit format, e.g. Y16 format. |
+ // glCopyTextureCHROMIUM will cause precision lost when uploading such video |
+ // texture to half float or float texture. |
+ if (useCopyTextureCHROMIUM) { |
DCHECK_EQ(xoffset, 0); |
DCHECK_EQ(yoffset, 0); |
DCHECK_EQ(zoffset, 0); |
@@ -5295,7 +5217,23 @@ void WebGLRenderingContextBase::texImageHelperHTMLVideoElement( |
m_unpackFlipY)) { |
return; |
} |
+ } |
+ |
+ if (sourceImageRectIsDefault) { |
+ // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It |
+ // leaves early for other formats or if frame is stored on GPU. |
+ ScopedUnpackParametersResetRestore( |
+ this, m_unpackFlipY || m_unpackPremultiplyAlpha); |
+ if (video->texImageImpl( |
+ static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target, |
+ contextGL(), level, convertTexInternalFormat(internalformat, type), |
+ format, type, xoffset, yoffset, zoffset, m_unpackFlipY, |
+ m_unpackPremultiplyAlpha && |
+ m_unpackColorspaceConversion == GL_NONE)) |
+ return; |
+ } |
+ if (useCopyTextureCHROMIUM) { |
// Try using an accelerated image buffer, this allows YUV conversion to be |
// done on the GPU. |
std::unique_ptr<ImageBufferSurface> surface = |
@@ -5317,9 +5255,9 @@ void WebGLRenderingContextBase::texImageHelperHTMLVideoElement( |
// was handled in the paintCurrentFrameInContext() call. |
if (imageBuffer->copyToPlatformTexture( |
- functionIDToSnapshotReason(functionID), contextGL(), |
- texture->object(), internalformat, type, level, |
- m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(0, 0), |
+ functionIDToSnapshotReason(functionID), contextGL(), target, |
+ texture->object(), m_unpackPremultiplyAlpha, m_unpackFlipY, |
+ IntPoint(0, 0), |
IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { |
return; |
} |
@@ -5327,20 +5265,6 @@ void WebGLRenderingContextBase::texImageHelperHTMLVideoElement( |
} |
} |
- if (sourceImageRectIsDefault) { |
- // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It |
- // leaves early for other formats or if frame is stored on GPU. |
- ScopedUnpackParametersResetRestore( |
- this, m_unpackFlipY || m_unpackPremultiplyAlpha); |
- if (video->texImageImpl( |
- static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target, |
- contextGL(), level, convertTexInternalFormat(internalformat, type), |
- format, type, xoffset, yoffset, zoffset, m_unpackFlipY, |
- m_unpackPremultiplyAlpha && |
- m_unpackColorspaceConversion == GL_NONE)) |
- return; |
- } |
- |
RefPtr<Image> image = videoFrameToImage(video); |
if (!image) |
return; |
@@ -5351,15 +5275,17 @@ void WebGLRenderingContextBase::texImageHelperHTMLVideoElement( |
unpackImageHeight); |
} |
-void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, |
- GLuint targetTexture, |
- GLenum targetInternalformat, |
- GLenum targetType, |
- GLint targetLevel, |
- bool flipY) { |
- bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), |
- targetTexture, targetInternalformat, |
- targetType, flipY); |
+void WebGLRenderingContextBase::texImageBitmapByGPU( |
+ ImageBitmap* bitmap, |
+ GLenum target, |
+ GLuint targetTexture, |
+ bool flipY, |
+ GLint xoffset, |
+ GLint yoffset, |
+ const IntRect& sourceSubRectangle) { |
+ bitmap->bitmapImage()->copyToTexture( |
+ drawingBuffer()->contextProvider(), target, targetTexture, flipY, |
+ IntPoint(xoffset, yoffset), sourceSubRectangle); |
} |
void WebGLRenderingContextBase::texImage2D(GLenum target, |
@@ -5421,17 +5347,16 @@ void WebGLRenderingContextBase::texImageHelperImageBitmap( |
// TODO(kbr): make this work for sub-rectangles of ImageBitmaps. |
if (functionID != TexSubImage3D && functionID != TexImage3D && |
- bitmap->isAccelerated() && |
- canUseTexImageByGPU(functionID, internalformat, type) && |
+ bitmap->isAccelerated() && canUseTexImageByGPU(type) && |
!selectingSubRectangle) { |
if (functionID == TexImage2D) { |
texImage2DBase(target, level, internalformat, width, height, 0, format, |
type, 0); |
- texImageByGPU(functionID, texture, target, level, internalformat, type, 0, |
- 0, 0, bitmap, sourceSubRect); |
+ texImageByGPU(functionID, texture, target, level, 0, 0, 0, bitmap, |
+ sourceSubRect); |
} else if (functionID == TexSubImage2D) { |
- texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, |
- yoffset, 0, bitmap, sourceSubRect); |
+ texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
+ bitmap, sourceSubRect); |
} |
return; |
} |