1 /* 2 * Copyright 2016 Google Inc. 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 SkNormalSource_DEFINED 9 #define SkNormalSource_DEFINED 10 11 #include "SkFlattenable.h" 12 #include "SkShaderBase.h" 13 14 class SkMatrix; 15 struct SkPoint3; 16 17 #if SK_SUPPORT_GPU 18 class GrFragmentProcessor; 19 #endif 20 21 /** Abstract class that generates or reads in normals for use by SkLightingShader. 22 */ 23 class SK_API SkNormalSource : public SkFlattenable { 24 public: 25 virtual ~SkNormalSource() override; 26 27 #if SK_SUPPORT_GPU 28 /** Returns a fragment processor that takes no input and outputs a normal (already rotated) 29 as its output color. To be used as a child fragment processor. 30 */ 31 virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const = 0; 32 #endif 33 34 class Provider { 35 public: ~Provider()36 virtual ~Provider() {} 37 38 /** Called for each span of the object being drawn on the CPU. Your subclass should set 39 the appropriate normals that correspond to the specified device coordinates. 40 */ 41 virtual void fillScanLine(int x, int y, SkPoint3 output[], int count) const = 0; 42 }; 43 44 /** Returns an instance of 'Provider' that provides normals for the CPU pipeline. The 45 necessary data will be initialized in place at 'storage'. 46 */ 47 virtual Provider* asProvider(const SkShaderBase::ContextRec&, SkArenaAlloc*) const = 0; 48 49 /** Returns a normal source that provides normals sourced from the the normal map argument. 50 51 @param map a shader that outputs the normal map 52 @param ctm the current canvas' total matrix, used to rotate normals when necessary. 53 54 nullptr will be returned if 'map' is null 55 56 The normal map is currently assumed to be an 8888 image where the normal at a texel 57 is retrieved by: 58 N.x = R-127; 59 N.y = G-127; 60 N.z = B-127; 61 N.normalize(); 62 The +Z axis is thus encoded in RGB as (127, 127, 255) while the -Z axis is 63 (127, 127, 0). 64 */ 65 static sk_sp<SkNormalSource> MakeFromNormalMap(sk_sp<SkShader> map, const SkMatrix& ctm); 66 67 /** Returns a normal source that provides straight-up normals only <0, 0, 1>. 68 */ 69 static sk_sp<SkNormalSource> MakeFlat(); 70 GetFlattenableType()71 static Type GetFlattenableType() { return kSkNormalSource_Type; } getFlattenableType()72 Type getFlattenableType() const override { return GetFlattenableType(); } 73 74 static sk_sp<SkNormalSource> Deserialize(const void* data, size_t size, 75 const SkDeserialProcs* procs = nullptr) { 76 return sk_sp<SkNormalSource>(static_cast<SkNormalSource*>( 77 SkFlattenable::Deserialize(GetFlattenableType(), data, size, procs).release())); 78 } 79 static void RegisterFlattenables(); 80 }; 81 82 #endif 83