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

Unified Diff: src/core/SkBitmapProcShader.cpp

Issue 1757993002: add support for new bitmapshader context (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: return max of the two sizes, so we can change our mind in MakeContext Created 4 years, 10 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/SkBitmapProcShader.h ('k') | src/image/SkImageShader.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkBitmapProcShader.cpp
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 895922c6b873a388210e0887d768f08dc05646c5..55b7f884be4f71d5cce944d3318b9cc62318d966 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -67,8 +67,8 @@ public:
// but will NOT free the memory.
BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec,
SkBitmapProcState* state)
- : INHERITED(shader, rec, state)
- , fState(state)
+ : INHERITED(shader, rec, state)
+ , fState(state)
{}
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
@@ -116,11 +116,76 @@ private:
};
///////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkLinearBitmapPipeline.h"
+#include "SkPM4f.h"
+#include "SkXfermode.h"
-size_t SkBitmapProcShader::ContextSize(const ContextRec& rec) {
- // The SkBitmapProcState is stored outside of the context object, with the context holding
- // a pointer to it.
- return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
+class LinearPipelineContext : public BitmapProcInfoContext {
+public:
+ // The context takes ownership of the state. It will call its destructor
mtklein 2016/03/03 01:30:37 Having read this code, or at least in a while, it'
reed1 2016/03/03 14:05:25 Done.
+ // but will NOT free the memory.
+ LinearPipelineContext(const SkShader& shader, const SkShader::ContextRec& rec,
+ SkBitmapProcInfo* info)
+ : INHERITED(shader, rec, info)
+ , fPipeline(info->fInvMatrix, info->fFilterQuality, info->fTileModeX, info->fTileModeY,
+ info->fPixmap)
+ {}
+
+ void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override {
+ fPipeline.shadeSpan4f(x, y, dstC, count);
+ }
+
+ void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
+ // we're not necessarily opaque, but we want the proc to treat us as if we are, so we
+ // get memcpy performance/semantics
mtklein 2016/03/03 01:30:37 remind me (or the reader) why this is okay?
reed1 2016/03/03 14:05:25 Done.
+ auto proc = SkXfermode::GetD32Proc(nullptr, SkXfermode::kSrcIsOpaque_D32Flag);
+ const int N = 128;
+ SkPM4f tmp[N];
+
+ while (count > 0) {
+ const int n = SkTMin(count, N);
+ fPipeline.shadeSpan4f(x, y, tmp, n);
+ proc(nullptr, dstC, tmp, n, nullptr);
+ dstC += n;
+ x += n;
+ count -= n;
+ }
+ }
+
+private:
+ SkLinearBitmapPipeline fPipeline;
+
+ typedef BitmapProcInfoContext INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImageInfo& srcInfo) {
+ // These src attributes are not supported in the new 4f context (yet)
+ //
+ if (srcInfo.bytesPerPixel() < 4 ||
+ kRGBA_F16_SkColorType == srcInfo.colorType()) {
+ return false;
+ }
+
+ // These src attributes are only supported in the new 4f context
+ //
+ if (srcInfo.isSRGB() ||
+ kUnpremul_SkAlphaType == srcInfo.alphaType() ||
+ (4 == srcInfo.bytesPerPixel() && kN32_SkColorType != srcInfo.colorType()))
+ {
+ return true;
+ }
+
+ // If we get here, we can reasonably use either context, respect the caller's preference
+ //
+ return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType;
+}
+
+size_t SkBitmapProcShader::ContextSize(const ContextRec& rec, const SkImageInfo& srcInfo) {
+ size_t size0 = sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
+ size_t size1 = sizeof(LinearPipelineContext) + sizeof(SkBitmapProcInfo);
+ return SkTMax(size0, size1);
}
SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
@@ -133,16 +198,32 @@ SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
return nullptr;
}
- void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
- SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy);
-
- SkASSERT(state);
- if (!state->setup(totalInverse, *rec.fPaint)) {
- state->~SkBitmapProcState();
- return nullptr;
+ // Decide if we can/want to use the new linear pipeine
+ bool useLinearPipeline = choose_linear_pipeline(rec, provider.info());
+ if (SkShader::kMirror_TileMode == tmx || SkShader::kMirror_TileMode == tmy) {
+ useLinearPipeline = false;
+ }
+ if (totalInverse.hasPerspective()) {
+ useLinearPipeline = false;
}
- return new (storage) BitmapProcShaderContext(shader, rec, state);
+ if (useLinearPipeline) {
+ void* infoStorage = (char*)storage + sizeof(LinearPipelineContext);
+ SkBitmapProcInfo* info = new (infoStorage) SkBitmapProcInfo(provider, tmx, tmy);
+ if (!info->init(totalInverse, *rec.fPaint)) {
+ info->~SkBitmapProcInfo();
+ return nullptr;
+ }
+ return new (storage) LinearPipelineContext(shader, rec, info);
+ } else {
+ void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
+ SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy);
+ if (!state->setup(totalInverse, *rec.fPaint)) {
+ state->~SkBitmapProcState();
+ return nullptr;
+ }
+ return new (storage) BitmapProcShaderContext(shader, rec, state);
+ }
}
SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {
« no previous file with comments | « src/core/SkBitmapProcShader.h ('k') | src/image/SkImageShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698