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:
parent
391395dcfb
commit
05a5647efe
@ -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"
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user