OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |