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

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: forgot a DCHECK 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(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)
3958 { 3958 {
3959 const char* funcName = getTexImageFunctionName(functionID);
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 (functionID == TexImage2D) {
3987 texImage2DBase(target, level, internalformat, imageExtractor.imageWidth( ), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData);
3988 } else if (functionID == TexSubImage2D) {
3989 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, imageExtract or.imageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? d ata.data() : imagePixelData);
3990 } else {
3991 DCHECK_EQ(functionID, TexSubImage3D);
3992 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, ima geExtractor.imageWidth(), imageExtractor.imageHeight(), 1, format, type, needCon version ? data.data() : imagePixelData);
3993 }
3986 restoreUnpackParameters(); 3994 restoreUnpackParameters();
3987 } 3995 }
3988 3996
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) 3997 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 { 3998 {
3991 if (!validateTexFuncLevel(functionName, target, level)) 3999 if (!validateTexFuncLevel(functionName, target, level))
3992 return false; 4000 return false;
3993 4001
3994 if (!validateTexFuncParameters(functionName, functionType, target, level, in ternalformat, width, height, depth, border, format, type)) 4002 if (!validateTexFuncParameters(functionName, functionType, target, level, in ternalformat, width, height, depth, border, format, type))
3995 return false; 4003 return false;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4044 if (!image->currentFrameKnownToBeOpaque()) 4052 if (!image->currentFrameKnownToBeOpaque())
4045 buf->canvas()->clear(SK_ColorTRANSPARENT); 4053 buf->canvas()->clear(SK_ColorTRANSPARENT);
4046 4054
4047 IntRect srcRect(IntPoint(), image->size()); 4055 IntRect srcRect(IntPoint(), image->size());
4048 IntRect destRect(0, 0, size.width(), size.height()); 4056 IntRect destRect(0, 0, size.width(), size.height());
4049 SkPaint paint; 4057 SkPaint paint;
4050 image->draw(buf->canvas(), paint, destRect, srcRect, DoNotRespectImageOrient ation, Image::DoNotClampImageToSourceRect); 4058 image->draw(buf->canvas(), paint, destRect, srcRect, DoNotRespectImageOrient ation, Image::DoNotClampImageToSourceRect);
4051 return buf->newImageSnapshot(); 4059 return buf->newImageSnapshot();
4052 } 4060 }
4053 4061
4062 WebGLTexture* WebGLRenderingContextBase::validateTexImageBinding(const char* fun cName, TexImageFunctionID functionID, GLenum target)
4063 {
4064 return validateTexture2DBinding(funcName, target);
4065 }
4066
4067 const char* WebGLRenderingContextBase::getTexImageFunctionName(TexImageFunctionI D funcName)
4068 {
4069 if (funcName == TexImage2D)
4070 return "texImage2D";
4071 if (funcName == TexSubImage2D)
4072 return "texSubImage2D";
4073 if (funcName == TexSubImage3D)
4074 return "texSubImage3D";
4075 return "texImage3D";
Ken Russell (switch to Gerrit) 2016/06/07 04:06:53 Based on my own experience with this, it's more fu
4076 }
4077
4078 void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView(TexImageFunctio nID functionID,
4079 GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei hei ght, GLint border,
4080 GLenum format, GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLi nt zoffset, DOMArrayBufferView* pixels)
4081 {
4082 const char* funcName = getTexImageFunctionName(functionID);
4083 if (isContextLost())
4084 return;
4085 if (!validateTexImageBinding(funcName, functionID, target))
4086 return;
4087 TexImageFunctionType functionType;
4088 if (functionID == TexImage2D || functionID == TexImage3D)
4089 functionType = TexImage;
4090 else
4091 functionType = TexSubImage;
4092 if (!validateTexFunc(funcName, functionType, SourceArrayBufferView, target, level, internalformat, width, height, depth, border, format, type, xoffset, yoff set, zoffset))
4093 return;
4094 TexImageDimension sourceType;
4095 if (functionID == TexImage2D || functionID == TexSubImage2D)
4096 sourceType = Tex2D;
4097 else
4098 sourceType = Tex3D;
4099 if (!validateTexFuncData(funcName, sourceType, level, width, height, depth, format, type, pixels, NullAllowed))
4100 return;
4101 void* data = pixels ? pixels->baseAddress() : 0;
4102 Vector<uint8_t> tempData;
4103 bool changeUnpackAlignment = false;
4104 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
4105 if (sourceType == Tex2D) {
4106 if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempDat a))
4107 return;
4108 data = tempData.data();
4109 }
4110 changeUnpackAlignment = true;
4111 }
4112 // FIXME: implement flipY and premultiplyAlpha for tex(Sub)3D.
4113 if (functionID == TexImage3D) {
4114 contextGL()->TexImage3D(target, level, convertTexInternalFormat(internal format, type), width, height, depth, border, format, type, data);
4115 return;
4116 }
4117 if (functionID == TexSubImage3D) {
4118 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, wid th, height, depth, format, type, data);
4119 return;
4120 }
4121
4122 if (changeUnpackAlignment)
4123 resetUnpackParameters();
4124 if (functionID == TexImage2D)
4125 texImage2DBase(target, level, internalformat, width, height, border, for mat, type, data);
4126 else if (functionID == TexSubImage2D)
4127 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, heigh t, format, type, data);
4128 if (changeUnpackAlignment)
4129 restoreUnpackParameters();
4130 }
4131
4054 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4132 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4055 GLsizei width, GLsizei height, GLint border, 4133 GLsizei width, GLsizei height, GLint border,
4056 GLenum format, GLenum type, DOMArrayBufferView* pixels) 4134 GLenum format, GLenum type, DOMArrayBufferView* pixels)
4057 { 4135 {
4058 if (isContextLost()) 4136 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 } 4137 }
4081 4138
4082 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4139 void WebGLRenderingContextBase::texImageHelperImageData(TexImageFunctionID funct ionID,
4083 GLenum format, GLenum type, ImageData* pixels) 4140 GLenum target, GLint level, GLint internalformat, GLint border, GLenum forma t,
4141 GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, Ima geData* pixels)
4084 { 4142 {
4143 const char* funcName = getTexImageFunctionName(functionID);
4085 if (isContextLost()) 4144 if (isContextLost())
4086 return; 4145 return;
4087 if (!pixels) { 4146 if (!pixels) {
4088 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "no image data"); 4147 synthesizeGLError(GL_INVALID_VALUE, funcName, "no image data");
4089 return; 4148 return;
4090 } 4149 }
4091 if (pixels->data()->bufferBase()->isNeutered()) { 4150 if (pixels->data()->bufferBase()->isNeutered()) {
4092 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "The source data has b een neutered."); 4151 synthesizeGLError(GL_INVALID_VALUE, funcName, "The source data has been neutered.");
4093 return; 4152 return;
4094 } 4153 }
4095 if (!validateTexture2DBinding("texImage2D", target)) 4154 if (!validateTexImageBinding(funcName, functionID, target))
4096 return; 4155 return;
4097 if (!validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 1, 0, format, type, 0, 0, 0) ) 4156 TexImageFunctionType functionType;
4157 if (functionID == TexImage2D)
4158 functionType = TexImage;
4159 else
4160 functionType = TexSubImage;
4161 if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), depth, border, format, type, xoffset, yoffset, zoffset))
4098 return; 4162 return;
4099 Vector<uint8_t> data; 4163 Vector<uint8_t> data;
4100 bool needConversion = true; 4164 bool needConversion = true;
4101 // The data from ImageData is always of format RGBA8. 4165 // 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. 4166 // 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) { 4167 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
4104 needConversion = false; 4168 needConversion = false;
4105 } else { 4169 } else {
4106 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4170 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4107 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4171 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4108 type = GL_FLOAT; 4172 type = GL_FLOAT;
4109 } 4173 }
4110 if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebG LImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_u npackFlipY, m_unpackPremultiplyAlpha, data)) { 4174 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"); 4175 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4112 return; 4176 return;
4113 } 4177 }
4114 } 4178 }
4115 resetUnpackParameters(); 4179 resetUnpackParameters();
4116 texImage2DBase(target, level, internalformat, pixels->width(), pixels->heigh t(), 0, format, type, needConversion ? data.data() : pixels->data()->data()); 4180 if (functionID == TexImage2D) {
4181 texImage2DBase(target, level, internalformat, pixels->width(), pixels->h eight(), border, format, type, needConversion ? data.data() : pixels->data()->da ta());
4182 } else if (functionID == TexSubImage2D) {
4183 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->widt h(), pixels->height(), format, type, needConversion ? data.data() : pixels->data ()->data());
4184 } else {
4185 DCHECK_EQ(functionID, TexSubImage3D);
4186 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, pix els->width(), pixels->height(), depth, format, type, needConversion ? data.data( ) : pixels->data()->data());
4187 }
4117 restoreUnpackParameters(); 4188 restoreUnpackParameters();
4118 } 4189 }
4119 4190
4120 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4191 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4192 GLenum format, GLenum type, ImageData* pixels)
4193 {
4194 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format , type, 1, 0, 0, 0, pixels);
4195 }
4196
4197 void WebGLRenderingContextBase::texImageHelperHTMLImageElement(TexImageFunctionI D functionID,
4198 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4199 GLint yoffset, GLint zoffset, HTMLImageElement* image, ExceptionState& excep tionState)
4200 {
4201 const char* funcName = getTexImageFunctionName(functionID);
4202 if (isContextLost())
4203 return;
4204 if (!validateHTMLImageElement(funcName, image, exceptionState))
4205 return;
4206 if (!validateTexImageBinding(funcName, functionID, target))
4207 return;
4208
4209 RefPtr<Image> imageForRender = image->cachedImage()->getImage();
4210 if (imageForRender && imageForRender->isSVGImage())
4211 imageForRender = drawImageIntoBuffer(imageForRender.release(), image->wi dth(), image->height(), funcName);
4212
4213 TexImageFunctionType functionType;
4214 if (functionID == TexImage2D)
4215 functionType = TexImage;
4216 else
4217 functionType = TexSubImage;
4218 if (!imageForRender || !validateTexFunc(funcName, functionType, SourceHTMLIm ageElement, target, level, internalformat, imageForRender->width(), imageForRend er->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
4219 return;
4220
4221 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m _unpackFlipY, m_unpackPremultiplyAlpha);
4222 }
4223
4224 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4121 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) 4225 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState)
4122 { 4226 {
4123 if (isContextLost()) 4227 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 } 4228 }
4143 4229
4144 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) 4230 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type)
4145 { 4231 {
4146 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) 4232 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat))
4147 return false; 4233 return false;
4148 return true; 4234 return true;
4149 } 4235 }
4150 4236
4151 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, 4237 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) { 4291 } else if (functionType == TexSubImage3DByGPU) {
4206 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height()); 4292 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height());
4207 } 4293 }
4208 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 4294 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
4209 restoreCurrentFramebuffer(); 4295 restoreCurrentFramebuffer();
4210 contextGL()->DeleteFramebuffers(1, &tmpFBO); 4296 contextGL()->DeleteFramebuffers(1, &tmpFBO);
4211 contextGL()->DeleteTextures(1, &targetTexture); 4297 contextGL()->DeleteTextures(1, &targetTexture);
4212 } 4298 }
4213 } 4299 }
4214 4300
4301 void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunction ID functionID,
4302 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4303 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState)
4304 {
4305 const char* funcName = getTexImageFunctionName(functionID);
4306 if (isContextLost())
4307 return;
4308 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState))
4309 return;
4310 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4311 if (!texture)
4312 return;
4313 TexImageFunctionType functionType;
4314 if (functionID == TexImage2D)
4315 functionType = TexImage;
4316 else
4317 functionType = TexSubImage;
4318 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
4319 return;
4320 if (functionID == TexImage2D) {
4321 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format.
4322 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4323 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || !canUseTexImageCanvasByGPU(internalformat, type)) {
4324 // 2D canvas has only FrontBuffer.
4325 texImageImpl(TexImage2D, target, level, internalformat, xoffset, yof fset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration ).get(),
4326 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4327 return;
4328 }
4329
4330 texImage2DBase(target, level, internalformat, canvas->width(), canvas->h eight(), 0, format, type, 0);
4331 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalfor mat, type, 0, 0, 0, canvas);
4332 } else if (functionID == TexSubImage2D) {
4333 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal format s.
4334 bool useReadBackPath = isWebGL2OrHigher()
4335 || extensionEnabled(OESTextureFloatName)
4336 || extensionEnabled(OESTextureHalfFloatName)
4337 || extensionEnabled(EXTsRGBName);
4338 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't suppo rt float/integer/sRGB internal format.
4339 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to han dle more formats.
4340 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccele rated() || useReadBackPath) {
4341 // 2D canvas has only FrontBuffer.
4342 texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, f ormat, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4343 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPrem ultiplyAlpha);
4344 return;
4345 }
4346
4347 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas);
4348 } else {
4349 DCHECK_EQ(functionID, TexSubImage3D);
4350 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269).
4351 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
4352 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha);
4353 }
4354 }
4355
4215 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4356 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4216 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4357 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
4217 { 4358 {
4218 if (isContextLost()) 4359 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 } 4360 }
4240 4361
4241 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) 4362 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video)
4242 { 4363 {
4243 IntSize size(video->videoWidth(), video->videoHeight()); 4364 IntSize size(video->videoWidth(), video->videoHeight());
4244 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); 4365 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
4245 if (!buf) { 4366 if (!buf) {
4246 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); 4367 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
4247 return nullptr; 4368 return nullptr;
4248 } 4369 }
4249 IntRect destRect(0, 0, size.width(), size.height()); 4370 IntRect destRect(0, 0, size.width(), size.height());
4250 video->paintCurrentFrame(buf->canvas(), destRect, nullptr); 4371 video->paintCurrentFrame(buf->canvas(), destRect, nullptr);
4251 return buf->newImageSnapshot(); 4372 return buf->newImageSnapshot();
4252 } 4373 }
4253 4374
4375 void WebGLRenderingContextBase::texImageHelperHTMLVideoElement(TexImageFunctionI D functionID,
4376 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4377 GLint yoffset, GLint zoffset, HTMLVideoElement* video, ExceptionState& excep tionState)
4378 {
4379 const char* funcName = getTexImageFunctionName(functionID);
4380 if (isContextLost())
4381 return;
4382 if (!validateHTMLVideoElement(funcName, video, exceptionState))
4383 return;
4384 WebGLTexture* texture = validateTexImageBinding(funcName, functionID, target );
4385 if (!texture)
4386 return;
4387 TexImageFunctionType functionType;
4388 if (functionID == TexImage2D)
4389 functionType = TexImage;
4390 else
4391 functionType = TexSubImage;
4392 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, zoffset))
4393 return;
4394
4395 if (functionID == TexImage2D) {
4396 // Go through the fast path doing a GPU-GPU textures copy without a read back to system memory if possible.
4397 // Otherwise, it will fall back to the normal SW path.
4398 if (GL_TEXTURE_2D == target) {
4399 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalform at, type, level)
4400 && video->copyVideoTextureToPlatformTexture(contextGL(), texture ->object(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4401 return;
4402 }
4403
4404 // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
4405 OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBu fferSurface(IntSize(video->videoWidth(), video->videoHeight())));
4406 if (surface->isValid()) {
4407 OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(std::move(su rface)));
4408 if (imageBuffer) {
4409 // The video element paints an RGBA frame into our surface h ere. By using an AcceleratedImageBufferSurface,
4410 // we enable the WebMediaPlayer implementation to do any nec essary color space conversion on the GPU (though it
4411 // may still do a CPU conversion and upload the results).
4412 video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0 , video->videoWidth(), video->videoHeight()), nullptr);
4413
4414 // This is a straight GPU-GPU copy, any necessary color spac e conversion was handled in the paintCurrentFrameInContext() call.
4415 if (imageBuffer->copyToPlatformTexture(contextGL(), texture- >object(), internalformat, type,
4416 level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
4417 return;
4418 }
4419 }
4420 }
4421 }
4422 }
4423
4424 RefPtr<Image> image = videoFrameToImage(video);
4425 if (!image)
4426 return;
4427 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, zo ffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFl ipY, m_unpackPremultiplyAlpha);
4428 }
4429
4254 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, 4430 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4255 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4431 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4256 { 4432 {
4433 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, fo rmat, type, 0, 0, 0, video, exceptionState);
4434 }
4435
4436 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun ctionID,
4437 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset,
4438 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State)
4439 {
4440 const char* funcName = getTexImageFunctionName(functionID);
4257 if (isContextLost()) 4441 if (isContextLost())
4258 return; 4442 return;
4259 if (!validateHTMLVideoElement("texImage2D", video, exceptionState)) 4443 if (!validateImageBitmap(funcName, bitmap, exceptionState))
4260 return; 4444 return;
4261 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target); 4445 if (!validateTexImageBinding(funcName, functionID, target))
4262 if (!texture)
4263 return; 4446 return;
4264 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, 0, 0, 0)) 4447 TexImageFunctionType functionType;
4265 return; 4448 if (functionID == TexImage2D)
4266 4449 functionType = TexImage;
4267 // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible. 4450 else
4268 // Otherwise, it will fall back to the normal SW path. 4451 functionType = TexSubImage;
4269 if (GL_TEXTURE_2D == target) { 4452 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; 4453 return;
4312 ASSERT(bitmap->bitmapImage()); 4454 ASSERT(bitmap->bitmapImage());
4313 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); 4455 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
4314 SkPixmap pixmap; 4456 SkPixmap pixmap;
4315 OwnPtr<uint8_t[]> pixelData; 4457 OwnPtr<uint8_t[]> pixelData;
4316 uint8_t* pixelDataPtr = nullptr; 4458 uint8_t* pixelDataPtr = nullptr;
4317 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed 4459 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed
4318 // Use texture mailbox in that case. 4460 // Use texture mailbox in that case.
4319 bool peekSucceed = skImage->peekPixels(&pixmap); 4461 bool peekSucceed = skImage->peekPixels(&pixmap);
4320 if (peekSucceed) { 4462 if (peekSucceed) {
(...skipping 10 matching lines...) Expand all
4331 needConversion = false; 4473 needConversion = false;
4332 } else { 4474 } else {
4333 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { 4475 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4334 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. 4476 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed.
4335 type = GL_FLOAT; 4477 type = GL_FLOAT;
4336 } 4478 }
4337 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. 4479 // 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); 4480 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)) 4481 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))) { 4482 || (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"); 4483 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
4342 return; 4484 return;
4343 } 4485 }
4344 } 4486 }
4345 resetUnpackParameters(); 4487 resetUnpackParameters();
4346 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->heigh t(), 0, format, type, needConversion ? data.data() : pixelDataPtr); 4488 if (functionID == TexImage2D) {
4489 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
4490 } else if (functionID == TexSubImage2D) {
4491 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr );
4492 } else {
4493 DCHECK_EQ(functionID, TexSubImage3D);
4494 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, bit map->width(), bitmap->height(), 1, format, type, needConversion ? data.data() : pixelDataPtr);
4495 }
4347 restoreUnpackParameters(); 4496 restoreUnpackParameters();
4348 } 4497 }
4349 4498
4499 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat,
4500 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4501 {
4502 texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format, type, 0, 0, 0, bitmap, exceptionState);
4503 }
4504
4350 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat) 4505 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat)
4351 { 4506 {
4352 if (isContextLost()) 4507 if (isContextLost())
4353 return; 4508 return;
4354 if (!validateTextureBinding("texParameter", target)) 4509 if (!validateTextureBinding("texParameter", target))
4355 return; 4510 return;
4356 switch (pname) { 4511 switch (pname) {
4357 case GL_TEXTURE_MIN_FILTER: 4512 case GL_TEXTURE_MIN_FILTER:
4358 case GL_TEXTURE_MAG_FILTER: 4513 case GL_TEXTURE_MAG_FILTER:
4359 break; 4514 break;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4402 void WebGLRenderingContextBase::texParameterf(GLenum target, GLenum pname, GLflo at param) 4557 void WebGLRenderingContextBase::texParameterf(GLenum target, GLenum pname, GLflo at param)
4403 { 4558 {
4404 texParameter(target, pname, param, 0, true); 4559 texParameter(target, pname, param, 0, true);
4405 } 4560 }
4406 4561
4407 void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint param) 4562 void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint param)
4408 { 4563 {
4409 texParameter(target, pname, 0, param, false); 4564 texParameter(target, pname, 0, param, false);
4410 } 4565 }
4411 4566
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, 4567 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4445 GLsizei width, GLsizei height, 4568 GLsizei width, GLsizei height,
4446 GLenum format, GLenum type, DOMArrayBufferView* pixels) 4569 GLenum format, GLenum type, DOMArrayBufferView* pixels)
4447 { 4570 {
4448 if (isContextLost()) 4571 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 } 4572 }
4472 4573
4473 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4574 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4474 GLenum format, GLenum type, ImageData* pixels) 4575 GLenum format, GLenum type, ImageData* pixels)
4475 { 4576 {
4476 if (isContextLost()) 4577 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 } 4578 }
4510 4579
4511 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4580 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4512 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) 4581 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState)
4513 { 4582 {
4514 if (isContextLost()) 4583 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 } 4584 }
4534 4585
4535 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4586 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4536 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) 4587 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState)
4537 { 4588 {
4538 if (isContextLost()) 4589 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 } 4590 }
4564 4591
4565 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4592 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4566 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) 4593 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState)
4567 { 4594 {
4568 if (isContextLost()) 4595 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 } 4596 }
4582 4597
4583 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 4598 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
4584 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) 4599 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate)
4585 { 4600 {
4586 if (isContextLost()) 4601 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 } 4602 }
4629 4603
4630 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) 4604 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x)
4631 { 4605 {
4632 if (isContextLost() || !location) 4606 if (isContextLost() || !location)
4633 return; 4607 return;
4634 4608
4635 if (location->program() != m_currentProgram) { 4609 if (location->program() != m_currentProgram) {
4636 synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for c urrent program"); 4610 synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for c urrent program");
4637 return; 4611 return;
(...skipping 1786 matching lines...) Expand 10 before | Expand all | Expand 10 after
6424 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); 6398 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
6425 } 6399 }
6426 6400
6427 void WebGLRenderingContextBase::restoreUnpackParameters() 6401 void WebGLRenderingContextBase::restoreUnpackParameters()
6428 { 6402 {
6429 if (m_unpackAlignment != 1) 6403 if (m_unpackAlignment != 1)
6430 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); 6404 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
6431 } 6405 }
6432 6406
6433 } // namespace blink 6407 } // 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