OLD | NEW |
---|---|
(Empty) | |
1 | |
2 /* | |
3 * Copyright 2006 The Android Open Source Project | |
4 * | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the LICENSE file. | |
herb_g
2016/02/19 21:36:46
I think this should be:
/*
* Copyright 2016 Googl
reed1
2016/02/20 19:37:17
Done.
| |
7 */ | |
8 | |
9 | |
10 #include "SkSpriteBlitter.h" | |
11 #include "SkColorFilter.h" | |
12 #include "SkHalf.h" | |
13 #include "SkNx.h" | |
14 #include "SkPM4f.h" | |
15 #include "SkPM4fPriv.h" | |
16 #include "SkTemplates.h" | |
17 #include "SkUtils.h" | |
18 #include "SkXfermode.h" | |
19 | |
20 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
21 | |
22 typedef void (*SkLoadSpanProc)(const SkPixmap&, int x, int y, SkPM4f span[], int count); | |
23 | |
24 static void load_l32(const SkPixmap& src, int x, int y, SkPM4f span[], int count ) { | |
25 SkASSERT(count > 0); | |
26 const uint32_t* addr = src.addr32(x, y); | |
27 SkASSERT(src.addr32(x + count - 1, y)); | |
28 | |
29 for (int i = 0; i < count; ++i) { | |
30 (SkNx_cast<float>(Sk4b::Load(&addr[i])) * Sk4f(1.0f/255)).store(span[i]. fVec); | |
f(malita)
2016/02/19 20:38:43
Is there a benefit to loading Sk4f(1/255) outside
mtklein
2016/02/19 20:41:17
It's very hoistable. I'd only move it out of the
| |
31 } | |
32 } | |
33 | |
34 static void load_s32(const SkPixmap& src, int x, int y, SkPM4f span[], int count ) { | |
35 SkASSERT(count > 0); | |
36 const uint32_t* addr = src.addr32(x, y); | |
37 SkASSERT(src.addr32(x + count - 1, y)); | |
38 | |
39 for (int i = 0; i < count; ++i) { | |
40 srgb_to_linear(SkNx_cast<float>(Sk4b::Load(&addr[i])) * Sk4f(1.0f/255)). store(span[i].fVec); | |
41 } | |
42 } | |
43 | |
44 static void load_f16(const SkPixmap& src, int x, int y, SkPM4f span[], int count ) { | |
45 SkASSERT(count > 0); | |
46 const uint64_t* addr = src.addr64(x, y); | |
47 SkASSERT(src.addr64(x + count - 1, y)); | |
48 | |
49 for (int i = 0; i < count; ++i) { | |
50 SkHalfToFloat_01(addr[i]).store(span[i].fVec); | |
51 } | |
52 } | |
53 | |
54 static SkLoadSpanProc choose_loadspanproc(const SkImageInfo& info) { | |
55 switch (info.colorType()) { | |
56 case kN32_SkColorType: | |
57 return info.isSRGB() ? load_s32 : load_l32; | |
58 case kRGBA_F16_SkColorType: | |
59 return load_f16; | |
60 default: | |
61 return nullptr; | |
62 } | |
63 } | |
64 | |
65 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
66 | |
67 typedef void (*SkFilterSpanProc)(const SkPaint& paint, SkPM4f span[], int count) ; | |
68 | |
69 static void noop_filterspan(const SkPaint& paint, SkPM4f[], int) { | |
70 SkASSERT(!paint.getColorFilter()); | |
71 SkASSERT(0xFF == paint.getAlpha()); | |
72 } | |
73 | |
74 static void alpha_filterspan(const SkPaint& paint, SkPM4f span[], int count) { | |
75 SkASSERT(!paint.getColorFilter()); | |
76 SkASSERT(0xFF != paint.getAlpha()); | |
77 const Sk4f scale = Sk4f(paint.getAlpha() * (1.0f/255)); | |
78 for (int i = 0; i < count; ++i) { | |
79 (Sk4f::Load(span[i].fVec) * scale).store(span[i].fVec); | |
80 } | |
81 } | |
82 | |
83 static void colorfilter_filterspan(const SkPaint& paint, SkPM4f span[], int coun t) { | |
84 SkASSERT(paint.getColorFilter()); | |
85 SkASSERT(0xFF == paint.getAlpha()); | |
86 paint.getColorFilter()->filterSpan4f(span, count, span); | |
87 } | |
88 | |
89 static void colorfilter_alpha_filterspan(const SkPaint& paint, SkPM4f span[], in t count) { | |
90 SkASSERT(paint.getColorFilter()); | |
91 SkASSERT(0xFF != paint.getAlpha()); | |
92 alpha_filterspan(paint, span, count); | |
93 paint.getColorFilter()->filterSpan4f(span, count, span); | |
94 } | |
95 | |
96 static SkFilterSpanProc choose_filterspanproc(const SkPaint& paint) { | |
97 if (paint.getColorFilter()) { | |
98 return 0xFF == paint.getAlpha() ? colorfilter_filterspan : colorfilter_a lpha_filterspan; | |
99 } else { | |
100 return 0xFF == paint.getAlpha() ? noop_filterspan : alpha_filterspan; | |
101 } | |
102 } | |
103 | |
104 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
105 | |
106 static SkXfermode::Mode get_mode(const SkXfermode* xfer) { | |
107 SkXfermode::Mode mode; | |
108 if (!SkXfermode::AsMode(xfer, &mode)) { | |
109 mode = SkXfermode::kSrcOver_Mode; | |
110 } | |
111 return mode; | |
112 } | |
113 | |
114 class Sprite_D64 : public SkSpriteBlitter { | |
115 public: | |
116 Sprite_D64(const SkPixmap& src, const SkPaint& paint) : INHERITED(src) { | |
117 fLoader = choose_loadspanproc(src.info()); | |
118 fFilter = choose_filterspanproc(paint); | |
119 fState = { paint.getXfermode(), SkXfermode::kDstIsFloat16_U64Flag }; | |
120 fXfer = SkXfermode::GetU64ProcN(get_mode(fState.fXfer), fState.fFlags); | |
121 fBuffer = new SkPM4f[src.width()]; | |
122 } | |
123 | |
124 ~Sprite_D64() { | |
125 delete[] fBuffer; | |
126 } | |
127 | |
128 void blitRect(int x, int y, int width, int height) override { | |
129 SkASSERT(width > 0 && height > 0); | |
130 uint64_t* SK_RESTRICT dst = fDst.writable_addr64(x, y); | |
131 size_t dstRB = fDst.rowBytes(); | |
132 | |
133 for (int bottom = y + height; y < bottom; ++y) { | |
134 fLoader(fSource, x - fLeft, y - fTop, fBuffer, width); | |
135 fFilter(*fPaint, fBuffer, width); | |
136 fXfer(fState, dst, fBuffer, width, nullptr); | |
137 dst = (uint64_t* SK_RESTRICT)((char*)dst + dstRB); | |
138 } | |
139 } | |
140 | |
141 protected: | |
142 SkLoadSpanProc fLoader; | |
143 SkFilterSpanProc fFilter; | |
144 SkXfermode::U64State fState; | |
145 SkXfermode::U64ProcN fXfer; | |
146 SkPM4f* fBuffer; | |
f(malita)
2016/02/19 20:38:43
SkAutoTMalloc?
| |
147 | |
148 private: | |
149 typedef SkSpriteBlitter INHERITED; | |
150 }; | |
151 | |
152 | |
153 SkSpriteBlitter* SkSpriteBlitter::ChooseD64(const SkPixmap& source, const SkPain t& paint, | |
154 SkTBlitterAllocator* allocator) { | |
155 SkASSERT(allocator != nullptr); | |
156 | |
157 if (paint.getMaskFilter() != nullptr) { | |
158 return nullptr; | |
159 } | |
160 | |
161 switch (source.colorType()) { | |
162 case kN32_SkColorType: | |
163 case kRGBA_F16_SkColorType: | |
164 return allocator->createT<Sprite_D64>(source, paint); | |
165 default: | |
166 return nullptr; | |
167 } | |
168 } | |
OLD | NEW |