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 4329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4340 GLint internalformat, | 4340 GLint internalformat, |
4341 GLint xoffset, | 4341 GLint xoffset, |
4342 GLint yoffset, | 4342 GLint yoffset, |
4343 GLint zoffset, | 4343 GLint zoffset, |
4344 GLenum format, | 4344 GLenum format, |
4345 GLenum type, | 4345 GLenum type, |
4346 Image* image, | 4346 Image* image, |
4347 WebGLImageConversion::ImageHtmlDomSource domSource, | 4347 WebGLImageConversion::ImageHtmlDomSource domSource, |
4348 bool flipY, | 4348 bool flipY, |
4349 bool premultiplyAlpha, | 4349 bool premultiplyAlpha, |
4350 const IntRect& sourceImageRect) { | 4350 const IntRect& sourceImageRect, |
4351 GLsizei depth, | |
4352 GLint unpackImageHeight) { | |
4351 const char* funcName = getTexImageFunctionName(functionID); | 4353 const char* funcName = getTexImageFunctionName(functionID); |
4352 // All calling functions check isContextLost, so a duplicate check is not | 4354 // All calling functions check isContextLost, so a duplicate check is not |
4353 // needed here. | 4355 // needed here. |
4354 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 4356 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
4355 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | 4357 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
4356 type = GL_FLOAT; | 4358 type = GL_FLOAT; |
4357 } | 4359 } |
4358 Vector<uint8_t> data; | 4360 Vector<uint8_t> data; |
4359 | 4361 |
4360 IntRect subRect = sourceImageRect; | 4362 IntRect subRect = sourceImageRect; |
(...skipping 19 matching lines...) Expand all Loading... | |
4380 | 4382 |
4381 if (subRect.x() < 0 || subRect.y() < 0 || subRect.maxX() > image->width() || | 4383 if (subRect.x() < 0 || subRect.y() < 0 || subRect.maxX() > image->width() || |
4382 subRect.maxY() > image->height() || subRect.width() < 0 || | 4384 subRect.maxY() > image->height() || subRect.width() < 0 || |
4383 subRect.height() < 0) { | 4385 subRect.height() < 0) { |
4384 synthesizeGLError(GL_INVALID_OPERATION, funcName, | 4386 synthesizeGLError(GL_INVALID_OPERATION, funcName, |
4385 "source sub-rectangle specified via pixel unpack " | 4387 "source sub-rectangle specified via pixel unpack " |
4386 "parameters is invalid"); | 4388 "parameters is invalid"); |
4387 return; | 4389 return; |
4388 } | 4390 } |
4389 | 4391 |
4392 if (functionID == TexImage3D || functionID == TexSubImage3D) { | |
4393 DCHECK_GE(unpackImageHeight, 0); | |
4394 | |
4395 // Verify that the image data can cover the required depth. | |
4396 CheckedNumeric<GLint> maxDepthSupported = 1; | |
4397 if (unpackImageHeight) { | |
4398 maxDepthSupported = subRect.height(); | |
4399 maxDepthSupported /= unpackImageHeight; | |
4400 } | |
4401 | |
4402 if (!maxDepthSupported.IsValid() || | |
4403 maxDepthSupported.ValueOrDie() < depth) { | |
4404 synthesizeGLError( | |
4405 GL_INVALID_OPERATION, funcName, | |
4406 "Not enough data supplied to upload to a 3D texture with depth > 1"); | |
Zhenyao Mo
2016/11/08 18:10:31
missing a return here.
Ken Russell (switch to Gerrit)
2016/11/08 21:46:32
Fixed.
| |
4407 } | |
4408 } else { | |
4409 DCHECK_EQ(depth, 1); | |
4410 DCHECK_EQ(unpackImageHeight, 0); | |
4411 } | |
4412 | |
4390 // Adjust the source image rectangle if doing a y-flip. | 4413 // Adjust the source image rectangle if doing a y-flip. |
4391 IntRect adjustedSourceImageRect = subRect; | 4414 IntRect adjustedSourceImageRect = subRect; |
4392 if (flipY) { | 4415 if (flipY) { |
4393 adjustedSourceImageRect.setY(image->height() - | 4416 adjustedSourceImageRect.setY(image->height() - |
4394 adjustedSourceImageRect.maxY()); | 4417 adjustedSourceImageRect.maxY()); |
4395 } | 4418 } |
4396 | 4419 |
4397 WebGLImageConversion::ImageExtractor imageExtractor( | 4420 WebGLImageConversion::ImageExtractor imageExtractor( |
4398 image, domSource, premultiplyAlpha, | 4421 image, domSource, premultiplyAlpha, |
4399 m_unpackColorspaceConversion == GL_NONE); | 4422 m_unpackColorspaceConversion == GL_NONE); |
(...skipping 29 matching lines...) Expand all Loading... | |
4429 texImage2DBase(target, level, internalformat, | 4452 texImage2DBase(target, level, internalformat, |
4430 adjustedSourceImageRect.width(), | 4453 adjustedSourceImageRect.width(), |
4431 adjustedSourceImageRect.height(), 0, format, type, | 4454 adjustedSourceImageRect.height(), 0, format, type, |
4432 needConversion ? data.data() : imagePixelData); | 4455 needConversion ? data.data() : imagePixelData); |
4433 } else if (functionID == TexSubImage2D) { | 4456 } else if (functionID == TexSubImage2D) { |
4434 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, | 4457 contextGL()->TexSubImage2D(target, level, xoffset, yoffset, |
4435 adjustedSourceImageRect.width(), | 4458 adjustedSourceImageRect.width(), |
4436 adjustedSourceImageRect.height(), format, type, | 4459 adjustedSourceImageRect.height(), format, type, |
4437 needConversion ? data.data() : imagePixelData); | 4460 needConversion ? data.data() : imagePixelData); |
4438 } else { | 4461 } else { |
4439 DCHECK_EQ(functionID, TexSubImage3D); | 4462 // 3D functions. |
4440 contextGL()->TexSubImage3D( | 4463 GLint uploadHeight = adjustedSourceImageRect.height(); |
4441 target, level, xoffset, yoffset, zoffset, | 4464 if (unpackImageHeight) { |
4442 adjustedSourceImageRect.width(), adjustedSourceImageRect.height(), 1, | 4465 // GL_UNPACK_IMAGE_HEIGHT overrides the passed-in height. |
4443 format, type, needConversion ? data.data() : imagePixelData); | 4466 uploadHeight = unpackImageHeight; |
4467 } | |
4468 if (functionID == TexImage3D) { | |
4469 contextGL()->TexImage3D(target, level, internalformat, | |
4470 adjustedSourceImageRect.width(), uploadHeight, | |
4471 depth, 0, format, type, | |
4472 needConversion ? data.data() : imagePixelData); | |
4473 } else { | |
4474 DCHECK_EQ(functionID, TexSubImage3D); | |
4475 contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, | |
4476 adjustedSourceImageRect.width(), uploadHeight, | |
4477 depth, format, type, | |
4478 needConversion ? data.data() : imagePixelData); | |
4479 } | |
4444 } | 4480 } |
4445 restoreUnpackParameters(); | 4481 restoreUnpackParameters(); |
4446 } | 4482 } |
4447 | 4483 |
4448 bool WebGLRenderingContextBase::validateTexFunc( | 4484 bool WebGLRenderingContextBase::validateTexFunc( |
4449 const char* functionName, | 4485 const char* functionName, |
4450 TexImageFunctionType functionType, | 4486 TexImageFunctionType functionType, |
4451 TexFuncValidationSourceType sourceType, | 4487 TexFuncValidationSourceType sourceType, |
4452 GLenum target, | 4488 GLenum target, |
4453 GLint level, | 4489 GLint level, |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4757 GLenum target, | 4793 GLenum target, |
4758 GLint level, | 4794 GLint level, |
4759 GLint internalformat, | 4795 GLint internalformat, |
4760 GLenum format, | 4796 GLenum format, |
4761 GLenum type, | 4797 GLenum type, |
4762 GLint xoffset, | 4798 GLint xoffset, |
4763 GLint yoffset, | 4799 GLint yoffset, |
4764 GLint zoffset, | 4800 GLint zoffset, |
4765 HTMLImageElement* image, | 4801 HTMLImageElement* image, |
4766 const IntRect& sourceImageRect, | 4802 const IntRect& sourceImageRect, |
4803 GLsizei depth, | |
4804 GLint unpackImageHeight, | |
4767 ExceptionState& exceptionState) { | 4805 ExceptionState& exceptionState) { |
4768 const char* funcName = getTexImageFunctionName(functionID); | 4806 const char* funcName = getTexImageFunctionName(functionID); |
4769 if (isContextLost()) | 4807 if (isContextLost()) |
4770 return; | 4808 return; |
4771 if (!validateHTMLImageElement(funcName, image, exceptionState)) | 4809 if (!validateHTMLImageElement(funcName, image, exceptionState)) |
4772 return; | 4810 return; |
4773 if (!validateTexImageBinding(funcName, functionID, target)) | 4811 if (!validateTexImageBinding(funcName, functionID, target)) |
4774 return; | 4812 return; |
4775 | 4813 |
4776 RefPtr<Image> imageForRender = image->cachedImage()->getImage(); | 4814 RefPtr<Image> imageForRender = image->cachedImage()->getImage(); |
4777 if (imageForRender && imageForRender->isSVGImage()) | 4815 if (imageForRender && imageForRender->isSVGImage()) |
4778 imageForRender = drawImageIntoBuffer( | 4816 imageForRender = drawImageIntoBuffer( |
4779 imageForRender.release(), image->width(), image->height(), funcName); | 4817 imageForRender.release(), image->width(), image->height(), funcName); |
4780 | 4818 |
4781 TexImageFunctionType functionType; | 4819 TexImageFunctionType functionType; |
4782 if (functionID == TexImage2D) | 4820 if (functionID == TexImage2D) |
4783 functionType = TexImage; | 4821 functionType = TexImage; |
4784 else | 4822 else |
4785 functionType = TexSubImage; | 4823 functionType = TexSubImage; |
4786 if (!imageForRender || | 4824 if (!imageForRender || |
4787 !validateTexFunc(funcName, functionType, SourceHTMLImageElement, target, | 4825 !validateTexFunc(funcName, functionType, SourceHTMLImageElement, target, |
4788 level, internalformat, imageForRender->width(), | 4826 level, internalformat, imageForRender->width(), |
4789 imageForRender->height(), 1, 0, format, type, xoffset, | 4827 imageForRender->height(), depth, 0, format, type, |
4790 yoffset, zoffset)) | 4828 xoffset, yoffset, zoffset)) |
4791 return; | 4829 return; |
4792 | 4830 |
4793 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 4831 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
4794 zoffset, format, type, imageForRender.get(), | 4832 zoffset, format, type, imageForRender.get(), |
4795 WebGLImageConversion::HtmlDomImage, m_unpackFlipY, | 4833 WebGLImageConversion::HtmlDomImage, m_unpackFlipY, |
4796 m_unpackPremultiplyAlpha, sourceImageRect); | 4834 m_unpackPremultiplyAlpha, sourceImageRect, depth, |
4835 unpackImageHeight); | |
4797 } | 4836 } |
4798 | 4837 |
4799 void WebGLRenderingContextBase::texImage2D(GLenum target, | 4838 void WebGLRenderingContextBase::texImage2D(GLenum target, |
4800 GLint level, | 4839 GLint level, |
4801 GLint internalformat, | 4840 GLint internalformat, |
4802 GLenum format, | 4841 GLenum format, |
4803 GLenum type, | 4842 GLenum type, |
4804 HTMLImageElement* image, | 4843 HTMLImageElement* image, |
4805 ExceptionState& exceptionState) { | 4844 ExceptionState& exceptionState) { |
4806 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, | 4845 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, |
4807 format, type, 0, 0, 0, image, | 4846 format, type, 0, 0, 0, image, |
4808 sentinelEmptyRect(), exceptionState); | 4847 sentinelEmptyRect(), 1, 0, exceptionState); |
4809 } | 4848 } |
4810 | 4849 |
4811 bool WebGLRenderingContextBase::canUseTexImageByGPU( | 4850 bool WebGLRenderingContextBase::canUseTexImageByGPU( |
4812 TexImageFunctionID functionID, | 4851 TexImageFunctionID functionID, |
4813 GLint internalformat, | 4852 GLint internalformat, |
4814 GLenum type) { | 4853 GLenum type) { |
4815 if (functionID == TexImage2D && | 4854 if (functionID == TexImage2D && |
4816 (isFloatType(type) || isIntegerFormat(internalformat) || | 4855 (isFloatType(type) || isIntegerFormat(internalformat) || |
4817 isSRGBFormat(internalformat))) | 4856 isSRGBFormat(internalformat))) |
4818 return false; | 4857 return false; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4966 // upgraded to handle more formats. | 5005 // upgraded to handle more formats. |
4967 if (!canvas->renderingContext() || | 5006 if (!canvas->renderingContext() || |
4968 !canvas->renderingContext()->isAccelerated() || | 5007 !canvas->renderingContext()->isAccelerated() || |
4969 !canUseTexImageByGPU(functionID, internalformat, type)) { | 5008 !canUseTexImageByGPU(functionID, internalformat, type)) { |
4970 // 2D canvas has only FrontBuffer. | 5009 // 2D canvas has only FrontBuffer. |
4971 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 5010 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
4972 zoffset, format, type, | 5011 zoffset, format, type, |
4973 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), | 5012 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), |
4974 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, | 5013 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, |
4975 m_unpackPremultiplyAlpha, | 5014 m_unpackPremultiplyAlpha, |
4976 IntRect(0, 0, canvas->width(), canvas->height())); | 5015 IntRect(0, 0, canvas->width(), canvas->height()), 1, 0); |
4977 return; | 5016 return; |
4978 } | 5017 } |
4979 | 5018 |
4980 if (functionID == TexImage2D) { | 5019 if (functionID == TexImage2D) { |
4981 texImage2DBase(target, level, internalformat, canvas->width(), | 5020 texImage2DBase(target, level, internalformat, canvas->width(), |
4982 canvas->height(), 0, format, type, 0); | 5021 canvas->height(), 0, format, type, 0); |
4983 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, | 5022 texImageByGPU(TexImage2DByGPU, texture, target, level, internalformat, |
4984 type, 0, 0, 0, canvas); | 5023 type, 0, 0, 0, canvas); |
4985 } else { | 5024 } else { |
4986 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, | 5025 texImageByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, |
4987 xoffset, yoffset, 0, canvas); | 5026 xoffset, yoffset, 0, canvas); |
4988 } | 5027 } |
4989 } else { | 5028 } else { |
4990 DCHECK_EQ(functionID, TexSubImage3D); | 5029 DCHECK_EQ(functionID, TexSubImage3D); |
4991 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269). | 5030 // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269). |
4992 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, | 5031 texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, |
4993 format, type, | 5032 format, type, |
4994 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), | 5033 canvas->copiedImage(FrontBuffer, PreferAcceleration).get(), |
4995 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, | 5034 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, |
4996 m_unpackPremultiplyAlpha, | 5035 m_unpackPremultiplyAlpha, |
4997 IntRect(0, 0, canvas->width(), canvas->height())); | 5036 IntRect(0, 0, canvas->width(), canvas->height()), 1, 0); |
4998 } | 5037 } |
4999 } | 5038 } |
5000 | 5039 |
5001 void WebGLRenderingContextBase::texImage2D(GLenum target, | 5040 void WebGLRenderingContextBase::texImage2D(GLenum target, |
5002 GLint level, | 5041 GLint level, |
5003 GLint internalformat, | 5042 GLint internalformat, |
5004 GLenum format, | 5043 GLenum format, |
5005 GLenum type, | 5044 GLenum type, |
5006 HTMLCanvasElement* canvas, | 5045 HTMLCanvasElement* canvas, |
5007 ExceptionState& exceptionState) { | 5046 ExceptionState& exceptionState) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5098 } | 5137 } |
5099 } | 5138 } |
5100 | 5139 |
5101 RefPtr<Image> image = videoFrameToImage(video); | 5140 RefPtr<Image> image = videoFrameToImage(video); |
5102 if (!image) | 5141 if (!image) |
5103 return; | 5142 return; |
5104 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 5143 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
5105 zoffset, format, type, image.get(), | 5144 zoffset, format, type, image.get(), |
5106 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, | 5145 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, |
5107 m_unpackPremultiplyAlpha, | 5146 m_unpackPremultiplyAlpha, |
5108 IntRect(0, 0, video->videoWidth(), video->videoHeight())); | 5147 IntRect(0, 0, video->videoWidth(), video->videoHeight()), 1, 0); |
5109 } | 5148 } |
5110 | 5149 |
5111 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, | 5150 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, |
5112 GLuint targetTexture, | 5151 GLuint targetTexture, |
5113 GLenum targetInternalformat, | 5152 GLenum targetInternalformat, |
5114 GLenum targetType, | 5153 GLenum targetType, |
5115 GLint targetLevel, | 5154 GLint targetLevel, |
5116 bool flipY) { | 5155 bool flipY) { |
5117 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), | 5156 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), |
5118 targetTexture, targetInternalformat, | 5157 targetTexture, targetInternalformat, |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5350 void WebGLRenderingContextBase::texSubImage2D(GLenum target, | 5389 void WebGLRenderingContextBase::texSubImage2D(GLenum target, |
5351 GLint level, | 5390 GLint level, |
5352 GLint xoffset, | 5391 GLint xoffset, |
5353 GLint yoffset, | 5392 GLint yoffset, |
5354 GLenum format, | 5393 GLenum format, |
5355 GLenum type, | 5394 GLenum type, |
5356 HTMLImageElement* image, | 5395 HTMLImageElement* image, |
5357 ExceptionState& exceptionState) { | 5396 ExceptionState& exceptionState) { |
5358 texImageHelperHTMLImageElement(TexSubImage2D, target, level, 0, format, type, | 5397 texImageHelperHTMLImageElement(TexSubImage2D, target, level, 0, format, type, |
5359 xoffset, yoffset, 0, image, | 5398 xoffset, yoffset, 0, image, |
5360 sentinelEmptyRect(), exceptionState); | 5399 sentinelEmptyRect(), 1, 0, exceptionState); |
5361 } | 5400 } |
5362 | 5401 |
5363 void WebGLRenderingContextBase::texSubImage2D(GLenum target, | 5402 void WebGLRenderingContextBase::texSubImage2D(GLenum target, |
5364 GLint level, | 5403 GLint level, |
5365 GLint xoffset, | 5404 GLint xoffset, |
5366 GLint yoffset, | 5405 GLint yoffset, |
5367 GLenum format, | 5406 GLenum format, |
5368 GLenum type, | 5407 GLenum type, |
5369 HTMLCanvasElement* canvas, | 5408 HTMLCanvasElement* canvas, |
5370 ExceptionState& exceptionState) { | 5409 ExceptionState& exceptionState) { |
(...skipping 2248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7619 | 7658 |
7620 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7659 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
7621 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7660 HTMLCanvasElementOrOffscreenCanvas& result) const { |
7622 if (canvas()) | 7661 if (canvas()) |
7623 result.setHTMLCanvasElement(canvas()); | 7662 result.setHTMLCanvasElement(canvas()); |
7624 else | 7663 else |
7625 result.setOffscreenCanvas(getOffscreenCanvas()); | 7664 result.setOffscreenCanvas(getOffscreenCanvas()); |
7626 } | 7665 } |
7627 | 7666 |
7628 } // namespace blink | 7667 } // namespace blink |
OLD | NEW |