| 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 4347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4358 type = GL_FLOAT; | 4358 type = GL_FLOAT; |
| 4359 } | 4359 } |
| 4360 Vector<uint8_t> data; | 4360 Vector<uint8_t> data; |
| 4361 | 4361 |
| 4362 IntRect subRect = sourceImageRect; | 4362 IntRect subRect = sourceImageRect; |
| 4363 if (subRect == sentinelEmptyRect()) { | 4363 if (subRect == sentinelEmptyRect()) { |
| 4364 // Recalculate based on the size of the Image. | 4364 // Recalculate based on the size of the Image. |
| 4365 subRect = safeGetImageSize(image); | 4365 subRect = safeGetImageSize(image); |
| 4366 } | 4366 } |
| 4367 | 4367 |
| 4368 bool selectingSubRectangle = image && | 4368 bool selectingSubRectangle = false; |
| 4369 !(subRect.x() == 0 && subRect.y() == 0 && | 4369 if (!validateTexImageSubRectangle(funcName, image, subRect, |
| 4370 subRect.width() == image->width() && | 4370 &selectingSubRectangle)) { |
| 4371 subRect.height() == image->height()); | |
| 4372 // If the source image rect selects anything except the entire | |
| 4373 // contents of the image, assert that we're running WebGL 2.0 or | |
| 4374 // higher, since this should never happen for WebGL 1.0 (even though | |
| 4375 // the code could support it). If the image is null, that will be | |
| 4376 // signaled as an error later. | |
| 4377 DCHECK(!selectingSubRectangle || isWebGL2OrHigher()) | |
| 4378 << "subRect = (" << subRect.width() << " x " << subRect.height() | |
| 4379 << ") @ (" << subRect.x() << ", " << subRect.y() << "), image = (" | |
| 4380 << (image ? image->width() : -1) << " x " | |
| 4381 << (image ? image->height() : -1) << ")"; | |
| 4382 | |
| 4383 if (subRect.x() < 0 || subRect.y() < 0 || subRect.maxX() > image->width() || | |
| 4384 subRect.maxY() > image->height() || subRect.width() < 0 || | |
| 4385 subRect.height() < 0) { | |
| 4386 synthesizeGLError(GL_INVALID_OPERATION, funcName, | |
| 4387 "source sub-rectangle specified via pixel unpack " | |
| 4388 "parameters is invalid"); | |
| 4389 return; | 4371 return; |
| 4390 } | 4372 } |
| 4391 | 4373 |
| 4392 if (functionID == TexImage3D || functionID == TexSubImage3D) { | 4374 if (functionID == TexImage3D || functionID == TexSubImage3D) { |
| 4393 DCHECK_GE(unpackImageHeight, 0); | 4375 DCHECK_GE(unpackImageHeight, 0); |
| 4394 | 4376 |
| 4395 // Verify that the image data can cover the required depth. | 4377 // Verify that the image data can cover the required depth. |
| 4396 CheckedNumeric<GLint> maxDepthSupported = 1; | 4378 CheckedNumeric<GLint> maxDepthSupported = 1; |
| 4397 if (unpackImageHeight) { | 4379 if (unpackImageHeight) { |
| 4398 maxDepthSupported = subRect.height(); | 4380 maxDepthSupported = subRect.height(); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4602 return IntRect(0, 0, -1, -1); | 4584 return IntRect(0, 0, -1, -1); |
| 4603 } | 4585 } |
| 4604 | 4586 |
| 4605 IntRect WebGLRenderingContextBase::safeGetImageSize(Image* image) { | 4587 IntRect WebGLRenderingContextBase::safeGetImageSize(Image* image) { |
| 4606 if (!image) | 4588 if (!image) |
| 4607 return IntRect(); | 4589 return IntRect(); |
| 4608 | 4590 |
| 4609 return IntRect(0, 0, image->width(), image->height()); | 4591 return IntRect(0, 0, image->width(), image->height()); |
| 4610 } | 4592 } |
| 4611 | 4593 |
| 4594 IntRect WebGLRenderingContextBase::getImageDataSize(ImageData* pixels) { |
| 4595 DCHECK(pixels); |
| 4596 return IntRect(0, 0, pixels->width(), pixels->height()); |
| 4597 } |
| 4598 |
| 4612 void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView( | 4599 void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView( |
| 4613 TexImageFunctionID functionID, | 4600 TexImageFunctionID functionID, |
| 4614 GLenum target, | 4601 GLenum target, |
| 4615 GLint level, | 4602 GLint level, |
| 4616 GLint internalformat, | 4603 GLint internalformat, |
| 4617 GLsizei width, | 4604 GLsizei width, |
| 4618 GLsizei height, | 4605 GLsizei height, |
| 4619 GLsizei depth, | 4606 GLsizei depth, |
| 4620 GLint border, | 4607 GLint border, |
| 4621 GLenum format, | 4608 GLenum format, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4711 GLenum target, | 4698 GLenum target, |
| 4712 GLint level, | 4699 GLint level, |
| 4713 GLint internalformat, | 4700 GLint internalformat, |
| 4714 GLint border, | 4701 GLint border, |
| 4715 GLenum format, | 4702 GLenum format, |
| 4716 GLenum type, | 4703 GLenum type, |
| 4717 GLsizei depth, | 4704 GLsizei depth, |
| 4718 GLint xoffset, | 4705 GLint xoffset, |
| 4719 GLint yoffset, | 4706 GLint yoffset, |
| 4720 GLint zoffset, | 4707 GLint zoffset, |
| 4721 ImageData* pixels) { | 4708 ImageData* pixels, |
| 4709 const IntRect& sourceImageRect) { |
| 4722 const char* funcName = getTexImageFunctionName(functionID); | 4710 const char* funcName = getTexImageFunctionName(functionID); |
| 4723 if (isContextLost()) | 4711 if (isContextLost()) |
| 4724 return; | 4712 return; |
| 4725 DCHECK(pixels); | 4713 DCHECK(pixels); |
| 4726 if (pixels->data()->bufferBase()->isNeutered()) { | 4714 if (pixels->data()->bufferBase()->isNeutered()) { |
| 4727 synthesizeGLError(GL_INVALID_VALUE, funcName, | 4715 synthesizeGLError(GL_INVALID_VALUE, funcName, |
| 4728 "The source data has been neutered."); | 4716 "The source data has been neutered."); |
| 4729 return; | 4717 return; |
| 4730 } | 4718 } |
| 4731 if (!validateTexImageBinding(funcName, functionID, target)) | 4719 if (!validateTexImageBinding(funcName, functionID, target)) |
| 4732 return; | 4720 return; |
| 4733 TexImageFunctionType functionType; | 4721 TexImageFunctionType functionType; |
| 4734 if (functionID == TexImage2D) | 4722 if (functionID == TexImage2D) |
| 4735 functionType = TexImage; | 4723 functionType = TexImage; |
| 4736 else | 4724 else |
| 4737 functionType = TexSubImage; | 4725 functionType = TexSubImage; |
| 4738 if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, | 4726 if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, |
| 4739 internalformat, pixels->width(), pixels->height(), depth, | 4727 internalformat, pixels->width(), pixels->height(), depth, |
| 4740 border, format, type, xoffset, yoffset, zoffset)) | 4728 border, format, type, xoffset, yoffset, zoffset)) |
| 4741 return; | 4729 return; |
| 4730 |
| 4731 bool selectingSubRectangle = false; |
| 4732 if (!validateTexImageSubRectangle(funcName, pixels, sourceImageRect, |
| 4733 &selectingSubRectangle)) { |
| 4734 return; |
| 4735 } |
| 4736 // Adjust the source image rectangle if doing a y-flip. |
| 4737 IntRect adjustedSourceImageRect = sourceImageRect; |
| 4738 if (m_unpackFlipY) { |
| 4739 adjustedSourceImageRect.setY(pixels->height() - |
| 4740 adjustedSourceImageRect.maxY()); |
| 4741 } |
| 4742 |
| 4742 Vector<uint8_t> data; | 4743 Vector<uint8_t> data; |
| 4743 bool needConversion = true; | 4744 bool needConversion = true; |
| 4744 // The data from ImageData is always of format RGBA8. | 4745 // The data from ImageData is always of format RGBA8. |
| 4745 // No conversion is needed if destination format is RGBA and type is | 4746 // No conversion is needed if destination format is RGBA and type is |
| 4746 // USIGNED_BYTE and no Flip or Premultiply operation is required. | 4747 // UNSIGNED_BYTE and no Flip or Premultiply operation is required. |
| 4747 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && | 4748 if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && |
| 4748 type == GL_UNSIGNED_BYTE) { | 4749 type == GL_UNSIGNED_BYTE && !selectingSubRectangle) { |
| 4749 needConversion = false; | 4750 needConversion = false; |
| 4750 } else { | 4751 } else { |
| 4751 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 4752 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| 4752 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | 4753 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| 4753 type = GL_FLOAT; | 4754 type = GL_FLOAT; |
| 4754 } | 4755 } |
| 4755 if (!WebGLImageConversion::extractImageData( | 4756 if (!WebGLImageConversion::extractImageData( |
| 4756 pixels->data()->data(), | 4757 pixels->data()->data(), |
| 4757 WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), | 4758 WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), |
| 4758 format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { | 4759 adjustedSourceImageRect, format, type, m_unpackFlipY, |
| 4760 m_unpackPremultiplyAlpha, data)) { |
| 4759 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); | 4761 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); |
| 4760 return; | 4762 return; |
| 4761 } | 4763 } |
| 4762 } | 4764 } |
| 4763 resetUnpackParameters(); | 4765 resetUnpackParameters(); |
| 4764 if (functionID == TexImage2D) { | 4766 if (functionID == TexImage2D) { |
| 4765 texImage2DBase(target, level, internalformat, pixels->width(), | 4767 texImage2DBase(target, level, internalformat, |
| 4766 pixels->height(), border, format, type, | 4768 adjustedSourceImageRect.width(), |
| 4769 adjustedSourceImageRect.height(), border, format, type, |
| 4767 needConversion ? data.data() : pixels->data()->data()); | 4770 needConversion ? data.data() : pixels->data()->data()); |
| 4768 } else if (functionID == TexSubImage2D) { | 4771 } else if (functionID == TexSubImage2D) { |
| 4769 contextGL()->TexSubImage2D( | 4772 contextGL()->TexSubImage2D( |
| 4770 target, level, xoffset, yoffset, pixels->width(), pixels->height(), | 4773 target, level, xoffset, yoffset, adjustedSourceImageRect.width(), |
| 4771 format, type, needConversion ? data.data() : pixels->data()->data()); | 4774 adjustedSourceImageRect.height(), format, type, |
| 4775 needConversion ? data.data() : pixels->data()->data()); |
| 4772 } else { | 4776 } else { |
| 4773 DCHECK_EQ(functionID, TexSubImage3D); | 4777 DCHECK_EQ(functionID, TexSubImage3D); |
| 4774 contextGL()->TexSubImage3D( | 4778 contextGL()->TexSubImage3D( |
| 4775 target, level, xoffset, yoffset, zoffset, pixels->width(), | 4779 target, level, xoffset, yoffset, zoffset, |
| 4776 pixels->height(), depth, format, type, | 4780 adjustedSourceImageRect.width(), adjustedSourceImageRect.height(), |
| 4781 depth, format, type, |
| 4777 needConversion ? data.data() : pixels->data()->data()); | 4782 needConversion ? data.data() : pixels->data()->data()); |
| 4778 } | 4783 } |
| 4779 restoreUnpackParameters(); | 4784 restoreUnpackParameters(); |
| 4780 } | 4785 } |
| 4781 | 4786 |
| 4782 void WebGLRenderingContextBase::texImage2D(GLenum target, | 4787 void WebGLRenderingContextBase::texImage2D(GLenum target, |
| 4783 GLint level, | 4788 GLint level, |
| 4784 GLint internalformat, | 4789 GLint internalformat, |
| 4785 GLenum format, | 4790 GLenum format, |
| 4786 GLenum type, | 4791 GLenum type, |
| 4787 ImageData* pixels) { | 4792 ImageData* pixels) { |
| 4788 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format, | 4793 texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format, |
| 4789 type, 1, 0, 0, 0, pixels); | 4794 type, 1, 0, 0, 0, pixels, getImageDataSize(pixels)); |
| 4790 } | 4795 } |
| 4791 | 4796 |
| 4792 void WebGLRenderingContextBase::texImageHelperHTMLImageElement( | 4797 void WebGLRenderingContextBase::texImageHelperHTMLImageElement( |
| 4793 TexImageFunctionID functionID, | 4798 TexImageFunctionID functionID, |
| 4794 GLenum target, | 4799 GLenum target, |
| 4795 GLint level, | 4800 GLint level, |
| 4796 GLint internalformat, | 4801 GLint internalformat, |
| 4797 GLenum format, | 4802 GLenum format, |
| 4798 GLenum type, | 4803 GLenum type, |
| 4799 GLint xoffset, | 4804 GLint xoffset, |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5235 (peekSucceed && | 5240 (peekSucceed && |
| 5236 pixmap.colorType() == SkColorType::kRGBA_8888_SkColorType); | 5241 pixmap.colorType() == SkColorType::kRGBA_8888_SkColorType); |
| 5237 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed); | 5242 bool isPixelDataRGBA = (havePeekableRGBA || !peekSucceed); |
| 5238 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { | 5243 if (isPixelDataRGBA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) { |
| 5239 needConversion = false; | 5244 needConversion = false; |
| 5240 } else { | 5245 } else { |
| 5241 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 5246 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
| 5242 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | 5247 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
| 5243 type = GL_FLOAT; | 5248 type = GL_FLOAT; |
| 5244 } | 5249 } |
| 5250 IntRect sourceImageRect(0, 0, bitmap->width(), bitmap->height()); |
| 5245 // In the case of ImageBitmap, we do not need to apply flipY or | 5251 // In the case of ImageBitmap, we do not need to apply flipY or |
| 5246 // premultiplyAlpha. | 5252 // premultiplyAlpha. |
| 5247 bool isPixelDataBGRA = | 5253 bool isPixelDataBGRA = |
| 5248 pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType; | 5254 pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType; |
| 5249 if ((isPixelDataBGRA && | 5255 if ((isPixelDataBGRA && |
| 5250 !WebGLImageConversion::extractImageData( | 5256 !WebGLImageConversion::extractImageData( |
| 5251 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, | 5257 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, |
| 5252 bitmap->size(), format, type, false, false, data)) || | 5258 bitmap->size(), sourceImageRect, format, type, false, false, |
| 5259 data)) || |
| 5253 (isPixelDataRGBA && | 5260 (isPixelDataRGBA && |
| 5254 !WebGLImageConversion::extractImageData( | 5261 !WebGLImageConversion::extractImageData( |
| 5255 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, | 5262 pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, |
| 5256 bitmap->size(), format, type, false, false, data))) { | 5263 bitmap->size(), sourceImageRect, format, type, false, false, |
| 5264 data))) { |
| 5257 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); | 5265 synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data"); |
| 5258 return; | 5266 return; |
| 5259 } | 5267 } |
| 5260 } | 5268 } |
| 5261 resetUnpackParameters(); | 5269 resetUnpackParameters(); |
| 5262 if (functionID == TexImage2D) { | 5270 if (functionID == TexImage2D) { |
| 5263 texImage2DBase(target, level, internalformat, bitmap->width(), | 5271 texImage2DBase(target, level, internalformat, bitmap->width(), |
| 5264 bitmap->height(), 0, format, type, | 5272 bitmap->height(), 0, format, type, |
| 5265 needConversion ? data.data() : pixelDataPtr); | 5273 needConversion ? data.data() : pixelDataPtr); |
| 5266 } else if (functionID == TexSubImage2D) { | 5274 } else if (functionID == TexSubImage2D) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5377 } | 5385 } |
| 5378 | 5386 |
| 5379 void WebGLRenderingContextBase::texSubImage2D(GLenum target, | 5387 void WebGLRenderingContextBase::texSubImage2D(GLenum target, |
| 5380 GLint level, | 5388 GLint level, |
| 5381 GLint xoffset, | 5389 GLint xoffset, |
| 5382 GLint yoffset, | 5390 GLint yoffset, |
| 5383 GLenum format, | 5391 GLenum format, |
| 5384 GLenum type, | 5392 GLenum type, |
| 5385 ImageData* pixels) { | 5393 ImageData* pixels) { |
| 5386 texImageHelperImageData(TexSubImage2D, target, level, 0, 0, format, type, 1, | 5394 texImageHelperImageData(TexSubImage2D, target, level, 0, 0, format, type, 1, |
| 5387 xoffset, yoffset, 0, pixels); | 5395 xoffset, yoffset, 0, pixels, |
| 5396 getImageDataSize(pixels)); |
| 5388 } | 5397 } |
| 5389 | 5398 |
| 5390 void WebGLRenderingContextBase::texSubImage2D(GLenum target, | 5399 void WebGLRenderingContextBase::texSubImage2D(GLenum target, |
| 5391 GLint level, | 5400 GLint level, |
| 5392 GLint xoffset, | 5401 GLint xoffset, |
| 5393 GLint yoffset, | 5402 GLint yoffset, |
| 5394 GLenum format, | 5403 GLenum format, |
| 5395 GLenum type, | 5404 GLenum type, |
| 5396 HTMLImageElement* image, | 5405 HTMLImageElement* image, |
| 5397 ExceptionState& exceptionState) { | 5406 ExceptionState& exceptionState) { |
| (...skipping 2261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7659 | 7668 |
| 7660 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7669 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
| 7661 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7670 HTMLCanvasElementOrOffscreenCanvas& result) const { |
| 7662 if (canvas()) | 7671 if (canvas()) |
| 7663 result.setHTMLCanvasElement(canvas()); | 7672 result.setHTMLCanvasElement(canvas()); |
| 7664 else | 7673 else |
| 7665 result.setOffscreenCanvas(getOffscreenCanvas()); | 7674 result.setOffscreenCanvas(getOffscreenCanvas()); |
| 7666 } | 7675 } |
| 7667 | 7676 |
| 7668 } // namespace blink | 7677 } // namespace blink |
| OLD | NEW |