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

Side by Side Diff: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 2489203002: support uploading sub-rectangles of ImageData (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 4347 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698