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 #ifndef SkComposeShader_DEFINED
9 #define SkComposeShader_DEFINED
10 
11 #include "SkShader.h"
12 #include "SkBlendMode.h"
13 
14 ///////////////////////////////////////////////////////////////////////////////////////////
15 
16 /** \class SkComposeShader
17     This subclass of shader returns the composition of two other shaders, combined by
18     a xfermode.
19 */
20 class SK_API SkComposeShader : public SkShader {
21 public:
22     /** Create a new compose shader, given shaders A, B, and a combining xfermode mode.
23         When the xfermode is called, it will be given the result from shader A as its
24         "dst", and the result from shader B as its "src".
25         mode->xfer32(sA_result, sB_result, ...)
26         @param shaderA  The colors from this shader are seen as the "dst" by the xfermode
27         @param shaderB  The colors from this shader are seen as the "src" by the xfermode
28         @param mode     The xfermode that combines the colors from the two shaders. If mode
29                         is null, then SRC_OVER is assumed.
30     */
SkComposeShader(sk_sp<SkShader> sA,sk_sp<SkShader> sB,SkBlendMode mode)31     SkComposeShader(sk_sp<SkShader> sA, sk_sp<SkShader> sB, SkBlendMode mode)
32         : fShaderA(std::move(sA))
33         , fShaderB(std::move(sB))
34         , fMode(mode)
35     {}
36 
37 #if SK_SUPPORT_GPU
38     sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
39 #endif
40 
41     class ComposeShaderContext : public SkShader::Context {
42     public:
43         // When this object gets destroyed, it will call contextA and contextB's destructor
44         // but it will NOT free the memory.
45         ComposeShaderContext(const SkComposeShader&, const ContextRec&,
46                              SkShader::Context* contextA, SkShader::Context* contextB);
47 
48         void shadeSpan(int x, int y, SkPMColor[], int count) override;
49 
50     private:
51         SkShader::Context* fShaderContextA;
52         SkShader::Context* fShaderContextB;
53 
54         typedef SkShader::Context INHERITED;
55     };
56 
57 #ifdef SK_DEBUG
getShaderA()58     SkShader* getShaderA() { return fShaderA.get(); }
getShaderB()59     SkShader* getShaderB() { return fShaderB.get(); }
60 #endif
61 
62     bool asACompose(ComposeRec* rec) const override;
63 
64     SK_TO_STRING_OVERRIDE()
65     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader)
66 
67 protected:
68     SkComposeShader(SkReadBuffer&);
69     void flatten(SkWriteBuffer&) const override;
70     Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
71 
72 private:
73     sk_sp<SkShader>     fShaderA;
74     sk_sp<SkShader>     fShaderB;
75     SkBlendMode         fMode;
76 
77     typedef SkShader INHERITED;
78 };
79 
80 #endif
81