bool SkBlitter::isNullBlitter() const { return false; }
-bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) {
- return true;
-}
-
const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
return nullptr;
}
fShader->unref();
}
-bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) {
- // Only destroy the old context if we have a new one. We need to ensure to have a
- // live context in fShaderContext because the storage is owned by an SkSmallAllocator
- // outside of this class.
- // The new context will be of the same size as the old one because we use the same
- // shader to create it. It is therefore safe to re-use the storage.
- fShaderContext->~Context();
- SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext);
- if (nullptr == ctx) {
- // Need a valid context in fShaderContext's storage, so we can later (or our caller) call
- // the in-place destructor.
- new (fShaderContext) SkZeroShaderContext(*fShader, rec);
- return false;
- }
- return true;
-}
-
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
virtual bool isNullBlitter() const;
/**
- * Special methods for SkShaderBlitter. On all other classes this is a no-op.
- */
- virtual bool resetShaderContext(const SkShader::ContextRec&);
-
- /**
* Special methods for blitters that can blit more than one row at a time.
* This function returns the number of rows that this blitter could optimally
* process at a time. It is still required to support blitting one scanline
SkShader::Context* shaderContext);
virtual ~SkShaderBlitter();
- /**
- * Create a new shader context and uses it instead of the old one if successful.
- * Will create the context at the same location as the old one (this is safe
- * because the shader itself is unchanged).
- */
- bool resetShaderContext(const SkShader::ContextRec&) override;
-
protected:
uint32_t fShaderFlags;
const SkShader* fShader;
#include "SkDeviceLooper.h"
#include "SkFindAndPlaceGlyph.h"
#include "SkFixed.h"
+#include "SkLocalMatrixShader.h"
#include "SkMaskFilter.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkRRect.h"
#include "SkScan.h"
#include "SkShader.h"
-#include "SkSmallAllocator.h"
#include "SkString.h"
#include "SkStroke.h"
#include "SkStrokeRec.h"
SkTriColorShader::TriColorShaderData verticesSetup = { vertices, colors, &state };
while (vertProc(&state)) {
+ auto* blitterPtr = blitter.get();
+
+ SkTLazy<SkLocalMatrixShader> localShader;
+ SkTLazy<SkAutoBlitterChoose> localBlitter;
+
if (textures) {
SkMatrix tempM;
if (texture_to_matrix(state, vertices, textures, &tempM)) {
- SkShader::ContextRec rec(p, *fMatrix, &tempM,
- SkBlitter::PreferredShaderDest(fDst.info()),
- fDst.colorSpace());
- if (!blitter->resetShaderContext(rec)) {
+ localShader.init(p.refShader(), tempM);
+
+ SkPaint localPaint(p);
+ localPaint.setShader(sk_ref_sp(localShader.get()));
+
+ blitterPtr = localBlitter.init(fDst, *fMatrix, localPaint)->get();
+ if (blitterPtr->isNullBlitter()) {
continue;
}
}
SkPoint tmp[] = {
devVerts[state.f0], devVerts[state.f1], devVerts[state.f2]
};
- SkScan::FillTriangle(tmp, *fRC, blitter.get());
- triShader->bindSetupData(NULL);
+ SkScan::FillTriangle(tmp, *fRC, blitterPtr);
+ triShader->bindSetupData(nullptr);
}
} else {
// no colors[] and no texture, stroke hairlines with paint's color.