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

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: offset should not be less than 0 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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);
Zhenyao Mo 2015/08/19 17:20:23 nit: ASSERT(readFramebufferBinding) here?
yunchao 2015/08/20 08:16:39 Seems that we can't add this assertion. In my opin
Zhenyao Mo 2015/08/20 17:27:34 You are right.
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);
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698