| Index: src/core/SkLinearBitmapPipeline.h
 | 
| diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h
 | 
| index 32e464100fc2144696193d77a5547ece56befd02..548302ef9acdade777548960e62dc9d35035e538 100644
 | 
| --- a/src/core/SkLinearBitmapPipeline.h
 | 
| +++ b/src/core/SkLinearBitmapPipeline.h
 | 
| @@ -8,11 +8,9 @@
 | 
|  #ifndef SkLinearBitmapPipeline_DEFINED
 | 
|  #define SkLinearBitmapPipeline_DEFINED
 | 
|  
 | 
| -
 | 
|  #include "SkColor.h"
 | 
|  #include "SkImageInfo.h"
 | 
|  #include "SkMatrix.h"
 | 
| -#include "SkNx.h"
 | 
|  #include "SkShader.h"
 | 
|  
 | 
|  class SkLinearBitmapPipeline {
 | 
| @@ -27,31 +25,33 @@ public:
 | 
|  
 | 
|      void shadeSpan4f(int x, int y, SkPM4f* dst, int count);
 | 
|  
 | 
| -    template<typename Base, size_t kSize>
 | 
| -    class PolymorphicUnion {
 | 
| +    template<typename Base, size_t kSize, typename Next = void>
 | 
| +    class Stage {
 | 
|      public:
 | 
| -        PolymorphicUnion() : fIsInitialized{false} {}
 | 
| +        Stage() : fIsInitialized{false} {}
 | 
| +        ~Stage();
 | 
|  
 | 
| -        ~PolymorphicUnion() {
 | 
| -            if (fIsInitialized) {
 | 
| -                this->get()->~Base();
 | 
| -            }
 | 
| -        }
 | 
| +        template<typename Variant, typename... Args>
 | 
| +        void initStage(Next* next, Args&& ... args);
 | 
|  
 | 
|          template<typename Variant, typename... Args>
 | 
| -        void Initialize(Args&&... args) {
 | 
| -            SkASSERTF(sizeof(Variant) <= sizeof(fSpace),
 | 
| -                      "Size Variant: %d, Space: %d", sizeof(Variant), sizeof(fSpace));
 | 
| +        void initSink(Args&& ... args);
 | 
|  
 | 
| -            new(&fSpace) Variant(std::forward<Args>(args)...);
 | 
| -            fIsInitialized = true;
 | 
| -        };
 | 
| +        template <typename To, typename From>
 | 
| +        To* getInterface();
 | 
| +
 | 
| +        // Copy this stage to `cloneToStage` with `next` as its next stage
 | 
| +        // (not necessarily the same as our next, you see), returning `cloneToStage`.
 | 
| +        // Note: There is no cloneSinkTo method because the code usually places the top part of
 | 
| +        // the pipeline on a new sampler.
 | 
| +        Base* cloneStageTo(Next* next, Stage* cloneToStage) const;
 | 
|  
 | 
|          Base* get() const { return reinterpret_cast<Base*>(&fSpace); }
 | 
|          Base* operator->() const { return this->get(); }
 | 
|          Base& operator*() const { return *(this->get()); }
 | 
|  
 | 
|      private:
 | 
| +        std::function<void (Next*, void*)> fStageCloner;
 | 
|          struct SK_STRUCT_ALIGN(16) Space {
 | 
|              char space[kSize];
 | 
|          };
 | 
| @@ -61,22 +61,22 @@ public:
 | 
|  
 | 
|      class PointProcessorInterface;
 | 
|      class SampleProcessorInterface;
 | 
| -    class PixelPlacerInterface;
 | 
| +    class BlendProcessorInterface;
 | 
|      class DestinationInterface;
 | 
|  
 | 
| -    // These values were generated by the assert above in PolymorphicUnion.
 | 
| -    using MatrixStage = PolymorphicUnion<PointProcessorInterface, 160>;
 | 
| -    using TileStage   = PolymorphicUnion<PointProcessorInterface, 160>;
 | 
| -    using SampleStage = PolymorphicUnion<SampleProcessorInterface,100>;
 | 
| -    using PixelStage  = PolymorphicUnion<PixelPlacerInterface,     80>;
 | 
| +    // These values were generated by the assert above in Stage::init{Sink|Stage}.
 | 
| +    using MatrixStage  = Stage<PointProcessorInterface, 160, PointProcessorInterface>;
 | 
| +    using TileStage    = Stage<PointProcessorInterface, 160, SampleProcessorInterface>;
 | 
| +    using SampleStage  = Stage<SampleProcessorInterface, 100, BlendProcessorInterface>;
 | 
| +    using BlenderStage = Stage<BlendProcessorInterface, 80>;
 | 
|  
 | 
|  private:
 | 
|      PointProcessorInterface* fFirstStage;
 | 
| -    MatrixStage fMatrixStage;
 | 
| -    TileStage   fTiler;
 | 
| -    SampleStage fSampleStage;
 | 
| -    PixelStage  fPixelStage;
 | 
| -    DestinationInterface* fLastStage;
 | 
| +    MatrixStage              fMatrixStage;
 | 
| +    TileStage                fTileStage;
 | 
| +    SampleStage              fSampleStage;
 | 
| +    BlenderStage             fBlenderStage;
 | 
| +    DestinationInterface*    fLastStage;
 | 
|  };
 | 
|  
 | 
|  #endif  // SkLinearBitmapPipeline_DEFINED
 | 
| 
 |