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 4033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4044 if (!image->currentFrameKnownToBeOpaque()) | 4044 if (!image->currentFrameKnownToBeOpaque()) |
4045 buf->canvas()->clear(SK_ColorTRANSPARENT); | 4045 buf->canvas()->clear(SK_ColorTRANSPARENT); |
4046 | 4046 |
4047 IntRect srcRect(IntPoint(), image->size()); | 4047 IntRect srcRect(IntPoint(), image->size()); |
4048 IntRect destRect(0, 0, size.width(), size.height()); | 4048 IntRect destRect(0, 0, size.width(), size.height()); |
4049 SkPaint paint; | 4049 SkPaint paint; |
4050 image->draw(buf->canvas(), paint, destRect, srcRect, DoNotRespectImageOrient ation, Image::DoNotClampImageToSourceRect); | 4050 image->draw(buf->canvas(), paint, destRect, srcRect, DoNotRespectImageOrient ation, Image::DoNotClampImageToSourceRect); |
4051 return buf->newImageSnapshot(); | 4051 return buf->newImageSnapshot(); |
4052 } | 4052 } |
4053 | 4053 |
4054 WebGLTexture* WebGLRenderingContextBase::validateTexImageBinding(const char* fun cName, TexImageFunctionName functionName, GLenum target) | |
4055 { | |
4056 return validateTexture2DBinding(funcName, target); | |
4057 } | |
4058 | |
4059 const char* WebGLRenderingContextBase::getTexImageFunctionName(TexImageFunctionN ame funcName) | |
4060 { | |
4061 if (funcName == TexImage2D) | |
4062 return "texImage2D"; | |
4063 if (funcName == TexSubImage2D) | |
4064 return "texSubImage2D"; | |
4065 if (funcName == TexSubImage3D) | |
4066 return "texSubImage3D"; | |
4067 return "texImage3D"; | |
4068 } | |
4069 | |
4070 void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView(TexImageFunctio nName functionName, | |
4071 GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei hei ght, GLint border, | |
4072 GLenum format, GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLi nt zoffset, DOMArrayBufferView* pixels) | |
4073 { | |
4074 const char* funcName = getTexImageFunctionName(functionName); | |
4075 if (isContextLost()) | |
4076 return; | |
4077 if (validateTexImageBinding(funcName, functionName, target)) | |
4078 return; | |
4079 TexImageFunctionType functionType; | |
4080 if (functionName == TexImage2D || functionName == TexImage3D) | |
4081 functionType = TexImage; | |
4082 else | |
4083 functionType = TexSubImage; | |
4084 if (!validateTexFunc(funcName, functionType, SourceArrayBufferView, target, level, internalformat, width, height, depth, border, format, type, xoffset, yoff set, zoffset)) | |
4085 return; | |
4086 TexImageDimension sourceType; | |
4087 if (functionName == TexImage2D || functionName == TexSubImage2D) | |
4088 sourceType = Tex2D; | |
4089 else | |
4090 sourceType = Tex3D; | |
4091 if (!validateTexFuncData(funcName, sourceType, level, width, height, depth, format, type, pixels, NullAllowed)) | |
4092 return; | |
4093 void* data = pixels ? pixels->baseAddress() : 0; | |
4094 Vector<uint8_t> tempData; | |
4095 bool changeUnpackAlignment = false; | |
4096 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) { | |
4097 if (functionName == TexImage2D || functionName == TexSubImage2D) { | |
4098 if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempDat a)) | |
4099 return; | |
4100 data = tempData.data(); | |
4101 } else { | |
4102 NOTIMPLEMENTED(); | |
4103 if (functionName == TexImage3D) | |
4104 return; | |
4105 } | |
4106 changeUnpackAlignment = true; | |
4107 } | |
4108 if (functionName == TexImage3D) { | |
4109 contextGL()->TexImage3D(target, level, convertTexInternalFormat(internal format, type), width, height, depth, border, format, type, data); | |
4110 return; | |
4111 } | |
4112 | |
4113 if (changeUnpackAlignment) | |
4114 resetUnpackParameters(); | |
4115 if (functionName == TexImage2D) | |
4116 texImage2DBase(target, level, internalformat, width, height, border, for mat, type, data); | |
4117 else if (functionName == TexSubImage2D) | |
4118 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, heigh t, format, type, data); | |
4119 else | |
4120 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, wid th, height, depth, format, type, data); | |
4121 if (changeUnpackAlignment) | |
4122 restoreUnpackParameters(); | |
4123 } | |
4124 | |
4054 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4125 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, |
4055 GLsizei width, GLsizei height, GLint border, | 4126 GLsizei width, GLsizei height, GLint border, |
4056 GLenum format, GLenum type, DOMArrayBufferView* pixels) | 4127 GLenum format, GLenum type, DOMArrayBufferView* pixels) |
4057 { | 4128 { |
4058 if (isContextLost()) | 4129 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 } | 4130 } |
4081 | 4131 |
4082 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4132 void WebGLRenderingContextBase::texImageHelperImageData(TexImageFunctionName fun ctionName, |
4083 GLenum format, GLenum type, ImageData* pixels) | 4133 GLenum target, GLint level, GLint internalformat, GLint border, GLenum forma t, |
4134 GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, Ima geData* pixels) | |
4084 { | 4135 { |
4136 const char* funcName = getTexImageFunctionName(functionName); | |
4085 if (isContextLost()) | 4137 if (isContextLost()) |
4086 return; | 4138 return; |
4087 if (!pixels) { | 4139 if (!pixels) { |
4088 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "no image data"); | 4140 synthesizeGLError(GL_INVALID_VALUE, funcName, "no image data"); |
4089 return; | 4141 return; |
4090 } | 4142 } |
4091 if (pixels->data()->bufferBase()->isNeutered()) { | 4143 if (pixels->data()->bufferBase()->isNeutered()) { |
4092 synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "The source data has b een neutered."); | 4144 synthesizeGLError(GL_INVALID_VALUE, funcName, "The source data has been neutered."); |
4093 return; | 4145 return; |
4094 } | 4146 } |
4095 if (!validateTexture2DBinding("texImage2D", target)) | 4147 if (validateTexImageBinding(funcName, functionName, target)) |
4096 return; | 4148 return; |
4097 if (!validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 1, 0, format, type, 0, 0, 0) ) | 4149 TexImageFunctionType functionType; |
4150 if (functionName == TexImage2D) | |
4151 functionType = TexImage; | |
4152 else | |
4153 functionType = TexSubImage; | |
4154 if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), depth, border, format, type, xoffset, yoffset, zoffset)) | |
4098 return; | 4155 return; |
4099 Vector<uint8_t> data; | 4156 Vector<uint8_t> data; |
4100 bool needConversion = true; | 4157 bool needConversion = true; |
4101 // The data from ImageData is always of format RGBA8. | 4158 // 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. | 4159 // 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) { | 4160 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { |
4104 needConversion = false; | 4161 needConversion = false; |
4105 } else { | 4162 } else { |
4106 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 4163 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
4107 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. | 4164 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. |
4108 type = GL_FLOAT; | 4165 type = GL_FLOAT; |
4109 } | 4166 } |
4110 if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebG LImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_u npackFlipY, m_unpackPremultiplyAlpha, data)) { | 4167 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"); | 4168 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); |
4112 return; | 4169 return; |
4113 } | 4170 } |
4114 } | 4171 } |
4115 resetUnpackParameters(); | 4172 resetUnpackParameters(); |
4116 texImage2DBase(target, level, internalformat, pixels->width(), pixels->heigh t(), 0, format, type, needConversion ? data.data() : pixels->data()->data()); | 4173 if (functionName == TexImage2D) |
4174 texImage2DBase(target, level, internalformat, pixels->width(), pixels->h eight(), border, format, type, needConversion ? data.data() : pixels->data()->da ta()); | |
4175 else if (functionName == TexSubImage2D) | |
4176 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->widt h(), pixels->height(), format, type, needConversion ? data.data() : pixels->data ()->data()); | |
4177 else // must be "texSubImage3D" | |
4178 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, pix els->width(), pixels->height(), depth, format, type, needConversion ? data.data( ) : pixels->data()->data()); | |
4117 restoreUnpackParameters(); | 4179 restoreUnpackParameters(); |
4118 } | 4180 } |
4119 | 4181 |
4120 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4182 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, |
4183 GLenum format, GLenum type, ImageData* pixels) | |
4184 { | |
4185 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format , type, 1, 0, 0, 0, pixels); | |
4186 } | |
4187 | |
4188 bool WebGLRenderingContextBase::texImageHelperHTMLImageElement(TexImageFunctionN ame functionName, | |
4189 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, | |
4190 GLint yoffset, GLint zoffset, HTMLImageElement* image, ExceptionState& excep tionState) | |
4191 { | |
4192 const char* funcName = getTexImageFunctionName(functionName); | |
4193 if (isContextLost()) | |
4194 return false; | |
4195 if (!validateHTMLImageElement(funcName, image, exceptionState)) | |
4196 return false; | |
4197 if (validateTexImageBinding(funcName, functionName, target)) | |
4198 return false; | |
4199 if (functionName == TexSubImage3D) | |
4200 return true; | |
4201 | |
4202 RefPtr<Image> imageForRender = image->cachedImage()->getImage(); | |
4203 if (imageForRender && imageForRender->isSVGImage()) | |
4204 imageForRender = drawImageIntoBuffer(imageForRender.release(), image->wi dth(), image->height(), funcName); | |
4205 | |
4206 TexImageFunctionType functionType; | |
4207 if (functionName == TexImage2D) | |
4208 functionType = TexImage; | |
4209 else | |
4210 functionType = TexSubImage; | |
4211 if (!imageForRender || !validateTexFunc(funcName, functionType, SourceHTMLIm ageElement, target, level, internalformat, imageForRender->width(), imageForRend er->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) | |
4212 return false; | |
4213 | |
4214 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | |
4215 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | |
4216 type = GL_FLOAT; | |
4217 } | |
4218 if (functionName == TexImage2D) | |
4219 texImage2DImpl(target, level, internalformat, format, type, imageForRend er.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiply Alpha); | |
4220 else if (functionName == TexSubImage2D) | |
4221 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageFo rRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremul tiplyAlpha); | |
4222 return true; | |
4223 } | |
4224 | |
4225 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | |
4121 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) | 4226 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) |
4122 { | 4227 { |
4123 if (isContextLost()) | 4228 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 } | 4229 } |
4143 | 4230 |
4144 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) | 4231 bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type) |
4145 { | 4232 { |
4146 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) | 4233 if (isFloatType(type) || isIntegerFormat(internalformat) || isSRGBFormat(int ernalformat)) |
4147 return false; | 4234 return false; |
4148 return true; | 4235 return true; |
4149 } | 4236 } |
4150 | 4237 |
4151 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, | 4238 void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy pe, WebGLTexture* texture, GLenum target, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4205 } else if (functionType == TexSubImage3DByGPU) { | 4292 } else if (functionType == TexSubImage3DByGPU) { |
4206 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height()); | 4293 contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoff set, 0, 0, canvas->width(), canvas->height()); |
4207 } | 4294 } |
4208 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); | 4295 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); |
4209 restoreCurrentFramebuffer(); | 4296 restoreCurrentFramebuffer(); |
4210 contextGL()->DeleteFramebuffers(1, &tmpFBO); | 4297 contextGL()->DeleteFramebuffers(1, &tmpFBO); |
4211 contextGL()->DeleteTextures(1, &targetTexture); | 4298 contextGL()->DeleteTextures(1, &targetTexture); |
4212 } | 4299 } |
4213 } | 4300 } |
4214 | 4301 |
4302 WebGLTexture* WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImag eFunctionName functionName, | |
4303 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, | |
4304 GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exc eptionState) | |
4305 { | |
4306 const char* funcName = getTexImageFunctionName(functionName); | |
4307 if (isContextLost()) | |
4308 return nullptr; | |
4309 if (!validateHTMLCanvasElement(funcName, canvas, exceptionState)) | |
4310 return nullptr; | |
4311 WebGLTexture* texture = validateTexImageBinding(funcName, functionName, targ et); | |
4312 if (!texture) | |
4313 return nullptr; | |
4314 TexImageFunctionType functionType; | |
4315 if (functionName == TexImage2D) | |
4316 functionType = TexImage; | |
4317 else | |
4318 functionType = TexSubImage; | |
4319 if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target , level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) | |
4320 return nullptr; | |
4321 return texture; | |
4322 } | |
4323 | |
4215 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4324 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, |
4216 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) | 4325 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) |
4217 { | 4326 { |
4218 if (isContextLost()) | 4327 WebGLTexture* texture = texImageHelperHTMLCanvasElement(TexImage2D, target, level, internalformat, format, 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) | 4328 if (!texture) |
4224 return; | 4329 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. | 4330 // 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. | 4331 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. |
4230 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) { | 4332 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) { |
4231 // 2D canvas has only FrontBuffer. | 4333 // 2D canvas has only FrontBuffer. |
4232 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(), | 4334 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(), |
4233 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); | 4335 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); |
4234 return; | 4336 return; |
4235 } | 4337 } |
4236 | 4338 |
4237 texImage2DBase(target, level, internalformat, canvas->width(), canvas->heigh t(), 0, format, type, 0); | 4339 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); | 4340 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas); |
4239 } | 4341 } |
4240 | 4342 |
4241 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) | 4343 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) |
4242 { | 4344 { |
4243 IntSize size(video->videoWidth(), video->videoHeight()); | 4345 IntSize size(video->videoWidth(), video->videoHeight()); |
4244 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); | 4346 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); |
4245 if (!buf) { | 4347 if (!buf) { |
4246 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); | 4348 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); |
4247 return nullptr; | 4349 return nullptr; |
4248 } | 4350 } |
4249 IntRect destRect(0, 0, size.width(), size.height()); | 4351 IntRect destRect(0, 0, size.width(), size.height()); |
4250 video->paintCurrentFrame(buf->canvas(), destRect, nullptr); | 4352 video->paintCurrentFrame(buf->canvas(), destRect, nullptr); |
4251 return buf->newImageSnapshot(); | 4353 return buf->newImageSnapshot(); |
4252 } | 4354 } |
4253 | 4355 |
4356 WebGLTexture* WebGLRenderingContextBase::texImageHelperHTMLVideoElement(TexImage FunctionName functionName, | |
4357 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, | |
4358 GLint yoffset, GLint zoffset, HTMLVideoElement* video, ExceptionState& excep tionState) | |
4359 { | |
4360 const char* funcName = getTexImageFunctionName(functionName); | |
4361 if (isContextLost()) | |
4362 return nullptr; | |
4363 if (!validateHTMLVideoElement(funcName, video, exceptionState)) | |
4364 return nullptr; | |
4365 WebGLTexture* texture = validateTexImageBinding(funcName, functionName, targ et); | |
4366 if (!texture) | |
4367 return nullptr; | |
4368 TexImageFunctionType functionType; | |
4369 if (functionName == TexImage2D) | |
4370 functionType = TexImage; | |
4371 else | |
4372 functionType = TexSubImage; | |
4373 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, zoffset)) | |
4374 return nullptr; | |
4375 return texture; | |
4376 } | |
4377 | |
4254 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4378 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, |
4255 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) | 4379 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) |
4256 { | 4380 { |
4257 if (isContextLost()) | 4381 WebGLTexture* texture = texImageHelperHTMLVideoElement(TexImage2D, target, l evel, internalformat, format, type, 0, 0, 0, video, exceptionState); |
4258 return; | |
4259 if (!validateHTMLVideoElement("texImage2D", video, exceptionState)) | |
4260 return; | |
4261 WebGLTexture* texture = validateTexture2DBinding("texImage2D", target); | |
4262 if (!texture) | 4382 if (!texture) |
4263 return; | 4383 return; |
4264 if (!validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, 0, 0, 0)) | |
4265 return; | |
4266 | |
4267 // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible. | 4384 // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible. |
4268 // Otherwise, it will fall back to the normal SW path. | 4385 // Otherwise, it will fall back to the normal SW path. |
4269 if (GL_TEXTURE_2D == target) { | 4386 if (GL_TEXTURE_2D == target) { |
4270 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level) | 4387 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level) |
4271 && video->copyVideoTextureToPlatformTexture(contextGL(), texture->ob ject(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) { | 4388 && video->copyVideoTextureToPlatformTexture(contextGL(), texture->ob ject(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
4272 return; | 4389 return; |
4273 } | 4390 } |
4274 | 4391 |
4275 // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU. | 4392 // 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()))); | 4393 OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBuffer Surface(IntSize(video->videoWidth(), video->videoHeight()))); |
(...skipping 14 matching lines...) Expand all Loading... | |
4291 } | 4408 } |
4292 } | 4409 } |
4293 | 4410 |
4294 // Normal pure SW path. | 4411 // Normal pure SW path. |
4295 RefPtr<Image> image = videoFrameToImage(video); | 4412 RefPtr<Image> image = videoFrameToImage(video); |
4296 if (!image) | 4413 if (!image) |
4297 return; | 4414 return; |
4298 texImage2DImpl(target, level, internalformat, format, type, image.get(), Web GLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); | 4415 texImage2DImpl(target, level, internalformat, format, type, image.get(), Web GLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); |
4299 } | 4416 } |
4300 | 4417 |
4301 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4418 void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionName f unctionName, |
4302 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) | 4419 GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type , GLint xoffset, |
4420 GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exception State) | |
4303 { | 4421 { |
4422 const char* funcName = getTexImageFunctionName(functionName); | |
4304 if (isContextLost()) | 4423 if (isContextLost()) |
4305 return; | 4424 return; |
4306 if (!validateImageBitmap("texImage2D", bitmap, exceptionState)) | 4425 if (!validateImageBitmap(funcName, bitmap, exceptionState)) |
4307 return; | 4426 return; |
4308 if (!validateTexture2DBinding("texImage2D", target)) | 4427 if (validateTexImageBinding(funcName, functionName, target)) |
4309 return; | 4428 return; |
4310 if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0)) | 4429 TexImageFunctionType functionType; |
4430 if (functionName == TexImage2D) | |
4431 functionType = TexImage; | |
4432 else | |
4433 functionType = TexSubImage; | |
4434 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, leve l, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffse t, yoffset, zoffset)) | |
4311 return; | 4435 return; |
4312 ASSERT(bitmap->bitmapImage()); | 4436 ASSERT(bitmap->bitmapImage()); |
4313 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); | 4437 RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); |
4314 SkPixmap pixmap; | 4438 SkPixmap pixmap; |
4315 OwnPtr<uint8_t[]> pixelData; | 4439 OwnPtr<uint8_t[]> pixelData; |
4316 uint8_t* pixelDataPtr = nullptr; | 4440 uint8_t* pixelDataPtr = nullptr; |
4317 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed | 4441 // TODO(crbug.com/613411): peekPixels fails if the SkImage is texture-backed |
4318 // Use texture mailbox in that case. | 4442 // Use texture mailbox in that case. |
4319 bool peekSucceed = skImage->peekPixels(&pixmap); | 4443 bool peekSucceed = skImage->peekPixels(&pixmap); |
4320 if (peekSucceed) { | 4444 if (peekSucceed) { |
(...skipping 10 matching lines...) Expand all Loading... | |
4331 needConversion = false; | 4455 needConversion = false; |
4332 } else { | 4456 } else { |
4333 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 4457 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
4334 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. | 4458 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implement ed. |
4335 type = GL_FLOAT; | 4459 type = GL_FLOAT; |
4336 } | 4460 } |
4337 // In the case of ImageBitmap, we do not need to apply flipY or premulti plyAlpha. | 4461 // 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); | 4462 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)) | 4463 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))) { | 4464 || (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"); | 4465 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); |
4342 return; | 4466 return; |
4343 } | 4467 } |
4344 } | 4468 } |
4345 resetUnpackParameters(); | 4469 resetUnpackParameters(); |
4346 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->heigh t(), 0, format, type, needConversion ? data.data() : pixelDataPtr); | 4470 if (functionName == TexImage2D) |
4471 texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->h eight(), 0, format, type, needConversion ? data.data() : pixelDataPtr); | |
4472 else if (functionName == TexSubImage2D) | |
4473 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->widt h(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr ); | |
4474 else // must be "texSubImage3D" | |
4475 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, bit map->width(), bitmap->height(), 1, format, type, needConversion ? data.data() : pixelDataPtr); | |
4347 restoreUnpackParameters(); | 4476 restoreUnpackParameters(); |
4348 } | 4477 } |
4349 | 4478 |
4479 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | |
4480 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) | |
4481 { | |
4482 texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format, type, 0, 0, 0, bitmap, exceptionState); | |
4483 } | |
4484 | |
4350 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat) | 4485 void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloa t paramf, GLint parami, bool isFloat) |
4351 { | 4486 { |
4352 if (isContextLost()) | 4487 if (isContextLost()) |
4353 return; | 4488 return; |
4354 if (!validateTextureBinding("texParameter", target)) | 4489 if (!validateTextureBinding("texParameter", target)) |
4355 return; | 4490 return; |
4356 switch (pname) { | 4491 switch (pname) { |
4357 case GL_TEXTURE_MIN_FILTER: | 4492 case GL_TEXTURE_MIN_FILTER: |
4358 case GL_TEXTURE_MAG_FILTER: | 4493 case GL_TEXTURE_MAG_FILTER: |
4359 break; | 4494 break; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4438 | 4573 |
4439 resetUnpackParameters(); | 4574 resetUnpackParameters(); |
4440 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, imageExtractor.i mageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data. data() : imagePixelData); | 4575 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, imageExtractor.i mageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data. data() : imagePixelData); |
4441 restoreUnpackParameters(); | 4576 restoreUnpackParameters(); |
4442 } | 4577 } |
4443 | 4578 |
4444 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4579 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
4445 GLsizei width, GLsizei height, | 4580 GLsizei width, GLsizei height, |
4446 GLenum format, GLenum type, DOMArrayBufferView* pixels) | 4581 GLenum format, GLenum type, DOMArrayBufferView* pixels) |
4447 { | 4582 { |
4448 if (isContextLost()) | 4583 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 } | 4584 } |
4472 | 4585 |
4473 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4586 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
4474 GLenum format, GLenum type, ImageData* pixels) | 4587 GLenum format, GLenum type, ImageData* pixels) |
4475 { | 4588 { |
4476 if (isContextLost()) | 4589 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 } | 4590 } |
4510 | 4591 |
4511 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4592 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
4512 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) | 4593 GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& excepti onState) |
4513 { | 4594 { |
4514 if (isContextLost()) | 4595 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 } | 4596 } |
4534 | 4597 |
4535 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4598 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
4536 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) | 4599 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) |
4537 { | 4600 { |
4538 if (isContextLost()) | 4601 WebGLTexture* texture = texImageHelperHTMLCanvasElement(TexSubImage2D, targe t, level, 0, format, type, xoffset, yoffset, 0, canvas, exceptionState); |
Ken Russell (switch to Gerrit)
2016/06/01 00:34:03
It's confusing that some of the new helpers are ex
| |
4539 return; | |
4540 if (!validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)) | |
4541 return; | |
4542 WebGLTexture* texture = validateTexture2DBinding("texSubImage2D", target); | |
4543 if (!texture) | 4602 if (!texture) |
4544 return; | 4603 return; |
4545 if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset , yoffset, 0)) | |
4546 return; | |
4547 | 4604 |
4548 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats. | 4605 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats. |
4549 bool useReadBackPath = isWebGL2OrHigher() | 4606 bool useReadBackPath = isWebGL2OrHigher() |
4550 || extensionEnabled(OESTextureFloatName) | 4607 || extensionEnabled(OESTextureFloatName) |
4551 || extensionEnabled(OESTextureHalfFloatName) | 4608 || extensionEnabled(OESTextureHalfFloatName) |
4552 || extensionEnabled(EXTsRGBName); | 4609 || extensionEnabled(EXTsRGBName); |
4553 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. | 4610 // 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. | 4611 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. |
4555 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) { | 4612 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) { |
4556 // 2D canvas has only FrontBuffer. | 4613 // 2D canvas has only FrontBuffer. |
4557 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(), | 4614 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(), |
4558 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); | 4615 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); |
4559 return; | 4616 return; |
4560 } | 4617 } |
4561 | 4618 |
4562 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, typ e, xoffset, yoffset, 0, canvas); | 4619 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, typ e, xoffset, yoffset, 0, canvas); |
4563 } | 4620 } |
4564 | 4621 |
4565 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4622 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
4566 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) | 4623 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) |
4567 { | 4624 { |
4568 if (isContextLost()) | 4625 WebGLTexture* texture = texImageHelperHTMLVideoElement(TexSubImage2D, target , level, 0, format, type, xoffset, yoffset, 0, video, exceptionState); |
4569 return; | 4626 if (!texture) |
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; | 4627 return; |
4576 | 4628 |
4577 RefPtr<Image> image = videoFrameToImage(video); | 4629 RefPtr<Image> image = videoFrameToImage(video); |
4578 if (!image) | 4630 if (!image) |
4579 return; | 4631 return; |
4580 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get() , WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); | 4632 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get() , WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha); |
4581 } | 4633 } |
4582 | 4634 |
4583 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4635 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
4584 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) | 4636 GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionSt ate) |
4585 { | 4637 { |
4586 if (isContextLost()) | 4638 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 } | 4639 } |
4629 | 4640 |
4630 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) | 4641 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x) |
4631 { | 4642 { |
4632 if (isContextLost() || !location) | 4643 if (isContextLost() || !location) |
4633 return; | 4644 return; |
4634 | 4645 |
4635 if (location->program() != m_currentProgram) { | 4646 if (location->program() != m_currentProgram) { |
4636 synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for c urrent program"); | 4647 synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for c urrent program"); |
4637 return; | 4648 return; |
(...skipping 1786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6424 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); | 6435 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, 1); |
6425 } | 6436 } |
6426 | 6437 |
6427 void WebGLRenderingContextBase::restoreUnpackParameters() | 6438 void WebGLRenderingContextBase::restoreUnpackParameters() |
6428 { | 6439 { |
6429 if (m_unpackAlignment != 1) | 6440 if (m_unpackAlignment != 1) |
6430 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); | 6441 contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); |
6431 } | 6442 } |
6432 | 6443 |
6433 } // namespace blink | 6444 } // namespace blink |
OLD | NEW |