Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
michael@0 | 2 | // Use of this source code is governed by a BSD-style license that can be |
michael@0 | 3 | // found in the LICENSE file. |
michael@0 | 4 | |
michael@0 | 5 | // contributor Siarhei Siamashka <siarhei.siamashka@gmail.com> |
michael@0 | 6 | |
michael@0 | 7 | #include "yuv_convert.h" |
michael@0 | 8 | #include "ycbcr_to_rgb565.h" |
michael@0 | 9 | |
michael@0 | 10 | |
michael@0 | 11 | |
michael@0 | 12 | #ifdef HAVE_YCBCR_TO_RGB565 |
michael@0 | 13 | |
michael@0 | 14 | namespace mozilla { |
michael@0 | 15 | |
michael@0 | 16 | namespace gfx { |
michael@0 | 17 | |
michael@0 | 18 | # if defined(MOZILLA_MAY_SUPPORT_NEON) |
michael@0 | 19 | void __attribute((noinline,optimize("-fomit-frame-pointer"))) |
michael@0 | 20 | yuv42x_to_rgb565_row_neon(uint16 *dst, |
michael@0 | 21 | const uint8 *y, |
michael@0 | 22 | const uint8 *u, |
michael@0 | 23 | const uint8 *v, |
michael@0 | 24 | int n, |
michael@0 | 25 | int oddflag) |
michael@0 | 26 | { |
michael@0 | 27 | static __attribute__((aligned(16))) uint16 acc_r[8] = { |
michael@0 | 28 | 22840, 22840, 22840, 22840, 22840, 22840, 22840, 22840, |
michael@0 | 29 | }; |
michael@0 | 30 | static __attribute__((aligned(16))) uint16 acc_g[8] = { |
michael@0 | 31 | 17312, 17312, 17312, 17312, 17312, 17312, 17312, 17312, |
michael@0 | 32 | }; |
michael@0 | 33 | static __attribute__((aligned(16))) uint16 acc_b[8] = { |
michael@0 | 34 | 28832, 28832, 28832, 28832, 28832, 28832, 28832, 28832, |
michael@0 | 35 | }; |
michael@0 | 36 | /* |
michael@0 | 37 | * Registers: |
michael@0 | 38 | * q0, q1 : d0, d1, d2, d3 - are used for initial loading of YUV data |
michael@0 | 39 | * q2 : d4, d5 - are used for storing converted RGB data |
michael@0 | 40 | * q3 : d6, d7 - are used for temporary storage |
michael@0 | 41 | * |
michael@0 | 42 | * q4-q7 - reserved |
michael@0 | 43 | * |
michael@0 | 44 | * q8, q9 : d16, d17, d18, d19 - are used for expanded Y data |
michael@0 | 45 | * q10 : d20, d21 |
michael@0 | 46 | * q11 : d22, d23 |
michael@0 | 47 | * q12 : d24, d25 |
michael@0 | 48 | * q13 : d26, d27 |
michael@0 | 49 | * q13, q14, q15 - various constants (#16, #149, #204, #50, #104, #154) |
michael@0 | 50 | */ |
michael@0 | 51 | asm volatile ( |
michael@0 | 52 | ".fpu neon\n" |
michael@0 | 53 | /* Allow to build on targets not supporting neon, and force the object file |
michael@0 | 54 | * target to avoid bumping the final binary target */ |
michael@0 | 55 | ".arch armv7-a\n" |
michael@0 | 56 | ".object_arch armv4t\n" |
michael@0 | 57 | ".macro convert_macroblock size\n" |
michael@0 | 58 | /* load up to 16 source pixels */ |
michael@0 | 59 | ".if \\size == 16\n" |
michael@0 | 60 | "pld [%[y], #64]\n" |
michael@0 | 61 | "pld [%[u], #64]\n" |
michael@0 | 62 | "pld [%[v], #64]\n" |
michael@0 | 63 | "vld1.8 {d1}, [%[y]]!\n" |
michael@0 | 64 | "vld1.8 {d3}, [%[y]]!\n" |
michael@0 | 65 | "vld1.8 {d0}, [%[u]]!\n" |
michael@0 | 66 | "vld1.8 {d2}, [%[v]]!\n" |
michael@0 | 67 | ".elseif \\size == 8\n" |
michael@0 | 68 | "vld1.8 {d1}, [%[y]]!\n" |
michael@0 | 69 | "vld1.8 {d0[0]}, [%[u]]!\n" |
michael@0 | 70 | "vld1.8 {d0[1]}, [%[u]]!\n" |
michael@0 | 71 | "vld1.8 {d0[2]}, [%[u]]!\n" |
michael@0 | 72 | "vld1.8 {d0[3]}, [%[u]]!\n" |
michael@0 | 73 | "vld1.8 {d2[0]}, [%[v]]!\n" |
michael@0 | 74 | "vld1.8 {d2[1]}, [%[v]]!\n" |
michael@0 | 75 | "vld1.8 {d2[2]}, [%[v]]!\n" |
michael@0 | 76 | "vld1.8 {d2[3]}, [%[v]]!\n" |
michael@0 | 77 | ".elseif \\size == 4\n" |
michael@0 | 78 | "vld1.8 {d1[0]}, [%[y]]!\n" |
michael@0 | 79 | "vld1.8 {d1[1]}, [%[y]]!\n" |
michael@0 | 80 | "vld1.8 {d1[2]}, [%[y]]!\n" |
michael@0 | 81 | "vld1.8 {d1[3]}, [%[y]]!\n" |
michael@0 | 82 | "vld1.8 {d0[0]}, [%[u]]!\n" |
michael@0 | 83 | "vld1.8 {d0[1]}, [%[u]]!\n" |
michael@0 | 84 | "vld1.8 {d2[0]}, [%[v]]!\n" |
michael@0 | 85 | "vld1.8 {d2[1]}, [%[v]]!\n" |
michael@0 | 86 | ".elseif \\size == 2\n" |
michael@0 | 87 | "vld1.8 {d1[0]}, [%[y]]!\n" |
michael@0 | 88 | "vld1.8 {d1[1]}, [%[y]]!\n" |
michael@0 | 89 | "vld1.8 {d0[0]}, [%[u]]!\n" |
michael@0 | 90 | "vld1.8 {d2[0]}, [%[v]]!\n" |
michael@0 | 91 | ".elseif \\size == 1\n" |
michael@0 | 92 | "vld1.8 {d1[0]}, [%[y]]!\n" |
michael@0 | 93 | "vld1.8 {d0[0]}, [%[u]]!\n" |
michael@0 | 94 | "vld1.8 {d2[0]}, [%[v]]!\n" |
michael@0 | 95 | ".else\n" |
michael@0 | 96 | ".error \"unsupported macroblock size\"\n" |
michael@0 | 97 | ".endif\n" |
michael@0 | 98 | |
michael@0 | 99 | /* d1 - Y data (first 8 bytes) */ |
michael@0 | 100 | /* d3 - Y data (next 8 bytes) */ |
michael@0 | 101 | /* d0 - U data, d2 - V data */ |
michael@0 | 102 | |
michael@0 | 103 | /* split even and odd Y color components */ |
michael@0 | 104 | "vuzp.8 d1, d3\n" /* d1 - evenY, d3 - oddY */ |
michael@0 | 105 | /* clip upper and lower boundaries */ |
michael@0 | 106 | "vqadd.u8 q0, q0, q4\n" |
michael@0 | 107 | "vqadd.u8 q1, q1, q4\n" |
michael@0 | 108 | "vqsub.u8 q0, q0, q5\n" |
michael@0 | 109 | "vqsub.u8 q1, q1, q5\n" |
michael@0 | 110 | |
michael@0 | 111 | "vshr.u8 d4, d2, #1\n" /* d4 = V >> 1 */ |
michael@0 | 112 | |
michael@0 | 113 | "vmull.u8 q8, d1, d27\n" /* q8 = evenY * 149 */ |
michael@0 | 114 | "vmull.u8 q9, d3, d27\n" /* q9 = oddY * 149 */ |
michael@0 | 115 | |
michael@0 | 116 | "vld1.16 {d20, d21}, [%[acc_r], :128]\n" /* q10 - initialize accumulator for red */ |
michael@0 | 117 | "vsubw.u8 q10, q10, d4\n" /* red acc -= (V >> 1) */ |
michael@0 | 118 | "vmlsl.u8 q10, d2, d28\n" /* red acc -= V * 204 */ |
michael@0 | 119 | "vld1.16 {d22, d23}, [%[acc_g], :128]\n" /* q11 - initialize accumulator for green */ |
michael@0 | 120 | "vmlsl.u8 q11, d2, d30\n" /* green acc -= V * 104 */ |
michael@0 | 121 | "vmlsl.u8 q11, d0, d29\n" /* green acc -= U * 50 */ |
michael@0 | 122 | "vld1.16 {d24, d25}, [%[acc_b], :128]\n" /* q12 - initialize accumulator for blue */ |
michael@0 | 123 | "vmlsl.u8 q12, d0, d30\n" /* blue acc -= U * 104 */ |
michael@0 | 124 | "vmlsl.u8 q12, d0, d31\n" /* blue acc -= U * 154 */ |
michael@0 | 125 | |
michael@0 | 126 | "vhsub.s16 q3, q8, q10\n" /* calculate even red components */ |
michael@0 | 127 | "vhsub.s16 q10, q9, q10\n" /* calculate odd red components */ |
michael@0 | 128 | "vqshrun.s16 d0, q3, #6\n" /* right shift, narrow and saturate even red components */ |
michael@0 | 129 | "vqshrun.s16 d3, q10, #6\n" /* right shift, narrow and saturate odd red components */ |
michael@0 | 130 | |
michael@0 | 131 | "vhadd.s16 q3, q8, q11\n" /* calculate even green components */ |
michael@0 | 132 | "vhadd.s16 q11, q9, q11\n" /* calculate odd green components */ |
michael@0 | 133 | "vqshrun.s16 d1, q3, #6\n" /* right shift, narrow and saturate even green components */ |
michael@0 | 134 | "vqshrun.s16 d4, q11, #6\n" /* right shift, narrow and saturate odd green components */ |
michael@0 | 135 | |
michael@0 | 136 | "vhsub.s16 q3, q8, q12\n" /* calculate even blue components */ |
michael@0 | 137 | "vhsub.s16 q12, q9, q12\n" /* calculate odd blue components */ |
michael@0 | 138 | "vqshrun.s16 d2, q3, #6\n" /* right shift, narrow and saturate even blue components */ |
michael@0 | 139 | "vqshrun.s16 d5, q12, #6\n" /* right shift, narrow and saturate odd blue components */ |
michael@0 | 140 | |
michael@0 | 141 | "vzip.8 d0, d3\n" /* join even and odd red components */ |
michael@0 | 142 | "vzip.8 d1, d4\n" /* join even and odd green components */ |
michael@0 | 143 | "vzip.8 d2, d5\n" /* join even and odd blue components */ |
michael@0 | 144 | |
michael@0 | 145 | "vshll.u8 q3, d0, #8\n\t" |
michael@0 | 146 | "vshll.u8 q8, d1, #8\n\t" |
michael@0 | 147 | "vshll.u8 q9, d2, #8\n\t" |
michael@0 | 148 | "vsri.u16 q3, q8, #5\t\n" |
michael@0 | 149 | "vsri.u16 q3, q9, #11\t\n" |
michael@0 | 150 | /* store pixel data to memory */ |
michael@0 | 151 | ".if \\size == 16\n" |
michael@0 | 152 | " vst1.16 {d6, d7}, [%[dst]]!\n" |
michael@0 | 153 | " vshll.u8 q3, d3, #8\n\t" |
michael@0 | 154 | " vshll.u8 q8, d4, #8\n\t" |
michael@0 | 155 | " vshll.u8 q9, d5, #8\n\t" |
michael@0 | 156 | " vsri.u16 q3, q8, #5\t\n" |
michael@0 | 157 | " vsri.u16 q3, q9, #11\t\n" |
michael@0 | 158 | " vst1.16 {d6, d7}, [%[dst]]!\n" |
michael@0 | 159 | ".elseif \\size == 8\n" |
michael@0 | 160 | " vst1.16 {d6, d7}, [%[dst]]!\n" |
michael@0 | 161 | ".elseif \\size == 4\n" |
michael@0 | 162 | " vst1.16 {d6}, [%[dst]]!\n" |
michael@0 | 163 | ".elseif \\size == 2\n" |
michael@0 | 164 | " vst1.16 {d6[0]}, [%[dst]]!\n" |
michael@0 | 165 | " vst1.16 {d6[1]}, [%[dst]]!\n" |
michael@0 | 166 | ".elseif \\size == 1\n" |
michael@0 | 167 | " vst1.16 {d6[0]}, [%[dst]]!\n" |
michael@0 | 168 | ".endif\n" |
michael@0 | 169 | ".endm\n" |
michael@0 | 170 | |
michael@0 | 171 | "vmov.u8 d8, #15\n" /* add this to U/V to saturate upper boundary */ |
michael@0 | 172 | "vmov.u8 d9, #20\n" /* add this to Y to saturate upper boundary */ |
michael@0 | 173 | "vmov.u8 d10, #31\n" /* sub this from U/V to saturate lower boundary */ |
michael@0 | 174 | "vmov.u8 d11, #36\n" /* sub this from Y to saturate lower boundary */ |
michael@0 | 175 | |
michael@0 | 176 | "vmov.u8 d26, #16\n" |
michael@0 | 177 | "vmov.u8 d27, #149\n" |
michael@0 | 178 | "vmov.u8 d28, #204\n" |
michael@0 | 179 | "vmov.u8 d29, #50\n" |
michael@0 | 180 | "vmov.u8 d30, #104\n" |
michael@0 | 181 | "vmov.u8 d31, #154\n" |
michael@0 | 182 | |
michael@0 | 183 | "cmp %[oddflag], #0\n" |
michael@0 | 184 | "beq 1f\n" |
michael@0 | 185 | "convert_macroblock 1\n" |
michael@0 | 186 | "sub %[n], %[n], #1\n" |
michael@0 | 187 | "1:\n" |
michael@0 | 188 | "subs %[n], %[n], #16\n" |
michael@0 | 189 | "blt 2f\n" |
michael@0 | 190 | "1:\n" |
michael@0 | 191 | "convert_macroblock 16\n" |
michael@0 | 192 | "subs %[n], %[n], #16\n" |
michael@0 | 193 | "bge 1b\n" |
michael@0 | 194 | "2:\n" |
michael@0 | 195 | "tst %[n], #8\n" |
michael@0 | 196 | "beq 3f\n" |
michael@0 | 197 | "convert_macroblock 8\n" |
michael@0 | 198 | "3:\n" |
michael@0 | 199 | "tst %[n], #4\n" |
michael@0 | 200 | "beq 4f\n" |
michael@0 | 201 | "convert_macroblock 4\n" |
michael@0 | 202 | "4:\n" |
michael@0 | 203 | "tst %[n], #2\n" |
michael@0 | 204 | "beq 5f\n" |
michael@0 | 205 | "convert_macroblock 2\n" |
michael@0 | 206 | "5:\n" |
michael@0 | 207 | "tst %[n], #1\n" |
michael@0 | 208 | "beq 6f\n" |
michael@0 | 209 | "convert_macroblock 1\n" |
michael@0 | 210 | "6:\n" |
michael@0 | 211 | ".purgem convert_macroblock\n" |
michael@0 | 212 | : [y] "+&r" (y), [u] "+&r" (u), [v] "+&r" (v), [dst] "+&r" (dst), [n] "+&r" (n) |
michael@0 | 213 | : [acc_r] "r" (&acc_r[0]), [acc_g] "r" (&acc_g[0]), [acc_b] "r" (&acc_b[0]), |
michael@0 | 214 | [oddflag] "r" (oddflag) |
michael@0 | 215 | : "cc", "memory", |
michael@0 | 216 | "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", |
michael@0 | 217 | "d8", "d9", "d10", "d11", /* "d12", "d13", "d14", "d15", */ |
michael@0 | 218 | "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", |
michael@0 | 219 | "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31" |
michael@0 | 220 | ); |
michael@0 | 221 | } |
michael@0 | 222 | # endif // MOZILLA_MAY_SUPPORT_NEON |
michael@0 | 223 | |
michael@0 | 224 | } // namespace gfx |
michael@0 | 225 | |
michael@0 | 226 | } // namespace mozilla |
michael@0 | 227 | |
michael@0 | 228 | #endif // HAVE_YCBCR_TO_RGB565 |