| 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;
|
| }
|
|
|