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

Unified Diff: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 2458943002: Support 2D texture sub-source uploads from HTMLImageElement. (Closed)
Patch Set: Fixed bug in computation of default image sub-rectangle. Created 4 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index 2b1255c4fdd622c31e31c0fe0c95b938e2787341..2c6a745b0dc8a3204c97228059f648856baaf0ad 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -4333,7 +4333,8 @@ void WebGLRenderingContextBase::texImageImpl(
Image* image,
WebGLImageConversion::ImageHtmlDomSource domSource,
bool flipY,
- bool premultiplyAlpha) {
+ bool premultiplyAlpha,
+ const IntRect& sourceImageRect) {
const char* funcName = getTexImageFunctionName(functionID);
// All calling functions check isContextLost, so a duplicate check is not
// needed here.
@@ -4342,6 +4343,44 @@ void WebGLRenderingContextBase::texImageImpl(
type = GL_FLOAT;
}
Vector<uint8_t> data;
+
+ IntRect subRect = sourceImageRect;
+ if (subRect == sentinelEmptyRect()) {
+ // Recalculate based on the size of the Image.
+ subRect = safeGetImageSize(image);
+ }
+
+ bool selectingSubRectangle = image &&
+ !(subRect.x() == 0 && subRect.y() == 0 &&
+ subRect.width() == image->width() &&
+ subRect.height() == image->height());
+ // If the source image rect selects anything except the entire
+ // contents of the image, assert that we're running WebGL 2.0 or
+ // higher, since this should never happen for WebGL 1.0 (even though
+ // the code could support it). If the image is null, that will be
+ // signaled as an error later.
+ DCHECK(!selectingSubRectangle || isWebGL2OrHigher())
+ << "subRect = (" << subRect.width() << " x " << subRect.height()
+ << ") @ (" << subRect.x() << ", " << subRect.y() << "), image = ("
+ << (image ? image->width() : -1) << " x "
+ << (image ? image->height() : -1) << ")";
+
+ if (subRect.x() < 0 || subRect.y() < 0 || subRect.maxX() > image->width() ||
+ subRect.maxY() > image->height() || subRect.width() < 0 ||
+ subRect.height() < 0) {
+ synthesizeGLError(GL_INVALID_OPERATION, funcName,
Zhenyao Mo 2016/10/31 22:50:51 Should we generate INVALID_VALUE here? subRect's w
Ken Russell (switch to Gerrit) 2016/11/01 00:31:34 Thanks, good point; I'll address this in a follow-
+ "source sub-rectangle specified via pixel unpack "
+ "parameters is invalid");
+ return;
+ }
+
+ // Adjust the source image rectangle if doing a y-flip.
+ IntRect adjustedSourceImageRect = subRect;
+ if (flipY) {
+ adjustedSourceImageRect.setY(image->height() -
+ adjustedSourceImageRect.maxY());
+ }
+
WebGLImageConversion::ImageExtractor imageExtractor(
image, domSource, premultiplyAlpha,
m_unpackColorspaceConversion == GL_NONE);
@@ -4349,6 +4388,7 @@ void WebGLRenderingContextBase::texImageImpl(
synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
return;
}
+
WebGLImageConversion::DataFormat sourceDataFormat =
imageExtractor.imageSourceFormat();
WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
@@ -4358,13 +4398,13 @@ void WebGLRenderingContextBase::texImageImpl(
if (type == GL_UNSIGNED_BYTE &&
sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 &&
format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing &&
- !flipY) {
+ !flipY && !selectingSubRectangle) {
needConversion = false;
} else {
if (!WebGLImageConversion::packImageData(
image, imagePixelData, format, type, flipY, alphaOp,
sourceDataFormat, imageExtractor.imageWidth(),
- imageExtractor.imageHeight(),
+ imageExtractor.imageHeight(), adjustedSourceImageRect,
imageExtractor.imageSourceUnpackAlignment(), data)) {
synthesizeGLError(GL_INVALID_VALUE, funcName, "packImage error");
return;
@@ -4373,20 +4413,21 @@ void WebGLRenderingContextBase::texImageImpl(
resetUnpackParameters();
if (functionID == TexImage2D) {
- texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(),
- imageExtractor.imageHeight(), 0, format, type,
+ texImage2DBase(target, level, internalformat,
+ adjustedSourceImageRect.width(),
+ adjustedSourceImageRect.height(), 0, format, type,
needConversion ? data.data() : imagePixelData);
} else if (functionID == TexSubImage2D) {
contextGL()->TexSubImage2D(target, level, xoffset, yoffset,
- imageExtractor.imageWidth(),
- imageExtractor.imageHeight(), format, type,
+ adjustedSourceImageRect.width(),
+ adjustedSourceImageRect.height(), format, type,
needConversion ? data.data() : imagePixelData);
} else {
DCHECK_EQ(functionID, TexSubImage3D);
- contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset,
- imageExtractor.imageWidth(),
- imageExtractor.imageHeight(), 1, format, type,
- needConversion ? data.data() : imagePixelData);
+ contextGL()->TexSubImage3D(
+ target, level, xoffset, yoffset, zoffset,
+ adjustedSourceImageRect.width(), adjustedSourceImageRect.height(), 1,
+ format, type, needConversion ? data.data() : imagePixelData);
}
restoreUnpackParameters();
}
@@ -4503,6 +4544,21 @@ const char* WebGLRenderingContextBase::getTexImageFunctionName(
}
}
+IntRect WebGLRenderingContextBase::sentinelEmptyRect() {
+ // Return a rectangle with -1 width and height so we can recognize
+ // it later and recalculate it based on the Image whose data we'll
+ // upload. It's important that there be no possible differences in
+ // the logic which computes the image's size.
+ return IntRect(0, 0, -1, -1);
+}
+
+IntRect WebGLRenderingContextBase::safeGetImageSize(Image* image) {
+ if (!image)
+ return IntRect();
+
+ return IntRect(0, 0, image->width(), image->height());
+}
+
void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView(
TexImageFunctionID functionID,
GLenum target,
@@ -4697,6 +4753,7 @@ void WebGLRenderingContextBase::texImageHelperHTMLImageElement(
GLint yoffset,
GLint zoffset,
HTMLImageElement* image,
+ const IntRect& sourceImageRect,
ExceptionState& exceptionState) {
const char* funcName = getTexImageFunctionName(functionID);
if (isContextLost())
@@ -4726,7 +4783,7 @@ void WebGLRenderingContextBase::texImageHelperHTMLImageElement(
texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
zoffset, format, type, imageForRender.get(),
WebGLImageConversion::HtmlDomImage, m_unpackFlipY,
- m_unpackPremultiplyAlpha);
+ m_unpackPremultiplyAlpha, sourceImageRect);
}
void WebGLRenderingContextBase::texImage2D(GLenum target,
@@ -4737,7 +4794,8 @@ void WebGLRenderingContextBase::texImage2D(GLenum target,
HTMLImageElement* image,
ExceptionState& exceptionState) {
texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat,
- format, type, 0, 0, 0, image, exceptionState);
+ format, type, 0, 0, 0, image,
+ sentinelEmptyRect(), exceptionState);
}
bool WebGLRenderingContextBase::canUseTexImageByGPU(
@@ -4904,7 +4962,8 @@ void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(
zoffset, format, type,
canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY,
- m_unpackPremultiplyAlpha);
+ m_unpackPremultiplyAlpha,
+ IntRect(0, 0, canvas->width(), canvas->height()));
return;
}
@@ -4924,7 +4983,8 @@ void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(
format, type,
canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY,
- m_unpackPremultiplyAlpha);
+ m_unpackPremultiplyAlpha,
+ IntRect(0, 0, canvas->width(), canvas->height()));
}
}
@@ -5034,7 +5094,8 @@ void WebGLRenderingContextBase::texImageHelperHTMLVideoElement(
texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
zoffset, format, type, image.get(),
WebGLImageConversion::HtmlDomVideo, m_unpackFlipY,
- m_unpackPremultiplyAlpha);
+ m_unpackPremultiplyAlpha,
+ IntRect(0, 0, video->videoWidth(), video->videoHeight()));
}
void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap,
@@ -5285,7 +5346,8 @@ void WebGLRenderingContextBase::texSubImage2D(GLenum target,
HTMLImageElement* image,
ExceptionState& exceptionState) {
texImageHelperHTMLImageElement(TexSubImage2D, target, level, 0, format, type,
- xoffset, yoffset, 0, image, exceptionState);
+ xoffset, yoffset, 0, image,
+ sentinelEmptyRect(), exceptionState);
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target,

Powered by Google App Engine
This is Rietveld 408576698