Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 2738163002: Enable CopyTextureCHROMIUM in Blink for Tex{Sub}Image2D with more cases (Closed)
Patch Set: enable fallback path Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshot( 812 sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshot(
813 SkImageInfo& imageInfo) { 813 SkImageInfo& imageInfo) {
814 drawingBuffer()->resolveAndBindForReadAndDraw(); 814 drawingBuffer()->resolveAndBindForReadAndDraw();
815 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); 815 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl();
816 816
817 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); 817 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
818 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( 818 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
819 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, 819 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0,
820 imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr 820 imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr
821 : &disableLCDProps); 821 : &disableLCDProps);
822 GLuint textureId = skia::GrBackendObjectToGrGLTextureInfo( 822 const GrGLTextureInfo* textureInfo = skia::GrBackendObjectToGrGLTextureInfo(
823 surface->getTextureHandle( 823 surface->getTextureHandle(SkSurface::kDiscardWrite_TextureHandleAccess));
824 SkSurface::kDiscardWrite_TextureHandleAccess)) 824 GLuint textureId = textureInfo->fID;
825 ->fID; 825 GLenum textureTarget = textureInfo->fTarget;
826 826
827 drawingBuffer()->copyToPlatformTexture( 827 drawingBuffer()->copyToPlatformTexture(
828 gl, textureId, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, IntPoint(0, 0), 828 gl, textureTarget, textureId, true, false, IntPoint(0, 0),
829 IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer); 829 IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer);
830 return surface->makeImageSnapshot(); 830 return surface->makeImageSnapshot();
831 } 831 }
832 832
833 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { 833 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) {
834 ImageData* imageData = nullptr; 834 ImageData* imageData = nullptr;
835 // TODO(ccameron): WebGL should produce sRGB images. 835 // TODO(ccameron): WebGL should produce sRGB images.
836 // https://crbug.com/672299 836 // https://crbug.com/672299
837 if (drawingBuffer()) { 837 if (drawingBuffer()) {
838 // For un-premultiplied data 838 // For un-premultiplied data
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 GL_UNSIGNED_INT_5_9_9_9_REV, 982 GL_UNSIGNED_INT_5_9_9_9_REV,
983 GL_UNSIGNED_INT_24_8, 983 GL_UNSIGNED_INT_24_8,
984 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 984 GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
985 }; 985 };
986 986
987 // ES3 enums supported by TexImageSource 987 // ES3 enums supported by TexImageSource
988 static const GLenum kSupportedTypesTexImageSourceES3[] = { 988 static const GLenum kSupportedTypesTexImageSourceES3[] = {
989 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, 989 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV,
990 }; 990 };
991 991
992 bool isUnsignedIntegerFormat(GLenum internalformat) {
993 switch (internalformat) {
994 case GL_R8UI:
995 case GL_R16UI:
996 case GL_R32UI:
997 case GL_RG8UI:
998 case GL_RG16UI:
999 case GL_RG32UI:
1000 case GL_RGB8UI:
1001 case GL_RGB16UI:
1002 case GL_RGB32UI:
1003 case GL_RGBA8UI:
1004 case GL_RGB10_A2UI:
1005 case GL_RGBA16UI:
1006 case GL_RGBA32UI:
1007 return true;
1008 default:
1009 return false;
1010 }
1011 }
1012
1013 bool isSignedIntegerFormat(GLenum internalformat) {
1014 switch (internalformat) {
1015 case GL_R8I:
1016 case GL_R16I:
1017 case GL_R32I:
1018 case GL_RG8I:
1019 case GL_RG16I:
1020 case GL_RG32I:
1021 case GL_RGB8I:
1022 case GL_RGB16I:
1023 case GL_RGB32I:
1024 case GL_RGBA8I:
1025 case GL_RGBA16I:
1026 case GL_RGBA32I:
1027 return true;
1028 default:
1029 return false;
1030 }
1031 }
1032
1033 bool isIntegerFormat(GLenum internalformat) {
1034 return (isUnsignedIntegerFormat(internalformat) ||
1035 isSignedIntegerFormat(internalformat));
1036 }
1037
1038 bool isFloatType(GLenum type) {
1039 switch (type) {
1040 case GL_FLOAT:
1041 case GL_HALF_FLOAT:
1042 case GL_HALF_FLOAT_OES:
1043 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1044 return true;
1045 default:
1046 return false;
1047 }
1048 }
1049
1050 bool isSRGBFormat(GLenum internalformat) {
1051 switch (internalformat) {
1052 case GL_SRGB_EXT:
1053 case GL_SRGB_ALPHA_EXT:
1054 case GL_SRGB8:
1055 case GL_SRGB8_ALPHA8:
1056 return true;
1057 default:
1058 return false;
1059 }
1060 }
1061
1062 } // namespace 992 } // namespace
1063 993
1064 WebGLRenderingContextBase::WebGLRenderingContextBase( 994 WebGLRenderingContextBase::WebGLRenderingContextBase(
1065 OffscreenCanvas* passedOffscreenCanvas, 995 OffscreenCanvas* passedOffscreenCanvas,
1066 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, 996 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
1067 const CanvasContextCreationAttributes& requestedAttributes, 997 const CanvasContextCreationAttributes& requestedAttributes,
1068 unsigned version) 998 unsigned version)
1069 : WebGLRenderingContextBase( 999 : WebGLRenderingContextBase(
1070 nullptr, 1000 nullptr,
1071 passedOffscreenCanvas, 1001 passedOffscreenCanvas,
(...skipping 3880 matching lines...) Expand 10 before | Expand all | Expand 10 after
4952 GLint internalformat, 4882 GLint internalformat,
4953 GLenum format, 4883 GLenum format,
4954 GLenum type, 4884 GLenum type,
4955 HTMLImageElement* image, 4885 HTMLImageElement* image,
4956 ExceptionState& exceptionState) { 4886 ExceptionState& exceptionState) {
4957 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, 4887 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat,
4958 format, type, 0, 0, 0, image, 4888 format, type, 0, 0, 0, image,
4959 sentinelEmptyRect(), 1, 0, exceptionState); 4889 sentinelEmptyRect(), 1, 0, exceptionState);
4960 } 4890 }
4961 4891
4962 bool WebGLRenderingContextBase::canUseTexImageByGPU( 4892 bool WebGLRenderingContextBase::canUseTexImageByGPU(GLenum type) {
4963 TexImageFunctionID functionID, 4893 #if OS(MACOSX)
4964 GLint internalformat, 4894 // RGB5_A1 is not color-renderable on NVIDIA Mac, see crbug.com/676209.
4965 GLenum type) { 4895 // Though, glCopyTextureCHROMIUM can handle RGB5_A1 internalformat by doing a
4966 if (functionID == TexImage2D && 4896 // fallback path, but it doesn't know the type info. So, we still cannot do
Zhenyao Mo 2017/03/31 21:12:59 Maybe I miss something, but in command buffer side
qiankun 2017/04/05 08:43:16 We can detect the type info as you said. The fallb
4967 (isFloatType(type) || isIntegerFormat(internalformat) || 4897 // the fallback path in glCopyTextureCHROMIUM for
4968 isSRGBFormat(internalformat))) 4898 // RGBA/RGBA/UNSIGNED_SHORT_5_5_5_1 format and type combination.
4899 if (type == GL_UNSIGNED_SHORT_5_5_5_1)
4969 return false; 4900 return false;
4970 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more 4901 #endif
4971 // internal formats. 4902 // OES_texture_half_float doesn't support HALF_FLOAT_OES type for
4972 if (functionID == TexSubImage2D && 4903 // CopyTexImage/CopyTexSubImage. And OES_texture_half_float doesn't require
4973 (isWebGL2OrHigher() || extensionEnabled(OESTextureFloatName) || 4904 // HALF_FLOAT_OES type texture to be renderable. So, HALF_FLOAT_OES type
4974 extensionEnabled(OESTextureHalfFloatName) || 4905 // texture cannot be copied to or drawn to by glCopyTextureCHROMIUM.
4975 extensionEnabled(EXTsRGBName))) 4906 if (type == GL_HALF_FLOAT_OES)
Zhenyao Mo 2017/03/31 21:12:59 Is this the right place for this? Because in most
qiankun 2017/04/05 08:43:15 This is used to skip gpu path for RGBA/RGBA/HALF_F
4976 return false; 4907 return false;
4908
4977 return true; 4909 return true;
4978 } 4910 }
4979 4911
4980 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( 4912 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason(
4981 TexImageFunctionID id) { 4913 TexImageFunctionID id) {
4982 switch (id) { 4914 switch (id) {
4983 case TexImage2D: 4915 case TexImage2D:
4984 return SnapshotReasonWebGLTexImage2D; 4916 return SnapshotReasonWebGLTexImage2D;
4985 case TexSubImage2D: 4917 case TexSubImage2D:
4986 return SnapshotReasonWebGLTexSubImage2D; 4918 return SnapshotReasonWebGLTexSubImage2D;
4987 case TexImage3D: 4919 case TexImage3D:
4988 return SnapshotReasonWebGLTexImage3D; 4920 return SnapshotReasonWebGLTexImage3D;
4989 case TexSubImage3D: 4921 case TexSubImage3D:
4990 return SnapshotReasonWebGLTexSubImage3D; 4922 return SnapshotReasonWebGLTexSubImage3D;
4991 } 4923 }
4992 NOTREACHED(); 4924 NOTREACHED();
4993 return SnapshotReasonUnknown; 4925 return SnapshotReasonUnknown;
4994 } 4926 }
4995 4927
4996 void WebGLRenderingContextBase::texImageCanvasByGPU( 4928 void WebGLRenderingContextBase::texImageCanvasByGPU(
4997 TexImageFunctionID functionID, 4929 TexImageFunctionID functionID,
4998 HTMLCanvasElement* canvas, 4930 HTMLCanvasElement* canvas,
4931 GLenum target,
4999 GLuint targetTexture, 4932 GLuint targetTexture,
5000 GLenum targetInternalformat,
5001 GLenum targetType,
5002 GLint targetLevel,
5003 GLint xoffset, 4933 GLint xoffset,
5004 GLint yoffset, 4934 GLint yoffset,
5005 const IntRect& sourceSubRectangle) { 4935 const IntRect& sourceSubRectangle) {
5006 if (!canvas->is3D()) { 4936 if (!canvas->is3D()) {
5007 ImageBuffer* buffer = canvas->buffer(); 4937 ImageBuffer* buffer = canvas->buffer();
5008 if (buffer && 4938 if (buffer &&
5009 !buffer->copyToPlatformTexture( 4939 !buffer->copyToPlatformTexture(
5010 functionIDToSnapshotReason(functionID), contextGL(), targetTexture, 4940 functionIDToSnapshotReason(functionID), contextGL(), target,
5011 targetInternalformat, targetType, targetLevel, 4941 targetTexture, m_unpackPremultiplyAlpha, m_unpackFlipY,
5012 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(xoffset, yoffset), 4942 IntPoint(xoffset, yoffset), sourceSubRectangle)) {
5013 sourceSubRectangle)) {
5014 NOTREACHED(); 4943 NOTREACHED();
5015 } 4944 }
5016 } else { 4945 } else {
5017 WebGLRenderingContextBase* gl = 4946 WebGLRenderingContextBase* gl =
5018 toWebGLRenderingContextBase(canvas->renderingContext()); 4947 toWebGLRenderingContextBase(canvas->renderingContext());
5019 ScopedTexture2DRestorer restorer(gl); 4948 ScopedTexture2DRestorer restorer(gl);
5020 if (!gl->drawingBuffer()->copyToPlatformTexture( 4949 if (!gl->drawingBuffer()->copyToPlatformTexture(
5021 contextGL(), targetTexture, targetInternalformat, targetType, 4950 contextGL(), target, targetTexture, m_unpackPremultiplyAlpha,
5022 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, 4951 !m_unpackFlipY, IntPoint(xoffset, yoffset), sourceSubRectangle,
5023 IntPoint(xoffset, yoffset), sourceSubRectangle, BackBuffer)) { 4952 BackBuffer)) {
5024 NOTREACHED(); 4953 NOTREACHED();
5025 } 4954 }
5026 } 4955 }
5027 } 4956 }
5028 4957
5029 void WebGLRenderingContextBase::texImageByGPU( 4958 void WebGLRenderingContextBase::texImageByGPU(
5030 TexImageFunctionID functionID, 4959 TexImageFunctionID functionID,
5031 WebGLTexture* texture, 4960 WebGLTexture* texture,
5032 GLenum target, 4961 GLenum target,
5033 GLint level, 4962 GLint level,
5034 GLint internalformat,
5035 GLenum type,
5036 GLint xoffset, 4963 GLint xoffset,
5037 GLint yoffset, 4964 GLint yoffset,
5038 GLint zoffset, 4965 GLint zoffset,
5039 CanvasImageSource* image, 4966 CanvasImageSource* image,
5040 const IntRect& sourceSubRectangle) { 4967 const IntRect& sourceSubRectangle) {
5041 DCHECK(image->isCanvasElement() || image->isImageBitmap()); 4968 DCHECK(image->isCanvasElement() || image->isImageBitmap());
5042 int width = sourceSubRectangle.width(); 4969 int width = sourceSubRectangle.width();
5043 int height = sourceSubRectangle.height(); 4970 int height = sourceSubRectangle.height();
5044 4971
5045 ScopedTexture2DRestorer restorer(this); 4972 ScopedTexture2DRestorer restorer(this);
5046 4973
5047 GLuint targetTexture = texture->object(); 4974 GLuint targetTexture = texture->object();
5048 GLenum targetType = type;
5049 GLenum targetInternalformat = internalformat;
5050 GLint targetLevel = level;
5051 bool possibleDirectCopy = false; 4975 bool possibleDirectCopy = false;
5052 if (functionID == TexImage2D) { 4976 if (functionID == TexImage2D || functionID == TexSubImage2D) {
5053 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM( 4977 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target);
5054 target, internalformat, type, level);
5055 } 4978 }
5056 4979
5057 GLint copyXOffset = xoffset; 4980 GLint copyXOffset = xoffset;
5058 GLint copyYOffset = yoffset; 4981 GLint copyYOffset = yoffset;
4982 GLenum copyTarget = target;
5059 4983
5060 // if direct copy is not possible, create a temporary texture and then copy 4984 // if direct copy is not possible, create a temporary texture and then copy
5061 // from canvas to temporary texture to target texture. 4985 // from canvas to temporary texture to target texture.
5062 if (!possibleDirectCopy) { 4986 if (!possibleDirectCopy) {
5063 targetLevel = 0;
5064 targetInternalformat = GL_RGBA;
5065 targetType = GL_UNSIGNED_BYTE;
5066 contextGL()->GenTextures(1, &targetTexture); 4987 contextGL()->GenTextures(1, &targetTexture);
5067 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); 4988 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture);
5068 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 4989 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
5069 GL_NEAREST); 4990 GL_NEAREST);
5070 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 4991 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
5071 GL_NEAREST); 4992 GL_NEAREST);
5072 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 4993 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
5073 GL_CLAMP_TO_EDGE); 4994 GL_CLAMP_TO_EDGE);
5074 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 4995 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
5075 GL_CLAMP_TO_EDGE); 4996 GL_CLAMP_TO_EDGE);
5076 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, 4997 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
5077 height, 0, GL_RGBA, targetType, 0); 4998 GL_RGBA, GL_UNSIGNED_BYTE, 0);
5078 copyXOffset = 0; 4999 copyXOffset = 0;
5079 copyYOffset = 0; 5000 copyYOffset = 0;
5001 copyTarget = GL_TEXTURE_2D;
5080 } 5002 }
5081 5003
5082 if (image->isCanvasElement()) { 5004 {
5083 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), 5005 // glCopyTextureCHROMIUM has a DRAW_AND_READBACK path which will call
5084 targetTexture, targetInternalformat, targetType, 5006 // texImage2D. So, reset unpack buffer parameters before that.
5085 targetLevel, copyXOffset, copyYOffset, 5007 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
5086 sourceSubRectangle); 5008 if (image->isCanvasElement()) {
5087 } else { 5009 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image),
5088 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), targetTexture, 5010 copyTarget, targetTexture, copyXOffset, copyYOffset,
5089 targetInternalformat, targetType, targetLevel, 5011 sourceSubRectangle);
5090 !m_unpackFlipY); 5012 } else {
5013 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), copyTarget,
5014 targetTexture, !m_unpackFlipY, copyXOffset,
5015 copyYOffset, sourceSubRectangle);
5016 }
5091 } 5017 }
5092 5018
5093 if (!possibleDirectCopy) { 5019 if (!possibleDirectCopy) {
5094 GLuint tmpFBO; 5020 GLuint tmpFBO;
5095 contextGL()->GenFramebuffers(1, &tmpFBO); 5021 contextGL()->GenFramebuffers(1, &tmpFBO);
5096 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); 5022 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO);
5097 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5023 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5098 GL_TEXTURE_2D, targetTexture, 0); 5024 GL_TEXTURE_2D, targetTexture, 0);
5099 contextGL()->BindTexture(texture->getTarget(), texture->object()); 5025 contextGL()->BindTexture(texture->getTarget(), texture->object());
5100 if (functionID == TexImage2D) { 5026 if (functionID == TexImage2D) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
5157 return; 5083 return;
5158 } 5084 }
5159 5085
5160 if (functionID == TexImage2D || functionID == TexSubImage2D) { 5086 if (functionID == TexImage2D || functionID == TexSubImage2D) {
5161 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support 5087 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support
5162 // float/integer/sRGB internal format. 5088 // float/integer/sRGB internal format.
5163 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is 5089 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is
5164 // upgraded to handle more formats. 5090 // upgraded to handle more formats.
5165 if (!canvas->renderingContext() || 5091 if (!canvas->renderingContext() ||
5166 !canvas->renderingContext()->isAccelerated() || 5092 !canvas->renderingContext()->isAccelerated() ||
5167 !canUseTexImageByGPU(functionID, internalformat, type)) { 5093 !canUseTexImageByGPU(type)) {
5168 // 2D canvas has only FrontBuffer. 5094 // 2D canvas has only FrontBuffer.
5169 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, 5095 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
5170 zoffset, format, type, 5096 zoffset, format, type,
5171 canvas 5097 canvas
5172 ->copiedImage(FrontBuffer, PreferAcceleration, 5098 ->copiedImage(FrontBuffer, PreferAcceleration,
5173 functionIDToSnapshotReason(functionID)) 5099 functionIDToSnapshotReason(functionID))
5174 .get(), 5100 .get(),
5175 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, 5101 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY,
5176 m_unpackPremultiplyAlpha, sourceSubRectangle, 1, 0); 5102 m_unpackPremultiplyAlpha, sourceSubRectangle, 1, 0);
5177 return; 5103 return;
5178 } 5104 }
5179 5105
5180 // The GPU-GPU copy path uses the Y-up coordinate system. 5106 // The GPU-GPU copy path uses the Y-up coordinate system.
5181 IntRect adjustedSourceSubRectangle = sourceSubRectangle; 5107 IntRect adjustedSourceSubRectangle = sourceSubRectangle;
5182 if (!m_unpackFlipY) { 5108 if (!m_unpackFlipY) {
5183 adjustedSourceSubRectangle.setY(canvas->height() - 5109 adjustedSourceSubRectangle.setY(canvas->height() -
5184 adjustedSourceSubRectangle.maxY()); 5110 adjustedSourceSubRectangle.maxY());
5185 } 5111 }
5186 5112
5187 if (functionID == TexImage2D) { 5113 if (functionID == TexImage2D) {
5188 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), 5114 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(),
5189 sourceSubRectangle.height(), 0, format, type, 0); 5115 sourceSubRectangle.height(), 0, format, type, 0);
5190 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, 5116 texImageByGPU(functionID, texture, target, level, 0, 0, 0, canvas,
5191 0, 0, canvas, adjustedSourceSubRectangle); 5117 adjustedSourceSubRectangle);
5192 } else { 5118 } else {
5193 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, 5119 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0,
5194 yoffset, 0, canvas, adjustedSourceSubRectangle); 5120 canvas, adjustedSourceSubRectangle);
5195 } 5121 }
5196 } else { 5122 } else {
5197 // 3D functions. 5123 // 3D functions.
5198 5124
5199 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542). 5125 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542).
5200 // Note that code will also be needed to copy to layers of 3D 5126 // Note that code will also be needed to copy to layers of 3D
5201 // textures, and elements of 2D texture arrays. 5127 // textures, and elements of 2D texture arrays.
5202 texImageImpl( 5128 texImageImpl(
5203 functionID, target, level, internalformat, xoffset, yoffset, zoffset, 5129 functionID, target, level, internalformat, xoffset, yoffset, zoffset,
5204 format, type, canvas 5130 format, type, canvas
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
5266 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, 5192 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target,
5267 level, internalformat, video->videoWidth(), 5193 level, internalformat, video->videoWidth(),
5268 video->videoHeight(), 1, 0, format, type, xoffset, 5194 video->videoHeight(), 1, 0, format, type, xoffset,
5269 yoffset, zoffset)) 5195 yoffset, zoffset))
5270 return; 5196 return;
5271 5197
5272 bool sourceImageRectIsDefault = 5198 bool sourceImageRectIsDefault =
5273 sourceImageRect == sentinelEmptyRect() || 5199 sourceImageRect == sentinelEmptyRect() ||
5274 sourceImageRect == 5200 sourceImageRect ==
5275 IntRect(0, 0, video->videoWidth(), video->videoHeight()); 5201 IntRect(0, 0, video->videoWidth(), video->videoHeight());
5276 if (functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && 5202 const bool useCopyTextureCHROMIUM =
5277 GL_TEXTURE_2D == target && Extensions3DUtil::canUseCopyTextureCHROMIUM( 5203 functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 &&
5278 target, internalformat, type, level)) { 5204 GL_TEXTURE_2D == target && canUseTexImageByGPU(type);
5205 // Format of source video may be 16-bit format, e.g. Y16 format.
5206 // glCopyTextureCHROMIUM requires the source texture to be in 8-bit format.
5207 // Converting 16-bits formated source texture to 8-bits formated texture will
5208 // cause precision lost. So, uploading such video texture to half float or
5209 // float texture can not use GPU-GPU path.
5210 if (useCopyTextureCHROMIUM) {
5279 DCHECK_EQ(xoffset, 0); 5211 DCHECK_EQ(xoffset, 0);
5280 DCHECK_EQ(yoffset, 0); 5212 DCHECK_EQ(yoffset, 0);
5281 DCHECK_EQ(zoffset, 0); 5213 DCHECK_EQ(zoffset, 0);
5282 // Go through the fast path doing a GPU-GPU textures copy without a readback 5214 // Go through the fast path doing a GPU-GPU textures copy without a readback
5283 // to system memory if possible. Otherwise, it will fall back to the normal 5215 // to system memory if possible. Otherwise, it will fall back to the normal
5284 // SW path. 5216 // SW path.
5285 5217
5286 // Note that neither 5218 // Note that neither
5287 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor 5219 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor
5288 // ImageBuffer::copyToPlatformTexture allocate the destination texture 5220 // ImageBuffer::copyToPlatformTexture allocate the destination texture
5289 // any more. 5221 // any more.
5290 texImage2DBase(target, level, internalformat, video->videoWidth(), 5222 texImage2DBase(target, level, internalformat, video->videoWidth(),
5291 video->videoHeight(), 0, format, type, nullptr); 5223 video->videoHeight(), 0, format, type, nullptr);
5292 5224
5293 if (video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(), 5225 if (video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(),
5294 m_unpackPremultiplyAlpha, 5226 m_unpackPremultiplyAlpha,
5295 m_unpackFlipY)) { 5227 m_unpackFlipY)) {
5296 texture->updateLastUploadedVideo(video->webMediaPlayer()); 5228 texture->updateLastUploadedVideo(video->webMediaPlayer());
5297 return; 5229 return;
5298 } 5230 }
5231 }
5299 5232
5233 if (sourceImageRectIsDefault) {
5234 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It
5235 // leaves early for other formats or if frame is stored on GPU.
5236 ScopedUnpackParametersResetRestore(
5237 this, m_unpackFlipY || m_unpackPremultiplyAlpha);
5238 if (video->texImageImpl(
5239 static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target,
5240 contextGL(), level, convertTexInternalFormat(internalformat, type),
5241 format, type, xoffset, yoffset, zoffset, m_unpackFlipY,
5242 m_unpackPremultiplyAlpha &&
5243 m_unpackColorspaceConversion == GL_NONE)) {
5244 texture->updateLastUploadedVideo(video->webMediaPlayer());
5245 return;
5246 }
5247 }
5248
5249 if (useCopyTextureCHROMIUM) {
5300 // Try using an accelerated image buffer, this allows YUV conversion to be 5250 // Try using an accelerated image buffer, this allows YUV conversion to be
5301 // done on the GPU. 5251 // done on the GPU.
5302 std::unique_ptr<ImageBufferSurface> surface = 5252 std::unique_ptr<ImageBufferSurface> surface =
5303 WTF::wrapUnique(new AcceleratedImageBufferSurface( 5253 WTF::wrapUnique(new AcceleratedImageBufferSurface(
5304 IntSize(video->videoWidth(), video->videoHeight()))); 5254 IntSize(video->videoWidth(), video->videoHeight())));
5305 if (surface->isValid()) { 5255 if (surface->isValid()) {
5306 std::unique_ptr<ImageBuffer> imageBuffer( 5256 std::unique_ptr<ImageBuffer> imageBuffer(
5307 ImageBuffer::create(std::move(surface))); 5257 ImageBuffer::create(std::move(surface)));
5308 if (imageBuffer) { 5258 if (imageBuffer) {
5309 // The video element paints an RGBA frame into our surface here. By 5259 // The video element paints an RGBA frame into our surface here. By
5310 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer 5260 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer
5311 // implementation to do any necessary color space conversion on the GPU 5261 // implementation to do any necessary color space conversion on the GPU
5312 // (though it may still do a CPU conversion and upload the results). 5262 // (though it may still do a CPU conversion and upload the results).
5313 video->paintCurrentFrame( 5263 video->paintCurrentFrame(
5314 imageBuffer->canvas(), 5264 imageBuffer->canvas(),
5315 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); 5265 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
5316 5266
5317 // This is a straight GPU-GPU copy, any necessary color space conversion 5267 // This is a straight GPU-GPU copy, any necessary color space conversion
5318 // was handled in the paintCurrentFrameInContext() call. 5268 // was handled in the paintCurrentFrameInContext() call.
5319 5269
5320 if (imageBuffer->copyToPlatformTexture( 5270 if (imageBuffer->copyToPlatformTexture(
5321 functionIDToSnapshotReason(functionID), contextGL(), 5271 functionIDToSnapshotReason(functionID), contextGL(), target,
5322 texture->object(), internalformat, type, level, 5272 texture->object(), m_unpackPremultiplyAlpha, m_unpackFlipY,
5323 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(0, 0), 5273 IntPoint(0, 0),
5324 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { 5274 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) {
5325 texture->updateLastUploadedVideo(video->webMediaPlayer()); 5275 texture->updateLastUploadedVideo(video->webMediaPlayer());
5326 return; 5276 return;
5327 } 5277 }
5328 } 5278 }
5329 } 5279 }
5330 } 5280 }
5331 5281
5332 if (sourceImageRectIsDefault) {
5333 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It
5334 // leaves early for other formats or if frame is stored on GPU.
5335 ScopedUnpackParametersResetRestore(
5336 this, m_unpackFlipY || m_unpackPremultiplyAlpha);
5337 if (video->texImageImpl(
5338 static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target,
5339 contextGL(), level, convertTexInternalFormat(internalformat, type),
5340 format, type, xoffset, yoffset, zoffset, m_unpackFlipY,
5341 m_unpackPremultiplyAlpha &&
5342 m_unpackColorspaceConversion == GL_NONE)) {
5343 texture->updateLastUploadedVideo(video->webMediaPlayer());
5344 return;
5345 }
5346 }
5347
5348 RefPtr<Image> image = videoFrameToImage(video); 5282 RefPtr<Image> image = videoFrameToImage(video);
5349 if (!image) 5283 if (!image)
5350 return; 5284 return;
5351 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, 5285 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
5352 zoffset, format, type, image.get(), 5286 zoffset, format, type, image.get(),
5353 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, 5287 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY,
5354 m_unpackPremultiplyAlpha, sourceImageRect, depth, 5288 m_unpackPremultiplyAlpha, sourceImageRect, depth,
5355 unpackImageHeight); 5289 unpackImageHeight);
5356 texture->updateLastUploadedVideo(video->webMediaPlayer()); 5290 texture->updateLastUploadedVideo(video->webMediaPlayer());
5357 } 5291 }
5358 5292
5359 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, 5293 void WebGLRenderingContextBase::texImageBitmapByGPU(
5360 GLuint targetTexture, 5294 ImageBitmap* bitmap,
5361 GLenum targetInternalformat, 5295 GLenum target,
5362 GLenum targetType, 5296 GLuint targetTexture,
5363 GLint targetLevel, 5297 bool flipY,
5364 bool flipY) { 5298 GLint xoffset,
5365 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), 5299 GLint yoffset,
5366 targetTexture, targetInternalformat, 5300 const IntRect& sourceSubRectangle) {
5367 targetType, flipY); 5301 bitmap->bitmapImage()->copyToTexture(
5302 drawingBuffer()->contextProvider(), target, targetTexture, flipY,
5303 IntPoint(xoffset, yoffset), sourceSubRectangle);
5368 } 5304 }
5369 5305
5370 void WebGLRenderingContextBase::texImage2D(GLenum target, 5306 void WebGLRenderingContextBase::texImage2D(GLenum target,
5371 GLint level, 5307 GLint level,
5372 GLint internalformat, 5308 GLint internalformat,
5373 GLenum format, 5309 GLenum format,
5374 GLenum type, 5310 GLenum type,
5375 HTMLVideoElement* video, 5311 HTMLVideoElement* video,
5376 ExceptionState& exceptionState) { 5312 ExceptionState& exceptionState) {
5377 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, 5313 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
5419 GLsizei width = sourceSubRect.width(); 5355 GLsizei width = sourceSubRect.width();
5420 GLsizei height = sourceSubRect.height(); 5356 GLsizei height = sourceSubRect.height();
5421 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, level, 5357 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, level,
5422 internalformat, width, height, depth, 0, format, type, 5358 internalformat, width, height, depth, 0, format, type,
5423 xoffset, yoffset, zoffset)) 5359 xoffset, yoffset, zoffset))
5424 return; 5360 return;
5425 ASSERT(bitmap->bitmapImage()); 5361 ASSERT(bitmap->bitmapImage());
5426 5362
5427 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. 5363 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps.
5428 if (functionID != TexSubImage3D && functionID != TexImage3D && 5364 if (functionID != TexSubImage3D && functionID != TexImage3D &&
5429 bitmap->isAccelerated() && 5365 bitmap->isAccelerated() && canUseTexImageByGPU(type) &&
5430 canUseTexImageByGPU(functionID, internalformat, type) &&
5431 !selectingSubRectangle) { 5366 !selectingSubRectangle) {
5432 if (functionID == TexImage2D) { 5367 if (functionID == TexImage2D) {
5433 texImage2DBase(target, level, internalformat, width, height, 0, format, 5368 texImage2DBase(target, level, internalformat, width, height, 0, format,
5434 type, 0); 5369 type, 0);
5435 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, 5370 texImageByGPU(functionID, texture, target, level, 0, 0, 0, bitmap,
5436 0, 0, bitmap, sourceSubRect); 5371 sourceSubRect);
5437 } else if (functionID == TexSubImage2D) { 5372 } else if (functionID == TexSubImage2D) {
5438 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, 5373 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0,
5439 yoffset, 0, bitmap, sourceSubRect); 5374 bitmap, sourceSubRect);
5440 } 5375 }
5441 return; 5376 return;
5442 } 5377 }
5443 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 5378 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
5444 SkPixmap pixmap; 5379 SkPixmap pixmap;
5445 uint8_t* pixelDataPtr = nullptr; 5380 uint8_t* pixelDataPtr = nullptr;
5446 RefPtr<Uint8Array> pixelData; 5381 RefPtr<Uint8Array> pixelData;
5447 // In the case where an ImageBitmap is not texture backed, peekPixels() always 5382 // In the case where an ImageBitmap is not texture backed, peekPixels() always
5448 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we 5383 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we
5449 // do a GPU read back. 5384 // do a GPU read back.
(...skipping 2400 matching lines...) Expand 10 before | Expand all | Expand 10 after
7850 7785
7851 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( 7786 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas(
7852 HTMLCanvasElementOrOffscreenCanvas& result) const { 7787 HTMLCanvasElementOrOffscreenCanvas& result) const {
7853 if (canvas()) 7788 if (canvas())
7854 result.setHTMLCanvasElement(canvas()); 7789 result.setHTMLCanvasElement(canvas());
7855 else 7790 else
7856 result.setOffscreenCanvas(offscreenCanvas()); 7791 result.setOffscreenCanvas(offscreenCanvas());
7857 } 7792 }
7858 7793
7859 } // namespace blink 7794 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698