aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkShader.h1
-rw-r--r--src/core/SkBitmapController.h8
-rw-r--r--src/core/SkBitmapProcShader.cpp32
-rw-r--r--src/core/SkBitmapProcShader.h16
-rw-r--r--src/core/SkBitmapProcState.cpp20
-rw-r--r--src/core/SkBitmapProcState.h5
-rw-r--r--src/core/SkLightingShader.cpp14
7 files changed, 62 insertions, 34 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 47934dd9ad..a95e7e713e 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -439,6 +439,7 @@ private:
// So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
friend class SkLocalMatrixShader;
+ friend class SkBitmapProcShader; // for computeTotalInverse()
typedef SkFlattenable INHERITED;
};
diff --git a/src/core/SkBitmapController.h b/src/core/SkBitmapController.h
index 435d9e72af..e6c4443872 100644
--- a/src/core/SkBitmapController.h
+++ b/src/core/SkBitmapController.h
@@ -16,8 +16,12 @@
class SkBitmapProvider {
public:
- SkBitmapProvider(const SkBitmap& bm) : fBitmap(bm) {}
- SkBitmapProvider(const SkImage* img) : fImage(SkRef(img)) {}
+ explicit SkBitmapProvider(const SkBitmap& bm) : fBitmap(bm) {}
+ explicit SkBitmapProvider(const SkImage* img) : fImage(SkSafeRef(img)) {}
+ SkBitmapProvider(const SkBitmapProvider& other)
+ : fBitmap(other.fBitmap)
+ , fImage(SkSafeRef(other.fImage.get()))
+ {}
int width() const;
int height() const;
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 97abbf9675..36bfb1e7d6 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -19,6 +19,12 @@
#include "effects/GrSimpleTextureEffect.h"
#endif
+size_t SkBitmapProcShader::ContextSize() {
+ // The SkBitmapProcState is stored outside of the context object, with the context holding
+ // a pointer to it.
+ return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
+}
+
SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
const SkMatrix* localMatrix)
: INHERITED(localMatrix) {
@@ -70,36 +76,36 @@ bool SkBitmapProcShader::isOpaque() const {
return fRawBitmap.isOpaque();
}
-SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {
+SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
+ TileMode tmx, TileMode tmy,
+ const SkBitmap& bitmap,
+ const ContextRec& rec, void* storage) {
SkMatrix totalInverse;
// Do this first, so we know the matrix can be inverted.
- if (!this->computeTotalInverse(rec, &totalInverse)) {
+ if (!shader.computeTotalInverse(rec, &totalInverse)) {
return nullptr;
}
void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
- SkBitmapProcState* state = new (stateStorage) SkBitmapProcState;
+ SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(SkBitmapProvider(bitmap),
+ tmx, tmy);
SkASSERT(state);
- state->fTileModeX = fTileModeX;
- state->fTileModeY = fTileModeY;
- state->fOrigBitmap = fRawBitmap;
if (!state->chooseProcs(totalInverse, *rec.fPaint)) {
state->~SkBitmapProcState();
return nullptr;
}
- return new (storage) BitmapProcShaderContext(*this, rec, state);
+ return new (storage) BitmapProcShaderContext(shader, rec, state);
}
-size_t SkBitmapProcShader::contextSize() const {
- // 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::onCreateContext(const ContextRec& rec, void* storage) const {
+ return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, fRawBitmap, rec, storage);
}
-SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
- const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state)
+SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(const SkShader& shader,
+ const ContextRec& rec,
+ SkBitmapProcState* state)
: INHERITED(shader, rec)
, fState(state)
{
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 63985c06c5..9e90f9faac 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -22,7 +22,7 @@ public:
bool isOpaque() const override;
- size_t contextSize() const override;
+ size_t contextSize() const override { return ContextSize(); }
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader)
@@ -33,11 +33,12 @@ public:
GrProcessorDataManager*) const override;
#endif
+protected:
class BitmapProcShaderContext : public SkShader::Context {
public:
// The context takes ownership of the state. It will call its destructor
// but will NOT free the memory.
- BitmapProcShaderContext(const SkBitmapProcShader&, const ContextRec&, SkBitmapProcState*);
+ BitmapProcShaderContext(const SkShader&, const ContextRec&, SkBitmapProcState*);
~BitmapProcShaderContext() override;
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
@@ -52,8 +53,7 @@ public:
typedef SkShader::Context INHERITED;
};
-
-protected:
+
void flatten(SkWriteBuffer&) const override;
Context* onCreateContext(const ContextRec&, void* storage) const override;
bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override;
@@ -62,6 +62,12 @@ protected:
uint8_t fTileModeX, fTileModeY;
private:
+ friend class SkImageShader;
+
+ static size_t ContextSize();
+ static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy, const SkBitmap&,
+ const ContextRec&, void* storage);
+
typedef SkShader INHERITED;
};
@@ -70,7 +76,7 @@ private:
// an Sk3DBlitter in SkDraw.cpp
// Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not
// yet found a situation where the size below isn't big enough.
-typedef SkSmallAllocator<3, 1152> SkTBlitterAllocator;
+typedef SkSmallAllocator<3, 1160> SkTBlitterAllocator;
// If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive
// the SkShader.
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index 31109aaee9..5ec6721436 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -37,7 +37,23 @@ extern void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const SkBitmapProcState&
#include "SkBitmapProcState_filter.h"
#include "SkBitmapProcState_procs.h"
-SkBitmapProcState::SkBitmapProcState() : fBMState(nullptr) {}
+SkBitmapProcState::SkBitmapProcState(const SkBitmapProvider& provider,
+ SkShader::TileMode tmx, SkShader::TileMode tmy)
+ : fProvider(provider)
+ , fBMState(nullptr)
+{
+ fTileModeX = tmx;
+ fTileModeY = tmy;
+}
+
+SkBitmapProcState::SkBitmapProcState(const SkBitmap& bm,
+ SkShader::TileMode tmx, SkShader::TileMode tmy)
+ : fProvider(SkBitmapProvider(bm))
+ , fBMState(nullptr)
+{
+ fTileModeX = tmx;
+ fTileModeY = tmy;
+}
SkBitmapProcState::~SkBitmapProcState() {
SkInPlaceDeleteCheck(fBMState, fBMStateStorage.get());
@@ -119,7 +135,7 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
fFilterLevel = paint.getFilterQuality();
SkDefaultBitmapController controller;
- fBMState = controller.requestBitmap(fOrigBitmap, inv, paint.getFilterQuality(),
+ fBMState = controller.requestBitmap(fProvider, inv, paint.getFilterQuality(),
fBMStateStorage.get(), fBMStateStorage.size());
// Note : we allow the controller to return an empty (zero-dimension) result. Should we?
if (nullptr == fBMState || fBMState->pixmap().info().isEmpty()) {
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 814c79a92c..b66299cbff 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -25,7 +25,8 @@ typedef SkFixed3232 SkFractionalInt;
class SkPaint;
struct SkBitmapProcState {
- SkBitmapProcState();
+ SkBitmapProcState(const SkBitmapProvider&, SkShader::TileMode tmx, SkShader::TileMode tmy);
+ SkBitmapProcState(const SkBitmap&, SkShader::TileMode tmx, SkShader::TileMode tmy);
~SkBitmapProcState();
typedef void (*ShaderProc32)(const SkBitmapProcState&, int x, int y,
@@ -128,7 +129,7 @@ private:
SampleProc32 fSampleProc32; // chooseProcs
SampleProc16 fSampleProc16; // chooseProcs
- SkBitmap fOrigBitmap; // CONSTRUCTOR
+ const SkBitmapProvider fProvider;
enum {
kBMStateSize = 136 // found by inspection. if too small, we will call new/delete
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp
index 4ab233a828..2907dba7d5 100644
--- a/src/core/SkLightingShader.cpp
+++ b/src/core/SkLightingShader.cpp
@@ -664,24 +664,18 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
}
void* diffuseStateStorage = (char*)storage + sizeof(LightingShaderContext);
- SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState;
+ SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState(fDiffuseMap,
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
SkASSERT(diffuseState);
-
- diffuseState->fTileModeX = SkShader::kClamp_TileMode;
- diffuseState->fTileModeY = SkShader::kClamp_TileMode;
- diffuseState->fOrigBitmap = fDiffuseMap;
if (!diffuseState->chooseProcs(diffTotalInv, *rec.fPaint)) {
diffuseState->~SkBitmapProcState();
return nullptr;
}
void* normalStateStorage = (char*)storage + sizeof(LightingShaderContext) + sizeof(SkBitmapProcState);
- SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState;
+ SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState(fNormalMap,
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
SkASSERT(normalState);
-
- normalState->fTileModeX = SkShader::kClamp_TileMode;
- normalState->fTileModeY = SkShader::kClamp_TileMode;
- normalState->fOrigBitmap = fNormalMap;
if (!normalState->chooseProcs(normTotalInv, *rec.fPaint)) {
diffuseState->~SkBitmapProcState();
normalState->~SkBitmapProcState();