SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void* storage) const { char* aStorage = (char*) storage + sizeof(ComposeShaderContext); char* bStorage = aStorage + fShaderA->contextSize(rec); // we preconcat our localMatrix (if any) with the device matrix // before calling our sub-shaders SkMatrix tmpM; tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); // Our sub-shaders need to see opaque, so by combining them we don't double-alphatize the // result. ComposeShader itself will respect the alpha, and post-apply it after calling the // sub-shaders. SkPaint opaquePaint(*rec.fPaint); opaquePaint.setAlpha(0xFF); ContextRec newRec(rec); newRec.fMatrix = &tmpM; newRec.fPaint = &opaquePaint; SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); if (!contextA || !contextB) { safe_call_destructor(contextA); safe_call_destructor(contextB); return nullptr; } return new (storage) ComposeShaderContext(*this, rec, contextA, contextB); }
SkShader::Context* SkComposeShader::onMakeContext( const ContextRec& rec, SkArenaAlloc* alloc) const { // we preconcat our localMatrix (if any) with the device matrix // before calling our sub-shaders SkMatrix tmpM; tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); // Our sub-shaders need to see opaque, so by combining them we don't double-alphatize the // result. ComposeShader itself will respect the alpha, and post-apply it after calling the // sub-shaders. SkPaint opaquePaint(*rec.fPaint); opaquePaint.setAlpha(0xFF); ContextRec newRec(rec); newRec.fMatrix = &tmpM; newRec.fPaint = &opaquePaint; SkShader::Context* contextA = fShaderA->makeContext(newRec, alloc); SkShader::Context* contextB = fShaderB->makeContext(newRec, alloc); if (!contextA || !contextB) { return nullptr; } return alloc->make<ComposeShaderContext>(*this, rec, contextA, contextB); }