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

Unified Diff: Source/WebCore/platform/graphics/GraphicsContext3D.cpp

Issue 10444013: Merge 117191 - Assertion failure running Mozilla's WebGL performance regression tests (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1132/
Patch Set: Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/WebCore/platform/graphics/GraphicsContext3D.cpp
===================================================================
--- Source/WebCore/platform/graphics/GraphicsContext3D.cpp (revision 118409)
+++ Source/WebCore/platform/graphics/GraphicsContext3D.cpp (working copy)
@@ -200,8 +200,13 @@
return false;
int width = imageData->width();
int height = imageData->height();
- int dataBytes = width * height * 4;
- data.resize(dataBytes);
+
+ unsigned int packedSize;
+ // Output data is tightly packed (alignment == 1).
+ if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
+ return false;
+ data.resize(packedSize);
+
if (!packPixels(imageData->data()->data(),
SourceFormatRGBA8,
width,
@@ -704,6 +709,32 @@
}
}
+void unpackOneRowOfRGBA8ToRGBA32F(const uint8_t* source, float* destination, unsigned int pixelsPerRow)
+{
+ const float scaleFactor = 1.0f / 255.0f;
+ for (unsigned int i = 0; i < pixelsPerRow; ++i) {
+ destination[0] = source[0] * scaleFactor;
+ destination[1] = source[1] * scaleFactor;
+ destination[2] = source[2] * scaleFactor;
+ destination[3] = source[3] * scaleFactor;
+ source += 4;
+ destination += 4;
+ }
+}
+
+void unpackOneRowOfBGRA8ToRGBA32F(const uint8_t* source, float* destination, unsigned int pixelsPerRow)
+{
+ const float scaleFactor = 1.0f / 255.0f;
+ for (unsigned int i = 0; i < pixelsPerRow; ++i) {
+ destination[0] = source[2] * scaleFactor;
+ destination[1] = source[1] * scaleFactor;
+ destination[2] = source[0] * scaleFactor;
+ destination[3] = source[3] * scaleFactor;
+ source += 4;
+ destination += 4;
+ }
+}
+
void unpackOneRowOfRGB32FToRGBA32F(const float* source, float* destination, unsigned int pixelsPerRow)
{
for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -1062,6 +1093,31 @@
}
}
+void packOneRowOfRGBA32FToRGB32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow)
+{
+ for (unsigned int i = 0; i < pixelsPerRow; ++i) {
+ float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
+ destination[0] = source[0] * scaleFactor;
+ destination[1] = source[1] * scaleFactor;
+ destination[2] = source[2] * scaleFactor;
+ source += 4;
+ destination += 3;
+ }
+}
+
+// Used only during RGBA8 or BGRA8 -> floating-point uploads.
+void packOneRowOfRGBA32FToRGBA32F(const float* source, float* destination, unsigned int pixelsPerRow)
+{
+ for (unsigned int i = 0; i < pixelsPerRow; ++i) {
+ destination[0] = source[0];
+ destination[1] = source[1];
+ destination[2] = source[2];
+ destination[3] = source[3];
+ source += 4;
+ destination += 4;
+ }
+}
+
void packOneRowOfRGBA32FToRGBA32FPremultiply(const float* source, float* destination, unsigned int pixelsPerRow)
{
for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -1075,6 +1131,19 @@
}
}
+void packOneRowOfRGBA32FToRGBA32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow)
+{
+ for (unsigned int i = 0; i < pixelsPerRow; ++i) {
+ float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
+ destination[0] = source[0] * scaleFactor;
+ destination[1] = source[1] * scaleFactor;
+ destination[2] = source[2] * scaleFactor;
+ destination[3] = source[3];
+ source += 4;
+ destination += 4;
+ }
+}
+
void packOneRowOfRGBA32FToA32F(const float* source, float* destination, unsigned int pixelsPerRow)
{
for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -1103,6 +1172,15 @@
}
}
+void packOneRowOfRGBA32FToR32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow)
+{
+ for (unsigned int i = 0; i < pixelsPerRow; ++i) {
+ float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
+ destination[0] = source[0] * scaleFactor;
+ source += 4;
+ destination += 1;
+ }
+}
void packOneRowOfRGBA32FToRA32F(const float* source, float* destination, unsigned int pixelsPerRow)
{
@@ -1119,12 +1197,23 @@
for (unsigned int i = 0; i < pixelsPerRow; ++i) {
float scaleFactor = source[3];
destination[0] = source[0] * scaleFactor;
- destination[1] = scaleFactor;
+ destination[1] = source[3];
source += 4;
destination += 2;
}
}
+void packOneRowOfRGBA32FToRA32FUnmultiply(const float* source, float* destination, unsigned int pixelsPerRow)
+{
+ for (unsigned int i = 0; i < pixelsPerRow; ++i) {
+ float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
+ destination[0] = source[0] * scaleFactor;
+ destination[1] = source[3];
+ source += 4;
+ destination += 2;
+ }
+}
+
} // anonymous namespace
// This is used whenever unpacking is necessary; i.e., the source data
@@ -1367,6 +1456,16 @@
{
switch (sourceDataFormat) {
case GraphicsContext3D::SourceFormatRGBA8: {
+ unsigned int sourceElementsPerRow = computeSourceElementsPerRow<uint8_t>(width, 4, sourceUnpackAlignment);
+ doUnpackingAndPacking<uint8_t, float, float>(static_cast<const uint8_t*>(sourceData), unpackOneRowOfRGBA8ToRGBA32F, width, height, sourceElementsPerRow, destinationData, rowPackingFunc, destinationElementsPerPixel);
+ break;
+ }
+ case GraphicsContext3D::SourceFormatBGRA8: {
+ unsigned int sourceElementsPerRow = computeSourceElementsPerRow<uint8_t>(width, 4, sourceUnpackAlignment);
+ doUnpackingAndPacking<uint8_t, float, float>(static_cast<const uint8_t*>(sourceData), unpackOneRowOfBGRA8ToRGBA32F, width, height, sourceElementsPerRow, destinationData, rowPackingFunc, destinationElementsPerPixel);
+ break;
+ }
+ case GraphicsContext3D::SourceFormatRGBA32F: {
unsigned int sourceElementsPerRow = computeSourceElementsPerRow<float>(width, 4, sourceUnpackAlignment);
const float* source = static_cast<const float*>(sourceData);
const float* endPointer = source + height * sourceElementsPerRow;
@@ -1403,6 +1502,23 @@
}
}
+
+#if !ASSERT_DISABLED
+static bool isFloatingPointSource(GraphicsContext3D::SourceDataFormat format)
+{
+ switch (format) {
+ case GraphicsContext3D::SourceFormatRGBA32F:
+ case GraphicsContext3D::SourceFormatRGB32F:
+ case GraphicsContext3D::SourceFormatRA32F:
+ case GraphicsContext3D::SourceFormatR32F:
+ case GraphicsContext3D::SourceFormatA32F:
+ return true;
+ default:
+ return false;
+ }
+}
+#endif
+
bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
GraphicsContext3D::SourceDataFormat sourceDataFormat,
unsigned int width,
@@ -1539,16 +1655,21 @@
}
case FLOAT: {
// OpenGL ES, and therefore WebGL, require that the format and
- // internalformat be identical, which implies that the source and
- // destination formats will both be floating-point in this branch -- at
- // least, until WebKit supports floating-point image formats natively.
- ASSERT(sourceDataFormat == SourceFormatRGBA32F || sourceDataFormat == SourceFormatRGB32F
- || sourceDataFormat == SourceFormatRA32F || sourceDataFormat == SourceFormatR32F
- || sourceDataFormat == SourceFormatA32F);
- // Because WebKit doesn't use floating-point color channels for anything
- // internally, there's no chance we have to do a (lossy) unmultiply
- // operation.
- ASSERT(alphaOp == AlphaDoNothing || alphaOp == AlphaDoPremultiply);
+ // internalformat be identical. This means that whenever the
+ // developer supplies an ArrayBufferView on this code path,
+ // the source data will be in a floating-point format.
+ //
+ // The only time the source data will not be floating-point is
+ // when uploading a DOM element or ImageData as a
+ // floating-point texture. Only RGBA8 and BGRA8 are handled in
+ // this case.
+ ASSERT(isFloatingPointSource(sourceDataFormat)
+ || sourceDataFormat == SourceFormatRGBA8
+ || sourceDataFormat == SourceFormatBGRA8);
+ // When uploading a canvas into a floating-point texture,
+ // unmultiplication may be necessary.
+ ASSERT((alphaOp == AlphaDoNothing || alphaOp == AlphaDoPremultiply)
+ || !isFloatingPointSource(sourceDataFormat));
// For the source formats with an even number of channels (RGBA32F,
// RA32F) it is guaranteed that the pixel data is tightly packed because
// unpack alignment <= sizeof(float) * number of channels.
@@ -1570,14 +1691,25 @@
case AlphaDoPremultiply:
doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGB32FPremultiply, 3);
break;
- default:
- ASSERT_NOT_REACHED();
+ case AlphaDoUnmultiply:
+ doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGB32FUnmultiply, 3);
+ break;
}
break;
case RGBA:
- // AlphaDoNothing is handled above with fast path.
- ASSERT(alphaOp == AlphaDoPremultiply);
- doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32FPremultiply, 4);
+ // AlphaDoNothing for RGBA32F -> RGBA is handled above with fast path.
+ ASSERT(alphaOp != AlphaDoNothing || sourceDataFormat != SourceFormatRGBA32F);
+ switch (alphaOp) {
+ case AlphaDoNothing:
+ doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32F, 4);
+ break;
+ case AlphaDoPremultiply:
+ doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32FPremultiply, 4);
+ break;
+ case AlphaDoUnmultiply:
+ doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRGBA32FUnmultiply, 4);
+ break;
+ }
break;
case ALPHA:
// From the desktop OpenGL conversion rules (OpenGL 2.1
@@ -1596,8 +1728,9 @@
case AlphaDoPremultiply:
doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToR32FPremultiply, 1);
break;
- default:
- ASSERT_NOT_REACHED();
+ case AlphaDoUnmultiply:
+ doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToR32FUnmultiply, 1);
+ break;
}
break;
case LUMINANCE_ALPHA:
@@ -1611,8 +1744,9 @@
case AlphaDoPremultiply:
doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRA32FPremultiply, 2);
break;
- default:
- ASSERT_NOT_REACHED();
+ case AlphaDoUnmultiply:
+ doFloatingPointPacking(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, packOneRowOfRGBA32FToRA32FUnmultiply, 2);
+ break;
}
break;
}
« no previous file with comments | « no previous file | Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698