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
This commit is contained in:
reed 2016-03-02 09:49:02 -08:00 committed by Commit bot
parent 391395dcfb
commit 05a5647efe
12 changed files with 259 additions and 254 deletions

View File

@ -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 @@ bool SkBitmapProcShader::isOpaque() const {
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"

View File

@ -1,4 +1,3 @@
/*
* Copyright 2006 The Android Open Source Project
*
@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
#ifndef SkBitmapProcShader_DEFINED
#define SkBitmapProcShader_DEFINED
@ -23,7 +21,7 @@ public:
bool isOpaque() const override;
size_t contextSize(const ContextRec&) const override { return ContextSize(); }
size_t contextSize(const ContextRec& rec) const override { return ContextSize(rec); }
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader)
@ -34,25 +32,6 @@ public:
#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 SkShader&, const ContextRec&, SkBitmapProcState*);
~BitmapProcShaderContext() override;
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
ShadeProc asAShadeProc(void** ctx) override;
uint32_t getFlags() const override { return fFlags; }
private:
SkBitmapProcState* fState;
uint32_t fFlags;
typedef SkShader::Context INHERITED;
};
void flatten(SkWriteBuffer&) const override;
Context* onCreateContext(const ContextRec&, void* storage) const override;
bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override;
@ -63,7 +42,7 @@ protected:
private:
friend class SkImageShader;
static size_t ContextSize();
static size_t ContextSize(const ContextRec&);
static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy,
const SkBitmapProvider&, const ContextRec&, void* storage);

View File

@ -36,25 +36,23 @@ extern void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const void*, int, int, u
#include "SkBitmapProcState_filter.h"
#include "SkBitmapProcState_procs.h"
SkBitmapProcState::SkBitmapProcState(const SkBitmapProvider& provider,
SkShader::TileMode tmx, SkShader::TileMode tmy)
SkBitmapProcInfo::SkBitmapProcInfo(const SkBitmapProvider& provider,
SkShader::TileMode tmx, SkShader::TileMode tmy)
: fProvider(provider)
, fTileModeX(tmx)
, fTileModeY(tmy)
, fBMState(nullptr)
{
fTileModeX = tmx;
fTileModeY = tmy;
}
{}
SkBitmapProcState::SkBitmapProcState(const SkBitmap& bm,
SkShader::TileMode tmx, SkShader::TileMode tmy)
SkBitmapProcInfo::SkBitmapProcInfo(const SkBitmap& bm,
SkShader::TileMode tmx, SkShader::TileMode tmy)
: fProvider(SkBitmapProvider(bm))
, fTileModeX(tmx)
, fTileModeY(tmy)
, fBMState(nullptr)
{
fTileModeX = tmx;
fTileModeY = tmy;
}
{}
SkBitmapProcState::~SkBitmapProcState() {
SkBitmapProcInfo::~SkBitmapProcInfo() {
SkInPlaceDeleteCheck(fBMState, fBMStateStorage.get());
}
@ -118,25 +116,16 @@ static bool valid_for_filtering(unsigned dimension) {
return (dimension & ~0x3FFF) == 0;
}
/*
* Analyze filter-quality and matrix, and decide how to implement that.
*
* In general, we cascade down the request level [ High ... None ]
* - for a given level, if we can fulfill it, fine, else
* - else we downgrade to the next lower level and try again.
* We can always fulfill requests for Low and None
* - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack
* and may be removed.
*/
bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
fPixmap.reset();
fInvMatrix = inv;
fFilterLevel = paint.getFilterQuality();
bool SkBitmapProcInfo::init(const SkMatrix& inv, const SkPaint& paint) {
const int origW = fProvider.info().width();
const int origH = fProvider.info().height();
fPixmap.reset();
fInvMatrix = inv;
fFilterQuality = paint.getFilterQuality();
bool allow_ignore_fractional_translate = true; // historical default
if (kMedium_SkFilterQuality == fFilterLevel) {
if (kMedium_SkFilterQuality == fFilterQuality) {
allow_ignore_fractional_translate = false;
}
@ -149,9 +138,10 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
}
fPixmap = fBMState->pixmap();
fInvMatrix = fBMState->invMatrix();
fFilterLevel = fBMState->quality();
fPaintColor = paint.getColor();
fFilterQuality = fBMState->quality();
SkASSERT(fPixmap.addr());
bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0;
bool clampClamp = SkShader::kClamp_TileMode == fTileModeX &&
SkShader::kClamp_TileMode == fTileModeY;
@ -179,30 +169,14 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
SkMatrix forward;
if (fInvMatrix.invert(&forward)) {
if ((clampClamp && allow_ignore_fractional_translate)
? just_trans_clamp(forward, fPixmap)
: just_trans_general(forward)) {
? just_trans_clamp(forward, fPixmap)
: just_trans_general(forward)) {
fInvMatrix.setTranslate(-forward.getTranslateX(), -forward.getTranslateY());
}
}
}
fInvProc = fInvMatrix.getMapXYProc();
fInvType = fInvMatrix.getType();
fInvSx = SkScalarToFixed(fInvMatrix.getScaleX());
fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix.getScaleX());
fInvKy = SkScalarToFixed(fInvMatrix.getSkewY());
fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix.getSkewY());
fAlphaScale = SkAlpha255To256(paint.getAlpha());
fShaderProc32 = nullptr;
fShaderProc16 = nullptr;
fSampleProc32 = nullptr;
// recompute the triviality of the matrix here because we may have
// changed it!
trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0;
fInvType = fInvMatrix.getType();
// If our target pixmap is the same as the original, then we revert back to legacy behavior
// and allow the code to ignore fractional translate.
@ -214,22 +188,51 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
allow_ignore_fractional_translate = true;
}
if (kLow_SkFilterQuality == fFilterLevel && allow_ignore_fractional_translate) {
if (kLow_SkFilterQuality == fFilterQuality && allow_ignore_fractional_translate) {
// Only try bilerp if the matrix is "interesting" and
// the image has a suitable size.
if (fInvType <= SkMatrix::kTranslate_Mask ||
!valid_for_filtering(fPixmap.width() | fPixmap.height()))
{
fFilterLevel = kNone_SkFilterQuality;
fFilterQuality = kNone_SkFilterQuality;
}
}
return this->chooseScanlineProcs(trivialMatrix, clampClamp, paint);
return true;
}
bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp,
const SkPaint& paint) {
/*
* Analyze filter-quality and matrix, and decide how to implement that.
*
* In general, we cascade down the request level [ High ... None ]
* - for a given level, if we can fulfill it, fine, else
* - else we downgrade to the next lower level and try again.
* We can always fulfill requests for Low and None
* - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack
* and may be removed.
*/
bool SkBitmapProcState::chooseProcs() {
fInvProc = fInvMatrix.getMapXYProc();
fInvSx = SkScalarToFixed(fInvMatrix.getScaleX());
fInvSxFractionalInt = SkScalarToFractionalInt(fInvMatrix.getScaleX());
fInvKy = SkScalarToFixed(fInvMatrix.getSkewY());
fInvKyFractionalInt = SkScalarToFractionalInt(fInvMatrix.getSkewY());
fAlphaScale = SkAlpha255To256(SkColorGetA(fPaintColor));
fShaderProc32 = nullptr;
fShaderProc16 = nullptr;
fSampleProc32 = nullptr;
const bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0;
const bool clampClamp = SkShader::kClamp_TileMode == fTileModeX &&
SkShader::kClamp_TileMode == fTileModeY;
return this->chooseScanlineProcs(trivialMatrix, clampClamp);
}
bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp) {
fMatrixProc = this->chooseMatrixProc(trivialMatrix);
// TODO(dominikg): SkASSERT(fMatrixProc) instead? chooseMatrixProc never returns nullptr.
if (nullptr == fMatrixProc) {
@ -244,7 +247,7 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp,
// still set to HQ by the time we get here, then we must have installed
// the shader procs above and can skip all this.
if (fFilterLevel < kHigh_SkFilterQuality) {
if (fFilterQuality < kHigh_SkFilterQuality) {
int index = 0;
if (fAlphaScale < 256) { // note: this distinction is not used for D16
@ -253,7 +256,7 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp,
if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
index |= 2;
}
if (fFilterLevel > kNone_SkFilterQuality) {
if (fFilterQuality > kNone_SkFilterQuality) {
index |= 4;
}
// bits 3,4,5 encoding the source bitmap format
@ -281,11 +284,11 @@ bool SkBitmapProcState::chooseScanlineProcs(bool trivialMatrix, bool clampClamp,
break;
case kAlpha_8_SkColorType:
index |= 32;
fPaintPMColor = SkPreMultiplyColor(paint.getColor());
fPaintPMColor = SkPreMultiplyColor(fPaintColor);
break;
case kGray_8_SkColorType:
index |= 40;
fPaintPMColor = SkPreMultiplyColor(paint.getColor());
fPaintPMColor = SkPreMultiplyColor(fPaintColor);
break;
default:
// TODO(dominikg): Should we ever get here? SkASSERT(false) instead?
@ -381,7 +384,7 @@ static void Clamp_S32_D32_nofilter_trans_shaderproc(const void* sIn,
SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
SkASSERT(s.fInvKy == 0);
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
SkASSERT(kNone_SkFilterQuality == s.fFilterQuality);
const int maxX = s.fPixmap.width() - 1;
const int maxY = s.fPixmap.height() - 1;
@ -444,7 +447,7 @@ static void Repeat_S32_D32_nofilter_trans_shaderproc(const void* sIn,
SkASSERT(((s.fInvType & ~SkMatrix::kTranslate_Mask)) == 0);
SkASSERT(s.fInvKy == 0);
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
SkASSERT(kNone_SkFilterQuality == s.fFilterQuality);
const int stopX = s.fPixmap.width();
const int stopY = s.fPixmap.height();
@ -479,7 +482,7 @@ static void S32_D32_constX_shaderproc(const void* sIn,
int iY1 SK_INIT_TO_AVOID_WARNING;
int iSubY SK_INIT_TO_AVOID_WARNING;
if (kNone_SkFilterQuality != s.fFilterLevel) {
if (kNone_SkFilterQuality != s.fFilterQuality) {
SkBitmapProcState::MatrixProc mproc = s.getMatrixProc();
uint32_t xy[2];
@ -556,7 +559,7 @@ static void S32_D32_constX_shaderproc(const void* sIn,
const SkPMColor* row0 = s.fPixmap.addr32(0, iY0);
SkPMColor color;
if (kNone_SkFilterQuality != s.fFilterLevel) {
if (kNone_SkFilterQuality != s.fFilterQuality) {
const SkPMColor* row1 = s.fPixmap.addr32(0, iY1);
if (s.fAlphaScale < 256) {
@ -613,7 +616,7 @@ SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() {
static const unsigned kMask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
if (1 == fPixmap.width() && 0 == (fInvType & ~kMask)) {
if (kNone_SkFilterQuality == fFilterLevel &&
if (kNone_SkFilterQuality == fFilterQuality &&
fInvType <= SkMatrix::kTranslate_Mask &&
!this->setupForTranslate()) {
return DoNothing_shaderproc;
@ -627,7 +630,7 @@ SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() {
if (fInvType > SkMatrix::kTranslate_Mask) {
return nullptr;
}
if (kNone_SkFilterQuality != fFilterLevel) {
if (kNone_SkFilterQuality != fFilterQuality) {
return nullptr;
}
@ -723,9 +726,11 @@ void SkBitmapProcState::DebugMatrixProc(const SkBitmapProcState& state,
// scale -vs- affine
// filter -vs- nofilter
if (state.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
proc = state.fFilterLevel != kNone_SkFilterQuality ? check_scale_filter : check_scale_nofilter;
proc = state.fFilterQuality != kNone_SkFilterQuality ?
check_scale_filter : check_scale_nofilter;
} else {
proc = state.fFilterLevel != kNone_SkFilterQuality ? check_affine_filter : check_affine_nofilter;
proc = state.fFilterQuality != kNone_SkFilterQuality ?
check_affine_filter : check_affine_nofilter;
}
proc(bitmapXY, count, state.fPixmap.width(), state.fPixmap.height());
}
@ -760,7 +765,7 @@ int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
size >>= 2;
}
if (fFilterLevel != kNone_SkFilterQuality) {
if (fFilterQuality != kNone_SkFilterQuality) {
size >>= 1;
}

View File

@ -27,10 +27,40 @@ typedef SkFixed3232 SkFractionalInt;
class SkPaint;
struct SkBitmapProcState {
SkBitmapProcState(const SkBitmapProvider&, SkShader::TileMode tmx, SkShader::TileMode tmy);
SkBitmapProcState(const SkBitmap&, SkShader::TileMode tmx, SkShader::TileMode tmy);
~SkBitmapProcState();
struct SkBitmapProcInfo {
SkBitmapProcInfo(const SkBitmapProvider&, SkShader::TileMode tmx, SkShader::TileMode tmy);
SkBitmapProcInfo(const SkBitmap&, SkShader::TileMode tmx, SkShader::TileMode tmy);
~SkBitmapProcInfo();
const SkBitmapProvider fProvider;
SkPixmap fPixmap;
SkMatrix fInvMatrix; // copy of what is in fBMState, can we remove the dup?
SkColor fPaintColor;
SkShader::TileMode fTileModeX;
SkShader::TileMode fTileModeY;
SkFilterQuality fFilterQuality;
SkMatrix::TypeMask fInvType;
bool init(const SkMatrix& inverse, const SkPaint&);
private:
enum {
kBMStateSize = 136 // found by inspection. if too small, we will call new/delete
};
SkAlignedSStorage<kBMStateSize> fBMStateStorage;
SkBitmapController::State* fBMState;
};
struct SkBitmapProcState : public SkBitmapProcInfo {
SkBitmapProcState(const SkBitmapProvider& prov, SkShader::TileMode tmx, SkShader::TileMode tmy)
: SkBitmapProcInfo(prov, tmx, tmy) {}
SkBitmapProcState(const SkBitmap& bitmap, SkShader::TileMode tmx, SkShader::TileMode tmy)
: SkBitmapProcInfo(bitmap, tmx, tmy) {}
bool setup(const SkMatrix& inv, const SkPaint& paint) {
return this->init(inv, paint) && this->chooseProcs();
}
typedef void (*ShaderProc32)(const void* ctx, int x, int y, SkPMColor[], int count);
@ -50,11 +80,7 @@ struct SkBitmapProcState {
typedef U16CPU (*FixedTileLowBitsProc)(SkFixed, int); // returns 0..0xF
typedef U16CPU (*IntTileProc)(int value, int count); // returns 0..count-1
SkPixmap fPixmap;
SkMatrix fInvMatrix; // copy of what is in fBMState, can we remove the dup?
SkMatrix::MapXYProc fInvProc; // chooseProcs
SkFractionalInt fInvSxFractionalInt;
SkFractionalInt fInvKyFractionalInt;
@ -66,14 +92,10 @@ struct SkBitmapProcState {
SkFixed fFilterOneX;
SkFixed fFilterOneY;
SkPMColor fPaintPMColor; // chooseProcs - A8 config
SkFixed fInvSx; // chooseProcs
SkFixed fInvKy; // chooseProcs
SkPMColor fPaintPMColor; // chooseProcs - A8 config
uint16_t fAlphaScale; // chooseProcs
uint8_t fInvType; // chooseProcs
uint8_t fTileModeX; // CONSTRUCTOR
uint8_t fTileModeY; // CONSTRUCTOR
uint8_t fFilterLevel; // chooseProcs
/** Platforms implement this, and can optionally overwrite only the
following fields:
@ -114,26 +136,15 @@ struct SkBitmapProcState {
SampleProc32 getSampleProc32() const { return fSampleProc32; }
private:
friend class SkBitmapProcShader;
friend class SkLightingShaderImpl;
ShaderProc32 fShaderProc32; // chooseProcs
ShaderProc16 fShaderProc16; // chooseProcs
// These are used if the shaderproc is nullptr
MatrixProc fMatrixProc; // chooseProcs
SampleProc32 fSampleProc32; // chooseProcs
const SkBitmapProvider fProvider;
enum {
kBMStateSize = 136 // found by inspection. if too small, we will call new/delete
};
SkAlignedSStorage<kBMStateSize> fBMStateStorage;
SkBitmapController::State* fBMState;
MatrixProc chooseMatrixProc(bool trivial_matrix);
bool chooseProcs(const SkMatrix& inv, const SkPaint&);
bool chooseScanlineProcs(bool trivialMatrix, bool clampClamp, const SkPaint& paint);
bool chooseProcs(); // caller must have called init() first (on our base-class)
bool chooseScanlineProcs(bool trivialMatrix, bool clampClamp);
ShaderProc32 chooseShaderProc32();
// Return false if we failed to setup for fast translate (e.g. overflow)
@ -199,7 +210,7 @@ public:
SkIntToScalar(y) + SK_ScalarHalf, &pt);
SkFixed biasX, biasY;
if (s.fFilterLevel == kNone_SkFilterQuality) {
if (s.fFilterQuality == kNone_SkFilterQuality) {
// SkFixed epsilon bias to ensure inverse-mapped bitmap coordinates are rounded
// consistently WRT geometry. Note that we only need the bias for positive scales:
// for negative scales, the rounding is intrinsically correct.

View File

@ -485,7 +485,7 @@ static void mirrorx_nofilter_trans(const SkBitmapProcState& s,
SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) {
// test_int_tileprocs();
// check for our special case when there is no scale/affine/perspective
if (trivial_matrix && kNone_SkFilterQuality == fFilterLevel) {
if (trivial_matrix && kNone_SkFilterQuality == fFilterQuality) {
fIntTileProcY = choose_int_tile_proc(fTileModeY);
switch (fTileModeX) {
case SkShader::kClamp_TileMode:
@ -498,7 +498,7 @@ SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc(bool trivial_m
}
int index = 0;
if (fFilterLevel != kNone_SkFilterQuality) {
if (fFilterQuality != kNone_SkFilterQuality) {
index = 1;
}
if (fInvType & SkMatrix::kPerspective_Mask) {

View File

@ -25,7 +25,7 @@ void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
int count, SkPMColor* SK_RESTRICT colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
SkASSERT(kNone_SkFilterQuality == s.fFilterQuality);
SkDEBUGCODE(CHECKSTATE(s);)
#ifdef PREAMBLE
@ -68,7 +68,7 @@ void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
int count, SkPMColor* SK_RESTRICT colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
SkASSERT(kNone_SkFilterQuality == s.fFilterQuality);
SkDEBUGCODE(CHECKSTATE(s);)
#ifdef PREAMBLE
@ -122,7 +122,7 @@ void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
int count, SkPMColor* SK_RESTRICT colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkDEBUGCODE(CHECKSTATE(s);)
#ifdef PREAMBLE
@ -168,7 +168,7 @@ void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
int count, SkPMColor* SK_RESTRICT colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkDEBUGCODE(CHECKSTATE(s);)
#ifdef PREAMBLE

View File

@ -19,7 +19,7 @@ void SCALE_FILTER_NAME(const void* sIn, int x, int y, SkPMColor* SK_RESTRICT col
SkMatrix::kScale_Mask)) == 0);
SkASSERT(s.fInvKy == 0);
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkDEBUGCODE(CHECKSTATE(s);)
const unsigned maxX = s.fPixmap.width() - 1;

View File

@ -671,7 +671,7 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
SkBitmapProcState* diffuseState = new (diffuseStateStorage) SkBitmapProcState(fDiffuseMap,
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
SkASSERT(diffuseState);
if (!diffuseState->chooseProcs(diffTotalInv, *rec.fPaint)) {
if (!diffuseState->setup(diffTotalInv, *rec.fPaint)) {
diffuseState->~SkBitmapProcState();
return nullptr;
}
@ -680,7 +680,7 @@ SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
SkBitmapProcState* normalState = new (normalStateStorage) SkBitmapProcState(fNormalMap,
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
SkASSERT(normalState);
if (!normalState->chooseProcs(normTotalInv, *rec.fPaint)) {
if (!normalState->setup(normTotalInv, *rec.fPaint)) {
diffuseState->~SkBitmapProcState();
normalState->~SkBitmapProcState();
return nullptr;

View File

@ -42,8 +42,8 @@ bool SkImageShader::isOpaque() const {
return fImage->isOpaque();
}
size_t SkImageShader::contextSize(const ContextRec&) const {
return SkBitmapProcShader::ContextSize();
size_t SkImageShader::contextSize(const ContextRec& rec) const {
return SkBitmapProcShader::ContextSize(rec);
}
SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const {

View File

@ -15,7 +15,7 @@ void S32_opaque_D32_filter_DX_SSE2(const SkBitmapProcState& s,
const uint32_t* xy,
int count, uint32_t* colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkASSERT(kN32_SkColorType == s.fPixmap.colorType());
SkASSERT(s.fAlphaScale == 256);
@ -121,7 +121,7 @@ void S32_alpha_D32_filter_DX_SSE2(const SkBitmapProcState& s,
const uint32_t* xy,
int count, uint32_t* colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkASSERT(kN32_SkColorType == s.fPixmap.colorType());
SkASSERT(s.fAlphaScale < 256);

View File

@ -394,7 +394,7 @@ void S32_generic_D32_filter_DX_SSSE3(const SkBitmapProcState& s,
const uint32_t* xy,
int count, uint32_t* colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkASSERT(kN32_SkColorType == s.fPixmap.colorType());
if (has_alpha) {
SkASSERT(s.fAlphaScale < 256);
@ -586,7 +586,7 @@ void S32_generic_D32_filter_DXDY_SSSE3(const SkBitmapProcState& s,
const uint32_t* xy,
int count, uint32_t* colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
SkASSERT(s.fFilterQuality != kNone_SkFilterQuality);
SkASSERT(kN32_SkColorType == s.fPixmap.colorType());
if (has_alpha) {
SkASSERT(s.fAlphaScale < 256);

View File

@ -17,7 +17,7 @@ static void SI8_opaque_D32_nofilter_DX_mips_dsp(const SkBitmapProcState& s,
int count, SkPMColor* SK_RESTRICT colors) {
SkASSERT(count > 0 && colors != nullptr);
SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
SkASSERT(kNone_SkFilterQuality == s.fFilterQuality);
const SkPMColor* SK_RESTRICT table = s.fPixmap.ctable()->readColors();
const uint8_t* SK_RESTRICT srcAddr = (const uint8_t*)s.fPixmap.addr();
srcAddr = (const uint8_t*)((const char*)srcAddr + xy[0] * s.fPixmap.rowBytes());
@ -246,7 +246,7 @@ void SkBitmapProcState::platformProcs() {
switch (fPixmap.colorType()) {
case kIndex_8_SkColorType:
if (justDx && kNone_SkFilterQuality == fFilterLevel) {
if (justDx && kNone_SkFilterQuality == fFilterQuality) {
if (isOpaque) {
fSampleProc32 = SI8_opaque_D32_nofilter_DX_mips_dsp;
fShaderProc32 = nullptr;