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

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