Home | History | Annotate | Download | only in core
      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     */
     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
     58     SkShader* getShaderA() { return fShaderA.get(); }
     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