blob: 9ad94ff54dec546e7da7377df868ef00f59cd424 [file] [log] [blame]
senorblanco@chromium.org4e753552009-11-16 21:09:00 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
senorblanco@chromium.org4e753552009-11-16 21:09:00 +00006 */
7
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +00008#include "SkBitmapProcState_opts_SSE2.h"
reed@google.com58af9a62011-10-12 13:43:52 +00009#include "SkBlitMask.h"
senorblanco@chromium.org4e753552009-11-16 21:09:00 +000010#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
senorblanco@chromium.org0c547bc2009-11-20 18:55:44 +000019#if defined(__x86_64__) || defined(_WIN64)
senorblanco@chromium.org4e753552009-11-16 21:09:00 +000020/* All x86_64 machines have SSE2, so don't even bother checking. */
21static inline bool hasSSE2() {
22 return true;
23}
24#else
25#ifdef _MSC_VER
26static 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
38static 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 : "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
46 : "a"(info_type)
senorblanco@chromium.org4e753552009-11-16 21:09:00 +000047 );
48}
49#endif
50
51static inline bool hasSSE2() {
52 int cpu_info[4] = { 0 };
53 getcpuid(1, cpu_info);
54 return (cpu_info[3] & (1<<26)) != 0;
55}
56#endif
57
reed@google.comedb606c2011-10-18 13:56:50 +000058static bool cachedHasSSE2() {
59 static bool gHasSSE2 = hasSSE2();
60 return gHasSSE2;
61}
62
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +000063void SkBitmapProcState::platformProcs() {
reed@google.comedb606c2011-10-18 13:56:50 +000064 if (cachedHasSSE2()) {
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +000065 if (fSampleProc32 == S32_opaque_D32_filter_DX) {
66 fSampleProc32 = S32_opaque_D32_filter_DX_SSE2;
senorblanco@chromium.orgf3f0bd72009-12-10 22:46:31 +000067 } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
68 fSampleProc32 = S32_alpha_D32_filter_DX_SSE2;
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +000069 }
70 }
71}
72
senorblanco@chromium.org4e753552009-11-16 21:09:00 +000073static 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
80SkBlitRow::Proc SkBlitRow::PlatformProcs4444(unsigned flags) {
81 return NULL;
82}
83
84SkBlitRow::Proc SkBlitRow::PlatformProcs565(unsigned flags) {
85 return NULL;
86}
87
senorblanco@chromium.orgc3856382010-12-13 15:27:20 +000088SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
reed@google.comedb606c2011-10-18 13:56:50 +000089 if (cachedHasSSE2()) {
senorblanco@chromium.orgc3856382010-12-13 15:27:20 +000090 return Color32_SSE2;
91 } else {
92 return NULL;
93 }
94}
95
senorblanco@chromium.org4e753552009-11-16 21:09:00 +000096SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
reed@google.comedb606c2011-10-18 13:56:50 +000097 if (cachedHasSSE2()) {
senorblanco@chromium.org4e753552009-11-16 21:09:00 +000098 return platform_32_procs[flags];
99 } else {
100 return NULL;
101 }
102}
103
reed@google.com981d4792011-03-09 12:55:47 +0000104
reed@google.come901b4c2011-11-14 21:56:45 +0000105SkBlitMask::ColorProc SkBlitMask::PlatformColorProcs(SkBitmap::Config dstConfig,
106 SkMask::Format maskFormat,
107 SkColor color) {
reed@google.comedb606c2011-10-18 13:56:50 +0000108 if (SkMask::kA8_Format != maskFormat) {
109 return NULL;
110 }
reed@google.come901b4c2011-11-14 21:56:45 +0000111
112 ColorProc proc = NULL;
reed@google.comedb606c2011-10-18 13:56:50 +0000113 if (cachedHasSSE2()) {
reed@google.com981d4792011-03-09 12:55:47 +0000114 switch (dstConfig) {
115 case SkBitmap::kARGB_8888_Config:
reed@google.come6ea6062011-07-07 19:12:50 +0000116 // The SSE2 version is not (yet) faster for black, so we check
117 // for that.
118 if (SK_ColorBLACK != color) {
reed@google.comedb606c2011-10-18 13:56:50 +0000119 proc = SkARGB32_A8_BlitMask_SSE2;
reed@google.come6ea6062011-07-07 19:12:50 +0000120 }
reed@google.com981d4792011-03-09 12:55:47 +0000121 break;
122 default:
reed@google.come901b4c2011-11-14 21:56:45 +0000123 break;
reed@google.com981d4792011-03-09 12:55:47 +0000124 }
125 }
126 return proc;
127}
128
reed@google.come901b4c2011-11-14 21:56:45 +0000129SkBlitMask::RowProc SkBlitMask::PlatformRowProcs(SkBitmap::Config dstConfig,
130 SkMask::Format maskFormat) {
131 return NULL;
132}
133
senorblanco@chromium.org4e753552009-11-16 21:09:00 +0000134SkMemset16Proc SkMemset16GetPlatformProc() {
reed@google.comedb606c2011-10-18 13:56:50 +0000135 if (cachedHasSSE2()) {
senorblanco@chromium.org4e753552009-11-16 21:09:00 +0000136 return sk_memset16_SSE2;
137 } else {
138 return NULL;
139 }
140}
141
142SkMemset32Proc SkMemset32GetPlatformProc() {
reed@google.comedb606c2011-10-18 13:56:50 +0000143 if (cachedHasSSE2()) {
senorblanco@chromium.org4e753552009-11-16 21:09:00 +0000144 return sk_memset32_SSE2;
145 } else {
146 return NULL;
147 }
148}