diff options
author | Robert Phillips <robertphillips@google.com> | 2017-08-04 11:27:00 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-08-07 13:33:49 +0000 |
commit | 6dd8cf144ecbc395dc12bd5f775bbeee04b9d38c (patch) | |
tree | f05965ad55589843158accb1e538411a43068648 | |
parent | 35ee0e09b4966bd087147e2c9b4c3177e9737d3b (diff) |
Remove SkLightingShader and associated classes
Change-Id: I8050414c30dfdb5df23ca79955adc5ba3a29d3f5
Reviewed-on: https://skia-review.googlesource.com/31140
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | gm/lightingshader.cpp | 182 | ||||
-rw-r--r-- | gm/lightingshader2.cpp | 274 | ||||
-rw-r--r-- | gn/core.gni | 10 | ||||
-rw-r--r-- | gn/gm.gni | 2 | ||||
-rw-r--r-- | gn/samples.gni | 2 | ||||
-rw-r--r-- | include/core/SkCanvas.h | 1 | ||||
-rw-r--r-- | include/core/SkFlattenable.h | 4 | ||||
-rw-r--r-- | include/core/SkLights.h | 205 | ||||
-rw-r--r-- | samplecode/SampleLighting.cpp | 98 | ||||
-rw-r--r-- | samplecode/SampleLitAtlas.cpp | 517 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 1 | ||||
-rw-r--r-- | src/core/SkLights.cpp | 111 | ||||
-rw-r--r-- | src/core/SkNormalFlatSource.cpp | 101 | ||||
-rw-r--r-- | src/core/SkNormalFlatSource.h | 47 | ||||
-rw-r--r-- | src/core/SkNormalMapSource.cpp | 256 | ||||
-rw-r--r-- | src/core/SkNormalMapSource.h | 57 | ||||
-rw-r--r-- | src/core/SkNormalSource.cpp | 22 | ||||
-rw-r--r-- | src/core/SkNormalSource.h | 75 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_default.cpp | 4 | ||||
-rw-r--r-- | src/shaders/SkLightingShader.cpp | 504 | ||||
-rw-r--r-- | src/shaders/SkLightingShader.h | 39 | ||||
-rw-r--r-- | tests/SerializationTest.cpp | 60 | ||||
-rw-r--r-- | tools/sk_tool_utils.cpp | 108 | ||||
-rw-r--r-- | tools/sk_tool_utils.h | 6 |
24 files changed, 2 insertions, 2684 deletions
diff --git a/gm/lightingshader.cpp b/gm/lightingshader.cpp deleted file mode 100644 index 95e30acda4..0000000000 --- a/gm/lightingshader.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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. -class LightingShaderGM : public GM { -public: - LightingShaderGM() { - this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); - - SkLights::Builder builder; - - 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(); - } - -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 { - 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); - } - - void onDraw(SkCanvas* canvas) override { - SkMatrix m; - SkRect r; - - { - r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize)); - this->drawRect(canvas, r, kHemi_NormalMap); - - canvas->save(); - m.setRotate(45.0f, r.centerX(), r.centerY()); - m.postTranslate(kGMSize/2.0f - kTexSize/2.0f, 0.0f); - canvas->setMatrix(m); - this->drawRect(canvas, r, kHemi_NormalMap); - canvas->restore(); - } - - { - r.offset(kGMSize - kTexSize, 0); - this->drawRect(canvas, r, kFrustum_NormalMap); - - canvas->save(); - m.setRotate(45.0f, r.centerX(), r.centerY()); - m.postTranslate(0.0f, kGMSize/2.0f - kTexSize/2.0f); - canvas->setMatrix(m); - this->drawRect(canvas, r, kFrustum_NormalMap); - canvas->restore(); - } - - { - r.offset(0, kGMSize - kTexSize); - this->drawRect(canvas, r, kTetra_NormalMap); - - canvas->save(); - m.setRotate(45.0f, r.centerX(), r.centerY()); - m.postTranslate(-kGMSize/2.0f + kTexSize/2.0f, 0.0f); - canvas->setMatrix(m); - this->drawRect(canvas, r, kTetra_NormalMap); - canvas->restore(); - } - - { - r.offset(kTexSize - kGMSize, 0); - this->drawRect(canvas, r, kHemi_NormalMap); - - canvas->save(); - m.setRotate(45.0f, r.centerX(), r.centerY()); - m.postTranslate(0.0f, -kGMSize/2.0f + kTexSize/2.0f); - canvas->setMatrix(m); - this->drawRect(canvas, r, kHemi_NormalMap); - canvas->restore(); - } - } - -private: - static constexpr int kTexSize = 128; - static constexpr int kGMSize = 512; - - SkBitmap fDiffuse; - SkBitmap fNormalMaps[kNormalMapCount]; - - sk_sp<SkLights> fLights; - - typedef GM INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -DEF_GM(return new LightingShaderGM;) -} diff --git a/gm/lightingshader2.cpp b/gm/lightingshader2.cpp deleted file mode 100644 index b0c7beec46..0000000000 --- a/gm/lightingshader2.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2016 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 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; -} - -namespace skiagm { - -// This GM exercises lighting shaders. Specifically, nullptr arguments, scaling when using -// normal maps, paint transparency, zero directional lights, multiple directional lights. -class LightingShader2GM : public GM { -public: - LightingShader2GM() { - this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); - } - -protected: - SkString onShortName() override { - return SkString("lightingshader2"); - } - - SkISize onISize() override { - return SkISize::Make(600, 740); - } - - void onOnceBeforeDraw() override { - const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0.473f); - const SkVector3 kLightFromUpperLeft = SkVector3::Make(-0.788f, 0.394f, 0.473f); - - // Standard set of lights - SkLights::Builder builder; - builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), - kLightFromUpperRight)); - builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f)); - fLights = builder.finish(); - - // No directional lights - SkLights::Builder builderNoDir; - builderNoDir.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f)); - fLightsNoDir = builderNoDir.finish(); - - // Two directional lights - SkLights::Builder builderTwoDir; - builderTwoDir.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 0.0f, 1.0f), - kLightFromUpperRight)); - builderTwoDir.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.0f, 1.0f, 1.0f), - kLightFromUpperLeft)); - builderTwoDir.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f)); - fLightsTwoDir = builderTwoDir.finish(); - - fRect = SkRect::MakeIWH(kTexSize, kTexSize); - SkMatrix matrix; - SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize); - matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit); - - SkBitmap opaqueDiffuseMap = sk_tool_utils::create_checkerboard_bitmap( - kTexSize, kTexSize, - sk_tool_utils::color_to_565(0x0), - sk_tool_utils::color_to_565(0xFF804020), - 8); - fOpaqueDiffuse = SkShader::MakeBitmapShader(opaqueDiffuseMap, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, &matrix); - - SkBitmap translucentDiffuseMap = sk_tool_utils::create_checkerboard_bitmap( - kTexSize, kTexSize, - SkColorSetARGB(0x55, 0x00, 0x00, 0x00), - SkColorSetARGB(0x55, 0x80, 0x40, 0x20), - 8); - fTranslucentDiffuse = SkShader::MakeBitmapShader(translucentDiffuseMap, - SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, &matrix); - - SkBitmap normalMap = make_frustum_normalmap(kTexSize); - fNormalMapShader = SkShader::MakeBitmapShader(normalMap, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, &matrix); - - } - - // Scales shape around origin, rotates shape around origin, then translates shape to origin - void positionCTM(SkCanvas *canvas, SkScalar scaleX, SkScalar scaleY, SkScalar rotate) const { - canvas->translate(kTexSize/2.0f, kTexSize/2.0f); - canvas->scale(scaleX, scaleY); - canvas->rotate(rotate); - canvas->translate(-kTexSize/2.0f, -kTexSize/2.0f); - } - - static constexpr int NUM_BOOLEAN_PARAMS = 4; - void drawRect(SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY, - SkScalar rotate, bool useNormalSource, bool useDiffuseShader, - bool useTranslucentPaint, bool useTranslucentShader, sk_sp<SkLights> lights) { - canvas->save(); - - this->positionCTM(canvas, scaleX, scaleY, rotate); - - const SkMatrix& ctm = canvas->getTotalMatrix(); - - SkPaint paint; - sk_sp<SkNormalSource> normalSource = nullptr; - sk_sp<SkShader> diffuseShader = nullptr; - - if (useNormalSource) { - normalSource = SkNormalSource::MakeFromNormalMap(fNormalMapShader, ctm); - } - - if (useDiffuseShader) { - diffuseShader = (useTranslucentShader) ? fTranslucentDiffuse : fOpaqueDiffuse; - } else { - paint.setColor(0xFF00FF00); - } - - if (useTranslucentPaint) { - paint.setAlpha(0x99); - } - - paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource), - std::move(lights))); - canvas->drawRect(fRect, paint); - - canvas->restore(); - } - - void onDraw(SkCanvas* canvas) override { - - constexpr SkScalar LABEL_SIZE = 10.0f; - SkPaint labelPaint; - labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-serif",SkFontStyle())); - labelPaint.setAntiAlias(true); - labelPaint.setTextSize(LABEL_SIZE); - - constexpr int GRID_COLUMN_NUM = 4; - constexpr SkScalar GRID_CELL_WIDTH = kTexSize + 20.0f + NUM_BOOLEAN_PARAMS * LABEL_SIZE; - - int gridNum = 0; - - // Running through all possible bool parameter combinations - for (bool useNormalSource : {true, false}) { - for (bool useDiffuseShader : {true, false}) { - for (bool useTranslucentPaint : {true, false}) { - for (bool useTranslucentShader : {true, false}) { - - // Determining position - SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - - canvas->save(); - - canvas->translate(xPos, yPos); - this->drawRect(canvas, 1.0f, 1.0f, 0.f, useNormalSource, useDiffuseShader, - useTranslucentPaint, useTranslucentShader, fLights); - // Drawing labels - canvas->translate(0.0f, SkIntToScalar(kTexSize)); - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("useNormalSource: %d", useNormalSource); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("useDiffuseShader: %d", useDiffuseShader); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("useTranslucentPaint: %d", useTranslucentPaint); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("useTranslucentShader: %d", useTranslucentShader); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - - canvas->restore(); - - gridNum++; - } - } - } - } - - - // Rotation/scale test - { - SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - - canvas->save(); - canvas->translate(xPos, yPos); - this->drawRect(canvas, 0.6f, 0.6f, 45.0f, true, true, true, true, fLights); - canvas->restore(); - - gridNum++; - } - - // Anisotropic scale test - { - SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - - canvas->save(); - canvas->translate(xPos, yPos); - this->drawRect(canvas, 0.6f, 0.4f, 30.0f, true, true, true, true, fLights); - canvas->restore(); - - gridNum++; - } - - // No directional lights test - { - SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - - canvas->save(); - canvas->translate(xPos, yPos); - this->drawRect(canvas, 1.0f, 1.0f, 0.0f, true, true, false, false, fLightsNoDir); - canvas->restore(); - - gridNum++; - } - - // Two directional lights test - { - SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; - - canvas->save(); - canvas->translate(xPos, yPos); - this->drawRect(canvas, 1.0f, 1.0f, 0.0f, true, true, false, false, fLightsTwoDir); - canvas->restore(); - - gridNum++; - } - } - -private: - static constexpr int kTexSize = 96; - - sk_sp<SkShader> fOpaqueDiffuse; - sk_sp<SkShader> fTranslucentDiffuse; - sk_sp<SkShader> fNormalMapShader; - - SkRect fRect; - sk_sp<SkLights> fLights; - sk_sp<SkLights> fLightsNoDir; - sk_sp<SkLights> fLightsTwoDir; - - typedef GM INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -DEF_GM(return new LightingShader2GM;) -} diff --git a/gn/core.gni b/gn/core.gni index fbb4c7a98a..084f47e125 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -161,7 +161,6 @@ skia_core_sources = [ "$_src/core/SkImageInfo.cpp", "$_src/core/SkImageCacherator.h", "$_src/core/SkImageGenerator.cpp", - "$_src/core/SkLights.cpp", "$_src/core/SkLineClipper.cpp", "$_src/core/SkLiteDL.cpp", "$_src/core/SkLiteRecorder.cpp", @@ -194,12 +193,6 @@ skia_core_sources = [ "$_src/core/SkNextID.h", "$_src/core/SkLatticeIter.cpp", "$_src/core/SkLatticeIter.h", - "$_src/core/SkNormalMapSource.cpp", - "$_src/core/SkNormalMapSource.h", - "$_src/core/SkNormalFlatSource.cpp", - "$_src/core/SkNormalFlatSource.h", - "$_src/core/SkNormalSource.cpp", - "$_src/core/SkNormalSource.h", "$_src/core/SkNx.h", "$_src/core/SkOpts.cpp", "$_src/core/SkOpts.h", @@ -364,8 +357,6 @@ skia_core_sources = [ "$_src/shaders/SkEmptyShader.h", "$_src/shaders/SkImageShader.cpp", "$_src/shaders/SkImageShader.h", - "$_src/shaders/SkLightingShader.cpp", - "$_src/shaders/SkLightingShader.h", "$_src/shaders/SkLocalMatrixShader.cpp", "$_src/shaders/SkLocalMatrixShader.h", "$_src/shaders/SkPictureShader.cpp", @@ -394,7 +385,6 @@ skia_core_sources = [ "$_include/core/SkImageEncoder.h", "$_include/core/SkImageFilter.h", "$_include/core/SkImageInfo.h", - "$_include/core/SkLights.h", "$_include/core/SkMallocPixelRef.h", "$_include/core/SkMask.h", "$_include/core/SkMaskFilter.h", @@ -190,8 +190,6 @@ gm_sources = [ "$_gm/lcdoverlap.cpp", "$_gm/lcdtext.cpp", "$_gm/lighting.cpp", - "$_gm/lightingshader.cpp", - "$_gm/lightingshader2.cpp", "$_gm/linepaths.cpp", "$_gm/localmatriximagefilter.cpp", "$_gm/localmatriximageshader.cpp", diff --git a/gn/samples.gni b/gn/samples.gni index 58f89729da..edb2fe8608 100644 --- a/gn/samples.gni +++ b/gn/samples.gni @@ -57,9 +57,7 @@ samples_sources = [ "$_samplecode/SampleLayerMask.cpp", "$_samplecode/SampleLayers.cpp", "$_samplecode/SampleLCD.cpp", - "$_samplecode/SampleLighting.cpp", "$_samplecode/SampleLines.cpp", - "$_samplecode/SampleLitAtlas.cpp", "$_samplecode/SampleManyRects.cpp", "$_samplecode/SampleMeasure.cpp", "$_samplecode/SampleMegaStroke.cpp", diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index c4cb1752d8..5881808520 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -28,7 +28,6 @@ class SkDrawFilter; struct SkDrawShadowRec; class SkImage; class SkImageFilter; -class SkLights; class SkMetaData; class SkPath; class SkPicture; diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h index c36d181c1a..40cbaa5d0d 100644 --- a/include/core/SkFlattenable.h +++ b/include/core/SkFlattenable.h @@ -80,8 +80,8 @@ public: kSkRasterizer_Type, kSkShaderBase_Type, kSkUnused_Type, // used to be SkUnitMapper - kSkUnused_Xfermode_Type, - kSkNormalSource_Type, + kSkUnused_Type2, + kSkUnused_Type3, // used to be SkNormalSource }; typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&); diff --git a/include/core/SkLights.h b/include/core/SkLights.h deleted file mode 100644 index 5c6648751d..0000000000 --- a/include/core/SkLights.h +++ /dev/null @@ -1,205 +0,0 @@ - -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkLights_DEFINED -#define SkLights_DEFINED - -#include "../private/SkTArray.h" -#include "SkImage.h" -#include "SkPoint3.h" -#include "SkRefCnt.h" - -class SkReadBuffer; -class SkWriteBuffer; - -class SK_API SkLights : public SkRefCnt { -public: - class Light { - public: - enum LightType { - kDirectional_LightType, - kPoint_LightType - }; - - Light(const Light& other) - : fType(other.fType) - , fColor(other.fColor) - , fDirOrPos(other.fDirOrPos) - , fIntensity(other.fIntensity) - , fShadowMap(other.fShadowMap) - , fIsRadial(other.fIsRadial) { - } - - Light(Light&& other) - : fType(other.fType) - , fColor(other.fColor) - , fDirOrPos(other.fDirOrPos) - , fIntensity(other.fIntensity) - , fShadowMap(std::move(other.fShadowMap)) - , fIsRadial(other.fIsRadial) { - } - - static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir, - bool isRadial = false) { - Light light(kDirectional_LightType, color, dir, isRadial); - if (!light.fDirOrPos.normalize()) { - light.fDirOrPos.set(0.0f, 0.0f, 1.0f); - } - return light; - } - - static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity, - bool isRadial = false) { - return Light(kPoint_LightType, color, pos, intensity, isRadial); - } - - LightType type() const { return fType; } - const SkColor3f& color() const { return fColor; } - const SkVector3& dir() const { - SkASSERT(kDirectional_LightType == fType); - return fDirOrPos; - } - const SkPoint3& pos() const { - SkASSERT(kPoint_LightType == fType); - return fDirOrPos; - } - SkScalar intensity() const { - SkASSERT(kPoint_LightType == fType); - return fIntensity; - } - - void setShadowMap(sk_sp<SkImage> shadowMap) { - fShadowMap = std::move(shadowMap); - } - - SkImage* getShadowMap() const { - return fShadowMap.get(); - } - - bool isRadial() const { return fIsRadial; } - - Light& operator= (const Light& b) { - if (this == &b) { - return *this; - } - - fColor = b.fColor; - fType = b.fType; - fDirOrPos = b.fDirOrPos; - fIntensity = b.fIntensity; - fShadowMap = b.fShadowMap; - fIsRadial = b.fIsRadial; - return *this; - } - - bool operator== (const Light& b) { - if (this == &b) { - return true; - } - - return (fColor == b.fColor) && - (fType == b.fType) && - (fDirOrPos == b.fDirOrPos) && - (fShadowMap == b.fShadowMap) && - (fIntensity == b.fIntensity) && - (fIsRadial == b.fIsRadial); - } - - bool operator!= (const Light& b) { return !(this->operator==(b)); } - - private: - friend class SkLights; - - LightType fType; - SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel. - - SkVector3 fDirOrPos; // For directional lights, holds the direction towards the - // light (+Z is out of the screen). - // If degenerate, it will be replaced with (0, 0, 1). - // For point lights, holds location of point light - - SkScalar fIntensity; // For point lights, dictates the light intensity. - // Simply a multiplier to the final light output value. - sk_sp<SkImage> fShadowMap; - bool fIsRadial; // Whether the light is radial or not. Radial lights will - // cast shadows and lights radially outwards. - - Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos, - SkScalar intensity = 0.0f, bool isRadial = false) { - fType = type; - fColor = color; - fDirOrPos = dirOrPos; - fIntensity = intensity; - fIsRadial = isRadial; - } - }; - - class Builder { - public: - Builder() : fLights(new SkLights) {} - - void add(const Light& light) { - if (fLights) { - fLights->fLights.push_back(light); - } - } - - void add(Light&& light) { - if (fLights) { - fLights->fLights.push_back(std::move(light)); - } - } - - void setAmbientLightColor(const SkColor3f& color) { - if (fLights) { - fLights->fAmbientLightColor = color; - } - } - - sk_sp<SkLights> finish() { - return std::move(fLights); - } - - private: - sk_sp<SkLights> fLights; - }; - - int numLights() const { - return fLights.count(); - } - - const Light& light(int index) const { - return fLights[index]; - } - - Light& light(int index) { - return fLights[index]; - } - - const SkColor3f& ambientLightColor() const { - return fAmbientLightColor; - } - - static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf); - - void flatten(SkWriteBuffer& buf) const; - -private: - SkLights() { - fAmbientLightColor.set(0.0f, 0.0f, 0.0f); - } - - friend class SkLightingShaderImpl; - sk_sp<SkLights> makeColorSpace(SkColorSpaceXformer* xformer) const; - - SkTArray<Light> fLights; - SkColor3f fAmbientLightColor; - typedef SkRefCnt INHERITED; -}; - -#endif diff --git a/samplecode/SampleLighting.cpp b/samplecode/SampleLighting.cpp deleted file mode 100644 index 2218f31022..0000000000 --- a/samplecode/SampleLighting.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 "DecodeFile.h" -#include "SampleCode.h" -#include "Resources.h" -#include "SkCanvas.h" -#include "SkLightingShader.h" -#include "SkNormalSource.h" -#include "SkPoint3.h" - -static sk_sp<SkLights> create_lights(SkScalar angle, SkScalar blue) { - - const SkVector3 dir = SkVector3::Make(SkScalarSin(angle)*SkScalarSin(SK_ScalarPI*0.25f), - SkScalarCos(angle)*SkScalarSin(SK_ScalarPI*0.25f), - SkScalarCos(SK_ScalarPI*0.25f)); - - SkLights::Builder builder; - - builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, blue), dir)); - builder.setAmbientLightColor(SkColor3f::Make(0.1f, 0.1f, 0.1f)); - - return builder.finish(); -} - -//////////////////////////////////////////////////////////////////////////// - -class LightingView : public SampleView { -public: - SkBitmap fDiffuseBitmap; - SkBitmap fNormalBitmap; - SkScalar fLightAngle; - SkScalar fColorFactor; - - LightingView() { - SkString diffusePath = GetResourcePath("brickwork-texture.jpg"); - decode_file(diffusePath.c_str(), &fDiffuseBitmap); - SkString normalPath = GetResourcePath("brickwork_normal-map.jpg"); - decode_file(normalPath.c_str(), &fNormalBitmap); - - fLightAngle = 0.0f; - fColorFactor = 0.0f; - } - -protected: - // overrides from SkEventSink - bool onQuery(SkEvent* evt) override { - if (SampleCode::TitleQ(*evt)) { - SampleCode::TitleR(evt, "Lighting"); - return true; - } - return this->INHERITED::onQuery(evt); - } - - void onDrawContent(SkCanvas* canvas) override { - fLightAngle += 0.015f; - fColorFactor += 0.01f; - if (fColorFactor > 1.0f) { - fColorFactor = 0.0f; - } - - sk_sp<SkLights> lights(create_lights(fLightAngle, fColorFactor)); - SkPaint paint; - sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(fNormalBitmap, - SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, nullptr); - sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap( - std::move(normalMap), SkMatrix::I()); - sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(fDiffuseBitmap, - SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, nullptr); - paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource), - std::move(lights))); - paint.setColor(SK_ColorBLACK); - - SkRect r = SkRect::MakeWH((SkScalar)fDiffuseBitmap.width(), - (SkScalar)fDiffuseBitmap.height()); - canvas->drawRect(r, paint); - - // so we're constantly updating - this->inval(nullptr); - } - - SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { - this->inval(nullptr); - return this->INHERITED::onFindClickHandler(x, y, modi); - } - -private: - typedef SampleView INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -static SkView* MyFactory() { return new LightingView; } -static SkViewRegister reg(MyFactory); diff --git a/samplecode/SampleLitAtlas.cpp b/samplecode/SampleLitAtlas.cpp deleted file mode 100644 index ee639d3549..0000000000 --- a/samplecode/SampleLitAtlas.cpp +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SampleCode.h" -#include "SkAnimTimer.h" -#include "SkBitmapProcShader.h" -#include "SkCanvas.h" -#include "SkDrawable.h" -#include "SkLightingShader.h" -#include "SkLights.h" -#include "SkNormalSource.h" -#include "SkRandom.h" -#include "SkRSXform.h" -#include "SkView.h" - -#include "sk_tool_utils.h" - -class DrawLitAtlasDrawable : public SkDrawable { -public: - DrawLitAtlasDrawable(const SkRect& r) - : fBounds(r) - , fUseColors(false) - , fLightDir(SkVector3::Make(1.0f, 0.0f, 0.0f)) { - fAtlas = MakeAtlas(); - - SkRandom rand; - for (int i = 0; i < kNumAsteroids; ++i) { - fAsteroids[i].initAsteroid(&rand, fBounds, &fDiffTex[i], &fNormTex[i]); - } - - fShip.initShip(fBounds, &fDiffTex[kNumAsteroids], &fNormTex[kNumAsteroids]); - - this->updateLights(); - } - - void toggleUseColors() { - fUseColors = !fUseColors; - } - - void rotateLight() { - SkScalar c; - SkScalar s = SkScalarSinCos(SK_ScalarPI/6.0f, &c); - - SkScalar newX = c * fLightDir.fX - s * fLightDir.fY; - SkScalar newY = s * fLightDir.fX + c * fLightDir.fY; - - fLightDir.set(newX, newY, 0.0f); - - this->updateLights(); - } - - void left() { - SkScalar newRot = SkScalarMod(fShip.rot() + (2*SK_ScalarPI - SK_ScalarPI/32.0f), - 2 * SK_ScalarPI); - fShip.setRot(newRot); - } - - void right() { - SkScalar newRot = SkScalarMod(fShip.rot() + SK_ScalarPI/32.0f, 2 * SK_ScalarPI); - fShip.setRot(newRot); - } - - void thrust() { - SkScalar c; - SkScalar s = SkScalarSinCos(fShip.rot(), &c); - - SkVector newVel = fShip.velocity(); - newVel.fX += s; - newVel.fY += -c; - - if (newVel.lengthSqd() > kMaxShipSpeed*kMaxShipSpeed) { - newVel.setLength(SkIntToScalar(kMaxShipSpeed)); - } - - fShip.setVelocity(newVel); - } - -protected: - void onDraw(SkCanvas* canvas) override { - SkRSXform xforms[kNumAsteroids+kNumShips]; - SkColor colors[kNumAsteroids+kNumShips]; - - for (int i = 0; i < kNumAsteroids; ++i) { - fAsteroids[i].advance(fBounds); - xforms[i] = fAsteroids[i].asRSXform(); - if (fUseColors) { - colors[i] = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF); - } - } - - fShip.advance(fBounds); - xforms[kNumAsteroids] = fShip.asRSXform(); - if (fUseColors) { - colors[kNumAsteroids] = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF); - } - -#ifdef SK_DEBUG - canvas->drawBitmap(fAtlas, 0, 0); // just to see the atlas - - this->drawLightDir(canvas, fBounds.centerX(), fBounds.centerY()); -#endif - -#if 0 - // TODO: revitalize when drawLitAtlas API lands - SkPaint paint; - paint.setFilterQuality(kLow_SkFilterQuality); - - const SkRect cull = this->getBounds(); - const SkColor* colorsPtr = fUseColors ? colors : NULL; - - canvas->drawLitAtlas(fAtlas, xforms, fDiffTex, fNormTex, colorsPtr, kNumAsteroids+1, - SkXfermode::kModulate_Mode, &cull, &paint, fLights); -#else - SkMatrix diffMat, normalMat; - - for (int i = 0; i < kNumAsteroids+1; ++i) { - colors[i] = colors[i] & 0xFF000000; // to silence compilers - SkPaint paint; - - SkRect r = fDiffTex[i]; - r.offsetTo(0, 0); - - diffMat.setRectToRect(fDiffTex[i], r, SkMatrix::kFill_ScaleToFit); - normalMat.setRectToRect(fNormTex[i], r, SkMatrix::kFill_ScaleToFit); - - SkMatrix m; - m.setRSXform(xforms[i]); - - sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(fAtlas, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, &normalMat); - sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap( - std::move(normalMap), m); - sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(fAtlas, - SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &diffMat); - paint.setShader(SkLightingShader::Make(std::move(diffuseShader), - std::move(normalSource), fLights)); - - canvas->save(); - canvas->setMatrix(m); - canvas->drawRect(r, paint); - canvas->restore(); - } -#endif - -#ifdef SK_DEBUG - { - SkPaint paint; - paint.setColor(SK_ColorRED); - - for (int i = 0; i < kNumAsteroids; ++i) { - canvas->drawCircle(fAsteroids[i].pos().x(), fAsteroids[i].pos().y(), 2, paint); - } - canvas->drawCircle(fShip.pos().x(), fShip.pos().y(), 2, paint); - - paint.setStyle(SkPaint::kStroke_Style); - canvas->drawRect(this->getBounds(), paint); - } -#endif - } - - SkRect onGetBounds() override { - return fBounds; - } - -private: - - enum ObjType { - kBigAsteroid_ObjType = 0, - kMedAsteroid_ObjType, - kSmAsteroid_ObjType, - kShip_ObjType, - - kLast_ObjType = kShip_ObjType - }; - - static const int kObjTypeCount = kLast_ObjType + 1; - - void updateLights() { - SkLights::Builder builder; - - builder.add(SkLights::Light::MakeDirectional( - SkColor3f::Make(1.0f, 1.0f, 1.0f), fLightDir)); - builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f)); - - fLights = builder.finish(); - } - -#ifdef SK_DEBUG - // Draw a vector to the light - void drawLightDir(SkCanvas* canvas, SkScalar centerX, SkScalar centerY) { - static const int kBgLen = 30; - static const int kSmLen = 5; - - // TODO: change the lighting coordinate system to be right handed - SkPoint p1 = SkPoint::Make(centerX + kBgLen * fLightDir.fX, - centerY - kBgLen * fLightDir.fY); - SkPoint p2 = SkPoint::Make(centerX + (kBgLen-kSmLen) * fLightDir.fX, - centerY - (kBgLen-kSmLen) * fLightDir.fY); - - SkPaint p; - canvas->drawLine(centerX, centerY, p1.fX, p1.fY, p); - canvas->drawLine(p1.fX, p1.fY, - p2.fX - kSmLen * fLightDir.fY, p2.fY - kSmLen * fLightDir.fX, p); - canvas->drawLine(p1.fX, p1.fY, - p2.fX + kSmLen * fLightDir.fY, p2.fY + kSmLen * fLightDir.fX, p); - } -#endif - - // Create the mixed diffuse & normal atlas - // - // big color circle | big normal hemi - // ------------------------------------ - // med color circle | med normal pyra - // ------------------------------------ - // sm color circle | sm normal hemi - // ------------------------------------ - // big ship | big tetra normal - static SkBitmap MakeAtlas() { - - SkBitmap atlas; - atlas.allocN32Pixels(kAtlasWidth, kAtlasHeight); - - for (int y = 0; y < kAtlasHeight; ++y) { - int x = 0; - for ( ; x < kBigSize+kPad; ++x) { - *atlas.getAddr32(x, y) = SK_ColorTRANSPARENT; - } - for ( ; x < kAtlasWidth; ++x) { - *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0x88, 0x88, 0xFF); - } - } - - // big asteroid - { - SkPoint bigCenter = SkPoint::Make(kDiffXOff + kBigSize/2.0f, kBigYOff + kBigSize/2.0f); - - for (int y = kBigYOff; y < kBigYOff+kBigSize; ++y) { - for (int x = kDiffXOff; x < kDiffXOff+kBigSize; ++x) { - SkScalar distSq = (x - bigCenter.fX) * (x - bigCenter.fX) + - (y - bigCenter.fY) * (y - bigCenter.fY); - if (distSq > kBigSize*kBigSize/4.0f) { - *atlas.getAddr32(x, y) = SkPreMultiplyARGB(0, 0, 0, 0); - } else { - *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0xFF, 0, 0); - } - } - } - - sk_tool_utils::create_hemi_normal_map(&atlas, - SkIRect::MakeXYWH(kNormXOff, kBigYOff, - kBigSize, kBigSize)); - } - - // medium asteroid - { - for (int y = kMedYOff; y < kMedYOff+kMedSize; ++y) { - for (int x = kDiffXOff; x < kDiffXOff+kMedSize; ++x) { - *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0xFF, 0); - } - } - - sk_tool_utils::create_frustum_normal_map(&atlas, - SkIRect::MakeXYWH(kNormXOff, kMedYOff, - kMedSize, kMedSize)); - } - - // small asteroid - { - SkPoint smCenter = SkPoint::Make(kDiffXOff + kSmSize/2.0f, kSmYOff + kSmSize/2.0f); - - for (int y = kSmYOff; y < kSmYOff+kSmSize; ++y) { - for (int x = kDiffXOff; x < kDiffXOff+kSmSize; ++x) { - SkScalar distSq = (x - smCenter.fX) * (x - smCenter.fX) + - (y - smCenter.fY) * (y - smCenter.fY); - if (distSq > kSmSize*kSmSize/4.0f) { - *atlas.getAddr32(x, y) = SkPreMultiplyARGB(0, 0, 0, 0); - } else { - *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0, 0xFF); - } - } - } - - sk_tool_utils::create_hemi_normal_map(&atlas, - SkIRect::MakeXYWH(kNormXOff, kSmYOff, - kSmSize, kSmSize)); - } - - // ship - { - SkScalar shipMidLine = kDiffXOff + kMedSize/2.0f; - - for (int y = kShipYOff; y < kShipYOff+kMedSize; ++y) { - SkScalar scaledY = (y - kShipYOff)/(float)kMedSize; // 0..1 - - for (int x = kDiffXOff; x < kDiffXOff+kMedSize; ++x) { - SkScalar scaledX; - - if (x < shipMidLine) { - scaledX = 1.0f - (x - kDiffXOff)/(kMedSize/2.0f); // 0..1 - } else { - scaledX = (x - shipMidLine)/(kMedSize/2.0f); // 0..1 - } - - if (scaledX < scaledY) { - *atlas.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0xFF, 0xFF); - } else { - *atlas.getAddr32(x, y) = SkPackARGB32(0, 0, 0, 0); - } - } - } - - sk_tool_utils::create_tetra_normal_map(&atlas, - SkIRect::MakeXYWH(kNormXOff, kShipYOff, - kMedSize, kMedSize)); - } - - return atlas; - } - - class ObjectRecord { - public: - void initAsteroid(SkRandom *rand, const SkRect& bounds, - SkRect* diffTex, SkRect* normTex) { - static const SkScalar gMaxSpeeds[3] = { 1, 2, 5 }; // smaller asteroids can go faster - static const SkScalar gYOffs[3] = { kBigYOff, kMedYOff, kSmYOff }; - static const SkScalar gSizes[3] = { kBigSize, kMedSize, kSmSize }; - - static unsigned int asteroidType = 0; - fObjType = static_cast<ObjType>(asteroidType++ % 3); - - fPosition.set(bounds.fLeft + rand->nextUScalar1() * bounds.width(), - bounds.fTop + rand->nextUScalar1() * bounds.height()); - fVelocity.fX = rand->nextSScalar1(); - fVelocity.fY = sqrt(1.0f - fVelocity.fX * fVelocity.fX); - SkASSERT(SkScalarNearlyEqual(fVelocity.length(), 1.0f)); - fVelocity *= gMaxSpeeds[fObjType]; - fRot = 0; - fDeltaRot = rand->nextSScalar1() / 32; - - diffTex->setXYWH(SkIntToScalar(kDiffXOff), gYOffs[fObjType], - gSizes[fObjType], gSizes[fObjType]); - normTex->setXYWH(SkIntToScalar(kNormXOff), gYOffs[fObjType], - gSizes[fObjType], gSizes[fObjType]); - } - - void initShip(const SkRect& bounds, SkRect* diffTex, SkRect* normTex) { - fObjType = kShip_ObjType; - fPosition.set(bounds.centerX(), bounds.centerY()); - fVelocity = SkVector::Make(0.0f, 0.0f); - fRot = 0.0f; - fDeltaRot = 0.0f; - - diffTex->setXYWH(SkIntToScalar(kDiffXOff), SkIntToScalar(kShipYOff), - SkIntToScalar(kMedSize), SkIntToScalar(kMedSize)); - normTex->setXYWH(SkIntToScalar(kNormXOff), SkIntToScalar(kShipYOff), - SkIntToScalar(kMedSize), SkIntToScalar(kMedSize)); - } - - void advance(const SkRect& bounds) { - fPosition += fVelocity; - if (fPosition.fX > bounds.right()) { - SkASSERT(fVelocity.fX > 0); - fVelocity.fX = -fVelocity.fX; - } else if (fPosition.fX < bounds.left()) { - SkASSERT(fVelocity.fX < 0); - fVelocity.fX = -fVelocity.fX; - } - if (fPosition.fY > bounds.bottom()) { - if (fVelocity.fY > 0) { - fVelocity.fY = -fVelocity.fY; - } - } else if (fPosition.fY < bounds.top()) { - if (fVelocity.fY < 0) { - fVelocity.fY = -fVelocity.fY; - } - } - - fRot += fDeltaRot; - fRot = SkScalarMod(fRot, 2 * SK_ScalarPI); - } - - const SkPoint& pos() const { return fPosition; } - - SkScalar rot() const { return fRot; } - void setRot(SkScalar rot) { fRot = rot; } - - const SkPoint& velocity() const { return fVelocity; } - void setVelocity(const SkPoint& velocity) { fVelocity = velocity; } - - SkRSXform asRSXform() const { - static const SkScalar gHalfSizes[kObjTypeCount] = { - SkScalarHalf(kBigSize), - SkScalarHalf(kMedSize), - SkScalarHalf(kSmSize), - SkScalarHalf(kMedSize), - }; - - return SkRSXform::MakeFromRadians(1.0f, fRot, fPosition.x(), fPosition.y(), - gHalfSizes[fObjType], - gHalfSizes[fObjType]); - } - - private: - ObjType fObjType; - SkPoint fPosition; - SkVector fVelocity; - SkScalar fRot; // In radians. - SkScalar fDeltaRot; // In radiands. Not used by ship. - }; - - - - -private: - static const int kNumLights = 2; - static const int kNumAsteroids = 6; - static const int kNumShips = 1; - - static const int kBigSize = 128; - static const int kMedSize = 64; - static const int kSmSize = 32; - static const int kPad = 1; - static const int kAtlasWidth = kBigSize + kBigSize + 2 * kPad; // 2 pads in the middle - static const int kAtlasHeight = kBigSize + kMedSize + kSmSize + kMedSize + 3 * kPad; - - static const int kDiffXOff = 0; - static const int kNormXOff = kBigSize + 2 * kPad; - - static const int kBigYOff = 0; - static const int kMedYOff = kBigSize + kPad; - static const int kSmYOff = kMedYOff + kMedSize + kPad; - static const int kShipYOff = kSmYOff + kSmSize + kPad; - static const int kMaxShipSpeed = 5; - - SkBitmap fAtlas; - ObjectRecord fAsteroids[kNumAsteroids]; - ObjectRecord fShip; - SkRect fDiffTex[kNumAsteroids+kNumShips]; - SkRect fNormTex[kNumAsteroids+kNumShips]; - SkRect fBounds; - bool fUseColors; - SkVector3 fLightDir; - sk_sp<SkLights> fLights; - - typedef SkDrawable INHERITED; -}; - -class DrawLitAtlasView : public SampleView { -public: - DrawLitAtlasView() - : fDrawable(new DrawLitAtlasDrawable(SkRect::MakeWH(640, 480))) { - } - -protected: - bool onQuery(SkEvent* evt) override { - if (SampleCode::TitleQ(*evt)) { - SampleCode::TitleR(evt, "DrawLitAtlas"); - return true; - } - SkUnichar uni; - if (SampleCode::CharQ(*evt, &uni)) { - switch (uni) { - case 'C': - fDrawable->toggleUseColors(); - this->inval(NULL); - return true; - case 'j': - fDrawable->left(); - this->inval(NULL); - return true; - case 'k': - fDrawable->thrust(); - this->inval(NULL); - return true; - case 'l': - fDrawable->right(); - this->inval(NULL); - return true; - case 'o': - fDrawable->rotateLight(); - this->inval(NULL); - return true; - default: - break; - } - } - return this->INHERITED::onQuery(evt); - } - - void onDrawContent(SkCanvas* canvas) override { - canvas->drawDrawable(fDrawable.get()); - this->inval(NULL); - } - -#if 0 - // TODO: switch over to use this for our animation - bool onAnimate(const SkAnimTimer& timer) override { - SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360)); - fAnimatingDrawable->setSweep(angle); - return true; - } -#endif - -private: - sk_sp<DrawLitAtlasDrawable> fDrawable; - - typedef SampleView INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -static SkView* MyFactory() { return new DrawLitAtlasView; } -static SkViewRegister reg(MyFactory); diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 4a777b2d5c..66e1faf889 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -20,7 +20,6 @@ #include "SkImageFilter.h" #include "SkImageFilterCache.h" #include "SkLatticeIter.h" -#include "SkLights.h" #include "SkMakeUnique.h" #include "SkMatrixUtils.h" #include "SkMetaData.h" diff --git a/src/core/SkLights.cpp b/src/core/SkLights.cpp deleted file mode 100644 index 1073ba0b82..0000000000 --- a/src/core/SkLights.cpp +++ /dev/null @@ -1,111 +0,0 @@ - -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkColorSpaceXformer.h" -#include "SkLights.h" -#include "SkReadBuffer.h" - -sk_sp<SkLights> SkLights::MakeFromBuffer(SkReadBuffer& buf) { - Builder builder; - - SkColor3f ambColor; - if (!buf.readScalarArray(&ambColor.fX, 3)) { - return nullptr; - } - - builder.setAmbientLightColor(ambColor); - - int numLights = buf.readInt(); - - for (int l = 0; l < numLights; ++l) { - bool isPoint = buf.readBool(); - - SkColor3f color; - if (!buf.readScalarArray(&color.fX, 3)) { - return nullptr; - } - - SkVector3 dirOrPos; - if (!buf.readScalarArray(&dirOrPos.fX, 3)) { - return nullptr; - } - - sk_sp<SkImage> depthMap; - bool hasShadowMap = buf.readBool(); - if (hasShadowMap) { - if (!(depthMap = buf.readImage())) { - return nullptr; - } - } - - bool isRadial = buf.readBool(); - if (isPoint) { - SkScalar intensity; - intensity = buf.readScalar(); - Light light = Light::MakePoint(color, dirOrPos, intensity, isRadial); - light.setShadowMap(depthMap); - builder.add(light); - } else { - Light light = Light::MakeDirectional(color, dirOrPos, isRadial); - light.setShadowMap(depthMap); - builder.add(light); - } - } - - return builder.finish(); -} - -static SkColor3f xform_color(const SkColor3f& color, SkColorSpaceXformer* xformer) { - SkColor origColor = SkColorSetARGBInline(0xFF, - SkScalarRoundToInt(color.fX), - SkScalarRoundToInt(color.fY), - SkScalarRoundToInt(color.fZ)); - SkColor xformedColor = xformer->apply(origColor); - return SkColor3f::Make(SkIntToScalar(SkGetPackedR32(xformedColor)), - SkIntToScalar(SkGetPackedG32(xformedColor)), - SkIntToScalar(SkGetPackedB32(xformedColor))); -} - -sk_sp<SkLights> SkLights::makeColorSpace(SkColorSpaceXformer* xformer) const { - SkLights::Builder builder; - for (int i = 0; i < this->numLights(); i++) { - Light light(fLights[i].type(), xform_color(fLights[i].color(), xformer), - fLights[i].fDirOrPos, fLights[i].fIntensity, fLights[i].isRadial()); - builder.add(light); - } - builder.setAmbientLightColor(xform_color(fAmbientLightColor, xformer)); - return builder.finish(); -} - -void SkLights::flatten(SkWriteBuffer& buf) const { - buf.writeScalarArray(&this->ambientLightColor().fX, 3); - - buf.writeInt(this->numLights()); - for (int l = 0; l < this->numLights(); ++l) { - const Light& light = this->light(l); - - bool isPoint = Light::kPoint_LightType == light.type(); - - buf.writeBool(isPoint); - buf.writeScalarArray(&light.color().fX, 3); - buf.writeScalarArray(&light.dir().fX, 3); - - bool hasShadowMap = light.getShadowMap() != nullptr; - buf.writeBool(hasShadowMap); - - bool isRadial = light.isRadial(); - buf.writeBool(isRadial); - - if (hasShadowMap) { - buf.writeImage(light.getShadowMap()); - } - if (isPoint) { - buf.writeScalar(light.intensity()); - } - } -} diff --git a/src/core/SkNormalFlatSource.cpp b/src/core/SkNormalFlatSource.cpp deleted file mode 100644 index 1e97ca7224..0000000000 --- a/src/core/SkNormalFlatSource.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkNormalFlatSource.h" - -#include "SkArenaAlloc.h" -#include "SkNormalSource.h" -#include "SkPoint3.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" - -#if SK_SUPPORT_GPU -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" - -class NormalFlatFP : public GrFragmentProcessor { -public: - static sk_sp<GrFragmentProcessor> Make() { - return sk_sp<GrFragmentProcessor>(new NormalFlatFP()); - } - - const char* name() const override { return "NormalFlatFP"; } - - sk_sp<GrFragmentProcessor> clone() const override { return Make(); } - -private: - class GLSLNormalFlatFP : public GrGLSLFragmentProcessor { - public: - GLSLNormalFlatFP() {} - - void emitCode(EmitArgs& args) override { - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - - fragBuilder->codeAppendf("%s = float4(0, 0, 1, 0);", args.fOutputColor); - } - - private: - void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override {} - }; - - NormalFlatFP() : INHERITED(kConstantOutputForConstantInput_OptimizationFlag) { - this->initClassID<NormalFlatFP>(); - } - - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {} - - GrColor4f constantOutputForConstantInput(GrColor4f) const override { - return GrColor4f(0, 0, 1, 0); - } - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLNormalFlatFP; } - - bool onIsEqual(const GrFragmentProcessor&) const override { return true; } - - typedef GrFragmentProcessor INHERITED; -}; - -sk_sp<GrFragmentProcessor> SkNormalFlatSourceImpl::asFragmentProcessor( - const SkShaderBase::AsFPArgs&) const { - - return NormalFlatFP::Make(); -} - -#endif // SK_SUPPORT_GPU - -//////////////////////////////////////////////////////////////////////////// - -SkNormalFlatSourceImpl::Provider::Provider() {} - -SkNormalFlatSourceImpl::Provider::~Provider() {} - -SkNormalSource::Provider* SkNormalFlatSourceImpl::asProvider(const SkShaderBase::ContextRec &rec, - SkArenaAlloc *alloc) const { - return alloc->make<Provider>(); -} - -void SkNormalFlatSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[], - int count) const { - for (int i = 0; i < count; i++) { - output[i] = {0.0f, 0.0f, 1.0f}; - } -} - -//////////////////////////////////////////////////////////////////////////////// - -sk_sp<SkFlattenable> SkNormalFlatSourceImpl::CreateProc(SkReadBuffer& buf) { - return sk_make_sp<SkNormalFlatSourceImpl>(); -} - -void SkNormalFlatSourceImpl::flatten(SkWriteBuffer& buf) const { - this->INHERITED::flatten(buf); -} - -//////////////////////////////////////////////////////////////////////////// - -sk_sp<SkNormalSource> SkNormalSource::MakeFlat() { - return sk_make_sp<SkNormalFlatSourceImpl>(); -} diff --git a/src/core/SkNormalFlatSource.h b/src/core/SkNormalFlatSource.h deleted file mode 100644 index 938e28f3c5..0000000000 --- a/src/core/SkNormalFlatSource.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkNormalFlatSource_DEFINED -#define SkNormalFlatSource_DEFINED - -#include "SkNormalSource.h" - -class SK_API SkNormalFlatSourceImpl : public SkNormalSource { -public: - SkNormalFlatSourceImpl(){} - -#if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override; -#endif - - SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec, - SkArenaAlloc* alloc) const override; - - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalFlatSourceImpl) - -protected: - void flatten(SkWriteBuffer& buf) const override; - -private: - class Provider : public SkNormalSource::Provider { - public: - Provider(); - - ~Provider() override; - - void fillScanLine(int x, int y, SkPoint3 output[], int count) const override; - - private: - typedef SkNormalSource::Provider INHERITED; - }; - - friend class SkNormalSource; - - typedef SkNormalSource INHERITED; -}; - -#endif diff --git a/src/core/SkNormalMapSource.cpp b/src/core/SkNormalMapSource.cpp deleted file mode 100644 index dbbbf2ea48..0000000000 --- a/src/core/SkNormalMapSource.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkNormalMapSource.h" - -#include "SkArenaAlloc.h" -#include "SkLightingShader.h" -#include "SkMatrix.h" -#include "SkNormalSource.h" -#include "SkPM4f.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" - -#if SK_SUPPORT_GPU -#include "GrCoordTransform.h" -#include "GrSamplerParams.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "SkGr.h" - -class NormalMapFP : public GrFragmentProcessor { -public: - static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> mapFP, - const SkMatrix& invCTM) { - return sk_sp<GrFragmentProcessor>(new NormalMapFP(std::move(mapFP), invCTM)); - } - - const char* name() const override { return "NormalMapFP"; } - - const SkMatrix& invCTM() const { return fInvCTM; } - - sk_sp<GrFragmentProcessor> clone() const override { - return Make(this->childProcessor(0).clone(), fInvCTM); - } - -private: - class GLSLNormalMapFP : public GrGLSLFragmentProcessor { - public: - GLSLNormalMapFP() - : fColumnMajorInvCTM22{0.0f} {} - - void emitCode(EmitArgs& args) override { - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - - // add uniform - const char* xformUniName = nullptr; - fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat22f_GrSLType, - kDefault_GrSLPrecision, "Xform", &xformUniName); - - SkString dstNormalColorName("dstNormalColor"); - this->emitChild(0, &dstNormalColorName, args); - fragBuilder->codeAppendf("float3 normal = normalize(%s.rgb - float3(0.5));", - dstNormalColorName.c_str()); - - // If there's no x & y components, return (0, 0, +/- 1) instead to avoid division by 0 - fragBuilder->codeAppend( "if (abs(normal.z) > 0.999) {"); - fragBuilder->codeAppendf(" %s = normalize(float4(0.0, 0.0, normal.z, 0.0));", - args.fOutputColor); - // Else, Normalizing the transformed X and Y, while keeping constant both Z and the - // vector's angle in the XY plane. This maintains the "slope" for the surface while - // appropriately rotating the normal regardless of any anisotropic scaling that occurs. - // Here, we call 'scaling factor' the number that must divide the transformed X and Y so - // that the normal's length remains equal to 1. - fragBuilder->codeAppend( "} else {"); - fragBuilder->codeAppendf(" float2 transformed = %s * normal.xy;", - xformUniName); - fragBuilder->codeAppend( " float scalingFactorSquared = " - "( (transformed.x * transformed.x) " - "+ (transformed.y * transformed.y) )" - "/(1.0 - (normal.z * normal.z));"); - fragBuilder->codeAppendf(" %s = float4(transformed*inversesqrt(scalingFactorSquared)," - "normal.z, 0.0);", - args.fOutputColor); - fragBuilder->codeAppend( "}"); - } - - static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b) { - b->add32(0x0); - } - - private: - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& proc) override { - const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); - - const SkMatrix& invCTM = normalMapFP.invCTM(); - fColumnMajorInvCTM22[0] = invCTM.get(SkMatrix::kMScaleX); - fColumnMajorInvCTM22[1] = invCTM.get(SkMatrix::kMSkewY); - fColumnMajorInvCTM22[2] = invCTM.get(SkMatrix::kMSkewX); - fColumnMajorInvCTM22[3] = invCTM.get(SkMatrix::kMScaleY); - pdman.setMatrix2f(fXformUni, fColumnMajorInvCTM22); - } - - private: - // Upper-right 2x2 corner of the inverse of the CTM in column-major form - float fColumnMajorInvCTM22[4]; - GrGLSLProgramDataManager::UniformHandle fXformUni; - }; - - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { - GLSLNormalMapFP::GenKey(*this, caps, b); - } - NormalMapFP(sk_sp<GrFragmentProcessor> mapFP, const SkMatrix& invCTM) - : INHERITED(kNone_OptimizationFlags), fInvCTM(invCTM) { - this->registerChildProcessor(mapFP); - - this->initClassID<NormalMapFP>(); - } - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLNormalMapFP; } - - bool onIsEqual(const GrFragmentProcessor& proc) const override { - const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); - return fInvCTM == normalMapFP.fInvCTM; - } - - SkMatrix fInvCTM; - - typedef GrFragmentProcessor INHERITED; -}; - -sk_sp<GrFragmentProcessor> SkNormalMapSourceImpl::asFragmentProcessor( - const SkShaderBase::AsFPArgs& args) const { - sk_sp<GrFragmentProcessor> mapFP = as_SB(fMapShader)->asFragmentProcessor(args); - if (!mapFP) { - return nullptr; - } - - return NormalMapFP::Make(std::move(mapFP), fInvCTM); -} - -#endif // SK_SUPPORT_GPU - -//////////////////////////////////////////////////////////////////////////// - -SkNormalMapSourceImpl::Provider::Provider(const SkNormalMapSourceImpl& source, - SkShaderBase::Context* mapContext) - : fSource(source) - , fMapContext(mapContext) {} - -SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShaderBase::ContextRec &rec, - SkArenaAlloc* alloc) const { - SkMatrix normTotalInv; - if (!this->computeNormTotalInverse(rec, &normTotalInv)) { - return nullptr; - } - - // Overriding paint's alpha because we need the normal map's RGB channels to be unpremul'd - SkPaint overridePaint {*(rec.fPaint)}; - overridePaint.setAlpha(0xFF); - SkShaderBase::ContextRec overrideRec(overridePaint, *(rec.fMatrix), rec.fLocalMatrix, - rec.fPreferredDstType, rec.fDstColorSpace); - - auto* context = as_SB(fMapShader)->makeContext(overrideRec, alloc); - if (!context) { - return nullptr; - } - - return alloc->make<Provider>(*this, context); -} - -bool SkNormalMapSourceImpl::computeNormTotalInverse(const SkShaderBase::ContextRec& rec, - SkMatrix* normTotalInverse) const { - SkMatrix total = SkMatrix::Concat(*rec.fMatrix, fMapShader->getLocalMatrix()); - if (rec.fLocalMatrix) { - total.preConcat(*rec.fLocalMatrix); - } - - return total.invert(normTotalInverse); -} - -#define BUFFER_MAX 16 -void SkNormalMapSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[], - int count) const { - SkPMColor tmpNormalColors[BUFFER_MAX]; - - do { - int n = SkTMin(count, BUFFER_MAX); - - fMapContext->shadeSpan(x, y, tmpNormalColors, n); - - for (int i = 0; i < n; i++) { - SkPoint3 tempNorm; - - tempNorm.set(SkIntToScalar(SkGetPackedR32(tmpNormalColors[i])) - 127.0f, - SkIntToScalar(SkGetPackedG32(tmpNormalColors[i])) - 127.0f, - SkIntToScalar(SkGetPackedB32(tmpNormalColors[i])) - 127.0f); - - tempNorm.normalize(); - - - if (!SkScalarNearlyEqual(SkScalarAbs(tempNorm.fZ), 1.0f)) { - SkVector transformed = fSource.fInvCTM.mapVector(tempNorm.fX, tempNorm.fY); - - // Normalizing the transformed X and Y, while keeping constant both Z and the - // vector's angle in the XY plane. This maintains the "slope" for the surface while - // appropriately rotating the normal for any anisotropic scaling that occurs. - // Here, we call scaling factor the number that must divide the transformed X and Y - // so that the normal's length remains equal to 1. - SkScalar scalingFactorSquared = - (SkScalarSquare(transformed.fX) + SkScalarSquare(transformed.fY)) - / (1.0f - SkScalarSquare(tempNorm.fZ)); - SkScalar invScalingFactor = SkScalarInvert(SkScalarSqrt(scalingFactorSquared)); - - output[i].fX = transformed.fX * invScalingFactor; - output[i].fY = transformed.fY * invScalingFactor; - output[i].fZ = tempNorm.fZ; - } else { - output[i] = {0.0f, 0.0f, tempNorm.fZ}; - output[i].normalize(); - } - - SkASSERT(SkScalarNearlyEqual(output[i].length(), 1.0f)); - } - - output += n; - x += n; - count -= n; - } while (count > 0); -} - -//////////////////////////////////////////////////////////////////////////////// - -sk_sp<SkFlattenable> SkNormalMapSourceImpl::CreateProc(SkReadBuffer& buf) { - - sk_sp<SkShader> mapShader = buf.readFlattenable<SkShaderBase>(); - - SkMatrix invCTM; - buf.readMatrix(&invCTM); - - return sk_make_sp<SkNormalMapSourceImpl>(std::move(mapShader), invCTM); -} - -void SkNormalMapSourceImpl::flatten(SkWriteBuffer& buf) const { - this->INHERITED::flatten(buf); - - buf.writeFlattenable(fMapShader.get()); - buf.writeMatrix(fInvCTM); -} - -//////////////////////////////////////////////////////////////////////////// - -sk_sp<SkNormalSource> SkNormalSource::MakeFromNormalMap(sk_sp<SkShader> map, const SkMatrix& ctm) { - SkMatrix invCTM; - - if (!ctm.invert(&invCTM) || !map) { - return nullptr; - } - - return sk_make_sp<SkNormalMapSourceImpl>(std::move(map), invCTM); -} diff --git a/src/core/SkNormalMapSource.h b/src/core/SkNormalMapSource.h deleted file mode 100644 index a02e6abd09..0000000000 --- a/src/core/SkNormalMapSource.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkNormalMapSource_DEFINED -#define SkNormalMapSource_DEFINED - -#include "SkNormalSource.h" - -class SkNormalMapSourceImpl : public SkNormalSource { -public: - SkNormalMapSourceImpl(sk_sp<SkShader> mapShader, const SkMatrix& invCTM) - : fMapShader(std::move(mapShader)) - , fInvCTM(invCTM) {} - -#if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override; -#endif - - SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec, - SkArenaAlloc* alloc) const override; - - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalMapSourceImpl) - -protected: - void flatten(SkWriteBuffer& buf) const override; - - bool computeNormTotalInverse(const SkShaderBase::ContextRec& rec, - SkMatrix* normTotalInverse) const; - -private: - class Provider : public SkNormalSource::Provider { - public: - Provider(const SkNormalMapSourceImpl& source, SkShaderBase::Context* mapContext); - - void fillScanLine(int x, int y, SkPoint3 output[], int count) const override; - - private: - const SkNormalMapSourceImpl& fSource; - SkShaderBase::Context* fMapContext; - - typedef SkNormalSource::Provider INHERITED; - }; - - sk_sp<SkShader> fMapShader; - SkMatrix fInvCTM; // Inverse of the canvas total matrix, used for rotating normals. - - friend class SkNormalSource; - - typedef SkNormalSource INHERITED; -}; - -#endif - diff --git a/src/core/SkNormalSource.cpp b/src/core/SkNormalSource.cpp deleted file mode 100644 index ad1f5a3e40..0000000000 --- a/src/core/SkNormalSource.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkNormalFlatSource.h" -#include "SkNormalMapSource.h" -#include "SkNormalSource.h" - -// Generating vtable -SkNormalSource::~SkNormalSource() {} - -//////////////////////////////////////////////////////////////////////////// - -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkNormalSource) -SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalMapSourceImpl) -SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalFlatSourceImpl) -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END - -//////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkNormalSource.h b/src/core/SkNormalSource.h deleted file mode 100644 index e9879feb70..0000000000 --- a/src/core/SkNormalSource.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkNormalSource_DEFINED -#define SkNormalSource_DEFINED - -#include "SkFlattenable.h" -#include "SkShaderBase.h" - -class SkMatrix; -struct SkPoint3; - -#if SK_SUPPORT_GPU -class GrFragmentProcessor; -#endif - -/** Abstract class that generates or reads in normals for use by SkLightingShader. -*/ -class SK_API SkNormalSource : public SkFlattenable { -public: - virtual ~SkNormalSource() override; - -#if SK_SUPPORT_GPU - /** Returns a fragment processor that takes no input and outputs a normal (already rotated) - as its output color. To be used as a child fragment processor. - */ - virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const = 0; -#endif - - class Provider { - public: - virtual ~Provider() {} - - /** Called for each span of the object being drawn on the CPU. Your subclass should set - the appropriate normals that correspond to the specified device coordinates. - */ - virtual void fillScanLine(int x, int y, SkPoint3 output[], int count) const = 0; - }; - - /** Returns an instance of 'Provider' that provides normals for the CPU pipeline. The - necessary data will be initialized in place at 'storage'. - */ - virtual Provider* asProvider(const SkShaderBase::ContextRec&, SkArenaAlloc*) const = 0; - - /** Returns a normal source that provides normals sourced from the the normal map argument. - - @param map a shader that outputs the normal map - @param ctm the current canvas' total matrix, used to rotate normals when necessary. - - nullptr will be returned if 'map' is null - - The normal map is currently assumed to be an 8888 image where the normal at a texel - is retrieved by: - N.x = R-127; - N.y = G-127; - N.z = B-127; - N.normalize(); - The +Z axis is thus encoded in RGB as (127, 127, 255) while the -Z axis is - (127, 127, 0). - */ - static sk_sp<SkNormalSource> MakeFromNormalMap(sk_sp<SkShader> map, const SkMatrix& ctm); - - /** Returns a normal source that provides straight-up normals only <0, 0, 1>. - */ - static sk_sp<SkNormalSource> MakeFlat(); - - SK_DEFINE_FLATTENABLE_TYPE(SkNormalSource) - SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() -}; - -#endif diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp index 73195b1ce5..d372f12228 100644 --- a/src/ports/SkGlobalInitialization_default.cpp +++ b/src/ports/SkGlobalInitialization_default.cpp @@ -26,14 +26,12 @@ #include "SkLayerDrawLooper.h" #include "SkLayerRasterizer.h" #include "SkLightingImageFilter.h" -#include "SkLightingShader.h" #include "SkLocalMatrixImageFilter.h" #include "SkLumaColorFilter.h" #include "SkMagnifierImageFilter.h" #include "SkMatrixConvolutionImageFilter.h" #include "SkMergeImageFilter.h" #include "SkMorphologyImageFilter.h" -#include "SkNormalSource.h" #include "SkOffsetImageFilter.h" #include "../../src/effects/SkOverdrawColorFilter.h" #include "SkPaintImageFilter.h" @@ -88,8 +86,6 @@ void SkFlattenable::PrivateInitializer::InitEffects() { // Shader SkPerlinNoiseShader::InitializeFlattenables(); SkGradientShader::InitializeFlattenables(); - SkLightingShader::InitializeFlattenables(); - SkNormalSource::InitializeFlattenables(); // PathEffect SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect) diff --git a/src/shaders/SkLightingShader.cpp b/src/shaders/SkLightingShader.cpp deleted file mode 100644 index 97c5ac6ce4..0000000000 --- a/src/shaders/SkLightingShader.cpp +++ /dev/null @@ -1,504 +0,0 @@ -/* - * 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 "SkArenaAlloc.h" -#include "SkBitmapProcShader.h" -#include "SkBitmapProcState.h" -#include "SkColor.h" -#include "SkColorSpaceXformer.h" -#include "SkEmptyShader.h" -#include "SkLightingShader.h" -#include "SkMathPriv.h" -#include "SkNormalSource.h" -#include "SkPoint3.h" -#include "SkReadBuffer.h" -#include "SkShaderBase.h" -#include "SkWriteBuffer.h" - -//////////////////////////////////////////////////////////////////////////// - -/* - SkLightingShader TODOs: - support different light types - support multiple lights - fix non-opaque diffuse textures - - To Test: - A8 diffuse textures - down & upsampled draws -*/ - - - -/** \class SkLightingShaderImpl - This subclass of shader applies lighting. -*/ -class SkLightingShaderImpl : public SkShaderBase { -public: - /** Create a new lighting shader that uses the provided normal map and - lights to light the diffuse bitmap. - @param diffuseShader the shader that provides the diffuse colors - @param normalSource the source of normals for lighting computation - @param lights the lights applied to the geometry - */ - SkLightingShaderImpl(sk_sp<SkShader> diffuseShader, - sk_sp<SkNormalSource> normalSource, - sk_sp<SkLights> lights) - : fDiffuseShader(std::move(diffuseShader)) - , fNormalSource(std::move(normalSource)) - , fLights(std::move(lights)) {} - - bool isOpaque() const override; - -#if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override; -#endif - - class LightingShaderContext : public Context { - public: - // The context takes ownership of the context and provider. It will call their destructors - // and then indirectly free their memory by calling free() on heapAllocated - LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&, - SkShaderBase::Context* diffuseContext, SkNormalSource::Provider*, - void* heapAllocated); - - void shadeSpan(int x, int y, SkPMColor[], int count) override; - - uint32_t getFlags() const override { return fFlags; } - - private: - SkShaderBase::Context* fDiffuseContext; - SkNormalSource::Provider* fNormalProvider; - SkColor fPaintColor; - uint32_t fFlags; - - typedef Context INHERITED; - }; - - SK_TO_STRING_OVERRIDE() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl) - -protected: - void flatten(SkWriteBuffer&) const override; - Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override; - sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override; - -private: - sk_sp<SkShader> fDiffuseShader; - sk_sp<SkNormalSource> fNormalSource; - sk_sp<SkLights> fLights; - - friend class SkLightingShader; - - typedef SkShaderBase INHERITED; -}; - -//////////////////////////////////////////////////////////////////////////// - -#if SK_SUPPORT_GPU - -#include "GrCoordTransform.h" -#include "GrFragmentProcessor.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "glsl/GrGLSLProgramDataManager.h" -#include "glsl/GrGLSLUniformHandler.h" -#include "SkGr.h" - -// This FP expects a premul'd color input for its diffuse color. Premul'ing of the paint's color is -// handled by the asFragmentProcessor() factory, but shaders providing diffuse color must output it -// premul'd. -class LightingFP : public GrFragmentProcessor { -public: - static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> normalFP, - sk_sp<SkLights> lights) { - return sk_sp<GrFragmentProcessor>(new LightingFP(std::move(normalFP), std::move(lights))); - } - - const char* name() const override { return "LightingFP"; } - - sk_sp<GrFragmentProcessor> clone() const override { - return sk_sp<GrFragmentProcessor>(new LightingFP(*this)); - } - - const SkTArray<SkLights::Light>& directionalLights() const { return fDirectionalLights; } - const SkColor3f& ambientColor() const { return fAmbientColor; } - -private: - class GLSLLightingFP : public GrGLSLFragmentProcessor { - public: - GLSLLightingFP() { - fAmbientColor.fX = 0.0f; - } - - void emitCode(EmitArgs& args) override { - - GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - const LightingFP& lightingFP = args.fFp.cast<LightingFP>(); - - const char *lightDirsUniName = nullptr; - const char *lightColorsUniName = nullptr; - if (lightingFP.fDirectionalLights.count() != 0) { - fLightDirsUni = uniformHandler->addUniformArray( - kFragment_GrShaderFlag, - kVec3f_GrSLType, - kDefault_GrSLPrecision, - "LightDir", - lightingFP.fDirectionalLights.count(), - &lightDirsUniName); - fLightColorsUni = uniformHandler->addUniformArray( - kFragment_GrShaderFlag, - kVec3f_GrSLType, - kDefault_GrSLPrecision, - "LightColor", - lightingFP.fDirectionalLights.count(), - &lightColorsUniName); - } - - const char* ambientColorUniName = nullptr; - fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec3f_GrSLType, kDefault_GrSLPrecision, - "AmbientColor", &ambientColorUniName); - - fragBuilder->codeAppendf("float4 diffuseColor = %s;", args.fInputColor); - - SkString dstNormalName("dstNormal"); - this->emitChild(0, &dstNormalName, args); - - fragBuilder->codeAppendf("float3 normal = %s.xyz;", dstNormalName.c_str()); - - fragBuilder->codeAppend( "float3 result = float3(0.0);"); - - // diffuse light - if (lightingFP.fDirectionalLights.count() != 0) { - fragBuilder->codeAppendf("for (int i = 0; i < %d; i++) {", - lightingFP.fDirectionalLights.count()); - // TODO: modulate the contribution from each light based on the shadow map - fragBuilder->codeAppendf(" float NdotL = clamp(dot(normal, %s[i]), 0.0, 1.0);", - lightDirsUniName); - fragBuilder->codeAppendf(" result += %s[i]*diffuseColor.rgb*NdotL;", - lightColorsUniName); - fragBuilder->codeAppend("}"); - } - - // ambient light - fragBuilder->codeAppendf("result += %s * diffuseColor.rgb;", ambientColorUniName); - - // Clamping to alpha (equivalent to an unpremul'd clamp to 1.0) - fragBuilder->codeAppendf("%s = float4(clamp(result.rgb, 0.0, diffuseColor.a), " - "diffuseColor.a);", args.fOutputColor); - } - - static void GenKey(const GrProcessor& proc, const GrShaderCaps&, GrProcessorKeyBuilder* b) { - const LightingFP& lightingFP = proc.cast<LightingFP>(); - b->add32(lightingFP.fDirectionalLights.count()); - } - - protected: - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& proc) override { - const LightingFP& lightingFP = proc.cast<LightingFP>(); - - const SkTArray<SkLights::Light>& directionalLights = lightingFP.directionalLights(); - if (directionalLights != fDirectionalLights) { - SkTArray<SkColor3f> lightDirs(directionalLights.count()); - SkTArray<SkVector3> lightColors(directionalLights.count()); - for (const SkLights::Light& light : directionalLights) { - lightDirs.push_back(light.dir()); - lightColors.push_back(light.color()); - } - - pdman.set3fv(fLightDirsUni, directionalLights.count(), &(lightDirs[0].fX)); - pdman.set3fv(fLightColorsUni, directionalLights.count(), &(lightColors[0].fX)); - - fDirectionalLights = directionalLights; - } - - const SkColor3f& ambientColor = lightingFP.ambientColor(); - if (ambientColor != fAmbientColor) { - pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); - fAmbientColor = ambientColor; - } - } - - private: - SkTArray<SkLights::Light> fDirectionalLights; - GrGLSLProgramDataManager::UniformHandle fLightDirsUni; - GrGLSLProgramDataManager::UniformHandle fLightColorsUni; - - SkColor3f fAmbientColor; - GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; - }; - - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { - GLSLLightingFP::GenKey(*this, caps, b); - } - - LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights) - : INHERITED(kPreservesOpaqueInput_OptimizationFlag) { - // fuse all ambient lights into a single one - fAmbientColor = lights->ambientLightColor(); - for (int i = 0; i < lights->numLights(); ++i) { - if (SkLights::Light::kDirectional_LightType == lights->light(i).type()) { - fDirectionalLights.push_back(lights->light(i)); - // TODO get the handle to the shadow map if there is one - } else { - SkDEBUGFAIL("Unimplemented Light Type passed to LightingFP"); - } - } - - this->registerChildProcessor(std::move(normalFP)); - this->initClassID<LightingFP>(); - } - - LightingFP(const LightingFP& that) - : INHERITED(kPreservesOpaqueInput_OptimizationFlag) - , fDirectionalLights(that.fDirectionalLights) - , fAmbientColor(that.fAmbientColor) { - this->registerChildProcessor(that.childProcessor(0).clone()); - this->initClassID<LightingFP>(); - } - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLLightingFP; } - - bool onIsEqual(const GrFragmentProcessor& proc) const override { - const LightingFP& lightingFP = proc.cast<LightingFP>(); - return fDirectionalLights == lightingFP.fDirectionalLights && - fAmbientColor == lightingFP.fAmbientColor; - } - - SkTArray<SkLights::Light> fDirectionalLights; - SkColor3f fAmbientColor; - - typedef GrFragmentProcessor INHERITED; -}; - -//////////////////////////////////////////////////////////////////////////// - -sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(const AsFPArgs& args) const { - sk_sp<GrFragmentProcessor> normalFP(fNormalSource->asFragmentProcessor(args)); - if (!normalFP) { - return nullptr; - } - - if (fDiffuseShader) { - sk_sp<GrFragmentProcessor> fpPipeline[] = { - as_SB(fDiffuseShader)->asFragmentProcessor(args), - LightingFP::Make(std::move(normalFP), fLights) - }; - if (!fpPipeline[0] || !fpPipeline[1]) { - return nullptr; - } - - sk_sp<GrFragmentProcessor> innerLightFP = GrFragmentProcessor::RunInSeries(fpPipeline, 2); - // FP is wrapped because paint's alpha needs to be applied to output - return GrFragmentProcessor::MulOutputByInputAlpha(std::move(innerLightFP)); - } else { - // FP is wrapped because paint comes in unpremul'd to fragment shader, but LightingFP - // expects premul'd color. - return GrFragmentProcessor::PremulInput(LightingFP::Make(std::move(normalFP), fLights)); - } -} - -#endif - -//////////////////////////////////////////////////////////////////////////// - -bool SkLightingShaderImpl::isOpaque() const { - return (fDiffuseShader ? fDiffuseShader->isOpaque() : false); -} - -SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( - const SkLightingShaderImpl& shader, const ContextRec& rec, - SkShaderBase::Context* diffuseContext, SkNormalSource::Provider* normalProvider, - void* heapAllocated) - : INHERITED(shader, rec) - , fDiffuseContext(diffuseContext) - , fNormalProvider(normalProvider) { - bool isOpaque = shader.isOpaque(); - - // update fFlags - uint32_t flags = 0; - if (isOpaque && (255 == this->getPaintAlpha())) { - flags |= kOpaqueAlpha_Flag; - } - - fPaintColor = rec.fPaint->getColor(); - fFlags = flags; -} - -static inline SkPMColor convert(SkColor3f color, U8CPU a) { - if (color.fX <= 0.0f) { - color.fX = 0.0f; - } else if (color.fX >= 255.0f) { - color.fX = 255.0f; - } - - if (color.fY <= 0.0f) { - color.fY = 0.0f; - } else if (color.fY >= 255.0f) { - color.fY = 255.0f; - } - - if (color.fZ <= 0.0f) { - color.fZ = 0.0f; - } else if (color.fZ >= 255.0f) { - color.fZ = 255.0f; - } - - return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ); -} - -// larger is better (fewer times we have to loop), but we shouldn't -// take up too much stack-space (each one here costs 16 bytes) -#define BUFFER_MAX 16 -void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, - SkPMColor result[], int count) { - const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShaderImpl&>(fShader); - - SkPMColor diffuse[BUFFER_MAX]; - SkPoint3 normals[BUFFER_MAX]; - - SkColor diffColor = fPaintColor; - - do { - int n = SkTMin(count, BUFFER_MAX); - - fNormalProvider->fillScanLine(x, y, normals, n); - - if (fDiffuseContext) { - fDiffuseContext->shadeSpan(x, y, diffuse, n); - } - - for (int i = 0; i < n; ++i) { - if (fDiffuseContext) { - diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]); - } - - SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); - - // Adding ambient light - accum.fX += lightShader.fLights->ambientLightColor().fX * SkColorGetR(diffColor); - accum.fY += lightShader.fLights->ambientLightColor().fY * SkColorGetG(diffColor); - accum.fZ += lightShader.fLights->ambientLightColor().fZ * SkColorGetB(diffColor); - - // This is all done in linear unpremul color space (each component 0..255.0f though) - for (int l = 0; l < lightShader.fLights->numLights(); ++l) { - const SkLights::Light& light = lightShader.fLights->light(l); - - SkScalar illuminanceScalingFactor = 1.0f; - - if (SkLights::Light::kDirectional_LightType == light.type()) { - illuminanceScalingFactor = normals[i].dot(light.dir()); - if (illuminanceScalingFactor < 0.0f) { - illuminanceScalingFactor = 0.0f; - } - } - - accum.fX += light.color().fX * SkColorGetR(diffColor) * illuminanceScalingFactor; - accum.fY += light.color().fY * SkColorGetG(diffColor) * illuminanceScalingFactor; - accum.fZ += light.color().fZ * SkColorGetB(diffColor) * illuminanceScalingFactor; - } - - // convert() premultiplies the accumulate color with alpha - result[i] = convert(accum, SkColorGetA(diffColor)); - } - - result += n; - x += n; - count -= n; - } while (count > 0); -} - -//////////////////////////////////////////////////////////////////////////// - -#ifndef SK_IGNORE_TO_STRING -void SkLightingShaderImpl::toString(SkString* str) const { - str->appendf("LightingShader: ()"); -} -#endif - -sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { - - // Discarding SkShader flattenable params - bool hasLocalMatrix = buf.readBool(); - SkAssertResult(!hasLocalMatrix); - - sk_sp<SkLights> lights = SkLights::MakeFromBuffer(buf); - - sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>()); - - bool hasDiffuse = buf.readBool(); - sk_sp<SkShader> diffuseShader = nullptr; - if (hasDiffuse) { - diffuseShader = buf.readFlattenable<SkShaderBase>(); - } - - return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move(normalSource), - std::move(lights)); -} - -void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { - this->INHERITED::flatten(buf); - - fLights->flatten(buf); - - buf.writeFlattenable(fNormalSource.get()); - buf.writeBool(static_cast<bool>(fDiffuseShader)); - if (fDiffuseShader) { - buf.writeFlattenable(fDiffuseShader.get()); - } -} - -SkShaderBase::Context* SkLightingShaderImpl::onMakeContext( - const ContextRec& rec, SkArenaAlloc* alloc) const -{ - SkShaderBase::Context *diffuseContext = nullptr; - if (fDiffuseShader) { - diffuseContext = as_SB(fDiffuseShader)->makeContext(rec, alloc); - if (!diffuseContext) { - return nullptr; - } - } - - SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec, alloc); - if (!normalProvider) { - return nullptr; - } - - return alloc->make<LightingShaderContext>(*this, rec, diffuseContext, normalProvider, nullptr); -} - -sk_sp<SkShader> SkLightingShaderImpl::onMakeColorSpace(SkColorSpaceXformer* xformer) const { - sk_sp<SkShader> xformedDiffuseShader = - fDiffuseShader ? xformer->apply(fDiffuseShader.get()) : nullptr; - return SkLightingShader::Make(std::move(xformedDiffuseShader), fNormalSource, - fLights->makeColorSpace(xformer)); -} - -/////////////////////////////////////////////////////////////////////////////// - -sk_sp<SkShader> SkLightingShader::Make(sk_sp<SkShader> diffuseShader, - sk_sp<SkNormalSource> normalSource, - sk_sp<SkLights> lights) { - SkASSERT(lights); - if (!normalSource) { - normalSource = SkNormalSource::MakeFlat(); - } - - return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move(normalSource), - std::move(lights)); -} - -/////////////////////////////////////////////////////////////////////////////// - -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) - SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END - -/////////////////////////////////////////////////////////////////////////////// diff --git a/src/shaders/SkLightingShader.h b/src/shaders/SkLightingShader.h deleted file mode 100644 index aa90710aa4..0000000000 --- a/src/shaders/SkLightingShader.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkLightingShader_DEFINED -#define SkLightingShader_DEFINED - -#include "SkLights.h" -#include "SkShader.h" - -class SkBitmap; -class SkMatrix; -class SkNormalSource; - -class SK_API SkLightingShader { -public: - /** Returns a shader that lights the shape, colored by the diffuseShader, using the - normals from normalSource, with the set of lights provided. - - @param diffuseShader the shader that provides the colors. If nullptr, uses the paint's - color. - @param normalSource the source for the shape's normals. If nullptr, assumes straight - up normals (<0,0,1>). - @param lights the lights applied to the normals - - The lighting equation is currently: - result = (LightColor * dot(Normal, LightDir) + AmbientColor) * DiffuseColor - - */ - static sk_sp<SkShader> Make(sk_sp<SkShader> diffuseShader, sk_sp<SkNormalSource> normalSource, - sk_sp<SkLights> lights); - - SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() -}; - -#endif diff --git a/tests/SerializationTest.cpp b/tests/SerializationTest.cpp index 3c24c558ef..898b12f220 100644 --- a/tests/SerializationTest.cpp +++ b/tests/SerializationTest.cpp @@ -12,10 +12,8 @@ #include "SkFontDescriptor.h" #include "SkImage.h" #include "SkImageSource.h" -#include "SkLightingShader.h" #include "SkMakeUnique.h" #include "SkMallocPixelRef.h" -#include "SkNormalSource.h" #include "SkOSFile.h" #include "SkPictureRecorder.h" #include "SkShaderBase.h" @@ -552,64 +550,6 @@ DEF_TEST(Serialization, reporter) { } TestPictureTypefaceSerialization(reporter); - - // Test SkLightingShader/NormalMapSource serialization - { - const int kTexSize = 2; - - SkLights::Builder builder; - - builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), - SkVector3::Make(1.0f, 0.0f, 0.0f))); - builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f)); - - sk_sp<SkLights> fLights = builder.finish(); - - SkBitmap diffuse = sk_tool_utils::create_checkerboard_bitmap( - kTexSize, kTexSize, - sk_tool_utils::color_to_565(0x0), - sk_tool_utils::color_to_565(0xFF804020), - 8); - - SkRect bitmapBounds = SkRect::MakeIWH(diffuse.width(), diffuse.height()); - - SkMatrix matrix; - SkRect r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize)); - matrix.setRectToRect(bitmapBounds, r, SkMatrix::kFill_ScaleToFit); - - SkMatrix ctm; - ctm.setRotate(45); - SkBitmap normals; - normals.allocN32Pixels(kTexSize, kTexSize); - - sk_tool_utils::create_frustum_normal_map(&normals, SkIRect::MakeWH(kTexSize, kTexSize)); - sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(normals, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, &matrix); - sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(std::move(normalMap), - ctm); - sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(diffuse, - SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix); - - sk_sp<SkShader> lightingShader = SkLightingShader::Make(diffuseShader, - normalSource, - fLights); - sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter)); - - lightingShader = SkLightingShader::Make(std::move(diffuseShader), - nullptr, - fLights); - sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter)); - - lightingShader = SkLightingShader::Make(nullptr, - std::move(normalSource), - fLights); - sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter)); - - lightingShader = SkLightingShader::Make(nullptr, - nullptr, - fLights); - sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter)); - } } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp index d957d53f12..a8d877bf8b 100644 --- a/tools/sk_tool_utils.cpp +++ b/tools/sk_tool_utils.cpp @@ -261,114 +261,6 @@ void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPain memcpy(run.glyphs, glyphs.begin(), glyphs.count() * sizeof(uint16_t)); } -static inline void norm_to_rgb(SkBitmap* bm, int x, int y, const SkVector3& norm) { - SkASSERT(SkScalarNearlyEqual(norm.length(), 1.0f)); - unsigned char r = static_cast<unsigned char>((0.5f * norm.fX + 0.5f) * 255); - unsigned char g = static_cast<unsigned char>((-0.5f * norm.fY + 0.5f) * 255); - unsigned char b = static_cast<unsigned char>((0.5f * norm.fZ + 0.5f) * 255); - *bm->getAddr32(x, y) = SkPackARGB32(0xFF, r, g, b); -} - -void create_hemi_normal_map(SkBitmap* bm, const SkIRect& dst) { - const SkPoint center = SkPoint::Make(dst.fLeft + (dst.width() / 2.0f), - dst.fTop + (dst.height() / 2.0f)); - const SkPoint halfSize = SkPoint::Make(dst.width() / 2.0f, dst.height() / 2.0f); - - SkVector3 norm; - - for (int y = dst.fTop; y < dst.fBottom; ++y) { - for (int x = dst.fLeft; x < dst.fRight; ++x) { - norm.fX = (x + 0.5f - center.fX) / halfSize.fX; - norm.fY = (y + 0.5f - center.fY) / halfSize.fY; - - SkScalar tmp = norm.fX * norm.fX + norm.fY * norm.fY; - if (tmp >= 1.0f) { - norm.set(0.0f, 0.0f, 1.0f); - } else { - norm.fZ = sqrtf(1.0f - tmp); - } - - norm_to_rgb(bm, x, y, norm); - } - } -} - -void create_frustum_normal_map(SkBitmap* bm, const SkIRect& dst) { - const SkPoint center = SkPoint::Make(dst.fLeft + (dst.width() / 2.0f), - dst.fTop + (dst.height() / 2.0f)); - - SkIRect inner = dst; - inner.inset(dst.width()/4, dst.height()/4); - - SkPoint3 norm; - const SkPoint3 left = SkPoint3::Make(-SK_ScalarRoot2Over2, 0.0f, SK_ScalarRoot2Over2); - const SkPoint3 up = SkPoint3::Make(0.0f, -SK_ScalarRoot2Over2, SK_ScalarRoot2Over2); - const SkPoint3 right = SkPoint3::Make(SK_ScalarRoot2Over2, 0.0f, SK_ScalarRoot2Over2); - const SkPoint3 down = SkPoint3::Make(0.0f, SK_ScalarRoot2Over2, SK_ScalarRoot2Over2); - - for (int y = dst.fTop; y < dst.fBottom; ++y) { - for (int x = dst.fLeft; x < dst.fRight; ++x) { - if (inner.contains(x, y)) { - norm.set(0.0f, 0.0f, 1.0f); - } else { - SkScalar locX = x + 0.5f - center.fX; - SkScalar locY = y + 0.5f - center.fY; - - if (locX >= 0.0f) { - if (locY > 0.0f) { - norm = locX >= locY ? right : down; // LR corner - } else { - norm = locX > -locY ? right : up; // UR corner - } - } else { - if (locY > 0.0f) { - norm = -locX > locY ? left : down; // LL corner - } else { - norm = locX > locY ? up : left; // UL corner - } - } - } - - norm_to_rgb(bm, x, y, norm); - } - } -} - -void create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst) { - const SkPoint center = SkPoint::Make(dst.fLeft + (dst.width() / 2.0f), - dst.fTop + (dst.height() / 2.0f)); - - static const SkScalar k1OverRoot3 = 0.5773502692f; - - SkPoint3 norm; - const SkPoint3 leftUp = SkPoint3::Make(-k1OverRoot3, -k1OverRoot3, k1OverRoot3); - const SkPoint3 rightUp = SkPoint3::Make(k1OverRoot3, -k1OverRoot3, k1OverRoot3); - const SkPoint3 down = SkPoint3::Make(0.0f, SK_ScalarRoot2Over2, SK_ScalarRoot2Over2); - - for (int y = dst.fTop; y < dst.fBottom; ++y) { - for (int x = dst.fLeft; x < dst.fRight; ++x) { - SkScalar locX = x + 0.5f - center.fX; - SkScalar locY = y + 0.5f - center.fY; - - if (locX >= 0.0f) { - if (locY > 0.0f) { - norm = locX >= locY ? rightUp : down; // LR corner - } else { - norm = rightUp; - } - } else { - if (locY > 0.0f) { - norm = -locX > locY ? leftUp : down; // LL corner - } else { - norm = leftUp; - } - } - - norm_to_rgb(bm, x, y, norm); - } - } -} - #if !defined(__clang__) && defined(_MSC_VER) // MSVC takes ~2 minutes to compile this function with optimization. // We don't really care to wait that long for this function. diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h index 6283225c7f..ea06c119e7 100644 --- a/tools/sk_tool_utils.h +++ b/tools/sk_tool_utils.h @@ -121,12 +121,6 @@ namespace sk_tool_utils { void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPaint& origPaint, SkScalar x, SkScalar y); - void create_hemi_normal_map(SkBitmap* bm, const SkIRect& dst); - - void create_frustum_normal_map(SkBitmap* bm, const SkIRect& dst); - - void create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst); - void make_big_path(SkPath& path); // Return a blurred version of 'src'. This doesn't use a separable filter |