Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Unified Diff: src/core/SkLinearBitmapPipeline.cpp

Issue 1868723003: Add specialized rgba8888 unit sampler. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkLinearBitmapPipeline.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkLinearBitmapPipeline.cpp
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index 3410ec1727f54c417e7623209a35ed552f4f419e..dc2ee513ca259b00ac577190c4b1c38f51744fbf 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -62,7 +62,14 @@ public:
virtual void bilerpSpan(Span span, SkScalar y) = 0;
};
-class SkLinearBitmapPipeline::PixelPlacerInterface {
+class SkLinearBitmapPipeline::DestinationInterface {
+public:
+ virtual ~DestinationInterface() { }
+ virtual void setDestination(void* dst, int count) = 0;
+};
+
+class SkLinearBitmapPipeline::PixelPlacerInterface
+ : public SkLinearBitmapPipeline::DestinationInterface {
public:
virtual ~PixelPlacerInterface() { }
// Count is normally not needed, but in these early stages of development it is useful to
@@ -397,7 +404,6 @@ static SkLinearBitmapPipeline::PointProcessorInterface* choose_tiler(
return tileStage->get();
}
-
////////////////////////////////////////////////////////////////////////////////////////////////////
// Source Sampling Stage
template <typename SourceStrategy, typename Next>
@@ -476,6 +482,78 @@ private:
GeneralSampler<SourceStrategy, Next> fSampler;
};
+// RGBA8888UnitRepeatSrc - A sampler that takes advantage of the fact the the src and destination
+// are the same format and do not need in transformations in pixel space. Therefore, there is no
+// need to convert them to HiFi pixel format.
+class RGBA8888UnitRepeat final : public SkLinearBitmapPipeline::SampleProcessorInterface,
+ public SkLinearBitmapPipeline::DestinationInterface {
+public:
+ RGBA8888UnitRepeat(const uint32_t* src, int32_t width)
+ : fSrc{src}, fWidth{width} { }
+
+ void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
+ SkASSERT(fDest + n <= fEnd);
+ // At this point xs and ys should be >= 0, so trunc is the same as floor.
+ Sk4i iXs = SkNx_cast<int>(xs);
+ Sk4i iYs = SkNx_cast<int>(ys);
+
+ if (n >= 1) *fDest++ = *this->pixelAddress(iXs[0], iYs[0]);
+ if (n >= 2) *fDest++ = *this->pixelAddress(iXs[1], iYs[1]);
+ if (n >= 3) *fDest++ = *this->pixelAddress(iXs[2], iYs[2]);
+ }
+
+ void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
+ SkASSERT(fDest + 4 <= fEnd);
+ Sk4i iXs = SkNx_cast<int>(xs);
+ Sk4i iYs = SkNx_cast<int>(ys);
+ *fDest++ = *this->pixelAddress(iXs[0], iYs[0]);
+ *fDest++ = *this->pixelAddress(iXs[1], iYs[1]);
+ *fDest++ = *this->pixelAddress(iXs[2], iYs[2]);
+ *fDest++ = *this->pixelAddress(iXs[3], iYs[3]);
+ }
+
+ void pointSpan(Span span) override {
+ SkASSERT(fDest + span.count() <= fEnd);
+ int32_t x = (int32_t)span.startX();
+ int32_t y = (int32_t)span.startY();
+ const uint32_t* src = this->pixelAddress(x, y);
+ memmove(fDest, src, span.count() * sizeof(uint32_t));
+ fDest += span.count();
+ }
+
+ void repeatSpan(Span span, int32_t repeatCount) override {
+ SkASSERT(fDest + span.count() * repeatCount <= fEnd);
+
+ int32_t x = (int32_t)span.startX();
+ int32_t y = (int32_t)span.startY();
+ const uint32_t* src = this->pixelAddress(x, y);
+ uint32_t* dest = fDest;
+ while (repeatCount --> 0) {
+ memmove(dest, src, span.count() * sizeof(uint32_t));
+ dest += span.count();
+ }
+ fDest = dest;
+ }
+
+ void VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override { SkFAIL("Not Implemented"); }
+
+ void bilerpSpan(Span span, SkScalar y) override { SkFAIL("Not Implemented"); }
+
+ void setDestination(void* dst, int count) override {
+ fDest = static_cast<uint32_t*>(dst);
+ fEnd = fDest + count;
+ }
+
+private:
+ const uint32_t* pixelAddress(int32_t x, int32_t y) {
+ return &fSrc[fWidth * y + x];
f(malita) 2016/04/08 12:58:12 Do we need to worry about row padding here or rowb
herb_g 2016/04/08 13:48:59 I talked with MikeR about this. RowBytes must alwa
+ }
+ const uint32_t* const fSrc;
+ const int32_t fWidth;
+ uint32_t* fDest;
+ uint32_t* fEnd;
+};
+
using Placer = SkLinearBitmapPipeline::PixelPlacerInterface;
template<template <typename, typename> class Sampler>
@@ -531,6 +609,7 @@ template <SkAlphaType alphaType>
class PlaceFPPixel final : public SkLinearBitmapPipeline::PixelPlacerInterface {
public:
PlaceFPPixel(float postAlpha) : fPostAlpha{postAlpha} { }
+
void VECTORCALL placePixel(Sk4f pixel) override {
SkASSERT(fDst + 1 <= fEnd );
PlacePixel(fDst, pixel, 0);
@@ -626,11 +705,14 @@ SkLinearBitmapPipeline::SkLinearBitmapPipeline(
auto tilerStage = choose_tiler(samplerStage,
dimensions, xTile, yTile, filterQuality, dx, &fTiler);
fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage);
+ fLastStage = placementStage;
+
}
void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) {
SkASSERT(count > 0);
- fPixelStage->setDestination(dst, count);
+ fLastStage->setDestination(dst, count);
+
// The count and length arguments start out in a precise relation in order to keep the
// math correct through the different stages. Count is the number of pixel to produce.
// Since the code samples at pixel centers, length is the distance from the center of the
« no previous file with comments | « src/core/SkLinearBitmapPipeline.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698