From 4c9155bd66d86de48069192f4b73bc292cfec135 Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Tue, 2 May 2017 10:37:45 -0400 Subject: [PATCH] Remove EXPERIMENTAL_SHADOWING, Part 1 Bug: skia:6557 Change-Id: I6482d74be7b360c93141a73dd80c67854530c7a1 Reviewed-on: https://skia-review.googlesource.com/15101 Reviewed-by: Mike Klein Reviewed-by: Florin Malita Commit-Queue: Mike Klein --- gm/shadowmaps.cpp | 118 --- gn/core.gni | 5 - gn/gm.gni | 1 - gn/samples.gni | 1 - gn/utils.gni | 2 - include/core/SkCanvas.h | 55 -- include/private/SkRecords.h | 6 - include/private/SkShadowParams.h | 50 -- samplecode/SampleShadowing.cpp | 301 -------- src/core/SkCanvas.cpp | 194 ----- src/core/SkLiteDL.cpp | 25 - src/core/SkLiteDL.h | 2 - src/core/SkLiteRecorder.cpp | 6 - src/core/SkLiteRecorder.h | 4 - src/core/SkPictureRecord.cpp | 23 - src/core/SkPictureRecord.h | 8 - src/core/SkRadialShadowMapShader.cpp | 428 ----------- src/core/SkRadialShadowMapShader.h | 31 - src/core/SkRecordDraw.cpp | 13 - src/core/SkRecorder.cpp | 17 - src/core/SkRecorder.h | 12 - src/core/SkShadowShader.cpp | 955 ------------------------ src/core/SkShadowShader.h | 40 - src/utils/SkShadowPaintFilterCanvas.cpp | 307 -------- src/utils/SkShadowPaintFilterCanvas.h | 117 --- tools/debugger/SkDebugCanvas.cpp | 21 - tools/debugger/SkDebugCanvas.h | 12 - tools/debugger/SkDrawCommand.cpp | 87 --- tools/debugger/SkDrawCommand.h | 35 - 29 files changed, 2876 deletions(-) delete mode 100644 gm/shadowmaps.cpp delete mode 100644 include/private/SkShadowParams.h delete mode 100644 samplecode/SampleShadowing.cpp delete mode 100644 src/core/SkRadialShadowMapShader.cpp delete mode 100644 src/core/SkRadialShadowMapShader.h delete mode 100644 src/core/SkShadowShader.cpp delete mode 100644 src/core/SkShadowShader.h delete mode 100644 src/utils/SkShadowPaintFilterCanvas.cpp delete mode 100644 src/utils/SkShadowPaintFilterCanvas.h diff --git a/gm/shadowmaps.cpp b/gm/shadowmaps.cpp deleted file mode 100644 index e8222f4813..0000000000 --- a/gm/shadowmaps.cpp +++ /dev/null @@ -1,118 +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 "SkPathEffect.h" -#include "SkPictureRecorder.h" -#include "SkShadowPaintFilterCanvas.h" -#include "SkShadowShader.h" -#include "SkSurface.h" - -#ifdef SK_EXPERIMENTAL_SHADOWING - - -static sk_sp make_test_picture(int width, int height) { - SkPictureRecorder recorder; - - // LONG RANGE TODO: eventually add SkBBHFactory (bounding box factory) - SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(width, height)); - - SkASSERT(canvas->getTotalMatrix().isIdentity()); - SkPaint paint; - paint.setColor(SK_ColorGRAY); - - // LONG RANGE TODO: tag occluders - // LONG RANGE TODO: track number of IDs we need (hopefully less than 256) - // and determinate the mapping from z to id - - // universal receiver, "ground" - canvas->drawRect(SkRect::MakeIWH(width, height), paint); - - // TODO: Maybe add the ID here along with the depth - - paint.setColor(0xFFEE8888); - - canvas->translateZ(80); - canvas->drawRect(SkRect::MakeLTRB(200,150,350,300), paint); - - paint.setColor(0xFF88EE88); - - canvas->translateZ(80); - canvas->drawRect(SkRect::MakeLTRB(150,200,300,350), paint); - - paint.setColor(0xFF8888EE); - - canvas->translateZ(80); - canvas->drawRect(SkRect::MakeLTRB(100,100,250,250), paint); - // TODO: Add an assert that Z order matches painter's order - // TODO: think about if the Z-order always matching painting order is too strict - - return recorder.finishRecordingAsPicture(); -} - -namespace skiagm { - -class ShadowMapsGM : public GM { -public: - ShadowMapsGM() { - this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); - } - - void onOnceBeforeDraw() override { - // Create a light set consisting of - // - bluish directional light pointing more right than down - // - reddish directional light pointing more down than right - // - soft white ambient light - - SkLights::Builder builder; - builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.2f, 0.3f, 0.4f), - SkVector3::Make(0.2f, 0.1f, 1.0f))); - builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.4f, 0.3f, 0.2f), - SkVector3::Make(0.1f, 0.2f, 1.0f))); - builder.setAmbientLightColor(SkColor3f::Make(0.4f, 0.4f, 0.4f)); - fLights = builder.finish(); - - fShadowParams.fShadowRadius = 4.0f; - fShadowParams.fBiasingConstant = 0.3f; - fShadowParams.fMinVariance = 1024; - fShadowParams.fType = SkShadowParams::kVariance_ShadowType; - } - -protected: - static constexpr int kWidth = 400; - static constexpr int kHeight = 400; - - SkString onShortName() override { - return SkString("shadowmaps"); - } - - SkISize onISize() override { - return SkISize::Make(kWidth, kHeight); - } - - void onDraw(SkCanvas* canvas) override { - // This picture stores the picture of the scene. - // It's used to generate the depth maps. - sk_sp pic(make_test_picture(kWidth, kHeight)); - canvas->setLights(fLights); - canvas->drawShadowedPicture(pic, nullptr, nullptr, fShadowParams); - } - -private: - sk_sp fLights; - SkShadowParams fShadowParams; - typedef GM INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -DEF_GM(return new ShadowMapsGM;) -} - -#endif diff --git a/gn/core.gni b/gn/core.gni index 8f2491d145..10104ffb17 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -261,8 +261,6 @@ skia_core_sources = [ "$_src/core/SkPtrRecorder.cpp", "$_src/core/SkQuadClipper.cpp", "$_src/core/SkQuadClipper.h", - "$_src/core/SkRadialShadowMapShader.cpp", - "$_src/core/SkRadialShadowMapShader.h", "$_src/core/SkRasterClip.cpp", "$_src/core/SkRasterPipeline.cpp", "$_src/core/SkRasterPipelineBlitter.cpp", @@ -369,8 +367,6 @@ skia_core_sources = [ "$_src/core/SkXfermodeInterpretation.h", "$_src/core/SkYUVPlanesCache.cpp", "$_src/core/SkYUVPlanesCache.h", - "$_src/core/SkShadowShader.cpp", - "$_src/core/SkShadowShader.h", "$_src/image/SkImage.cpp", @@ -466,7 +462,6 @@ skia_core_sources = [ "$_include/private/SkRecords.h", "$_include/private/SkSemaphore.h", "$_include/private/SkShadowFlags.h", - "$_include/private/SkShadowParams.h", "$_include/private/SkSpinlock.h", "$_include/private/SkTemplates.h", "$_include/private/SkTArray.h", diff --git a/gn/gm.gni b/gn/gm.gni index 413e5695f5..6d43b3a28a 100644 --- a/gn/gm.gni +++ b/gn/gm.gni @@ -248,7 +248,6 @@ gm_sources = [ "$_gm/shadertext.cpp", "$_gm/shadertext2.cpp", "$_gm/shadertext3.cpp", - "$_gm/shadowmaps.cpp", "$_gm/shadows.cpp", "$_gm/shadowutils.cpp", "$_gm/shallowgradient.cpp", diff --git a/gn/samples.gni b/gn/samples.gni index 13a762cf19..7c9f4e2034 100644 --- a/gn/samples.gni +++ b/gn/samples.gni @@ -82,7 +82,6 @@ samples_sources = [ "$_samplecode/SampleRepeatTile.cpp", "$_samplecode/SampleShaders.cpp", "$_samplecode/SampleShaderText.cpp", - "$_samplecode/SampleShadowing.cpp", "$_samplecode/SampleShip.cpp", "$_samplecode/SampleSlides.cpp", "$_samplecode/SampleStringArt.cpp", diff --git a/gn/utils.gni b/gn/utils.gni index 3bf947b124..14bec37def 100644 --- a/gn/utils.gni +++ b/gn/utils.gni @@ -58,8 +58,6 @@ skia_utils_sources = [ "$_src/utils/SkParsePath.cpp", "$_src/utils/SkPatchUtils.cpp", "$_src/utils/SkPatchUtils.h", - "$_src/utils/SkShadowPaintFilterCanvas.cpp", - "$_src/utils/SkShadowPaintFilterCanvas.h", "$_src/utils/SkShadowTessellator.cpp", "$_src/utils/SkShadowTessellator.h", "$_src/utils/SkShadowUtils.cpp", diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 837b2ff92a..21e5c1c521 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -15,7 +15,6 @@ #include "SkRasterHandleAllocator.h" #include "SkSurfaceProps.h" #include "SkLights.h" -#include "../private/SkShadowParams.h" class GrContext; class GrRenderTargetContext; @@ -1083,53 +1082,6 @@ public: this->drawPicture(picture.get(), matrix, paint); } -#ifdef SK_EXPERIMENTAL_SHADOWING - /** - * Draw the picture into this canvas, with shadows! - * - * We will use the canvas's lights along with the picture information (draw depths of - * objects, etc) to first create a set of shadowmaps for the light-picture pairs, and - * then use that set of shadowmaps to render the scene with shadows. - * - * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is - * logically equivalent to - * save/concat/drawPicture/restore - * - * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's - * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas. - * This is logically equivalent to - * saveLayer(paint)/drawPicture/restore - * - * We also support using variance shadow maps for blurred shadows; the user can specify - * what shadow mapping algorithm to use with params. - * - Variance Shadow Mapping works by storing both the depth and depth^2 in the shadow map. - * - Then, the shadow map can be blurred, and when reading from it, the fragment shader - * can calculate the variance of the depth at a position by doing E(x^2) - E(x)^2. - * - We can then use the depth variance and depth at a fragment to arrive at an upper bound - * of the probability that the current surface is shadowed by using Chebyshev's - * inequality, and then use that to shade the fragment. - * - * - There are a few problems with VSM. - * * Light Bleeding | Areas with high variance, such as near the edges of high up rects, - * will cause their shadow penumbras to overwrite otherwise solid - * shadows. - * * Shape Distortion | We can combat Light Bleeding by biasing the shadow (setting - * mostly shaded fragments to completely shaded) and increasing - * the minimum allowed variance. However, this warps and rounds - * out the shape of the shadow. - */ - void drawShadowedPicture(const SkPicture*, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params); - void drawShadowedPicture(const sk_sp& picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) { - this->drawShadowedPicture(picture.get(), matrix, paint, params); - } -#endif - /** Draw vertices from an immutable SkVertices object. @param vertices The mesh to draw. @@ -1413,13 +1365,6 @@ protected: virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*); -#ifdef SK_EXPERIMENTAL_SHADOWING - virtual void onDrawShadowedPicture(const SkPicture*, - const SkMatrix*, - const SkPaint*, - const SkShadowParams& params); -#endif - // Clip rectangle bounds. Called internally by saveLayer. // returns false if the entire rectangle is entirely clipped out // If non-NULL, The imageFilter parameter will be used to expand the clip diff --git a/include/private/SkRecords.h b/include/private/SkRecords.h index 4d7b217f71..95067d18cb 100644 --- a/include/private/SkRecords.h +++ b/include/private/SkRecords.h @@ -68,7 +68,6 @@ namespace SkRecords { M(DrawPath) \ M(DrawPatch) \ M(DrawPicture) \ - M(DrawShadowedPicture) \ M(DrawPoints) \ M(DrawPosText) \ M(DrawPosTextH) \ @@ -278,11 +277,6 @@ RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag, Optional paint; sk_sp picture; TypedMatrix matrix); -RECORD(DrawShadowedPicture, kDraw_Tag|kHasPaint_Tag, - Optional paint; - sk_sp picture; - TypedMatrix matrix; - const SkShadowParams& params); RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag, SkPaint paint; SkCanvas::PointMode mode; diff --git a/include/private/SkShadowParams.h b/include/private/SkShadowParams.h deleted file mode 100644 index 65d6c06b86..0000000000 --- a/include/private/SkShadowParams.h +++ /dev/null @@ -1,50 +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 SkShadowParams_DEFINED -#define SkShadowParams_DEFINED - -#include "SkScalar.h" - -/** \struct SkShadowParams - - This struct holds information needed for drawing shadows. - - fShadowRadius - radius of the shadow blur - - fBiasingConstant - A constant used in variance shadow mapping to directly - 0.0 - 1.0 reduce light bleeding. Essentially sets all shadows - ~.25 below a certain brightness equal to no light, and does - a linear step on the rest. Essentially makes shadows - darker and more rounded at higher values. - - fMinVariance - Too low of a variance (near the outer edges of blurry - ~512, 1024 shadows) will lead to ugly sharp shadow brightness - distortions. This enforces a minimum amount of variance - in the calculation to smooth out the outside edges of - blurry shadows. However, too high of a value for this will - cause all shadows to be lighter by visibly different - amounts varying on depth. - - fType - Decides which algorithm to use to draw shadows. -*/ -struct SkShadowParams { - SkScalar fShadowRadius; - SkScalar fBiasingConstant; - SkScalar fMinVariance; - - enum ShadowType { - kNoBlur_ShadowType, - kVariance_ShadowType, - - kLast_ShadowType = kVariance_ShadowType - }; - static const int kShadowTypeCount = kLast_ShadowType + 1; - - ShadowType fType; -}; - -#endif diff --git a/samplecode/SampleShadowing.cpp b/samplecode/SampleShadowing.cpp deleted file mode 100644 index 929d62ba7e..0000000000 --- a/samplecode/SampleShadowing.cpp +++ /dev/null @@ -1,301 +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 "SkPictureRecorder.h" -#include "SkShadowPaintFilterCanvas.h" -#include "SkShadowShader.h" -#include "SkSurface.h" - -#ifdef SK_EXPERIMENTAL_SHADOWING - -class ShadowingView : public SampleView { -public: - ShadowingView() - : fSceneChanged(true) - , fLightsChanged(true) - , fMoveLight(false) - , fClearShadowMaps(false) - , fSelectedRectID(-1) - , fSelectedSliderID(-1) - , fLightDepth(400.0f) { - this->setBGColor(0xFFCCCCCC); - - this->updateLights(100, 100); - - fTestRects[0].fColor = 0xFFEE8888; - fTestRects[0].fDepth = 80; - fTestRects[0].fGeometry = SkRect::MakeLTRB(300,200,350,250); - - fTestRects[1].fColor = 0xFF88EE88; - fTestRects[1].fDepth = 160; - fTestRects[1].fGeometry = SkRect::MakeLTRB(200,300,250,350); - - fTestRects[2].fColor = 0xFF8888EE; - fTestRects[2].fDepth = 240; - fTestRects[2].fGeometry = SkRect::MakeLTRB(100,100,150,150); - - fSliders[0].fGeometry = SkRect::MakeLTRB(20, 400, 30, 420); - fSliders[0].fOffset = 0.0f; - fSliders[0].fScale = 0.1f; - - fSliders[1].fGeometry = SkRect::MakeLTRB(100, 420, 110, 440); - fSliders[1].fOffset = 0.0f; - fSliders[1].fScale = 10.0f; - - fSliders[2].fGeometry = SkRect::MakeLTRB(0, 440, 10, 460); - fSliders[2].fOffset = 0.0f; - fSliders[2].fScale = 0.0025f; - - fShadowParams.fShadowRadius = 4.0f; - fShadowParams.fBiasingConstant = 0.3f; - fShadowParams.fMinVariance = 2048; // we need a higher min variance for point lights - fShadowParams.fType = SkShadowParams::kNoBlur_ShadowType; - } - -protected: - bool onQuery(SkEvent *evt) override { - if (SampleCode::TitleQ(*evt)) { - SampleCode::TitleR(evt, "shadowing"); - return true; - } - - SkUnichar uni; - if (SampleCode::CharQ(*evt, &uni)) { - switch (uni) { - case 'L': - fMoveLight = !fMoveLight; - break; - case 'd': - // Raster generated shadow maps have their origin in the UL corner - // GPU shadow maps can have an arbitrary origin. - // We override the 'd' keypress so that when the device is cycled, - // the shadow maps will be re-generated according to the new backend. - fClearShadowMaps = true; - break; - case 'q': - fLightDepth += 5.0f; - fMoveLight = true; - break; - case 'B': - if (SkShadowParams::kVariance_ShadowType == fShadowParams.fType) { - fShadowParams.fType = SkShadowParams::kNoBlur_ShadowType; - } else if (SkShadowParams::kNoBlur_ShadowType == - fShadowParams.fType) { - fShadowParams.fType = SkShadowParams::kVariance_ShadowType; - } - fLightsChanged = true; - break; - case 'w': - fLightDepth -= 5.0f; - fMoveLight = true; - break; - default: - break; - } - } - return this->INHERITED::onQuery(evt); - } - - sk_sp makeTestPicture(int width, int height) { - SkPictureRecorder recorder; - - // LONG RANGE TODO: eventually add SkBBHFactory (bounding box factory) - SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(width, height)); - - SkASSERT(canvas->getTotalMatrix().isIdentity()); - SkPaint paint; - paint.setColor(SK_ColorGRAY); - - // LONG RANGE TODO: tag occluders - // LONG RANGE TODO: track number of IDs we need (hopefully less than 256) - // and determinate the mapping from z to id - - // universal receiver, "ground" - canvas->drawRect(SkRect::MakeIWH(width, height), paint); - - for (int i = 0; i < kNumTestRects; i++) { - paint.setColor(fTestRects[i].fColor); - if (i == 0) { - canvas->translateZ(fTestRects[0].fDepth); - } else { - canvas->translateZ(fTestRects[i].fDepth - fTestRects[i-1].fDepth); - } - canvas->drawRect(fTestRects[i].fGeometry, paint); - } - - return recorder.finishRecordingAsPicture(); - } - - void onDrawContent(SkCanvas *canvas) override { - if (fSceneChanged) { - fPicture = this->makeTestPicture(kWidth, kHeight); - } - - if (fSceneChanged || fLightsChanged || fClearShadowMaps) { - for (int i = 0; i < fLights->numLights(); i++) { - fLights->light(i).setShadowMap(nullptr); - } - - fSceneChanged = false; - fLightsChanged = false; - fClearShadowMaps = false; - } - - canvas->setLights(fLights); - canvas->drawShadowedPicture(fPicture, nullptr, nullptr, fShadowParams); - - for (int i = 0; i < kNumSliders; i++) { - SkPaint paint; - paint.setColor(SK_ColorBLACK); - canvas->drawRect(fSliders[i].fGeometry, paint); - } - } - - SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { - return new SkView::Click(this); - } - - void updateLights(int x, int y) { - SkLights::Builder builder; - builder.add(SkLights::Light::MakePoint(SkColor3f::Make(1.0f, 1.0f, 1.0f), - SkVector3::Make(x, - kHeight - y, - fLightDepth), - 400, true)); - fLights = builder.finish(); - } - - void updateFromSelectedSlider() { - SkScalar newValue = fSliders[fSelectedSliderID].fGeometry.fLeft * - fSliders[fSelectedSliderID].fScale + - fSliders[fSelectedSliderID].fOffset; - - switch (fSelectedSliderID) { - case 0: - fShadowParams.fShadowRadius = newValue; - break; - case 1: - fShadowParams.fMinVariance = newValue; - break; - case 2: - fShadowParams.fBiasingConstant = newValue; - break; - default: - break; - } - } - - bool onClick(Click *click) override { - SkScalar x = click->fCurr.fX; - SkScalar y = click->fCurr.fY; - - SkScalar dx = x - click->fPrev.fX; - SkScalar dy = y - click->fPrev.fY; - - if (fMoveLight) { - if (dx != 0 || dy != 0) { - this->updateLights(x, y); - fLightsChanged = true; - this->inval(nullptr); - } - return true; - } - - if (click->fState == Click::State::kUp_State) { - fSelectedRectID = -1; - fSelectedSliderID = -1; - return true; - } - - if (fSelectedRectID > -1) { - fTestRects[fSelectedRectID].fGeometry.offset(dx, dy); - - fSceneChanged = true; - this->inval(nullptr); - return true; - } - - if (fSelectedSliderID > -1) { - fSliders[fSelectedSliderID].fGeometry.offset(dx, 0); - - this->updateFromSelectedSlider(); - - fLightsChanged = true; - this->inval(nullptr); - return true; - } - - // assume last elements are highest - for (int i = kNumTestRects - 1; i >= 0; i--) { - if (fTestRects[i].fGeometry.contains(SkRect::MakeXYWH(x, y, 1, 1))) { - fSelectedRectID = i; - fTestRects[i].fGeometry.offset(dx, dy); - - fSceneChanged = true; - this->inval(nullptr); - break; - } - } - - for (int i = 0; i <= kNumSliders; i++) { - if (fSliders[i].fGeometry.contains(SkRect::MakeXYWH(x, y, 1, 1))) { - fSelectedSliderID = i; - fSliders[i].fGeometry.offset(dx, 0); - - this->updateFromSelectedSlider(); - - fLightsChanged = true; - - this->inval(nullptr); - break; - } - } - - return true; - } - -private: - static constexpr int kNumTestRects = 3; - static constexpr int kNumSliders = 3; - - static const int kWidth = 400; - static const int kHeight = 400; - - bool fSceneChanged; - bool fLightsChanged; - bool fMoveLight; - bool fClearShadowMaps; - - struct { - SkRect fGeometry; - int fDepth; - SkColor fColor; - } fTestRects[kNumTestRects]; - int fSelectedRectID; - - struct { - SkRect fGeometry; - SkScalar fOffset; - SkScalar fScale; - } fSliders[kNumSliders]; - int fSelectedSliderID; - - SkScalar fLightDepth; - - sk_sp fPicture; - SkShadowParams fShadowParams; - sk_sp fLights; - - typedef SampleView INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// -static SkView* MyFactory() { return new ShadowingView; } -static SkViewRegister reg(MyFactory); - -#endif diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index c09e6cbb7d..ad9bcf5132 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -28,12 +28,9 @@ #include "SkPaintPriv.h" #include "SkPatchUtils.h" #include "SkPicture.h" -#include "SkRadialShadowMapShader.h" #include "SkRasterClip.h" #include "SkRasterHandleAllocator.h" #include "SkRRect.h" -#include "SkShadowPaintFilterCanvas.h" -#include "SkShadowShader.h" #include "SkSpecialImage.h" #include "SkString.h" #include "SkSurface_Base.h" @@ -2837,197 +2834,6 @@ void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, picture->playback(this); } -#ifdef SK_EXPERIMENTAL_SHADOWING -void SkCanvas::drawShadowedPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) { - RETURN_ON_NULL(picture); - - TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); - - this->onDrawShadowedPicture(picture, matrix, paint, params); -} - -void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) { - if (!paint || paint->canComputeFastBounds()) { - SkRect bounds = picture->cullRect(); - if (paint) { - paint->computeFastBounds(bounds, &bounds); - } - if (matrix) { - matrix->mapRect(&bounds); - } - if (this->quickReject(bounds)) { - return; - } - } - - SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); - - sk_sp povDepthMap; - sk_sp diffuseMap; - - // povDepthMap - { - SkLights::Builder builder; - builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), - SkVector3::Make(0.0f, 0.0f, 1.0f))); - sk_sp povLight = builder.finish(); - - SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), - picture->cullRect().height(), - kBGRA_8888_SkColorType, - kOpaque_SkAlphaType); - - // Create a new surface (that matches the backend of canvas) - // to create the povDepthMap - sk_sp surf(this->makeSurface(info)); - - // Wrap another SPFCanvas around the surface - sk_sp depthMapCanvas = - sk_make_sp(surf->getCanvas()); - - // set the depth map canvas to have the light as the user's POV - depthMapCanvas->setLights(std::move(povLight)); - - depthMapCanvas->drawPicture(picture); - povDepthMap = surf->makeImageSnapshot(); - } - - // diffuseMap - { - SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), - picture->cullRect().height(), - kBGRA_8888_SkColorType, - kOpaque_SkAlphaType); - - sk_sp surf(this->makeSurface(info)); - surf->getCanvas()->drawPicture(picture); - - diffuseMap = surf->makeImageSnapshot(); - } - - sk_sp povDepthShader = povDepthMap->makeShader(); - sk_sp diffuseShader = diffuseMap->makeShader(); - - // TODO: pass the depth to the shader in vertices, or uniforms - // so we don't have to render depth and color separately - for (int i = 0; i < fLights->numLights(); ++i) { - // skip over ambient lights; they don't cast shadows - // lights that have shadow maps do not need updating (because lights are immutable) - sk_sp depthMap; - SkISize shMapSize; - - if (fLights->light(i).getShadowMap() != nullptr) { - continue; - } - - if (fLights->light(i).isRadial()) { - shMapSize.fHeight = 1; - shMapSize.fWidth = (int) picture->cullRect().width(); - - SkImageInfo info = SkImageInfo::Make(diffuseMap->width(), 1, - kBGRA_8888_SkColorType, - kOpaque_SkAlphaType); - - // Create new surface (that matches the backend of canvas) - // for each shadow map - sk_sp surf(this->makeSurface(info)); - - // Wrap another SPFCanvas around the surface - SkCanvas* depthMapCanvas = surf->getCanvas(); - - SkLights::Builder builder; - builder.add(fLights->light(i)); - sk_sp curLight = builder.finish(); - - sk_sp shadowMapShader; - shadowMapShader = SkRadialShadowMapShader::Make( - povDepthShader, curLight, - (int) picture->cullRect().width(), - (int) picture->cullRect().height()); - - SkPaint shadowMapPaint; - shadowMapPaint.setShader(std::move(shadowMapShader)); - - depthMapCanvas->setLights(curLight); - - depthMapCanvas->drawRect(SkRect::MakeIWH(diffuseMap->width(), - diffuseMap->height()), - shadowMapPaint); - - depthMap = surf->makeImageSnapshot(); - - } else { - // TODO: compute the correct size of the depth map from the light properties - // TODO: maybe add a kDepth_8_SkColorType - // TODO: find actual max depth of picture - shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( - fLights->light(i), 255, - (int) picture->cullRect().width(), - (int) picture->cullRect().height()); - - SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, - kBGRA_8888_SkColorType, - kOpaque_SkAlphaType); - - // Create a new surface (that matches the backend of canvas) - // for each shadow map - sk_sp surf(this->makeSurface(info)); - - // Wrap another SPFCanvas around the surface - sk_sp depthMapCanvas = - sk_make_sp(surf->getCanvas()); - depthMapCanvas->setShadowParams(params); - - // set the depth map canvas to have the light we're drawing. - SkLights::Builder builder; - builder.add(fLights->light(i)); - sk_sp curLight = builder.finish(); - depthMapCanvas->setLights(std::move(curLight)); - - depthMapCanvas->drawPicture(picture); - depthMap = surf->makeImageSnapshot(); - } - - if (params.fType == SkShadowParams::kNoBlur_ShadowType) { - fLights->light(i).setShadowMap(std::move(depthMap)); - } else if (params.fType == SkShadowParams::kVariance_ShadowType) { - // we blur the variance map - SkPaint blurPaint; - blurPaint.setImageFilter(SkImageFilter::MakeBlur(params.fShadowRadius, - params.fShadowRadius, nullptr)); - - SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, - kBGRA_8888_SkColorType, - kOpaque_SkAlphaType); - - sk_sp blurSurf(this->makeSurface(blurInfo)); - - blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); - - fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); - } - } - - SkPaint shadowPaint; - sk_sp shadowShader = SkShadowShader::Make(std::move(povDepthShader), - std::move(diffuseShader), - fLights, - diffuseMap->width(), - diffuseMap->height(), - params); - - shadowPaint.setShader(shadowShader); - - this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), shadowPaint); -} -#endif - /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp index 71cbf681eb..fb629ddc66 100644 --- a/src/core/SkLiteDL.cpp +++ b/src/core/SkLiteDL.cpp @@ -51,7 +51,6 @@ namespace { M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion) \ M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawRegion) M(DrawOval) M(DrawArc) \ M(DrawRRect) M(DrawDRRect) M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) \ - M(DrawShadowedPicture) \ M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) \ M(DrawText) M(DrawPosText) M(DrawPosTextH) \ M(DrawTextOnPath) M(DrawTextRSXform) M(DrawTextBlob) \ @@ -276,25 +275,6 @@ namespace { c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr); } }; - struct DrawShadowedPicture final : Op { - static const auto kType = Type::DrawShadowedPicture; - DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint, const SkShadowParams& params) - : picture(sk_ref_sp(picture)) { - if (matrix) { this->matrix = *matrix; } - if (paint) { this->paint = *paint; } - this->params = params; - } - sk_sp picture; - SkMatrix matrix = SkMatrix::I(); - SkPaint paint; - SkShadowParams params; - void draw(SkCanvas* c, const SkMatrix&) const { - #ifdef SK_EXPERIMENTAL_SHADOWING - c->drawShadowedPicture(picture.get(), &matrix, &paint, params); - #endif - } - }; struct DrawImage final : Op { static const auto kType = Type::DrawImage; @@ -611,11 +591,6 @@ void SkLiteDL::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { this->push(0, picture, matrix, paint); } -void SkLiteDL::drawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint, const SkShadowParams& params) { - push(0, picture, matrix, paint, params); -} - void SkLiteDL::drawImage(sk_sp image, SkScalar x, SkScalar y, const SkPaint* paint) { this->push(0, std::move(image), x,y, paint); } diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h index f8e7910c82..270b2ef4ce 100644 --- a/src/core/SkLiteDL.h +++ b/src/core/SkLiteDL.h @@ -55,8 +55,6 @@ public: void drawAnnotation (const SkRect&, const char*, SkData*); void drawDrawable (SkDrawable*, const SkMatrix*); void drawPicture (const SkPicture*, const SkMatrix*, const SkPaint*); - void drawShadowedPicture(const SkPicture*, const SkMatrix*, - const SkPaint*, const SkShadowParams& params); void drawText (const void*, size_t, SkScalar, SkScalar, const SkPaint&); void drawPosText (const void*, size_t, const SkPoint[], const SkPaint&); diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp index 29de29ac5a..d25254956d 100644 --- a/src/core/SkLiteRecorder.cpp +++ b/src/core/SkLiteRecorder.cpp @@ -198,9 +198,3 @@ void SkLiteRecorder::onDrawAtlas(const SkImage* atlas, void SkLiteRecorder::didTranslateZ(SkScalar dz) { fDL->translateZ(dz); } -void SkLiteRecorder::onDrawShadowedPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) { - fDL->drawShadowedPicture(picture, matrix, paint, params); -} diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h index ea7cc78b2d..9f524939fd 100644 --- a/src/core/SkLiteRecorder.h +++ b/src/core/SkLiteRecorder.h @@ -80,12 +80,8 @@ public: #ifdef SK_EXPERIMENTAL_SHADOWING void didTranslateZ(SkScalar) override; - void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, - const SkPaint*, const SkShadowParams& params) override; #else void didTranslateZ(SkScalar); - void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, - const SkPaint*, const SkShadowParams& params); #endif private: diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 608c6b3997..f794b73423 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -696,29 +696,6 @@ void SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* ma this->validate(initialOffset, size); } -void SkPictureRecord::onDrawShadowedPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) { - // op + picture index - size_t size = 2 * kUInt32Size; - size_t initialOffset; - - // TODO: handle recording params. - if (nullptr == matrix && nullptr == paint) { - initialOffset = this->addDraw(DRAW_PICTURE, &size); - this->addPicture(picture); - } else { - const SkMatrix& m = matrix ? *matrix : SkMatrix::I(); - size += m.writeToMemory(nullptr) + kUInt32Size; // matrix + paint - initialOffset = this->addDraw(DRAW_PICTURE_MATRIX_PAINT, &size); - this->addPaintPtr(paint); - this->addMatrix(m); - this->addPicture(picture); - } - this->validate(initialOffset, size); -} - void SkPictureRecord::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { // op + drawable index size_t size = 2 * kUInt32Size; diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index dc9a002ac9..dcdfebe984 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -212,14 +212,6 @@ protected: void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; -#ifdef SK_EXPERIMENTAL_SHADOWING - void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, - const SkPaint*, const SkShadowParams& params) override; -#else - void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, - const SkPaint*, const SkShadowParams& params); -#endif - void onDrawDrawable(SkDrawable*, const SkMatrix*) override; void onDrawAnnotation(const SkRect&, const char[], SkData*) override; diff --git a/src/core/SkRadialShadowMapShader.cpp b/src/core/SkRadialShadowMapShader.cpp deleted file mode 100644 index afbb3c79d2..0000000000 --- a/src/core/SkRadialShadowMapShader.cpp +++ /dev/null @@ -1,428 +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 "SkLights.h" -#include "SkPoint3.h" -#include "SkRadialShadowMapShader.h" - -//////////////////////////////////////////////////////////////////////////// -#ifdef SK_EXPERIMENTAL_SHADOWING - - -/** \class SkRadialShadowMapShaderImpl - This subclass of shader applies shadowing radially around a light -*/ -class SkRadialShadowMapShaderImpl : public SkShader { -public: - /** Create a new shadowing shader that shadows radially around a light - */ - SkRadialShadowMapShaderImpl(sk_sp occluderShader, - sk_sp lights, - int diffuseWidth, int diffuseHeight) - : fOccluderShader(std::move(occluderShader)) - , fLight(std::move(lights)) - , fWidth(diffuseWidth) - , fHeight(diffuseHeight) { } - - bool isOpaque() const override; - -#if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(const AsFPArgs&) const override; -#endif - - class ShadowMapRadialShaderContext : public SkShader::Context { - public: - // The context takes ownership of the states. It will call their destructors - // but will NOT free the memory. - ShadowMapRadialShaderContext(const SkRadialShadowMapShaderImpl&, const ContextRec&, - SkShader::Context* occluderContext, - void* heapAllocated); - - ~ShadowMapRadialShaderContext() override; - - void shadeSpan(int x, int y, SkPMColor[], int count) override; - - uint32_t getFlags() const override { return fFlags; } - - private: - SkShader::Context* fOccluderContext; - uint32_t fFlags; - - void* fHeapAllocated; - - typedef SkShader::Context INHERITED; - }; - - SK_TO_STRING_OVERRIDE() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialShadowMapShaderImpl) - -protected: - void flatten(SkWriteBuffer&) const override; - size_t onContextSize(const ContextRec&) const override; - Context* onCreateContext(const ContextRec&, void*) const override; - -private: - sk_sp fOccluderShader; - sk_sp fLight; - - int fWidth; - int fHeight; - - friend class SkRadialShadowMapShader; - - typedef SkShader INHERITED; -}; - -//////////////////////////////////////////////////////////////////////////// - -#if SK_SUPPORT_GPU - -#include "GrContext.h" -#include "GrCoordTransform.h" -#include "GrFragmentProcessor.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "SkGr.h" -#include "SkImage_Base.h" -#include "GrInvariantOutput.h" -#include "SkSpecialImage.h" - -class RadialShadowMapFP : public GrFragmentProcessor { -public: - RadialShadowMapFP(sk_sp occluder, - sk_sp light, - int diffuseWidth, int diffuseHeight, - GrContext* context) { - fLightPos = light->light(0).pos(); - - fWidth = diffuseWidth; - fHeight = diffuseHeight; - - this->registerChildProcessor(std::move(occluder)); - this->initClassID(); - } - - class GLSLRadialShadowMapFP : public GrGLSLFragmentProcessor { - public: - GLSLRadialShadowMapFP() { } - - void emitCode(EmitArgs& args) override { - - GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - - const char* lightPosUniName = nullptr; - - fLightPosUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec3f_GrSLType, - kDefault_GrSLPrecision, - "lightPos", - &lightPosUniName); - - const char* widthUniName = nullptr; - const char* heightUniName = nullptr; - - fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kInt_GrSLType, - kDefault_GrSLPrecision, - "width", &widthUniName); - fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kInt_GrSLType, - kDefault_GrSLPrecision, - "height", &heightUniName); - - - SkString occluder("occluder"); - this->emitChild(0, nullptr, &occluder, args); - - // Modify the input texture coordinates to index into our 1D output - fragBuilder->codeAppend("float distHere;"); - - // we use a max shadow distance of 2 times the max of width/height - fragBuilder->codeAppend("float closestDistHere = 2;"); - fragBuilder->codeAppend("vec2 coords = vMatrixCoord_0_0_Stage0;"); - fragBuilder->codeAppend("coords.y = 0;"); - fragBuilder->codeAppend("vec2 destCoords = vec2(0,0);"); - fragBuilder->codeAppendf("float step = 1.0 / %s;", heightUniName); - - // assume that we are at 0, 0 light pos - // TODO use correct light positions - - // this goes through each depth value in the final output buffer, - // basically raycasting outwards, and finding the first collision. - // we also increment coords.y to 2 instead 1 so our shadows stretch the whole screen. - fragBuilder->codeAppendf("for (coords.y = 0; coords.y <= 2; coords.y += step) {"); - - fragBuilder->codeAppend("float theta = (coords.x * 2.0 - 1.0) * 3.1415;"); - fragBuilder->codeAppend("float r = coords.y;"); - fragBuilder->codeAppend("destCoords = " - "vec2(r * cos(theta), - r * sin(theta)) /2.0 + 0.5;"); - fragBuilder->codeAppendf("vec2 lightOffset = (vec2(%s)/vec2(%s,%s) - 0.5)" - "* vec2(1.0, 1.0);", - lightPosUniName, widthUniName, heightUniName); - - fragBuilder->codeAppend("distHere = texture(uTextureSampler0_Stage1," - "destCoords + lightOffset).b;"); - fragBuilder->codeAppend("if (distHere > 0.0) {" - "closestDistHere = coords.y;" - "break;}"); - fragBuilder->codeAppend("}"); - - fragBuilder->codeAppendf("%s = vec4(vec3(closestDistHere / 2.0),1);", args.fOutputColor); - } - - static void GenKey(const GrProcessor& proc, const GrShaderCaps&, - GrProcessorKeyBuilder* b) { - b->add32(0); // nothing to add here - } - - protected: - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& proc) override { - const RadialShadowMapFP &radialShadowMapFP = proc.cast(); - - const SkVector3& lightPos = radialShadowMapFP.lightPos(); - if (lightPos != fLightPos) { - pdman.set3fv(fLightPosUni, 1, &lightPos.fX); - fLightPos = lightPos; - } - - int width = radialShadowMapFP.width(); - if (width != fWidth) { - pdman.set1i(fWidthUni, width); - fWidth = width; - } - int height = radialShadowMapFP.height(); - if (height != fHeight) { - pdman.set1i(fHeightUni, height); - fHeight = height; - } - } - - private: - SkVector3 fLightPos; - GrGLSLProgramDataManager::UniformHandle fLightPosUni; - - int fWidth; - GrGLSLProgramDataManager::UniformHandle fWidthUni; - int fHeight; - GrGLSLProgramDataManager::UniformHandle fHeightUni; - }; - - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { - GLSLRadialShadowMapFP::GenKey(*this, caps, b); - } - - const char* name() const override { return "RadialShadowMapFP"; } - - const SkVector3& lightPos() const { - return fLightPos; - } - - int width() const { return fWidth; } - int height() const { return fHeight; } - -private: - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { - return new GLSLRadialShadowMapFP; - } - - bool onIsEqual(const GrFragmentProcessor& proc) const override { - const RadialShadowMapFP& radialShadowMapFP = proc.cast(); - - if (fWidth != radialShadowMapFP.fWidth || fHeight != radialShadowMapFP.fHeight) { - return false; - } - - if (fLightPos != radialShadowMapFP.fLightPos) { - return false; - } - - return true; - } - - SkVector3 fLightPos; - - int fHeight; - int fWidth; -}; - -//////////////////////////////////////////////////////////////////////////// - -sk_sp SkRadialShadowMapShaderImpl::asFragmentProcessor - (const AsFPArgs& fpargs) const { - - sk_sp occluderFP = fOccluderShader->asFragmentProcessor(fpargs); - - sk_sp shadowFP = sk_make_sp(std::move(occluderFP), - fLight, fWidth, fHeight, - fpargs.fContext); - return shadowFP; -} - -#endif - -//////////////////////////////////////////////////////////////////////////// - -bool SkRadialShadowMapShaderImpl::isOpaque() const { - return fOccluderShader->isOpaque(); -} - -SkRadialShadowMapShaderImpl::ShadowMapRadialShaderContext::ShadowMapRadialShaderContext( - const SkRadialShadowMapShaderImpl& shader, const ContextRec& rec, - SkShader::Context* occluderContext, - void* heapAllocated) - : INHERITED(shader, rec) - , fOccluderContext(occluderContext) - , fHeapAllocated(heapAllocated) { - bool isOpaque = shader.isOpaque(); - - // update fFlags - uint32_t flags = 0; - if (isOpaque && (255 == this->getPaintAlpha())) { - flags |= kOpaqueAlpha_Flag; - } - - fFlags = flags; -} - -SkRadialShadowMapShaderImpl::ShadowMapRadialShaderContext::~ShadowMapRadialShaderContext() { - // The dependencies have been created outside of the context on memory that was allocated by - // the onCreateContext() method. Call the destructors and free the memory. - fOccluderContext->~Context(); - - sk_free(fHeapAllocated); -} - -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 SkRadialShadowMapShaderImpl::ShadowMapRadialShaderContext::shadeSpan - (int x, int y, SkPMColor result[], int count) { - do { - int n = SkTMin(count, BUFFER_MAX); - - // just fill with white for now - SkPMColor accum = convert(SkColor3f::Make(1.0f, 1.0f, 1.0f), 0xFF); - - for (int i = 0; i < n; ++i) { - result[i] = accum; - } - - result += n; - x += n; - count -= n; - } while (count > 0); -} - -//////////////////////////////////////////////////////////////////////////// - -#ifndef SK_IGNORE_TO_STRING -void SkRadialShadowMapShaderImpl::toString(SkString* str) const { - str->appendf("RadialShadowMapShader: ()"); -} -#endif - -sk_sp SkRadialShadowMapShaderImpl::CreateProc(SkReadBuffer& buf) { - - // Discarding SkShader flattenable params - bool hasLocalMatrix = buf.readBool(); - SkAssertResult(!hasLocalMatrix); - - sk_sp light = SkLights::MakeFromBuffer(buf); - - int diffuseWidth = buf.readInt(); - int diffuseHeight = buf.readInt(); - - sk_sp occluderShader(buf.readFlattenable()); - - return sk_make_sp(std::move(occluderShader), - std::move(light), - diffuseWidth, diffuseHeight); -} - -void SkRadialShadowMapShaderImpl::flatten(SkWriteBuffer& buf) const { - this->INHERITED::flatten(buf); - - fLight->flatten(buf); - - buf.writeInt(fWidth); - buf.writeInt(fHeight); - - buf.writeFlattenable(fOccluderShader.get()); -} - -size_t SkRadialShadowMapShaderImpl::onContextSize(const ContextRec& rec) const { - return sizeof(ShadowMapRadialShaderContext); -} - -SkShader::Context* SkRadialShadowMapShaderImpl::onCreateContext(const ContextRec& rec, - void* storage) const { - size_t heapRequired = fOccluderShader->contextSize(rec); - - void* heapAllocated = sk_malloc_throw(heapRequired); - - void* occluderContextStorage = heapAllocated; - - SkShader::Context* occluderContext = - fOccluderShader->createContext(rec, occluderContextStorage); - - if (!occluderContext) { - sk_free(heapAllocated); - return nullptr; - } - - return new (storage) ShadowMapRadialShaderContext(*this, rec, occluderContext, heapAllocated); -} - -/////////////////////////////////////////////////////////////////////////////// - -sk_sp SkRadialShadowMapShader::Make(sk_sp occluderShader, - sk_sp light, - int diffuseWidth, int diffuseHeight) { - if (!occluderShader) { - // TODO: Use paint's color in absence of a diffuseShader - // TODO: Use a default implementation of normalSource instead - return nullptr; - } - - return sk_make_sp(std::move(occluderShader), - std::move(light), - diffuseWidth, diffuseHeight); -} - -/////////////////////////////////////////////////////////////////////////////// - -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkRadialShadowMapShader) -SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialShadowMapShaderImpl) -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END - -/////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/src/core/SkRadialShadowMapShader.h b/src/core/SkRadialShadowMapShader.h deleted file mode 100644 index 4d6956ca82..0000000000 --- a/src/core/SkRadialShadowMapShader.h +++ /dev/null @@ -1,31 +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 "SkReadBuffer.h" - -#ifndef SkRadialShadowMapShader_DEFINED -#define SkRadialShadowMapShader_DEFINED - -#ifdef SK_EXPERIMENTAL_SHADOWING - -class SkLights; -class SkShader; - -class SK_API SkRadialShadowMapShader { -public: - /** This shader creates a 1D strip depth map for radial lights. - * It can only take in 1 light to generate one shader at a time. - */ - static sk_sp Make(sk_sp occluderShader, - sk_sp light, - int diffuseWidth, int diffuseHeight); - - SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() -}; - -#endif -#endif diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 9e8d6fcea2..634676c2d6 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -117,13 +117,6 @@ DRAW(DrawPaint, drawPaint(r.paint)); DRAW(DrawPath, drawPath(r.path, r.paint)); DRAW(DrawPatch, drawPatch(r.cubics, r.colors, r.texCoords, r.bmode, r.paint)); DRAW(DrawPicture, drawPicture(r.picture.get(), &r.matrix, r.paint)); - -#ifdef SK_EXPERIMENTAL_SHADOWING -DRAW(DrawShadowedPicture, drawShadowedPicture(r.picture.get(), &r.matrix, r.paint, r.params)); -#else -template <> void Draw::draw(const DrawShadowedPicture& r) { } -#endif - DRAW(DrawPoints, drawPoints(r.mode, r.count, r.pts, r.paint)); DRAW(DrawPosText, drawPosText(r.text, r.byteLength, r.pos, r.paint)); DRAW(DrawPosTextH, drawPosTextH(r.text, r.byteLength, r.xpos, r.y, r.paint)); @@ -474,12 +467,6 @@ private: return this->adjustAndMap(dst, op.paint); } - Bounds bounds(const DrawShadowedPicture& op) const { - SkRect dst = op.picture->cullRect(); - op.matrix.mapRect(&dst); - return this->adjustAndMap(dst, op.paint); - } - Bounds bounds(const DrawPosText& op) const { const int N = op.paint.countText(op.text, op.byteLength); if (N == 0) { diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 47e4d74909..c111db6606 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -310,23 +310,6 @@ void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con } } -void SkRecorder::onDrawShadowedPicture(const SkPicture* pic, const SkMatrix* matrix, - const SkPaint* paint, const SkShadowParams& params) { - if (fDrawPictureMode == Record_DrawPictureMode) { - fApproxBytesUsedBySubPictures += pic->approximateBytesUsed(); - APPEND(DrawShadowedPicture, this->copy(paint), - sk_ref_sp(pic), - matrix ? *matrix : SkMatrix::I(), - params); - } else { - // TODO update pic->playback(this) to draw the shadowed pic - SkASSERT(fDrawPictureMode == Playback_DrawPictureMode); - SkAutoCanvasMatrixPaint acmp(this, matrix, paint, pic->cullRect()); - pic->playback(this); - } -} - - void SkRecorder::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, const SkPaint& paint) { APPEND(DrawVertices, paint, sk_ref_sp(const_cast(vertices)), bmode); diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 3407fc7032..c815744046 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -135,18 +135,6 @@ public: void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; -#ifdef SK_EXPERIMENTAL_SHADOWING - void onDrawShadowedPicture(const SkPicture*, - const SkMatrix*, - const SkPaint*, - const SkShadowParams& params) override; -#else - void onDrawShadowedPicture(const SkPicture*, - const SkMatrix*, - const SkPaint*, - const SkShadowParams& params); -#endif - void onDrawAnnotation(const SkRect&, const char[], SkData*) override; sk_sp onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override; diff --git a/src/core/SkShadowShader.cpp b/src/core/SkShadowShader.cpp deleted file mode 100644 index 9353ca60cf..0000000000 --- a/src/core/SkShadowShader.cpp +++ /dev/null @@ -1,955 +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 "SkCanvas.h" -#include "SkReadBuffer.h" -#include "SkShadowShader.h" - -//////////////////////////////////////////////////////////////////////////// -#ifdef SK_EXPERIMENTAL_SHADOWING - - -/** \class SkShadowShaderImpl - This subclass of shader applies shadowing -*/ -class SkShadowShaderImpl : public SkShader { -public: - /** Create a new shadowing shader that shadows - @param to do to do - */ - SkShadowShaderImpl(sk_sp povDepthShader, - sk_sp diffuseShader, - sk_sp lights, - int diffuseWidth, int diffuseHeight, - const SkShadowParams& params) - : fPovDepthShader(std::move(povDepthShader)) - , fDiffuseShader(std::move(diffuseShader)) - , fLights(std::move(lights)) - , fDiffuseWidth(diffuseWidth) - , fDiffuseHeight(diffuseHeight) - , fShadowParams(params) { } - - bool isOpaque() const override; - -#if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(const AsFPArgs&) const override; -#endif - - class ShadowShaderContext : public SkShader::Context { - public: - // The context takes ownership of the states. It will call their destructors - // but will NOT free the memory. - ShadowShaderContext(const SkShadowShaderImpl&, const ContextRec&, - SkShader::Context* povDepthContext, - SkShader::Context* diffuseContext, - void* heapAllocated); - - ~ShadowShaderContext() override; - - void shadeSpan(int x, int y, SkPMColor[], int count) override; - - uint32_t getFlags() const override { return fFlags; } - - private: - SkShader::Context* fPovDepthContext; - SkShader::Context* fDiffuseContext; - uint32_t fFlags; - - void* fHeapAllocated; - - int fNonAmbLightCnt; - SkPixmap* fShadowMapPixels; - - - typedef SkShader::Context INHERITED; - }; - - SK_TO_STRING_OVERRIDE() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkShadowShaderImpl) - -protected: - void flatten(SkWriteBuffer&) const override; - size_t onContextSize(const ContextRec&) const override; - Context* onCreateContext(const ContextRec&, void*) const override; - -private: - sk_sp fPovDepthShader; - sk_sp fDiffuseShader; - sk_sp fLights; - - int fDiffuseWidth; - int fDiffuseHeight; - - SkShadowParams fShadowParams; - - friend class SkShadowShader; - - typedef SkShader INHERITED; -}; - -//////////////////////////////////////////////////////////////////////////// - -#if SK_SUPPORT_GPU - -#include "GrCoordTransform.h" -#include "GrFragmentProcessor.h" -#include "GrInvariantOutput.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "SkGr.h" -#include "SkSpecialImage.h" -#include "SkImage_Base.h" -#include "GrContext.h" - -class ShadowFP : public GrFragmentProcessor { -public: - ShadowFP(sk_sp povDepth, - sk_sp diffuse, - sk_sp lights, - int diffuseWidth, int diffuseHeight, - const SkShadowParams& params, - GrContext* context) { - - fAmbientColor = lights->ambientLightColor(); - - fNumNonAmbLights = 0; // count of non-ambient lights - for (int i = 0; i < lights->numLights(); ++i) { - if (fNumNonAmbLights < SkShadowShader::kMaxNonAmbientLights) { - fLightColor[fNumNonAmbLights] = lights->light(i).color(); - - if (SkLights::Light::kPoint_LightType == lights->light(i).type()) { - fLightDirOrPos[fNumNonAmbLights] = lights->light(i).pos(); - fLightColor[fNumNonAmbLights].scale(lights->light(i).intensity()); - } else { - fLightDirOrPos[fNumNonAmbLights] = lights->light(i).dir(); - } - - fIsPointLight[fNumNonAmbLights] = - SkLights::Light::kPoint_LightType == lights->light(i).type(); - - fIsRadialLight[fNumNonAmbLights] = lights->light(i).isRadial(); - - SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getShadowMap()); - - // gets deleted when the ShadowFP is destroyed, and frees the GrTexture* - fTexture[fNumNonAmbLights] = sk_sp(shadowMap->asTextureRef(context, - GrSamplerParams::ClampNoFilter(), - SkDestinationSurfaceColorMode::kLegacy, - nullptr)); - fDepthMapSampler[fNumNonAmbLights].reset(fTexture[fNumNonAmbLights].get()); - this->addTextureSampler(&fDepthMapSampler[fNumNonAmbLights]); - - fDepthMapHeight[fNumNonAmbLights] = shadowMap->height(); - fDepthMapWidth[fNumNonAmbLights] = shadowMap->width(); - - fNumNonAmbLights++; - } - } - - fWidth = diffuseWidth; - fHeight = diffuseHeight; - - fShadowParams = params; - - this->registerChildProcessor(std::move(povDepth)); - this->registerChildProcessor(std::move(diffuse)); - this->initClassID(); - } - - class GLSLShadowFP : public GrGLSLFragmentProcessor { - public: - GLSLShadowFP() { } - - void emitCode(EmitArgs& args) override { - GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - const ShadowFP& shadowFP = args.fFp.cast(); - - SkASSERT(shadowFP.fNumNonAmbLights <= SkShadowShader::kMaxNonAmbientLights); - - // add uniforms - int32_t numLights = shadowFP.fNumNonAmbLights; - SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); - - int blurAlgorithm = shadowFP.fShadowParams.fType; - - const char* lightDirOrPosUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; - const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; - const char* ambientColorUniName = nullptr; - - const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; - const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; - const char* widthUniName = nullptr; // dimensions of povDepth - const char* heightUniName = nullptr; - - const char* shBiasUniName = nullptr; - const char* minVarianceUniName = nullptr; - - // setting uniforms - for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { - SkString lightDirOrPosUniNameStr("lightDir"); - lightDirOrPosUniNameStr.appendf("%d", i); - SkString lightColorUniNameStr("lightColor"); - lightColorUniNameStr.appendf("%d", i); - SkString lightIntensityUniNameStr("lightIntensity"); - lightIntensityUniNameStr.appendf("%d", i); - - SkString depthMapWidthUniNameStr("dmapWidth"); - depthMapWidthUniNameStr.appendf("%d", i); - SkString depthMapHeightUniNameStr("dmapHeight"); - depthMapHeightUniNameStr.appendf("%d", i); - - fLightDirOrPosUni[i] = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec3f_GrSLType, - kDefault_GrSLPrecision, - lightDirOrPosUniNameStr.c_str(), - &lightDirOrPosUniName[i]); - fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec3f_GrSLType, - kDefault_GrSLPrecision, - lightColorUniNameStr.c_str(), - &lightColorUniName[i]); - - fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrShaderFlag, - kInt_GrSLType, - kDefault_GrSLPrecision, - depthMapWidthUniNameStr.c_str(), - &depthMapWidthUniName[i]); - fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrShaderFlag, - kInt_GrSLType, - kDefault_GrSLPrecision, - depthMapHeightUniNameStr.c_str(), - &depthMapHeightUniName[i]); - } - - fBiasingConstantUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, - kDefault_GrSLPrecision, - "shadowBias", &shBiasUniName); - fMinVarianceUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, - kDefault_GrSLPrecision, - "minVariance", &minVarianceUniName); - - fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kInt_GrSLType, - kDefault_GrSLPrecision, - "width", &widthUniName); - fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kInt_GrSLType, - kDefault_GrSLPrecision, - "height", &heightUniName); - - fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec3f_GrSLType, kDefault_GrSLPrecision, - "AmbientColor", &ambientColorUniName); - - SkString povDepthSampler("_povDepth"); - SkString povDepth("povDepth"); - this->emitChild(0, nullptr, &povDepthSampler, args); - fragBuilder->codeAppendf("vec4 %s = %s;", povDepth.c_str(), povDepthSampler.c_str()); - - SkString diffuseColorSampler("_inDiffuseColor"); - SkString diffuseColor("inDiffuseColor"); - this->emitChild(1, nullptr, &diffuseColorSampler, args); - fragBuilder->codeAppendf("vec4 %s = %s;", diffuseColor.c_str(), - diffuseColorSampler.c_str()); - - SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; - - fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseColor.c_str()); - fragBuilder->codeAppend ("vec3 totalLightColor = vec3(0);"); - - // probability that a fragment is lit. For each light, we multiply this by the - // light's color to get its contribution to totalLightColor. - fragBuilder->codeAppend ("float lightProbability;"); - - // coordinates of current fragment in world space - fragBuilder->codeAppend ("vec3 worldCor;"); - - // Multiply by 255 to transform from sampler coordinates to world - // coordinates (since 1 channel is 0xFF) - // Note: vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. - fragBuilder->codeAppendf("worldCor = vec3(vMatrixCoord_0_1_Stage0 * " - "vec2(%s, %s), %s.b * 255);", - widthUniName, heightUniName, povDepth.c_str()); - - // Applies the offset indexing that goes from our view space into the light's space. - for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { - SkString povCoord("povCoord"); - povCoord.appendf("%d", i); - - SkString offset("offset"); - offset.appendf("%d", i); - fragBuilder->codeAppendf("vec2 %s;", offset.c_str()); - - if (shadowFP.fIsPointLight[i]) { - fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor;", - i, lightDirOrPosUniName[i]); - fragBuilder->codeAppendf("float dist%d = length(fragToLight%d);", - i, i); - fragBuilder->codeAppendf("%s = vec2(-fragToLight%d) * povDepth.b;", - offset.c_str(), i); - fragBuilder->codeAppendf("fragToLight%d = normalize(fragToLight%d);", - i, i); - } - - if (shadowFP.fIsRadialLight[i]) { - fragBuilder->codeAppendf("vec2 %s = vec2(vMatrixCoord_0_1_Stage0.x, " - "1 - vMatrixCoord_0_1_Stage0.y);\n", - povCoord.c_str()); - - fragBuilder->codeAppendf("%s = (%s) * 2.0 - 1.0 + (vec2(%s)/vec2(%s,%s) - 0.5)" - "* vec2(-2.0, 2.0);\n", - povCoord.c_str(), povCoord.c_str(), - lightDirOrPosUniName[i], - widthUniName, heightUniName); - - fragBuilder->codeAppendf("float theta = atan(%s.y, %s.x);", - povCoord.c_str(), povCoord.c_str()); - fragBuilder->codeAppendf("float r = length(%s);", povCoord.c_str()); - - // map output of atan to [0, 1] - fragBuilder->codeAppendf("%s.x = (theta + 3.1415) / (2.0 * 3.1415);", - povCoord.c_str()); - fragBuilder->codeAppendf("%s.y = 0.0;", povCoord.c_str()); - } else { - // note that we flip the y-coord of the offset and then later add - // a value just to the y-coord of povCoord. This is to account for - // the shifted origins from switching from raster into GPU. - if (shadowFP.fIsPointLight[i]) { - // the 0.375s are precalculated transform values, given that the depth - // maps for pt lights are 4x the size (linearly) as diffuse maps. - // The vec2(0.375, -0.375) is used to transform us to - // the center of the map. - fragBuilder->codeAppendf("vec2 %s = ((vec2(%s, %s) *" - "vMatrixCoord_0_1_Stage0 +" - "vec2(0,%s - %s)" - "+ %s) / (vec2(%s, %s))) +" - "vec2(0.375, -0.375);", - povCoord.c_str(), - widthUniName, heightUniName, - depthMapHeightUniName[i], heightUniName, - offset.c_str(), - depthMapWidthUniName[i], - depthMapWidthUniName[i]); - } else { - fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * " - "vec2(255.0, -255.0);", - offset.c_str(), lightDirOrPosUniName[i]); - - fragBuilder->codeAppendf("vec2 %s = ((vec2(%s, %s) *" - "vMatrixCoord_0_1_Stage0 +" - "vec2(0,%s - %s)" - "+ %s) / vec2(%s, %s));", - povCoord.c_str(), - widthUniName, heightUniName, - depthMapHeightUniName[i], heightUniName, - offset.c_str(), - depthMapWidthUniName[i], - depthMapWidthUniName[i]); - } - } - - fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSamplers[i], - povCoord.c_str(), - kVec2f_GrSLType); - } - - // helper variables for calculating shadowing - - // variance of depth at this fragment in the context of surrounding area - // (area size and weighting dependent on blur size and type) - fragBuilder->codeAppendf("float variance;"); - - // the difference in depth between the user POV and light POV. - fragBuilder->codeAppendf("float d;"); - - // add up light contributions from all lights to totalLightColor - for (int i = 0; i < numLights; i++) { - fragBuilder->codeAppendf("lightProbability = 1;"); - - if (shadowFP.fIsRadialLight[i]) { - fragBuilder->codeAppend("totalLightColor = vec3(0);"); - - fragBuilder->codeAppend("vec2 tc = vec2(povCoord0.x, 0.0);"); - fragBuilder->codeAppend("float depth = texture(uTextureSampler0_Stage1," - "povCoord0).b * 2.0;"); - - fragBuilder->codeAppendf("lightProbability = step(r, depth);"); - - // 2 is the maximum depth. If this is reached, probably we have - // not intersected anything. So values after this should be unshadowed. - fragBuilder->codeAppendf("if (%s.b != 0 || depth == 2) {" - "lightProbability = 1.0; }", - povDepth.c_str()); - } else { - // 1/512 == .00195... is less than half a pixel; imperceptible - fragBuilder->codeAppendf("if (%s.b <= %s.b + .001953125) {", - povDepth.c_str(), depthMaps[i].c_str()); - if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { - // We mess with depth and depth^2 in their given scales. - // (i.e. between 0 and 1) - fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b, %s.g);", - i, depthMaps[i].c_str(), depthMaps[i].c_str()); - - // variance biasing lessens light bleeding - fragBuilder->codeAppendf("variance = max(moments%d.y - " - "(moments%d.x * moments%d.x)," - "%s);", i, i, i, - minVarianceUniName); - - fragBuilder->codeAppendf("d = (%s.b) - moments%d.x;", - povDepth.c_str(), i); - fragBuilder->codeAppendf("lightProbability = " - "(variance / (variance + d * d));"); - - SkString clamp("clamp"); - clamp.appendf("%d", i); - - // choosing between light artifacts or correct shape shadows - // linstep - fragBuilder->codeAppendf("float %s = clamp((lightProbability - %s) /" - "(1 - %s), 0, 1);", - clamp.c_str(), shBiasUniName, shBiasUniName); - - fragBuilder->codeAppendf("lightProbability = %s;", clamp.c_str()); - } else { - fragBuilder->codeAppendf("if (%s.b >= %s.b) {", - povDepth.c_str(), depthMaps[i].c_str()); - fragBuilder->codeAppendf("lightProbability = 1;"); - fragBuilder->codeAppendf("} else { lightProbability = 0; }"); - } - - // VSM: The curved shadows near plane edges are artifacts from blurring - // lightDir.z is equal to the lightDir dot the surface normal. - fragBuilder->codeAppendf("}"); - } - - if (shadowFP.isPointLight(i)) { - fragBuilder->codeAppendf("totalLightColor += max(fragToLight%d.z, 0) * %s /" - "(1 + dist%d) * lightProbability;", - i, lightColorUniName[i], i); - } else { - fragBuilder->codeAppendf("totalLightColor += %s.z * %s * lightProbability;", - lightDirOrPosUniName[i], - lightColorUniName[i]); - } - - fragBuilder->codeAppendf("totalLightColor += %s;", ambientColorUniName); - fragBuilder->codeAppendf("%s = resultDiffuseColor * vec4(totalLightColor, 1);", - args.fOutputColor); - } - - } - - static void GenKey(const GrProcessor& proc, const GrShaderCaps&, - GrProcessorKeyBuilder* b) { - const ShadowFP& shadowFP = proc.cast(); - b->add32(shadowFP.fNumNonAmbLights); - int isPLR = 0; - for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) { - isPLR = isPLR | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i); - isPLR = isPLR | ((shadowFP.fIsRadialLight[i] ? 1 : 0) << (i+4)); - } - b->add32(isPLR); - b->add32(shadowFP.fShadowParams.fType); - } - - protected: - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& proc) override { - const ShadowFP &shadowFP = proc.cast(); - - for (int i = 0; i < shadowFP.numLights(); i++) { - const SkVector3& lightDirOrPos = shadowFP.lightDirOrPos(i); - if (lightDirOrPos != fLightDirOrPos[i]) { - pdman.set3fv(fLightDirOrPosUni[i], 1, &lightDirOrPos.fX); - fLightDirOrPos[i] = lightDirOrPos; - } - - const SkColor3f& lightColor = shadowFP.lightColor(i); - if (lightColor != fLightColor[i]) { - pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); - fLightColor[i] = lightColor; - } - - int depthMapWidth = shadowFP.depthMapWidth(i); - if (depthMapWidth != fDepthMapWidth[i]) { - pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); - fDepthMapWidth[i] = depthMapWidth; - } - int depthMapHeight = shadowFP.depthMapHeight(i); - if (depthMapHeight != fDepthMapHeight[i]) { - pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); - fDepthMapHeight[i] = depthMapHeight; - } - } - - SkScalar biasingConstant = shadowFP.shadowParams().fBiasingConstant; - if (biasingConstant != fBiasingConstant) { - pdman.set1f(fBiasingConstantUni, biasingConstant); - fBiasingConstant = biasingConstant; - } - - SkScalar minVariance = shadowFP.shadowParams().fMinVariance; - if (minVariance != fMinVariance) { - // transform variance from pixel-scale to normalized scale - pdman.set1f(fMinVarianceUni, minVariance / 65536.0f); - fMinVariance = minVariance / 65536.0f; - } - - int width = shadowFP.width(); - if (width != fWidth) { - pdman.set1i(fWidthUni, width); - fWidth = width; - } - int height = shadowFP.height(); - if (height != fHeight) { - pdman.set1i(fHeightUni, height); - fHeight = height; - } - - const SkColor3f& ambientColor = shadowFP.ambientColor(); - if (ambientColor != fAmbientColor) { - pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); - fAmbientColor = ambientColor; - } - } - - private: - SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; - GrGLSLProgramDataManager::UniformHandle - fLightDirOrPosUni[SkShadowShader::kMaxNonAmbientLights]; - - SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; - GrGLSLProgramDataManager::UniformHandle - fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; - - int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; - GrGLSLProgramDataManager::UniformHandle - fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; - - int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; - GrGLSLProgramDataManager::UniformHandle - fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; - - int fWidth; - GrGLSLProgramDataManager::UniformHandle fWidthUni; - int fHeight; - GrGLSLProgramDataManager::UniformHandle fHeightUni; - - SkScalar fBiasingConstant; - GrGLSLProgramDataManager::UniformHandle fBiasingConstantUni; - SkScalar fMinVariance; - GrGLSLProgramDataManager::UniformHandle fMinVarianceUni; - - SkColor3f fAmbientColor; - GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; - }; - - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { - GLSLShadowFP::GenKey(*this, caps, b); - } - - const char* name() const override { return "shadowFP"; } - - int32_t numLights() const { return fNumNonAmbLights; } - const SkColor3f& ambientColor() const { return fAmbientColor; } - bool isPointLight(int i) const { - SkASSERT(i < fNumNonAmbLights); - return fIsPointLight[i]; - } - bool isRadialLight(int i) const { - SkASSERT(i < fNumNonAmbLights); - return fIsRadialLight[i]; - } - const SkVector3& lightDirOrPos(int i) const { - SkASSERT(i < fNumNonAmbLights); - return fLightDirOrPos[i]; - } - const SkVector3& lightColor(int i) const { - SkASSERT(i < fNumNonAmbLights); - return fLightColor[i]; - } - int depthMapWidth(int i) const { - SkASSERT(i < fNumNonAmbLights); - return fDepthMapWidth[i]; - } - int depthMapHeight(int i) const { - SkASSERT(i < fNumNonAmbLights); - return fDepthMapHeight[i]; - } - int width() const {return fWidth; } - int height() const {return fHeight; } - - const SkShadowParams& shadowParams() const {return fShadowParams; } - -private: - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; } - - bool onIsEqual(const GrFragmentProcessor& proc) const override { - const ShadowFP& shadowFP = proc.cast(); - if (fAmbientColor != shadowFP.fAmbientColor || - fNumNonAmbLights != shadowFP.fNumNonAmbLights) { - return false; - } - - if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { - return false; - } - - for (int i = 0; i < fNumNonAmbLights; i++) { - if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] || - fLightColor[i] != shadowFP.fLightColor[i] || - fIsPointLight[i] != shadowFP.fIsPointLight[i] || - fIsRadialLight[i] != shadowFP.fIsRadialLight[i]) { - return false; - } - - if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || - fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { - return false; - } - } - - return true; - } - - int fNumNonAmbLights; - - bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights]; - bool fIsRadialLight[SkShadowShader::kMaxNonAmbientLights]; - SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; - SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; - TextureSampler fDepthMapSampler[SkShadowShader::kMaxNonAmbientLights]; - sk_sp fTexture[SkShadowShader::kMaxNonAmbientLights]; - - int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; - int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; - - int fHeight; - int fWidth; - - SkShadowParams fShadowParams; - - SkColor3f fAmbientColor; -}; - -//////////////////////////////////////////////////////////////////////////// - -sk_sp SkShadowShaderImpl::asFragmentProcessor(const AsFPArgs& fpargs) const { - - sk_sp povDepthFP = fPovDepthShader->asFragmentProcessor(fpargs); - - sk_sp diffuseFP = fDiffuseShader->asFragmentProcessor(fpargs); - - sk_sp shadowfp = sk_make_sp(std::move(povDepthFP), - std::move(diffuseFP), - std::move(fLights), - fDiffuseWidth, fDiffuseHeight, - fShadowParams, fpargs.fContext); - return shadowfp; -} - - -#endif - -//////////////////////////////////////////////////////////////////////////// - -bool SkShadowShaderImpl::isOpaque() const { - return fDiffuseShader->isOpaque(); -} - -SkShadowShaderImpl::ShadowShaderContext::ShadowShaderContext( - const SkShadowShaderImpl& shader, const ContextRec& rec, - SkShader::Context* povDepthContext, - SkShader::Context* diffuseContext, - void* heapAllocated) - : INHERITED(shader, rec) - , fPovDepthContext(povDepthContext) - , fDiffuseContext(diffuseContext) - , fHeapAllocated(heapAllocated) { - bool isOpaque = shader.isOpaque(); - - // update fFlags - uint32_t flags = 0; - if (isOpaque && (255 == this->getPaintAlpha())) { - flags |= kOpaqueAlpha_Flag; - } - - fFlags = flags; - - const SkShadowShaderImpl& lightShader = static_cast(fShader); - - fNonAmbLightCnt = lightShader.fLights->numLights(); - fShadowMapPixels = new SkPixmap[fNonAmbLightCnt]; - - for (int i = 0; i < fNonAmbLightCnt; i++) { - if (lightShader.fLights->light(i).type() == SkLights::Light::kDirectional_LightType) { - lightShader.fLights->light(i).getShadowMap()-> - peekPixels(&fShadowMapPixels[i]); - } - } -} - -SkShadowShaderImpl::ShadowShaderContext::~ShadowShaderContext() { - delete[] fShadowMapPixels; - - // The dependencies have been created outside of the context on memory that was allocated by - // the onCreateContext() method. Call the destructors and free the memory. - fPovDepthContext->~Context(); - fDiffuseContext->~Context(); - - sk_free(fHeapAllocated); -} - -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 SkShadowShaderImpl::ShadowShaderContext::shadeSpan(int x, int y, - SkPMColor result[], int count) { - const SkShadowShaderImpl& lightShader = static_cast(fShader); - - SkPMColor diffuse[BUFFER_MAX]; - SkPMColor povDepth[BUFFER_MAX]; - - do { - int n = SkTMin(count, BUFFER_MAX); - - fDiffuseContext->shadeSpan(x, y, diffuse, n); - fPovDepthContext->shadeSpan(x, y, povDepth, n); - - for (int i = 0; i < n; ++i) { - SkColor diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]); - SkColor povDepthColor = povDepth[i]; - - SkColor3f totalLight = lightShader.fLights->ambientLightColor(); - // 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); - - int pvDepth = SkColorGetB(povDepthColor); // depth stored in blue channel - - if (light.type() == SkLights::Light::kDirectional_LightType) { - - int xOffset = SkScalarRoundToInt(light.dir().fX * pvDepth); - int yOffset = SkScalarRoundToInt(light.dir().fY * pvDepth); - - int shX = SkClampMax(x + i + xOffset, light.getShadowMap()->width() - 1); - int shY = SkClampMax(y + yOffset, light.getShadowMap()->height() - 1); - - int shDepth = 0; - int shDepthsq = 0; - - // pixmaps that point to things have nonzero heights - if (fShadowMapPixels[l].height() > 0) { - uint32_t pix = *fShadowMapPixels[l].addr32(shX, shY); - SkColor shColor(pix); - - shDepth = SkColorGetB(shColor); - shDepthsq = SkColorGetG(shColor) * 256; - } else { - // Make lights w/o a shadow map receive the full light contribution - shDepth = pvDepth; - } - - SkScalar lightProb = 1.0f; - if (pvDepth < shDepth) { - if (lightShader.fShadowParams.fType == - SkShadowParams::ShadowType::kVariance_ShadowType) { - int variance = SkMaxScalar(shDepthsq - shDepth * shDepth, - lightShader.fShadowParams.fMinVariance); - int d = pvDepth - shDepth; - - lightProb = (SkScalar) variance / ((SkScalar) (variance + d * d)); - - SkScalar bias = lightShader.fShadowParams.fBiasingConstant; - - lightProb = SkMaxScalar((lightProb - bias) / (1.0f - bias), 0.0f); - } else { - lightProb = 0.0f; - } - } - - // assume object normals are pointing straight up - totalLight.fX += light.dir().fZ * light.color().fX * lightProb; - totalLight.fY += light.dir().fZ * light.color().fY * lightProb; - totalLight.fZ += light.dir().fZ * light.color().fZ * lightProb; - - } else { - // right now we only expect directional and point light types. - SkASSERT(light.type() == SkLights::Light::kPoint_LightType); - - int height = lightShader.fDiffuseHeight; - - SkVector3 fragToLight = SkVector3::Make(light.pos().fX - x - i, - light.pos().fY - (height - y), - light.pos().fZ - pvDepth); - - SkScalar dist = fragToLight.length(); - SkScalar normalizedZ = fragToLight.fZ / dist; - - SkScalar distAttenuation = light.intensity() / (1.0f + dist); - - // assume object normals are pointing straight up - totalLight.fX += normalizedZ * light.color().fX * distAttenuation; - totalLight.fY += normalizedZ * light.color().fY * distAttenuation; - totalLight.fZ += normalizedZ * light.color().fZ * distAttenuation; - } - } - - SkColor3f totalColor = SkColor3f::Make(SkColorGetR(diffColor) * totalLight.fX, - SkColorGetG(diffColor) * totalLight.fY, - SkColorGetB(diffColor) * totalLight.fZ); - - result[i] = convert(totalColor, SkColorGetA(diffColor)); - } - - result += n; - x += n; - count -= n; - } while (count > 0); -} - -//////////////////////////////////////////////////////////////////////////// - -#ifndef SK_IGNORE_TO_STRING -void SkShadowShaderImpl::toString(SkString* str) const { - str->appendf("ShadowShader: ()"); -} -#endif - -sk_sp SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) { - - // Discarding SkShader flattenable params - bool hasLocalMatrix = buf.readBool(); - SkAssertResult(!hasLocalMatrix); - - sk_sp lights = SkLights::MakeFromBuffer(buf); - - SkShadowParams params; - params.fMinVariance = buf.readScalar(); - params.fBiasingConstant = buf.readScalar(); - params.fType = (SkShadowParams::ShadowType) buf.readInt(); - params.fShadowRadius = buf.readScalar(); - - int diffuseWidth = buf.readInt(); - int diffuseHeight = buf.readInt(); - - sk_sp povDepthShader(buf.readFlattenable()); - sk_sp diffuseShader(buf.readFlattenable()); - - return sk_make_sp(std::move(povDepthShader), - std::move(diffuseShader), - std::move(lights), - diffuseWidth, diffuseHeight, - params); -} - -void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const { - this->INHERITED::flatten(buf); - - fLights->flatten(buf); - - buf.writeScalar(fShadowParams.fMinVariance); - buf.writeScalar(fShadowParams.fBiasingConstant); - buf.writeInt(fShadowParams.fType); - buf.writeScalar(fShadowParams.fShadowRadius); - - buf.writeInt(fDiffuseWidth); - buf.writeInt(fDiffuseHeight); - - buf.writeFlattenable(fPovDepthShader.get()); - buf.writeFlattenable(fDiffuseShader.get()); -} - -size_t SkShadowShaderImpl::onContextSize(const ContextRec& rec) const { - return sizeof(ShadowShaderContext); -} - -SkShader::Context* SkShadowShaderImpl::onCreateContext(const ContextRec& rec, - void* storage) const { - size_t heapRequired = fPovDepthShader->contextSize(rec) + - fDiffuseShader->contextSize(rec); - - void* heapAllocated = sk_malloc_throw(heapRequired); - - void* povDepthContextStorage = heapAllocated; - - SkShader::Context* povDepthContext = - fPovDepthShader->createContext(rec, povDepthContextStorage); - - if (!povDepthContext) { - sk_free(heapAllocated); - return nullptr; - } - - void* diffuseContextStorage = (char*)heapAllocated + fPovDepthShader->contextSize(rec); - - SkShader::Context* diffuseContext = fDiffuseShader->createContext(rec, diffuseContextStorage); - if (!diffuseContext) { - sk_free(heapAllocated); - return nullptr; - } - - return new (storage) ShadowShaderContext(*this, rec, povDepthContext, diffuseContext, - heapAllocated); -} - -/////////////////////////////////////////////////////////////////////////////// - -sk_sp SkShadowShader::Make(sk_sp povDepthShader, - sk_sp diffuseShader, - sk_sp lights, - int diffuseWidth, int diffuseHeight, - const SkShadowParams& params) { - if (!povDepthShader || !diffuseShader) { - // TODO: Use paint's color in absence of a diffuseShader - // TODO: Use a default implementation of normalSource instead - return nullptr; - } - - return sk_make_sp(std::move(povDepthShader), - std::move(diffuseShader), - std::move(lights), - diffuseWidth, diffuseHeight, - params); -} - -/////////////////////////////////////////////////////////////////////////////// - -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) - SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END - -/////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/src/core/SkShadowShader.h b/src/core/SkShadowShader.h deleted file mode 100644 index ea05ccae89..0000000000 --- a/src/core/SkShadowShader.h +++ /dev/null @@ -1,40 +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 SkShadowShader_DEFINED -#define SkShadowShader_DEFINED - -#ifdef SK_EXPERIMENTAL_SHADOWING - -class SkLights; -class SkShader; - -class SK_API SkShadowShader { -public: - /** This shader combines the diffuse color in 'diffuseShader' with the shadows - * determined by the 'povDepthShader' and the shadow maps stored in each of the - * lights in 'lights' - * - * Please note that the shadow shader is required to be in Stage0, otherwise - * the texture coords will be wrong within the shader. - */ - static sk_sp Make(sk_sp povDepthShader, - sk_sp diffuseShader, - sk_sp lights, - int diffuseWidth, int diffuseHeight, - const SkShadowParams& params); - - // The shadow shader supports any number of ambient lights, but only - // 4 non-ambient lights (currently just refers to directional lights). - static constexpr int kMaxNonAmbientLights = 4; - - SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() -}; - -#endif -#endif diff --git a/src/utils/SkShadowPaintFilterCanvas.cpp b/src/utils/SkShadowPaintFilterCanvas.cpp deleted file mode 100644 index bf4a4242f2..0000000000 --- a/src/utils/SkShadowPaintFilterCanvas.cpp +++ /dev/null @@ -1,307 +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 "SkPathEffect.h" -#include "SkShadowPaintFilterCanvas.h" - -#ifdef SK_EXPERIMENTAL_SHADOWING - -SkShadowPaintFilterCanvas::SkShadowPaintFilterCanvas(SkCanvas *canvas) - : SkPaintFilterCanvas(canvas) { - fShadowParams.fShadowRadius = 0.0f; - fShadowParams.fType = SkShadowParams::kNoBlur_ShadowType; - fShadowParams.fBiasingConstant = 0.0f; - fShadowParams.fMinVariance = 0.0f; -} - -// TODO use a shader instead -bool SkShadowPaintFilterCanvas::onFilter(SkTCopyOnFirstWrite* paint, Type type) const { - if (*paint) { - int z = this->getZ(); - SkASSERT(z <= 0xFF && z >= 0x00); - - SkPaint newPaint; - newPaint.setPathEffect(sk_ref_sp((*paint)->getPathEffect())); - - SkColor color = 0xFF000000; // init color to opaque black - color |= z; // Put the index into the blue component - - if (fShadowParams.fType == SkShadowParams::kVariance_ShadowType) { - int z2 = z * z; - if (z2 > 255 * 256) { - color |= 0xff00; - } else { - // Let's only store the more significant bits of z2 to save space. - // In practice, this should barely impact shadow blur quality. - color |= z2 & 0x0000ff00; - } - } - newPaint.setColor(color); - - *paint->writable() = newPaint; - } - - return true; -} - -SkISize SkShadowPaintFilterCanvas::ComputeDepthMapSize(const SkLights::Light& light, int maxDepth, - int width, int height) { - if (light.type() != SkLights::Light::kDirectional_LightType) { - // Calculating the right depth map size for point lights is complex, - // as it depends on the max depth, the max depth delta, the location - // of the point light and the shapes, etc... If we take upper bounds - // on those metrics, the shadow map will be pretty big in any case. - // Thus, just using 4x the width and height seems to work for most scenes. - return {width * 4, height * 4}; - } - - int dMapWidth = SkMin32(maxDepth * fabs(light.dir().fX) + width, - width * 2); - int dMapHeight = SkMin32(maxDepth * fabs(light.dir().fY) + height, - height * 2); - return SkISize::Make(dMapWidth, dMapHeight); -} - -void SkShadowPaintFilterCanvas::setShadowParams(const SkShadowParams ¶ms) { - fShadowParams = params; -} - -void SkShadowPaintFilterCanvas::onDrawPicture(const SkPicture *picture, const SkMatrix *matrix, - const SkPaint *paint) { - SkTCopyOnFirstWrite filteredPaint(paint); - if (this->onFilter(&filteredPaint, kPicture_Type)) { - SkCanvas::onDrawPicture(picture, matrix, filteredPaint); - } -} - -void SkShadowPaintFilterCanvas::updateMatrix() { - // It is up to the user to set the 0th light in fLights to - // the light the want to render the depth map with. - if (this->fLights->light(0).type() == SkLights::Light::kDirectional_LightType) { - const SkVector3& lightDir = this->fLights->light(0).dir(); - SkScalar x = lightDir.fX * this->getZ(); - SkScalar y = lightDir.fY * this->getZ(); - - this->translate(x, y); - } else if (this->fLights->light(0).type() == SkLights::Light::kPoint_LightType) { - SkISize size = this->getBaseLayerSize(); - - SkPoint3 lightPos = this->fLights->light(0).pos(); - - // shadow maps for point lights are 4x the size of the diffuse map, by experimentation - // (see SPFCanvas::ComputeDepthMapSize()) - SkScalar diffuseHeight = size.fHeight / 4.0f; - - // move point light with canvas's CTM - SkPoint lightPoint = SkPoint::Make(lightPos.fX, diffuseHeight - lightPos.fY); - SkMatrix mat = this->getTotalMatrix(); - if (mat.invert(&mat)) { - mat.mapPoints(&lightPoint, 1); - } - lightPoint.set(lightPoint.fX, diffuseHeight - lightPoint.fY); - - // center the shadow map - // note: the 3/8 constant is specific to the 4.0 depth map size multiplier - mat = this->getTotalMatrix(); - mat.postTranslate(size.width() * 0.375f, size.height() * 0.375f); - this->setMatrix(mat); - - // project shapes onto canvas as shadows - SkScalar scale = (lightPos.fZ) / (lightPos.fZ - this->getZ()); - this->scale(scale, scale); - - this->translate(-lightPoint.fX * this->getZ() / - ((lightPos.fZ - this->getZ()) * scale), - -(diffuseHeight - lightPoint.fY) * this->getZ() / - ((lightPos.fZ - this->getZ()) * scale)); - } -} - -void SkShadowPaintFilterCanvas::onDrawPaint(const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawPaint(paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawPoints(mode, count, pts, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawRect(const SkRect &rect, const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawRect(rect, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawRRect(const SkRRect &rrect, const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawRRect(rrect, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawDRRect(const SkRRect &outer, const SkRRect &inner, - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawDRRect(outer, inner, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawOval(const SkRect &rect, const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawOval(rect, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawArc(const SkRect &rect, SkScalar startAngle, - SkScalar sweepAngle, bool useCenter, - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawArc(rect, startAngle, sweepAngle, useCenter, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawPath(const SkPath &path, const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawPath(path, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawBitmap(const SkBitmap &bm, SkScalar left, SkScalar top, - const SkPaint *paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawBitmap(bm, left, top, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawBitmapRect(const SkBitmap &bm, const SkRect *src, - const SkRect &dst, const SkPaint *paint, - SrcRectConstraint constraint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawBitmapRect(bm, src, dst, paint, constraint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawBitmapNine(const SkBitmap &bm, const SkIRect ¢er, - const SkRect &dst, const SkPaint *paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawBitmapNine(bm, center, dst, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawImage(const SkImage *image, SkScalar left, - SkScalar top, const SkPaint *paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawImage(image, left, top, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawImageRect(const SkImage *image, const SkRect *src, - const SkRect &dst, const SkPaint *paint, - SrcRectConstraint constraint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawImageRect(image, src, dst, paint, constraint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawImageNine(const SkImage *image, const SkIRect ¢er, - const SkRect &dst, const SkPaint *paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawImageNine(image, center, dst, paint); - this->restore(); -} - - -void SkShadowPaintFilterCanvas::onDrawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode *xmode, - const uint16_t indices[], int indexCount, - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawVertices(vmode, vertexCount, vertices, texs, colors, - xmode, indices, indexCount, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawPatch(const SkPoint cubics[], const SkColor colors[], - const SkPoint texCoords[], SkXfermode *xmode, - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawPatch(cubics, colors, texCoords, xmode, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawText(const void *text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawText(text, byteLength, x, y, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawPosText(const void *text, size_t byteLength, - const SkPoint pos[], const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawPosText(text, byteLength, pos, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawPosTextH(const void *text, size_t byteLength, - const SkScalar xpos[], - SkScalar constY, const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawPosTextH(text, byteLength, xpos, constY, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawTextOnPath(const void *text, size_t byteLength, - const SkPath &path, const SkMatrix *matrix, - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawTextRSXform(const void *text, size_t byteLength, - const SkRSXform xform[], const SkRect *cull, - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawTextRSXform(text, byteLength, xform, cull, paint); - this->restore(); -} - -void SkShadowPaintFilterCanvas::onDrawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, - const SkPaint &paint) { - this->save(); - this->updateMatrix(); - this->INHERITED::onDrawTextBlob(blob, x, y, paint); - this->restore(); -} - -#endif diff --git a/src/utils/SkShadowPaintFilterCanvas.h b/src/utils/SkShadowPaintFilterCanvas.h deleted file mode 100644 index 190c68b7ce..0000000000 --- a/src/utils/SkShadowPaintFilterCanvas.h +++ /dev/null @@ -1,117 +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 SkShadowPaintFilterCanvas_DEFINED -#define SkShadowPaintFilterCanvas_DEFINED - -#include "SkPaintFilterCanvas.h" - -#ifdef SK_EXPERIMENTAL_SHADOWING - -/** \class SkShadowPaintFilterCanvas - * - * A utility proxy class for implementing shadow maps. - * - * We override the onFilter method to draw depths into the canvas - * depending on the current draw depth of the canvas, throwing out - * the actual draw color. - * - * Note that we can only do this for one light at a time! - * It is up to the user to set the 0th light in fLights to - * the light the want to render the depth map with. - */ -class SkShadowPaintFilterCanvas : public SkPaintFilterCanvas { -public: - - SkShadowPaintFilterCanvas(SkCanvas *canvas); - - // TODO use a shader instead - bool onFilter(SkTCopyOnFirstWrite* paint, Type type) const override; - - static SkISize ComputeDepthMapSize(const SkLights::Light& light, int maxDepth, - int width, int height); - - void setShadowParams(const SkShadowParams ¶ms); -protected: - void updateMatrix(); - - void onDrawPicture(const SkPicture *picture, const SkMatrix *matrix, - const SkPaint *paint) override; - - void onDrawPaint(const SkPaint &paint) override; - - void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint &paint) override; - - void onDrawRect(const SkRect &rect, const SkPaint &paint) override; - - void onDrawRRect(const SkRRect &rrect, const SkPaint &paint) override; - - void onDrawDRRect(const SkRRect &outer, const SkRRect &inner, - const SkPaint &paint) override; - - void onDrawOval(const SkRect &rect, const SkPaint &paint) override; - - void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; - - void onDrawPath(const SkPath &path, const SkPaint &paint) override; - - void onDrawBitmap(const SkBitmap &bm, SkScalar left, SkScalar top, - const SkPaint *paint) override; - - void onDrawBitmapRect(const SkBitmap &bm, const SkRect *src, const SkRect &dst, - const SkPaint *paint, SrcRectConstraint constraint) override; - - void onDrawBitmapNine(const SkBitmap &bm, const SkIRect ¢er, - const SkRect &dst, const SkPaint *paint) override; - - void onDrawImage(const SkImage *image, SkScalar left, SkScalar top, - const SkPaint *paint) override; - - void onDrawImageRect(const SkImage *image, const SkRect *src, - const SkRect &dst, const SkPaint *paint, - SrcRectConstraint constraint) override; - - void onDrawImageNine(const SkImage *image, const SkIRect ¢er, - const SkRect &dst, const SkPaint *paint) override; - - void onDrawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode *xmode, - const uint16_t indices[], int indexCount, - const SkPaint &paint) override; - - void onDrawPatch(const SkPoint cubics[], const SkColor colors[], - const SkPoint texCoords[], SkXfermode *xmode, - const SkPaint &paint) override; - - void onDrawText(const void *text, size_t byteLength, SkScalar x, SkScalar y, - const SkPaint &paint) override; - - void onDrawPosText(const void *text, size_t byteLength, const SkPoint pos[], - const SkPaint &paint) override; - - void onDrawPosTextH(const void *text, size_t byteLength, const SkScalar xpos[], - SkScalar constY, const SkPaint &paint) override; - - void onDrawTextOnPath(const void *text, size_t byteLength, const SkPath &path, - const SkMatrix *matrix, const SkPaint &paint) override; - - void onDrawTextRSXform(const void *text, size_t byteLength, - const SkRSXform xform[], const SkRect *cull, - const SkPaint &paint) override; - - void onDrawTextBlob(const SkTextBlob *blob, SkScalar x, - SkScalar y, const SkPaint &paint) override; -private: - SkShadowParams fShadowParams; - typedef SkPaintFilterCanvas INHERITED; -}; - - -#endif -#endif diff --git a/tools/debugger/SkDebugCanvas.cpp b/tools/debugger/SkDebugCanvas.cpp index 3b84b85934..bed6da03cf 100644 --- a/tools/debugger/SkDebugCanvas.cpp +++ b/tools/debugger/SkDebugCanvas.cpp @@ -58,17 +58,6 @@ protected: this->SkCanvas::onDrawPicture(picture, matrix, paint); } - void onDrawShadowedPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) { -#ifdef SK_EXPERIMENTAL_SHADOWING - this->SkCanvas::onDrawShadowedPicture(picture, matrix, paint, params); -#else - this->SkCanvas::onDrawPicture(picture, matrix, paint); -#endif - } - private: bool fOverdrawViz; bool fOverrideFilterQuality; @@ -546,16 +535,6 @@ void SkDebugCanvas::onDrawPicture(const SkPicture* picture, this->addDrawCommand(new SkEndDrawPictureCommand(SkToBool(matrix) || SkToBool(paint))); } -void SkDebugCanvas::onDrawShadowedPicture(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) { - this->addDrawCommand(new SkBeginDrawShadowedPictureCommand(picture, matrix, paint, params)); - SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); - picture->playback(this); - this->addDrawCommand(new SkEndDrawShadowedPictureCommand(SkToBool(matrix) || SkToBool(paint))); -} - void SkDebugCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { this->addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint)); diff --git a/tools/debugger/SkDebugCanvas.h b/tools/debugger/SkDebugCanvas.h index 7c6a0f4d54..6eb3456dff 100644 --- a/tools/debugger/SkDebugCanvas.h +++ b/tools/debugger/SkDebugCanvas.h @@ -244,18 +244,6 @@ protected: void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; -#ifdef SK_EXPERIMENTAL_SHADOWING - void onDrawShadowedPicture(const SkPicture*, - const SkMatrix*, - const SkPaint*, - const SkShadowParams& params) override; -#else - void onDrawShadowedPicture(const SkPicture*, - const SkMatrix*, - const SkPaint*, - const SkShadowParams& params); -#endif - void markActiveCommands(int index); private: diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp index 23cc6b21f8..6029f83018 100644 --- a/tools/debugger/SkDrawCommand.cpp +++ b/tools/debugger/SkDrawCommand.cpp @@ -204,7 +204,6 @@ SkDrawCommand::~SkDrawCommand() { const char* SkDrawCommand::GetCommandString(OpType type) { switch (type) { case kBeginDrawPicture_OpType: return "BeginDrawPicture"; - case kBeginDrawShadowedPicture_OpType: return "BeginDrawShadowedPicture"; case kClipPath_OpType: return "ClipPath"; case kClipRegion_OpType: return "ClipRegion"; case kClipRect_OpType: return "ClipRect"; @@ -234,7 +233,6 @@ const char* SkDrawCommand::GetCommandString(OpType type) { case kDrawTextRSXform_OpType: return "DrawTextRSXform"; case kDrawVertices_OpType: return "DrawVertices"; case kEndDrawPicture_OpType: return "EndDrawPicture"; - case kEndDrawShadowedPicture_OpType: return "EndDrawShadowedPicture"; case kRestore_OpType: return "Restore"; case kSave_OpType: return "Save"; case kSaveLayer_OpType: return "SaveLayer"; @@ -2595,91 +2593,6 @@ void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const { } } -SkBeginDrawShadowedPictureCommand::SkBeginDrawShadowedPictureCommand(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params) - : INHERITED(kBeginDrawShadowedPicture_OpType) -#ifdef SK_EXPERIMENTAL_SHADOWING - , fPicture(SkRef(picture)) - , fShadowParams(params) { -#else - , fPicture(SkRef(picture)) { -#endif - SkString* str = new SkString; - str->appendf("SkPicture: L: %f T: %f R: %f B: %f\n", - picture->cullRect().fLeft, picture->cullRect().fTop, - picture->cullRect().fRight, picture->cullRect().fBottom); - str->appendf("SkShadowParams: bias:%f, minVariance:%f, shRadius:%f, shType:", - params.fBiasingConstant, - params.fMinVariance, - params.fShadowRadius); - - SkASSERT(SkShadowParams::kShadowTypeCount == 2); - - switch (params.fType) { - case SkShadowParams::ShadowType::kNoBlur_ShadowType: - str->append("kNoBlur_ShadowType\n"); - break; - case SkShadowParams::ShadowType::kVariance_ShadowType: - str->append("kVariance_ShadowType\n"); - break; - } - - fInfo.push(str); - - if (matrix) { - fMatrix.set(*matrix); - fInfo.push(SkObjectParser::MatrixToString(*matrix)); - } - - if (paint) { - fPaint.set(*paint); - fInfo.push(SkObjectParser::PaintToString(*paint)); - } -} - -void SkBeginDrawShadowedPictureCommand::execute(SkCanvas* canvas) const { - if (fPaint.isValid()) { - SkRect bounds = fPicture->cullRect(); - if (fMatrix.isValid()) { - fMatrix.get()->mapRect(&bounds); - } - canvas->saveLayer(&bounds, fPaint.get()); - } - - if (fMatrix.isValid()) { - if (!fPaint.isValid()) { - canvas->save(); - } - canvas->concat(*fMatrix.get()); - } -} - -bool SkBeginDrawShadowedPictureCommand::render(SkCanvas* canvas) const { - canvas->clear(0xFFFFFFFF); - canvas->save(); - - xlate_and_scale_to_bounds(canvas, fPicture->cullRect()); -#ifdef SK_EXPERIMENTAL_SHADOWING - canvas->drawShadowedPicture(fPicture.get(), fMatrix.get(), fPaint.get(), fShadowParams); -#else - canvas->drawPicture(fPicture.get(), fMatrix.get(), fPaint.get()); -#endif - canvas->restore(); - - return true; -} - -SkEndDrawShadowedPictureCommand::SkEndDrawShadowedPictureCommand(bool restore) - : INHERITED(kEndDrawShadowedPicture_OpType) , fRestore(restore) { } - -void SkEndDrawShadowedPictureCommand::execute(SkCanvas* canvas) const { - if (fRestore) { - canvas->restore(); - } -} - SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) : INHERITED(kDrawPoints_OpType) { diff --git a/tools/debugger/SkDrawCommand.h b/tools/debugger/SkDrawCommand.h index 4004b3bc2c..ff64dd5d9f 100644 --- a/tools/debugger/SkDrawCommand.h +++ b/tools/debugger/SkDrawCommand.h @@ -24,7 +24,6 @@ class SkDrawCommand { public: enum OpType { kBeginDrawPicture_OpType, - kBeginDrawShadowedPicture_OpType, kClipPath_OpType, kClipRegion_OpType, kClipRect_OpType, @@ -54,7 +53,6 @@ public: kDrawTextRSXform_OpType, kDrawVertices_OpType, kEndDrawPicture_OpType, - kEndDrawShadowedPicture_OpType, kRestore_OpType, kSave_OpType, kSaveLayer_OpType, @@ -496,39 +494,6 @@ private: typedef SkDrawCommand INHERITED; }; -class SkBeginDrawShadowedPictureCommand : public SkDrawCommand { -public: - SkBeginDrawShadowedPictureCommand(const SkPicture* picture, - const SkMatrix* matrix, - const SkPaint* paint, - const SkShadowParams& params); - - void execute(SkCanvas* canvas) const override; - bool render(SkCanvas* canvas) const override; - -private: - sk_sp fPicture; - SkTLazy fMatrix; - SkTLazy fPaint; -#ifdef SK_EXPERIMENTAL_SHADOWING - SkShadowParams fShadowParams; -#endif - - typedef SkDrawCommand INHERITED; -}; - -class SkEndDrawShadowedPictureCommand : public SkDrawCommand { -public: - SkEndDrawShadowedPictureCommand(bool restore); - - void execute(SkCanvas* canvas) const override; - -private: - bool fRestore; - - typedef SkDrawCommand INHERITED; -}; - class SkDrawPointsCommand : public SkDrawCommand { public: SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],