| 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 5fbbbae804cc29c5758b026e8aa9762a0231e295..d890e8026cd8a367450a57fa30c6097715bdc1e5 100644
|
| --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| @@ -515,6 +515,29 @@ private:
|
| Member<WebGLRenderingContextBase> m_context;
|
| };
|
|
|
| +class ScopedUnpackParametersResetRestore {
|
| + STACK_ALLOCATED();
|
| +
|
| +public:
|
| + explicit ScopedUnpackParametersResetRestore(WebGLRenderingContextBase* context, bool enabled = true)
|
| + : m_context(context)
|
| + , m_enabled(enabled)
|
| + {
|
| + if (enabled)
|
| + m_context->resetUnpackParameters();
|
| + }
|
| +
|
| + ~ScopedUnpackParametersResetRestore()
|
| + {
|
| + if (m_enabled)
|
| + m_context->restoreUnpackParameters();
|
| + }
|
| +
|
| +private:
|
| + Member<WebGLRenderingContextBase> m_context;
|
| + bool m_enabled;
|
| +};
|
| +
|
| static void formatWebGLStatusString(const StringView& glInfo, const StringView& infoString, StringBuilder& builder)
|
| {
|
| if (infoString.isEmpty())
|
| @@ -4038,7 +4061,7 @@ void WebGLRenderingContextBase::texImageImpl(TexImageFunctionID functionID, GLen
|
| }
|
| }
|
|
|
| - resetUnpackParameters();
|
| + ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
|
| if (functionID == TexImage2D) {
|
| texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData);
|
| } else if (functionID == TexSubImage2D) {
|
| @@ -4047,7 +4070,6 @@ void WebGLRenderingContextBase::texImageImpl(TexImageFunctionID functionID, GLen
|
| DCHECK_EQ(functionID, TexSubImage3D);
|
| contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 1, format, type, needConversion ? data.data() : imagePixelData);
|
| }
|
| - restoreUnpackParameters();
|
| }
|
|
|
| bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexImageFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset, GLint zoffset)
|
| @@ -4189,14 +4211,11 @@ void WebGLRenderingContextBase::texImageHelperDOMArrayBufferView(TexImageFunctio
|
| return;
|
| }
|
|
|
| - if (changeUnpackAlignment)
|
| - resetUnpackParameters();
|
| + ScopedUnpackParametersResetRestore temporaryResetUnpack(this, changeUnpackAlignment);
|
| if (functionID == TexImage2D)
|
| texImage2DBase(target, level, internalformat, width, height, border, format, type, data);
|
| else if (functionID == TexSubImage2D)
|
| contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
|
| - if (changeUnpackAlignment)
|
| - restoreUnpackParameters();
|
| }
|
|
|
| void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint internalformat,
|
| @@ -4246,7 +4265,7 @@ void WebGLRenderingContextBase::texImageHelperImageData(TexImageFunctionID funct
|
| return;
|
| }
|
| }
|
| - resetUnpackParameters();
|
| + ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
|
| if (functionID == TexImage2D) {
|
| texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), border, format, type, needConversion ? data.data() : pixels->data()->data());
|
| } else if (functionID == TexSubImage2D) {
|
| @@ -4255,7 +4274,6 @@ void WebGLRenderingContextBase::texImageHelperImageData(TexImageFunctionID funct
|
| DCHECK_EQ(functionID, TexSubImage3D);
|
| 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,
|
| @@ -4311,8 +4329,7 @@ void WebGLRenderingContextBase::texImageCanvasByGPU(HTMLCanvasElement* canvas, G
|
| {
|
| if (!canvas->is3D()) {
|
| ImageBuffer* buffer = canvas->buffer();
|
| - if (!buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInternalformat, targetType,
|
| - targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
|
| + if (extensionsUtil()->canUseCopyTextureCHROMIUM(targetTexture, targetInternalformat, targetType, targetLevel) && !buffer->copyToPlatformTexture(contextGL(), targetTexture, targetInternalformat, targetType, targetLevel, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
|
| NOTREACHED();
|
| }
|
| } else {
|
| @@ -4340,7 +4357,7 @@ void WebGLRenderingContextBase::texImageByGPU(TexImageByGPUType functionType, We
|
| GLint targetLevel = level;
|
| bool possibleDirectCopy = false;
|
| if (functionType == TexImage2DByGPU) {
|
| - possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level);
|
| + possibleDirectCopy = extensionsUtil()->canUseCopyTextureCHROMIUM(target, internalformat, type, level);
|
| }
|
|
|
| // if direct copy is not possible, create a temporary texture and then copy from canvas to temporary texture to target texture.
|
| @@ -4464,30 +4481,37 @@ void WebGLRenderingContextBase::texImageHelperHTMLVideoElement(TexImageFunctionI
|
| if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, format, type, xoffset, yoffset, zoffset))
|
| return;
|
|
|
| - if (functionID == TexImage2D) {
|
| + if (functionID == TexImage2D && GL_TEXTURE_2D == target && extensionsUtil()->canUseCopyTextureCHROMIUM(target, internalformat, type, level)) {
|
| // 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 (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.
|
| - std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new AcceleratedImageBufferSurface(IntSize(video->videoWidth(), video->videoHeight())));
|
| - if (surface->isValid()) {
|
| - std::unique_ptr<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,
|
| + {
|
| + // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It leaves early for other formats or if frame is stored on GPU.
|
| + ScopedUnpackParametersResetRestore(this, m_unpackFlipY || m_unpackPremultiplyAlpha);
|
| + if (video->texImageImpl(getTexImageFunctionName(functionID), target, contextGL(), level, internalformat, format, type, xoffset, yoffset, zoffset,
|
| + m_unpackFlipY, m_unpackPremultiplyAlpha && m_unpackColorspaceConversion == GL_NONE))
|
| + return;
|
| + }
|
| +
|
| + if (functionID == TexImage2D && GL_TEXTURE_2D == target && extensionsUtil()->canUseCopyTextureCHROMIUM(target, internalformat, type, level)) {
|
| + // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU.
|
| + std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new AcceleratedImageBufferSurface(IntSize(video->videoWidth(), video->videoHeight())));
|
| + if (surface->isValid()) {
|
| + std::unique_ptr<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;
|
| - }
|
| + return;
|
| }
|
| }
|
| }
|
| @@ -4572,7 +4596,7 @@ void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun
|
| return;
|
| }
|
| }
|
| - resetUnpackParameters();
|
| + ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
|
| if (functionID == TexImage2D) {
|
| texImage2DBase(target, level, internalformat, bitmap->width(), bitmap->height(), 0, format, type, needConversion ? data.data() : pixelDataPtr);
|
| } else if (functionID == TexSubImage2D) {
|
| @@ -4581,7 +4605,6 @@ void WebGLRenderingContextBase::texImageHelperImageBitmap(TexImageFunctionID fun
|
| DCHECK_EQ(functionID, 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,
|
|
|