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

Unified Diff: src/core/SkLightingShader.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: SkLS Context dependencies now allocated on the heap 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
« no previous file with comments | « src/core/SkLightingShader.h ('k') | src/core/SkLightingShader_NormalSource.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkLightingShader.cpp
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp
index ca1c3417b4581ab5c404654e6acc4bd51bd8858c..f32aa9f411b1f30a93c6f081713f0385c87f1051 100644
--- a/src/core/SkLightingShader.cpp
+++ b/src/core/SkLightingShader.cpp
@@ -12,6 +12,7 @@
#include "SkErrorInternals.h"
#include "SkLightingShader.h"
#include "SkMathPriv.h"
+#include "SkNormalSource.h"
#include "SkPoint3.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
@@ -55,7 +56,7 @@ public:
const sk_sp<SkLights> lights,
const SkVector& invNormRotation,
const SkMatrix* diffLocalM, const SkMatrix* normLocalM,
- sk_sp<SkLightingShader::NormalSource> normalSource)
+ sk_sp<SkNormalSource> normalSource)
: INHERITED(diffLocalM)
, fDiffuseMap(diffuse)
, fNormalMap(normal)
@@ -88,7 +89,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, SkNormalSource::Provider*,
+ void* heapAllocated);
~LightingShaderContext() override;
void shadeSpan(int x, int y, SkPMColor[], int count) override;
@@ -96,9 +98,11 @@ public:
uint32_t getFlags() const override { return fFlags; }
private:
- SkBitmapProcState* fDiffuseState;
- SkBitmapProcState* fNormalState;
- uint32_t fFlags;
+ SkBitmapProcState* fDiffuseState;
+ SkNormalSource::Provider* fNormalProvider;
+ uint32_t fFlags;
+
+ void* fHeapAllocated;
typedef SkShader::Context INHERITED;
};
@@ -110,7 +114,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;
@@ -121,7 +124,7 @@ private:
SkMatrix fNormLocalMatrix;
SkVector fInvNormRotation;
- sk_sp<SkLightingShader::NormalSource> fNormalSource;
+ sk_sp<SkNormalSource> fNormalSource;
friend class SkLightingShader;
@@ -367,13 +370,12 @@ 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,
+ SkNormalSource::Provider* normalProvider, void* heapAllocated)
: INHERITED(shader, rec)
, fDiffuseState(diffuseState)
- , fNormalState(normalState) {
+ , fNormalProvider(normalProvider)
+ , fHeapAllocated(heapAllocated) {
const SkPixmap& pixmap = fDiffuseState->fPixmap;
bool isOpaque = pixmap.isOpaque();
@@ -390,7 +392,9 @@ 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();
+
+ sk_free(fHeapAllocated);
}
static inline SkPMColor convert(SkColor3f color, U8CPU a) {
@@ -417,29 +421,24 @@ 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 TMP_COUNT 16
+#define BUFFER_MAX ((int)(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 max = fDiffuseState->maxCountForBufferSize(BUFFER_MAX);
SkASSERT(fDiffuseState->fPixmap.addr());
- SkASSERT(fNormalState->fPixmap.addr());
- SkPoint3 norm, xformedNorm;
+ SkASSERT(max <= BUFFER_MAX);
+ SkPoint3 normals[BUFFER_MAX];
do {
int n = count;
@@ -450,21 +449,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);
+ fNormalProvider->fillScanLine(x, y, normals, n);
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]);
@@ -476,7 +463,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;
}
@@ -563,8 +550,7 @@ sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) {
invNormRotation = buf.readPoint();
}
- sk_sp<SkLightingShader::NormalSource> normalSource(
- buf.readFlattenable<SkLightingShader::NormalSource>());
+ sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>());
return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights), invNormRotation,
&diffLocalM, &normLocalM, std::move(normalSource));
@@ -599,21 +585,8 @@ 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);
+size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const {
+ return sizeof(LightingShaderContext);
}
SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
@@ -623,35 +596,31 @@ 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;
- }
+ size_t heapRequired = sizeof(SkBitmapProcState) + fNormalSource->providerSize(rec);
+ void* heapAllocated = sk_malloc_throw(heapRequired);
- void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext);
+ void* diffuseStateStorage = heapAllocated;
SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState(fDiffuseMap,
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
SkMipMap::DeduceTreatment(rec));
SkASSERT(diffuseState);
if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) {
diffuseState->~SkBitmapProcState();
+ sk_free(heapAllocated);
return nullptr;
}
+ void* normalProviderStorage = (char*)heapAllocated + 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)) {
+ SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec,
+ normalProviderStorage);
+ if (!normalProvider) {
diffuseState->~SkBitmapProcState();
- normalState->~SkBitmapProcState();
+ sk_free(heapAllocated);
return nullptr;
}
- return new (storage) LightingShaderContext(*this, rec, diffuseState, normalState);
+ return new (storage) LightingShaderContext(*this, rec, diffuseState, normalProvider,
+ heapAllocated);
}
///////////////////////////////////////////////////////////////////////////////
@@ -668,8 +637,12 @@ sk_sp<SkShader> SkLightingShader::Make(const SkBitmap& diffuse, const SkBitmap&
}
SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1));
- sk_sp<SkLightingShader::NormalSource> normalSource =
- SkLightingShader::NormalSource::MakeMap(normal, invNormRotation, normLocalM);
+ // 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);
return sk_make_sp<SkLightingShaderImpl>(diffuse, normal, std::move(lights),
invNormRotation, diffLocalM, normLocalM, std::move(normalSource));
« no previous file with comments | « src/core/SkLightingShader.h ('k') | src/core/SkLightingShader_NormalSource.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698