Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 if (!desiredSize.isEmpty()) { | 215 if (!desiredSize.isEmpty()) { |
| 216 forciblyEvictedContexts().remove(0); | 216 forciblyEvictedContexts().remove(0); |
| 217 evictedContext->forceRestoreContext(); | 217 evictedContext->forceRestoreContext(); |
| 218 } | 218 } |
| 219 break; | 219 break; |
| 220 } | 220 } |
| 221 } | 221 } |
| 222 | 222 |
| 223 namespace { | 223 namespace { |
| 224 | 224 |
| 225 // ScopedDrawingBufferBinder is used for ReadPixels/CopyTexImage2D/CopySubImage2 D to read from | |
| 226 // a multisampled DrawingBuffer. In this situation, we need to blit to a single sampled buffer | |
| 227 // for reading, during which the bindings could be changed and need to be recove red. | |
| 228 class ScopedDrawingBufferBinder { | |
| 229 STACK_ALLOCATED(); | |
| 230 public: | |
| 231 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* fr amebufferBinding) | |
| 232 : m_drawingBuffer(drawingBuffer) | |
| 233 , m_readFramebufferBinding(framebufferBinding) | |
| 234 { | |
| 235 // Commit DrawingBuffer if needed (e.g., for multisampling) | |
| 236 if (!m_readFramebufferBinding && m_drawingBuffer) | |
| 237 m_drawingBuffer->commit(); | |
| 238 } | |
| 239 | |
| 240 ~ScopedDrawingBufferBinder() | |
| 241 { | |
| 242 // Restore DrawingBuffer if needed | |
| 243 if (!m_readFramebufferBinding && m_drawingBuffer) | |
| 244 m_drawingBuffer->restoreFramebufferBindings(); | |
| 245 } | |
| 246 | |
| 247 private: | |
| 248 DrawingBuffer* m_drawingBuffer; | |
| 249 Member<WebGLFramebuffer> m_readFramebufferBinding; | |
| 250 }; | |
| 251 | |
| 252 GLint clamp(GLint value, GLint min, GLint max) | 225 GLint clamp(GLint value, GLint min, GLint max) |
| 253 { | 226 { |
| 254 if (value < min) | 227 if (value < min) |
| 255 value = min; | 228 value = min; |
| 256 if (value > max) | 229 if (value > max) |
| 257 value = max; | 230 value = max; |
| 258 return value; | 231 return value; |
| 259 } | 232 } |
| 260 | 233 |
| 261 // Return true if a character belongs to the ASCII subset as defined in | 234 // Return true if a character belongs to the ASCII subset as defined in |
| (...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1601 case GL_DYNAMIC_DRAW: | 1574 case GL_DYNAMIC_DRAW: |
| 1602 break; | 1575 break; |
| 1603 default: | 1576 default: |
| 1604 synthesizeGLError(GL_INVALID_ENUM, "bufferData", "invalid usage"); | 1577 synthesizeGLError(GL_INVALID_ENUM, "bufferData", "invalid usage"); |
| 1605 return; | 1578 return; |
| 1606 } | 1579 } |
| 1607 | 1580 |
| 1608 if (!validateValueFitNonNegInt32("bufferData", "size", size)) | 1581 if (!validateValueFitNonNegInt32("bufferData", "size", size)) |
| 1609 return; | 1582 return; |
| 1610 | 1583 |
| 1584 buffer->setSize(size); | |
| 1585 | |
| 1611 webContext()->bufferData(target, static_cast<GLsizeiptr>(size), data, usage) ; | 1586 webContext()->bufferData(target, static_cast<GLsizeiptr>(size), data, usage) ; |
| 1612 } | 1587 } |
| 1613 | 1588 |
| 1614 void WebGLRenderingContextBase::bufferData(GLenum target, long long size, GLenum usage) | 1589 void WebGLRenderingContextBase::bufferData(GLenum target, long long size, GLenum usage) |
| 1615 { | 1590 { |
| 1616 if (isContextLost()) | 1591 if (isContextLost()) |
| 1617 return; | 1592 return; |
| 1618 if (!size) { | 1593 if (!size) { |
| 1619 synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0"); | 1594 synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0"); |
| 1620 return; | 1595 return; |
| (...skipping 2101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3722 case GL_FLOAT: | 3697 case GL_FLOAT: |
| 3723 return DOMArrayBufferView::TypeFloat32; | 3698 return DOMArrayBufferView::TypeFloat32; |
| 3724 case GL_HALF_FLOAT_OES: | 3699 case GL_HALF_FLOAT_OES: |
| 3725 return DOMArrayBufferView::TypeUint16; | 3700 return DOMArrayBufferView::TypeUint16; |
| 3726 default: | 3701 default: |
| 3727 ASSERT_NOT_REACHED(); | 3702 ASSERT_NOT_REACHED(); |
| 3728 return DOMArrayBufferView::TypeUint8; | 3703 return DOMArrayBufferView::TypeUint8; |
| 3729 } | 3704 } |
| 3730 } | 3705 } |
| 3731 | 3706 |
| 3732 void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi zei height, GLenum format, GLenum type, DOMArrayBufferView* pixels) | 3707 bool WebGLRenderingContextBase::validateReadPixelsFuncParameters(GLsizei width, GLsizei height, GLenum format, GLenum type, long long bufferSize) |
| 3733 { | 3708 { |
| 3734 if (isContextLost()) | |
| 3735 return; | |
| 3736 // Due to WebGL's same-origin restrictions, it is not possible to | |
| 3737 // taint the origin using the WebGL API. | |
| 3738 ASSERT(canvas()->originClean()); | |
| 3739 // Validate input parameters. | |
| 3740 if (!pixels) { | |
| 3741 synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayB ufferView"); | |
| 3742 return; | |
| 3743 } | |
| 3744 if (!validateReadPixelsFormatAndType(format, type)) | 3709 if (!validateReadPixelsFormatAndType(format, type)) |
| 3745 return; | 3710 return false; |
| 3711 WebGLFramebuffer* readFramebufferBinding = nullptr; | |
| 3746 GLenum readBufferInternalFormat = 0, readBufferType = 0; | 3712 GLenum readBufferInternalFormat = 0, readBufferType = 0; |
| 3747 WebGLFramebuffer* readFramebufferBinding = nullptr; | |
| 3748 if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &rea dBufferInternalFormat, &readBufferType)) | 3713 if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &rea dBufferInternalFormat, &readBufferType)) |
| 3749 return; | 3714 return false; |
| 3750 if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInterna lFormat, readBufferType)) | 3715 if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInterna lFormat, readBufferType)) |
| 3751 return; | 3716 return false; |
| 3752 | |
| 3753 DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBuffe rViewType(type); | |
| 3754 // Validate array type against pixel type. | |
| 3755 if (pixels->type() != expectedViewType) { | |
| 3756 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format"); | |
| 3757 return; | |
| 3758 } | |
| 3759 | 3717 |
| 3760 // Calculate array size, taking into consideration of PACK_ALIGNMENT. | 3718 // Calculate array size, taking into consideration of PACK_ALIGNMENT. |
| 3761 unsigned totalBytesRequired = 0; | 3719 unsigned totalBytesRequired = 0; |
| 3762 unsigned padding = 0; | 3720 unsigned padding = 0; |
| 3763 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding); | 3721 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding); |
| 3764 if (error != GL_NO_ERROR) { | 3722 if (error != GL_NO_ERROR) { |
| 3765 synthesizeGLError(error, "readPixels", "invalid dimensions"); | 3723 synthesizeGLError(error, "readPixels", "invalid dimensions"); |
| 3724 return false; | |
| 3725 } | |
| 3726 if (bufferSize < static_cast<long long>(totalBytesRequired)) { | |
| 3727 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "buffer is not lar ge enough for dimensions"); | |
| 3728 return false; | |
| 3729 } | |
| 3730 return true; | |
| 3731 } | |
| 3732 | |
| 3733 void WebGLRenderingContextBase::readPixelsImpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* data, long long bufferSize) | |
| 3734 { | |
| 3735 // Due to WebGL's same-origin restrictions, it is not possible to | |
| 3736 // taint the origin using the WebGL API. | |
| 3737 ASSERT(canvas()->originClean()); | |
| 3738 | |
| 3739 if (!validateReadPixelsFuncParameters(width, height, format, type, bufferSiz e)) | |
| 3766 return; | 3740 return; |
| 3767 } | |
| 3768 if (pixels->byteLength() < totalBytesRequired) { | |
| 3769 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions"); | |
| 3770 return; | |
| 3771 } | |
| 3772 | 3741 |
| 3773 clearIfComposited(); | 3742 clearIfComposited(); |
| 3774 void* data = pixels->baseAddress(); | |
| 3775 | 3743 |
| 3744 GLenum target = isWebGL2OrHigher() ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER; | |
| 3745 WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(target); | |
| 3776 { | 3746 { |
| 3777 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding ); | 3747 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding ); |
| 3778 webContext()->readPixels(x, y, width, height, format, type, data); | 3748 webContext()->readPixels(x, y, width, height, format, type, data); |
| 3779 } | 3749 } |
| 3780 } | 3750 } |
| 3781 | 3751 |
| 3752 void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi zei height, GLenum format, GLenum type, DOMArrayBufferView* pixels) | |
| 3753 { | |
| 3754 if (isContextLost()) | |
| 3755 return; | |
| 3756 // Validate input parameters. | |
| 3757 if (!pixels) { | |
| 3758 synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayB ufferView"); | |
| 3759 return; | |
| 3760 } | |
| 3761 | |
| 3762 DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBuffe rViewType(type); | |
|
yunchao
2015/09/01 02:49:57
readPixelsExpectedArrayBufferViewType(type) suppos
| |
| 3763 // Validate array type against pixel type. | |
| 3764 if (pixels->type() != expectedViewType) { | |
| 3765 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format"); | |
| 3766 return; | |
| 3767 } | |
| 3768 | |
| 3769 readPixelsImpl(x, y, width, height, format, type, pixels->baseAddress(), sta tic_cast<long long>(pixels->byteLength())); | |
| 3770 } | |
| 3771 | |
| 3782 void WebGLRenderingContextBase::renderbufferStorageImpl( | 3772 void WebGLRenderingContextBase::renderbufferStorageImpl( |
| 3783 GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsize i height, | 3773 GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsize i height, |
| 3784 const char* functionName) | 3774 const char* functionName) |
| 3785 { | 3775 { |
| 3786 ASSERT(!samples); // |samples| > 0 is only valid in WebGL2's renderbufferSto rageMultisample(). | 3776 ASSERT(!samples); // |samples| > 0 is only valid in WebGL2's renderbufferSto rageMultisample(). |
| 3787 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2. | 3777 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2. |
| 3788 switch (internalformat) { | 3778 switch (internalformat) { |
| 3789 case GL_DEPTH_COMPONENT16: | 3779 case GL_DEPTH_COMPONENT16: |
| 3790 case GL_RGBA4: | 3780 case GL_RGBA4: |
| 3791 case GL_RGB5_A1: | 3781 case GL_RGB5_A1: |
| (...skipping 2835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6627 | 6617 |
| 6628 return totalBytesPerPixel; | 6618 return totalBytesPerPixel; |
| 6629 } | 6619 } |
| 6630 | 6620 |
| 6631 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const | 6621 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const |
| 6632 { | 6622 { |
| 6633 return m_drawingBuffer.get(); | 6623 return m_drawingBuffer.get(); |
| 6634 } | 6624 } |
| 6635 | 6625 |
| 6636 } // namespace blink | 6626 } // namespace blink |
| OLD | NEW |