Bug 998742 - Switch to MOZ_LITTLE_ENDIAN, and assert correctness. - r=bjacob
authorJeff Gilbert <jgilbert@mozilla.com>
Fri, 25 Apr 2014 17:35:36 -0700
changeset 199927 3d0432bbcb8f1d88f3b0d514d6c8e410fa622c0e
parent 199926 d1b899e683c2b31a1cbe46da8f96525bf7884c8a
child 199928 83c0c0d2436d20205eacc9aece839adf491254ad
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs998742
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 998742 - Switch to MOZ_LITTLE_ENDIAN, and assert correctness. - r=bjacob
gfx/layers/LayerUtils.cpp
--- a/gfx/layers/LayerUtils.cpp
+++ b/gfx/layers/LayerUtils.cpp
@@ -1,29 +1,48 @@
 /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "LayerUtils.h"
 #include "PremultiplyTables.h"
+#include "mozilla/Endian.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 static inline const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
   return PremultiplyTable[a*256+v];
 }
 
 static inline const uint8_t UnpremultiplyValue(uint8_t a, uint8_t v) {
   return UnpremultiplyTable[a*256+v];
 }
 
+#ifdef DEBUG
+static bool IsLittleEndian()
+{
+    // Violate strict aliasing, because violating strict aliasing is how
+    // we always pack and unpack between uint32_t and uint8_t[].
+    uint16_t testShort;
+    static const uint8_t testBytes[2] = { 0xAA, 0xBB };
+    memcpy(&testShort, testBytes, sizeof(testBytes));
+    return testShort == 0xBBAA;
+}
+#endif // DEBUG
+
+#ifdef MOZ_LITTLE_ENDIAN
+#define ASSERT_ENDIAN() MOZ_ASSERT(IsLittleEndian(), "Defined as little endian, but actually big!")
+#else
+#define ASSERT_ENDIAN() MOZ_ASSERT(!IsLittleEndian(), "Defined as big endian, but actually little!")
+#endif
+
 void
 PremultiplySurface(DataSourceSurface* srcSurface,
                    DataSourceSurface* destSurface)
 {
   if (!destSurface)
     destSurface = srcSurface;
 
   IntSize srcSize = srcSurface->GetSize();
@@ -43,19 +62,22 @@ PremultiplySurface(DataSourceSurface* sr
              srcSurface->Stride() * srcSize.height);
     }
     return;
   }
 
   uint8_t *src = srcSurface->GetData();
   uint8_t *dst = destSurface->GetData();
 
+  // Assert that our endian define is correct.
+  ASSERT_ENDIAN();
+
   uint32_t dim = srcSize.width * srcSize.height;
   for (uint32_t i = 0; i < dim; ++i) {
-#ifdef IS_LITTLE_ENDIAN
+#ifdef MOZ_LITTLE_ENDIAN
     uint8_t b = *src++;
     uint8_t g = *src++;
     uint8_t r = *src++;
     uint8_t a = *src++;
 
     *dst++ = PremultiplyValue(a, b);
     *dst++ = PremultiplyValue(a, g);
     *dst++ = PremultiplyValue(a, r);