10#ifndef SK_USE_DRAWING_MIPMAP_DOWNSAMPLER
19struct ColorTypeFilter_8888 {
20 typedef uint32_t
Type;
26 skvx::cast<uint8_t>(
x).store(&r);
31struct ColorTypeFilter_565 {
32 typedef uint16_t
Type;
33 static uint32_t Expand(uint16_t
x) {
36 static uint16_t Compact(uint32_t
x) {
41struct ColorTypeFilter_4444 {
42 typedef uint16_t
Type;
43 static uint32_t Expand(uint16_t
x) {
44 return (
x & 0xF0F) | ((
x & ~0xF0F) << 12);
46 static uint16_t Compact(uint32_t
x) {
47 return (
x & 0xF0F) | ((
x >> 12) & ~0xF0F);
51struct ColorTypeFilter_8 {
53 static unsigned Expand(
unsigned x) {
56 static uint8_t Compact(
unsigned x) {
61struct ColorTypeFilter_Alpha_F16 {
62 typedef uint16_t
Type;
64 uint64_t x4 = (uint64_t)
x;
74struct ColorTypeFilter_RGBA_F16 {
75 typedef uint64_t
Type;
86struct ColorTypeFilter_88 {
87 typedef uint16_t
Type;
88 static uint32_t Expand(uint16_t
x) {
89 return (
x & 0xFF) | ((
x & ~0xFF) << 8);
91 static uint16_t Compact(uint32_t
x) {
92 return (
x & 0xFF) | ((
x >> 8) & ~0xFF);
96struct ColorTypeFilter_1616 {
97 typedef uint32_t
Type;
98 static uint64_t Expand(uint32_t
x) {
99 return (
x & 0xFFFF) | ((
x & ~0xFFFF) << 16);
101 static uint16_t Compact(uint64_t
x) {
102 return (
x & 0xFFFF) | ((
x >> 16) & ~0xFFFF);
106struct ColorTypeFilter_F16F16 {
107 typedef uint32_t
Type;
109 uint64_t x4 = (uint64_t)
x;
115 return (uint32_t) (r & 0xFFFFFFFF);
119struct ColorTypeFilter_16161616 {
120 typedef uint64_t
Type;
126 skvx::cast<uint16_t>(
x).store(&r);
131struct ColorTypeFilter_16 {
132 typedef uint16_t
Type;
133 static uint32_t Expand(uint16_t
x) {
136 static uint16_t Compact(uint32_t
x) {
141struct ColorTypeFilter_1010102 {
142 typedef uint32_t
Type;
143 static uint64_t Expand(uint64_t
x) {
144 return (((
x ) & 0x3ff) ) |
145 (((
x >> 10) & 0x3ff) << 20) |
146 (((
x >> 20) & 0x3ff) << 40) |
147 (((
x >> 30) & 0x3 ) << 60);
149 static uint32_t Compact(uint64_t
x) {
150 return (((
x ) & 0x3ff) ) |
151 (((
x >> 20) & 0x3ff) << 10) |
152 (((
x >> 40) & 0x3ff) << 20) |
153 (((
x >> 60) & 0x3 ) << 30);
157template <
typename T>
T add_121(
const T&
a,
const T&
b,
const T& c) {
158 return a +
b +
b + c;
161template <
typename T>
T shift_right(
const T&
x,
int bits) {
166 return x * (1.0f / (1 <<
bits));
169template <
typename T>
T shift_left(
const T&
x,
int bits) {
174 return x * (1 <<
bits);
190template <
typename F>
void downsample_1_2(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
192 auto p0 =
static_cast<const typename
F::Type*
>(
src);
193 auto p1 = (
const typename F::Type*)((
const char*)p0 + srcRB);
197 auto c00 = F::Expand(p0[0]);
198 auto c10 = F::Expand(p1[0]);
201 d[
i] = F::Compact(shift_right(c, 1));
207template <
typename F>
void downsample_1_3(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
209 auto p0 =
static_cast<const typename
F::Type*
>(
src);
210 auto p1 = (
const typename F::Type*)((
const char*)p0 + srcRB);
211 auto p2 = (
const typename F::Type*)((
const char*)p1 + srcRB);
215 auto c00 = F::Expand(p0[0]);
216 auto c10 = F::Expand(p1[0]);
217 auto c20 = F::Expand(p2[0]);
219 auto c = add_121(c00, c10, c20);
220 d[
i] = F::Compact(shift_right(c, 2));
227template <
typename F>
void downsample_2_1(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
229 auto p0 =
static_cast<const typename
F::Type*
>(
src);
233 auto c00 = F::Expand(p0[0]);
234 auto c01 = F::Expand(p0[1]);
237 d[
i] = F::Compact(shift_right(c, 1));
242template <
typename F>
void downsample_2_2(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
244 auto p0 =
static_cast<const typename
F::Type*
>(
src);
245 auto p1 = (
const typename F::Type*)((
const char*)p0 + srcRB);
249 auto c00 = F::Expand(p0[0]);
250 auto c01 = F::Expand(p0[1]);
251 auto c10 = F::Expand(p1[0]);
252 auto c11 = F::Expand(p1[1]);
254 auto c = c00 + c10 + c01 + c11;
255 d[
i] = F::Compact(shift_right(c, 2));
261template <
typename F>
void downsample_2_3(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
263 auto p0 =
static_cast<const typename
F::Type*
>(
src);
264 auto p1 = (
const typename F::Type*)((
const char*)p0 + srcRB);
265 auto p2 = (
const typename F::Type*)((
const char*)p1 + srcRB);
269 auto c00 = F::Expand(p0[0]);
270 auto c01 = F::Expand(p0[1]);
271 auto c10 = F::Expand(p1[0]);
272 auto c11 = F::Expand(p1[1]);
273 auto c20 = F::Expand(p2[0]);
274 auto c21 = F::Expand(p2[1]);
276 auto c = add_121(c00, c10, c20) + add_121(c01, c11, c21);
277 d[
i] = F::Compact(shift_right(c, 3));
284template <
typename F>
void downsample_3_1(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
286 auto p0 =
static_cast<const typename
F::Type*
>(
src);
289 auto c02 = F::Expand(p0[0]);
292 auto c01 = F::Expand(p0[1]);
293 c02 = F::Expand(p0[2]);
295 auto c = add_121(c00, c01, c02);
296 d[
i] = F::Compact(shift_right(c, 2));
301template <
typename F>
void downsample_3_2(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
303 auto p0 =
static_cast<const typename
F::Type*
>(
src);
304 auto p1 = (
const typename F::Type*)((
const char*)p0 + srcRB);
315 auto c0 = F::Expand(p0[0]);
316 auto c1 = F::Expand(p1[0]);
321 auto b0 = F::Expand(p0[1]);
322 auto b1 = F::Expand(p1[1]);
323 auto b = b0 + b0 + b1 + b1;
325 c0 = F::Expand(p0[2]);
326 c1 = F::Expand(p1[2]);
329 auto sum =
a +
b + c;
330 d[
i] = F::Compact(shift_right(sum, 3));
336template <
typename F>
void downsample_3_3(
void*
dst,
const void*
src,
size_t srcRB,
int count) {
338 auto p0 =
static_cast<const typename
F::Type*
>(
src);
339 auto p1 = (
const typename F::Type*)((
const char*)p0 + srcRB);
340 auto p2 = (
const typename F::Type*)((
const char*)p1 + srcRB);
352 auto c0 = F::Expand(p0[0]);
353 auto c1 = F::Expand(p1[0]);
354 auto c2 = F::Expand(p2[0]);
355 auto c = add_121(c0, c1, c2);
359 auto b0 = F::Expand(p0[1]);
360 auto b1 = F::Expand(p1[1]);
361 auto b2 = F::Expand(p2[1]);
362 auto b = shift_left(add_121(b0, b1, b2), 1);
364 c0 = F::Expand(p0[2]);
365 c1 = F::Expand(p1[2]);
366 c2 = F::Expand(p2[2]);
367 c = add_121(c0, c1, c2);
369 auto sum =
a +
b + c;
370 d[
i] = F::Compact(shift_right(sum, 4));
378typedef void FilterProc(
void*,
const void* srcPtr,
size_t srcRB,
int count);
381 FilterProc* proc_1_2 =
nullptr;
382 FilterProc* proc_1_3 =
nullptr;
383 FilterProc* proc_2_1 =
nullptr;
384 FilterProc* proc_2_2 =
nullptr;
385 FilterProc* proc_2_3 =
nullptr;
386 FilterProc* proc_3_1 =
nullptr;
387 FilterProc* proc_3_2 =
nullptr;
388 FilterProc* proc_3_3 =
nullptr;
428 const void* srcBasePtr =
src.addr();
429 const size_t srcRB =
src.rowBytes();
430 void* dstBasePtr =
dst.writable_addr();
432 for (
int y = 0;
y <
dst.height();
y++) {
433 proc(dstBasePtr, srcBasePtr, srcRB,
dst.width());
434 srcBasePtr = (
const char*)srcBasePtr + srcRB * 2;
435 dstBasePtr = (
char*)dstBasePtr +
dst.rowBytes();
442 FilterProc* proc_1_2 =
nullptr;
443 FilterProc* proc_1_3 =
nullptr;
444 FilterProc* proc_2_1 =
nullptr;
445 FilterProc* proc_2_2 =
nullptr;
446 FilterProc* proc_2_3 =
nullptr;
447 FilterProc* proc_3_1 =
nullptr;
448 FilterProc* proc_3_2 =
nullptr;
449 FilterProc* proc_3_3 =
nullptr;
451 switch (
root.colorType()) {
454 proc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
455 proc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
456 proc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
457 proc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
458 proc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
459 proc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
460 proc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
461 proc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
464 proc_1_2 = downsample_1_2<ColorTypeFilter_565>;
465 proc_1_3 = downsample_1_3<ColorTypeFilter_565>;
466 proc_2_1 = downsample_2_1<ColorTypeFilter_565>;
467 proc_2_2 = downsample_2_2<ColorTypeFilter_565>;
468 proc_2_3 = downsample_2_3<ColorTypeFilter_565>;
469 proc_3_1 = downsample_3_1<ColorTypeFilter_565>;
470 proc_3_2 = downsample_3_2<ColorTypeFilter_565>;
471 proc_3_3 = downsample_3_3<ColorTypeFilter_565>;
474 proc_1_2 = downsample_1_2<ColorTypeFilter_4444>;
475 proc_1_3 = downsample_1_3<ColorTypeFilter_4444>;
476 proc_2_1 = downsample_2_1<ColorTypeFilter_4444>;
477 proc_2_2 = downsample_2_2<ColorTypeFilter_4444>;
478 proc_2_3 = downsample_2_3<ColorTypeFilter_4444>;
479 proc_3_1 = downsample_3_1<ColorTypeFilter_4444>;
480 proc_3_2 = downsample_3_2<ColorTypeFilter_4444>;
481 proc_3_3 = downsample_3_3<ColorTypeFilter_4444>;
486 proc_1_2 = downsample_1_2<ColorTypeFilter_8>;
487 proc_1_3 = downsample_1_3<ColorTypeFilter_8>;
488 proc_2_1 = downsample_2_1<ColorTypeFilter_8>;
489 proc_2_2 = downsample_2_2<ColorTypeFilter_8>;
490 proc_2_3 = downsample_2_3<ColorTypeFilter_8>;
491 proc_3_1 = downsample_3_1<ColorTypeFilter_8>;
492 proc_3_2 = downsample_3_2<ColorTypeFilter_8>;
493 proc_3_3 = downsample_3_3<ColorTypeFilter_8>;
497 proc_1_2 = downsample_1_2<ColorTypeFilter_RGBA_F16>;
498 proc_1_3 = downsample_1_3<ColorTypeFilter_RGBA_F16>;
499 proc_2_1 = downsample_2_1<ColorTypeFilter_RGBA_F16>;
500 proc_2_2 = downsample_2_2<ColorTypeFilter_RGBA_F16>;
501 proc_2_3 = downsample_2_3<ColorTypeFilter_RGBA_F16>;
502 proc_3_1 = downsample_3_1<ColorTypeFilter_RGBA_F16>;
503 proc_3_2 = downsample_3_2<ColorTypeFilter_RGBA_F16>;
504 proc_3_3 = downsample_3_3<ColorTypeFilter_RGBA_F16>;
507 proc_1_2 = downsample_1_2<ColorTypeFilter_88>;
508 proc_1_3 = downsample_1_3<ColorTypeFilter_88>;
509 proc_2_1 = downsample_2_1<ColorTypeFilter_88>;
510 proc_2_2 = downsample_2_2<ColorTypeFilter_88>;
511 proc_2_3 = downsample_2_3<ColorTypeFilter_88>;
512 proc_3_1 = downsample_3_1<ColorTypeFilter_88>;
513 proc_3_2 = downsample_3_2<ColorTypeFilter_88>;
514 proc_3_3 = downsample_3_3<ColorTypeFilter_88>;
517 proc_1_2 = downsample_1_2<ColorTypeFilter_1616>;
518 proc_1_3 = downsample_1_3<ColorTypeFilter_1616>;
519 proc_2_1 = downsample_2_1<ColorTypeFilter_1616>;
520 proc_2_2 = downsample_2_2<ColorTypeFilter_1616>;
521 proc_2_3 = downsample_2_3<ColorTypeFilter_1616>;
522 proc_3_1 = downsample_3_1<ColorTypeFilter_1616>;
523 proc_3_2 = downsample_3_2<ColorTypeFilter_1616>;
524 proc_3_3 = downsample_3_3<ColorTypeFilter_1616>;
527 proc_1_2 = downsample_1_2<ColorTypeFilter_16>;
528 proc_1_3 = downsample_1_3<ColorTypeFilter_16>;
529 proc_2_1 = downsample_2_1<ColorTypeFilter_16>;
530 proc_2_2 = downsample_2_2<ColorTypeFilter_16>;
531 proc_2_3 = downsample_2_3<ColorTypeFilter_16>;
532 proc_3_1 = downsample_3_1<ColorTypeFilter_16>;
533 proc_3_2 = downsample_3_2<ColorTypeFilter_16>;
534 proc_3_3 = downsample_3_3<ColorTypeFilter_16>;
538 proc_1_2 = downsample_1_2<ColorTypeFilter_1010102>;
539 proc_1_3 = downsample_1_3<ColorTypeFilter_1010102>;
540 proc_2_1 = downsample_2_1<ColorTypeFilter_1010102>;
541 proc_2_2 = downsample_2_2<ColorTypeFilter_1010102>;
542 proc_2_3 = downsample_2_3<ColorTypeFilter_1010102>;
543 proc_3_1 = downsample_3_1<ColorTypeFilter_1010102>;
544 proc_3_2 = downsample_3_2<ColorTypeFilter_1010102>;
545 proc_3_3 = downsample_3_3<ColorTypeFilter_1010102>;
548 proc_1_2 = downsample_1_2<ColorTypeFilter_Alpha_F16>;
549 proc_1_3 = downsample_1_3<ColorTypeFilter_Alpha_F16>;
550 proc_2_1 = downsample_2_1<ColorTypeFilter_Alpha_F16>;
551 proc_2_2 = downsample_2_2<ColorTypeFilter_Alpha_F16>;
552 proc_2_3 = downsample_2_3<ColorTypeFilter_Alpha_F16>;
553 proc_3_1 = downsample_3_1<ColorTypeFilter_Alpha_F16>;
554 proc_3_2 = downsample_3_2<ColorTypeFilter_Alpha_F16>;
555 proc_3_3 = downsample_3_3<ColorTypeFilter_Alpha_F16>;
558 proc_1_2 = downsample_1_2<ColorTypeFilter_F16F16>;
559 proc_1_3 = downsample_1_3<ColorTypeFilter_F16F16>;
560 proc_2_1 = downsample_2_1<ColorTypeFilter_F16F16>;
561 proc_2_2 = downsample_2_2<ColorTypeFilter_F16F16>;
562 proc_2_3 = downsample_2_3<ColorTypeFilter_F16F16>;
563 proc_3_1 = downsample_3_1<ColorTypeFilter_F16F16>;
564 proc_3_2 = downsample_3_2<ColorTypeFilter_F16F16>;
565 proc_3_3 = downsample_3_3<ColorTypeFilter_F16F16>;
568 proc_1_2 = downsample_1_2<ColorTypeFilter_16161616>;
569 proc_1_3 = downsample_1_3<ColorTypeFilter_16161616>;
570 proc_2_1 = downsample_2_1<ColorTypeFilter_16161616>;
571 proc_2_2 = downsample_2_2<ColorTypeFilter_16161616>;
572 proc_2_3 = downsample_2_3<ColorTypeFilter_16161616>;
573 proc_3_1 = downsample_3_1<ColorTypeFilter_16161616>;
574 proc_3_2 = downsample_3_2<ColorTypeFilter_16161616>;
575 proc_3_3 = downsample_3_3<ColorTypeFilter_16161616>;
592 auto sampler = std::make_unique<HQDownSampler>();
593 sampler->proc_1_2 = proc_1_2;
594 sampler->proc_1_3 = proc_1_3;
595 sampler->proc_2_1 = proc_2_1;
596 sampler->proc_2_2 = proc_2_2;
597 sampler->proc_2_3 = proc_2_3;
598 sampler->proc_3_1 = proc_3_1;
599 sampler->proc_3_2 = proc_3_2;
600 sampler->proc_3_3 = proc_3_3;
#define SK_G16_MASK_IN_PLACE
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
@ kRGBA_10x6_SkColorType
pixel with 10 used bits (most significant) followed by 6 unused
@ kBGR_101010x_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
@ kSRGBA_8888_SkColorType
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
@ kBGRA_10101010_XR_SkColorType
pixel with 10 bits each for blue, green, red, alpha; in 64-bit word, extended range
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
@ kBGRA_1010102_SkColorType
10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
@ kA16_float_SkColorType
pixel with a half float for alpha
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
@ kUnknown_SkColorType
uninitialized
@ kR16G16_float_SkColorType
pixel with a half float for red and green
static std::unique_ptr< SkMipmapDownSampler > MakeDownSampler(const SkPixmap &)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
SIN Vec< N, float > from_half(const Vec< N, uint16_t > &x)
SIN Vec< N, uint16_t > to_half(const Vec< N, float > &x)
virtual void buildLevel(const SkPixmap &dst, const SkPixmap &src)=0
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)