return sk_ref_sp(const_cast<SkShader*>(this));
}
+ virtual bool isRasterPipelineOnly() const { return false; }
+
private:
virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
const SkMatrix&, const SkPaint&, const SkMatrix* localM) const;
friend class SkLocalMatrixShader; // sets fLocalMatrix in SkReadBuffer constructor
friend class SkBitmapProcLegacyShader; // calls computeTotalInverse()
friend class SkColorSpaceXformer; // calls makeColorSpace()
+ friend class SkBlitter; // calls isRasterPipelineOnly()
+ friend class SkComposeShader; // calls isRasterPipelineOnly()
typedef SkFlattenable INHERITED;
};
#endif
}
-static bool use_raster_pipeline_blitter(const SkPixmap& device, const SkPaint& paint) {
+bool SkBlitter::UseRasterPipelineBlitter(const SkPixmap& device, const SkPaint& paint) {
#if defined(SK_FORCE_RASTER_PIPELINE_BLITTER)
return true;
#else
if (device.colorSpace()) {
return true;
}
+
+ // ... unless the shader is raster pipeline-only.
+ if (paint.getShader() && paint.getShader()->isRasterPipelineOnly()) {
+ return true;
+ }
+
return device.colorType() != kN32_SkColorType;
#endif
}
return alloc->make<SkA8_Coverage_Blitter>(device, *paint);
}
- if (use_raster_pipeline_blitter(device, *paint)) {
+ if (UseRasterPipelineBlitter(device, *paint)) {
auto blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc);
SkASSERT(blitter);
return blitter;
static SkShader::ContextRec::DstType PreferredShaderDest(const SkImageInfo&);
+ static bool UseRasterPipelineBlitter(const SkPixmap&, const SkPaint&);
+
protected:
SkAutoMalloc fBlitMemory;
};
return true;
}
+bool SkComposeShader::isRasterPipelineOnly() const {
+ return fShaderA->isRasterPipelineOnly() || fShaderB->isRasterPipelineOnly();
+}
+
bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS,
SkArenaAlloc* alloc, const SkMatrix& ctm,
const SkPaint& paint, const SkMatrix* localM) const {
bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
const SkMatrix&, const SkPaint&, const SkMatrix* localM) const override;
+ bool isRasterPipelineOnly() const final;
+
private:
sk_sp<SkShader> fShaderA;
sk_sp<SkShader> fShaderB;
}
#endif
+ bool isRasterPipelineOnly() const final {
+ return fProxyShader->isRasterPipelineOnly();
+ }
+
private:
sk_sp<SkShader> fProxyShader;
SkShader::Context::Context(const SkShader& shader, const ContextRec& rec)
: fShader(shader), fCTM(*rec.fMatrix)
{
+ // We should never use a context for RP-only shaders.
+ SkASSERT(!shader.isRasterPipelineOnly());
+
// Because the context parameters must be valid at this point, we know that the matrix is
// invertible.
SkAssertResult(fShader.computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, &fTotalInverse));
const SkSweepGradient& shader, const ContextRec& rec)
: INHERITED(shader, rec) {}
-// returns angle in a circle [0..2PI) -> [0..255]
+bool SkSweepGradient::isRasterPipelineOnly() const {
#ifdef SK_LEGACY_SWEEP_GRADIENT
+ return false;
+#else
+ return true;
+#endif
+}
+
+// returns angle in a circle [0..2PI) -> [0..255]
static unsigned SkATan2_255(float y, float x) {
// static const float g255Over2PI = 255 / (2 * SK_ScalarPI);
static const float g255Over2PI = 40.584510488433314f;
SkASSERT(ir >= 0 && ir <= 255);
return ir;
}
-#else
-static unsigned SkATan2_255(float y, float x) {
- float yabs = sk_float_abs(y),
- xabs = sk_float_abs(x);
- float little, big;
- std::tie(little, big) = std::minmax(yabs, xabs);
- float a = little/big;
- if (!std::isfinite(a)) {
- return 0;
- }
- SkASSERT(a >=0 && a <= 1);
-
- float s = a * a;
- float r = a*(40.57589784014689f
- + s*(-13.222755844396332f + s*(6.314046289038564f - s*1.7989502668982151f)));
- r = xabs < yabs ? 255/4.0f - r : r;
- r = x < 0.0f ? 255/2.0f - r : r;
- r = y < 0.0f ? 255 - r : r;
-
- int ir = (int)r;
- SkASSERT(ir >= 0 && ir <= 255);
- return ir;
-}
-#endif
void SkSweepGradient::SweepGradientContext::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC,
int count) {
SkMatrix* matrix,
SkRasterPipeline* p) const final;
+ bool isRasterPipelineOnly() const final;
+
private:
const SkPoint fCenter;