| 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 c6c516405e22dafefe477ae7466e7859f0554510..60957a197799bcf24886ad87c304cef6a9bc4276 100644
|
| --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| @@ -822,13 +822,13 @@ sk_sp<SkImage> WebGLRenderingContextBase::MakeImageSnapshot(
|
| SharedGpuContext::Gr(), SkBudgeted::kYes, image_info, 0,
|
| image_info.alphaType() == kOpaque_SkAlphaType ? nullptr
|
| : &disable_lcd_props);
|
| - GLuint texture_id = skia::GrBackendObjectToGrGLTextureInfo(
|
| - surface->getTextureHandle(
|
| - SkSurface::kDiscardWrite_TextureHandleAccess))
|
| - ->fID;
|
| + const GrGLTextureInfo* texture_info = skia::GrBackendObjectToGrGLTextureInfo(
|
| + surface->getTextureHandle(SkSurface::kDiscardWrite_TextureHandleAccess));
|
| + GLuint texture_id = texture_info->fID;
|
| + GLenum texture_target = texture_info->fTarget;
|
|
|
| GetDrawingBuffer()->CopyToPlatformTexture(
|
| - gl, texture_id, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, IntPoint(0, 0),
|
| + gl, texture_target, texture_id, true, false, IntPoint(0, 0),
|
| IntRect(IntPoint(0, 0), GetDrawingBuffer()->size()), kBackBuffer);
|
| return surface->makeImageSnapshot();
|
| }
|
| @@ -992,76 +992,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(
|
| @@ -4980,21 +4910,23 @@ void WebGLRenderingContextBase::texImage2D(GLenum target,
|
| SentinelEmptyRect(), 1, 0, exception_state);
|
| }
|
|
|
| -bool WebGLRenderingContextBase::CanUseTexImageByGPU(
|
| - TexImageFunctionID function_id,
|
| - GLint internalformat,
|
| - GLenum type) {
|
| - if (function_id == kTexImage2D &&
|
| - (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.
|
| + // Though, glCopyTextureCHROMIUM can handle RGB5_A1 internalformat by doing a
|
| + // fallback path, but it doesn't know the type info. So, we still cannot do
|
| + // the fallback path in glCopyTextureCHROMIUM for
|
| + // RGBA/RGBA/UNSIGNED_SHORT_5_5_5_1 format and type combination.
|
| + 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 (function_id == kTexSubImage2D &&
|
| - (IsWebGL2OrHigher() || ExtensionEnabled(kOESTextureFloatName) ||
|
| - ExtensionEnabled(kOESTextureHalfFloatName) ||
|
| - ExtensionEnabled(kEXTsRGBName)))
|
| +#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;
|
| }
|
|
|
| @@ -5017,20 +4949,18 @@ SnapshotReason WebGLRenderingContextBase::FunctionIDToSnapshotReason(
|
| void WebGLRenderingContextBase::TexImageCanvasByGPU(
|
| TexImageFunctionID function_id,
|
| HTMLCanvasElement* canvas,
|
| + GLenum target,
|
| GLuint target_texture,
|
| - GLenum target_internalformat,
|
| - GLenum target_type,
|
| - GLint target_level,
|
| GLint xoffset,
|
| GLint yoffset,
|
| const IntRect& source_sub_rectangle) {
|
| if (!canvas->Is3D()) {
|
| ImageBuffer* buffer = canvas->Buffer();
|
| - if (buffer && !buffer->CopyToPlatformTexture(
|
| - FunctionIDToSnapshotReason(function_id), ContextGL(),
|
| - target_texture, target_internalformat, target_type,
|
| - target_level, unpack_premultiply_alpha_, unpack_flip_y_,
|
| - IntPoint(xoffset, yoffset), source_sub_rectangle)) {
|
| + if (buffer &&
|
| + !buffer->CopyToPlatformTexture(
|
| + FunctionIDToSnapshotReason(function_id), ContextGL(), target,
|
| + target_texture, unpack_premultiply_alpha_, unpack_flip_y_,
|
| + IntPoint(xoffset, yoffset), source_sub_rectangle)) {
|
| NOTREACHED();
|
| }
|
| } else {
|
| @@ -5038,9 +4968,9 @@ void WebGLRenderingContextBase::TexImageCanvasByGPU(
|
| ToWebGLRenderingContextBase(canvas->RenderingContext());
|
| ScopedTexture2DRestorer restorer(gl);
|
| if (!gl->GetDrawingBuffer()->CopyToPlatformTexture(
|
| - ContextGL(), target_texture, target_internalformat, target_type,
|
| - target_level, unpack_premultiply_alpha_, !unpack_flip_y_,
|
| - IntPoint(xoffset, yoffset), source_sub_rectangle, kBackBuffer)) {
|
| + ContextGL(), target, target_texture, unpack_premultiply_alpha_,
|
| + !unpack_flip_y_, IntPoint(xoffset, yoffset), source_sub_rectangle,
|
| + kBackBuffer)) {
|
| NOTREACHED();
|
| }
|
| }
|
| @@ -5051,8 +4981,6 @@ void WebGLRenderingContextBase::TexImageByGPU(
|
| WebGLTexture* texture,
|
| GLenum target,
|
| GLint level,
|
| - GLint internalformat,
|
| - GLenum type,
|
| GLint xoffset,
|
| GLint yoffset,
|
| GLint zoffset,
|
| @@ -5065,24 +4993,18 @@ void WebGLRenderingContextBase::TexImageByGPU(
|
| ScopedTexture2DRestorer restorer(this);
|
|
|
| GLuint target_texture = texture->Object();
|
| - GLenum target_type = type;
|
| - GLenum target_internalformat = internalformat;
|
| - GLint target_level = level;
|
| bool possible_direct_copy = false;
|
| - if (function_id == kTexImage2D) {
|
| - possible_direct_copy = Extensions3DUtil::CanUseCopyTextureCHROMIUM(
|
| - target, internalformat, type, level);
|
| + if (function_id == kTexImage2D || function_id == kTexSubImage2D) {
|
| + possible_direct_copy = Extensions3DUtil::CanUseCopyTextureCHROMIUM(target);
|
| }
|
|
|
| GLint copy_x_offset = xoffset;
|
| GLint copy_y_offset = yoffset;
|
| + GLenum copy_target = target;
|
|
|
| // if direct copy is not possible, create a temporary texture and then copy
|
| // from canvas to temporary texture to target texture.
|
| if (!possible_direct_copy) {
|
| - target_level = 0;
|
| - target_internalformat = GL_RGBA;
|
| - target_type = GL_UNSIGNED_BYTE;
|
| ContextGL()->GenTextures(1, &target_texture);
|
| ContextGL()->BindTexture(GL_TEXTURE_2D, target_texture);
|
| ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
| @@ -5093,21 +5015,26 @@ 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, target_internalformat, width,
|
| - height, 0, GL_RGBA, target_type, 0);
|
| + ContextGL()->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
| + GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
| copy_x_offset = 0;
|
| copy_y_offset = 0;
|
| + copy_target = GL_TEXTURE_2D;
|
| }
|
|
|
| - if (image->IsCanvasElement()) {
|
| - TexImageCanvasByGPU(function_id, static_cast<HTMLCanvasElement*>(image),
|
| - target_texture, target_internalformat, target_type,
|
| - target_level, copy_x_offset, copy_y_offset,
|
| - source_sub_rectangle);
|
| - } else {
|
| - TexImageBitmapByGPU(static_cast<ImageBitmap*>(image), target_texture,
|
| - target_internalformat, target_type, target_level,
|
| - !unpack_flip_y_);
|
| + {
|
| + // glCopyTextureCHROMIUM has a DRAW_AND_READBACK path which will call
|
| + // texImage2D. So, reset unpack buffer parameters before that.
|
| + ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
|
| + if (image->IsCanvasElement()) {
|
| + TexImageCanvasByGPU(function_id, static_cast<HTMLCanvasElement*>(image),
|
| + copy_target, target_texture, copy_x_offset,
|
| + copy_y_offset, source_sub_rectangle);
|
| + } else {
|
| + TexImageBitmapByGPU(static_cast<ImageBitmap*>(image), copy_target,
|
| + target_texture, !unpack_flip_y_, copy_x_offset,
|
| + copy_y_offset, source_sub_rectangle);
|
| + }
|
| }
|
|
|
| if (!possible_direct_copy) {
|
| @@ -5184,8 +5111,7 @@ void WebGLRenderingContextBase::TexImageHelperHTMLCanvasElement(
|
| // float/integer/sRGB internal format.
|
| // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is
|
| // upgraded to handle more formats.
|
| - if (!canvas->IsAccelerated() ||
|
| - !CanUseTexImageByGPU(function_id, internalformat, type)) {
|
| + if (!canvas->IsAccelerated() || !CanUseTexImageByGPU(type)) {
|
| // 2D canvas has only FrontBuffer.
|
| TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset,
|
| zoffset, format, type,
|
| @@ -5209,11 +5135,11 @@ void WebGLRenderingContextBase::TexImageHelperHTMLCanvasElement(
|
| TexImage2DBase(target, level, internalformat,
|
| source_sub_rectangle.Width(),
|
| source_sub_rectangle.Height(), 0, format, type, 0);
|
| - TexImageByGPU(function_id, texture, target, level, internalformat, type,
|
| - 0, 0, 0, canvas, adjusted_source_sub_rectangle);
|
| + TexImageByGPU(function_id, texture, target, level, 0, 0, 0, canvas,
|
| + adjusted_source_sub_rectangle);
|
| } else {
|
| - TexImageByGPU(function_id, texture, target, level, GL_RGBA, type, xoffset,
|
| - yoffset, 0, canvas, adjusted_source_sub_rectangle);
|
| + TexImageByGPU(function_id, texture, target, level, xoffset, yoffset, 0,
|
| + canvas, adjusted_source_sub_rectangle);
|
| }
|
| } else {
|
| // 3D functions.
|
| @@ -5297,10 +5223,15 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
|
| source_image_rect == SentinelEmptyRect() ||
|
| source_image_rect ==
|
| IntRect(0, 0, video->videoWidth(), video->videoHeight());
|
| - if (function_id == kTexImage2D && source_image_rect_is_default &&
|
| - depth == 1 && GL_TEXTURE_2D == target &&
|
| - Extensions3DUtil::CanUseCopyTextureCHROMIUM(target, internalformat, type,
|
| - level)) {
|
| + const bool use_copyTextureCHROMIUM =
|
| + function_id == kTexImage2D && source_image_rect_is_default &&
|
| + depth == 1 && GL_TEXTURE_2D == target && CanUseTexImageByGPU(type);
|
| + // Format of source video may be 16-bit format, e.g. Y16 format.
|
| + // glCopyTextureCHROMIUM requires the source texture to be in 8-bit format.
|
| + // Converting 16-bits formated source texture to 8-bits formated texture will
|
| + // cause precision lost. So, uploading such video texture to half float or
|
| + // float texture can not use GPU-GPU path.
|
| + if (use_copyTextureCHROMIUM) {
|
| DCHECK_EQ(xoffset, 0);
|
| DCHECK_EQ(yoffset, 0);
|
| DCHECK_EQ(zoffset, 0);
|
| @@ -5321,7 +5252,26 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
|
| texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
|
| return;
|
| }
|
| + }
|
| +
|
| + if (source_image_rect_is_default) {
|
| + // 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, unpack_flip_y_ || unpack_premultiply_alpha_);
|
| + if (video->TexImageImpl(
|
| + static_cast<WebMediaPlayer::TexImageFunctionID>(function_id),
|
| + target, ContextGL(), level,
|
| + ConvertTexInternalFormat(internalformat, type), format, type,
|
| + xoffset, yoffset, zoffset, unpack_flip_y_,
|
| + unpack_premultiply_alpha_ &&
|
| + unpack_colorspace_conversion_ == GL_NONE)) {
|
| + texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
|
| + return;
|
| + }
|
| + }
|
|
|
| + if (use_copyTextureCHROMIUM) {
|
| // Try using an accelerated image buffer, this allows YUV conversion to be
|
| // done on the GPU.
|
| std::unique_ptr<ImageBufferSurface> surface =
|
| @@ -5343,9 +5293,9 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
|
| // was handled in the paintCurrentFrameInContext() call.
|
|
|
| if (image_buffer->CopyToPlatformTexture(
|
| - FunctionIDToSnapshotReason(function_id), ContextGL(),
|
| - texture->Object(), internalformat, type, level,
|
| - unpack_premultiply_alpha_, unpack_flip_y_, IntPoint(0, 0),
|
| + FunctionIDToSnapshotReason(function_id), ContextGL(), target,
|
| + texture->Object(), unpack_premultiply_alpha_, unpack_flip_y_,
|
| + IntPoint(0, 0),
|
| IntRect(0, 0, video->videoWidth(), video->videoHeight()))) {
|
| texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
|
| return;
|
| @@ -5354,23 +5304,6 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
|
| }
|
| }
|
|
|
| - if (source_image_rect_is_default) {
|
| - // 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, unpack_flip_y_ || unpack_premultiply_alpha_);
|
| - if (video->TexImageImpl(
|
| - static_cast<WebMediaPlayer::TexImageFunctionID>(function_id),
|
| - target, ContextGL(), level,
|
| - ConvertTexInternalFormat(internalformat, type), format, type,
|
| - xoffset, yoffset, zoffset, unpack_flip_y_,
|
| - unpack_premultiply_alpha_ &&
|
| - unpack_colorspace_conversion_ == GL_NONE)) {
|
| - texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
|
| - return;
|
| - }
|
| - }
|
| -
|
| RefPtr<Image> image = VideoFrameToImage(video);
|
| if (!image)
|
| return;
|
| @@ -5384,14 +5317,15 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
|
|
|
| void WebGLRenderingContextBase::TexImageBitmapByGPU(
|
| ImageBitmap* bitmap,
|
| + GLenum target,
|
| GLuint target_texture,
|
| - GLenum target_internalformat,
|
| - GLenum target_type,
|
| - GLint target_level,
|
| - bool flip_y) {
|
| - bitmap->BitmapImage()->CopyToTexture(GetDrawingBuffer()->ContextProvider(),
|
| - target_texture, target_internalformat,
|
| - target_type, flip_y);
|
| + bool flip_y,
|
| + GLint xoffset,
|
| + GLint yoffset,
|
| + const IntRect& source_sub_rect) {
|
| + bitmap->BitmapImage()->CopyToTexture(
|
| + GetDrawingBuffer()->ContextProvider(), target, target_texture, flip_y,
|
| + IntPoint(xoffset, yoffset), source_sub_rect);
|
| }
|
|
|
| void WebGLRenderingContextBase::texImage2D(GLenum target,
|
| @@ -5454,17 +5388,16 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap(
|
|
|
| // TODO(kbr): make this work for sub-rectangles of ImageBitmaps.
|
| if (function_id != kTexSubImage3D && function_id != kTexImage3D &&
|
| - bitmap->IsAccelerated() &&
|
| - CanUseTexImageByGPU(function_id, internalformat, type) &&
|
| + bitmap->IsAccelerated() && CanUseTexImageByGPU(type) &&
|
| !selecting_sub_rectangle) {
|
| if (function_id == kTexImage2D) {
|
| TexImage2DBase(target, level, internalformat, width, height, 0, format,
|
| type, 0);
|
| - TexImageByGPU(function_id, texture, target, level, internalformat, type,
|
| - 0, 0, 0, bitmap, source_sub_rect);
|
| + TexImageByGPU(function_id, texture, target, level, 0, 0, 0, bitmap,
|
| + source_sub_rect);
|
| } else if (function_id == kTexSubImage2D) {
|
| - TexImageByGPU(function_id, texture, target, level, GL_RGBA, type, xoffset,
|
| - yoffset, 0, bitmap, source_sub_rect);
|
| + TexImageByGPU(function_id, texture, target, level, xoffset, yoffset, 0,
|
| + bitmap, source_sub_rect);
|
| }
|
| return;
|
| }
|
|
|