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

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

Issue 1300573002: WebGL 2: add readPixels API to read pixels into pixel pack buffer (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 4 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 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 949 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 ASSERT(drawingBuffer()); 960 ASSERT(drawingBuffer());
961 961
962 m_markedCanvasDirty = false; 962 m_markedCanvasDirty = false;
963 m_activeTextureUnit = 0; 963 m_activeTextureUnit = 0;
964 m_packAlignment = 4; 964 m_packAlignment = 4;
965 m_unpackAlignment = 4; 965 m_unpackAlignment = 4;
966 m_unpackFlipY = false; 966 m_unpackFlipY = false;
967 m_unpackPremultiplyAlpha = false; 967 m_unpackPremultiplyAlpha = false;
968 m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL; 968 m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
969 m_boundArrayBuffer = nullptr; 969 m_boundArrayBuffer = nullptr;
970 m_boundPixelPackBuffer = nullptr;
970 m_currentProgram = nullptr; 971 m_currentProgram = nullptr;
971 m_framebufferBinding = nullptr; 972 m_framebufferBinding = nullptr;
972 m_renderbufferBinding = nullptr; 973 m_renderbufferBinding = nullptr;
973 m_valuebufferBinding = nullptr; 974 m_valuebufferBinding = nullptr;
974 m_depthMask = true; 975 m_depthMask = true;
975 m_stencilEnabled = false; 976 m_stencilEnabled = false;
976 m_stencilMask = 0xFFFFFFFF; 977 m_stencilMask = 0xFFFFFFFF;
977 m_stencilMaskBack = 0xFFFFFFFF; 978 m_stencilMaskBack = 0xFFFFFFFF;
978 m_stencilFuncRef = 0; 979 m_stencilFuncRef = 0;
979 m_stencilFuncRefBack = 0; 980 m_stencilFuncRefBack = 0;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 if (!context->is3d()) 1092 if (!context->is3d())
1092 return 0; 1093 return 0;
1093 return static_cast<const WebGLRenderingContextBase*>(context)->version(); 1094 return static_cast<const WebGLRenderingContextBase*>(context)->version();
1094 } 1095 }
1095 1096
1096 WebGLRenderingContextBase::~WebGLRenderingContextBase() 1097 WebGLRenderingContextBase::~WebGLRenderingContextBase()
1097 { 1098 {
1098 // Remove all references to WebGLObjects so if they are the last reference 1099 // Remove all references to WebGLObjects so if they are the last reference
1099 // they will be freed before the last context is removed from the context gr oup. 1100 // they will be freed before the last context is removed from the context gr oup.
1100 m_boundArrayBuffer = nullptr; 1101 m_boundArrayBuffer = nullptr;
1102 m_boundPixelPackBuffer = nullptr;
1101 m_defaultVertexArrayObject = nullptr; 1103 m_defaultVertexArrayObject = nullptr;
1102 m_boundVertexArrayObject = nullptr; 1104 m_boundVertexArrayObject = nullptr;
1103 m_vertexAttrib0Buffer = nullptr; 1105 m_vertexAttrib0Buffer = nullptr;
1104 m_currentProgram = nullptr; 1106 m_currentProgram = nullptr;
1105 m_framebufferBinding = nullptr; 1107 m_framebufferBinding = nullptr;
1106 m_renderbufferBinding = nullptr; 1108 m_renderbufferBinding = nullptr;
1107 m_valuebufferBinding = nullptr; 1109 m_valuebufferBinding = nullptr;
1108 1110
1109 for (size_t i = 0; i < m_textureUnits.size(); ++i) { 1111 for (size_t i = 0; i < m_textureUnits.size(); ++i) {
1110 m_textureUnits[i].m_texture2DBinding = nullptr; 1112 m_textureUnits[i].m_texture2DBinding = nullptr;
(...skipping 2611 matching lines...) Expand 10 before | Expand all | Expand 10 after
3722 case GL_FLOAT: 3724 case GL_FLOAT:
3723 return DOMArrayBufferView::TypeFloat32; 3725 return DOMArrayBufferView::TypeFloat32;
3724 case GL_HALF_FLOAT_OES: 3726 case GL_HALF_FLOAT_OES:
3725 return DOMArrayBufferView::TypeUint16; 3727 return DOMArrayBufferView::TypeUint16;
3726 default: 3728 default:
3727 ASSERT_NOT_REACHED(); 3729 ASSERT_NOT_REACHED();
3728 return DOMArrayBufferView::TypeUint8; 3730 return DOMArrayBufferView::TypeUint8;
3729 } 3731 }
3730 } 3732 }
3731 3733
3734 bool WebGLRenderingContextBase::validateReadPixelsFuncParameters(GLsizei width, GLsizei height, GLenum format, GLenum type, unsigned domArrayBufferLength, WebGL Framebuffer*& readFramebufferBinding)
3735 {
3736 if (!validateReadPixelsFormatAndType(format, type))
3737 return false;
3738 GLenum readBufferInternalFormat = 0, readBufferType = 0;
3739 if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &rea dBufferInternalFormat, &readBufferType))
3740 return false;
3741 if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInterna lFormat, readBufferType))
3742 return false;
3743
3744 // Calculate array size, taking into consideration of PACK_ALIGNMENT.
3745 unsigned totalBytesRequired = 0;
3746 unsigned padding = 0;
3747 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding);
3748 if (error != GL_NO_ERROR) {
3749 synthesizeGLError(error, "readPixels", "invalid dimensions");
3750 return false;
3751 }
3752 if (domArrayBufferLength && domArrayBufferLength < totalBytesRequired) {
3753 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions");
3754 return false;
3755 }
3756 return true;
3757 }
3758
3732 void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi zei height, GLenum format, GLenum type, DOMArrayBufferView* pixels) 3759 void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi zei height, GLenum format, GLenum type, DOMArrayBufferView* pixels)
3733 { 3760 {
3734 if (isContextLost()) 3761 if (isContextLost())
3735 return; 3762 return;
3736 // Due to WebGL's same-origin restrictions, it is not possible to 3763 // Due to WebGL's same-origin restrictions, it is not possible to
3737 // taint the origin using the WebGL API. 3764 // taint the origin using the WebGL API.
3738 ASSERT(canvas()->originClean()); 3765 ASSERT(canvas()->originClean());
3766 if (isWebGL2OrHigher() && m_boundPixelPackBuffer.get()) {
3767 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "PIXEL_PACK buffer should not bound");
3768 return;
3769 }
3739 // Validate input parameters. 3770 // Validate input parameters.
3740 if (!pixels) { 3771 if (!pixels) {
3741 synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayB ufferView"); 3772 synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayB ufferView");
3742 return; 3773 return;
3743 } 3774 }
3744 if (!validateReadPixelsFormatAndType(format, type))
3745 return;
3746 GLenum readBufferInternalFormat = 0, readBufferType = 0;
3747 WebGLFramebuffer* readFramebufferBinding = nullptr;
3748 if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &rea dBufferInternalFormat, &readBufferType))
3749 return;
3750 if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInterna lFormat, readBufferType))
3751 return;
3752 3775
3753 DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBuffe rViewType(type); 3776 DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBuffe rViewType(type);
3754 // Validate array type against pixel type. 3777 // Validate array type against pixel type.
3755 if (pixels->type() != expectedViewType) { 3778 if (pixels->type() != expectedViewType) {
3756 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format"); 3779 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format");
3757 return; 3780 return;
3758 } 3781 }
3759 3782
3760 // Calculate array size, taking into consideration of PACK_ALIGNMENT. 3783 WebGLFramebuffer* readFramebufferBinding = nullptr;
3761 unsigned totalBytesRequired = 0; 3784 if (!validateReadPixelsFuncParameters(format, type, width, height, pixels->b yteLength(), readFramebufferBinding))
3762 unsigned padding = 0;
3763 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding);
3764 if (error != GL_NO_ERROR) {
3765 synthesizeGLError(error, "readPixels", "invalid dimensions");
3766 return; 3785 return;
3767 }
3768 if (pixels->byteLength() < totalBytesRequired) {
3769 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions");
3770 return;
3771 }
3772 3786
3773 clearIfComposited(); 3787 clearIfComposited();
3774 void* data = pixels->baseAddress(); 3788 void* data = pixels->baseAddress();
3775 3789
3776 { 3790 {
3777 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding ); 3791 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding );
3778 webContext()->readPixels(x, y, width, height, format, type, data); 3792 webContext()->readPixels(x, y, width, height, format, type, data);
3779 } 3793 }
3780 } 3794 }
3781 3795
3796 void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi zei height, GLenum format, GLenum type, long long offset)
3797 {
3798 if (isContextLost() || !isWebGL2OrHigher())
3799 return;
3800 // Due to WebGL's same-origin restrictions, it is not possible to
3801 // taint the origin using the WebGL API.
3802 ASSERT(canvas()->originClean());
3803 if (!m_boundPixelPackBuffer.get()) {
3804 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "no PIXEL_PACK buf fer bound");
3805 return;
3806 }
3807
3808 WebGLFramebuffer* readFramebufferBinding = nullptr;
3809 if (!validateReadPixelsFuncParameters(format, type, width, height, 0, readFr amebufferBinding))
3810 return;
3811
3812 clearIfComposited();
3813 {
3814 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding );
3815 webContext()->readPixels(x, y, width, height, format, type, (void*)offse t);
3816 }
3817 }
3818
3782 void WebGLRenderingContextBase::renderbufferStorageImpl( 3819 void WebGLRenderingContextBase::renderbufferStorageImpl(
3783 GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsize i height, 3820 GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsize i height,
3784 const char* functionName) 3821 const char* functionName)
3785 { 3822 {
3786 ASSERT(!samples); // |samples| > 0 is only valid in WebGL2's renderbufferSto rageMultisample(). 3823 ASSERT(!samples); // |samples| > 0 is only valid in WebGL2's renderbufferSto rageMultisample().
3787 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2. 3824 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2.
3788 switch (internalformat) { 3825 switch (internalformat) {
3789 case GL_DEPTH_COMPONENT16: 3826 case GL_DEPTH_COMPONENT16:
3790 case GL_RGBA4: 3827 case GL_RGBA4:
3791 case GL_RGB5_A1: 3828 case GL_RGB5_A1:
(...skipping 2789 matching lines...) Expand 10 before | Expand all | Expand 10 after
6581 visitor->trace(m_texture3DBinding); 6618 visitor->trace(m_texture3DBinding);
6582 visitor->trace(m_texture2DArrayBinding); 6619 visitor->trace(m_texture2DArrayBinding);
6583 } 6620 }
6584 6621
6585 DEFINE_TRACE(WebGLRenderingContextBase) 6622 DEFINE_TRACE(WebGLRenderingContextBase)
6586 { 6623 {
6587 visitor->trace(m_contextObjects); 6624 visitor->trace(m_contextObjects);
6588 visitor->trace(m_contextLostCallbackAdapter); 6625 visitor->trace(m_contextLostCallbackAdapter);
6589 visitor->trace(m_errorMessageCallbackAdapter); 6626 visitor->trace(m_errorMessageCallbackAdapter);
6590 visitor->trace(m_boundArrayBuffer); 6627 visitor->trace(m_boundArrayBuffer);
6628 visitor->trace(m_boundPixelPackBuffer);
6591 visitor->trace(m_defaultVertexArrayObject); 6629 visitor->trace(m_defaultVertexArrayObject);
6592 visitor->trace(m_boundVertexArrayObject); 6630 visitor->trace(m_boundVertexArrayObject);
6593 visitor->trace(m_vertexAttrib0Buffer); 6631 visitor->trace(m_vertexAttrib0Buffer);
6594 visitor->trace(m_currentProgram); 6632 visitor->trace(m_currentProgram);
6595 visitor->trace(m_framebufferBinding); 6633 visitor->trace(m_framebufferBinding);
6596 visitor->trace(m_renderbufferBinding); 6634 visitor->trace(m_renderbufferBinding);
6597 visitor->trace(m_valuebufferBinding); 6635 visitor->trace(m_valuebufferBinding);
6598 visitor->trace(m_textureUnits); 6636 visitor->trace(m_textureUnits);
6599 visitor->trace(m_blackTexture2D); 6637 visitor->trace(m_blackTexture2D);
6600 visitor->trace(m_blackTextureCubeMap); 6638 visitor->trace(m_blackTextureCubeMap);
(...skipping 26 matching lines...) Expand all
6627 6665
6628 return totalBytesPerPixel; 6666 return totalBytesPerPixel;
6629 } 6667 }
6630 6668
6631 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const 6669 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const
6632 { 6670 {
6633 return m_drawingBuffer.get(); 6671 return m_drawingBuffer.get();
6634 } 6672 }
6635 6673
6636 } // namespace blink 6674 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698