Index: src/core/SkNormalBevelSource.cpp |
diff --git a/src/core/SkNormalBevelSource.cpp b/src/core/SkNormalBevelSource.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e7dcc5b0d73e3eaa880122d8cb2cea8a07a307fe |
--- /dev/null |
+++ b/src/core/SkNormalBevelSource.cpp |
@@ -0,0 +1,163 @@ |
+/* |
+ * 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 "SkError.h" |
+#include "SkErrorInternals.h" |
+#include "SkLightingShader.h" |
+#include "SkMatrix.h" |
+#include "SkNormalSource.h" |
+#include "SkPM4f.h" |
+#include "SkReadBuffer.h" |
+#include "SkWriteBuffer.h" |
+ |
+#if SK_SUPPORT_GPU |
+#include "GrCoordTransform.h" |
+#include "GrInvariantOutput.h" |
+#include "GrTextureParams.h" |
+#include "glsl/GrGLSLFragmentProcessor.h" |
+#include "glsl/GrGLSLFragmentShaderBuilder.h" |
+#include "SkGr.h" |
+#endif |
+ |
+#if SK_SUPPORT_GPU |
egdaniel
2016/07/25 15:48:00
can we share the #if sk_support_gpu with the inclu
dvonbeck
2016/07/25 20:37:13
I felt like it was clearer this way when there wer
|
+ |
+class NormalBevelFP : public GrFragmentProcessor { |
+public: |
+ NormalBevelFP(SkNormalSource::BevelType type, SkScalar width, SkScalar height) |
+ : fType(type) |
+ , fWidth(width) |
+ , fHeight(height) { |
+ this->initClassID<NormalBevelFP>(); |
+ } |
+ |
+ class GLSLNormalBevelFP : public GrGLSLFragmentProcessor { |
+ public: |
+ GLSLNormalBevelFP() { |
+ fPrevType = SkNormalSource::BevelType::kLinear; |
+ fPrevWidth = SkFloatToScalar(0.0f); |
+ fPrevHeight = SkFloatToScalar(0.0f); |
+ } |
+ |
+ void emitCode(EmitArgs& args) override { |
+ GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
+ |
+ fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor); |
+ } |
+ |
+ static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
+ GrProcessorKeyBuilder* b) { |
+ b->add32(0x0); |
+ } |
+ |
+ protected: |
+ void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { |
+ const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>(); |
+ |
+ fPrevType = normalBevelFP.fType; |
egdaniel
2016/07/25 15:48:00
can we put this in the form Rob suggested earlier,
dvonbeck
2016/07/25 20:37:13
Done.
|
+ fPrevWidth = normalBevelFP.fWidth; |
+ fPrevHeight = normalBevelFP.fHeight; |
+ } |
+ |
+ private: |
+ SkNormalSource::BevelType fPrevType; |
egdaniel
2016/07/25 15:48:00
Do you need to store the type here? Seems like thi
dvonbeck
2016/07/25 20:37:13
Done.
|
+ SkScalar fPrevWidth; |
+ SkScalar fPrevHeight; |
+ }; |
+ |
+ void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { |
+ GLSLNormalBevelFP::GenKey(*this, caps, b); |
+ } |
+ |
+ const char* name() const override { return "NormalBevelFP"; } |
+ |
+ void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
+ inout->setToUnknown(GrInvariantOutput::ReadInput::kWillNot_ReadInput); |
+ } |
+ |
+private: |
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLNormalBevelFP; } |
+ |
+ bool onIsEqual(const GrFragmentProcessor& proc) const override { |
+ const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>(); |
+ return fType == normalBevelFP.fType && |
+ fWidth == normalBevelFP.fWidth && |
+ fHeight == normalBevelFP.fHeight; |
+ } |
+ |
+ SkNormalSource::BevelType fType; |
+ SkScalar fWidth; |
+ SkScalar fHeight; |
+}; |
+ |
+sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor( |
+ GrContext *context, |
+ const SkMatrix &viewM, |
+ const SkMatrix *localMatrix, |
+ SkFilterQuality filterQuality, |
+ SkSourceGammaTreatment gammaTreatment) const { |
+ |
+ return sk_make_sp<NormalBevelFP>(fType, fWidth, fHeight); |
+} |
+ |
+#endif // SK_SUPPORT_GPU |
+ |
+//////////////////////////////////////////////////////////////////////////// |
+ |
+SkNormalBevelSourceImpl::Provider::Provider(const SkNormalBevelSourceImpl& source) |
+ : fSource(source) {} |
+ |
+SkNormalBevelSourceImpl::Provider::~Provider() {} |
+ |
+SkNormalSource::Provider* SkNormalBevelSourceImpl::asProvider(const SkShader::ContextRec &rec, |
+ void *storage) const { |
+ return new (storage) Provider(*this); |
+} |
+ |
+size_t SkNormalBevelSourceImpl::providerSize(const SkShader::ContextRec&) const { |
+ return sizeof(Provider); |
+} |
+ |
+void SkNormalBevelSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[], |
+ int count) const { |
+ for (int i = 0; i < count; i++) { |
+ output[i] = {0, 0, 1.0}; |
egdaniel
2016/07/25 15:48:00
1.0f?
dvonbeck
2016/07/25 20:37:13
Oops. Done.
|
+ } |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+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 this 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); |
+} |