Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Unified Diff: src/core/SkLightingShader_NormalSource.cpp

Issue 2050773002: Refactoring of CPU NormalMap handling out into its own class (Closed) Base URL: https://skia.googlesource.com/skia@dvonbeck-normals-gpu-cl
Patch Set: Got rid of variable-length arrays Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/core/SkLightingShader.cpp ('K') | « src/core/SkLightingShader.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkLightingShader_NormalSource.cpp
diff --git a/src/core/SkLightingShader_NormalSource.cpp b/src/core/SkLightingShader_NormalSource.cpp
index 8ad3ed9ec57691811a0580574bbb9908831acda3..a09ff16f35fe2952487b84aa7549423178e97e52 100644
--- a/src/core/SkLightingShader_NormalSource.cpp
+++ b/src/core/SkLightingShader_NormalSource.cpp
@@ -6,6 +6,7 @@
*/
#include "SkBitmapProcShader.h"
+#include "SkBitmapProcState.h"
#include "SkError.h"
#include "SkErrorInternals.h"
#include "SkLightingShader.h"
@@ -41,12 +42,36 @@ public:
SkSourceGammaTreatment) const override;
#endif
+ SkLightingShader::NormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
+ void* storage) const override;
+
+ size_t providerSize() const override;
+
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(NormalMapSourceImpl)
protected:
void flatten(SkWriteBuffer& buf) const override;
private:
+
+ class Provider : public SkLightingShader::NormalSource::Provider {
+ public:
+ Provider(const NormalMapSourceImpl& source, SkBitmapProcState* state);
+
+ virtual ~Provider();
+
+ void fillScanLine(int x, int y, SkPoint3 output[], int count) const override;
+
+ int maxCountForFillScanLine(int count) const override;
+ private:
+ const NormalMapSourceImpl& fSource;
egdaniel 2016/06/16 13:48:10 Generally we store pointers here if you just need
dvonbeck 2016/06/16 22:05:40 I did this because it's what LightingShader contex
+ SkBitmapProcState* fState;
+
+ typedef SkLightingShader::NormalSource::Provider INHERITED;
+ };
+
+ bool computeNormTotalInverse(const SkShader::ContextRec& rec, SkMatrix* normTotalInverse) const;
+
SkBitmap fNormalMap;
SkMatrix fNormLocalMatrix;
SkVector fInvNormRotation;
@@ -228,6 +253,91 @@ sk_sp<GrFragmentProcessor> NormalMapSourceImpl::asFragmentProcessor(
////////////////////////////////////////////////////////////////////////////
+NormalMapSourceImpl::Provider::Provider(const NormalMapSourceImpl& source, SkBitmapProcState* state)
+ : fSource(source)
+ , fState(state) {
+ SkASSERT(fState->fPixmap.addr());
+}
+
+NormalMapSourceImpl::Provider::~Provider() {
+ fState->~SkBitmapProcState();
+}
+
+SkLightingShader::NormalSource::Provider* NormalMapSourceImpl::asProvider(
+ const SkShader::ContextRec &rec, void *storage) const {
+ SkMatrix normTotalInv;
+ if (!this->computeNormTotalInverse(rec, &normTotalInv)) {
+ return nullptr;
+ }
+
+ void* stateStorage = (char*)storage + sizeof(Provider);
+ SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(fNormalMap,
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, SkMipMap::DeduceTreatment(rec));
+ SkASSERT(state);
+ if (!state->setup(normTotalInv, *rec.fPaint)) {
+ state->~SkBitmapProcState();
+ return nullptr;
+ }
+
+ return new (storage) Provider(*this, state);
+}
+
+size_t NormalMapSourceImpl::providerSize() const {
+ return sizeof(Provider) + sizeof(SkBitmapProcState);
+}
+
+// TODO: these defines are redundant with the ones in SkLightingShader.cpp, will consolidate in a
+// future CL when the source of diffuse colores is factored out
+#define TMP_COUNT 16
+#define BUFFER_MAX (TMP_COUNT * sizeof(uint32_t))
+void NormalMapSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[],
+ int count) const {
+ SkBitmapProcState::MatrixProc normalMProc = fState->getMatrixProc();
+ SkBitmapProcState::SampleProc32 normalSProc = fState->getSampleProc32();
+
+ uint32_t tmpNormal[BUFFER_MAX];
+ SkPMColor tmpNormal2[2*BUFFER_MAX];
+ normalMProc(*fState, tmpNormal, count, x, y);
+ normalSProc(*fState, tmpNormal, count, tmpNormal2);
+
+ for (int i = 0; i < count; i++) {
+ SkASSERT(0xFF == SkColorGetA(tmpNormal2[i])); // opaque -> unpremul
+
+ SkPoint3 tempNorm;
+
+ tempNorm.set(SkIntToScalar(SkGetPackedR32(tmpNormal2[i])) - 127.0f,
+ SkIntToScalar(SkGetPackedG32(tmpNormal2[i])) - 127.0f,
+ SkIntToScalar(SkGetPackedB32(tmpNormal2[i])) - 127.0f);
+ tempNorm.normalize();
+
+
+ output[i].fX = fSource.fInvNormRotation.fX * tempNorm.fX +
+ fSource.fInvNormRotation.fY * tempNorm.fY;
+ output[i].fY = -fSource.fInvNormRotation.fY * tempNorm.fX +
+ fSource.fInvNormRotation.fX * tempNorm.fY;
+ output[i].fZ = tempNorm.fZ;
+ }
+}
+
+int NormalMapSourceImpl::Provider::maxCountForFillScanLine(int count) const {
+ return fState->maxCountForBufferSize(sizeof(uint32_t /*tmpNormal[0]*/) * count);
+}
+
+bool NormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& rec,
+ SkMatrix* normTotalInverse) const {
+ SkMatrix total;
+ total.setConcat(*rec.fMatrix, fNormLocalMatrix);
+
+ const SkMatrix* m = &total;
+ if (rec.fLocalMatrix) {
+ total.setConcat(*m, *rec.fLocalMatrix);
+ m = &total;
+ }
+ return m->invert(normTotalInverse);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
sk_sp<SkFlattenable> NormalMapSourceImpl::CreateProc(SkReadBuffer& buf) {
SkMatrix normLocalM;
« src/core/SkLightingShader.cpp ('K') | « src/core/SkLightingShader.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698