Changeset 117191 in webkit
- Timestamp:
- May 15, 2012 5:00:52 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r117190 r117191 1 2012-05-15 Kenneth Russell <kbr@google.com> 2 3 Assertion failure running Mozilla's WebGL performance regression tests 4 https://bugs.webkit.org/show_bug.cgi?id=85942 5 6 Reviewed by Stephen White. 7 8 Fixed incorrect assumptions about source formats and buffer sizes 9 when uploading to floating-point textures. Added code paths 10 supporting the necessary conversions. 11 12 Tests have been added to the WebGL conformance suite which cover 13 these new code paths; they verify uploads of HTMLCanvasElement, 14 HTMLImageElement, HTMLVideoElement, and ImageData to 15 floating-point textures. However, because floating-point texture 16 support is optional, and generally only supported on bots which 17 run with real GPUs and not in virtual machines, it isn't feasible 18 to incorporate these tests as layout tests. 19 20 Ran the new WebGL conformance tests in Chromium on Linux; all 21 pass. 22 23 * platform/graphics/GraphicsContext3D.cpp: 24 (WebCore::GraphicsContext3D::extractImageData): 25 Properly compute size of destination buffer. 26 27 (WebCore): 28 Add pack/unpack routines for converting RGBA8/BGRA8 to floating point. 29 30 (WebCore::doFloatingPointPacking): 31 Support RGBA8 and BGRA8 source formats. 32 33 (WebCore::isFloatingPointSource): 34 Factored out logic for assertions. 35 36 (WebCore::GraphicsContext3D::packPixels): 37 Generalized assertions and logic. 38 39 * platform/graphics/cairo/GraphicsContext3DCairo.cpp: 40 (WebCore::GraphicsContext3D::getImageData): 41 Properly compute size of destination buffer. 42 43 * platform/graphics/cg/GraphicsContext3DCG.cpp: 44 (WebCore::GraphicsContext3D::getImageData): 45 Properly compute size of destination buffer. 46 47 * platform/graphics/qt/GraphicsContext3DQt.cpp: 48 (WebCore::GraphicsContext3D::getImageData): 49 Properly compute size of destination buffer. 50 51 * platform/graphics/skia/GraphicsContext3DSkia.cpp: 52 (WebCore::GraphicsContext3D::getImageData): 53 Properly compute size of destination buffer. 54 1 55 2012-05-15 James Robinson <jamesr@chromium.org> 2 56 -
trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
r116198 r117191 201 201 int width = imageData->width(); 202 202 int height = imageData->height(); 203 int dataBytes = width * height * 4; 204 data.resize(dataBytes); 203 204 unsigned int packedSize; 205 // Output data is tightly packed (alignment == 1). 206 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR) 207 return false; 208 data.resize(packedSize); 209 205 210 if (!packPixels(imageData->data()->data(), 206 211 SourceFormatRGBA8, … … 705 710 } 706 711 712 void unpackOneRowOfRGBA8ToRGBA32F(const uint8_t* source, float* destination, unsigned int pixelsPerRow) 713 { 714 const float scaleFactor = 1.0f / 255.0f; 715 for (unsigned int i = 0; i < pixelsPerRow; ++i) { 716 destination[0] = source[0] * scaleFactor; 717 destination[1] = source[1] * scaleFactor; 718 destination[2] = source[2] * scaleFactor; 719 destination[3] = source[3] * scaleFactor; 720 source += 4; 721 destination += 4; 722 } 723 } 724 725 void unpackOneRowOfBGRA8ToRGBA32F(const uint8_t* source, float* destination, unsigned int pixelsPerRow) 726 { 727 const float scaleFactor = 1.0f / 255.0f; 728 for (unsigned int i = 0; i < pixelsPerRow; ++i) { 729 destination[0] = source[2] * scaleFactor; 730 destination[1] = source[1] * scaleFactor; 731 destination[2] = source[0] * scaleFactor; 732 destination[3] = source[3] * scaleFactor; 733 source += 4; 734 destination += 4; 735 } 736 } 737 707 738 void unpackOneRowOfRGB32FToRGBA32F(const float* source, float* destination, unsigned int pixelsPerRow) 708 739 { … … 1063 1094 } 1064 1095 1096 void packOneRowOfRGBA32FToRGB32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow) 1097 { 1098 for (unsigned int i = 0; i < pixelsPerRow; ++i) { 1099 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; 1100 destination[0] = source[0] * scaleFactor; 1101 destination[1] = source[1] * scaleFactor; 1102 destination[2] = source[2] * scaleFactor; 1103 source += 4; 1104 destination += 3; 1105 } 1106 } 1107 1108 // Used only during RGBA8 or BGRA8 -> floating-point uploads. 1109 void packOneRowOfRGBA32FToRGBA32F(const float* source, float* destination, unsigned int pixelsPerRow) 1110 { 1111 for (unsigned int i = 0; i < pixelsPerRow; ++i) { 1112 destination[0] = source[0]; 1113 destination[1] = source[1]; 1114 destination[2] = source[2]; 1115 destination[3] = source[3]; 1116 source += 4; 1117 destination += 4; 1118 } 1119 } 1120 1065 1121 void packOneRowOfRGBA32FToRGBA32FPremultiply(const float* source, float* destination, unsigned int pixelsPerRow) 1066 1122 { … … 1076 1132 } 1077 1133 1134 void packOneRowOfRGBA32FToRGBA32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow) 1135 { 1136 for (unsigned int i = 0; i < pixelsPerRow; ++i) { 1137 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; 1138 destination[0] = source[0] * scaleFactor; 1139 destination[1] = source[1] * scaleFactor; 1140 destination[2] = source[2] * scaleFactor; 1141 destination[3] = source[3]; 1142 source += 4; 1143 destination += 4; 1144 } 1145 } 1146 1078 1147 void packOneRowOfRGBA32FToA32F(const float* source, float* destination, unsigned int pixelsPerRow) 1079 1148 { … … 1104 1173 } 1105 1174 1175 void packOneRowOfRGBA32FToR32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow) 1176 { 1177 for (unsigned int i = 0; i < pixelsPerRow; ++i) { 1178 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; 1179 destination[0] = source[0] * scaleFactor; 1180 source += 4; 1181 destination += 1; 1182 } 1183 } 1106 1184 1107 1185 void packOneRowOfRGBA32FToRA32F(const float* source, float* destination, unsigned int pixelsPerRow) … … 1120 1198 float scaleFactor = source[3]; 1121 1199 destination[0] = source[0] * scaleFactor; 1122 destination[1] = scaleFactor; 1200 destination[1] = source[3]; 1201 source += 4; 1202 destination += 2; 1203 } 1204 } 1205 1206 void packOneRowOfRGBA32FToRA32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow) 1207 { 1208 for (unsigned int i = 0; i < pixelsPerRow; ++i) { 1209 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; 1210 destination[0] = source[0] * scaleFactor; 1211 destination[1] = source[3]; 1123 1212 source += 4; 1124 1213 destination += 2; … … 1368 1457 switch (sourceDataFormat) { 1369 1458 case GraphicsContext3D::SourceFormatRGBA8: { 1459 unsigned int sourceElementsPerRow = computeSourceElementsPerRow<uint8_t>(width, 4, sourceUnpackAlignment); 1460 doUnpackingAndPacking<uint8_t, float, float>(static_cast<const uint8_t*>(sourceData), unpackOneRowOfRGBA8ToRGBA32F, width, height, sourceElementsPerRow, destinationData, rowPackingFunc, destinationElementsPerPixel); 1461 break; 1462 } 1463 case GraphicsContext3D::SourceFormatBGRA8: { 1464 unsigned int sourceElementsPerRow = computeSourceElementsPerRow<uint8_t>(width, 4, sourceUnpackAlignment); 1465 doUnpackingAndPacking<uint8_t, float, float>(static_cast<const uint8_t*>(sourceData), unpackOneRowOfBGRA8ToRGBA32F, width, height, sourceElementsPerRow, destinationData, rowPackingFunc, destinationElementsPerPixel); 1466 break; 1467 } 1468 case GraphicsContext3D::SourceFormatRGBA32F: { 1370 1469 unsigned int sourceElementsPerRow = computeSourceElementsPerRow<float>(width, 4, sourceUnpackAlignment); 1371 1470 const float* source = static_cast<const float*>(sourceData); … … 1404 1503 } 1405 1504 1505 1506 #if !ASSERT_DISABLED 1507 static bool isFloatingPointSource(GraphicsContext3D::SourceDataFormat format) 1508 { 1509 switch (format) { 1510 case GraphicsContext3D::SourceFormatRGBA32F: 1511 case GraphicsContext3D::SourceFormatRGB32F: 1512 case GraphicsContext3D::SourceFormatRA32F: 1513 case GraphicsContext3D::SourceFormatR32F: 1514 case GraphicsContext3D::SourceFormatA32F: 1515 return true; 1516 default: 1517 return false; 1518 } 1519 } 1520 #endif 1521 1406 1522 bool GraphicsContext3D::packPixels(const uint8_t* sourceData, 1407 1523 GraphicsContext3D::SourceDataFormat sourceDataFormat, … … 1540 1656 case FLOAT: { 1541 1657 // OpenGL ES, and therefore WebGL, require that the format and 1542 // internalformat be identical, which implies that the source and 1543 // destination formats will both be floating-point in this branch -- at 1544 // least, until WebKit supports floating-point image formats natively. 1545 ASSERT(sourceDataFormat == SourceFormatRGBA32F || sourceDataFormat == SourceFormatRGB32F 1546 || sourceDataFormat == SourceFormatRA32F || sourceDataFormat == SourceFormatR32F 1547 || sourceDataFormat == SourceFormatA32F); 1548 // Because WebKit doesn't use floating-point color channels for anything 1549 // internally, there's no chance we have to do a (lossy) unmultiply 1550 // operation. 1551 ASSERT(alphaOp == AlphaDoNothing || alphaOp == AlphaDoPremultiply); 1658 // internalformat be identical. This means that whenever the 1659 // developer supplies an ArrayBufferView on this code path, 1660 // the source data will be in a floating-point format. 1661 // 1662 // The only time the source data will not be floating-point is 1663 // when uploading a DOM element or ImageData as a 1664 // floating-point texture. Only RGBA8 and BGRA8 are handled in 1665 // this case. 1666 ASSERT(isFloatingPointSource(sourceDataFormat) 1667 || sourceDataFormat == SourceFormatRGBA8 1668 || sourceDataFormat == SourceFormatBGRA8); 1669 // When uploading a canvas into a floating-point texture, 1670 // unmultiplication may be necessary. 1671 ASSERT((alphaOp == AlphaDoNothing || alphaOp == AlphaDoPremultiply) 1672 || !isFloatingPointSource(sourceDataFormat)); 1552 1673 // For the source formats with an even number of channels (RGBA32F, 1553 1674 // RA32F) it is guaranteed that the pixel data is tightly packed because … … 1571 1692 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGB32FPremultiply, 3); 1572 1693 break; 1573 default: 1574 ASSERT_NOT_REACHED(); 1694 case AlphaDoUnmultiply: 1695 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGB32FUnmultiply, 3); 1696 break; 1575 1697 } 1576 1698 break; 1577 1699 case RGBA: 1578 // AlphaDoNothing is handled above with fast path. 1579 ASSERT(alphaOp == AlphaDoPremultiply); 1580 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32FPremultiply, 4); 1700 // AlphaDoNothing for RGBA32F -> RGBA is handled above with fast path. 1701 ASSERT(alphaOp != AlphaDoNothing || sourceDataFormat != SourceFormatRGBA32F); 1702 switch (alphaOp) { 1703 case AlphaDoNothing: 1704 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32F, 4); 1705 break; 1706 case AlphaDoPremultiply: 1707 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32FPremultiply, 4); 1708 break; 1709 case AlphaDoUnmultiply: 1710 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32FUnmultiply, 4); 1711 break; 1712 } 1581 1713 break; 1582 1714 case ALPHA: … … 1597 1729 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToR32FPremultiply, 1); 1598 1730 break; 1599 default: 1600 ASSERT_NOT_REACHED(); 1731 case AlphaDoUnmultiply: 1732 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToR32FUnmultiply, 1); 1733 break; 1601 1734 } 1602 1735 break; … … 1612 1745 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRA32FPremultiply, 2); 1613 1746 break; 1614 default: 1615 ASSERT_NOT_REACHED(); 1747 case AlphaDoUnmultiply: 1748 doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRA32FUnmultiply, 2); 1749 break; 1616 1750 } 1617 1751 break; -
trunk/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
r115385 r117191 186 186 } 187 187 188 outputVector.resize(width * height * 4); 188 unsigned int packedSize; 189 // Output data is tightly packed (alignment == 1). 190 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR) 191 return false; 192 outputVector.resize(packedSize); 193 189 194 return packPixels(cairo_image_surface_get_data(imageSurface.get()), SourceFormatBGRA8, 190 195 width, height, srcUnpackAlignment, format, type, alphaOp, outputVector.data()); -
trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
r95901 r117191 241 241 return false; 242 242 const UInt8* rgba = CFDataGetBytePtr(pixelData.get()); 243 outputVector.resize(width * height * 4); 243 244 unsigned int packedSize; 245 // Output data is tightly packed (alignment == 1). 246 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR) 247 return false; 248 outputVector.resize(packedSize); 249 244 250 unsigned int srcUnpackAlignment = 0; 245 251 size_t bytesPerRow = CGImageGetBytesPerRow(cgImage); -
trunk/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
r113733 r117191 1615 1615 if (premultiplyAlpha) 1616 1616 neededAlphaOp = AlphaDoPremultiply; 1617 outputVector.resize(nativeImage.byteCount()); 1617 1618 unsigned int packedSize; 1619 // Output data is tightly packed (alignment == 1). 1620 if (computeImageSizeInBytes(format, type, image->width(), image->height(), 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR) 1621 return false; 1622 outputVector.resize(packedSize); 1623 1618 1624 return packPixels(nativeImage.bits(), SourceFormatBGRA8, image->width(), image->height(), 0, format, type, neededAlphaOp, outputVector.data()); 1619 1625 } -
trunk/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
r95901 r117191 80 80 SkAutoLockPixels lock(skiaImageRef); 81 81 ASSERT(skiaImageRef.rowBytes() == skiaImageRef.width() * 4); 82 outputVector.resize(skiaImageRef.rowBytes() * skiaImageRef.height()); 82 unsigned int packedSize; 83 // Output data is tightly packed (alignment == 1). 84 if (computeImageSizeInBytes(format, type, skiaImageRef.width(), skiaImageRef.height(), 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR) 85 return false; 86 outputVector.resize(packedSize); 83 87 return packPixels(reinterpret_cast<const uint8_t*>(skiaImageRef.getPixels()), 84 88 SK_B32_SHIFT ? SourceFormatRGBA8 : SourceFormatBGRA8,
Note: See TracChangeset
for help on using the changeset viewer.