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