Changeset 57574 in webkit
- Timestamp:
- Apr 14, 2010 3:23:49 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r57573 r57574 1 2010-04-14 Zhenyao Mo <zmo@google.com> 2 3 Reviewed by Dimitri Glazkov. 4 5 readPixels must take PACK_ALIGNMENT into account 6 https://bugs.webkit.org/show_bug.cgi?id=34718 7 8 * fast/canvas/webgl/read-pixels-expected.txt: Verify pixelStorei and readPixels. 9 * fast/canvas/webgl/read-pixels.html: Ditto. 10 1 11 2010-04-14 Nicolas Weber <thakis@chromium.org> 2 12 -
trunk/WebCore/ChangeLog
r57564 r57574 1 2010-04-14 Zhenyao Mo <zmo@google.com> 2 3 Reviewed by Dimitri Glazkov. 4 5 readPixels must take PACK_ALIGNMENT into account 6 https://bugs.webkit.org/show_bug.cgi?id=34718 7 8 Test: fast/canvas/webgl/read-pixels.html 9 10 * html/canvas/WebGLRenderingContext.cpp: 11 (WebCore::WebGLRenderingContext::WebGLRenderingContext): Init members to support pack_alignment. 12 (WebCore::WebGLRenderingContext::pixelStorei): Save pack/unpack_alignment. 13 (WebCore::WebGLRenderingContext::readPixels): Validate enum and deal with pack_alignment. 14 * html/canvas/WebGLRenderingContext.h: Add members to support pack_alignment. 15 * platform/graphics/GraphicsContext3D.h: Refactor readPixels. 16 * platform/graphics/mac/GraphicsContext3DMac.cpp: 17 (WebCore::GraphicsContext3D::readPixels): Move array allocation and alpha fix to WebGLRenderingContext; flush before read pixels. 18 1 19 2010-04-13 Dirk Schulze <krit@webkit.org> 2 20 -
trunk/WebCore/html/canvas/WebGLRenderingContext.cpp
r57324 r57574 39 39 #include "RenderLayer.h" 40 40 #include "WebGLActiveInfo.h" 41 #include "WebGLUnsignedShortArray.h" 41 42 #include "WebGLBuffer.h" 42 43 #include "WebGLContextAttributes.h" … … 86 87 , m_markedCanvasDirty(false) 87 88 , m_activeTextureUnit(0) 89 , m_packAlignment(4) 90 , m_unpackAlignment(4) 88 91 { 89 92 ASSERT(m_context); … … 91 94 m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs); 92 95 m_maxVertexAttribs = numVertexAttribs; 96 int implementationColorReadFormat = GraphicsContext3D::RGBA; 97 m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT, &implementationColorReadFormat); 98 m_implementationColorReadFormat = implementationColorReadFormat; 99 int implementationColorReadType = GraphicsContext3D::UNSIGNED_BYTE; 100 m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType); 101 // FIXME: remove the getError() when IMPLEMENTATION_COLOR_READ_FORMAT/TYPE are supported. 102 m_context->getError(); 103 m_implementationColorReadType = implementationColorReadType; 93 104 m_context->reshape(canvas()->width(), canvas()->height()); 94 105 m_context->viewport(0, 0, canvas()->width(), canvas()->height()); … … 1565 1576 { 1566 1577 m_context->pixelStorei(pname, param); 1578 if (param == 1 || param == 2 || param == 4 || param == 8) { 1579 switch (pname) { 1580 case GraphicsContext3D::PACK_ALIGNMENT: 1581 m_packAlignment = static_cast<int>(param); 1582 break; 1583 case GraphicsContext3D::UNPACK_ALIGNMENT: 1584 m_unpackAlignment = static_cast<int>(param); 1585 break; 1586 } 1587 } 1567 1588 cleanupAfterGraphicsCall(false); 1568 1589 } … … 1576 1597 PassRefPtr<WebGLArray> WebGLRenderingContext::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type) 1577 1598 { 1578 RefPtr<WebGLArray> array = m_context->readPixels(x, y, width, height, format, type); 1599 // Validate enums. 1600 unsigned long componentsPerPixel = 0; 1601 switch (format) { 1602 case GraphicsContext3D::ALPHA: 1603 componentsPerPixel = 1; 1604 break; 1605 case GraphicsContext3D::RGB: 1606 componentsPerPixel = 3; 1607 break; 1608 case GraphicsContext3D::RGBA: 1609 componentsPerPixel = 4; 1610 break; 1611 default: 1612 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1613 return 0; 1614 } 1615 unsigned long bytesPerComponent = 0; 1616 switch (type) { 1617 case GraphicsContext3D::UNSIGNED_BYTE: 1618 bytesPerComponent = sizeof(unsigned char); 1619 break; 1620 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: 1621 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: 1622 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: 1623 componentsPerPixel = 1; 1624 bytesPerComponent = sizeof(unsigned short); 1625 break; 1626 default: 1627 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1628 return 0; 1629 } 1630 if (!(format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE || format == m_implementationColorReadFormat && type == m_implementationColorReadFormat)) { 1631 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1632 return 0; 1633 } 1634 // Calculate array size, taking into consideration of PACK_ALIGNMENT. 1635 unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width; 1636 unsigned long padding = 0; 1637 unsigned long residualBytes = bytesPerRow % m_packAlignment; 1638 if (residualBytes) { 1639 padding = m_packAlignment - residualBytes; 1640 bytesPerRow += padding; 1641 } 1642 // The last row needs no padding. 1643 unsigned long totalBytes = bytesPerRow * height - padding; 1644 unsigned long num = totalBytes / bytesPerComponent; 1645 RefPtr<WebGLArray> array; 1646 if (type == GraphicsContext3D::UNSIGNED_BYTE) 1647 array = WebGLUnsignedByteArray::create(num); 1648 else 1649 array = WebGLUnsignedShortArray::create(num); 1650 void* data = array->baseAddress(); 1651 m_context->readPixels(x, y, width, height, format, type, data); 1652 #if PLATFORM(CG) 1653 // FIXME: remove this section when GL driver bug on Mac is fixed, i.e., 1654 // when alpha is off, readPixels should set alpha to 255 instead of 0. 1655 if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) { 1656 if (type == GraphicsContext3D::UNSIGNED_BYTE) { 1657 unsigned char* pixels = reinterpret_cast<unsigned char*>(data); 1658 for (unsigned long iy = 0; iy < height; ++iy) { 1659 for (unsigned long ix = 0; ix < width; ++ix) { 1660 pixels[componentsPerPixel - 1] = 255; 1661 pixels += componentsPerPixel; 1662 } 1663 pixels += padding; 1664 } 1665 } 1666 // FIXME: check whether we need to do the same with UNSIGNED_SHORT. 1667 } 1668 #endif 1579 1669 cleanupAfterGraphicsCall(false); 1580 1670 return array; -
trunk/WebCore/html/canvas/WebGLRenderingContext.h
r57324 r57574 345 345 unsigned long m_activeTextureUnit; 346 346 347 int m_packAlignment; 348 int m_unpackAlignment; 349 unsigned long m_implementationColorReadFormat; 350 unsigned long m_implementationColorReadType; 351 347 352 // Helpers for getParameter and others 348 353 WebGLGetInfo getBooleanParameter(unsigned long pname); -
trunk/WebCore/platform/graphics/GraphicsContext3D.h
r57174 r57574 593 593 void polygonOffset(double factor, double units); 594 594 595 PassRefPtr<WebGLArray> readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type);595 void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data); 596 596 597 597 void releaseShaderCompiler(); -
trunk/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
r57322 r57574 802 802 } 803 803 804 PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type) 805 { 806 ensureContext(m_contextObj); 807 808 // FIXME: For now we only accept GL_UNSIGNED_BYTE/GL_RGBA. In reality OpenGL ES 2.0 accepts that pair and one other 809 // as specified by GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE. But for now we will 810 // not accept those. 811 // FIXME: Also, we should throw when an unacceptable value is passed 812 if (type != GL_UNSIGNED_BYTE || format != GL_RGBA) 813 return 0; 814 804 void GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data) 805 { 806 // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., 807 // all previous rendering calls should be done before reading pixels. 808 ensureContext(m_contextObj); 809 ::glFlush(); 815 810 if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { 816 811 ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); … … 818 813 ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); 819 814 ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); 820 }821 RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);822 ::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data());815 ::glFlush(); 816 } 817 ::glReadPixels(x, y, width, height, format, type, data); 823 818 if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) 824 819 ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); 825 if (!m_attrs.alpha) {826 // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.827 // This is a hack until ::glReadPixels fixes its behavior.828 GLubyte* data = reinterpret_cast<GLubyte*>(array->data());829 unsigned byteLength = array->byteLength();830 for (unsigned i = 3; i < byteLength; i += 4)831 data[i] = 255;832 }833 return array;834 820 } 835 821 -
trunk/WebKit/chromium/ChangeLog
r57571 r57574 1 2010-04-14 Zhenyao Mo <zmo@google.com> 2 3 Reviewed by Dimitri Glazkov. 4 5 readPixels must take PACK_ALIGNMENT into account 6 https://bugs.webkit.org/show_bug.cgi?id=34718 7 8 * src/GraphicsContext3D.cpp: Refactor readPixels. 9 * src/WebGraphicsContext3DDefaultImpl.cpp: 10 (WebKit::WebGraphicsContext3DDefaultImpl::readBackFramebuffer): Temporarily disable pack alignment for glReadPixels. 11 (WebKit::WebGraphicsContext3DDefaultImpl::readPixels): Move array allocation and alpha fix to WebGLRenderingContext; flush before read pixels. 12 1 13 2010-04-14 Mikhail Naganov <mnaganov@chromium.org> 2 14 -
trunk/WebKit/chromium/src/GraphicsContext3D.cpp
r56825 r57574 219 219 void polygonOffset(double factor, double units); 220 220 221 PassRefPtr<WebGLArray> readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type);221 void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data); 222 222 223 223 void releaseShaderCompiler(); … … 591 591 } 592 592 593 #define DELEGATE_TO_IMPL_7(name, t1, t2, t3, t4, t5, t6, t7) \ 594 void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ 595 { \ 596 m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ 597 } 598 593 599 #define DELEGATE_TO_IMPL_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \ 594 600 rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ … … 805 811 DELEGATE_TO_IMPL_2(pixelStorei, unsigned long, long) 806 812 DELEGATE_TO_IMPL_2(polygonOffset, double, double) 807 808 PassRefPtr<WebGLArray> GraphicsContext3DInternal::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type) 809 { 810 // FIXME: take into account pack alignment. 811 RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4); 812 m_impl->readPixels(x, y, width, height, format, type, array->baseAddress()); 813 return array; 814 } 815 813 DELEGATE_TO_IMPL_7(readPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, void*) 816 814 DELEGATE_TO_IMPL(releaseShaderCompiler) 817 815 DELEGATE_TO_IMPL_4(renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long) … … 1025 1023 { \ 1026 1024 return m_internal->name(a1, a2, a3, a4, a5, a6); \ 1025 } 1026 1027 #define DELEGATE_TO_INTERNAL_7(name, t1, t2, t3, t4, t5, t6, t7) \ 1028 void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ 1029 { \ 1030 m_internal->name(a1, a2, a3, a4, a5, a6, a7); \ 1027 1031 } 1028 1032 … … 1184 1188 DELEGATE_TO_INTERNAL_2(polygonOffset, double, double) 1185 1189 1186 DELEGATE_TO_INTERNAL_ 6R(readPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, PassRefPtr<WebGLArray>)1190 DELEGATE_TO_INTERNAL_7(readPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, void*) 1187 1191 1188 1192 DELEGATE_TO_INTERNAL(releaseShaderCompiler) -
trunk/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp
r57322 r57574 662 662 } 663 663 } 664 665 GLint packAlignment = 4; 666 bool mustRestorePackAlignment = false; 667 glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); 668 if (packAlignment > 4) { 669 glPixelStorei(GL_PACK_ALIGNMENT, 4); 670 mustRestorePackAlignment = true; 671 } 672 664 673 #if PLATFORM(SKIA) 665 674 glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); … … 669 678 #error Must port to your platform 670 679 #endif 680 681 if (mustRestorePackAlignment) 682 glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); 671 683 672 684 if (mustRestoreFBO) … … 1153 1165 void WebGraphicsContext3DDefaultImpl::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels) 1154 1166 { 1167 // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., 1168 // all previous rendering calls should be done before reading pixels. 1169 glFlush(); 1155 1170 #ifndef RENDER_TO_DEBUGGING_WINDOW 1156 1171 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { … … 1159 1174 glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); 1160 1175 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); 1176 glFlush(); 1161 1177 } 1162 1178 #endif 1163 1179 glReadPixels(x, y, width, height, format, type, pixels); 1164 #if PLATFORM(CG)1165 if (!m_attributes.alpha) {1166 // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.1167 // This is a hack until glReadPixels fixes its behavior.1168 // Pixels are stored in WebGLUnsignedByteArray, which is unsigned char array.1169 unsigned char* data = reinterpret_cast<unsigned char*>(pixels);1170 // FIXME: take into account pack alignment.1171 unsigned long byteLength = width * height * 4 * sizeof(unsigned char);1172 for (unsigned long i = 3; i < byteLength; i += 4)1173 data[i] = 255;1174 }1175 #endif1176 1180 #ifndef RENDER_TO_DEBUGGING_WINDOW 1177 1181 if (m_attributes.antialias && m_boundFBO == m_multisampleFBO)
Note: See TracChangeset
for help on using the changeset viewer.