fission bitmapprocstate
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1753903002
CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot
Review URL: https://codereview.chromium.org/1753903002
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 804c688..895922c 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -20,12 +20,138 @@
#include "effects/GrSimpleTextureEffect.h"
#endif
-size_t SkBitmapProcShader::ContextSize() {
+static bool only_scale_and_translate(const SkMatrix& matrix) {
+ unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
+ return (matrix.getType() & ~mask) == 0;
+}
+
+class BitmapProcInfoContext : public SkShader::Context {
+public:
+ // The context takes ownership of the info. It will call its destructor
+ // but will NOT free the memory.
+ BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& rec,
+ SkBitmapProcInfo* info)
+ : INHERITED(shader, rec)
+ , fInfo(info)
+ {
+ fFlags = 0;
+ if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) {
+ fFlags |= SkShader::kOpaqueAlpha_Flag;
+ }
+
+ if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) {
+ fFlags |= SkShader::kConstInY32_Flag;
+ }
+ }
+
+ ~BitmapProcInfoContext() override {
+ // The bitmap proc state has been created outside of the context on memory that will be freed
+ // elsewhere. Only call the destructor but leave the freeing of the memory to the caller.
+ fInfo->~SkBitmapProcInfo();
+ }
+
+ uint32_t getFlags() const override { return fFlags; }
+
+private:
+ SkBitmapProcInfo* fInfo;
+ uint32_t fFlags;
+
+ typedef SkShader::Context INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class BitmapProcShaderContext : public BitmapProcInfoContext {
+public:
+ // The context takes ownership of the state. It will call its destructor
+ // but will NOT free the memory.
+ BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec,
+ SkBitmapProcState* state)
+ : INHERITED(shader, rec, state)
+ , fState(state)
+ {}
+
+ void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
+ const SkBitmapProcState& state = *fState;
+ if (state.getShaderProc32()) {
+ state.getShaderProc32()(&state, x, y, dstC, count);
+ return;
+ }
+
+ const int BUF_MAX = 128;
+ uint32_t buffer[BUF_MAX];
+ SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
+ SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
+ const int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
+
+ SkASSERT(state.fPixmap.addr());
+
+ for (;;) {
+ int n = SkTMin(count, max);
+ SkASSERT(n > 0 && n < BUF_MAX*2);
+ mproc(state, buffer, n, x, y);
+ sproc(state, buffer, n, dstC);
+
+ if ((count -= n) == 0) {
+ break;
+ }
+ SkASSERT(count > 0);
+ x += n;
+ dstC += n;
+ }
+ }
+
+ ShadeProc asAShadeProc(void** ctx) override {
+ if (fState->getShaderProc32()) {
+ *ctx = fState;
+ return (ShadeProc)fState->getShaderProc32();
+ }
+ return nullptr;
+ }
+
+private:
+ SkBitmapProcState* fState;
+
+ typedef BitmapProcInfoContext INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+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);
}
+SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
+ TileMode tmx, TileMode tmy,
+ const SkBitmapProvider& provider,
+ const ContextRec& rec, void* storage) {
+ SkMatrix totalInverse;
+ // Do this first, so we know the matrix can be inverted.
+ if (!shader.computeTotalInverse(rec, &totalInverse)) {
+ 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;
+ }
+
+ return new (storage) BitmapProcShaderContext(shader, rec, state);
+}
+
+SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {
+ return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY,
+ SkBitmapProvider(fRawBitmap), rec, storage);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
const SkMatrix* localMatrix)
: INHERITED(localMatrix) {
@@ -72,123 +198,7 @@
return fRawBitmap.isOpaque();
}
-SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
- TileMode tmx, TileMode tmy,
- const SkBitmapProvider& provider,
- const ContextRec& rec, void* storage) {
- SkMatrix totalInverse;
- // Do this first, so we know the matrix can be inverted.
- if (!shader.computeTotalInverse(rec, &totalInverse)) {
- return nullptr;
- }
-
- void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
- SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy);
-
- SkASSERT(state);
- if (!state->chooseProcs(totalInverse, *rec.fPaint)) {
- state->~SkBitmapProcState();
- return nullptr;
- }
-
- return new (storage) BitmapProcShaderContext(shader, rec, state);
-}
-
-SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {
- return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY,
- SkBitmapProvider(fRawBitmap), rec, storage);
-}
-
-static bool only_scale_and_translate(const SkMatrix& matrix) {
- unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
- return (matrix.getType() & ~mask) == 0;
-}
-
-SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(const SkShader& shader,
- const ContextRec& rec,
- SkBitmapProcState* state)
- : INHERITED(shader, rec)
- , fState(state)
-{
- fFlags = 0;
- if (fState->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) {
- fFlags |= kOpaqueAlpha_Flag;
- }
-
- if (1 == fState->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) {
- fFlags |= kConstInY32_Flag;
- }
-}
-
-SkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() {
- // The bitmap proc state has been created outside of the context on memory that will be freed
- // elsewhere. Only call the destructor but leave the freeing of the memory to the caller.
- fState->~SkBitmapProcState();
-}
-
-#define BUF_MAX 128
-
-#define TEST_BUFFER_OVERRITEx
-
-#ifdef TEST_BUFFER_OVERRITE
- #define TEST_BUFFER_EXTRA 32
- #define TEST_PATTERN 0x88888888
-#else
- #define TEST_BUFFER_EXTRA 0
-#endif
-
-void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMColor dstC[],
- int count) {
- const SkBitmapProcState& state = *fState;
- if (state.getShaderProc32()) {
- state.getShaderProc32()(&state, x, y, dstC, count);
- return;
- }
-
- uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
- SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
- SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
- int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
-
- SkASSERT(state.fPixmap.addr());
-
- for (;;) {
- int n = count;
- if (n > max) {
- n = max;
- }
- SkASSERT(n > 0 && n < BUF_MAX*2);
-#ifdef TEST_BUFFER_OVERRITE
- for (int i = 0; i < TEST_BUFFER_EXTRA; i++) {
- buffer[BUF_MAX + i] = TEST_PATTERN;
- }
-#endif
- mproc(state, buffer, n, x, y);
-#ifdef TEST_BUFFER_OVERRITE
- for (int j = 0; j < TEST_BUFFER_EXTRA; j++) {
- SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN);
- }
-#endif
- sproc(state, buffer, n, dstC);
-
- if ((count -= n) == 0) {
- break;
- }
- SkASSERT(count > 0);
- x += n;
- dstC += n;
- }
-}
-
-SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asAShadeProc(void** ctx) {
- if (fState->getShaderProc32()) {
- *ctx = fState;
- return (ShadeProc)fState->getShaderProc32();
- }
- return nullptr;
-}
-
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
#include "SkUnPreMultiply.h"
#include "SkColorShader.h"