Index: src/core/SkLightingShader.cpp |
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp |
index c80f26884ae1f2b89b04d293f53fc3695db08f77..e45c17f3b1b78050a96a6d1c6644821ced5723b7 100644 |
--- a/src/core/SkLightingShader.cpp |
+++ b/src/core/SkLightingShader.cpp |
@@ -88,7 +88,8 @@ 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, SkBitmapProcState* normalState); |
+ SkBitmapProcState* diffuseState, |
+ SkLightingShader::NormalSource::Provider*); |
~LightingShaderContext() override; |
void shadeSpan(int x, int y, SkPMColor[], int count) override; |
@@ -96,9 +97,9 @@ public: |
uint32_t getFlags() const override { return fFlags; } |
private: |
- SkBitmapProcState* fDiffuseState; |
- SkBitmapProcState* fNormalState; |
- uint32_t fFlags; |
+ SkBitmapProcState* fDiffuseState; |
+ SkLightingShader::NormalSource::Provider* fNormalProvider; |
+ uint32_t fFlags; |
typedef SkShader::Context INHERITED; |
}; |
@@ -110,7 +111,6 @@ 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; |
@@ -367,13 +367,11 @@ bool SkLightingShaderImpl::isOpaque() const { |
} |
SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( |
- const SkLightingShaderImpl& shader, |
- const ContextRec& rec, |
- SkBitmapProcState* diffuseState, |
- SkBitmapProcState* normalState) |
+ const SkLightingShaderImpl& shader, const ContextRec& rec, SkBitmapProcState* diffuseState, |
+ SkLightingShader::NormalSource::Provider* normalProvider) |
: INHERITED(shader, rec) |
, fDiffuseState(diffuseState) |
- , fNormalState(normalState) { |
+ , fNormalProvider(normalProvider) { |
const SkPixmap& pixmap = fDiffuseState->fPixmap; |
bool isOpaque = pixmap.isOpaque(); |
@@ -390,7 +388,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(); |
- fNormalState->~SkBitmapProcState(); |
+ fNormalProvider->~Provider(); |
} |
static inline SkPMColor convert(SkColor3f color, U8CPU a) { |
@@ -417,32 +415,32 @@ 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) |
+// TODO: these defines are redundant with the ones in SkLightingShader_NormalSource.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 SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, |
SkPMColor result[], int count) { |
const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShaderImpl&>(fShader); |
- uint32_t tmpColor[TMP_COUNT], tmpNormal[TMP_COUNT]; |
- SkPMColor tmpColor2[2*TMP_COUNT], tmpNormal2[2*TMP_COUNT]; |
+ uint32_t tmpColor[TMP_COUNT]; |
+ SkPMColor tmpColor2[2*TMP_COUNT]; |
SkBitmapProcState::MatrixProc diffMProc = fDiffuseState->getMatrixProc(); |
SkBitmapProcState::SampleProc32 diffSProc = fDiffuseState->getSampleProc32(); |
- 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); |
+ int diffMax = fDiffuseState->maxCountForBufferSize(BUFFER_MAX); |
+ int normMax = fNormalProvider->maxCountForFillScanLine(TMP_COUNT); |
+ size_t max = SkTMin(diffMax, normMax); |
SkASSERT(fDiffuseState->fPixmap.addr()); |
- SkASSERT(fNormalState->fPixmap.addr()); |
- SkPoint3 norm, xformedNorm; |
+ SkASSERT(max <= BUFFER_MAX); |
+ SkPoint3 normals[BUFFER_MAX]; |
do { |
- int n = count; |
+ size_t n = count; |
egdaniel
2016/06/16 13:48:10
why the change to size_t here? Quick scan seems to
dvonbeck
2016/06/16 22:05:40
I was avoiding a compiler error "comparison betwee
|
if (n > max) { |
n = max; |
} |
@@ -450,21 +448,9 @@ void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, |
diffMProc(*fDiffuseState, tmpColor, n, x, y); |
diffSProc(*fDiffuseState, tmpColor, n, tmpColor2); |
- 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(); |
+ fNormalProvider->fillScanLine(x, y, normals, n); |
- 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; |
+ for (size_t i = 0; i < n; ++i) { |
SkColor diffColor = SkUnPreMultiply::PMColorToColor(tmpColor2[i]); |
@@ -476,7 +462,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 = xformedNorm.dot(light.dir()); |
+ SkScalar NdotL = normals[i].dot(light.dir()); |
if (NdotL < 0.0f) { |
NdotL = 0.0f; |
} |
@@ -599,21 +585,10 @@ void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { |
buf.writeFlattenable(fNormalSource.get()); |
} |
-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); |
+ return sizeof(LightingShaderContext) + |
+ sizeof(SkBitmapProcState) + |
+ fNormalSource->providerSize(); |
} |
SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, |
@@ -623,11 +598,6 @@ 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, |
@@ -637,21 +607,18 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, |
diffuseState->~SkBitmapProcState(); |
return nullptr; |
} |
+ void* normalProviderStorage = (char*)storage + |
+ sizeof(LightingShaderContext) + |
+ sizeof(SkBitmapProcState); |
- 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)) { |
+ SkLightingShader::NormalSource::Provider* normalProvider = |
+ fNormalSource->asProvider(rec, normalProviderStorage); |
+ if (!normalProvider) { |
diffuseState->~SkBitmapProcState(); |
- normalState->~SkBitmapProcState(); |
return nullptr; |
} |
- return new (storage) LightingShaderContext(*this, rec, diffuseState, normalState); |
+ return new (storage) LightingShaderContext(*this, rec, diffuseState, normalProvider); |
} |
/////////////////////////////////////////////////////////////////////////////// |