diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkColorFilter.cpp | 2 | ||||
-rw-r--r-- | src/core/SkModeColorFilter.cpp | 4 | ||||
-rw-r--r-- | src/core/SkPM4fPriv.h | 2 | ||||
-rw-r--r-- | src/core/SkRasterPipeline.cpp | 38 | ||||
-rw-r--r-- | src/core/SkRasterPipeline.h | 7 | ||||
-rw-r--r-- | src/core/SkRasterPipelineBlitter.cpp | 18 |
6 files changed, 57 insertions, 14 deletions
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index ecfa54be66..6cc8ae8161 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -69,7 +69,7 @@ SkColor4f SkColorFilter::filterColor4f(const SkColor4f& c) const { SkSTArenaAlloc<128> alloc; SkRasterPipeline pipeline(&alloc); - pipeline.append(SkRasterPipeline::constant_color, &src); + pipeline.append_uniform_color(&alloc, src); this->onAppendStages(&pipeline, nullptr, &alloc, c.fA == 1); SkPM4f* dstPtr = &dst; pipeline.append(SkRasterPipeline::store_f32, &dstPtr); diff --git a/src/core/SkModeColorFilter.cpp b/src/core/SkModeColorFilter.cpp index ca86675c95..089bcd39e8 100644 --- a/src/core/SkModeColorFilter.cpp +++ b/src/core/SkModeColorFilter.cpp @@ -77,10 +77,8 @@ void SkModeColorFilter::onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkArenaAlloc* scratch, bool shaderIsOpaque) const { - auto color = scratch->make<SkPM4f>(SkPM4f_from_SkColor(fColor, dst)); - p->append(SkRasterPipeline::move_src_dst); - p->append(SkRasterPipeline::constant_color, color); + p->append_uniform_color(scratch, SkPM4f_from_SkColor(fColor, dst)); SkBlendMode_AppendStages(fMode, p); } diff --git a/src/core/SkPM4fPriv.h b/src/core/SkPM4fPriv.h index 700e1280da..44f6603cfe 100644 --- a/src/core/SkPM4fPriv.h +++ b/src/core/SkPM4fPriv.h @@ -153,7 +153,7 @@ static inline SkColor4f to_colorspace(const SkColor4f& c, SkColorSpace* src, SkC float scratch_matrix_3x4[12]; SkRasterPipeline_<256> p; - p.append(SkRasterPipeline::constant_color, color4f_ptr); + p.append(SkRasterPipeline::uniform_color, color4f_ptr); append_gamut_transform(&p, scratch_matrix_3x4, src, dst, kUnpremul_SkAlphaType); p.append(SkRasterPipeline::store_f32, &color4f_ptr); diff --git a/src/core/SkRasterPipeline.cpp b/src/core/SkRasterPipeline.cpp index 05fa75f062..a7b25d7ef9 100644 --- a/src/core/SkRasterPipeline.cpp +++ b/src/core/SkRasterPipeline.cpp @@ -6,6 +6,7 @@ */ #include "SkRasterPipeline.h" +#include "SkPM4f.h" SkRasterPipeline::SkRasterPipeline(SkArenaAlloc* alloc) : fAlloc(alloc) { this->reset(); @@ -61,6 +62,43 @@ void SkRasterPipeline::dump() const { SkDebugf("\n"); } +//#define TRACK_COLOR_HISTOGRAM +#ifdef TRACK_COLOR_HISTOGRAM + static int gBlack; + static int gWhite; + static int gColor; + #define INC_BLACK gBlack++ + #define INC_WHITE gWhite++ + #define INC_COLOR gColor++ +#else + #define INC_BLACK + #define INC_WHITE + #define INC_COLOR +#endif + +void SkRasterPipeline::append_uniform_color(SkArenaAlloc* alloc, const SkPM4f& c) { + if (c.r() == 0 && c.g() == 0 && c.b() == 0 && c.a() == 1) { + this->append(black_color); + INC_BLACK; + } else if (c.r() == 1 && c.g() == 1 && c.b() == 1 && c.a() == 1) { + this->append(white_color); + INC_WHITE; + } else { + float* storage = alloc->makeArray<float>(4); + memcpy(storage, c.fVec, 4 * sizeof(float)); + this->append(uniform_color, storage); + INC_COLOR; + } + +#ifdef TRACK_COLOR_HISTOGRAM + SkDebugf("B=%d W=%d C=%d\n", gBlack, gWhite, gColor); +#endif +} + +#undef INC_BLACK +#undef INC_WHITE +#undef INC_COLOR + // It's pretty easy to start with sound premultiplied linear floats, pack those // to sRGB encoded bytes, then read them back to linear floats and find them not // quite premultiplied, with a color channel just a smidge greater than the alpha diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h index 2374201e05..fee5346bf0 100644 --- a/src/core/SkRasterPipeline.h +++ b/src/core/SkRasterPipeline.h @@ -17,6 +17,7 @@ #include <vector> struct SkJumper_constants; +struct SkPM4f; /** * SkRasterPipeline provides a cheap way to chain together a pixel processing pipeline. @@ -42,7 +43,8 @@ struct SkJumper_constants; M(unpremul) M(premul) \ M(set_rgb) M(swap_rb) \ M(from_srgb) M(from_srgb_dst) M(to_srgb) \ - M(constant_color) M(seed_shader) M(dither) \ + M(black_color) M(white_color) M(uniform_color) \ + M(seed_shader) M(dither) \ M(gather_i8) \ M(load_a8) M(load_a8_dst) M(store_a8) M(gather_a8) \ M(load_g8) M(load_g8_dst) M(gather_g8) \ @@ -132,6 +134,9 @@ public: // the type of matrix. void append_matrix(SkArenaAlloc*, const SkMatrix&); + // Appends a stage for the uniform color. Tries to optimize the stage based on the color. + void append_uniform_color(SkArenaAlloc*, const SkPM4f& color); + bool empty() const { return fStages == nullptr; } private: diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp index fff3d8ba71..b35bfadcdb 100644 --- a/src/core/SkRasterPipelineBlitter.cpp +++ b/src/core/SkRasterPipelineBlitter.cpp @@ -91,21 +91,21 @@ SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, const SkMatrix& ctm, SkArenaAlloc* alloc) { SkColorSpace* dstCS = dst.colorSpace(); - auto paintColor = alloc->make<SkPM4f>(SkPM4f_from_SkColor(paint.getColor(), dstCS)); + SkPM4f paintColor = SkPM4f_from_SkColor(paint.getColor(), dstCS); auto shader = as_SB(paint.getShader()); SkRasterPipeline_<256> shaderPipeline; if (!shader) { // Having no shader makes things nice and easy... just use the paint color. - shaderPipeline.append(SkRasterPipeline::constant_color, paintColor); - bool is_opaque = paintColor->a() == 1.0f, + shaderPipeline.append_uniform_color(alloc, paintColor); + bool is_opaque = paintColor.a() == 1.0f, is_constant = true; return SkRasterPipelineBlitter::Create(dst, paint, alloc, shaderPipeline, nullptr, is_opaque, is_constant); } - bool is_opaque = shader->isOpaque() && paintColor->a() == 1.0f; + bool is_opaque = shader->isOpaque() && paintColor.a() == 1.0f; bool is_constant = shader->isConstant(); // Check whether the shader prefers to run in burst mode. @@ -118,8 +118,9 @@ SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, } if (shader->appendStages(&shaderPipeline, dstCS, alloc, ctm, paint)) { - if (paintColor->a() != 1.0f) { - shaderPipeline.append(SkRasterPipeline::scale_1_float, &paintColor->fVec[SkPM4f::A]); + if (paintColor.a() != 1.0f) { + shaderPipeline.append(SkRasterPipeline::scale_1_float, + alloc->make<float>(paintColor.a())); } return SkRasterPipelineBlitter::Create(dst, paint, alloc, shaderPipeline, nullptr, is_opaque, is_constant); @@ -190,11 +191,12 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, // A pipeline that's still constant here can collapse back into a constant color. if (is_constant) { - auto constantColor = alloc->make<SkPM4f>(); + SkPM4f storage; + SkPM4f* constantColor = &storage; colorPipeline->append(SkRasterPipeline::store_f32, &constantColor); colorPipeline->run(0,0,1); colorPipeline->reset(); - colorPipeline->append(SkRasterPipeline::constant_color, constantColor); + colorPipeline->append_uniform_color(alloc, *constantColor); is_opaque = constantColor->a() == 1.0f; } |