aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkColorFilter.cpp2
-rw-r--r--src/core/SkModeColorFilter.cpp4
-rw-r--r--src/core/SkPM4fPriv.h2
-rw-r--r--src/core/SkRasterPipeline.cpp38
-rw-r--r--src/core/SkRasterPipeline.h7
-rw-r--r--src/core/SkRasterPipelineBlitter.cpp18
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;
}