Revert of add support for new bitmapshader context (patchset #5 id:80001 of https://codereview.chromium.org/1757993002/ )

Reason for revert:
oops, need to update bench to know about the large size needed for the new shader

Original issue's description:
> add support for new bitmapshader context
>
> BUG=skia:
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1757993002
>
> Committed: https://skia.googlesource.com/skia/+/19cef56344b5a5f26f802d7be34c44af36b7e797

TBR=herb@google.com,mtklein@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/1763743002
This commit is contained in:
reed 2016-03-03 09:36:50 -08:00 committed by Commit bot
parent 19cef56344
commit cd660e1c07
7 changed files with 30 additions and 115 deletions

View File

@ -60,7 +60,7 @@ static void draw_rect_orig(SkCanvas* canvas, const SkRect& r, SkColor c, const S
SkAutoTUnref<SkImage> image{SkImage::NewRasterCopy( SkAutoTUnref<SkImage> image{SkImage::NewRasterCopy(
info, pmsrc.addr32(), pmsrc.rowBytes())}; info, pmsrc.addr32(), pmsrc.rowBytes())};
SkPaint paint; SkPaint paint;
int32_t storage[300]; int32_t storage[200];
SkShader* shader = image->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); SkShader* shader = image->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
if (useBilerp) { if (useBilerp) {
paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality); paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);

View File

@ -27,7 +27,8 @@ static bool only_scale_and_translate(const SkMatrix& matrix) {
class BitmapProcInfoContext : public SkShader::Context { class BitmapProcInfoContext : public SkShader::Context {
public: public:
// The info has been allocated elsewhere, but we are responsible for calling its destructor. // 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, BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& rec,
SkBitmapProcInfo* info) SkBitmapProcInfo* info)
: INHERITED(shader, rec) : INHERITED(shader, rec)
@ -44,6 +45,8 @@ public:
} }
~BitmapProcInfoContext() override { ~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(); fInfo->~SkBitmapProcInfo();
} }
@ -60,6 +63,8 @@ private:
class BitmapProcShaderContext : public BitmapProcInfoContext { class BitmapProcShaderContext : public BitmapProcInfoContext {
public: 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, BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec,
SkBitmapProcState* state) SkBitmapProcState* state)
: INHERITED(shader, rec, state) : INHERITED(shader, rec, state)
@ -111,80 +116,11 @@ private:
}; };
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
#include "SkLinearBitmapPipeline.h"
#include "SkPM4f.h"
#include "SkXfermode.h"
class LinearPipelineContext : public BitmapProcInfoContext { size_t SkBitmapProcShader::ContextSize(const ContextRec& rec) {
public: // The SkBitmapProcState is stored outside of the context object, with the context holding
LinearPipelineContext(const SkShader& shader, const SkShader::ContextRec& rec, // a pointer to it.
SkBitmapProcInfo* info) return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
: INHERITED(shader, rec, info)
, fPipeline(info->fInvMatrix, info->fFilterQuality, info->fTileModeX, info->fTileModeY,
info->fPixmap)
{
// To implement the old shadeSpan entry-point, we need to efficiently convert our native
// floats into SkPMColor. The SkXfermode::D32Procs do exactly that.
//
sk_sp<SkXfermode> xfer(SkXfermode::Create(SkXfermode::kSrc_Mode));
fXferProc = SkXfermode::GetD32Proc(xfer.get(), 0);
}
void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override {
fPipeline.shadeSpan4f(x, y, dstC, count);
}
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
const int N = 128;
SkPM4f tmp[N];
while (count > 0) {
const int n = SkTMin(count, N);
fPipeline.shadeSpan4f(x, y, tmp, n);
fXferProc(nullptr, dstC, tmp, n, nullptr);
dstC += n;
x += n;
count -= n;
}
}
private:
SkLinearBitmapPipeline fPipeline;
SkXfermode::D32Proc fXferProc;
typedef BitmapProcInfoContext INHERITED;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImageInfo& srcInfo) {
// These src attributes are not supported in the new 4f context (yet)
//
if (srcInfo.bytesPerPixel() < 4 ||
kRGBA_F16_SkColorType == srcInfo.colorType()) {
return false;
}
#if 0 // later we may opt-in to the new code even if the client hasn't requested it...
// These src attributes are only supported in the new 4f context
//
if (srcInfo.isSRGB() ||
kUnpremul_SkAlphaType == srcInfo.alphaType() ||
(4 == srcInfo.bytesPerPixel() && kN32_SkColorType != srcInfo.colorType()))
{
return true;
}
#endif
// If we get here, we can reasonably use either context, respect the caller's preference
//
return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType;
}
size_t SkBitmapProcShader::ContextSize(const ContextRec& rec, const SkImageInfo& srcInfo) {
size_t size0 = sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
size_t size1 = sizeof(LinearPipelineContext) + sizeof(SkBitmapProcInfo);
return SkTMax(size0, size1);
} }
SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
@ -197,32 +133,16 @@ SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
return nullptr; return nullptr;
} }
// Decide if we can/want to use the new linear pipeine void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
bool useLinearPipeline = choose_linear_pipeline(rec, provider.info()); SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy);
if (SkShader::kMirror_TileMode == tmx || SkShader::kMirror_TileMode == tmy) {
useLinearPipeline = false; SkASSERT(state);
} if (!state->setup(totalInverse, *rec.fPaint)) {
if (totalInverse.hasPerspective()) { state->~SkBitmapProcState();
useLinearPipeline = false; return nullptr;
} }
if (useLinearPipeline) { return new (storage) BitmapProcShaderContext(shader, rec, state);
void* infoStorage = (char*)storage + sizeof(LinearPipelineContext);
SkBitmapProcInfo* info = new (infoStorage) SkBitmapProcInfo(provider, tmx, tmy);
if (!info->init(totalInverse, *rec.fPaint)) {
info->~SkBitmapProcInfo();
return nullptr;
}
return new (storage) LinearPipelineContext(shader, rec, info);
} else {
void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy);
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 { SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {

View File

@ -21,9 +21,7 @@ public:
bool isOpaque() const override; bool isOpaque() const override;
size_t contextSize(const ContextRec& rec) const override { size_t contextSize(const ContextRec& rec) const override { return ContextSize(rec); }
return ContextSize(rec, fRawBitmap.info());
}
SK_TO_STRING_OVERRIDE() SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader) SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader)
@ -38,13 +36,13 @@ protected:
Context* onCreateContext(const ContextRec&, void* storage) const override; Context* onCreateContext(const ContextRec&, void* storage) const override;
bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override; bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override;
SkBitmap fRawBitmap; SkBitmap fRawBitmap; // experimental for RLE encoding
uint8_t fTileModeX, fTileModeY; uint8_t fTileModeX, fTileModeY;
private: private:
friend class SkImageShader; friend class SkImageShader;
static size_t ContextSize(const ContextRec&, const SkImageInfo& srcInfo); static size_t ContextSize(const ContextRec&);
static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy, static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy,
const SkBitmapProvider&, const ContextRec&, void* storage); const SkBitmapProvider&, const ContextRec&, void* storage);
@ -56,7 +54,7 @@ private:
// an Sk3DBlitter in SkDraw.cpp // an Sk3DBlitter in SkDraw.cpp
// Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not // 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. // yet found a situation where the size below isn't big enough.
typedef SkSmallAllocator<3, 2100> SkTBlitterAllocator; typedef SkSmallAllocator<3, 1500> SkTBlitterAllocator;
// If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive // If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive
// the SkShader. // the SkShader.

View File

@ -31,9 +31,9 @@ SkComposeShader::~SkComposeShader() {
} }
size_t SkComposeShader::contextSize(const ContextRec& rec) const { size_t SkComposeShader::contextSize(const ContextRec& rec) const {
return SkAlign16(sizeof(ComposeShaderContext)) return sizeof(ComposeShaderContext)
+ SkAlign16(fShaderA->contextSize(rec)) + fShaderA->contextSize(rec)
+ SkAlign16(fShaderB->contextSize(rec)); + fShaderB->contextSize(rec);
} }
class SkAutoAlphaRestore { class SkAutoAlphaRestore {
@ -76,8 +76,8 @@ template <typename T> void safe_call_destructor(T* obj) {
} }
SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void* storage) const { SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void* storage) const {
char* aStorage = (char*) storage + SkAlign16(sizeof(ComposeShaderContext)); char* aStorage = (char*) storage + sizeof(ComposeShaderContext);
char* bStorage = aStorage + SkAlign16(fShaderA->contextSize(rec)); char* bStorage = aStorage + fShaderA->contextSize(rec);
// we preconcat our localMatrix (if any) with the device matrix // we preconcat our localMatrix (if any) with the device matrix
// before calling our sub-shaders // before calling our sub-shaders

View File

@ -86,9 +86,6 @@ bool SkShader::asLuminanceColor(SkColor* colorPtr) const {
} }
SkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const { SkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const {
// We currently require 16byte alignment for some of our subclasses, so assert that here.
SkASSERT(SkIsAlign16((intptr_t)storage));
if (!this->computeTotalInverse(rec, nullptr)) { if (!this->computeTotalInverse(rec, nullptr)) {
return nullptr; return nullptr;
} }

View File

@ -43,7 +43,7 @@ bool SkImageShader::isOpaque() const {
} }
size_t SkImageShader::contextSize(const ContextRec& rec) const { size_t SkImageShader::contextSize(const ContextRec& rec) const {
return SkBitmapProcShader::ContextSize(rec, SkBitmapProvider(fImage).info()); return SkBitmapProcShader::ContextSize(rec);
} }
SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const { SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const {

View File

@ -149,7 +149,7 @@ DEF_TEST(Color4f_shader, reporter) {
SkPaint paint; SkPaint paint;
for (const auto& rec : recs) { for (const auto& rec : recs) {
uint32_t storage[300]; uint32_t storage[200];
paint.setShader(rec.fFact())->unref(); paint.setShader(rec.fFact())->unref();
// Encourage 4f context selection. At some point we may need // Encourage 4f context selection. At some point we may need
// to instantiate two separate contexts for optimal 4b/4f selection. // to instantiate two separate contexts for optimal 4b/4f selection.