summaryrefslogtreecommitdiffstats
path: root/remoting/host/differ_block.cc
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/host/differ_block.cc')
-rw-r--r--remoting/host/differ_block.cc48
1 files changed, 33 insertions, 15 deletions
diff --git a/remoting/host/differ_block.cc b/remoting/host/differ_block.cc
index 4dfe58c..f7b785d 100644
--- a/remoting/host/differ_block.cc
+++ b/remoting/host/differ_block.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "differ_block.h"
+#include "remoting/host/differ_block.h"
#include <stdlib.h>
@@ -20,11 +20,6 @@
namespace remoting {
-// TODO(fbarchard): Use common header for block size.
-const int kBlockWidth = 32;
-const int kBlockHeight = 32;
-const int kBytesPerPixel = 3;
-
#if USE_SSE2
int BlockDifference(const uint8* image1, const uint8* image2, int stride) {
__m128i acc = _mm_setzero_si128();
@@ -58,25 +53,48 @@ int BlockDifference(const uint8* image1, const uint8* image2, int stride) {
v1 = _mm_loadu_si128(i2 + 5);
sad = _mm_sad_epu8(v0, v1);
acc = _mm_adds_epu16(acc, sad);
+ v0 = _mm_loadu_si128(i1 + 6);
+ v1 = _mm_loadu_si128(i2 + 6);
+ sad = _mm_sad_epu8(v0, v1);
+ acc = _mm_adds_epu16(acc, sad);
+ v0 = _mm_loadu_si128(i1 + 7);
+ v1 = _mm_loadu_si128(i2 + 7);
+ sad = _mm_sad_epu8(v0, v1);
+ acc = _mm_adds_epu16(acc, sad);
+ sad = _mm_shuffle_epi32(acc, 0xEE); // [acc3, acc2, acc3, acc2]
+ sad = _mm_adds_epu16(sad, acc);
+ int diff = _mm_cvtsi128_si32(sad);
+ if (diff) {
+ return 1;
+ }
image1 += stride;
image2 += stride;
}
- sad = _mm_shuffle_epi32(acc, 0xEE); // [acc3, acc2, acc3, acc2]
- sad = _mm_adds_epu16(sad, acc);
- int diff = _mm_cvtsi128_si32(sad);
- return diff;
+ return 0;
}
#else
int BlockDifference(const uint8* image1, const uint8* image2, int stride) {
- int diff = 0;
- for (int y = 0; y < kBlockHeight; ++y) {
- for (int x = 0; x < kBlockWidth * kBytesPerPixel; ++x) {
- diff += abs(image1[x] - image2[x]);
+ // Number of uint64s in each row of the block.
+ // This must be an integral number.
+ int int64s_per_row = (kBlockWidth * kBytesPerPixel) / sizeof(uint64);
+
+ for (int y = 0; y < kBlockHeight; y++) {
+ const uint64* prev = reinterpret_cast<const uint64*>(image1);
+ const uint64* curr = reinterpret_cast<const uint64*>(image2);
+
+ // Check each row in uint64-sized chunks.
+ // Note that this check may straddle multiple pixels. This is OK because
+ // we're interested in identifying whether or not there was change - we
+ // don't care what the actual change is.
+ for (int x = 0; x < int64s_per_row; x++) {
+ if (*prev++ != *curr++) {
+ return 1;
+ }
}
image1 += stride;
image2 += stride;
}
- return diff;
+ return 0;
}
#endif