diff options
34 files changed, 44 insertions, 1803 deletions
diff --git a/gm/lightingshaderbevel.cpp b/gm/lightingshaderbevel.cpp deleted file mode 100644 index 9e15a8e7f1..0000000000 --- a/gm/lightingshaderbevel.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "gm.h" -#include "sk_tool_utils.h" -#include "SkLightingShader.h" -#include "SkNormalSource.h" -#include "SkPath.h" -#include "SkPoint3.h" -#include "SkShader.h" - - -namespace skiagm { - -// This GM exercises lighting shaders when used with bevel SkNormalSource objects. -class LightingShaderBevelGM : public GM { -public: - LightingShaderBevelGM() { - this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); - } - -protected: - SkString onShortName() override { - return SkString("lightingshaderbevel"); - } - - SkISize onISize() override { - return SkISize::Make(SkScalarCeilToInt(GRID_NUM_COLUMNS * GRID_CELL_WIDTH), - SkScalarCeilToInt(GRID_NUM_ROWS * GRID_CELL_WIDTH)); - } - - void onOnceBeforeDraw() override { - SkLights::Builder builder; - const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0.473f); - - builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), - kLightFromUpperRight)); - builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f)); - fLights = builder.finish(); - - // fRect is assumed to be square throughout this file - fRect = SkRect::MakeIWH(kTexSize, kTexSize); - SkMatrix matrix; - SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize); - matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit); - - SkBitmap diffuseMap = sk_tool_utils::create_checkerboard_bitmap( - kTexSize, kTexSize, - sk_tool_utils::color_to_565(0x0), - sk_tool_utils::color_to_565(0xFF804020), - 8); - fDiffuse = SkShader::MakeBitmapShader(diffuseMap, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, &matrix); - - fConvexPath.moveTo(fRect.width() / 2.0f, 0.0f); - fConvexPath.lineTo(0.0f, fRect.height()); - fConvexPath.lineTo(fRect.width(), fRect.height()); - fConvexPath.close(); - - // Creating concave path - { - SkScalar x = 0.0f; - SkScalar y = fRect.height() / 2.0f; - - const int NUM_SPIKES = 8; - - const SkScalar x0 = x; - const SkScalar dx = fRect.width() / (NUM_SPIKES * 2); - const SkScalar dy = SK_Scalar1 * 10; - - - fConcavePath.moveTo(x, y + dy); - for (int i = 0; i < NUM_SPIKES; i++) { - x += dx; - fConcavePath.lineTo(x, y - dy); - x += dx; - fConcavePath.lineTo(x, y + dy); - } - fConcavePath.lineTo(x, y + (2 * dy)); - fConcavePath.lineTo(x0, y + (2 * dy)); - fConcavePath.close(); - } - } - - // Scales shape around origin, rotates shape around origin, then translates shape to origin - void positionCTM(SkCanvas *canvas, SkScalar scaleX, SkScalar scaleY, SkScalar rotate) const { - canvas->translate(kTexSize/2.0f, kTexSize/2.0f); - canvas->scale(scaleX, scaleY); - canvas->rotate(rotate); - canvas->translate(-kTexSize/2.0f, -kTexSize/2.0f); - } - - enum Shape { - kCircle_Shape, - kRect_Shape, - kRRect_Shape, - kConvexPath_Shape, - kConcavePath_Shape, - - kLast_Shape = kConcavePath_Shape - }; - void drawShape(enum Shape shape, SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY, - SkScalar rotate, SkNormalSource::BevelType bevelType, SkScalar bevelHeight) { - canvas->save(); - - this->positionCTM(canvas, scaleX, scaleY, rotate); - - SkPaint paint; - - SkScalar bevelWidth = 10.0f; - sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeBevel(bevelType, bevelWidth, - bevelHeight); - - paint.setShader(SkLightingShader::Make(fDiffuse, std::move(normalSource), fLights)); - paint.setAntiAlias(true); - switch(shape) { - case kCircle_Shape: - canvas->drawCircle(fRect.centerX(), fRect.centerY(), fRect.width()/2.0f, paint); - break; - case kRect_Shape: - canvas->drawRect(fRect, paint); - break; - case kRRect_Shape: - canvas->drawRoundRect(fRect, 5.0f, 5.0f, paint); - break; - case kConvexPath_Shape: - canvas->drawPath(fConvexPath, paint); - break; - case kConcavePath_Shape: - canvas->drawPath(fConcavePath, paint); - break; - default: - SkDEBUGFAIL("Invalid shape enum for drawShape"); - } - - canvas->restore(); - } - - void onDraw(SkCanvas* canvas) override { - SkPaint labelPaint; - labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-serif", - SkFontStyle())); - labelPaint.setAntiAlias(true); - labelPaint.setTextSize(LABEL_SIZE); - - int gridNum = 0; - - // Running through all possible parameter combinations - for (auto bevelType : {SkNormalSource::BevelType::kLinear, - SkNormalSource::BevelType::kRoundedIn, - SkNormalSource::BevelType::kRoundedOut}) { - for (SkScalar bevelHeight: {-7.0f, 7.0f}) { - for (int shapeInt = 0; shapeInt < NUM_SHAPES; shapeInt++) { - Shape shape = (Shape)shapeInt; - - // Determining position - SkScalar xPos = (gridNum / GRID_NUM_ROWS) * GRID_CELL_WIDTH; - SkScalar yPos = (gridNum % GRID_NUM_ROWS) * GRID_CELL_WIDTH; - - canvas->save(); - - canvas->translate(xPos, yPos); - this->drawShape(shape, canvas, 1.0f, 1.0f, 0.f, bevelType, bevelHeight); - // Drawing labels - canvas->translate(0.0f, SkIntToScalar(kTexSize)); - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.append("bevelType: "); - switch (bevelType) { - case SkNormalSource::BevelType::kLinear: - label.append("linear"); - break; - case SkNormalSource::BevelType::kRoundedIn: - label.append("roundedIn"); - break; - case SkNormalSource::BevelType::kRoundedOut: - label.append("roundedOut"); - break; - } - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("bevelHeight: %.1f", bevelHeight); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - - canvas->restore(); - - gridNum++; - } - } - } - - // Testing rotation - for (int shapeInt = 0; shapeInt < NUM_SHAPES; shapeInt++) { - Shape shape = (Shape)shapeInt; - - // Determining position - SkScalar xPos = (gridNum / GRID_NUM_ROWS) * GRID_CELL_WIDTH; - SkScalar yPos = (gridNum % GRID_NUM_ROWS) * GRID_CELL_WIDTH; - - canvas->save(); - - canvas->translate(xPos, yPos); - this->drawShape(shape, canvas, SK_ScalarRoot2Over2, SK_ScalarRoot2Over2, 45.0f, - SkNormalSource::BevelType::kLinear, 7.0f); - - // Drawing labels - canvas->translate(0.0f, SkIntToScalar(kTexSize)); - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("bevelType: linear"); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("bevelHeight: %.1f", 7.0f); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - { - canvas->translate(0.0f, LABEL_SIZE); - SkString label; - label.appendf("rotated"); - canvas->drawString(label, 0.0f, 0.0f, labelPaint); - } - - canvas->restore(); - - gridNum++; - } - - // Making sure NUM_COMBINATIONS_PER_SHAPE is set correctly - SkASSERT(gridNum == (NUM_COMBINATIONS_PER_SHAPE*NUM_SHAPES)); - } - -private: - static constexpr int kTexSize = 96; - static constexpr int NUM_SHAPES = kLast_Shape + 1; - static constexpr int NUM_COMBINATIONS_PER_SHAPE = 7; - static constexpr int GRID_NUM_ROWS = NUM_SHAPES; - static constexpr int GRID_NUM_COLUMNS = NUM_COMBINATIONS_PER_SHAPE; - static constexpr SkScalar LABEL_SIZE = 10.0f; - static constexpr int NUM_LABELS_PER_CELL = 3; - static constexpr SkScalar GRID_CELL_WIDTH = kTexSize + 10.0f + NUM_LABELS_PER_CELL * LABEL_SIZE; - - sk_sp<SkShader> fDiffuse; - - SkRect fRect; - SkPath fConvexPath; - SkPath fConcavePath; - sk_sp<SkLights> fLights; - - typedef GM INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -DEF_GM(return new LightingShaderBevelGM;) -} diff --git a/gn/core.gni b/gn/core.gni index 2e6be2d7fb..aac07b5c70 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -202,15 +202,12 @@ skia_core_sources = [ "$_src/core/SkNextID.h", "$_src/core/SkLatticeIter.cpp", "$_src/core/SkLatticeIter.h", - "$_src/core/SkNormalBevelSource.cpp", - "$_src/core/SkNormalBevelSource.h", "$_src/core/SkNormalMapSource.cpp", "$_src/core/SkNormalMapSource.h", "$_src/core/SkNormalFlatSource.cpp", "$_src/core/SkNormalFlatSource.h", "$_src/core/SkNormalSource.cpp", "$_src/core/SkNormalSource.h", - "$_src/core/SkNormalSourcePriv.h", "$_src/core/SkNx.h", "$_src/core/SkOpts.cpp", "$_src/core/SkOpts.h", @@ -187,7 +187,6 @@ gm_sources = [ "$_gm/lighting.cpp", "$_gm/lightingshader.cpp", "$_gm/lightingshader2.cpp", - "$_gm/lightingshaderbevel.cpp", "$_gm/linepaths.cpp", "$_gm/localmatriximagefilter.cpp", "$_gm/localmatriximageshader.cpp", diff --git a/gn/samples.gni b/gn/samples.gni index 2f79a35eec..4a503136b9 100644 --- a/gn/samples.gni +++ b/gn/samples.gni @@ -22,7 +22,6 @@ samples_sources = [ "$_samplecode/SampleAnimBlur.cpp", "$_samplecode/SampleArc.cpp", "$_samplecode/SampleAtlas.cpp", - "$_samplecode/SampleBevel.cpp", "$_samplecode/SampleBigBlur.cpp", "$_samplecode/SampleBigGradient.cpp", "$_samplecode/SampleBitmapRect.cpp", diff --git a/samplecode/SampleBevel.cpp b/samplecode/SampleBevel.cpp deleted file mode 100644 index 3f193cfc45..0000000000 --- a/samplecode/SampleBevel.cpp +++ /dev/null @@ -1,833 +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 "SkCanvas.h" -#include "SkLightingShader.h" -#include "SkNormalSource.h" -#include "sk_tool_utils.h" - -class ParentControl; - -// Abstract base class for all components that a control panel must have -class Control : public SkRefCnt { -public: - Control(SkString name) - : fName(name) - , fParent(nullptr) - , fRelativePos(SkPoint::Make(0.0f, 0.0f)) {} - - // Use this to propagate a click's position down to a control. Gets modulated by the component's - // relative position - bool click(const SkPoint& clickPos) { - SkPoint relativeClickPos = SkPoint::Make(clickPos.fX - fRelativePos.fX, - clickPos.fY - fRelativePos.fY); - return this->onClick(relativeClickPos); - } - - // Use this to draw the control and its appropriate children. Gets modulated by the component's - // relative position. - void drawContent(SkCanvas *canvas) { - canvas->save(); - canvas->translate(fRelativePos.fX, fRelativePos.fY); - this->onDrawContent(canvas); - canvas->restore(); - } - - /* Returns true when click position argumend lands over a control region in this control. Click - * position gets modulated by the component's relative position. - * - * @param click The position of the click in the coordinate space relative to the parent - */ - bool isInCtrlRegion(const SkPoint& click) { - SkPoint relativeClickPos = SkPoint::Make(click.fX - fRelativePos.fX, - click.fY - fRelativePos.fY); - return this->onIsInCtrlRegion(relativeClickPos); - } - - // Returns height of content drawn - virtual SkScalar height() const = 0; - - // Sets the parent of this component. May only be used once. Height must remain constant after - // parent is set. - void setParent(ParentControl *parent, const SkPoint& relativePos) { - SkASSERT(parent); - SkASSERT(!fParent); // No chidren transfer since relativeY would get invalid for younger kid - - fParent = parent; - fRelativePos = relativePos; - this->onSetParent(); - } - - // Overriden by sub-classes that need to recompute fields after parent is set. Called after - // setting fParent. - virtual void onSetParent() {} - - // Overriden by sub-classes that need to know when a click is released. - virtual void onClickRelease() {} - -protected: - - // Draws a label for the component, using its name and a passed value. Does NOT modulate by - // relative height, expects CTM to have been adjusted in advance. - void drawLabel(SkCanvas *canvas, const SkString& valueStr) const { - // TODO Cache this - sk_sp<SkTypeface> fLabelTypeface = - sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle()); - - SkString label; - label.append(fName); - label.append(": "); - label.append(valueStr); - - SkPaint labelPaint; - labelPaint.setTypeface(fLabelTypeface); - labelPaint.setAntiAlias(true); - labelPaint.setColor(0xFFFFFFFF); - labelPaint.setTextSize(12.0f); - - canvas->drawString(label, 0, kLabelHeight - 6.0f, labelPaint); - } - - SkString fName; - ParentControl* fParent; - - static constexpr SkScalar kLabelHeight = 20.0f; - -private: - // Overriden by sub-class to draw component. Do not call directly, drawContent() modulates by - // relative position. - virtual void onDrawContent(SkCanvas *canvas) = 0; - - // Overriden by sub-class to handle clicks. Do not call directly, click() modulates by relative - // position. Return true if holding mouse capture - virtual bool onClick(const SkPoint& clickPos) { return false; } - - // Overriden by sub-classes with controls. Should return true if clickPos lands inside a control - // region, to enable mouse caputre. - virtual bool onIsInCtrlRegion(const SkPoint& clickPos) const { return false; } - - // The position of the control relative to it's parent - SkPoint fRelativePos; -}; - -class ParentControl : public Control { // Interface for all controls that have children -public: - ParentControl(const SkString& name) : INHERITED(name) {} - - // Adds a child - virtual void add(sk_sp<Control> control) = 0; - - // Returns the control's width. Used to propagate width down to components that don't specify it - virtual SkScalar width() const = 0; - -private: - typedef Control INHERITED; -}; - -class ControlPanel : public ParentControl { -public: - - ControlPanel(SkScalar width) - : ParentControl(SkString("ControlPanel")) - , fWidth(width) - , fHeight(0.0f) - , fSelectedControl(-1) {} - - // Width unspecified, expectation is inheritance from parent - ControlPanel() : ControlPanel(-1.0f) {} - - // Use this for introducing clicks on a ControlPanel from outside of the framework. It - // propagates click release or position down the chain. Returns false when click capture is - // being released. - bool inClick(SkView::Click *inClick) { - if (SkView::Click::State::kUp_State == inClick->fState) { - this->onClickRelease(); - return false; - } - return this->click(inClick->fCurr); - } - - // Add children - void add(sk_sp<Control> control) override { - SkASSERT(!fParent); // Validity of parent's relativeY and fHeight depends on immutability - fControls.push_back(control); - control->setParent(this, SkPoint::Make(0.0f, fHeight)); - fHeight += control->height(); - } - - SkScalar width() const override { - return fParent ? fParent->width() : fWidth; // Width inherited from parent if there is one - } - - SkScalar height() const override { - return fHeight; - } - - // Propagate click release to selected control, deselect control - void onClickRelease() override { - if (fSelectedControl >= 0) { - fControls[fSelectedControl]->onClickRelease(); - } - fSelectedControl = -1; - } - - // Propagate onSetParent() down to children, some might need fParent->width() refresh - void onSetParent() override { - for (int i = 0; i < fControls.count(); i++) { - fControls[i]->onSetParent(); - } - } - - // Holds a vertical shelf of controls. Can't be hierarchy root if not given a width value. - static sk_sp<ParentControl> Make() { - return sk_sp<ParentControl>(new ControlPanel()); - } - - // Holds a vertical shelf of controls. Only control that can be hooked from outside the - // framework. - static sk_sp<ParentControl> Make(SkScalar width) { - return sk_sp<ParentControl>(new ControlPanel(width)); - } - -protected: - // Returns true if control panel has mouse captured, false when it is ready to release - // capture - bool onClick(const SkPoint& click) override { - - if (fSelectedControl == -1) { // If no child control selected, check every child - for (int i = 0; i < fControls.count(); i++) { - if (fControls[i]->isInCtrlRegion(click)) { - fSelectedControl = i; - break; - } - } - } - - if (fSelectedControl >= 0) { // If child control selected, propagate click - bool keepSelection = fControls[fSelectedControl]->click(click); - if (!keepSelection) { - fSelectedControl = -1; - } - return keepSelection; - } - - return false; - } - - // Draw all children - void onDrawContent(SkCanvas* canvas) override { - canvas->save(); - for (int i = 0; i < fControls.count(); i++) { - fControls[i]->drawContent(canvas); - } - canvas->restore(); - } - - // Check all children's control regions - bool onIsInCtrlRegion(const SkPoint& clickPos) const override { - for (int i = 0; i < fControls.count(); i++) { - if (fControls[i]->isInCtrlRegion(clickPos)) { - return true; - } - } - - return false; - } - -private: - SkScalar fWidth; - SkScalar fHeight; - - SkTArray<sk_sp<Control>> fControls; - int fSelectedControl; -}; - -class DiscreteSliderControl : public Control { -public: - SkScalar height() const override { - return 2.0f * kLabelHeight; - } - - // Set width-dependant variables when new parent is set - void onSetParent() override { - fCtrlRegion = SkRect::MakeXYWH(0.0f, kLabelHeight, fParent->width(), kSliderHeight); - fSliderRange = fParent->width() - kSliderWidth; - } - - /* Make a slider for an integer value. Snaps to discrete positions. - * - * @params name The name of the control, displayed in the label - * @params output Pointer to the integer that will be set by the slider - * @params min Min value for output. - * @params max Max value for output. - */ - static sk_sp<Control> Make(SkString name, int* output, int min, int max) { - return sk_sp<Control>(new DiscreteSliderControl(name, output, min, max)); - } - -protected: - void onDrawContent(SkCanvas* canvas) override { - SkASSERT(fParent); - int numChoices = fMax - fMin + 1; - fSlider.offsetTo(fSliderRange * ( (*fOutput)/SkIntToScalar(numChoices) - + 1.0f/(2.0f * numChoices) ), - fSlider.fTop); - - SkString valueStr; - valueStr.appendS32(*fOutput); - this->drawLabel(canvas, valueStr); - - SkPaint sliderPaint; - sliderPaint.setColor(0xFFF3F3F3); - canvas->drawRect(fSlider, sliderPaint); - - SkPaint ctrlRegionPaint; - ctrlRegionPaint.setColor(0xFFFFFFFF); - ctrlRegionPaint.setStyle(SkPaint::kStroke_Style); - ctrlRegionPaint.setStrokeWidth(2.0f); - canvas->drawRect(fCtrlRegion, ctrlRegionPaint); - } - - bool onClick(const SkPoint& clickPos) override { - SkASSERT(fParent); - SkScalar x = SkScalarPin(clickPos.fX, 0.0f, fSliderRange); - int numChoices = fMax - fMin + 1; - *fOutput = SkTMin(SkScalarFloorToInt(numChoices * x / fSliderRange) + fMin, fMax); - - return true; - } - - bool onIsInCtrlRegion(const SkPoint& clickPos) const override { - SkASSERT(fParent); - return fCtrlRegion.contains(SkRect::MakeXYWH(clickPos.fX, clickPos.fY, 1, 1)); - } - -private: - DiscreteSliderControl(SkString name, int* output, int min, int max) - : INHERITED(name) - , fOutput(output) - , fMin(min) - , fMax(max) { - fSlider = SkRect::MakeXYWH(0, kLabelHeight, kSliderWidth, kSliderHeight); - } - - int* fOutput; - int fMin; - int fMax; - SkRect fSlider; // The rectangle that slides - // The region in which the rectangle slides. Also the region in which mouse is caputred - SkRect fCtrlRegion; - SkScalar fSliderRange; // The width in pixels over which the slider can slide - - static constexpr SkScalar kSliderHeight = 20.0f; - static constexpr SkScalar kSliderWidth = 10.0f; - - typedef Control INHERITED; -}; - -class ControlSwitcher : public ParentControl { -public: - // Add children - void add(sk_sp<Control> control) override { - SkASSERT(!fParent); // Validity of parent's relativeY and fHeight depends on immutability - fControls.push_back(control); - control->setParent(this, SkPoint::Make(0.0f, kSelectorHeight)); - fHeight = SkMaxScalar(fHeight, control->height()); // Setting height to max child height. - } - - SkScalar width() const override { return fParent ? (fParent->width()) : 0; } - - SkScalar height() const override { - return fHeight; - } - - // Propagate onClickRelease to control that currently captures mouse - void onClickRelease() override { - if (fCtrlOnClick) { - fCtrlOnClick->onClickRelease(); - } - fCtrlOnClick = nullptr; - } - - void onSetParent() override { - for (int i = 0; i < fControls.count(); i++) { - fControls[i]->onSetParent(); // Propagate to children - } - - // Finalize control selector - // TODO can be moved to constructor if list-initialized - if (!finalizedChildren) { - fControlSelector = DiscreteSliderControl::Make( - SkString(fName), &fSelectedControl, 0, fControls.count()-1); - fControlSelector->setParent(this, SkPoint::Make(0.0f, 0.0f)); - fHeight += kSelectorHeight; - - SkASSERT(fControlSelector->height() <= kSelectorHeight); - } - } - - /* A set of a selector and a list of controls. Displays the control from the list of controls - * with the index set by the aforementioned selector. - * - * @param name The name of the switcher. Will be displayed in the selector's label. - */ - static sk_sp<ParentControl> Make(const SkString& name) { - return sk_sp<ParentControl>(new ControlSwitcher(name)); - } - -protected: - // Draw selector and currently selected control - void onDrawContent(SkCanvas* canvas) override { - fControlSelector->drawContent(canvas); - fControls[fSelectedControl]->drawContent(canvas); - } - - // Returns true if control panel has mouse captured, false when it is ready to release - // capture - bool onClick(const SkPoint& click) override { - if (!fCtrlOnClick) { - if (fControlSelector->isInCtrlRegion(click)) { - fCtrlOnClick = fControlSelector.get(); - } else if (fControls[fSelectedControl]->isInCtrlRegion(click)) { - fCtrlOnClick = fControls[fSelectedControl].get(); - } - } - if (fCtrlOnClick) { - return fCtrlOnClick->click(click); - } - - return false; - } - - // Is in control region of selector or currently selected control - bool onIsInCtrlRegion(const SkPoint& clickPos) const override { - if (fControlSelector->isInCtrlRegion(clickPos)) { - return true; - } - if (fControls[fSelectedControl]->isInCtrlRegion(clickPos)) { - return true; - } - - return false; - } - -private: - ControlSwitcher(const SkString& name) - : INHERITED(name) - , fHeight(0.0) - , fSelectedControl(0) - , fCtrlOnClick(nullptr){} - - bool finalizedChildren = false; - - sk_sp<Control> fControlSelector; - SkScalar fHeight; - SkTArray<sk_sp<Control>> fControls; - int fSelectedControl; - - Control* fCtrlOnClick; - - static constexpr SkScalar kSelectorHeight = 40.0f; - - typedef ParentControl INHERITED; -}; - -class ContinuousSliderControl : public Control { -public: - SkScalar height() const override { - return 2.0f * kLabelHeight; - } - - void onSetParent() override { - fSlider = SkRect::MakeXYWH(0, kLabelHeight, kSliderWidth, kSliderHeight); - fCtrlRegion = SkRect::MakeXYWH(0.0f, kLabelHeight, fParent->width(), kSliderHeight); - fSliderRange = fParent->width() - kSliderWidth; - } - - /* Make a slider for an SkScalar. - * - * @params name The name of the control, displayed in the label - * @params output Pointer to the SkScalar that will be set by the slider - * @params min Min value for output - * @params max Max value for output - */ - static sk_sp<Control> Make(const SkString& name, SkScalar* output, SkScalar min, SkScalar max) { - return sk_sp<Control>(new ContinuousSliderControl(name, output, min, max)); - } - -protected: - void onDrawContent(SkCanvas* canvas) override { - SkASSERT(fParent); - SkScalar x = fSliderRange * (*fOutput - fMin) / (fMax - fMin); - fSlider.offsetTo(SkScalarPin(x, 0.0f, fSliderRange), fSlider.fTop); - - SkString valueStr; - valueStr.appendScalar(*fOutput); - this->drawLabel(canvas, valueStr); - - SkPaint sliderPaint; - sliderPaint.setColor(0xFFF3F3F3); - canvas->drawRect(fSlider, sliderPaint); - - SkPaint ctrlRegionPaint; - ctrlRegionPaint.setColor(0xFFFFFFFF); - ctrlRegionPaint.setStyle(SkPaint::kStroke_Style); - ctrlRegionPaint.setStrokeWidth(2.0f); - canvas->drawRect(fCtrlRegion, ctrlRegionPaint); - } - - bool onClick(const SkPoint& clickPos) override { - SkASSERT(fParent); - SkScalar x = SkScalarPin(clickPos.fX, 0.0f, fSliderRange); - *fOutput = (x/fSliderRange) * (fMax - fMin) + fMin; - return true; - } - - bool onIsInCtrlRegion(const SkPoint& clickPos) const override { - SkASSERT(fParent); - return fCtrlRegion.contains(SkRect::MakeXYWH(clickPos.fX, clickPos.fY, 1, 1)); - } - -private: - ContinuousSliderControl(const SkString& name, SkScalar* output, SkScalar min, SkScalar max) - : INHERITED(name) - , fOutput(output) - , fMin(min) - , fMax(max) {} - - SkScalar* fOutput; - SkScalar fMin; - SkScalar fMax; - SkRect fSlider; - SkRect fCtrlRegion; - SkScalar fSliderRange; - - static constexpr SkScalar kSliderHeight = 20.0f; - static constexpr SkScalar kSliderWidth = 10.0f; - - typedef Control INHERITED; -}; - -class RadialDirectionControl : public Control { -public: - SkScalar height() const override { - return kLabelHeight + 2.0f * kRegionRadius; - } - - /* Make a direction selector. - * - * @params name The name of the control, displayed in the label - * @params output Pointer to the SkVector that will be set by the slider - */ - static sk_sp<Control> Make(const SkString& name, SkVector* output) { - return sk_sp<Control>(new RadialDirectionControl(name, output)); - } - -protected: - void onDrawContent(SkCanvas* canvas) override { - SkASSERT(fParent); - - SkString valueStr; - valueStr.appendf("%.2f, %.2f", fOutput->fX, fOutput->fY); - this->drawLabel(canvas, valueStr); - - SkPoint lineEnd = SkPoint::Make(fCtrlRegion.centerX(), fCtrlRegion.centerY()) - + (*fOutput * (kRegionRadius - kCapRadius)); - SkPaint linePaint; - linePaint.setColor(0xFFF3F3F3); - linePaint.setStrokeWidth(kStrokeWidth); - linePaint.setAntiAlias(true); - linePaint.setStrokeCap(SkPaint::kRound_Cap); - canvas->drawLine(fCtrlRegion.centerX(), fCtrlRegion.centerY(), - lineEnd.fX, lineEnd.fY, linePaint); - - SkPaint ctrlRegionPaint; - ctrlRegionPaint.setColor(0xFFFFFFFF); - ctrlRegionPaint.setStyle(SkPaint::kStroke_Style); - ctrlRegionPaint.setStrokeWidth(2.0f); - ctrlRegionPaint.setAntiAlias(true); - canvas->drawCircle(fCtrlRegion.centerX(), fCtrlRegion.centerY(), kRegionRadius, - ctrlRegionPaint); - } - - bool onClick(const SkPoint& clickPos) override { - SkASSERT(fParent); - fOutput->fX = clickPos.fX - fCtrlRegion.centerX(); - fOutput->fY = clickPos.fY - fCtrlRegion.centerY(); - fOutput->normalize(); - - return true; - } - - bool onIsInCtrlRegion(const SkPoint& clickPos) const override { - SkASSERT(fParent); - return fCtrlRegion.contains(SkRect::MakeXYWH(clickPos.fX, clickPos.fY, - 1, 1)); - } - -private: - RadialDirectionControl(const SkString& name, SkVector* output) - : INHERITED(name) - , fOutput(output) { - fCtrlRegion = SkRect::MakeXYWH(0.0f, kLabelHeight, - kRegionRadius * 2.0f, kRegionRadius * 2.0f); - } - - SkVector* fOutput; - SkRect fCtrlRegion; - - static constexpr SkScalar kRegionRadius = 50.0f; - static constexpr SkScalar kStrokeWidth = 6.0f; - static constexpr SkScalar kCapRadius = kStrokeWidth / 2.0f; - - typedef Control INHERITED; -}; - -class ColorDisplay: public Control { -public: - SkScalar height() const override { - return kHeight; - } - - void onSetParent() override { - fDisplayRect = SkRect::MakeXYWH(0.0f, kPadding, fParent->width(), kHeight - kPadding); - } - - /* Make a display that shows an SkColor3f. - * - * @params output Pointer to the SkColor3f that will be displayed - */ - static sk_sp<Control> Make(SkColor3f* input) { - return sk_sp<Control>(new ColorDisplay(SkString("ColorDisplay"), input)); - } - -protected: - void onDrawContent(SkCanvas* canvas) override { - SkASSERT(fParent); - - SkPaint displayPaint; - displayPaint.setColor(SkColor4f::FromColor3f(*fInput, 1.0f).toSkColor()); - canvas->drawRect(fDisplayRect, displayPaint); - } - -private: - ColorDisplay(const SkString& name, SkColor3f* input) - : INHERITED(name) - , fInput(input) {} - - SkColor3f* fInput; - SkRect fDisplayRect; - - static constexpr SkScalar kHeight = 24.0f; - static constexpr SkScalar kPadding = 4.0f; - - typedef Control INHERITED; -}; - -class BevelView : public SampleView { -public: - BevelView() - : fShapeBounds(SkRect::MakeWH(kShapeBoundsSize, kShapeBoundsSize)) - , fControlPanel(kCtrlRange) { - this->setBGColor(0xFF666868); // Slightly colorized gray for contrast - - // Controls - fBevelWidth = 25.0f; - fBevelHeight = 25.0f; - fBevelType = 0; - - int currLight = 0; - fLightDefs[currLight++] = - {SkVector::Make(0.0f, 1.0f), 1.0f, SkColor3f::Make(0.6f, 0.45f, 0.3f)}; - fLightDefs[currLight++] = - {SkVector::Make(0.0f, -1.0f), 1.0f, SkColor3f::Make(0.3f, 0.45f, 0.6f)}; - fLightDefs[currLight++] = - {SkVector::Make(1.0f, 0.0f), 1.0f, SkColor3f::Make(0.0f, 0.0f, 0.0f)}; - // Making sure we initialized all lights - SkASSERT(currLight == kNumLights); - - fControlPanel.add(ContinuousSliderControl::Make(SkString("BevelWidth"), &fBevelWidth, - 1.0f, kShapeBoundsSize)); - fControlPanel.add(ContinuousSliderControl::Make(SkString("BevelHeight"), &fBevelHeight, - -50.0f, 50.0f)); - fControlPanel.add(DiscreteSliderControl::Make(SkString("BevelType"), &fBevelType, - 0, 2)); - sk_sp<ParentControl> lightCtrlSelector = ControlSwitcher::Make(SkString("SelectedLight")); - for (int i = 0; i < kNumLights; i++) { - SkString name("Light"); - name.appendS32(i); - sk_sp<ParentControl> currLightPanel = ControlPanel::Make(); - SkString dirName(name); - dirName.append("Dir"); - currLightPanel->add(RadialDirectionControl::Make(dirName, &(fLightDefs[i].fDirXY))); - SkString heightName(name); - heightName.append("Height"); - currLightPanel->add(ContinuousSliderControl::Make(heightName, &(fLightDefs[i].fDirZ), - 0.0f, 2.0f)); - SkString redName(name); - redName.append("Red"); - currLightPanel->add(ContinuousSliderControl::Make(redName, &(fLightDefs[i].fColor.fX), - 0.0f, 1.0f)); - SkString greenName(name); - greenName.append("Green"); - currLightPanel->add(ContinuousSliderControl::Make(greenName, &(fLightDefs[i].fColor.fY), - 0.0f, 1.0f)); - SkString blueName(name); - blueName.append("Blue"); - currLightPanel->add(ContinuousSliderControl::Make(blueName, &(fLightDefs[i].fColor.fZ), - 0.0f, 1.0f)); - currLightPanel->add(ColorDisplay::Make(&(fLightDefs[i].fColor))); - lightCtrlSelector->add(currLightPanel); - } - fControlPanel.add(lightCtrlSelector); - - fControlPanelSelected = false; - fDirtyNormalSource = true; - - fLabelTypeface = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle()); - } - -protected: - bool onQuery(SkEvent *evt) override { - if (SampleCode::TitleQ(*evt)) { - SampleCode::TitleR(evt, "Bevel"); - return true; - } - - return this->INHERITED::onQuery(evt); - } - - enum Shape { - kCircle_Shape, - kRect_Shape, - }; - void drawShape(enum Shape shape, SkCanvas* canvas) { - canvas->save(); - - SkPaint paint; - - if (fDirtyNormalSource) { - fNormalSource = SkNormalSource::MakeBevel((SkNormalSource::BevelType)fBevelType, - fBevelWidth, fBevelHeight); - fDirtyNormalSource = false; - } - - paint.setShader(SkLightingShader::Make(nullptr, fNormalSource, fLights)); - paint.setAntiAlias(true); - paint.setColor(0xFFDDDDDD); - switch (shape) { - case kCircle_Shape: - canvas->drawCircle(fShapeBounds.centerX(), fShapeBounds.centerY(), - fShapeBounds.width()/2.0f, paint); - break; - case kRect_Shape: - canvas->drawRect(fShapeBounds, paint); - break; - default: - SkDEBUGFAIL("Invalid shape enum for drawShape"); - } - - canvas->restore(); - } - - void onDrawContent(SkCanvas *canvas) override { - - canvas->save(); - canvas->resetMatrix(); // Force static control panel position - fControlPanel.drawContent(canvas); - canvas->restore(); - - SkLights::Builder builder; - for (int i = 0; i < kNumLights; i++) { - builder.add(SkLights::Light::MakeDirectional(fLightDefs[i].fColor, - SkPoint3::Make(fLightDefs[i].fDirXY.fX, - fLightDefs[i].fDirXY.fY, - fLightDefs[i].fDirZ))); - } - builder.setAmbientLightColor(SkColor3f::Make(0.4f, 0.4f, 0.4f)); - fLights = builder.finish(); - - // Draw shapes - SkScalar xPos = kCtrlRange + 25.0f; - SkScalar yPos = fShapeBounds.height(); - for (Shape shape : { kCircle_Shape, kRect_Shape }) { - canvas->save(); - canvas->translate(xPos, yPos); - this->drawShape(shape, canvas); - canvas->restore(); - - xPos += 1.2f * fShapeBounds.width(); - } - } - - SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { - return new SkView::Click(this); - } - - bool onClick(Click *click) override { - // Control panel mouse handling - fControlPanelSelected = fControlPanel.inClick(click); - - if (fControlPanelSelected) { // Control modification - fDirtyNormalSource = true; - - this->inval(nullptr); - return true; - } - - // TODO move shapes - this->inval(nullptr); - return true; - } - -private: - static constexpr int kNumTestRects = 3; - - static constexpr SkScalar kShapeBoundsSize = 120.0f; - - static constexpr SkScalar kCtrlRange = 150.0f; - - static constexpr int kNumLights = 3; - - const SkRect fShapeBounds; - - SkScalar fBevelWidth; - SkScalar fBevelHeight; - int fBevelType; - - sk_sp<SkNormalSource> fNormalSource; - bool fDirtyNormalSource; - - sk_sp<SkLights> fLights; - - struct LightDef { - SkVector fDirXY; - SkScalar fDirZ; - SkColor3f fColor; - - LightDef() {} - LightDef(SkVector dirXY, SkScalar dirZ, SkColor3f color) - : fDirXY(dirXY) - , fDirZ(dirZ) - , fColor(color) {} - }; - LightDef fLightDefs[kNumLights]; - - ControlPanel fControlPanel; - bool fControlPanelSelected; - - sk_sp<SkTypeface> fLabelTypeface; - - typedef SampleView INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -static SkView* MyFactory() { return new BevelView; } -static SkViewRegister reg(MyFactory); - diff --git a/src/core/SkNormalBevelSource.cpp b/src/core/SkNormalBevelSource.cpp deleted file mode 100644 index 0f1305cd15..0000000000 --- a/src/core/SkNormalBevelSource.cpp +++ /dev/null @@ -1,304 +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 "SkNormalBevelSource.h" - -#include "SkArenaAlloc.h" -#include "SkNormalSource.h" -#include "SkNormalSourcePriv.h" -#include "SkPoint3.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" - -#if SK_SUPPORT_GPU -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "SkGr.h" - -/** \class NormalBevelFP - * - * Fragment processor for the SkNormalBevelSource. - * - * @param bevelType type of the bevel - * @param bevelWidth width of the bevel in device space - * @param bevelHeight height of the bevel in device space - */ -class NormalBevelFP : public GrFragmentProcessor { -public: - NormalBevelFP(SkNormalSource::BevelType bevelType, SkScalar bevelWidth, SkScalar bevelHeight) - : INHERITED(kNone_OptimizationFlags) - , fBevelType(bevelType) - , fBevelWidth(bevelWidth) - , fBevelHeight(bevelHeight) { - this->initClassID<NormalBevelFP>(); - - this->setWillUseDistanceVectorField(); - } - - class GLSLNormalBevelFP : public GLSLNormalFP { - public: - GLSLNormalBevelFP() { - fPrevWidth = SkFloatToScalar(0.0f); - fPrevHeight = SkFloatToScalar(0.0f); - } - - void onEmitCode(EmitArgs& args) override { - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - const NormalBevelFP& fp = args.fFp.cast<NormalBevelFP>(); - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - - // Determining necessary uniforms and initializing them - bool needWidth = true; - bool needHeight = (fp.fBevelType == SkNormalSource::BevelType::kRoundedOut || - fp.fBevelType == SkNormalSource::BevelType::kRoundedIn); - bool needNormalized = (fp.fBevelType == SkNormalSource::BevelType::kLinear); - - const char *widthUniName = nullptr; - if (needWidth) { - fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, - kDefault_GrSLPrecision, "Width", - &widthUniName); - } - - const char* heightUniName = nullptr; - if (needHeight) { - fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, - kDefault_GrSLPrecision, "Height", - &heightUniName); - } - - const char* normalizedWidthUniName = nullptr; - const char* normalizedHeightUniName = nullptr; - if (needNormalized) { - fNormalizedWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, - kDefault_GrSLPrecision, - "NormalizedWidth", - &normalizedWidthUniName); - fNormalizedHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, - kDefault_GrSLPrecision, - "NormalizedHeight", - &normalizedHeightUniName); - } - - // Here we are splitting the distance vector into length and normalized direction - fragBuilder->codeAppendf("float dv_length = %s.z;", - fragBuilder->distanceVectorName()); - fragBuilder->codeAppendf("vec2 dv_norm = %s.xy;", - fragBuilder->distanceVectorName()); - - // Asserting presence of necessary uniforms - SkASSERT(widthUniName); - - fragBuilder->codeAppend( "vec3 normal;"); - fragBuilder->codeAppendf("if (dv_length >= %s) {", widthUniName); - fragBuilder->codeAppend( " normal = vec3(0.0, 0.0, 1.0);"); - fragBuilder->codeAppend( "} else {"); - this->emitMath(fragBuilder, fp.fBevelType, widthUniName, heightUniName, - normalizedWidthUniName, normalizedHeightUniName); - fragBuilder->codeAppend( "}"); - fragBuilder->codeAppendf("%s = vec4(normal, 0.0);", args.fOutputColor); - } - - static void GenKey(const GrProcessor& proc, const GrShaderCaps&, GrProcessorKeyBuilder* b) { - const NormalBevelFP& fp = proc.cast<NormalBevelFP>(); - b->add32(static_cast<int>(fp.fBevelType)); - } - - protected: - void setNormalData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& proc) override { - const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>(); - - // Updating uniform if bevel type requires it and data has changed - - bool needWidth = true; - bool needHeight = (normalBevelFP.fBevelType == SkNormalSource::BevelType::kRoundedOut || - normalBevelFP.fBevelType == SkNormalSource::BevelType::kRoundedIn); - bool needNormalized = (normalBevelFP.fBevelType == SkNormalSource::BevelType::kLinear); - - bool dirtyWidth = (fPrevWidth != normalBevelFP.fBevelWidth); - bool dirtyHeight = (fPrevHeight != normalBevelFP.fBevelHeight); - bool dirtyNormalized = (dirtyHeight || dirtyWidth); - - - if (needWidth && dirtyWidth) { - pdman.set1f(fWidthUni, normalBevelFP.fBevelWidth); - fPrevWidth = normalBevelFP.fBevelWidth; - } - if (needHeight && dirtyHeight) { - pdman.set1f(fHeightUni, normalBevelFP.fBevelHeight); - fPrevHeight = normalBevelFP.fBevelHeight; - } - if (needNormalized && dirtyNormalized) { - SkScalar height = normalBevelFP.fBevelHeight; - SkScalar width = normalBevelFP.fBevelWidth; - - SkScalar length = SkScalarSqrt(SkScalarSquare(height) + SkScalarSquare(width)); - pdman.set1f(fNormalizedHeightUni, height/length); - pdman.set1f(fNormalizedWidthUni, width/length); - } - } - - // This method emits the code that calculates the normal orthgonal to the simulated beveled - // surface. In the comments inside the function, the math involved is described. For this - // purpose, the d-axis is defined to be the axis co-linear to the distance vector, where the - // origin is the end of the bevel inside the shape. - void emitMath(GrGLSLFPFragmentBuilder* fb, SkNormalSource::BevelType type, - const char* width, const char* height, const char* normalizedWidth, - const char* normalizedHeight) { - switch (type) { - case SkNormalSource::BevelType::kLinear: - // Asserting presence of necessary uniforms - SkASSERT(normalizedHeight); - SkASSERT(normalizedWidth); - - // Because the slope of the bevel is -height/width, the vector - // normalized(vec2(height, width)) is the d- and z-components of the normal - // vector that is orthogonal to the linear bevel. Multiplying the d-component - // to the normalized distance vector splits it into x- and y-components. - fb->codeAppendf("normal = vec3(%s * dv_norm, %s);", - normalizedHeight, normalizedWidth); - break; - case SkNormalSource::BevelType::kRoundedOut: - // Fall through - case SkNormalSource::BevelType::kRoundedIn: - // Asserting presence of necessary uniforms - SkASSERT(height); - SkASSERT(width); - - // Setting the current position in the d-axis to the distance from the end of - // the bevel as opposed to the beginning if the bevel is rounded in, essentially - // flipping the bevel calculations. - if ( type == SkNormalSource::BevelType::kRoundedIn ) { - fb->codeAppendf("float currentPos_d = %s - dv_length;", width); - } else if (type == SkNormalSource::BevelType::kRoundedOut) { - fb->codeAppendf("float currentPos_d = dv_length;"); - } - - fb->codeAppendf("float rootDOverW = sqrt(currentPos_d/%s);", width); - - // Calculating the d- and z-components of the normal, where 'd' is the axis - // co-linear to the distance vector. Equation was derived from the formula for - // a bezier curve by solving the parametric equation for d(t) and z(t), then - // with those, calculate d'(t), z'(t) and t(d), and from these, d'(d) and z'(d). - // z'(d)/d'(d) results in the slope of the bevel at d, so we construct an - // orthogonal vector of slope -d'(d)/z'(d) and length 1. - fb->codeAppendf("vec2 unnormalizedNormal_dz = vec2(%s*(1.0-rootDOverW), " - "%s*rootDOverW);", - height, width); - fb->codeAppendf("vec2 normal_dz = normalize(unnormalizedNormal_dz);"); - - // Multiplying the d-component to the normalized distance vector splits it into - // x- and y-components. - fb->codeAppendf("normal = vec3(normal_dz.x*dv_norm, normal_dz.y);"); - - break; - default: - SkDEBUGFAIL("Invalid bevel type passed to emitMath"); - } - } - - private: - SkScalar fPrevWidth; - GrGLSLProgramDataManager::UniformHandle fWidthUni; - - SkScalar fPrevHeight; - GrGLSLProgramDataManager::UniformHandle fHeightUni; - - // width / length(<width,height>) - GrGLSLProgramDataManager::UniformHandle fNormalizedWidthUni; - // height / length(<width,height>) - GrGLSLProgramDataManager::UniformHandle fNormalizedHeightUni; - }; - - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { - GLSLNormalBevelFP::GenKey(*this, caps, b); - } - - const char* name() const override { return "NormalBevelFP"; } - -private: - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLNormalBevelFP; } - - bool onIsEqual(const GrFragmentProcessor& proc) const override { - const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>(); - return fBevelType == normalBevelFP.fBevelType && - fBevelWidth == normalBevelFP.fBevelWidth && - fBevelHeight == normalBevelFP.fBevelHeight; - } - - SkNormalSource::BevelType fBevelType; - SkScalar fBevelWidth; - SkScalar fBevelHeight; - - typedef GrFragmentProcessor INHERITED; -}; - -sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor( - const SkShaderBase::AsFPArgs& args) const { - - // This assumes a uniform scale. Anisotropic scaling might not be handled gracefully. - SkScalar maxScale = args.fViewMatrix->getMaxScale(); - - // Providing device-space width and height - return sk_make_sp<NormalBevelFP>(fType, maxScale * fWidth, maxScale * fHeight); -} - -#endif // SK_SUPPORT_GPU - -//////////////////////////////////////////////////////////////////////////// - -SkNormalBevelSourceImpl::Provider::Provider() {} - -SkNormalBevelSourceImpl::Provider::~Provider() {} - -SkNormalSource::Provider* SkNormalBevelSourceImpl::asProvider(const SkShaderBase::ContextRec &rec, - SkArenaAlloc* alloc) const { - return alloc->make<Provider>(); -} - -// TODO Implement feature for the CPU pipeline -void SkNormalBevelSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[], - int count) const { - for (int i = 0; i < count; i++) { - output[i] = {0.0f, 0.0f, 1.0f}; - } -} - -//////////////////////////////////////////////////////////////////////////////// - -sk_sp<SkFlattenable> SkNormalBevelSourceImpl::CreateProc(SkReadBuffer& buf) { - - auto type = static_cast<SkNormalSource::BevelType>(buf.readInt()); - SkScalar width = buf.readScalar(); - SkScalar height = buf.readScalar(); - - return sk_make_sp<SkNormalBevelSourceImpl>(type, width, height); -} - -void SkNormalBevelSourceImpl::flatten(SkWriteBuffer& buf) const { - this->INHERITED::flatten(buf); - - buf.writeInt(static_cast<int>(fType)); - buf.writeScalar(fWidth); - buf.writeScalar(fHeight); -} - -//////////////////////////////////////////////////////////////////////////// - -sk_sp<SkNormalSource> SkNormalSource::MakeBevel(BevelType type, SkScalar width, SkScalar height) { - /* TODO make sure these checks are tolerant enough to account for loss of conversion when GPUs - use 16-bit float types. We don't want to assume stuff is non-zero on the GPU and be wrong.*/ - SkASSERT(width > 0.0f && !SkScalarNearlyZero(width)); - if (SkScalarNearlyZero(height)) { - return SkNormalSource::MakeFlat(); - } - - return sk_make_sp<SkNormalBevelSourceImpl>(type, width, height); -} diff --git a/src/core/SkNormalBevelSource.h b/src/core/SkNormalBevelSource.h deleted file mode 100644 index 1e06303879..0000000000 --- a/src/core/SkNormalBevelSource.h +++ /dev/null @@ -1,56 +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 SkNormalBevelSource_DEFINED -#define SkNormalBevelSource_DEFINED - -#include "SkNormalSource.h" - -class SK_API SkNormalBevelSourceImpl : public SkNormalSource { -public: - SkNormalBevelSourceImpl(BevelType type, SkScalar width, SkScalar height) - : fType(type) - , fWidth(width) - , fHeight(height) {} - -#if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override; -#endif - - SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec, - SkArenaAlloc*) const override; - - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalBevelSourceImpl) - -protected: - void flatten(SkWriteBuffer& buf) const override; - -private: - class Provider : public SkNormalSource::Provider { - public: - Provider(); - - ~Provider() override; - - void fillScanLine(int x, int y, SkPoint3 output[], int count) const override; - - private: - typedef SkNormalSource::Provider INHERITED; - - }; - - SkNormalSource::BevelType fType; - SkScalar fWidth; - SkScalar fHeight; - - friend class SkNormalSource; - - typedef SkNormalSource INHERITED; -}; - - -#endif diff --git a/src/core/SkNormalFlatSource.cpp b/src/core/SkNormalFlatSource.cpp index 922ad15e92..c7cde03a62 100644 --- a/src/core/SkNormalFlatSource.cpp +++ b/src/core/SkNormalFlatSource.cpp @@ -9,7 +9,6 @@ #include "SkArenaAlloc.h" #include "SkNormalSource.h" -#include "SkNormalSourcePriv.h" #include "SkPoint3.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" @@ -24,30 +23,24 @@ public: this->initClassID<NormalFlatFP>(); } - class GLSLNormalFlatFP : public GLSLNormalFP { + class GLSLNormalFlatFP : public GrGLSLFragmentProcessor { public: GLSLNormalFlatFP() {} - void onEmitCode(EmitArgs& args) override { + void emitCode(EmitArgs& args) override { GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor); } - static void GenKey(const GrProcessor& proc, const GrShaderCaps&, GrProcessorKeyBuilder* b) { - b->add32(0x0); - } - - protected: - void setNormalData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override {} + private: + void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override {} }; const char* name() const override { return "NormalFlatFP"; } private: - void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { - GLSLNormalFlatFP::GenKey(*this, caps, b); - } + void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {} GrColor4f constantOutputForConstantInput(GrColor4f) const override { return GrColor4f(0, 0, 1, 0); diff --git a/src/core/SkNormalMapSource.cpp b/src/core/SkNormalMapSource.cpp index f655b687d6..741db66e64 100644 --- a/src/core/SkNormalMapSource.cpp +++ b/src/core/SkNormalMapSource.cpp @@ -11,7 +11,6 @@ #include "SkLightingShader.h" #include "SkMatrix.h" #include "SkNormalSource.h" -#include "SkNormalSourcePriv.h" #include "SkPM4f.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" @@ -32,12 +31,12 @@ public: this->initClassID<NormalMapFP>(); } - class GLSLNormalMapFP : public GLSLNormalFP { + class GLSLNormalMapFP : public GrGLSLFragmentProcessor { public: GLSLNormalMapFP() : fColumnMajorInvCTM22{0.0f} {} - void onEmitCode(EmitArgs& args) override { + void emitCode(EmitArgs& args) override { GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; @@ -77,9 +76,9 @@ public: b->add32(0x0); } - protected: - void setNormalData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& proc) override { + private: + void onSetData(const GrGLSLProgramDataManager& pdman, + const GrFragmentProcessor& proc) override { const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); const SkMatrix& invCTM = normalMapFP.invCTM(); diff --git a/src/core/SkNormalSource.cpp b/src/core/SkNormalSource.cpp index 2bea7baf6f..ad1f5a3e40 100644 --- a/src/core/SkNormalSource.cpp +++ b/src/core/SkNormalSource.cpp @@ -5,7 +5,6 @@ * found in the LICENSE file. */ -#include "SkNormalBevelSource.h" #include "SkNormalFlatSource.h" #include "SkNormalMapSource.h" #include "SkNormalSource.h" @@ -18,7 +17,6 @@ SkNormalSource::~SkNormalSource() {} SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkNormalSource) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalMapSourceImpl) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalFlatSourceImpl) -SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNormalBevelSourceImpl) SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END //////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkNormalSource.h b/src/core/SkNormalSource.h index 54d44d410a..e9879feb70 100644 --- a/src/core/SkNormalSource.h +++ b/src/core/SkNormalSource.h @@ -68,54 +68,6 @@ public: */ static sk_sp<SkNormalSource> MakeFlat(); - /** This enum specifies the shape of the bevel. All bevels output <0, 0, 1> as the surface - * normal for any point more than 'width' away from any edge. - * - * Mathematical details: - * For the purpose of describing the shape of the bevel, we define 'w' to be the given width of - * the bevel, and 'h' to be the given height. We will assume the shape is rotated such that the - * point being shaded as well as the closest point in the shape's edge to that point are in the - * x-axis, and the shape is translated so that the aforementioned point in the edge is at - * coordinates (w, 0, 0) and the end of the bevel is at (0, 0, h). - * - */ - enum class BevelType { - /* This bevel simulates a surface that is slanted from the shape's edges inwards, linearly. - * - * Mathematical details: - * This bevel follows a straight line from (w, 0, 0) to (0, 0, h). - */ - kLinear, - /* This bevel simulates a surface that rounds off at the shape's edges, smoothly becoming - * perpendicular to the x-y plane. - * - * Mathematical details: - * This bevel follows the only quadratic bezier curve whose start point is at (w, 0, 0), - * control point is at (w, 0, h), and end point is at (0, 0, h). - */ - kRoundedOut, - /* This bevel simulates a surface that sharply becomes perpendicular to the x-y plane when - * at 'width' units from the nearest edge, and then rounds off towards the shape's - * edge, smoothly becoming parallel to the x-y plane. - * - * Mathematical details: - * This bevel follows the only quadratic bezier curve whose start point is at (w, 0, 0), - * control point is at (0, 0, 0), and end point is at (0, 0, h). - */ - kRoundedIn - }; - - /** Returns a normal source that generates a bevel for the shape being drawn. Currently this is - not implemented on CPU rendering. On GPU this currently only works for anti-aliased circles - and rectangles. - - @param type the type of bevel to add. - @param width the width of the bevel, in source space. Must be positive. - @param height the height of the plateau, in source space. Can be positive, negative, - or zero. A negative height means the simulated bevels slope downwards. - */ - static sk_sp<SkNormalSource> MakeBevel(BevelType, SkScalar width, SkScalar height); - SK_DEFINE_FLATTENABLE_TYPE(SkNormalSource) SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() }; diff --git a/src/core/SkNormalSourcePriv.h b/src/core/SkNormalSourcePriv.h deleted file mode 100644 index d508bed841..0000000000 --- a/src/core/SkNormalSourcePriv.h +++ /dev/null @@ -1,58 +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 SkNormalSourcePriv_DEFINED -#define SkNormalSourcePriv_DEFINED - -#if SK_SUPPORT_GPU -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" - -/* GLSLFragmentProcessors for NormalSourceImpls must sub-class this class and override onEmitCode, - * and setNormalData calls, as well as all other calls FPs normally override, except for the 2 - * defined in this superclass. - * This class exists to intercept emitCode calls and emit <0, 0, 1> if the FP requires a distance - * vector but the GP doesn't provide it. onSetData calls need to be intercepted too because - * uniform handlers will be invalid in subclasses where onEmitCode isn't called. - * We don't need to adjust the key here since the use of a given GP (through its class ID already in - * the key), will determine what code gets emitted here. - */ -class GLSLNormalFP : public GrGLSLFragmentProcessor { -public: - GLSLNormalFP() - : fDidIntercept(false) {} - - void emitCode(EmitArgs& args) final override { - if (args.fFp.usesDistanceVectorField() && !args.fGpImplementsDistanceVector) { - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - fragBuilder->codeAppendf("// GLSLNormalFP intercepted emitCode call, GP does not " - "implement required distance vector feature\n"); - fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor); - - fDidIntercept = true; - } else { - this->onEmitCode(args); - } - } - - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& proc) final override { - if (!fDidIntercept) { - this->setNormalData(pdman, proc); - } - } - -protected: - virtual void onEmitCode(EmitArgs& args) = 0; - virtual void setNormalData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) = 0; - -private: - bool fDidIntercept; -}; -#endif - -#endif diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 70de1650ed..d69b34d94d 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -81,9 +81,6 @@ int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child if (child->usesLocalCoords()) { fFlags |= kUsesLocalCoords_Flag; } - if (child->usesDistanceVectorField()) { - fFlags |= kUsesDistanceVectorField_Flag; - } int index = fChildProcessors.count(); fChildProcessors.push_back(child.release()); diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h index ec8f317381..a4b28c21c0 100644 --- a/src/gpu/GrFragmentProcessor.h +++ b/src/gpu/GrFragmentProcessor.h @@ -114,11 +114,6 @@ public: /** Do any of the coordtransforms for this processor require local coords? */ bool usesLocalCoords() const { return SkToBool(fFlags & kUsesLocalCoords_Flag); } - /** Does this FP need a vector to the nearest edge? */ - bool usesDistanceVectorField() const { - return SkToBool(fFlags & kUsesDistanceVectorField_Flag); - } - /** * A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color * output under the following scenario: @@ -295,12 +290,6 @@ protected: */ int registerChildProcessor(sk_sp<GrFragmentProcessor> child); - /** - * Sub-classes should call this in their constructors if they need access to a distance - * vector field to the nearest edge - */ - void setWillUseDistanceVectorField() { fFlags |= kUsesDistanceVectorField_Flag; } - private: void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); } void removeRefs() const override { GrResourceIOProcessor::removeRefs(); } @@ -334,7 +323,6 @@ private: enum PrivateFlags { kFirstPrivateFlag = kAll_OptimizationFlags + 1, kUsesLocalCoords_Flag = kFirstPrivateFlag, - kUsesDistanceVectorField_Flag = kFirstPrivateFlag << 1, }; mutable uint32_t fFlags = 0; diff --git a/src/gpu/GrPaint.h b/src/gpu/GrPaint.h index 6fe561ab33..e2b494ff6f 100644 --- a/src/gpu/GrPaint.h +++ b/src/gpu/GrPaint.h @@ -70,11 +70,6 @@ public: bool getAllowSRGBInputs() const { return fAllowSRGBInputs; } /** - * Does one of the fragment processors need a field of distance vectors to the nearest edge? - */ - bool usesDistanceVectorField() const { return fUsesDistanceVectorField; } - - /** * Should rendering be gamma-correct, end-to-end. Causes sRGB render targets to behave * as such (with linear blending), and sRGB inputs to be filtered and decoded correctly. */ @@ -97,7 +92,6 @@ public: */ void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> fp) { SkASSERT(fp); - fUsesDistanceVectorField |= fp->usesDistanceVectorField(); fColorFragmentProcessors.push_back(std::move(fp)); fTrivial = false; } @@ -107,7 +101,6 @@ public: */ void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> fp) { SkASSERT(fp); - fUsesDistanceVectorField |= fp->usesDistanceVectorField(); fCoverageFragmentProcessors.push_back(std::move(fp)); fTrivial = false; } @@ -182,7 +175,6 @@ private: SkSTArray<2, sk_sp<GrFragmentProcessor>> fCoverageFragmentProcessors; bool fDisableOutputConversionToSRGB = false; bool fAllowSRGBInputs = false; - bool fUsesDistanceVectorField = false; bool fTrivial = true; GrColor4f fColor = GrColor4f::OpaqueWhite(); }; diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index 394d545242..8d1b926be1 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -33,9 +33,6 @@ void GrPipeline::init(const InitArgs& args) { } fWindowRectsState = args.fAppliedClip->windowRectsState(); } - if (args.fProcessors->usesDistanceVectorField()) { - fFlags |= kUsesDistanceVectorField_Flag; - } if (!args.fUserStencil->isDisabled(fFlags & kHasStencilClip_Flag)) { fFlags |= kStencilEnabled_Flag; } diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h index 4f2f010188..078cb68437 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -212,9 +212,6 @@ public: bool getAllowSRGBInputs() const { return SkToBool(fFlags & kAllowSRGBInputs_Flag); } - bool usesDistanceVectorField() const { - return SkToBool(fFlags & kUsesDistanceVectorField_Flag); - } bool hasStencilClip() const { return SkToBool(fFlags & kHasStencilClip_Flag); } @@ -236,10 +233,9 @@ private: /** This is a continuation of the public "Flags" enum. */ enum PrivateFlags { - kUsesDistanceVectorField_Flag = 0x10, - kHasStencilClip_Flag = 0x20, - kStencilEnabled_Flag = 0x40, - kIsBad_Flag = 0x80, + kHasStencilClip_Flag = 0x10, + kStencilEnabled_Flag = 0x20, + kIsBad_Flag = 0x40, }; using RenderTarget = GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>; diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h index 63265f02a6..3b90689aca 100644 --- a/src/gpu/GrPrimitiveProcessor.h +++ b/src/gpu/GrPrimitiveProcessor.h @@ -114,10 +114,6 @@ public: return 0.0; } - /* Sub-class should override and return true if this primitive processor implements the distance - * vector field, a field of vectors to the nearest point in the edge of the shape. */ - virtual bool implementsDistanceVector() const { return false; } - protected: /** * Subclasses call these from their constructor to register vertex and instance attributes. diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp index 22fa63589f..01de53d94d 100644 --- a/src/gpu/GrProcessorSet.cpp +++ b/src/gpu/GrProcessorSet.cpp @@ -28,9 +28,6 @@ GrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) { for (auto& fp : paint.fCoverageFragmentProcessors) { fFragmentProcessors[i++] = fp.release(); } - if (paint.usesDistanceVectorField()) { - fFlags |= kUseDistanceVectorField_Flag; - } } else { SkDebugf("Insane number of color fragment processors in paint. Dropping all processors."); fColorFragmentProcessorCnt = 0; diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h index b13175ab10..d7cecedc47 100644 --- a/src/gpu/GrProcessorSet.h +++ b/src/gpu/GrProcessorSet.h @@ -52,8 +52,6 @@ public: return sk_ref_sp(fXP.fProcessor); } - bool usesDistanceVectorField() const { return SkToBool(fFlags & kUseDistanceVectorField_Flag); } - /** Comparisons are only legal on finalized processor sets. */ bool operator==(const GrProcessorSet& that) const; bool operator!=(const GrProcessorSet& that) const { return !(*this == that); } @@ -143,7 +141,7 @@ private: // This absurdly large limit allows Analysis and this to pack fields together. static constexpr int kMaxColorProcessors = UINT8_MAX; - enum Flags : uint16_t { kUseDistanceVectorField_Flag = 0x1, kFinalized_Flag = 0x2 }; + enum Flags : uint16_t { kFinalized_Flag = 0x1 }; union XP { XP(const GrXPFactory* factory) : fFactory(factory) {} diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index c72c4d1d6f..0bbfbf65b3 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -929,7 +929,6 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip, if (GrAAType::kCoverage == aaType) { const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeRRectOp(std::move(paint), - paint.usesDistanceVectorField(), viewMatrix, rrect, stroke, diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp index a37c173c0b..1996a942c2 100644 --- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp +++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp @@ -21,17 +21,8 @@ public: GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; fragBuilder->codeAppendf("vec4 color = %s;", args.fInputColor); - if (!args.fGpImplementsDistanceVector) { - fragBuilder->codeAppendf("// assuming interpolant is set in vertex colors\n"); - fragBuilder->codeAppendf("float factor = 1.0 - color.a;"); - } else { - fragBuilder->codeAppendf("// using distance to edge to compute interpolant\n"); - fragBuilder->codeAppend("float radius = color.r*256.0*64.0 + color.g*64.0;"); - fragBuilder->codeAppend("float pad = color.b*64.0;"); - - fragBuilder->codeAppendf("float factor = 1.0 - clamp((%s.z - pad)/radius, 0.0, 1.0);", - fragBuilder->distanceVectorName()); - } + fragBuilder->codeAppendf("// assuming interpolant is set in vertex colors\n"); + fragBuilder->codeAppendf("float factor = 1.0 - color.a;"); switch (mode) { case GrBlurredEdgeFP::kGaussian_Mode: fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;"); diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h index d0864ed864..cfcc17adaf 100644 --- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h +++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h @@ -46,9 +46,6 @@ private: GrBlurredEdgeFP(Mode mode) : INHERITED(kNone_OptimizationFlags) , fMode(mode) { - // enable output of distance information for shape - this->setWillUseDistanceVectorField(); - this->initClassID<GrBlurredEdgeFP>(); } diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp index 28e5a211a8..006fe587f7 100644 --- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp +++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp @@ -59,8 +59,7 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu coordVars, textureSamplers, texelBuffers, - imageStorages, - args.fGpImplementsDistanceVector); + imageStorages); this->childProcessor(childIndex)->emitCode(childArgs); fragBuilder->codeAppend("}\n"); diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h index fe7775a9c4..355d490225 100644 --- a/src/gpu/glsl/GrGLSLFragmentProcessor.h +++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h @@ -105,9 +105,6 @@ public: @param imageStorages Contains one entry for each ImageStorageAccess of the GrProcessor. These can be passed to the builder to emit image loads and stores in the generated code. - @param gpImplementsDistanceVector - Does the GrGeometryProcessor implement the feature where it - provides a vector to the nearest edge of the shape being rendered. */ struct EmitArgs { EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder, @@ -119,19 +116,17 @@ public: const TransformedCoordVars& transformedCoordVars, const TextureSamplers& textureSamplers, const TexelBuffers& texelBuffers, - const ImageStorages& imageStorages, - bool gpImplementsDistanceVector) - : fFragBuilder(fragBuilder) - , fUniformHandler(uniformHandler) - , fShaderCaps(caps) - , fFp(fp) - , fOutputColor(outputColor) - , fInputColor(inputColor) - , fTransformedCoords(transformedCoordVars) - , fTexSamplers(textureSamplers) - , fTexelBuffers(texelBuffers) - , fImageStorages(imageStorages) - , fGpImplementsDistanceVector(gpImplementsDistanceVector) {} + const ImageStorages& imageStorages) + : fFragBuilder(fragBuilder) + , fUniformHandler(uniformHandler) + , fShaderCaps(caps) + , fFp(fp) + , fOutputColor(outputColor) + , fInputColor(inputColor) + , fTransformedCoords(transformedCoordVars) + , fTexSamplers(textureSamplers) + , fTexelBuffers(texelBuffers) + , fImageStorages(imageStorages) {} GrGLSLFPFragmentBuilder* fFragBuilder; GrGLSLUniformHandler* fUniformHandler; const GrShaderCaps* fShaderCaps; @@ -142,7 +137,6 @@ public: const TextureSamplers& fTexSamplers; const TexelBuffers& fTexelBuffers; const ImageStorages& fImageStorages; - bool fGpImplementsDistanceVector; }; virtual void emitCode(EmitArgs&) = 0; diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp index 484bd78211..4fd886b4fb 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp @@ -124,10 +124,6 @@ SkString GrGLSLFragmentShaderBuilder::ensureCoords2D(const GrShaderVar& coords) return coords2D; } -const char* GrGLSLFragmentShaderBuilder::distanceVectorName() const { - return "fsDistanceVector"; -} - void GrGLSLFragmentShaderBuilder::appendOffsetToSample(const char* sampleIdx, Coordinates coords) { SkASSERT(fProgramBuilder->header().fSamplePatternKey); SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kSampleLocations_RequiredFeature); diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h index 65bcb8dae6..73fe51f171 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h @@ -89,10 +89,6 @@ public: */ virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0; - /** Returns a variable name that represents a vector to the nearest edge of the shape, in source - space coordinates. */ - virtual const char* distanceVectorName() const = 0; - /** * Overrides the default precision for the entire fragment program. Processors that require * high precision input (eg from incoming texture samples) may use this. For calculations that @@ -168,7 +164,6 @@ public: // Shared GrGLSLFragmentBuilder interface. bool enableFeature(GLSLFeature) override; virtual SkString ensureCoords2D(const GrShaderVar&) override; - const char* distanceVectorName() const override; // GrGLSLFPFragmentBuilder interface. void appendOffsetToSample(const char* sampleIdx, Coordinates) override; @@ -239,7 +234,6 @@ private: bool fHasSecondaryOutput; uint8_t fUsedSampleOffsetArrays; bool fHasInitializedSampleMask; - SkString fDistanceVectorOutput; GrSLPrecision fDefaultPrecision; #ifdef SK_DEBUG diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h index 2443f4745e..c4f3115f5a 100644 --- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h +++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h @@ -75,7 +75,6 @@ public: const GrPrimitiveProcessor& gp, const char* outputColor, const char* outputCoverage, - const char* distanceVectorName, const char* rtAdjustName, const SamplerHandle* texSamplers, const TexelBufferHandle* texelBuffers, @@ -90,7 +89,6 @@ public: , fGP(gp) , fOutputColor(outputColor) , fOutputCoverage(outputCoverage) - , fDistanceVectorName(distanceVectorName) , fRTAdjustName(rtAdjustName) , fTexSamplers(texSamplers) , fTexelBuffers(texelBuffers) @@ -105,7 +103,6 @@ public: const GrPrimitiveProcessor& fGP; const char* fOutputColor; const char* fOutputCoverage; - const char* fDistanceVectorName; const char* fRTAdjustName; const SamplerHandle* fTexSamplers; const TexelBufferHandle* fTexelBuffers; diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp index 337ee6d0ea..0d87c4f5a2 100644 --- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp +++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp @@ -76,17 +76,6 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr this->nameExpression(outputColor, "outputColor"); this->nameExpression(outputCoverage, "outputCoverage"); - const char* distanceVectorName = nullptr; - if (this->fPipeline.usesDistanceVectorField() && proc.implementsDistanceVector()) { - // Each individual user (FP) of the distance vector must be able to handle having this - // variable be undeclared. There is no single default value that will yield a reasonable - // result for all users. - distanceVectorName = fFS.distanceVectorName(); - fFS.codeAppend( "// Normalized vector to the closest geometric edge (in device space)\n"); - fFS.codeAppend( "// Distance to the edge encoded in the z-component\n"); - fFS.codeAppendf("vec4 %s;", distanceVectorName); - } - SkASSERT(!fUniformHandles.fRTAdjustmentUni.isValid()); GrShaderFlags rtAdjustVisibility = kVertex_GrShaderFlag; if (proc.willUseGeoShader()) { @@ -124,7 +113,6 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr proc, outputColor->c_str(), outputCoverage->c_str(), - distanceVectorName, rtAdjustName, texSamplers.begin(), texelBuffers.begin(), @@ -199,8 +187,7 @@ SkString GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& coords, textureSamplers, texelBuffers, - imageStorages, - this->primitiveProcessor().implementsDistanceVector()); + imageStorages); fragProc->emitCode(args); diff --git a/src/gpu/ops/GrAnalyticRectOp.cpp b/src/gpu/ops/GrAnalyticRectOp.cpp index 358b5622e3..f62f0c628e 100644 --- a/src/gpu/ops/GrAnalyticRectOp.cpp +++ b/src/gpu/ops/GrAnalyticRectOp.cpp @@ -60,8 +60,6 @@ public: fInWidthHeight = &this->addVertexAttrib("inWidthHeight", kVec2f_GrVertexAttribType); } - bool implementsDistanceVector() const override { return true; } - const Attribute* inPosition() const { return fInPosition; } const Attribute* inColor() const { return fInColor; } const Attribute* inRectEdge() const { return fInRectEdge; } @@ -141,46 +139,17 @@ public: fragBuilder->codeAppendf("float perpDot = abs(offset.x * %s.w - offset.y * %s.z);", rectEdgeVary.fsIn(), rectEdgeVary.fsIn()); - if (args.fDistanceVectorName) { - fragBuilder->codeAppendf("float widthDistance = %s.x - perpDot;", - widthHeightVary.fsIn()); - } - fragBuilder->codeAppendf( "float coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);", widthHeightVary.fsIn()); // Compute the coverage for the rect's height and merge with the width fragBuilder->codeAppendf("perpDot = abs(dot(offset, %s.zw));", rectEdgeVary.fsIn()); - if (args.fDistanceVectorName) { - fragBuilder->codeAppendf("float heightDistance = %s.y - perpDot;", - widthHeightVary.fsIn()); - } - fragBuilder->codeAppendf( "coverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);", widthHeightVary.fsIn()); fragBuilder->codeAppendf("%s = vec4(coverage);", args.fOutputCoverage); - - if (args.fDistanceVectorName) { - fragBuilder->codeAppend("// Calculating distance vector\n"); - fragBuilder->codeAppend("vec2 dvAxis;"); - fragBuilder->codeAppend("float dvLength;"); - - fragBuilder->codeAppend("if (heightDistance < widthDistance) {"); - fragBuilder->codeAppendf(" dvAxis = %s.zw;", rectEdgeVary.fsIn()); - fragBuilder->codeAppend(" dvLength = heightDistance;"); - fragBuilder->codeAppend("} else {"); - fragBuilder->codeAppendf(" dvAxis = vec2(-%s.w, %s.z);", rectEdgeVary.fsIn(), - rectEdgeVary.fsIn()); - fragBuilder->codeAppend(" dvLength = widthDistance;"); - fragBuilder->codeAppend("}"); - - fragBuilder->codeAppend("float dvSign = sign(dot(offset, dvAxis));"); - fragBuilder->codeAppendf("%s = vec4(dvSign * dvAxis, dvLength, 0.0);", - args.fDistanceVectorName); - } } static void GenKey(const GrGeometryProcessor& gp, diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp index 174dc4015e..2b9d1c8e56 100644 --- a/src/gpu/ops/GrOvalOpFactory.cpp +++ b/src/gpu/ops/GrOvalOpFactory.cpp @@ -57,12 +57,6 @@ static inline bool circle_stays_circle(const SkMatrix& m) { return m.isSimilarit * p is the position in the normalized space. * outerRad is the outerRadius in device space. * innerRad is the innerRadius in normalized space (ignored if not stroking). - * If fUsesDistanceVectorField is set in fragment processors in the same program, then - * an additional vertex attribute is available via args.fFragBuilder->distanceVectorName(): - * vec4f : (v.xy, outerDistance, innerDistance) - * v is a normalized vector pointing to the outer edge - * outerDistance is the distance to the outer edge, < 0 if we are outside of the shape - * if stroking, innerDistance is the distance to the inner edge, < 0 if outside * Additional clip planes are supported for rendering circular arcs. The additional planes are * either intersected or unioned together. Up to three planes are supported (an initial plane, * a plane intersected with the initial plane, and a plane unioned with the first two). Only two @@ -99,8 +93,6 @@ public: fStroke = stroke; } - bool implementsDistanceVector() const override { return !fInClipPlane; } - ~CircleGeometryProcessor() override {} const char* name() const override { return "CircleEdge"; } @@ -170,21 +162,6 @@ private: fragBuilder->codeAppend("edgeAlpha *= innerAlpha;"); } - if (args.fDistanceVectorName) { - const char* innerEdgeDistance = cgp.fStroke ? "distanceToInnerEdge" : "0.0"; - fragBuilder->codeAppendf( - "if (d == 0.0) {" // if on the center of the circle - " %s = vec4(1.0, 0.0, distanceToOuterEdge, " - " %s);", // no normalize - args.fDistanceVectorName, - innerEdgeDistance); - fragBuilder->codeAppendf( - "} else {" - " %s = vec4(normalize(circleEdge.xy)," - " distanceToOuterEdge, %s);" - "}", - args.fDistanceVectorName, innerEdgeDistance); - } if (cgp.fInClipPlane) { fragBuilder->codeAppend( "float clip = clamp(circleEdge.z * dot(circleEdge.xy, clipPlane.xy) + " @@ -1689,7 +1666,6 @@ enum RRectType { kFill_RRectType, kStroke_RRectType, kOverstroke_RRectType, - kFillWithDist_RRectType }; static int rrect_type_to_vert_count(RRectType type) { @@ -1698,7 +1674,6 @@ static int rrect_type_to_vert_count(RRectType type) { case kStroke_RRectType: return kVertsPerStandardRRect; case kOverstroke_RRectType: - case kFillWithDist_RRectType: return kVertsPerOverstrokeRRect; } SkFAIL("Invalid type"); @@ -1712,7 +1687,6 @@ static int rrect_type_to_index_count(RRectType type) { case kStroke_RRectType: return kIndicesPerStrokeRRect; case kOverstroke_RRectType: - case kFillWithDist_RRectType: return kIndicesPerOverstrokeRRect; } SkFAIL("Invalid type"); @@ -1725,7 +1699,6 @@ static const uint16_t* rrect_type_to_indices(RRectType type) { case kStroke_RRectType: return gStandardRRectIndices; case kOverstroke_RRectType: - case kFillWithDist_RRectType: return gOverstrokeRRectIndices; } SkFAIL("Invalid type"); @@ -1752,16 +1725,14 @@ public: // A devStrokeWidth <= 0 indicates a fill only. If devStrokeWidth > 0 then strokeOnly indicates // whether the rrect is only stroked or stroked and filled. - static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, bool needsDistance, - const SkMatrix& viewMatrix, const SkRect& devRect, - float devRadius, float devStrokeWidth, bool strokeOnly) { - return Helper::FactoryHelper<CircularRRectOp>(std::move(paint), needsDistance, viewMatrix, - devRect, devRadius, devStrokeWidth, - strokeOnly); + static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, + const SkRect& devRect, float devRadius, + float devStrokeWidth, bool strokeOnly) { + return Helper::FactoryHelper<CircularRRectOp>(std::move(paint), viewMatrix, devRect, + devRadius, devStrokeWidth, strokeOnly); } - CircularRRectOp(Helper::MakeArgs& helperArgs, GrColor color, bool needsDistance, - const SkMatrix& viewMatrix, const SkRect& devRect, float devRadius, - float devStrokeWidth, bool strokeOnly) + CircularRRectOp(Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix, + const SkRect& devRect, float devRadius, float devStrokeWidth, bool strokeOnly) : INHERITED(ClassID()) , fViewMatrixIfUsingLocalCoords(viewMatrix) , fHelper(helperArgs, GrAAType::kCoverage) { @@ -1791,9 +1762,6 @@ public: outerRadius += halfWidth; bounds.outset(halfWidth, halfWidth); } - if (kFill_RRectType == type && needsDistance) { - type = kFillWithDist_RRectType; - } // The radii are outset for two reasons. First, it allows the shader to simply perform // simpler computation because the computed alpha is zero, rather than 50%, at the radius. @@ -1958,10 +1926,9 @@ private: SkScalar yOuterRadii[4] = {-1, 0, 0, 1}; // The inner radius in the vertex data must be specified in normalized space. // For fills, specifying -1/outerRadius guarantees an alpha of 1.0 at the inner radius. - SkScalar innerRadius = - rrect.fType != kFill_RRectType && rrect.fType != kFillWithDist_RRectType - ? rrect.fInnerRadius / rrect.fOuterRadius - : -1.0f / rrect.fOuterRadius; + SkScalar innerRadius = rrect.fType != kFill_RRectType + ? rrect.fInnerRadius / rrect.fOuterRadius + : -1.0f / rrect.fOuterRadius; for (int i = 0; i < 4; ++i) { verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); verts->fColor = color; @@ -2011,15 +1978,6 @@ private: overstrokeOuterRadius, 0.0f, rrect.fColor); } - if (kFillWithDist_RRectType == rrect.fType) { - SkScalar halfMinDim = 0.5f * SkTMin(bounds.width(), bounds.height()); - - SkScalar xOffset = 1.0f - outerRadius / halfMinDim; - - FillInOverstrokeVerts(&verts, bounds, outerRadius, halfMinDim, xOffset, halfMinDim, - -1.0f, rrect.fColor); - } - const uint16_t* primIndices = rrect_type_to_indices(rrect.fType); const int primIndexCount = rrect_type_to_index_count(rrect.fType); for (int i = 0; i < primIndexCount; ++i) { @@ -2321,7 +2279,6 @@ private: }; static std::unique_ptr<GrDrawOp> make_rrect_op(GrPaint&& paint, - bool needsDistance, const SkMatrix& viewMatrix, const SkRRect& rrect, const SkStrokeRec& stroke) { @@ -2382,8 +2339,8 @@ static std::unique_ptr<GrDrawOp> make_rrect_op(GrPaint&& paint, // if the corners are circles, use the circle renderer if (isCircular) { - return CircularRRectOp::Make(std::move(paint), needsDistance, viewMatrix, bounds, xRadius, - scaledStroke.fX, isStrokeOnly); + return CircularRRectOp::Make(std::move(paint), viewMatrix, bounds, xRadius, scaledStroke.fX, + isStrokeOnly); // otherwise we use the ellipse renderer } else { return EllipticalRRectOp::Make(std::move(paint), viewMatrix, bounds, xRadius, yRadius, @@ -2392,7 +2349,6 @@ static std::unique_ptr<GrDrawOp> make_rrect_op(GrPaint&& paint, } std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeRRectOp(GrPaint&& paint, - bool needsDistance, const SkMatrix& viewMatrix, const SkRRect& rrect, const SkStrokeRec& stroke, @@ -2405,7 +2361,7 @@ std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeRRectOp(GrPaint&& paint, return nullptr; } - return make_rrect_op(std::move(paint), needsDistance, viewMatrix, rrect, stroke); + return make_rrect_op(std::move(paint), viewMatrix, rrect, stroke); } /////////////////////////////////////////////////////////////////////////////// @@ -2508,9 +2464,7 @@ GR_DRAW_OP_TEST_DEFINE(DIEllipseOp) { GR_DRAW_OP_TEST_DEFINE(RRectOp) { SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); const SkRRect& rrect = GrTest::TestRRectSimple(random); - bool needsDistance = random->nextBool(); - return make_rrect_op(std::move(paint), needsDistance, viewMatrix, rrect, - GrTest::TestStrokeRec(random)); + return make_rrect_op(std::move(paint), viewMatrix, rrect, GrTest::TestStrokeRec(random)); } #endif diff --git a/src/gpu/ops/GrOvalOpFactory.h b/src/gpu/ops/GrOvalOpFactory.h index 8a51c5301e..4c85ee84f5 100644 --- a/src/gpu/ops/GrOvalOpFactory.h +++ b/src/gpu/ops/GrOvalOpFactory.h @@ -33,7 +33,6 @@ public: const GrShaderCaps*); static std::unique_ptr<GrDrawOp> MakeRRectOp(GrPaint&&, - bool needsDistance, const SkMatrix&, const SkRRect&, const SkStrokeRec&, diff --git a/src/gpu/ops/GrRectOpFactory.h b/src/gpu/ops/GrRectOpFactory.h index f4b1b803fb..58927ef91b 100644 --- a/src/gpu/ops/GrRectOpFactory.h +++ b/src/gpu/ops/GrRectOpFactory.h @@ -31,11 +31,7 @@ inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFill(const GrPaint& paint, const SkRect& rect, const SkRect& croppedRect, const SkRect& devRect) { - if (!paint.usesDistanceVectorField()) { - return GrAAFillRectOp::Make(paint.getColor(), viewMatrix, croppedRect, devRect); - } else { - return GrAnalyticRectOp::Make(paint.getColor(), viewMatrix, rect, croppedRect, devRect); - } + return GrAAFillRectOp::Make(paint.getColor(), viewMatrix, croppedRect, devRect); } inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFill(GrColor color, diff --git a/tests/SerializationTest.cpp b/tests/SerializationTest.cpp index 1212833c0e..fccf21156a 100644 --- a/tests/SerializationTest.cpp +++ b/tests/SerializationTest.cpp @@ -628,16 +628,6 @@ DEF_TEST(Serialization, reporter) { fLights); sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter)); } - - // Test NormalBevelSource serialization - { - sk_sp<SkNormalSource> bevelSource = SkNormalSource::MakeBevel( - SkNormalSource::BevelType::kLinear, 2.0f, 5.0f); - - sk_sp<SkNormalSource>(TestFlattenableSerialization(bevelSource.get(), true, reporter)); - // TODO test equality? - - } } /////////////////////////////////////////////////////////////////////////////////////////////////// |