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

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

Issue 2025703002: Pack repeated code in tex(Sub)Image2D and texSubImage3D into helper func (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: all done, hand to bots Created 4 years, 7 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
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 70d454fe26280c8b1fb0f5a6742bb196a21fb48d..f58885d2914dabf638d7933e1c0f8873b8dc01dc 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -3954,8 +3954,9 @@ void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLint
contextGL()->TexImage2D(target, level, convertTexInternalFormat(internalformat, type), width, height, border, format, type, pixels);
}
-void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
+void WebGLRenderingContextBase::texImageImpl(TexImageFunctionName functionName, GLenum target, GLint level, GLint internalformat, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
{
+ const char* funcName = getTexImageFunctionName(functionName);
// All calling functions check isContextLost, so a duplicate check is not needed here.
if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
// The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
@@ -3964,7 +3965,7 @@ void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLint
Vector<uint8_t> data;
WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
if (!imageExtractor.imagePixelData()) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
return;
}
WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
@@ -3976,13 +3977,18 @@ void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLint
needConversion = false;
} else {
if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error");
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "packImage error");
return;
}
}
resetUnpackParameters();
- texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData);
+ if (functionName == TexImage2D)
+ texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData);
+ else if (functionName == TexSubImage2D)
+ contextGL()->TexSubImage2D(target, level, xoffset, yoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data.data() : imagePixelData);
+ else // must be "texSubImage3D"
+ contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 1, format, type, needConversion ? data.data() : imagePixelData);
restoreUnpackParameters();
}
@@ -4051,50 +4057,107 @@ PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer(PassRefPtr<Imag
return buf->newImageSnapshot();
}
-void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLint border,
- GLenum format, GLenum type, DOMArrayBufferView* pixels)
+WebGLTexture* WebGLRenderingContextBase::validateTexImageBinding(const char* funcName, TexImageFunctionName functionName, GLenum target)
+{
+ return validateTexture2DBinding(funcName, target);
+}
+
+const char* WebGLRenderingContextBase::getTexImageFunctionName(TexImageFunctionName funcName)
+{
+ if (funcName == TexImage2D)
+ return "texImage2D";
+ if (funcName == TexSubImage2D)
+ return "texSubImage2D";
+ if (funcName == TexSubImage3D)
+ return "texSubImage3D";
+ return "texImage3D";
+}
+
+void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView(TexImageFunctionName functionName,
+ GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, DOMArrayBufferView* pixels)
{
+ const char* funcName = getTexImageFunctionName(functionName);
if (isContextLost())
return;
- if (!validateTexture2DBinding("texImage2D", target))
+ if (!validateTexImageBinding(funcName, functionName, target))
Zhenyao Mo 2016/06/03 17:49:51 This funcName and functionName is very confusing.
xidachen 2016/06/03 18:28:29 functionID is much clearer. Changed all over the p
return;
- if (!validateTexFunc("texImage2D", TexImage, SourceArrayBufferView, target, level, internalformat, width, height, 1, border, format, type, 0, 0, 0))
+ TexImageFunctionType functionType;
+ if (functionName == TexImage2D || functionName == TexImage3D)
+ functionType = TexImage;
+ else
+ functionType = TexSubImage;
+ if (!validateTexFunc(funcName, functionType, SourceArrayBufferView, target, level, internalformat, width, height, depth, border, format, type, xoffset, yoffset, zoffset))
return;
- if (!validateTexFuncData("texImage2D", Tex2D, level, width, height, 1, format, type, pixels, NullAllowed))
+ TexImageDimension sourceType;
+ if (functionName == TexImage2D || functionName == TexSubImage2D)
+ sourceType = Tex2D;
+ else
+ sourceType = Tex3D;
+ if (!validateTexFuncData(funcName, sourceType, level, width, height, depth, format, type, pixels, NullAllowed))
return;
void* data = pixels ? pixels->baseAddress() : 0;
Vector<uint8_t> tempData;
bool changeUnpackAlignment = false;
if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
- return;
- data = tempData.data();
+ if (functionName == TexImage2D || functionName == TexSubImage2D) {
Zhenyao Mo 2016/06/03 17:49:51 sourceType == Tex2D
xidachen 2016/06/03 18:28:29 Done.
+ if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
+ return;
+ data = tempData.data();
+ } else {
+ NOTIMPLEMENTED();
+ if (functionName == TexImage3D)
+ return;
Zhenyao Mo 2016/06/03 17:49:51 For now let's not worry about flipY and premultipl
xidachen 2016/06/03 18:28:30 Done.
+ }
changeUnpackAlignment = true;
}
+ if (functionName == TexImage3D) {
+ contextGL()->TexImage3D(target, level, convertTexInternalFormat(internalformat, type), width, height, depth, border, format, type, data);
+ return;
+ }
+
if (changeUnpackAlignment)
resetUnpackParameters();
- texImage2DBase(target, level, internalformat, width, height, border, format, type, data);
+ if (functionName == TexImage2D)
+ texImage2DBase(target, level, internalformat, width, height, border, format, type, data);
+ else if (functionName == TexSubImage2D)
+ contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
+ else
+ contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
Zhenyao Mo 2016/06/03 17:49:51 Same here, let's move this before the resetUnpackP
xidachen 2016/06/03 18:28:29 Done.
if (changeUnpackAlignment)
restoreUnpackParameters();
}
void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
- GLenum format, GLenum type, ImageData* pixels)
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, DOMArrayBufferView* pixels)
{
+ texImageHelperDOMArrayBufferView(TexImage2D, target, level, internalformat, width, height, border, format, type, 1, 0, 0, 0, pixels);
+}
+
+void WebGLRenderingContextBase::texImageHelperImageData(TexImageFunctionName functionName,
+ GLenum target, GLint level, GLint internalformat, GLint border, GLenum format,
+ GLenum type, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, ImageData* pixels)
+{
+ const char* funcName = getTexImageFunctionName(functionName);
if (isContextLost())
return;
if (!pixels) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "no image data");
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "no image data");
return;
}
if (pixels->data()->bufferBase()->isNeutered()) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "The source data has been neutered.");
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "The source data has been neutered.");
return;
}
- if (!validateTexture2DBinding("texImage2D", target))
+ if (!validateTexImageBinding(funcName, functionName, target))
return;
- if (!validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 1, 0, format, type, 0, 0, 0))
+ TexImageFunctionType functionType;
+ if (functionName == TexImage2D)
+ functionType = TexImage;
+ else
+ functionType = TexSubImage;
+ if (!validateTexFunc(funcName, functionType, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), depth, border, format, type, xoffset, yoffset, zoffset))
return;
Vector<uint8_t> data;
bool needConversion = true;
@@ -4108,37 +4171,57 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int
type = GL_FLOAT;
}
if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
return;
}
}
resetUnpackParameters();
- texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data());
+ if (functionName == TexImage2D)
+ texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), border, format, type, needConversion ? data.data() : pixels->data()->data());
+ else if (functionName == TexSubImage2D)
+ contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data());
+ else // must be "texSubImage3D"
Zhenyao Mo 2016/06/03 17:49:51 Can you ASSERT? here and other places.
xidachen 2016/06/03 18:28:30 Done.
+ contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, pixels->width(), pixels->height(), depth, format, type, needConversion ? data.data() : pixels->data()->data());
restoreUnpackParameters();
}
void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
- GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+ GLenum format, GLenum type, ImageData* pixels)
{
+ texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format, type, 1, 0, 0, 0, pixels);
+}
+
+void WebGLRenderingContextBase::texImageHelperHTMLImageElement(TexImageFunctionName functionName,
+ GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, GLint xoffset,
+ GLint yoffset, GLint zoffset, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ const char* funcName = getTexImageFunctionName(functionName);
if (isContextLost())
return;
- if (!validateHTMLImageElement("texImage2D", image, exceptionState))
+ if (!validateHTMLImageElement(funcName, image, exceptionState))
return;
- if (!validateTexture2DBinding("texImage2D", target))
+ if (!validateTexImageBinding(funcName, functionName, target))
return;
RefPtr<Image> imageForRender = image->cachedImage()->getImage();
if (imageForRender && imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), "texImage2D");
+ imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), funcName);
- if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 1, 0, format, type, 0, 0, 0))
+ TexImageFunctionType functionType;
+ if (functionName == TexImage2D)
+ functionType = TexImage;
+ else
+ functionType = TexSubImage;
+ if (!imageForRender || !validateTexFunc(funcName, functionType, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
return;
- if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
- // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
- type = GL_FLOAT;
- }
- texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ texImageImpl(functionName, target, level, internalformat, xoffset, yoffset, zoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
+ GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, format, type, 0, 0, 0, image, exceptionState);
}
bool WebGLRenderingContextBase::canUseTexImageCanvasByGPU(GLint internalformat, GLenum type)
@@ -4212,30 +4295,64 @@ void WebGLRenderingContextBase::texImageCanvasByGPU(TexImageByGPUType functionTy
}
}
-void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
- GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+void WebGLRenderingContextBase::texImageHelperHTMLCanvasElement(TexImageFunctionName functionName,
+ GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, GLint xoffset,
+ GLint yoffset, GLint zoffset, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
{
+ const char* funcName = getTexImageFunctionName(functionName);
if (isContextLost())
return;
- if (!validateHTMLCanvasElement("texImage2D", canvas, exceptionState))
+ if (!validateHTMLCanvasElement(funcName, canvas, exceptionState))
return;
- WebGLTexture* texture = validateTexture2DBinding("texImage2D", target);
+ WebGLTexture* texture = validateTexImageBinding(funcName, functionName, target);
if (!texture)
return;
- if (!validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0))
- return;
+ TexImageFunctionType functionType;
+ if (functionName == TexImage2D)
+ functionType = TexImage;
+ else
+ functionType = TexSubImage;
+ if (!validateTexFunc(funcName, functionType, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
+ return;
+ if (functionName == TexImage2D) {
+ // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support float/integer/sRGB internal format.
+ // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
+ if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated() || !canUseTexImageCanvasByGPU(internalformat, type)) {
+ // 2D canvas has only FrontBuffer.
+ texImageImpl(TexImage2D, target, level, internalformat, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
+ WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return;
+ }
- // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support float/integer/sRGB internal format.
- // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
- if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated() || !canUseTexImageCanvasByGPU(internalformat, type)) {
- // 2D canvas has only FrontBuffer.
- texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
+ texImage2DBase(target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0);
+ texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas);
+ } else if (functionName == TexSubImage2D) {
+ // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats.
+ bool useReadBackPath = isWebGL2OrHigher()
+ || extensionEnabled(OESTextureFloatName)
+ || extensionEnabled(OESTextureHalfFloatName)
+ || extensionEnabled(EXTsRGBName);
+ // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support float/integer/sRGB internal format.
+ // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
+ if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated() || useReadBackPath) {
+ // 2D canvas has only FrontBuffer.
+ texImageImpl(TexSubImage2D, target, level, 0, xoffset, yoffset, 0, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
+ WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return;
+ }
+
+ texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas);
+ } else { // must be TexSubImage3D
+ // FIXME: Implement GPU-to-GPU copy path (crbug.com/586269).
+ texImageImpl(TexSubImage3D, target, level, 0, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
- return;
}
+}
- texImage2DBase(target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0);
- texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas);
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+ texImageHelperHTMLCanvasElement(TexImage2D, target, level, internalformat, format, type, 0, 0, 0, canvas, exceptionState);
}
PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video)
@@ -4251,63 +4368,84 @@ PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement*
return buf->newImageSnapshot();
}
-void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
- GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
+void WebGLRenderingContextBase::texImageHelperHTMLVideoElement(TexImageFunctionName functionName,
+ GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, GLint xoffset,
+ GLint yoffset, GLint zoffset, HTMLVideoElement* video, ExceptionState& exceptionState)
{
+ const char* funcName = getTexImageFunctionName(functionName);
if (isContextLost())
return;
- if (!validateHTMLVideoElement("texImage2D", video, exceptionState))
+ if (!validateHTMLVideoElement(funcName, video, exceptionState))
return;
- WebGLTexture* texture = validateTexture2DBinding("texImage2D", target);
+ WebGLTexture* texture = validateTexImageBinding(funcName, functionName, target);
if (!texture)
return;
- if (!validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, 0, 0, 0))
+ TexImageFunctionType functionType;
+ if (functionName == TexImage2D)
+ functionType = TexImage;
+ else
+ functionType = TexSubImage;
+ if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, zoffset))
return;
- // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
- // Otherwise, it will fall back to the normal SW path.
- if (GL_TEXTURE_2D == target) {
- if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level)
- && video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- return;
- }
+ if (functionName == TexImage2D) {
+ // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
+ // Otherwise, it will fall back to the normal SW path.
+ if (GL_TEXTURE_2D == target) {
+ if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level)
+ && video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ return;
+ }
- // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
- OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBufferSurface(IntSize(video->videoWidth(), video->videoHeight())));
- if (surface->isValid()) {
- OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(std::move(surface)));
- if (imageBuffer) {
- // The video element paints an RGBA frame into our surface here. By using an AcceleratedImageBufferSurface,
- // we enable the WebMediaPlayer implementation to do any necessary color space conversion on the GPU (though it
- // may still do a CPU conversion and upload the results).
- video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
-
- // This is a straight GPU-GPU copy, any necessary color space conversion was handled in the paintCurrentFrameInContext() call.
- if (imageBuffer->copyToPlatformTexture(contextGL(), texture->object(), internalformat, type,
- level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- return;
+ // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
+ OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBufferSurface(IntSize(video->videoWidth(), video->videoHeight())));
+ if (surface->isValid()) {
+ OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(std::move(surface)));
+ if (imageBuffer) {
+ // The video element paints an RGBA frame into our surface here. By using an AcceleratedImageBufferSurface,
+ // we enable the WebMediaPlayer implementation to do any necessary color space conversion on the GPU (though it
+ // may still do a CPU conversion and upload the results).
+ video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
+
+ // This is a straight GPU-GPU copy, any necessary color space conversion was handled in the paintCurrentFrameInContext() call.
+ if (imageBuffer->copyToPlatformTexture(contextGL(), texture->object(), internalformat, type,
+ level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ return;
+ }
}
}
}
}
- // Normal pure SW path.
RefPtr<Image> image = videoFrameToImage(video);
if (!image)
return;
- texImage2DImpl(target, level, internalformat, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ texImageImpl(functionName, target, level, internalformat, xoffset, yoffset, zoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
}
void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
- GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionState)
+ GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
{
+ texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, format, type, 0, 0, 0, video, exceptionState);
+}
+
+void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionName functionName,
+ GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, GLint xoffset,
+ GLint yoffset, GLint zoffset, ImageBitmap* bitmap, ExceptionState& exceptionState)
+{
+ const char* funcName = getTexImageFunctionName(functionName);
if (isContextLost())
return;
- if (!validateImageBitmap("texImage2D", bitmap, exceptionState))
+ if (!validateImageBitmap(funcName, bitmap, exceptionState))
return;
- if (!validateTexture2DBinding("texImage2D", target))
+ if (!validateTexImageBinding(funcName, functionName, target))
return;
- if (!validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, level, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0))
+ TexImageFunctionType functionType;
+ if (functionName == TexImage2D)
+ functionType = TexImage;
+ else
+ functionType = TexSubImage;
+ if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, level, internalformat, bitmap->width(), bitmap->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
return;
ASSERT(bitmap->bitmapImage());
RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
@@ -4338,15 +4476,26 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int
bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType);
if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
|| (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), format, type, false, false, data))) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "bad image data");
return;
}
}
resetUnpackParameters();
- texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->height(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
+ if (functionName == TexImage2D)
+ texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->height(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
+ else if (functionName == TexSubImage2D)
+ contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr);
+ else // must be "texSubImage3D"
+ contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, bitmap->width(), bitmap->height(), 1, format, type, needConversion ? data.data() : pixelDataPtr);
restoreUnpackParameters();
}
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
+ GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionState)
+{
+ texImageHelperImageBitmap(TexImage2D, target, level, internalformat, format, type, 0, 0, 0, bitmap, exceptionState);
+}
+
void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloat paramf, GLint parami, bool isFloat)
{
if (isContextLost())
@@ -4409,222 +4558,41 @@ void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint
texParameter(target, pname, 0, param, false);
}
-void WebGLRenderingContextBase::texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
- // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
- type = GL_FLOAT;
- }
- Vector<uint8_t> data;
- WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
- if (!imageExtractor.imagePixelData()) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
- return;
- }
- WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY) {
- needConversion = false;
- } else {
- if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
-
- resetUnpackParameters();
- contextGL()->TexSubImage2D(target, level, xoffset, yoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data.data() : imagePixelData);
- restoreUnpackParameters();
-}
-
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLenum type, DOMArrayBufferView* pixels)
{
- if (isContextLost())
- return;
- if (!validateTexture2DBinding("texSubImage2D", target))
- return;
- if (!validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, 0, width, height, 1, 0, format, type, xoffset, yoffset, 0))
- return;
- if (!validateTexFuncData("texSubImage2D", Tex2D, level, width, height, 1, format, type, pixels, NullNotAllowed))
- return;
- void* data = pixels->baseAddress();
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!WebGLImageConversion::extractTextureData(width, height, format, type,
- m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- resetUnpackParameters();
- contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
- if (changeUnpackAlignment)
- restoreUnpackParameters();
+ texImageHelperDOMArrayBufferView(TexSubImage2D, target, level, 0, width, height, 0, format, type, 1, xoffset, yoffset, 0, pixels);
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum format, GLenum type, ImageData* pixels)
{
- if (isContextLost())
- return;
- if (!pixels) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "no image data");
- return;
- }
- if (pixels->data()->bufferBase()->isNeutered()) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "The source data has been neutered.");
- return;
- }
- if (!validateTexture2DBinding("texSubImage2D", target))
- return;
- if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, 0, pixels->width(), pixels->height(), 1, 0, format, type, xoffset, yoffset, 0))
- return;
- if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
- // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
- type = GL_FLOAT;
- }
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha) {
- needConversion = false;
- } else {
- if (!WebGLImageConversion::extractImageData(pixels->data()->data(), WebGLImageConversion::DataFormat::DataFormatRGBA8, pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
- resetUnpackParameters();
- contextGL()->TexSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data());
- restoreUnpackParameters();
+ texImageHelperImageData(TexSubImage2D, target, level, 0, 0, format, type, 1, xoffset, yoffset, 0, pixels);
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
{
- if (isContextLost())
- return;
- if (!validateHTMLImageElement("texSubImage2D", image, exceptionState))
- return;
- if (!validateTexture2DBinding("texSubImage2D", target))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->getImage();
- if (imageForRender && imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), "texSubImage2D");
-
- if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, 0, imageForRender->width(), imageForRender->height(), 1, 0, format, type, xoffset, yoffset, 0))
- return;
-
- if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
- // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
- type = GL_FLOAT;
- }
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ texImageHelperHTMLImageElement(TexSubImage2D, target, level, 0, format, type, xoffset, yoffset, 0, image, exceptionState);
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
{
- if (isContextLost())
- return;
- if (!validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState))
- return;
- WebGLTexture* texture = validateTexture2DBinding("texSubImage2D", target);
- if (!texture)
- return;
- if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, 0))
- return;
-
- // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats.
- bool useReadBackPath = isWebGL2OrHigher()
- || extensionEnabled(OESTextureFloatName)
- || extensionEnabled(OESTextureHalfFloatName)
- || extensionEnabled(EXTsRGBName);
- // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support float/integer/sRGB internal format.
- // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats.
- if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated() || useReadBackPath) {
- // 2D canvas has only FrontBuffer.
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
- WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
- return;
- }
-
- texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, 0, canvas);
+ texImageHelperHTMLCanvasElement(TexSubImage2D, target, level, 0, format, type, xoffset, yoffset, 0, canvas, exceptionState);
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
{
- if (isContextLost())
- return;
- if (!validateHTMLVideoElement("texSubImage2D", video, exceptionState))
- return;
- if (!validateTexture2DBinding("texSubImage2D", target))
- return;
- if (!validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, 0, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, 0))
- return;
-
- RefPtr<Image> image = videoFrameToImage(video);
- if (!image)
- return;
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ texImageHelperHTMLVideoElement(TexSubImage2D, target, level, 0, format, type, xoffset, yoffset, 0, video, exceptionState);
}
void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum format, GLenum type, ImageBitmap* bitmap, ExceptionState& exceptionState)
{
- if (isContextLost())
- return;
- if (!validateImageBitmap("texSubImage2D", bitmap, exceptionState))
- return;
- if (!validateTexture2DBinding("texSubImage2D", target))
- return;
- if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target, level, 0, bitmap->width(), bitmap->height(), 1, 0, format, type, 0, 0, 0))
- return;
- if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
- // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented.
- type = GL_FLOAT;
- }
- ASSERT(bitmap->bitmapImage());
- RefPtr<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame();
- SkPixmap pixmap;
- OwnPtr<uint8_t[]> pixelData;
- uint8_t* pixelDataPtr = nullptr;
- bool peekSucceed = skImage->peekPixels(&pixmap);
- if (peekSucceed) {
- pixelDataPtr = static_cast<uint8_t*>(pixmap.writable_addr());
- } else if (skImage->isTextureBacked()) {
- pixelData = bitmap->copyBitmapData(bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha);
- pixelDataPtr = pixelData.get();
- }
- Vector<uint8_t> data;
- bool needConversion = true;
- bool havePeekableRGBA = (peekSucceed && pixmap.colorType() == SkColorType::kRGBA_8888_SkColorType);
- bool isPixelDataRBGA = (havePeekableRGBA || !peekSucceed);
- if (isPixelDataRBGA && format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
- needConversion = false;
- } else {
- // In the case of ImageBitmap, we do not need to apply flipY or premultiplyAlpha.
- bool isPixelDataBGRA = (peekSucceed && pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType);
- if ((isPixelDataBGRA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatBGRA8, bitmap->size(), format, type, false, false, data))
- || (isPixelDataRBGA && !WebGLImageConversion::extractImageData(pixelDataPtr, WebGLImageConversion::DataFormat::DataFormatRGBA8, bitmap->size(), format, type, false, false, data))) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
- resetUnpackParameters();
- contextGL()->TexSubImage2D(target, level, xoffset, yoffset, bitmap->width(), bitmap->height(), format, type, needConversion ? data.data() : pixelDataPtr);
- restoreUnpackParameters();
+ texImageHelperImageBitmap(TexSubImage2D, target, level, 0, format, type, xoffset, yoffset, 0, bitmap, exceptionState);
}
void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x)
« no previous file with comments | « third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698