• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
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 "include/core/SkColorFilter.h"
9 #include "include/core/SkPaint.h"
10 #include "include/private/SkColorData.h"
11 #include "include/private/base/SkTemplates.h"
12 #include "src/base/SkArenaAlloc.h"
13 #include "src/core/SkBlitRow.h"
14 #include "src/core/SkSpriteBlitter.h"
15 #include "src/core/SkXfermodePriv.h"
16 
17 ///////////////////////////////////////////////////////////////////////////////
18 
19 class Sprite_D32_S32 : public SkSpriteBlitter {
20 public:
Sprite_D32_S32(const SkPixmap & src,U8CPU alpha)21     Sprite_D32_S32(const SkPixmap& src, U8CPU alpha)  : INHERITED(src) {
22         SkASSERT(src.colorType() == kN32_SkColorType);
23 
24         unsigned flags32 = 0;
25         if (255 != alpha) {
26             flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
27         }
28         if (!src.isOpaque()) {
29             flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
30         }
31 
32         fProc32 = SkBlitRow::Factory32(flags32);
33         fAlpha = alpha;
34     }
35 
blitRect(int x,int y,int width,int height)36     void blitRect(int x, int y, int width, int height) override {
37         SkASSERT(width > 0 && height > 0);
38         uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
39         const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
40         size_t dstRB = fDst.rowBytes();
41         size_t srcRB = fSource.rowBytes();
42         SkBlitRow::Proc32 proc = fProc32;
43         U8CPU             alpha = fAlpha;
44 
45         do {
46             proc(dst, src, width, alpha);
47             dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
48             src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
49         } while (--height != 0);
50     }
51 
52 private:
53     SkBlitRow::Proc32   fProc32;
54     U8CPU               fAlpha;
55 
56     using INHERITED = SkSpriteBlitter;
57 };
58 
59 ///////////////////////////////////////////////////////////////////////////////
60 
61 class Sprite_D32_S32A_Xfer: public SkSpriteBlitter {
62 public:
Sprite_D32_S32A_Xfer(const SkPixmap & source,const SkPaint & paint)63     Sprite_D32_S32A_Xfer(const SkPixmap& source, const SkPaint& paint) : SkSpriteBlitter(source) {
64         fXfermode = SkXfermode::Peek(paint.getBlendMode_or(SkBlendMode::kSrcOver));
65         SkASSERT(fXfermode);
66     }
67 
blitRect(int x,int y,int width,int height)68     void blitRect(int x, int y, int width, int height) override {
69         SkASSERT(width > 0 && height > 0);
70         uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
71         const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
72         size_t dstRB = fDst.rowBytes();
73         size_t srcRB = fSource.rowBytes();
74         SkXfermode* xfermode = fXfermode;
75 
76         do {
77             xfermode->xfer32(dst, src, width, nullptr);
78 
79             dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
80             src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
81         } while (--height != 0);
82     }
83 
84 protected:
85     SkXfermode* fXfermode;
86 
87 private:
88     using INHERITED = SkSpriteBlitter;
89 };
90 
91 ///////////////////////////////////////////////////////////////////////////////
92 
ChooseL32(const SkPixmap & source,const SkPaint & paint,SkArenaAlloc * allocator)93 SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPaint& paint,
94                                             SkArenaAlloc* allocator) {
95     SkASSERT(allocator != nullptr);
96 
97     if (paint.getColorFilter() != nullptr) {
98         return nullptr;
99     }
100     if (paint.getMaskFilter() != nullptr) {
101         return nullptr;
102     }
103     if (!paint.asBlendMode()) {
104         return nullptr;
105     }
106 
107     U8CPU alpha = paint.getAlpha();
108 
109     if (source.colorType() == kN32_SkColorType) {
110         if (paint.isSrcOver()) {
111             // this can handle alpha, but not xfermode
112             return allocator->make<Sprite_D32_S32>(source, alpha);
113         }
114         if (255 == alpha) {
115             // this can handle an xfermode, but not alpha
116             return allocator->make<Sprite_D32_S32A_Xfer>(source, paint);
117         }
118     }
119     return nullptr;
120 }
121