1 : /*
2 : * Copyright 2009 The Android Open Source Project
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #include "SkBitmapProcState_opts_SSE2.h"
9 : #include "SkBlitMask.h"
10 : #include "SkBlitRow_opts_SSE2.h"
11 : #include "SkUtils_opts_SSE2.h"
12 : #include "SkUtils.h"
13 :
14 : /* This file must *not* be compiled with -msse or -msse2, otherwise
15 : gcc may generate sse2 even for scalar ops (and thus give an invalid
16 : instruction on Pentium3 on the code below). Only files named *_SSE2.cpp
17 : in this directory should be compiled with -msse2. */
18 :
19 : #if defined(__x86_64__) || defined(_WIN64)
20 : /* All x86_64 machines have SSE2, so don't even bother checking. */
21 : static inline bool hasSSE2() {
22 : return true;
23 : }
24 : #else
25 : #ifdef _MSC_VER
26 : static inline void getcpuid(int info_type, int info[4]) {
27 : __asm {
28 : mov eax, [info_type]
29 : cpuid
30 : mov edi, [info]
31 : mov [edi], eax
32 : mov [edi+4], ebx
33 : mov [edi+8], ecx
34 : mov [edi+12], edx
35 : }
36 : }
37 : #else
38 0 : static inline void getcpuid(int info_type, int info[4]) {
39 : // We save and restore ebx, so this code can be compatible with -fPIC
40 : asm volatile (
41 : "pushl %%ebx \n\t"
42 : "cpuid \n\t"
43 : "movl %%ebx, %1 \n\t"
44 : "popl %%ebx \n\t"
45 0 : : "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
46 : : "a"(info_type)
47 0 : );
48 0 : }
49 : #endif
50 :
51 0 : static inline bool hasSSE2() {
52 0 : int cpu_info[4] = { 0 };
53 0 : getcpuid(1, cpu_info);
54 0 : return (cpu_info[3] & (1<<26)) != 0;
55 : }
56 : #endif
57 :
58 0 : static bool cachedHasSSE2() {
59 0 : static bool gHasSSE2 = hasSSE2();
60 0 : return gHasSSE2;
61 : }
62 :
63 0 : void SkBitmapProcState::platformProcs() {
64 0 : if (cachedHasSSE2()) {
65 0 : if (fSampleProc32 == S32_opaque_D32_filter_DX) {
66 0 : fSampleProc32 = S32_opaque_D32_filter_DX_SSE2;
67 0 : } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
68 0 : fSampleProc32 = S32_alpha_D32_filter_DX_SSE2;
69 : }
70 : }
71 0 : }
72 :
73 : static SkBlitRow::Proc32 platform_32_procs[] = {
74 : NULL, // S32_Opaque,
75 : S32_Blend_BlitRow32_SSE2, // S32_Blend,
76 : S32A_Opaque_BlitRow32_SSE2, // S32A_Opaque
77 : S32A_Blend_BlitRow32_SSE2, // S32A_Blend,
78 : };
79 :
80 0 : SkBlitRow::Proc SkBlitRow::PlatformProcs4444(unsigned flags) {
81 0 : return NULL;
82 : }
83 :
84 0 : SkBlitRow::Proc SkBlitRow::PlatformProcs565(unsigned flags) {
85 0 : return NULL;
86 : }
87 :
88 0 : SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
89 0 : if (cachedHasSSE2()) {
90 0 : return Color32_SSE2;
91 : } else {
92 0 : return NULL;
93 : }
94 : }
95 :
96 0 : SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
97 0 : if (cachedHasSSE2()) {
98 0 : return platform_32_procs[flags];
99 : } else {
100 0 : return NULL;
101 : }
102 : }
103 :
104 :
105 0 : SkBlitMask::ColorProc SkBlitMask::PlatformColorProcs(SkBitmap::Config dstConfig,
106 : SkMask::Format maskFormat,
107 : SkColor color) {
108 0 : if (SkMask::kA8_Format != maskFormat) {
109 0 : return NULL;
110 : }
111 :
112 0 : ColorProc proc = NULL;
113 0 : if (cachedHasSSE2()) {
114 0 : switch (dstConfig) {
115 : case SkBitmap::kARGB_8888_Config:
116 : // The SSE2 version is not (yet) faster for black, so we check
117 : // for that.
118 0 : if (SK_ColorBLACK != color) {
119 0 : proc = SkARGB32_A8_BlitMask_SSE2;
120 : }
121 0 : break;
122 : default:
123 0 : break;
124 : }
125 : }
126 0 : return proc;
127 : }
128 :
129 0 : SkBlitMask::RowProc SkBlitMask::PlatformRowProcs(SkBitmap::Config dstConfig,
130 : SkMask::Format maskFormat,
131 : RowFlags flags) {
132 0 : return NULL;
133 : }
134 :
135 0 : SkMemset16Proc SkMemset16GetPlatformProc() {
136 0 : if (cachedHasSSE2()) {
137 0 : return sk_memset16_SSE2;
138 : } else {
139 0 : return NULL;
140 : }
141 : }
142 :
143 0 : SkMemset32Proc SkMemset32GetPlatformProc() {
144 0 : if (cachedHasSSE2()) {
145 0 : return sk_memset32_SSE2;
146 : } else {
147 0 : return NULL;
148 : }
149 : }
|