Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1586)

Side by Side Diff: src/core/SkSpriteBlitterU64.cpp

Issue 1685203002: lots of sRGB and F16 blits (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: xfermodes gm now works in srgb and f16 using saveLayer Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkSpriteBlitter.h ('k') | src/core/SkXfermode.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 }
OLDNEW
« no previous file with comments | « src/core/SkSpriteBlitter.h ('k') | src/core/SkXfermode.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698