Blitter for repeat RGBA8888->RGBA8888.
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1852613002 Review URL: https://codereview.chromium.org/1852613002
This commit is contained in:
parent
9ac5b91957
commit
69076fe5cf
@ -121,12 +121,19 @@ public:
|
||||
SkBitmapProcInfo* info)
|
||||
: INHERITED(shader, rec, info)
|
||||
{
|
||||
// Save things off in case we need to build a blitter pipeline.
|
||||
fSrcPixmap = info->fPixmap;
|
||||
fAlpha = SkColorGetA(info->fPaintColor) / 255.0f;
|
||||
fXMode = info->fTileModeX;
|
||||
fYMode = info->fTileModeY;
|
||||
fFilterQuality = info->fFilterQuality;
|
||||
fMatrixTypeMask = info->fRealInvMatrix.getType();
|
||||
|
||||
// Need to ensure that our pipeline is created at a 16byte aligned address
|
||||
fPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fStorage);
|
||||
float alpha = SkColorGetA(info->fPaintColor) / 255.0f;
|
||||
new (fPipeline) SkLinearBitmapPipeline(info->fRealInvMatrix, info->fFilterQuality,
|
||||
fShaderPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fShaderStorage);
|
||||
new (fShaderPipeline) SkLinearBitmapPipeline(info->fRealInvMatrix, info->fFilterQuality,
|
||||
info->fTileModeX, info->fTileModeY,
|
||||
alpha,
|
||||
fAlpha,
|
||||
info->fPixmap);
|
||||
|
||||
// To implement the old shadeSpan entry-point, we need to efficiently convert our native
|
||||
@ -138,11 +145,14 @@ public:
|
||||
|
||||
~LinearPipelineContext() override {
|
||||
// since we did a manual new, we need to manually destroy as well.
|
||||
fPipeline->~SkLinearBitmapPipeline();
|
||||
fShaderPipeline->~SkLinearBitmapPipeline();
|
||||
if (fBlitterPipeline != nullptr) {
|
||||
fBlitterPipeline->~SkLinearBitmapPipeline();
|
||||
}
|
||||
}
|
||||
|
||||
void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override {
|
||||
fPipeline->shadeSpan4f(x, y, dstC, count);
|
||||
fShaderPipeline->shadeSpan4f(x, y, dstC, count);
|
||||
}
|
||||
|
||||
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
|
||||
@ -151,7 +161,7 @@ public:
|
||||
|
||||
while (count > 0) {
|
||||
const int n = SkTMin(count, N);
|
||||
fPipeline->shadeSpan4f(x, y, tmp, n);
|
||||
fShaderPipeline->shadeSpan4f(x, y, tmp, n);
|
||||
fXferProc(nullptr, dstC, tmp, n, nullptr);
|
||||
dstC += n;
|
||||
x += n;
|
||||
@ -159,14 +169,53 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool onChooseBlitProcs(const SkImageInfo& dstInfo, BlitState* state) override {
|
||||
SkXfermode::Mode mode;
|
||||
if (!SkXfermode::AsMode(state->fXfer, &mode)) { return false; }
|
||||
|
||||
// Need to ensure that our pipeline is created at a 16byte aligned address
|
||||
fBlitterPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fBlitterStorage);
|
||||
if (SkLinearBitmapPipeline::ClonePipelineForBlitting(
|
||||
fBlitterPipeline, *fShaderPipeline,
|
||||
fMatrixTypeMask,
|
||||
fXMode, fYMode,
|
||||
fFilterQuality, fSrcPixmap,
|
||||
fAlpha, mode, dstInfo)) {
|
||||
|
||||
state->fStorage[0] = fBlitterPipeline;
|
||||
state->fBlitBW = &LinearPipelineContext::ForwardToPipeline;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Did not successfully create a pipeline so don't destruct it.
|
||||
fBlitterPipeline = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ForwardToPipeline(BlitState* state, int x, int y, const SkPixmap& dst, int count) {
|
||||
SkLinearBitmapPipeline* pipeline = static_cast<SkLinearBitmapPipeline*>(state->fStorage[0]);
|
||||
void* addr = dst.writable_addr32(x, y);
|
||||
pipeline->blitSpan(x, y, addr, count);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
enum {
|
||||
kActualSize = sizeof(SkLinearBitmapPipeline),
|
||||
kPaddedSize = SkAlignPtr(kActualSize + 12),
|
||||
};
|
||||
void* fStorage[kPaddedSize / sizeof(void*)];
|
||||
SkLinearBitmapPipeline* fPipeline;
|
||||
void* fShaderStorage[kPaddedSize / sizeof(void*)];
|
||||
SkLinearBitmapPipeline* fShaderPipeline;
|
||||
void* fBlitterStorage[kPaddedSize / sizeof(void*)];
|
||||
SkLinearBitmapPipeline* fBlitterPipeline{nullptr};
|
||||
SkXfermode::D32Proc fXferProc;
|
||||
SkPixmap fSrcPixmap;
|
||||
float fAlpha;
|
||||
SkShader::TileMode fXMode;
|
||||
SkShader::TileMode fYMode;
|
||||
SkMatrix::TypeMask fMatrixTypeMask;
|
||||
SkFilterQuality fFilterQuality;
|
||||
|
||||
typedef BitmapProcInfoContext INHERITED;
|
||||
};
|
||||
|
@ -50,7 +50,7 @@ private:
|
||||
typedef SkShader INHERITED;
|
||||
};
|
||||
|
||||
enum {kSkBlitterContextSize = 2400};
|
||||
enum {kSkBlitterContextSize = 3100};
|
||||
|
||||
// Commonly used allocator. It currently is only used to allocate up to 3 objects. The total
|
||||
// bytes requested is calculated using one of our large shaders, its context size plus the size of
|
||||
|
@ -776,7 +776,68 @@ SkLinearBitmapPipeline::SkLinearBitmapPipeline(
|
||||
fLastStage = blenderStage;
|
||||
}
|
||||
|
||||
bool SkLinearBitmapPipeline::ClonePipelineForBlitting(
|
||||
void* blitterStorage,
|
||||
const SkLinearBitmapPipeline& pipeline,
|
||||
SkMatrix::TypeMask matrixMask,
|
||||
SkShader::TileMode xTileMode,
|
||||
SkShader::TileMode yTileMode,
|
||||
SkFilterQuality filterQuality,
|
||||
const SkPixmap& srcPixmap,
|
||||
float finalAlpha,
|
||||
SkXfermode::Mode xferMode,
|
||||
const SkImageInfo& dstInfo)
|
||||
{
|
||||
if (matrixMask & ~SkMatrix::kTranslate_Mask ) { return false; }
|
||||
if (filterQuality != SkFilterQuality::kNone_SkFilterQuality) { return false; }
|
||||
if (finalAlpha != 1.0f) { return false; }
|
||||
if (srcPixmap.info().colorType() != kRGBA_8888_SkColorType
|
||||
|| dstInfo.colorType() != kRGBA_8888_SkColorType) { return false; }
|
||||
|
||||
if (srcPixmap.info().profileType() != dstInfo.profileType()) { return false; }
|
||||
|
||||
if (xTileMode != SkShader::kRepeat_TileMode || yTileMode != SkShader::kRepeat_TileMode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xferMode == SkXfermode::kSrcOver_Mode
|
||||
&& srcPixmap.info().alphaType() == kOpaque_SkAlphaType) {
|
||||
xferMode = SkXfermode::kSrc_Mode;
|
||||
}
|
||||
|
||||
if (xferMode != SkXfermode::kSrc_Mode) { return false; }
|
||||
|
||||
new (blitterStorage) SkLinearBitmapPipeline(pipeline, srcPixmap, xferMode, dstInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SkLinearBitmapPipeline::SkLinearBitmapPipeline(
|
||||
const SkLinearBitmapPipeline& pipeline,
|
||||
const SkPixmap& srcPixmap,
|
||||
SkXfermode::Mode mode,
|
||||
const SkImageInfo& dstInfo)
|
||||
{
|
||||
SkASSERT(mode == SkXfermode::kSrc_Mode);
|
||||
SkASSERT(srcPixmap.info().colorType() == dstInfo.colorType()
|
||||
&& srcPixmap.info().colorType() == kRGBA_8888_SkColorType);
|
||||
|
||||
fSampleStage.initSink<RGBA8888UnitRepeat>(srcPixmap.writable_addr32(0, 0), srcPixmap.width());
|
||||
auto sampleStage = fSampleStage.get();
|
||||
auto tilerStage = pipeline.fTileStage.cloneStageTo(sampleStage, &fTileStage);
|
||||
tilerStage = (tilerStage != nullptr) ? tilerStage : sampleStage;
|
||||
auto matrixStage = pipeline.fMatrixStage.cloneStageTo(tilerStage, &fMatrixStage);
|
||||
matrixStage = (matrixStage != nullptr) ? matrixStage : tilerStage;
|
||||
fFirstStage = matrixStage;
|
||||
fLastStage = fSampleStage.getInterface<DestinationInterface, RGBA8888UnitRepeat>();
|
||||
}
|
||||
|
||||
void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) {
|
||||
SkASSERT(count > 0);
|
||||
this->blitSpan(x, y, dst, count);
|
||||
}
|
||||
|
||||
void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) {
|
||||
SkASSERT(count > 0);
|
||||
fLastStage->setDestination(dst, count);
|
||||
|
||||
|
@ -21,9 +21,25 @@ public:
|
||||
SkShader::TileMode xTile, SkShader::TileMode yTile,
|
||||
float postAlpha,
|
||||
const SkPixmap& srcPixmap);
|
||||
|
||||
|
||||
|
||||
static bool ClonePipelineForBlitting(
|
||||
void* blitterStorage,
|
||||
const SkLinearBitmapPipeline& pipeline,
|
||||
SkMatrix::TypeMask matrixMask,
|
||||
SkShader::TileMode xTileMode,
|
||||
SkShader::TileMode yTileMode,
|
||||
SkFilterQuality filterQuality,
|
||||
const SkPixmap& srcPixmap,
|
||||
float finalAlpha,
|
||||
SkXfermode::Mode xferMode,
|
||||
const SkImageInfo& dstInfo);
|
||||
|
||||
~SkLinearBitmapPipeline();
|
||||
|
||||
void shadeSpan4f(int x, int y, SkPM4f* dst, int count);
|
||||
void blitSpan(int32_t x, int32_t y, void* dst, int count);
|
||||
|
||||
template<typename Base, size_t kSize, typename Next = void>
|
||||
class Stage {
|
||||
@ -65,12 +81,18 @@ public:
|
||||
class DestinationInterface;
|
||||
|
||||
// These values were generated by the assert above in Stage::init{Sink|Stage}.
|
||||
using MatrixStage = Stage<PointProcessorInterface, 160, PointProcessorInterface>;
|
||||
using TileStage = Stage<PointProcessorInterface, 160, SampleProcessorInterface>;
|
||||
using MatrixStage = Stage<PointProcessorInterface, 160, PointProcessorInterface>;
|
||||
using TileStage = Stage<PointProcessorInterface, 160, SampleProcessorInterface>;
|
||||
using SampleStage = Stage<SampleProcessorInterface, 100, BlendProcessorInterface>;
|
||||
using BlenderStage = Stage<BlendProcessorInterface, 80>;
|
||||
using BlenderStage = Stage<BlendProcessorInterface, 40>;
|
||||
|
||||
private:
|
||||
SkLinearBitmapPipeline(
|
||||
const SkLinearBitmapPipeline& pipeline,
|
||||
const SkPixmap& srcPixmap,
|
||||
SkXfermode::Mode xferMode,
|
||||
const SkImageInfo& dstInfo);
|
||||
|
||||
PointProcessorInterface* fFirstStage;
|
||||
MatrixStage fMatrixStage;
|
||||
TileStage fTileStage;
|
||||
|
Loading…
Reference in New Issue
Block a user