Restore SkLightingShader and associated classes

This reverts https://skia-review.googlesource.com/c/skia/+/31140 (Remove SkLightingShader and associated classes) and updates the classes to ToT

Change-Id: I3b1df1704cca8907aa00f081a7e93339b65ad4fa
Reviewed-on: https://skia-review.googlesource.com/141545
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gm/lightingshader.cpp b/gm/lightingshader.cpp
new file mode 100644
index 0000000..303a4e2
--- /dev/null
+++ b/gm/lightingshader.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "sk_tool_utils.h"
+#include "SkLightingShader.h"
+#include "SkNormalSource.h"
+#include "SkPoint3.h"
+#include "SkShader.h"
+
+// Create a hemispherical normal map
+static SkBitmap make_hemi_normalmap(int texSize) {
+    SkBitmap hemi;
+    hemi.allocN32Pixels(texSize, texSize);
+
+    sk_tool_utils::create_hemi_normal_map(&hemi, SkIRect::MakeWH(texSize, texSize));
+    return hemi;
+}
+
+// Create a truncated pyramid normal map
+static SkBitmap make_frustum_normalmap(int texSize) {
+    SkBitmap frustum;
+    frustum.allocN32Pixels(texSize, texSize);
+
+    sk_tool_utils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize, texSize));
+    return frustum;
+}
+
+// Create a tetrahedral normal map
+static SkBitmap make_tetra_normalmap(int texSize) {
+    SkBitmap tetra;
+    tetra.allocN32Pixels(texSize, texSize);
+
+    sk_tool_utils::create_tetra_normal_map(&tetra, SkIRect::MakeWH(texSize, texSize));
+    return tetra;
+}
+
+namespace skiagm {
+
+// This GM exercises lighting shaders by drawing rotated and non-rotated normal mapped rects with
+// a directional light off to the viewers right.
+class LightingShaderGM : public GM {
+public:
+    LightingShaderGM() {
+        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
+    }
+
+protected:
+    enum NormalMap {
+        kHemi_NormalMap,
+        kFrustum_NormalMap,
+        kTetra_NormalMap,
+
+        kLast_NormalMap = kTetra_NormalMap
+    };
+
+    static constexpr int kNormalMapCount = kLast_NormalMap+1;
+
+    SkString onShortName() override { return SkString("lightingshader"); }
+
+    SkISize onISize() override { return SkISize::Make(kGMSize, kGMSize); }
+
+    void onOnceBeforeDraw() override {
+        {
+            SkLights::Builder builder;
+
+            // The direction vector is towards the light w/ +Z coming out of the screen
+            builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
+                                                         SkVector3::Make(SK_ScalarRoot2Over2,
+                                                                         0.0f,
+                                                                         SK_ScalarRoot2Over2)));
+            builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));
+
+            fLights = builder.finish();
+        }
+
+        fDiffuse = sk_tool_utils::create_checkerboard_bitmap(
+                                                        kTexSize, kTexSize,
+                                                        sk_tool_utils::color_to_565(0x0),
+                                                        sk_tool_utils::color_to_565(0xFF804020),
+                                                        8);
+
+        fNormalMaps[kHemi_NormalMap]    = make_hemi_normalmap(kTexSize);
+        fNormalMaps[kFrustum_NormalMap] = make_frustum_normalmap(kTexSize);
+        fNormalMaps[kTetra_NormalMap]   = make_tetra_normalmap(kTexSize);
+    }
+
+    void drawRect(SkCanvas* canvas, const SkRect& r, NormalMap mapType) {
+
+        SkRect bitmapBounds = SkRect::MakeIWH(fDiffuse.width(), fDiffuse.height());
+
+        SkMatrix matrix;
+        matrix.setRectToRect(bitmapBounds, r, SkMatrix::kFill_ScaleToFit);
+
+        const SkMatrix& ctm = canvas->getTotalMatrix();
+
+        SkPaint paint;
+        sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(fDiffuse,
+                SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix);
+        sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(fNormalMaps[mapType],
+                SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix);
+        sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(std::move(normalMap),
+                                                                               ctm);
+        paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource),
+                                               fLights));
+
+        canvas->drawRect(r, paint);
+    }
+
+    // Draw an axis-aligned and rotated version of the normal mapped rect
+    void drawPair(SkCanvas* canvas, const SkRect& r, NormalMap mapType, const SkVector& v) {
+        SkMatrix m;
+        m.setRotate(45.0f, r.centerX(), r.centerY());
+        m.postTranslate(kScale * v.fX, kScale * v.fY);
+
+        this->drawRect(canvas, r, mapType);
+
+        canvas->save();
+            canvas->setMatrix(m);
+            this->drawRect(canvas, r, mapType);
+        canvas->restore();
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        SkRect r;
+
+        r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize));
+        this->drawPair(canvas, r, kHemi_NormalMap, SkVector::Make(1.0f, 0.0f));
+
+        r.offset(kGMSize - kTexSize, 0);
+        this->drawPair(canvas, r, kFrustum_NormalMap, SkVector::Make(0.0f, 1.0f));
+
+        r.offset(0, kGMSize - kTexSize);
+        this->drawPair(canvas, r, kTetra_NormalMap, SkVector::Make(-1.0, 0.0f));
+
+        r.offset(kTexSize - kGMSize, 0);
+        this->drawPair(canvas, r, kHemi_NormalMap, SkVector::Make(0.0f, -1));
+    }
+
+private:
+    static constexpr int kTexSize = 128;
+    static constexpr int kGMSize  = 512;
+    static constexpr SkScalar kScale = kGMSize/2.0f - kTexSize/2.0f;
+
+    SkBitmap        fDiffuse;
+    SkBitmap        fNormalMaps[kNormalMapCount];
+
+    sk_sp<SkLights> fLights;
+
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM(return new LightingShaderGM;)
+}