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

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

Issue 2025703002: Pack repeated code in tex(Sub)Image2D and texSubImage3D into helper func (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: all done, hand to bots Created 4 years, 6 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
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3936 matching lines...) Expand 10 before | Expand all | Expand 10 after
3947 return GL_RGB32F_EXT; 3947 return GL_RGB32F_EXT;
3948 return internalformat; 3948 return internalformat;
3949 } 3949 }
3950 3950
3951 void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLe num type, const void* pixels) 3951 void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLe num type, const void* pixels)
3952 { 3952 {
3953 // All calling functions check isContextLost, so a duplicate check is not ne eded here. 3953 // All calling functions check isContextLost, so a duplicate check is not ne eded here.
3954 contextGL()->TexImage2D(target, level, convertTexInternalFormat(internalform at, type), width, height, border, format, type, pixels); 3954 contextGL()->TexImage2D(target, level, convertTexInternalFormat(internalform at, type), width, height, border, format, type, pixels);
3955 } 3955 }
3956 3956
3957 void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion: :ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha) 3957 void WebGLRenderingContextBase::texImageImpl(TexImageFunctionName functionName, GLenum target, GLint level, GLint internalformat, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::I mageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
3958 { 3958 {
3959 const char* funcName = getTexImageFunctionName(functionName);
3959 // All calling functions check isContextLost, so a duplicate check is not ne eded here. 3960 // All calling functions check isContextLost, so a duplicate check is not ne eded here.
3960 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 3961 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
3961 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. 3962 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
3962 type = GL_FLOAT; 3963 type = GL_FLOAT;
3963 } 3964 }
3964 Vector<uint8_t> data; 3965 Vector<uint8_t> data;
3965 WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premul tiplyAlpha, m_unpackColorspaceConversion == GL_NONE); 3966 WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premul tiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
3966 if (!imageExtractor.imagePixelData()) { 3967 if (!imageExtractor.imagePixelData()) {
3967 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data"); 3968 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
3968 return; 3969 return;
3969 } 3970 }
3970 WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSour ceFormat(); 3971 WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSour ceFormat();
3971 WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp(); 3972 WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
3972 const void* imagePixelData = imageExtractor.imagePixelData(); 3973 const void* imagePixelData = imageExtractor.imagePixelData();
3973 3974
3974 bool needConversion = true; 3975 bool needConversion = true;
3975 if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::Da taFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNo thing && !flipY) { 3976 if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::Da taFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNo thing && !flipY) {
3976 needConversion = false; 3977 needConversion = false;
3977 } else { 3978 } else {
3978 if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtrac tor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) { 3979 if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtrac tor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
3979 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error") ; 3980 synthesizeGLError(GL_INVALID_VALUE, funcName, "packImage error");
3980 return; 3981 return;
3981 } 3982 }
3982 } 3983 }
3983 3984
3984 resetUnpackParameters(); 3985 resetUnpackParameters();
3985 texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), i mageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : ima gePixelData); 3986 if (functionName == TexImage2D)
3987 texImage2DBase(target, level, internalformat, imageExtractor.imageWidth( ), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData);
3988 else if (functionName == TexSubImage2D)
3989 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, imageExtract or.imageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? d ata.data() : imagePixelData);
3990 else // must be "texSubImage3D"
3991 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, ima geExtractor.imageWidth(), imageExtractor.imageHeight(), 1, format, type, needCon version ? data.data() : imagePixelData);
3986 restoreUnpackParameters(); 3992 restoreUnpackParameters();
3987 } 3993 }
3988 3994
3989 bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexIma geFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum targ et, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei d epth, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset, GL int zoffset) 3995 bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexIma geFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum targ et, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei d epth, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset, GL int zoffset)
3990 { 3996 {
3991 if (!validateTexFuncLevel(functionName, target, level)) 3997 if (!validateTexFuncLevel(functionName, target, level))
3992 return false; 3998 return false;
3993 3999
3994 if (!validateTexFuncParameters(functionName, functionType, target, level, in ternalformat, width, height, depth, border, format, type)) 4000 if (!validateTexFuncParameters(functionName, functionType, target, level, in ternalformat, width, height, depth, border, format, type))
3995 return false; 4001 return false;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4044 if (!image->currentFrameKnownToBeOpaque()) 4050 if (!image->currentFrameKnownToBeOpaque())
4045 buf->canvas()->clear(SK_ColorTRANSPARENT); 4051 buf->canvas()->clear(SK_ColorTRANSPARENT);
4046 4052
4047 IntRect srcRect(IntPoint(), image->size()); 4053 IntRect srcRect(IntPoint(), image->size());
4048 IntRect destRect(0, 0, size.width(), size.height()); 4054 IntRect destRect(0, 0, size.width(), size.height());
4049 SkPaint paint; 4055 SkPaint paint;
4050 image->draw(buf->canvas(), paint, destRect, srcRect, DoNotRespectImageOrient ation, Image::DoNotClampImageToSourceRect); 4056 image->draw(buf->canvas(), paint, destRect, srcRect, DoNotRespectImageOrient ation, Image::DoNotClampImageToSourceRect);
4051 return buf->newImageSnapshot(); 4057 return buf->newImageSnapshot();
4052 } 4058 }
4053 4059
4060 WebGLTexture* WebGLRenderingContextBase::validateTexImageBinding(const char* fun cName, TexImageFunctionName functionName, GLenum target)
4061 {
4062 return validateTexture2DBinding(funcName, target);
4063 }
4064
4065 const char* WebGLRenderingContextBase::getTexImageFunctionName(TexImageFunctionN ame funcName)
4066 {
4067 if (funcName == TexImage2D)
4068 return "texImage2D";
4069 if (funcName == TexSubImage2D)
4070 return "texSubImage2D";
4071 if (funcName == TexSubImage3D)
4072 return "texSubImage3D";
4073 return "texImage3D";
4074 }
4075
4076 void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView(TexImageFunctio nName functionName,
4077 GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei hei ght, GLint border,
4078 GLenum format, GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLi nt zoffset, DOMArrayBufferView* pixels)
4079 {
4080 const char* funcName = getTexImageFunctionName(functionName);
4081 if (isContextLost())
4082 return;
4083 if (!validateTexImageBinding(funcName, functionName, target))
Zhenyao Mo 2016/06/03 17:49:51 This funcName and functionName is very confusing.
xidachen 2016/06/03 18:28:29 functionID is much clearer. Changed all over the p
4084 return;
4085 TexImageFunctionType functionType;
4086 if (functionName == TexImage2D || functionName == TexImage3D)
4087 functionType = TexImage;
4088 else
4089 functionType = TexSubImage;
4090 if (!validateTexFunc(funcName, functionType, SourceArrayBufferView, target, level, internalformat, width, height, depth, border, format, type, xoffset, yoff set, zoffset))
4091 return;
4092 TexImageDimension sourceType;
4093 if (functionName == TexImage2D || functionName == TexSubImage2D)
4094 sourceType = Tex2D;
4095 else
4096 sourceType = Tex3D;
4097 if (!validateTexFuncData(funcName, sourceType, level, width, height, depth, format, type, pixels, NullAllowed))
4098 return;
4099 void* data = pixels ? pixels->baseAddress() : 0;
4100 Vector<uint8_t> tempData;
4101 bool changeUnpackAlignment = false;
4102 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
4103 if (functionName == TexImage2D || functionName == TexSubImage2D) {
Zhenyao Mo 2016/06/03 17:49:51 sourceType == Tex2D
xidachen 2016/06/03 18:28:29 Done.
4104 if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempDat a))
4105 return;
4106 data = tempData.data();
4107 } else {
4108 NOTIMPLEMENTED();
4109 if (functionName == TexImage3D)
4110 return;
Zhenyao Mo 2016/06/03 17:49:51 For now let's not worry about flipY and premultipl
xidachen 2016/06/03 18:28:30 Done.
4111 }
4112 changeUnpackAlignment = true;
4113 }
4114 if (functionName == TexImage3D) {
4115 contextGL()->TexImage3D(target, level, convertTexInternalFormat(internal format, type), width, height, depth, border, format, type, data);
4116 return;
4117 }
4118
4119 if (changeUnpackAlignment)
4120 resetUnpackParameters();
4121 if (functionName == TexImage2D)
4122 texImage2DBase(target, level, internalformat, width, height, border, for mat, type, data);
4123 else if (functionName == TexSubImage2D)
4124 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, heigh t, format, type, data);
4125 else
4126 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, wid th, height, depth, format, type, data);
Zhenyao Mo 2016/06/03 17:49:51 Same here, let's move this before the resetUnpackP
xidachen 2016/06/03 18:28:29 Done.
4127 if (changeUnpackAlignment)
4128 restoreUnpackParameters();
4129 }
4130
4054 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4131 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4055 GLsizei width, GLsizei height, GLint border, 4132 GLsizei width, GLsizei height, GLint border,
4056 GLenum format, GLenum type, DOMArrayBufferView* pixels) 4133 GLenum format, GLenum type, DOMArrayBufferView* pixels)
4057 { 4134 {
4058 if (isContextLost()) 4135 texImageHelperDOMArrayBufferView(TexImage2D, target, level, internalformat, width, height, border, format, type, 1, 0, 0, 0, pixels);
4059 return;
4060 if (!validateTexture2DBinding("texImage2D", target))
4061 return;
4062 if (!validateTexFunc("texImage2D", TexImage, SourceArrayBufferView, target, level, internalformat, width, height, 1, border, format, type, 0, 0, 0))
4063 return;
4064 if (!validateTexFuncData("texImage2D", Tex2D, level, width, height, 1, forma t, type, pixels, NullAllowed))
4065 return;
4066 void* data = pixels ? pixels->baseAddress() : 0;
4067 Vector<uint8_t> tempData;
4068 bool changeUnpackAlignment = false;
4069 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
4070 if (!WebGLImageConversion::extractTextureData(width, height, format, typ e, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
4071 return;
4072 data = tempData.data();
4073 changeUnpackAlignment = true;
4074 }
4075 if (changeUnpackAlignment)
4076 resetUnpackParameters();
4077 texImage2DBase(target, level, internalformat, width, height, border, format, type, data);
4078 if (changeUnpackAlignment)
4079 restoreUnpackParameters();
4080 } 4136 }
4081 4137
4082 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4138 void WebGLRenderingContextBase::texImageHelperImageData(TexImageFunctionName fun ctionName,
4083 GLenum format, GLenum type, ImageData* pixels) 4139 GLenum target, GLint level, GLint internalformat, GLint border, GLenum forma t,
4140 GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, Ima geData* pixels)
4084 { 4141 {
4142 const char* funcName = getTexImageFunctionName(functionName);
4085 if (isContextLost()) 4143 if (isContextLost())
4086 return; 4144 return;
4087 if (!pixels) { 4145 if (!pixels) {
4088 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "no image data"); 4146 synthesizeGLError(GL_INVALID_VALUE, funcName, "no image data");
4089 return; 4147 return;
4090 } 4148 }
4091 if (pixels->data()->bufferBase()->isNeutered()) { 4149 if (pixels->data()->bufferBase()->isNeutered()) {
4092 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "The source data has b een neutered."); 4150 synthesizeGLError(GL_INVALID_VALUE, funcName, "The source data has been neutered.");
4093 return; 4151 return;
4094 } 4152 }
4095 if (!validateTexture2DBinding("texImage2D", target)) 4153 if (!validateTexImageBinding(funcName, functionName, target))
4096 return; 4154 return;
4097 if (!validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 1, 0, format, type, 0, 0, 0) ) 4155 TexImageFunctionType functionType;
4156 if (functionName == TexImage2D)
4157 functionType = TexImage;
4158 else
4159 functionType = TexSubImage;
4160 if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), depth, border, format, type, xoffset, yoffset, zoffset))
4098 return; 4161 return;
4099 Vector<uint8_t> data; 4162 Vector<uint8_t> data;
4100 bool needConversion = true; 4163 bool needConversion = true;
4101 // The data from ImageData is always of format RGBA8. 4164 // The data from ImageData is always of format RGBA8.
4102 // No conversion is needed if destination format is RGBA and type is USIGNED _BYTE and no Flip or Premultiply operation is required. 4165 // No conversion is needed if destination format is RGBA and type is USIGNED _BYTE and no Flip or Premultiply operation is required.
4103 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { 4166 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4104 needConversion = false; 4167 needConversion = false;
4105 } else { 4168 } else {
4106 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4169 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4107 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4170 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4108 type = GL_FLOAT; 4171 type = GL_FLOAT;
4109 } 4172 }
4110 if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebG LImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_u npackFlipY, m_unpackPremultiplyAlpha, data)) { 4173 if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebG LImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_u npackFlipY, m_unpackPremultiplyAlpha, data)) {
4111 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data"); 4174 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4112 return; 4175 return;
4113 } 4176 }
4114 } 4177 }
4115 resetUnpackParameters(); 4178 resetUnpackParameters();
4116 texImage2DBase(target, level, internalformat, pixels->width(), pixels->heigh t(), 0, format, type, needConversion ? data.data() : pixels->data()->data()); 4179 if (functionName == TexImage2D)
4180 texImage2DBase(target, level, internalformat, pixels->width(), pixels->h eight(), border, format, type, needConversion ? data.data() : pixels->data()->da ta());
4181 else if (functionName == TexSubImage2D)
4182 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->widt h(), pixels->height(), format, type, needConversion ? data.data() : pixels->data ()->data());
4183 else // must be "texSubImage3D"
Zhenyao Mo 2016/06/03 17:49:51 Can you ASSERT? here and other places.
xidachen 2016/06/03 18:28:30 Done.
4184 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, pix els->width(), pixels->height(), depth, format, type, needConversion ? data.data( ) : pixels->data()->data());
4117 restoreUnpackParameters(); 4185 restoreUnpackParameters();
4118 } 4186 }
4119 4187
4120 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4188 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4189 GLenum format, GLenum type, ImageData* pixels)
4190 {
4191 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format , type, 1, 0, 0, 0, pixels);
4192 }
4193
4194 void WebGLRenderingContextBase::texImageHelperHTMLImageElement(TexImageFunctionN ame functionName,
4195 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4196 GLint yoffset, GLint zoffset, HTMLImageElement* image, ExceptionState& excep tionState)
4197 {
4198 const char* funcName = getTexImageFunctionName(functionName);
4199 if (isContextLost())
4200 return;
4201 if (!validateHTMLImageElement(funcName, image, exceptionState))
4202 return;
4203 if (!validateTexImageBinding(funcName, functionName, target))
4204 return;
4205
4206 RefPtr<Image> imageForRender = image->cachedImage()->getImage();
4207 if (imageForRender && imageForRender->isSVGImage())
4208 imageForRender = drawImageIntoBuffer(imageForRender.release(), image->wi dth(), image->height(), funcName);
4209
4210 TexImageFunctionType functionType;
4211 if (functionName == TexImage2D)
4212 functionType = TexImage;
4213 else
4214 functionType = TexSubImage;
4215 if (!imageForRender || !validateTexFunc(funcName, functionType, SourceHTMLIm ageElement, target, level, internalformat, imageForRender->width(), imageForRend er->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
4216 return;
4217
4218 texImageImpl(functionName, target, level, internalformat, xoffset, yoffset, zoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
4219 }
4220
4221 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4121 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) 4222 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState)
4122 { 4223 {
4123 if (isContextLost()) 4224 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, image, exceptionState);
4124 return;
4125 if (!validateHTMLImageElement("texImage2D", image, exceptionState))
4126 return;
4127 if (!validateTexture2DBinding("texImage2D", target))
4128 return;
4129
4130 RefPtr<Image> imageForRender = image->cachedImage()->getImage();
4131 if (imageForRender && imageForRender->isSVGImage())
4132 imageForRender = drawImageIntoBuffer(imageForRender.release(), image->wi dth(), image->height(), "texImage2D");
4133
4134 if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLIm ageElement, target, level, internalformat, imageForRender->width(), imageForRend er->height(), 1, 0, format, type, 0, 0, 0))
4135 return;
4136
4137 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4138 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
4139 type = GL_FLOAT;
4140 }
4141 texImage2DImpl(target, level, internalformat, format, type, imageForRender.g et(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlph a);
4142 } 4225 }
4143 4226
4144 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) 4227 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type)
4145 { 4228 {
4146 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) 4229 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat))
4147 return false; 4230 return false;
4148 return true; 4231 return true;
4149 } 4232 }
4150 4233
4151 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, 4234 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4205 } else if (functionType == TexSubImage3DByGPU) { 4288 } else if (functionType == TexSubImage3DByGPU) {
4206 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height()); 4289 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height());
4207 } 4290 }
4208 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 4291 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
4209 restoreCurrentFramebuffer(); 4292 restoreCurrentFramebuffer();
4210 contextGL()->DeleteFramebuffers(1, &tmpFBO); 4293 contextGL()->DeleteFramebuffers(1, &tmpFBO);
4211 contextGL()->DeleteTextures(1, &targetTexture); 4294 contextGL()->DeleteTextures(1, &targetTexture);
4212 } 4295 }
4213 } 4296 }
4214 4297
4298 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction Name functionName,
4299 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4300 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState)
4301 {
4302 const char* funcName = getTexImageFunctionName(functionName);
4303 if (isContextLost())
4304 return;
4305 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState))
4306 return;
4307 WebGLTexture* texture = validateTexImageBinding(funcName, functionName, targ et);
4308 if (!texture)
4309 return;
4310 TexImageFunctionType functionType;
4311 if (functionName == TexImage2D)
4312 functionType = TexImage;
4313 else
4314 functionType = TexSubImage;
4315 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
4316 return;
4317 if (functionName == TexImage2D) {
4318 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format.
4319 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4320 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageCanvasByGPU(internalformat, type)) {
4321 // 2D canvas has only FrontBuffer.
4322 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(),
4323 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4324 return;
4325 }
4326
4327 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0);
4328 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalfor mat, type, 0, 0, 0, canvas);
4329 } else if (functionName == TexSubImage2D) {
4330 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal format s.
4331 bool useReadBackPath = isWebGL2OrHigher()
4332 || extensionEnabled(OESTextureFloatName)
4333 || extensionEnabled(OESTextureHalfFloatName)
4334 || extensionEnabled(EXTsRGBName);
4335 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format.
4336 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4337 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) {
4338 // 2D canvas has only FrontBuffer.
4339 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4340 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4341 return;
4342 }
4343
4344 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas);
4345 } else { // must be TexSubImage3D
4346 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269).
4347 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4348 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4349 }
4350 }
4351
4215 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4352 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4216 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4353 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
4217 { 4354 {
4218 if (isContextLost()) 4355 texImageHelperHTMLCanvasElement(TexImage2D, target, level, internalformat, f ormat, type, 0, 0, 0, canvas, exceptionState);
4219 return;
4220 if (!validateHTMLCanvasElement("texImage2D", canvas, exceptionState))
4221 return;
4222 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target);
4223 if (!texture)
4224 return;
4225 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0))
4226 return;
4227
4228 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format.
4229 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
4230 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) {
4231 // 2D canvas has only FrontBuffer.
4232 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(),
4233 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4234 return;
4235 }
4236
4237 texImage2DBase(target, level, internalformat, canvas->width(), canvas->heigh t(), 0, format, type, 0);
4238 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas);
4239 } 4356 }
4240 4357
4241 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) 4358 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video)
4242 { 4359 {
4243 IntSize size(video->videoWidth(), video->videoHeight()); 4360 IntSize size(video->videoWidth(), video->videoHeight());
4244 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); 4361 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
4245 if (!buf) { 4362 if (!buf) {
4246 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); 4363 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
4247 return nullptr; 4364 return nullptr;
4248 } 4365 }
4249 IntRect destRect(0, 0, size.width(), size.height()); 4366 IntRect destRect(0, 0, size.width(), size.height());
4250 video->paintCurrentFrame(buf->canvas(), destRect, nullptr); 4367 video->paintCurrentFrame(buf->canvas(), destRect, nullptr);
4251 return buf->newImageSnapshot(); 4368 return buf->newImageSnapshot();
4252 } 4369 }
4253 4370
4371 void WebGLRenderingContextBase::texImageHelperHTMLVideoElement(TexImageFunctionN ame functionName,
4372 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4373 GLint yoffset, GLint zoffset, HTMLVideoElement* video, ExceptionState& excep tionState)
4374 {
4375 const char* funcName = getTexImageFunctionName(functionName);
4376 if (isContextLost())
4377 return;
4378 if (!validateHTMLVideoElement(funcName, video, exceptionState))
4379 return;
4380 WebGLTexture* texture = validateTexImageBinding(funcName, functionName, targ et);
4381 if (!texture)
4382 return;
4383 TexImageFunctionType functionType;
4384 if (functionName == TexImage2D)
4385 functionType = TexImage;
4386 else
4387 functionType = TexSubImage;
4388 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, zoffset))
4389 return;
4390
4391 if (functionName == TexImage2D) {
4392 // Go through the fast path doing a GPU-GPU textures copy without a read back to system memory if possible.
4393 // Otherwise, it will fall back to the normal SW path.
4394 if (GL_TEXTURE_2D == target) {
4395 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalform at, type, level)
4396 && video->copyVideoTextureToPlatformTexture(contextGL(), texture ->object(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4397 return;
4398 }
4399
4400 // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
4401 OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBu fferSurface(IntSize(video->videoWidth(), video->videoHeight())));
4402 if (surface->isValid()) {
4403 OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(std::move(su rface)));
4404 if (imageBuffer) {
4405 // The video element paints an RGBA frame into our surface h ere. By using an AcceleratedImageBufferSurface,
4406 // we enable the WebMediaPlayer implementation to do any nec essary color space conversion on the GPU (though it
4407 // may still do a CPU conversion and upload the results).
4408 video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0 , video->videoWidth(), video->videoHeight()), nullptr);
4409
4410 // This is a straight GPU-GPU copy, any necessary color spac e conversion was handled in the paintCurrentFrameInContext() call.
4411 if (imageBuffer->copyToPlatformTexture(contextGL(), texture- >object(), internalformat, type,
4412 level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4413 return;
4414 }
4415 }
4416 }
4417 }
4418 }
4419
4420 RefPtr<Image> image = videoFrameToImage(video);
4421 if (!image)
4422 return;
4423 texImageImpl(functionName, target, level, internalformat, xoffset, yoffset, zoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpack FlipY, m_unpackPremultiplyAlpha);
4424 }
4425
4254 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4426 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4255 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4427 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4256 { 4428 {
4429 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState);
4430 }
4431
4432 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionName f unctionName,
4433 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4434 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State)
4435 {
4436 const char* funcName = getTexImageFunctionName(functionName);
4257 if (isContextLost()) 4437 if (isContextLost())
4258 return; 4438 return;
4259 if (!validateHTMLVideoElement("texImage2D", video, exceptionState)) 4439 if (!validateImageBitmap(funcName, bitmap, exceptionState))
4260 return; 4440 return;
4261 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target); 4441 if (!validateTexImageBinding(funcName, functionName, target))
4262 if (!texture)
4263 return; 4442 return;
4264 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, 0, 0, 0)) 4443 TexImageFunctionType functionType;
4265 return; 4444 if (functionName == TexImage2D)
4266 4445 functionType = TexImage;
4267 // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible. 4446 else
4268 // Otherwise, it will fall back to the normal SW path. 4447 functionType = TexSubImage;
4269 if (GL_TEXTURE_2D == target) { 4448 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset))
4270 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level)
4271 && video->copyVideoTextureToPlatformTexture(contextGL(), texture->ob ject(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4272 return;
4273 }
4274
4275 // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
4276 OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBuffer Surface(IntSize(video->videoWidth(), video->videoHeight())));
4277 if (surface->isValid()) {
4278 OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(std::move(surfac e)));
4279 if (imageBuffer) {
4280 // The video element paints an RGBA frame into our surface here. By using an AcceleratedImageBufferSurface,
4281 // we enable the WebMediaPlayer implementation to do any necessa ry color space conversion on the GPU (though it
4282 // may still do a CPU conversion and upload the results).
4283 video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0, vi deo->videoWidth(), video->videoHeight()), nullptr);
4284
4285 // This is a straight GPU-GPU copy, any necessary color space co nversion was handled in the paintCurrentFrameInContext() call.
4286 if (imageBuffer->copyToPlatformTexture(contextGL(), texture->obj ect(), internalformat, type,
4287 level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4288 return;
4289 }
4290 }
4291 }
4292 }
4293
4294 // Normal pure SW path.
4295 RefPtr<Image> image = videoFrameToImage(video);
4296 if (!image)
4297 return;
4298 texImage2DImpl(target, level, internalformat, format, type, image.get(), Web GLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
4299 }
4300
4301 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4302 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4303 {
4304 if (isContextLost())
4305 return;
4306 if (!validateImageBitmap("texImage2D", bitmap, exceptionState))
4307 return;
4308 if (!validateTexture2DBinding("texImage2D", target))
4309 return;
4310 if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0))
4311 return; 4449 return;
4312 ASSERT(bitmap->bitmapImage()); 4450 ASSERT(bitmap->bitmapImage());
4313 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4451 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4314 SkPixmap pixmap; 4452 SkPixmap pixmap;
4315 OwnPtr<uint8_t[]> pixelData; 4453 OwnPtr<uint8_t[]> pixelData;
4316 uint8_t* pixelDataPtr = nullptr; 4454 uint8_t* pixelDataPtr = nullptr;
4317 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4455 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed
4318 // Use texture mailbox in that case. 4456 // Use texture mailbox in that case.
4319 bool peekSucceed = skImage->peekPixels(&pixmap); 4457 bool peekSucceed = skImage->peekPixels(&pixmap);
4320 if (peekSucceed) { 4458 if (peekSucceed) {
(...skipping 10 matching lines...) Expand all
4331 needConversion = false; 4469 needConversion = false;
4332 } else { 4470 } else {
4333 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4471 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4334 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4472 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4335 type = GL_FLOAT; 4473 type = GL_FLOAT;
4336 } 4474 }
4337 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4475 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha.
4338 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType); 4476 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType);
4339 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data)) 4477 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
4340 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) { 4478 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) {
4341 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data"); 4479 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4342 return; 4480 return;
4343 } 4481 }
4344 } 4482 }
4345 resetUnpackParameters(); 4483 resetUnpackParameters();
4346 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->heigh t(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4484 if (functionName == TexImage2D)
4485 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4486 else if (functionName == TexSubImage2D)
4487 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr );
4488 else // must be "texSubImage3D"
4489 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, bit map->width(), bitmap->height(), 1, format, type, needConversion ? data.data() : pixelDataPtr);
4347 restoreUnpackParameters(); 4490 restoreUnpackParameters();
4348 } 4491 }
4349 4492
4493 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4494 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4495 {
4496 texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format, type, 0, 0, 0, bitmap, exceptionState);
4497 }
4498
4350 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat) 4499 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat)
4351 { 4500 {
4352 if (isContextLost()) 4501 if (isContextLost())
4353 return; 4502 return;
4354 if (!validateTextureBinding("texParameter", target)) 4503 if (!validateTextureBinding("texParameter", target))
4355 return; 4504 return;
4356 switch (pname) { 4505 switch (pname) {
4357 case GL_TEXTURE_MIN_FILTER: 4506 case GL_TEXTURE_MIN_FILTER:
4358 case GL_TEXTURE_MAG_FILTER: 4507 case GL_TEXTURE_MAG_FILTER:
4359 break; 4508 break;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4402 void WebGLRenderingContextBase::texParameterf(GLenum target, GLenum pname, GLflo at param) 4551 void WebGLRenderingContextBase::texParameterf(GLenum target, GLenum pname, GLflo at param)
4403 { 4552 {
4404 texParameter(target, pname, param, 0, true); 4553 texParameter(target, pname, param, 0, true);
4405 } 4554 }
4406 4555
4407 void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint param) 4556 void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint param)
4408 { 4557 {
4409 texParameter(target, pname, 0, param, false); 4558 texParameter(target, pname, 0, param, false);
4410 } 4559 }
4411 4560
4412 void WebGLRenderingContextBase::texSubImage2DImpl(GLenum target, GLint level, GL int xoffset, GLint yoffset, GLenum format, GLenum type, Image* image, WebGLImage Conversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
4413 {
4414 // All calling functions check isContextLost, so a duplicate check is not ne eded here.
4415 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4416 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
4417 type = GL_FLOAT;
4418 }
4419 Vector<uint8_t> data;
4420 WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premul tiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
4421 if (!imageExtractor.imagePixelData()) {
4422 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
4423 return;
4424 }
4425 WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSour ceFormat();
4426 WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
4427 const void* imagePixelData = imageExtractor.imagePixelData();
4428
4429 bool needConversion = true;
4430 if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::Da taFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNo thing && !flipY) {
4431 needConversion = false;
4432 } else {
4433 if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtrac tor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
4434 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data ");
4435 return;
4436 }
4437 }
4438
4439 resetUnpackParameters();
4440 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, imageExtractor.i mageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data. data() : imagePixelData);
4441 restoreUnpackParameters();
4442 }
4443
4444 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4561 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4445 GLsizei width, GLsizei height, 4562 GLsizei width, GLsizei height,
4446 GLenum format, GLenum type, DOMArrayBufferView* pixels) 4563 GLenum format, GLenum type, DOMArrayBufferView* pixels)
4447 { 4564 {
4448 if (isContextLost()) 4565 texImageHelperDOMArrayBufferView(TexSubImage2D, target, level, 0, width, hei ght, 0, format, type, 1, xoffset, yoffset, 0, pixels);
4449 return;
4450 if (!validateTexture2DBinding("texSubImage2D", target))
4451 return;
4452 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, ta rget, level, 0, width, height, 1, 0, format, type, xoffset, yoffset, 0))
4453 return;
4454 if (!validateTexFuncData("texSubImage2D", Tex2D, level, width, height, 1, fo rmat, type, pixels, NullNotAllowed))
4455 return;
4456 void* data = pixels->baseAddress();
4457 Vector<uint8_t> tempData;
4458 bool changeUnpackAlignment = false;
4459 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
4460 if (!WebGLImageConversion::extractTextureData(width, height, format, typ e,
4461 m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, te mpData))
4462 return;
4463 data = tempData.data();
4464 changeUnpackAlignment = true;
4465 }
4466 if (changeUnpackAlignment)
4467 resetUnpackParameters();
4468 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, f ormat, type, data);
4469 if (changeUnpackAlignment)
4470 restoreUnpackParameters();
4471 } 4566 }
4472 4567
4473 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4568 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4474 GLenum format, GLenum type, ImageData* pixels) 4569 GLenum format, GLenum type, ImageData* pixels)
4475 { 4570 {
4476 if (isContextLost()) 4571 texImageHelperImageData(TexSubImage2D, target, level, 0, 0, format, type, 1, xoffset, yoffset, 0, pixels);
4477 return;
4478 if (!pixels) {
4479 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "no image data");
4480 return;
4481 }
4482 if (pixels->data()->bufferBase()->isNeutered()) {
4483 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "The source data ha s been neutered.");
4484 return;
4485 }
4486 if (!validateTexture2DBinding("texSubImage2D", target))
4487 return;
4488 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, 0, pixels->width(), pixels->height(), 1, 0, format, type, xoffset, yoffs et, 0))
4489 return;
4490 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4491 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
4492 type = GL_FLOAT;
4493 }
4494 Vector<uint8_t> data;
4495 bool needConversion = true;
4496 // The data from ImageData is always of format RGBA8.
4497 // No conversion is needed if destination format is RGBA and type is USIGNED _BYTE and no Flip or Premultiply operation is required.
4498 if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_un packPremultiplyAlpha) {
4499 needConversion = false;
4500 } else {
4501 if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebG LImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_u npackFlipY, m_unpackPremultiplyAlpha, data)) {
4502 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data ");
4503 return;
4504 }
4505 }
4506 resetUnpackParameters();
4507 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()-> data());
4508 restoreUnpackParameters();
4509 } 4572 }
4510 4573
4511 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4574 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4512 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) 4575 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState)
4513 { 4576 {
4514 if (isContextLost()) 4577 texImageHelperHTMLImageElement(TexSubImage2D, target, level, 0, format, type , xoffset, yoffset, 0, image, exceptionState);
4515 return;
4516 if (!validateHTMLImageElement("texSubImage2D", image, exceptionState))
4517 return;
4518 if (!validateTexture2DBinding("texSubImage2D", target))
4519 return;
4520
4521 RefPtr<Image> imageForRender = image->cachedImage()->getImage();
4522 if (imageForRender && imageForRender->isSVGImage())
4523 imageForRender = drawImageIntoBuffer(imageForRender.release(), image->wi dth(), image->height(), "texSubImage2D");
4524
4525 if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, Source HTMLImageElement, target, level, 0, imageForRender->width(), imageForRender->hei ght(), 1, 0, format, type, xoffset, yoffset, 0))
4526 return;
4527
4528 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4529 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
4530 type = GL_FLOAT;
4531 }
4532 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRen der.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultipl yAlpha);
4533 } 4578 }
4534 4579
4535 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4580 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4536 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4581 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
4537 { 4582 {
4538 if (isContextLost()) 4583 texImageHelperHTMLCanvasElement(TexSubImage2D, target, level, 0, format, typ e, xoffset, yoffset, 0, canvas, exceptionState);
4539 return;
4540 if (!validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState))
4541 return;
4542 WebGLTexture* texture = validateTexture2DBinding("texSubImage2D", target);
4543 if (!texture)
4544 return;
4545 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset , yoffset, 0))
4546 return;
4547
4548 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats.
4549 bool useReadBackPath = isWebGL2OrHigher()
4550 || extensionEnabled(OESTextureFloatName)
4551 || extensionEnabled(OESTextureHalfFloatName)
4552 || extensionEnabled(EXTsRGBName);
4553 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format.
4554 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
4555 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) {
4556 // 2D canvas has only FrontBuffer.
4557 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(),
4558 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4559 return;
4560 }
4561
4562 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, typ e, xoffset, yoffset, 0, canvas);
4563 } 4584 }
4564 4585
4565 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4586 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4566 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4587 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4567 { 4588 {
4568 if (isContextLost()) 4589 texImageHelperHTMLVideoElement(TexSubImage2D, target, level, 0, format, type , xoffset, yoffset, 0, video, exceptionState);
4569 return;
4570 if (!validateHTMLVideoElement("texSubImage2D", video, exceptionState))
4571 return;
4572 if (!validateTexture2DBinding("texSubImage2D", target))
4573 return;
4574 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, t arget, level, 0, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, 0))
4575 return;
4576
4577 RefPtr<Image> image = videoFrameToImage(video);
4578 if (!image)
4579 return;
4580 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get() , WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
4581 } 4590 }
4582 4591
4583 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4592 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4584 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) 4593 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4585 { 4594 {
4586 if (isContextLost()) 4595 texImageHelperImageBitmap(TexSubImage2D, target, level, 0, format, type, xof fset, yoffset, 0, bitmap, exceptionState);
4587 return;
4588 if (!validateImageBitmap("texSubImage2D", bitmap, exceptionState))
4589 return;
4590 if (!validateTexture2DBinding("texSubImage2D", target))
4591 return;
4592 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target , level, 0, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0))
4593 return;
4594 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4595 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
4596 type = GL_FLOAT;
4597 }
4598 ASSERT(bitmap->bitmapImage());
4599 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4600 SkPixmap pixmap;
4601 OwnPtr<uint8_t[]> pixelData;
4602 uint8_t* pixelDataPtr = nullptr;
4603 bool peekSucceed = skImage->peekPixels(&pixmap);
4604 if (peekSucceed) {
4605 pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
4606 } else if (skImage->isTextureBacked()) {
4607 pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? Premultip lyAlpha : DontPremultiplyAlpha);
4608 pixelDataPtr = pixelData.get();
4609 }
4610 Vector<uint8_t> data;
4611 bool needConversion = true;
4612 bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::k RGBA_8888_SkColorType);
4613 bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed);
4614 if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4615 needConversion = false;
4616 } else {
4617 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha.
4618 bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType ::kBGRA_8888_SkColorType);
4619 if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDat aPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
4620 || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixel DataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), form at, type, false, false, data))) {
4621 synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data ");
4622 return;
4623 }
4624 }
4625 resetUnpackParameters();
4626 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr);
4627 restoreUnpackParameters();
4628 } 4596 }
4629 4597
4630 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) 4598 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x)
4631 { 4599 {
4632 if (isContextLost() || !location) 4600 if (isContextLost() || !location)
4633 return; 4601 return;
4634 4602
4635 if (location->program() != m_currentProgram) { 4603 if (location->program() != m_currentProgram) {
4636 synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for c urrent program"); 4604 synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for c urrent program");
4637 return; 4605 return;
(...skipping 1786 matching lines...) Expand 10 before | Expand all | Expand 10 after
6424 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); 6392 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6425 } 6393 }
6426 6394
6427 void WebGLRenderingContextBase::restoreUnpackParameters() 6395 void WebGLRenderingContextBase::restoreUnpackParameters()
6428 { 6396 {
6429 if (m_unpackAlignment != 1) 6397 if (m_unpackAlignment != 1)
6430 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6398 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6431 } 6399 }
6432 6400
6433 } // namespace blink 6401 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698