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

Unified Diff: src/core/SkComposeShader.cpp

Issue 198193005: Work (in progress) to make SkShader immutable. (Closed) Base URL: https://skia.googlesource.com/skia.git@shaderGenerator
Patch Set: Created 6 years, 9 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
Index: src/core/SkComposeShader.cpp
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index b5ea63c24c5ed7e60dbe54d671ef9f59c076953d..8aefed4233297c15eab0dc6cf48cd73fbf11f6c4 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -45,6 +45,11 @@ SkComposeShader::~SkComposeShader() {
fShaderA->unref();
}
+size_t SkComposeShader::shaderImplSize() const {
+ return sizeof(ComposeImpl) + fShaderA->shaderImplSize()
+ + fShaderB->shaderImplSize();
+}
+
class SkAutoAlphaRestore {
public:
SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) {
@@ -73,13 +78,11 @@ void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
always let them see opaque alpha, and if the paint really
is translucent, then we apply that after the fact.
- We need to keep the calls to setContext/endContext balanced, since if we
- return false, our endContext() will not be called.
*/
-bool SkComposeShader::setContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix) {
- if (!this->INHERITED::setContext(device, paint, matrix)) {
+bool SkComposeShader::validContext(const SkBitmap& device,
+ const SkPaint& paint,
+ const SkMatrix& matrix) {
+ if (!this->INHERITED::validContext(device, paint, matrix)) {
return false;
}
@@ -90,27 +93,52 @@ bool SkComposeShader::setContext(const SkBitmap& device,
tmpM.setConcat(matrix, this->getLocalMatrix());
+ return fShaderA->validContext(device, paint, tmpM)
+ && fShaderB->validContext(device, paint, tmpM);
+}
+
+SkShaderGenerator::ShaderImpl* SkComposeShader::createShaderImpl(
+ const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix, void* storage) const
+{
+ SkASSERT(this->validContext(device, paint, matrix));
+
+ // we preconcat our localMatrix (if any) with the device matrix
+ // before calling our sub-shaders
+
+ SkMatrix tmpM;
+
+ tmpM.setConcat(matrix, this->getLocalMatrix());
+
SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF);
- bool setContextA = fShaderA->setContext(device, paint, tmpM);
- bool setContextB = fShaderB->setContext(device, paint, tmpM);
- if (!setContextA || !setContextB) {
- if (setContextB) {
- fShaderB->endContext();
- }
- else if (setContextA) {
- fShaderA->endContext();
- }
- this->INHERITED::endContext();
- return false;
- }
- return true;
+ char* aStorage = (char*) storage + sizeof(ComposeImpl);
+ char* bStorage = aStorage + fShaderA->shaderImplSize();
+
+ ShaderImpl* implA = fShaderA->createShaderImpl(device, paint, matrix,
+ aStorage);
+ ShaderImpl* implB = fShaderB->createShaderImpl(device, paint, matrix,
+ bStorage);
+
+ // Both functions must succeed; otherwise validContext should have returned
+ // false.
+ SkASSERT(implA);
+ SkASSERT(implB);
+
+ return SkNEW_PLACEMENT_ARGS(storage, ComposeImpl,
+ (*this, device, paint, matrix, implA, implB));
}
-void SkComposeShader::endContext() {
- fShaderB->endContext();
- fShaderA->endContext();
- this->INHERITED::endContext();
+SkComposeShader::ComposeImpl::ComposeImpl(const SkComposeShader& shader,
+ const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix,
+ ShaderImpl* shaderImplA, ShaderImpl* shaderImplB)
+ : INHERITED(shader, device, paint, matrix)
+ , fShaderImplA(shaderImplA)
+ , fShaderImplB(shaderImplB) {}
+
+void SkComposeShader::ComposeImpl::~ComposeImpl() {
+ fShaderImplA->~ShaderImpl();
+ fShaderImplB->~ShaderImpl();
}
// larger is better (fewer times we have to loop), but we shouldn't
@@ -118,9 +146,7 @@ void SkComposeShader::endContext() {
#define TMP_COLOR_COUNT 64
void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
- SkShader* shaderA = fShaderA;
- SkShader* shaderB = fShaderB;
- SkXfermode* mode = fMode;
+ SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode;
unsigned scale = SkAlpha255To256(this->getPaintAlpha());
SkPMColor tmp[TMP_COLOR_COUNT];
@@ -134,8 +160,8 @@ void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
n = TMP_COLOR_COUNT;
}
- shaderA->shadeSpan(x, y, result, n);
- shaderB->shadeSpan(x, y, tmp, n);
+ fShaderImplA->shadeSpan(x, y, result, n);
+ fShaderImplB->shadeSpan(x, y, tmp, n);
if (256 == scale) {
for (int i = 0; i < n; i++) {
@@ -159,8 +185,8 @@ void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
n = TMP_COLOR_COUNT;
}
- shaderA->shadeSpan(x, y, result, n);
- shaderB->shadeSpan(x, y, tmp, n);
+ fShaderImplA->shadeSpan(x, y, result, n);
+ fShaderImplB->shadeSpan(x, y, tmp, n);
mode->xfer32(result, tmp, n, NULL);
if (256 == scale) {
« no previous file with comments | « src/core/SkBlitter_RGB16.cpp ('k') | src/core/SkCoreBlitters.h » ('j') | src/core/SkShader.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698