diff options
author | 2016-06-27 09:30:19 -0700 | |
---|---|---|
committer | 2016-06-27 09:30:19 -0700 | |
commit | 2c80711f90a5dafe3b726bc6562b1e769702c34b (patch) | |
tree | eea1fe5e0dd506f7bbad4b8b348eb85ca60727c5 /src/core/SkLightingShader.cpp | |
parent | c411f2d963cdee3a934c9ff65b0728d2b927586a (diff) |
Revert of Refactoring of CPU NormalMap handling out into its own class (patchset #13 id:240001 of https://codereview.chromium.org/2050773002/ )
Reason for revert:
GMs are crashing on Windows Test trybots
Original issue's description:
> SkLightingShader normal vector CPU computation refactor.
>
> The purpose of this change is to refactor the handling of normal maps out of SkLightingShader, laying the groundwork to eventually allow for multiple normal sources.
>
> This CL's base was the CL for GPU handling: https://codereview.chromium.org/2043393002/
>
> What this CL includes:
>
> - A refactor of the SkLightingShader context's code that deals with reading normals off of a normal map. This is now abstracted out into a NormalSource::Provider class that the context uses.
>
> BUG=skia:
> GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2050773002
>
> Committed: https://skia.googlesource.com/skia/+/790a70118327a129cb6b48fabe80f4e184c1e67c
TBR=egdaniel@google.com,reed@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Review-Url: https://codereview.chromium.org/2101653002
Diffstat (limited to 'src/core/SkLightingShader.cpp')
-rw-r--r-- | src/core/SkLightingShader.cpp | 111 |
1 files changed, 73 insertions, 38 deletions
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp index 52b208f8df..ca1c3417b4 100644 --- a/src/core/SkLightingShader.cpp +++ b/src/core/SkLightingShader.cpp @@ -12,7 +12,6 @@ #include "SkErrorInternals.h" #include "SkLightingShader.h" #include "SkMathPriv.h" -#include "SkNormalSource.h" #include "SkPoint3.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" @@ -56,7 +55,7 @@ public: const sk_sp<SkLights> lights, const SkVector& invNormRotation, const SkMatrix* diffLocalM, const SkMatrix* normLocalM, - sk_sp<SkNormalSource> normalSource) + sk_sp<SkLightingShader::NormalSource> normalSource) : INHERITED(diffLocalM) , fDiffuseMap(diffuse) , fNormalMap(normal) @@ -89,7 +88,7 @@ public: // The context takes ownership of the states. It will call their destructors // but will NOT free the memory. LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&, - SkBitmapProcState* diffuseState, SkNormalSource::Provider*); + SkBitmapProcState* diffuseState, SkBitmapProcState* normalState); ~LightingShaderContext() override; void shadeSpan(int x, int y, SkPMColor[], int count) override; @@ -97,9 +96,9 @@ public: uint32_t getFlags() const override { return fFlags; } private: - SkBitmapProcState* fDiffuseState; - SkNormalSource::Provider* fNormalProvider; - uint32_t fFlags; + SkBitmapProcState* fDiffuseState; + SkBitmapProcState* fNormalState; + uint32_t fFlags; typedef SkShader::Context INHERITED; }; @@ -111,6 +110,7 @@ protected: void flatten(SkWriteBuffer&) const override; size_t onContextSize(const ContextRec&) const override; Context* onCreateContext(const ContextRec&, void*) const override; + bool computeNormTotalInverse(const ContextRec& rec, SkMatrix* normTotalInverse) const; private: SkBitmap fDiffuseMap; @@ -121,7 +121,7 @@ private: SkMatrix fNormLocalMatrix; SkVector fInvNormRotation; - sk_sp<SkNormalSource> fNormalSource; + sk_sp<SkLightingShader::NormalSource> fNormalSource; friend class SkLightingShader; @@ -367,11 +367,13 @@ bool SkLightingShaderImpl::isOpaque() const { } SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( - const SkLightingShaderImpl& shader, const ContextRec& rec, SkBitmapProcState* diffuseState, - SkNormalSource::Provider* normalProvider) + const SkLightingShaderImpl& shader, + const ContextRec& rec, + SkBitmapProcState* diffuseState, + SkBitmapProcState* normalState) : INHERITED(shader, rec) , fDiffuseState(diffuseState) - , fNormalProvider(normalProvider) { + , fNormalState(normalState) { const SkPixmap& pixmap = fDiffuseState->fPixmap; bool isOpaque = pixmap.isOpaque(); @@ -388,7 +390,7 @@ SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() { // The bitmap proc states have been created outside of the context on memory that will be freed // elsewhere. Call the destructors but leave the freeing of the memory to the caller. fDiffuseState->~SkBitmapProcState(); - fNormalProvider->~Provider(); + fNormalState->~SkBitmapProcState(); } static inline SkPMColor convert(SkColor3f color, U8CPU a) { @@ -415,24 +417,29 @@ static inline SkPMColor convert(SkColor3f color, U8CPU a) { // larger is better (fewer times we have to loop), but we shouldn't // take up too much stack-space (each one here costs 16 bytes) -#define TMP_COUNT 16 -#define BUFFER_MAX ((int)(TMP_COUNT * sizeof(uint32_t))) +#define TMP_COUNT 16 + void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) { const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShaderImpl&>(fShader); - uint32_t tmpColor[TMP_COUNT]; - SkPMColor tmpColor2[2*TMP_COUNT]; + uint32_t tmpColor[TMP_COUNT], tmpNormal[TMP_COUNT]; + SkPMColor tmpColor2[2*TMP_COUNT], tmpNormal2[2*TMP_COUNT]; SkBitmapProcState::MatrixProc diffMProc = fDiffuseState->getMatrixProc(); SkBitmapProcState::SampleProc32 diffSProc = fDiffuseState->getSampleProc32(); - int max = fDiffuseState->maxCountForBufferSize(BUFFER_MAX); + SkBitmapProcState::MatrixProc normalMProc = fNormalState->getMatrixProc(); + SkBitmapProcState::SampleProc32 normalSProc = fNormalState->getSampleProc32(); + + int diffMax = fDiffuseState->maxCountForBufferSize(sizeof(tmpColor[0]) * TMP_COUNT); + int normMax = fNormalState->maxCountForBufferSize(sizeof(tmpNormal[0]) * TMP_COUNT); + int max = SkTMin(diffMax, normMax); SkASSERT(fDiffuseState->fPixmap.addr()); + SkASSERT(fNormalState->fPixmap.addr()); - SkASSERT(max <= BUFFER_MAX); - SkPoint3 normals[BUFFER_MAX]; + SkPoint3 norm, xformedNorm; do { int n = count; @@ -443,9 +450,21 @@ void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, diffMProc(*fDiffuseState, tmpColor, n, x, y); diffSProc(*fDiffuseState, tmpColor, n, tmpColor2); - fNormalProvider->fillScanLine(x, y, normals, n); + normalMProc(*fNormalState, tmpNormal, n, x, y); + normalSProc(*fNormalState, tmpNormal, n, tmpNormal2); for (int i = 0; i < n; ++i) { + SkASSERT(0xFF == SkColorGetA(tmpNormal2[i])); // opaque -> unpremul + norm.set(SkIntToScalar(SkGetPackedR32(tmpNormal2[i]))-127.0f, + SkIntToScalar(SkGetPackedG32(tmpNormal2[i]))-127.0f, + SkIntToScalar(SkGetPackedB32(tmpNormal2[i]))-127.0f); + norm.normalize(); + + xformedNorm.fX = lightShader.fInvNormRotation.fX * norm.fX + + lightShader.fInvNormRotation.fY * norm.fY; + xformedNorm.fY = -lightShader.fInvNormRotation.fY * norm.fX + + lightShader.fInvNormRotation.fX * norm.fY; + xformedNorm.fZ = norm.fZ; SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); @@ -457,7 +476,7 @@ void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, if (SkLights::Light::kAmbient_LightType == light.type()) { accum += light.color().makeScale(255.0f); } else { - SkScalar NdotL = normals[i].dot(light.dir()); + SkScalar NdotL = xformedNorm.dot(light.dir()); if (NdotL < 0.0f) { NdotL = 0.0f; } @@ -544,7 +563,8 @@ sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { invNormRotation = buf.readPoint(); } - sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>()); + sk_sp<SkLightingShader::NormalSource> normalSource( + buf.readFlattenable<SkLightingShader::NormalSource>()); return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation, &diffLocalM, &normLocalM, std::move(normalSource)); @@ -579,10 +599,21 @@ void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { buf.writeFlattenable(fNormalSource.get()); } -size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const { - return sizeof(LightingShaderContext) + - sizeof(SkBitmapProcState) + - fNormalSource->providerSize(rec); +bool SkLightingShaderImpl::computeNormTotalInverse(const 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); +} + +size_t SkLightingShaderImpl::onContextSize(const ContextRec&) const { + return 2 * sizeof(SkBitmapProcState) + sizeof(LightingShaderContext); } SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, @@ -592,6 +623,11 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, // computeTotalInverse was called in SkShader::createContext so we know it will succeed SkAssertResult(this->computeTotalInverse(rec, &diffTotalInv)); + SkMatrix normTotalInv; + if (!this->computeNormTotalInverse(rec, &normTotalInv)) { + return nullptr; + } + void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext); SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState(fDiffuseMap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, @@ -601,18 +637,21 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, diffuseState->~SkBitmapProcState(); return nullptr; } - void* normalProviderStorage = (char*)storage + - sizeof(LightingShaderContext) + - sizeof(SkBitmapProcState); - SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec, - normalProviderStorage); - if (!normalProvider) { + void* normalStateStorage = (char*)storage + + sizeof(LightingShaderContext) + + sizeof(SkBitmapProcState); + SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState(fNormalMap, + SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, + SkMipMap::DeduceTreatment(rec)); + SkASSERT(normalState); + if (!normalState->setup(normTotalInv, *rec.fPaint)) { diffuseState->~SkBitmapProcState(); + normalState->~SkBitmapProcState(); return nullptr; } - return new (storage) LightingShaderContext(*this, rec, diffuseState, normalProvider); + return new (storage) LightingShaderContext(*this, rec, diffuseState, normalState); } /////////////////////////////////////////////////////////////////////////////// @@ -629,12 +668,8 @@ sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap& } SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1)); - // TODO: support other tile modes - sk_sp<SkShader> mapShader = SkMakeBitmapShader(normal, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode, normLocalM, nullptr); - - sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(mapShader, - invNormRotation); + sk_sp<SkLightingShader::NormalSource> normalSource = + SkLightingShader::NormalSource::MakeMap(normal, invNormRotation, normLocalM); return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation, diffLocalM, normLocalM, std::move(normalSource)); |