// So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
friend class SkLocalMatrixShader;
+ friend class SkBitmapProcShader; // for computeTotalInverse()
typedef SkFlattenable INHERITED;
};
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;
#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) {
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)
{
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)
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;
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;
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;
};
// 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.
#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());
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()) {
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,
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
}
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();