WebGL: Move the format conversion for 16-bit per channel formats into Core Graphics...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Feb 2013 02:11:31 +0000 (02:11 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Feb 2013 02:11:31 +0000 (02:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=108304

Patch by Jun Jiang <jun.a.jiang@intel.com> on 2013-02-04
Reviewed by Kenneth Russell.

Since the 16-bit per channel formats are only used for Core Graphics port in WebGL and not a standard to represent any file format that is widely used
for each platform, it is better to limit and hide this kinds of information and processing in CG specific code only.
It can make the code more clear and reduce the binary size for both CG port and non-CG port.

Already covered by current tests.

* platform/graphics/GraphicsContext3D.cpp:
(WebCore):
* platform/graphics/GraphicsContext3D.h:
(GraphicsContext3D):
(WebCore::GraphicsContext3D::srcFormatComeFromDOMElementOrImageData):
(ImageExtractor):
* platform/graphics/cg/GraphicsContext3DCG.cpp:
(WebCore):
(WebCore::GraphicsContext3D::ImageExtractor::extractImage):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@141841 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GraphicsContext3D.cpp
Source/WebCore/platform/graphics/GraphicsContext3D.h
Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp

index b8e7e83..a4a4256 100644 (file)
@@ -1,3 +1,26 @@
+2013-02-04  Jun Jiang  <jun.a.jiang@intel.com>
+
+        WebGL: Move the format conversion for 16-bit per channel formats into Core Graphics port only
+        https://bugs.webkit.org/show_bug.cgi?id=108304
+
+        Reviewed by Kenneth Russell.
+
+        Since the 16-bit per channel formats are only used for Core Graphics port in WebGL and not a standard to represent any file format that is widely used 
+        for each platform, it is better to limit and hide this kinds of information and processing in CG specific code only. 
+        It can make the code more clear and reduce the binary size for both CG port and non-CG port.
+
+        Already covered by current tests.
+
+        * platform/graphics/GraphicsContext3D.cpp:
+        (WebCore):
+        * platform/graphics/GraphicsContext3D.h:
+        (GraphicsContext3D):
+        (WebCore::GraphicsContext3D::srcFormatComeFromDOMElementOrImageData):
+        (ImageExtractor):
+        * platform/graphics/cg/GraphicsContext3DCG.cpp:
+        (WebCore):
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage):
+
 2013-02-04  Dean Jackson  <dino@apple.com>
 
         Allow TextTracks to be marked as closed captions
index 7db3fde..0bf0a9c 100644 (file)
@@ -47,16 +47,6 @@ namespace WebCore {
 
 namespace {
 
-uint8_t convertColor16LittleTo8(uint16_t value)
-{
-    return value >> 8;
-}
-
-uint8_t convertColor16BigTo8(uint16_t value)
-{
-    return static_cast<uint8_t>(value & 0x00FF);
-}
-
 GraphicsContext3D::DataFormat getDataFormat(GC3Denum destinationFormat, GC3Denum destinationType)
 {
     GraphicsContext3D::DataFormat dstFormat = GraphicsContext3D::DataFormatRGBA8;
@@ -331,33 +321,6 @@ ALWAYS_INLINE void unpack(const SourceType*, DstType*, unsigned)
     ASSERT_NOT_REACHED();
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGBA16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-#if HAVE(ARM_NEON_INTRINSICS)
-    SIMD::unpackOneRowOfRGBA16LittleToRGBA8(source, destination, pixelsPerRow);
-#endif
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16LittleTo8(source[0]);
-        destination[1] = convertColor16LittleTo8(source[1]);
-        destination[2] = convertColor16LittleTo8(source[2]);
-        destination[3] = convertColor16LittleTo8(source[3]);
-        source += 4;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGBA16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16BigTo8(source[0]);
-        destination[1] = convertColor16BigTo8(source[1]);
-        destination[2] = convertColor16BigTo8(source[2]);
-        destination[3] = convertColor16BigTo8(source[3]);
-        source += 4;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
 {
     for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -370,33 +333,6 @@ template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t,
     }
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGB16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-#if HAVE(ARM_NEON_INTRINSICS)
-    SIMD::unpackOneRowOfRGB16LittleToRGBA8(source, destination, pixelsPerRow);
-#endif
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16LittleTo8(source[0]);
-        destination[1] = convertColor16LittleTo8(source[1]);
-        destination[2] = convertColor16LittleTo8(source[2]);
-        destination[3] = 0xFF;
-        source += 3;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGB16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16BigTo8(source[0]);
-        destination[1] = convertColor16BigTo8(source[1]);
-        destination[2] = convertColor16BigTo8(source[2]);
-        destination[3] = 0xFF;
-        source += 3;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatBGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
 {
     for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -421,33 +357,6 @@ template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatARGB8, uint8_t
     }
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatARGB16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-#if HAVE(ARM_NEON_INTRINSICS)
-    SIMD::unpackOneRowOfARGB16LittleToRGBA8(source, destination, pixelsPerRow);
-#endif
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16LittleTo8(source[1]);
-        destination[1] = convertColor16LittleTo8(source[2]);
-        destination[2] = convertColor16LittleTo8(source[3]);
-        destination[3] = convertColor16LittleTo8(source[0]);
-        source += 4;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatARGB16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16BigTo8(source[1]);
-        destination[1] = convertColor16BigTo8(source[2]);
-        destination[2] = convertColor16BigTo8(source[3]);
-        destination[3] = convertColor16BigTo8(source[0]);
-        source += 4;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatABGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
 {
     for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -478,33 +387,6 @@ template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatBGRA8, uint8_t
     }
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatBGRA16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-#if HAVE(ARM_NEON_INTRINSICS)
-    SIMD::unpackOneRowOfBGRA16LittleToRGBA8(source, destination, pixelsPerRow);
-#endif
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16LittleTo8(source[2]);
-        destination[1] = convertColor16LittleTo8(source[1]);
-        destination[2] = convertColor16LittleTo8(source[0]);
-        destination[3] = convertColor16LittleTo8(source[3]);
-        source += 4;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatBGRA16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16BigTo8(source[2]);
-        destination[1] = convertColor16BigTo8(source[1]);
-        destination[2] = convertColor16BigTo8(source[0]);
-        destination[3] = convertColor16BigTo8(source[3]);
-        source += 4;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGBA5551, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
 {
 #if HAVE(ARM_NEON_INTRINSICS)
@@ -575,30 +457,6 @@ template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatR8, uint8_t, u
     }
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatR16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16LittleTo8(source[0]);
-        destination[1] = convertColor16LittleTo8(source[0]);
-        destination[2] = convertColor16LittleTo8(source[0]);
-        destination[3] = 0xFF;
-        source += 1;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatR16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16BigTo8(source[0]);
-        destination[1] = convertColor16BigTo8(source[0]);
-        destination[2] = convertColor16BigTo8(source[0]);
-        destination[3] = 0xFF;
-        source += 1;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
 {
     for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -611,30 +469,6 @@ template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRA8, uint8_t,
     }
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRA16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16LittleTo8(source[0]);
-        destination[1] = convertColor16LittleTo8(source[0]);
-        destination[2] = convertColor16LittleTo8(source[0]);
-        destination[3] = convertColor16LittleTo8(source[1]);
-        source += 2;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRA16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16BigTo8(source[0]);
-        destination[1] = convertColor16BigTo8(source[0]);
-        destination[2] = convertColor16BigTo8(source[0]);
-        destination[3] = convertColor16BigTo8(source[1]);
-        source += 2;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatAR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
 {
     for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -647,30 +481,6 @@ template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatAR8, uint8_t,
     }
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatAR16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16LittleTo8(source[1]);
-        destination[1] = convertColor16LittleTo8(source[1]);
-        destination[2] = convertColor16LittleTo8(source[1]);
-        destination[3] = convertColor16LittleTo8(source[0]);
-        source += 2;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatAR16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = convertColor16BigTo8(source[1]);
-        destination[1] = convertColor16BigTo8(source[1]);
-        destination[2] = convertColor16BigTo8(source[1]);
-        destination[3] = convertColor16BigTo8(source[0]);
-        source += 2;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
 {
     for (unsigned int i = 0; i < pixelsPerRow; ++i) {
@@ -683,30 +493,6 @@ template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatA8, uint8_t, u
     }
 }
 
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatA16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = 0x0;
-        destination[1] = 0x0;
-        destination[2] = 0x0;
-        destination[3] = convertColor16LittleTo8(source[0]);
-        source += 1;
-        destination += 4;
-    }
-}
-
-template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatA16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
-{
-    for (unsigned int i = 0; i < pixelsPerRow; ++i) {
-        destination[0] = 0x0;
-        destination[1] = 0x0;
-        destination[2] = 0x0;
-        destination[3] = convertColor16BigTo8(source[0]);
-        source += 1;
-        destination += 4;
-    }
-}
-
 template<> ALWAYS_INLINE void unpack<GraphicsContext3D::DataFormatRGBA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
 {
     const float scaleFactor = 1.0f / 255.0f;
@@ -1229,25 +1015,13 @@ template<> ALWAYS_INLINE void pack<GraphicsContext3D::DataFormatRA32F, GraphicsC
 ALWAYS_INLINE bool HasAlpha(int format)
 {
     return format == GraphicsContext3D::DataFormatA8
-        || format == GraphicsContext3D::DataFormatA16Little
-        || format == GraphicsContext3D::DataFormatA16Big
         || format == GraphicsContext3D::DataFormatA32F
         || format == GraphicsContext3D::DataFormatRA8
         || format == GraphicsContext3D::DataFormatAR8
-        || format == GraphicsContext3D::DataFormatRA16Little
-        || format == GraphicsContext3D::DataFormatRA16Big
-        || format == GraphicsContext3D::DataFormatAR16Little
-        || format == GraphicsContext3D::DataFormatAR16Big
         || format == GraphicsContext3D::DataFormatRA32F
         || format == GraphicsContext3D::DataFormatRGBA8
-        || format == GraphicsContext3D::DataFormatRGBA16Little
-        || format == GraphicsContext3D::DataFormatRGBA16Big
         || format == GraphicsContext3D::DataFormatBGRA8
-        || format == GraphicsContext3D::DataFormatBGRA16Little
-        || format == GraphicsContext3D::DataFormatBGRA16Big
         || format == GraphicsContext3D::DataFormatARGB8
-        || format == GraphicsContext3D::DataFormatARGB16Little
-        || format == GraphicsContext3D::DataFormatARGB16Big
         || format == GraphicsContext3D::DataFormatABGR8
         || format == GraphicsContext3D::DataFormatRGBA32F
         || format == GraphicsContext3D::DataFormatRGBA4444
@@ -1257,35 +1031,21 @@ ALWAYS_INLINE bool HasAlpha(int format)
 ALWAYS_INLINE bool HasColor(int format)
 {
     return format == GraphicsContext3D::DataFormatRGBA8
-        || format == GraphicsContext3D::DataFormatRGBA16Little
-        || format == GraphicsContext3D::DataFormatRGBA16Big
         || format == GraphicsContext3D::DataFormatRGBA32F
         || format == GraphicsContext3D::DataFormatRGB8
-        || format == GraphicsContext3D::DataFormatRGB16Little
-        || format == GraphicsContext3D::DataFormatRGB16Big
         || format == GraphicsContext3D::DataFormatRGB32F
         || format == GraphicsContext3D::DataFormatBGR8
         || format == GraphicsContext3D::DataFormatBGRA8
-        || format == GraphicsContext3D::DataFormatBGRA16Little
-        || format == GraphicsContext3D::DataFormatBGRA16Big
         || format == GraphicsContext3D::DataFormatARGB8
-        || format == GraphicsContext3D::DataFormatARGB16Little
-        || format == GraphicsContext3D::DataFormatARGB16Big
         || format == GraphicsContext3D::DataFormatABGR8
         || format == GraphicsContext3D::DataFormatRGBA5551
         || format == GraphicsContext3D::DataFormatRGBA4444
         || format == GraphicsContext3D::DataFormatRGB565
         || format == GraphicsContext3D::DataFormatR8
-        || format == GraphicsContext3D::DataFormatR16Little
-        || format == GraphicsContext3D::DataFormatR16Big
         || format == GraphicsContext3D::DataFormatR32F
         || format == GraphicsContext3D::DataFormatRA8
-        || format == GraphicsContext3D::DataFormatRA16Little
-        || format == GraphicsContext3D::DataFormatRA16Big
         || format == GraphicsContext3D::DataFormatRA32F
-        || format == GraphicsContext3D::DataFormatAR8
-        || format == GraphicsContext3D::DataFormatAR16Little
-        || format == GraphicsContext3D::DataFormatAR16Big;
+        || format == GraphicsContext3D::DataFormatAR8;
 }
 
 template<int Format>
@@ -1301,25 +1061,9 @@ struct IsFloatFormat {
 template<int Format>
 struct Is16bppFormat {
     static const bool Value =
-        Format == GraphicsContext3D::DataFormatRGBA16Little
-        || Format == GraphicsContext3D::DataFormatRGBA16Big
-        || Format == GraphicsContext3D::DataFormatRGB16Little
-        || Format == GraphicsContext3D::DataFormatRGB16Big
-        || Format == GraphicsContext3D::DataFormatBGRA16Little
-        || Format == GraphicsContext3D::DataFormatBGRA16Big
-        || Format == GraphicsContext3D::DataFormatARGB16Little
-        || Format == GraphicsContext3D::DataFormatARGB16Big
-        || Format == GraphicsContext3D::DataFormatRGBA5551
+        Format == GraphicsContext3D::DataFormatRGBA5551
         || Format == GraphicsContext3D::DataFormatRGBA4444
-        || Format == GraphicsContext3D::DataFormatRGB565
-        || Format == GraphicsContext3D::DataFormatR16Little
-        || Format == GraphicsContext3D::DataFormatR16Big
-        || Format == GraphicsContext3D::DataFormatRA16Little
-        || Format == GraphicsContext3D::DataFormatRA16Big
-        || Format == GraphicsContext3D::DataFormatAR16Little
-        || Format == GraphicsContext3D::DataFormatAR16Big
-        || Format == GraphicsContext3D::DataFormatA16Little
-        || Format == GraphicsContext3D::DataFormatA16Big;
+        || Format == GraphicsContext3D::DataFormatRGB565;
 };
 
 template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Value>
@@ -1353,10 +1097,6 @@ ALWAYS_INLINE unsigned TexelBytesForFormat(GraphicsContext3D::DataFormat format)
     case GraphicsContext3D::DataFormatRGBA5551:
     case GraphicsContext3D::DataFormatRGBA4444:
     case GraphicsContext3D::DataFormatRGB565:
-    case GraphicsContext3D::DataFormatR16Little:
-    case GraphicsContext3D::DataFormatR16Big:
-    case GraphicsContext3D::DataFormatA16Little:
-    case GraphicsContext3D::DataFormatA16Big:
         return 2;
     case GraphicsContext3D::DataFormatRGB8:
     case GraphicsContext3D::DataFormatBGR8:
@@ -1364,24 +1104,11 @@ ALWAYS_INLINE unsigned TexelBytesForFormat(GraphicsContext3D::DataFormat format)
     case GraphicsContext3D::DataFormatRGBA8:
     case GraphicsContext3D::DataFormatARGB8:
     case GraphicsContext3D::DataFormatABGR8:
-    case GraphicsContext3D::DataFormatRA16Little:
-    case GraphicsContext3D::DataFormatRA16Big:
     case GraphicsContext3D::DataFormatBGRA8:
     case GraphicsContext3D::DataFormatR32F:
     case GraphicsContext3D::DataFormatA32F:
-    case GraphicsContext3D::DataFormatAR16Little:
-    case GraphicsContext3D::DataFormatAR16Big:
         return 4;
-    case GraphicsContext3D::DataFormatRGB16Little:
-    case GraphicsContext3D::DataFormatRGB16Big:
-        return 6;
     case GraphicsContext3D::DataFormatRA32F:
-    case GraphicsContext3D::DataFormatRGBA16Little:
-    case GraphicsContext3D::DataFormatRGBA16Big:
-    case GraphicsContext3D::DataFormatBGRA16Little:
-    case GraphicsContext3D::DataFormatBGRA16Big:
-    case GraphicsContext3D::DataFormatARGB16Little:
-    case GraphicsContext3D::DataFormatARGB16Big:
         return 8;
     case GraphicsContext3D::DataFormatRGB32F:
         return 12;
@@ -1402,8 +1129,8 @@ public:
     {
         const unsigned MaxNumberOfComponents = 4;
         const unsigned MaxBytesPerComponent  = 4;
-        unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxNumberOfComponents *MaxBytesPerComponent]);
-        ASSERT(unpackedIntermediateSrcData.get());
+        m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxNumberOfComponents *MaxBytesPerComponent]);
+        ASSERT(m_unpackedIntermediateSrcData.get());
     }
 
     void convert(GraphicsContext3D::DataFormat srcFormat, GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp);
@@ -1424,7 +1151,7 @@ private:
     void* const m_dstStart;
     const int m_srcStride, m_dstStride;
     bool m_success;
-    OwnArrayPtr<uint8_t> unpackedIntermediateSrcData;
+    OwnArrayPtr<uint8_t> m_unpackedIntermediateSrcData;
 };
 
 void FormatConverter::convert(GraphicsContext3D::DataFormat srcFormat, GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp alphaOp)
@@ -1445,25 +1172,9 @@ void FormatConverter::convert(GraphicsContext3D::DataFormat srcFormat, GraphicsC
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB565)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB32F)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA8)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA16Big)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB16Big)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatBGRA16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatBGRA16Big)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatARGB8)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatARGB16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatARGB16Big)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatABGR8)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatAR8)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatR16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatR16Big)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRA16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRA16Big)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatAR16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatAR16Big)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatA16Little)
-            FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatA16Big)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatBGRA8)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA5551)
             FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA4444)
@@ -1573,8 +1284,8 @@ ALWAYS_INLINE void FormatConverter::convert()
         }
     } else if (!trivialUnpack && !trivialPack) {
         for (size_t i = 0; i < m_height; ++i) {
-            unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType*>(unpackedIntermediateSrcData.get()), m_width);
-            pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(unpackedIntermediateSrcData.get()), dstRowStart, m_width);
+            unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType*>(m_unpackedIntermediateSrcData.get()), m_width);
+            pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(m_unpackedIntermediateSrcData.get()), dstRowStart, m_width);
             srcRowStart += srcStrideInElements;
             dstRowStart += dstStrideInElements;
         }
index 0f8d379..aede4fd 100644 (file)
@@ -34,6 +34,8 @@
 #include <wtf/HashMap.h>
 #include <wtf/ListHashSet.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassOwnArrayPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
@@ -591,12 +593,6 @@ public:
                             const void* pixels,
                             Vector<uint8_t>& data);
 
-    // Flips the given image data vertically, in-place.
-    static void flipVertically(void* imageData,
-                        unsigned int width,
-                        unsigned int height,
-                        unsigned int bytesPerPixel,
-                        unsigned int unpackAlignment);
 
     // Attempt to enumerate all possible native image formats to
     // reduce the amount of temporary allocations during texture
@@ -642,19 +638,17 @@ public:
 
     // Check if the format is one of the formats from the ImageData or DOM elements.
     // The formats from ImageData is always RGBA8.
-    // The formats from DOM elements vary with Graphics ports. It can only be RGBA8 or BGRA8 for non-CG port while much more for CG port.
+    // The formats from DOM elements vary with Graphics ports. It can only be RGBA8 or BGRA8 for non-CG port while a little more for CG port.
     static ALWAYS_INLINE bool srcFormatComeFromDOMElementOrImageData(DataFormat SrcFormat)
     {
 #if USE(CG)
 #if CPU(BIG_ENDIAN)
-    return SrcFormat == DataFormatRGBA8 || SrcFormat == DataFormatRGBA16Big
-        || SrcFormat == DataFormatARGB8 || SrcFormat == DataFormatARGB16Big
-        || SrcFormat == DataFormatRGB8 || SrcFormat == DataFormatRGB16Big;
+    return SrcFormat == DataFormatRGBA8 || SrcFormat == DataFormatARGB8 || SrcFormat == DataFormatRGB8;
 #else
-    return SrcFormat == DataFormatBGRA8 || SrcFormat == DataFormatARGB16Little
-        || SrcFormat == DataFormatABGR8 || SrcFormat == DataFormatRGBA16Little
-        || SrcFormat == DataFormatBGR8 || SrcFormat == DataFormatRGB16Little
-        || SrcFormat == DataFormatRGBA8 || SrcFormat == DataFormatRGB8;
+    // That LITTLE_ENDIAN case has more possible formats than BIG_ENDIAN case is because some decoded image data is actually big endian
+    // even on little endian architectures.
+    return SrcFormat == DataFormatBGRA8 || SrcFormat == DataFormatABGR8 || SrcFormat == DataFormatBGR8
+        || SrcFormat == DataFormatRGBA8 || SrcFormat == DataFormatARGB8 || SrcFormat == DataFormatRGB8;
 #endif
 #else
     return SrcFormat == DataFormatBGRA8 || SrcFormat == DataFormatRGBA8;
@@ -937,6 +931,7 @@ public:
         CGImageRef m_cgImage;
         RetainPtr<CGImageRef> m_decodedImage;
         RetainPtr<CFDataRef> m_pixelData;
+        OwnArrayPtr<uint8_t> m_formalizedRGBA8Data;
 #elif PLATFORM(QT)
         QImage m_qtImage;
 #endif
index f6eb973..8a485ee 100644 (file)
@@ -31,6 +31,7 @@
 #include "GraphicsContext3D.h"
 
 #include "BitmapImage.h"
+#include "GraphicsContext3DNEON.h"
 #include "GraphicsContextCG.h"
 #include "Image.h"
 
@@ -89,6 +90,229 @@ static GraphicsContext3D::DataFormat getSourceDataFormat(unsigned componentsPerP
     return formatTable[formatBase][(is16BitFormat ? 2 : 0) + (bigEndian ? 1 : 0)];
 }
 
+namespace {
+uint8_t convertColor16LittleTo8(uint16_t value)
+{
+    return value >> 8;
+}
+
+uint8_t convertColor16BigTo8(uint16_t value)
+{
+    return static_cast<uint8_t>(value & 0x00FF);
+}
+
+template<int format, typename SourceType, typename DstType>
+ALWAYS_INLINE void convert16BitFormatToRGBA8(const SourceType*, DstType*, unsigned)
+{
+    ASSERT_NOT_REACHED();
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatRGBA16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+#if HAVE(ARM_NEON_INTRINSICS)
+    SIMD::unpackOneRowOfRGBA16LittleToRGBA8(source, destination, pixelsPerRow);
+#endif
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16LittleTo8(source[0]);
+        destination[1] = convertColor16LittleTo8(source[1]);
+        destination[2] = convertColor16LittleTo8(source[2]);
+        destination[3] = convertColor16LittleTo8(source[3]);
+        source += 4;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatRGBA16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16BigTo8(source[0]);
+        destination[1] = convertColor16BigTo8(source[1]);
+        destination[2] = convertColor16BigTo8(source[2]);
+        destination[3] = convertColor16BigTo8(source[3]);
+        source += 4;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatRGB16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+#if HAVE(ARM_NEON_INTRINSICS)
+    SIMD::unpackOneRowOfRGB16LittleToRGBA8(source, destination, pixelsPerRow);
+#endif
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16LittleTo8(source[0]);
+        destination[1] = convertColor16LittleTo8(source[1]);
+        destination[2] = convertColor16LittleTo8(source[2]);
+        destination[3] = 0xFF;
+        source += 3;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatRGB16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16BigTo8(source[0]);
+        destination[1] = convertColor16BigTo8(source[1]);
+        destination[2] = convertColor16BigTo8(source[2]);
+        destination[3] = 0xFF;
+        source += 3;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatARGB16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+#if HAVE(ARM_NEON_INTRINSICS)
+    SIMD::unpackOneRowOfARGB16LittleToRGBA8(source, destination, pixelsPerRow);
+#endif
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16LittleTo8(source[1]);
+        destination[1] = convertColor16LittleTo8(source[2]);
+        destination[2] = convertColor16LittleTo8(source[3]);
+        destination[3] = convertColor16LittleTo8(source[0]);
+        source += 4;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatARGB16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16BigTo8(source[1]);
+        destination[1] = convertColor16BigTo8(source[2]);
+        destination[2] = convertColor16BigTo8(source[3]);
+        destination[3] = convertColor16BigTo8(source[0]);
+        source += 4;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatR16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16LittleTo8(source[0]);
+        destination[1] = convertColor16LittleTo8(source[0]);
+        destination[2] = convertColor16LittleTo8(source[0]);
+        destination[3] = 0xFF;
+        source += 1;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatR16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16BigTo8(source[0]);
+        destination[1] = convertColor16BigTo8(source[0]);
+        destination[2] = convertColor16BigTo8(source[0]);
+        destination[3] = 0xFF;
+        source += 1;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatRA16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16LittleTo8(source[0]);
+        destination[1] = convertColor16LittleTo8(source[0]);
+        destination[2] = convertColor16LittleTo8(source[0]);
+        destination[3] = convertColor16LittleTo8(source[1]);
+        source += 2;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatRA16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16BigTo8(source[0]);
+        destination[1] = convertColor16BigTo8(source[0]);
+        destination[2] = convertColor16BigTo8(source[0]);
+        destination[3] = convertColor16BigTo8(source[1]);
+        source += 2;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatAR16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16LittleTo8(source[1]);
+        destination[1] = convertColor16LittleTo8(source[1]);
+        destination[2] = convertColor16LittleTo8(source[1]);
+        destination[3] = convertColor16LittleTo8(source[0]);
+        source += 2;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatAR16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = convertColor16BigTo8(source[1]);
+        destination[1] = convertColor16BigTo8(source[1]);
+        destination[2] = convertColor16BigTo8(source[1]);
+        destination[3] = convertColor16BigTo8(source[0]);
+        source += 2;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatA16Little, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = 0x0;
+        destination[1] = 0x0;
+        destination[2] = 0x0;
+        destination[3] = convertColor16LittleTo8(source[0]);
+        source += 1;
+        destination += 4;
+    }
+}
+
+template<> ALWAYS_INLINE void convert16BitFormatToRGBA8<GraphicsContext3D::DataFormatA16Big, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+    for (unsigned i = 0; i < pixelsPerRow; ++i) {
+        destination[0] = 0x0;
+        destination[1] = 0x0;
+        destination[2] = 0x0;
+        destination[3] = convertColor16BigTo8(source[0]);
+        source += 1;
+        destination += 4;
+    }
+}
+
+void convert16BitFormatToRGBA8(GraphicsContext3D::DataFormat srcFormat, const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
+{
+#define CONVERT16BITFORMATTORGBA8(SrcFormat) \
+    case SrcFormat: \
+        return convert16BitFormatToRGBA8<SrcFormat>(source, destination, pixelsPerRow);
+
+    switch (srcFormat) {
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatR16Little)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatR16Big)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatA16Little)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatA16Big)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatRA16Little)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatRA16Big)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatAR16Little)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatAR16Big)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatRGB16Little)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatRGB16Big)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatRGBA16Little)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatRGBA16Big)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatARGB16Little)
+        CONVERT16BITFORMATTORGBA8(GraphicsContext3D::DataFormatARGB16Big)
+    default:
+        ASSERT_NOT_REACHED();
+    }
+#undef CONVERT16BITFORMATTORGBA8
+}
+
+}
+
 GraphicsContext3D::ImageExtractor::~ImageExtractor()
 {
 }
@@ -249,7 +473,24 @@ bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool
     }
 
     m_imageSourceUnpackAlignment = srcUnpackAlignment;
-
+    // Using a bitmap context created according to destination format and drawing the CGImage to the bitmap context can also do the format conversion,
+    // but it would premultiply the alpha channel as a side effect.
+    // Prefer to mannually Convert 16bit per-component formats to RGBA8 formats instead.
+    if (bitsPerComponent == 16) {
+        m_formalizedRGBA8Data = adoptArrayPtr(new uint8_t[m_imageWidth * m_imageHeight * 4]);
+        const uint16_t* source = reinterpret_cast<const uint16_t*>(m_imagePixelData);
+        uint8_t* destination = m_formalizedRGBA8Data.get();
+        const ptrdiff_t srcStrideInElements = bytesPerRow / sizeof(uint16_t);
+        const ptrdiff_t dstStrideInElements = 4 * m_imageWidth;
+        for (unsigned i =0; i < m_imageHeight; i++) {
+            convert16BitFormatToRGBA8(m_imageSourceFormat, source, destination, m_imageWidth);
+            source += srcStrideInElements;
+            destination += dstStrideInElements;
+        }
+        m_imagePixelData = reinterpret_cast<const void*>(m_formalizedRGBA8Data.get());
+        m_imageSourceFormat = DataFormatRGBA8;
+        m_imageSourceUnpackAlignment = 1;
+    }
     return true;
 }