epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 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 | |
Herb Derby | 83e939b | 2017-02-07 14:25:11 -0500 | [diff] [blame] | 8 | #include "SkArenaAlloc.h" |
Mike Reed | 9959f72 | 2017-05-15 09:34:22 -0400 | [diff] [blame] | 9 | #include "SkBlendModePriv.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 10 | #include "SkComposeShader.h" |
| 11 | #include "SkColorFilter.h" |
| 12 | #include "SkColorPriv.h" |
reed@google.com | 573f22b | 2011-11-30 19:17:15 +0000 | [diff] [blame] | 13 | #include "SkColorShader.h" |
Mike Reed | 9959f72 | 2017-05-15 09:34:22 -0400 | [diff] [blame] | 14 | #include "SkRasterPipeline.h" |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 15 | #include "SkReadBuffer.h" |
| 16 | #include "SkWriteBuffer.h" |
robertphillips@google.com | 76f9e93 | 2013-01-15 20:17:47 +0000 | [diff] [blame] | 17 | #include "SkString.h" |
Mike Reed | 9959f72 | 2017-05-15 09:34:22 -0400 | [diff] [blame] | 18 | #include "../jumper/SkJumper.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 19 | |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 20 | sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src, |
| 21 | SkBlendMode mode) { |
| 22 | if (!src || !dst) { |
| 23 | return nullptr; |
| 24 | } |
| 25 | if (SkBlendMode::kSrc == mode) { |
| 26 | return src; |
| 27 | } |
| 28 | if (SkBlendMode::kDst == mode) { |
| 29 | return dst; |
| 30 | } |
| 31 | return sk_sp<SkShader>(new SkComposeShader(std::move(dst), std::move(src), mode)); |
| 32 | } |
| 33 | |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 34 | /////////////////////////////////////////////////////////////////////////////// |
| 35 | |
reed | 60c9b58 | 2016-04-03 09:11:13 -0700 | [diff] [blame] | 36 | sk_sp<SkFlattenable> SkComposeShader::CreateProc(SkReadBuffer& buffer) { |
reed | 8a21c9f | 2016-03-08 18:50:00 -0800 | [diff] [blame] | 37 | sk_sp<SkShader> shaderA(buffer.readShader()); |
| 38 | sk_sp<SkShader> shaderB(buffer.readShader()); |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 39 | SkBlendMode mode; |
| 40 | if (buffer.isVersionLT(SkReadBuffer::kXfermodeToBlendMode2_Version)) { |
| 41 | sk_sp<SkXfermode> xfer = buffer.readXfermode(); |
| 42 | mode = xfer ? xfer->blend() : SkBlendMode::kSrcOver; |
| 43 | } else { |
| 44 | mode = (SkBlendMode)buffer.read32(); |
| 45 | } |
reed | 8a21c9f | 2016-03-08 18:50:00 -0800 | [diff] [blame] | 46 | if (!shaderA || !shaderB) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 47 | return nullptr; |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 48 | } |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 49 | return sk_make_sp<SkComposeShader>(std::move(shaderA), std::move(shaderB), mode); |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 50 | } |
| 51 | |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 52 | void SkComposeShader::flatten(SkWriteBuffer& buffer) const { |
reed | 8a21c9f | 2016-03-08 18:50:00 -0800 | [diff] [blame] | 53 | buffer.writeFlattenable(fShaderA.get()); |
| 54 | buffer.writeFlattenable(fShaderB.get()); |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 55 | buffer.write32((int)fMode); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 56 | } |
| 57 | |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 58 | SkShaderBase::Context* SkComposeShader::onMakeContext( |
Herb Derby | 83e939b | 2017-02-07 14:25:11 -0500 | [diff] [blame] | 59 | const ContextRec& rec, SkArenaAlloc* alloc) const |
| 60 | { |
commit-bot@chromium.org | e901b6d | 2014-05-01 19:31:31 +0000 | [diff] [blame] | 61 | // we preconcat our localMatrix (if any) with the device matrix |
| 62 | // before calling our sub-shaders |
commit-bot@chromium.org | e901b6d | 2014-05-01 19:31:31 +0000 | [diff] [blame] | 63 | SkMatrix tmpM; |
| 64 | tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); |
skia.committer@gmail.com | 9a40803 | 2014-05-02 03:03:47 +0000 | [diff] [blame] | 65 | |
commit-bot@chromium.org | 1ab536f | 2014-05-05 16:45:01 +0000 | [diff] [blame] | 66 | // Our sub-shaders need to see opaque, so by combining them we don't double-alphatize the |
| 67 | // result. ComposeShader itself will respect the alpha, and post-apply it after calling the |
| 68 | // sub-shaders. |
| 69 | SkPaint opaquePaint(*rec.fPaint); |
| 70 | opaquePaint.setAlpha(0xFF); |
skia.committer@gmail.com | edda70e | 2014-05-06 03:06:53 +0000 | [diff] [blame] | 71 | |
commit-bot@chromium.org | e901b6d | 2014-05-01 19:31:31 +0000 | [diff] [blame] | 72 | ContextRec newRec(rec); |
| 73 | newRec.fMatrix = &tmpM; |
commit-bot@chromium.org | 1ab536f | 2014-05-05 16:45:01 +0000 | [diff] [blame] | 74 | newRec.fPaint = &opaquePaint; |
commit-bot@chromium.org | e901b6d | 2014-05-01 19:31:31 +0000 | [diff] [blame] | 75 | |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 76 | SkShaderBase::Context* contextA = as_SB(fShaderA)->makeContext(newRec, alloc); |
| 77 | SkShaderBase::Context* contextB = as_SB(fShaderB)->makeContext(newRec, alloc); |
commit-bot@chromium.org | ce56d96 | 2014-05-05 18:39:18 +0000 | [diff] [blame] | 78 | if (!contextA || !contextB) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 79 | return nullptr; |
commit-bot@chromium.org | ce56d96 | 2014-05-05 18:39:18 +0000 | [diff] [blame] | 80 | } |
commit-bot@chromium.org | 87fcd95 | 2014-04-23 19:10:51 +0000 | [diff] [blame] | 81 | |
Herb Derby | 83e939b | 2017-02-07 14:25:11 -0500 | [diff] [blame] | 82 | return alloc->make<ComposeShaderContext>(*this, rec, contextA, contextB); |
reed@google.com | a641f3f | 2012-12-13 22:16:30 +0000 | [diff] [blame] | 83 | } |
| 84 | |
Mike Klein | 2814d91 | 2017-05-10 12:35:51 -0400 | [diff] [blame] | 85 | sk_sp<SkShader> SkComposeShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const { |
| 86 | return SkShader::MakeComposeShader(xformer->apply(fShaderA.get()), |
| 87 | xformer->apply(fShaderB.get()), fMode); |
| 88 | } |
| 89 | |
commit-bot@chromium.org | 87fcd95 | 2014-04-23 19:10:51 +0000 | [diff] [blame] | 90 | SkComposeShader::ComposeShaderContext::ComposeShaderContext( |
commit-bot@chromium.org | e901b6d | 2014-05-01 19:31:31 +0000 | [diff] [blame] | 91 | const SkComposeShader& shader, const ContextRec& rec, |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 92 | SkShaderBase::Context* contextA, SkShaderBase::Context* contextB) |
commit-bot@chromium.org | e901b6d | 2014-05-01 19:31:31 +0000 | [diff] [blame] | 93 | : INHERITED(shader, rec) |
commit-bot@chromium.org | 87fcd95 | 2014-04-23 19:10:51 +0000 | [diff] [blame] | 94 | , fShaderContextA(contextA) |
| 95 | , fShaderContextB(contextB) {} |
| 96 | |
commit-bot@chromium.org | 7959055 | 2014-05-13 18:14:45 +0000 | [diff] [blame] | 97 | bool SkComposeShader::asACompose(ComposeRec* rec) const { |
| 98 | if (rec) { |
Mike Reed | faba371 | 2016-11-03 14:45:31 -0400 | [diff] [blame] | 99 | rec->fShaderA = fShaderA.get(); |
| 100 | rec->fShaderB = fShaderB.get(); |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 101 | rec->fBlendMode = fMode; |
commit-bot@chromium.org | 7959055 | 2014-05-13 18:14:45 +0000 | [diff] [blame] | 102 | } |
| 103 | return true; |
| 104 | } |
| 105 | |
Florin Malita | 7d022e0 | 2017-05-15 15:06:39 -0400 | [diff] [blame] | 106 | bool SkComposeShader::isRasterPipelineOnly() const { |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 107 | return as_SB(fShaderA)->isRasterPipelineOnly() || as_SB(fShaderB)->isRasterPipelineOnly(); |
Florin Malita | 7d022e0 | 2017-05-15 15:06:39 -0400 | [diff] [blame] | 108 | } |
| 109 | |
Mike Reed | 9959f72 | 2017-05-15 09:34:22 -0400 | [diff] [blame] | 110 | bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS, |
| 111 | SkArenaAlloc* alloc, const SkMatrix& ctm, |
| 112 | const SkPaint& paint, const SkMatrix* localM) const { |
| 113 | struct Storage { |
Mike Reed | 9959f72 | 2017-05-15 09:34:22 -0400 | [diff] [blame] | 114 | float fRGBA[4 * SkJumper_kMaxStride]; |
| 115 | float fAlpha; |
| 116 | }; |
| 117 | auto storage = alloc->make<Storage>(); |
| 118 | |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 119 | if (!as_SB(fShaderB)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // SRC |
Mike Reed | 9959f72 | 2017-05-15 09:34:22 -0400 | [diff] [blame] | 120 | return false; |
| 121 | } |
| 122 | // This outputs r,g,b,a, which we'll need later when we apply the mode, but we save it off now |
| 123 | // since fShaderB will overwrite them. |
| 124 | pipeline->append(SkRasterPipeline::store_rgba, storage->fRGBA); |
Mike Klein | 5df94d5 | 2017-06-01 14:43:51 -0400 | [diff] [blame] | 125 | |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 126 | if (!as_SB(fShaderA)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // DST |
Mike Reed | 9959f72 | 2017-05-15 09:34:22 -0400 | [diff] [blame] | 127 | return false; |
| 128 | } |
| 129 | // We now have our logical 'dst' in r,g,b,a, but we need it in dr,dg,db,da for the mode |
| 130 | // so we have to shuttle them. If we had a stage the would load_into_dst, then we could |
| 131 | // reverse the two shader invocations, and avoid this move... |
| 132 | pipeline->append(SkRasterPipeline::move_src_dst); |
| 133 | pipeline->append(SkRasterPipeline::load_rgba, storage->fRGBA); |
| 134 | |
| 135 | // Idea: should time this, and see if it helps to have custom versions of the overflow modes |
| 136 | // that do their own clamping, avoiding the overhead of an extra stage. |
| 137 | SkBlendMode_AppendStages(fMode, pipeline); |
| 138 | if (SkBlendMode_CanOverflow(fMode)) { |
| 139 | pipeline->append(SkRasterPipeline::clamp_a); |
| 140 | } |
| 141 | return true; |
| 142 | } |
commit-bot@chromium.org | 7959055 | 2014-05-13 18:14:45 +0000 | [diff] [blame] | 143 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 144 | // larger is better (fewer times we have to loop), but we shouldn't |
| 145 | // take up too much stack-space (each element is 4 bytes) |
| 146 | #define TMP_COLOR_COUNT 64 |
| 147 | |
commit-bot@chromium.org | 87fcd95 | 2014-04-23 19:10:51 +0000 | [diff] [blame] | 148 | void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) { |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 149 | auto* shaderContextA = fShaderContextA; |
| 150 | auto* shaderContextB = fShaderContextB; |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 151 | SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode; |
commit-bot@chromium.org | 87fcd95 | 2014-04-23 19:10:51 +0000 | [diff] [blame] | 152 | unsigned scale = SkAlpha255To256(this->getPaintAlpha()); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 153 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 154 | SkPMColor tmp[TMP_COLOR_COUNT]; |
| 155 | |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 156 | SkXfermode* xfer = SkXfermode::Peek(mode); |
| 157 | if (nullptr == xfer) { // implied SRC_OVER |
reed@android.com | c4cae85 | 2009-09-23 15:06:10 +0000 | [diff] [blame] | 158 | // TODO: when we have a good test-case, should use SkBlitRow::Proc32 |
| 159 | // for these loops |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 160 | do { |
| 161 | int n = count; |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 162 | if (n > TMP_COLOR_COUNT) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 163 | n = TMP_COLOR_COUNT; |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 164 | } |
| 165 | |
commit-bot@chromium.org | 87fcd95 | 2014-04-23 19:10:51 +0000 | [diff] [blame] | 166 | shaderContextA->shadeSpan(x, y, result, n); |
| 167 | shaderContextB->shadeSpan(x, y, tmp, n); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 168 | |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 169 | if (256 == scale) { |
| 170 | for (int i = 0; i < n; i++) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 171 | result[i] = SkPMSrcOver(tmp[i], result[i]); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 172 | } |
| 173 | } else { |
| 174 | for (int i = 0; i < n; i++) { |
| 175 | result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]), |
| 176 | scale); |
| 177 | } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 178 | } |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 179 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 180 | result += n; |
| 181 | x += n; |
| 182 | count -= n; |
| 183 | } while (count > 0); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 184 | } else { // use mode for the composition |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 185 | do { |
| 186 | int n = count; |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 187 | if (n > TMP_COLOR_COUNT) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 188 | n = TMP_COLOR_COUNT; |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 189 | } |
| 190 | |
commit-bot@chromium.org | 87fcd95 | 2014-04-23 19:10:51 +0000 | [diff] [blame] | 191 | shaderContextA->shadeSpan(x, y, result, n); |
| 192 | shaderContextB->shadeSpan(x, y, tmp, n); |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 193 | xfer->xfer32(result, tmp, n, nullptr); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 194 | |
commit-bot@chromium.org | 1ab536f | 2014-05-05 16:45:01 +0000 | [diff] [blame] | 195 | if (256 != scale) { |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 196 | for (int i = 0; i < n; i++) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 197 | result[i] = SkAlphaMulQ(result[i], scale); |
reed@google.com | 82065d6 | 2011-02-07 15:30:46 +0000 | [diff] [blame] | 198 | } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | result += n; |
| 202 | x += n; |
| 203 | count -= n; |
| 204 | } while (count > 0); |
| 205 | } |
| 206 | } |
robertphillips@google.com | 76f9e93 | 2013-01-15 20:17:47 +0000 | [diff] [blame] | 207 | |
Mike Reed | 273eead | 2017-05-12 13:07:46 -0400 | [diff] [blame] | 208 | void SkComposeShader::ComposeShaderContext::shadeSpan4f(int x, int y, SkPM4f result[], int count) { |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 209 | auto* shaderContextA = fShaderContextA; |
| 210 | auto* shaderContextB = fShaderContextB; |
Mike Reed | 273eead | 2017-05-12 13:07:46 -0400 | [diff] [blame] | 211 | SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode; |
| 212 | unsigned alpha = this->getPaintAlpha(); |
| 213 | Sk4f scale(alpha * (1.0f / 255)); |
| 214 | |
| 215 | SkPM4f tmp[TMP_COLOR_COUNT]; |
| 216 | |
| 217 | SkXfermodeProc4f xfer = SkXfermode::GetProc4f(mode); |
| 218 | do { |
| 219 | int n = SkTMin(count, TMP_COLOR_COUNT); |
| 220 | |
| 221 | shaderContextA->shadeSpan4f(x, y, result, n); |
| 222 | shaderContextB->shadeSpan4f(x, y, tmp, n); |
| 223 | if (255 == alpha) { |
| 224 | for (int i = 0; i < n; ++i) { |
| 225 | result[i] = xfer(tmp[i], result[i]); |
| 226 | } |
| 227 | } else { |
| 228 | for (int i = 0; i < n; ++i) { |
| 229 | (xfer(tmp[i], result[i]).to4f() * scale).store(result + i); |
| 230 | } |
| 231 | } |
| 232 | result += n; |
| 233 | x += n; |
| 234 | count -= n; |
| 235 | } while (count > 0); |
| 236 | } |
| 237 | |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 238 | #if SK_SUPPORT_GPU |
| 239 | |
wangyix | 036fd8e | 2015-09-08 15:23:34 -0700 | [diff] [blame] | 240 | #include "effects/GrConstColorProcessor.h" |
wangyix | 809e5af | 2015-09-09 12:58:32 -0700 | [diff] [blame] | 241 | #include "effects/GrXfermodeFragmentProcessor.h" |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 242 | |
| 243 | ///////////////////////////////////////////////////////////////////// |
| 244 | |
brianosman | 839345d | 2016-07-22 11:04:53 -0700 | [diff] [blame] | 245 | sk_sp<GrFragmentProcessor> SkComposeShader::asFragmentProcessor(const AsFPArgs& args) const { |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 246 | switch (fMode) { |
| 247 | case SkBlendMode::kClear: |
Brian Osman | 618d304 | 2016-10-25 10:51:28 -0400 | [diff] [blame] | 248 | return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), |
bungeman | 06ca8ec | 2016-06-09 08:01:03 -0700 | [diff] [blame] | 249 | GrConstColorProcessor::kIgnore_InputMode); |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 250 | break; |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 251 | case SkBlendMode::kSrc: |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 252 | return as_SB(fShaderB)->asFragmentProcessor(args); |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 253 | break; |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 254 | case SkBlendMode::kDst: |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 255 | return as_SB(fShaderA)->asFragmentProcessor(args); |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 256 | break; |
| 257 | default: |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 258 | sk_sp<GrFragmentProcessor> fpA(as_SB(fShaderA)->asFragmentProcessor(args)); |
bungeman | 06ca8ec | 2016-06-09 08:01:03 -0700 | [diff] [blame] | 259 | if (!fpA) { |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 260 | return nullptr; |
| 261 | } |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 262 | sk_sp<GrFragmentProcessor> fpB(as_SB(fShaderB)->asFragmentProcessor(args)); |
bungeman | 06ca8ec | 2016-06-09 08:01:03 -0700 | [diff] [blame] | 263 | if (!fpB) { |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 264 | return nullptr; |
| 265 | } |
bungeman | 06ca8ec | 2016-06-09 08:01:03 -0700 | [diff] [blame] | 266 | return GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(fpB), |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 267 | std::move(fpA), fMode); |
wangyix | 73fa616 | 2015-09-01 09:45:08 -0700 | [diff] [blame] | 268 | } |
| 269 | } |
| 270 | #endif |
| 271 | |
commit-bot@chromium.org | 0f10f7b | 2014-03-13 18:02:17 +0000 | [diff] [blame] | 272 | #ifndef SK_IGNORE_TO_STRING |
robertphillips@google.com | 76f9e93 | 2013-01-15 20:17:47 +0000 | [diff] [blame] | 273 | void SkComposeShader::toString(SkString* str) const { |
| 274 | str->append("SkComposeShader: ("); |
| 275 | |
| 276 | str->append("ShaderA: "); |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 277 | as_SB(fShaderA)->toString(str); |
robertphillips@google.com | 76f9e93 | 2013-01-15 20:17:47 +0000 | [diff] [blame] | 278 | str->append(" ShaderB: "); |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 279 | as_SB(fShaderB)->toString(str); |
Mike Reed | 7d954ad | 2016-10-28 15:42:34 -0400 | [diff] [blame] | 280 | if (SkBlendMode::kSrcOver != fMode) { |
| 281 | str->appendf(" Xfermode: %s", SkXfermode::ModeName(fMode)); |
halcanary | 8464a96 | 2015-06-16 11:53:26 -0700 | [diff] [blame] | 282 | } |
robertphillips@google.com | 76f9e93 | 2013-01-15 20:17:47 +0000 | [diff] [blame] | 283 | |
| 284 | this->INHERITED::toString(str); |
| 285 | |
| 286 | str->append(")"); |
| 287 | } |
| 288 | #endif |