OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkComposeShader.h" | 8 #include "SkComposeShader.h" |
9 #include "SkColorFilter.h" | 9 #include "SkColorFilter.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
11 #include "SkColorShader.h" | 11 #include "SkColorShader.h" |
12 #include "SkReadBuffer.h" | 12 #include "SkReadBuffer.h" |
13 #include "SkWriteBuffer.h" | 13 #include "SkWriteBuffer.h" |
14 #include "SkXfermode.h" | 14 #include "SkXfermode.h" |
15 #include "SkString.h" | 15 #include "SkString.h" |
16 | 16 |
17 /////////////////////////////////////////////////////////////////////////////// | 17 /////////////////////////////////////////////////////////////////////////////// |
18 | 18 |
19 SkComposeShader::SkComposeShader(sk_sp<SkShader> sA, sk_sp<SkShader> sB, SkXferm
ode* mode) | |
20 : fShaderA(std::move(sA)) | |
21 , fShaderB(std::move(sB)) | |
22 { | |
23 // mode may be null | |
24 fMode = mode; | |
25 SkSafeRef(mode); | |
26 } | |
27 | |
28 SkComposeShader::~SkComposeShader() { | |
29 SkSafeUnref(fMode); | |
30 } | |
31 | |
32 size_t SkComposeShader::onContextSize(const ContextRec& rec) const { | 19 size_t SkComposeShader::onContextSize(const ContextRec& rec) const { |
33 return sizeof(ComposeShaderContext) | 20 return sizeof(ComposeShaderContext) |
34 + fShaderA->contextSize(rec) | 21 + fShaderA->contextSize(rec) |
35 + fShaderB->contextSize(rec); | 22 + fShaderB->contextSize(rec); |
36 } | 23 } |
37 | 24 |
38 class SkAutoAlphaRestore { | 25 class SkAutoAlphaRestore { |
39 public: | 26 public: |
40 SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) { | 27 SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) { |
41 fAlpha = paint->getAlpha(); | 28 fAlpha = paint->getAlpha(); |
42 fPaint = paint; | 29 fPaint = paint; |
43 paint->setAlpha(newAlpha); | 30 paint->setAlpha(newAlpha); |
44 } | 31 } |
45 | 32 |
46 ~SkAutoAlphaRestore() { | 33 ~SkAutoAlphaRestore() { |
47 fPaint->setAlpha(fAlpha); | 34 fPaint->setAlpha(fAlpha); |
48 } | 35 } |
49 private: | 36 private: |
50 SkPaint* fPaint; | 37 SkPaint* fPaint; |
51 uint8_t fAlpha; | 38 uint8_t fAlpha; |
52 }; | 39 }; |
53 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore) | 40 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore) |
54 | 41 |
55 SkFlattenable* SkComposeShader::CreateProc(SkReadBuffer& buffer) { | 42 SkFlattenable* SkComposeShader::CreateProc(SkReadBuffer& buffer) { |
56 sk_sp<SkShader> shaderA(buffer.readShader()); | 43 sk_sp<SkShader> shaderA(buffer.readShader()); |
57 sk_sp<SkShader> shaderB(buffer.readShader()); | 44 sk_sp<SkShader> shaderB(buffer.readShader()); |
58 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode()); | 45 sk_sp<SkXfermode> mode(buffer.readXfermode()); |
59 if (!shaderA || !shaderB) { | 46 if (!shaderA || !shaderB) { |
60 return nullptr; | 47 return nullptr; |
61 } | 48 } |
62 return new SkComposeShader(std::move(shaderA), std::move(shaderB), mode); | 49 return new SkComposeShader(std::move(shaderA), std::move(shaderB), std::move
(mode)); |
63 } | 50 } |
64 | 51 |
65 void SkComposeShader::flatten(SkWriteBuffer& buffer) const { | 52 void SkComposeShader::flatten(SkWriteBuffer& buffer) const { |
66 buffer.writeFlattenable(fShaderA.get()); | 53 buffer.writeFlattenable(fShaderA.get()); |
67 buffer.writeFlattenable(fShaderB.get()); | 54 buffer.writeFlattenable(fShaderB.get()); |
68 buffer.writeFlattenable(fMode); | 55 buffer.writeFlattenable(fMode.get()); |
69 } | 56 } |
70 | 57 |
71 template <typename T> void safe_call_destructor(T* obj) { | 58 template <typename T> void safe_call_destructor(T* obj) { |
72 if (obj) { | 59 if (obj) { |
73 obj->~T(); | 60 obj->~T(); |
74 } | 61 } |
75 } | 62 } |
76 | 63 |
77 SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void*
storage) const { | 64 SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void*
storage) const { |
78 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); | 65 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 | 100 |
114 SkComposeShader::ComposeShaderContext::~ComposeShaderContext() { | 101 SkComposeShader::ComposeShaderContext::~ComposeShaderContext() { |
115 fShaderContextA->~Context(); | 102 fShaderContextA->~Context(); |
116 fShaderContextB->~Context(); | 103 fShaderContextB->~Context(); |
117 } | 104 } |
118 | 105 |
119 bool SkComposeShader::asACompose(ComposeRec* rec) const { | 106 bool SkComposeShader::asACompose(ComposeRec* rec) const { |
120 if (rec) { | 107 if (rec) { |
121 rec->fShaderA = fShaderA.get(); | 108 rec->fShaderA = fShaderA.get(); |
122 rec->fShaderB = fShaderB.get(); | 109 rec->fShaderB = fShaderB.get(); |
123 rec->fMode = fMode; | 110 rec->fMode = fMode.get(); |
124 } | 111 } |
125 return true; | 112 return true; |
126 } | 113 } |
127 | 114 |
128 | 115 |
129 // larger is better (fewer times we have to loop), but we shouldn't | 116 // larger is better (fewer times we have to loop), but we shouldn't |
130 // take up too much stack-space (each element is 4 bytes) | 117 // take up too much stack-space (each element is 4 bytes) |
131 #define TMP_COLOR_COUNT 64 | 118 #define TMP_COLOR_COUNT 64 |
132 | 119 |
133 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re
sult[], int count) { | 120 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re
sult[], int count) { |
134 SkShader::Context* shaderContextA = fShaderContextA; | 121 SkShader::Context* shaderContextA = fShaderContextA; |
135 SkShader::Context* shaderContextB = fShaderContextB; | 122 SkShader::Context* shaderContextB = fShaderContextB; |
136 SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode
; | 123 SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode
.get(); |
137 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); | 124 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); |
138 | 125 |
139 SkPMColor tmp[TMP_COLOR_COUNT]; | 126 SkPMColor tmp[TMP_COLOR_COUNT]; |
140 | 127 |
141 if (nullptr == mode) { // implied SRC_OVER | 128 if (nullptr == mode) { // implied SRC_OVER |
142 // TODO: when we have a good test-case, should use SkBlitRow::Proc32 | 129 // TODO: when we have a good test-case, should use SkBlitRow::Proc32 |
143 // for these loops | 130 // for these loops |
144 do { | 131 do { |
145 int n = count; | 132 int n = count; |
146 if (n > TMP_COLOR_COUNT) { | 133 if (n > TMP_COLOR_COUNT) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 235 |
249 this->INHERITED::toString(str); | 236 this->INHERITED::toString(str); |
250 | 237 |
251 str->append(")"); | 238 str->append(")"); |
252 } | 239 } |
253 #endif | 240 #endif |
254 | 241 |
255 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 242 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
256 | 243 |
257 sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader>
src, | 244 sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader>
src, |
258 SkXfermode* xfer) { | 245 sk_sp<SkXfermode> xfer) { |
259 if (!dst || !src) { | 246 if (!dst || !src) { |
260 return nullptr; | 247 return nullptr; |
261 } | 248 } |
262 return sk_make_sp<SkComposeShader>(std::move(dst), std::move(src), xfer); | 249 return sk_make_sp<SkComposeShader>(std::move(dst), std::move(src), std::move
(xfer)); |
263 } | 250 } |
264 | 251 |
265 sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader>
src, | 252 sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader>
src, |
266 SkXfermode::Mode mode) { | 253 SkXfermode::Mode mode) { |
267 SkAutoTUnref<SkXfermode> xfer(SkXfermode::Create(mode)); | 254 return MakeComposeShader(std::move(dst), std::move(src), SkXfermode::Make(mo
de)); |
268 return MakeComposeShader(std::move(dst), std::move(src), xfer); | |
269 } | 255 } |
OLD | NEW |