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

Side by Side Diff: remoting/host/differ_block.cc

Issue 6501005: Resubmit - Use SSE2 block differ for chromoting (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/differ_block.h ('k') | remoting/host/differ_block_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/differ_block.h" 5 #include "remoting/host/differ_block.h"
6 6
7 #include <stdlib.h> 7 #include "build/build_config.h"
8 8 #include "media/base/cpu_features.h"
9 #if !defined(USE_SSE2) 9 #include "remoting/host/differ_block_internal.h"
10 #if defined(__SSE2__) || defined(ARCH_CPU_X86_64) || defined(_MSC_VER)
11 #define USE_SSE2 1
12 #else
13 #define USE_SSE2 0
14 #endif
15 #endif
16
17 #if USE_SSE2
18 #include <emmintrin.h>
19 #endif
20 10
21 namespace remoting { 11 namespace remoting {
22 12
23 #if USE_SSE2 13 int BlockDifference_C(const uint8* image1, const uint8* image2, int stride) {
24 int BlockDifference(const uint8* image1, const uint8* image2, int stride) {
25 __m128i acc = _mm_setzero_si128();
26 __m128i v0;
27 __m128i v1;
28 __m128i sad;
29 for (int y = 0; y < kBlockHeight; ++y) {
30 const __m128i* i1 = reinterpret_cast<const __m128i*>(image1);
31 const __m128i* i2 = reinterpret_cast<const __m128i*>(image2);
32 v0 = _mm_loadu_si128(i1);
33 v1 = _mm_loadu_si128(i2);
34 sad = _mm_sad_epu8(v0, v1);
35 acc = _mm_adds_epu16(acc, sad);
36 v0 = _mm_loadu_si128(i1 + 1);
37 v1 = _mm_loadu_si128(i2 + 1);
38 sad = _mm_sad_epu8(v0, v1);
39 acc = _mm_adds_epu16(acc, sad);
40 v0 = _mm_loadu_si128(i1 + 2);
41 v1 = _mm_loadu_si128(i2 + 2);
42 sad = _mm_sad_epu8(v0, v1);
43 acc = _mm_adds_epu16(acc, sad);
44 v0 = _mm_loadu_si128(i1 + 3);
45 v1 = _mm_loadu_si128(i2 + 3);
46 sad = _mm_sad_epu8(v0, v1);
47 acc = _mm_adds_epu16(acc, sad);
48 v0 = _mm_loadu_si128(i1 + 4);
49 v1 = _mm_loadu_si128(i2 + 4);
50 sad = _mm_sad_epu8(v0, v1);
51 acc = _mm_adds_epu16(acc, sad);
52 v0 = _mm_loadu_si128(i1 + 5);
53 v1 = _mm_loadu_si128(i2 + 5);
54 sad = _mm_sad_epu8(v0, v1);
55 acc = _mm_adds_epu16(acc, sad);
56 v0 = _mm_loadu_si128(i1 + 6);
57 v1 = _mm_loadu_si128(i2 + 6);
58 sad = _mm_sad_epu8(v0, v1);
59 acc = _mm_adds_epu16(acc, sad);
60 v0 = _mm_loadu_si128(i1 + 7);
61 v1 = _mm_loadu_si128(i2 + 7);
62 sad = _mm_sad_epu8(v0, v1);
63 acc = _mm_adds_epu16(acc, sad);
64 sad = _mm_shuffle_epi32(acc, 0xEE); // [acc3, acc2, acc3, acc2]
65 sad = _mm_adds_epu16(sad, acc);
66 int diff = _mm_cvtsi128_si32(sad);
67 if (diff) {
68 return 1;
69 }
70 image1 += stride;
71 image2 += stride;
72 }
73 return 0;
74 }
75 #else
76 int BlockDifference(const uint8* image1, const uint8* image2, int stride) {
77 // Number of uint64s in each row of the block. 14 // Number of uint64s in each row of the block.
78 // This must be an integral number. 15 // This must be an integral number.
79 int int64s_per_row = (kBlockWidth * kBytesPerPixel) / sizeof(uint64); 16 int int64s_per_row = (kBlockWidth * kBytesPerPixel) / sizeof(uint64);
80 17
81 for (int y = 0; y < kBlockHeight; y++) { 18 for (int y = 0; y < kBlockHeight; y++) {
82 const uint64* prev = reinterpret_cast<const uint64*>(image1); 19 const uint64* prev = reinterpret_cast<const uint64*>(image1);
83 const uint64* curr = reinterpret_cast<const uint64*>(image2); 20 const uint64* curr = reinterpret_cast<const uint64*>(image2);
84 21
85 // Check each row in uint64-sized chunks. 22 // Check each row in uint64-sized chunks.
86 // Note that this check may straddle multiple pixels. This is OK because 23 // Note that this check may straddle multiple pixels. This is OK because
87 // we're interested in identifying whether or not there was change - we 24 // we're interested in identifying whether or not there was change - we
88 // don't care what the actual change is. 25 // don't care what the actual change is.
89 for (int x = 0; x < int64s_per_row; x++) { 26 for (int x = 0; x < int64s_per_row; x++) {
90 if (*prev++ != *curr++) { 27 if (*prev++ != *curr++) {
91 return 1; 28 return 1;
92 } 29 }
93 } 30 }
94 image1 += stride; 31 image1 += stride;
95 image2 += stride; 32 image2 += stride;
96 } 33 }
97 return 0; 34 return 0;
98 } 35 }
36
37 int BlockDifference(const uint8* image1, const uint8* image2, int stride) {
38 static int (*diff_proc)(const uint8*, const uint8*, int) = NULL;
39
40 if (!diff_proc) {
41 #if defined(ARCH_CPU_ARM_FAMILY)
42 // For ARM processors, always use C version.
43 // TODO(hclam): Implement a NEON version.
44 diff_proc = &BlockDifference_C;
45 #else
46 // For x86 processors, check if SSE2 is supported.
47 if (media::hasSSE2() && kBlockWidth == 32)
48 diff_proc = &BlockDifference_SSE2_W32;
49 else if (media::hasSSE2() && kBlockWidth == 16)
50 diff_proc = &BlockDifference_SSE2_W16;
51 else
52 diff_proc = &BlockDifference_C;
99 #endif 53 #endif
54 }
55
56 return diff_proc(image1, image2, stride);
57 }
100 58
101 } // namespace remoting 59 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/differ_block.h ('k') | remoting/host/differ_block_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698