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

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: move the new readPixels to WebGL 2 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 3460 matching lines...) Expand 10 before | Expand all | Expand 10 after
3722 case GL_FLOAT: 3695 case GL_FLOAT:
3723 return DOMArrayBufferView::TypeFloat32; 3696 return DOMArrayBufferView::TypeFloat32;
3724 case GL_HALF_FLOAT_OES: 3697 case GL_HALF_FLOAT_OES:
3725 return DOMArrayBufferView::TypeUint16; 3698 return DOMArrayBufferView::TypeUint16;
3726 default: 3699 default:
3727 ASSERT_NOT_REACHED(); 3700 ASSERT_NOT_REACHED();
3728 return DOMArrayBufferView::TypeUint8; 3701 return DOMArrayBufferView::TypeUint8;
3729 } 3702 }
3730 } 3703 }
3731 3704
3732 void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi zei height, GLenum format, GLenum type, DOMArrayBufferView* pixels) 3705 bool WebGLRenderingContextBase::validateReadPixelsFuncParameters(GLsizei width, GLsizei height, GLenum format, GLenum type, unsigned domArrayBufferLength, WebGL Framebuffer*& readFramebufferBinding)
Zhenyao Mo 2015/08/18 21:48:39 I prefer not to return the readFramebufferBinding
yunchao 2015/08/19 09:33:39 Make sense. Done.
3733 { 3706 {
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)) 3707 if (!validateReadPixelsFormatAndType(format, type))
3745 return; 3708 return false;
3746 GLenum readBufferInternalFormat = 0, readBufferType = 0; 3709 GLenum readBufferInternalFormat = 0, readBufferType = 0;
3747 WebGLFramebuffer* readFramebufferBinding = nullptr;
3748 if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &rea dBufferInternalFormat, &readBufferType)) 3710 if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &rea dBufferInternalFormat, &readBufferType))
3749 return; 3711 return false;
3750 if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInterna lFormat, readBufferType)) 3712 if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInterna lFormat, readBufferType))
3751 return; 3713 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 3714
3760 // Calculate array size, taking into consideration of PACK_ALIGNMENT. 3715 // Calculate array size, taking into consideration of PACK_ALIGNMENT.
3761 unsigned totalBytesRequired = 0; 3716 unsigned totalBytesRequired = 0;
3762 unsigned padding = 0; 3717 unsigned padding = 0;
3763 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding); 3718 GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, w idth, height, m_packAlignment, &totalBytesRequired, &padding);
3764 if (error != GL_NO_ERROR) { 3719 if (error != GL_NO_ERROR) {
3765 synthesizeGLError(error, "readPixels", "invalid dimensions"); 3720 synthesizeGLError(error, "readPixels", "invalid dimensions");
3721 return false;
3722 }
3723 if (domArrayBufferLength && domArrayBufferLength < totalBytesRequired) {
3724 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions");
3725 return false;
3726 }
3727 return true;
3728 }
3729
3730 void WebGLRenderingContextBase::readPixelsImpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* data, unsigned domArrayBufferL ength)
3731 {
3732 // Due to WebGL's same-origin restrictions, it is not possible to
3733 // taint the origin using the WebGL API.
3734 ASSERT(canvas()->originClean());
3735
3736 WebGLFramebuffer* readFramebufferBinding = nullptr;
3737 if (!validateReadPixelsFuncParameters(format, type, width, height, domArrayB ufferLength, readFramebufferBinding))
3766 return; 3738 return;
3767 }
3768 if (pixels->byteLength() < totalBytesRequired) {
3769 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView n ot large enough for dimensions");
3770 return;
3771 }
3772 3739
3773 clearIfComposited(); 3740 clearIfComposited();
3774 void* data = pixels->baseAddress();
3775 3741
3776 { 3742 {
3777 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding ); 3743 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding );
3778 webContext()->readPixels(x, y, width, height, format, type, data); 3744 webContext()->readPixels(x, y, width, height, format, type, data);
3779 } 3745 }
3780 } 3746 }
3781 3747
3748 void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi zei height, GLenum format, GLenum type, DOMArrayBufferView* pixels)
3749 {
3750 if (isContextLost())
3751 return;
3752 // Validate input parameters.
3753 if (!pixels) {
3754 synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayB ufferView");
3755 return;
3756 }
3757
3758 DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBuffe rViewType(type);
3759 // Validate array type against pixel type.
3760 if (pixels->type() != expectedViewType) {
3761 synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView w as the wrong type for the pixel format");
3762 return;
3763 }
3764
3765 readPixelsImpl(x, y, width, height, format, type, pixels->baseAddress(), pix els->byteLength());
3766 }
3767
3782 void WebGLRenderingContextBase::renderbufferStorageImpl( 3768 void WebGLRenderingContextBase::renderbufferStorageImpl(
3783 GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsize i height, 3769 GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsize i height,
3784 const char* functionName) 3770 const char* functionName)
3785 { 3771 {
3786 ASSERT(!samples); // |samples| > 0 is only valid in WebGL2's renderbufferSto rageMultisample(). 3772 ASSERT(!samples); // |samples| > 0 is only valid in WebGL2's renderbufferSto rageMultisample().
3787 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2. 3773 ASSERT(!isWebGL2OrHigher()); // Make sure this is overridden in WebGL 2.
3788 switch (internalformat) { 3774 switch (internalformat) {
3789 case GL_DEPTH_COMPONENT16: 3775 case GL_DEPTH_COMPONENT16:
3790 case GL_RGBA4: 3776 case GL_RGBA4:
3791 case GL_RGB5_A1: 3777 case GL_RGB5_A1:
(...skipping 2835 matching lines...) Expand 10 before | Expand all | Expand 10 after
6627 6613
6628 return totalBytesPerPixel; 6614 return totalBytesPerPixel;
6629 } 6615 }
6630 6616
6631 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const 6617 DrawingBuffer* WebGLRenderingContextBase::drawingBuffer() const
6632 { 6618 {
6633 return m_drawingBuffer.get(); 6619 return m_drawingBuffer.get();
6634 } 6620 }
6635 6621
6636 } // namespace blink 6622 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698