1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkSpriteBlitter.h"
9 #include "SkArenaAlloc.h"
10 #include "SkSpanProcs.h"
11 #include "SkTemplates.h"
12 #include "SkXfermodePriv.h"
13
14 class Sprite_4f : public SkSpriteBlitter {
15 public:
Sprite_4f(const SkPixmap & src,const SkPaint & paint)16 Sprite_4f(const SkPixmap& src, const SkPaint& paint) : INHERITED(src) {
17 fMode = paint.getBlendMode();
18 fLoader = SkLoadSpanProc_Choose(src.info());
19 fFilter = SkFilterSpanProc_Choose(paint);
20 fBuffer.reset(src.width());
21 }
22
23 protected:
24 SkBlendMode fMode;
25 SkLoadSpanProc fLoader;
26 SkFilterSpanProc fFilter;
27 SkAutoTMalloc<SkPM4f> fBuffer;
28
29 private:
30 typedef SkSpriteBlitter INHERITED;
31 };
32
33 ///////////////////////////////////////////////////////////////////////////////////////////////////
34
35 class Sprite_F16 : public Sprite_4f {
36 public:
Sprite_F16(const SkPixmap & src,const SkPaint & paint)37 Sprite_F16(const SkPixmap& src, const SkPaint& paint) : INHERITED(src, paint) {
38 uint32_t flags = 0;
39 if (src.isOpaque()) {
40 flags |= SkXfermode::kSrcIsOpaque_F16Flag;
41 }
42 fWriter = SkXfermode::GetF16Proc(fMode, flags);
43 }
44
blitRect(int x,int y,int width,int height)45 void blitRect(int x, int y, int width, int height) override {
46 SkASSERT(width > 0 && height > 0);
47 uint64_t* SK_RESTRICT dst = fDst.writable_addr64(x, y);
48 size_t dstRB = fDst.rowBytes();
49
50 for (int bottom = y + height; y < bottom; ++y) {
51 fLoader(fSource, x - fLeft, y - fTop, fBuffer, width);
52 fFilter(*fPaint, fBuffer, width);
53 fWriter(fMode, dst, fBuffer, width, nullptr);
54 dst = (uint64_t* SK_RESTRICT)((char*)dst + dstRB);
55 }
56 }
57
58 private:
59 SkXfermode::F16Proc fWriter;
60
61 typedef Sprite_4f INHERITED;
62 };
63
64
ChooseF16(const SkPixmap & source,const SkPaint & paint,SkArenaAlloc * allocator)65 SkSpriteBlitter* SkSpriteBlitter::ChooseF16(const SkPixmap& source, const SkPaint& paint,
66 SkArenaAlloc* allocator) {
67 SkASSERT(allocator != nullptr);
68
69 if (paint.getMaskFilter() != nullptr) {
70 return nullptr;
71 }
72
73 switch (source.colorType()) {
74 case kN32_SkColorType:
75 case kRGBA_F16_SkColorType:
76 return allocator->make<Sprite_F16>(source, paint);
77 default:
78 return nullptr;
79 }
80 }
81
82 ///////////////////////////////////////////////////////////////////////////////////////////////////
83
84 class Sprite_sRGB : public Sprite_4f {
85 public:
Sprite_sRGB(const SkPixmap & src,const SkPaint & paint)86 Sprite_sRGB(const SkPixmap& src, const SkPaint& paint) : INHERITED(src, paint) {
87 uint32_t flags = SkXfermode::kDstIsSRGB_D32Flag;
88 if (src.isOpaque()) {
89 flags |= SkXfermode::kSrcIsOpaque_D32Flag;
90 }
91 fWriter = SkXfermode::GetD32Proc(fMode, flags);
92 }
93
blitRect(int x,int y,int width,int height)94 void blitRect(int x, int y, int width, int height) override {
95 SkASSERT(width > 0 && height > 0);
96 uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
97 size_t dstRB = fDst.rowBytes();
98
99 for (int bottom = y + height; y < bottom; ++y) {
100 fLoader(fSource, x - fLeft, y - fTop, fBuffer, width);
101 fFilter(*fPaint, fBuffer, width);
102 fWriter(fMode, dst, fBuffer, width, nullptr);
103 dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
104 }
105 }
106
107 protected:
108 SkXfermode::D32Proc fWriter;
109
110 private:
111 typedef Sprite_4f INHERITED;
112 };
113
114
ChooseS32(const SkPixmap & source,const SkPaint & paint,SkArenaAlloc * allocator)115 SkSpriteBlitter* SkSpriteBlitter::ChooseS32(const SkPixmap& source, const SkPaint& paint,
116 SkArenaAlloc* allocator) {
117 SkASSERT(allocator != nullptr);
118
119 if (paint.getMaskFilter() != nullptr) {
120 return nullptr;
121 }
122
123 switch (source.colorType()) {
124 case kN32_SkColorType:
125 case kRGBA_F16_SkColorType:
126 return allocator->make<Sprite_sRGB>(source, paint);
127 default:
128 return nullptr;
129 }
130 }
131